Skip to content

Publish canonical external request application artifacts - #177

Merged
flyingrobots merged 16 commits into
mainfrom
task/176-external-request-artifacts
Jul 30, 2026
Merged

Publish canonical external request application artifacts#177
flyingrobots merged 16 commits into
mainfrom
task/176-external-request-artifacts

Conversation

@flyingrobots

@flyingrobots flyingrobots commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • publish exact compiler-owned Core and Target IR for explicit external-action builds
  • validate root-reachable, digest-bound request authority without invoking provider components
  • bind request-only lawpack profiles to exact budgets and target configuration

Closes #176.

Plain-English Walkthrough

[CLAIM: explicit route] buildKind: externalAction selects a separate public build route while the omitted field preserves the existing executable-operation default. Source

[CLAIM: compiler ownership] The route writes the canonical Core and Target IR bytes returned by Edict encoders, before any provider-component selection or invocation. Source

[CLAIM: authority closure] Publication requires at least one typed request, refuses callable target steps, binds operation authority by an exact root-reachable manifest digest, and rejects disconnected lawpacks. Request gate Root closure

[CLAIM: no callable grant] A request-only lawpack profile must supply a budget and target configuration while carrying no semantic effects; compiler facts retain the profile-to-budget association. Source

[CLAIM: reproducible closure] The owning generator builds and checks the manifest, exports, adapter, configuration, source, Core, and Target IR as one exact corpus. Source

flowchart LR
    S[Exact Edict source] --> C[Canonical Core]
    L[Root-reachable lawpack closure] --> C
    C --> T[Canonical Target IR]
    T --> G{Request-only gate}
    G -->|accepted| O[core.cbor and target-ir.cbor]
    G -->|callable or unbound| R[typed refusal]
    P[Provider components] -. not invoked .-> G
Loading

Validation

  • cargo xtask verify
  • request-only profile budget mismatch regression
  • disconnected lawpack and manifest-digest authority regressions
  • exact Echo target-profile byte comparison
  • Echo production vocabulary scan: no Graft, Hello Echo, greeting, or workspace-snapshot terms

@flyingrobots

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@flyingrobots

Copy link
Copy Markdown
Owner Author

@codex please review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added request-only application builds using buildKind: externalAction.
    • Builds now publish canonical Core and Target IR artifacts without invoking providers or performing external actions.
    • Added reproducible workspace snapshot build support with exact capability, budget, and target configuration validation.
  • Bug Fixes

    • Prevented invalid mixed callable/request builds and capability substitutions.
    • Replaced output artifacts transactionally and removed stale executable-build outputs.
  • Documentation

    • Added CLI guidance, requirements, test plans, schemas, and workspace snapshot examples for the new build mode.

Walkthrough

Adds an explicit externalAction application-build route that validates request-only Target IR, publishes canonical Core and Target IR artifacts transactionally, extends lawpack adapter profiles with request-only bindings, and adds reproducible workspace-snapshot fixtures and coverage.

Changes

External-action application build

Layer / File(s) Summary
Request-only profile contract
crates/edict-syntax/src/lawpack_adapter.rs, docs/abi/..., fixtures/provider-contracts/..., crates/edict-syntax/tests/lawpack.rs
Operation profiles support optional budget and target-configuration references; empty semantic-effect profiles require exact bindings and are validated accordingly.
Workspace snapshot golden closure
xtask/src/lawpack_goldens.rs, fixtures/lawpack/workspace-snapshot/*, fixtures/providers/echo-target-profile/README.md
Generates and records the manifest, adapter, configuration, source, Core, Target IR, and digest artifacts for a request-only workspace snapshot.
Application build routing and validation
crates/edict-cli/src/application_build.rs, docs/topics/cli/README.md, docs/topics/external-action-requests/README.md, docs/REQUIREMENTS.md, README.md, CHANGELOG.md
Adds buildKind, validates typed external-action requests, rejects callable-step mixtures and capability substitution, and bypasses provider setup for the external-action route.
Paired artifact publication and coverage
crates/edict-cli/src/application_build.rs
Stages, atomically publishes, rolls back, and removes obsolete output pairs while testing validation, determinism, stale-output cleanup, and failure behavior.
Lawpack and external-request contract documentation
docs/topics/lawpacks/*, docs/topics/README.md
Documents request-only profile requirements, reproducible workspace-snapshot artifacts, and the boundary before provider execution.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant build_application
  participant LawpackAdapter
  participant TargetIrArtifact
  participant OutputPublisher
  Client->>build_application: submit application manifest
  build_application->>LawpackAdapter: validate lawpack closure and profile bindings
  build_application->>TargetIrArtifact: compile and lower source
  TargetIrArtifact-->>build_application: canonical Core and Target IR
  build_application->>OutputPublisher: publish core.cbor and target-ir.cbor
Loading

Possibly related PRs

Poem

A request takes shape in canonical light,
Core and Target IR lock tight.
No callable step may slip the gate,
Old outputs vanish; pairs translate.
Goldens hum where digests align.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR matches #176: it adds the externalAction route, validates request-only closure, emits canonical Core/Target IR, and preserves executable-operation builds.
Out of Scope Changes check ✅ Passed The added docs, fixtures, tests, and goldens all support the external-request build feature and do not appear unrelated.
Title check ✅ Passed The title clearly summarizes the main change: publishing canonical external-request application artifacts.
Description check ✅ Passed The description directly matches the changeset, covering external-action builds, request-only profiles, and canonical artifact publication.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bb1cbc5d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/edict-syntax/src/lawpack_adapter.rs
Comment thread crates/edict-cli/src/application_build.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/edict-cli/src/application_build.rs`:
- Around line 455-483: Clarify or enforce the operation-coordinate invariant
used by validate_external_action_artifacts: the current rsplit_once('@') and
id-prefix checks incorrectly reject valid lawpack operations and classify
malformed coordinates as closure substitution. Either document and validate this
coordinate schema at the lawpack ABI boundary, or change the substituted
detection to use digest-only binding and report malformed coordinates through a
separate validation error.
- Around line 1479-1549: Update the rollback publication flow around the
output-building function to derive published recovery entries from the `outputs`
slice rather than assuming exactly two items. Change the `outputs` and
`obsolete` parameters from fixed-size arrays to slices, size `destinations` from
the slice lengths, and replace the hard-coded reverse indices with a reverse
iteration over `outputs` zipped to the corresponding published recovery entries
and staged paths. Preserve publishing in reverse order and keep obsolete
recoveries excluded from publication.

In `@crates/edict-syntax/src/lawpack_adapter.rs`:
- Around line 65-70: Add concise doc comments to the budget_obligation and
target_configuration fields of LawpackAdapterOperationProfile, documenting that
both are mandatory when semantic_effects is empty (request-only profiles) and
optional otherwise. Keep the validation behavior in validate_adapter_closure
unchanged.

In `@crates/edict-syntax/tests/lawpack.rs`:
- Around line 275-410: Extract the duplicated request-only adapter construction
from the three tests into a shared request_only_adapter helper, parameterized by
optional budgetObligation and whether to include targetConfiguration. Update
request_only_profile_supplies_budget_without_callable_effect_authority,
request_only_profile_requires_an_exact_budget_obligation, and
request_only_profile_requires_an_exact_target_configuration to use the helper
while preserving each test’s existing setup and assertions.

In `@docs/REQUIREMENTS.md`:
- Line 71: Update the ID Scheme section of REQUIREMENTS.md to declare the
EDICT-CLI domain alongside the existing legal prefixes before retaining the new
EDICT-CLI-EXTERNAL-REQUEST-BUILD-001 requirement row. Keep the row’s identifier
unchanged and ensure the domain declaration explicitly covers CLI requirements.

In `@docs/topics/cli/README.md`:
- Around line 79-90: The request-only route documentation must explain why the
example still requires providerPackage: it is used only to load and verify the
provider manifest and target-profile artifact, not to invoke a provider
component. Add this clarification near the example and state that omitting
providerPackage causes InvalidApplicationConfig, while preserving the existing
no-component-host behavior.

In `@docs/topics/cli/test-plan.md`:
- Line 45: Reconcile the CLI-REQ-015 status with its available evidence: because
CLI-TP-028 remains planned and no automated executable-provider fixture exists,
do not mark the executable build route implemented based only on CLI-TP-027.
Either reference a test that witnesses the full lowerer/verifier/provider-host
and output crossing, or restore the prior status and leave the externalAction
scope unchanged.

In `@docs/topics/external-action-requests/test-plan.md`:
- Line 71: Add a Fixtures-table row documenting the publication-determinism
corpus seed used by
external_action_pair_publication_is_deterministic_for_a_fixed_seed_corpus,
including the STRESS_SEED value from application_build.rs. Ensure EXTREQ-TP-018
and the Determinism Obligations section reference this recorded seed explicitly.

In `@fixtures/providers/echo-target-profile/README.md`:
- Around line 6-17: Convert the Provenance evidence block in the README from
bullet points to a two-column table with consistent labels and values for
repository, source commit, source path, generator identity, Edict domain-framed
identity, and raw file SHA-256; preserve all existing values unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 48353942-39bf-45eb-ab3a-480aa897f674

📥 Commits

Reviewing files that changed from the base of the PR and between eb873d3 and 4bb1cbc.

⛔ Files ignored due to path filters (1)
  • fixtures/providers/echo-target-profile/generated/primary/target-profile.echo-dpo.cbor is excluded by !**/generated/**
📒 Files selected for processing (32)
  • CHANGELOG.md
  • README.md
  • crates/edict-cli/src/application_build.rs
  • crates/edict-syntax/src/lawpack_adapter.rs
  • crates/edict-syntax/tests/lawpack.rs
  • docs/REQUIREMENTS.md
  • docs/abi/edict-lawpack-adapter.cddl
  • docs/topics/README.md
  • docs/topics/cli/README.md
  • docs/topics/cli/test-plan.md
  • docs/topics/external-action-requests/README.md
  • docs/topics/external-action-requests/test-plan.md
  • docs/topics/lawpacks/README.md
  • docs/topics/lawpacks/test-plan.md
  • fixtures/lawpack/workspace-snapshot/README.md
  • fixtures/lawpack/workspace-snapshot/adapter.cbor
  • fixtures/lawpack/workspace-snapshot/adapter.sha256
  • fixtures/lawpack/workspace-snapshot/exports.cbor
  • fixtures/lawpack/workspace-snapshot/exports.sha256
  • fixtures/lawpack/workspace-snapshot/manifest.cbor
  • fixtures/lawpack/workspace-snapshot/manifest.sha256
  • fixtures/lawpack/workspace-snapshot/observe-workspace.core.cbor
  • fixtures/lawpack/workspace-snapshot/observe-workspace.core.sha256
  • fixtures/lawpack/workspace-snapshot/observe-workspace.edict
  • fixtures/lawpack/workspace-snapshot/observe-workspace.target-ir.cbor
  • fixtures/lawpack/workspace-snapshot/observe-workspace.target-ir.sha256
  • fixtures/lawpack/workspace-snapshot/request-profile-configuration.cbor
  • fixtures/lawpack/workspace-snapshot/request-profile-configuration.sha256
  • fixtures/provider-contracts/v1/edict-provider-contracts.cddl
  • fixtures/provider-contracts/v1/manifest.json
  • fixtures/providers/echo-target-profile/README.md
  • xtask/src/lawpack_goldens.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: rust msrv 1.94.0 (fmt · clippy · test)
  • GitHub Check: rust stable (fmt · clippy · test)
  • GitHub Check: supply-chain (cargo-deny)
🧰 Additional context used
📓 Path-based instructions (6)
**/*

📄 CodeRabbit inference engine (AGENTS.md)

**/*: Never amend Git commits, use git rebase without explicit user approval, or force any Git operation; use new commits and regular merge commits instead.
Do not create draft pull requests, and never use a codex prefix in branch names, pull request titles, or commit messages.
Pull requests for issue work must include GitHub auto-close text such as Closes #123`` for every issue they intend to close.
Use codex-think --remember --json when starting a session, entering the repository, or regaining context, and record significant durable events with `codex-think "..." --json`. Treat Think as memory rather than repository truth.
Every pull request body must contain `## Plain-English Walkthrough` with `### TL;DR` and `### Walkthrough`, explaining the prior behavior, new model and dataflow, invariants, failures, compatibility, and verification as applicable.
Use Mermaid diagrams for nontrivial flow, lifecycle, ownership, or component interaction when clearer than prose; every diagram requires an introductory paragraph, the diagram, the exact collapsed caption structure, and a concluding interpretation.
Tag each material technical claim at first occurrence as `[claim:, confidence:]`, cite evidence using repository-relative paths, line numbers, and Git SHAs, and end the explanatory body with a collapsed citations appendix.
If CodeRabbit is actively reviewing, obtain its approval before merge; if unavailable due to limits or credits, request `@codex review please` and wait for the alternate response. Do not treat unavailability as approval unless a maintainer explicitly overrides the gate.
For release preparation, write the release thesis first, reconcile changes from the previous tag, update release policy and tests, verify the milestone has no open issues and no unauthorized crates.io publication occurred, and record a durable release report.
Run `cargo xtask verify` before claiming a branch is ready.

Files:

  • fixtures/lawpack/workspace-snapshot/manifest.sha256
  • fixtures/lawpack/workspace-snapshot/adapter.sha256
  • fixtures/lawpack/workspace-snapshot/exports.sha256
  • fixtures/lawpack/workspace-snapshot/observe-workspace.core.sha256
  • docs/topics/README.md
  • README.md
  • fixtures/lawpack/workspace-snapshot/request-profile-configuration.cbor
  • fixtures/lawpack/workspace-snapshot/request-profile-configuration.sha256
  • fixtures/lawpack/workspace-snapshot/observe-workspace.target-ir.sha256
  • fixtures/lawpack/workspace-snapshot/exports.cbor
  • fixtures/providers/echo-target-profile/README.md
  • fixtures/lawpack/workspace-snapshot/observe-workspace.target-ir.cbor
  • docs/REQUIREMENTS.md
  • docs/abi/edict-lawpack-adapter.cddl
  • fixtures/lawpack/workspace-snapshot/manifest.cbor
  • fixtures/lawpack/workspace-snapshot/README.md
  • fixtures/provider-contracts/v1/edict-provider-contracts.cddl
  • fixtures/provider-contracts/v1/manifest.json
  • CHANGELOG.md
  • docs/topics/external-action-requests/test-plan.md
  • fixtures/lawpack/workspace-snapshot/observe-workspace.edict
  • fixtures/lawpack/workspace-snapshot/adapter.cbor
  • fixtures/lawpack/workspace-snapshot/observe-workspace.core.cbor
  • docs/topics/external-action-requests/README.md
  • docs/topics/lawpacks/test-plan.md
  • docs/topics/cli/README.md
  • docs/topics/lawpacks/README.md
  • crates/edict-syntax/tests/lawpack.rs
  • xtask/src/lawpack_goldens.rs
  • docs/topics/cli/test-plan.md
  • crates/edict-syntax/src/lawpack_adapter.rs
  • crates/edict-cli/src/application_build.rs
docs/topics/**

📄 CodeRabbit inference engine (AGENTS.md)

docs/topics/**: Topic shelves document landed behavior: README.md describes current HEAD truth, test-plan.md records verification and known gaps, and optional architecture or rationale pages contain durable supporting information.
For every nontrivial behavior, contract, workflow, release, schema, validation, or public-surface change, identify or create the owning topic shelf, update test-plan.md, add executable evidence, update README.md only after behavior exists, and run cargo xtask verify.
Do not update topic shelves for purely mechanical edits that do not change a contract; explain the omission in the pull request or final report.

Files:

  • docs/topics/README.md
  • docs/topics/external-action-requests/test-plan.md
  • docs/topics/external-action-requests/README.md
  • docs/topics/lawpacks/test-plan.md
  • docs/topics/cli/README.md
  • docs/topics/lawpacks/README.md
  • docs/topics/cli/test-plan.md
**/*.{rs,md}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,md}: Tests must assert software behavior and stable error kinds or structured artifacts, not implementation details, prose, paths, or merely is_err(); documentation-tool tests may test validator behavior.
For nontrivial behavior, contract, workflow, release, schema, validation, or public-surface changes, follow RED/GREEN TDD: update the owning test-plan.md, write the deterministic test first, observe the RED failure, implement the smallest coherent fix, then mark the case implemented only after executable evidence exists.

Files:

  • docs/topics/README.md
  • README.md
  • fixtures/providers/echo-target-profile/README.md
  • docs/REQUIREMENTS.md
  • fixtures/lawpack/workspace-snapshot/README.md
  • CHANGELOG.md
  • docs/topics/external-action-requests/test-plan.md
  • docs/topics/external-action-requests/README.md
  • docs/topics/lawpacks/test-plan.md
  • docs/topics/cli/README.md
  • docs/topics/lawpacks/README.md
  • crates/edict-syntax/tests/lawpack.rs
  • xtask/src/lawpack_goldens.rs
  • docs/topics/cli/test-plan.md
  • crates/edict-syntax/src/lawpack_adapter.rs
  • crates/edict-cli/src/application_build.rs
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{md,mdx}: Documentation pages must have one primary reader job, separate user task help from contributor architecture and evidence maps, use concrete valid examples with expected results when relevant, and keep exact public facts in validated or generated reference material.
Update affected documentation in the same change as behavior, schema, release, workflow, or public-surface changes, or state docs-impact: none with a concise rationale.

Files:

  • docs/topics/README.md
  • README.md
  • fixtures/providers/echo-target-profile/README.md
  • docs/REQUIREMENTS.md
  • fixtures/lawpack/workspace-snapshot/README.md
  • CHANGELOG.md
  • docs/topics/external-action-requests/test-plan.md
  • docs/topics/external-action-requests/README.md
  • docs/topics/lawpacks/test-plan.md
  • docs/topics/cli/README.md
  • docs/topics/lawpacks/README.md
  • docs/topics/cli/test-plan.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Use tables for consistent-shape comparisons and evidence, bullets for unordered sets, numbered lists for ordered procedures or states, and focused branch-accurate snippets for exact syntax.

Files:

  • docs/topics/README.md
  • README.md
  • fixtures/providers/echo-target-profile/README.md
  • docs/REQUIREMENTS.md
  • fixtures/lawpack/workspace-snapshot/README.md
  • CHANGELOG.md
  • docs/topics/external-action-requests/test-plan.md
  • docs/topics/external-action-requests/README.md
  • docs/topics/lawpacks/test-plan.md
  • docs/topics/cli/README.md
  • docs/topics/lawpacks/README.md
  • docs/topics/cli/test-plan.md
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: For Rust changes, preserve claim integrity by providing executable evidence, keep compiler and validation paths deterministic and free of hidden I/O, and prefer structured public failures with stable error kinds over prose-only diagnostics.
Do not add Rust dependencies without pull-request rationale and contract-impact notes; treat planned lint, dependency, and fuzzing ratchets as planned until executable checks land.

Files:

  • crates/edict-syntax/tests/lawpack.rs
  • xtask/src/lawpack_goldens.rs
  • crates/edict-syntax/src/lawpack_adapter.rs
  • crates/edict-cli/src/application_build.rs
🧠 Learnings (3)
📚 Learning: 2026-07-29T12:58:15.297Z
Learnt from: flyingrobots
Repo: flyingrobots/edict PR: 174
File: fixtures/provider-contracts/v1/edict-provider-contracts.cddl:798-829
Timestamp: 2026-07-29T12:58:15.297Z
Learning: When reviewing CDDL schema files and generated provider-contract fixtures for Rust result projections, ensure the schema-expressible bounds match what the authoritative decoder enforces: `maxOutputBytes` must be positive; root-record fields must be ≤ 255; source-path segments must be ≤ 32. Also verify the decoder’s non-CDDL-global runtime limits are respected/consistent—specifically the 256 recursive expression-node limit and the 64 KiB canonical artifact-byte limit—so the CDDL constraints don’t drift from `crates/edict-syntax/src/result_projection.rs`.

Applied to files:

  • docs/abi/edict-lawpack-adapter.cddl
  • fixtures/provider-contracts/v1/edict-provider-contracts.cddl
📚 Learning: 2026-07-29T12:58:25.905Z
Learnt from: flyingrobots
Repo: flyingrobots/edict PR: 174
File: fixtures/provider-contracts/v1/edict-provider-contracts.cddl:798-829
Timestamp: 2026-07-29T12:58:25.905Z
Learning: When reviewing Edict result projection CDDL fixtures (e.g., provider-contracts/*/edict-provider-contracts.cddl generated from docs/abi/edict-result-projection.cddl), ensure the CDDL enforces only the CDDL-expressible *local* bounds: `maxOutputBytes` must be positive, records must have at most 255 fields, source-paths must have at most 32 segments, and text length limits must be present. Do not rely on (or duplicate) global limits for recursive expression nodes and total canonical-artifact bytes in CDDL; those *global* limits are intentionally enforced during authoritative decode/verification by `crates/edict-syntax/src/result_projection.rs`, which is invoked by `crates/edict-cli/src/application_build.rs` before provider binding.

Applied to files:

  • fixtures/provider-contracts/v1/edict-provider-contracts.cddl
📚 Learning: 2026-07-29T12:58:32.500Z
Learnt from: flyingrobots
Repo: flyingrobots/edict PR: 174
File: fixtures/provider-contracts/v1/edict-provider-contracts.cddl:798-829
Timestamp: 2026-07-29T12:58:32.500Z
Learning: When reviewing CDDL artifacts for `edict.result-projection/v1` (both `docs/abi/edict-result-projection.cddl` and the generated `fixtures/provider-contracts/v1/edict-provider-contracts.cddl`), ensure the CDDL-expressible bounds remain correct: `maxOutputBytes` must be positive, each record must have at most 255 fields, and each record must have at most 32 source-path segments. Also confirm reviewers understand and preserve that the whole-value constraints—(1) the 256 aggregate-expression-node limit and (2) the 64 KiB encoded-artifact limit—are enforced authoritatively in `decode_result_projection`/`verify_result_projection` (`crates/edict-syntax/src/result_projection.rs`), and that `crates/edict-cli/src/application_build.rs` independently verifies the compiler-owned projection before using it as provider semantic input. Do not assume the CDDL constraints cover those whole-value limits; keep CDDL and Rust validation logic consistent when changes are proposed.

Applied to files:

  • fixtures/provider-contracts/v1/edict-provider-contracts.cddl
🔇 Additional comments (38)
crates/edict-cli/src/application_build.rs (5)

51-64: LGTM!


290-313: LGTM!


769-775: LGTM!


1354-1420: LGTM!

Also applies to: 1641-1668


1919-2104: LGTM!

Also applies to: 2306-2497, 2525-2703

docs/topics/cli/README.md (1)

29-34: LGTM!

Also applies to: 64-78, 91-99

docs/topics/external-action-requests/README.md (1)

67-83: LGTM!

docs/topics/cli/test-plan.md (1)

46-46: LGTM!

Also applies to: 55-56, 106-107, 126-129

docs/topics/external-action-requests/test-plan.md (1)

39-39: LGTM!

Also applies to: 48-48, 68-70

README.md (1)

581-583: LGTM!

CHANGELOG.md (1)

28-37: LGTM!

docs/topics/README.md (1)

61-61: LGTM!

docs/topics/lawpacks/README.md (1)

44-52: LGTM!

Also applies to: 81-95, 118-119

docs/topics/lawpacks/test-plan.md (2)

50-53: LGTM!

Also applies to: 63-63


79-79: 🩺 Stability & Availability

No change needed for LAWPACKS-TP-011.
The cited witnesses exist and assert structured failure behavior for the negative cases.

crates/edict-syntax/src/lawpack_adapter.rs (4)

304-346: Parsing correctly decoupled from validation.

parse_operation_profiles correctly treats budgetObligation/targetConfiguration as unconditionally optional at parse time and relaxes semanticEffects to permit [], deferring the "required when request-only" enforcement to validate_adapter_closure. Consistent with the CDDL union in docs/abi/edict-lawpack-adapter.cddl (lines 23-35).


472-488: 🎯 Functional Correctness

Request-only budget/target-configuration gate is logically sound.

Traced all four combinations of budget_obligation/semantic_effects: Some(budget) always inserts into required_budgets regardless of effects (line 474); None + empty effects correctly fails MissingBudget (line 476-480); the second check independently fails InvalidTargetConfiguration only when effects are empty and target_configuration is absent (line 482-488). This matches the two-branch CDDL union in docs/abi/edict-lawpack-adapter.cddl exactly — non-request-only profiles keep both fields optional, request-only profiles require both.

One residual question: target_configuration is validated here only for presence, never resolved/read again in this file (prepare_lawpack_compilation, shown in the provided context snippet, never touches profile.target_configuration). Confirm that's intentional (i.e. its digest-locked payload is interpreted downstream by the target profile/provider rather than by the compiler), and not a forgotten wiring step for actually threading the request-profile configuration into TargetIrLoweringFacts.


507-513: exact_keys budgets check correctly widened.

Moving this to after the profile loop means required_budgets now includes both effect-derived cost_obligations and profile-level budget_obligations before the exhaustiveness check against adapter.budgets. Correct.


65-70: 🎯 Functional Correctness

No action needed. The only LawpackAdapterOperationProfile struct literal already sets all added fields, including budget_obligation and target_configuration.

docs/abi/edict-lawpack-adapter.cddl (1)

23-35: Union alternation correctly models the request-only vs. effect-bearing split.

semanticEffects: [+ tstr] (non-empty) vs. semanticEffects: [] (empty, with budgetObligation/targetConfiguration promoted to mandatory) are structurally disjoint on the array-length constraint, so there's no ambiguity between the two branches. Matches the Rust enforcement in validate_adapter_closure.

fixtures/provider-contracts/v1/edict-provider-contracts.cddl (1)

587-599: 🗄️ Data Integrity & Integration

Byte-for-byte match with the source ABI fragment — but this file says "DO NOT EDIT."

The union here is identical to docs/abi/edict-lawpack-adapter.cddl (lines 23-35), which is correct in substance. Since the file header states Generated from Edict-owned ABI fragments. DO NOT EDIT., confirm this was produced by re-running the actual generator (presumably part of cargo xtask verify) rather than hand-copied, so future regenerations don't silently diverge from a manually-synced copy.

As per coding guidelines: "Run cargo xtask verify before claiming a branch is ready."

Source: Coding guidelines

xtask/src/lawpack_goldens.rs (6)

64-90: LGTM!


98-120: LGTM!


122-226: Golden generation correctly enforces the "exactly one request, zero callable steps" invariant.

Digest dependency ordering (exports → configuration → adapter → manifest) is correct, and the post-lowering assertion (request_count != 1 || any(!steps.is_empty())) matches issue #176's requirement to reject mixed callable/request execution for this fixture. Good defensive check for a fixture generator that could otherwise silently emit a golden that doesn't exercise the intended scenario.


228-330: Fixture construction matches the new request-only adapter schema.

workspace_snapshot_adapter correctly uses the empty-semanticEffects branch with both budgetObligation and targetConfiguration populated — this is the one place in the diff that actually exercises the new CDDL/Rust validation branch end-to-end.


332-368: LGTM!


370-409: 🗄️ Data Integrity & Integration

Same manifest digest locks both the lawpack and capability imports — confirm this is intended, not copy-paste. The root cause is workspace_snapshot_application_source's digest wiring; the fixture file is a faithful, mechanical reproduction of that choice, not an independent defect.

  • xtask/src/lawpack_goldens.rs#L370-L409: verify ImportKind::Capability digest resolution semantics against the actual compiler import-resolution code before trusting that reusing bundle.manifest_digest_review_string() for the capability import is correct (there's no prior fixture using use capability to cross-check against).
  • fixtures/lawpack/workspace-snapshot/observe-workspace.edict#L3-L4: no fixture-side change needed unless the generator's digest wiring turns out to be wrong, in which case this file must be regenerated via cargo xtask lawpack-goldens --write.
fixtures/lawpack/workspace-snapshot/observe-workspace.core.sha256 (1)

1-1: LGTM!

fixtures/lawpack/workspace-snapshot/observe-workspace.edict (1)

1-35: Intent body matches the external-action-request-node / external-action-budget CDDL shape.

authority, basis (both intent-level and request-level), and budget { maxSettlementBytes, maxAttempts } line up field-for-field with external-action-request-node/external-action-budget in edict-provider-contracts.cddl. Nothing to flag beyond the digest-reuse question noted above.

fixtures/lawpack/workspace-snapshot/observe-workspace.target-ir.cbor (1)

1-1: LGTM!

fixtures/lawpack/workspace-snapshot/observe-workspace.target-ir.sha256 (1)

1-1: LGTM!

fixtures/lawpack/workspace-snapshot/request-profile-configuration.cbor (1)

1-1: LGTM!

fixtures/lawpack/workspace-snapshot/request-profile-configuration.sha256 (1)

1-1: LGTM!

fixtures/providers/echo-target-profile/README.md (1)

19-21: LGTM!

crates/edict-syntax/tests/lawpack.rs (1)

1092-1131: LGTM!

fixtures/lawpack/workspace-snapshot/README.md (1)

1-43: LGTM!

fixtures/provider-contracts/v1/manifest.json (1)

6-7: 🗄️ Data Integrity & Integration

No change needed. rawSha256 matches the decoded bytesHex payload.

fixtures/lawpack/workspace-snapshot/manifest.cbor (1)

1-2: 🗄️ Data Integrity & Integration

No digest issue here. The sidecar hashes match their corresponding .cbor canonical digests; the earlier mismatch came from using a non-canonical digest format, not a fixture desync.

Comment thread crates/edict-cli/src/application_build.rs
Comment thread crates/edict-cli/src/application_build.rs
Comment thread crates/edict-syntax/src/lawpack_adapter.rs
Comment thread crates/edict-syntax/tests/lawpack.rs
Comment thread docs/REQUIREMENTS.md
Comment thread docs/topics/cli/README.md Outdated
Comment thread docs/topics/cli/test-plan.md Outdated
Comment thread docs/topics/external-action-requests/test-plan.md Outdated
Comment thread fixtures/providers/echo-target-profile/README.md Outdated
@flyingrobots

Copy link
Copy Markdown
Owner Author

@codex please review current head 7668c20

@flyingrobots
flyingrobots merged commit 97ef5ea into main Jul 30, 2026
4 checks passed
@flyingrobots
flyingrobots deleted the task/176-external-request-artifacts branch July 30, 2026 01:12
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 7668c2077c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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.

Emit canonical external-request application artifacts

1 participant