Skip to content

feat: convert source-control to the retirement manifest; rationale-line the rest (Phase 2c) - #3601

Merged
kyle-sexton merged 7 commits into
mainfrom
chore/bespoke-conversion
Sep 2, 2026
Merged

feat: convert source-control to the retirement manifest; rationale-line the rest (Phase 2c)#3601
kyle-sexton merged 7 commits into
mainfrom
chore/bespoke-conversion

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

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 ships its first retirement manifest. Record source-control-r001 detects the redundant ## convention_source pointer 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: synced lib/check-retirements.sh, the two fixed setup lines in check/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.
  • Twin dedup (ADR 0018, decision 6): the guards' shim-revision ladder and legacy version-pinned wiring detection now live in one byte-identical spoke, skills/setup/reference/legacy-statusline-detect.md (context-guard canonical), with scripts/sync-legacy-statusline-detect.sh, a registry entry, and the legacy-statusline-detect-sync CI lane in ci-status.needs.
  • Rationale lines: context-guard, rate-limit-guard, machine-health (machine-scope surface, outside the repo-scope schema per ADR 0018), work-items (forge-label backfill), guardrails (hook provisioning), planning and review (versioned-contract upgrade under apply) each state in one sentence why their migration logic stays bespoke.
  • Eight plugins patch-bumped with CHANGELOG entries (source-control 0.55.16, context-guard 0.7.22, rate-limit-guard 0.7.13, machine-health 0.11.5, work-items 0.39.25, guardrails 0.29.14, planning 0.34.7, review 0.26.9).

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).
  • Fixture-repo run of the helper: detect emits the source-control-r001 row (exit 1); --clean without --i-migrated refuses (exit 2); --clean --i-migrated removes exactly the pointer line (exit 0); re-detect clean (exit 0).
  • sync-check-retirements.sh and sync-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.
  • markdownlint clean on all touched markdown; shellcheck clean on the new sync script; catalog and cheatsheet checks in sync.
  • PLAN.md 2c Sanity Check: 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread .github/workflows/ci.yml
Comment thread plugins/source-control/retirements.yaml
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T22:40:20.326548Z 64ff162 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@kyle-sexton
kyle-sexton force-pushed the chore/retired-conventions-mechanism branch from f7aec15 to f3d0a22 Compare September 1, 2026 23:28
@cursor
cursor Bot force-pushed the chore/retired-conventions-mechanism branch from 3315cbc to 26502c9 Compare September 2, 2026 10:59
Base automatically changed from chore/retired-conventions-mechanism to main September 2, 2026 11:41
kyle-sexton and others added 4 commits September 2, 2026 11:43
…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>
@cursor
cursor Bot force-pushed the chore/bespoke-conversion branch from b90e144 to 5777f74 Compare September 2, 2026 11:43
@claude

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 5m 30s —— View job


Code review in progress

  • Gather context (PR diff, CLAUDE.md/AGENTS.md conventions)
  • Review changed files for correctness and maintainability
  • Post inline findings (if any)
  • Final summary

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

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Claude finished @cursor[bot]'s task in 6m 39s —— View job


Code review complete

  • Gather context (PR diff, CLAUDE.md/AGENTS.md conventions)
  • Invoke /review:code-review and follow its procedure
  • Review changed files for correctness and maintainability
  • Post inline findings (if any)
  • Final summary

This lane is scoped to correctness/maintainability (the repo carries a separate claude-security-review workflow, so security concerns are left to that lane per /review:code-review's gotchas).

Findings

Posted one inline finding:

  • plugins/source-control/retirements.yaml:10 (P2) — the source-control-r001 record's kind: line match has no heading context. Confirmed by reading present()/the --clean path in check-retirements.sh: it's a plain grep -E over every line, no awareness that the intended target is a value under the ## convention_source heading. The schema's only worked kind: line example is a .gitignore entry (every line independently meaningful); applying it to a heading-structured markdown file is a narrower fit. If the literal path string ever stands alone on a line elsewhere in .claude/source-control.md, detection false-fires and apply --clean --i-migrated deletes the wrong line. This is the same schema-expressiveness gap the PR body already calls out for the rung-3 WARN case — worth the same treatment (stay bespoke) or a heading-scoped matcher.

Codex's earlier finding on .github/workflows/ci.yml:663 (script not executable) no longer applies — I checked git ls-files -s at the current head (55c032c) and scripts/sync-legacy-statusline-detect.sh is mode 100755; a later commit in this PR (5777f74) already fixed it.

Other areas checked, no issues found

  • Version bumps and CHANGELOG entries for all 8 patch-bumped plugins line up correctly (one patch increment each, entry text matches the actual diff).
  • scripts/cross-plugin-source-registry.txt / scripts/sync-check-retirements.sh / scripts/sync-legacy-statusline-detect.sh wiring is internally consistent with ci.yml's new legacy-statusline-detect-sync job and its place in ci-status.needs.
  • The two legacy-statusline-detect.md reference copies (context-guard canonical, rate-limit-guard carrier) are byte-identical, and plugins/source-control/lib/check-retirements.sh is byte-identical to the claude-config canonical — both are real syncs, not new logic.
  • The severity mapping documented in source-control/skills/setup/SKILL.md (migrate→FAIL, delete/remove-line→WARN, report-only→INFO) matches docs/conventions/retired-conventions/README.md verbatim.
  • New eval id (21) in plugins/source-control/skills/setup/evals/evals.json doesn't collide with existing ids.
  • scripts/sync-legacy-statusline-detect.test.sh exercises sync/--check/--check-bump/--print-manifest with a real drift-discrimination case.

Not independently verified

I could not execute shell scripts in this environment (bash scripts/sync-legacy-statusline-detect.sh ..., the fixture-repo helper run, markdownlint/shellcheck) — commands beyond read-only git/grep required approval that wasn't available here. The PR body's listed verification commands and their claimed outputs are author-claimed and unverified by me; my review is based on static reading of the diff and the referenced scripts.

Comment thread plugins/source-control/retirements.yaml
Comment thread plugins/source-control/retirements.yaml
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

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

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Claude finished @cursor[bot]'s task in 2m 31s —— View job


Code review complete

  • Gather context (PR diff, CLAUDE.md/AGENTS.md conventions)
  • Invoke /review:code-review and follow its procedure
  • Review changed files for correctness and maintainability
  • Post inline findings (if any)
  • Final summary

This lane is scoped to correctness/maintainability (security concerns are left to the separate claude-security-review workflow per /review:code-review's gotchas).

What changed since the last review

Commit 49a9332 ("fix: scope kind:line retirements to an optional ATX heading") lands since the prior review round and directly addresses the P2 finding both Codex and the earlier Claude review raised on plugins/source-control/retirements.yaml — that the kind: line matcher had no heading context and could false-fire/mis-delete on a standalone occurrence of the path elsewhere in .claude/source-control.md.

Findings

None. I re-read the fix in full and it resolves the prior finding correctly rather than papering over it:

  • New optional heading field (retired-conventions contract bumped 1.0 → 1.1, docs/conventions/retired-conventions/README.md) — valid only on kind: line, an ATX heading string, frozen once published (implicitly, via RETIREMENT_MUTABLE_KEYS in validate-plugin-contracts.mjs:577 not listing it).
  • section_body_nrs/matching_line_nrs in check-retirements.sh:428-479 correctly scope both detection (present()) and --clean to the named heading's section body, ending a section at the next ATX heading of the same or higher level — so a nested subsection (e.g. ### nested under ## convention_source) is correctly still in-scope, while a sibling ## later section is not. I traced this by hand against the new test fixtures and it's right.
  • source-control-r001 now carries heading: '## convention_source' (retirements.yaml:10), closing exactly the false-positive/mis-delete gap flagged before.
  • Test coverage is thorough: plugins/claude-config/lib/check-retirements.test.sh case 22 covers in-section vs. decoy-outside-section vs. heading-with-no-match, nested subsections, CRLF, trailing whitespace, and two same-titled sections — including a --clean byte-for-byte diff assertion.
  • plugins/claude-config/lib/check-retirements.sh and plugins/source-control/lib/check-retirements.sh remain byte-identical after the change (verified with diff), so the cross-plugin sync invariant still holds.
  • validate-plugin-contracts.mjs's schema check for heading (kind-gating, ATX-shape regex) mirrors the shell helper's own validation, and its test file adds matching malformed-manifest cases.
  • Version bumps/CHANGELOGs for claude-config (0.40.29) and the retired-conventions contract (1.1) are consistent with the change; source-control's CHANGELOG entry text was updated to describe the heading scoping without a version bump, since 0.55.39 already covered this PR's addition.
  • The two findings from the previous review round are both resolved on this head: the heading scoping above, and (already fixed by an earlier commit, 5777f74) scripts/sync-legacy-statusline-detect.sh is confirmed still 100755 in git ls-files -s.

Not independently verified

I don't have shell-execution approval in this environment (bash/awk/test-script invocations were all declined) — I could not run check-retirements.test.sh, validate-plugin-contracts.test.sh, or the fixture-repo helper run myself. My review of the new section_body_nrs/matching_line_nrs logic and the test fixtures is a static trace, not an executed one. The PR body's listed verification commands and outputs remain author-claimed and unverified by me.

ShellCheck SC2249 (add-default-case) failed hygiene on the new
matching_line_nrs intersection loop.

Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
@claude

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Claude finished @cursor[bot]'s task in 56s —— View job


Code review complete

  • Gather context (PR diff, CLAUDE.md/AGENTS.md conventions)
  • Invoke /review:code-review and follow its procedure
  • Review changed files for correctness and maintainability
  • Post inline findings (if any)
  • Final summary

Skip gate: no meaningful review surface since the last full review

The last full review round (12:09:38 UTC) covered everything through commit 49a9332 — including the heading-scoping fix (matching_line_nrs/section_body_nrs) that resolved the earlier P2 finding on plugins/source-control/retirements.yaml. The only commit added since then is:

I confirmed the two files remain byte-identical after this change, so the cross-plugin sync invariant the earlier reviews checked still holds.

Per /review:code-review's skip gate ("change is trivial/automated with no meaningful review surface"), there is nothing new to review or flag. No inline comments posted this round; the prior findings (both resolved) and full review coverage stand as reported in the earlier comments on this PR.

@kyle-sexton
kyle-sexton merged commit 3355d57 into main Sep 2, 2026
66 checks passed
@kyle-sexton
kyle-sexton deleted the chore/bespoke-conversion branch September 2, 2026 12:33
kyle-sexton added a commit that referenced this pull request Sep 2, 2026
…#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>
kyle-sexton added a commit that referenced this pull request Sep 2, 2026
…#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>&nbsp;<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>&nbsp;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: ksextonmelodic <ksextonmelodic@gmail.com>
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.

conversion: source-control retirement manifest, twin dedup, stays-bespoke rationales (Phase 2c)

2 participants