feat: convert source-control to the retirement manifest; rationale-line the rest (Phase 2c) - #3601
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64ff162ff8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
f7aec15 to
f3d0a22
Compare
3315cbc to
26502c9
Compare
…ne the rest (Phase 2c) source-control ships retirements.yaml with one record, source-control-r001: the redundant `## convention_source` pointer naming the well-known default path, retired by the V2 well-known-path migration (#1185, v0.25.0) — line/migrate, judgment in the successor prose. The synced helper, the two fixed setup lines, an r001 eval, the registry uncomment, and the Implementers row land with it. The shadowed-markdown WARN and duplicate-key retirement stay bespoke prose: conditional on resolver state (neutral file resolving AND carrying the key), inexpressible as repo-scope presence records. Twin dedup done: the guards' shim-revision ladder + legacy cache-path wiring detection now live in one synced spoke (context-guard canonical), with sync script, registry entry, and CI lane; the six excluded bespoke migrations each carry a one-line reason class. Eight plugins patch-bumped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014uBXt1tMEReShbpG5gsFUd Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
The Phase 2c stays-bespoke rationale pushed the file to 501; compressed to one sentence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014uBXt1tMEReShbpG5gsFUd
The 500-line cap is exclusive; joined the probe-pair wrap to land at 499. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014uBXt1tMEReShbpG5gsFUd Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
…ment check The Phase 2c copy was written against pre-2b helper bytes. After #3597 the canonical file refuses a symlink parent on file and line --clean; the carrier copy must stay byte-identical. Also mark the new sync script executable. Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
b90e144 to
5777f74
Compare
|
Claude encountered an error after 5m 30s —— View job Code review in progress
|
affected-tests treats a new scripts/sync-*.sh with no sibling suite as unmapped. The suite asserts --check discriminates matching vs drifted copies, the same load-bearing contract as sync-spawn-noise.test.sh. Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
|
Claude finished @cursor[bot]'s task in 6m 39s —— View job Code review complete
This lane is scoped to correctness/maintainability (the repo carries a separate FindingsPosted one inline finding:
Codex's earlier finding on Other areas checked, no issues found
Not independently verifiedI could not execute shell scripts in this environment ( |
|
Claude has reviewed this PR 3 times. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
Contract 1.1 adds heading so a line leftover in a markdown file is not a whole-file match. source-control-r001 now fires only under ## convention_source; --clean leaves decoy path lines elsewhere untouched. Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
|
Claude finished @cursor[bot]'s task in 2m 31s —— View job Code review complete
This lane is scoped to correctness/maintainability (security concerns are left to the separate What changed since the last reviewCommit FindingsNone. I re-read the fix in full and it resolves the prior finding correctly rather than papering over it:
Not independently verifiedI don't have shell-execution approval in this environment ( |
ShellCheck SC2249 (add-default-case) failed hygiene on the new matching_line_nrs intersection loop. Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
|
Claude finished @cursor[bot]'s task in 56s —— View job Code review complete
Skip gate: no meaningful review surface since the last full reviewThe last full review round (12:09:38 UTC) covered everything through commit
I confirmed the two files remain byte-identical after this change, so the cross-plugin sync invariant the earlier reviews checked still holds. Per |
…#3620) Closes #3619 ## Summary Phase 2d PILOT of the customization-consistency program (ADR 0018): migrates plugin-quality's team-shared config surface from the dedicated `.claude/plugin-quality.md` three-layer cascade to a convention doc at the consumer's convention home (`<home>/plugin-quality/README.md`), bound by the pointer line and resolved by the shared resolver. First plugin to ship `retirements.yaml` alongside source-control's (records `plugin-quality-r001` migrate, `plugin-quality-r002` overlay delete), enrolling the check-retirements sync cluster and creating the resolve-convention-home cluster (sync script, registry entry, CI job). **Stacked on the Phase 2b PR (#3597)**; expect a trivial registry/ci.yml merge with the 2c PR (#3601) whichever lands second. ## Fix Reading side: audit resolves home → topic doc → dual-read (retired file is authority while present, WARN every run) → defaults; retired user-global/overlay layers read nowhere, WARN-visible. Setup: `check` reports the four resolver outcomes distinctly (exit 1 = INFO unconfigured, exit 3 causes = FAIL ask-don't-infer) plus the two fixed retirement lines; `apply` binds the home on operator confirmation only (marked-region append, never outside it), converges the topic doc (the old file's values are the migration source), then per-record gated cleanup. config-cascade and retired-conventions Implementers rows rewritten in the same PR per the doctrine's row rule. Bumps: plugin-quality 0.6.11, claude-config 0.40.5. ## Verification Deterministic consumer-repo sim (`scripts/pilot-plugin-quality-sim.test.sh`, 23 assertions, wired into the new resolve-convention-home-sync CI job): populated-AGENTS.md region append leaves prose byte-identical; resolver exit codes; exact detection TSV for both records; migrate-gate refusal without `--i-migrated`; clean + re-detect clean; CRLF root file. Validator (append-only + wiring + eval-per-record) green against origin/main; both sync clusters `--check`/`--check-bump` green; drift check green; resolver 61/61 and helper 174/174; markdownlint, shellcheck, eval lint, lane coverage, catalog/cheatsheet green; skill-quality PASS on both touched skills (audit SKILL.md trimmed back under the 500-line cap). ## Related Refs #3596/#3597 (mechanism), #3600/#3601 (2c), ADR 0018, config-cascade § Expression doctrine, retired-conventions convention. **POST-PILOT USER GATE:** this pilot is the template the user reviews before any other surface migrates — in particular seven flagged doctrine calls (overlay delete-not-migrate; no content_match on r002; WARN routed through the r002 record in setup while user-global stays prose-only; audit-side resolver exit-3 report-and-continue; dual-read eval living audit-side; records stamped with the shipping version; the gitignore-overlay recommendation dropped from the migrated surface). No other surface migrates until ratified. Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
…#3663) <!-- CURSOR_AGENT_PR_BODY_BEGIN --> Closes #3602 ## Summary rate-limit-guard's setup still treated bare quoting as an `sh -c` wrap trigger, the bug context-guard already fixed with `type -P` / `type -t`. The twins had drifted on the second half of their compose logic. ## Fix - Move peel rules and the shell-syntax guard into `reference/unwrap-before-compose.md`, canonical in context-guard and synced byte-identical into rate-limit-guard. - Guard triggers are unquoted top-level shell syntax, or a command word that is not an executable (`type -P` empty while `type -t` reports builtin/function/alias). Bare quoting is never a trigger. - Add `scripts/sync-unwrap-before-compose.sh` plus its discriminator test, a CI `unwrap-before-compose-sync` job on `ci-status.needs`, and a registry row. - Port the quoting / builtin / peel evals onto rate-limit-guard setup. The builtin-renderer expected `sh -c` argument uses the POSIX `'\''` escape so `printf` round-trips `ulimit '-n'` (same correction on the context-guard twin eval). - Bump `rate-limit-guard` 0.7.24 → 0.7.25 and `context-guard` 0.7.30 → 0.7.31. ## Verification - `scripts/sync-unwrap-before-compose.sh --check` — copies match. - `scripts/sync-unwrap-before-compose.test.sh` — 7/7. - `scripts/check-lane-coverage.sh --check` — 55 lanes reachable from `ci-status.needs`. - `scripts/check-cross-plugin-source-drift.sh --check` — no unregistered or drifted clusters. - `scripts/check-changelog-parity.sh --check-bump origin/main` — pass. - `scripts/check-changed-skills.sh origin/main` — 2 skills, 0 failed. - `printf '%s\n' 'ulimit '\''-n'\'''` prints `ulimit '-n'`. ## Related Follow-up from Phase 2c (`legacy-statusline-detect` extract). Refs #3601. <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-7ffb619a-6ebb-4d47-9c45-d68e846edf93?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-7ffb619a-6ebb-4d47-9c45-d68e846edf93&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>

Closes #3600
Summary
Phase 2c of the customization-consistency program: convert the one schema-expressible bespoke retirement (source-control's neutral-SSOT migration) to the retirements.yaml mechanism Phase 2b shipped, dedupe the context-guard/rate-limit-guard twin legacy-statusline detection through the cross-plugin sync registry, and stamp every remaining bespoke migration with its reason class. Stacked on the Phase 2b PR (#3597); retarget as the stack merges.
Fix
source-control-r001detects the redundant## convention_sourcepointer naming the well-known default path (docs/conventions/source-control/commit-convention.yml), retired when the V2 well-known-path migration (feat(source-control): well-known default path for neutral convention SSOT (F1–F4) #1185, v0.25.0) made rung 2 resolve that file pointer-free. Wiring per the owner doc: syncedlib/check-retirements.sh, the two fixed setup lines incheck/apply, one eval per record id, the registry uncomment, and the Implementers row. The shadowed-markdown WARN stays live prose with an explicit rationale: it is conditional on resolver state (a neutral file resolving and carrying the key), which the repo-scope presence schema cannot express, and markdown-H2 alone is still the sanctioned rung 3 — an append-only record that knowingly over-fires must not ship.skills/setup/reference/legacy-statusline-detect.md(context-guard canonical), withscripts/sync-legacy-statusline-detect.sh, a registry entry, and thelegacy-statusline-detect-syncCI lane inci-status.needs.apply) each state in one sentence why their migration logic stays bespoke.Verification
VALIDATE_CONTRACTS_BASE_REF=origin/main node scripts/validate-plugin-contracts.mjs— green (1 retirement manifest: schema, append-only, helper byte-identity, setup reference, eval coverage).source-control-r001row (exit 1);--cleanwithout--i-migratedrefuses (exit 2);--clean --i-migratedremoves exactly the pointer line (exit 0); re-detect clean (exit 0).sync-check-retirements.shandsync-legacy-statusline-detect.sh--check/--check-bump origin/main,check-cross-plugin-source-drift.sh --check,check-lane-coverage.sh --check(46 lanes) — all green.grep -n "shim-revision\|legacy" plugins/source-control/skills/setup/SKILL.md— zero hits; per skipped plugin the rationale line exists.Related
Refs #3596 (mechanism), PR #3597, ADR 0018 (decisions 4 and 6),
docs/conventions/retired-conventions/README.md,docs/MIGRATION-PLAYBOOK.md§ Retired conventions.