2026-09-21 15:24:05 -07:00
|
|
|
# Checked capability and component artifacts
|
2026-09-20 00:25:53 -07:00
|
|
|
|
2026-10-09 10:09:17 -07:00
|
|
|
This is the **current helper/output format**, not the core package abstraction.
|
|
|
|
|
See [the architecture](../../docs/ARCHITECTURE.md) and
|
|
|
|
|
[current gaps](../../docs/ARCHITECTURE_STATUS.md). In particular, the universal
|
|
|
|
|
artifact inventory and component-only omission of a server are implementation
|
|
|
|
|
gaps to resolve, not requirements for arbitrary package servers.
|
|
|
|
|
|
2026-09-21 15:24:05 -07:00
|
|
|
`mkCaminoArtifacts` is the fresh package builder. It regenerates candidate
|
2026-09-20 00:25:53 -07:00
|
|
|
bindings, typechecks the entry's dependency closure, bundles declared targets,
|
|
|
|
|
generates a process service when requested, and emits content manifests and
|
|
|
|
|
receipts. It has no migration step or package-defined shell hooks.
|
|
|
|
|
|
|
|
|
|
```nix
|
|
|
|
|
# Inside a per-system flake output:
|
|
|
|
|
quixosPackages.checkedArtifacts =
|
2026-09-30 22:03:17 -07:00
|
|
|
{ buildContract, sourceDigest, generator, core, sharedRuntime, typescript, packageRevisionId, ... }:
|
2026-09-21 15:24:05 -07:00
|
|
|
helpers.mkCaminoArtifacts {
|
2026-09-30 22:03:17 -07:00
|
|
|
inherit pkgs buildContract sourceDigest core sharedRuntime typescript packageRevisionId;
|
2026-09-20 00:25:53 -07:00
|
|
|
protocol = generator;
|
|
|
|
|
src = ./.;
|
|
|
|
|
portable = {
|
|
|
|
|
entry = "src/portable.ts";
|
|
|
|
|
bindingOutput = "src/gen/qx.ts";
|
|
|
|
|
registryExport = "registry";
|
|
|
|
|
targets = [ "browser" "server" ];
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
2026-09-30 22:03:17 -07:00
|
|
|
`buildContract` is a canonical, source-free capability slice. `sourceDigest`
|
|
|
|
|
records the exact selected package source in the final installation manifest;
|
|
|
|
|
it does not enter the reusable compilation group. Ordinary source dependencies,
|
|
|
|
|
SDKs and React props companions remain explicit Nix inputs. Raw QX and resource
|
|
|
|
|
lock files enter through the checked contract and evaluated recipe, and are
|
|
|
|
|
excluded from the implementation source tree. The `plan` argument on the low-level
|
|
|
|
|
helper is a composition convenience for fixtures; it is projected before building.
|
|
|
|
|
Package recipes receive the contract directly and can be checked without a workspace.
|
|
|
|
|
|
2026-10-01 01:37:46 -07:00
|
|
|
Inside `checkedArtifacts = context: ...`, the package helpers expose
|
|
|
|
|
`camino.packageSet { inherit nixpkgs system context; }` as the usual package set
|
|
|
|
|
selection. It shares the workspace composition's evaluated Nixpkgs when the
|
|
|
|
|
source content, system, and default import arguments match. Pass ordinary Nixpkgs
|
|
|
|
|
arguments such as `config` or `overlays` to use a separate import. A direct
|
|
|
|
|
`import nixpkgs { inherit system; }` also works, with additional evaluation cost.
|
|
|
|
|
The implementation groups depend on the complete execution compiler bundle and
|
|
|
|
|
JavaScript build drivers by content; unrelated checker CLI and publication
|
|
|
|
|
metadata changes do not enter those inputs.
|
|
|
|
|
|
2026-09-20 00:25:53 -07:00
|
|
|
The handler entry exports `registry = createRegistry(handlers)` from the generated
|
|
|
|
|
bindings. One registry contains many exports. The builder always supplies a server
|
|
|
|
|
implementation for the generated process service. A service-only package instead
|
|
|
|
|
omits `portable` and supplies `service.entry`, an ordinary JavaScript process entry
|
|
|
|
|
using the versioned stdin/stdout protocol. Custom services own their lifecycle and
|
|
|
|
|
may hold external resources. This first helper supports JavaScript custom service
|
|
|
|
|
entries; other languages can emit the same checked artifact contract independently.
|
|
|
|
|
|
|
|
|
|
Additional portable source dependencies can be provided as a locked `nodeModules` directory.
|
|
|
|
|
The workspace supplies the exact SDK and compiler; packages cannot replace those
|
|
|
|
|
with their own versions. Authored source symlinks and non-bundled portable imports
|
|
|
|
|
other than the SDK and server Node builtins are rejected. This is build closure
|
|
|
|
|
checking, not a purity proof or security sandbox.
|
|
|
|
|
|
2026-10-10 08:16:21 -07:00
|
|
|
`mkCaminoYarnDependencies` installs the locked dependency recipe and exports its
|
|
|
|
|
installed Node dependency tree, including native package results and executable
|
|
|
|
|
links. Generated Yarn install/linker state stays outside runtime outputs. Yarn
|
|
|
|
|
describes its install-state file as an optimization cache in its
|
|
|
|
|
[configuration reference](https://yarnpkg.com/configuration/yarnrc#installStatePath).
|
|
|
|
|
This helper output is a dependency directory for a build, not a standalone
|
|
|
|
|
Package or a runnable Yarn project. Its `devShell` supplies freestanding Yarn for
|
|
|
|
|
editable projects; do not run Yarn against the readonly dependency output.
|
|
|
|
|
|
|
|
|
|
Use the shared `installDependencies` assembly for consumers: authored libraries
|
|
|
|
|
are copied into the consumer's `node_modules`, where Node can find their
|
|
|
|
|
transitive dependencies, while selected SDK links retain their canonical type
|
|
|
|
|
identity. Reserved SDK substitutions fail checks. Web Studio uses this same
|
|
|
|
|
assembly rather than retaining a full Yarn project just to resolve UI libraries.
|
|
|
|
|
Its dependency inputs contain manifests, lock and Yarn configuration/plugin
|
|
|
|
|
recipe; ordinary Studio source edits do not enter that dependency derivation.
|
|
|
|
|
Recipes with local/workspace dependencies must still include their needed source.
|
|
|
|
|
This is language-specific build machinery; it adds no core Package file contract.
|
|
|
|
|
|
2026-09-20 00:25:53 -07:00
|
|
|
The core/Automerge bundle and Replicache bundle are built once. Browser modules
|
|
|
|
|
import the core through a content-addressed gateway URL, independent of package
|
|
|
|
|
identity. Each manifest covers the shared bytes it uses. The gateway retains its
|
|
|
|
|
workspace authentication and explicit file registry; it never interprets an HTTP
|
|
|
|
|
path as a Nix store path. Applications cannot import Replicache through the SDK.
|
|
|
|
|
|
|
|
|
|
`checked-artifacts.nix` evaluates a package's `checkedArtifacts` output without
|
2026-09-21 21:49:52 -07:00
|
|
|
activation. During the checked Nix build, `loadCheckedArtifactWorld` verifies manifest bytes, the selected
|
2026-09-20 00:25:53 -07:00
|
|
|
generator identity, and exact regenerated binding sources. Receipts are consistency
|
|
|
|
|
evidence from a trusted Nix build, not cryptographic attestations of remote builds.
|
2026-09-21 21:49:52 -07:00
|
|
|
The build stores the checked plan, kernel/query programs, their digests and original
|
|
|
|
|
compiler provenance in its immutable candidate output. Runtime loading validates
|
|
|
|
|
that output's identities, artifact contents and supported runtime contracts. It
|
|
|
|
|
does not regenerate bindings or programs with the currently running compiler.
|
|
|
|
|
Nix owns rebuilding and cache reuse when a toolchain input changes.
|
2026-09-20 00:25:53 -07:00
|
|
|
|
|
|
|
|
The root `camino-artifact-builds` check exercises actual reader/service outputs,
|
|
|
|
|
module and process execution, browser shared imports, rejection recovery, and
|
2026-09-21 21:49:52 -07:00
|
|
|
altered receipt rejection at the build boundary. The managed workspace host loads
|
|
|
|
|
the resulting checked candidate before activation. No adapter pretends this ABI
|
|
|
|
|
works in the old server dispatcher.
|
2026-09-21 15:24:05 -07:00
|
|
|
|
|
|
|
|
Component packages add `components = { inherit (react) sdk runtime; entries; }`.
|
|
|
|
|
The ordinary execution candidate checker supplies the selected React build inputs
|
|
|
|
|
when the package declares components. Each entry maps a component ID to
|
|
|
|
|
`{ entry = "src/card.tsx"; export = "Card"; }`. See the
|
|
|
|
|
[React SDK](../camino-react/README.md) for bindings and hooks. CSS is emitted as a
|
|
|
|
|
checked artifact; local image/font imports are inlined. The helper rejects
|
|
|
|
|
undeclared external assets and substituted React/client dependencies.
|
|
|
|
|
Component-only packages produce no backend service.
|
|
|
|
|
|
|
|
|
|
`camino-component-artifacts` checks bad subject/SDK/dependency/asset inputs and
|
|
|
|
|
proves that a component-only edit preserves a mixed package's service digest.
|
|
|
|
|
Run `nix run .#camino-component-source-qualification` from the monorepo to
|
|
|
|
|
materialize separate retained Git resources and compile an ordinary Nix candidate.
|
|
|
|
|
This is a source/build qualification harness; it does not deploy a workspace.
|
2026-10-07 02:21:22 -07:00
|
|
|
|
|
|
|
|
## Restricted execution in a workspace VM
|
|
|
|
|
|
|
|
|
|
Add `service.restricted = true` to a checked portable package to select the pinned
|
|
|
|
|
`workerd` executor. Generated bindings and the ordinary transaction-port protocol
|
|
|
|
|
stay the same. All server exports must belong to one checked portable registry;
|
|
|
|
|
remote exports and custom process services retain their ordinary VM execution
|
|
|
|
|
path. The restricted build rejects Node imports and unresolved dependencies,
|
|
|
|
|
and supplies an explicit SDK for value codecs, identities and declared graph ports.
|
|
|
|
|
|
|
|
|
|
```nix
|
|
|
|
|
service = {
|
|
|
|
|
restricted = true;
|
|
|
|
|
limits = {
|
2026-10-09 16:50:50 -07:00
|
|
|
deadlineMs = 10000;
|
2026-10-07 02:21:22 -07:00
|
|
|
maxBytes = 1048576;
|
|
|
|
|
maxPortCalls = 1000;
|
|
|
|
|
maxQueued = 8;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
2026-10-07 20:28:19 -07:00
|
|
|
Each invocation gets a fresh Worker in a reusable engine process. An engine runs
|
|
|
|
|
one active frame; the adapter has bounded concurrency and queueing. Queue wait
|
|
|
|
|
consumes the deadline. Overflow is an explicit
|
2026-10-07 02:21:22 -07:00
|
|
|
`RESTRICTED_QUEUE_FULL` result. Cancellation kills the engine process group and
|
|
|
|
|
removes its sockets before acknowledgement. All graph calls inherit the trusted
|
|
|
|
|
invocation identity; authored code cannot choose another frame or workspace.
|
|
|
|
|
Native graph grants and transaction commit remain enforced by Camino outside
|
|
|
|
|
the guest. Initialization and synchronous loops are subject to the same deadline.
|
|
|
|
|
|
2026-10-09 16:50:50 -07:00
|
|
|
The default root/Package Invocation wall deadline is 10 seconds. The separate
|
|
|
|
|
root CPU allowance remains at most 4 CPU seconds; extra wall time accommodates
|
|
|
|
|
queueing and graph-port waits. Ordinary graph database transactions and idle
|
|
|
|
|
transactions allow 30 seconds, and ordinary client HTTP requests allow 45 seconds
|
|
|
|
|
so server failures can be returned. Nested calls inherit the remaining root
|
|
|
|
|
budget; explicit smaller limits still apply. Restore/activation jobs retain their
|
|
|
|
|
separate budgets. These defaults are starting limits, not latency targets.
|
|
|
|
|
|
2026-10-07 02:21:22 -07:00
|
|
|
Direct network access, native filesystem imports, ambient clock and entropy,
|
|
|
|
|
parent environment credentials, and unlisted modules are denied. Explicit dates,
|
|
|
|
|
`Intl.Segmenter`, deterministic hashes and normal JavaScript computation remain
|
|
|
|
|
available. Host-managed HTTP bridges expose only the current frame's declared
|
|
|
|
|
graph ports. Authored serialization is untrusted protocol input.
|
|
|
|
|
|
2026-10-07 20:28:19 -07:00
|
|
|
The packaged runtime uses the platform's Bubblewrap/seccomp launcher. Only the
|
|
|
|
|
engine's read-only runtime closure and private broker directory are mounted;
|
|
|
|
|
native filesystem/process/network escape probes qualify that boundary. Systemd
|
|
|
|
|
limits the whole package in a workspace VM. Shared authority additionally charges
|
|
|
|
|
each engine to its own cgroup before launch. No per-isolate memory protection or
|
|
|
|
|
Cloudflare hosted side-channel defenses are claimed. See the
|
|
|
|
|
[runtime decision](../../docs/RESTRICTED_RUNTIME_DECISION.md#os-process-confinement-implementation)
|
|
|
|
|
for the exact boundary and residual risks. A guest user can control its VM, so
|
|
|
|
|
authoritative graph grants and credentials must remain outside it.
|
2026-10-07 02:21:22 -07:00
|
|
|
|
|
|
|
|
Qualification commands:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
nix build .#checks.x86_64-linux.camino-restricted-execution
|
|
|
|
|
nix build .#checks.x86_64-linux.camino-restricted-package-runners
|
|
|
|
|
nix build .#checks.x86_64-linux.camino-restricted-execution-vm
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The first uses the actual pinned engine for frame isolation, graph ports,
|
|
|
|
|
SDK codecs, denied ambient access, cancellation and overload. The second runs
|
|
|
|
|
ordinary package dispatch, rollback, PostgreSQL and browser replica tests with
|
|
|
|
|
the restricted reader fixture. The VM check adds actual cgroup allocation
|
|
|
|
|
exhaustion, neighboring-service survival, native socket egress rejection and
|
|
|
|
|
fresh-frame timing. VM qualification is independent of hosted rollout.
|