# cellos-core
The typed-authority kernel and CloudEvent vocabulary shared by every CellOS
control-plane crate. No I/O — only data, ports, and pure validators.
## What it is
`cellos-core` owns the *domain language* of CellOS: execution-cell specs,
the four typed-authority variants (Observed / Proven / Imposed / Declared),
the CloudEvent envelopes the rest of the system reads and writes, and the
port traits (`CellBackend`, `EventSink`, `SecretBroker`, `ExportSink`,
`InferenceBroker`) that every host backend, sink, and broker implements.
It sits at L1 of the layer model — beneath the supervisor, the server, the
projector, and the Cortex bridge. Every crate that touches a spec, a
CloudEvent, or an authority claim depends on this crate; nothing in this
crate depends on tokio, axum, hickory, nats, reqwest, or any other I/O
substrate. The lib-level docstring (`src/lib.rs:1`) states the invariant
plainly: "no network, filesystem, or host syscalls here."
What `cellos-core` deliberately does NOT do:
- It does not run cells (that is `cellos-supervisor`).
- It does not serve HTTP or WebSocket (that is `cellos-server`).
- It does not project state from a JetStream stream (that is
`cellos-projector`).
- It does not bridge to Cortex (that is `cellos-cortex`).
- It does not perform DNS resolution, TLS termination, or any other
dataplane work — the spec types describe those policies; the supervisor
enforces them.
The binding doctrine is ADR-0005 (typed authority model), ADR-0006
(in-VM observability and the `DeclaredAuthority` evidence form), ADR-0009
(Cortex doctrine → CellOS authority mapping), ADR-0010 (formation
authority invariant), and ADR-0014 (formation CloudEvent state model).
## Public API surface
The crate re-exports a deliberately wide flat surface from `src/lib.rs`.
Group by purpose:
### Typed authority (ADR-0005, ADR-0006)
- `authority::ObservedAuthority` — host-observed evidence (SNI, Host,
H2 `:authority`). `src/authority/validator.rs:571`.
- `authority::ProvenAuthority` — cryptographic proof carrier (TLS-CT,
DNSSEC, signed token). `src/authority/validator.rs:663`.
- `authority::ImposedAuthority` — supervisor-imposed interception (e.g.
policy-driven SNI rewrite). `src/authority/validator.rs:749`.
- `authority::DeclaredAuthority` — guest-declared evidence from
`cellos-telemetry` over vsock; tier-1 ceiling. `src/authority/validator.rs:821`.
- `authority::AuthorityDerivation`, `AppliedRule`, `Rule`, `RuleClass`,
`EpistemicStatus`, `BindingStatus`, `ValidationError` — the Authority
Derivation Graph (ADG) shape and its validator errors.
- `authority::derivation_result::validate_authority_derivation` /
`AuthorityValidationResult` — typed validator result for admission-side
callers. `src/authority/derivation_result.rs:43`.
- `authority::declared::validate_declared_authority_surface` /
`DeclaredAuthoritySurface` — F2 host-side subset check for in-VM
declarations.
- `AuthorityDerivationToken` (in `types.rs:1360`) — the wire token an
ExecutionCell carries to bind its emissions to a derivation.
- `verify_authority_derivation` / `enforce_derivation_scope_policy` —
the supervisor's admission-side verifiers.
### CloudEvent vocabulary (`src/events.rs`)
- `CloudEventV1` — the v1.0 CloudEvents envelope (`types.rs:1265`).
- One `*_data_v1` builder per event family — e.g.
`lifecycle_started_data_v1`, `lifecycle_destroyed_data_v1`,
`identity_materialized_data_v1`, `observability_network_policy_data_v1`,
`dns_query_data_v1`, `keyset_verified_data_v1`,
`homeostasis_signal_data_v1`, `compliance_summary_data_v1`,
`evidence_bundle_emitted_data_v1`.
- One `cloud_event_v1_*` builder per event family — assembles the
envelope + data into a complete `CloudEventV1`.
- Typed enums for event payloads: `LifecycleTerminalState`,
`LifecycleReason`, `LifecycleDestroyOutcome`,
`LifecycleResidueClass`, `IdentityFailureOperation`, `ResidueClass`.
- `Provenance`, `SubjectUrn`, `cell_subject_urn` — the subject-URN
contract every event carries.
- Trust-plane constants: `TRUST_PLANE_BUILTIN_KEYSET_ID`,
`TRUST_PLANE_BUILTIN_RESOLVER_KID`, `TRUST_PLANE_BUILTIN_L7_KID`,
`TRUST_PLANE_AGGREGATE_EGRESS_FQDN`.
### Spec model (`src/types.rs`)
- `ExecutionCellDocument` / `ExecutionCellSpec` — the top-level spec
shape supervised by `cellos-supervisor`.
- `RunSpec`, `RunLimits`, `RunCpuMax`, `EgressRule`, `Correlation`,
`Ingress`, `GitIngress`, `OciImageIngress`, `EnvironmentSpec`,
`PlacementSpec`, `PolicyRef`, `WorkloadIdentity`,
`WorkloadIdentityKind`, `Lifetime`, `SecretDeliveryMode`.
- DNS / authority types: `AuthorityBundle`, `DnsAuthority`,
`DnsResolver`, `DnsResolverDnssecPolicy`, `DnsResolverProtocol`,
`DnsQueryType`, `DnsRefreshPolicy`, `DnsRefreshStrategy`,
`DnsRebindingPolicy`, `CdnAuthority`, `CdnProvider`.
- Telemetry: `TelemetrySpec`, `TelemetryChannel`.
- Export targets: `ExportTarget`, `S3ExportTarget`, `HttpExportTarget`,
`ExportChannels`, `ExportReceipt`, `ExportArtifact`,
`ExportArtifactMetadata`, `ExportReceiptTargetKind`.
- Inference shapes: `InferenceMessage`, `InferenceRequest`,
`InferenceResponse`, `InferenceRole`.
- Trust keyset: `SignedTrustKeysetEnvelope`, `TrustKeysetSignature`.
- Spec hashing: `canonical_spec_hash`.
### Policy (`src/policy.rs`)
- `PolicyPackDocument`, `PolicyPackSpec`, `PolicyRules`,
`PolicyViolation` — the spec-admission rules.
- `validate_policy_pack_document`, `validate_spec_against_policy`,
`check_policy_pack_version_compatibility`,
`spec_matches_placement_scope`.
- `AuthorizationPolicyDocument`, `AuthorizationPolicy`,
`validate_authorization_policy` — the RBAC shape (ADR-0007).
- Constants `MIN_SUPPORTED_POLICY_PACK_VERSION`,
`POLICY_ALLOW_DOWNGRADE_ENV`.
### Ports (`src/ports.rs`) — the L1 traits
- `CellBackend` — what `cellos-host-*` crates implement.
- `EventSink` — what `cellos-sink-*` crates implement.
- `SecretBroker` — what `cellos-broker-*` crates implement.
- `ExportSink` — what `cellos-export-*` crates implement.
- `InferenceBroker` — local LLM brokers (kept out of cellos-lite).
- `NoopEventSink`, `NoopExportSink`, `NoopInferenceBroker`,
`NoopSecretBroker` — wired defaults for tests and fail-closed
configurations.
- `CellHandle`, `TeardownReport`, `RuntimeSecretLeaseRequest` — values
exchanged across the port traits.
### Spec / trust validation (`src/spec_validation.rs`, `src/trust_keys.rs`)
- `validate_execution_cell_document`, `verify_authority_derivation`,
`verify_signed_trust_keyset_envelope`,
`verify_signed_trust_keyset_chain`,
`validate_tenant_id_for_subject_token`,
`enforce_derivation_scope_policy`.
- `SignedEventEnvelopeV1`, `sign_event_ed25519`,
`sign_event_hmac_sha256`, `verify_signed_event_envelope`,
`canonical_event_signing_payload`, `parse_trust_verify_keys`,
`load_trust_verify_keys_file`.
### State projection (`src/state_projection.rs`)
- `CellStateProjection` — the apply-and-snapshot machine consumed by
`cellos-projector`.
- `CellStateSnapshot`, `ProjectionCurrentState`,
`ProjectionLifecycleStage`, `ProjectionIdentityStage`,
`ProjectionExportStage`, `ExportProjectionRecord`.
### Errors and helpers
- `CellosError` — the crate's `thiserror` error enum (`src/error.rs:5`).
- `sanitize_cgroup_leaf_segment` (`src/cgroup_id.rs`),
`redact_url_credentials_for_logs`, `redact_url_if_echoed_in_text`
(`src/redaction.rs`).
- `hostname_allowlist` (module) — host-name policy matching primitives.
## Architecture / how it works
`cellos-core` is organised as a single flat crate that exposes its
modules through a wide re-export surface from `lib.rs`. The shape is
deliberately a *vocabulary*, not a framework: each module is independent
and pure, and the crate has no `#[tokio::main]`, no `async fn`s outside
trait definitions, and no I/O beyond `serde_json` and Ed25519/HMAC
crypto primitives.
```
┌───────────────────────────────┐
│ cellos-core │
│ (vocabulary, ports) │
└────────────────┬───────────────┘
│
┌──────────────┬─────────────┼─────────────┬──────────────┐
▼ ▼ ▼ ▼ ▼
cellos-server cellos- cellos- cellos- cellos-host-*
supervisor projector cortex
│
└─► CellStateProjection
consumes CloudEventV1
```
The authority module enforces six structural invariants on every typed
authority instance at construction time — see the doc-comment at
`src/authority/mod.rs:60`. The validator is pure: it takes plain values,
returns `Result`. There is no global state, no thread-local config, no
I/O.
The CloudEvent vocabulary in `src/events.rs` is intentionally flat: each
event family has a `*_data_v1` function that builds the typed `data`
payload (returning `Result<Value, serde_json::Error>` where the payload
can fail to serialize), and a `cloud_event_v1_*` function that wraps it
in the envelope with `Provenance`, `SubjectUrn`, and the canonical
`type` string. Producers (supervisor, projector, cortex bridge) call
these directly; the strings are not constructed elsewhere.
## Configuration
`cellos-core` does no I/O of its own, but it defines the env-var contract
that callers honour:
| `POLICY_ALLOW_DOWNGRADE_ENV` (`CELLOS_POLICY_ALLOW_DOWNGRADE`) | When set truthy, callers of `check_policy_pack_version_compatibility` may downgrade pack version on apply. |
The crate also exposes a `cellos-lite` constraint: it must not pull in
local LLM / on-device inference dependencies (see `deny.toml` and the
top-of-`lib.rs` note).
## Examples
Build the `data` payload for a `cell.lifecycle.v1.started` event from a
typed spec, then wrap it in a `CloudEventV1`:
```rust
use cellos_core::{lifecycle_started_data_v1, CloudEventV1};
use cellos_core::types::ExecutionCellSpec;
# fn demo(spec: &ExecutionCellSpec) -> Result<(), Box<dyn std::error::Error>> {
let data = lifecycle_started_data_v1(
spec,
/* cell_id = */ "cell-abc123",
/* run_id = */ Some("run-2026-05-16-001"),
/* derivation_verified = */ Some(true),
/* role_root = */ Some("ops"),
/* parent_run_id = */ None,
/* spec_hash = */ Some("sha256:..."),
/* kernel_digest_sha256 = */ None,
/* rootfs_digest_sha256 = */ None,
/* firecracker_digest_sha256 = */ None,
)?;
let event = CloudEventV1 {
specversion: "1.0".into(),
id: uuid::Uuid::new_v4().to_string(),
source: "//cellos/supervisor".into(),
ty: "dev.cellos.events.cell.lifecycle.v1.started".into(),
datacontenttype: Some("application/json".into()),
data: Some(data),
time: Some(chrono::Utc::now().to_rfc3339()),
traceparent: None,
};
# Ok(()) }
```
Build a typed `ObservedAuthority` — the constructor runs the validator
and enforces the §14 type-class envelope:
```rust
use cellos_core::authority::{
AppliedRule, AuthorityDerivation, AuthorityInput, AuthorityInputType,
AuthorityOutput, BindingStatus, EpistemicStatus, ObservedAuthority,
Rule, RuleClass,
};
let derivation = AuthorityDerivation {
inputs: vec![AuthorityInput {
input_type: AuthorityInputType::Sni,
value: "api.example.com".into(),
confidence: 0.95,
source_event_id: None,
}],
rules_applied: vec![AppliedRule {
rule: Rule::RawSniObserved,
class: RuleClass::RawObservation,
}],
output: AuthorityOutput {
tier: 2,
confidence: 0.95,
epistemic_status: EpistemicStatus::DirectObservation,
binding_status: BindingStatus::NotApplicable,
},
};
let observed = ObservedAuthority::try_new(derivation)?;
println!("tier={} confidence={}", observed.output().tier, observed.output().confidence);
# Ok::<(), cellos_core::authority::ValidationError>(())
```
Verify against `src/authority/validator.rs` for the current field names
before copying.
## Testing
This crate is pure; tests are fast and have no external dependencies.
```bash
cargo test -p cellos-core
```
Property tests for the §9 non-inflation invariants live under
`crates/cellos-core/src/authority/tests.rs` and run as part of the
default `cargo test` invocation. No `#[ignore]` tests, no broker
required.
## Related crates
- [`cellos-supervisor`](../cellos-supervisor/README.md) — consumes
`ExecutionCellDocument`, emits CloudEvents built here.
- [`cellos-server`](../cellos-server/README.md) — admits formation
specs, replays `CELLOS_EVENTS` through `CellStateProjection`.
- [`cellos-projector`](../cellos-projector/README.md) — builds
`CellStateSnapshot`s from a JSONL CloudEvent log.
- [`cellos-cortex`](../cellos-cortex/README.md) — translates Cortex
ContextPacks into `ExecutionCellDocument`s, emits ledger entries from
`CloudEventV1`s.
- `cellos-host-*` crates — implement `CellBackend` from `ports.rs`.
- `cellos-sink-*` crates — implement `EventSink` from `ports.rs`.
## ADRs
- [ADR-0005](../../docs/adr/0005-tls-termination-design.md) — typed
authority model (the four variants and the ADG).
- [ADR-0006](../../docs/adr/0006-in-vm-observability-runner-evidence.md)
— `DeclaredAuthority`, the guest-side evidence form.
- [ADR-0007](../../docs/adr/0007-rbac-secret-ref-admission.md) —
authorization policy shape and `validate_authorization_policy`.
- [ADR-0009](../../docs/adr/0009-cortex-doctrine-to-cellos-authority-mapping.md)
— doctrine → authority mapping; consumed by `cellos-cortex`.
- [ADR-0010](../../docs/adr/0010-formation-authority-invariant.md) —
formation authority invariant (enforced via spec validators here).
- [ADR-0014](../../docs/adr/0014-formation-cloudevent-state-model.md) —
formation CloudEvent state model.