docs(mosaic): preserve nested receipt integrity and independent review evidence

This commit is contained in:
fy59 2026-10-13 18:56:48 +02:00
parent bbd7da2403
commit 54392cc0de
10 changed files with 982 additions and 104 deletions

View file

@ -88,3 +88,21 @@
- Preserved the [geometry gate](docs/design/STEP20C_STATIC_NESTED_GEOMETRY_REPLAY_GATE.md)
and experimental source fixture with its historical INCONCLUSIVE verdict; STEP20C NEXT, architecture UNDECIDED and
production multi-output NOT YET SUPPORTED. No production/package/UX change.
## Local receipt semantic integrity gate — offline only
The [R02 receipt-integrity gate](docs/design/STEP20C_STATIC_NESTED_RECEIPT_INTEGRITY_GATE.md)
is local and experimental. The real writer/aggregate share semantic validation
through the existing immutable-data replay and R01 input correlation; typed
receipt content, scenario-specific omissions, AST/test inventories and final
review bindings are checked. Historical geometry evidence remains INCONCLUSIVE;
this correction cannot retroactively qualify static popups. The final local gate
is READY_FOR_NEW_RUNTIME: 206 offline tests pass, 13478 recorded invalid mutations
are rejected, and independent review accepts the final 18-source/15-receipt
bindings after one bounded B-01 writer repair. The actual writer returns READY
with five PASS markers and no blockers. R02 is RESOLVED for this offline fixture;
partial AST coverage and runtime limitations remain explicit. Phase B is
uncommitted and unpublished, and readiness only permits requesting a separate
future authorization. No compositor/runtime authorization,
production/UX/package change or STEP20D work follows. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.

View file

@ -454,3 +454,21 @@ terminal-code repairs are accepted; no readiness or new static popup result.
No graphical run or execution reservation occurred. Close the residual offline
receipt-validation gate before proposing runtime. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.
## Local receipt semantic integrity gate — offline only
The [R02 receipt-integrity gate](design/STEP20C_STATIC_NESTED_RECEIPT_INTEGRITY_GATE.md)
is local and experimental. The real writer/aggregate share semantic validation
through the existing immutable-data replay and R01 input correlation; typed
receipt content, scenario-specific omissions, AST/test inventories and final
review bindings are checked. Historical geometry evidence remains INCONCLUSIVE;
this correction cannot retroactively qualify static popups. The final local gate
is READY_FOR_NEW_RUNTIME: 206 offline tests pass, 13478 recorded invalid mutations
are rejected, and independent review accepts the final 18-source/15-receipt
bindings after one bounded B-01 writer repair. The actual writer returns READY
with five PASS markers and no blockers. R02 is RESOLVED for this offline fixture;
partial AST coverage and runtime limitations remain explicit. Phase B is
uncommitted and unpublished, and readiness only permits requesting a separate
future authorization. No compositor/runtime authorization,
production/UX/package change or STEP20D work follows. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.

View file

@ -395,3 +395,21 @@ terminal-code repairs are accepted; no readiness or new static popup result.
No graphical run or execution reservation occurred. Close the residual offline
receipt-validation gate before proposing runtime. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.
## Local receipt semantic integrity gate — offline only
The [R02 receipt-integrity gate](design/STEP20C_STATIC_NESTED_RECEIPT_INTEGRITY_GATE.md)
is local and experimental. The real writer/aggregate share semantic validation
through the existing immutable-data replay and R01 input correlation; typed
receipt content, scenario-specific omissions, AST/test inventories and final
review bindings are checked. Historical geometry evidence remains INCONCLUSIVE;
this correction cannot retroactively qualify static popups. The final local gate
is READY_FOR_NEW_RUNTIME: 206 offline tests pass, 13478 recorded invalid mutations
are rejected, and independent review accepts the final 18-source/15-receipt
bindings after one bounded B-01 writer repair. The actual writer returns READY
with five PASS markers and no blockers. R02 is RESOLVED for this offline fixture;
partial AST coverage and runtime limitations remain explicit. Phase B is
uncommitted and unpublished, and readiness only permits requesting a separate
future authorization. No compositor/runtime authorization,
production/UX/package change or STEP20D work follows. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.

View file

@ -313,3 +313,21 @@ terminal-code repairs are accepted; no readiness or new static popup result.
No graphical run or execution reservation occurred. Close the residual offline
receipt-validation gate before proposing runtime. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.
## Local receipt semantic integrity gate — offline only
The [R02 receipt-integrity gate](design/STEP20C_STATIC_NESTED_RECEIPT_INTEGRITY_GATE.md)
is local and experimental. The real writer/aggregate share semantic validation
through the existing immutable-data replay and R01 input correlation; typed
receipt content, scenario-specific omissions, AST/test inventories and final
review bindings are checked. Historical geometry evidence remains INCONCLUSIVE;
this correction cannot retroactively qualify static popups. The final local gate
is READY_FOR_NEW_RUNTIME: 206 offline tests pass, 13478 recorded invalid mutations
are rejected, and independent review accepts the final 18-source/15-receipt
bindings after one bounded B-01 writer repair. The actual writer returns READY
with five PASS markers and no blockers. R02 is RESOLVED for this offline fixture;
partial AST coverage and runtime limitations remain explicit. Phase B is
uncommitted and unpublished, and readiness only permits requesting a separate
future authorization. No compositor/runtime authorization,
production/UX/package change or STEP20D work follows. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.

View file

@ -399,3 +399,21 @@ terminal-code repairs are accepted; no readiness or new static popup result.
No graphical run or execution reservation occurred. Close the residual offline
receipt-validation gate before proposing runtime. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.
## Local receipt semantic integrity gate — offline only
The [R02 receipt-integrity gate](design/STEP20C_STATIC_NESTED_RECEIPT_INTEGRITY_GATE.md)
is local and experimental. The real writer/aggregate share semantic validation
through the existing immutable-data replay and R01 input correlation; typed
receipt content, scenario-specific omissions, AST/test inventories and final
review bindings are checked. Historical geometry evidence remains INCONCLUSIVE;
this correction cannot retroactively qualify static popups. The final local gate
is READY_FOR_NEW_RUNTIME: 206 offline tests pass, 13478 recorded invalid mutations
are rejected, and independent review accepts the final 18-source/15-receipt
bindings after one bounded B-01 writer repair. The actual writer returns READY
with five PASS markers and no blockers. R02 is RESOLVED for this offline fixture;
partial AST coverage and runtime limitations remain explicit. Phase B is
uncommitted and unpublished, and readiness only permits requesting a separate
future authorization. No compositor/runtime authorization,
production/UX/package change or STEP20D work follows. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.

View file

@ -0,0 +1,224 @@
# STEP20C static nested receipt semantic integrity gate
EXPERIMENTAL, offline only; semantic integrity gate READY_FOR_NEW_RUNTIME,
with independent acceptance of the final bound fixture and receipts.
Historical geometry gate remains INCONCLUSIVE. Architecture UNDECIDED;
STEP20C NEXT, production multi-output NOT YET SUPPORTED. No graphical run,
Mosaic/SceneFX build, client execution, capture, input, grab, camera or runtime reservation.
## Pre-implementation contract
The published `write_results.py` SHA-256 is
`94ddab595dd9765d3edaa7158a6a98319f3be6b15a62842e4b10eeacfb530cfa`.
Its `REQUIRED` names fifteen receipts; independent-review is the sixteenth
dependency. `write()` loads the receipts, computes bindings, and calls
`aggregate(evidence, hash_file, bindings)`. The pre-correction function checks status,
field presence, nine-case cardinality and some file hashes. It does not verify
the effective nested content. Three actual in-memory calls accept a bare PASS
input correlation, null rendered content/bbox/count/intersection, or nine
empty root objects. These are R02-A/B/C, not compositor observations.
The correction must use this entrypoint for all decisions. Downstream gates not checked after a failed prerequisite are also INCONCLUSIVE. Invalid evidence
returns INCONCLUSIVE with a named blocker and degrades its dependent marker;
invalid evidence is neither a compositor crash nor an architectural rejection.
Unexpected implementation failures cannot become PASS. Missing files and
malformed JSON must also produce blockers. No old receipts are overwritten.
## Required receipt schema and relationships
| Receipt | Required real content and types | Provenance and semantic relationship |
| --- | --- | --- |
| native-shm | positive integer buffer, rectangle size, positive stride, format, source, identity qualification | Replay actual SHM create/attach/ACK; 420×320, stride 1680, format 1; frame identity remains NOT PROVEN |
| xdg-configure | toplevel rectangle, positive initial/assigned ACK, initial configure, new-buffer boolean, popup qualification | Replay initial 0×0/ACK20 versus assigned 636×573/ACK21; no replacement buffer |
| applied | positive owner/PID/workspace, scene/window rectangles, titlebar, finite scroll, globalclip, generation qualification | Replay IPC/source/applied trace; scene (-320,0,640,600), titlebar25, scroll160, viewport(-800,0,800,600) |
| rendered | content rectangle, bbox, nonnegative integer count, visible intersection, native/destination distinction | Replay native geometry and retained image through existing typed model: (-318,25,636,573), bbox[482,25,800,598), 182214 pixels; output origin, clipping and area agree |
| positioner | integer flags, A/B local rectangles, content origin, predicted A/B, runtime qualification | Source-backed flags0; translate A then B from painted origin; prediction never runtime |
| historical-evidence | complete mandatory input path/hash mapping, diagnostic path, runtime qualification | Actual immutable files must exist; replay source/IPC/calibration/reference inputs are all verified |
| historical-replay | exactly nine unique campaign identities; owner/PID/workspace, origin, A/B/configured, protocol, clip, colors, callbacks, injections, buttons, lifecycle, file inventory, input correlation | Re-execute unchanged replay and R01 correlation on retained logs/IPC/images in a disposable directory, then compare every field, type and value |
| popup-root | nine case/origin/A/clip projections | Exact identity join and projection from independently replayed original data; owner is supplied by that joined replay, not fabricated in the historical root schema |
| popup-nested | nine case/B/protocol/standard/dismissal projections | B→A parent, distinct actual serials, configure/ACK/map and lifecycle replay; same identities/geometries/protocol as historical-replay |
| source-audit | pins, 17 unique source contracts, functions, claims, excerpts, source-version receipt/hash | Mandatory historical contract set; actual source/excerpt/version bytes verified |
| client-provenance | mandatory inputs, patch, adapted source, four protocols, comparison, three builds, C17 command receipts | Retained compilation receipts only; source/output/protocol hashes and flags verified, no new build or execution |
| assertion-register | full source/artifact inventories, AST records, counts, 145 historical assertions | Enumerate current AST and use the existing assertion checker for identities, classification and actual test correlations |
| assertion-coverage | entries, 145 assertions, coverage counts, unresolved list, runtime scope | Recompute from register; partial executed coverage remains explicit |
| offline-core-coverage | status, unproved list | Recompute necessary existing pure model guards from register; no invented runtime coverage |
| test-receipts | complete source inventory, unique actual tests, mode/line/contract observations, statuses | Fresh current code; genuine non-aggregator then negative-suite preflights bootstrap aggregation tests without forcing PASS; the complete mandatory negative test set and final full suite must pass before review |
| independent-review | ACCEPTED, independent=true, exact final source and evidence bindings | Genuine report file/hash, reviewer provenance, executed commands, mandatory independent attack results, findings and limitations; positive unit control has memory-only synthetic acceptance, rejected by the real file-backed writer |
Rectangles use [x,y,width,height]; PNG bbox uses [x1,y1,x2,y2).
IDs/serials/counts are integers (booleans are invalid), coordinates are finite.
Positive visible counts require positive valid bboxes; count cannot exceed area.
No semantic trust is granted merely because a file hashes to its own receipt.
Re-derived source observations must match, including owner, workspace, camera,
output origin, titlebar, source/destination and input local/global translation.
The fixed nine-campaign gate is intentionally scenario-specific. Standard
control `clip=null` is required and legitimate. Color `bbox=null` is legitimate
with zero pixels. Nested `standard=null` and `dismissal=null` are legitimate
only where their original scenario did not exercise that operation. Toggle
requires its real standard receipt; close_b requires explicit B close and A
survival in the original replay (the historical nested projection lacks that
field); outside/dismissal scenarios require real done/destruction and absence
of forbidden popup buttons. Unattributable early seat callbacks keep their
explicit NOT AVAILABLE label. Native-frame and atomic-generation qualifications
remain unproved. Missing scenario-required facts are invalid, never filled in.
## Freshness, mutation tests and independent review
Bind all fixture source files and all fifteen evidence files. The aggregator
checks the current source bytes and actual loaded evidence against these files;
review must contain the identical bindings. A source or receipt change after
review invalidates acceptance, even if a new matching author hash is supplied.
Inventories with defined mandatory sets reject omitted members. The historical
67/88-entry sealed manifests remain read-only and are never regenerated.
Order: reproduce R02; correct real aggregate; positive control; deletion,
null/{}/[]/empty-string mutations; cross-receipt contradictions; stale/missing
source/evidence/patch/review bindings; writer test in a private directory;
nine-case replay; new receipts; AST/Shell/Git/inventory; source freeze;
independent review of final bytes; binding verification; verdict; new manifests.
Each original counterexample has its own test and receipt. Tests use independent
deep copies and call the actual aggregate, with no replacement policy/mock.
One configured Astra/high final-reviewer independently reproduces attacks
without relying on the author's mutation suite. It records files/hashes,
commands/results, limits and ACCEPTED/CORRECTION_REQUIRED/NOT_PROVEN. One
bounded correction and delta review are allowed; unresolved material findings
keep INCONCLUSIVE. An accepted earlier version cannot sign changed bytes.
Marker dependencies retain the existing geometry/XDG/assertion/regression/
review groups; any invalid mandatory dependency prevents READY_FOR_NEW_RUNTIME.
READY means only readiness to request authorization in a separate ticket.
Static popup qualification and architectural conclusions are untouched.
## Results
Phase A was published at `bbd7da24036f741130b2ff542f429b416fb9c7e5` on both
origin/main and github/main, with a clean worktree at its gate. Phase B remains
local, uncommitted and unpublished. The historical verdict is not superseded.
`SWAYFX_MOSAIC_STATIC_NESTED_RECEIPT_INTEGRITY_GATE=READY_FOR_NEW_RUNTIME`
The final genuine independent review is ACCEPTED. The actual file-backed writer,
using that review rather than a synthetic test receipt, returns READY_FOR_NEW_RUNTIME
with all five markers PASS and no blockers. R02 is RESOLVED for this offline
fixture; R01/R03 retain their historical accepted status. No material finding
remains in the bounded review scope. Architecture remains UNDECIDED.
## Initial independent review and bounded repair
The initial Astra/high read-only audit rejects the version with B-01:
`write()` lets a JSON decoder RecursionError escape, leaving pre-existing
runner-readiness/offline-gate READY files unchanged. The direct reproduction
uses a 200001-byte rendered.json with 100000 nested arrays. The initial
CORRECTION_REQUIRED report and bindings are retained separately; no acceptance
of changed bytes is implied.
The authorized repair is limited to treating decoder/encoder RecursionError
as an invalid required receipt, and a real writer regression proving both
old READY artifacts become INCONCLUSIVE. No parser framework, runtime change
or scientific dataset limit is introduced. The current-code offline
validation was rerun and the repaired delta submitted to an independent reviewer.
## Final executed evidence and limitations
Private laboratory: `/home/fy59/swayfx-mosaic-receipt-integrity-cof0umuk/`.
Historical laboratory: `/home/fy59/swayfx-mosaic-static-nested-geometry-replay-a56csvoo/`.
The original `aggregate()` and fixture are retained in `sources-before/`; the
initial reviewed version is in `reviewed-fixture-v1/`, and final code in
`proposed-fixture/`. `raw/phase-B-complete.diff` records the complete local delta.
| Executed check | Final observed result |
| --- | --- |
| Non-aggregator bootstrap | 145 tests PASS, genuine receipts |
| Mandatory negative bootstrap | 204 tests PASS, genuine receipts |
| Final full offline suite | 206 tests PASS, 474.694 seconds |
| Original R02-A/B/C | 3 separate mutations INCONCLUSIVE with named blockers |
| Field deletion | 2668 mutations INCONCLUSIVE |
| Null / empty object / empty list / empty string | 10604 invalid mutations INCONCLUSIVE; legitimate omissions separately accepted |
| Cross-receipt contradiction | 173 mutations INCONCLUSIVE |
| Stale/missing files, source/patch/review bindings | 30 mutations INCONCLUSIVE |
| Recorded mutation total | 13478 rejected, no recorded invalid mutation READY |
| Positive complete receipt control | READY_FOR_NEW_RUNTIME; SYNTHETIC_IN_MEMORY_ONLY |
| Historical replay | All nine campaigns PASS through unchanged replay/R01 functions |
| AST register | 2371 sites, including 145 frozen historical assertions; 314 positive+negative, 872 positive-only, 1179 unexecuted |
| Pure model coverage | No unresolved pure invariant; partial executed coverage remains explicit |
| Independent final delta | 12 required attacks rejected, one memory positive accepted, three real-writer controls PASS |
| Actual accepted writer | READY_FOR_NEW_RUNTIME, five PASS markers, no blockers; final source/receipt bindings unchanged |
The initial independent Astra/high report is CORRECTION_REQUIRED due to B-01.
One bounded repair was performed, followed by the read-only Sol/medium delta
review ACCEPTED for the new 18-source/15-receipt bindings. These are distinct
reviews; the older review was never reused as acceptance of changed code.
The final report is `independent-review.md` (SHA-256
`311af1fe694d1bde88884afa21ef16a4fe908d6cfa47b6cbed515d1a21fedc9e`),
and its receipt is `results/independent-review.json` (SHA-256
`4d8401978e69a6c54f2f6144ba06deff4952671bc8e1ae3008376ab6ffe01e09`).
Final source SHA-256 values:
- `write_results.py`: `9202522721caa1815d3824a3db315c8cdb27e607ce1678907774faa1c9c14c0c`.
- `receipt_integrity.py`: `3f32003f7de74336f2be17e063295d51f683d40936568fd8aebebeb5d3f9b45f`.
- `tests_offline.py`: `0e188fe64d0c3d8a6fda227bf4ef8b31658b86390b5ed73d97d0e3bf851b67d1`.
Commands and exit codes are retained in `results/commands.json`, reviewer
receipts, final validation receipts and `raw/`. Intermediate author test failures
(including an incomplete assertion inventory and test-bootstrap completeness)
were corrected before freeze and remain preserved. The delta review's first
static-harness attempt exited 1 due to a Path conversion typo; its correction
and successful retry are retained. None is concealed as a successful run.
The existing offline suite prepared three client-only C17 utilities in disposable
test directories; no client was executed, and neither compositor nor SceneFX
was built. No new image, serial, pointer injection, grab, camera operation,
compositor socket, runtime reservation or installation was produced. Retained
image parsing is offline replay, not capture. Protected production files,
package, cumulative patch and historical sealed manifest entries are unchanged.
Freshness binds raw receipt bytes as well as canonical parsed content and source
bytes. A formatting change also expires a reviewed file. New source or receipt
bytes require new independent acceptance; matching freshly calculated author
hashes alone cannot preserve a prior ACCEPTED verdict. Source/evidence manifests
are sealed only for this new laboratory after final checks. Historical manifests
remain exactly the published 67/88-entry originals.
This finite mutation campaign and independent audit support the fixed historical
fixture contract; they do not prove arbitrary future receipt schemas or universal
parser/resource resilience. READY is solely permission-request readiness.
Native-frame identity, atomic transaction generation, GPU-reference lifetime,
new static popup geometry/pixels/input/grabs/dismissal/standard return, and the
remaining output/damage/effects/ABI matrix remain NOT TESTED or NOT PROVEN as
previously documented. No architectural or UX decision follows. STEP20C stays
NEXT and production multi-output stays NOT YET SUPPORTED. The smallest next
step is a separately authorized static-popup runtime ticket; this ticket
performs no such run.
## Historical receipt-integrity evidence freeze — 2026-10-13
Ticket `SWAYFX_MOSAIC_STEP20C_RECEIPT_FREEZE_AND_STATIC_NESTED_RUNTIME_V1`,
phase A, preserves the accepted R02 version for publication. Statements above
about local/unpublished phase B and absent runtime authorization describe the
previous offline ticket. This freeze changes no reviewed fixture byte and no
sealed laboratory file; the separate runtime handoff requires its own evidence,
authorization and independent acceptance.
The 76 source entries and 199 evidence entries in the receipt-integrity LAB
were individually verified. Manifest SHA-256 values are respectively
`dbd96db3f19f6eb60fc8be13c62b1e71944a759b481d008a7825b3720cf525ce` and
`f00ca54e39bff031a5bda585ea52cfebe9239e71b4c7ee7dc5c41a930e1598b3`.
The final report and review receipt hashes remain exactly those recorded above.
All 18 source and 15 mandatory receipt bindings match independent acceptance.
The actual aggregate was freshly called: READY_FOR_NEW_RUNTIME, five PASS
markers, no blocker. The three original R02 counterexamples were freshly
rejected; a disposable real-writer B-01 check replaced both prior READY files
with INCONCLUSIVE. No synthetic independent acceptance was persisted.
The retained 206-test, nine-replay and 13478-rejected-mutation results were
verified from their immutable receipts, not relabelled as a newly executed full
suite. Python AST, Markdown links, complete diff including untracked files,
310 protected paths and `git diff --check` passed. No runtime, build, capture,
client execution, socket or reservation belongs to phase A. Historical initial
CORRECTION_REQUIRED and final ACCEPTED reviews remain separate. Architecture
UNDECIDED; static popup runtime NOT TESTED; STEP20C NEXT, production multi-output
NOT YET SUPPORTED.

View file

@ -125,7 +125,7 @@ forbidden action is separated from earlier legitimate visible buttons and its
actual observed events feed dismissal. Corrupted coordinates, recipients,
extra invisible buttons and button order fail closed.
R02: `aggregate` is the single gate implementation used by writer and tests.
Historical R02 disposition (published freeze): `aggregate` was the single gate implementation used by writer and tests.
SHM, XDG/configured geometry, source contracts/pins, client provenance/C17,
all nine historical cases, register/coverage/core and test receipts are
mandatory and checked for freshness and structural presence. The bounded
@ -151,7 +151,7 @@ remain inventoried. Re-run the offline sequence after source changes before
handing the final unsealed fixture to the parent for bounded review.
## Final offline disposition — INCONCLUSIVE / NOT READY
## Historical offline disposition — INCONCLUSIVE / NOT READY
The independent tester ran195 tests with0 failures and all9 historical cases.
The bounded independent reviewer ran65 targeted tests PASS and resolved R01/R03,
@ -167,3 +167,46 @@ The four raw technical PASS labels do not prove effective receipt completeness.
The fixture is prepared but NOT READY; run.py must remain unexecuted. The next
step is a separately scoped offline correction of aggregate's semantic-content
guards and their negative regressions. No new runtime/budget is authorized.
## Local R02 semantic integrity correction
See [the receipt contract](../../../docs/design/STEP20C_STATIC_NESTED_RECEIPT_INTEGRITY_GATE.md).
`aggregate()` remains the single decision function used by `write()` and tests.
`receipt_integrity.py` replays the original data through existing geometry,
protocol and R01 correlation functions in disposable offline directories, and
compares every typed receipt field. It uses the existing AST checker and checks
complete mandatory file inventories. Null clips in standard controls, zero-color
null bboxes and scenario-specific absent standard/dismissal observations remain
legitimate; required toggle/close/dismissal observations cannot be deleted.
No historical receipt, raw log, image or sealed manifest is rewritten.
Bindings cover all fixture sources, all mandatory receipt file bytes and the
canonical parsed content. A changed source/receipt loses prior acceptance.
Unit M0 acceptance is synthetic, explicitly memory-only. The real writer only
reads the external independent review; it never signs acceptance. Final readiness
is determined by that exact bound review and the genuine test receipts.
In a new offline LAB, run the existing replay, run `tests_offline.py LAB --preflight`,
then `assertions.py LAB`. Copy these genuine receipts under `LAB/preflight/results/`
before running `tests_offline.py LAB --negative-preflight`. Regenerate the AST
receipts and replace the new LAB preflight snapshot with these genuinely executed
negative-suite receipts, then run `tests_offline.py LAB` for the final validation.
This prevents circular test bootstrapping
without forcing PASS or substituting old source hashes. Regenerate the final
AST receipts, freeze source/evidence bytes, and request independent review.
Initial preflight covers non-aggregator tests. Negative preflight collects all
required negative test IDs without claiming M0 readiness. Final validation uses
that complete snapshot and must pass its positive controls as well. The suite
executes the R02/mutation/writer tests. No synthetic review file is written.
All generated output belongs outside Git. These are Python/offline operations
only; no runtime command or ledger initialization is authorized.
The historical INCONCLUSIVE verdict above remains frozen. The local semantic
gate can establish only readiness to request a separate future authorization,
never static popup success. R01/R03 and the runner are unchanged. Phase B is
local, uncommitted and unpublished.
The bounded B-01 repair treats JSON decoder/encoder recursion exhaustion as
malformed required evidence. The real writer must replace pre-existing READY
artifacts with INCONCLUSIVE; decoder failure never retains a qualified gate.
This is receipt error handling, not a compositor/SceneFX rejection.

View file

@ -0,0 +1,314 @@
"""Semantic checks for the fixed, retained offline campaign; no runtime action.
WHY: self-consistent labels/hashes cannot establish observations. Reuse the
qualified replay, input correlation and AST checker instead of a second model.
CONTRACT: historical inputs are read-only; all checker output is disposable.
INVARIANT: cached replay is bound to sealed input bytes, never caller receipts.
"""
from functools import lru_cache
import hashlib
import json
import math
from pathlib import Path
import tempfile
from support import sha
HERE = Path(__file__).resolve().parent
SEALED = Path('/home/fy59/swayfx-mosaic-static-nested-geometry-replay-a56csvoo')
SEALS = {'source-sha256.txt': 'e1230ba1292f12d913b762f0678e638a2effb513b74eb44dd232c12aa4acea1d',
'evidence-sha256.txt': '22b9ac035da95ba914c28d72d8aa6f019c16c2854095d81ceb62c0bd10da8dbe'}
REVIEW_ATTACKS = {'R02-A','R02-B','R02-C','root-empty','nested-empty','input-partial',
'render-incoherent','standard-missing','dismissal-missing',
'serial-contradiction','source-stale','old-review-bindings'}
def check(ok, reason):
if not ok:
raise ValueError(reason)
def encoded(value):
return json.dumps(value, sort_keys=True, separators=(',', ':'), allow_nan=False)
def same(actual, expected, path='receipt'):
"""Types matter: Python's True == 1 must not accept a serial or count."""
check(type(actual) is type(expected), path + ': wrong type')
if isinstance(expected, dict):
check(set(actual) == set(expected), path + ': missing/unexpected fields')
for key in expected:
same(actual[key], expected[key], path + '.' + key)
elif isinstance(expected, list):
check(len(actual) == len(expected), path + ': incomplete observations')
for index, value in enumerate(expected):
same(actual[index], value, path + '[' + str(index) + ']')
else:
if isinstance(actual, float):
check(math.isfinite(actual), path + ': nonfinite coordinate')
check(actual == expected, path + ': contradicts original observation')
def fresh(mapping, hash_file, required=None):
check(isinstance(mapping, dict) and bool(mapping), 'missing hash inventory')
if required is not None:
check(set(mapping) == set(required), 'incomplete mandatory inventory')
for path, digest in mapping.items():
check(isinstance(path, str) and bool(path), 'invalid input path')
check(isinstance(digest, str) and len(digest) == 64 and
all(c in '0123456789abcdef' for c in digest), 'missing/invalid SHA-256')
check(hash_file(path) == digest, 'missing/stale file: ' + path)
@lru_cache(maxsize=1)
def sealed_receipts():
"""Bootstrap only the immutable historical source/provenance contracts.
The fixed manifests authenticate the campaign used by this bounded gate.
This does not accept derived semantics: geometry/input are replayed below.
"""
for name, digest in SEALS.items():
check(sha(SEALED / 'results' / name) == digest, 'historical seal changed')
rows = (SEALED / 'results' / name).read_text().splitlines()
check(len(rows) == (67 if name.startswith('source') else 88), 'seal inventory incomplete')
for row in rows:
expected, path = row.split(' ', 1)
check(sha(path) == expected, 'sealed historical file changed: ' + path)
return {name: json.loads((SEALED / 'results' / (name + '.json')).read_text())
for name in ('source-audit', 'client-provenance', 'historical-replay', 'historical-evidence')}
def historical_inputs():
from replay import NESTED, HISTORICAL
old = sealed_receipts()
expected = dict(old['historical-evidence']['inputs'])
manifest = HISTORICAL / 'results/evidence-sha256.txt'
check(sha(manifest) == '5750d1e74636c2d276800f795ed0214c3e12999908149855af0b382a2da9bfb4',
'original geometry evidence seal changed')
sealed_raw = {path: digest for digest,path in
(line.split(' ',1) for line in manifest.read_text().splitlines())}
# Replay also reads these original IPC/calibration/reference observations.
extra = [str(HISTORICAL / rel) for rel in (
'results/camera-calibration.json', 'results/E1-applied-snapshot.json',
'results/geometry-fixture-diagnostic.json', 'run/H2-reference-1.png', 'run/H2-reference-2.png')]
for path in extra:expected[path]=sealed_raw[path]
for row in old['historical-replay']['cases']:
expected.update({str(NESTED / row['case'] / name): digest for name,digest in row['files'].items()})
fresh(expected, sha)
return dict(sorted(expected.items()))
@lru_cache(maxsize=1)
def rederived(input_key):
"""Bounded cache: one replay, keyed by every raw input's real SHA-256.
Rechecking hashes before lookup prevents a stale cache from authorizing
changed observations. No subprocess, client or compositor is executed.
"""
from replay import replay_native, replay_nested
with tempfile.TemporaryDirectory(prefix='mosaic-receipt-replay-') as tmp:
root = Path(tmp)
(root / 'results').mkdir()
replay_native(root)
replay_nested(root)
values = {p.stem: json.loads(p.read_text()) for p in (root / 'results').glob('*.json')}
# The positioner is a source prediction, separate from historical configure.
values['positioner'] = dict(status='PASS source-backed prediction', flags=0,
A=[100,80,350,170], B=[100,60,300,130], predicted_content_origin=[-318,25],
predicted_A=[-218,105,350,170], predicted_B=[-118,165,300,130],
runtime='NOT TESTED; actual configure/ACK/map required')
return values
@lru_cache(maxsize=16)
def checked_historical(name, receipt_key, input_key):
same(json.loads(receipt_key), rederived(input_key)[name], name)
def validate_historical(name, data, hash_file, inputs=None):
inputs = historical_inputs() if inputs is None else inputs
# Exact typed comparisons include all scenario-specific observations, not
# just lists/status. Standard/null/zero-color cases follow the real replay.
checked_historical(name, encoded(data), tuple(inputs.items()))
def validate_source_audit(data, hash_file):
expected = sealed_receipts()['source-audit']
same(data, expected, 'source-audit')
for contract in data['contracts']:
fresh({contract['source']: contract['sha256']}, hash_file)
lines = Path(contract['source']).read_text().splitlines()
for excerpt in contract['excerpts']:
check(excerpt['token'] in lines[excerpt['line'] - 1], 'source excerpt token/line mismatch')
check(excerpt['text'] in '\n'.join(lines), 'source excerpt absent')
fresh({data['source_version_receipt']: data['source_version_sha256']}, hash_file)
def validate_client(data, hash_file):
expected = sealed_receipts()['client-provenance']
same(data, expected, 'client-provenance')
fresh(data['inputs'], hash_file, expected['inputs'])
fresh({str(HERE / 'placement.patch'): data['patch']}, hash_file)
builds = {b['client']: b for b in data['builds']}
for command in data['commands']:
check(command['exit'] == 0, 'historical C17 command failed')
label, argv = command['label'], command['argv']
if label.endswith('-compile') and label[:-8] in builds:
build = builds[label[:-8]]
source = next(v for v in argv if v.endswith('/' + label[:-8] + '.c'))
output = argv[argv.index('-o') + 1]
fresh({source: build['source'], output: build['binary']}, hash_file)
fresh({str(Path(source).parent / n): v for n, v in data['protocols'].items()}, hash_file)
def validate_tests(data, hash_file):
check(set(data)=={'status','source_inventory','tests'}, 'missing test receipt fields')
files = {str(p) for p in HERE.iterdir() if p.suffix in ('.py', '.patch', '.json')}
fresh(data['source_inventory'], hash_file, files)
tests = data['tests']
check(isinstance(tests, list) and bool(tests), 'missing executed tests')
ids = set()
# WHY: M0 must consume a genuinely completed negative suite. Excluding the
# two positive controls avoids a circular requirement for their own PASS.
import tests_offline
mandatory = {'Case.' + n for n in dir(tests_offline.Case)
if n.startswith('test_') and n not in (
'test_positive_aggregate_complete_bound','test_integrity_legitimate_omissions')}
allowed={'Case.'+n for n in dir(tests_offline.Case) if n.startswith('test_')}
for test in tests:
check(isinstance(test, dict), 'malformed test receipt')
check(test['status'] == 'PASS' and test['mode'] in ('positive', 'negative'), 'failed/unclassified test')
check(isinstance(test['id'], str) and '.Case.test_' in test['id'], 'invalid test identity')
check(test['id'] not in ids, 'duplicate test identity')
ids.add(test['id'])
check(test['id'].split('.Case.')[0] in ('__main__','tests_offline') and
test['id'][test['id'].index('Case.'):] in allowed,'unknown executed test identity')
for field in ('executed_lines', 'failed_lines', 'contracts'):
check(isinstance(test[field], list), 'missing test trace: ' + field)
check(bool(test['executed_lines']) and all(isinstance(line,str) and bool(line)
for line in test['executed_lines']), 'empty executed test trace')
for c in test['contracts']:
check(isinstance(c['contract'], str) and bool(c['contract']) and type(c['pass']) is bool,
'invalid executed contract')
check(mandatory <= {n[n.index('Case.'):] for n in ids}, 'incomplete mandatory negative suite')
@lru_cache(maxsize=1)
def checked_register(key):
"""Use the original qualified AST checker, writing only to a temp LAB."""
import assertions
evidence = json.loads(key)
with tempfile.TemporaryDirectory(prefix='mosaic-receipt-register-') as tmp:
lab = Path(tmp)
(lab / 'results').mkdir()
for name, data in evidence.items():
(lab / 'results' / (name + '.json')).write_text(json.dumps(data))
# WHY: checking existing AST keys alone allowed null or misleading
# derived classification/coverage fields. Regenerate every record
# through the same classifier and executed-receipt logic as the writer
# workflow, then compare the full caller-provided register and core.
coverage=assertions.build(lab)
generated=json.loads((lab/'results/assertion-register.json').read_text())
same(evidence['assertion-register'],generated,'assertion-register effective content')
same(evidence['offline-core-coverage'],json.loads((lab/'results/offline-core-coverage.json').read_text()),'offline-core-coverage effective content')
return coverage
def validate_register(name, evidence, hash_file):
import assertions
register = evidence['assertion-register']
check(set(register)=={'status','source_inventory','artifact_inventory','records','counts','historical_asserts'},
'missing register receipt fields')
same(register['historical_asserts'],145,'historical assertion count')
same(register['status'],'CLASSIFIED; execution status is per-entry','register classification scope')
paths = [assertions.HISTORY / n for n in assertions.HISTORICAL_FILES] + [
p for p in sorted(HERE.glob('*.py')) if p.name != 'tests_offline.py']
required = {str(p.relative_to(assertions.REPO)) for p in paths}
check(set(register['source_inventory']) == required, 'incomplete AST source inventory')
fresh({str(assertions.REPO / p): v for p,v in register['source_inventory'].items()}, hash_file)
artifacts = {str(p) for p in HERE.iterdir() if p.suffix in ('.patch', '.json')}
fresh(register['artifact_inventory'], hash_file, artifacts)
selected = {n: evidence[n] for n in ('assertion-register', 'test-receipts', 'offline-core-coverage')}
coverage = checked_register(encoded(selected))
records = register['records']
counts = {kind: sum(r['kind'] == kind for r in records) for kind in sorted({r['kind'] for r in records})}
same(register['counts'], counts, 'AST counts')
same(evidence['assertion-coverage'], coverage, 'assertion-coverage')
core = {'model.py', 'ledger.py', 'authorization.py', 'observations.py', 'pixels.py'}
unproved = [r['id'] for r in records if Path(r['source']).name in core and
r['kind'] == 'checked invariant' and not
(r['positive_executed_test_ids'] and r['negative_executed_test_ids'])]
same(evidence['offline-core-coverage'], dict(status='PASS' if not unproved else 'FAIL NOT PROVEN', unproved=unproved), 'offline-core-coverage')
check(not unproved and coverage['unresolved_pure_invariants'] == [], 'necessary pure coverage unproved')
def make_bindings(evidence, evidence_files=None):
"""Canonical content digest supports M0 in memory and binds real receipts.
WHY: raw file hashes alone cannot bind a caller's mutated parsed object.
File hashes remain separate; formatting changes after review also expire it.
"""
from write_results import REQUIRED
result = dict(source_delta={p.name: sha(p) for p in HERE.iterdir() if p.is_file()},
evidence_content={n: hashlib.sha256(encoded(evidence[n]).encode()).hexdigest() for n in REQUIRED})
if evidence_files is not None:
result['evidence_files'] = {n: str(p) for n,p in evidence_files.items()}
result['evidence_sha256'] = {n: sha(p) for n,p in evidence_files.items()}
else:
# Memory-only tests bind canonical bytes, not imaginary evidence files.
result['evidence_sha256'] = dict(result['evidence_content'])
return result
def validate_review(evidence, bindings, hash_file):
from write_results import REQUIRED
check(isinstance(bindings, dict), 'missing final bindings')
current = make_bindings(evidence)
same(bindings['source_delta'], current['source_delta'], 'review final sources')
fresh({str(HERE / n): v for n,v in bindings['source_delta'].items()}, hash_file)
same(bindings['evidence_content'], current['evidence_content'], 'review final receipt content')
check(set(bindings['evidence_sha256']) == set(REQUIRED), 'missing evidence bindings')
if 'evidence_files' in bindings:
check(set(bindings['evidence_files']) == set(REQUIRED), 'missing evidence paths')
for name in REQUIRED:
path = bindings['evidence_files'][name]
fresh({path: bindings['evidence_sha256'][name]}, hash_file)
same(json.loads(Path(path).read_text()), evidence[name], 'loaded proof ' + name)
else:
same(bindings['evidence_sha256'], current['evidence_content'], 'memory evidence hashes')
review = evidence['independent-review']
check(review['status'] == 'ACCEPTED' and review['independent'] is True, 'review not independently ACCEPTED')
for key, value in bindings.items():
same(review[key], value, 'review not bound to final source/evidence hashes: ' + key)
if 'evidence_files' not in bindings:
# CONTRACT: only the in-memory positive control may use synthetic
# acceptance. The writer always supplies evidence_files and cannot
# turn this test receipt into independent publication authority.
check(review['scope']=='SYNTHETIC_IN_MEMORY_ONLY','unqualified memory review')
return
check(review['scope']=='FINAL_OFFLINE_RECEIPT_INTEGRITY','synthetic/incorrect persisted review scope')
check(review['reviewer_role'] in ('final-reviewer','reviewer') and
isinstance(review['reviewer_agent'],str) and bool(review['reviewer_agent']) and
review['read_only'] is True,'missing independent reviewer provenance')
fresh({review['report_file']:review['report_sha256']},hash_file)
report=Path(review['report_file']).read_text()
check('RECEIPT_INTEGRITY_REVIEW=ACCEPTED' in report,'report does not accept final version')
commands=review['commands']
check(isinstance(commands,list) and bool(commands),'missing executed review commands')
for command in commands:
check(isinstance(command['argv'],list) and bool(command['argv']) and
all(isinstance(a,str) and bool(a) for a in command['argv']) and
type(command['exit_code']) is int and command['exit_code']==0,
'review command absent/failed')
mutations=review['mutations']
check(isinstance(mutations,dict) and REVIEW_ATTACKS<=set(mutations),'incomplete independent mutation set')
for name in REVIEW_ATTACKS:
result=mutations[name]
check(result['status']=='INCONCLUSIVE' and isinstance(result['blockers'],list) and
bool(result['blockers']) and all(isinstance(b,str) and bool(b) for b in result['blockers']),
'independent attack not rejected: '+name)
check(isinstance(review['findings'],list) and
all(isinstance(f,dict) and f.get('severity') in ('NON_BLOCKING','FUTURE_SCOPE') for f in review['findings']),
'material independent finding unresolved')
check(isinstance(review['limitations'],list) and bool(review['limitations']) and
all(isinstance(s,str) and bool(s) for s in review['limitations']), 'review scope absent')

View file

@ -20,6 +20,9 @@ from support import save
HERE=Path(__file__).resolve().parent
RECEIPTS=[]
FIXTURE_SNAPSHOT=None
BASELINE_CHECKED=False
BOOTSTRAP=False
ACTIVE=None
TRACKED={str(p.resolve()) for p in HERE.glob('*.py')}
LINES={}
@ -331,8 +334,8 @@ class Case(unittest.TestCase):
auth['registered_lab']='wrong';f.write_text(json.dumps(auth));self.reject('registered-fresh-lab-required',lambda:authorize(root,f))
def test_negative_offline_lab_authorization(self):
with tempfile.TemporaryDirectory(prefix='geometry-auth-test-') as tmp:
root=Path(tmp);f=root/'auth.json';f.write_text(json.dumps(dict(scope='one-new-static-nested-headless-run',explicit_user_authorization=True,ticket='synthetic-future-unit-test',registered_lab=str(LAB.resolve()))))
self.reject('historical-or-offline-lab-forbidden',lambda:authorize(LAB,f))
root=Path(tmp);f=root/'auth.json';f.write_text(json.dumps(dict(scope='one-new-static-nested-headless-run',explicit_user_authorization=True,ticket='synthetic-future-unit-test',registered_lab=str(HISTORICAL.resolve()))))
self.reject('historical-or-offline-lab-forbidden',lambda:authorize(HISTORICAL,f))
def test_negative_ledger_sequences(self):
with tempfile.TemporaryDirectory(prefix='geometry-ledger-test-') as tmp:
p=Path(tmp)/'budget.json';initial_for_offline_test(p);reserve(p,'click');state=json.loads(p.read_text());state['events'][0]['seq']=5
@ -455,40 +458,41 @@ class Case(unittest.TestCase):
data,recorded=self.exchange(invocation=True);self.assertIsNone(data['ipc_exit'])
self.assertIn('ipc_error',data);self.assertFalse(data['scientific_cleanup_pass']);self.assertEqual(recorded,[])
def test_receipt_fail_closed_empty(self):
from write_results import aggregate
result=aggregate({},lambda path:None,{})
self.assertEqual(result['status'],'INCONCLUSIVE')
self.assertTrue(result['blockers'])
def test_receipt_fail_closed_status_only(self):
from write_results import aggregate,REQUIRED
result=aggregate({n:{'status':'PASS'} for n in REQUIRED},lambda path:None,{})
self.assertEqual(result['status'],'INCONCLUSIVE')
self.assertEqual(set(result['markers'].values()),{'INCONCLUSIVE'})
def aggregate_fixture(self):
from write_results import REQUIRED,aggregate
from support import sha
evidence={n:json.loads((LAB/'results'/(n+'.json')).read_text()) for n in REQUIRED}
# CONTRACT: all acceptance here is a synthetic complete snapshot in memory.
# The real receipts are written only after the entire suite finishes.
evidence['test-receipts']['status']='PASS'
for receipt in evidence['test-receipts']['tests']:receipt['status']='PASS'
# CONTRACT: this is synthetic independent acceptance in memory only.
bindings={'source_delta':{'fixture':'synthetic-final-hash'},'evidence_sha256':{'proof':'synthetic-proof-hash'}}
evidence['independent-review']=dict(status='ACCEPTED',independent=True,**bindings)
# INVARIANT: immutable synthetic hash provider avoids bootstrapping current
# test receipts from the suite that is still producing those receipts.
# WHY: source inventories in this synthetic snapshot must describe the
# same bytes even while the real on-disk register awaits regeneration.
evidence['test-receipts']['source_inventory']={n:sha(n) for n in evidence['test-receipts']['source_inventory']}
evidence['assertion-register']['source_inventory']={n:sha(HERE.parents[2]/n) for n in evidence['assertion-register']['source_inventory']}
hashes={}
for name in ('historical-evidence','client-provenance','test-receipts'):
hashes.update(evidence[name].get('inputs',{}));hashes.update(evidence[name].get('source_inventory',{}))
reg=evidence['assertion-register'];hashes.update({str(HERE.parents[2]/n):v for n,v in reg['source_inventory'].items()});hashes.update(reg['artifact_inventory'])
audit=evidence['source-audit'];hashes.update({c['source']:c['sha256'] for c in audit['contracts']})
hashes[audit['source_version_receipt']]=audit['source_version_sha256']
for case in evidence['historical-replay']['cases']:
hashes.update({str(NESTED/case['case']/n):v for n,v in case['files'].items()})
client=evidence['client-provenance'];hashes[str(HERE/'placement.patch')]=client['patch']
builds={v['client']:v for v in client['builds']}
for command in client['commands']:
label=command['label'];argv=command['argv']
if label.endswith('-compile') and label[:-8] in builds:
build=builds[label[:-8]];source=next(v for v in argv if v.endswith('/'+label[:-8]+'.c'))
hashes[source]=build['source'];hashes[argv[argv.index('-o')+1]]=build['binary']
hashes.update({str(Path(source).parent/n):v for n,v in client['protocols'].items()})
return aggregate,evidence,lambda path:hashes.get(str(path)),bindings
from receipt_integrity import make_bindings
# WHY: bootstrap with genuine current preflight receipts, collected
# before aggregation tests, not forced statuses or obsolete hashes.
root=LAB/'preflight'/'results'
global FIXTURE_SNAPSHOT
import pickle,copy
if FIXTURE_SNAPSHOT is None:
evidence={n:json.loads((root/(n+'.json')).read_text()) for n in REQUIRED}
FIXTURE_SNAPSHOT=(pickle.dumps(evidence),make_bindings(evidence))
# Separate object graphs for every mutation. The serialization is an
# in-memory copy of our own JSON, never untrusted external pickle input.
evidence=pickle.loads(FIXTURE_SNAPSHOT[0])
bindings=copy.deepcopy(FIXTURE_SNAPSHOT[1])
# CONTRACT: synthetic acceptance exists in this independent memory
# snapshot only. It is never persisted as the real review.
evidence['independent-review']=dict(status='ACCEPTED',independent=True,scope='SYNTHETIC_IN_MEMORY_ONLY',**__import__('copy').deepcopy(bindings))
def safe_hash(path):
try:return sha(path)
except (OSError,ValueError):return None
return aggregate,evidence,safe_hash,bindings
def test_positive_aggregate_complete_bound(self):
fn,e,h,b=self.aggregate_fixture();result=fn(e,h,b)
@ -576,24 +580,237 @@ for gate in REQUIRED:
current=copy.deepcopy(original);current['evidence_sha256'][gate]='changed-proof'
result=fn(e,h,current)
self.assertEqual(result['status'],'INCONCLUSIVE')
self.assertTrue(any('review not bound' in x for x in result['blockers']))
self.assertTrue(any(x.startswith('independent-review:') for x in result['blockers']))
setattr(Case,'test_negative_aggregate_'+gate.replace('-','_')+'_stale_review_binding',test)
def integrity_negative(self, label, mutate, group, category):
import copy
from receipt_integrity import make_bindings
fn,e,h,b=self.aggregate_fixture()
global BASELINE_CHECKED
if not BOOTSTRAP and not BASELINE_CHECKED:
self.assertEqual(fn(e,h,b)['status'],'READY_FOR_NEW_RUNTIME','mutation baseline must be complete')
BASELINE_CHECKED=True
mutate(e)
# Rebind the synthetic memory-only review to the mutation so the semantic
# checker itself must reject it; stale-review rejection alone is inadequate.
if group!='independent-review':
import hashlib
from receipt_integrity import encoded
b=copy.deepcopy(b)
b['evidence_content'][group]=hashlib.sha256(encoded(e[group]).encode()).hexdigest()
b['evidence_sha256'][group]=b['evidence_content'][group]
e['independent-review']=dict(status='ACCEPTED',independent=True,scope='SYNTHETIC_IN_MEMORY_ONLY',**copy.deepcopy(b))
r=fn(e,h,b)
self.assertEqual(r['status'],'INCONCLUSIVE',label)
self.assertTrue(any(x.startswith(group+':') for x in r['blockers']),(label,r['blockers']))
for marker,dependencies in r['marker_scope'].items():
if group in dependencies:self.assertEqual(r['markers'][marker],'INCONCLUSIVE',label)
MUTATIONS.append(dict(label=label,category=category,gate=group,status=r['status'],blockers=r['blockers'],markers=r['markers']))
MUTATIONS=[]
def original_R02(self, name):
def mutate(e):
if name=='A':e['historical-replay']['cases'][0]['input_correlation']={'status':'PASS'}
elif name=='B':
for k in ('content','PNG_bbox','count','visible_intersection'):e['rendered'][k]=None
else:e['popup-root']['cases']=[{} for _ in range(9)]
integrity_negative(self,'R02-'+name,mutate,{'A':'historical-replay','B':'rendered','C':'popup-root'}[name],'original')
for letter in 'ABC':
def test(self,letter=letter):original_R02(self,letter)
setattr(Case,'test_integrity_R02_'+letter,test)
def essential_paths(evidence):
"""Required fields, including scenario-specific nested original facts.
All root/nested observations are inspected in all nine cases. Empty
failed_lines/contracts and scenario nulls are legitimate and not mutated
into the same value; deleting their schema key still must be rejected.
"""
for gate in REQUIRED:
for key in evidence[gate]:yield gate,[key]
for gate in ('historical-replay','popup-root','popup-nested'):
for index,row in enumerate(evidence[gate]['cases']):
def walk(value,path):
if isinstance(value,dict):
for k,v in value.items():
yield path+[k]
# File inventories are complete mappings, not samples.
yield from walk(v,path+[k])
elif isinstance(value,list) and value and isinstance(value[0],dict):
for i,v in enumerate(value):yield from walk(v,path+[i])
for path in walk(row,['cases',index]):yield gate,path
def access(e,gate,path):
node=e[gate]
for part in path[:-1]:node=node[part]
return node,path[-1]
def test_deletions(self):
# WHY: bulk mutation receipts prove returned verdicts, not line coverage.
# Individual R02/positive tests keep tracing; suppressing tracing here
# avoids charging repeated read/hash loops as scientific branch proof.
sys.settrace(None)
_,e,_,_=self.aggregate_fixture()
for gate,path in essential_paths(e):
def mutate(d,gate=gate,path=path):
parent,key=access(d,gate,path);del parent[key]
integrity_negative(self,gate+'/'+str(path),mutate,gate,'deletion')
def test_nullifications(self):
sys.settrace(None)
_,e,_,_=self.aggregate_fixture()
for gate,path in essential_paths(e):
parent,key=access(e,gate,path);original=parent[key]
for value in (None,{},[], ''):
if type(value) is type(original) and value==original:continue
def mutate(d,gate=gate,path=path,value=value):
parent,key=access(d,gate,path);parent[key]=value
integrity_negative(self,gate+'/'+str(path)+'='+repr(value),mutate,gate,'nullification')
def test_contradictions(self):
sys.settrace(None)
attacks=[('rendered',['content',3],320),('rendered',['content',1],0),
('rendered',['PNG_bbox',0],483),('rendered',['count'],182215),
('rendered',['count'],True),('applied',['scroll'],161.0),
('applied',['globalclip',0],0),('applied',['titlebar'],0),
('native-shm',['stride'],1280),('native-shm',['buffer'],True),
('xdg-configure',['assigned_ACK'],20),('positioner',['flags'],1)]
attacks += [('assertion-register',['records',0,'test_status'],None),
('assertion-register',['records',0,'domain'],'invented classification'),
('assertion-register',['historical_asserts'],True),
('test-receipts',['tests',0,'executed_lines'],[]),
('test-receipts',['tests',0,'id'],'__main__.Case.test_fabricated')]
for index in range(9):
for field,value in [('owner',999),('workspace',999),('origin',[0,0]),('A',[0,0,300,170]),('B',[0,0,300,130]),('case','unknown')]:
attacks.append(('historical-replay',['cases',index,field],value))
attacks += [('historical-replay',['cases',index,'protocol','grabs',1,'parent'],'TOPLEVEL'),
('historical-replay',['cases',index,'protocol','grabs',1,'serial'],55),
('historical-replay',['cases',index,'input_correlation','buttons',0,'target'],'POPUP_B'),
('historical-replay',['cases',index,'input_correlation','buttons',0,'serial'],999),
('historical-replay',['cases',index,'input_correlation','buttons',1,'state'],1),
('historical-replay',['cases',index,'input_correlation','callbacks',-1,'local'],[99999.0,1.0]),
('historical-replay',['cases',index,'input_correlation','actions',0,'motion_msec'],99999),
('popup-root',['cases',index,'origin'],[0,0]),
('popup-root',['cases',index,'clip'],[0,0,1,1]),
('popup-nested',['cases',index,'B'],[0,0,300,130]),
('popup-nested',['cases',index,'protocol','grabs',1,'ack'],999)]
for gate,path,value in attacks:
def mutate(d,gate=gate,path=path,value=value):
parent,key=access(d,gate,path);parent[key]=value
integrity_negative(self,gate+'/'+str(path),mutate,gate,'contradiction')
for gate in ('historical-replay','popup-root','popup-nested'):
integrity_negative(self,gate+' duplicated identity',lambda d,gate=gate:d[gate]['cases'].__setitem__(1,__import__('copy').deepcopy(d[gate]['cases'][0])),gate,'contradiction')
def test_freshness(self):
import copy
fn,e,h,b=self.aggregate_fixture()
from receipt_integrity import make_bindings
from support import sha
# A correct source hash replaced by the hash of its own mutated file must
# still lose the previously signed acceptance.
for key in ('source_delta','evidence_sha256','evidence_content'):
current=copy.deepcopy(b);first=next(iter(current[key]));current[key][first]='0'*64
r=fn(e,h,current);self.assertEqual(r['status'],'INCONCLUSIVE');self.assertTrue(r['blockers'])
MUTATIONS.append(dict(label='stale '+key,category='freshness',status=r['status'],blockers=r['blockers']))
for gate in REQUIRED:
d=copy.deepcopy(e);d[gate]={};current=make_bindings(d)
# Old acceptance, even with fresh current bindings, is not reusable.
r=fn(d,h,current);self.assertEqual(r['status'],'INCONCLUSIVE')
self.assertTrue(any(x.startswith('independent-review:') for x in r['blockers']))
for key in ('status','independent','scope','source_delta','evidence_sha256','evidence_content'):
for value in (None,{},[], ''):
integrity_negative(self,'review '+key+'='+repr(value),lambda d,key=key,value=value:d['independent-review'].__setitem__(key,value),'independent-review','freshness')
for file in (str(HERE/'placement.patch'),str(HERE/'receipt_integrity.py'),next(iter(e['historical-evidence']['inputs']))):
r=fn(e,lambda p,file=file:None if str(p)==file else h(p),b)
self.assertEqual(r['status'],'INCONCLUSIVE');self.assertTrue(r['blockers'])
MUTATIONS.append(dict(label='missing '+file,category='freshness',status=r['status'],blockers=r['blockers']))
def test_omissions(self):
fn,e,h,b=self.aggregate_fixture()
self.assertIsNone(e['popup-root']['cases'][4]['clip'])
self.assertIsNone(e['popup-nested']['cases'][0]['standard'])
self.assertIsNone(e['popup-nested']['cases'][2]['dismissal'])
self.assertIsNone(e['historical-replay']['cases'][0]['colors']['right']['POPUP_B']['bbox'])
self.assertEqual(e['historical-replay']['cases'][0]['colors']['right']['POPUP_B']['count'],0)
self.assertEqual(fn(e,h,b)['status'],'READY_FOR_NEW_RUNTIME')
def test_writer(self):
import contextlib,io,copy
from write_results import write,aggregate
from receipt_integrity import make_bindings
fn,e,h,b=self.aggregate_fixture()
# CONTRACT: no synthetic acceptance is persisted, even in the writer test.
e['independent-review']={'status':'NOT RUN','independent':False}
with tempfile.TemporaryDirectory(prefix='mosaic-real-writer-') as tmp:
root=Path(tmp);(root/'results').mkdir()
for name,data in e.items():save(root,name,data)
current=make_bindings(e,{n:root/'results'/(n+'.json') for n in REQUIRED})
expected=aggregate(e,h,current)
with contextlib.redirect_stdout(io.StringIO()):observed=write(root)
self.assertEqual(observed['status'],expected['status']);self.assertEqual(observed['markers'],expected['markers'])
e['rendered']['count']=None;save(root,'rendered',e['rendered'])
with contextlib.redirect_stdout(io.StringIO()):observed=write(root)
self.assertEqual(observed['status'],'INCONCLUSIVE')
self.assertEqual(observed['markers']['STATIC_NESTED_SHM_RENDER_GEOMETRY_REPLAY'],'INCONCLUSIVE')
self.assertTrue(any(x.startswith('rendered:') for x in observed['blockers']))
# CONTRACT B-01: decoder exhaustion must invalidate persisted READY,
# not merely raise before publication. The fake prior marker is an
# adversarial receipt in this test-owned temp LAB, not signed review.
prior={'status':'READY_FOR_NEW_RUNTIME','marker':'SWAYFX_MOSAIC_STATIC_NESTED_GEOMETRY_OFFLINE_GATE=READY_FOR_NEW_RUNTIME'}
save(root,'runner-readiness',prior);save(root,'offline-gate',prior)
(root/'results/rendered.json').write_text('['*100000+'0'+']'*100000)
with contextlib.redirect_stdout(io.StringIO()):observed=write(root)
self.assertEqual(observed['status'],'INCONCLUSIVE')
self.assertTrue(any(x.startswith('rendered:') for x in observed['blockers']))
for name in ('runner-readiness','offline-gate'):
persisted=json.loads((root/'results'/(name+'.json')).read_text())
self.assertEqual(persisted['status'],'INCONCLUSIVE')
self.assertEqual(persisted['markers']['STATIC_NESTED_SHM_RENDER_GEOMETRY_REPLAY'],'INCONCLUSIVE')
save(LAB,'writer-entrypoint-test',dict(status='PASS',aggregate_source=str(Path(aggregate.__code__.co_filename)),mock=False,synthetic_review_persisted=False,invalid=observed['blockers']))
Case.test_integrity_deletions=test_deletions
Case.test_integrity_nullifications=test_nullifications
Case.test_integrity_contradictions=test_contradictions
Case.test_integrity_freshness=test_freshness
Case.test_integrity_legitimate_omissions=test_omissions
Case.test_integrity_writer=test_writer
class Result(unittest.TextTestResult):
def addSuccess(self,test):
super().addSuccess(test);RECEIPTS.append(dict(id=test.id(),status='PASS',mode='negative' if '.test_negative_' in test.id() else 'positive',executed_lines=sorted(LINES.get(test.id(),set())),failed_lines=sorted(FAILED.get(test.id(),set())),contracts=[{'contract':c,'pass':v} for c,v in sorted(CONTRACTS.get(test.id(),set()))]))
super().addSuccess(test);RECEIPTS.append(dict(id=test.id(),status='PASS',mode='negative' if '.test_negative_' in test.id() else 'positive',executed_lines=sorted(LINES.get(test.id(),set())),failed_lines=sorted(FAILED.get(test.id(),set())),contracts=[{'contract':c,'pass':v} for c,v in sorted(CONTRACTS.get(test.id(),set()))]));sys.settrace(trace)
def addFailure(self,test,err):
super().addFailure(test,err);RECEIPTS.append(dict(id=test.id(),status='FAIL',error=str(err[1])))
super().addFailure(test,err);RECEIPTS.append(dict(id=test.id(),status='FAIL',error=str(err[1])));sys.settrace(trace)
def addError(self,test,err):
super().addError(test,err);RECEIPTS.append(dict(id=test.id(),status='FAIL',error=str(err[1])))
super().addError(test,err);RECEIPTS.append(dict(id=test.id(),status='FAIL',error=str(err[1])));sys.settrace(trace)
if __name__=='__main__':
parser=argparse.ArgumentParser();parser.add_argument('lab',type=Path);args=parser.parse_args();LAB=args.lab
parser=argparse.ArgumentParser();parser.add_argument('lab',type=Path);parser.add_argument('--preflight',action='store_true');parser.add_argument('--negative-preflight',action='store_true');args=parser.parse_args();LAB=args.lab
sys.settrace(trace)
result=unittest.TextTestRunner(verbosity=2,resultclass=Result).run(unittest.defaultTestLoader.loadTestsFromTestCase(Case))
suite=unittest.defaultTestLoader.loadTestsFromTestCase(Case)
if args.preflight:suite=unittest.TestSuite(t for t in suite if 'aggregate' not in t.id() and 'integrity' not in t.id())
if args.negative_preflight:suite=unittest.TestSuite(t for t in suite if t._testMethodName not in ('test_positive_aggregate_complete_bound','test_integrity_legitimate_omissions'))
BOOTSTRAP=args.negative_preflight
result=unittest.TextTestRunner(verbosity=2,resultclass=Result).run(suite)
sys.settrace(None)
save(LAB,'test-receipts',dict(source_inventory={str(p):__import__('hashlib').sha256(p.read_bytes()).hexdigest() for p in HERE.iterdir() if p.suffix in ('.py','.patch','.json')},status='PASS' if result.wasSuccessful() else 'FAIL',tests=RECEIPTS))
save(LAB,'positive',{'tests':[r for r in RECEIPTS if r.get('mode')=='positive']})
save(LAB,'negative',{'tests':[r for r in RECEIPTS if r.get('mode')=='negative']})
if not args.preflight:
save(LAB,'aggregate-negative',{'status':'PASS' if result.wasSuccessful() else 'FAIL', 'mutations':MUTATIONS})
for category in ('deletion','nullification','contradiction','freshness','original'):
save(LAB,category+'-tests',{'status':'PASS' if result.wasSuccessful() else 'FAIL','mutations':[r for r in MUTATIONS if r['category']==category]})
raise SystemExit(0 if result.wasSuccessful() else 1)

View file

@ -20,71 +20,48 @@ def aggregate(evidence,hash_file,bindings):
WHY: no author test or successful compile can substitute for another gate.
Bindings describe the exact final evidence/source bytes reviewed independently.
"""
from receipt_integrity import (validate_historical, validate_source_audit,
validate_client, validate_register, validate_tests, validate_review, historical_inputs, fresh)
failures={}
def need(name,ok,reason):
if not ok:failures.setdefault(name,[]).append(reason)
def fresh(mapping):
return bool(mapping) and all(hash_file(path)==digest for path,digest in mapping.items())
def guarded(name, validator):
# CONTRACT: invalid/missing evidence degrades its gate, never crashes
# the writer or becomes a compositor/SceneFX architectural failure.
try:
validator()
except (OSError, ValueError, TypeError, KeyError, IndexError, AttributeError,
AssertionError, RuntimeError, StopIteration) as error:
need(name,False,str(error) or type(error).__name__)
if not isinstance(evidence,dict):evidence={}
for name in REQUIRED:
d=evidence.get(name)
need(name,isinstance(d,dict) and bool(d),'missing evidence')
need(name,isinstance(d,dict) and bool(d),'missing/malformed evidence')
if not isinstance(d,dict):continue
status=d.get('status','')
need(name,status=='PASS' or status.startswith('PASS ')
or name=='assertion-register' and status=='CLASSIFIED; execution status is per-entry','gate not PASS')
def record(name):return evidence.get(name) or {}
for name in ('native-shm','xdg-configure','applied','rendered','positioner'):
fields={'native-shm':('size','buffer','stride','format'), 'xdg-configure':('toplevel','initial_ACK','assigned_ACK'),
'applied':('owner','workspace','scene','window','titlebar','globalclip'),
'rendered':('content','PNG_bbox','count','visible_intersection'),
'positioner':('flags','A','B')}[name]
need(name,all(k in record(name) for k in fields),'incomplete geometry proof')
need('historical-evidence',fresh(record('historical-evidence').get('inputs',{})),'stale/missing historical inputs')
cases=record('historical-replay').get('cases',[])
expected={'run-private_mosaic-crossing-b_cross','run-private_mosaic-crossing-both_cross',
'run-private_mosaic-toggle-b_cross','run-private_mosaic-outside-visible',
'run-control-crossing-b_cross','run-control-crossing-both_cross','run-control-outside-visible',
'run-private_mosaic-close_b-visible','run-control-close_b-visible'}
need('historical-replay',len(cases)==9 and {c.get('case') for c in cases}==expected,'required nine cases incomplete')
for c in cases:
need('historical-replay',c.get('status')=='PASS historical sampled replay' and c.get('input_correlation',{}).get('status')=='PASS','case/input proof incomplete')
need('historical-replay',fresh({str(__import__('replay').NESTED/c.get('case','')/n):v for n,v in c.get('files',{}).items()}),'stale case files')
for name in ('popup-root','popup-nested'):
need(name,len(record(name).get('cases',[]))==9,'incomplete popup proof')
audit=record('source-audit');contracts=audit.get('contracts',[])
need('source-audit',len(contracts)==17 and all(c.get('claim') and c.get('excerpts') and hash_file(c.get('source',''))==c.get('sha256') for c in contracts),'incomplete/stale source contracts')
need('source-audit',bool(audit.get('pins')) and hash_file(audit.get('source_version_receipt',''))==audit.get('source_version_sha256') and bool(audit.get('source_version_sha256')),'stale pinned receipt')
client=record('client-provenance');commands=client.get('commands',[])
need('client-provenance',fresh(client.get('inputs',{})),'stale client sources')
need('client-provenance',all(client.get(k) for k in ('patch','adapted_nested','protocols','protocol_comparison','builds')),'incomplete provenance')
needed={n+'-'+mode for n in ('nested-client','pointer-daemon','static-reference') for mode in ('syntax','compile')}
need('client-provenance',needed<={c.get('label') for c in commands} and all(c.get('exit')==0 for c in commands),'C17 commands missing/failed')
for command in commands:
if command.get('label') in needed:need('client-provenance','-std=c17' in command.get('argv',[]) and '-Werror' in command.get('argv',[]),'C17 flags incomplete')
need('client-provenance',hash_file(str(HERE/'placement.patch'))==client.get('patch'),'stale placement patch')
builds={c.get('client'):c for c in client.get('builds',[])}
need('client-provenance',set(builds)=={'nested-client','pointer-daemon','static-reference'},'missing client builds')
for command in commands:
label=command.get('label','');argv=command.get('argv',[])
if label.endswith('-compile') and label[:-8] in builds:
build=builds[label[:-8]]
output=argv[argv.index('-o')+1] if '-o' in argv else ''
source=next((v for v in argv if v.endswith('/'+label[:-8]+'.c')),'')
need('client-provenance',bool(output) and hash_file(output)==build.get('binary') and bool(source) and hash_file(source)==build.get('source'),'stale built client/source')
directory=Path(source).parent
need('client-provenance',all(hash_file(str(directory/n))==v for n,v in client.get('protocols',{}).items()),'stale generated protocols')
register=record('assertion-register');inventory=register.get('source_inventory',{})
need('assertion-register',fresh({str(HERE.parents[2]/p):v for p,v in inventory.items()}) and fresh(register.get('artifact_inventory',{})),'stale inventory')
need('assertion-register',register.get('historical_asserts')==145 and bool(register.get('records')),'incomplete register')
coverage=record('assertion-coverage')
need('assertion-coverage',coverage.get('status')=='PASS' and coverage.get('historical_asserts')==145 and coverage.get('entries')==len(register.get('records',[])) and coverage.get('unresolved_pure_invariants')==[],'coverage incomplete')
need('offline-core-coverage',record('offline-core-coverage').get('unproved')==[],'core unproved')
tests=record('test-receipts');receipts=tests.get('tests',[])
need('test-receipts',fresh(tests.get('source_inventory',{})),'stale test sources')
need('test-receipts',bool(receipts) and all(t.get('status')=='PASS' for t in receipts) and len({t.get('id') for t in receipts})==len(receipts),'missing/failed test receipts')
review=record('independent-review')
need('independent-review',review.get('status')=='ACCEPTED' and review.get('independent') is True,'review not independently ACCEPTED')
need('independent-review',bool(bindings.get('source_delta')) and bool(bindings.get('evidence_sha256')) and all(review.get(k)==v for k,v in bindings.items()),'review not bound to final source/evidence hashes')
status=d.get('status')
need(name,isinstance(status,str) and (status=='PASS' or status.startswith('PASS ')
or name=='assertion-register' and status=='CLASSIFIED; execution status is per-entry'),'gate not PASS')
input_error=None
try:
inputs=historical_inputs()
fresh(inputs,hash_file)
except (OSError,ValueError,TypeError,KeyError,AssertionError) as error:
inputs=None;input_error=str(error) or type(error).__name__
for name in ('native-shm','xdg-configure','applied','rendered','positioner',
'historical-evidence','historical-replay','popup-root','popup-nested'):
if input_error:need(name,False,input_error)
else:guarded(name,lambda name=name:validate_historical(name,evidence.get(name),hash_file,inputs))
# CONTRACT: after a failed prerequisite, unchecked downstream gates are
# INCONCLUSIVE too. This bounds work on invalid input without granting PASS.
def downstream(name,validator):
if failures:need(name,False,'not qualified after failed prerequisite')
else:guarded(name,validator)
downstream('source-audit',lambda:validate_source_audit(evidence.get('source-audit'),hash_file))
downstream('client-provenance',lambda:validate_client(evidence.get('client-provenance'),hash_file))
downstream('test-receipts',lambda:validate_tests(evidence.get('test-receipts'),hash_file))
for name in ('assertion-register','assertion-coverage','offline-core-coverage'):
downstream(name,lambda name=name:validate_register(name,evidence,hash_file))
downstream('independent-review',lambda:validate_review(evidence,bindings,hash_file))
groups={'STATIC_NESTED_SHM_RENDER_GEOMETRY_REPLAY':('native-shm','applied','rendered','historical-evidence'),
'STATIC_NESTED_XDG_GEOMETRY_AUDIT':('xdg-configure','positioner','historical-replay','popup-root','popup-nested','source-audit','client-provenance'),
'STATIC_NESTED_ASSERTION_COVERAGE':('assertion-register','assertion-coverage','offline-core-coverage'),
@ -99,16 +76,25 @@ def write(lab):
results=lab/'results'
def read(name):
path=results/(name+'.json')
return json.loads(path.read_text()) if path.exists() else {}
try:return json.loads(path.read_text()) if path.exists() else {}
# WHY: a decoder-depth failure must not leave previous READY artifacts
# authoritative. CONTRACT: malformed proof reaches the same aggregate
# as missing proof, which publishes explicit INCONCLUSIVE markers.
except (OSError,ValueError,RecursionError):return {}
aliases={'native-shm-geometry':'native-shm','xdg-configure-geometry':'xdg-configure','applied-content-geometry':'applied','rendered-paint-geometry':'rendered','popup-positioner-audit':'positioner','historical-popup-replay':'historical-replay','root-clip-model':'popup-root','nested-clip-model':'popup-nested','positive-tests':'positive','negative-tests':'negative'}
for name,source in aliases.items():save(lab,name,read(source))
coverage=read('assertion-coverage');tests=read('test-receipts');core=read('offline-core-coverage')
coverage=coverage if isinstance(coverage,dict) else {}
tests=tests if isinstance(tests,dict) else {}
reviewfile=results/'independent-review.json'
review=read('independent-review') if reviewfile.exists() else {'status':'NOT RUN','independent':False}
evidence={name:read(name) for name in REQUIRED}
evidence['independent-review']=review
source_delta={p.name:sha(p) for p in HERE.iterdir() if p.is_file()}
bindings=dict(source_delta=source_delta,evidence_sha256={name:sha(results/(name+'.json')) for name in REQUIRED if (results/(name+'.json')).exists()})
from receipt_integrity import make_bindings
try:
bindings=make_bindings(evidence,{name:results/(name+'.json') for name in REQUIRED})
except (OSError,ValueError,TypeError,KeyError,RecursionError):
bindings={} # Missing/malformed proof cannot carry accepted bindings.
def safe_hash(path):
try:return sha(path)
except (OSError,ValueError):return None
@ -117,7 +103,10 @@ def write(lab):
save(lab,'popup-geometry-model',dict(status=markers['STATIC_NESTED_XDG_GEOMETRY_AUDIT'],scope='offline typed model and sampled historical replay; new runtime NOT TESTED',root=read('popup-root'),nested=read('popup-nested'),prediction=read('positioner'),source='source-audit.json',native_input='Opening click must lie in actual native surface bounds; destination scaling alone is insufficient'))
readiness=dict(status=status,marker='SWAYFX_MOSAIC_STATIC_NESTED_GEOMETRY_OFFLINE_GATE='+status,markers=markers,marker_scope=gates['marker_scope'],review_bindings=bindings,blockers=blockers,runtime='NOT TESTED',architectural_conclusion='UNDECIDED',fixture_only=True,current_ticket_runtime_authorized=False,runtime_budget_initialized=False,independent_review=review)
save(lab,'runner-readiness',readiness);save(lab,'offline-gate',readiness)
save(lab,'summary',dict(status=status,markers=markers,tests=len(tests.get('tests',[])),coverage=coverage,core=core,historical_cases=len(read('historical-replay').get('cases',[])),runtime_runs=0,new_popups=0,new_grabs=0,new_captures=0,new_camera_operations=0,runtime_budget_initialized=False,production_changes=False,source_delta={p.name:sha(p) for p in HERE.iterdir() if p.is_file()},manifest='UNSEALED; parent review required',next='independent review of final fixture/register/evidence; separate future authorization required for runtime',limitations=['atomic transaction-generation/native-buffer-frame identity NOT PROVEN','new static popup crossing/grab/input/standard NOT TESTED','vertical/scaled/rotated/migration/full damage NOT TESTED','production cross-output viewport NOT YET SUPPORTED']))
def count_rows(value,key):
rows=value.get(key) if isinstance(value,dict) else None
return len(rows) if isinstance(rows,list) else 0
save(lab,'summary',dict(status=status,markers=markers,tests=count_rows(tests,'tests'),coverage=coverage,core=core,historical_cases=count_rows(read('historical-replay'),'cases'),runtime_runs=0,new_popups=0,new_grabs=0,new_captures=0,new_camera_operations=0,runtime_budget_initialized=False,production_changes=False,source_delta={p.name:sha(p) for p in HERE.iterdir() if p.is_file()},manifest='UNSEALED; parent review required',next='independent review of final fixture/register/evidence; separate future authorization required for runtime',limitations=['atomic transaction-generation/native-buffer-frame identity NOT PROVEN','new static popup crossing/grab/input/standard NOT TESTED','vertical/scaled/rotated/migration/full damage NOT TESTED','production cross-output viewport NOT YET SUPPORTED']))
(lab/'independent-review-input.md').write_text('''# Independent review input — EXPERIMENTAL
Review this final fixture against the offline gate; review E1/E2, actual
@ -134,6 +123,7 @@ ACCEPTED/CORRECTION_REQUIRED/NOT PROVEN findings. No author review PASS, runtime
launch, budget initialization or manifest sealing is authorized here.
''')
print(json.dumps(readiness,indent=2))
return readiness
if __name__=='__main__':
parser=argparse.ArgumentParser();parser.add_argument('lab',type=Path);write(parser.parse_args().lab)