Skip to content

feat: pin the iss-35 crosscheck gate's scope and depth#141

Open
REPPL wants to merge 4 commits into
chore/iss-35-ledger-resolvefrom
feat/iss-122-pinned-crosscheck-gate
Open

feat: pin the iss-35 crosscheck gate's scope and depth#141
REPPL wants to merge 4 commits into
chore/iss-35-ledger-resolvefrom
feat/iss-122-pinned-crosscheck-gate

Conversation

@REPPL

@REPPL REPPL commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Implements the pinned crosscheck gate (ledger issue iss-122, tech-debt): the iss-35 brief-surface crosscheck's scope and depth are now committed, hashed, and tiered, so a PROMOTE means the same thing every release — v0.3.0's zero-findings receipt versus the full-depth run's 102 can no longer be two honest readings of one gate.

Chained PR: base is chore/iss-35-ledger-resolve (#140). Merge order #136#137#138#139#140 → this; GitHub retargets automatically.

What changed (the 2026-07-24 grill design, implemented exactly)

  • Committed input manifest at .abcd/development/release-gate/manifest.json: the 17 brief docs, both directions, the 22 checkers, and the sha256 of the pinned prompt (replacing the receipt's literal no-pinned-prompt admission). The crosscheck script consumes the manifest rather than choosing scope per run.
  • Tiered depth: full (both directions) required for additive/breaking releases; shallow (Direction-B only) sufficient for fix/internal. The release's class is derived from the shipped records (ShippedSince(base).Impact()), not the version delta — at 0.x the version folds additive into patch, so the records are the only honest source. Every ambiguity path fails closed to full, including unlabelled added records.
  • Receipt contract, strictly additive (the run plan's STOP condition): receipts gain tier and manifestHash only; no existing field renamed, removed, or re-gated. Findings dispositions read a field already in the schema.
  • Three procedural refusals in receipt_gate: manifestHash mismatch, tier insufficient for the release class, undispositioned findings. Content is never judged — confirmed findings route to the maintainer, whose PROMOTE with recorded dispositions is the gate (the grill rejected hard-blocking on finding severity).
  • Era gating: the refusals arm only when the manifest exists in the armed content tree, so the committed v0.3.0/v0.4.0 receipts remain valid for their commits. The known tradeoff — deleting the manifest disarms the refusals — is recorded as iss-130 on this branch; its backstop is a release.yml check, which is CI config and stays maintainer-gated.

Verification

  • Five behaviours test-first, each watched to fail: the three refusals (including accept-with-disposition and full-on-patch over-delivery), the conforming-receipt acceptance, and the pre-manifest era exemption; plus a fail-closed guard test for unlabelled records.
  • Manifest values are real, not invented: doc list confirmed against the 102-findings run corpus, prompt hash reproducible from the manifest's own text, manifest hash verified identical between shasum and the Go implementation.
  • Gate run independently by the orchestrator: make preflight exit 0, record-lint exit 0.
  • iss-122 resolved open/ → resolved/ on this branch with impact: internal (matches the gate family's precedents; .abcd/development/** is excluded from the release artifact, so no CHANGELOG entry).
  • Independent reviews before this PR opened, both PROMOTE with zero blocking findings. Correctness verified the semver base selection (int compare, no v0.10-vs-v0.4 trap), traced every ambiguity path to fail-closed-full, confirmed over-delivery (full on patch) is accepted, and independently re-verified additive-only compliance and the committed hash. Security attacked the gate as an attestation boundary: hash-format confusion, malformed-manifest fail-open, JSON depth bombs, terminal injection and tier downgrades all held closed or landed inside the acknowledged iss-130 tradeoff. Residual non-blocking observations captured as iss-131 on this branch.

REPPL added 4 commits July 25, 2026 23:12
The iss-35 brief-surface crosscheck ran at a maintainer-chosen scope, so two
honest runs of the same gate could disagree by two orders of magnitude and the
receipt's promptHash was the literal "no-pinned-prompt" admission.

Add a committed input manifest (manifest.json) that pins the 17 brief docs, the
two directions, the checker count (22), and the prompt (with its own sha256).
The crosscheck detector consumes the manifest instead of composing an ad-hoc
list. The receipt gains two additive fields, tier and manifestHash, and
receipt_gate adds three procedural refusals, all era-gated on the manifest's
presence in the armed content tree:

  1. manifestHash must equal the committed manifest's actual sha256;
  2. tier (full/shallow) must be sufficient for the release's impact class;
  3. every recorded finding must carry a disposition.

The impact class is derived at gate time from the shipped records' impact
frontmatter (changelog-driven versioning), not the version number: pre-1.0 an
additive feature and a fix both bump the patch component, so only the records
distinguish a feature release from a patch one. Every fallback (no CHANGELOG,
git error, no prior tag, unclassifiable cut) falls back to the strict full
tier. The refusals are procedural only and never judge a finding's content or
severity; confirmed findings route to the maintainer whose PROMOTE with
recorded dispositions is the gate.

The refusals arm only when the manifest exists in the armed tree, so receipts
committed for pre-manifest releases stay valid for their own commits. No
existing receipt field is renamed, removed, or re-gated.

Assisted-by: Claude:claude-opus-4-8
The pinned-crosscheck gate shipped, so iss-122's residue is closed. Impact
internal: the manifest and its supporting docs live under
.abcd/development/release-gate/ (excluded from the release artifact) and the
receipt_gate change is era-gated on a manifest path that exists only in this
repo, so it is invisible to other repos running record-lint — matching the
iss-35 gate family (iss-35 and iss-121 both resolved internal).

Assisted-by: Claude:claude-opus-4-8
The iss-122 review flagged that removing the committed manifest
reverts the gate to pre-manifest rules by design (era marker).
The backstop is a release.yml check — CI config, maintainer-gated —
so the residue is recorded rather than fixed here.

Assisted-by: Claude:claude-fable-5
Non-blocking review observations recorded behind the armed detector
discipline: the ReadGuarded sibling divergence on the manifest read,
the un-pinned example hash, and duplicate-key tolerance in the
receipt parse.

Assisted-by: Claude:claude-fable-5
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