197 lines
5.6 KiB
Markdown
197 lines
5.6 KiB
Markdown
# amduatd API v2 Design (PEL-only writes)
|
|
|
|
## Status
|
|
|
|
Draft proposal for discussion.
|
|
First server slice implemented: `POST /v2/pel/execute` with `inputs.refs`,
|
|
`inputs.inline_artifacts[{body_hex,type_tag?}]`, and required `receipt`.
|
|
|
|
## Goals
|
|
|
|
- Keep `amduatd` thin: transport, parsing, auth, and mapping to core calls.
|
|
- Make **PEL the only write primitive** in HTTP v2.
|
|
- Enforce artifact provenance for writes: adding new artifacts must go through:
|
|
1. store inputs,
|
|
2. run a PEL program,
|
|
3. persist and return receipt.
|
|
- Keep `/v1/*` behavior unchanged while v2 is introduced.
|
|
|
|
## Non-goals
|
|
|
|
- Re-implementing PEL semantics in `amduat-api`.
|
|
- Creating new substrate semantics in daemon code.
|
|
- Removing v1 immediately.
|
|
|
|
## High-level model
|
|
|
|
v2 separates read and write concerns:
|
|
|
|
- Read paths remain direct and deterministic (`GET /v2/meta`, `GET /v2/artifacts/{ref}`, federation/space read endpoints).
|
|
- All state-changing operations are executed as PEL runs.
|
|
|
|
In v2, `POST /v1/artifacts` equivalent is replaced by a mutation endpoint that always drives a PEL run.
|
|
|
|
For simplified clients, v2 also exposes async operation endpoints:
|
|
|
|
- `POST /v2/ops/put`
|
|
- `POST /v2/ops/concat`
|
|
- `POST /v2/ops/slice`
|
|
- `GET /v2/jobs/{id}`
|
|
|
|
These enqueue work and execute PEL in the daemon background loop.
|
|
|
|
Graph-oriented endpoints can be added as thin wrappers over concepts/relations:
|
|
|
|
- `POST /v2/graph/nodes` (maps to concept create/publish)
|
|
- `POST /v2/graph/edges` (maps to relation edge append)
|
|
- `GET /v2/graph/nodes/{name}` (node + versions + incoming/outgoing edges)
|
|
- `GET /v2/graph/history/{name}` (version + edge timeline)
|
|
|
|
## Versioning and contract id
|
|
|
|
- Base path: `/v2`
|
|
- Contract id: `AMDUATD/API/2`
|
|
- Keep the same store-seeded contract model used in v1.
|
|
|
|
## Endpoint shape
|
|
|
|
### Read-only endpoints (v2)
|
|
|
|
- `GET /v2/meta`
|
|
- `GET /v2/contract`
|
|
- `GET /v2/artifacts/{ref}`
|
|
- `HEAD /v2/artifacts/{ref}`
|
|
- `GET /v2/artifacts/{ref}?format=info`
|
|
- Space/federation read endpoints can be mirrored under `/v2/*` unchanged where possible.
|
|
|
|
### Write endpoints (v2)
|
|
|
|
- `POST /v2/pel/execute`
|
|
|
|
No direct artifact write endpoint in v2 (`POST /v2/artifacts` is intentionally absent).
|
|
|
|
## `POST /v2/pel/execute`
|
|
|
|
Single mutation primitive for v2.
|
|
|
|
### Request
|
|
|
|
```json
|
|
{
|
|
"program_ref": "<hex-ref-or-name>",
|
|
"scheme_ref": "dag",
|
|
"params_ref": "<optional-ref-or-name>",
|
|
"inputs": {
|
|
"refs": ["<hex-ref-or-name>"],
|
|
"inline_artifacts": [
|
|
{
|
|
"content_type": "application/octet-stream",
|
|
"type_tag": "0x00000000",
|
|
"body_hex": "48656c6c6f"
|
|
}
|
|
]
|
|
},
|
|
"receipt": {
|
|
"input_manifest_ref": "<ref-or-name>",
|
|
"environment_ref": "<ref-or-name>",
|
|
"evaluator_id": "local-amduatd",
|
|
"executor_ref": "<ref-or-name>",
|
|
"started_at": 1731000000,
|
|
"completed_at": 1731000005
|
|
},
|
|
"effects": {
|
|
"publish_outputs": true,
|
|
"append_fed_log": true
|
|
}
|
|
}
|
|
```
|
|
|
|
### Processing contract
|
|
|
|
Server behavior is deterministic and ordered:
|
|
|
|
1. Resolve `program_ref`, `scheme_ref`, `params_ref`, and `inputs.refs` to refs.
|
|
2. Decode and store `inputs.inline_artifacts` into ASL store.
|
|
3. Build effective `input_refs = refs + stored_inline_refs`.
|
|
4. Execute PEL using core `pel_surf_run_with_result`.
|
|
5. Build FER receipt from run result + receipt fields.
|
|
6. Store receipt artifact and return `receipt_ref`.
|
|
7. Apply requested side effects (`publish_outputs`, `append_fed_log`) after successful run.
|
|
|
|
If any step fails:
|
|
|
|
- return non-2xx,
|
|
- do not publish outputs,
|
|
- do not append federation publish records.
|
|
|
|
## Response
|
|
|
|
```json
|
|
{
|
|
"run_ref": "<pel1-result-ref>",
|
|
"trace_ref": "<optional-trace-ref>",
|
|
"receipt_ref": "<fer1-receipt-ref>",
|
|
"stored_input_refs": ["<ref>"],
|
|
"output_refs": ["<ref>"],
|
|
"status": "OK"
|
|
}
|
|
```
|
|
|
|
Notes:
|
|
|
|
- `stored_input_refs` are refs created from `inline_artifacts`.
|
|
- `receipt_ref` is required for successful writes in v2.
|
|
|
|
## Error model
|
|
|
|
- `400` invalid request or schema violation.
|
|
- `404` referenced input/program/params not found.
|
|
- `409` conflict in post-run side effects (e.g. cursor/update conflicts).
|
|
- `422` run completed but business policy failed (reserved for policy checks).
|
|
- `500` internal failure.
|
|
|
|
Error payload:
|
|
|
|
```json
|
|
{
|
|
"error": {
|
|
"code": "invalid_input_ref",
|
|
"message": "input ref not found",
|
|
"retryable": false
|
|
}
|
|
}
|
|
```
|
|
|
|
## Behavioral differences from v1
|
|
|
|
- Removed write path: direct `POST /artifacts`.
|
|
- New requirement: every write returns a receipt ref tied to a PEL run.
|
|
- `pel/run` semantics become the write gateway rather than an optional compute endpoint.
|
|
|
|
## Compatibility and rollout
|
|
|
|
1. Add `/v2/pel/execute` while keeping `/v1/*` unchanged.
|
|
2. Mirror core read endpoints under `/v2/*`.
|
|
3. Mark `POST /v1/artifacts` as deprecated in docs.
|
|
4. Migrate clients to v2 execute flow.
|
|
5. Remove v1 write endpoints in a later major release.
|
|
|
|
## Open questions
|
|
|
|
- Should v2 require exactly one output for write operations, or allow multiple outputs with one receipt?
|
|
- Should inline artifact body support both `body_hex` and `body_base64`, or move to multipart for large payloads?
|
|
- Should `publish_outputs` default to `true` or be explicit-only?
|
|
- Do we need async execution (`202 + run status endpoint`) for long-running programs in v2?
|
|
|
|
## Minimal implementation plan
|
|
|
|
1. Add v2 contract bytes (`registry/amduatd-api-contract.v2.json`).
|
|
2. Add `/v2/pel/execute` handler by adapting existing `POST /v1/pel/run` + artifact ingest path.
|
|
3. Factor shared receipt parsing/building from current v1 pel handler.
|
|
4. Add tests:
|
|
- inline artifact -> stored -> run -> receipt success,
|
|
- failure before run,
|
|
- failure during run,
|
|
- side effect gating (no publish on failure).
|
|
5. Document deprecation notice for `POST /v1/artifacts`.
|