diff --git a/ROADMAP.md b/ROADMAP.md index 06e3cc0ffc1..0fa2ca30c56 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -177,7 +177,7 @@ Tracked debt not dispatched with the 2026-04-21 lane wave currently in flight (L - **`algebra.dag` signature/comment reconciliation**: `dsl/std/algebra.dag:265-302` — `FreeMonoid`'s comments promise `index(FreeMonoid, Nat) -> T?`, `map(FreeMonoid, fn(T)->U) -> FreeMonoid`, `fold(FreeMonoid, init: U, fn(U,T)->U) -> U`; the declarations drop the carrier/source parameters (`index: fn(Int) -> T`, `map: fn(fn(T)->T) -> FreeMonoid`, `fold: fn(T, fn(T,T)->T) -> T`). `PartialFunction` at `:307-325` has the same issue — comment promises `merge(Map, Map, fn(V,V)->V) -> Map`, declaration is `merge: fn(PartialFunction) -> PartialFunction` (missing fn argument). One of the two (comments or declarations) is wrong; reconcile. P1 Modeling Faithfulness receipt. Owner: unassigned; small scope. - **`container_to_algebra` string table is duplicate authority**: `dsl/std/types.dag:128-141` declares `container_to_algebra: Map` mapping `"List" -> "FreeMonoid"`, `"Set" -> "BooleanAlgebra"`, `"Map" -> "PartialFunction"` — but the authoritative type aliases already exist at `:206-208` (`type List = FreeMonoid`, etc.). The file's own comment at `:126-127` carries the dissolution TODO. Dissolution: delete the map, point consumers at the typed aliases via structural identity. P2 Boundary Discipline / P1 receipt. Owner: unassigned; small scope. -- **`pipeline_authority.rs` reconstructs stage order from source text**: `src/v3/compiler/src/pipeline_authority.rs:225-275` tokenizes+parses `pipeline.dag`, slices `body_span` as raw source, iterates `body.lines()` for stage names. But `src/v3/compiler/pipeline.dag:17-23` declares `PipelineStageBinding` and `:49-83` declares per-stage bindings — the typed authority already exists. Dissolution: replace text-slicing with typed substrate read of `PipelineStageBinding` rows. P2 Boundary Discipline receipt. Owner: unassigned; small-medium scope. +- **`pipeline_authority.rs` structural read — RESOLVED (#637).** `ordered_pipeline_stages()` in `src/v3/compiler/src/pipeline_authority.rs` is now the authority function: it reads `PipelineStageBinding` declarations structurally from the Dag, and its docstring states "the declaration order of the bindings in `pipeline.dag` is the ordering authority." `pipeline_compile_order_names()` at `:185` is a thin wrapper around `ordered_pipeline_stages(dag).map(.stage_name)` — no text slicing. The text-slicing lives in `compile_body_stage_names_from_source()` at `:130-180`, called only from `reconcile_with_compile_body()` at `:110-128` as a **drift-check fail-closed reconciliation** — if the text-sliced compile-body stage order disagrees with the structural authority, compilation fails. The drift check is a legitimate belt-and-suspenders pattern, not a P2 violation. This row kept as a historical cross-reference; candidate for the stale-receipt sweep. Earlier review characterization of "substrate-capability blocker for ordered-body reflection" was incorrect — the authority moved to `PipelineStageBinding` declaration order, so no capability gap remains here. - **Emitter render-helper consolidation (Phase 3.1 candidate after 1e P3.0)**: `named_variant_id` / `render_named_template` / `primitive_type_id_for_port` / `walk_to_disj` / `algebra_field_for_operator` exist 3-5× across `src/v3/compiler/src/emit.rs` + `emit/python_target.rs` + `emit/rust_target.rs` (plus `walk_to_disj_decl` also in `lower.rs` and `infer.rs`). Collapse into one emitter-shared module. Different scope from 1e P3.0 which targets `behavior_result_port` / `port_is_consumed_from`; this is the render-side tranche. P2 Boundary Discipline receipt. Owner: queued behind 1e P3.0 as the natural follow-up. - **Stale §-style and line-number cross-references to pre-rewrite `INVARIANTS.md`**: Pro's post-#620 observation. Line-number refs in `docs/design-db16-refined-generic-substitution.md:297,298,413`, `docs/perf/clone-elimination.md:101`, `docs/lane2-compile-time-proofs.md:182`; §-style heading-name refs in `src/v3/M1_DESIGN.md` (§"No short-term solutions" / §"No bridges"), `src/v3/SELF_HOSTING.md` (§"Recursive syntax is sugar"), `docs/briefs/sg-4b-1-fix-declaration-lookup-cleanup.md` (§C-8 / §Track 9), `docs/briefs/p0-bug-no-profile-sentinel.md` (§"No fabrication sentinels"). Grep navigation still works because the strings survive as bullets in the new INVARIANTS.md, but line numbers have shifted and §-as-section framing is now approximate. Dissolution: sweep replacing line refs with `INVARIANTS.md#` anchors (post-#620) or name-based refs. Cosmetic, low urgency. Owner: unassigned. - **`Strict Forward Progress` subdoc ↔ heading drift**: pre-existing inconsistency between `docs/invariants/strict-forward-progress.md` (bounded-execution content) and the reviewer-usage meaning of the SFP rule name (dissolution-progress). Flagged explicitly in both P4 and P5 of INVARIANTS.md post-#620 as future cleanup. Dissolution: either rename the subdoc to reflect its bounded-execution content (and author a new dissolution-progress subdoc), or split the subdoc into two. Small scope once the design call is made on naming. Owner: unassigned. @@ -193,6 +193,12 @@ Tracked debt not dispatched with the 2026-04-21 lane wave currently in flight (L - **`Node` → `std/node.dag`** — already captured in `project_node_to_std` memory as prior pattern. Relevant to this program as a precedent. - **Generic `Lookup` in `std/` — dissolve per-lens `CostLookup` / `SymbolicCostLookup` / `TemplateArgumentLookup` duplicates** — three lenses currently declare their own 2-variant `Missing | Found(T)` carrier. Collapse to a single `std/Lookup` generic consumed by every lens that returns a possibly-missing result. 3 types dissolve into 1. Scope is strict 2-variant shape only — carriers with additional semantic variants (e.g., `VariantPayloadShapeLookup`'s `NotPayloadProduct`, `TemplateArgumentBinding`'s `Conflict | NoOp | Append`) stay lens-API. Owner: unassigned; migration-gate: none (pure type-declaration work; generics already work per the earlier ParseStep discussion). +- **Target emit-spec fabrication sentinels — `__EMIT_BUG_{0}__`** (**rescoped** after Lane F investigation, PR #657): originally framed as "converge three target specs on native compile-time error forms." Investigation (see `docs/briefs/emit-bug-sentinel-convergence-2026-04-22.md`) found all four sentinels (including Rust's `compile_error!`) are **already fail-closed in their target's native sense** — all cause target-compile failure. The legibility concern is real but not a P3 violation at the template layer. **Real dissolution is upstream** at `src/v2/05_emit.dag:996, 1046` where the emitter chooses to emit sentinel output when it detects an error condition (`n_is_type_var || n_is_error`, or anonymous-coproduct branch) — it should produce a Diagnostic and halt emission instead. **Dissolution trigger**: when `05_emit.dag:996, 1046` are refactored to produce Diagnostic + halt, `error_type_template` becomes unreachable and the four template declarations can dissolve or remain as defensive fallback. Surfaced by 2026-04-22 exploratory analysis; rescoped by Lane F. Owner: unassigned (F-rescope brief drafted); M scope. + +- **`algebra.dag` declaration-vs-template surface asymmetry** (**reclassified** after Lane G investigation, PR #654): originally framed as "parallel authority, derive templates from declaration." Investigation found the two surfaces are **not redundant** — `*_templates()` carries per-method metadata (`size_effect`, `cost_shape`, `callback_element_position`) consumed by complexity/cost lenses; the type declaration has no field-level slot for this metadata. Attaching it would require substrate extensions (field-level annotations, currently partial per DB-11). **Real dissolution is a modeling question**: where should per-method metadata live structurally? Three options scoped in the Lane E substrate-carrier-port design doc (options 1/2/3 per the coordination note). **Dissolution trigger**: when Lane E's design lands a chosen option for per-method metadata carriers, `*_templates()` is replaced by the chosen structural form, and the declaration/template surface converges to one. Related to but separate from the four named substrate carriers. Surfaced by 2026-04-22 exploratory analysis; reclassified by Lane G. Owner: blocked on Lane E design doc; L scope once unblocked (substrate work). + +- **`extdeps/browser.dag` typed-carrier service-boundary collapse**: `dsl/extdeps/browser.dag:21-32` declares typed carriers (`BrowserConfig`, opaque `BrowserContext` / `Page` / `Element` handles, imports `Url`), but service ops use raw `String`: `Launch.input.headless: String = "false"`, `output.context_id: String`; `Goto.input.url: String`, `wait_until: String`, `output.final_url: String`; selector/query/evaluate outputs all remain `String` (`:42-47,56-60,75-103`). Same class as the LLM service flattening and the GitHub auth model bypass (both tracked separately). P1 Modeling Faithfulness / M8 "dispatch structural, not string extraction". **Dissolution trigger**: when the transport layer (REST/shell/file) can consume typed carriers end-to-end rather than stringly — this requires transport-level capability support that currently forces the String fallback. The Lane H brief (PR #658) pilots the pattern on browser.dag specifically; if that lands cleanly, LLM + GitHub dissolutions can consume the same pattern. Until then, the transport-capability gap is the upstream blocker. Surfaced by 2026-04-22 exploratory analysis. Owner: unassigned (pilot in-flight on Lane H #658); M per service family, contingent on transport capability. + ### Reviewer-noise class — a practice, not a debt - **Integration-reflection cadence**: every ~few days, run a reflective + exploratory analysis pair. The 2026-04-15 and 2026-04-18 passes caught items individual PR reviews missed (authority split across PRs, silent cross-PR name-based lookups, the `CreateComment` drift, the `repeat_string` bug). Worth institutionalizing.