refactor(tests): one invariant namespace — every catalog entry resolves, the canary mapping is guarded, and journey families are runnable (#2337) - #2740
Merged
Conversation
…es, the canary mapping is guarded, and journey families are runnable (#2337) The journey validator resolved `invariants:` ids from the catalog's one markdown table (the 12-row "Recommended starting subset"), so 11 of the 71 defined invariants were citable and citing P-02 — a real §7 entry, J10's own permission promise — failed as "coverage theatre". One stdlib parser (tests/unit/_invariant_catalog.py) now resolves every `**X-NN** … *(Tier` definition; a table is never a definition. Catalog E-06 (the unimplemented #129 orphan check) shared its id with the registry's E-06 ("no overdue next_run_at", #1472). The #129 entry is re-homed to E-09 — AC4 relaxed for this one id by operator ruling — so the id means the same thing in the catalog and in canary/invariants/e06_no_overdue_next_run.py. A Canary mapping table (module → registry id → catalog id) documents live vs journey-only, and tests/unit/test_2337_invariant_namespace.py asserts INVARIANTS == every module's INVARIANT_ID == the table, every catalog id resolves, and no row's two ids differ. Exact per-family pins; `Signal:` mandatory on new families with a shrink-only allowlist for the 60 legacy entries without the line; synthetic-markdown self-tests prove a bold mention, a dagger row and a table row are not definitions. Mutation-verified: deleting a cited entry, unregistering E-03, drifting a mapping row and adding a Signal-less entry each turn exactly the intended tests red. New families scoped to runnable predicates: SK- (skills), RD- (repo-bound deployment), PLG- (plugins, file/HTTP), IA- (one-hop permission edge, fan-out batch bound, dead callee fails fast). Inter-agent recursion depth has no product guard to predicate on and is recorded in Gaps. L-03's documented cascade list is re-synced to snapshot.ORPHAN_SCAN_TABLES. J01/J06/J07/J08/J09/J10 records gain ids; JOURNEYS.md regenerated; the two docs that stated the collision as current (requirements/infrastructure.md, a canary_alerts.py comment) updated. CSO diff report: clean in scope; one out-of-scope finding routed privately (ent#614). Fixes #2337 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
test_2338_journey_catalog.pyresolved journeyinvariants:ids from the catalog's one markdown table, so 11 of 71 defined invariants were citable; citingP-02(a real §7 entry — J10's own permission promise) failed as "coverage theatre". One stdlib parser (tests/unit/_invariant_catalog.py) now resolves every**X-NN** … *(Tierdefinition through the same code path for both validators; a summary table is never a definition.E-06collision removed, not documented again. CatalogE-06(the unimplemented Active watchdog: remediate stuck executions detected by monitoring #129 orphan check) shared its id with registryE-06("no overduenext_run_at", bug: enabled schedule shows "Next: 1d ago" — stale next_run_at, cron fires silently skipped with no execution record #1472). The Active watchdog: remediate stuck executions detected by monitoring #129 entry is re-homed toE-09— AC4 relaxed for this one id by operator ruling (recorded on the issue). Zero references break: catalogE-06was uncitable before this change.tests/unit/test_2337_invariant_namespace.pyassertsINVARIANTS== every module'sINVARIANT_ID== the table, every catalog id resolves, and no row's two ids differ; exact per-family pins;Signal:mandatory on new families with a frozen, shrink-only allowlist for the 60 legacy entries lacking the line (registered as debt); synthetic-markdown self-tests in both directions.SK-skills (SQL),RD-repo-bound deployment (SQL),PLG-plugins (file/HTTP, journey-only),IA-inter-agent (one-hop permission edge, fan-out batch boundMAX_TASKS, dead callee fails fast — measured 0.16 s live). Recursion depth has no product guard to predicate on → Gaps to fill next. J01/J06/J07/J08/J09/J10 records gain ids;JOURNEYS.mdregenerated.Changes
docs/testing/orchestration-invariant-catalog.md— E-06→E-09 + shipped E-06 entry; §16–§19; Canary mapping; L-03 list re-synced tosnapshot.ORPHAN_SCAN_TABLES(six tables were missing); Gaps; status linetests/unit/_invariant_catalog.py(new),tests/unit/test_2337_invariant_namespace.py(new, 16 tests),tests/unit/test_2338_journey_catalog.py(resolver via the parser; list-shape check)tests/journeys/catalog.yaml,docs/testing/JOURNEYS.md(regenerated),tests/registry.json(additive)docs/memory/requirements/infrastructure.md,src/backend/services/canary_alerts.py(comment only) — the two places that stated the collision as currentdocs/memory/learnings.md(+1 entry),docs/security-reports/cso-diff-2026-09-12-2337-journey-invariants.{json,md}Test Plan
cd tests && ../.venv/bin/python -m pytest unit/test_2337_invariant_namespace.py unit/test_2338_journey_catalog.py unit/test_1880_canary_alert_parity.py -q→ 83 passed; randomized run green; 381 passed across the seven neighbouring tests that read the touched files; 15,338 tests collectcmp-verified): delete citedSK-02→ pin + J07 unresolved; dropE-03fromINVARIANTS→ three-way equality (andtest_1880) red; drift a mapping row toSCH-03→ drift test red; addSK-04withoutSignal:→ pin + no-Signal redPOST /api/canary/run-cycleenumerates exactly the 16 ids the mapping table lists (422 names them for anything else)/review: 0 critical, 3 informational applied ·/cso --diff: clean in scope; one out-of-scope VERIFIED finding routed privately as abilityai/trinity-enterprise#614Deviations from the ACs, on record
E-06→E-09) by operator ruling; the alternative was documenting the collision a fifth time.Fixes #2337
🤖 Generated with Claude Code