Skip to content

Commit b9e722c

Browse files
committed
fcc-verify pass two: pins, integration vectors, claim algebra
PINS.json pins the foreign trees the suite is derived against: axioma-spec 9a20f026 (registry of record, DVEC-001 v1.4) and exp1-runner 4d2bf333 (integration-vector writer). The repo's own head is deliberately unpinned; the head of this commit is the verifier_commit harvested into the EXP-1 C at freeze, and a pin that certifies the suite must postdate it. Runner-replay integration vectors iv01 (UPHELD) and iv02 (REFUTED), written by exp1-runner chain.py via the committed tools/gen_integration.py, gated by SHA-256 manifest plus replay and determinism since CI cannot run the foreign writer. They confirm the verifier's independently reimplemented reader consumes the writer of record byte-for-byte; the twenty-six hand-derived vectors remain the primary conviction evidence. F-INC-1 folded: a trial success that is not a JSON boolean is INVALID-ATTEMPT (FABRICATION). Pass one scored success by Python truthiness; a Tier B reimplementation has no licensed coercion for a non-boolean, so two conformant verifiers could disagree on the same bytes. Gate, not pin. Vector v26. FCC-001-CLAIM-ALGEBRA-v0.1.md committed beside the spec: every probabilistic guarantee derived from stated assumptions, the assumption register as the proof boundary. A Tier B refuter needs the proofs next to the text they implement. Python 3 stdlib only; Fraction in the verdict path, no float in any verdict decision. AGPL-3.0.
1 parent f721a27 commit b9e722c

17 files changed

Lines changed: 458 additions & 8 deletions

PINS.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"calculus_version": "FCC-001-v0.4.1",
3+
"registry_version": "DVEC-001 v1.4",
4+
"pinned": [
5+
{
6+
"name": "axioma-spec",
7+
"role": "registry of record (DVEC-001 v1.4)",
8+
"head": "9a20f026a3ad3de68a758783891623f2fa2f6de4",
9+
"pinned": "2026-07-04"
10+
},
11+
{
12+
"name": "exp1-runner",
13+
"role": "integration-vector writer",
14+
"head": "4d2bf333f242593687cf379e8c19319fdcc5a19e",
15+
"pinned": "2026-07-04"
16+
}
17+
]
18+
}

README.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,34 @@ harness, re-deriving per-episode outcomes from transcripts, are named in the
8787
fccverify/exact.py exact Clopper-Pearson by binomial tail sums
8888
fccverify/verdict.py the FCC-001 6.2 verdict pipeline
8989
fccverify/cli.py command-line entry point
90-
spec/ FCC-001-SPEC-v0.4.1.md, the specification of record
91-
golden/ committed vectors, one per verdict and cause
90+
spec/ FCC-001-SPEC-v0.4.1.md, the specification of
91+
record, and FCC-001-CLAIM-ALGEBRA-v0.1.md, the
92+
formal derivations behind it
93+
golden/ committed vectors, one per verdict and cause,
94+
plus the runner-written integration pairs and
95+
their hash manifest
96+
tools/ gen_integration.py, the integration-vector
97+
writer harness (runs beside an exp1-runner
98+
checkout, not in CI)
99+
PINS.json foreign trees this suite was derived against
92100
VECTORS.md hand derivation of every vector
93101

102+
## Pass two
103+
104+
Pass one built the verdict program and the hand-derived golden vectors.
105+
Pass two pins the foreign trees (PINS.json: axioma-spec for the registry of
106+
record, exp1-runner for the writer), commits the claim algebra beside the
107+
spec so a Tier B refuter has the proofs next to the text they implement,
108+
and adds the runner-replay integration vectors iv01 and iv02, written by
109+
the actual exp1-runner chain.py and gated by SHA-256 manifest since CI
110+
cannot run the foreign writer. The conviction hierarchy is unchanged: the
111+
hand-derived vectors are the primary evidence, derived from the
112+
specification in VECTORS.md; the integration pairs confirm the verifier's
113+
independently reimplemented reader consumes the writer of record
114+
byte-for-byte, nothing more. The head of the commit that closes pass two is
115+
the verifier_commit harvested into the EXP-1 C at freeze, which is why it
116+
cannot be pinned here: the pin certifies the suite, so it must postdate it.
117+
94118
## Licence
95119

96120
AGPL-3.0. The verifier is meant to be cloned, read, and run by adversaries;

VECTORS.md

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,15 @@ delta <= 0 (already excluded by positivity) would make NULL unreachable, the
188188
opposite degeneracy. Range constraints are enumerated per field in the shape
189189
gate, R1's table argument applied to ranges. INVALID-CLAIM (MALFORMED).
190190

191+
**v26 FABRICATION, observation shape (F-INC-1).** Twelve trial records whose
192+
success is the JSON string "yes". Pass one scored success by Python
193+
truthiness, so the pair adjudicated REFUTED with k = 12, demonstrated against
194+
the signed pass-one tree; the JSON number 1 behaved identically. A Tier B
195+
reimplementation has no licensed coercion for a non-boolean, so two
196+
conformant verifiers could disagree on the same bytes. The gate, not the
197+
coercion, is pinned: success must be a JSON boolean, else INVALID-ATTEMPT
198+
(FABRICATION). Genuine booleans adjudicate unchanged.
199+
191200
---
192201

193202
## Coverage
@@ -199,15 +208,41 @@ gate, R1's table argument applied to ranges. INVALID-CLAIM (MALFORMED).
199208
v11/v12/v13/v20/v22/v23/v25 (MALFORMED)
200209
INVALID-ATTEMPT v14 (UNREGISTERED), v15 (INCOMPLETE),
201210
v16/v21 (SNAPSHOT-MISMATCH),
202-
v17/v18/v19/v24 (FABRICATION)
211+
v17/v18/v19/v24/v26 (FABRICATION)
203212

204213
Both REFUTED polarities present for NULL (v02, v03). Both THREAT signs present
205214
(v05 to v09) with the opposite-side and band-overlap disjointness cases that the
206215
one-definition rule requires. The boundary control (v04) fixes the tie-break.
207216
The committed-parameter perimeter is covered on both sides of N' (v15 below,
208217
v19 above), on canonicality (v20), on multiplicity for both chains (v22
209218
claimant, the single-genesis rule refuter), on type consumability for both
210-
chains (v23, v24), and on the range degeneracies that make a claim unrefutable
211-
or unreachable by construction (v25). The four INVALID-ATTEMPT causes reachable
212-
without the harness are covered; BEACON-VIOLATION content stays deferred, named
213-
in the verdict record, and lands with the harness pin.
219+
chains (v23, v24), on the range degeneracies that make a claim unrefutable
220+
or unreachable by construction (v25), and on evidence shape (v26). The four
221+
INVALID-ATTEMPT causes reachable without the harness are covered;
222+
BEACON-VIOLATION content stays deferred, named in the verdict record, and
223+
lands with the harness pin.
224+
225+
---
226+
227+
## Integration vectors
228+
229+
Written by exp1-runner chain.py at the RUNNER_HEAD pinned in PINS.json, via
230+
the committed tools/gen_integration.py. They confirm integration: the
231+
verifier's own reader (reimplemented from the frame format of record,
232+
sharing no code with the writer) consumes the writer of record
233+
byte-for-byte. They do not carry the conviction; the hand-derived v-series
234+
above remains the primary evidence. CI cannot regenerate them (foreign
235+
writer), so the gate is the SHA-256 manifest in
236+
golden/integration-manifest.json plus verdict replay and byte-determinism,
237+
enforced by tests/test_integration.py.
238+
239+
**iv01 UPHELD.** NULL claim, standing parameters (delta = 5/100, alpha' =
240+
1/100); refuter k = 6, n = 12, N' = 12. The v01 arithmetic exactly: CI' at
241+
alpha' straddles the band, not disjoint, UPHELD. The claimant chain also
242+
carries an AX:FCC:TS:v1 record between the state frame and C, exercising the
243+
reader's tolerance of registered non-C tags on a claimant chain, a surface
244+
no hand vector touches.
245+
246+
**iv02 REFUTED.** Same claim; refuter k = 12, n = 12, N' = 12. The v02
247+
arithmetic exactly: p_lo solves p^12 = 0.005, p_lo = 0.6431 > 0.525, CI'
248+
entirely above the band, disjoint, REFUTED.

fccverify/verdict.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ def _stage1_claim(frames, v):
304304
# {claim_c_hash, claim_alpha_prime, k, n} and returns either
305305
# (True, pass_detail) or (False, cause, fail_detail). Adding a committed
306306
# parameter means adding a row; there is no second place to forget.
307+
#
308+
# Judges validate integer operands through _is_int, never bare
309+
# isinstance(_, int): Python booleans are int subclasses, and a bare
310+
# isinstance would let a JSON true in as 1 (A3).
307311

308312
def _judge_binds_claim(reg, ctx):
309313
"""The genesis must commit the hash of the C it attacks (FCC-7.1)."""
@@ -427,6 +431,18 @@ def _stage2_attempt(refuter_frames, claim_c_hash, claim_alpha_prime, v):
427431
"attempt.observation_wellformed", "fail",
428432
"an AX:OBS:v1 trial record lacks a success field")
429433
return None
434+
# F-INC-1: success must be a JSON boolean. Truthiness coercion would
435+
# import Python semantics into the calculus; a Tier B
436+
# reimplementation has no licensed coercion for a non-boolean, so
437+
# two conformant verifiers could disagree. Bare isinstance(_, bool)
438+
# is total and correct here; do not route this through _is_int,
439+
# whose job is the opposite exclusion (A3).
440+
if not isinstance(rec["success"], bool):
441+
v.terminal(INVALID_ATTEMPT, "FABRICATION",
442+
"attempt.observation_wellformed", "fail",
443+
"an AX:OBS:v1 trial record's success is not a JSON "
444+
"boolean")
445+
return None
430446
n += 1
431447
if rec["success"]:
432448
k += 1

golden/integration-manifest.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"cause": null,
4+
"expected": "UPHELD",
5+
"name": "iv01_integration_upheld.bin",
6+
"note": "runner-written pair, k=6 n=12, v01 arithmetic; claimant chain carries an AX:FCC:TS:v1 record",
7+
"refuter": "iv01_integration_upheld.refuter.bin",
8+
"refuter_sha256": "f9e8ef1a000486cb05af6e9c4afd3bfa2ff32115d95cc4b4f98ec5ce69805f58",
9+
"sha256": "559341efe8b749f72008d18081aed8446ac8f9bbf0e846574b75d03ab4186167",
10+
"written_by": "exp1-runner chain.py at the RUNNER_HEAD pinned in PINS.json"
11+
},
12+
{
13+
"cause": null,
14+
"expected": "REFUTED",
15+
"name": "iv02_integration_refuted.bin",
16+
"note": "runner-written pair, k=12 n=12, v02 arithmetic",
17+
"refuter": "iv02_integration_refuted.refuter.bin",
18+
"refuter_sha256": "7e02356c2aeb008a78d172d19a85352425d90ec7bae1c3e6cae1f91e756fe173",
19+
"sha256": "3698a006dd0be08a183d84b2eaa5c140443366cd9c7bfec1444200e8180e9923",
20+
"written_by": "exp1-runner chain.py at the RUNNER_HEAD pinned in PINS.json"
21+
}
22+
]

golden/iv01_integration_upheld.bin

1.02 KB
Binary file not shown.
1.52 KB
Binary file not shown.
878 Bytes
Binary file not shown.
1.51 KB
Binary file not shown.

golden/manifest.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,5 +248,15 @@
248248
"name": "v25_invalid_claim_delta_range.bin",
249249
"note": "delta=150/100 not strictly below 1: band swallows [-1, 1]",
250250
"pass": true
251+
},
252+
{
253+
"cause": "FABRICATION",
254+
"expected": "INVALID-ATTEMPT",
255+
"got": "INVALID-ATTEMPT",
256+
"got_cause": "FABRICATION",
257+
"has_refuter": true,
258+
"name": "v26_invalid_attempt_obs_shape.bin",
259+
"note": "trial success is the string 'yes', not a JSON boolean",
260+
"pass": true
251261
}
252262
]

0 commit comments

Comments
 (0)