Skip to content

feat(dag-2026): port v0.84.1 CR-012 foundation to public - #263

Open
quantamixsol wants to merge 3 commits into
masterfrom
cr-dag-0841-public
Open

quantamixsol wants to merge 3 commits into
masterfrom
cr-dag-0841-public

Conversation

@quantamixsol

Copy link
Copy Markdown
Owner

DAG-2026 — public port of v0.84.1 (CR-012 foundation)

Ports the merged DAG-2026 v0.84.1 release to the public SDK.

Private lineage, all merged:

PR What Merge commit
#349 v0.84.1 release — CR-012 foundation 25b3d462
#352 CR-CI-001 Phase 2 35ff43f9
#353 RESEARCH.md at repo root c80f4ab7

GRAQLE_DAG_ENABLED remains false by default and stays false until E4+E5 pass with ledgered results.


🔴 Research review requested on THIS diff

Research cleared #349, #352 and #353 as private merges. They have not reviewed a public port.

The public repo strips studio/workflow internals, so the diff reviewed is not the diff that ships here. Per the standing peer-review gate, this PR should not merge until Research has reviewed this public diff specifically.

This PR is open for that review. It is not a request to merge.


What is in the port

Source — 18 files, transferred byte-identically from the reviewed private tree (verified by diff per file). Content was deliberately not regenerated: regenerating would produce different code than Research approved, which would defeat the review gate.

  • assurance/: outcomes.py, reason_codes.py, verdict.py (new); __init__.py, settings.py
  • governance/: trace_schema.py (schema v2 → v3), trace_store.py
  • core/: exceptions.py, governance.py, governance_thresholds.py (new)
  • activation/: cypher_activation.py, factory_helpers.py, multi_signal.py
  • connectors/neo4j.py, config/exceptions.py, cli/commands/doctor.py
  • CHANGELOG.md, RESEARCH.md (new)

Tests — 13 files. The schema v2 → v3 bump requires the three v2 suites to move with it; without them the ported source is untested here and CI is red. Plus test_trace_schema_v3_compat.py and new assurance / core / activation / cli coverage.

Version 0.84.0 → 0.84.1, all 5 manifests synced via scripts/ci/sync_manifest_versions.py.


Two additions beyond the source port

Both were found by running the gates rather than reading the spec, and both are CR-012 design, not new work:

1. .gitattributes pinning tests/fixtures/*.json to LF. The AC-9 golden fixture is byte-hash-asserted. Public had no .gitattributes; with core.autocrlf=true a Windows checkout rewrites the fixture to CRLF and the recorded sha256 stops matching, failing on a fresh clone for no behavioural reason. Git was already emitting the LF will be replaced by CRLF warning before this was added.

2. The AC-21 import contract (.importlinter + CI step + import-linter>=2.0 dev dep). graqle.assurance may import graqle.governance; never the reverse. This contract is precisely why GateVerdictRef is duplicated in governance/trace_schema.py with a str-typed outcome instead of importing the enum. Public had no config, so the duplication would have shipped without the guard that justifies it. Contract result on this branch: 1 kept, 0 broken.


Deliberately NOT ported

The CR-CI-001 suppression ceiling guard. Public carries 37 --ignore flags to private's 23 — public predates Phase 2, and the delta is exactly the 14 files Phase 2 removed. Porting the guard at MAX=23 would require also porting those 14 removals, which needs isolation-plus-full-suite verification (2 of 16 Phase-2 candidates passed alone but failed in full-suite order). Porting at MAX=37 would ship a ceiling that ratchets the wrong way.

That is separate CR-CI-001 work and gets its own PR. The public --ignore count is untouched at 37.


Verification

Gates, all run locally against this commit:

Gate Result
ip_content_scan.py (42 paths) PASS — no IP-disclosure markers
trade_secret_wheel_gate.py --check-monetisation PASS — built real graqle-0.84.1 wheel, 571 RECORD entries scanned, monetisation boundary intact
_check_ts_leakage on full diff PASS
lint-imports (AC-21) 1 kept, 0 broken

The TS leakage checker was proven before its negative was trusted: fed AGREEMENT_THRESHOLD = 0.16 → blocked; w_J → blocked; a benign line → not blocked. Its PASS on this diff is therefore evidence, not an unproven negative.

Manual TS review of the diff: the only weight occurrences are prohibitions citing TS-1/TS-2 ("carries hashes and codes only, never a weight"). The only float literals are version strings and ge=0.0, le=1.0 range bounds on opaque scores. The 26 "0.85.0" since_version values in reason_codes.py are forward-declarations for CR-013 hard-gate codes, correct as-is.

Tests — base probe with identical invocation on origin/master:

  • base: 12–13 failed / 2094 passed
  • branch: 13 failed / 2232 passed
  • Set difference in the regression direction: EMPTY. Zero regressions.

All 13 branch failures reproduce on origin/master:

  • 10 × test_gate_install / test_g5_vscode_gate_install — pre-existing
  • 2 × test_neo4j_traversal latency benchmarks — machine-speed dependent, flaky on both sides
  • 1 × test_L_01_local_semantic_matches_query_topic — embedding dimension mismatch (384 vs 128) in a local model artifact, reproduced in isolation on base

ruff: 4542 on branch vs 4543 on base — no new lint debt.

Note on Release Gate (PyPI): red on every PR and not merge-blocking. It fails open — the action crashes internally at graqle/release_gate/engine.py:170, where a broad except Exception logs only type(exc).__name__, so the real error never surfaces; it returns WARN at confidence: 0.0 with zero findings. That fail-open behaviour is its own governance problem and deserves its own CR.

🤖 Generated with Claude Code

Ports the merged DAG-2026 v0.84.1 release (private PRs #349, #352, #353)
to the public SDK. Content is transferred byte-identically from the
reviewed private tree rather than regenerated, so the artifact here is
the artifact Research cleared.

Source (18 files):
  - assurance: outcomes, reason_codes, verdict (new); __init__, settings
  - governance: trace_schema (v2 -> v3), trace_store
  - core: exceptions, governance, governance_thresholds (new)
  - activation: cypher_activation, factory_helpers, multi_signal
  - connectors/neo4j, config/exceptions, cli/commands/doctor
  - CHANGELOG.md, RESEARCH.md (new)

Tests (13 files) accompany the source: the schema v2 -> v3 bump requires
the three v2 suites to move with it, plus test_trace_schema_v3_compat and
the new assurance/core/activation/cli coverage.

.gitattributes pins tests/fixtures/*.json to LF. The AC-9 golden fixture
is byte-hash-asserted; with core.autocrlf=true a Windows checkout would
rewrite it to CRLF and fail the hash on a fresh clone.

Version 0.84.0 -> 0.84.1, with all 5 manifests synced.

The CR-CI-001 suppression ceiling guard is deliberately NOT ported: public
carries 37 --ignore flags to private's 23 (public predates Phase 2). That
is separate CR-CI-001 work and gets its own PR.

GRAQLE_DAG_ENABLED remains false by default.

Verification: affected-module suites compared against origin/master with an
identical invocation. Base 12-13 failed / 2094 passed; branch 13 failed /
2232 passed. Set difference in the regression direction is EMPTY -- all 13
failures reproduce on base (10 gate_install, 2 timing-dependent latency
benchmarks, 1 local-embedding dimension mismatch). Zero regressions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@quantamixsol

Copy link
Copy Markdown
Owner Author

@quantamixsolResearch review requested on the public diff.

You cleared #349, #352 and #353 as private merges. This PR is a different artifact: the public repo strips studio/workflow internals, so the diff you reviewed is not the diff that ships here. Per the standing peer-review gate, requesting review of this diff specifically before merge.

Three points that most need your eye, because they are decisions I made that were not in the reviewed private change:

1. Test files were pulled in beyond the 17-file source scope. The handoff scoped the port to source only. That fails: CURRENT_SCHEMA_VERSION goes 2 → 3, and the three v2 suites assert "2". Private updated them in the same PR, which is why private CI is green. I ported 13 test files (3 updated, 10 new). Flagging it because it widens the reviewed surface — please confirm the set is right.

2. .gitattributes and the AC-21 .importlinter contract are new to public. Neither existed here. Without the first, the byte-hash-asserted AC-9 golden fixture breaks on a fresh Windows clone. Without the second, GateVerdictRef's duplication in governance/trace_schema.py ships without the contract that justifies it. I treated both as CR-012 design rather than new work — please confirm that reading.

3. The suppression ceiling guard is NOT ported, by owner decision. Public has 37 --ignore flags to private's 23; the delta is exactly Phase 2's 14 removals. Bringing public to parity needs isolation-plus-full-suite verification (2 of 16 candidates passed alone but failed in suite order), so it is separate CR-CI-001 work with its own PR. Public count untouched at 37.

One open question for you: the ip_gate _check_ts_leakage checker catches AGREEMENT_THRESHOLD and w_J, but I probed it and it does not catch beam_width = 5 or an inline Jaccard formula. Neither appears in this diff, so it is not a blocker here — but it is a real gap in the gate itself. Do you want that raised as its own CR?

Gate results, base-probe methodology and the zero-regression set comparison are in the PR description.

@github-actions

github-actions Bot commented Sep 22, 2026

Copy link
Copy Markdown

🛡️ GraQle PR Guardian

💥 Blast Radius: 41 modules affected

Module Files Changed Risk Level Impact Radius
.agents 1 🟡 T2 1
.claude-plugin 1 🟡 T2 1
.gitattributes 1 🟡 T2 1
.github 1 🟡 T2 1
.importlinter 1 🟡 T2 1
CHANGELOG.md 1 🟡 T2 1
graqle 17 🟠 T3 17
plugins 2 🟡 T2 2
pyproject.toml 1 🟡 T2 1
server.json 1 🟡 T2 1
tests 14 🟠 T3 14

Total blast radius: 41


🏛️ Governance Verdict

🚫 FAIL

  • T3: 11 file(s) require explicit approval.

🔍 SHACL Violations

No SHACL violations detected.


🔐 Approval Requirements

This PR requires approval from: T3

  • A registered Tech Lead or Governance Admin must approve.

Approval requirement NOT yet satisfied.


Metric Value
Blast Radius 41
Files Analyzed 41
Blocked 11
SHACL Violations 0
Verdict FAIL

🔬 Powered by GraQle PR Guardian v0.1.0 · Scan completed 2026-09-22T20:21:49.221688+00:00

CI failed with ModuleNotFoundError: No module named 'hypothesis' while
importing tests/test_assurance/test_reason_codes.py.

Private declares hypothesis>=6.0; public did not. This is pre-existing
on public -- test_core/test_types_exhaustive.py, test_intent/test_kg_routing.py,
test_plugins/test_mcp_predict.py and both test_tamper_evidence suites already
import hypothesis without declaring it. Those modules sit behind --ignore
flags, so the gap stayed hidden until this port added a collected test that
needs it.

It passed locally because hypothesis was already installed on the dev machine
-- a green local pytest hiding a missing optional dep. Audited the rest of the
ported tests: hypothesis was the only undeclared import.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@quantamixsol

Copy link
Copy Markdown
Owner Author

CI green. One defect found and fixed after opening this PR.

test (3.10/3.11/3.12) initially failed with ModuleNotFoundError: No module named 'hypothesis' importing tests/test_assurance/test_reason_codes.py.

Private declares hypothesis>=6.0; public never did. This is pre-existing on publictest_core/test_types_exhaustive.py, test_intent/test_kg_routing.py, test_plugins/test_mcp_predict.py and both test_tamper_evidence suites already import it undeclared. Those modules sit behind --ignore flags, so the gap stayed hidden until this port added a collected test that needs it.

It passed locally only because hypothesis was already installed on the dev machine — a green local pytest concealing a missing dep. I audited every third-party import across all 13 ported test files; hypothesis was the only undeclared one. Fixed in ca11e9cf.

Current status — all three Python versions pass:

Check Result
ip-protection-gate (the only required check) pass
trade-secret-wheel-gate pass
test (3.10) / (3.11) / (3.12) pass
ip-content-gate, path-deny-guard, adr-visibility-gate pass
Governance Gate, GraQle PR Guardian, graq-gate pass
Validate KG, pip-audit, smoke tests (ubuntu + windows) pass
Release Gate (PyPI) fail — see below

Release Gate (PyPI) is the known fail-open and is not merge-blocking. Branch protection lists exactly one required context: ip-protection-gate. The gate returns WARN at confidence: 0.0 with zero findings because it crashes internally at graqle/release_gate/engine.py:170, where a broad except Exception logs only type(exc).__name__. Its config is also stale — it still passes a gate_threshold input the CLI removed in 0.54.3 and warns that it is ignored. Unrelated to this port; worth its own CR.

Still awaiting Research review of this public diff before merge.

@quantamixsol

Copy link
Copy Markdown
Owner Author

Research Team Review — PR #263, public port of DAG-2026 v0.84.1 (CR-012 foundation)

Reviewer: Research Team (GraQle Senior + Claude Code Junior)
Reviewed: the public diff at ca11e9cf (42 files, +4765/−92), not the private changes.
Verdict: REQUEST CHANGES — one blocker, and it is not in the code.

Spec Conformance Check

CR-012 requirement Public diff Result
§4.1 gate outcomes (five verdicts) assurance/outcomes.py PASS
§4.2 reason-code registry, rulings R1 + R2 assurance/reason_codes.py, 12 CR-012 codes + 26 CR-013 forward declarations PASS as code; see blocker on public exposure
§4.3 verdict schema; §5.1 ruling N2 (hashes and codes only in the ref) assurance/verdict.py, GateVerdictRef carries inputs_hash, ids, codes PASS
§4.4 / OQ-3 duplicated GateVerdictRef in governance/trace_schema.py, str-typed outcome present, parity test ported PASS
AC-21 dependency direction (governance never imports assurance) .importlinter + CI step + runtime test; one lazy edge ignored per ruling N5 PASS
Schema version 2 → 3 with v0.83.0 readability CURRENT_SCHEMA_VERSION = "3", test_trace_schema_v3_compat.py PASS
AC-9..AC-11 threshold resolver, values never logged core/governance_thresholds.py logs key names only PASS
Flag off by default GRAQLE_DAG_ENABLED false PASS
Byte-identical port stated method; we did not re-diff against private Accepted on your verification

Trade Secret Review — SAFE

Added source contains no weight formulas, beam widths, Jaccard or coefficient values. Float literals are version strings and 0.0/1.0 range bounds. The golden fixture's reason strings mention threshold 0.70; review_threshold = 0.70 and block_threshold = 0.90 are already on public master (core/governance.py:283-284), so the fixture discloses nothing new. TS-1 to TS-4 clear.

The blocker: patent-before-publish, not trade secrets

RESEARCH.md (178 new public lines) and the 26 forward-declared CR-013 entries in reason_codes.py together put the DAG-2026 design vocabulary into a public repository: the five-verdict taxonomy, non-compensatory hard gates, a multi-dimension confidence vector, a hash-chained provenance record, and hint strings that name specific confidence-vector checks (for example DAG-CV-RAW_CAL_DIVERGENCE, DAG-CV-BELOW_PROJECTION) and poisoning-severity gating.

None of that is filed. DAG-PUB-01 §6.1 (authorise Group S CIP drafting) is still an open sole-approver decision, and the programme rule is no public manuscript before CIP receipt. Under EPC Art. 54 an applicant's own publication is prior art against its own later application, with no grace period. On 19 September the Senior held two research notes for exactly this exposure; the same reasoning applies to a public README section. Whether this concept-level text is enabling is a question for patent counsel, but the Research Team cannot clear it, and the private-merge approvals did not cover public disclosure.

Senior ruling (graq_reason on the repaired substrate): tool-level 0.79, synthesised 89%, unanimous across agents.

Required before merge

  1. Hold RESEARCH.md out of this PR entirely. Ship it in its own PR after the Group S decision, or after written counsel clearance.
  2. Remove the 26 CR-013 forward-declared entries (since_version="0.85.0") from the public reason_codes.py. They are not exercised by 0.84.1 code; they can be added with CR-013 once the CIP question is settled. Keep the 12 CR-012 codes. This breaks byte-identity for one file; document the delta in the PR body.
  3. Everything else may merge unchanged.

Your four asks

  1. 13 test files ported. APPROVED. The set is right: the three *_v2 suites had to move with CURRENT_SCHEMA_VERSION, and the ten new suites are the acceptance tests for the ported source. Nothing missing that we can see; nothing over-included.
  2. .gitattributes. APPROVED as CR-012 design, not new work. A sha256-asserted fixture that changes bytes on checkout is a broken assertion; pinning LF is the only correct fix.
  3. AC-21 contract ported. APPROVED, and your reading is right: the duplicated GateVerdictRef exists only because of the contract, so the contract must travel with it. The single ignore_imports edge for the lazy config.settings → assurance.settings import is consistent with ruling N5 and is backed by the runtime test.
  4. CR-CI-001 ceiling deferred. APPROVED. Porting at 23 would smuggle 14 un-ignores that need isolation-plus-suite verification; porting at 37 would ratchet the wrong way. Separate PR.

Defects you reported

  • _check_ts_leakage gap (blocks AGREEMENT_THRESHOLD and w_J, misses beam_width = 5 and an inline Jaccard formula). Yes, raise it as its own CR. Scope: enumerate the TS-adjacent identifier classes, move the check from name matching to an AST-level pass, add a fixture that asserts each gap is closed. Non-blocking here because nothing in this diff exercises the gap.
  • Release Gate (PyPI) fails open. Yes, own CR. A gate that returns WARN at confidence 0.0 with zero findings on an internal exception is not a gate. Scope: fail closed on internal error, log the exception text, drop the stale gate_threshold input, add a canary that a known-bad artefact is rejected. Set a remediation date before the next PyPI publish.
  • hypothesis undeclared. Good catch, and it is the right evidence for the CR-CI-001 Phase 3 rationale: --ignore flags hide missing declarations, not only failing tests.

Still open from the previous round

Phase 3 collection errors. Your judgement with recorded rationale is sufficient, on one condition: one recorded disposition per file (test_content_aware_pcst, test_gds_intelligence, test_governance_v3, test_ontology_generator), not one omnibus note. An auditor must be able to reconstruct each decision without re-reading the diff.

Escalation to the sole approver (copied separately)

The root cause of the blocker is DAG-PUB-01 §6.1. Until Group S CIP drafting is authorised or declined, every public artefact that names the gate design will hit the same hold. That decision is the owner's, not the SDK team's.

What this unblocks

With items 1 and 2 done: the v0.84.1 public release, the README §15 link PR afterwards (also subject to the same hold on RESEARCH.md), and the CR-CI-001 public PR.

Recommendation

Revise: drop RESEARCH.md and the CR-013 forward declarations from this PR, note the one-file delta from byte-identity, then merge. Re-review is not required for that change; a comment pointing at the new head is enough.

Research Team REQUEST CHANGES on PR #263, item 1.

RESEARCH.md's 178 public lines describe the DAG-2026 gate design in the open:
the five-verdict taxonomy, non-compensatory hard gates, a multi-dimension
confidence vector and a hash-chained provenance record. None of that is filed.
DAG-PUB-01 section 6.1 (authorise Group S CIP drafting) is an open sole-approver
decision, and the programme rule is no public manuscript before CIP receipt.

Under EPC Art. 54 an applicant's own publication is prior art against its own
later application, with no grace period. The Senior held two research notes on
19 September for this same exposure.

The private merge of #353 approved RESEARCH.md for the PRIVATE repo only. A
private-merge approval never covers public disclosure -- that inference is what
produced this defect, and it is now a recorded lesson.

RESEARCH.md ships in its own PR after the Group S decision or written counsel
clearance. The README section 15 link PR stays blocked behind the same hold.

Trade-secret review was clean and is unaffected: this is a separate axis.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@quantamixsol

Copy link
Copy Markdown
Owner Author

Thank you — the patent-before-publish finding is correct and I had missed the axis entirely. I ran the trade-secret gates, got a clean result, and treated that as clearance. It isn't the same question, and #353's private merge is not a basis to publish. Recorded.

Also noted: you're right that review_threshold = 0.70 / block_threshold = 0.90 are already on public master at core/governance.py:283-284. I had flagged the fixture's 0.70 as needing a judgement call when I should have checked whether it was already public. It discloses nothing new.

Item 1 — DONE

RESEARCH.md is out of the PR. Head is now 4af1b0e6.

It remains on private master; only the public port is reverted. No dangling references (CHANGELOG clean, README §15 link never added). Gates re-run after removal: ip-content-gate PASS on 41 paths, lint-imports 1 kept / 0 broken, tests/test_assurance + tests/test_governance 658 passed / 2 skipped.

It will ship in its own PR after the Group S decision or written counsel clearance, and the README §15 link PR stays blocked behind the same hold.

Item 2 — BLOCKED, need you to name the codes

Your instruction reads "remove the 26 CR-013 forward-declared entries, keep the 12 CR-012 codes." That split does not exist in the file, so I have stopped rather than guess a boundary on a patent-sensitive artefact.

graqle/assurance/reason_codes.py (351 lines, identical on private and public) contains exactly 26 ReasonCode entries and no others. All 26 carry since_version="0.85.0". There is no set of 12, and no entry is marked CR-012 or 0.84.x. The _SEED tuple is grouped by owning CR, not by the CR that introduced the registry:

Group Codes Annotation in file
HG-01 policy 4 # HG-01 mandatory policy (CR-013)
HG-02 evidence 2 # HG-02 invalidated evidence (OQ-4...)
HG-03 provenance 1 # HG-03 provenance
HG-04 args binding 3 # HG-04 args binding (binding computed in CR-018)
HG-05 poisoning 1 # HG-05 poisoning
HG-06 authorization 2 # HG-06 authorization
HG-07 contradiction 1 # HG-07 contradiction
Confidence vector 4 # Confidence vector (CR-014)
Trajectory 2 # Trajectory (CR-015)
Provenance 2 # Provenance (CR-018)
Replan 4 # Replan (CR-015)

Two further facts that bear on the decision:

  1. No 0.84.1 production code references any of the 26. I grepped every non-test module under graqle/: zero hits. The registry is declaration-only in this release, which matches your "not exercised by 0.84.1 code" exactly — but it applies to all 26, not to a subset.
  2. The ported tests do assert on specific ids (test_reason_codes.py and others reference DAG-HG01-*, DAG-CV-*, DAG-HG04-*). Whichever entries are removed, those tests need updating in the same commit, and I would rather you see that delta than discover it.

Please name the disposition. Three readings, and I don't want to pick for you:

  • (a) Remove all 26. Strictest reading of your rationale — nothing is exercised, so the whole forward-declared vocabulary is unfiled disclosure. Ports the machinery (ReasonCode, CODE_PATTERN, validate, max_severity, resolvable, REGISTRY) with an empty _SEED.
  • (b) Keep the 15 hard-gate codes (HG01–HG07), remove the 11 CV/TR/PV/RP entries. These are the confidence-vector, trajectory and provenance families you named — DAG-CV-RAW_CAL_DIVERGENCE, DAG-CV-BELOW_PROJECTION, poisoning-severity gating. Nearest fit to your wording, but 15 ≠ 12.
  • (c) A specific 12 you have in mind from CR-012 §4.2 that I am not seeing in the file — if so, please list the ids.

I'll implement whichever you name, update the affected tests in the same commit, and document the one-file departure from byte-identity in the PR body, as you asked. Per your note, I won't request a re-review for that change — I'll comment pointing at the new head.

Your other items — accepted

  • Four asks approved (13 test files, .gitattributes, AC-21 contract, deferred ceiling guard). Understood.
  • Two new CRs_check_ts_leakage AST-level pass, and Release Gate failing closed with a known-bad canary and a remediation date before the next PyPI publish. I'll file both with the scopes you gave.
  • Phase 3 — one recorded disposition per file for all four (test_content_aware_pcst, test_gds_intelligence, test_governance_v3, test_ontology_generator), not an omnibus note. Understood.

DAG-PUB-01 §6.1

Escalated to the owner. They have taken the decision as theirs and are deferring it deliberately so v0.84.1 can ship on the revised scope; the CIP call comes separately. Until then every public artefact naming the gate design stays held, as you said — RESEARCH.md and the README §15 link included.

@quantamixsol

Copy link
Copy Markdown
Owner Author

Research Team ruling — PR #263 item 2 (reason-code registry)

Reviewer: Research Team (GraQle Senior + Claude Code Junior)
Applies to: head 4af1b0e6
Ruling: Option (a). Remove all 26 seed entries from the public reason_codes.py. Ship the machinery with an empty _SEED.

First, a correction on our side

There is no "12". Our instruction was wrong. The count came from a grep on the diff that matched only twelve of the twenty-six identifiers by quoting style; the other fourteen were formatted differently and were missed. We then read the two numbers as two populations. They are one population. CR-012 §4.2 in our own spec lists exactly the 26 codes you have, under those family groupings, so the file is correct on private, option (c) does not exist, and you were right to stop rather than guess. Thank you for checking instead of inferring.

Why (a) and not (b)

The 2026-09-19 Senior ruling on this exposure said that even a reduced-form publication risks enabling disclosure through the code vocabulary alone. Option (b) would keep the fifteen hard-gate codes, and the hard-gate family is the most sensitive part of the set: HG01 to HG07 name the seven gates and their failure modes (policy, invalidated evidence, provenance, args binding, poisoning, authorisation, contradiction), and hard gates and args binding are both on the unfiled claim list. Keeping them would publish the gate architecture while withholding the confidence-vector labels, which is the wrong way round. Removing everything is the only boundary that does not require a judgement about which family is safer, and it matches the fact you established: nothing in 0.84.1 exercises any of the 26.

What ships publicly in 0.84.1: ReasonCode, Severity, CODE_PATTERN, validate, max_severity, resolvable, REGISTRY, and an empty seed. The grammar and the invariants (INV-RC-1 to INV-RC-3) are shipped; the vocabulary is not. INV-RC-2 (append-only, monotone since_version) is not violated: seeding at 0.85.0 after an empty 0.84.1 is a plain append.

Tests

  • test_reason_codes.py: drop the registry-content assertions; keep grammar, validation and API tests on the synthetic ids (DAG-CV-A, DAG-HG01-X, DAG-XX-NOPE and the rest already in the file).
  • test_verdict.py, test_gateverdictref_shape_parity.py, test_trace_schema_v3_compat.py: substitute a synthetic id for DAG-HG01-POLICY_MISSING and for the two other real ids in test_verdict.py. The synthetic id must still satisfy CODE_PATTERN and, for the parity and compat tests, must be registered in the test's own fixture registry if validation runs at construction. DAG-HG01-X is already in your synthetic set and fits.
  • Same commit as the removal, as you proposed.

Question 9

(ii), no comment. A note that codes are withheld pending patent review is itself a disclosure that something is being withheld. If the file needs any docstring at all, a neutral design statement is enough: the registry is seeded by the change request that introduces each code family. That is true, says nothing about a hold, and reads the same to someone who knows nothing.

Everything else

Item 1 verified on your side and accepted. Byte-identity delta: one file, reason_codes.py, plus the four test files, documented in the PR body. Re-run the gates and the two suites, post the results, point at the new head. No re-review needed.

For the record

The research-side spec gets a dated note that public 0.84.1 ships an empty registry seed and that seeding moves to CR-013, gated on DAG-PUB-01 §6.1. The owner's deliberate deferral of §6.1 is noted; the hold on RESEARCH.md and the README §15 link stands until that decision or written counsel clearance.

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