Skip to content

feat(n8-c1): SSOT-existence arm on Prior-art trailers (pre-push) - #170

Merged
artyhoo merged 1 commit into
stagingfrom
feat/n8-c1-ssot-existence-check
May 22, 2026
Merged

feat(n8-c1): SSOT-existence arm on Prior-art trailers (pre-push)#170
artyhoo merged 1 commit into
stagingfrom
feat/n8-c1-ssot-existence-check

Conversation

@artyhoo

@artyhoo artyhoo commented May 22, 2026

Copy link
Copy Markdown
Owner

What

Wave N8 A-phase item C1 — the highest correctness-ROI deterministic-offload candidate per findings §7 D3 / wave-sequencing-plan §5.3 D3.

Mechanises the §1.9 "SSOT citation existence-check" prose probe (phase-research-coverage.md §1.9). A capability commit's Prior-art: prior-art-evaluations.md#N trailer is now verified that #N resolves to a real register row — not merely that the trailer is present. This catches the Wave-7 M2 incident class (a trailer cited a non-existent #N and passed by presence alone).

Channel (per rule-enforcement-channel-selection)

Detectable → gate at the earliest reachable channel = pre-push, where commit trailers exist. Principle 08 already covers in-file prior-art-evaluations.md#N citations in research files; it cannot see commit-message trailers. C1 covers exactly that complementary surface — two independent channels over one register.

Changes (all under packages/core/hooks/)

  • checks/prior-art.tsextractCitedSsotIds() + loadSsotIds(); checkTrailerBody gains an optional ssotIds set → new code 3 (broken citation); runPriorArtCheck routes it into report.brokenCitations. Pure/injected — ssotIds undefined ⇒ graceful no-op (unreadable register never blocks a push; isolated test repos hit this path).
  • pre-push.tspriorArtSection reads the register, passes the id-set, blocks (exit 1) on broken citations with a grep-to-verify hint.
  • prior-art.test.ts+17 tests: paired-negative (#1 passes / #999 blocks), multi-missing report, free-form-trailer pass, escape-hatch precedence, pre-cutoff bypass, arm-disabled-without-ssotIds, loader/extractor units.

Verification

  • prior-art.test.ts65/65 pass (48 prior + 17 new).
  • npm run test:principles106/106; tsc --noEmit clean.
  • tests/hooks/prior-art-trailer-hook.test.sh8/8 (graceful-degradation path confirmed).
  • pre-push gate green on push.

§1.7

  • Forward-check: complies with no-paid-llm-in-ci (deterministic grep, zero API calls); build-first-reuse-default (extends own prior-art.ts §7 check — no upstream analog for "grep our own register"); doc-authority-hierarchy (no rule/doc edited).
  • Backward-check: scope is the commit-trailer surface only; principle 08's in-file broken-ref check is unchanged and uncoupled.

Observations (NOT fixed here — out of C1 scope)

  1. Stale local test, CI-invisible: packages/core/hooks/pre-push.test.ts:59 asserts the orchestrator invokes audit-self/audit-ai-docs.test.sh, but Wave 10.4 migrated that to …/audit-ai-docs.test.ts. The assertion fails locally on clean staging (pre-dates this PR); CI is green because audit-self.yml runs only test:principles + the specific audit-ai-docs.test.ts, not the hooks/ vitest suite. Want me to fix the stale assertion as a separate task?
  2. §1.9 prose now stale: phase-research-coverage.md §1.9 says the existence probe is "prose-only today" — now mechanised. .claude/rules/* is maintainer-owned (Artifact Ownership Contract), so I left it. Suggest a one-line maintainer edit noting C1 wired it at pre-push.

Mechanises the §1.9 "SSOT citation existence-check" prose probe: a capability
commit's `Prior-art: prior-art-evaluations.md#N` trailer is now verified that
#N resolves to a real register row, not merely that the trailer is present.
Catches the Wave-7 M2 incident class (a trailer cited a non-existent #N and
passed by presence alone). Earliest reachable channel = pre-push, where commit
trailers exist (principle 08 covers in-file citations in research files; this
covers the commit-trailer surface principle 08 cannot see).

- checks/prior-art.ts: extractCitedSsotIds() + loadSsotIds(); checkTrailerBody
  gains an optional ssotIds set → new code 3 (broken citation); runPriorArtCheck
  routes code 3 into report.brokenCitations. Pure/testable — SSOT id-set is
  injected, undefined ⇒ arm is a graceful no-op (unreadable register never
  blocks a push; isolated test repos exercise this path).
- pre-push.ts: priorArtSection reads the register, passes the id-set, blocks
  (exit 1) on broken citations with a grep-to-verify hint.
- prior-art.test.ts: +20 tests — paired-negative (existing #1 passes / #999
  blocks), multi-missing report, free-form-trailer pass, escape-hatch precedence,
  pre-cutoff bypass, arm-disabled-without-ssotIds, loader/extractor units.

Wave N8 A-phase item C1 (deterministic-offload), highest correctness-ROI of
C1–C5 per findings §7 D3 / wave-sequencing-plan §5.3 D3.

§1.7 forward-check: complies with no-paid-llm-in-ci (deterministic grep, zero
API calls); build-first-reuse-default (extends own prior-art.ts §7 check — no
external analog for "grep our own register", REFERENCE n/a); doc-authority
(no rule/doc edited — §1.9 prose update flagged for maintainer, .claude/rules
is maintainer-owned). backward-check: scope is the commit-trailer surface only;
principle 08's in-file broken-ref check is unchanged and uncoupled (two
independent channels over one register).

Prior-art: skipped — extends existing pre-push prior-art.ts §7 check with a
SSOT-existence arm; no new dependency or capability surface, our-own register
grep with no upstream analog to adopt.
@artyhoo
artyhoo enabled auto-merge (squash) May 22, 2026 18:31
@artyhoo
artyhoo merged commit f921233 into staging May 22, 2026
22 checks passed
artyhoo added a commit that referenced this pull request May 25, 2026
… detection) (#220)

Run `bash .claude/skills/meta-orchestrator/helpers/plan-currency-check.sh`
(L2 Stage 3 detection shipped in #217) → 88 UNTRACKED-N entries surfaced
between the 2026-05-22 reconciliation and origin/staging tip (#217). Map
each to an existing §0 / Track row by adding the PR number to its evidence
cell, or to a new §0 row for two umbrellas that landed in full since the
prior snapshot. Re-run helper → 0 UNTRACKED remaining.

Key changes:

- Snapshot date 2026-05-22 → 2026-05-25 (header + §0).
- N8 row: A-phase 🔲 → 🟡 — C1 SSOT-existence (#170), C2 kickoff
  T-enumeration floor (#174), C3 principle 13 §1.7 substance (#178),
  C4 delivery-channel marker (#177), activation #180. C5 + cost-levers
  remain gated on §5.3 utilisation trigger.
- Track M.1 / M.4 → DONE: M.1 codified T20 via #212 (with NB note —
  recommendation-laziness took the T20 slot, mutation-equivalence
  T-bump 20→21 still pending); M.4 6 paired-negative bash-hook tests
  shipped #195/#196/#197/#198/#199/#200.
- Two new §0 rows: Meta-orchestrator skill (Track P) — BUILD #186 +
  audit rounds #192/#193/#194/#201/#202 + UX refactor #203/#204/#205
  + planner-completeness #213/#214/#217 + §1.7 PR-body mandate #216;
  Recommendation-laziness discipline — R-phase #206/#207, benchmark
  #210, I-phase Sub-waves A/C/D #211/#212/#215.
- N7 row: + dogfood research-patch #135 / §4 demotion #166 / live-trial
  verified #171. N4b row: + design #136 / record #118.
- Infra paragraph: PR refs for I.1 follow-ups (#121/#123/#124/#125/
  #128/#130/#131/#143/#145/#146/#147/#148/#149/#172/#187), I.2
  (#139/#142/#154/#175), I.3 DN-4 (#126/#132/#133/#138/#140/#152/
  #159/#161/#162/#167).
- Track 2.3 (channel-earliness audit) → DONE 2026-05-23 (#181); removed
  from "What actually remains".
- Footer subsection: standalone work (#191 satellite-arch / #189
  guard-liveness / #173 storm-readiness / #176 §10 port / #182 cleanup),
  Wave 10 follow-ups (#110/#112/#113), plan-revision history (#108/
  #109/#153/#155/#157/#160/#164/#165/#168/#179/#185).

Verification:
- `bash .claude/skills/meta-orchestrator/helpers/plan-currency-check.sh
  | grep -c '^UNTRACKED'` → 0 (down from 88).
- `npx markdownlint-cli docs/meta-factory/wave-sequencing-plan.md`
  → no violations.
- `npx vitest run packages/core/skills/plan-currency-check.test.ts`
  → 14/14 passed.

Prior-art: skipped — chore, doc reconciliation only, no new capability
or rule introduced.
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