From 7785ec3e639c0619768882cc095baf6cae4ecee0 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 14 May 2026 17:15:56 +0000 Subject: [PATCH 1/7] =?UTF-8?q?R3=20gate=20#62:=20=C2=A7Acceptance=20recei?= =?UTF-8?q?pt=20=E2=80=94=20CI=20ratchet=20on=20include=5Fstr!-free=20dsl/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Promotes §1.8 row #62 `substrate_gap_file_ingestion_closed` from CONSUMER_LANDED to CONSUMER_LANDED + PASSING. Carrier + structural ratchet + demo already landed via PR #2823 (`FileAttachment` in `src/v3/std/timing_lens.dag` + Refined-B-1 shape ratchet in `file_attachment_substrate_carrier_test.rs` + `gate_62_file_attachment_demo_record` existence proof). §Acceptance per §1.8 row #62 is ".dag program ingests external file w/o `include_str!`". Director's PR #2820 ratification-time grep established the gate-fact (zero matches under `dsl/`); this PR extends that one-time grep into a CI-visible tree-state ratchet `r3_gate_62_no_include_str_in_dsl` that scans every `.dag`/`.v3` file under `dsl/` and fails with the offending paths if any reintroduce `include_str!`. The predicate is over substrate file bodies — distinct from grep-on-doc-comment textual-enforcement per `feedback_no_textual_enforcement_bridges`. Scope-bound per Substrate Mgr direction (msg_210620aa): - Sub-canvas-2 (workflow blob-store / content_digest → bytes resolution) remains Substrate-Mgr-owned, out-of-scope. - No changes to the ratified Refined-B-1 5-field structure (anti-pattern #7); no `AttachmentEncoding` / `WorkflowAssetPath` authoring (anti-patterns #4 + #5). Receipts: - `cargo test -p v3-compiler --test integration r3_gate_62` — passes - `cargo test -p v3-compiler --test integration file_attachment` — carrier ratchet still green (3 passed) Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/r3-program-plan.md | 2 +- src/v3/compiler/tests/integration.rs | 2 + .../r3_gate_62_file_ingestion_passing_test.rs | 91 +++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs diff --git a/docs/r3-program-plan.md b/docs/r3-program-plan.md index 717136853b3..234460e5671 100644 --- a/docs/r3-program-plan.md +++ b/docs/r3-program-plan.md @@ -286,7 +286,7 @@ This principle is NOT a separate lane; it's a per-lane gate-shape requirement ap | 59 | `recursive_flex_demonstration_landed` | demonstration | T-Lens-Self-Application | DECLARED — per `docs/r3-structure.md` §"Acceptance" T-Lens-Self-Application / INVARIANTS P2, the emit-back narrative requires a **`.dag`-authoritative** receipt — **`project_github_actions(ci_workflow_dag, YamlStatic)`** (pinned as `data gunbc_ci_yml_workflow` in `dsl/gunbc/ci_emission.dag`) **or** a **direct-execution** witness — **not** substitutable by a YAML-ingestion drift lock alone. **Supporting ratchet (orthogonal):** `t_ci_workflow_as_data_demo_test::gunbc_ci_github_actions_workflow_dag_matches_yaml_generator_output` keeps committed `dsl/gunbc/ci_github_actions_workflow.dag` **byte-identical to** `gen_gunbc_ci_workflow_dag` output when fed **YAML authority** `.github/workflows/ci.yml` (direction: YAML upstream → generator → derived `.dag` bytes on disk). **Bootstrap / follow-on / deferred:** `bootstrap_authority.dag` lists `t_ci_workflow_as_data_demo.dag`; companion `compile_to_dag` receipts blocked on M1(2.8) for generator-sized `Workflow` literals; `evaluate_body` on `demo_ci_modeled_timing_dimension_report` remains `#[ignore]` (ROADMAP T-WAD). | narrative thesis cashes (pending projection or direct-execution receipt) | | 60 | `substrate_gap_parser_grammar_closed` | substrate-gap-class | T-V2-Retirement + T-Numeric-Construction + Substrate (cross-lane) | DECLARED (NEW 2026-05-06) | concept faithfully modeled (per Q-MachineConstraint sub-decision 5): substrate carries algebra + machine-constraint as independent composing axes with `.dag`-generated interaction substrate; min existence-proof = `Int<64>` / `Real<64>` / `Nat<8>` lower without v2-fallback (evidence, not target) | | 61 | `substrate_gap_function_valued_data_closed` | substrate-gap-class | T-E-P-Producer-Broadening (Phase 1) + E6-G0d (landed #1813) | DECLARED YELLOW (NEW 2026-05-06; reframed RED→YELLOW 2026-05-06 per option (a) RATIFIED) | chain-break dissolved by Q-Class-2-Chain-Break option (a) gap-test re-pick + Q-LBP-R3-Closeability option (b) narrowing; single-prereq-blocked on T-E-P P1 / S10 | -| 62 | `substrate_gap_file_ingestion_closed` | substrate-gap-class | T-Workflow-As-Data | **CONSUMER_LANDED** (`src/v3/std/timing_lens.dag` `FileAttachment` + `gate_62_file_attachment_demo_record`; `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` — ratified shape unchanged per msg_09df44c6 / msg_61e302c6 / PR #2820) | `.dag` program ingests external file w/o include_str!. **Ratified top-level shape**: workflow-substrate `FileAttachment` carrier extending gate #53 (sibling-carrier pattern with WorkflowSecret + CronExpression β-ratified via PR #2160). **Ratified carrier-internals** (Refined-B-1 — strict 5-of-7 subset of #55 `WorkflowObservationAnchor` at `src/v3/std/timing_lens.dag:98-106`): `FileAttachment { subject_node: NodeId, content_digest: ContentHash, producer_id: WorkflowProducerId, workflow_run_id: WorkflowRunId, attached_at_ns: Nanoseconds }`. Drops observer_id + prover_id (timing-observation-specific epistemological roles; not applicable to file attachment). **Q1-Q6 dispositions** (Director verbatim): Q2 encoding ABSENT default (if needed, `Encoding` from `dsl/std/encoding.dag` — NEVER novel `AttachmentEncoding`); Q3 `WorkflowAssetPath` NOT introduced (digest-only canonical); Q4 workflow-coupling deferred to worker brief / consumer evidence (#55 `TimingObservationSet = List` is own carrier, not embedded; analogy: no preemptive `List` on Job/Step); Q5 eager confirmed; Q6 `AttachmentEncoding` Practice-4 🔴 RED — dissolved to existing `dsl/std/encoding.dag` 6-variant `Encoding` BoundedLattice. **Disqualified top-level candidates** (per Director original disposition): (a) compile-time `read_utf8_file` — P5-style intrinsic, doesn't match §4.3 framing, re-introduces `include_str!` semantics under new syntax (PR #2819 STAND DOWN); (c) precedent-mirror — no precedent enumerated, §4.3 already names answer; (d) A+B bundle — creates parallel-authority violating §P1. **Disqualified carrier-shape candidates** (per Director sub-canvas disposition): B-2 path+digest — parallel-representation (two canonical identifiers for same fact); B-3 anchor+entry-pair — over-engineered (no separate payload to split). **Anti-patterns post-ratification** (Director-enumerated 7 total — 3 from top-level + 4 from sub-canvas): (1) compile-time `read_utf8_file`-equivalent additions; (2) FileAttachment landed without #55/#53 sibling-carrier alignment; (3) bridge variants alongside FileAttachment violating §P5 atomic-migration; (4) any `AttachmentEncoding` or equivalent encoding sum-type duplicating `dsl/std/encoding.dag`; (5) path field on FileAttachment (parallel-rep vs canonical digest); (6) `List` on Job/Step preemptively (consumer-evidence-required); (7) carrier-pattern deviation from Refined-B-1 5-field structure (no novel field-name renames; producer_id stays producer_id). **Ratification-time Director grep (PR #2820 snapshot, pre-`FileAttachment` land):** #55 anchor 7 fields at `timing_lens.dag:98-106`; 5 branded nominals (`ContentHash` :324, `WorkflowProducerId` :328, `WorkflowObserverId` :329, `WorkflowProverId` :330, `WorkflowRunId` :331) at `dsl/std/types.dag`; `dsl/std/encoding.dag` exists with `Encoding = ASCII \| UTF8 \| Latin1 \| Text \| Binary \| Unknown` BoundedLattice (compile-time narrowing); at ratification time none of `FileAttachment` / `AttachmentEncoding` / `WorkflowAssetPath` were present under those names (parallel-authority collision avoided). **Current tree (post gate-62 land):** `FileAttachment` is authored in `timing_lens.dag`; `AttachmentEncoding` / `WorkflowAssetPath` remain unauthored per Director Q2/Q3. **Sub-canvas-2 trigger** (follow-on, not blocking this carrier-internals ratification): workflow blob-store substrate — Refined-B-1 requires `content_digest → bytes` resolution; substrate may not exist at HEAD per sub-canvas §3.B-1.Cons; Substrate Mgr authors as separate canvas after Refined-B-1 lands. **PR #2823 land:** carrier (`FileAttachment`) + sibling-alignment / bootstrap ratchet (`file_attachment_substrate_carrier_test.rs`) + existence proof (`gate_62_file_attachment_demo_record`) per worker brief. **`include_str!` audit (ratification snapshot)** (Director-verified `grep -rn "include_str!" dsl/` on PR #2820 canvas): no matches — gate is forward-looking (model the carrier so future file-ingestion sites have first-class workflow-substrate form), not retire-existing-side-channel. | +| 62 | `substrate_gap_file_ingestion_closed` | substrate-gap-class | T-Workflow-As-Data | **CONSUMER_LANDED + PASSING** (carrier + structural ratchet + demo: `src/v3/std/timing_lens.dag` `FileAttachment` + `gate_62_file_attachment_demo_record`; `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` — ratified shape unchanged per msg_09df44c6 / msg_61e302c6 / PR #2820. **§Acceptance receipt** (this gate's `.dag` program-ingests-external-file-w/o-`include_str!` predicate): CI-visible tree-state ratchet `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` `r3_gate_62_no_include_str_in_dsl` asserts zero `include_str!` matches across every `.dag`/`.v3` file under `dsl/` — extends Director's PR #2820 ratification-time grep into a CI-enforced predicate over the file tree's authoritative substrate body, distinct from grep-on-doc-comment textual-enforcement per `feedback_no_textual_enforcement_bridges` (the gate-fact is over substrate files, not over text mentioning the string). Scope-bound per Substrate Mgr msg_210620aa — sub-canvas-2 workflow blob-store / `content_digest → bytes` resolution remains Substrate-Mgr-owned out-of-scope.) | `.dag` program ingests external file w/o include_str!. **Ratified top-level shape**: workflow-substrate `FileAttachment` carrier extending gate #53 (sibling-carrier pattern with WorkflowSecret + CronExpression β-ratified via PR #2160). **Ratified carrier-internals** (Refined-B-1 — strict 5-of-7 subset of #55 `WorkflowObservationAnchor` at `src/v3/std/timing_lens.dag:98-106`): `FileAttachment { subject_node: NodeId, content_digest: ContentHash, producer_id: WorkflowProducerId, workflow_run_id: WorkflowRunId, attached_at_ns: Nanoseconds }`. Drops observer_id + prover_id (timing-observation-specific epistemological roles; not applicable to file attachment). **Q1-Q6 dispositions** (Director verbatim): Q2 encoding ABSENT default (if needed, `Encoding` from `dsl/std/encoding.dag` — NEVER novel `AttachmentEncoding`); Q3 `WorkflowAssetPath` NOT introduced (digest-only canonical); Q4 workflow-coupling deferred to worker brief / consumer evidence (#55 `TimingObservationSet = List` is own carrier, not embedded; analogy: no preemptive `List` on Job/Step); Q5 eager confirmed; Q6 `AttachmentEncoding` Practice-4 🔴 RED — dissolved to existing `dsl/std/encoding.dag` 6-variant `Encoding` BoundedLattice. **Disqualified top-level candidates** (per Director original disposition): (a) compile-time `read_utf8_file` — P5-style intrinsic, doesn't match §4.3 framing, re-introduces `include_str!` semantics under new syntax (PR #2819 STAND DOWN); (c) precedent-mirror — no precedent enumerated, §4.3 already names answer; (d) A+B bundle — creates parallel-authority violating §P1. **Disqualified carrier-shape candidates** (per Director sub-canvas disposition): B-2 path+digest — parallel-representation (two canonical identifiers for same fact); B-3 anchor+entry-pair — over-engineered (no separate payload to split). **Anti-patterns post-ratification** (Director-enumerated 7 total — 3 from top-level + 4 from sub-canvas): (1) compile-time `read_utf8_file`-equivalent additions; (2) FileAttachment landed without #55/#53 sibling-carrier alignment; (3) bridge variants alongside FileAttachment violating §P5 atomic-migration; (4) any `AttachmentEncoding` or equivalent encoding sum-type duplicating `dsl/std/encoding.dag`; (5) path field on FileAttachment (parallel-rep vs canonical digest); (6) `List` on Job/Step preemptively (consumer-evidence-required); (7) carrier-pattern deviation from Refined-B-1 5-field structure (no novel field-name renames; producer_id stays producer_id). **Ratification-time Director grep (PR #2820 snapshot, pre-`FileAttachment` land):** #55 anchor 7 fields at `timing_lens.dag:98-106`; 5 branded nominals (`ContentHash` :324, `WorkflowProducerId` :328, `WorkflowObserverId` :329, `WorkflowProverId` :330, `WorkflowRunId` :331) at `dsl/std/types.dag`; `dsl/std/encoding.dag` exists with `Encoding = ASCII \| UTF8 \| Latin1 \| Text \| Binary \| Unknown` BoundedLattice (compile-time narrowing); at ratification time none of `FileAttachment` / `AttachmentEncoding` / `WorkflowAssetPath` were present under those names (parallel-authority collision avoided). **Current tree (post gate-62 land):** `FileAttachment` is authored in `timing_lens.dag`; `AttachmentEncoding` / `WorkflowAssetPath` remain unauthored per Director Q2/Q3. **Sub-canvas-2 trigger** (follow-on, not blocking this carrier-internals ratification): workflow blob-store substrate — Refined-B-1 requires `content_digest → bytes` resolution; substrate may not exist at HEAD per sub-canvas §3.B-1.Cons; Substrate Mgr authors as separate canvas after Refined-B-1 lands. **PR #2823 land:** carrier (`FileAttachment`) + sibling-alignment / bootstrap ratchet (`file_attachment_substrate_carrier_test.rs`) + existence proof (`gate_62_file_attachment_demo_record`) per worker brief. **`include_str!` audit (ratification snapshot)** (Director-verified `grep -rn "include_str!" dsl/` on PR #2820 canvas): no matches — gate is forward-looking (model the carrier so future file-ingestion sites have first-class workflow-substrate form), not retire-existing-side-channel. | | 63 | `substrate_gap_workflow_scheduling_closed` | substrate-gap-class | T-Workflow-As-Data + T-Lens-Self-Application | **CANVAS_RATIFIED** (2026-05-13 per PR **#2831** squash `89df284e3` — Substrate Mgr canvas `docs/briefs/r3-substrate-gate-63-workflow-scheduling-canvas.md` + worker `docs/briefs/r3-substrate-gate-63-workflow-scheduling-worker.md`; Director **msg_804cdc93** ratifies **Q1=Candidate A** administrative closure path — gate-criterion test `ci_workflow_as_data_demo_timing_dimension_report_evaluates_via_evaluator` passes in isolation per snappy-bear-502 **msg_cef1340b**; **Q2 OR-semantics**; **Q3** planned-deferral anchor `73969f4a9`; **Q4** substrate-lane-owned; snappy-bear-502 audit **msg_140d9bc7**; sibling `--include-ignored` failures Director-allocated to §1.8 rows **#99/#100** per msg_804cdc93 — **not** gate #63 closure scope) | CI workflow as `.dag` data executes through evaluator + `DimensionReport`; §4.4 substrate-prereq mapping table in canvas §2. **CONSUMER_LANDED + PASSING** requires worker Phases A–C (un-ignore + §1.4 (a)+(b) receipts + §4.4 footnote reconciliation + ledger flip), not claimed at ratification. | | 64 | `substrate_gap_reflection_closure_closed` | substrate-gap-class | T-LensProducer-Retirement | **DECLARED** (substrate-plumbing receipt via PR #2694 — `src/v3/compiler/tests/fixtures/r3_substrate_gap_reflection_closure.dag` adds non-canonical claim `substrate_gap_reflection_residual_census_receipt` over the live `CensusSubsetCount` lens-producer residual predicate; `r3_substrate_gap_reflection_closure_test.rs` proves the state-check receipt executes and reports residual count 3 while residuals remain. This is **NOT** the canonical reflection-closure consumer.) | `lens_apply.rs` reflection via PB-Runtime; canonical Pass-condition per `r3-structure.md:181`: `lens_apply.rs` reflection routes via PB-Runtime interpreter-as-data and reflection-as-data substrate is exercised end-to-end. Status re-promotes only when PB-Runtime + T-LensProducer-Retirement land that consumer; census state-check is one half of the conjunctive class closure and remains a placeholder per PR #2657 / `feedback_grep_consumer_surfaces_for_lane_completeness`. P5 deferral receipts: non-test residual tracked under `ROADMAP.md` §"Lane acceptance — .dag gates" / T-PB-A row `lens_producer_files_remaining` (anchor `#lane-acceptance--dag-gates`), whose dissolution target is the priority lens-producer non-test census reaching zero; new host test harness tracked under `ROADMAP.md` §"Lane acceptance — .dag gates" / T-PB-B row `pb_rust_tests_outside_residual_zero` plus `EXPECTED_HAND_AUTHORED_TEST` in `sg0_census_test.rs`, dissolving when the generic TestClaim runner can execute the receipt without this harness. | | 65 | `tier3_dissolution_demonstration_executes` | demonstration | T-Tier3-Dissolution | PASSING | `src/v3/compiler/tests/dag/t_r3_tier3_dissolution_demonstration.dag` runs through `t_pb_b_1_dag_runner_test::r3_tier3_dissolution_demonstration_suite_passes_through_runner` | diff --git a/src/v3/compiler/tests/integration.rs b/src/v3/compiler/tests/integration.rs index 69c5ad7e6d5..ca5bf391d94 100644 --- a/src/v3/compiler/tests/integration.rs +++ b/src/v3/compiler/tests/integration.rs @@ -185,6 +185,8 @@ mod r3_free_consequences_first_batch_test; mod r3_free_consequences_second_batch_test; #[path = "integration/r3_gate_60_phase2_width_nat_parser_test.rs"] mod r3_gate_60_phase2_width_nat_parser_test; +#[path = "integration/r3_gate_62_file_ingestion_passing_test.rs"] +mod r3_gate_62_file_ingestion_passing_test; #[path = "integration/r3_gate_87_lens_cementing_regen_receipts_test.rs"] mod r3_gate_87_lens_cementing_regen_receipts_test; #[path = "integration/r3_lens_producer_retirement_executable_witness_test.rs"] diff --git a/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs new file mode 100644 index 00000000000..66bdd573e79 --- /dev/null +++ b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs @@ -0,0 +1,91 @@ +//! **Layer:** integration +//! +//! R3 §1.8 gate **#62** `substrate_gap_file_ingestion_closed` — PASSING +//! receipt. CONSUMER_LANDED already supplied via the `FileAttachment` +//! carrier landing in `src/v3/std/timing_lens.dag` plus the structural +//! ratchet in `file_attachment_substrate_carrier_test.rs` and the +//! `gate_62_file_attachment_demo_record` existence proof (PR #2823). +//! +//! §Acceptance per `docs/r3-program-plan.md` §1.8 row #62: ".dag program +//! ingests external file w/o `include_str!`". The gate is forward-looking +//! (Director-verified at ratification time on PR #2820 canvas — no +//! `include_str!` matches under `dsl/`). This test promotes that +//! one-time grep into a CI-visible ratchet on tree state, distinct from +//! grep-on-doc-comment textual-enforcement (`feedback_no_textual_enforcement_bridges`): +//! the predicate is over the file tree's authoritative substrate body, +//! not over comments or briefs that mention the string. +//! +//! STOP-AND-PING trigger (per parent Mgr brief msg_210620aa): ANY match +//! at HEAD is a substrate-gap regression, not a paper-over — investigate +//! and route through the workflow-substrate carrier (`FileAttachment`) +//! before re-greening this test. + +use std::collections::BTreeSet; +use std::ffi::OsStr; +use std::fs; +use std::path::{Path, PathBuf}; + +const DSL_ROOT: &str = "dsl"; +const NEEDLE: &str = "include_str!"; + +fn workspace_root() -> PathBuf { + let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + manifest_dir + .ancestors() + .nth(3) + .expect("workspace root is three ancestors above src/v3/compiler/") + .to_path_buf() +} + +fn walk_dag_files(root: &Path, out: &mut BTreeSet) { + let entries = fs::read_dir(root).unwrap_or_else(|e| panic!("read_dir {}: {e}", root.display())); + for entry in entries { + let entry = entry.expect("read_dir entry"); + let path = entry.path(); + if path.is_dir() { + walk_dag_files(&path, out); + } else if path.extension() == Some(OsStr::new("dag")) + || path.extension() == Some(OsStr::new("v3")) + { + out.insert(path); + } + } +} + +#[test] +fn r3_gate_62_no_include_str_in_dsl() { + let ws = workspace_root(); + let dsl_root = ws.join(DSL_ROOT); + assert!( + dsl_root.is_dir(), + "expected workspace `{DSL_ROOT}/` directory at {}", + dsl_root.display() + ); + + let mut files = BTreeSet::new(); + walk_dag_files(&dsl_root, &mut files); + assert!( + !files.is_empty(), + "expected at least one `.dag`/`.v3` file under `{DSL_ROOT}/`" + ); + + let mut hits: Vec = Vec::new(); + for path in &files { + let body = + fs::read_to_string(path).unwrap_or_else(|e| panic!("read {}: {e}", path.display())); + if body.contains(NEEDLE) { + let rel = path.strip_prefix(&ws).unwrap_or(path).display().to_string(); + hits.push(rel); + } + } + + assert!( + hits.is_empty(), + "R3 gate #62 (`substrate_gap_file_ingestion_closed`) requires zero \ + `include_str!` occurrences under `{DSL_ROOT}/`. Workflow-substrate \ + file ingestion belongs on the ratified `FileAttachment` carrier \ + (`src/v3/std/timing_lens.dag`; Refined-B-1 per PR #2820 canvas / \ + PR #2823 land). Offending files:\n {}", + hits.join("\n ") + ); +} From c81b6cb732029dcfcd8ac85b273eba015dfc9738 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 14 May 2026 17:19:27 +0000 Subject: [PATCH 2/7] =?UTF-8?q?SG-0=20census=20+=20INVARIANTS=20=C2=A7P5?= =?UTF-8?q?=20receipt=20for=20r3=5Fgate=5F62=20file-ingestion=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses cursor/composer-2 REQUEST_CHANGES on PR #3111: the new `r3_gate_62_file_ingestion_passing_test.rs` is a hand-authored integration test, so the SG-0 census enforces it must be listed in `EXPECTED_HAND_AUTHORED_TEST` and carry an INVARIANTS §P5 Mechanism (b) receipt row in the same PR (per `sg0_v3_hand_authored_census`). - `src/v3/compiler/tests/integration/sg0_census_test.rs`: add the path to `EXPECTED_HAND_AUTHORED_TEST` with dissolution trigger (`.dag` `TestClaim` / PB-B-1 runner receipt that asserts workspace file-tree predicates without a host-side filesystem walker). - `INVARIANTS.md`: matching SG-0 hand-authored compiler test receipt row citing R3 program plan §1.8 gate #62, the carrier pairing with `file_attachment_substrate_carrier_test.rs`, and the `feedback_no_textual_enforcement_bridges` distinction (predicate over substrate file bodies, not over doc-comment text). Receipts: - `cargo test -p v3-compiler --test integration sg0_v3_hand_authored_census` — passes Co-Authored-By: Claude Opus 4.7 (1M context) --- INVARIANTS.md | 1 + src/v3/compiler/tests/integration/sg0_census_test.rs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/INVARIANTS.md b/INVARIANTS.md index 6bf9e09065c..15298105d89 100644 --- a/INVARIANTS.md +++ b/INVARIANTS.md @@ -341,6 +341,7 @@ Per **Dispatch-Discipline Mechanisms (b)** above, each **new** path added to `EX | `src/v3/compiler/tests/integration/ctrl_pr_digests_dag_smoke_test.rs` | **Project plan:** `docs/r4-ctrl-dag-migration-project-plan.md` §3 — catalog **#8** `dsl/ctrl/pr_digests.dag` (Wave-1 ctrl → `.dag` subsystem modeling). **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + the matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs` land in the same PR as the smoke test. **Dissolution:** remove when `compile_to_dag` (or a single generated harness) validates `module … service …` ctrl carrier files end-to-end without a parallel Rust string/lexer ratchet, or when the contract migrates to `.dag` `TestClaim` coverage. **Interim ratchet:** `ctrl_pr_digests_dag_tokenizes_and_matches_expected_surface` requires clean tokenization plus presence of `module ctrl.pr_digests`, `import extdeps.github.pulls { PullRequest, PullReview, ReviewComment }`, `std.errors` / `std.types` imports, the four Practice-4 sum/record carriers (with `🟡 STAGED` / `🟢 TERMINAL` markers per `dsl/ctrl/README.md`), `ReviewCommentBody` + `review_line_comments` wiring, and `service ctrl.PrDigests` / the four `operation` blocks / `readonly`. | | `src/v3/compiler/tests/integration/extdeps_sql_transport_test.rs` | **ROADMAP:** `ROADMAP.md` § **Nine lanes** row `T-PB-B` / `pb_rust_tests_outside_residual_zero`; this Rust integration receipt keeps HTTP/SQL/audit extdeps compiled by the existing v3 parser before downstream emission-target consumers rely on them. **Dissolution:** remove when extdeps transport and Phase 3 emission-target files are covered by a `.dag`-native parse/authority suite or generated test harness rather than per-file Rust `compile_to_dag` probes. **Interim ratchet:** `rest_transport_dag_compiles_cleanly` and `sql_transport_dag_compiles_cleanly` pin `dsl/extdeps/transports/rest.dag` and `dsl/extdeps/transports/sql.dag`; `http_server_extdep_dag_compiles_cleanly`, `sql_migration_extdep_dag_compiles_cleanly`, and `audit_event_extdep_dag_compiles_cleanly` pin `dsl/extdeps/http/server.dag`, `dsl/extdeps/sql/migration.dag`, and `dsl/extdeps/audit/event.dag` as parseable staged emission-target substrate. The field-sensitive companions (`http_server_target_fields_are_authoritative_substrate_edges`, `sql_migration_target_fields_bound_raw_sql_scaffold`, `audit_event_target_fields_preserve_cloudevents_core_names`) consume the new target-contract fields directly so they fail on raw `String`/`Int` regressions, missing SQL scaffold bounds, or CloudEvents alias drift while the first real projection consumer is still staged; the audit ratchet also locks CloudEvents core fields to branded carriers and `std.types.Timestamp` rather than raw strings. | | `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#62** `substrate_gap_file_ingestion_closed` (T-Workflow-As-Data substrate-gap class; worker brief `docs/briefs/r3-substrate-gate-62-file-attachment-carrier-worker.md`). **Dissolution:** remove when a `.dag` `TestClaim` / PB-B-1 runner receipt can assert `FileAttachment` field names + cross-module nominal wiring against `generated_full_bootstrap_dag()` without this hand-Rust structural ratchet (same dissolution posture as `timing_lens_substrate_carrier_test.rs` for gate #55). **Interim ratchet:** `file_attachment_shape_locked` + `file_attachment_field_types_locked` + `file_attachment_field_count_is_five` pin the ratified Refined-B-1 five-field subset of `WorkflowObservationAnchor` (`NodeId`, `ContentHash`, `WorkflowProducerId`, `WorkflowRunId`, `Nanoseconds`) exactly as declared in `src/v3/std/timing_lens.dag`; existence proof carrier construction stays in-module as `gate_62_file_attachment_demo_record`. | +| `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#62** `substrate_gap_file_ingestion_closed` §Acceptance receipt (T-Workflow-As-Data substrate-gap class). Extends Director's PR #2820 ratification-time `grep -rn 'include_str!' dsl/` into a CI-visible tree-state ratchet over the substrate file tree; distinct from grep-on-doc-comment textual-enforcement per `feedback_no_textual_enforcement_bridges` (predicate is over `.dag`/`.v3` file bodies under `dsl/`, not over text mentioning the string). Pairs with the carrier ratchet `file_attachment_substrate_carrier_test.rs` above (PR #2823 — Refined-B-1 `FileAttachment` shape). **Dissolution:** remove when a `.dag` `TestClaim` / PB-B-1 runner receipt can assert workspace file-tree predicates fail-closed without a host-side filesystem walker. **Interim ratchet:** `r3_gate_62_no_include_str_in_dsl` walks every `.dag`/`.v3` file under `dsl/` and fails with the offending paths if any reintroduce `include_str!` (workflow-substrate file ingestion belongs on the ratified `FileAttachment` carrier). | | `src/v3/compiler/tests/integration/m2_substrate_inhabitance_test.rs` | **ROADMAP:** `ROADMAP.md` — **Tier-3 perf-budget Phase-1 hand-Rust mirror benches** / T-Tier3-Dissolution paired-dispatch (`docs/briefs/r3-pb-t-tier3-consumer-slice-worker.md`). **Plan:** `docs/r3-program-plan.md` §1.8 gate **#2** `tier3_computation_mirror_dissolved` (state-check; **CONSUMER_LANDED** = §1.7 executable-consumer sense, not INVARIANTS §P2 generated-consumer — see plan §1.7 “State-check …” paragraph). **Dissolution:** retire remaining Tier3 host mirrors per `docs/r3-structure.md` §Acceptance as Evaluator-backed std bodies land. **Interim ratchet (P5 Mechanism (b)):** `tier3_computation_mirror_trivial_constructors_dissolved` (PR #2789 narrow slice) + `tier3_computation_mirror_kernel_algebra_profile_substrate_authority` with brace-bounded `dag.rs` scan asserting `type_iteration_dimension` delegates through `BOOTSTRAPPED_DAG.kernel_algebra_profile` (forbid parallel hand-maintained type→profile tables); sibling Tier3 rows in this file carry the same lane receipts. | | `src/v3/compiler/tests/integration/r3_gate_60_phase2_width_nat_parser_test.rs` | **ROADMAP:** `ROADMAP.md` — **`substrate_gap_parser_grammar_closed`** / R3 gate **#60** (Phase 2.1 parser slice: angle-only width nat in `<…>`, `TypeAngleArg` substrate split, `Compose>` lowering with literal phantom width). **Dissolution:** remove when gate #60 parse/lower/routing receipts are carried by `.dag` `TestClaim` / generated harness without this hand-authored `compile_to_dag` + `parse_for_test` module (per `docs/audit/r3-gate-60-decomposition.md` follow-on slices). **Interim ratchet:** `gate_60_phase2_parse_accepts_algebra_angle_width_nat`, `gate_60_phase2_int_64_lowers_to_compose_int_machine_width_literal`, `gate_60_phase2_nat_8_lowers_via_uint_slot`, `gate_60_integer_routing_witness_accepts_literal_nat_machine_width`, `gate_60_bare_numeric_type_is_parse_rejected`, `gate_60_int_disallowed_width_fails_closed_without_malformed_template_args`. | | `src/v3/compiler/tests/integration/t_gate_58_apply_lens_self_application_test.rs` | **ROADMAP:** `ROADMAP.md` → `### Nine lanes` → **T-PB-B** / `pb_rust_tests_outside_residual_zero`. **Plan:** `docs/r3-program-plan.md` §1.8 gate **#58** `apply_lens_self_application_demonstrated` — lane **T-Lens-Self-Application** (`EnforcedApplication` bootstrap receipt over `gate_58_apply_lens_self_application_pass` + typed witness `gate_58_modeled_ci_timing_measurement` (`gate_58_ci_workflow_timing_row` with `workflow: modeled_gunbc_ci_workflow`) in `src/v3/std/t_ci_workflow_as_data_demo.dag`). **Dissolution:** remove when a `.dag` `TestClaim` / runner receipt asserts the same `generated_full_bootstrap_dag()` facts (empty bootstrap diagnostics + witness declarations) without this Rust harness. **Interim ratchet:** `apply_lens_self_application_demonstrated_bootstrap_receipt` + `gate_58_modeled_ci_timing_measurement` presence checks. **Co-receipt (same PR, P5 single surface):** expanded `src/v3/compiler/src/enforced_lens_application.rs` timing consumer + `src/v3/compiler/build.rs` default-rank std `STAGED_FILES` ordering from parsed `import v3.std.*` edges (Kahn topo among co-ranked files; single authority with module imports) are documented in `scripts/ci-merge/sg0-pr-body-append.2827.txt` (prepended to the PR body in CI) with explicit ROADMAP rows + dissolution triggers per INVARIANTS §P5 Mechanism **(b)**. | diff --git a/src/v3/compiler/tests/integration/sg0_census_test.rs b/src/v3/compiler/tests/integration/sg0_census_test.rs index 0f73d914170..61bb001d781 100644 --- a/src/v3/compiler/tests/integration/sg0_census_test.rs +++ b/src/v3/compiler/tests/integration/sg0_census_test.rs @@ -642,6 +642,16 @@ const EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[ // R3 gate #60 Phase 2.1 (`substrate_gap_parser_grammar_closed` parser slice): hermetic // parse + lower receipts for angle-bracket width nat (`Int<64>`) surface; SG-0 P5 receipt. "src/v3/compiler/tests/integration/r3_gate_60_phase2_width_nat_parser_test.rs", + // R3 gate #62 `substrate_gap_file_ingestion_closed` §Acceptance receipt: tree-state + // ratchet asserting zero `include_str!` matches under `dsl/`. Pairs with the carrier + // ratchet `file_attachment_substrate_carrier_test.rs` + `gate_62_file_attachment_demo_record` + // (PR #2823) and the `FileAttachment` Refined-B-1 carrier in + // `src/v3/std/timing_lens.dag`. Hand-Rust because the predicate is over the + // workspace `.dag`/`.v3` file tree (filesystem walk + read), distinct from + // grep-on-doc-comment textual-enforcement per `feedback_no_textual_enforcement_bridges`. + // Dissolves when a `.dag` `TestClaim` / PB-B-1 runner can assert + // file-tree predicates fail-closed without a host-side filesystem walker. + "src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs", // R3 gate #87 (`lens_cementing_test_discipline_complete` / issue #2609): Rust receipts // paired with `tests/dag/t_r3_gate_87_cementing_regen_*.dag` + `t_pb_b_1_dag_runner_test` // until strict modules can freeze full `LensOutputEquals` carriers (M1(2.8)). From 09e8cb86a65ca22e253e544cd3805c5554e7f8b2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 14 May 2026 17:28:32 +0000 Subject: [PATCH 3/7] ci: retrigger after SG-0 pairing body update From f14475e67a05e62d375392d24ae71c458b966ade Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 14 May 2026 18:25:50 +0000 Subject: [PATCH 4/7] gate #62 ratchet: strip comments + string literals before substring check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses codex/codex-default REQUEST_CHANGES on PR #3111 (review #11981): the prior `body.contains("include_str!")` over raw file bytes would trip on a comment, doc block, or string literal mentioning the bridge name — collapsing the receipt into raw text policing rather than the program-body predicate the gate's §Acceptance text states. Fix: introduce `strip_comments_and_string_literals` (single-pass scan, handles `//` line comments, `/* … */` block comments, `"…"` / `` `…` `` string literals with `\` escape handling) and run the substring check over the stripped output. The gate-fact is now "no `.dag` program body invokes `include_str!`", not "no `.dag` file's bytes contain the substring". Four unit tests pin the stripping behaviour: line/block-comment mentions, string-literal mention, and an actual invocation surviving the strip. Existing gate-#62 ratchet over `dsl/` stays green. Receipts: - `cargo test -p v3-compiler --test integration r3_gate_62` — 5/5 pass Co-Authored-By: Claude Opus 4.7 (1M context) --- .../r3_gate_62_file_ingestion_passing_test.rs | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs index 66bdd573e79..6870119e7f9 100644 --- a/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs +++ b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs @@ -15,6 +15,14 @@ //! the predicate is over the file tree's authoritative substrate body, //! not over comments or briefs that mention the string. //! +//! Per codex REQUEST_CHANGES on PR #3111 (2026-05-14 review #11981): the +//! check operates over **program body** text, not raw bytes — line +//! comments (`// …`), block comments (`/* … */`), and string literals +//! (`"…"` / `` `…` ``) are stripped before the substring search so a +//! comment or doc-block discussing the bridge name does not trip the +//! ratchet. The gate-fact is "no `.dag` program body invokes +//! `include_str!`", not "no `.dag` file's bytes contain the substring". +//! //! STOP-AND-PING trigger (per parent Mgr brief msg_210620aa): ANY match //! at HEAD is a substrate-gap regression, not a paper-over — investigate //! and route through the workflow-substrate carrier (`FileAttachment`) @@ -73,7 +81,8 @@ fn r3_gate_62_no_include_str_in_dsl() { for path in &files { let body = fs::read_to_string(path).unwrap_or_else(|e| panic!("read {}: {e}", path.display())); - if body.contains(NEEDLE) { + let program_body = strip_comments_and_string_literals(&body); + if program_body.contains(NEEDLE) { let rel = path.strip_prefix(&ws).unwrap_or(path).display().to_string(); hits.push(rel); } @@ -89,3 +98,80 @@ fn r3_gate_62_no_include_str_in_dsl() { hits.join("\n ") ); } + +/// Strip `//` line comments, `/* … */` block comments, and `"…"` / `` `…` `` +/// string literals from `src` so the gate-#62 substring check operates over +/// program-body tokens rather than raw bytes. Conservative single-pass scan +/// with `\` escape handling inside string literals; unterminated literals or +/// block comments are dropped to end-of-input fail-closed (any surviving +/// `include_str!` outside a literal still trips the ratchet). +fn strip_comments_and_string_literals(src: &str) -> String { + let bytes = src.as_bytes(); + let mut out = String::with_capacity(src.len()); + let mut i = 0; + while i < bytes.len() { + let b = bytes[i]; + // `//` line comment: drop through end-of-line, keep the newline. + if b == b'/' && i + 1 < bytes.len() && bytes[i + 1] == b'/' { + while i < bytes.len() && bytes[i] != b'\n' { + i += 1; + } + continue; + } + // `/* … */` block comment: drop through closing `*/`. + if b == b'/' && i + 1 < bytes.len() && bytes[i + 1] == b'*' { + i += 2; + while i + 1 < bytes.len() && !(bytes[i] == b'*' && bytes[i + 1] == b'/') { + i += 1; + } + i = (i + 2).min(bytes.len()); + continue; + } + // `"…"` or `` `…` `` string literal: drop through matching unescaped quote. + if b == b'"' || b == b'`' { + let quote = b; + i += 1; + while i < bytes.len() && bytes[i] != quote { + if bytes[i] == b'\\' && i + 1 < bytes.len() { + i += 2; + } else { + i += 1; + } + } + i = (i + 1).min(bytes.len()); + continue; + } + out.push(b as char); + i += 1; + } + out +} + +#[cfg(test)] +mod strip_tests { + use super::{strip_comments_and_string_literals, NEEDLE}; + + #[test] + fn line_comment_mentioning_needle_is_stripped() { + let src = "// retired: include_str! side-channel\nfn ok() = 0\n"; + assert!(!strip_comments_and_string_literals(src).contains(NEEDLE)); + } + + #[test] + fn block_comment_mentioning_needle_is_stripped() { + let src = "/* note: include_str! once lived here */\nfn ok() = 0\n"; + assert!(!strip_comments_and_string_literals(src).contains(NEEDLE)); + } + + #[test] + fn string_literal_mentioning_needle_is_stripped() { + let src = "fn label() = \"name: include_str!\"\n"; + assert!(!strip_comments_and_string_literals(src).contains(NEEDLE)); + } + + #[test] + fn body_invocation_survives_stripping() { + let src = "fn bad() = include_str!(\"path\")\n"; + assert!(strip_comments_and_string_literals(src).contains(NEEDLE)); + } +} From ee8d99e3d5835890869e810f6a18a47133275640 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 14 May 2026 19:22:34 +0000 Subject: [PATCH 5/7] =?UTF-8?q?gate=20#62:=20revert=20PASSING=20claim=20?= =?UTF-8?q?=E2=80=94=20keep=20CONSUMER=5FLANDED=20+=20negative-bridge=20au?= =?UTF-8?q?dit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses operator BLOCKING on PR #3111 (2026-05-14T19:13:37Z, inline on docs/r3-program-plan.md:290): marking #62 `CONSUMER_LANDED + PASSING` from a zero-`include_str!` tree ratchet weakens §1.4/§4.3, which require a positive `.dag` program ingesting an external file via `FileAttachment`, not just absence of the old bridge (THESIS/P1 modeling faithfulness). Also addresses codex BLOCKING review on `7f92455d`: - (1) Negative bridge-audit promoted to gap-test closure — fixed by reverting PASSING flip. - (2) INVARIANTS row paired only with R3 plan-row receipt — fixed by adding explicit T-PB-B / `pb_rust_tests_outside_residual_zero` deferral lane citation. Changes: - `docs/r3-program-plan.md` §1.8 row #62: `CONSUMER_LANDED + PASSING` → `CONSUMER_LANDED`. New test reclassified as supporting evidence (negative-bridge audit), not §Acceptance receipt. PASSING flip awaits a positive ingestion-via-`FileAttachment` `.dag` `TestClaim` / runner receipt. - `INVARIANTS.md` SG-0 hand-authored test row: reframed as supporting evidence (not §Acceptance receipt); added T-PB-B deferral lane citation; dissolution broadened to (a) `.dag` `TestClaim` carries the audit OR (b) PASSING flip via positive demonstration. - `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` header: drop PASSING-receipt framing; document operator BLOCKING and the audit's supporting-evidence-only role. - `src/v3/compiler/tests/integration/sg0_census_test.rs` census comment: mirror the supporting-evidence framing + T-PB-B deferral lane. Test behaviour unchanged; the audit still ratchets zero `include_str!` matches across `.dag`/`.v3` program bodies under `dsl/` (comments + string literals stripped). What changed is the *claim* the audit supports — no longer §Acceptance closure. Receipts: - `cargo test -p v3-compiler --test integration r3_gate_62` — 5/5 - `cargo test -p v3-compiler --test integration sg0_v3_hand_authored_census` — pass Co-Authored-By: Claude Opus 4.7 (1M context) --- INVARIANTS.md | 2 +- docs/r3-program-plan.md | 2 +- .../r3_gate_62_file_ingestion_passing_test.rs | 21 ++++++++++--------- .../tests/integration/sg0_census_test.rs | 21 ++++++++++++------- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/INVARIANTS.md b/INVARIANTS.md index 7e5577a7461..d1ab29d2f08 100644 --- a/INVARIANTS.md +++ b/INVARIANTS.md @@ -342,7 +342,7 @@ Per **Dispatch-Discipline Mechanisms (b)** above, each **new** path added to `EX | `src/v3/compiler/tests/integration/ctrl_pr_digests_dag_smoke_test.rs` | **Project plan:** `docs/r4-ctrl-dag-migration-project-plan.md` §3 — catalog **#8** `dsl/ctrl/pr_digests.dag` (Wave-1 ctrl → `.dag` subsystem modeling). **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + the matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs` land in the same PR as the smoke test. **Dissolution:** remove when `compile_to_dag` (or a single generated harness) validates `module … service …` ctrl carrier files end-to-end without a parallel Rust string/lexer ratchet, or when the contract migrates to `.dag` `TestClaim` coverage. **Interim ratchet:** `ctrl_pr_digests_dag_tokenizes_and_matches_expected_surface` requires clean tokenization plus presence of `module ctrl.pr_digests`, `import extdeps.github.pulls { PullRequest, PullReview, ReviewComment }`, `std.errors` / `std.types` imports, the four Practice-4 sum/record carriers (with `🟡 STAGED` / `🟢 TERMINAL` markers per `dsl/ctrl/README.md`), `ReviewCommentBody` + `review_line_comments` wiring, and `service ctrl.PrDigests` / the four `operation` blocks / `readonly`. | | `src/v3/compiler/tests/integration/extdeps_sql_transport_test.rs` | **ROADMAP:** `ROADMAP.md` § **Nine lanes** row `T-PB-B` / `pb_rust_tests_outside_residual_zero`; this Rust integration receipt keeps HTTP/SQL/audit extdeps compiled by the existing v3 parser before downstream emission-target consumers rely on them. **Dissolution:** remove when extdeps transport and Phase 3 emission-target files are covered by a `.dag`-native parse/authority suite or generated test harness rather than per-file Rust `compile_to_dag` probes. **Interim ratchet:** `rest_transport_dag_compiles_cleanly` and `sql_transport_dag_compiles_cleanly` pin `dsl/extdeps/transports/rest.dag` and `dsl/extdeps/transports/sql.dag`; `http_server_extdep_dag_compiles_cleanly`, `sql_migration_extdep_dag_compiles_cleanly`, and `audit_event_extdep_dag_compiles_cleanly` pin `dsl/extdeps/http/server.dag`, `dsl/extdeps/sql/migration.dag`, and `dsl/extdeps/audit/event.dag` as parseable staged emission-target substrate. The field-sensitive companions (`http_server_target_fields_are_authoritative_substrate_edges`, `sql_migration_target_fields_bound_raw_sql_scaffold`, `audit_event_target_fields_preserve_cloudevents_core_names`) consume the new target-contract fields directly so they fail on raw `String`/`Int` regressions, missing SQL scaffold bounds, or CloudEvents alias drift while the first real projection consumer is still staged; the audit ratchet also locks CloudEvents core fields to branded carriers and `std.types.Timestamp` rather than raw strings. | | `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#62** `substrate_gap_file_ingestion_closed` (T-Workflow-As-Data substrate-gap class; worker brief `docs/briefs/r3-substrate-gate-62-file-attachment-carrier-worker.md`). **Dissolution:** remove when a `.dag` `TestClaim` / PB-B-1 runner receipt can assert `FileAttachment` field names + cross-module nominal wiring against `generated_full_bootstrap_dag()` without this hand-Rust structural ratchet (same dissolution posture as `timing_lens_substrate_carrier_test.rs` for gate #55). **Interim ratchet:** `file_attachment_shape_locked` + `file_attachment_field_types_locked` + `file_attachment_field_count_is_five` pin the ratified Refined-B-1 five-field subset of `WorkflowObservationAnchor` (`NodeId`, `ContentHash`, `WorkflowProducerId`, `WorkflowRunId`, `Nanoseconds`) exactly as declared in `src/v3/std/timing_lens.dag`; existence proof carrier construction stays in-module as `gate_62_file_attachment_demo_record`. | -| `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#62** `substrate_gap_file_ingestion_closed` §Acceptance receipt (T-Workflow-As-Data substrate-gap class). Extends Director's PR #2820 ratification-time `grep -rn 'include_str!' dsl/` into a CI-visible tree-state ratchet over the substrate file tree; distinct from grep-on-doc-comment textual-enforcement per `feedback_no_textual_enforcement_bridges` (predicate is over `.dag`/`.v3` file bodies under `dsl/`, not over text mentioning the string). Pairs with the carrier ratchet `file_attachment_substrate_carrier_test.rs` above (PR #2823 — Refined-B-1 `FileAttachment` shape). **Dissolution:** remove when a `.dag` `TestClaim` / PB-B-1 runner receipt can assert workspace file-tree predicates fail-closed without a host-side filesystem walker. **Interim ratchet:** `r3_gate_62_no_include_str_in_dsl` walks every `.dag`/`.v3` file under `dsl/` and fails with the offending paths if any reintroduce `include_str!` (workflow-substrate file ingestion belongs on the ratified `FileAttachment` carrier). | +| `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#62** `substrate_gap_file_ingestion_closed` supporting evidence (T-Workflow-As-Data substrate-gap class). **NOT a §Acceptance receipt**: §1.4/§4.3 require a positive `.dag` ingestion-via-`FileAttachment` demonstration, not absence-of-bridge evidence (operator BLOCKING 2026-05-14T19:13:37Z, THESIS/P1 modeling faithfulness). This row is a CI-visible negative-bridge audit only — it ratchets that no `.dag`/`.v3` program body under `dsl/` re-introduces `include_str!` while the workflow-substrate file-ingestion path is built out; program bodies are scanned with `//` line comments, `/* … */` block comments, and `"…"` / `` `…` `` string literals stripped so a doc-comment or label mentioning the bridge name does not trip the audit (`feedback_no_textual_enforcement_bridges`). **ROADMAP:** `ROADMAP.md` → `### Nine lanes` → **T-PB-B** / `pb_rust_tests_outside_residual_zero` — hand-Rust integration test held under the T-PB-B deferral lane until a `.dag` `TestClaim` / PB-B-1 runner can carry the predicate. **Dissolution:** remove when (a) a `.dag` `TestClaim` / PB-B-1 runner receipt asserts the same file-tree audit fail-closed without a host-side filesystem walker, OR (b) the gate flips PASSING via a positive ingestion-via-`FileAttachment` `.dag` program and the carrier-reachability ratchets alone carry the audit. **Interim ratchet:** `r3_gate_62_no_include_str_in_dsl` walks every `.dag`/`.v3` file under `dsl/` and fails with the offending paths if any reintroduce `include_str!` in a program body. | | `src/v3/compiler/tests/integration/m2_substrate_inhabitance_test.rs` | **ROADMAP:** `ROADMAP.md` — **Tier-3 perf-budget Phase-1 hand-Rust mirror benches** / T-Tier3-Dissolution paired-dispatch (`docs/briefs/r3-pb-t-tier3-consumer-slice-worker.md`). **Plan:** `docs/r3-program-plan.md` §1.8 gate **#2** `tier3_computation_mirror_dissolved` (state-check; **CONSUMER_LANDED** = §1.7 executable-consumer sense, not INVARIANTS §P2 generated-consumer — see plan §1.7 “State-check …” paragraph). **Dissolution:** retire remaining Tier3 host mirrors per `docs/r3-structure.md` §Acceptance as Evaluator-backed std bodies land. **Interim ratchet (P5 Mechanism (b)):** `tier3_computation_mirror_trivial_constructors_dissolved` (PR #2789 narrow slice) + `tier3_computation_mirror_kernel_algebra_profile_substrate_authority` with brace-bounded `dag.rs` scan asserting `type_iteration_dimension` delegates through `BOOTSTRAPPED_DAG.kernel_algebra_profile` (forbid parallel hand-maintained type→profile tables); sibling Tier3 rows in this file carry the same lane receipts. | | `src/v3/compiler/tests/integration/no_coercion_cost_dimension_ratchet_test.rs` | **ROADMAP:** `ROADMAP.md` → `### Nine lanes` → **T-PB-B** / `pb_rust_tests_outside_residual_zero` (SG-0 `EXPECTED_HAND_AUTHORED_TEST` hand-authored integration census; same “Hand-Rust census” partition narrative as `ROADMAP.md` §Nine lanes / T-PB-B row in the lanes table). **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#39** `no_coercion_cost_dimension` (T-CostLens-Composition — host walk over `src/v3/{std,lenses,spec}/**/*.dag` forbidding standalone `CoercionCost` outside `//` comments). **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` literal land in the same PR as the ratchet. **Dissolution:** remove when the same structural claim is carried by `.dag` `TestClaim` / generated harness without this host file walk. **Interim ratchet:** `no_coercion_cost_dimension_substrate_dag_has_no_coercion_cost_carrier_token` + `standalone_needle_tests` pin identifier-boundary matching. | | `src/v3/compiler/tests/integration/r3_gate_60_phase2_width_nat_parser_test.rs` | **ROADMAP:** `ROADMAP.md` — **`substrate_gap_parser_grammar_closed`** / R3 gate **#60** (Phase 2.1 parser slice: angle-only width nat in `<…>`, `TypeAngleArg` substrate split, `Compose>` lowering with literal phantom width). **Dissolution:** remove when gate #60 parse/lower/routing receipts are carried by `.dag` `TestClaim` / generated harness without this hand-authored `compile_to_dag` + `parse_for_test` module (per `docs/audit/r3-gate-60-decomposition.md` follow-on slices). **Interim ratchet:** `gate_60_phase2_parse_accepts_algebra_angle_width_nat`, `gate_60_phase2_int_64_lowers_to_compose_int_machine_width_literal`, `gate_60_phase2_nat_8_lowers_via_uint_slot`, `gate_60_integer_routing_witness_accepts_literal_nat_machine_width`, `gate_60_bare_numeric_type_is_parse_rejected`, `gate_60_int_disallowed_width_fails_closed_without_malformed_template_args`. | diff --git a/docs/r3-program-plan.md b/docs/r3-program-plan.md index 9f39225a3fa..839a737ecc3 100644 --- a/docs/r3-program-plan.md +++ b/docs/r3-program-plan.md @@ -286,7 +286,7 @@ This principle is NOT a separate lane; it's a per-lane gate-shape requirement ap | 59 | `recursive_flex_demonstration_landed` | demonstration | T-Lens-Self-Application | **CONSUMER_LANDED + PASSING** — `t_ci_workflow_as_data_demo_test::recursive_flex_demonstration_landed`: on linked `ci_github_actions_workflow.dag` + `ci.dag`, `ci_workflow_dag.github_actions_workflow` is structurally **identical** to lowered `gunbc_ci_github_actions_workflow` (YamlStatic arm of `project_github_actions` is definitionally that field); source-text ratchet pins `YamlStatic => dag.github_actions_workflow` + `data gunbc_ci_yml_workflow: Workflow = project_github_actions(ci_workflow_dag, YamlStatic)` in `dsl/gunbc/ci_emission.dag`. **M1(2.8) note:** user-range `compile_to_dag(ci_emission.dag)` remains blocked (data body call + binary-shim block-bodied record literal); this gate’s executable consumer is the **projection lemma + structural carrier equality + emission source contract**, not a full emission-module compile. **Supporting ratchet:** `gunbc_ci_github_actions_workflow_dag_matches_yaml_generator_output`. | recursive-flex YamlStatic carrier + emit-back source authority | | 60 | `substrate_gap_parser_grammar_closed` | substrate-gap-class | T-V2-Retirement + T-Numeric-Construction + Substrate (cross-lane) | DECLARED (NEW 2026-05-06) | concept faithfully modeled (per Q-MachineConstraint sub-decision 5): substrate carries algebra + machine-constraint as independent composing axes with `.dag`-generated interaction substrate; min existence-proof = `Int<64>` / `Real<64>` / `Nat<8>` lower without v2-fallback (evidence, not target) | | 61 | `substrate_gap_function_valued_data_closed` | substrate-gap-class | T-E-P-Producer-Broadening (Phase 1) + E6-G0d (landed #1813) | DECLARED YELLOW (NEW 2026-05-06; reframed RED→YELLOW 2026-05-06 per option (a) RATIFIED) | chain-break dissolved by Q-Class-2-Chain-Break option (a) gap-test re-pick + Q-LBP-R3-Closeability option (b) narrowing; single-prereq-blocked on T-E-P P1 / S10 | -| 62 | `substrate_gap_file_ingestion_closed` | substrate-gap-class | T-Workflow-As-Data | **CONSUMER_LANDED + PASSING** (carrier + structural ratchet + demo: `src/v3/std/timing_lens.dag` `FileAttachment` + `gate_62_file_attachment_demo_record`; `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` — ratified shape unchanged per msg_09df44c6 / msg_61e302c6 / PR #2820. **§Acceptance receipt** (this gate's `.dag` program-ingests-external-file-w/o-`include_str!` predicate): CI-visible tree-state ratchet `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` `r3_gate_62_no_include_str_in_dsl` asserts zero `include_str!` matches across every `.dag`/`.v3` file under `dsl/` — extends Director's PR #2820 ratification-time grep into a CI-enforced predicate over the file tree's authoritative substrate body, distinct from grep-on-doc-comment textual-enforcement per `feedback_no_textual_enforcement_bridges` (the gate-fact is over substrate files, not over text mentioning the string). Scope-bound per Substrate Mgr msg_210620aa — sub-canvas-2 workflow blob-store / `content_digest → bytes` resolution remains Substrate-Mgr-owned out-of-scope.) | `.dag` program ingests external file w/o include_str!. **Ratified top-level shape**: workflow-substrate `FileAttachment` carrier extending gate #53 (sibling-carrier pattern with WorkflowSecret + CronExpression β-ratified via PR #2160). **Ratified carrier-internals** (Refined-B-1 — strict 5-of-7 subset of #55 `WorkflowObservationAnchor` at `src/v3/std/timing_lens.dag:98-106`): `FileAttachment { subject_node: NodeId, content_digest: ContentHash, producer_id: WorkflowProducerId, workflow_run_id: WorkflowRunId, attached_at_ns: Nanoseconds }`. Drops observer_id + prover_id (timing-observation-specific epistemological roles; not applicable to file attachment). **Q1-Q6 dispositions** (Director verbatim): Q2 encoding ABSENT default (if needed, `Encoding` from `dsl/std/encoding.dag` — NEVER novel `AttachmentEncoding`); Q3 `WorkflowAssetPath` NOT introduced (digest-only canonical); Q4 workflow-coupling deferred to worker brief / consumer evidence (#55 `TimingObservationSet = List` is own carrier, not embedded; analogy: no preemptive `List` on Job/Step); Q5 eager confirmed; Q6 `AttachmentEncoding` Practice-4 🔴 RED — dissolved to existing `dsl/std/encoding.dag` 6-variant `Encoding` BoundedLattice. **Disqualified top-level candidates** (per Director original disposition): (a) compile-time `read_utf8_file` — P5-style intrinsic, doesn't match §4.3 framing, re-introduces `include_str!` semantics under new syntax (PR #2819 STAND DOWN); (c) precedent-mirror — no precedent enumerated, §4.3 already names answer; (d) A+B bundle — creates parallel-authority violating §P1. **Disqualified carrier-shape candidates** (per Director sub-canvas disposition): B-2 path+digest — parallel-representation (two canonical identifiers for same fact); B-3 anchor+entry-pair — over-engineered (no separate payload to split). **Anti-patterns post-ratification** (Director-enumerated 7 total — 3 from top-level + 4 from sub-canvas): (1) compile-time `read_utf8_file`-equivalent additions; (2) FileAttachment landed without #55/#53 sibling-carrier alignment; (3) bridge variants alongside FileAttachment violating §P5 atomic-migration; (4) any `AttachmentEncoding` or equivalent encoding sum-type duplicating `dsl/std/encoding.dag`; (5) path field on FileAttachment (parallel-rep vs canonical digest); (6) `List` on Job/Step preemptively (consumer-evidence-required); (7) carrier-pattern deviation from Refined-B-1 5-field structure (no novel field-name renames; producer_id stays producer_id). **Ratification-time Director grep (PR #2820 snapshot, pre-`FileAttachment` land):** #55 anchor 7 fields at `timing_lens.dag:98-106`; 5 branded nominals (`ContentHash` :324, `WorkflowProducerId` :328, `WorkflowObserverId` :329, `WorkflowProverId` :330, `WorkflowRunId` :331) at `dsl/std/types.dag`; `dsl/std/encoding.dag` exists with `Encoding = ASCII \| UTF8 \| Latin1 \| Text \| Binary \| Unknown` BoundedLattice (compile-time narrowing); at ratification time none of `FileAttachment` / `AttachmentEncoding` / `WorkflowAssetPath` were present under those names (parallel-authority collision avoided). **Current tree (post gate-62 land):** `FileAttachment` is authored in `timing_lens.dag`; `AttachmentEncoding` / `WorkflowAssetPath` remain unauthored per Director Q2/Q3. **Sub-canvas-2 trigger** (follow-on, not blocking this carrier-internals ratification): workflow blob-store substrate — Refined-B-1 requires `content_digest → bytes` resolution; substrate may not exist at HEAD per sub-canvas §3.B-1.Cons; Substrate Mgr authors as separate canvas after Refined-B-1 lands. **PR #2823 land:** carrier (`FileAttachment`) + sibling-alignment / bootstrap ratchet (`file_attachment_substrate_carrier_test.rs`) + existence proof (`gate_62_file_attachment_demo_record`) per worker brief. **`include_str!` audit (ratification snapshot)** (Director-verified `grep -rn "include_str!" dsl/` on PR #2820 canvas): no matches — gate is forward-looking (model the carrier so future file-ingestion sites have first-class workflow-substrate form), not retire-existing-side-channel. | +| 62 | `substrate_gap_file_ingestion_closed` | substrate-gap-class | T-Workflow-As-Data | **CONSUMER_LANDED** (`src/v3/std/timing_lens.dag` `FileAttachment` + `gate_62_file_attachment_demo_record`; `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` — ratified shape unchanged per msg_09df44c6 / msg_61e302c6 / PR #2820. **Supporting evidence (NOT PASSING)**: CI-visible negative-bridge audit `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` `r3_gate_62_no_include_str_in_dsl` ratchets zero `include_str!` matches under `dsl/` (program-body scan with comments + string literals stripped). **PASSING NOT YET CLAIMED** per operator BLOCKING 2026-05-14T19:13:37Z: §1.4/§4.3 require a positive `.dag` program that ingests an external file via `FileAttachment`, not just absence of the old bridge (THESIS/P1 modeling faithfulness). The negative-bridge ratchet is supporting evidence only; the PASSING flip awaits a positive `.dag` `TestClaim` / runner receipt that constructs and consumes a `FileAttachment` over real external file content.) | `.dag` program ingests external file w/o include_str!. **Ratified top-level shape**: workflow-substrate `FileAttachment` carrier extending gate #53 (sibling-carrier pattern with WorkflowSecret + CronExpression β-ratified via PR #2160). **Ratified carrier-internals** (Refined-B-1 — strict 5-of-7 subset of #55 `WorkflowObservationAnchor` at `src/v3/std/timing_lens.dag:98-106`): `FileAttachment { subject_node: NodeId, content_digest: ContentHash, producer_id: WorkflowProducerId, workflow_run_id: WorkflowRunId, attached_at_ns: Nanoseconds }`. Drops observer_id + prover_id (timing-observation-specific epistemological roles; not applicable to file attachment). **Q1-Q6 dispositions** (Director verbatim): Q2 encoding ABSENT default (if needed, `Encoding` from `dsl/std/encoding.dag` — NEVER novel `AttachmentEncoding`); Q3 `WorkflowAssetPath` NOT introduced (digest-only canonical); Q4 workflow-coupling deferred to worker brief / consumer evidence (#55 `TimingObservationSet = List` is own carrier, not embedded; analogy: no preemptive `List` on Job/Step); Q5 eager confirmed; Q6 `AttachmentEncoding` Practice-4 🔴 RED — dissolved to existing `dsl/std/encoding.dag` 6-variant `Encoding` BoundedLattice. **Disqualified top-level candidates** (per Director original disposition): (a) compile-time `read_utf8_file` — P5-style intrinsic, doesn't match §4.3 framing, re-introduces `include_str!` semantics under new syntax (PR #2819 STAND DOWN); (c) precedent-mirror — no precedent enumerated, §4.3 already names answer; (d) A+B bundle — creates parallel-authority violating §P1. **Disqualified carrier-shape candidates** (per Director sub-canvas disposition): B-2 path+digest — parallel-representation (two canonical identifiers for same fact); B-3 anchor+entry-pair — over-engineered (no separate payload to split). **Anti-patterns post-ratification** (Director-enumerated 7 total — 3 from top-level + 4 from sub-canvas): (1) compile-time `read_utf8_file`-equivalent additions; (2) FileAttachment landed without #55/#53 sibling-carrier alignment; (3) bridge variants alongside FileAttachment violating §P5 atomic-migration; (4) any `AttachmentEncoding` or equivalent encoding sum-type duplicating `dsl/std/encoding.dag`; (5) path field on FileAttachment (parallel-rep vs canonical digest); (6) `List` on Job/Step preemptively (consumer-evidence-required); (7) carrier-pattern deviation from Refined-B-1 5-field structure (no novel field-name renames; producer_id stays producer_id). **Ratification-time Director grep (PR #2820 snapshot, pre-`FileAttachment` land):** #55 anchor 7 fields at `timing_lens.dag:98-106`; 5 branded nominals (`ContentHash` :324, `WorkflowProducerId` :328, `WorkflowObserverId` :329, `WorkflowProverId` :330, `WorkflowRunId` :331) at `dsl/std/types.dag`; `dsl/std/encoding.dag` exists with `Encoding = ASCII \| UTF8 \| Latin1 \| Text \| Binary \| Unknown` BoundedLattice (compile-time narrowing); at ratification time none of `FileAttachment` / `AttachmentEncoding` / `WorkflowAssetPath` were present under those names (parallel-authority collision avoided). **Current tree (post gate-62 land):** `FileAttachment` is authored in `timing_lens.dag`; `AttachmentEncoding` / `WorkflowAssetPath` remain unauthored per Director Q2/Q3. **Sub-canvas-2 trigger** (follow-on, not blocking this carrier-internals ratification): workflow blob-store substrate — Refined-B-1 requires `content_digest → bytes` resolution; substrate may not exist at HEAD per sub-canvas §3.B-1.Cons; Substrate Mgr authors as separate canvas after Refined-B-1 lands. **PR #2823 land:** carrier (`FileAttachment`) + sibling-alignment / bootstrap ratchet (`file_attachment_substrate_carrier_test.rs`) + existence proof (`gate_62_file_attachment_demo_record`) per worker brief. **`include_str!` audit (ratification snapshot)** (Director-verified `grep -rn "include_str!" dsl/` on PR #2820 canvas): no matches — gate is forward-looking (model the carrier so future file-ingestion sites have first-class workflow-substrate form), not retire-existing-side-channel. | | 63 | `substrate_gap_workflow_scheduling_closed` | substrate-gap-class | T-Workflow-As-Data + T-Lens-Self-Application | **CANVAS_RATIFIED** (2026-05-13 per PR **#2831** squash `89df284e3` — Substrate Mgr canvas `docs/briefs/r3-substrate-gate-63-workflow-scheduling-canvas.md` + worker `docs/briefs/r3-substrate-gate-63-workflow-scheduling-worker.md`; Director **msg_804cdc93** ratifies **Q1=Candidate A** administrative closure path — gate-criterion test `ci_workflow_as_data_demo_timing_dimension_report_evaluates_via_evaluator` passes in isolation per snappy-bear-502 **msg_cef1340b**; **Q2 OR-semantics**; **Q3** planned-deferral anchor `73969f4a9`; **Q4** substrate-lane-owned; snappy-bear-502 audit **msg_140d9bc7**; sibling `--include-ignored` failures Director-allocated to §1.8 rows **#99/#100** per msg_804cdc93 — **not** gate #63 closure scope) | CI workflow as `.dag` data executes through evaluator + `DimensionReport`; §4.4 substrate-prereq mapping table in canvas §2. **CONSUMER_LANDED + PASSING** requires worker Phases A–C (un-ignore + §1.4 (a)+(b) receipts + §4.4 footnote reconciliation + ledger flip), not claimed at ratification. | | 64 | `substrate_gap_reflection_closure_closed` | substrate-gap-class | T-LensProducer-Retirement | **DECLARED** (substrate-plumbing receipt via PR #2694 — `src/v3/compiler/tests/fixtures/r3_substrate_gap_reflection_closure.dag` adds non-canonical claim `substrate_gap_reflection_residual_census_receipt` over the live `CensusSubsetCount` lens-producer residual predicate; `r3_substrate_gap_reflection_closure_test.rs` proves the state-check receipt executes and reports residual count 2 while residuals remain (post-gate-#5 close per PR #2812 / docs sync PR #3079; bounded lens host `lens_declaration_apply.rs` + `bin/regen_lens.rs` per `is_lens_producer_census_path` in `src/v3/compiler/src/test_runner.rs`). This is **NOT** the canonical reflection-closure consumer.) | `lens_apply.rs` reflection via PB-Runtime; canonical Pass-condition per `r3-structure.md:181`: `lens_apply.rs` reflection routes via PB-Runtime interpreter-as-data and reflection-as-data substrate is exercised end-to-end. Status re-promotes only when PB-Runtime + T-LensProducer-Retirement land that consumer; census state-check is one half of the conjunctive class closure and remains a placeholder per PR #2657 / `feedback_grep_consumer_surfaces_for_lane_completeness`. P5 deferral receipts: non-test residual tracked under `ROADMAP.md` §"Lane acceptance — .dag gates" / T-PB-A row `lens_producer_files_remaining` (anchor `#lane-acceptance--dag-gates`), whose dissolution target is the priority lens-producer non-test census reaching zero; new host test harness tracked under `ROADMAP.md` §"Lane acceptance — .dag gates" / T-PB-B row `pb_rust_tests_outside_residual_zero` plus `EXPECTED_HAND_AUTHORED_TEST` in `sg0_census_test.rs`, dissolving when the generic TestClaim runner can execute the receipt without this harness. | | 65 | `tier3_dissolution_demonstration_executes` | demonstration | T-Tier3-Dissolution | PASSING | `src/v3/compiler/tests/dag/t_r3_tier3_dissolution_demonstration.dag` runs through `t_pb_b_1_dag_runner_test::r3_tier3_dissolution_demonstration_suite_passes_through_runner` | diff --git a/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs index 6870119e7f9..8a4559ef932 100644 --- a/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs +++ b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs @@ -1,19 +1,20 @@ //! **Layer:** integration //! -//! R3 §1.8 gate **#62** `substrate_gap_file_ingestion_closed` — PASSING -//! receipt. CONSUMER_LANDED already supplied via the `FileAttachment` +//! R3 §1.8 gate **#62** `substrate_gap_file_ingestion_closed` — +//! **negative-bridge audit (supporting evidence; NOT a §Acceptance +//! PASSING receipt)**. CONSUMER_LANDED supplied via the `FileAttachment` //! carrier landing in `src/v3/std/timing_lens.dag` plus the structural //! ratchet in `file_attachment_substrate_carrier_test.rs` and the //! `gate_62_file_attachment_demo_record` existence proof (PR #2823). //! -//! §Acceptance per `docs/r3-program-plan.md` §1.8 row #62: ".dag program -//! ingests external file w/o `include_str!`". The gate is forward-looking -//! (Director-verified at ratification time on PR #2820 canvas — no -//! `include_str!` matches under `dsl/`). This test promotes that -//! one-time grep into a CI-visible ratchet on tree state, distinct from -//! grep-on-doc-comment textual-enforcement (`feedback_no_textual_enforcement_bridges`): -//! the predicate is over the file tree's authoritative substrate body, -//! not over comments or briefs that mention the string. +//! Per operator BLOCKING on PR #3111 (2026-05-14T19:13:37Z): §1.4/§4.3 +//! of `docs/r3-program-plan.md` require a positive `.dag` program that +//! ingests an external file via `FileAttachment`, not just absence of +//! the old bridge (THESIS/P1 modeling faithfulness). This audit +//! ratchets that no `.dag`/`.v3` program body under `dsl/` re-introduces +//! `include_str!` while the positive ingestion-via-`FileAttachment` +//! demonstration is built out; it is paired with that future positive +//! receipt, not a substitute for it. //! //! Per codex REQUEST_CHANGES on PR #3111 (2026-05-14 review #11981): the //! check operates over **program body** text, not raw bytes — line diff --git a/src/v3/compiler/tests/integration/sg0_census_test.rs b/src/v3/compiler/tests/integration/sg0_census_test.rs index 0ad38296af6..4a735a1fb05 100644 --- a/src/v3/compiler/tests/integration/sg0_census_test.rs +++ b/src/v3/compiler/tests/integration/sg0_census_test.rs @@ -650,15 +650,20 @@ const EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[ // R3 gate #60 Phase 2.1 (`substrate_gap_parser_grammar_closed` parser slice): hermetic // parse + lower receipts for angle-bracket width nat (`Int<64>`) surface; SG-0 P5 receipt. "src/v3/compiler/tests/integration/r3_gate_60_phase2_width_nat_parser_test.rs", - // R3 gate #62 `substrate_gap_file_ingestion_closed` §Acceptance receipt: tree-state - // ratchet asserting zero `include_str!` matches under `dsl/`. Pairs with the carrier + // R3 gate #62 `substrate_gap_file_ingestion_closed` negative-bridge audit + // (supporting evidence; NOT a §Acceptance PASSING receipt — operator BLOCKING + // 2026-05-14T19:13:37Z held PASSING flip pending a positive + // ingestion-via-`FileAttachment` `.dag` demonstration). Pairs with the carrier // ratchet `file_attachment_substrate_carrier_test.rs` + `gate_62_file_attachment_demo_record` - // (PR #2823) and the `FileAttachment` Refined-B-1 carrier in - // `src/v3/std/timing_lens.dag`. Hand-Rust because the predicate is over the - // workspace `.dag`/`.v3` file tree (filesystem walk + read), distinct from - // grep-on-doc-comment textual-enforcement per `feedback_no_textual_enforcement_bridges`. - // Dissolves when a `.dag` `TestClaim` / PB-B-1 runner can assert - // file-tree predicates fail-closed without a host-side filesystem walker. + // (PR #2823) and the `FileAttachment` Refined-B-1 carrier in `src/v3/std/timing_lens.dag`. + // Hand-Rust because the predicate is over the workspace `.dag`/`.v3` file tree + // (filesystem walk + read) with comments / string literals stripped from each + // program body, distinct from grep-on-doc-comment textual-enforcement per + // `feedback_no_textual_enforcement_bridges`. T-PB-B deferral lane + // (`pb_rust_tests_outside_residual_zero`); dissolves when a `.dag` `TestClaim` / + // PB-B-1 runner can assert the file-tree audit fail-closed without a host-side + // filesystem walker, or when the gate flips PASSING via a positive ingestion + // demonstration and the carrier-reachability ratchets alone carry the audit. "src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs", // R3 gate #87 (`lens_cementing_test_discipline_complete` / issue #2609): Rust receipts // paired with `tests/dag/t_r3_gate_87_cementing_regen_*.dag` + `t_pb_b_1_dag_runner_test` From ec68c64b7a684910a9203bdfedab07e46f7aa6bb Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 14 May 2026 19:46:41 +0000 Subject: [PATCH 6/7] rename r3_gate_62 test to *_negative_bridge_audit_test (filename honesty) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses non-blocking nits from both reviewers on PR #3111: - cursor/composer-2 review #12121: "the filename `r3_gate_62_file_ingestion_passing_test.rs` reads like a PASSING receipt even though the module docs and plan row stress the opposite; a rename in a follow-up would reduce confusion for future grep-based audits." - claude/claude-opus-4-7 review #12156: same observation, suggesting `r3_gate_62_file_ingestion_negative_bridge_audit_test.rs`. Rename via `git mv`; updated path in: - `src/v3/compiler/tests/integration.rs` (#[path] + mod) - `src/v3/compiler/tests/integration/sg0_census_test.rs` `EXPECTED_HAND_AUTHORED_TEST` entry - `INVARIANTS.md` row - `docs/r3-program-plan.md` §1.8 row #62 supporting-evidence cite No semantic change. Tests still pass (5/5). Co-Authored-By: Claude Opus 4.7 (1M context) --- INVARIANTS.md | 2 +- docs/r3-program-plan.md | 2 +- src/v3/compiler/tests/integration.rs | 4 ++-- ...> r3_gate_62_file_ingestion_negative_bridge_audit_test.rs} | 0 src/v3/compiler/tests/integration/sg0_census_test.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename src/v3/compiler/tests/integration/{r3_gate_62_file_ingestion_passing_test.rs => r3_gate_62_file_ingestion_negative_bridge_audit_test.rs} (100%) diff --git a/INVARIANTS.md b/INVARIANTS.md index c0f6b051802..9ac60cacdec 100644 --- a/INVARIANTS.md +++ b/INVARIANTS.md @@ -342,7 +342,7 @@ Per **Dispatch-Discipline Mechanisms (b)** above, each **new** path added to `EX | `src/v3/compiler/tests/integration/ctrl_pr_digests_dag_smoke_test.rs` | **Project plan:** `docs/r4-ctrl-dag-migration-project-plan.md` §3 — catalog **#8** `dsl/ctrl/pr_digests.dag` (Wave-1 ctrl → `.dag` subsystem modeling). **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + the matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs` land in the same PR as the smoke test. **Dissolution:** remove when `compile_to_dag` (or a single generated harness) validates `module … service …` ctrl carrier files end-to-end without a parallel Rust string/lexer ratchet, or when the contract migrates to `.dag` `TestClaim` coverage. **Interim ratchet:** `ctrl_pr_digests_dag_tokenizes_and_matches_expected_surface` requires clean tokenization plus presence of `module ctrl.pr_digests`, `import extdeps.github.pulls { PullRequest, PullReview, ReviewComment }`, `std.errors` / `std.types` imports, the four Practice-4 sum/record carriers (with `🟡 STAGED` / `🟢 TERMINAL` markers per `dsl/ctrl/README.md`), `ReviewCommentBody` + `review_line_comments` wiring, and `service ctrl.PrDigests` / the four `operation` blocks / `readonly`. | | `src/v3/compiler/tests/integration/extdeps_sql_transport_test.rs` | **ROADMAP:** `ROADMAP.md` § **Nine lanes** row `T-PB-B` / `pb_rust_tests_outside_residual_zero`; this Rust integration receipt keeps HTTP/SQL/audit extdeps compiled by the existing v3 parser before downstream emission-target consumers rely on them. **Dissolution:** remove when extdeps transport and Phase 3 emission-target files are covered by a `.dag`-native parse/authority suite or generated test harness rather than per-file Rust `compile_to_dag` probes. **Interim ratchet:** `rest_transport_dag_compiles_cleanly` and `sql_transport_dag_compiles_cleanly` pin `dsl/extdeps/transports/rest.dag` and `dsl/extdeps/transports/sql.dag`; `http_server_extdep_dag_compiles_cleanly`, `sql_migration_extdep_dag_compiles_cleanly`, and `audit_event_extdep_dag_compiles_cleanly` pin `dsl/extdeps/http/server.dag`, `dsl/extdeps/sql/migration.dag`, and `dsl/extdeps/audit/event.dag` as parseable staged emission-target substrate. The field-sensitive companions (`http_server_target_fields_are_authoritative_substrate_edges`, `sql_migration_target_fields_bound_raw_sql_scaffold`, `audit_event_target_fields_preserve_cloudevents_core_names`) consume the new target-contract fields directly so they fail on raw `String`/`Int` regressions, missing SQL scaffold bounds, or CloudEvents alias drift while the first real projection consumer is still staged; the audit ratchet also locks CloudEvents core fields to branded carriers and `std.types.Timestamp` rather than raw strings. | | `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#62** `substrate_gap_file_ingestion_closed` (T-Workflow-As-Data substrate-gap class; worker brief `docs/briefs/r3-substrate-gate-62-file-attachment-carrier-worker.md`). **Dissolution:** remove when a `.dag` `TestClaim` / PB-B-1 runner receipt can assert `FileAttachment` field names + cross-module nominal wiring against `generated_full_bootstrap_dag()` without this hand-Rust structural ratchet (same dissolution posture as `timing_lens_substrate_carrier_test.rs` for gate #55). **Interim ratchet:** `file_attachment_shape_locked` + `file_attachment_field_types_locked` + `file_attachment_field_count_is_five` pin the ratified Refined-B-1 five-field subset of `WorkflowObservationAnchor` (`NodeId`, `ContentHash`, `WorkflowProducerId`, `WorkflowRunId`, `Nanoseconds`) exactly as declared in `src/v3/std/timing_lens.dag`; existence proof carrier construction stays in-module as `gate_62_file_attachment_demo_record`. | -| `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#62** `substrate_gap_file_ingestion_closed` supporting evidence (T-Workflow-As-Data substrate-gap class). **NOT a §Acceptance receipt**: §1.4/§4.3 require a positive `.dag` ingestion-via-`FileAttachment` demonstration, not absence-of-bridge evidence (operator BLOCKING 2026-05-14T19:13:37Z, THESIS/P1 modeling faithfulness). This row is a CI-visible negative-bridge audit only — it ratchets that no `.dag`/`.v3` program body under `dsl/` re-introduces `include_str!` while the workflow-substrate file-ingestion path is built out; program bodies are scanned with `//` line comments, `/* … */` block comments, and `"…"` / `` `…` `` string literals stripped so a doc-comment or label mentioning the bridge name does not trip the audit (`feedback_no_textual_enforcement_bridges`). **ROADMAP:** `ROADMAP.md` → `### Nine lanes` → **T-PB-B** / `pb_rust_tests_outside_residual_zero` — hand-Rust integration test held under the T-PB-B deferral lane until a `.dag` `TestClaim` / PB-B-1 runner can carry the predicate. **Dissolution:** remove when (a) a `.dag` `TestClaim` / PB-B-1 runner receipt asserts the same file-tree audit fail-closed without a host-side filesystem walker, OR (b) the gate flips PASSING via a positive ingestion-via-`FileAttachment` `.dag` program and the carrier-reachability ratchets alone carry the audit. **Interim ratchet:** `r3_gate_62_no_include_str_in_dsl` walks every `.dag`/`.v3` file under `dsl/` and fails with the offending paths if any reintroduce `include_str!` in a program body. | +| `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#62** `substrate_gap_file_ingestion_closed` supporting evidence (T-Workflow-As-Data substrate-gap class). **NOT a §Acceptance receipt**: §1.4/§4.3 require a positive `.dag` ingestion-via-`FileAttachment` demonstration, not absence-of-bridge evidence (operator BLOCKING 2026-05-14T19:13:37Z, THESIS/P1 modeling faithfulness). This row is a CI-visible negative-bridge audit only — it ratchets that no `.dag`/`.v3` program body under `dsl/` re-introduces `include_str!` while the workflow-substrate file-ingestion path is built out; program bodies are scanned with `//` line comments, `/* … */` block comments, and `"…"` / `` `…` `` string literals stripped so a doc-comment or label mentioning the bridge name does not trip the audit (`feedback_no_textual_enforcement_bridges`). **ROADMAP:** `ROADMAP.md` → `### Nine lanes` → **T-PB-B** / `pb_rust_tests_outside_residual_zero` — hand-Rust integration test held under the T-PB-B deferral lane until a `.dag` `TestClaim` / PB-B-1 runner can carry the predicate. **Dissolution:** remove when (a) a `.dag` `TestClaim` / PB-B-1 runner receipt asserts the same file-tree audit fail-closed without a host-side filesystem walker, OR (b) the gate flips PASSING via a positive ingestion-via-`FileAttachment` `.dag` program and the carrier-reachability ratchets alone carry the audit. **Interim ratchet:** `r3_gate_62_no_include_str_in_dsl` walks every `.dag`/`.v3` file under `dsl/` and fails with the offending paths if any reintroduce `include_str!` in a program body. | | `src/v3/compiler/tests/integration/workflow_substrate_carriers_test.rs` | **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#53** `workflow_substrate_carriers_landed` (T-Workflow-As-Data Slice 1; worker brief `docs/briefs/r3-substrate-t-workflow-as-data-slice-1-worker.md`). **Dissolution:** remove when a `.dag` `TestClaim` / PB-B-1 runner receipt can assert `WorkflowSecret`, `SecretScope`, `CronSchedule`, and `CronField` structural shape against `generated_full_bootstrap_dag()` without this hand-Rust ratchet. **Interim ratchet:** `workflow_secret_shape_locked` + `secret_scope_variants_locked` + `cron_schedule_shape_locked` + `cron_field_variants_locked` pin the Slice 1 β-ratified carriers (STOP+PING discipline on `CronSchedule` field-count drift >5 per brief). | | `src/v3/compiler/tests/integration/m2_substrate_inhabitance_test.rs` | **ROADMAP:** `ROADMAP.md` — **Tier-3 perf-budget Phase-1 hand-Rust mirror benches** / T-Tier3-Dissolution paired-dispatch (`docs/briefs/r3-pb-t-tier3-consumer-slice-worker.md`). **Plan:** `docs/r3-program-plan.md` §1.8 gate **#2** `tier3_computation_mirror_dissolved` (state-check; **CONSUMER_LANDED** = §1.7 executable-consumer sense, not INVARIANTS §P2 generated-consumer — see plan §1.7 “State-check …” paragraph). **Dissolution:** retire remaining Tier3 host mirrors per `docs/r3-structure.md` §Acceptance as Evaluator-backed std bodies land. **Interim ratchet (P5 Mechanism (b)):** `tier3_computation_mirror_trivial_constructors_dissolved` (PR #2789 narrow slice) + `tier3_computation_mirror_kernel_algebra_profile_substrate_authority` with brace-bounded `dag.rs` scan asserting `type_iteration_dimension` delegates through `BOOTSTRAPPED_DAG.kernel_algebra_profile` (forbid parallel hand-maintained type→profile tables); sibling Tier3 rows in this file carry the same lane receipts. | | `src/v3/compiler/tests/integration/no_coercion_cost_dimension_ratchet_test.rs` | **ROADMAP:** `ROADMAP.md` → `### Nine lanes` → **T-PB-B** / `pb_rust_tests_outside_residual_zero` (SG-0 `EXPECTED_HAND_AUTHORED_TEST` hand-authored integration census; same “Hand-Rust census” partition narrative as `ROADMAP.md` §Nine lanes / T-PB-B row in the lanes table). **R3 program plan:** `docs/r3-program-plan.md` §1.8 gate **#39** `no_coercion_cost_dimension` (T-CostLens-Composition — host walk over `src/v3/{std,lenses,spec}/**/*.dag` forbidding standalone `CoercionCost` outside `//` comments). **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` literal land in the same PR as the ratchet. **Dissolution:** remove when the same structural claim is carried by `.dag` `TestClaim` / generated harness without this host file walk. **Interim ratchet:** `no_coercion_cost_dimension_substrate_dag_has_no_coercion_cost_carrier_token` + `standalone_needle_tests` pin identifier-boundary matching. | diff --git a/docs/r3-program-plan.md b/docs/r3-program-plan.md index cd7a105bb13..771264f162e 100644 --- a/docs/r3-program-plan.md +++ b/docs/r3-program-plan.md @@ -286,7 +286,7 @@ This principle is NOT a separate lane; it's a per-lane gate-shape requirement ap | 59 | `recursive_flex_demonstration_landed` | demonstration | T-Lens-Self-Application | **CONSUMER_LANDED + PASSING** — `t_ci_workflow_as_data_demo_test::recursive_flex_demonstration_landed`: on linked `ci_github_actions_workflow.dag` + `ci.dag`, `ci_workflow_dag.github_actions_workflow` is structurally **identical** to lowered `gunbc_ci_github_actions_workflow` (YamlStatic arm of `project_github_actions` is definitionally that field); source-text ratchet pins `YamlStatic => dag.github_actions_workflow` + `data gunbc_ci_yml_workflow: Workflow = project_github_actions(ci_workflow_dag, YamlStatic)` in `dsl/gunbc/ci_emission.dag`. **M1(2.8) note:** user-range `compile_to_dag(ci_emission.dag)` remains blocked (data body call + binary-shim block-bodied record literal); this gate’s executable consumer is the **projection lemma + structural carrier equality + emission source contract**, not a full emission-module compile. **Supporting ratchet:** `gunbc_ci_github_actions_workflow_dag_matches_yaml_generator_output`. | recursive-flex YamlStatic carrier + emit-back source authority | | 60 | `substrate_gap_parser_grammar_closed` | substrate-gap-class | T-V2-Retirement + T-Numeric-Construction + Substrate (cross-lane) | DECLARED (NEW 2026-05-06) | concept faithfully modeled (per Q-MachineConstraint sub-decision 5): substrate carries algebra + machine-constraint as independent composing axes with `.dag`-generated interaction substrate; min existence-proof = `Int<64>` / `Real<64>` / `Nat<8>` lower without v2-fallback (evidence, not target) | | 61 | `substrate_gap_function_valued_data_closed` | substrate-gap-class | T-E-P-Producer-Broadening (Phase 1) + E6-G0d (landed #1813) | DECLARED YELLOW (NEW 2026-05-06; reframed RED→YELLOW 2026-05-06 per option (a) RATIFIED) | chain-break dissolved by Q-Class-2-Chain-Break option (a) gap-test re-pick + Q-LBP-R3-Closeability option (b) narrowing; single-prereq-blocked on T-E-P P1 / S10 | -| 62 | `substrate_gap_file_ingestion_closed` | substrate-gap-class | T-Workflow-As-Data | **CONSUMER_LANDED** (`src/v3/std/timing_lens.dag` `FileAttachment` + `gate_62_file_attachment_demo_record`; `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` — ratified shape unchanged per msg_09df44c6 / msg_61e302c6 / PR #2820. **Supporting evidence (NOT PASSING)**: CI-visible negative-bridge audit `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs` `r3_gate_62_no_include_str_in_dsl` ratchets zero `include_str!` matches under `dsl/` (program-body scan with comments + string literals stripped). **PASSING NOT YET CLAIMED** per operator BLOCKING 2026-05-14T19:13:37Z: §1.4/§4.3 require a positive `.dag` program that ingests an external file via `FileAttachment`, not just absence of the old bridge (THESIS/P1 modeling faithfulness). The negative-bridge ratchet is supporting evidence only; the PASSING flip awaits a positive `.dag` `TestClaim` / runner receipt that constructs and consumes a `FileAttachment` over real external file content.) | `.dag` program ingests external file w/o include_str!. **Ratified top-level shape**: workflow-substrate `FileAttachment` carrier extending gate #53 (sibling-carrier pattern with WorkflowSecret + CronExpression β-ratified via PR #2160). **Ratified carrier-internals** (Refined-B-1 — strict 5-of-7 subset of #55 `WorkflowObservationAnchor` at `src/v3/std/timing_lens.dag:98-106`): `FileAttachment { subject_node: NodeId, content_digest: ContentHash, producer_id: WorkflowProducerId, workflow_run_id: WorkflowRunId, attached_at_ns: Nanoseconds }`. Drops observer_id + prover_id (timing-observation-specific epistemological roles; not applicable to file attachment). **Q1-Q6 dispositions** (Director verbatim): Q2 encoding ABSENT default (if needed, `Encoding` from `dsl/std/encoding.dag` — NEVER novel `AttachmentEncoding`); Q3 `WorkflowAssetPath` NOT introduced (digest-only canonical); Q4 workflow-coupling deferred to worker brief / consumer evidence (#55 `TimingObservationSet = List` is own carrier, not embedded; analogy: no preemptive `List` on Job/Step); Q5 eager confirmed; Q6 `AttachmentEncoding` Practice-4 🔴 RED — dissolved to existing `dsl/std/encoding.dag` 6-variant `Encoding` BoundedLattice. **Disqualified top-level candidates** (per Director original disposition): (a) compile-time `read_utf8_file` — P5-style intrinsic, doesn't match §4.3 framing, re-introduces `include_str!` semantics under new syntax (PR #2819 STAND DOWN); (c) precedent-mirror — no precedent enumerated, §4.3 already names answer; (d) A+B bundle — creates parallel-authority violating §P1. **Disqualified carrier-shape candidates** (per Director sub-canvas disposition): B-2 path+digest — parallel-representation (two canonical identifiers for same fact); B-3 anchor+entry-pair — over-engineered (no separate payload to split). **Anti-patterns post-ratification** (Director-enumerated 7 total — 3 from top-level + 4 from sub-canvas): (1) compile-time `read_utf8_file`-equivalent additions; (2) FileAttachment landed without #55/#53 sibling-carrier alignment; (3) bridge variants alongside FileAttachment violating §P5 atomic-migration; (4) any `AttachmentEncoding` or equivalent encoding sum-type duplicating `dsl/std/encoding.dag`; (5) path field on FileAttachment (parallel-rep vs canonical digest); (6) `List` on Job/Step preemptively (consumer-evidence-required); (7) carrier-pattern deviation from Refined-B-1 5-field structure (no novel field-name renames; producer_id stays producer_id). **Ratification-time Director grep (PR #2820 snapshot, pre-`FileAttachment` land):** #55 anchor 7 fields at `timing_lens.dag:98-106`; 5 branded nominals (`ContentHash` :324, `WorkflowProducerId` :328, `WorkflowObserverId` :329, `WorkflowProverId` :330, `WorkflowRunId` :331) at `dsl/std/types.dag`; `dsl/std/encoding.dag` exists with `Encoding = ASCII \| UTF8 \| Latin1 \| Text \| Binary \| Unknown` BoundedLattice (compile-time narrowing); at ratification time none of `FileAttachment` / `AttachmentEncoding` / `WorkflowAssetPath` were present under those names (parallel-authority collision avoided). **Current tree (post gate-62 land):** `FileAttachment` is authored in `timing_lens.dag`; `AttachmentEncoding` / `WorkflowAssetPath` remain unauthored per Director Q2/Q3. **Sub-canvas-2 trigger** (follow-on, not blocking this carrier-internals ratification): workflow blob-store substrate — Refined-B-1 requires `content_digest → bytes` resolution; substrate may not exist at HEAD per sub-canvas §3.B-1.Cons; Substrate Mgr authors as separate canvas after Refined-B-1 lands. **PR #2823 land:** carrier (`FileAttachment`) + sibling-alignment / bootstrap ratchet (`file_attachment_substrate_carrier_test.rs`) + existence proof (`gate_62_file_attachment_demo_record`) per worker brief. **`include_str!` audit (ratification snapshot)** (Director-verified `grep -rn "include_str!" dsl/` on PR #2820 canvas): no matches — gate is forward-looking (model the carrier so future file-ingestion sites have first-class workflow-substrate form), not retire-existing-side-channel. | +| 62 | `substrate_gap_file_ingestion_closed` | substrate-gap-class | T-Workflow-As-Data | **CONSUMER_LANDED** (`src/v3/std/timing_lens.dag` `FileAttachment` + `gate_62_file_attachment_demo_record`; `src/v3/compiler/tests/integration/file_attachment_substrate_carrier_test.rs` — ratified shape unchanged per msg_09df44c6 / msg_61e302c6 / PR #2820. **Supporting evidence (NOT PASSING)**: CI-visible negative-bridge audit `src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs` `r3_gate_62_no_include_str_in_dsl` ratchets zero `include_str!` matches under `dsl/` (program-body scan with comments + string literals stripped). **PASSING NOT YET CLAIMED** per operator BLOCKING 2026-05-14T19:13:37Z: §1.4/§4.3 require a positive `.dag` program that ingests an external file via `FileAttachment`, not just absence of the old bridge (THESIS/P1 modeling faithfulness). The negative-bridge ratchet is supporting evidence only; the PASSING flip awaits a positive `.dag` `TestClaim` / runner receipt that constructs and consumes a `FileAttachment` over real external file content.) | `.dag` program ingests external file w/o include_str!. **Ratified top-level shape**: workflow-substrate `FileAttachment` carrier extending gate #53 (sibling-carrier pattern with WorkflowSecret + CronExpression β-ratified via PR #2160). **Ratified carrier-internals** (Refined-B-1 — strict 5-of-7 subset of #55 `WorkflowObservationAnchor` at `src/v3/std/timing_lens.dag:98-106`): `FileAttachment { subject_node: NodeId, content_digest: ContentHash, producer_id: WorkflowProducerId, workflow_run_id: WorkflowRunId, attached_at_ns: Nanoseconds }`. Drops observer_id + prover_id (timing-observation-specific epistemological roles; not applicable to file attachment). **Q1-Q6 dispositions** (Director verbatim): Q2 encoding ABSENT default (if needed, `Encoding` from `dsl/std/encoding.dag` — NEVER novel `AttachmentEncoding`); Q3 `WorkflowAssetPath` NOT introduced (digest-only canonical); Q4 workflow-coupling deferred to worker brief / consumer evidence (#55 `TimingObservationSet = List` is own carrier, not embedded; analogy: no preemptive `List` on Job/Step); Q5 eager confirmed; Q6 `AttachmentEncoding` Practice-4 🔴 RED — dissolved to existing `dsl/std/encoding.dag` 6-variant `Encoding` BoundedLattice. **Disqualified top-level candidates** (per Director original disposition): (a) compile-time `read_utf8_file` — P5-style intrinsic, doesn't match §4.3 framing, re-introduces `include_str!` semantics under new syntax (PR #2819 STAND DOWN); (c) precedent-mirror — no precedent enumerated, §4.3 already names answer; (d) A+B bundle — creates parallel-authority violating §P1. **Disqualified carrier-shape candidates** (per Director sub-canvas disposition): B-2 path+digest — parallel-representation (two canonical identifiers for same fact); B-3 anchor+entry-pair — over-engineered (no separate payload to split). **Anti-patterns post-ratification** (Director-enumerated 7 total — 3 from top-level + 4 from sub-canvas): (1) compile-time `read_utf8_file`-equivalent additions; (2) FileAttachment landed without #55/#53 sibling-carrier alignment; (3) bridge variants alongside FileAttachment violating §P5 atomic-migration; (4) any `AttachmentEncoding` or equivalent encoding sum-type duplicating `dsl/std/encoding.dag`; (5) path field on FileAttachment (parallel-rep vs canonical digest); (6) `List` on Job/Step preemptively (consumer-evidence-required); (7) carrier-pattern deviation from Refined-B-1 5-field structure (no novel field-name renames; producer_id stays producer_id). **Ratification-time Director grep (PR #2820 snapshot, pre-`FileAttachment` land):** #55 anchor 7 fields at `timing_lens.dag:98-106`; 5 branded nominals (`ContentHash` :324, `WorkflowProducerId` :328, `WorkflowObserverId` :329, `WorkflowProverId` :330, `WorkflowRunId` :331) at `dsl/std/types.dag`; `dsl/std/encoding.dag` exists with `Encoding = ASCII \| UTF8 \| Latin1 \| Text \| Binary \| Unknown` BoundedLattice (compile-time narrowing); at ratification time none of `FileAttachment` / `AttachmentEncoding` / `WorkflowAssetPath` were present under those names (parallel-authority collision avoided). **Current tree (post gate-62 land):** `FileAttachment` is authored in `timing_lens.dag`; `AttachmentEncoding` / `WorkflowAssetPath` remain unauthored per Director Q2/Q3. **Sub-canvas-2 trigger** (follow-on, not blocking this carrier-internals ratification): workflow blob-store substrate — Refined-B-1 requires `content_digest → bytes` resolution; substrate may not exist at HEAD per sub-canvas §3.B-1.Cons; Substrate Mgr authors as separate canvas after Refined-B-1 lands. **PR #2823 land:** carrier (`FileAttachment`) + sibling-alignment / bootstrap ratchet (`file_attachment_substrate_carrier_test.rs`) + existence proof (`gate_62_file_attachment_demo_record`) per worker brief. **`include_str!` audit (ratification snapshot)** (Director-verified `grep -rn "include_str!" dsl/` on PR #2820 canvas): no matches — gate is forward-looking (model the carrier so future file-ingestion sites have first-class workflow-substrate form), not retire-existing-side-channel. | | 63 | `substrate_gap_workflow_scheduling_closed` | substrate-gap-class | T-Workflow-As-Data + T-Lens-Self-Application | **CANVAS_RATIFIED** (2026-05-13 per PR **#2831** squash `89df284e3` — Substrate Mgr canvas `docs/briefs/r3-substrate-gate-63-workflow-scheduling-canvas.md` + worker `docs/briefs/r3-substrate-gate-63-workflow-scheduling-worker.md`; Director **msg_804cdc93** ratifies **Q1=Candidate A** administrative closure path — gate-criterion test `ci_workflow_as_data_demo_timing_dimension_report_evaluates_via_evaluator` passes in isolation per snappy-bear-502 **msg_cef1340b**; **Q2 OR-semantics**; **Q3** planned-deferral anchor `73969f4a9`; **Q4** substrate-lane-owned; snappy-bear-502 audit **msg_140d9bc7**; sibling `--include-ignored` failures Director-allocated to §1.8 rows **#99/#100** per msg_804cdc93 — **not** gate #63 closure scope) | CI workflow as `.dag` data executes through evaluator + `DimensionReport`; §4.4 substrate-prereq mapping table in canvas §2. **CONSUMER_LANDED + PASSING** requires worker Phases A–C (un-ignore + §1.4 (a)+(b) receipts + §4.4 footnote reconciliation + ledger flip), not claimed at ratification. | | 64 | `substrate_gap_reflection_closure_closed` | substrate-gap-class | T-LensProducer-Retirement | **DECLARED** (substrate-plumbing receipt via PR #2694 — `src/v3/compiler/tests/fixtures/r3_substrate_gap_reflection_closure.dag` adds non-canonical claim `substrate_gap_reflection_residual_census_receipt` over the live `CensusSubsetCount` lens-producer residual predicate; `r3_substrate_gap_reflection_closure_test.rs` proves the state-check receipt executes and reports residual count 2 while residuals remain (post-gate-#5 close per PR #2812 / docs sync PR #3079; bounded lens host `lens_declaration_apply.rs` + `bin/regen_lens.rs` per `is_lens_producer_census_path` in `src/v3/compiler/src/test_runner.rs`). This is **NOT** the canonical reflection-closure consumer.) | `lens_apply.rs` reflection via PB-Runtime; canonical Pass-condition per `r3-structure.md:181`: `lens_apply.rs` reflection routes via PB-Runtime interpreter-as-data and reflection-as-data substrate is exercised end-to-end. Status re-promotes only when PB-Runtime + T-LensProducer-Retirement land that consumer; census state-check is one half of the conjunctive class closure and remains a placeholder per PR #2657 / `feedback_grep_consumer_surfaces_for_lane_completeness`. P5 deferral receipts: non-test residual tracked under `ROADMAP.md` §"Lane acceptance — .dag gates" / T-PB-A row `lens_producer_files_remaining` (anchor `#lane-acceptance--dag-gates`), whose dissolution target is the priority lens-producer non-test census reaching zero; new host test harness tracked under `ROADMAP.md` §"Lane acceptance — .dag gates" / T-PB-B row `pb_rust_tests_outside_residual_zero` plus `EXPECTED_HAND_AUTHORED_TEST` in `sg0_census_test.rs`, dissolving when the generic TestClaim runner can execute the receipt without this harness. | | 65 | `tier3_dissolution_demonstration_executes` | demonstration | T-Tier3-Dissolution | PASSING | `src/v3/compiler/tests/dag/t_r3_tier3_dissolution_demonstration.dag` runs through `t_pb_b_1_dag_runner_test::r3_tier3_dissolution_demonstration_suite_passes_through_runner` | diff --git a/src/v3/compiler/tests/integration.rs b/src/v3/compiler/tests/integration.rs index 374cb060075..e825bd0c239 100644 --- a/src/v3/compiler/tests/integration.rs +++ b/src/v3/compiler/tests/integration.rs @@ -187,8 +187,8 @@ mod r3_free_consequences_first_batch_test; mod r3_free_consequences_second_batch_test; #[path = "integration/r3_gate_60_phase2_width_nat_parser_test.rs"] mod r3_gate_60_phase2_width_nat_parser_test; -#[path = "integration/r3_gate_62_file_ingestion_passing_test.rs"] -mod r3_gate_62_file_ingestion_passing_test; +#[path = "integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs"] +mod r3_gate_62_file_ingestion_negative_bridge_audit_test; #[path = "integration/r3_gate_87_lens_cementing_regen_receipts_test.rs"] mod r3_gate_87_lens_cementing_regen_receipts_test; #[path = "integration/r3_lens_producer_retirement_executable_witness_test.rs"] diff --git a/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs similarity index 100% rename from src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs rename to src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs diff --git a/src/v3/compiler/tests/integration/sg0_census_test.rs b/src/v3/compiler/tests/integration/sg0_census_test.rs index 32324d0445c..77d0026a167 100644 --- a/src/v3/compiler/tests/integration/sg0_census_test.rs +++ b/src/v3/compiler/tests/integration/sg0_census_test.rs @@ -664,7 +664,7 @@ const EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[ // PB-B-1 runner can assert the file-tree audit fail-closed without a host-side // filesystem walker, or when the gate flips PASSING via a positive ingestion // demonstration and the carrier-reachability ratchets alone carry the audit. - "src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_passing_test.rs", + "src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs", // R3 gate #87 (`lens_cementing_test_discipline_complete` / issue #2609): Rust receipts // paired with `tests/dag/t_r3_gate_87_cementing_regen_*.dag` + `t_pb_b_1_dag_runner_test` // until strict modules can freeze full `LensOutputEquals` carriers (M1(2.8)). From 75a8576acfd04239916298ad9bb26591401486cf Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 14 May 2026 19:59:21 +0000 Subject: [PATCH 7/7] gate #62 ratchet: correct rustdoc on unterminated-literal behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses non-blocking nit from cursor/composer-2 review #12190 on PR #3111: prior rustdoc on `strip_comments_and_string_literals` said any surviving `include_str!` "still trips the ratchet" even for malformed sources. Not accurate — an unterminated `"`/`` ` ``/`/*` causes the scanner to consume through end-of-input and the post-opener tail is dropped, not searched. Tightened doc to state this honestly and note that the audit relies on lex-level well-formedness of substrate it walks (realistic `.dag`/`.v3` trees would fail parse elsewhere on unbalanced delimiters). Behaviour unchanged; only the doc-comment is updated. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...te_62_file_ingestion_negative_bridge_audit_test.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs index 8a4559ef932..210114dae7e 100644 --- a/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs +++ b/src/v3/compiler/tests/integration/r3_gate_62_file_ingestion_negative_bridge_audit_test.rs @@ -103,9 +103,14 @@ fn r3_gate_62_no_include_str_in_dsl() { /// Strip `//` line comments, `/* … */` block comments, and `"…"` / `` `…` `` /// string literals from `src` so the gate-#62 substring check operates over /// program-body tokens rather than raw bytes. Conservative single-pass scan -/// with `\` escape handling inside string literals; unterminated literals or -/// block comments are dropped to end-of-input fail-closed (any surviving -/// `include_str!` outside a literal still trips the ratchet). +/// with `\` escape handling inside string literals. If an opening `"`, +/// `` ` ``, or `/*` has no closing delimiter, the scanner consumes through +/// end-of-input — anything after the unbalanced opener is dropped, not +/// searched. Realistic `.dag` / `.v3` trees would fail parse elsewhere if +/// they contained unbalanced delimiters; the negative-bridge audit therefore +/// relies on lex-level well-formedness of the substrate it walks. A +/// well-formed `include_str!` token outside any literal remains visible to +/// the needle search. fn strip_comments_and_string_literals(src: &str) -> String { let bytes = src.as_bytes(); let mut out = String::with_capacity(src.len());