Skip to content

Add transport middleware pipeline with retry, rate limit, and metrics - #104

Merged
briansrls merged 14 commits into
mainfrom
claude/slack-plan-lane-five-QkE2i
Mar 1, 2026
Merged

briansrls merged 14 commits into
mainfrom
claude/slack-plan-lane-five-QkE2i

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

Summary

This PR introduces a comprehensive middleware infrastructure for the transport layer, enabling cross-cutting concerns like automatic retry with exponential backoff, rate limiting with token bucket/sliding window algorithms, circuit breaker protection, and observability through metrics collection.

Key Changes

  • Middleware Infrastructure (middleware/mod.rs): Core trait-based middleware system with TransportMiddleware trait, MiddlewareContext for request metadata, and PostProcessOutcome for handling retries/aborts.

  • Retry Middleware (retry.rs):

    • Automatic retry for transient failures (5xx, network errors, rate limits)
    • Configurable backoff strategies: Fixed, Exponential, and ExponentialJitter
    • Circuit breaker state machine (Closed → Open → HalfOpen) to prevent cascading failures
    • Safety checks: only retries idempotent or readonly operations by default
  • Rate Limit Middleware (rate_limit.rs):

    • Token bucket and sliding window rate limiting algorithms
    • Per-scope rate limit tracking (e.g., "github:core", "github:search")
    • Respects Retry-After headers from 429 responses
    • Headroom tracking for metrics
  • Metrics Middleware (metrics.rs):

    • Pluggable MetricsSink trait for metrics collection
    • Built-in implementations: NullMetricsSink, LogMetricsSink, InMemoryMetricsSink
    • Records request/response timing, retry attempts, rate limit headroom, and error classifications
  • Pipeline Composition (pipeline.rs):

    • TransportPipelineBuilder for composing middleware layers
    • TransportPipeline for executing requests through the middleware stack
    • Standard pipeline builder that automatically configures metrics, rate limit, and retry based on config
    • Proper request/response flow: outer→inner on request, inner→outer on response
  • Classification Integration (classify.rs):

    • New classify_for_middleware() function for middleware to classify responses
    • Helper functions: extract_status_code(), is_success()
    • Supports both HTTP and non-HTTP transport types

Notable Implementation Details

  • Safety-First Retry: Non-idempotent operations require explicit configuration to retry, preventing accidental duplicate operations
  • Circuit Breaker: Protects against cascading failures with configurable thresholds and recovery probes
  • Flexible Rate Limiting: Supports multiple algorithms and respects provider-specific rate limit headers
  • Composable Metrics: Metrics sink is pluggable, allowing integration with various observability systems
  • Deterministic Jitter: Exponential jitter uses deterministic calculation for reproducibility in tests
  • Proper Middleware Ordering: Metrics (outermost) → rate limit → retry → execute, ensuring correct timing and classification

All middleware is fully tested with comprehensive unit tests covering success paths, error conditions, and edge cases.

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS

claude added 14 commits March 1, 2026 01:34
Adds production-ready middleware for the transport layer:

- TL-8: MetricsSink trait + LogMetricsSink/InMemoryMetricsSink for observability
- TL-3: classify_for_middleware() integration hook for middleware decisions
- TL-1: Rate limit middleware with token bucket + sliding window algorithms
- TL-2: Retry middleware with exponential/jittered backoff + circuit breaker
- TL-9: TransportPipeline composition (metrics → rate_limit → retry → execute)
- TL-10: Verified IR transport types already complete

Core middleware infrastructure (153 tests pass):
- TransportMiddleware trait with pre_request/post_response/on_error hooks
- MiddlewareContext carrying operation metadata through pipeline
- SharedMiddlewareState for cross-request coordination

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
Implements credential middleware for the transport pipeline:

- CredentialCache with thread-safe storage per cache_key
- TTL tracking with proactive refresh at configurable threshold (default 80%)
- CredentialProviderFn type for pluggable credential acquisition
- Automatic credential application to REST requests requiring auth
- Fail-closed behavior when no credential available

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
Added TL-0 task capturing the foundational type work completed:
- TransportClass enum (Rest, Shell, File, Grpc, Stream, Pubsub, Custom)
- TransportCapabilities struct (connection_pooling, retry_safe, etc.)
- EndpointBehavior enum (RateLimited, Cacheable, Idempotent, etc.)
- OperationBehavior struct (readonly, idempotent, hermetic + config)

These types in lib/transport/src/transport_types.rs provide the
foundation for the remaining TL middleware tasks.

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
This implements task C20 from tasks.md (RT59, RT63), enabling:

1. **available_profiles in CompileOutput** - Extracts profile names from
   `profile` declarations during compilation and exposes them in the
   compile output for downstream use.

2. **--profile enum flag generation** - When a tool has available_profiles,
   the CLI generator adds a --profile param with validation against the
   known profile names. Invalid profiles exit with an error listing valid
   options.

3. **ToolMeta.available_profiles** - New field and builder method to wire
   profile info through the registry to CLI generation.

Key changes:
- daglang-driver: Add collect_available_profiles() and expose in CompileOutput
- cli_gen.rs: Add generate_profile_block() and update arg parsing
- registry.rs: Add available_profiles field and builder method

Tests added for both profile flag presence and absence.

Note: --mode (verify/ensure) and subcommand dispatch were already
implemented. This completes the remaining profile support needed
to unblock Worker A binary elimination tasks.

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
C20 (CLI generator: profile, mode, subcommand support) has been
implemented. Added to completed historical section and marked
with strikethrough in the Worker C table.

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
- TokenBucket/SlidingWindow: Add explicit pause_until field for Retry-After
  handling instead of manipulating tokens/refill math (avoids instant bursts
  and Instant underflow panics)

- Credential: Fall back to cached token if proactive refresh fails instead
  of throwing error; fix TTL math by storing total_ttl at creation time

- Retry jitter: Use true random via RandomState instead of deterministic
  formula based on attempt number (prevents thundering herd)

- Circuit breaker: Only trip on Server/Network errors, not Client errors
  like 404s which are the caller's fault

- Metrics: Use unique request_id instead of operation_id as HashMap key
  to prevent collision when concurrent requests have same operation_id

- Circuit breaker: Add in_flight counter to HalfOpen state to prevent
  thundering herd when transitioning from Open (only one probe at a time)

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
- Pass has_profiles flag to generate_graph_builder_call so the profile
  selection flows through to DAG construction via selected_profile.as_deref()

- Add profile_block generation to build_subcmd_run_fn so subcommand
  functions also validate and extract the --profile flag

- Step mode functions (run_full_dag, run_single_step, list_dag_steps)
  explicitly pass has_profiles=false since they're for CI step execution

- Add C21 task for KEY=VALUE and multi-value flag support (required for
  A5/infra.rs elimination) - this was part of original C20 scope but
  not yet implemented

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
Pipeline middleware cleanup:
- Track layers_completed_pre count during pre_request phase
- Call cleanup_layers() when inner layer aborts or short-circuits
- Ensures outer layers (metrics, rate_limit) clean up state on early exit
- Fixes memory leak where metrics HashMap entries were never removed

Rate limiter race condition:
- Wrap sleep/acquire in a loop with MAX_ACQUIRE_ATTEMPTS=10
- Prevents thundering herd where all threads wake simultaneously and
  only one gets the token while others immediately abort
- Failed acquisition after sleep now retries instead of aborting

TL-0 transport foundation types:
- Create lib/transport/src/transport_types.rs
- TransportClass enum (Rest, Http, Shell, File, Tcp, Grpc, Stream, etc.)
- TransportCapabilities struct (pooling, retry_safe, streaming, etc.)
- EndpointBehavior enum (RateLimited, Cacheable, Idempotent, etc.)
- OperationBehavior struct (readonly, idempotent, hermetic flags)
- FailureMode enum for declaring known failure modes

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
Pipeline layer ordering (critical):
- Swap retry/rate_limit order so rate_limit is inner (closer to executor)
- RateLimit now sees 429 responses first, updates pause_until from
  Retry-After header, then passes response to outer Retry layer
- Fixes: rate limit state never updated when retry consumed 429

Err branch cleanup bypass:
- Add cleanup_layers() call when inner layer transforms error to Retry
- Mirror the Ok branch's cleanup logic for symmetry
- Fixes: metrics timing leaked on network retry

Synthetic cleanup error guards:
- MetricsMiddleware::on_error: skip record_error for "pipeline cleanup"
- RetryMiddleware::on_error: skip circuit breaker trip for cleanup errors
- Fixes: bogus telemetry and circuit breaker corruption

Provider error shape parsing (TL-3):
- Add ProviderDiagnostics struct capturing all provider-specific fields
- GitHub: message + documentation_url
- GCP: error.message + error.status + error.code
- Anthropic: error.message + error.type + top-level type
- OpenAI: error.message + error.type + error.code
- Expose parse_provider_error() for richer diagnostics

is_success() fix:
- File responses now check r.success field instead of always true
- Aligns with FileResponse::success semantics

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
Design doc: docs/design/transport-primitives.md
- Proposes rate_limit, retry, circuit_breaker, credential as DSL patterns
- Consistent syntax with loop/branch/upsert primitives
- Phased migration: DSL syntax → IR lowering → domain data → emit → elimination

Tasks added to Worker C:
- C22: DSL syntax for transport blocks
- C23: IR lowering to TransportMiddlewareConfig
- C24: Domain data migration (rate limits from Rust to .dag)
- C25: Emit transport logic per target language
- C26: Delete lib/transport/ middleware (goal state)

Rationale: transport concerns should be language-agnostic DSL constructs,
not Rust runtime code. Enables emit to Go/C/MIPS without reimplementing.

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
Design doc updated with clear What/How distinction:
- Domain policy (What) → .dag — "GitHub rate limit is 5000/hour"
- OS mechanisms (How) → Target SDK — "How do I atomically decrement?"

Phase 1 (TL-0:10): Build domain-agnostic Rust middleware (token bucket,
retry loops, credential cache). This is the "runtime library" — it handles
mutexes, clocks, sockets. It knows config values, not service names.

Phase 2 (TL-11:15): Move domain data from Rust to .dag. Rate limit budgets,
error shapes, retry policies live in service definitions. Compiler generates
configuration code that links to Target SDK. Same .dag → Rust/Go/Python.

This follows Protobuf/gRPC pattern: schema in IDL, runtime per language,
compiler generates glue code.

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
P0-3: File is_success() test
- Added explicit test for File failure (success=false)
- Fixed misleading comment that said "File always success"
- Code was already correct, just test coverage was missing

P1-4: Metrics error classification
- Added classify_exec_error() heuristic for ExecError messages
- Now detects auth/rate_limit/client/server errors from message content
- Falls back to Network for connection/timeout issues

P1-5: Rate limit division-by-zero
- Added safe defaults: if sustained_per_minute=0, use 1/hour minimum
- Added safe defaults: if max_burst=0, use 1 token minimum
- Prevents infinity/NaN in wait time calculation

P1-6: Circuit breaker non-HTTP failures
- Fixed: circuit breaker now checks is_success() for non-HTTP transports
- Shell exit code 1 and File success=false now trip the circuit breaker
- Previously these were silently treated as success

P1-7: Docs/code mismatch
- Updated pipeline.rs and middleware/mod.rs docs
- Clarified: standard pipeline is metrics → retry → rate_limit (no credential)
- Added note about manually adding credential layer

P0-2 (pipeline post-hook semantics) deferred - requires larger refactor
to thread outcome through all post-hooks without early-return.

https://claude.ai/code/session_01DwRsV4WNLUPLdv6Y4ucaGS
@briansrls
briansrls merged commit deb9106 into main Mar 1, 2026
1 check failed
briansrls added a commit that referenced this pull request May 12, 2026
…ss dissolution gate per Director ratification msg_915aa2c1) (#2804)

* docs(r3): §1.8 row #104 — lens_read_witness_shape_dissolved (Miss-class dissolution gate)

Director ratification msg_915aa2c1 (b-with-refinements disposition) ratifies §1.8 row #104 addition with:
- 2-part predicate (Part A terminal `git grep -nE "Lookup<" src/v3/lenses/ src/v3/std/ ; expected = 0` + Part B regression `git grep -nE "::Miss\b" src/v3/compiler/src/lens_*_generated.rs ; expected = 0`)
- Bundled-migration shape (Substrate primary + Testgen companion, NOT one)
- Status progression refinement (CONSUMER_LANDED requires BOTH brief authored ≥3 lens carriers AND ≥1 universal-coverage TestClaim landed)
- Lane T-Lens-Behavioral-Parity (cross-lens read-channel discipline)

Scope at HEAD (Director-grep msg_cefcbe05): 64 sites across cost.dag (25) + complexity.dag (25) + substrate.dag (3) + lookup.dag (11). Parallelism + effect_enumeration + timing_lens .dag layers already clean (0 sites).

Authority chain: operator directive 2026-05-11 (audit §0) + audit §3.1/§3.4 + design-lens-framework.md:51,326,382-384 + design-emission-model.md:958,1206 + R4.D §4 (WISHLIST.md:147).

Canvas-framing relayed to Substrate Mgr per Director ratification: Q-MissOrError + Q-WhyTestgenMissed + bundled-migration shape. Brief authoring in their Wave-2 queue.

Gate-count canonicalization updated: 103→104 enumerated; 102→103 R3-load-bearing; composition total 87+16+1=104; all references swept.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): sweep remaining "102" → "103" load-bearing references (claude #10514 finding)

claude review #10514 (APPROVE_WITH_COMMENTS) caught 4 stale "102 R3-load-bearing" references the initial sed sweep missed:
- :88 "forward-looking R3 close target is 102"
- :114 "**102** R3-load-bearing gates green"
- :335 "R3-load-bearing §1.8 lane gates GREEN (102 load-bearing..."
- :624 "R3-load-bearing §1.8 gates GREEN (**102** load-bearing..."

All 4 updated to 103. INVARIANTS P2 single-authority within the same doc — gate-count must be consistent across all references.

Remaining "102" references are legitimate gate IDs (#102 `slow_test_exemptions_dissolved` itself) — not stale counts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 12, 2026
… predicate 64→70 across 6 files)

codex BLOCKING on merged PR #2804 (review 4276876807 @ 23:10:31Z):
"The row scopes the migration from a relayed count instead of deriving
it from its own terminal grep predicate → include every current Part A
match in the phase plan, or explicitly narrow the predicate and route
the excluded Lookup< sites to a separate gate. ⚠️ One blocking scope
gap in the new closure gate would leave the terminal predicate red
after the documented migration."

Verified at `7a7c19d3` HEAD: `git grep -nE "Lookup<" src/v3/lenses/
src/v3/std/` = 70 matches (NOT 64 as Director's relay msg_cefcbe05 had it):
- cost.dag: 25
- complexity.dag: 25
- infer_helpers.dag: 3 (incl. active `-> Lookup<DeclarationId>` :141)
- algebra.dag: 3 (incl. canonical `miss_symbolic_cost_lookup()` :225
  + `hit_symbolic_cost_lookup` :229)
- substrate.dag: 3
- lookup.dag: 11

Critical: `algebra.dag:225 miss_symbolic_cost_lookup()` is THE
constructor at the bind layer that emits the 15 Miss returns
Director's complexity-lens dump (msg_32a3775e) originally surfaced —
it being out-of-scope contradicted the row's own Origin statement.

Fixes:
1. Scope at HEAD: 64 → 70 across 6 files (was 4); added
   `algebra.dag` 3 + `infer_helpers.dag` 3.
2. Bundled-migration Phase 2 reframed as "monomorphized accessor
   sweep" (substrate 3 + algebra 3 + infer_helpers 3 = 9 sites; line
   anchors added).
3. Origin trailer: appended PR #2807 scope-correction note + codex
   BLOCKING #4276876807 attribution; flagged msg_cefcbe05 as superseded.

Part A terminal predicate unchanged; the migration plan now matches it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 12, 2026
… (64→70) + cursor #10531 shell-escape + :205 arithmetic (PR #2804 merged before any fix landed) (#2807)

* docs(r3): fix shell-escape artifact + arithmetic drift (cursor #10531 APPROVE_WITH_COMMENTS)

cursor review #10531 (APPROVE_WITH_COMMENTS) caught 2 small fixes:

1. **:330 Origin field** — literal `Director'\''s` shell-escape artifact (leaked from heredoc authoring) → corrected to `Director's`. P1 documentation-faithfulness.

2. **:205 parenthetical** — "was 97; +6 T-WAD FULL R3 elevation" only sums to 103, not the headline 104. Added "+1 Miss-class dissolution 2026-05-12" so arithmetic reconciles: 97 + 6 + 1 = 104. P2 single-authority consistency.

Both small fixes; no scope change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): row #104 — codex BLOCKING #4276876807 scope-gap fix (Part A predicate 64→70 across 6 files)

codex BLOCKING on merged PR #2804 (review 4276876807 @ 23:10:31Z):
"The row scopes the migration from a relayed count instead of deriving
it from its own terminal grep predicate → include every current Part A
match in the phase plan, or explicitly narrow the predicate and route
the excluded Lookup< sites to a separate gate. ⚠️ One blocking scope
gap in the new closure gate would leave the terminal predicate red
after the documented migration."

Verified at `7a7c19d3` HEAD: `git grep -nE "Lookup<" src/v3/lenses/
src/v3/std/` = 70 matches (NOT 64 as Director's relay msg_cefcbe05 had it):
- cost.dag: 25
- complexity.dag: 25
- infer_helpers.dag: 3 (incl. active `-> Lookup<DeclarationId>` :141)
- algebra.dag: 3 (incl. canonical `miss_symbolic_cost_lookup()` :225
  + `hit_symbolic_cost_lookup` :229)
- substrate.dag: 3
- lookup.dag: 11

Critical: `algebra.dag:225 miss_symbolic_cost_lookup()` is THE
constructor at the bind layer that emits the 15 Miss returns
Director's complexity-lens dump (msg_32a3775e) originally surfaced —
it being out-of-scope contradicted the row's own Origin statement.

Fixes:
1. Scope at HEAD: 64 → 70 across 6 files (was 4); added
   `algebra.dag` 3 + `infer_helpers.dag` 3.
2. Bundled-migration Phase 2 reframed as "monomorphized accessor
   sweep" (substrate 3 + algebra 3 + infer_helpers 3 = 9 sites; line
   anchors added).
3. Origin trailer: appended PR #2807 scope-correction note + codex
   BLOCKING #4276876807 attribution; flagged msg_cefcbe05 as superseded.

Part A terminal predicate unchanged; the migration plan now matches it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 13, 2026
…ape (b) FileAttachment extending #53 per Director msg_09df44c6 (#2821)

* docs(r3): fix shell-escape artifact + arithmetic drift (cursor #10531 APPROVE_WITH_COMMENTS)

cursor review #10531 (APPROVE_WITH_COMMENTS) caught 2 small fixes:

1. **:330 Origin field** — literal `Director'\''s` shell-escape artifact (leaked from heredoc authoring) → corrected to `Director's`. P1 documentation-faithfulness.

2. **:205 parenthetical** — "was 97; +6 T-WAD FULL R3 elevation" only sums to 103, not the headline 104. Added "+1 Miss-class dissolution 2026-05-12" so arithmetic reconciles: 97 + 6 + 1 = 104. P2 single-authority consistency.

Both small fixes; no scope change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): row #104 — codex BLOCKING #4276876807 scope-gap fix (Part A predicate 64→70 across 6 files)

codex BLOCKING on merged PR #2804 (review 4276876807 @ 23:10:31Z):
"The row scopes the migration from a relayed count instead of deriving
it from its own terminal grep predicate → include every current Part A
match in the phase plan, or explicitly narrow the predicate and route
the excluded Lookup< sites to a separate gate. ⚠️ One blocking scope
gap in the new closure gate would leave the terminal predicate red
after the documented migration."

Verified at `7a7c19d3` HEAD: `git grep -nE "Lookup<" src/v3/lenses/
src/v3/std/` = 70 matches (NOT 64 as Director's relay msg_cefcbe05 had it):
- cost.dag: 25
- complexity.dag: 25
- infer_helpers.dag: 3 (incl. active `-> Lookup<DeclarationId>` :141)
- algebra.dag: 3 (incl. canonical `miss_symbolic_cost_lookup()` :225
  + `hit_symbolic_cost_lookup` :229)
- substrate.dag: 3
- lookup.dag: 11

Critical: `algebra.dag:225 miss_symbolic_cost_lookup()` is THE
constructor at the bind layer that emits the 15 Miss returns
Director's complexity-lens dump (msg_32a3775e) originally surfaced —
it being out-of-scope contradicted the row's own Origin statement.

Fixes:
1. Scope at HEAD: 64 → 70 across 6 files (was 4); added
   `algebra.dag` 3 + `infer_helpers.dag` 3.
2. Bundled-migration Phase 2 reframed as "monomorphized accessor
   sweep" (substrate 3 + algebra 3 + infer_helpers 3 = 9 sites; line
   anchors added).
3. Origin trailer: appended PR #2807 scope-correction note + codex
   BLOCKING #4276876807 attribution; flagged msg_cefcbe05 as superseded.

Part A terminal predicate unchanged; the migration plan now matches it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): §1.8 row #62 status refinement — gate #62 file-ingestion ratified shape (b) FileAttachment carrier extending #53

Director ratification msg_09df44c6 on canvas PR #2820 + §4.3 line 505 verbatim authority. Disposition (b) wins per:
- §4.3 line 505 explicitly names "T-Workflow-As-Data file-ingestion substrate (workflow_substrate_carriers_landed extended to file-attachment)" as closure path
- Lane fit: gate #62 is T-WAD per §1.8; carrier extension is canonical T-WAD pattern
- Sibling-carrier precedent: WorkflowSecret + CronExpression in #53 establish the pattern
- Construction-first: model workflow concept, not compile-time intrinsic
- No parallel-authority: (a)+(b) coexistence violates §P1 single-authority

Status: DECLARED → DECLARED-with-ratified-shape-and-sub-canvas-pending. Sub-canvas (FileAttachment carrier-shape: type def + fields + workflow-context coupling) queued for Substrate Mgr per recursive feedback_substrate_shape_belongs_in_mgr_canvas. Worker dispatch follows sub-shape ratification.

PR #2819 STAND DOWN per Director disposition (msg_09df44c6); bright-otter-731 audit (msg_e85224dc) preserved as diagnostic-trail input.

Anti-patterns enumerated for post-ratification reviewers:
- Compile-time read_utf8_file-equivalent (Candidate A drift)
- FileAttachment landed without #53 sibling-carrier alignment
- Legacy include_str! bridges preserved alongside FileAttachment (§P5 atomic-migration violation)

include_str! audit at HEAD (Director-verified): no matches — gate is forward-looking, not retire-existing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): §1.8 row #62 — carrier-internals Refined-B-1 ratified (Director sub-canvas disposition msg_61e302c6)

Director-ratified FileAttachment carrier-internals shape per msg_61e302c6 on PR #2820 sub-canvas (commit 4a96d33). Status: DECLARED-with-ratified-shape-and-sub-canvas-pending → DECLARED-with-ratified-shape-and-carrier-internals-ratified.

Refined-B-1 carrier (5-of-7 strict subset of #55 WorkflowObservationAnchor):
  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 verbatim from Director:
- Q1 carrier shape: Refined-B-1 (B-2 + B-3 disqualified)
- Q2 encoding field: ABSENT default; if needed use `Encoding` from `dsl/std/encoding.dag`
- Q3 `WorkflowAssetPath` branded nominal: NOT introduced (digest-only canonical)
- Q4 workflow-coupling: deferred to worker brief / consumer evidence (#55 List analogy)
- Q5 eager-vs-lazy: EAGER confirmed
- Q6 `AttachmentEncoding`: Practice-4 RED — dissolved to existing `Encoding` lattice

Director grep-verified at HEAD: #55 anchor structure at timing_lens.dag:98-106, 5 branded nominals at dsl/std/types.dag:324-331, dsl/std/encoding.dag exists with 6-variant `Encoding` BoundedLattice, no FileAttachment/AttachmentEncoding/WorkflowAssetPath at HEAD (no parallel-authority risk).

Anti-patterns extended from 3 (top-level) to 7 (sub-canvas additions):
- (4) AttachmentEncoding duplicating dsl/std/encoding.dag — Practice-4 RED dissolution
- (5) path field on FileAttachment — parallel-rep vs canonical digest
- (6) List<FileAttachment> on Job/Step preemptively — consumer-evidence-required
- (7) Carrier deviation from Refined-B-1 5-field structure — strict subset of #55

Cascade:
- Sub-canvas closure: carrier-internals ratified
- Worker brief authoring: 5-field carrier + sibling-alignment receipt + bootstrap ratchet test + existence-proof use case
- Sub-canvas-2 trigger (forward-looking): workflow blob-store substrate (content_digest -> bytes resolution); Substrate Mgr authors after Refined-B-1 lands; NOT blocking carrier-internals ratification

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 13, 2026
…ep (operator BLOCKING on PR #2824:85 INVARIANTS P2)

Operator briansrls flagged at `docs/r3-program-plan.md:85` that PR #2824
introduced "105 enumerated" while the same §1.5 block still said "104
gate IDs" and "103 R3-load-bearing arithmetic", creating competing
authorities (INVARIANTS P2).

PR #2824's prior commit message claimed a header count sweep but the
diff only updated SOME of the count sites, leaving 10 lines internally
inconsistent. This commit completes the sweep.

Lines updated (all 104→105 / 103→104 where the count was a TOTAL or
LOAD-BEARING reference, not a row-number reference):

- §1.5 line 84: "104 gate IDs enumerated at this commit" → "105 gate IDs"
- §1.5 line 86: "103 R3-thesis = 104 − 1" → "104 R3-thesis = 105 − 1"
- §1.5 line 88: "forward-looking R3 close target is 103" → "104"
- §1.5 line 90: "Total: 87 + 16 + 1 = 104" → "Total: 87 + 16 + 2 = 105"
  (the +2 represents #104 + #105 routed to T-Lens-Behavioral-Parity +
  T-CostLens-Composition respectively; kept in trailing tail vs
  lane-incorporated to preserve the 2026-05-12 lane-breakdown snapshot's
  audit shape)
- §1.5 line 96: "103 R3-thesis = 104 − 1 = 103" → "104 = 105 − 1 = 104"
- §1 line 114: "103 R3-load-bearing gates green" → "104"
- §1.7 line 125: "DECLARE 104 closure gates" → "105"
- §1.8 line 338: "103 load-bearing" → "104"
- §2 line 627: "103 load-bearing" → "104"
- §Q-table line 805: "104 closure gates total" → "105"

Lines NOT updated (correct references to row numbers, not count totals):
- Lines 8, 84, 88, 90, 98, 108, 111, 148, 239 references to gates
  #98-#103 (T-WAD FULL R3) and gate #104 (Miss-class) and gate #105
  (cost-textbook) — these are row-number references, not totals
- §1.8 line 331/332 row entries (gate #103 ci_uses_affected_set,
  gate #104 lens_read_witness_shape_dissolved) — row identifiers

INVARIANTS P2 single-authority restored across §1.5 / §1.7 / §1 close
criteria / §2 close criteria / §Q-table.

Lesson: header-count sweep PRs MUST grep-verify every occurrence of
the prior counts before claiming the sweep is complete. PR #2824's
prior commit message overstated coverage; operator caught.

— sent from deep-wolf-155
briansrls added a commit that referenced this pull request May 13, 2026
…gle-authority parity with §1.8 (operator BLOCKING on PR #2824:207 INVARIANTS P2)

Operator briansrls flagged at `docs/r3-program-plan.md:207` that PR #2824
claims "the 105-gate ledger is consolidated with r3-structure.md" but
the diff doesn't update r3-structure.md, leaving #105 without the
canonical acceptance body that line 340 says lives there.

Audit found the gap is wider than #105 alone — gate #104
(`lens_read_witness_shape_dissolved`, added 2026-05-12 in a prior PR)
is also missing from r3-structure.md §Acceptance. Same INVARIANTS P2
single-authority violation class.

Fixed both in PR #2824 (cleanest bundle — same gap class, both rows
added to §Acceptance in their canonical lanes):

- **#105 `symbolic_cost_textbook_coverage_landed`** added to
  T-CostLens-Composition lane (after `cost_lens_reads_target_realization`
  + `coercion_cost_equals_complexity_by_construction`). Encodes Path A
  Tier 1 carrier extension shape (PolynomialCost{degree: Rational} +
  PolyLogCost + ExponentialCost + FactorialCost) + Tier 2 R4-deferral
  + structural-extension caveat + two-part predicate (Part A carrier
  landed + Part B algebra rules pass). Cross-refs §1.8 row #105 for
  full receipt + 5 sub-canvas substrate-shape questions.

- **#104 `lens_read_witness_shape_dissolved`** added to
  T-Lens-Behavioral-Parity lane (after `lens_capability_register_zero_
  proxy_zero_stub`). Encodes bundled-migration shape per Director
  ratification msg_915aa2c1 — (1) substrate-level Miss→Violates
  collapse across 70 sites in 6 files (cost.dag/complexity.dag/
  infer_helpers.dag/algebra.dag/substrate.dag/lookup.dag); (2)
  testgen-level universal-coverage TestClaim. Two-part predicate
  (Part A terminal + Part B regression guard). Cross-refs §1.8 row
  #104 for full receipt.

INVARIANTS P2 single-authority restored: §1.8 ledger ↔ §Acceptance
canonical body now in parity at gate-ID level for all 105 enumerated
gates (104 R3-load-bearing post-canvas-deferral).

Lesson logged: when adding §1.8 rows, r3-structure.md §Acceptance
must update in same PR. Prior PR #2824 commit message did not
include this discipline; #104's prior PR also missed it. Class
violation traceable to: section-anchor authoring discipline that
prevents the missing-mirror class.

— sent from deep-wolf-155
briansrls added a commit that referenced this pull request May 13, 2026
…h A Tier 1 per Director msg_ad5e934d) + §1.2/§1.5 interrogation probe refinement (#2824)

* docs(briefs): R3 CI Layer 2 — PM pre-staged Mgr-fill template

Author the pre-staged Mgr-fill reference doc Director accepted via
msg_4623068b at 22:54Z (greenlight on PM's pre-staged-skeleton offer
from gunbc#828 c4425726922). Director will cite this file in their
forthcoming worker brief (`docs/briefs/r3-ci-layer-2-path-conditional-
gating-worker.md`) as the starting template for Verification Mgr
(clever-tern-670) inventory finalization.

Content:
- §1 affected-set lens Dimension enum reference (cite design doc §2)
- §2 slow-test inventory grouped into 9 clusters (78 entries from
  scripts/slow-test-exemptions.txt)
- §3 path-mapping skeleton table — (test_pattern, dimension,
  required_paths_regex, confidence, dissolution_note). PM partial-
  fills high-confidence rows; ~12 [Mgr-fill] placeholders left for
  rows requiring deeper substrate-lens / consumer-tracing knowledge
- §4 open questions for Mgr (multi-dim split, conservative defaults,
  pilot cluster selection — recommended Cluster B = Lane 2 Stage 2d
  symbolic cost; high-confidence single-dimension contained module)
- §5 acceptance checklist for Mgr-fill completion
- §6 STOP triggers (new substrate carrier need; dimension outside
  enum; test-output dependency = lens not bridge)
- §7 cross-refs (Layer 1 PR #2718, lens canvas PR #2713, routing
  msg_a77c7f42, memory feedback_parallel_representation_debt)

Hard constraint per feedback_parallel_representation_debt: every row
carries a dimension: field matching the lens Dimension enum so post-
dissolution skip_* flags compute structurally as
`affected_dimensions.contains(group.dimension)` — same enum,
structural source. Prevents path-mapping schema divergence from
future lens API surface.

Dissolution trigger: gate
ci_uses_provable_minimal_affected_set_selection (R3 close-blocking;
docs/design-affected-set-lens.md §5). When the lens lands, this
template + the worker output are deleted.

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — dimensions is Set<Dimension>, not single primary (codex REQUEST_CHANGES fix on PR #2721)

codex REQUEST_CHANGES on PR #2721 (review #9707) caught a semantic-
contract violation: the template asserted "every entry carries exactly
one primary `dimension:`" and post-dissolution `skip_*` computation as
`affected_dimensions.contains(group.dimension)`. This conflicts with
the locked design at `docs/design-affected-set-lens.md` §2:

  affected_set(Dag_before, Dag_after) =
    ⋃ over dim in {Value, Cost, Complexity, Effect, Refinement}
      affected_set(Dag_before, Dag_after, dim)

A test that reads BOTH Cost AND Complexity (e.g., D-cluster LBP
demonstration; lane2_stage_2f composed-matches-lens) would be silently
skipped when only Complexity changes if its dimension is narrowed to
"Cost." That's `INVARIANTS.md` P2 single-authority violation against
the locked lens design.

Fixes:
- §1: rewrite from "exactly one primary dimension" to "dimensions is
  Set<Dimension> = full read-set; affectedness is union semantics"
- Header bullet: hard constraint reframed — multi-dim REQUIRED when
  consumer reads multi; post-dissolution math is `(affected ∩ row.dimensions) ≠ ∅`
- §3 table: column rename `dimension` → `dimensions`; rows updated:
  - D-cluster LBP, lens_cost_target_realization, cost_lens_consumer:
    expanded to multi-dim sets [Complexity, Cost], [Cost, Value]
  - lane2_stage_2f_dimension: [Complexity, Cost] (composed-matches-lens)
  - F-`m0_acceptance` + I-`thesis_validation_test`: full 5-dim set
    (compile-boundary + thesis-level read every dim)
  - G-`t_las_crdt_cost_basis_demo`: [Cost, Effect, Value]
  - G-`r3_free_consequences_second_batch`: [Cost, Value]
  - H-`t_ci_workflow_as_data_demo`: [Value, Cost] (DimensionReport timing)
  - All single-dim rows (A, B, Most-C, etc.): formatted as set `[Cost]`
- §4 Open question 1: rewrite to forbid narrowing, mandate ADD-when-doubt
- §5 acceptance: add dim-set-semantics + union-formula checks
- §6 STOP triggers: add "tempted to narrow set → STOP and EXPAND"

Director's Layer 2 brief at PR #2719 has the same singular-`dimension:`
shape and likely has the same finding waiting to surface; will flag to
Director after this lands.

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template count + wording fixes (cursor BLOCKING #9719 on PR #2721)

cursor BLOCKING REVIEW on PR #2721 (review #9719 at dedcf69) caught
factual count discrepancies + the stale singular `dimension` echo
that openai-pro had flagged as non-blocking:

1. Cluster A banner — was "(~10)", actual sum = 1+6+2+6 = 15 → fixed to "(15)"
2. Cluster B individual-row count "6" while listing 7 names → fixed to 7;
   banner "(~6)" → "(7)"
3. emit_matrix Notes "5× emit matrix sweep" while listing 6 tests
   (3 module + 3 program) → fixed to "6× emit matrix sweep (3 module
   + 3 program)" for explicit attribution
4. Cluster D banner "(~5)", actual sum = 2+3+2+2 = 9 → fixed to "(9)"
5. Line 7 (Purpose) stale singular `(test_pattern, dimension,
   required_paths_regex)` echo → fixed to `dimensions` plural;
   converges with openai-pro APPROVE_WITH_COMMENTS observation (review
   #9714) that had been deferred to follow-up — cursor's BLOCKING
   verdict overrides the deferral

§4 Open question 5 (pilot recommendation) also corrected from
"~6 tests" to "7 tests" for Cluster B consistency.

Clusters C/E/F/G/H/I banner counts re-verified against table sums
(7/12/6/10/7/5 respectively) — all already exact, no change needed.

P1 Modeling Faithfulness restored: every cluster banner now matches
its enumerated tests-column sum.

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — fix skip_<cluster> polarity (openai-pro BLOCKING #9721 on PR #2721)

openai-pro re-review on PR #2721 at sha 93080af caught a critical
boolean polarity inversion in the skip_<cluster> formula. A Mgr/worker
following the brief literally would have wired the CI gate backward,
silently skipping affected tests — TESTING.md "test selection must
not skip affected behavior" violation + Boundary Discipline violation
(boolean carrier name and contract encoded opposite meanings).

**The bug**: 4 places stated post-dissolution `skip_<cluster>` formula
as `(affected_dimensions ∩ group.dimensions) ≠ ∅` (skip when
intersection NON-empty), while the CI consumer wires
`if: skip_<cluster> != 'true'` (run when skip is NOT true). Combined:
when intersection is non-empty (= affected), skip=true → tests don't
run → affected tests silently skipped.

**The fix**: invert the formula to `(intersection = ∅)` (skip when
intersection IS empty = no affected dim that this cluster reads). The
CI gate semantics stay the same; the polarity correction is on the
post-dissolution lens mapping.

Sites corrected:
- §1 hard-constraint para (line 9): replaced "(non-empty intersection
  means run)" with an explicit Boolean polarity block defining
  `skip = (intersection = ∅)` and equivalent `run = (intersection ≠ ∅)`
- §3 path-mapping intro (was line 132, now 142): same polarity fix
  + "Equivalently: `run = (intersection ≠ ∅)`"
- §4 open-question 4 (was line 186, now 196): "skip_<cluster> becomes
  `(intersection ≠ ∅)`" → `(intersection = ∅)` with explicit
  "same polarity: skip when no affected dim" note
- §5 acceptance (was line 206, now 216): same polarity fix +
  explicit "inverting the polarity silently skips affected tests" warning

All 4 references now consistent. Polarity table:
  intersection = ∅  → skip=true  → "do not run" (NOT affected, safe to skip)
  intersection ≠ ∅  → skip=false → "run" (affected, must run)

Director's brief #2719 likely has the same polarity issue and will need
parallel fix from the same authority chain. Flagging separately.

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — cluster aggregation + path-regex verification discipline (codex BLOCKING on PR #2721)

codex BLOCKING review on PR #2721 at sha 262f42d caught two
substantive gaps:

**(1) Cluster aggregation predicate missing**: §3 defined per-row
intersection check but didn't specify how multi-row clusters
aggregate to the cluster-level `skip_<cluster>` boolean. A worker
following the brief could implement disjunction (any-row-empty
= skip cluster) which would silently skip the OTHER affected rows
in the cluster when only one row is unaffected.

Fix: explicit conjunction predicate in §3 + §4 + §5 + §6:
  skip_<cluster> = ∀ row ∈ cluster : (changed_files ∩ row.regex) = ∅
Equivalently: run_<cluster> = ∃ row ∈ cluster : row affected.

**(2) Path regexes PM-authored without source-tree verification**:
PM concrete `required_paths_regex` values in §3 were manually
authored from the inventory SHA references without validation
against actual paths in the source tree. Workers might wire CI
gates against stale paths.

Fix: explicit Mgr-verification discipline in §3 + §4 + §5 + §6:
- Workers MUST validate each concrete regex against source tree
  at HEAD before CI implementation
- Unverified or unverifiable regexes → `.*` per conservative
  fail-closed default
- Confidence column treated as audit priority (low → `.*` first,
  medium → audit then decide, high → audit but likely fine)
- Validation record kept (PR description or commit message)

Both fixes preserve the locked-design polarity from earlier
revisions:
- Per-row formula stays `(intersection = ∅)` for skip semantic
- Cluster aggregation is conjunction over rows (∀)
- Run formula is the structural complement (∃ ↔ ≠ ∅)

All 4 places updated: §3 path-mapping skeleton intro + §4 mechanism
+ §5 acceptance + §6 STOP triggers. Brief now structurally
guards against:
- polarity inversion (skip = ∅, not ≠ ∅; openai-pro caught prior)
- dimension cardinality narrowing (Set<Dimension>, not single; codex
  caught prior)
- cluster aggregation by disjunction (∀, not ∃; codex caught this)
- regex authoring without source-tree validation (codex caught this)

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — fix stale dsl/std/ lens-paths (codex BLOCKING inline at line 152)

codex BLOCKING inline-review at line 152 (sha 262f42d) caught
that Cluster B's regex used stale `dsl/std/lens_cost.*\.dag` +
`dsl/std/cost.*\.dag` paths while the live cost-lens authority
is at `src/v3/lenses/cost.dag`. A change to the live authority
file would NOT match the stale regex → skip_b=true → cost-lens
tests silently skipped (P3 fail-closed + P2 single-authority
violation).

**Systematic audit + fix**: stale `dsl/std/<lens>.dag` pattern
applied across many rows (PM authored assuming lens .dag lived
in dsl/std/, but the live tree has them at src/v3/lenses/):

| Row | Old (stale)                                    | New (verified)                                                 |
|-----|------------------------------------------------|----------------------------------------------------------------|
| B   | dsl/std/lens_cost.*.dag + dsl/std/cost.*.dag   | src/v3/lenses/cost(_target_realization)?.dag                   |
| C-i | dsl/std/lens_idempotency.*.dag                 | src/v3/lenses/idempotency.dag                                  |
| C-p | dsl/std/lens_provenance.*.dag                  | src/v3/lenses/(provenance\|emission_provenance).dag            |
| C-u | dsl/std/lens_unused_parameters.*.dag           | src/v3/lenses/unused_parameters.dag                            |
| E×4 | dsl/std/(complexity\|cost\|symbolic_cost).*.dag | src/v3/lenses/(complexity\|cost).dag                           |
| F-b | dsl/std/boolean_algebra.*.dag                  | dsl/std/logic.dag (boolean-algebra concepts live there)        |
| G-c | dsl/std/complexity.*.dag                       | src/v3/lenses/complexity.dag                                   |
| G-l | dsl/std/(cost\|las\|crdt).*.dag                | `.*` (Mgr-fill; T-LAS substrate-deps not PM-traced yet)        |
| H-2 | dsl/std/parse.*.dag                            | src/v3/std/parse_surface.dag + src/v3/compiler/parse_tables.dag|
| H-2c| dsl/std/parse_tables.*.dag + dsl/std/tokenize  | src/v3/compiler/parse_tables.dag + src/v3/(compiler\|std)/tokenize.dag |
| H-w | dsl/std/workflow.*.dag                         | src/v3/std/workflows.dag                                       |

Confidence column dropped from `high` to `medium` for all
post-correction rows — Mgr should still validate each path
against live source tree at HEAD before CI implementation per
the verification-discipline added at d19a1a0. dissolution_note
column carries inline "**Path correction**: ..." annotations
documenting each fix for reviewer audit.

Cross-cluster bug-class catches now mapped on this template:
1. Dimension cardinality (Set<Dimension>; dedcf69)
2. Boolean polarity (skip = ∅; 262f42d)
3. Count discrepancies + line-7 singular (93080af)
4. Cluster aggregation predicate (∀ not ∃; d19a1a0)
5. Path-regex verification discipline (d19a1a0)
6. **Stale dsl/std/ lens-paths corrected to src/v3/lenses/** (this fix)

Brief structurally validated across 6 distinct axes.

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — fix regex alternation escape (openai-pro APPROVE_WITH_COMMENTS on #2721)

openai-pro APPROVE_WITH_COMMENTS on PR #2721 at sha 45fc195 caught
a non-blocking regex error: line 185 had `src/v3/(compiler\|std)/tokenize.dag`
with `\|` (markdown-cell pipe escape), which a regex engine would
interpret as the literal string `compiler|std`, NOT as alternation
between `compiler` and `std`.

Mechanism of the bug:
- Markdown tables use `|` as column separator
- To put a literal `|` IN a cell (outside backticks), you escape with `\|`
- PM authored the regex with `\|` thinking the markdown-table escape
  was needed, but the regex is INSIDE backticks (code span) which
  preserves pipe character literally
- A worker copying the regex into ci.yml would silently miss
  tokenize.dag changes (only matches literal `compiler|std/tokenize.dag`)

Fix: drop the unnecessary `\` escape; markdown code spans preserve
`|` literally. Now regex correctly reads
`src/v3/(compiler|std)/tokenize.dag` — alternation between
src/v3/compiler/tokenize.dag and src/v3/std/tokenize.dag, both of
which exist per the source tree verified at 45fc195.

Mitigation: the template's own validation discipline at §3 + §5 §6
(workers MUST validate regex against live source tree before CI
implementation) would have caught this, but per openai-pro's read
"the concrete row should still not carry a known-bad example" — fair.

Cumulative bug-class catches on this template now 7 axes hardened:
1. Dimension cardinality (Set<Dimension>; dedcf69)
2. Boolean polarity inversion (skip = ∅; 262f42d)
3. Count discrepancies + line-7 singular (93080af)
4. Cluster aggregation predicate (∀ not ∃; d19a1a0)
5. Path-regex verification discipline (d19a1a0)
6. Stale dsl/std/ lens-paths corrected (45fc195)
7. Markdown-cell-escape leaking into regex semantics (this fix)

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — Dimension enum is OPEN per design §2 + THESIS user-defined dims (codex BLOCKING on PR #2721)

codex BLOCKING inline-review at line 186-ish caught that my §6 STOP
trigger hard-rejected any `dimensions:` element outside the built-in
base set `{Value, Cost, Complexity, Effect, Refinement}` — which closes
the user-extensibility surface that THESIS + docs/design-affected-set-
lens.md §2 leave intentionally open with the trailing `...`.

Verification (codex was correct):

- `docs/design-affected-set-lens.md` §2: `⋃ over dim in {value, cost,
  complexity, effect, refinement, ...}` (note ellipsis = open enum)
- `THESIS.md` "User-defined dimensions" section: 'User-declared
  dimensions extend the same structural proof surface ... the ceiling
  of what gunbc can prove is user-extensible.'

The built-in base set ≠ the full enum. My template was treating them
as equivalent, which would have rejected valid user-defined dims at
the STOP gate (INVARIANTS P1 single-authority violation against
THESIS/design + P3 fail-closed violation since rejection-instead-of-
fail-closed is the opposite of safety).

Fixes:
- **§1** Dimension enum reference: rewrote with explicit `Dimension =
  {value, cost, complexity, effect, refinement, ...}` notation + the
  trailing `...` annotated as "OPEN for user-defined" + paragraph on
  THESIS user-extensibility framing + explicit instruction to treat
  unknown dim as fail-closed (always-run), NOT reject
- **§5** acceptance criterion: updated to reference the open enum +
  fail-closed-for-unknown behavior
- **§6** STOP trigger: now reads "cannot be carried as a typed
  Dimension at all (e.g., string-as-dimension, runtime-only)" — that's
  the genuine structural failure. Encountering a NEW user-defined
  dimension is NOT a STOP; it's a row carried as fail-closed-always-run

Cumulative bug-class catches on this template now 8 axes hardened
(was 7 before this fix; ci-skip-pattern-script wasn't applicable here):
1. Dimension cardinality (Set<Dimension>; dedcf69)
2. Boolean polarity inversion (skip = ∅; 262f42d)
3. Count discrepancies + line-7 singular (93080af)
4. Cluster aggregation predicate (∀ not ∃; d19a1a0)
5. Path-regex verification discipline (d19a1a0)
6. Stale dsl/std/ lens-paths corrected (45fc195)
7. Markdown-cell-escape leaking into regex semantics (7cbf29f)
8. **Dimension enum hard-closed rejecting user-defined** (this fix) —
   THESIS + design doc §2 explicitly leave open

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — carry user-defined Timing dim explicitly (codex BLOCKING on PR #2721)

codex BLOCKING re-review at sha c61a7ed line 197 (~193 in their
relay) caught a narrowing residual after the prior open-enum fix:
the `t_ci_workflow_as_data_demo_test` row carried `[Value, Cost]`
but the test actually evaluates `DimensionReport<TimingMeasurement>`
/ `ci_modeled_timing` — a user-defined Timing dim distinct from
generic Cost.

My prior open-enum fix (c61a7ed) updated §1/§5/§6 to ALLOW user-
defined dims but I didn't fix THIS row to USE one. Per the just-
established 'carry the dim, don't narrow' framing in §6, this row
should carry `[Value, Cost, Timing]` (or just `[Value, Timing]` if
Cost is sufficiently distinct from Timing in the test).

**Why it's load-bearing**: a future timing-only delta (e.g.,
DimensionReport schema change touching only timing fields, not Cost)
would be 'affected' for this test under the lens but the prior row
narrowed Timing → Cost → if Cost.affected = empty but Timing.affected
non-empty, test would be silently skipped (TESTING.md violation +
THESIS user-defined-dims framing violation).

Fix:
- Row dimensions: `[Value, Cost]` → `[Value, Cost, Timing]`
- Row dissolution-note: explicit annotation citing
  `DimensionReport<TimingMeasurement>` + `ci_modeled_timing` user-
  defined dim + the carrying-vs-narrowing rationale
- Self-references this template's own open-enum support per §1 —
  the row is now an in-table demonstration of the open-enum framing
  (consistency between framing and example)

This also re-stress-tests cluster aggregation: cluster H aggregates
over multiple rows including this Timing-carrying row, so cluster-
level skip computation correctly fail-closes when ANY row's dim
intersects with affected_dims.

Cumulative bug-class catches on this template now 9 axes hardened:
1. Dimension cardinality (Set<Dimension>)
2. Boolean polarity inversion (skip = ∅)
3. Count discrepancies + line-7 singular
4. Cluster aggregation predicate (∀ not ∃)
5. Path-regex verification discipline
6. Stale dsl/std/ lens-paths corrected
7. Markdown-cell-escape regex
8. Dimension enum hard-closed (open per THESIS)
9. **Narrowing user-defined dim to built-in** (this fix; carry don't normalize)

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — codify 3-arm regex completeness invariant (mirror Director PR #2727 worker-brief discipline)

Director's PR #2727 absorbed Brian inline + codex BLOCKING convergent
finding on post-#2719 fail-open hole: per-group regex must include
THREE arms — deps + test-source + fixture — missing any is a
P3 fail-open boundary class.

This template (PR #2721) had the same structural issue: most PM-
authored rows have arms (1) deps + (2) test-source but lack arm (3)
`tests/dag/*.dag` fixture explicitly. Per Director's canonical
worker-brief discipline (PR #2727), this mirrors the gap and adds
the 3-arm completeness invariant to align.

Updates:
- §3 path-mapping intro: explicit 3-arm completeness invariant + per-
  arm fail-open semantics + audit note that PM-authored rows in §3
  below need Mgr fixture-arm audit for tests reading from
  `tests/dag/*.dag` (e.g., `t_pb_b_1_dag_runner_test` consumes
  `tests/dag/t_pb_b_1_*.dag`)
- §5 acceptance: new checklist item — every concrete regex includes
  arms (1) + (2) + (3) where applicable; Mgr-fill rejects missing
  arms 2/3
- §6 STOP triggers: two new STOP triggers for missing test-source
  arm OR missing fixture-arm-when-applicable
- Cross-link to Director PR #2727 / #2719 for canonical framing

This codifies but does NOT retrofit existing §3 rows — that's
Mgr-fill audit work (per the §3 disclaimer + Mgr-fill discipline).
PM signals the gap; Mgr fixes per row.

Cumulative bug-class catches on this template now 10 axes:
1. Dimension cardinality (Set<Dimension>)
2. Boolean polarity inversion
3. Count discrepancies + line-7 singular
4. Cluster aggregation predicate (∀ not ∃)
5. Path-regex verification discipline
6. Stale dsl/std/ lens-paths
7. Markdown-cell-escape regex
8. Dimension enum hard-closed (open per THESIS)
9. Narrowing user-defined dim (Timing→Cost)
10. **Missing test-source/fixture arms in regex** (this fix mirroring
    Director PR #2727 worker-brief discipline)

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — restore `...` ellipsis in quoted §2 union formula (cursor APPROVE_WITH_COMMENTS-level exploratory on PR #2721)

cursor APPROVE review #9858 at sha 5c227c5 noted an exploratory
inconsistency: my quoted design-doc §2 union formula at lines 48-51
enumerated only the 5 built-in dimensions without the trailing `...`
that the actual `docs/design-affected-set-lens.md` §2 has, while my
surrounding text (lines 27-33, §1 enum reference) stresses the open-
enum framing.

Fix: restore the `...` in the quoted formula + add inline annotation
'← OPEN per §2; user-defined dims extend' so Mgr-fill readers can't
misread the box as closed.

Now lines 27-33 (open-enum framing) + lines 48-51 (formula quote) +
§5 acceptance + §6 STOP triggers all consistently affirm the open-
enum framing per THESIS user-defined dimensions.

Non-blocking exploratory observation; quick fix because the cost is
trivial (1-char + comment) and the value is internal-consistency
preservation.

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): Layer 2 template — add test-source arm to 4 rows violating own 3-arm invariant (codex BLOCKING on PR #2721)

codex BLOCKING REQUEST_CHANGES at sha 8f11a35 caught my OWN 3-arm
completeness invariant being violated by 4 rows that ship concrete
regex but lack test-source arm. Per the invariant I codified in §3 +
§5 + §6, every concrete regex MUST include the OWN test-source arm
under `src/v3/compiler/tests/integration/`. These rows didn't:

1. `dimension::analyze_complexity_tests::.*` — had `tests/integration/dimension.*\.rs` arm but that file doesn't exist (tests live inline as a module in `tests/integration.rs`); arm matched nothing → fail-open
2. `dimension::fail_closed_tests::.*` — NO test-source arm
3. `e7_analyze_complexity_integration::.*` — NO test-source arm
4. `lane2_stage_2f_dimension_test::.*` — NO test-source arm
5. `sg2c1_parse_tables_authority_test::.*` — NO test-source arm

Fix: add test-source arm to each row:
- For inline modules (dimension/e7/lane2_stage_2f): test lives inline
  in `src/v3/compiler/tests/integration.rs`; add that path. Broad-but-
  correct per fail-closed default (any edit to integration.rs triggers
  these tests; a finer-grained match isn't expressible via path regex
  because the modules are inline in the file).
- For sg2c1 (standalone file): add explicit
  `src/v3/compiler/tests/integration/sg2c1_parse_tables_authority_test\.rs`.

Each row's dissolution_note now carries inline annotation citing the
codex BLOCKING finding + the test-source-arm correction rationale.

**Lesson**: codifying the invariant in §3/§5/§6 doesn't retrofit
existing rows — needed to AUDIT each concrete regex against the
invariant after codification. PM did partial audit on path correctness
(dsl/std → src/v3/lenses) but didn't re-audit for test-source-arm
presence. cursor #9858 noted earlier the boxed-formula inconsistency
in §1; codex now caught the same class on §3 row content. Audit
discipline = match-the-framing-everywhere, not just-codify-the-framing.

Cumulative bug-class catches on this template now 11 axes hardened:
1. Dimension cardinality (Set<Dimension>)
2. Boolean polarity inversion
3. Count discrepancies + line-7 singular
4. Cluster aggregation predicate (∀ not ∃)
5. Path-regex verification discipline
6. Stale dsl/std/ lens-paths
7. Markdown-cell-escape regex
8. Dimension enum hard-closed (open per THESIS)
9. Narrowing user-defined dim (Timing→Cost)
10. 3-arm regex completeness invariant codified
11. **Existing rows violated own 3-arm invariant** (this fix — codification didn't retrofit)

SG-0 hand-path delta: 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): §1.8 row #105 — symbolic_cost_textbook_coverage_landed (Path A Tier 1 ratified per Director msg_ad5e934d) + §1.2/§1.5 interrogation probe refinement

Operator directive 2026-05-13 ("anything you would find in an algorithms textbook ... we need to land this all in R3 please") + Director ratification msg_ad5e934d (RATIFIED Path A + Tier 1 IN-R3 + Tier 2 R4-deferred + 5 sub-canvas questions routed to Substrate Mgr).

§1.8 row #105 changes:
- New gate symbolic_cost_textbook_coverage_landed; substrate-shape predicate-family; T-CostLens-Composition lane
- Tier 1 carrier extension: PROMOTE PolynomialCost { degree: DegreeAtLeastTwo } -> { degree: Rational } per dsl/std/rational.dag:26 Field<FieldOfFractions<Int>>; ADD PolyLogCost { exponent: Int } + ExponentialCost { base: Int } + FactorialCost; net 7 -> 11 variants per src/v3/std/algebra.dag:190-197
- Tier 2 R4-deferred: LogLogCost / InverseAckermannCost / IteratedLogCost / HyperExponentialCost (each requires consumer-evidence trigger)
- 5 sub-canvas questions for warm-wolf-698: (Q1) Rational dominance lattice ordering (Field<FieldOfFractions> lacks Order); (Q2) Linear-vs-Polynomial split reconciliation; (Q3) Sum/Product algebra interaction rules; (Q4) STOP-SIGNAL update; (Q5) canvas-shape authoring
- Two-part predicate: Part A (carrier landed via grep on type SymbolicCost) + Part B (algebra rules pass via cargo test)
- 5 Director-enumerated anti-patterns for post-ratification reviewers

§1.8 header gate-count updates (multiple lines):
- 104 enumerated -> 105 enumerated across plan, Q1 row, R3-close target arithmetic
- 103 R3-load-bearing -> 104 R3-load-bearing (only #11 canvas-deferred subtracted)
- Authority history extended: +Director ratification msg_ad5e934d + cost-textbook-coverage row #105 added 2026-05-13

§1.2 (Cost) interrogation probe refinement (post-PR-#2822 fix-forward):
- Promise updated to include #105 + R3-committed Tier 1 scope verbatim
- Split into Implementation probes (carrier scope) + Scope probes (Tier 1 textbook coverage with concrete bound examples: √n, exp, factorial, polylog, matrix mult) + Tier 2 boundary probes (R4-deferred bounds with expected behavior) + Falsification probes (Tier-3 recursive, Tier-2-not-named, STOP-SIGNAL trigger for Tier-1-coverable bound collapsing to UnknownCost)

§1.5 (User-defined dimensions) escape-hatch probes for Tier 2+:
- Compositional-mechanism probe per Director structural-extension caveat (if user-defined-dim supports cost-variant authoring with dominance lattice integration, Tier 2 R4-deferral is structurally bounded)
- Falsification probe: author a user-defined cost lens for inverse Ackermann; if it integrates -> R4-deferral bounded; if not -> load-bearing gap

Effort estimate: ~3-4 weeks total substrate work (carrier change + dominance lattice + Sum/Product algebra + testgen + parity validation); R3 close timeline extends accordingly.

Cascade: PM §1.8 row added (this PR) -> Substrate Mgr authors canvas (Q1-Q5) -> Director ratifies canvas -> worker dispatch -> gate #105 CONSUMER_LANDED -> PASSING through standard cycle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): §1.5/§1.7/§1/§3 — comprehensive 104→105 / 103→104 count sweep (operator BLOCKING on PR #2824:85 INVARIANTS P2)

Operator briansrls flagged at `docs/r3-program-plan.md:85` that PR #2824
introduced "105 enumerated" while the same §1.5 block still said "104
gate IDs" and "103 R3-load-bearing arithmetic", creating competing
authorities (INVARIANTS P2).

PR #2824's prior commit message claimed a header count sweep but the
diff only updated SOME of the count sites, leaving 10 lines internally
inconsistent. This commit completes the sweep.

Lines updated (all 104→105 / 103→104 where the count was a TOTAL or
LOAD-BEARING reference, not a row-number reference):

- §1.5 line 84: "104 gate IDs enumerated at this commit" → "105 gate IDs"
- §1.5 line 86: "103 R3-thesis = 104 − 1" → "104 R3-thesis = 105 − 1"
- §1.5 line 88: "forward-looking R3 close target is 103" → "104"
- §1.5 line 90: "Total: 87 + 16 + 1 = 104" → "Total: 87 + 16 + 2 = 105"
  (the +2 represents #104 + #105 routed to T-Lens-Behavioral-Parity +
  T-CostLens-Composition respectively; kept in trailing tail vs
  lane-incorporated to preserve the 2026-05-12 lane-breakdown snapshot's
  audit shape)
- §1.5 line 96: "103 R3-thesis = 104 − 1 = 103" → "104 = 105 − 1 = 104"
- §1 line 114: "103 R3-load-bearing gates green" → "104"
- §1.7 line 125: "DECLARE 104 closure gates" → "105"
- §1.8 line 338: "103 load-bearing" → "104"
- §2 line 627: "103 load-bearing" → "104"
- §Q-table line 805: "104 closure gates total" → "105"

Lines NOT updated (correct references to row numbers, not count totals):
- Lines 8, 84, 88, 90, 98, 108, 111, 148, 239 references to gates
  #98-#103 (T-WAD FULL R3) and gate #104 (Miss-class) and gate #105
  (cost-textbook) — these are row-number references, not totals
- §1.8 line 331/332 row entries (gate #103 ci_uses_affected_set,
  gate #104 lens_read_witness_shape_dissolved) — row identifiers

INVARIANTS P2 single-authority restored across §1.5 / §1.7 / §1 close
criteria / §2 close criteria / §Q-table.

Lesson: header-count sweep PRs MUST grep-verify every occurrence of
the prior counts before claiming the sweep is complete. PR #2824's
prior commit message overstated coverage; operator caught.

— sent from deep-wolf-155

* docs(r3-structure): add gate #104 + #105 to §Acceptance — restore single-authority parity with §1.8 (operator BLOCKING on PR #2824:207 INVARIANTS P2)

Operator briansrls flagged at `docs/r3-program-plan.md:207` that PR #2824
claims "the 105-gate ledger is consolidated with r3-structure.md" but
the diff doesn't update r3-structure.md, leaving #105 without the
canonical acceptance body that line 340 says lives there.

Audit found the gap is wider than #105 alone — gate #104
(`lens_read_witness_shape_dissolved`, added 2026-05-12 in a prior PR)
is also missing from r3-structure.md §Acceptance. Same INVARIANTS P2
single-authority violation class.

Fixed both in PR #2824 (cleanest bundle — same gap class, both rows
added to §Acceptance in their canonical lanes):

- **#105 `symbolic_cost_textbook_coverage_landed`** added to
  T-CostLens-Composition lane (after `cost_lens_reads_target_realization`
  + `coercion_cost_equals_complexity_by_construction`). Encodes Path A
  Tier 1 carrier extension shape (PolynomialCost{degree: Rational} +
  PolyLogCost + ExponentialCost + FactorialCost) + Tier 2 R4-deferral
  + structural-extension caveat + two-part predicate (Part A carrier
  landed + Part B algebra rules pass). Cross-refs §1.8 row #105 for
  full receipt + 5 sub-canvas substrate-shape questions.

- **#104 `lens_read_witness_shape_dissolved`** added to
  T-Lens-Behavioral-Parity lane (after `lens_capability_register_zero_
  proxy_zero_stub`). Encodes bundled-migration shape per Director
  ratification msg_915aa2c1 — (1) substrate-level Miss→Violates
  collapse across 70 sites in 6 files (cost.dag/complexity.dag/
  infer_helpers.dag/algebra.dag/substrate.dag/lookup.dag); (2)
  testgen-level universal-coverage TestClaim. Two-part predicate
  (Part A terminal + Part B regression guard). Cross-refs §1.8 row
  #104 for full receipt.

INVARIANTS P2 single-authority restored: §1.8 ledger ↔ §Acceptance
canonical body now in parity at gate-ID level for all 105 enumerated
gates (104 R3-load-bearing post-canvas-deferral).

Lesson logged: when adding §1.8 rows, r3-structure.md §Acceptance
must update in same PR. Prior PR #2824 commit message did not
include this discipline; #104's prior PR also missed it. Class
violation traceable to: section-anchor authoring discipline that
prevents the missing-mirror class.

— sent from deep-wolf-155

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
…wedge review

- Expand Witness/SymbolicCost links in symbolic_cost_of docs
- rustfmt wrapping for symbolic_cost_lookup assertions

No behavior change.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request May 15, 2026
…solution

Authority brief covering (a) requirement for DECLARED→CONSUMER_LANDED
progression per §1.8 row #104. ≥3 lens carriers bar met by structural
authoring across 6 files: cost.dag + complexity.dag (Phase 1
canonical) + infer_helpers.dag + algebra.dag + substrate.dag +
lookup.dag (Phase 2/3 sweep).

Brief cites:
- Director ratification msg_915aa2c1 (2026-05-12)
- Operator directive 2026-05-11 audit §0
- Two-part predicate (Part A grep terminal + Part B regression guard)
- Bundled migration shape (substrate-level Phase 1/2/3 + testgen-level
  universal-coverage TestClaim companion)
- Phase 1 wedge evidence accruing via nimble-dove-181 PR #3137
- STOP-AND-PING triggers for future Phase 2/3/TestClaim dispatches

§1.8 row #104 STAYS at DECLARED post-merge (wedge alone insufficient
per ≥3 carriers + universal-coverage bar). Substantive evidence
accruing per ratchet-only-down discipline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
- lens_cost_symbolic module + symbolic_cost_of: document port-keyed producer
  walk vs generated cost_lens_read (caller Behavior, table-only).
- cost.dag header: mirror the same Lens.read vs symbolic_cost_of split.
- Document non-empty Dag.nodes precondition for diagnostic-anchor Violates.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
Composer review on #3137: mirror modeling-discipline.md §4 checkpoint for new
multi-variant enums (🟢 + ledger). ViolatesSubject stays aligned with
dimensions.dag and ProducerLookup discrimination (gate #104).

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
briansrls added a commit that referenced this pull request May 15, 2026
…ookup Hit

Gate #104 / claude-opus-4 review: emitter name-match aligns single-field `_0` at
positional patterns for the mirrored tuple variant — same scaffolding as
`Lookup`/`Hit`; document dissolution trigger symmetry.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request May 15, 2026
…st_lookup wedge (#3137)

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* chore(cost lens): tighten lens_cost_symbolic rustdoc before gate #104 wedge review

- Expand Witness/SymbolicCost links in symbolic_cost_of docs
- rustfmt wrapping for symbolic_cost_lookup assertions

No behavior change.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* chore: apply rustfmt to lens_cost_symbolic symbolic_cost_of (fixes CI fmt)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cost lens): BindCycle Violates anchors at resolver detected_at node

Codex REVIEW: ProducerLookup::BindCycle already carries authoritative NodeId;
use dag.node(detected_at) for Witness::Violates.at — not substrate_lens_read_diagnostic_anchor.

MissingPort/MissingNode keep diagnostic-anchor fallback when no Behavior exists.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(cost): clarify dual lens read contracts (gate #104)

- lens_cost_symbolic module + symbolic_cost_of: document port-keyed producer
  walk vs generated cost_lens_read (caller Behavior, table-only).
- cost.dag header: mirror the same Lens.read vs symbolic_cost_of split.
- Document non-empty Dag.nodes precondition for diagnostic-anchor Violates.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* docs(dimension): classify ViolatesSubject TERMINAL per Practice 4

Composer review on #3137: mirror modeling-discipline.md §4 checkpoint for new
multi-variant enums (🟢 + ledger). ViolatesSubject stays aligned with
dimensions.dag and ProducerLookup discrimination (gate #104).

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(lens_cost_symbolic): align module rustdoc with ViolatesSubject variants

Composer #12455: use ProducerLookupMissing{Port,Node} names; describe Lens.read
Miss path as Violates.subject = AtBehavior(b), not stale at = b prose.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* feat(v3): ground ProducerLookup violates diagnostic spans via query port

Expose violates_subject_diagnostic_span so malformed producer-walk residues
(ViolatesSubject::ProducerLookupMissing*) can reuse the keyed symbolic_cost_of
port's declaring Behavior span (INVARIANTS P3 / thesis "show the correct code"),
with the prior sentinel when no hint is available.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* WIP: Gate #104 lens_read_witness_shape_dissolved is DECLARED-status with no S

* chore(bootstrap): resync snapshots for regen_bootstrap --verify

CI ci job failed snapshot drift (`next_*_id` / fixture hash); regenerate from
authority .dag corpus so `--verify` matches committed files.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(emit): note ViolatesSubject::AtBehavior tuple bridge parallels Lookup Hit

Gate #104 / claude-opus-4 review: emitter name-match aligns single-field `_0` at
positional patterns for the mirrored tuple variant — same scaffolding as
`Lookup`/`Hit`; document dissolution trigger symmetry.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants