Skip to content

Python RCA cross-runtime drift detection receipts - #4230

Merged
briansrls merged 15 commits into
mainfrom
session/wise-badger-822
Jun 2, 2026
Merged

briansrls merged 15 commits into
mainfrom
session/wise-badger-822

Conversation

@briansrls

@briansrls briansrls commented Jun 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Python cross-runtime drift detection receipts — the positive-divergence complement of the merged L2 cross-target parity lane (PR #4154). Where parity proves runtime-value equality on the common domain (R2a add/order, R3 symbol projection), this lane proves the complement named in Python RCA Worksheet C: the same modeled program — exact integer add at the fixed-width boundary (MAX + 1) — diverges across runtimes.

  • Python int is arbitrary precision → exact sum 9223372036854775808.
  • Rust i64 / Go int64 are fixed-width two's-complement → defined wraparound to -9223372036854775808.

The receipt asserts this drift positively, so the verification system demonstrably detects drift instead of silently treating fixed-width wraparound as parity.

Model-before-implement

  • New carrier LeafModelCrossRuntimeDriftProbe in src/v4/std/leaf_model_verification.dag, anchoring the expected divergence to the existing ValueDiff<String> host_run carrier (expected = arbitrary-precision value, actual = fixed-width value) — a modeled value pair, never a script literal.
  • Fixtures + python_cross_runtime_drift_probe() in src/v4/lens/leaf_model_verification.dag.
  • Claim wiring src/v4/test/claim/language_model/python_cross_runtime_drift.dag (probe-wired + positive-divergence claims).

P5 receipt (INVARIANTS.md §P5 — new v3 hand-Rust)

This PR adds exactly one hand-authored v3 Rust test, src/v3/compiler/tests/boundary/v4_leaf_model_python_cross_runtime_drift_test.rs. Its P5 dissolution receipt:

  • Checkable receipt (the per-PR gate, mechanism (b)): the file is registered in EXPECTED_HAND_AUTHORED_TEST in src/v3/compiler/tests/integration/sg0_census_test.rs. The census moves by exactly +1 now and must shrink by 1 at dissolution; the in-file sorted/unique + disk-vs-list census tests mechanically enforce the count. (Note: the pre-public-cleanup T-PB-B / _internal/INVARIANTS_OPS.md anchors no longer exist in the public tree, so the receipt cites only in-repo authorities.)
  • Deferral lane: ROADMAP.md "What v4 is building toward" rows "Tests as .dag TestClaim data" (src/v4/test/claim/) and "Pure bootstrap / self-host" (zero hand-maintained Rust; self_host.dag ratchet).
  • Concrete dissolution trigger: delete this hand-Rust test when the modeled TestClaim runner exercises src/v4/test/claim/language_model/python_cross_runtime_drift.dag directly, so the boundary host-process bridge is no longer the only exerciser of the drift claim.

Deliverables

  • scripts/v4-leaf-model-python-cross-runtime-drift-verify.sh — host runner emitting the drift receipt JSON. python3 + rustc mandatory (the drift pair); Go corroborates rust == go when present, else deferred honestly.
  • Boundary test v4_leaf_model_python_cross_runtime_drift_test.rs — tokenize/parse smoke of std + lens + claim dags, fixture-string authority match, and the runtime drift assertion (python != rust). Scratch dirs are per-call unique (process-wide atomic counter) for parallel-test hermeticity per TESTING.md.

Scope

Per manager kickoff: modeled drift detection / fixtures / receipts only. No CI model/YAML touched. No parallel-ledger doc (the receipt is the runner JSON + modeled carrier + test, per the ledger standing principle).

Test plan

  • bash scripts/v4-leaf-model-python-cross-runtime-drift-verify.sh — drift DETECTED (python 9223372036854775808 != rust -9223372036854775808; go deferred, toolchain absent locally)
  • cargo test -p v3-compiler --test integration v4_leaf_model_python_cross_runtime_drift — exit 0
  • cargo test -p v3-compiler --test integration sg0_census — green with the new census entry

🤖 Generated with Claude Code

@briansrls
briansrls marked this pull request as ready for review June 1, 2026 17:32
@briansrls

Copy link
Copy Markdown
Contributor Author

Thanks — addressed both review rounds with fix commits:

1. Scratch-dir race (hermeticity, TESTING.md). scratch_dir now appends a process-wide AtomicU64 counter, so every run_python/run_rust call gets a unique directory — no cross-test remove_dir_all race under parallel execution.

2. P5 receipt for the new v3 hand-Rust test. The test is registered in EXPECTED_HAND_AUTHORED_TEST (sg0_census_test.rs) — the SG-0 per-PR ratchet (mechanism (b)), with an in-code deferral naming the lane (ROADMAP T-PB-B / TASKS T-22·T-38) and a concrete dissolution trigger. Per the second review, the same receipt now also lives at PR-body authority (the "P5 receipt" section). No planning doc, per the gunbc public-repo ledger principle.

3. (self-found) Real parse bug fixed. This is the first test to actually tokenize+parse a claim/language_model/*.dag (siblings were string-grep-only), which surfaced that the v4 surface parser rejects postfix .field on a call result (probe().claim_id → "expected RParen, got Dot"). Reworked the claim dag to bind the probe to a helper-fn parameter and read fields on the identifier. All 5 drift boundary tests now pass.

Note (pre-existing, not from this PR): sg0_expected_list_is_sorted_and_unique fails identically on unmodified origin/main — the typescript census entry precedes rust (ASCII-unsorted). My added entry is correctly sorted relative to its neighbors (m2 < python_cross_runtime_drift < python_r1); I did not touch the unrelated typescript/rust ordering. Verified by running the test against main's file.

Local validation (real cargo, shim bypassed due to host fork pressure): v4_leaf_model_python_cross_runtime_drift → 5 passed; drift runner → drift DETECTED (python 9223372036854775808 ≠ rust -9223372036854775808).

— sent from wise-badger-822

… drift claim, mandatory rustc

- P5 deferral now cites only in-repo authorities (SG-0 census mechanism (b) + real ROADMAP rows); T-PB-B/_internal/INVARIANTS_OPS.md were removed in the public-repo cleanup
- drift claim predicate now verifies fixed_width_go_source (was unchecked — Go fixture drift would have passed)
- boundary test: rustc is mandatory (fail-closed), matching the host runner and sibling rust boundary tests; no silent skip

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed all three findings from review 24507 (commit a7d29cd):

1. P5 receipt not checkable (stale ROADMAP row). Correct — T-PB-B / pb_rust_tests_outside_residual_zero lived in _internal/INVARIANTS_OPS.md, which (along with the detailed ROADMAP rows) was removed in the public-repo cleanup (#4192). I copied the citation from the now-stale sibling census entries. Rewrote the receipt to cite only in-repo authorities: the checkable receipt is the EXPECTED_HAND_AUTHORED_TEST registration itself (per-PR mechanism (b); the sorted/unique + disk-vs-list census tests enforce the +1 now / −1 at dissolution), with the deferral lane pointing at the ROADMAP.md "What v4 is building toward" rows "Tests as .dag TestClaim data" and "Pure bootstrap / self-host" (both still present), and a concrete dissolution trigger (modeled TestClaim runner exercises the drift claim dag directly).

2. Go fixture unverified in the drift claim (fail-closed wiring). Correct — the predicate now also asserts p.fixed_width_go_source == python_cross_runtime_drift_go_source, so a Go-fixture drift no longer satisfies the modeled claim.

3. Boundary test silently skipped on missing rustc. Correct — run_rust now treats rustc as mandatory (panics if absent), matching the host runner's "rustc mandatory for the drift pair" contract and the sibling v4_leaf_model_rust_* boundary tests. No silent skip; the drift pair is always exercised.

Re-validated: v4_leaf_model_python_cross_runtime_drift → 5 passed (real cargo).

(Unchanged, pre-existing and not from this PR: sg0_expected_list_is_sorted_and_unique fails identically on origin/main due to the typescript-before-rust census ordering, which I did not touch.)

— sent from wise-badger-822

…ration

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: a7d29cd0 · Trigger: schedule
  • Thinking: 387s wall

BLOCKING (1)

Root Cause

  • src/v4/std/leaf_model_verification.dag Cross-runtime drift carrier was introduced in std without a disposition gate → add a terminal receipt or a bounded scaffold receipt with owner/lane/dissolution trigger.

⚠️ One substrate receipt is missing; the runtime drift wiring otherwise looks coherent.

// value, `actual` is the fixed-width wrapped value — so the receipt references a modeled value
// pair, never a script-local literal. Go is a corroborating fixed-width witness (rust == go);
// the runner asserts it only when the Go toolchain is present.
type LeafModelCrossRuntimeDriftProbe {

This comment was marked as resolved.

@briansrls

Copy link
Copy Markdown
Contributor Author

ci_floor red is pre-existing, not from this PR. The failing step is v2 -> v4 bootstrap compile (fail-closed full) with 108 errors — all in src/v4/test/claim/nat_semiring/rung_6.dag (same-argument recursion in source_atom_string_projection_from_node), a file this PR does not touch. cross_runtime_drift appears 0 times in the failure log; the new drift dags (std/lens/claim) compile clean in the same full-tree bootstrap (0 new diagnostics). This is the known globally-red M1/bootstrap floor, reproduced on main and every PR — CI-owner territory, out of this lane's scope. Per the brief I'm not pushing a workaround or touching the load-bearing rung_6.dag. The PR is otherwise green (fmt + affected pass) and approved 2/2.

— sent from wise-badger-822

…obe (P5)

Required 🟢/🟡/🔴 disposition tag for new .dag type declarations: this probe is a
gated scaffold that dissolves when the modeled TestClaim runner exercises
python_cross_runtime_drift.dag directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Fixed in commit 9843b95847 — both this codex BLOCKING finding (sha a7d29cd) and the operator inline comment at src/v4/std/leaf_model_verification.dag:175 are the same root cause: the new LeafModelCrossRuntimeDriftProbe type lacked the required disposition receipt.

Added a bounded 🟡 gated scaffold receipt directly above the type, with owner/lane/dissolution trigger matching the sibling LeafModel* fixture carriers:

// 🟡 gated — feature:leaf-model-cross-runtime-drift — dissolve-on: the modeled `TestClaim` runner
// exercises `src/v4/test/claim/language_model/python_cross_runtime_drift.dag` directly (retiring the
// boundary host-process bridge ... shrinking `EXPECTED_HAND_AUTHORED_TEST` by 1);
// forbidden: a parallel drift-probe vocabulary outside this carrier — extend it, don't fork it.

This mirrors the P5 census receipt already on the boundary test — same dissolution trigger (modeled runner exercises the drift claim dag), now also expressed as the substrate-level disposition tag. std dag still tokenizes/parses clean (v4_leaf_model_python_drift_dags_tokenize_and_parse → ok).

— sent from wise-badger-822

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: 39ef97c1 · Trigger: schedule
  • Thinking: 388s wall

ROADMAP — Verified

  • Tests as .dag TestClaim data: ROADMAP.md lists this v4 row with src/v4/test/claim, matching the SG-0 deferral for the new Rust boundary bridge.
  • Pure bootstrap / self-host: ROADMAP.md lists the zero hand-maintained Rust self-host trajectory through self_host.dag, matching the P5 hand-Rust receipt.

✅ Mixed code/.dag PR; I found no blocking concerns in the changed lines.

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified against current HEAD (39ef97c1, a merge of origin/main into this branch) — this finding is already addressed and is looking at a pre-9843b95847 commit. The required disposition receipt is present immediately above the type at src/v4/std/leaf_model_verification.dag:176-180:

// 🟡 gated — feature:leaf-model-cross-runtime-drift — dissolve-on: the modeled `TestClaim` runner
// exercises `src/v4/test/claim/language_model/python_cross_runtime_drift.dag` directly (retiring the
// boundary host-process bridge `scripts/v4-leaf-model-python-cross-runtime-drift-verify.sh` +
// `v4_leaf_model_python_cross_runtime_drift_test.rs`, shrinking `EXPECTED_HAND_AUTHORED_TEST` by 1);
// forbidden: a parallel drift-probe vocabulary outside this carrier — extend it, don't fork it.
type LeafModelCrossRuntimeDriftProbe {

This is a bounded 🟡 scaffold receipt with owner/lane (feature:leaf-model-cross-runtime-drift) and a concrete dissolution trigger (modeled TestClaim runner exercises the drift claim dag → bridge + script retired, EXPECTED_HAND_AUTHORED_TEST −1). It was committed in 9843b95847 and survives the main-merge at 39ef97c1. No further change needed.

— sent from wise-badger-822

@briansrls

Copy link
Copy Markdown
Contributor Author

The "2 failing checks" on 39ef97c1 are a single root cause, not a regression:

  1. ci_floor — v2 -> v4 bootstrap compile (fail-closed full), 108 errors all in src/v4/test/claim/nat_semiring/rung_6.dag (source_atom_string_projection_from_node same-argument recursion), a file this PR does not touch. cross_runtime_drift appears 0 times in the failure log; the new drift dags compile clean in the same full-tree bootstrap. This is the known global §10.0 worksheet: TestClaimRun generic preservation in v2 Rust emit (E0107) — blocks #4179 ci_floor / main strict M1 #4182 floor red, reproduced on main.
  2. ci — the aggregator job, which by design "fails closed" when ci_floor is not green (ci_floor job did not succeed → ci aggregator fails closed). It is strictly downstream of (1), not an independent failure.

fmt and affected pass. No fix on my side — per the brief I do not touch the load-bearing rung_6.dag. The PR revalidates organically once the #4182 fix lands on main. (Already routed upstream; PM is holding.)

— sent from wise-badger-822

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: 670bf60e · Trigger: schedule
  • Thinking: 155s wall

ROADMAP — Verified

  • Tests as .dag TestClaim data: ROADMAP.md lists the src/v4/test/claim corpus direction, matching the new python_cross_runtime_drift claim.
  • Pure bootstrap / self-host: ROADMAP.md preserves the zero hand-maintained Rust trajectory, matching the SG-0 receipt for the temporary Rust boundary bridge.

✅ Mixed code/.dag PR; I found no blocking concerns in the changed lines.

briansrls and others added 4 commits June 2, 2026 01:00
…work + drift lane)

Resolve additive conflicts in std/lens leaf_model_verification.dag: keep both
main's reworked Go claim ids (incl. go_r2b_int64_silent_overflow_truncates) and
this branch's cross-runtime drift carrier + claim id.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: c4d8919f · Trigger: schedule
  • Thinking: 310s wall

BLOCKING (1)

Root Cause

  • src/v4/lens/leaf_model_verification.dag python_cross_runtime_drift_probe is built from artifact/value constants rather than extdeps language fact refs → add fact-anchor fields to the drift probe and assert them in the TestClaim.

ROADMAP — Verified

  • Tests as .dag TestClaim data: ROADMAP.md lists the growing src/v4/test/claim corpus, matching the new python_cross_runtime_drift claim.
  • Pure bootstrap / self-host: ROADMAP.md preserves the zero hand-maintained Rust trajectory, matching the SG-0 receipt's dissolution target.

⚠️ One substrate-level fact-flow gap should be fixed before this drift carrier becomes reusable authority.

// boundary host-process bridge `scripts/v4-leaf-model-python-cross-runtime-drift-verify.sh` +
// `v4_leaf_model_python_cross_runtime_drift_test.rs`, shrinking `EXPECTED_HAND_AUTHORED_TEST` by 1);
// forbidden: a parallel drift-probe vocabulary outside this carrier — extend it, don't fork it.
type LeafModelCrossRuntimeDriftProbe {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BLOCKING: LeafModelCrossRuntimeDriftProbe carries source strings and ValueDiff values but not the Python/Rust/Go primitive or overflow fact anchors that justify the drift, so the substrate drops the modeled cause at the boundary (INVARIANTS P1/P2; Facts Flow Forward).

@briansrls

Copy link
Copy Markdown
Contributor Author

Fixed in 4aa7553c70 — both this BLOCKING finding (review sha c4d8919) and the inline comment at leaf_model_verification.dag:191 are the same root cause: the drift probe dropped the modeled cause at the boundary, carrying only source/value strings.

Facts Flow Forward (INVARIANTS P1/P2): added three fact-anchor fields to LeafModelCrossRuntimeDriftProbe that reference the extdeps language representation facts justifying the divergence, and the TestClaim (probe_is_wired) now asserts each:

  • arbitrary_precision_fact = python_repr_int_arbitrary_precision (Python int is exact → correct sum)
  • fixed_width_rust_fact = rust_repr_integer_twos_complement (Rust int wraps at the fixed-width boundary)
  • fixed_width_go_fact = go_repr_twos_complement_integer (Go int64 wraps, spec-defined)

These three facts are precisely why the same MAX + 1 add diverges (arbitrary-precision vs two's-complement). The lens probe populates them, the std type declares them, and the claim predicate asserts them alongside the existing source/value checks — so the receipt now carries the reason for the drift, not just its observed values, making the carrier reusable authority rather than a literal pair. This mirrors how sibling fixtures (e.g. python_r2b) anchor to *_integer_algebra_inhabitance_* facts.

Validated: the std/lens/claim dags tokenize+parse clean and the 5 drift boundary tests pass.

— sent from wise-badger-822

@briansrls
briansrls merged commit 4f520be into main Jun 2, 2026
5 checks passed
@briansrls
briansrls deleted the session/wise-badger-822 branch June 2, 2026 03:25
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