Skip to content

✨ feat(examples): EX-S10 exit gate — P5-EX epic complete - #66

Merged
konih merged 6 commits into
mainfrom
lane/ex-s10
Aug 16, 2026
Merged

✨ feat(examples): EX-S10 exit gate — P5-EX epic complete#66
konih merged 6 commits into
mainfrom
lane/ex-s10

Conversation

@konih

@konih konih commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds hack/examples/ex_exitgate_test.sh, the P5-EX epic's capstone exit gate (EX-S10, openspec/specs/p5-ex-complex-examples/spec.md), proving the epic's invariants hold across the whole example suite:

  • REQ-EX-S10-01: all four formats (yaml/json/tfvars/tf) present via extraction independently derived from each pack's config.yaml match: lines (not the whole classes: block).
  • REQ-EX-S10-02/03: C1-C8 fixtures present with correct decisions — C3 (wildcard-grant) measured BLOCK, C8 (companion-delete) measured REVIEW via its inline cases.yaml shape (not the originally-assumed directory form).
  • REQ-EX-S10-04: schema freeze checked ref-relative against the v0.1.0 tag, not the working tree — avoids the D-132 vacuity trap (HEAD-substitution, empty base ref, tag-shaped branch, nonexistent tag all independently proven to fail red).
  • REQ-EX-S10-05: task check wiring intact (dogfood-examples, docs-gates, dogfood-wiring-test all present).
  • REQ-EX-S10-06: re-invokes S01's README-vs-dogfood format inventory.
  • REQ-EX-S10-07: internal/core untouched vs origin/main (three-dot diff), decision-path determinism (AGENTS.md rule 7) reaffirmed.
  • REQ-EX-S10-08: D-002 sanitization (hack/check-sanitization.sh) green, with a planted-token positive control on the scanner itself.
  • Provider fence (REQ-EX-S07-05) re-verified: assent test never calls the provider host.

Also closes the REF-EX row in openspec/specs/backlog.md and updates the stale Phase-5 roadmap row.

Went through three independent review rounds, each closing a genuine vacuity bug in the gate's own format-detection logic — a fitting capstone irony for an anti-vacuity gate:

  1. A comment on its own line shaped like *.tf could satisfy the check after the real glob was removed.
  2. Format extraction was scoped to the whole classes: block rather than just match: lines (F2).
  3. A same-line trailing comment mentioning *.tf could still fool the check after the real glob was removed (F6).

Each fix was independently reproduced by a fresh reviewer against the real tree, not just trusted from the implementer's self-report.

This closes the entire P5-EX epic (S01-S10, ten stories).

Test plan

  • git rebase origin/main — already fast-forward, no conflicts (merge-base == origin/main tip)
  • task check green (full gate matrix, incl. depguard boundary, ARCH-02, workflow pins, dogfood wiring, CI audit)
  • bash hack/examples/ex_exitgate_test.sh passes directly (this is the lane's own deliverable — not wired into task check by design/scope, per this lane's own F3 finding)
  • Independent review: APPROVE after 3 rounds (2 real bugs found and fixed in the gate's own logic)
  • CI required checks green (verify, Analyze (go), Analyze (actions), CodeQL)

konih added 6 commits August 16, 2026 14:40
hack/examples/ex_exitgate_test.sh proves the epic's invariants in one
invocation: yaml/json/tfvars/tf all present in class match paths;
C1-C8 fixtures present (C8 is an inline cases.yaml entry per the
REQ-EX-S07-04 amendment, not a directory) with C8 measured REVIEW;
schema freeze is ref-relative against the v0.1.0 tag, not a
working-tree diff (D-132); internal/core untouched vs origin/main
(three-dot); task check still wires dogfood-examples/docs-gates/
dogfood-wiring-test; the README-format-vs-dogfood inventory (S01) is
re-invoked and named-PASS verified; the provider fence and D-002
sanitization stay green. Every check is mutation-tested in place
(deleted C-series dirs, flipped decisions, HEAD/branch/empty base-ref
substitutions, unauthorized schema edits in a scratch sandbox) so the
gate whose job is catching vacuous gates is not itself one.

Marks backlog REF-EX CLOSED (P5-EX EX-S06/EX-S07, exit-gated by
EX-S10) and updates the stale Phase-5 roadmap row.
…le classes: block (F2)

check_formats grabbed the entire classes: block and grepped it for
*.ext tokens, including comment lines. infra-vars' real config.yaml
carries a KNOWN LIMITATION comment reading "...matches only *.tfvars
and *.tf..." directly under its match: line, so removing the real
.tf class-match entry left "tf" still detectable via that comment's
own prose — the mutation control that was supposed to catch this only
ever ran against a synthetic, comment-free fixture, so it never
exercised the confound it existed to catch (independent review F2).

Anchors extraction on the `match: { paths: [...] }` line shape itself
(comment lines never start with "match:", so they are excluded by
construction, not by a separate strip pass), and adds a second
mutation control that mutates the REAL infra-vars config.yaml in
place (comment prose intact) alongside the existing synthetic one.

Also (F5, non-blocking): check_c_series now requires each C1-C7
expect.yaml to be non-empty (`find -size +0c`), matching what the
gate's own report already claimed it checked.
…xtraction (F6)

check_formats' F2 fix anchored extraction on the match:/paths: line
shape but still printed the WHOLE matched line before token-grepping,
so a "*.tf"-shaped substring trailing the SAME line (e.g. an inline
`# legacy note: ... *.tf` comment) still leaked through — this
codebase's own comment style already puts trailing `#` comments on
match: lines (examples/packs/topic-registry/.assent/config.yaml:12),
so it is not a contrived shape. Narrows extraction to the bracketed
`[...]` path-list itself (match(s, /\[[^]]*\]/)) so no same-line
trailing content can ever fall inside the extracted substring,
structurally.

Adds a third mutation control (same-line trailing comment on a
scratch copy of the REAL infra-vars config.yaml) alongside the
existing synthetic and separate-line-comment controls. That control's
own first draft had a companion bug worth naming: its sanity checks
used a plain `*.tf` substring grep, which false-matches the "tf"
prefix of "*.tfvars" — fixed to compare exact extracted tokens
instead. Updates the header comment to describe what is actually
covered now (same-line and separate-line, not just separate-line).

Also (F3, non-blocking, carried): backlog.md's P5-EX/REF-EX rows now
say the exit gate is manual-invocation-only, not wired into `task
check` or CI, so a future reader does not assume automated coverage
that doesn't exist.
@konih
konih merged commit 93edfcc into main Aug 16, 2026
5 checks passed
@konih
konih deleted the lane/ex-s10 branch August 16, 2026 13:36
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