Skip to content

fix(han-planning): pin shared contracts before implementation - #204

Merged
mxriverlynn merged 3 commits into
v5.5.0-betafrom
gh-107-shared-data-contract
Sep 8, 2026
Merged

fix(han-planning): pin shared contracts before implementation#204
mxriverlynn merged 3 commits into
v5.5.0-betafrom
gh-107-shared-data-contract

Conversation

@mxriverlynn

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a contract-pinning checkpoint to the planning chain so a shared interface or data contract reaches concrete, buildable form before implementation instead of being invented mid-build. Closes Planning chain lets shared interface/data contracts reach implementation un-pinned (invented mid-build) #107.
  • One new owned rule (han-planning/references/contract-pinning-rule.md) consumed by four skills, plus one executable check with 15 Bats tests.
  • Second commit is guidance conformance and is reviewable on its own: script invocations converted from fenced blocks to prose across five skills, and plan-a-feature/SKILL.md brought under the 500-line ceiling.

Why

The chain (plan-a-featureplan-implementationplan-work-items, with iterative-plan-review as backstop) had no checkpoint forcing a contract into concrete form, so a "trusted" implementation plan could ship one as a to-be-authored deliverable. In the grounding incident the ledger's entry types were named but its line grammar never was: the schema doc shipped without it, a scanner invented a parsing regex against the undefined format, and the real grammar was retrofitted a day later. Zero of 17 review findings raised the gap.

Two additive gaps caused it. plan-implementation never required a contract in concrete form, and plan-work-items split one contract across items with no rule against it. Fixing either alone leaves the other live.

What reviewers should look at closely

The rule is binary, with no deferred-with-reason state. That was deliberate: an author who has an escape hatch writes "the grammar depends on the serialization library, TBD at build" and passes while leaving the same hole.

The new aggregation check stays out of the spec-maturity gate. That gate counts findings from distinct specialists, and a binary condition bolted onto counted logic breaks it. An unpinned contract raises an OQ-N instead, which the Step 6 loop already knows how to settle.

plan-work-items now reads the plan's Open Items. It previously never looked at that section at all, so a non-blocking open item vanished at the last stage that could see it. This came from a comment on the issue and generalizes past contracts.

The script is the only non-prose enforcement. Nine of ten changes are instructions followed by the same class of agent that missed the gap. check-contract-pinning.sh reports four failure classes separately and skips fenced blocks so a worked example never reads as a deferral. Two tests guard it beyond behavior: the per-skill copies stay byte-identical, and every phrase the script owns appears in the canonical rule.

How to verify

  • npm run lint
  • npm test (95 tests, 15 of them new)
  • bash han-planning/skills/plan-implementation/scripts/check-contract-pinning.sh <a plan file> <its folder> against a real plan folder
  • Read han-planning/references/contract-pinning-rule.md first; every other change cites it

Risk / rollback

Low. Nothing here changes an existing check's pass condition, and the one new executable check is additive. The largest behavioral change is that plan-implementation now treats an unpinned contract as reason to keep iterating rather than to ship, which can add a round on a plan that introduces a format. Revert with git revert.

Not in this PR

  • No version bump and no CHANGELOG entry; both belong to /han-release.
  • feature-implementation-plan-template.md is 163 lines with no Contents list. It is a document skeleton, so a Contents list would be copied into every plan it generates. Left as-is deliberately.

Closes #107.

The planning chain had no checkpoint forcing an interface or data contract
into concrete, buildable form before implementation, so a "trusted" plan
could ship a shared contract as a to-be-authored deliverable and a builder
would invent it mid-build. Two additive gaps: plan-implementation never
required a contract in concrete form, and plan-work-items split one contract
across items with no rule against it.

Adds han-planning/references/contract-pinning-rule.md, owned by han-planning
and consumed by four skills. It defines what counts as a contract, what
counts as pinned, the phrases that never close one, and which stage owns
pinning it. The rule is binary: there is no deferred-with-reason state,
because an author who has one writes "TBD at build" and passes.

plan-implementation pins it: a new operating principle, a Decision-field
rule making the decision log treat a format grammar the way it already
treats a key name, a specialist-brief directive so the finding is generated
at all, and a binary aggregation check that raises an Open Question rather
than touching the spec-maturity gate's counted trip conditions.

plan-work-items keeps it whole: a shared contract is pinned in the item that
introduces it with consumers sequenced behind it, and the passive
"not draftable" flag gains an exception for a contract this breakdown itself
authors. Step 4 now reads the plan's Open Items, including the non-blocking
ones it previously never looked at.

iterative-plan-review backstops it: five keywords added to both force-up
lists and a Contract Check in the iteration checklist.

plan-a-feature records the delegation: routing rule 3 gains one carve-out so
a shared contract becomes an Open Item rather than vanishing.

check-contract-pinning.sh gives the rule a mechanical proxy, reporting four
failure classes separately and skipping fenced blocks so a worked example
never reads as a deferral. Two tests guard it beyond behavior: the two
per-skill copies stay byte-identical, and every phrase the script owns
appears in the canonical rule.
…guidance

Two conformance fixes plus one gap the contract-pinning work missed.

Script calls were fenced code blocks in five skills. The authoring guidance
(han-plugin-builder/skills/guidance/references/skill-building-guidance/script-execution-instructions.md)
requires prose with an action verb, because Claude may read a fenced block as
code to display rather than a command to run. Converted every remaining call
site: plan-a-feature, plan-a-phased-build, plan-work-items, and
han-reporting/html-summary.

plan-a-feature/SKILL.md was 501 lines, one past the 500-line ceiling. The
`T#` note lifecycle was split across Step 4 (capture) and Step 5 (flush),
which is how the two halves drift apart. Both now live in one owned
reference, references/t-note-protocol.md, carrying the qualifying tests, the
in-message accumulator form, the flush procedure, and the no-candidate case.
The file is 476 lines.

The contract-pinning change updated both force-up keyword lists in
iterative-plan-review but missed a third in plan-a-feature's
finding-resolution.md. A finding that leaves a shared contract un-pinned now
forces up to major there too, and the pure-implementation branch names the
Open Item carve-out that mechanic-routing.md added.
The CLAUDE.md repository layout named only references/ under the
han-planning skills directory, but every one of its five skills also
carries scripts/.

The plan-implementation long-form doc opened its "What you get back"
section with "Four cross-referenced files" and then listed three,
omitting artifacts/scope-boundary.md, and its summary bullet promised
"All three file paths". The section also never named the two executed
checks the skill runs before it summarizes, though the sibling planning
docs name theirs.
@mxriverlynn
mxriverlynn marked this pull request as ready for review September 8, 2026 19:15
@mxriverlynn
mxriverlynn merged commit 250bf30 into v5.5.0-beta Sep 8, 2026
2 checks passed
@mxriverlynn
mxriverlynn deleted the gh-107-shared-data-contract branch September 8, 2026 19:15
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