Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
cellos-cortex
The CellOS ↔ Cortex bridge. The only crate that owns wire shapes spanning both systems.
What it is
Two directions of flow cross this crate, and only this crate:
- Cortex → CellOS: Cortex hands a bounded [
ContextPack] (memory digest + doctrine refs + task description + optional expiry) to [CortexCellRunner], which translates it into a [cellos_core::types::ExecutionCellDocument] and submits it through a [CellSubmitter] (typically backed bycellos-supervisor). - CellOS → Cortex: every CellOS lifecycle
[
cellos_core::types::CloudEventV1] is serialized into a Cortex-shaped ledger row by [CellosLedgerEmitter], which implements [cellos_core::ports::EventSink].
The bridge sits at L6 of the layer model, beside cellos-supervisor.
The discipline (ADR-0008) is hard: neither cellos-* nor cortex-*
imports the other directly. This crate owns the simplified ContextPack
wire shape (intentionally flatter than Cortex's internal
cortex_context::ContextPack) and the CortexLedgerRow ingest shape;
either side may evolve internal types without breaking the bridge.
What cellos-cortex deliberately does NOT do:
- It does not depend on
cortex-*crates. CortexContextPackJSON is parsed viaContextPack::from_cortex_jsonrather than by linking the upstream type (src/context.rs:23). - It does not depend on CellOS supervisor internals beyond what
lib.rsexposes — submissions go through theCellSubmittertrait, not a direct method call. - It does not own Cortex's signed canonical ledger format. This crate
emits the ingest row (
CortexLedgerRow); Cortex anchors and re-signs on receipt. - It does not perform agent reasoning. The pack's
taskis appended to the cell'sargvand the agent inside the cell does the work.
Public API surface
The full re-export list lives in src/lib.rs:30. By module:
context
ContextPack— the bridge-shaped pack (memory digest, doctrine refs, task, optional expiry).src/context.rs:48.ContextPack::new(task)— convenience constructor for tests.ContextPack::from_cortex_json(&[u8])— parse a real Cortex wire-form pack and project to the bridge shape (see source TODO for the compatibility-gap rationale).ContextPack::is_expired(now_ms)—expires_atcomparator used by the runner to refuse stale packs.
runner
CortexCellRunner— the dispatcher.src/runner.rs:123.CellSubmitter— the abstract submission trait.src/runner.rs:113.CellSubmissionOutcome— the submitter's return value: cell id, optional exit code, captured lifecycle events.src/runner.rs:90.CortexCellResult— the bridge-shaped result of a completed cell run (exit code, success, destroyed-at, export paths, doctrine refs propagated from the dispatched pack).src/runner.rs:77.ContextPackTranslation— recorded pack → spec translation, useful for audit.src/runner.rs:105.wait_for_result_from_jsonl(cell_id, jsonl_path, timeout)— free-function result-reception helper that tails the supervisor's JSONL stream and builds aCortexCellResult.src/runner.rs:415.CELL_OS_JSONL_EVENTS_ENV— env-var name (CELL_OS_JSONL_EVENTS) the helper reads.src/runner.rs:55.
ledger
CellosLedgerEmitter— theEventSinkadapter that turns CloudEvents into ledger rows.src/ledger.rs:171.CellosLedgerEmitter::new(sink)— unsigned legacy path.CellosLedgerEmitter::with_signing_key(sink, Option<SigningKey>)— explicit Ed25519 signing key.CellosLedgerEmitter::with_env_signing(sink)— read the Ed25519 seed fromCELLOS_CORTEX_LEDGER_SIGNING_KEY_BASE64. Pair with the free associated functionCellosLedgerEmitter::from_env_signing_key()if you want the rawOption<SigningKey>.LedgerSink— pluggable destination trait.src/ledger.rs:125.NdjsonLedgerSink— append-NDJSON file sink.src/ledger.rs:132.CortexLedgerRow— the Cortex-shaped ingest row.src/ledger.rs:70.EmittedLedgerEntry— wire shape with optional detached signature.src/ledger.rs:110.LEDGER_SIGNING_KEY_ENV—"CELLOS_CORTEX_LEDGER_SIGNING_KEY_BASE64".src/ledger.rs:178.ledger::http_sink::HttpLedgerSink— HTTP transport, gated behind thehttp-ledgercargo feature.src/ledger.rs:277.
policy
DoctrineAuthorityRule— the per-doctrine constraint (max_ttl_seconds,require_secret_delivery,forbid_egress,require_egress_justification,correlation_label).src/policy.rs:47.DoctrineAuthorityPolicy— the doctrine id → rule table.src/policy.rs:88.DoctrineAuthorityPolicy::empty()— no-op policy.DoctrineAuthorityPolicy::built_in()— the canonical ADR-0009 defaults.DoctrineAuthorityPolicy::load_from_env()/load_from_path(&Path)— merge operator overrides on top of the built-ins (per-id keys win, missing keys fall back).apply_policy(policy, pack, spec)— apply every doctrine rule that matches the pack'sdoctrine_refs.src/policy.rs:238.
Architecture / how it works
┌────────────────────────────────────────────────────────────┐
│ Cortex (separate workspace) │
│ │
│ ContextPack (rich) ── reduce to wire JSON ─► │
└───────────────────────────────────┬────────────────────────┘
▼
┌────────────────────────────────────────────────────┐
│ cellos-cortex (this crate) │
│ │
│ ContextPack::from_cortex_json │
│ │ │
│ ▼ │
│ CortexCellRunner.translate(pack) │
│ 1. structural: task → argv, expires_at → TTL │
│ 2. apply_policy(DoctrineAuthorityPolicy, ...) │
│ 3. ExecutionCellDocument │
│ │ │
│ ▼ │
│ CellSubmitter.submit(document) ─────────────────►── cellos-supervisor
│ │ │
│ ▼ │
│ cloud_event_v1_cortex_dispatched → event_sink │
│ │
│ │
│ CellosLedgerEmitter (EventSink) │
│ CloudEventV1 → CortexLedgerRow │
│ → optional Ed25519 sign │
│ → LedgerSink::append │
│ │
└───────────┬────────────────────────────────────────┘
▼
NdjsonLedgerSink | HttpLedgerSink | (operator-supplied)
Doctrine policies are monotonic toward least authority
(src/policy.rs:13):
max_ttl_secondsonly clamps TTL down.require_secret_deliveryonly strengthens secret delivery; a broker mode is never downgraded toEnv.forbid_egress: trueemptiesauthority.egressRules.require_egress_justification: truestrips rules whosednsEgressJustificationis missing.correlation_labelrecords which doctrine rule fired inspec.correlation.labels.
Rules that would raise authority are silently dropped (ADR-0009 §Consequences).
Signed ledger entries (session 14 doctrine, src/ledger.rs:17): when
constructed with a signing key, each emitted EmittedLedgerEntry
carries cellos_sig — a base64 (URL-safe, no-pad) detached Ed25519
signature over the canonical JSON bytes of the inner event. Cortex
verifies entries against the operator-pinned verifying key; unsigned
entries preserve the legacy wire shape exactly (cellos_sig omitted via
#[serde(skip_serializing_if = "Option::is_none")]).
Configuration
| Env var | Effect |
|---|---|
CELLOS_CORTEX_LEDGER_SIGNING_KEY_BASE64 |
URL-safe, no-pad base64 of the 32-byte Ed25519 seed used to sign ledger entries. Read by CellosLedgerEmitter::with_env_signing (the constructor) and CellosLedgerEmitter::from_env_signing_key (the raw-key helper). Empty/unset → unsigned. src/ledger.rs:178. |
CELLOS_CORTEX_POLICY_PATH |
Path to a JSON file holding a DoctrineAuthorityPolicy. Merged on top of built_in(). Read by DoctrineAuthorityPolicy::load_from_env. src/policy.rs:204. |
CELL_OS_JSONL_EVENTS |
JSONL CloudEvent stream wait_for_result_from_jsonl tails to build CortexCellResult. src/runner.rs:55. |
CORTEX_LEDGER_ENDPOINT |
HTTP endpoint for http_sink::HttpLedgerSink::from_env (feature http-ledger). src/ledger.rs:13. |
Cargo features
| Feature | Effect |
|---|---|
http-ledger |
Pull in reqwest and build http_sink::HttpLedgerSink. |
Examples
Build a runner that dispatches Cortex packs to an in-process submitter
(typically a cellos-supervisor adapter), with the built-in doctrine
policy:
use Arc;
use ;
// Sink for CellOS → Cortex ledger rows.
let sink = new;
let emitter = new;
// `submitter: Arc<dyn CellSubmitter>` is built at the composition root —
// in tests we use an in-process fake; in production it wraps the supervisor.
let submitter: = /* ... */;
let runner = new
.with_default_ttl_seconds
.with_policy
.with_event_sink;
// Dispatch a pack:
let pack = new;
let outcome = runner.dispatch.await?;
println!;
Verify a signed ledger entry on the Cortex side (see
tests::verify_signature_roundtrip for a worked example).
Testing
Tests under crates/cellos-cortex/tests/ exercise the bridge
end-to-end: pack → spec translation, policy application, ledger
signature round-trip, JSONL result reception. No live broker or
network required.
The http-ledger feature is gated by default; to exercise it:
Related crates
cellos-core— ownsCloudEventV1,ExecutionCellDocument,EventSink, the lifecycle event builders.cellos-supervisor— the typicalCellSubmitterbackend (linked here but not the other way).cellos-sink-jsonl— pairs naturally withwait_for_result_from_jsonlon the receiver side.