Skip to content

fix(doctor): name last-resort reclaim for overbound project stores - #4799

Merged
ScriptedAlchemy merged 10 commits into
codex/cold-git-sync-diagnosticsfrom
fix/4616-doctor-last-resort-reclaim
Nov 9, 2026
Merged

ScriptedAlchemy merged 10 commits into
codex/cold-git-sync-diagnosticsfrom
fix/4616-doctor-last-resort-reclaim

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner

Root cause and narrow fix

Refs #4616 — partial acceptance item 4 only, not a sealed-generation garbage collector.

The canonical Doctor footprint finding for an overbound registered project reported only sizes. When automatic retention stalled there was no supported command in the finding to reclaim the project store. Existing tracedecay branch gc cannot collect these sealed generations, and a storage report is read-only. The existing first-party projects forget operation can reclaim the project store, but deletes the project’s local stored data, so it must never be presented as a routine or nondestructive fix.

  • In the existing footprint-to-Doctor production read path, name the actual supported tracedecay --dry-run projects forget proj_<id> preview, then explicit tracedecay --yes projects forget proj_<id> as a last resort only if retention stalls. State clearly that it DELETES project data. Do not run either command.
  • Offer this hint only when a registered project store is actually over its bound, with a validated project ID; not for a healthy store, unknown/unregistered store, or profile total.
  • Preserve actionable command and the numerical overage when the physical root path is very long by omitting only that verbose registered-root text from an already-bounded diagnostic.
  • Add a behavioral Rust regression using the existing real profile-footprint fixture and canonical Doctor finding to assert the actual overbound/healthy/unregistered/profile-total outcomes, supported command text, deletion warning, and long-path bound visibility.

Review and validation

Compared the exact three-commit branch against master 91c72aba7750a398dd28e83d64bf0c6d6fef4172: one file only, crates/tracedecay-maintenance/src/retention/footprint.rs; no schema, dependency, native filesystem cleanup, or scheduler changes. Each published update used force=false and an exact expected-old-head fast-forward; peer branches are untouched.

On 74904325cc, the full native macOS Bazel maintenance unit target passed all 161 tests in 29.93s. The overbound registered-store guidance, unusable project selectors, and sparse 15 GiB/long-root evidence regressions each executed and passed. The earlier 183-target Linux run on the same Doctor feature also ran the maintenance binary uncached in 78.5s. The current branch remains held for its prerequisite, independent review and exact hosted qualification.

Explicitly not solved

This does not satisfy #4616's full acceptance: automatic N>3 sealed retirement, ownership-safe removal under ancestor/real-directory substitution, unsafe-artifact isolation on the actual target, fair progress under sustained writers, and OOM-safe ~70-generation / 15 GB storage-report behavior still require independent proof on master. Do not close #4616 or claim this PR solves retention. Never merge or auto-merge the separate mixed draft #4776 or any Kev/decision-model changes. Release #4763 untouched. No production, infrastructure, tag, or credential writes.

At 74904325cc, the scope review identified three files unrelated to Doctor. The scheduler fixture already landed on master. Draft #4841 owns the two cold Git sync files. This PR now compares exactly one file against that prerequisite. Its footprint.rs blob is identical to 621940d19e. The updated-head workflow is pending. Keep this PR held for the draft prerequisite, independent review and qualification.

@changeset-bot

changeset-bot Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 4f8b7d7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Reject empty project selectors and budget the entire finding, including both commands, deletion warning and measured overage. Omit actions that cannot fit intact. Add filesystem-backed malformed/long-selector regressions and sparse 15 GiB reporting coverage with a canonical identity and long Unicode root.

Preserve concurrent formatting commit d7c2d3a. Native Bazel validation remains required; no Cargo commands or CI changes.

Refs #4616

Copy link
Copy Markdown
Owner Author

Published review follow-up f0c834d. Refs #4616 (partial Doctor acceptance only).

Two concrete gaps were found: the selector predicate accepted the empty proj_ suffix, and limiting only the displayed root length did not guarantee that a long selector's destructive command or the measured overage survived Doctor's 512-byte statement bound.

The production finding now rejects an empty selector suffix and checks the complete rendered finding using the same formatter/bounding function as the final output. It first omits the optional root text; if the deletion warning, both complete commands and measured bound still cannot fit, it omits the action rather than printing a partial destructive command. Healthy/unregistered/profile-total behavior is unchanged.

Added two filesystem-backed Rust regressions: malformed/empty/long registered selectors must remain degraded without unsafe command suggestions, and a sparse 15 GiB store with a canonical project identity and long Unicode root must retain both complete commands, deletion warning and numerical overage. Tests assert the fixture files are unchanged. These exercise the census -> canonical Doctor finding path; the negative empty/long-selector cases expose the prior behavior.

Concurrency: the initial exact-head publication was rejected after the branch advanced. I read and preserved concurrent formatting commit d7c2d3a, rebuilt on that exact parent, reviewed the resulting one-file diff, and published with force=false, expected_sha=d7c2d3a0d8ae20e5fcfc7ed2403b4d1cc44e5ad1. The superseded unattached candidate 734877b was not pushed to this branch.

Validation: a separate Python rendering probe reproduced the empty/long-selector failures and checked the revised layout, but this is NOT a Rust/Bazel test pass. This environment has no Bazel, rustc or rustfmt and cannot fetch a checkout. No Cargo commands, CI weakening or merge were performed. Run bazel test //crates/tracedecay-maintenance:unit_test --test_output=errors on this exact head, confirm both new tests execute, and require hosted formatting/lint/review checks before merging. The sparse metadata regression is NOT proof of the complete ~70-generation reporting/OOM acceptance requirement. #4616 remains open; mixed #4776 remains draft and untouched.

Repair three hosted automation_runner_test failures by supplying the
configured executable identity required by the production prefilter.
Use the same identity for the prefilter and retained runner, preserving
manual-schedule, exact-ledger, live-lock and lock-race assertions.

Add a production-prefilter regression for unconfigured refusal,
deduplication and same-occurrence recovery after binding, with zero
backend calls and no effectful terminal. Do not relax backend admission,
change timeouts, or alter the graph publication changes.

Refs #4532

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@ScriptedAlchemy ScriptedAlchemy left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refs #4616 — merge-scope blocker after current-master comparison, not a finding against the Doctor behavior itself. The current #4799 head 621940d1 is 8 commits ahead and 2 behind master 83694e00. The reviewable diff includes the intended crates/tracedecay-maintenance/src/retention/footprint.rs plus three unrelated paths: crates/tracedecay-cli/tests/core_cli_suite/cli_non_interactive_test.rs, crates/tracedecay-session-runtime/src/session_sync/git_topology.rs, and crates/tracedecay/tests/automation_runner_test/jobs.rs. The last two commits are test(automation): bind scheduler fixtures to backend identities and fix(sessions): retain the cause of cold Git sync failures, unrelated to the Doctor slice. The exact-head CI run 42528342951 is green, but that does not establish the branch is a scoped Doctor PR. Please isolate the footprint change on a distinct clean branch/PR or otherwise reconcile concurrent ownership without rewriting peer commits. I have not modified or merged this branch.

@ScriptedAlchemy
ScriptedAlchemy changed the base branch from master to codex/cold-git-sync-diagnostics November 9, 2026 06:55
@ScriptedAlchemy
ScriptedAlchemy merged commit c1d1c90 into codex/cold-git-sync-diagnostics Nov 9, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sealed code-graph generations (tracedecay.sealed/) are never collected; busy project store grew to 56 GB over a 10 GB bound

1 participant