chore(console): reconcile the June work that now has docs - #71
Conversation
96bfb2f to
c10548f
Compare
|
Review finding, fixed in-place before merge.
— a home directory and a real name, about to land in a public repo, and meaningless on any other host. Verified Replaced with the spec's own Safe to hand-edit: The generator bug is ContextLifecycle's and is not fixed here — it will reproduce on the next prune in any repo. |
First `cl reconcile prune --apply` this repo has had. It was unrunnable here until ContextLifecycle #52 gave the lock an msvcrt backend (`reconcile_lock` raised on any non-POSIX host) -- the mechanical reason this log has been hand-trimmed for months rather than reconciled. Six sections went to the private archive: INJ1, DC10 and the four D12 entries, exactly the work #68 documented. The DOC GAP gate held the rest back, correctly -- pattern-collision masking, the orphan-scaffold cleanup and the `--only` gate have no durable doc, so they stay `partial`. What this actually rescues: by the time it landed, #66/#67/#69 had each hand-pruned to fit under RC1 and all six sections were ALREADY DELETED from main. ADR 0001 named that pattern in the abstract ("D12's 'ships OPT-IN -- was red-walling consumers' shaped C16's default in #69, and entries from that era are now gone"); this is the concrete instance. The archive is therefore not a tidier copy of what main holds, it is the only copy outside git history. Ran with `--recent 20`, not the default 10. At 10 the prune also sweeps unclaimed sections past the tenth purely by age, so the recency rule silently outranks the DOC GAP gate and would have archived the undocumented work the gate had just declined to release. The pointer is hand-corrected. `cl reconcile prune` writes the archive's ABSOLUTE local path (`prune.py` `_pointer_section`), which on this machine put a home directory and a real name into this public repo, and is meaningless on any other host. Replaced with the spec's `<private-manifest>/...` form, which is what boundary rule I2 requires anyway. Safe to edit: `_ensure_pointer` is idempotent on the heading plus pointer prefix rather than the path, verified by re-running prune. The generator bug is ContextLifecycle's and is not fixed here. No narrative log entry, deliberately. main sits at 389/400 and a full entry runs ~36 lines, so adding one would have meant pruning history to land a commit about not pruning history. ADR 0001 argues rationale belongs in commit messages rather than duplicated into the log; this follows that. The pointer is the log's record. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
c10548f to
b42f4f1
Compare
The 2026-08-03 reconciliation (#71) landed log.md at 395 lines against a 400-line r1_line_budget, leaving no room for the next entry to be written at all — the find_tool entry took it to 437 and red-failed our own audit on RC1. Second pass, same convention as the first: prune the two oldest surviving entries (2026-06-20 INJ1 detector, 2026-07-10 C32 punctuation-only values) into the reconciled note, and condense the find_tool entry to a summary. Full rationale lives in the commit message and PR #72; full history in git as always. 396 lines. Custodian's own audit is back to baseline — the single remaining finding (W2, core.hooksPath unset) is environmental in this clone and does not occur in CI, which sets it as the audit job's first step. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…todian's (#72) * fix(adapters): find_tool must prefer the AUDITED repo's venv, not Custodian's A globally-installed `custodian-multi` audited OperationsCenter — which pins `ruff==0.15.13` — using a system-wide ruff 0.16.1, and reported 1222 findings against a tree OC's own `ruff check` calls clean (BLE001 x316, UP045 x290, UP037 x118, ...). Same repo, same config, ruff 0.15.13: 0 findings. Vulture skewed the same way (621 findings). All of them phantom. Root cause: `find_tool()` resolved `Path(sys.executable).parent / name` — the venv Custodian ITSELF is installed in — then fell back to PATH. For a multi-repo auditor that is backwards. Each repo pins the toolchain its config was written against, so an audit is only meaningful when it runs those versions; the venv Custodian happens to live in has no authority over the repo in front of it. The old order was right by accident in the single-repo case (Custodian installed into the audited repo's venv) and silently wrong everywhere else — and "silently" is the problem, since the output is a plausible-looking wall of real rule codes. A second bug hid in the same three lines: `Path(sys.executable).parent / name` can never match on Windows, where console scripts are `ruff.exe` and live in `Scripts/` rather than `bin/`. The venv branch was dead code on that platform. Resolution order is now: 1. the audited repo's own venv (`.venv` then `venv`, `bin/` or `Scripts/`) 2. Custodian's own venv (unchanged fallback, still needed when the venv is not fully activated and `shutil.which` alone would miss it) 3. PATH `_executable()` tries `.exe`/`.bat`/`.cmd` on Windows, and both script-dir spellings are accepted on either host — a venv built under WSL but audited from Windows over /mnt/c carries the other platform's layout. The audited repo is scoped with a ContextVar and an `audited_repo()` context manager rather than a new parameter: `is_available()` takes no arguments, and it and `run()` must agree on which binary they are talking about. `cli/runner._run_adapters` wraps its adapter loop in it. Verified: 1238 passed, 5 skipped. Six new tests cover repo-venv preference, the no-venv fallback, both script-dir spellings, and that the ContextVar does not leak past the loop — a leak would make later repos in a `--repos a b c` run inherit the first repo's toolchain. Custodian's own audit is unchanged from baseline; the one remaining finding (W2, core.hooksPath unset) is environmental. Live proof: under `audited_repo(~/GitHub/OperationsCenter)`, `find_tool('ruff')` returns OC's pinned `.venv/bin/ruff` rather than Custodian's own. Noted, not fixed (pre-existing, reproduces at origin/main): tests/test_reconcile.py does not isolate $REPOGRAPH_BOUNDARY_ARTIFACT_FILE, so two tests fail whenever that variable is set in the caller's environment. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore(console): reconcile log.md so the new entry fits the RC1 budget The 2026-08-03 reconciliation (#71) landed log.md at 395 lines against a 400-line r1_line_budget, leaving no room for the next entry to be written at all — the find_tool entry took it to 437 and red-failed our own audit on RC1. Second pass, same convention as the first: prune the two oldest surviving entries (2026-06-20 INJ1 detector, 2026-07-10 C32 punctuation-only values) into the reconciled note, and condense the find_tool entry to a summary. Full rationale lives in the commit message and PR #72; full history in git as always. 396 lines. Custodian's own audit is back to baseline — the single remaining finding (W2, core.hooksPath unset) is environmental in this clone and does not occur in CI, which sets it as the audit job's first step. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
The first
cl reconcile prune --applythis repo has ever had. The workflow was unrunnable here until ContextLifecycle #52 gave the lock an msvcrt backend —reconcile_lockraised on any non-POSIX host, which is why this log kept being hand-trimmed instead of reconciled.Pairs with PrivateManifest#1, which carries the archived sections. Merge that one too, or the pointer in this log leads nowhere.
What moved
Six sections →
PrivateManifest/archive/console/Custodian/log-2026-08-03.md:feat: INJ1 prompt-injection signature detectorfeat(DC10): claims-integrated-while-deferring detector (opt-in)fix(doctor): register d12_baseline as a known audit keyfeat(D12): baseline ratchet (audit.d12_baseline)D12 ships OPT-IN (default-off) — was red-walling consumersD12 precision: skip pytest_* plugin hooks (FP class)Exactly the work #68 documented. The DOC GAP gate holds the rest back, correctly — pattern-collision masking, the orphan-scaffold cleanup and the
--onlygate still have no durable doc, so they staypartialand stay in the log.The
--recentflag matters more than it looksRan with
--recent 20, not the default 10. At 10, prune archives claimed sections plus every unclaimed section past the tenth, purely by age — so the recency rule silently outranks the DOC GAP gate and would have archived exactly the undocumented work the gate had just declined to release.Worth knowing before anyone runs this with defaults.
Verification
nothing to archive; post-prunecheckis GREEN.console/log.md399 → 346, then 371 with this entry — RC1 clearOne wart
CHANGELOG lines are generated from worksheet titles, and those titles are built from tokens unique to each log heading rather than written as prose. Hence
ships default red walling consumers was. Legible, not elegant — flagging it since those lines are durable.🤖 Generated with Claude Code