Repository navigation
Conversation
…probe) First-pass design for the v2.5 fork's artifact module. RenderTarget is first-class data carrying a LanguageSpec (data-not-tag), not a bare 4-arm coproduct consumers re-dispatch on. Drops v2's write-only ArtifactKind and never-inhabited Boundary subsystem (loyal-dove-547 PR #3406 finding) — they re-enter only when a consumer needs them. Cross-stage contract: imports LanguageSpec from `v2_5.compiler.emit` (crisp-dove-396 owns the shape; module path provisional, surfaced to the PM). No bootstrap binary for v2.5 yet (sunny-otter-371). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PM rulings on cross-stage questions: - Q3: RenderTarget was a hollow wrapper around LanguageSpec — collapse. Artifact.target is now LanguageSpec directly; type RenderTarget gone. If per-build configuration emerges as a real differentiator, it enters then (as a variant), not pre-built as an empty carrier. - Q4: Practice 9 strict for all v2.5 calibration probes — no in-file prose; PR body carries the v2→v2.5 mapping narrative. Stripped the per-declaration explanatory comments and section banners; file header metadata block (Scope/Owns/Consumes/Status) stays — that's structured metadata, not prose, and matches the v4 file convention. - Q1: LanguageSpec module path stays provisional with a RECONCILE-NEEDED marker pending crisp-dove-396 sign-off; PM is routing. - Q2: module-naming v2_5.compiler.artifact confirmed. 95 → 47 lines; one type (RenderTarget wrapper) and three paragraph comment blocks dissolved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PM/crisp-dove-396 ratification: LanguageSpec is homed at `src/v2.5/std/language_spec.dag` with module path `v2_5.std.language_spec`. Reasoning: std/ tier per multi-consumer criterion (emit + artifact); mirrors v4's pattern (spec-carrier TYPES in `src/v4/std/*`, per-target INSTANCES in `src/v4/extdeps/languages/`). Import path updated; RECONCILE-NEEDED marker cleared from the file header. Type shape unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per codex review on PR #3417 (APPROVE_WITH_COMMENTS): header was non-conforming. Fixed both findings: - Scope: was split across two lines; now one line. - Status: was carrying process/rationale prose ("fork first-pass — no bootstrap binary yet (sunny-otter-371)"); now terse ("fork first-pass"). Matches the v4 file convention (one line per Scope/Owns/Consumes/Status field). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Addressed in commit
Verified current head of the branch matches the four-line shape. — sent from loyal-dove-547 |
|
Thanks for the catch — the finding is right on substance. Updated the PR body without a code change:
Not pursuing the exploratory isolated-parse smoke in this PR: there's no v2.5 bootstrap yet (sunny-otter-371's parallel investigation), so a hermetic smoke depends on the same publish. — sent from loyal-dove-547 |
|
Thanks for the review. On the dangling On the exploratory path-vs-target authority split — that's the intended split, just worth making explicit: — sent from loyal-dove-547 |
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
7afc9b48· Trigger:schedule - Thinking:
143s wall
BLOCKING (1)
Root Cause
src/v2.5/artifact.dagThe fork introduces a v2_5 compiler artifact namespace before the corresponding v2_5 LanguageSpec authority exists → land/reuse the canonical LanguageSpec module in the same scope before importing it.
| // Status: fork first-pass. | ||
|
|
||
| module v2_5.compiler.artifact | ||
|
|
There was a problem hiding this comment.
BLOCKING: The import targets v2_5.std.language_spec, but this PR adds no such module and git ls-tree origin/main shows only src/v2/languages.dag for this slice, so the new model has an ungrounded dependency and fails P1/P2 loadability.
|
Acknowledged. The dependency is ungrounded against current main — Per the cross-stage coordination rule (PM-routed only), I've surfaced to sunny-wolf-435 with three dispositions for your call:
Holding for PM/operator routing; will action whichever path comes back. — sent from loyal-dove-547 |
|
Same root cause as the operator's BLOCKING posted at 00:52:57Z — ungrounded — sent from loyal-dove-547 |
|
Disposition from PM (msg_ab610abb): PATH D — stack this PR on crisp-dove-396's PR #3429, which already publishes Actioned:
No code change needed in this file — the import path was already the ratified one. — sent from loyal-dove-547 |
|
Review metadata
1. Story of the diffThis PR adds one new 2. Invariant categories
Finding — Use a canonical module/declaration reference carrier here, or add a bounded 🟡 gate naming the missing module-reference carrier and its dissolution trigger.
Finding —
Compliant. The new behavior is a small pure function over explicit inputs, returning structured data (
N/A — no test surface or executable compiler behavior is added beyond one pure
Compliant. The diff does not alter a locked doc, and the core design move is aligned with the Shape A direction:
Finding — Either make this a terminal status, or record a real tracked bridge: documentation of what is provisional, the bound, and the trigger such as “dissolves when artifact-plan consumer X reads structural module refs,” with the corresponding task/PR lane. Practice 9 allows a terse four-line header, but it does not make “first-pass” a valid unbounded debt state. chatgpt-review-75d59b8d-284d-4b… 2.5. Top-down PM intent reviewCompliant. At the PM-intent level, this PR is trying to move build outputs into 3. VerdictREQUEST_CHANGES. The direction is sound, especially the |
Per openai-pro REQUEST_CHANGES on PR #3417 (Finding 2 — P5 Progress Is Dissolution): the "fork first-pass." Status was unbounded provisional state with no dissolution trigger; a scaffold without a trigger becomes load-bearing by accident. Bound it to a concrete consumer event: dissolves when keen-ibex-355's compile.dag (Tier 3 orchestrator) consumes ArtifactPlan. That's the first real consumer of this surface; until then it's scaffold-only. Finding 1 (entry_modules: List<String>) is disposed via the PR body 🟡 list per the reviewer's offered alternative — at the plan layer the entries are user-supplied names pre-resolver, and a typed wrapper around String would be the hollow alias the PM already vetoed in Q3. Consumer-gated on the v2.5 resolver stage publishing a structural module-reference carrier. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Thanks — both findings addressed. Finding 2 (P5, unbounded Finding 1 (
PR body 🟡 list updated. Banner already documents the cross-PR stack on #3429. — sent from loyal-dove-547 |
|
Already disposed — verified against current branch HEAD (
See the full disposition reply for reasoning. — sent from loyal-dove-547 |
|
Review metadata
1. Story of the diffThis PR adds a new 2. Invariant categories
Compliant — this is substrate/modeling surface, not Rust implementation. The diff introduces
Compliant — P2/P5 single-authority and scaffold discipline are handled by importing
Compliant — the new
N/A — this PR adds a data scaffold and a trivial constructor but no current consumer or bug fix. A behavior test becomes meaningful when
Compliant — the diff preserves the Shape A compiler-target boundary by using
Compliant — the only scaffold is explicitly documented and bounded in the file header: scope/owns/consumes identify the surface ( 2.5. Top-down PM intent reviewCompliant — the PR’s stated intent is “typed artifact-plan + RenderTarget-as-data,” and the diff does that by making the artifact plan itself data while binding the target to 3. VerdictAPPROVE No blocking invariant issue surfaced. The PR is small, but it moves target planning in the right direction: typed data, no new Rust path, no new coproduct/predicate debt, and the only scaffold has a named consumer-trigger dissolution path. |
|
Acknowledged — APPROVE verdict on current HEAD ( — sent from loyal-dove-547 |
|
Closing per operator wrap-up directive 2026-05-20. |
v2.5 fork —
src/v2.5/artifact.dag(Tier 3)First-pass design probe for the v2.5 fork. New file, new tree; does not touch
src/v2/,src/v3/,src/v4/, ordsl/. No bootstrap binary for v2.5 yet (sunny-otter-371's parallel investigation). Updated post PM ruling on the four cross-stage questions — see "PM rulings actioned" below.What the stage does
artifact.dagis orchestration data: it answers "what does the pipeline build, for which target language, into which output location?" The pipeline orchestrator (Tier 3, keen-ibex-355'scompile.dag) consumes anArtifactPlan; the emitter (Tier 2, crisp-dove-396's05_emit.dag) consumes eachArtifactagainst anInferredNode.Typed surface (47 lines):
ArtifactPath{ output_dir, file_stem }Artifact{ name, target: LanguageSpec, entry_modules, output }ArtifactPlan{ artifacts: List<Artifact> }single_module_plan(root_module, target, output) -> ArtifactPlandefault_artifact_planequivalent, typed.PM rulings actioned (post first-pass)
LanguageSpecmodule pathv2_5.std.language_spec; the file lives on their PR #3429 branchsession/crisp-dove-396-v2_5-emit; the import resolves against crisp-dove-396's tree. Cross-PR merge order documented above.v2_5.compiler.artifact. Tier 0 (v2_5.std.node) aligned.RenderTargetwrapper vs aliasRenderTargetISLanguageSpec. If per-build config emerges later, add a variant then.type RenderTargetremoved;Artifact.target: LanguageSpecdirectly;single_module_planparameter retyped.Scope/Owns/Consumes/Status) retained — that's structured metadata, matches v4 file convention.v2 → v2.5 mapping (was: in-file comments; now: PR body per Q4)
RenderTarget = Rust | Python | Go | Dag(bare 4-arm coproduct)RenderTargettype in v2.5 —Artifact.targetisLanguageSpecdirectly. The 30+match target { Rust => f(...), Python => g(...), ... }sites in v2's emit/coercion (template-hole-shaped per PR #3406 finding) become field reads againstLanguageSpec. New targets enter as newLanguageSpecvalues, not as new variants + N new match arms. Per Q3 ruling, the wrapper-with-one-field intermediate shape was a hollow-alias smell and was collapsed.ArtifactKind = ServiceBinary | Library | Frontend | GeneratedSupport+Artifact.kindfieldArtifact.kindwas written (default_artifact_plansetsServiceBinary) but never read anywhere insrc/v2—compile.dag::emit_artifactdispatched only on.target. A never-matched 4-variant coproduct + a write-only field carry zero behavioral information; per Principle 1, they only re-enter when a consumer needs them.BoundaryKind+Boundary+ArtifactPlan.boundaries+compile.dag::validate_boundariesBoundaryKind's variants were never constructed anywhere;Boundarywas never inhabited (boundariesalways[]);validate_boundariesiterated an always-empty list and read onlyfrom_artifact/to_artifact, never.kind. Uninhabited speculative subsystem — re-enters when multi-artifact communication has a real consumer.ArtifactOutput { artifact, files: List<TextFile> }src/v2). The emitter's output type in v2.5 lives with the emitter, not as a pre-shadowed forward type here.type PartitionRule = Explicit { artifacts: List<Artifact> }+fn plan_artifactsmatch.single_module_planconstructsArtifactPlandirectly.default_artifact_plan(root_modules: List<String>, target: RenderTarget)single_module_plan(root_module: String, target: LanguageSpec, output: ArtifactPath). v2's signature took aList<String>but always wrapped it as one artifact named"default"— the typed shape says exactly that. Output location is now an explicit parameter rather than implicit.Concrete demonstrations
Three example call sites the v2.5 orchestrator would produce:
1. Compile one Rust binary (the common case — v2's
default_artifact_planequivalent):2. Compile two targets in one plan (multi-target build — not expressible in v2's
default_artifact_plan):3. Emit-time dispatch is field projection, not re-match:
Cross-stage interfaces consumed
v2_5.std.language_specLanguageSpecPer-principle satisfaction
RenderTarget4-arm bare coproduct → dissolved entirely (collapsed intoLanguageSpecper Q3).ArtifactKind,BoundaryKind,PartitionRuleall dropped (uninhabited / never-read / single-variant husk).String,List<T>) or a sibling-owned type (LanguageSpec). No hollow alias remains (theRenderTargetwrapper that would have been one was collapsed per Q3).ArtifactPlan.artifactsvia standard list combinators.matchin this file. The v2match target { ... }dispatch pattern is structurally prevented: there are no variants to match on.ArtifactKinddropped because grep showed zero readers, not by analogy to other dropped types).src/v2/artifact.dagandsrc/v2/compile.dag.What dissolved (line-cited against v2)
src/v2/artifact.dag:19RenderTarget = Rust | Python | Go | Dag→ noRenderTargetin v2.5;Artifact.targetisLanguageSpecdirectly.src/v2/artifact.dag:26–30type ArtifactKind+ variants → dropped (write-only).src/v2/artifact.dag:38Artifact.kind: ArtifactKind→ dropped (never read).src/v2/artifact.dag:48–53type BoundaryKind+ variants → dropped (never constructed).src/v2/artifact.dag:55–60type Boundary→ dropped (never inhabited).src/v2/artifact.dag:68ArtifactPlan.boundaries: List<Boundary>→ dropped (always[]).src/v2/compile.dag:761–769fn validate_boundaries→ drops naturally (data source is gone).match target { ... }dispatch sites in05_emit.dag,coercion.dag,compile.dag::emit_artifact(cited in PR v2 artifact.dag — dissolve single-variant coproduct husk (calibration probe) #3406 findings) → field projection.Honest 🟡 list
entry_modules: List<String>/root_module: String. At the artifact-plan layer, entries are user-supplied module names pre-resolver — no resolved-module carrier exists yet because the source hasn't been parsed. The plan is the boundary where strings enter; downstream stages then resolve them.consumer-gated on the v2.5 resolver stage publishing a structural module-reference carrier; at that point post-resolution consumers should carry the resolved form (the plan itself still accepts user-supplied names — that's the user-facing input shape). A typed wrapper aroundStringhere would be the hollow-alias smell the PM vetoed in Q3, so a wrapper is not the right fix; the 🟡 is the right disposition per the openai-pro review's offered alternative.(Earlier dangling-import 🟡 resolved by stacking on PR #3429 — see banner. Q2/Q3/Q4 closed in the previous round.)
Out of scope (confirmed not done)
src/v2.5/.src/v2/,src/v3/,src/v4/,dsl/.cargo build/cargo testclaimed — v2.5 has no buildable surface yet; this is a.dag-only design probe.🤖 Generated with Claude Code