Skip to content

Tasks.md actionable items - #77

Merged
briansrls merged 124 commits into
mainfrom
cursor/tasks-md-actionable-items-3881
Feb 26, 2026
Merged

briansrls merged 124 commits into
mainfrom
cursor/tasks-md-actionable-items-3881

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

Enhances compiler robustness, improves language feature correctness, and expands testing capabilities with interface stub transport and per-profile test generation.

This PR implements 23 tasks from Lane 1 of the task sheet, focusing on making the compiler more robust by replacing panics with structured errors and ensuring fail-closed behavior for unsupported features. It significantly improves the correctness of DSL language features like string interpolation across different backends and hex escape parsing. Furthermore, it enhances the testing infrastructure by introducing a full interface stub transport and enabling the generation of live tests for specific profiles, leading to better coverage and validation.


Open in Web Open in Cursor 

cursoragent and others added 20 commits February 25, 2026 05:43
- Remove [[bin]] entry for gunbc-review from gunbc-dag/Cargo.toml
  (review.dag has no func items, so codegen doesn't generate it)
- Remove gunbc-dag/tests/review_credentials.rs (depends on missing binary)
- Regenerate core/ir/src/generated/mod.rs to fix staleness test

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…rors

- Add LoweredOp::UnsupportedPattern variant for patterns not yet
  supported in daglang lowering (RetryController, RetryCollector,
  WhileInit, WhileController, PollTimer, PollCollector)
- Replace 6 panic!() calls with structured UnsupportedPattern nodes
  that produce ResolveError at resolution time instead of panicking
- Add resolve_unsupported_pattern_returns_error_not_panic test
- Fix generated types: resolve_symbol now returns &'static str

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…nable-items-3881

# Conflicts:
#	gunbc-dag/tests/review_credentials.rs

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
- Add UnsupportedPattern arms in daglang-lower (obligation_category,
  service_call_metadata, canonical_kind_lowered)
- Add UnsupportedPattern arms in daglang-derive (derive_node_labels,
  derive_module_metadata)
- Add UnsupportedPattern arms in daglang-emit (emit functions,
  collect_symbols, computation classify, rust_exec_runtime)
- Add UnsupportedPattern arm in daglang-cli render_expand
- Merge conflict from origin/main resolved (review_credentials.rs)

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
- Add comprehensive doc comment on SubDagDispatchOp explaining why it
  is #[cfg(test)]-gated and how the production path differs
- Add resolve_lowered_dag_preserves_subdag_structure test that verifies
  the production resolver preserves SubDag structure instead of flattening

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
- Document stage progression contract explicitly in execute() doc comment
- Fail closed on empty current_stage string (wiring bug detection)
- Include valid stage names in unknown-stage error message for diagnostics
- Add test: empty current_stage fails closed
- Add test: last stage next_stage loops to self (terminal self-loop)

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
… method

- Add ServiceOperationSpec::input_fields() and output_fields() methods
  that return the field slices for any variant, eliminating the need
  for 4 near-identical match arms (Rest, Shell, File, Local)
- Simplify service_prepare_ports() to use spec.input_fields()
- Simplify capability_prepare_ports() to use spec.input_fields()
  with non-empty guard (falls back to capability inputs otherwise)

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
- Add LocalRequest/LocalResponse structs to core/ir/src/transport/mod.rs
- Add Local(LocalRequest) and Local(LocalResponse) variants to
  TransportRequest and TransportResponse enums
- Add From impls for LocalRequest/LocalResponse
- Add LocalDirect variant to TransportKind in behavior.rs
- Update GenericLocalPrepareOp to produce TransportRequest::Local
- Update GenericLocalParseOp to handle both Local and Shell (backward compat)
- Add Local arm to transport executor (pass-through: inputs become outputs)
- Add Local arm to VirtualTransportBackend
- Handle Local variant in TransportOps::Execute (extract outputs)
- Add require_local() to TransportResponseExt trait
- Update exhaustive matches in value_expr.rs and contract.rs
- Add tests for LocalRequest/LocalResponse serialization and From impls

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
IS-1: Add InterfaceStub variant to ServiceTransportClass and
ServiceOperationSpec enums. Handle exhaustiveness in daglang-derive
(classify as external target) and daglang-emit computation (ShellExec
transport kind for emit purposes).

IS-3: Replace enforce_profile_for_bound_uses() with
interfaces_needing_stubs() — returns HashSet<String> of interface
types needing stub transport instead of hard-erroring.

IS-5: In resolve_service_call_source(), when active_profile_bindings
is None and interface is profile-bound, try endpoint registry lookup
(stubs registered there) instead of erroring. Return None to let
caller skip if not found.

IS-6: Add InterfaceStubPrepareOp (packages inputs as LocalRequest),
InterfaceStubExecuteOp (errors with 'requires --profile' in Real mode,
auto-mocked in DryRun), InterfaceStubParseOp (identity passthrough).
Wire into resolve_service_transport() with proper routing for all
three phases (prepare/execute/parse).

IS-8 (partial): Add 4 tests for InterfaceStub ops (prepare, skip
propagation, execute error, parse passthrough).

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
- fn_codegen.rs: ServiceCall/Map produce compile_error!() instead of silent comment
- render_c.rs: catch-all inline stmt produces #error directive
- type_codegen.rs: unsupported data value and expr produce compile_error!()

Add tests verifying these paths emit error markers, not silent comments.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…pe semantics

FC-2: Convert Rust-style {} placeholders to target-specific format
specifiers in Go (→ %v via fmt.Sprintf) and C (→ %s via snprintf)
lowerers. Rust backend already uses {} correctly in format!().

FC-3: In type_codegen render_expr_to_rust Record branch, replace
field-name-as-type-context with capitalize_first(name) heuristic
for enum variant qualification (e.g., field 'color' → context 'Color'
instead of raw 'color::Variant').

FC-9: Add proper \xHH hex escape handling to the DSL lexer:
- Interpret \xHH as the byte value (e.g., \x1b → ESC character)
- Malformed \xHH (non-hex digits) preserved literally for diagnostics
- Add 3 deterministic contract tests (byte value, uppercase, malformed)

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
The compile_single_file_bound_interface_requires_profile_flag test
previously expected a hard error when compiling without --profile.
With IS-3, compilation succeeds with stub interfaces for DryRun
testing. Update test to verify successful compilation instead.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
Three lowerer tests previously expected ProfileRequiredForBoundServiceCall
errors when compiling without --profile. With IS-3, compilation succeeds
with stub interfaces for DryRun testing. Tests now verify successful
compilation with non-empty DAG.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
The FC-9 lexer change affects how \xHH sequences are interpreted
in DSL source files, which changes the generated type code.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
Completed tasks (2026-02-25):
- Track B (IS-1..IS-8): Interface Stub Transport — all 8 tasks done
- Track D (FC-1..FC-6, FC-9..FC-11): Fail-Closed Cleanup — 9 tasks done

Remaining planned:
- Track A (NF-1..NF-6): Compile+Link No-Fallback Hardening
- Track C (PT-1..PT-6): Per-Profile Live Tests (deps on IS-8, now unblocked)
- Track D (FC-7..FC-8): Blocked on NF-2
- Track D (FC-14..FC-15): Design-doc-first tasks

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…ilableModule

PT-1: Create profile_discovery.rs with:
- DiscoveredProfile struct (name, module_path, bound_interfaces, test_class)
- discover_profiles(): scans dsl/profiles/*.dag, extracts ProfileDef items
- profiles_for_module(): filters profiles by interface overlap
- TestClass inference: Hermetic for unit_test/test-containing, Integration otherwise

PT-2: Augment CompilableModule in dag_test_discovery.rs:
- Add interface_imports: HashSet<String> field
- Populate from import interfaces.* bindings in collect_dag_files()
- Derive requires_profile as !interface_imports.is_empty() for backward compat

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
PT-3: Add LiveProfileTestConfig struct to TestgenTargetDef with
profile_name, test_class, fermi_cost, required_env, required_any_of,
and dag_builder_call fields. Add live_profile_tests: Vec<LiveProfileTestConfig>
to TestgenTargetDef.

PT-4: Add compile_lowered_with_profile() and build_dsl_graph_with_profile()
to dsl_builder.rs. Threads profile name through CompileOptions so the
lowerer resolves interface bindings via profile bind declarations.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
PT-5: Add build_per_profile_live_flow_sections() to TestGenerator.
Generates one test function per LiveProfileTestConfig entry, named
test_live_flow_{module}_{profile}_profile(), gated by env requirements.
Add live_profile_tests and target_name fields to TestConfig.
Wire sections into the main codegen pipeline after live_flow_tests.

PT-6: Wire profile discovery into build_testgen_graph_auto():
- Call discover_profiles() once at graph build time
- For each module with interface_imports, call profiles_for_module()
  to find applicable profiles
- Populate live_profile_tests in TestgenOp::AutoGenerate
- Remove requires_profile skip filter (IS-3 stubs enable compilation)
- Add live_profile_tests field to AutoGenerate variant

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
Track C (Per-Profile Live Tests) — all 6 tasks complete:
- PT-1: Profile discovery module
- PT-2: CompilableModule interface_imports
- PT-3: LiveProfileTestConfig
- PT-4: build_dsl_graph_with_profile()
- PT-5: Per-profile test sections in codegen
- PT-6: Pipeline wiring

Remaining: NF-1..NF-6 (multi-week), FC-7/8 (blocked), FC-14/15 (design-first)

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
@cursor

cursor Bot commented Feb 25, 2026

Copy link
Copy Markdown

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

cursoragent and others added 9 commits February 25, 2026 10:38
Add compute_reachable_node_ids() that performs BFS from DAG entrypoints
(nodes with no incoming edges) to determine the reachable node set.

Wire reachability filtering into:
- emit_rust_bundle(): skip unreachable nodes when emitting functions
- collect_symbols_with_metadata(): skip unreachable nodes for Go/C/MIPS

This ensures generated code only contains symbols reachable from
entrypoints, so strict -D warnings / -Wall -Werror builds don't fail
on dead emit branches.

Add 2 parity tests verifying reachability computation correctness.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…l slice

Design doc: docs/design/v4/by-construction-reachability.md
- Invariant spec: emitters receive only reachable subgraph
- Failure modes: entrypoint misclassification, edge omission, dynamic subgraphs
- Proof obligations: completeness, soundness, stability
- Migration plan: Phase 1 (pruning, done) → Phase 2 (ReachableDag type) → Phase 3 (remove pruning)
- Contract tests defined

Vertical slice: ReachableDag<T> in core/ir/src/dag.rs
- Wrapper type that structurally guarantees only reachable nodes
- from_dag() computes BFS from entrypoints, slices nodes + edges
- Exported from gunbc_ir
- 4 contract tests: exclusion, full preservation, edge filtering, determinism

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…ipeline

- Lexer: add Extern keyword token with keyword mapping
- AST: add ExternFuncDecl and ExternAssetDecl structs and Item variants
- Parser: parse 'extern func' and 'extern asset' declarations
- Typecheck: validate types in extern declarations, check for duplicates
- Lowerer: add ExternCall { symbol } variant to LoweredOp
- Resolver: return link-required error for ExternCall nodes
- Handle new variants in all exhaustive match sites
- Add tests for lexer, parser, and resolver

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…call_metadata

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
FC-14: Dead-path pruning emit variant (reachability analysis)
FC-15: By-construction reachability design doc + ReachableDag vertical slice
NF-1: Extern DSL surface (lexer, parser, typecheck, lowerer scaffolding)

Remaining planned: NF-2..NF-6 (symbol model, linker, migration, deletion, determinism) and FC-7/FC-8 (blocked on NF-2)

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
Introduce the compile+link symbol model per the design doc:

- ProgramSymbolId: canonical program symbol identity (module::name)
  with deterministic ordering, hashing, and From impls
- IntrinsicOp: enum for compiler-primitive operations (FsEnv,
  ParamSource, LiteralSource, file I/O, patterns, transport phases)
- OpRef: classifies each op as Intrinsic/Call/Extern/Unresolved
- SymbolTable: collects defined and extern symbols from a DAG,
  with unresolved_externs() for the link step (NF-3)

Lowerer integration:
- LoweredOp::classify_op_ref() maps each variant to OpRef
- build_symbol_table() walks a DAG and builds the SymbolTable

8 tests: 4 in core/ir (symbol model), 4 in daglang-lower (classify + table)

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
Add linker module to core/ir with:

- Backend trait: resolve_extern_func() and resolve_extern_asset()
  methods for extern symbol resolution
- ResolvedExternFunc/ResolvedExternAsset: resolution result types
- LinkError: MissingExternFunc/MissingExternAsset with deterministic
  diagnostic ordering (sorted by symbol name)
- link(): takes SymbolTable + Backend, resolves all externs or fails
  hard with deterministic error list
- EmptyBackend: no-op backend for testing link errors
- LinkResult: collected resolutions + diagnostics

4 tests: success, hard error, deterministic ordering, empty table

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
Add PrimitiveOpKind::ContentUpsertOutputPath { path } variant that
explicitly annotates output path nodes in content_upsert patterns.

extract_output_paths() now checks for ContentUpsertOutputPath first
(explicit metadata), with legacy content_upsert_path_ substring check
as fallback for backward compatibility.

The lowerer creates annotation nodes alongside path literal sources
so output paths are discoverable without ID substring matching.

Handle exhaustiveness for the new variant in computation, exec runtime,
and resolver.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
Make extract_file_contents() fail-closed for unexpected schemas:
- Map items missing 'content' key: return error description with key list
- Unexpected value types in list: return error description with discriminant
- Non-list file_contents value: return error description

Previously these returned empty strings, silently hiding schema mismatches.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
briansrls and others added 10 commits February 26, 2026 13:43
…fication

Add NodeKind enum to Node<T> with 9 variants (TransportExecute, TransportPrepare,
TransportParse, ToolEnvironment, ToolConsumer, ResourceEnvironment, ResourceAcquire,
ResourceRelease, Pure). The lowerer stamps every node via stamp_node_kinds() and all
downstream consumers read node.kind directly — zero fallback heuristics remain.

Key changes across 20 files:
- Phase 1: NodeKind enum + kind field on Node<T> with with_kind() builder
- Phase 2: obligation_to_node_kind() + stamp_node_kinds() in daglang-lower
- Phase 3: Executor reads node.kind (should_intercept_by_kind, classify_node_role)
- Phase 4: Delete EffectKind, rewrite classify_effect() to use node.kind
- Phase 5: Replace type_id.0 == heuristics in codegen, test, derive crates
- Phase 6: Stamp hand-built graphs (patterns, resolve.rs) + all test nodes

Eliminates ~30 duplicated type_id string checks across 8 crates. The only
remaining type_id checks are in obligation_to_node_kind() (the definition site),
a parity comparison utility, and data-level port inspection (Credential lookup,
FilesystemHandle mock selection).

https://claude.ai/code/session_01Jo1rmbehYNhfpTf86KCUJX
…odes

The prior NodeKind commit treated kind: None as non-effectful, which
silently skipped interception and resource validation for hand-built
DAGs. Instead of adding a structural fallback (violating the no-silent-
fallback invariant), this adds a pre-flight check that errors loudly
when a kind: None node has port patterns indicating it should have been
classified (TransportRequest inputs, ToolHandle ports, resource ports).

Changes:
- Add validate_node_kinds_for_interception() with looks_effectful_without_kind()
  heuristic that detects kindless nodes with effectful port patterns
- Call the validation at execute_flat() and execute_single_node() entry
  points when mode is DryRun or Simulate
- Update Node.kind doc comment: remove "falls back to port heuristics"
  promise, document that all effectful nodes must have kind set
- Update classify_effect doc comment for clarity
- Fix 4 existing tests that used kindless effectful nodes in DryRun/
  Simulate by adding .with_kind() calls
- Add 7 new tests covering the validation: reject kindless transport,
  tool consumer, tool environment, resource environment nodes; accept
  pure kindless and classified transport nodes; dry_run end-to-end

https://claude.ai/code/session_01Jo1rmbehYNhfpTf86KCUJX
The validate_node_kinds_for_interception() pre-flight check is a runtime
safety net. The target state is making kind: None on effectful nodes
structurally impossible by requiring NodeKind in Node constructors.

https://claude.ai/code/session_01Jo1rmbehYNhfpTf86KCUJX
Replace port-type heuristics with NodeKind classification
@briansrls
briansrls marked this pull request as ready for review February 26, 2026 21:07
@briansrls
briansrls merged commit 7b5e746 into main Feb 26, 2026
1 check failed
briansrls added a commit that referenced this pull request May 9, 2026
…om cluster-analysis audit + today's merges (#2399)

Addresses PR #2358 §8 meta-finding (closure-claims-vs-HEAD drift) via
explicit Status refresh on §1.8 rows. Cluster-analysis audit on main
(PR #2300 / docs/audit/r3-cluster-analysis-2026-05-09.md §1) identified
9 gates likely-promotable from DECLARED → CONSUMER_LANDED + named
specific PRs as evidence. Today's session adds 1 more (#92 via PR #2340).

Per cluster-analysis audit §1 closing note: "PM surface, not authoring:
ledger refresh is Mgr-owned per docs/r3-program-plan.md §10 cadence.
This list is input to next refresh cycle."

PM (deep-wolf-155) interpretation: Mgr-cadence-discipline holds, but
the cluster-analysis was published 2026-05-09T03:25Z + at least 9 gates
are mechanically derivable from PR-history. Authoring this sweep as
PM-tier signal-into-next-refresh; lane Mgrs review their lane's rows
in this PR before merge.

**Updates** (10 candidates):

| Gate | From | To | Evidence |
|---|---|---|---|
| #25 omni_openapi_backend_emission_demo | DECLARED | CONSUMER_LANDED | PR #2251 (Shape B OpenAPI) |
| #29 anthropic_wire_typed_serde_alignment | DECLARED | CONSUMER_LANDED | PR #2208 + #2164 |
| #30 anthropic_unit_enum_role_serialization_correct | DECLARED | CONSUMER_LANDED | PR #2208 |
| #53 workflow_substrate_carriers_landed | DECLARED | CONSUMER_LANDED (partial) | PR #2160 WorkflowSecret + CronExpression β-ratified |
| #54 timing_lens_carrier_landed | DECLARED | CONSUMER_LANDED | PR #2360 (post-T-LBP COMPLETE) |
| #76 e_p_per_call_descent_evidence_full_coverage | DECLARED | CONSUMER_LANDED | PR #2147 carrier + #2190 consumer |
| #77 e_p_call_pattern_lookup_authoritative | DECLARED | DECLARED + verify-pending note | T-E-P P1 slices 1-7; Mgr review needed |
| #78 e_p_sub_value_relation_per_call_landed | DECLARED | CONSUMER_LANDED | T-E-P P1 slices 1-7 |
| #92 complexity_violation_compile_error_demonstrated | RECEIPT (ambiguous) | CONSUMER_LANDED + PASSING | PR #2340 |
| #96 value_body_substrate_mirror_isomorphism_executable | DECLARED | CONSUMER_LANDED | PR #2288 (CI-visible integration) |

Each cite includes PR# + brief evidence summary. #77 retained as
DECLARED with verify-pending note (cluster-analysis audit said
"verify"; Mgr review recommended before promotion).

**Verification**: R4-carve dissolution discipline ratchet still passes
(32 citations, all properly annotated). No new drift introduced.

**Mgr review path**: Substrate Mgr (warm-wolf-698) reviews #29/#30/#53/
#54/#76/#77/#78/#96 lane rows. Verification Mgr (wise-bear-525) reviews
#92/#96 lane rows. Grounding Mgr (sunny-koi-893) reviews #25 lane row.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 10, 2026
Second assert_eq repeated the same lookup call; it did not exercise
idempotency (review feedback on PR #2533).

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request May 14, 2026
briansrls added a commit that referenced this pull request May 14, 2026
* Ratchet call pattern lookup authority

* Document gate 77 P5 receipt

* WIP: R3 gate #77: e_p_call_pattern_lookup_authoritative (T-E-P-Producer-Broad

* Fix gate 77 generated cost include
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.

3 participants