Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ exports:
- source/surface semantic validation;
- compiler context facts and authority-fact loading;
- source-to-Core compiler spine for the current supported subset;
- Core IR data structures;
- Core IR data structures, including non-callable typed external-action request
values;
- depth-bounded canonical-CBOR encoding/decoding plus canonical Core, Target IR,
bundle-layer encoders and digest helpers;
- target-profile conformance checks;
Expand Down Expand Up @@ -64,15 +65,15 @@ Module map:
| `ast` | Source-level syntax tree types. |
| `semantic` | Surface validation that does not require import resolution or target facts. |
| `authority_facts` | File-backed compiler context facts for profiles, budgets, write classes, and source identity. |
| `compiler` | Resolve, type-check, and lower the supported source subset to Core IR. |
| `core_ir` | Runtime-neutral Core module, intent, expression, budget, import, and obstruction data. |
| `compiler` | Resolve, type-check, and lower the supported source subset to Core IR, including typed external-action request construction without execution authority. |
| `core_ir` | Runtime-neutral Core module, intent, expression, budget, import, obstruction, and external-action request data. |
| `canonical` | Canonical value model, depth-bounded canonical CBOR encoder/decoder, digest frames, and reviewed golden digest helpers. |
| `target_profile` | Runtime-neutral target-profile manifest conformance. |
| `lowerability` | Checks whether Core requirements can be satisfied natively, by a direct adapter, or not at all. |
| `provider` | Runtime-neutral provider manifest and generated/component provenance envelope validation. |
| `provider_invocation` | Pure host-contract, explicitly injected owning-schema, WIT-shaped request/result, canonical artifact, limit, and sealed output-manifest validation. |
| `provider_lowering` | Explicit in-process compatibility adapters over the current built-in target lowerers. |
| `target_ir` | Current Echo and git-warp Target IR artifact construction from Core plus lowering facts. |
| `target_ir` | Current Echo and git-warp Target IR artifact construction from Core plus lowering facts, preserving external requests outside callable target steps. |
| `contract_bundle` | Participant-neutral bundle assembly, bundle digest preimages, validation, and assurance evidence binding. |
| `admission` | Edict-owned Gate C request/receipt shape and binding validation without participant policy execution. |
| `highlight` | Lexical highlight roles consumed by editor tooling. |
Expand Down Expand Up @@ -171,7 +172,7 @@ source text
-> semantic surface validation
-> compiler context facts
-> compiler spine
-> Core IR
-> Core IR (including typed external-action request data)
-> canonical Core bytes and digest
-> lowerability + target facts
-> direct lowering or built-in lowerer compatibility adapter
Expand Down Expand Up @@ -220,6 +221,8 @@ Use these rules when placing new code:
This workspace does not yet implement:

- target runtime execution;
- external-action request admission, adapter execution, or settlement
resumption;
- participant admission execution;
- participant policy evaluation;
- trusted lawpack or target-profile authorship;
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ versions still track specification maturity rather than a released product.

### Added

- Added typed external-action request values without adding external execution
authority to Edict. Digest-locked capability imports and `request` statements
preserve exact operation, schema, scope, basis, budget, input, reconciliation,
and awaiting-settlement data through canonical Core and Target IR. Operation
families remain bound in the semantic capability closure and the current
allowlist admits only the domain-specific `workspace` root. Floating
capabilities, empty request resources, duplicate request ids, capability
aliases outside request position, and raw ambient operation families reject
with stable kinds. Target steps remain non-callable, the provider seam gains
no host import, and checked Core/Target request goldens bind the complete
public request identity.
- Added the compiler-owned `edict.result-projection/v1` artifact for preserving
typed application results across the Echo target boundary. The bounded,
canonical projection names only declared application input and
Expand Down
4 changes: 2 additions & 2 deletions EDICT.md
Original file line number Diff line number Diff line change
Expand Up @@ -1267,9 +1267,9 @@ intent <name>(input: <Type>)

| Family | Codes |
| --- | --- |
| Parser (19) | `Lex`, `ExpectedToken`, `ExpectedKeyword`, `ExpectedIdentifier`, `ExpectedExpression`, `InvalidInteger`, `InvalidDigest`, `InvalidVersion`, `ReservedKeyword`, `UnsupportedSyntax`, `InvalidName`, `EmptyEnum`, `EmptyObstructionMap`, `EmptyMatch`, `MissingRequiredField`, `DuplicateField`, `NonCallEffect`, `ReturnInYieldBlock`, `InvalidTypeCall` |
| Parser (20) | `Lex`, `ExpectedToken`, `ExpectedKeyword`, `ExpectedIdentifier`, `ExpectedExpression`, `InvalidInteger`, `InvalidDigest`, `InvalidVersion`, `ReservedKeyword`, `UnsupportedSyntax`, `InvalidName`, `EmptyEnum`, `EmptyObstructionMap`, `EmptyMatch`, `MissingRequiredField`, `DuplicateField`, `NonCallEffect`, `NonCallExternalActionOperation`, `ReturnInYieldBlock`, `InvalidTypeCall` |
| Semantic (7) | `UnboundedScalar`, `MissingOperationMode`, `MissingBudget`, `MissingBasis`, `DuplicateIntentClause`, `DuplicateName`, `ShadowedName` |
| Compiler (10) | `SurfaceValidation`, `MissingContextFact`, `UnsupportedSourceShape`, `UnresolvedType`, `UnknownField`, `TypeMismatch`, `ExpectedPredicate`, `ProfileEffectMismatch`, `DuplicateObstructionFailure`, `DuplicateObstructionPayloadField` |
| Compiler (11) | `SurfaceValidation`, `MissingContextFact`, `UnsupportedSourceShape`, `UnresolvedType`, `UnknownField`, `TypeMismatch`, `ExpectedPredicate`, `ProfileEffectMismatch`, `UnrequestableExternalOperation`, `DuplicateObstructionFailure`, `DuplicateObstructionPayloadField` |
| CLI exit codes | `0` ok · `1` compiler/validation diagnostics · `2` invalid CLI input |

### D.5 Digest domains
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -575,10 +575,14 @@ What exists today:
`let ... = effect(arg) else { failure(binder) => Obstruction }` source shape
lowers through file-backed authority facts into typed Core with a semantic
effect node and deterministic obstruction map
- Typed external-action request construction: digest-locked operation families,
schemas, scope, basis, budgets, and reconciliation law lower as non-callable
Core and Target IR data with exact capability closure
- Reference `edict.canonical-cbor/v1` Core encoder and canonical byte validation
path for the current in-memory Core module model
- Reviewed Core golden bytes and exact `edict.core.module/v1` digest fixture for
the initial pure local-record Core artifact
the initial pure local-record Core artifact and typed workspace-snapshot
external request
- Typed v1 target-profile manifest conformance for runtime-neutral profile
validation, including `echo.dpo@1` and `kv.transactional@1` shaped profiles
- Typed v1 lowerability checks for `LoweringRequirements` against explicit
Expand All @@ -605,8 +609,8 @@ What exists today:
through the binary
- Published `v0.11.0-alpha.1` release notes for contract-bundle assembly and
canonical Target IR artifact bytes/digests: semantic/release bundle digest
goldens, Echo/git-warp Target IR byte/digest goldens, and computed
`targetIrDigest` bundle assembly from real `TargetIrArtifact` values
goldens, Echo/git-warp/workspace-request Target IR byte/digest goldens, and
computed `targetIrDigest` bundle assembly from real `TargetIrArtifact` values
- Published `v0.8.0-alpha.1` release notes for the minimal effectful
compiler-spine alpha
- Published `v0.7.0-alpha.1` release notes for the file-backed
Expand Down Expand Up @@ -638,6 +642,8 @@ What doesn't exist yet:
participant acceptance policy
- Target-runtime execution, Echo verifier reports, git-warp commit object
creation, or git-warp CRDT reducer verification
- External-action admission, adapter execution, settlement witnessing, or
settlement-driven resumption
- Canonical bytes for full `ContractBundleManifest` values
- Full admission execution tooling
- Participant policy evaluation, capability delegation, and revocation logic
Expand Down
28 changes: 28 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,33 @@ Edict owns deterministic validation of fact provenance, digest binding, review
references, and artifact shape. Continuum and participants own trust policy,
identity, delegation, revocation, and acceptance decisions.

## Parallel Integration Track: Typed External Requests

Milestone: `Typed External Requests` (#17)

Primary issue: #172

Roadmap label: `roadmap-a1`

This cross-repository track follows Echo's durable external-action protocol and
precedes Hello Echo's first bounded workspace observation:

```text
Echo #694 durable request and settlement protocol
-> Edict #172 typed request values
-> Hello Echo #10 observed workspace settlement proof
```

Edict owns deterministic request construction, exact operation/schema/law
identity, capability closure, and non-callable Core/Target IR representation.
Echo owns request admission, durability, adapter coordination, settlement,
recovery, and replay. Adapters alone own external authority.

The milestone closes when request source, Core, Target IR, canonical identity,
negative authority cases, and provider-seam non-authority are implemented and
validated. It does not add direct I/O, general algebraic effects, native stack
suspension, writable model authority, or the autonomous delivery loop.

## v2-design - Future Design Track

Milestone: `v2-design`
Expand Down Expand Up @@ -762,6 +789,7 @@ Milestones:
- `v0.13.0-alpha.1`: planned, issues TBD
- `v0.14.0-alpha.1`: planned, issues TBD
- `v0.15.0-alpha.1`: planned, issues TBD
- `Typed External Requests`: #172
- `v2-design`: #4

Alpha-train release labels:
Expand Down
73 changes: 70 additions & 3 deletions crates/edict-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ use edict_syntax::{
CoreBudget, CoreExpr, CoreImport, CoreIntent, CoreNode, CoreObstructionArm,
CoreObstructionReason, CorePredicate, CoreRequireFailureArm, CoreType, CoreValue,
HighlightRole, InputConstraint, InputConstraintSource, ParseError, ResourceRef, SemanticError,
Span, TargetEffectLowering, TargetIrArtifact, TargetIrIntent, TargetIrLoweringFacts,
TargetIrRequireFailure, TargetIrRequirement, TargetIrSemanticClosure, TargetIrStep,
TargetLoweringFailure, TargetLoweringFailureKind, WriteClass,
Span, TargetEffectLowering, TargetIrArtifact, TargetIrExternalActionRequest, TargetIrIntent,
TargetIrLoweringFacts, TargetIrRequireFailure, TargetIrRequirement, TargetIrSemanticClosure,
TargetIrStep, TargetLoweringFailure, TargetLoweringFailureKind, WriteClass,
};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
Expand Down Expand Up @@ -1189,6 +1189,7 @@ fn compiler_error_kind_name(kind: CompilerErrorKind) -> &'static str {
CompilerErrorKind::TypeMismatch => "TypeMismatch",
CompilerErrorKind::ExpectedPredicate => "ExpectedPredicate",
CompilerErrorKind::ProfileEffectMismatch => "ProfileEffectMismatch",
CompilerErrorKind::UnrequestableExternalOperation => "UnrequestableExternalOperation",
CompilerErrorKind::DuplicateObstructionFailure => "DuplicateObstructionFailure",
CompilerErrorKind::DuplicateObstructionPayloadField => "DuplicateObstructionPayloadField",
}
Expand Down Expand Up @@ -1261,6 +1262,11 @@ fn target_ir_semantic_closure_review(closure: &TargetIrSemanticClosure) -> Value
.iter()
.map(resource_ref_review)
.collect::<Vec<_>>(),
"capabilities": closure
.capabilities
.iter()
.map(resource_ref_review)
.collect::<Vec<_>>(),
})
}

Expand All @@ -1279,6 +1285,11 @@ fn target_ir_intent_review(intent: &TargetIrIntent) -> Value {
.map(target_ir_requirement_review)
.collect::<Vec<_>>(),
"steps": intent.steps.iter().map(target_ir_step_review).collect::<Vec<_>>(),
"externalActionRequests": intent
.external_action_requests
.iter()
.map(target_ir_external_action_request_review)
.collect::<Vec<_>>(),
"result": core_expr_review(&intent.result),
});
insert_optional_review_field(
Expand Down Expand Up @@ -1331,6 +1342,28 @@ fn target_ir_step_review(step: &TargetIrStep) -> Value {
})
}

fn target_ir_external_action_request_review(request: &TargetIrExternalActionRequest) -> Value {
json!({
"id": request.id,
"binding": local_ref_review(&request.binding),
"operation": resource_ref_review(&request.operation),
"inputType": request.input_type,
"settlementType": request.settlement_type,
"inputSchema": resource_ref_review(&request.input_schema),
"settlementSchema": resource_ref_review(&request.settlement_schema),
"input": core_expr_review(&request.input),
"authorityScope": core_expr_review(&request.authority_scope),
"basis": core_expr_review(&request.basis),
"budget": {
"maxSettlementBytes": core_expr_review(&request.budget.max_settlement_bytes),
"maxAttempts": core_expr_review(&request.budget.max_attempts),
},
"reconciliationLaw": resource_ref_review(&request.reconciliation_law),
"state": "awaitingSettlement",
"settlementAdmission": "schemaRequired",
})
}

fn core_import_review(import: &CoreImport) -> Value {
json!({
"kind": import.kind.as_str(),
Expand Down Expand Up @@ -1362,6 +1395,9 @@ fn core_type_review(ty: &CoreType) -> Value {
json!({ "kind": "map", "key": key, "value": value, "max": max })
}
CoreType::CapabilityRef { item } => json!({ "kind": "capabilityRef", "item": item }),
CoreType::ExternalActionRequest { settlement } => {
json!({ "kind": "externalActionRequest", "settlement": settlement })
}
}
}

Expand Down Expand Up @@ -1423,6 +1459,37 @@ fn core_node_review(node: &CoreNode) -> Value {
.map(|(name, arm)| (name.clone(), obstruction_arm_review(arm)))
.collect::<BTreeMap<_, _>>(),
}),
CoreNode::ExternalActionRequest {
binding,
operation,
input_type,
settlement_type,
input_schema,
settlement_schema,
input,
authority_scope,
basis,
budget,
reconciliation_law,
} => json!({
"kind": "externalActionRequest",
"binding": local_ref_review(binding),
"operation": resource_ref_review(operation),
"inputType": input_type,
"settlementType": settlement_type,
"inputSchema": resource_ref_review(input_schema),
"settlementSchema": resource_ref_review(settlement_schema),
"input": core_expr_review(input),
"authorityScope": core_expr_review(authority_scope),
"basis": core_expr_review(basis),
"budget": {
"maxSettlementBytes": core_expr_review(&budget.max_settlement_bytes),
"maxAttempts": core_expr_review(&budget.max_attempts),
},
"reconciliationLaw": resource_ref_review(reconciliation_law),
"state": "awaitingSettlement",
"settlementAdmission": "schemaRequired",
}),
}
}

Expand Down
Loading