Repository navigation
feat(v3): T-Substrate-AnthropicSchemaMirror — provider-domain type mirror for Messages signature - #1261
Conversation
…ages signature
- src/v3/std/anthropic_schema.dag: type-authority-only mirror of provider-domain
types reachable from operation Messages signature in
dsl/extdeps/llm/anthropic.dag (AnthropicChatMessage + content block variants,
AnthropicStopReason, AnthropicMessages200{TextBlock,Usage,Body}).
- AnthropicErrorShape deferred (4xx/5xx response slot only; not on the typed
return reach for fn anthropic_messages -> AnthropicMessages200Body).
- src/v3/compiler/tests/integration/anthropic_schema_lockstep_test.rs:
8 ratchets pinning v3 mirror against v2 source (variant labels, field labels,
type-name presence in v2). Discipline mirrors method_registry_test.rs.
- Type authority only — no fn anthropic_messages, no Operation rows. Those
are the next substrate precursor that consumes these types.
|
Review metadata
This is a clean substrate addition: typed mirror dag file + bidirectional lockstep ratchet test + regenerated bootstrap. Dissolution trigger documented (v3 service-DSL parser). Type-authority-only with a test asserting no value bodies leak. Set-equality (not subset) on both sides plus per-variant payload + optionality coverage — the ratchet fails closed in both directions. Verdict: APPROVE — narrow, well-scoped substrate mirror with a fail-closed lockstep test against the v2 authority and a named, bounded dissolution trigger. No INVARIANTS / modeling-discipline / CODING / TESTING violations observed in the diff. |
|
Review metadata
1. Story of the diffThis PR introduces a narrow v3 The load-bearing mechanism is the lockstep test: it treats the v2 file as the source authority and walks the generated v3 bootstrap declarations. That is the right direction for this staged bridge, but the current ratchet does not compare field type targets, so a core part of the “type mirror” can drift while tests stay green. 2. Invariant categories
Finding — BLOCKING. This diff adds substrate-level provider-domain types under
Finding — BLOCKING. Boundary Discipline / single-authority metadata is only partially enforced. The PR says the v2 file is the authority source (
Compliant. The new Rust test code stays in free-function/data style: helpers such as
Finding — BLOCKING. The new tests are behavior-targeted and wired into the integration suite (
Compliant. The PR does not appear to alter a locked thesis/design decision directly; where it introduces a staged mirror, it names the current v3 service-DSL parse/load limitation and scopes the bridge to the Anthropic Messages signature reach (
Compliant. The staged mirror has documentation, bounds, and a named dissolution trigger: it is type-authority only for this slice ( 3. VerdictREQUEST_CHANGES. The modeling direction is good and the debt is well bounded, but the lockstep ratchet does not yet protect the actual type carriers of the new substrate mirror. Add comparison of v2 field type expressions against v3 resolved field type shapes, including nested |
…t payloads) OpenAI-Pro REQUEST_CHANGES on PR #1261 (sha 1e08a24): label + optionality weren't enough to catch field type drift — content: List<X> could become content: String while tests stayed green. Adds: - v3_canonical_ty(dag, ty): walks declarations to produce a canonical type-expression string. Named decls (String, Bool, AnthropicStopReason, AnthropicMessages200TextBlock, …) canonicalize as their surface name even though their underlying connective unfolds to Instantiation (e.g. String = FreeMonoid<Int>). Anonymous Instantiation sites (List<X>, Map<K, V>) and Cardinality(AtMostOne, T) get unfolded. - normalize_ty_text(raw): strips trailing '?' and compresses internal whitespace so v2 source text matches v3 canonical form. - v2_record_fields and parse_v2_brace_body_fields now return (label, normalized_ty_text, is_optional); v3_variant_payload_fields returns (label, canonical_ty, is_optional). - assert_record_lockstep and assert_disj_lockstep added type-expression equality assertions in addition to label-set equality and optionality. Optionality is checked separately, so the type comparison strips the trailing '?' on both sides and compares inner-element forms only. Coverage: every mirrored field across AnthropicChatMessage, AnthropicUserContentBlock (incl. UserToolResultBlock.content/tool_use_id), AnthropicAssistantContentBlock (incl. AssistantToolUseBlock.input: Json), AnthropicMessages200TextBlock, AnthropicMessages200Usage (input_tokens: Int), and AnthropicMessages200Body (content: List<...>, stop_sequence: String?) now fails closed if v2 carrier type changes.
|
Review metadata
Findings
Verdict: REQUEST_CHANGES. The schema mirror itself is documented with a bounded dissolution trigger, but the committed lockstep test fails in a fresh checkout, so the PR cannot land as-is. |
|
Already fixed on current head. The reviewer was running against fn v3_canonical_ty(dag: &Dag, ty: DeclarationId) -> String {
let decl = dag.declaration(ty);
if let Some(name) = decl.name.as_deref() {
return name.to_string();
}
// anonymous Instantiation / Cardinality fallback below…
}A named declaration ( Verified locally on Clippy clean. CI is rerunning on — sent from sharp-raven-604 |
|
Review metadata
1. Story of the diffThis PR stages a v3 provider-domain type mirror for the Anthropic Messages signature because v3 cannot yet ingest the existing v2 The safety mechanism is the new 2. Invariant categories
3. VerdictAPPROVE. The PR introduces a temporary v3 mirror, but it is bounded, source-anchored, ratcheted against the v2 authority, and carries an explicit dissolution trigger. I did not find a changed line that violates the substrate/modeling, coding, testing, locked-design, or tracked-debt rules. |
|
Review metadata
Findings: None. I read the rubric files from the pinned Against that slice:
The Verdict: APPROVE — The diff is focused, fail-closed at the ratchet (set equality, optionality, no |
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
365e57f6· Trigger:schedule - Thinking:
266s wall
Non-blocking — Strengths
src/v3/compiler/tests/integration/anthropic_schema_lockstep_test.rsThe lockstep test checks field sets, variant sets, payload fields, optionality, and canonical type expressions, so the mirror has a useful fail-closed drift ratchet once the cited v2 authority exists.
Non-blocking — Improvements (fix in-PR if easy, else defer to roadmap)
src/v3/compiler/tests/integration/anthropic_schema_lockstep_test.rsThe type-only ratchet at line 558 only rejects value_body rows, so a future fn in anthropic_schema.dag would lower as an Arrow with value_body None and bypass the guard; extend it in the T-Substrate-AnthropicSchemaMirror follow-up lane if deferred.
…ard) Codex non-blocking improvement on PR #1261: prior anthropic_schema_authors_no_data_rows test rejected only declarations with value_body: Some(...), so a future fn anthropic_messages would lower as TypeConnective::Arrow with value_body: None and bypass the guard. Renamed to ..._or_fns and extended the filter to also reject TypeConnective::Arrow declarations authored in src/v3/std/anthropic_schema.dag.
|
Review metadata
1. Story of the diffThis PR stages a v3 provider-domain mirror for the Anthropic Messages signature rather than trying to ingest the v2 The key guardrail is the new integration ratchet: it extracts v2 type blocks from the v2 authority text and compares them against the full v3 bootstrap declarations for field/variant set equality, optionality, and canonical type expressions ( 2. Invariant categories
Compliant — this does touch Dag-visible substrate/domain types under
Compliant — boundary discipline / single authority is handled as a tracked mirror rather than silent parallel authority: the file names the v2 authority, adds a lockstep ratchet, and names the dissolution trigger when v3 can ingest
Compliant — the new Rust test is data + pure helper functions over explicit inputs: helpers take
Compliant — the PR adds behavior-driven lockstep tests at the right level for a bootstrap-visible mirrored schema: set equality, optionality, type-expression equality, and type-only enforcement are explicit test claims (
N/A — the diff references the known service-DSL parse/load gap and future service ingestion path, but does not edit or contradict a locked design document. The divergence is explicitly scoped as a temporary typed twin until service DSL ingestion exists (
Compliant — the mirror is a temporary parallel representation, but it has all three bridge properties: documentation of why it exists ( 3. VerdictAPPROVE The PR introduces a substrate-visible mirror, but it is narrowly scoped, structurally typed, ratcheted against its named authority, and explicitly marked as dissolving once v3 can ingest the upstream service DSL directly. I did not find a diff-local invariant violation that would justify blocking or comments. |
|
Review metadata
Verdict: APPROVE The diff is narrowly scoped: a documented v3 provider-domain mirror, generated bootstrap updates, and a lockstep ratchet against the v2 authority. I found no concrete violations of the pinned invariants or testing/coding guidance. The temporary duplicate authority is documented, bounded, tested bidirectionally, and has a named dissolution trigger. Verification run: |
Service-operation callable declaration precursor for the Anthropic Messages REST operation, the substrate slice Grounding PR-β #1252 is waiting on per parent #1130 dispatch. Adds: - src/v3/std/anthropic_messages.dag: top-level fn anthropic_messages with honest signature consuming v3.std.anthropic_schema mirror types (#1261). Returns AnthropicMessages200Body. host body lowers as ArrowBody::Unparsed (no producerless realization carrier minted). - src/v3/compiler/tests/integration/anthropic_messages_callable_test.rs: 5 ratchets — Arrow shape, parameter type list matches v2 source via v3 mirror, return type is AnthropicMessages200Body, callable is acceptable as Operation.callable.decl target, no Operation/data rows leak (those are PR-β scope). Two intentional simplifications vs v2 (documented in file header): - max_tokens: Int (v2 'Int = 4096'); v3 has no parameter defaults so the default is a caller-side fold, not a v3 contract change. - Return is the 200 body only; AnthropicErrorShape is PR-β response/ wire lockstep concern. Out of scope: anthropic_operations: List<Operation> data row, sibling binding/realization data rows. Grounding owns those.
…es declaration (#1266) * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * regen bootstrap after std.effects import path fix * WIP: sharp-raven-604 * chore: apply cargo fmt * WIP: sharp-raven-604 * regen bootstrap + refresh parse manifest after merge * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * PR-α: wrap Operation.callable in CallableRef (typed wrapper, mirrors MethodRef) * chore: apply cargo fmt * doc: align test comments with CallableRef wrapper (cosmetic) * regen bootstrap after merge main * T-Substrate-AnthropicSchemaMirror: v3 typed mirror for Anthropic Messages signature - src/v3/std/anthropic_schema.dag: type-authority-only mirror of provider-domain types reachable from operation Messages signature in dsl/extdeps/llm/anthropic.dag (AnthropicChatMessage + content block variants, AnthropicStopReason, AnthropicMessages200{TextBlock,Usage,Body}). - AnthropicErrorShape deferred (4xx/5xx response slot only; not on the typed return reach for fn anthropic_messages -> AnthropicMessages200Body). - src/v3/compiler/tests/integration/anthropic_schema_lockstep_test.rs: 8 ratchets pinning v3 mirror against v2 source (variant labels, field labels, type-name presence in v2). Discipline mirrors method_registry_test.rs. - Type authority only — no fn anthropic_messages, no Operation rows. Those are the next substrate precursor that consumes these types. * WIP: sharp-raven-604 * chore: apply cargo fmt * anthropic_schema lockstep: couple expected labels to v2 source + optionality Manager review on PR #1261: the prior lockstep tests asserted v3 labels against hard-coded constants and only checked v2 type-name presence. They would NOT catch v2 source drift on field/variant labels themselves. This commit: - Extracts the v2 type-block text via v2_type_block(name). - assert_lockstep_record / assert_lockstep_disj now verify each expected label appears literally in the v2 block, fail-closed on either-side drift. - New anthropic_optional_fields_remain_optional_in_v2_source asserts the '?' suffix on is_error: Bool? and stop_sequence: String? in the v2 source, with comment explaining structural inspection of v3 optionality is deferred to the operation-row precursor (per manager guidance). * anthropic_schema lockstep: bidirectional set equality + structural optionality OpenAI-Pro REQUEST_CHANGES on PR #1261: prior ratchet only checked v3 set == expected and expected ⊆ v2. v2 additions silently passed; v3 optionality was text-only on the v2 side, not structurally checked on v3. Strengthened: - v2_record_fields(name) parses the v2 type block and extracts (label, is_optional) tuples directly from the source. v2_disj_variants(name) extracts variant labels (including from inline 'A | B | C' and multi-line '= Foo {} | Bar {}' shapes). - assert_record_lockstep / assert_disj_lockstep assert SET EQUALITY between v2-extracted set and v3 bootstrap set (BTreeSet diff in the failure message names v3-only and v2-only labels). - Optionality is structural on v3: v3_field_is_optional walks the field declaration's TypeConnective and matches Cardinality(AtMostOne, _). Each v2 'T?' field must lower optional; each v2 'T' field must NOT. - New test anthropic_user_content_block_user_tool_result_block_optionality reaches the variant payload Conj for UserToolResultBlock and asserts is_error: Bool? lowers as Cardinality(AtMostOne, Bool) on the inner declaration (variant payloads aren't reached by the record-level ratchet). * chore: apply cargo fmt * fix clippy: use char array in split (manual char comparison lint) * WIP: sharp-raven-604 * anthropic_schema lockstep: per-variant payload field+optionality coverage OpenAI-Pro REQUEST_CHANGES on PR #1261: assert_disj_lockstep compared only variant labels, leaving variant payload field labels and optionality unguarded — UserToolResultBlock.content / tool_use_id and AssistantToolUseBlock.id / name / input could drift between v2 and v3 while the test passed. This commit: - v2_disj_variants now returns (label, Option<Vec<(field_label, is_optional)>>), parsing variant payload bodies via the same logic v2_record_fields uses (extracted as parse_v2_brace_body_fields). - v3_variant_payload_fields walks the v3 variant target's Conj declaration and projects (label, Cardinality(AtMostOne, _)?) tuples. - assert_disj_lockstep extends to per-variant payload set equality and optionality: bare-on-bare passes; record-on-record requires set equality + optionality match; mismatched (one-side bare, other-side payload) fails closed. - Drops the redundant special-case is_error optionality test — now subsumed by structural per-variant payload coverage on AnthropicUserContentBlock. * chore: apply cargo fmt * WIP: sharp-raven-604 * chore: apply cargo fmt * WIP: sharp-raven-604 * anthropic_schema lockstep: type-expression equality (records + variant payloads) OpenAI-Pro REQUEST_CHANGES on PR #1261 (sha 1e08a24): label + optionality weren't enough to catch field type drift — content: List<X> could become content: String while tests stayed green. Adds: - v3_canonical_ty(dag, ty): walks declarations to produce a canonical type-expression string. Named decls (String, Bool, AnthropicStopReason, AnthropicMessages200TextBlock, …) canonicalize as their surface name even though their underlying connective unfolds to Instantiation (e.g. String = FreeMonoid<Int>). Anonymous Instantiation sites (List<X>, Map<K, V>) and Cardinality(AtMostOne, T) get unfolded. - normalize_ty_text(raw): strips trailing '?' and compresses internal whitespace so v2 source text matches v3 canonical form. - v2_record_fields and parse_v2_brace_body_fields now return (label, normalized_ty_text, is_optional); v3_variant_payload_fields returns (label, canonical_ty, is_optional). - assert_record_lockstep and assert_disj_lockstep added type-expression equality assertions in addition to label-set equality and optionality. Optionality is checked separately, so the type comparison strips the trailing '?' on both sides and compares inner-element forms only. Coverage: every mirrored field across AnthropicChatMessage, AnthropicUserContentBlock (incl. UserToolResultBlock.content/tool_use_id), AnthropicAssistantContentBlock (incl. AssistantToolUseBlock.input: Json), AnthropicMessages200TextBlock, AnthropicMessages200Usage (input_tokens: Int), and AnthropicMessages200Body (content: List<...>, stop_sequence: String?) now fails closed if v2 carrier type changes. * anthropic_schema lockstep: also reject Arrow declarations (fn leak guard) Codex non-blocking improvement on PR #1261: prior anthropic_schema_authors_no_data_rows test rejected only declarations with value_body: Some(...), so a future fn anthropic_messages would lower as TypeConnective::Arrow with value_body: None and bypass the guard. Renamed to ..._or_fns and extended the filter to also reject TypeConnective::Arrow declarations authored in src/v3/std/anthropic_schema.dag. * chore: apply cargo fmt * T-Substrate-AnthropicMessagesCallable: fn anthropic_messages declaration Service-operation callable declaration precursor for the Anthropic Messages REST operation, the substrate slice Grounding PR-β #1252 is waiting on per parent #1130 dispatch. Adds: - src/v3/std/anthropic_messages.dag: top-level fn anthropic_messages with honest signature consuming v3.std.anthropic_schema mirror types (#1261). Returns AnthropicMessages200Body. host body lowers as ArrowBody::Unparsed (no producerless realization carrier minted). - src/v3/compiler/tests/integration/anthropic_messages_callable_test.rs: 5 ratchets — Arrow shape, parameter type list matches v2 source via v3 mirror, return type is AnthropicMessages200Body, callable is acceptable as Operation.callable.decl target, no Operation/data rows leak (those are PR-β scope). Two intentional simplifications vs v2 (documented in file header): - max_tokens: Int (v2 'Int = 4096'); v3 has no parameter defaults so the default is a caller-side fold, not a v3 contract change. - Return is the 200 body only; AnthropicErrorShape is PR-β response/ wire lockstep concern. Out of scope: anthropic_operations: List<Operation> data row, sibling binding/realization data rows. Grounding owns those. * chore: apply cargo fmt * chore: restore comment/test adjacency in SG-0 census (cosmetic) Reviewer (claude opus 4.7) non-blocking exploratory observation on PR #1266: the alphabetical insertion of anthropic_messages_callable_test.rs and anthropic_schema_lockstep_test.rs split the PB Tier-2 #1014 comment block from the test it describes. Moving the comment two lines down restores adjacency. No behavior change. * anthropic_messages: pin Unparsed body + correct file header prose OpenAI-Pro REQUEST_CHANGES on PR #1266: the file header claimed 'host anthropic_messages' lowers to ArrowBody::ExternalRealization, but the generated substrate has ArrowBody::Unparsed(span). Prose did not match the substrate fact, and no test pinned the body class so a silent rewrite was invisible. Fixes: - File header rewritten to honestly describe the actual lowered state: body remains Unparsed because the pipeline-stage post-processing patch in bootstrap.rs:256 is pipeline-specific and does not fire for service-operation callables. The patch is intentionally not added (would require a producerless CompilerHostRealization-style data row, the parallel surface the #1130 dispatch rejects). - New ratchet anthropic_messages_body_is_unparsed pins ArrowBody::Unparsed; a silent rewrite to ExternalRealization / UserDefined / Pending / NoBody fails closed. - File header explicitly bounds the unparsed-body state to the same dissolution trigger as the schema mirror. * regen bootstrap: re-sync byte spans after anthropic_messages.dag header rewrite
…ase 1 (rebase against #1246/#1261/#1266) Resume per manager dispatch (#1133 inbox 4353064310). Substrate cascade chain CLOSED: #1246 services + Operation/RestEndpointBinding, #1261 Anthropic schema mirror, #1266 anthropic_messages callable. Changes from queue-ahead draft: - Operation row: drop name field (per #1246 — Operation has no parallel display-name); add callable: { decl: anthropic_messages } (per #1266 callable-decl precursor). - Import std.effects (not v3.std.effects); add v3.std.anthropic_messages + v3.std.services { CallableRef } imports. - Test: pivot from name-based uniqueness to callable.decl uniqueness; pilot-row lookup resolves through callable.decl == anthropic_messages. - Variant-label resolution via parent Disj.variants helper (codex feedback re P2 single-authority). Two structural-honesty deferrals documented as separate receipts in the file header (per #1133 inbox 4353159066 — keep distinct): §1 INPUT-FIELDS POPULATION — parser-grammar gap; nested Map<String, X> literals don't parse in record-field positions. Even empty `{}` fails the Map type check (parses as record). Whole pilot row deferred; empty list lands as scaffolding. Substrate-tracked Phase 1.5+ slice (#1130 comment 4353153545). §2 v2 PARAMETER DEFAULTS — InputField.default carrier deferred; v2's max_tokens: Int = 4096 not represented. Substrate-tracked Phase 1.5+ slice (#1130 comment 4352585286). messages_pilot_present test #[ignore]'d with re-arm instructions; list-shape + uniqueness + ParamToken→inputs boundary checks land (vacuous on empty list but wired for Phase 1.5 row population). Pre-merge gate: regen clean; integration tests 3 passed + 1 ignored; parse-corpus manifest refreshed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ase 1 pilot (#1252) * feat(grounding): T-Ground services.dag PR-β — anthropic_operations Phase 1 pilot (DRAFT, gated on #1246) Queue-ahead authoring per manager dispatch (#1133 inbox 4349607248) for T-Ground services.dag PR-β. Mirrors the #1195 MethodTemplateContract Phase 1 pattern: typed v3 fixture row + bootstrap_fixture_authority extension + lockstep test. This PR is DRAFT until Substrate's PR-α (#1246; sharp-raven-604) lands the `Operation` / `RestEndpointBinding` / `InputField` type declarations at src/v3/std/services.dag. Authored against the proposed shape from #1246 diff inspection. Files: - src/v3/std/anthropic_operations.dag — single Messages operation row (POST /v1/messages with 6 input fields), lockstep with v2 source of truth at dsl/extdeps/llm/anthropic.dag:182-198. Home in src/v3/std/ per #1187 audit lesson. - src/v3/std/extdeps_bootstrap_fixtures.dag — extends BootstrapFixtureSet + bootstrap_fixture_authority with anthropic_operations. - src/v3/compiler/src/bootstrap.rs — extends BOOTSTRAP_FIXTURE_PATH_KEYS. - src/v3/compiler/tests/integration/anthropic_operations_test.rs + integration.rs mod entry — three load-bearing checks (lowers as List; names unique; Messages pilot present with expected POST /v1/messages endpoint + input-field key set per anthropic.dag:183-189). Pre-merge gate (per #1195 regression-class lesson): workspace-exclude + v2-compiler-tests + lane2-cost-test all pass before flipping ready. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: apply cargo fmt * test(grounding): wire ParamToken.name → Operation.inputs boundary check (vacuous on Messages) Per codex non-blocking finding on PR #1252: header claimed the ParamToken.name resolution check is wired, but no actual assertion existed. Adds anthropic_operations_param_tokens_resolve_to_input_keys which walks every row's path tokens and asserts each ParamToken's name is a present key in the operation's input map. Vacuous on the Phase 1 Messages pilot (/v1/messages is pure literal segments), but rows with path variables inherit the discipline by construction. Header text tightened to make the structural-wired vs runtime-active distinction explicit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(grounding): correct import path v3.std.effects → std.effects in anthropic_operations.dag Per codex non-blocking finding on PR #1252: the live staged effects authority at src/v3/std/effects.dag declares 'module std.effects', not 'v3.std.effects'. My queue-ahead import path was wrong; fixed before M2 module scoping starts consuming import paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(grounding): add anthropic_operations_test.rs to SG-0 hand-authored census Per codex BLOCKING on PR #1252: the new hand-authored Rust integration file at src/v3/compiler/tests/integration/anthropic_operations_test.rs must be tracked in the SG-0 hand-authored census ratchet. Entry added in alphabetical position with comment naming the gating chain (#1252 → Substrate schema-mirror → callable-decl precursor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(grounding): assert UrlPathToken constructor is LiteralToken before text check Per codex non-blocking finding on PR #1252: the Messages path-token walker matched any FieldValue::Variant with .. ignoring constructor — a ParamToken { name: "v1" } could satisfy the text assertion. Tightened to assert the variant name is LiteralToken before extracting text. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: wise-tern-480 * WIP: wise-tern-480 * chore: apply cargo fmt * feat(grounding): T-Ground services.dag PR-β — anthropic_operations Phase 1 (rebase against #1246/#1261/#1266) Resume per manager dispatch (#1133 inbox 4353064310). Substrate cascade chain CLOSED: #1246 services + Operation/RestEndpointBinding, #1261 Anthropic schema mirror, #1266 anthropic_messages callable. Changes from queue-ahead draft: - Operation row: drop name field (per #1246 — Operation has no parallel display-name); add callable: { decl: anthropic_messages } (per #1266 callable-decl precursor). - Import std.effects (not v3.std.effects); add v3.std.anthropic_messages + v3.std.services { CallableRef } imports. - Test: pivot from name-based uniqueness to callable.decl uniqueness; pilot-row lookup resolves through callable.decl == anthropic_messages. - Variant-label resolution via parent Disj.variants helper (codex feedback re P2 single-authority). Two structural-honesty deferrals documented as separate receipts in the file header (per #1133 inbox 4353159066 — keep distinct): §1 INPUT-FIELDS POPULATION — parser-grammar gap; nested Map<String, X> literals don't parse in record-field positions. Even empty `{}` fails the Map type check (parses as record). Whole pilot row deferred; empty list lands as scaffolding. Substrate-tracked Phase 1.5+ slice (#1130 comment 4353153545). §2 v2 PARAMETER DEFAULTS — InputField.default carrier deferred; v2's max_tokens: Int = 4096 not represented. Substrate-tracked Phase 1.5+ slice (#1130 comment 4352585286). messages_pilot_present test #[ignore]'d with re-arm instructions; list-shape + uniqueness + ParamToken→inputs boundary checks land (vacuous on empty list but wired for Phase 1.5 row population). Pre-merge gate: regen clean; integration tests 3 passed + 1 ignored; parse-corpus manifest refreshed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…edicate + runner (#1314) * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * regen bootstrap after std.effects import path fix * WIP: sharp-raven-604 * chore: apply cargo fmt * WIP: sharp-raven-604 * regen bootstrap + refresh parse manifest after merge * WIP: sharp-raven-604 * WIP: sharp-raven-604 * WIP: sharp-raven-604 * PR-α: wrap Operation.callable in CallableRef (typed wrapper, mirrors MethodRef) * chore: apply cargo fmt * doc: align test comments with CallableRef wrapper (cosmetic) * regen bootstrap after merge main * T-Substrate-AnthropicSchemaMirror: v3 typed mirror for Anthropic Messages signature - src/v3/std/anthropic_schema.dag: type-authority-only mirror of provider-domain types reachable from operation Messages signature in dsl/extdeps/llm/anthropic.dag (AnthropicChatMessage + content block variants, AnthropicStopReason, AnthropicMessages200{TextBlock,Usage,Body}). - AnthropicErrorShape deferred (4xx/5xx response slot only; not on the typed return reach for fn anthropic_messages -> AnthropicMessages200Body). - src/v3/compiler/tests/integration/anthropic_schema_lockstep_test.rs: 8 ratchets pinning v3 mirror against v2 source (variant labels, field labels, type-name presence in v2). Discipline mirrors method_registry_test.rs. - Type authority only — no fn anthropic_messages, no Operation rows. Those are the next substrate precursor that consumes these types. * WIP: sharp-raven-604 * chore: apply cargo fmt * anthropic_schema lockstep: couple expected labels to v2 source + optionality Manager review on PR #1261: the prior lockstep tests asserted v3 labels against hard-coded constants and only checked v2 type-name presence. They would NOT catch v2 source drift on field/variant labels themselves. This commit: - Extracts the v2 type-block text via v2_type_block(name). - assert_lockstep_record / assert_lockstep_disj now verify each expected label appears literally in the v2 block, fail-closed on either-side drift. - New anthropic_optional_fields_remain_optional_in_v2_source asserts the '?' suffix on is_error: Bool? and stop_sequence: String? in the v2 source, with comment explaining structural inspection of v3 optionality is deferred to the operation-row precursor (per manager guidance). * anthropic_schema lockstep: bidirectional set equality + structural optionality OpenAI-Pro REQUEST_CHANGES on PR #1261: prior ratchet only checked v3 set == expected and expected ⊆ v2. v2 additions silently passed; v3 optionality was text-only on the v2 side, not structurally checked on v3. Strengthened: - v2_record_fields(name) parses the v2 type block and extracts (label, is_optional) tuples directly from the source. v2_disj_variants(name) extracts variant labels (including from inline 'A | B | C' and multi-line '= Foo {} | Bar {}' shapes). - assert_record_lockstep / assert_disj_lockstep assert SET EQUALITY between v2-extracted set and v3 bootstrap set (BTreeSet diff in the failure message names v3-only and v2-only labels). - Optionality is structural on v3: v3_field_is_optional walks the field declaration's TypeConnective and matches Cardinality(AtMostOne, _). Each v2 'T?' field must lower optional; each v2 'T' field must NOT. - New test anthropic_user_content_block_user_tool_result_block_optionality reaches the variant payload Conj for UserToolResultBlock and asserts is_error: Bool? lowers as Cardinality(AtMostOne, Bool) on the inner declaration (variant payloads aren't reached by the record-level ratchet). * chore: apply cargo fmt * fix clippy: use char array in split (manual char comparison lint) * WIP: sharp-raven-604 * anthropic_schema lockstep: per-variant payload field+optionality coverage OpenAI-Pro REQUEST_CHANGES on PR #1261: assert_disj_lockstep compared only variant labels, leaving variant payload field labels and optionality unguarded — UserToolResultBlock.content / tool_use_id and AssistantToolUseBlock.id / name / input could drift between v2 and v3 while the test passed. This commit: - v2_disj_variants now returns (label, Option<Vec<(field_label, is_optional)>>), parsing variant payload bodies via the same logic v2_record_fields uses (extracted as parse_v2_brace_body_fields). - v3_variant_payload_fields walks the v3 variant target's Conj declaration and projects (label, Cardinality(AtMostOne, _)?) tuples. - assert_disj_lockstep extends to per-variant payload set equality and optionality: bare-on-bare passes; record-on-record requires set equality + optionality match; mismatched (one-side bare, other-side payload) fails closed. - Drops the redundant special-case is_error optionality test — now subsumed by structural per-variant payload coverage on AnthropicUserContentBlock. * chore: apply cargo fmt * WIP: sharp-raven-604 * chore: apply cargo fmt * WIP: sharp-raven-604 * anthropic_schema lockstep: type-expression equality (records + variant payloads) OpenAI-Pro REQUEST_CHANGES on PR #1261 (sha 1e08a24): label + optionality weren't enough to catch field type drift — content: List<X> could become content: String while tests stayed green. Adds: - v3_canonical_ty(dag, ty): walks declarations to produce a canonical type-expression string. Named decls (String, Bool, AnthropicStopReason, AnthropicMessages200TextBlock, …) canonicalize as their surface name even though their underlying connective unfolds to Instantiation (e.g. String = FreeMonoid<Int>). Anonymous Instantiation sites (List<X>, Map<K, V>) and Cardinality(AtMostOne, T) get unfolded. - normalize_ty_text(raw): strips trailing '?' and compresses internal whitespace so v2 source text matches v3 canonical form. - v2_record_fields and parse_v2_brace_body_fields now return (label, normalized_ty_text, is_optional); v3_variant_payload_fields returns (label, canonical_ty, is_optional). - assert_record_lockstep and assert_disj_lockstep added type-expression equality assertions in addition to label-set equality and optionality. Optionality is checked separately, so the type comparison strips the trailing '?' on both sides and compares inner-element forms only. Coverage: every mirrored field across AnthropicChatMessage, AnthropicUserContentBlock (incl. UserToolResultBlock.content/tool_use_id), AnthropicAssistantContentBlock (incl. AssistantToolUseBlock.input: Json), AnthropicMessages200TextBlock, AnthropicMessages200Usage (input_tokens: Int), and AnthropicMessages200Body (content: List<...>, stop_sequence: String?) now fails closed if v2 carrier type changes. * anthropic_schema lockstep: also reject Arrow declarations (fn leak guard) Codex non-blocking improvement on PR #1261: prior anthropic_schema_authors_no_data_rows test rejected only declarations with value_body: Some(...), so a future fn anthropic_messages would lower as TypeConnective::Arrow with value_body: None and bypass the guard. Renamed to ..._or_fns and extended the filter to also reject TypeConnective::Arrow declarations authored in src/v3/std/anthropic_schema.dag. * chore: apply cargo fmt * T-Substrate-AnthropicMessagesCallable: fn anthropic_messages declaration Service-operation callable declaration precursor for the Anthropic Messages REST operation, the substrate slice Grounding PR-β #1252 is waiting on per parent #1130 dispatch. Adds: - src/v3/std/anthropic_messages.dag: top-level fn anthropic_messages with honest signature consuming v3.std.anthropic_schema mirror types (#1261). Returns AnthropicMessages200Body. host body lowers as ArrowBody::Unparsed (no producerless realization carrier minted). - src/v3/compiler/tests/integration/anthropic_messages_callable_test.rs: 5 ratchets — Arrow shape, parameter type list matches v2 source via v3 mirror, return type is AnthropicMessages200Body, callable is acceptable as Operation.callable.decl target, no Operation/data rows leak (those are PR-β scope). Two intentional simplifications vs v2 (documented in file header): - max_tokens: Int (v2 'Int = 4096'); v3 has no parameter defaults so the default is a caller-side fold, not a v3 contract change. - Return is the 200 body only; AnthropicErrorShape is PR-β response/ wire lockstep concern. Out of scope: anthropic_operations: List<Operation> data row, sibling binding/realization data rows. Grounding owns those. * chore: apply cargo fmt * chore: restore comment/test adjacency in SG-0 census (cosmetic) Reviewer (claude opus 4.7) non-blocking exploratory observation on PR #1266: the alphabetical insertion of anthropic_messages_callable_test.rs and anthropic_schema_lockstep_test.rs split the PB Tier-2 #1014 comment block from the test it describes. Moving the comment two lines down restores adjacency. No behavior change. * anthropic_messages: pin Unparsed body + correct file header prose OpenAI-Pro REQUEST_CHANGES on PR #1266: the file header claimed 'host anthropic_messages' lowers to ArrowBody::ExternalRealization, but the generated substrate has ArrowBody::Unparsed(span). Prose did not match the substrate fact, and no test pinned the body class so a silent rewrite was invisible. Fixes: - File header rewritten to honestly describe the actual lowered state: body remains Unparsed because the pipeline-stage post-processing patch in bootstrap.rs:256 is pipeline-specific and does not fire for service-operation callables. The patch is intentionally not added (would require a producerless CompilerHostRealization-style data row, the parallel surface the #1130 dispatch rejects). - New ratchet anthropic_messages_body_is_unparsed pins ArrowBody::Unparsed; a silent rewrite to ExternalRealization / UserDefined / Pending / NoBody fails closed. - File header explicitly bounds the unparsed-body state to the same dissolution trigger as the schema mirror. * regen bootstrap: re-sync byte spans after anthropic_messages.dag header rewrite * T-Verification-BridgeLedger: substrate carrier for bridge-retirement ledger Adds: - src/v3/std/bridge_ledger.dag: substrate authority for the bridge- retirement ledger Verification's BridgeLedgerZero TestClaim folds. - BridgeStatus = Retired | Open (closed two-variant coproduct; structural partition, no stringly status). - BridgeLedgerRow { name, owner, status, authority } per dispatch contract. - data bridge_ledger: List<BridgeLedgerRow> = [...] populates the five canonical bridge rows from docs/r3-structure.md:79-83. - Per-row status rationale documented in file header: source-span- file-participation Open, mark-bootstrap-secret-nominal-opacity Retired, canonical-lens-name-dispatch Retired, include-str-side- channels Open, exact-string-patching-residual Open. - src/v3/compiler/tests/integration/bridge_ledger_carrier_test.rs: 6 ratchets — BridgeLedgerRow field set, BridgeStatus closed two- variant coproduct, bridge_ledger lowers as List<BridgeLedgerRow>, five canonical names in document order, name uniqueness, status field resolves structurally to a BridgeStatus constructor (not a string). - bootstrap regen + parse manifest refresh + integration mod entry + SG-0 census entry. Single substrate authority — no parallel Rust Vec, no test-side ledger table. Verification's BridgeLedgerZero fold is out of scope for this PR per dispatch. * regen bootstrap + manifest after merging origin/main * T-Verification-BridgeLedger: predicate variant + runner branch (Director scope extension) Per parent #1130 dispatch (#4356094666) extending #1314: substrate authority for BridgeLedgerZero gate, not just the carrier. Adds: - src/v3/std/verification.dag: TestPredicate variant BridgeLedgerZero { ledger: DeclarationRef }. Single payload field preserves typed-edge discipline; structural identity, not stringly ledger reference. - src/v3/compiler/src/test_runner.rs: eval_bridge_ledger_zero branch. Resolves the ledger DeclarationRef, walks ValueBody::List rows, reads each row's status Variant, partitions by structural comparison against BridgeStatus::Retired's variant id (not by name). Returns Pass iff every row is Retired; Fail names the open rows in declaration order. - src/v3/compiler/tests/integration/bridge_ledger_carrier_test.rs: Two new tests: - bridge_ledger_zero_predicate_carries_only_ledger_declaration_ref: pins the variant's payload set to {ledger} and asserts ledger's type is DeclarationRef from v3.spec.v3_l1. - bridge_ledger_zero_runner_fails_with_named_open_rows_at_head: compiles a TestClaim referencing the ledger via DeclarationRef and runs it through TestRunner. At HEAD with three Open rows (source_span_file_participation, include_str_side_channels, exact_string_patching_residual), expects Fail with all three named and the two Retired rows excluded. Re-arms as Pass once all five flip to Retired. - bootstrap regen + parse manifest refresh. 8/8 tests pass; clippy clean. Verification's #1310 can now author the .dag TestClaim consuming this predicate. * chore: apply cargo fmt * doc: bridge_ledger comment cites correct canonical-lens ratchet test (cosmetic) Reviewer (cursor) NON-BLOCKING finding on PR #1314: per-row rationale for bridge_canonical_lens_name_dispatch_retired cited bridge_lower_helpers_patch_zero_residual_test (lower-helper exact-string patch lane) instead of the canonical-lens-name-dispatch ratchet at canonical_lens_bridge_ratchet_test.rs. Comment text only; bootstrap + manifest re-synced for the byte-span shift. * WIP: sharp-raven-604 * eval_bridge_ledger_zero: enforce canonical ledger identity (single-authority) Codex REQUEST_CHANGES on PR #1314: the previous type-check accepted any List<BridgeLedgerRow> declaration, so a sibling list could become a parallel ledger authority and pass the gate independently of the canonical bridge_ledger. INVARIANTS P2 / single-authority violation. Adds: - Canonical-identity check before the type-check guard: the resolved ledger DeclarationId must match dag.declaration_by_name('bridge_ledger').id. Sibling List<BridgeLedgerRow> declarations fail closed with a diagnostic naming the canonical authority. Type-check stays as defense-in-depth (catches a future carrier-shape drift). - New test bridge_ledger_zero_runner_fails_closed_on_sibling_canonical_ shape_ledger: compiles a sibling 'data sibling_ledger: List<BridgeLedgerRow> = []' and asserts BridgeLedgerZero fails closed because the declaration identity isn't the canonical one (even though the type IS compatible). - Existing wrong-type test updated: identity check fires first for any non-canonical ledger, so the assertion now expects the canonical-identity diagnostic. * chore: apply cargo fmt * WIP: sharp-raven-604 * BridgeLedgerZero: tighten payload typing, per-row authority pointers, fail-closed name field Codex BLOCKING(3) on PR #1314 sha b5f7dd5: 1. Authority document: external doc anchor was generic. Made bridge_ledger.dag the explicit substrate authority for rows; per-row 'authority' field now points at the concrete ratchet (test, PR, or gating doc-anchor) that establishes that row's status, not a generic taxonomy heading. Status flips from Open to Retired are gated on the named ratchet reaching zero residual: - source_span_file_participation -> ROADMAP.md#lens-fold-file-path-semantics - mark_bootstrap_secret_nominal_opacity -> PR #937 - canonical_lens_name_dispatch -> canonical_lens_bridge_ratchet_test.rs - include_str_side_channels -> PR #1171 - exact_string_patching_residual -> bridge_lower_helpers_patch_zero_residual_test.rs 2. Predicate schema typing: TestPredicate::BridgeLedgerZero.ledger now typed as BridgeLedgerRef (typed wrapper { decl: DeclarationRef }), mirror of MethodRef / CallableRef. Adds bridge_ledger.dag::BridgeLedgerRef with the same #1175 substrate-gap dissolution trigger. Runner unwraps the record at the predicate boundary. 3. Runner row validation: missing or non-String name field now fails closed instead of using a placeholder, even before status partition. Defensive at the claim boundary, complementing the carrier ratchet that already guards bridge_ledger.dag's substrate-side shape. 10/10 tests pass on the new payload shape: predicate-shape ratchet updated to require BridgeLedgerRef wrapper (not bare DeclarationRef); runner tests use BridgeLedgerZero { ledger: { decl: <ref> } } literal construction; sibling-canonical-shape and wrong-type negative tests still fire fail-closed. * verification ratchet: include BridgeLedgerZero variant after main rebase m1_5_verification_test::bootstrap_loads_verification_authority_types expected variant list still ended at SubstrateResearchDeferredClaim; appended ('BridgeLedgerZero', vec!['ledger']) to match the live bootstrap. Bootstrap+manifest re-synced from the post-merge regen. 10/10 bridge_ledger_carrier tests + 1/1 verification ratchet pass. * doc: align eval_bridge_ledger_zero rustdoc with BridgeLedgerRef payload (cosmetic) Reviewer (cursor) NON-BLOCKING on PR #1314: rustdoc on eval_bridge_ledger_zero still described the predicate as { ledger: DeclarationRef } even though the substrate surface (and the implementation) now requires the BridgeLedgerRef { decl: DeclarationRef } wrapper. INVARIANTS 'documentation describes live state' alignment. Comment-only; no behavior change; .rs file edit so no bootstrap regen needed. * bridge_ledger tests: derive row set + open/retired partition from live ledger (single-authority) Codex BLOCKING on PR #1314: CANONICAL_BRIDGES + expected_open/retired arrays copied the ledger row set and status partition into Rust, creating exactly the test-side parallel table bridge_ledger.dag rules out (single-authority / M7). - Removed the CANONICAL_BRIDGES const and the bridge_ledger_carries_canonical_five_names_in_doc_order test (the test re-asserted ledger content from a hardcoded copy; row content authority lives only in bridge_ledger.dag). - bridge_ledger_lowers_as_list_with_at_least_one_row replaces the earlier exact-five-rows assertion: pins the structural shape (List value_body, every entry a Record, non-empty) without duplicating the row count. - bridge_ledger_zero_runner_fails_with_named_open_rows_at_head no longer hardcodes expected_open_rows / expected_retired_rows. It reads the live ledger from the bootstrap, partitions by structural comparison against BridgeStatus::Retired's variant id, and asserts: every Open row's name appears in the failure diagnostic and every Retired row's name does not. Re-arms automatically as upstream rows flip status — the test does not need an update each time. 9/9 tests pass; clippy clean. The only authority for ledger row content is now src/v3/std/bridge_ledger.dag. * bridge_ledger: repoint umbrella row authority at open-scope prose, not closed sub-slice ratchet OpenAI-Pro REQUEST_CHANGES on PR #1314: the bridge_exact_string_patching_residual_retired row's authority pointed at bridge_lower_helpers_patch_zero_residual_test.rs, the receipt for the RETIRED lower-helper sub-slice (#1014). The row stays Open because *other* exact-string patching classes remain outside that receipt's scope, so the closed-slice test was misleading as the row's authority. Repointed authority at docs/r3-structure.md:83 — the prose row where the umbrella's open-scope framing ('Other exact-string patching classes ... keep their own dissolution triggers') is defined. Each 'other class' has its own trigger; the umbrella row retires when those triggers all fire. Per-row inline comment in bridge_ledger.dag explains the distinction. * WIP: sharp-raven-604 * regen bootstrap + manifest after main rebase (clean conflicts)
Summary
T-Substrate-AnthropicSchemaMirror — v3 typed mirror of provider-domain schema types reachable from
dsl/extdeps/llm/anthropic.dag'soperation Messagessignature.Scope discipline:
datarows, nofndeclarations.fn anthropic_messagesand anyOperationrow land in the next substrate slice that consumes these types — outside this PR.service { operation { transport rest { … } } }block; pullinganthropic.dagwholesale intoBOOTSTRAP_FIXTURE_PATH_KEYSwould lower the service block asValueBody::Unparsed. This file is a v3-shaped typed twin, not a parse-import.Dag::new(); the integration test consumes the production accessor surface.Adds:
src/v3/std/anthropic_schema.dag— type authority only. Mirrors:AnthropicChatMessage(UserMessage/AssistantMessagediscriminator)AnthropicUserContentBlock(UserTextBlock/UserToolResultBlock)AnthropicAssistantContentBlock(AssistantTextBlock/AssistantToolUseBlock)AnthropicStopReason(closed Anthropic API enum, all 7 variants)AnthropicMessages200TextBlock/AnthropicMessages200Usage/AnthropicMessages200Bodysrc/v3/compiler/tests/integration/anthropic_schema_lockstep_test.rs— 9 ratchets pinning v3 mirror againstdsl/extdeps/llm/anthropic.dag. Each ratchet (a) walks the mirrored type's connective in the bootstrap and asserts the expected field/variant label set, then (b) extracts the matchingtype <name>block from the v2 source and asserts every expected label is present in that block — coupling the expected set to the v2 source itself, not just to constants in the test. Plus a textual optionality ratchet onis_error: Bool?andstop_sequence: String?.Out of scope (deferred)
AnthropicErrorShape— covers the 4xx/5xx response slot only; not on the typed return reach forfn anthropic_messages -> AnthropicMessages200Body. Lands with the response/wire lockstep lane (Grounding's PR-β scope).AnthropicModel,AnthropicModelSpec,AnthropicToolDefinition,AnthropicApiVersion,SystemPrompt,CacheControl,ThinkingMode,ThinkingConfig— outside the Messages operation's direct signature reach.fn anthropic_messagesand anyOperationdata row — next substrate precursor.Why a v3 typed twin (rather than ingesting
anthropic.dagdirectly)Per the prior
#1246STOP+PING: pullingdsl/extdeps/llm/anthropic.dagwholesale intoBOOTSTRAP_FIXTURE_PATH_KEYSwould lower the v2service { … }block asValueBody::Unparsed(v3's parser does not handle that DSL today). This file is the typed twin authored on the v3 surface — same staged-fixture discipline asMethodTemplateContract(#1195) andservices.dagPR-α (#1246).Dissolution trigger
When v3 grows a service-DSL parse/load surface that ingests
dsl/extdeps/llm/*.dagwith full structural fidelity, this twin retires — the v2 source becomes the only authority and this file collapses. Tracked dissolution per modeling-discipline (feedback_parallel_representation_debt).Local verification commands
Test plan
🤖 Generated with Claude Code