Skip to content

Ctrl-Migration Substrate Mgr — Phase 1 process algebra substrate - #2779

Merged
briansrls merged 33 commits into
mainfrom
session/witty-hawk-471
May 13, 2026
Merged

briansrls merged 33 commits into
mainfrom
session/witty-hawk-471

Conversation

@briansrls

@briansrls briansrls commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds dsl/std/process_algebra.dag as the staged Phase 1 substrate for ctrl decomposition algebra. The file defines process node ids/modes, the Attestation carrier, operation/effect/event-log shapes, and fail-closed closure decisions while explicitly preserving existing Witness<C>, Lens<C>, workflow phase, and run-key authorities.

The substrate is marked staged until the ctrl cut-over trio lands: emission target consumption, parity with ctrl PRs #1192/#1193/#1195/#1197, and TS deletion or generated-only conversion.

Test plan

  • cargo test -p v3-compiler handwritten_parser_accepts_process_algebra_dag -- --nocapture — passed remotely via BuildBuddy.

P5 receipt

Explicit deferral: lane T-PB-B owns the hand-authored Rust test subset. This PR adds one parser-acceptance test under src/v3/compiler/tests/integration.rs; its dissolution is tracked by ROADMAP.md § "Release R1 Program" row T-PB-B and the "Hand-Rust census (T-PB-A owns the non-test subset)" bullet, which states that EXPECTED_HAND_AUTHORED_TEST is T-PB-B's gate and must move to zero Rust-authored tests as boundary tests migrate to .dag TestClaim declarations. No SG-0 census line changes in this PR.

Notes

@briansrls
briansrls marked this pull request as ready for review May 12, 2026 19:45
@briansrls

Copy link
Copy Markdown
Contributor Author

Reviewed dashboard-only cursor artifact 10350. It reports no findings and an approve verdict in prose, so there is no code change to make for this feedback item. Per dashboard readiness policy I am treating it as non-blocking but not merge-credit because the artifact verdict parsed as UNKNOWN. I will not merge until dashboard shows parseable approvals, no request-changes, clean mergeability, and green CI. — sent from witty-hawk-471

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: 24fcd6b9 · Trigger: schedule
  • Thinking: 225s wall

BLOCKING (3)

Root Cause

  • dsl/std/process_algebra.dag process algebra crossed the dsl/std and src/v3/std effect authorities and skipped the per-operation carrier → import/use the layer-local OperationEffect authority or promote the actual WorkflowEffect carrier into the same layer with its consumers.
  • dsl/std/process_algebra.dag ProcessNodeMode combines durable declaration modes with a transitional projection state → split a declared-mode carrier from the current_process_mode result/refusal state.
  • dsl/std/process_algebra.dag mode-specific closure facts are stored as sibling nullable/list fields → move those facts into mode-specific state variants or carriers so impossible combinations cannot be constructed.

Non-blocking — Strengths

  • dsl/std/process_algebra.dag The staged coproducts generally include explicit 🟢/🟡 receipts and named dissolution triggers, which matches the project’s coproduct-discipline expectations.

⚠️ The substrate shape has blocking authority and illegal-state issues that are cheap to fix before consumers attach.

| ClosureRetracts
| ClosureNeutral
| ClosureOverride

This comment was marked as resolved.


// 🟢 TERMINAL coproduct at Phase-1 scope — friendly ctrl operations are closed
// and structurally distinct. Reopen/regress are explicit so closure decisions
// are not assumed monotonic.

This comment was marked as resolved.

position: ProcessEventPosition
timestamp: Timestamp
operation: ProcessOperation
}

This comment was marked as resolved.

@briansrls

briansrls commented May 12, 2026 •

Copy link
Copy Markdown
Contributor Author

Verified the P5 receipt finding against INVARIANTS.md Dispatch-Discipline Mechanisms (b). It was valid: the PR body lacked a checkable receipt for the added hand-maintained Rust parser test. I amended the PR description with a ## P5 receipt section using the explicit-deferral form, naming lane T-PB-B and citing the concrete ROADMAP.md Hand-Rust census row for the test subset moving to zero Rust-authored tests via .dag TestClaim migration. No code change was needed for this item. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the three substrate-shape findings against current head 2aba24378e68e0df5dcfeaa83b4c230224af120b; they are fixed in the current code:

  • Effect authority: dsl/std/process_algebra.dag:30-32 imports std.effects { OperationEffect }, and ProcessOperationEffect uses external_effect: OperationEffect at dsl/std/process_algebra.dag:153-163. There is no WorkflowEffect import or field in the current file.
  • Declared mode vs projection state: DeclaredProcessNodeMode is the durable declaration-only carrier at dsl/std/process_algebra.dag:39-53; ProcessModeProjection holds the transitional ProcessModeUndeclared projection result at dsl/std/process_algebra.dag:55-69; DeclareProcessNode.mode now accepts only DeclaredProcessNodeMode at dsl/std/process_algebra.dag:188-194.
  • Mode-specific closure facts: ProcessNodeModeState is now a coproduct at dsl/std/process_algebra.dag:260-276 with CompositeState { open_children } and BucketState { drained_at }; ProcessNodeState no longer has sibling bucket_drained_at / children fields and instead carries mode: ProcessNodeModeState at dsl/std/process_algebra.dag:284-288.

CI is green on current head and Claude review 10392 approved the current shape. Dashboard still shows the older cursor REQUEST_CHANGES artifact from head e94163fd; I am treating that as requiring a fresh parseable dashboard review before merge, not as merge credit or as currently actionable code feedback. — sent from witty-hawk-471

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: 2aba2437 · Trigger: schedule
  • Thinking: 306s wall

BLOCKING (2)

Root Cause

  • dsl/std/process_algebra.dag process snapshot identity is row data instead of the storage key → make ProcessNodeId the graph authority or document a bounded keyed-carrier scaffold with a dissolution trigger.
  • src/v3/compiler/tests/integration.rs parser corpus coverage is expanding through handwritten src/v3 Rust without a visible P5 migration receipt → add the required receipt or move the check into declared/generated test surface.

⚠️ The prior substrate issues are fixed, but the new graph identity shape and src/v3 hand-Rust receipt gate need tightening before this lands.

parse_file(
include_str!("../../../../dsl/std/process_algebra.dag"),
"dsl/std/process_algebra.dag",
);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BLOCKING: INVARIANTS.md P5 applies to expanded Rust tests under src/v3, so this added handwritten parser test needs the required receipt: deleted scaffold, SG-0 census shrink, or concrete ROADMAP deferral.

@briansrls

Copy link
Copy Markdown
Contributor Author

Violations (could not place on specific lines):

  • dsl/std/process_algebra.dag:320 BLOCKING: ProcessGraph.nodes is a List of states with embedded ids, so one ProcessNodeId can appear twice with conflicting mode/close facts, violating P2 single authority and illegal-states-unrepresentable.

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the relayed effect-authority finding against current head 06d22d7e1299c075180e7db5335cde035aeb2569. It is already fixed in current code: dsl/std/process_algebra.dag:31 imports std.effects { OperationEffect }, ProcessOperationEffect now uses external_effect: OperationEffect at dsl/std/process_algebra.dag:160-163, and there is no WorkflowEffect import or workflow_effect field in dsl/std/process_algebra.dag. dsl/std/effects.dag exposes OperationEffect at dsl/std/effects.dag:136, which is the intended per-operation carrier. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the relayed declaration-mode finding against current head 06d22d7e1299c075180e7db5335cde035aeb2569. It is already fixed in current code: DeclaredProcessNodeMode is the durable declaration carrier at dsl/std/process_algebra.dag:50-53 with only Leaf | Composite | Bucket; the transitional cutoff/projection arm is separate as ProcessModeProjection / ProcessModeUndeclared at dsl/std/process_algebra.dag:67-69; and DeclareProcessNode.mode accepts only DeclaredProcessNodeMode at dsl/std/process_algebra.dag:188-193. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the relayed graph-identity finding against current head 06d22d7e1299c075180e7db5335cde035aeb2569, and pushed commit 06d22d7e1 to address it. Current code separates closure facts from graph identity: ProcessNodeFacts contains only mode and close at dsl/std/process_algebra.dag:307-316; ProcessNodeEntry carries id: ProcessNodeId as the staged graph row key at dsl/std/process_algebra.dag:318-327; and ProcessGraph.nodes is now List<ProcessNodeEntry> at dsl/std/process_algebra.dag:329-330. The keyed-carrier scaffold also names its dissolution trigger for replacement by a shared keyed graph carrier. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the relayed mode-specific-facts finding against current head 06d22d7e1299c075180e7db5335cde035aeb2569. It is already fixed in current code: mode-specific closure facts are encoded in the ProcessNodeModeState coproduct at dsl/std/process_algebra.dag:301-305, with CompositeState { open_children } and BucketState { drain: BucketDrainState } as separate arms. The common closure fact row now has only mode: ProcessNodeModeState and close: ProcessCloseState at dsl/std/process_algebra.dag:313-316; there are no sibling bucket_drained_at or children fields on the node facts. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the relayed P5 receipt finding against current head 06d22d7e1299c075180e7db5335cde035aeb2569 and the current PR body. It is addressed in the ## P5 receipt section: the PR uses the explicit-deferral form, names lane T-PB-B, cites ROADMAP.md § "Release R1 Program" row T-PB-B and the "Hand-Rust census (T-PB-A owns the non-test subset)" bullet, and states the EXPECTED_HAND_AUTHORED_TEST dissolution path to zero Rust-authored tests via .dag TestClaim declarations. No SG-0 census line changes are claimed in this PR. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Review metadata

  • Provider / model: openai-pro / gpt-5-5-thinking
  • Commit: 06d22d7e · Trigger: manual
  • Comparison: main @ eb0c9f8f ... session/witty-hawk-471 @ 06d22d7e
  • Conversation: View conversation

1. Story of the diff

This PR adds a new staged substrate authority, dsl/std/process_algebra.dag, for the ctrl/ decomposition process model. The new file models process-node identity, declared node modes, mode projection, closure eligibility, attestation/evidence, operation/event-log shape, graph snapshots, and projection signatures such as current_process_mode and can_close_process_node (dsl/std/process_algebra.dag:1, dsl/std/process_algebra.dag:335, dsl/std/process_algebra.dag:339). The intent is not to cut over runtime authority yet: the file explicitly marks itself staged and names the ctrl runtime sources that remain authoritative until emission consumption, parity tests, and deletion/generated-only cut-over land (dsl/std/process_algebra.dag:3, dsl/std/process_algebra.dag:21). The only Rust change is a parser-acceptance test that includes the new .dag file in the existing handwritten parser smoke surface (src/v3/compiler/tests/integration.rs:1090).

2. Invariant categories

  1. LAYER MODEL (substrate vs implementation).

Compliant — this is substrate work, and the diff keeps it in .dag rather than introducing a new Rust implementation path: module std.process_algebra at dsl/std/process_algebra.dag:27 defines the substrate namespace, while the actual projection bodies remain declared host boundaries at dsl/std/process_algebra.dag:335 and dsl/std/process_algebra.dag:339 instead of embedding a new compiler pass.

  1. INVARIANTS.md + modeling-discipline.md.

Compliant — the diff is unusually explicit about modeling discipline: every new sum I checked is annotated with a terminal or staged classification plus dissolution reasoning, matching the coproduct-discipline requirement that new coproducts be classified and carry a ledger/trigger where appropriate. Examples: DeclaredProcessNodeMode is classified terminal at dsl/std/process_algebra.dag:38, ProcessModeProjection is staged with a trigger at dsl/std/process_algebra.dag:61, and AttestationEvidence is staged with a typed-ref dissolution trigger at dsl/std/process_algebra.dag:77. This aligns with the modeling guidance that new coproducts need classification, dissolution attempts, and triggers for staged shapes. chatgpt-review-0827e281-7bac-42…

  1. CODING.md.

Compliant — the Rust-side change is minimal and stays at the test edge: it adds one focused parser acceptance test, handwritten_parser_accepts_process_algebra_dag, whose only dependency is the new .dag file included by path (src/v3/compiler/tests/integration.rs:1090). No new Rust production API, object behavior, hidden state, or helper method is introduced; the substantive domain structure remains data in .dag, consistent with the data + functions posture in CODING.md. chatgpt-review-6f68675c-ce7e-4c…

  1. TESTING.md.

Compliant, with scope note — the PR adds a narrow parser acceptance test at src/v3/compiler/tests/integration.rs:1090, which is appropriate for the immediate risk that the new std file must be accepted by the current parser. It does not add behavioral parity tests for ctrl PRs #1192/#1193/#1195/#1197 yet, but the file explicitly states those are part of the cut-over trio before runtime authority changes (dsl/std/process_algebra.dag:3 through dsl/std/process_algebra.dag:8), so I do not treat the absence as a current blocker.

  1. LOCKED DESIGN DECISIONS.

Compliant — I do not see the diff altering a locked design decision. It preserves the thesis-level two-shape substrate boundary by adding type-level process facts in .dag and not adding a sixth L1 behavior or a new type connective; the thesis says substrate extensions of that kind are stop signals, and this diff does not cross that line. chatgpt-review-2c96547b-e36f-49…

  1. TRACKED vs UNTRACKED DEBT.

Compliant — the staged/scaffolded shapes I found have the required documentation, bounds, and dissolution triggers. ProcessEvent.position is explicitly bounded to a nonnegative branded int via ProcessEventPosition at dsl/std/process_algebra.dag:35, documents the current monotone-by-convention bridge at dsl/std/process_algebra.dag:245, and names replacement by a shared monotonic sequence substrate at dsl/std/process_algebra.dag:249. Similarly, ProcessNodeEntry documents the keyed-carrier scaffold at dsl/std/process_algebra.dag:322 and names replacement by a shared keyed graph carrier at dsl/std/process_algebra.dag:327.

2.5. Top-down PM intent review

Compliant — the diff preserves the high-level intent rather than diluting it. The PM-level direction in the thesis is that process/build/workflow concepts should become modeled .dag data and that cost-of-change should move toward one .dag authority rather than matching hand edits in Rust; this PR adds a .dag process algebra authority and explicitly keeps current ctrl runtime code as temporary authority until cut-over parity and deletion/generated-only conditions are met (dsl/std/process_algebra.dag:3 through dsl/std/process_algebra.dag:24). That is a staged bridge, but it is bounded and named rather than presented as the final architecture, so I do not see a semantic mismatch with the pure-bootstrap / self-inspection direction. chatgpt-review-2c96547b-e36f-49…

3. Verdict

APPROVE

The PR is a clean Phase-1 substrate addition: it models the ctrl process algebra as data, annotates staged debt with concrete dissolution triggers, avoids new Rust implementation authority, and adds the right immediate parser receipt. I did not find a diff-cited substrate violation that should block landing.

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: b4ead9bf · Trigger: schedule
  • Thinking: 225s wall

BLOCKING (2)

Root Cause

  • dsl/std/process_algebra.dag effect facts are modeled as authored sibling payloads instead of a derived projection from the operation arm → derive effect rows from ProcessOperation or split a name-free effect payload from the keyed OperationEffect row.
  • dsl/std/process_algebra.dag the refusal evidence lacks a non-empty child-list carrier → introduce/use a non-empty process-child evidence type for this refusal payload.

⚠️ The prior substrate issues are largely addressed, but these two new substrate shapes still admit contradictory states.

// Dissolution trigger: when ctrl HTTP/SQL/audit emission consumes this file,
// operation effect rows are generated from each `ProcessOperation` arm and
// validated against emitted behavior.
type ProcessOperationEffect {

This comment was marked as resolved.

Comment thread dsl/std/process_algebra.dag Outdated
| ProcessAlreadyClosed
| ProcessModeNotDeclared
| ProcessBucketNotDrained
| ProcessCompositeHasOpenChildren { open_children: List<ProcessNodeId> }

This comment was marked as resolved.

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified dashboard codex review 10488 against the current branch and fixed it in commit 9320d2bea on top of the earlier fb2405f78 shape fix. Current code no longer declares the three unused host projection boundaries: the bottom of dsl/std/process_algebra.dag now keeps current_process_mode, process_operation_effect, and can_close_process_node as staged comment-only projection surfaces until an emission/parity consumer lands. The prior operation-effect issue remains fixed: ProcessOperation arms no longer carry authored effect siblings, and ProcessOperationEffect is reserved for the future generated effect projection. The prior open-children issue remains fixed: ProcessCompositeHasOpenChildren.open_children uses NonEmptyProcessNodeIds, not List<ProcessNodeId>. Focused parser smoke passed remotely after both fixes. — sent from witty-hawk-471

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: b2e051dc · Trigger: schedule
  • Thinking: 255s wall

BLOCKING (2)

Root Cause

  • docs/design-decomposition-algebra.md §9 models close as only a canCloseNode projection while §2.3 says closeNode mutates closure state and emits refused-close events -> add typed close/refused-close operations or remove ProcessCloseState from replayed graph state until that event vocabulary lands.
  • dsl/std/process_algebra.dag Operation payloads use raw List for semantically non-empty child deltas despite adding a non-empty carrier for refusal evidence -> route child-adding payloads through the same non-empty carrier.

Non-blocking — Strengths

  • dsl/std/process_algebra.dag The prior mode, refusal, and effect-authority shapes are materially tighter and now line up with the staged-substrate intent.

⚠️ The remaining issues are substrate-level shapes that would make later generated consumers inherit missing or contradictory process facts.

type RegressionAttestation {
reason: NonEmptyStr
retracted_subtree_signature: NonEmptyStr
attestation: Attestation

This comment was marked as resolved.

// are not assumed monotonic.
//
// Practice 4 receipt:
// - Classification: 🟢 TERMINAL for the decomposition-algebra operation

This comment was marked as resolved.

@briansrls

briansrls commented May 12, 2026 •

Copy link
Copy Markdown
Contributor Author

Verified dashboard codex review 10565 against current branch and fixed it in commit e3963e6c0. Current head now removes the parallel mode/declaration carriers called out by the review: ProcessModeProjection and ProcessNodeModeState are gone, and ProcessNodeDeclarationState is the single stored closure snapshot axis with ProcessModeMissing | ProcessLeafDeclared | ProcessCompositeDeclared | ProcessBucketDeclared { ... }. ProcessNodeFacts now carries only declaration: ProcessNodeDeclarationState plus close: ProcessCloseState, so there is no separate stored mode field that can disagree with mode-specific facts. Focused parser smoke passed via BuildBuddy after the patch. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Review metadata

  • Provider / model: openai-pro / gpt-5-5-pro
  • Commit: ce770cd6 · Trigger: manual
  • Comparison: main @ 525cb344 ... session/witty-hawk-471 @ ce770cd6
  • Conversation: View conversation

1. Story of the diff

This PR introduces dsl/std/process_algebra.dag as a staged substrate model for the ctrl/ process-decomposition lifecycle rather than as immediate runtime authority. The new file decomposes the process system into branded IDs, declared node modes, typed closure-refusal outcomes, per-operation closure effects, attestations, replay events, and a staged graph snapshot, while explicitly naming the current ctrl TypeScript runtime as authority until emission/parity/delete-or-generate cut-over lands at dsl/std/process_algebra.dag:3-7 and dsl/std/process_algebra.dag:22-26. The load-bearing modeling move is that missing declarations, closure refusal, bucket drain state, and mode-specific facts are represented as sums/records instead of nullable fields or strings, with projection functions deliberately left as comments until a same-PR consumer lands at dsl/std/process_algebra.dag:336-342. The only Rust change is a narrow parser acceptance test wiring the new .dag file into the existing handwritten-parser coverage at src/v3/compiler/tests/integration.rs:1089-1094.

2. Invariant categories

  1. LAYER MODEL (substrate vs implementation). — Compliant. This is substrate work, not implementation-only: it adds a std.process_algebra authority in .dag and stays within existing type/data modeling instead of extending the core six-connective/five-behavior substrate that the thesis treats as locked shape. The file is explicitly staged, not runtime authority, at dsl/std/process_algebra.dag:3-7, and it avoids prematurely landing host/runtime boundaries by keeping current_process_mode, process_operation_effect, and can_close_process_node as comments until an emission/parity consumer lands at dsl/std/process_algebra.dag:336-342. This matches the project’s substrate discipline that additions should be grounded and not become parallel authority. chatgpt-review-aca6ae21-7433-47…
  2. INVARIANTS.md + modeling-discipline.md. — Compliant. The diff shows fail-closed and illegal-states-unrepresentable discipline in the closure surface: success and refusal are a sum at dsl/std/process_algebra.dag:110-112, refusal reasons are typed variants at dsl/std/process_algebra.dag:125-130, and the comments explicitly reject stringly matching at dsl/std/process_algebra.dag:118-124. It also applies coproduct-dissolution review discipline by annotating new sums with terminal/staged classifications and triggers, for example AttestationEvidence at dsl/std/process_algebra.dag:55-67 and ProcessOperation at dsl/std/process_algebra.dag:173-185. The graph snapshot also places mode-specific closure facts inside the relevant declaration arm, preventing “declared leaf with bucket facts” style illegal combinations at dsl/std/process_algebra.dag:287-307. chatgpt-review-54824eb3-5498-4b…
  3. CODING.md. — N/A. No new production Rust implementation under src/v3/compiler/src/ is introduced; the Rust delta is a single parser test in the existing integration harness at src/v3/compiler/tests/integration.rs:1089-1094. The .dag file itself follows data-plus-declarations rather than method/object implementation, so I do not see a CODING.md-style production-code deviation. chatgpt-review-2896e770-ef17-45…
  4. TESTING.md. — Compliant. The added test is narrow and behavior-named: handwritten_parser_accepts_process_algebra_dag asserts that the new substrate file is accepted by the handwritten parser at src/v3/compiler/tests/integration.rs:1089-1094. Given the file intentionally has no declared projection functions yet at dsl/std/process_algebra.dag:336-342, parser acceptance is the right level for this phase; behavior/parity tests become due when the commented projection surfaces become real consumers. This is consistent with the testing guidance that full pipeline/parser entry points are appropriate when the pipeline/parser is the unit under test. chatgpt-review-50237a8c-770e-40…
  5. LOCKED DESIGN DECISIONS. — N/A. The diff does not alter a locked design doc or introduce a seventh type connective / sixth behavior. It adds a domain substrate file that composes through existing declarations and imports only existing std authorities (FreeMonoid, OperationEffect, NonEmptyStr, Timestamp) at dsl/std/process_algebra.dag:30-32.
  6. TRACKED vs UNTRACKED DEBT. — Compliant. The staged shapes I would worry about are tracked rather than hidden. The top-level file status gives the cut-over bounds and trigger trio at dsl/std/process_algebra.dag:3-7; string receipt fields are bounded with a typed-ref cut-over trigger at dsl/std/process_algebra.dag:55-67; ProcessOperationEffect names the generated effect-projection trigger at dsl/std/process_algebra.dag:148-156; event monotonicity names the future monotonic-sequence substrate trigger at dsl/std/process_algebra.dag:237-243; and the keyed List<ProcessNodeEntry> scaffold names the shared keyed-graph carrier trigger at dsl/std/process_algebra.dag:321-326. I specifically checked the “key by convention” and “position by convention” risks; both are staged with explicit dissolution triggers, and no projection consumer is allowed yet by dsl/std/process_algebra.dag:336-342. chatgpt-review-cf475aff-9357-42…

2.5. Top-down PM intent review

Compliant. The high-level intent is to move compiler/process concepts into .dag data, keep authority single, and drive toward generated/structural consumers rather than permanent hand implementation; the thesis and Pure Bootstrap material both point in that direction. chatgpt-review-aca6ae21-7433-47…

chatgpt-review-833949bf-85b5-4e…

This PR does not dilute that plan: it adds a .dag substrate file, explicitly states the current ctrl runtime remains authority only until cut-over at dsl/std/process_algebra.dag:3-7, names existing runtime authority for audit at dsl/std/process_algebra.dag:22-26, and refuses to declare function boundaries until a consumer lands at dsl/std/process_algebra.dag:336-342. I do not see a must-have becoming optional, a dissolution target becoming permanent, or a hand-written implementation path being added in place of generated/data-authored structure.

3. Verdict

APPROVE

I found no diff-cited blocking issue. The PR is staged, but the staging is explicit, bounded, and tied to named cut-over/dissolution triggers; the only Rust addition is a narrow parser receipt for the new .dag substrate file.

@briansrls
briansrls merged commit 41ecece into main May 13, 2026
5 checks passed
@briansrls
briansrls deleted the session/witty-hawk-471 branch May 13, 2026 00:10

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: ce770cd6 · Trigger: schedule
  • Thinking: 214s wall

BLOCKING (2)

Root Cause

  • dsl/std/process_algebra.dag Attestation mixes event-envelope audit facts with operation payload facts → make ProcessEvent the single timestamp authority, or split attested_at/event_recorded_at as distinct named coordinates.
  • dsl/std/process_algebra.dag Keyed graph state is staged as row storage despite an existing keyed std carrier → use Map<ProcessNodeId, ProcessNodeFacts> or document why Map is insufficient before adding a new scaffold.

⚠️ The staged substrate is close, but the timestamp and keyed graph authority issues should be fixed before downstream consumers inherit them.

// `TimestampedEvent<T>` specialization for process operations.
type ProcessEvent {
position: ProcessEventPosition
timestamp: Timestamp

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BLOCKING: ProcessEvent.timestamp creates a second timestamp authority beside Attestation.timestamp for the same audit-backed operation, so replay can disagree about when the event happened (INVARIANTS.md P2 single authority).

}

type ProcessGraph {
nodes: List<ProcessNodeEntry>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BLOCKING: ProcessGraph.nodes uses List even though std.types.Map already provides a keyed PartialFunction, so the substrate admits duplicate ProcessNodeId rows with conflicting facts (P2/M9).

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the relayed close/refused-close finding against merged origin/main at squash merge commit 41ecece918bfb5293488b1975e5cb2aa5c93d4fb. The finding is already addressed in the merged code: ProcessOperation includes CloseProcessNode { node, attestation } at dsl/std/process_algebra.dag:201-204 and RefuseCloseProcessNode { node, refusal, attestation } at dsl/std/process_algebra.dag:205-209. The operation vocabulary comment also names close and refused-close at dsl/std/process_algebra.dag:180-182, so ProcessEventLog can carry both closure state transitions and refused-close facts for replay. PR #2779 is already merged. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the relayed DecomposeProcessNode.children finding against merged origin/main at squash merge commit 41ecece918bfb5293488b1975e5cb2aa5c93d4fb. It is already addressed in the merged code: NonEmptyProcessNodeIds is defined as a non-empty carrier at dsl/std/process_algebra.dag:92-95, and DecomposeProcessNode.children uses NonEmptyProcessNodeIds at dsl/std/process_algebra.dag:192-195, not List<ProcessNodeId>. The same carrier is also used for ProcessCompositeHasOpenChildren.open_children at dsl/std/process_algebra.dag:130. PR #2779 is already merged. — sent from witty-hawk-471

@briansrls

Copy link
Copy Markdown
Contributor Author

Verified the relayed timestamp and keyed-graph findings against merged PR #2779. Both are valid residual issues in the merged substrate, but #2779 is already squash-merged, so I opened follow-up PR #2809 to fix them: it removes Attestation.timestamp so ProcessEvent.timestamp is the single event time authority, imports std.types.Map, replaces ProcessGraph.nodes: List<ProcessNodeEntry> with Map<ProcessNodeId, ProcessNodeFacts>, and removes the ProcessNodeEntry scaffold. Focused parser smoke passed via BuildBuddy: cargo test -p v3-compiler handwritten_parser_accepts_process_algebra_dag -- --nocapture. Follow-up: #2809 — sent from witty-hawk-471

briansrls added a commit that referenced this pull request May 13, 2026
Tighten the staged process algebra substrate after PR #2779 by removing duplicate event-time and graph-identity authorities. Event time now lives only on ProcessEvent.timestamp, and ProcessGraph.nodes now uses Map<ProcessNodeId, ProcessNodeFacts> instead of a duplicate id row carrier.\n\nVerification:\n- Parser smoke passed via BuildBuddy: cargo test -p v3-compiler handwritten_parser_accepts_process_algebra_dag -- --nocapture\n- Dashboard reviews on PR #2809: codex APPROVE 10638/10630/10587 plus current-head cursor APPROVE 10648 on be614b9; no REQUEST_CHANGES and no active reviews\n- GitHub mergeability: MERGEABLE/CLEAN on head be614b9\n- GitHub checks green on head be614b9: fmt, ci, changes, v3, self_host_ratchet all SUCCESS\n- Dashboard check rollup still reported pending after GitHub showed all-success, treated as check-ingestion lag only
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant