Skip to content

docs(ac-rigor): proposal-path enumeration clause for cross-branch merge-base failure mode#498

Merged
lukstafi merged 1 commit intomainfrom
ludics/task-097cca67-s2/root
May 5, 2026
Merged

docs(ac-rigor): proposal-path enumeration clause for cross-branch merge-base failure mode#498
lukstafi merged 1 commit intomainfrom
ludics/task-097cca67-s2/root

Conversation

@lukstafi
Copy link
Copy Markdown
Owner

@lukstafi lukstafi commented May 5, 2026

Summary

  • Adds a new sibling ### Proposal-path enumeration goes stale when proposal commits to main first — anchor to scope invariant clause under ## Verification-evidence family in docs/ac-rigor-reference.md, documenting the cross-branch merge-base failure mode that hit task-9cd6cdb9 (PR docs: lockstep contract-prose rewrite + stash-prod mutation-test clauses #490) round 1.
  • Prescribes the (b)-form scope invariant ("no src/**, no scripts/**, no templates/**, no *.test.ts") as the durable AC shape, plus the same-PR proposal-edit recovery; cross-links the sibling ### Diff-enumerated verification lines go stale clause (same toolset git diff --name-only main...HEAD, distinct trigger: cross-branch merge-base advance vs within-branch growth).
  • Bumps clause count "sixteen" → "seventeen" on line 5; adds the new clause title to skills/worker-conventions.md's family-grouped pointer (Process-around-the-AC bullet).
  • Negative control: skills/ludics-draft-proposal-worker.md unchanged. AC-shape guidance lives at the reference layer per feedback_reference_layer_not_inline.md.

Test plan

  • AC1 — awk '/^## Verification-evidence family/{p=1;next} p && /^## /{exit} p' docs/ac-rigor-reference.md | grep -F "### Proposal-path enumeration goes stale when proposal commits to main first" returns 1; same slice contains ### Diff-enumerated.
  • AC2 — grep -F "before the implementation" hits the new clause body.
  • AC3 — grep -F "scope invariant" AND grep -F "no \src/**`"` hit inside the new clause.
  • AC4 — grep -F "task-9cd6cdb9" AND grep -F "PR #490" both hit inside the new clause.
  • AC5 — Diff-enumerated cross-link in body; same toolset, distinct trigger, merge-base all present.
  • AC6 — same-PR and same PR both hit inside the recovery sentence.
  • AC7 — grep -F "Proposal-path enumeration goes stale when proposal commits to main first" skills/worker-conventions.md returns 1 hit (line 49).
  • AC8 — grep -F "sixteen clauses" returns 0; grep -F "seventeen clauses" returns 1.
  • AC9 negative control — git diff --name-only main...HEAD has no skills/ludics-draft-proposal-worker.md.
  • AC10 doc-only — git diff --name-only main...HEAD matches no src/**, scripts/**, templates/**, or *.test.ts paths; only docs/ac-rigor-reference.md and skills/worker-conventions.md.

🤖 Generated with Claude Code

…evidence family

New `### Proposal-path enumeration goes stale when proposal commits to
main first — anchor to scope invariant` sibling clause under
`## Verification-evidence family` in `docs/ac-rigor-reference.md`,
documenting the cross-branch merge-base failure mode that bit
task-9cd6cdb9 (PR #490) round 1: when the proposal commit lands on
`main` before the implementation branch forks, a literal
four-path enumeration AC silently fails because `main...HEAD`
returns only the implementation paths.

Prescribes the (b)-form scope invariant ("no `src/**`, no
`scripts/**`, no `templates/**`, no `*.test.ts`") as the
durable AC shape — what's NOT in the diff survives a merge-base
advance — and documents the same-PR proposal-edit recovery for
coders who hit the failure mode mid-round. Cross-links the
sibling `### Diff-enumerated verification lines go stale` clause
(same toolset, distinct trigger).

Promotes the clause-count line from "sixteen" to "seventeen"
clauses, and adds the new clause title to
`skills/worker-conventions.md`'s family-grouped pointer
(Process-around-the-AC bullet) so workers landing there
discover both clauses together.

Negative control: `skills/ludics-draft-proposal-worker.md` is
unchanged; the worker prompt's existing "consult
`docs/ac-rigor-reference.md`" hook is the entry point per
`feedback_reference_layer_not_inline.md`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lukstafi
Copy link
Copy Markdown
Owner Author

lukstafi commented May 5, 2026

@codex review Focus on bugs, correctness issues, and edge cases. Do not check adherence to a spec or plan.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

ℹ️ 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".

@lukstafi lukstafi merged commit 47f670c into main May 5, 2026
1 check passed
@lukstafi lukstafi deleted the ludics/task-097cca67-s2/root branch May 5, 2026 07:34
@lukstafi
Copy link
Copy Markdown
Owner Author

lukstafi commented May 5, 2026

Suggest Refactor — task-097cca67 / PR #498 retrospective

What I'd do differently next time, ordered by leverage:

1. Absorb the reciprocal cross-link (one-line addition I deferred)

The new ### Proposal-path enumeration goes stale… clause cross-links to the sibling ### Diff-enumerated verification lines go stale…, but the existing diff-enumerated clause has no link back to the new one. The proposal's Approach explicitly called this out as "optional" but flagged the asymmetry against the existing stash-prod ↔ stash-and-rerun precedent ("a reader landing on either clause should follow the cross-link to find the other"). I left it one-way. A one-sentence addition to the existing clause body — "See also: ### Proposal-path enumeration goes stale when proposal commits to main first for the cross-branch merge-base sibling case (same toolset, distinct trigger)." — would have closed the asymmetry inside the absorb-without-ceremony boundary (≤5 lines, same file already being edited). Reach for absorb on optional-marked symmetry-fixes when the addition is mechanical and the precedent is already in the same family. Pattern: "optional under the proposal's ACs" usually still satisfies the absorb test; ask whether the deferral is principled or a flinch.

2. The clause-count line is a drift hazard worth retiring

docs/ac-rigor-reference.md:5 reads "Today it covers seventeen clauses across five thematic families." Every clause add must remember to bump that integer; a lint script could derive it (grep -c '^### ' | xargs printf 'covers %d clauses') but the simpler fix is to drop the integer entirely — readers don't navigate by count, and the count adds no signal that the table-of-contents on line 11 doesn't already provide. Future task: either (a) replace "seventeen clauses across five thematic families" with "clauses across five thematic families" (count-free), or (b) add scripts/lint-ac-rigor-clause-count.ts that asserts the integer matches grep -c '^### '. (a) is cheaper and CI-resilient by construction; (b) is more aligned with this repo's lint-pair patterns. Either way, the integer is a near-certain drift target on the next clause add.

3. (b)-form scope invariants need explicit "verify post-commit" guidance

AC10 of this proposal modelled the (b)-form invariant the new clause prescribes — "no src/**, scripts/**, templates/**, or *.test.ts paths in git diff --name-only main...HEAD" — and I caught this round 1 only because I happened to run the falsifier after committing. Pre-commit, the diff was empty (the precipitating case was actively reproducing on this branch — proposal 1609532 had merged to main as part of elaboration, leaving main..HEAD empty until I committed). A pre-commit run of the same falsifier passes vacuously: "no src/** paths" is trivially satisfied by an empty diff. The new clause should say so explicitly — add a sentence like "Verify the falsifier after committing the implementation; pre-commit, the diff against main is empty for the very reason the clause documents (the proposal already merged), so the harness condition isn't even instantiated." This generalises feedback_ac_evidence_post_commit_diff.md to (b)-form scope ACs specifically. Worth a follow-up sentence-add to the new clause, or — cheaper — a sibling clause that names the post-commit-verification rule for (b)-form invariants generally.

4. Eat-your-own-dog-food is a teachable proposal-authoring pattern

The proposal's AC10 instantiated the (b)-form invariant the clause prescribes — "the (b)-form this proposal is itself prescribing — eats its own dog food." This is a deliberate authoring pattern that's currently undocumented anywhere and would belong as a one-line addition to either ludics-draft-proposal-worker.md's template guidance or ac-rigor-reference.md's Falsifier-shape family: "When a proposal introduces a new AC shape at the reference layer, instantiate that shape in the proposal's own ACs — not just describe it. The proposal then demonstrates the pattern is enforceable rather than merely advocating it." Could pair with the existing feedback_reference_layer_not_inline.md rule. Future task seed: "extract dog-fooding as an AC-authoring pattern."

5. Branch state inspection should precede AC10-shape verifications

Before running any main...HEAD-based falsifier, check git log main..HEAD --oneline. If empty, the falsifier is vacuous (no commits on the branch yet); if it contains the proposal commit, the (b)-form invariant has signal; if it's empty and the proposal commit is on main (the precipitating case), AC10-shape ACs verify only post-commit. This is a five-second sanity check that catches "I'm about to run a vacuous probe" without ceremony. Worth a one-line addition to the worker's pre-flight checklist or the orchestration-patterns "exhaustive occurrence search" section.

Strengths to preserve (not for change, for memory)

  • Single-commit, two-file PR with all 10 ACs verified post-commit and codex review clean. Doc-only invariants verified round 1.
  • The awk '/^## Foo/{p=1;next} p && /^## /{exit} p' bounded-slice pattern (the safer form per feedback_awk_range_degenerate_when_start_matches_close.md) generalised cleanly to taxonomy-doc family-bounded clause-presence verification — promote as default shape when verifying "clause X exists inside section Y of doc Z."

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.

1 participant