Compile closed execution plans and checked artifact manifests

This commit is contained in:
Timothy J. Aveni
2026-09-19 23:27:00 -07:00
parent 15c132a38b
commit ac36edf62d
11 changed files with 1193 additions and 39 deletions
+86
View File
@@ -0,0 +1,86 @@
# Closed execution plans and artifacts
`compileExecutionPlan` validates a workspace, links its checked queries, resolves
public forwarding, and emits one versioned plan with an SHA-256 digest. It retains
exact interface/package revisions and generic applications, owner initialization,
storage definitions/profiles, selected operation identities, query placement, and
source provenance. `quixos-workspace-compile --execution-plan-out PATH` writes it.
The compiler emits operation dependencies as a graph. A traversed interface port
retains its edge/projection and exact selected operations; native reads identify
the canonical storage inputs. Cycles do not become infinitely expanded paths.
Execution and admission must apply their runtime depth/work budgets when walking
this graph. The plan includes the full linked GraphQL selections, not just root
traversals or a list of fields.
Local and replica queries must have the same root contract. A local query cannot
introduce a relationship path absent from its replica source; authors expand the
source selection explicitly. Portable getters may require extra canonical fields
and exactly-one dependency traversals, recorded in the dependency graph. Admission
resolves those inputs on the server for selected objects. This never changes the
source query's candidate membership, and does not claim a limited source is a
complete interface extent. An incomplete runtime projection remains a coverage
state, not permission to invent a missing value.
A portable transaction cannot depend on a local presentation query, including
through a selector. Pass explicit references and preconditions as mutation input.
Otherwise an admitted top-N list could select different mutation targets locally
and at acceptance. Remote transactions can implement explicit server workflows.
This restriction does not ban local queries from snapshot selectors. Such query
ports are view-relative: both hosts must use the frame's admitted candidate
universe. An executor must report unavailable coverage when that view is absent,
not substitute a full-server extent. Query-port acquisition remains unavailable
until the query executor implements this rule; emitting its checked dependency
graph is not runtime support.
## Artifacts and world identity
`PackageArtifacts` describes one package output containing a process service and
optional target modules. Implementation IDs are stable manifest keys, separate
from export capability IDs and JavaScript registry names. Each implementation
covers its ABI, export map, entrypoint, and declared asset paths/digests/sizes/MIME.
Its digest excludes its own digest field. Paths must be normalized and relative.
`checkExecutionWorld` verifies plan identity, supported codecs, exact source and
binding schema, service fallback, promised targets, declared exports, and all
supplied file bytes. The reader must confine paths/symlinks to the checked output
and honor its byte limit before allocation. LF-05 supplies that filesystem adapter,
checks actual module registries/imports, and verifies build receipts; a manifest
claim alone does not establish the JavaScript exports or an isolated process.
The returned `camino-world-v1` descriptor includes every declared implementation
and its digest, so executor choice does not change semantics or silently load new
code. Each binding key is the JSON pair `[packageRevisionId, implementationId]`;
there can be both a service and module for the server target. World hashing uses
the core codec's canonical ordering and domain-separated SHA-256 framing. The
monorepo `camino-execution-world` check compares the compiler and core implementations.
No machine-local Nix path enters the world descriptor.
The current binding schema is the closed workspace schema. This is conservative:
an unrelated contract change can require checking/rebuilding several packages.
LF-05 may narrow it to exact checked per-package closures, but must use the same
schema for generation, receipts, and world validation. It must not substitute an
older package schema just because the source revision did not change.
## Transaction-port ABI
`quixos-transaction-ports-v1` uses coordinator-issued frame/invocation handles and
monotonic invocation-local sequence numbers. A package receives its export ID,
input, and optional receiver. Port calls name a declared port and its allowed
primitive or exact interface operation; they never select arbitrary private slots,
packages, or coordinator transactions. Creation uses an explicit stable call key. Interface calls into transaction
operations also require a stable key, checked after resolving the selected
operation. The coordinator extends the birth path; it never derives that path
from an asynchronous completion order or the transport sequence number.
The coordinator resolves each port through the installed operation binding,
checks effects/selected methods, validates typed arguments/references, and joins
nested calls to the outer logical transaction. A nested failure rolls back to its
frame boundary; process completion cannot independently commit. The coordinator
owns savepoints, cancellation, frame expiry, and rejection. These enforcement
mechanisms are LF-06/LF-08, not guarantees provided by TypeScript frame types.
The service control vocabulary includes readiness, cancellation, and shutdown;
transport framing and generated adapters are LF-05/LF-08. Portable modules and
services implement the same declared operation contracts. ABI compatibility is
not a statement about package trust, co-location permission, or multi-user isolation.