kamaji 0.8.26

Kamaji — yah's relocatable workload supervisor. Trait surface + supporting types; backend impls land in R484-T2. See .yah/docs/working/W199-kamaji-universal-supervisor.md.
Documentation

Kamaji — yah's relocatable workload-supervisor primitive.

This crate is the public surface of Kamaji (per W199): the trait one caller hand-rolls against (Kamaji), the typed inputs/outputs it exchanges with the runtime backend, and the Backend enum tagging which concrete backend a given Kamaji instance is driving.

Two deployment shapes

Per W199 §The move, the same trait is used in both shapes:

  • Inlined — the caller holds Arc<dyn Kamaji> directly. Used by the desktop app where Kamaji shares the Tauri process tree.
  • Sibling — the caller holds a KamajiClient that speaks the W154 postcard-over-UDS protocol to a separate kamaji.service process. Used by yubaba on cluster hosts.

T1 only ships the public surface; the inlined / sibling constructors and the backend impls land in R484-T2 / T4 / T5.

Package naming

Package is kamaji-core (not kamaji) because app/yah/kamaji already claims the kamaji workspace package name. Once R484-T5 rewires that binary to depend on this crate, a follow-up may rename one of them. The crate path (crates/yah/kamaji/) matches the W199 plan.

@arch:see(.yah/docs/working/W199-kamaji-universal-supervisor.md) @arch:see(.yah/docs/working/W154-yubaba-dual-runtime.md)

@yah:ticket(R592-T1, "Extract shared kamaji backend core so inlined and sibling shapes cannot drift (containerd/native/docker/probe)") @yah:status(review) @yah:assignee(agent:claude) @yah:at(2026-07-02T20:00:56Z) @yah:phase(P1) @yah:parent(R592) @yah:next("Duplicated logic: oss/kamaji/crates/kamaji/src/{containerd,native,docker,probe}.rs (inlined shape) vs oss/kamaji/crates/kamaji-bin/src/{containerd,native,probe}.rs (sibling daemon). Extract shared OCI-spec-building / task-lifecycle / spawn+sandbox / probe logic into one home — smallest workable shape (shared module in the kamaji crate that kamaji-bin consumes, or a new core crate). Verify the existing dep direction between kamaji and kamaji-bin first and follow it.") @yah:next("No behavior change. The sandbox/caps code (setresuid, capability bounding clear, landlock, cgroup-v2 writes) is exactly what security audits read twice — exactly one copy after this ticket.") @yah:next("Do NOT touch oss/kamaji/crates/kamaji-proto/src/codec.rs (live peer fix in flight, R590-B3).") @yah:verify("cd oss/kamaji && cargo check --workspace --all-features && cargo test --workspace") @yah:gotcha("Host is macOS: containerd/native integration paths cannot run here. Keep the refactor compile-clean: cargo check --workspace --all-features must pass; run the cross-platform unit tests; document anything only checkable on Linux.") @yah:tier(Warrior) @yah:handoff("Delivered: new crate kamaji-containerd-core (containerd-integration-gated) deduping OCI-spec build, image-digest/rootfs resolution, task-status probe, client plumbing; both containerd.rs backends now delegate (net -732 lines). Scope finding: containerd was the ONLY genuine dup — native.rs pair = different maturity (inlined has NO sandbox yet), probe.rs pair = unrelated features sharing a filename; W266 corrected. Drift found+resolved: (1) capability sets had diverged — inlined granted CAP_KILL+CAP_NET_BIND_SERVICE, sibling only CAP_NET_BIND_SERVICE per W154 parity contract; narrower set adopted for both (behavior change on a dormant path — containerd-integration ships in no build today). (2) missing-process task-status semantics had diverged; adversarial review caught the dedup silently moving inlined Failed->Stopped — fixed via three-variant TaskProbe in core, each shape's wrapper restores its exact prior folding (inlined: code-0->Failed; sibling: Pending). (3) mesh-env/label gap: sibling has NO MeshAssignment concept — preserved via extra_env seam, real maturity gap relevant to R593. Adversarial review: 6/6 claims CONFIRMED after fix. Verify: cargo check+test workspace all-features green (me + implementer + reviewer independently); one pre-existing probe.rs flake filed as R592-B6. Linux-only paths (cgroup/landlock/pidfd/live containerd round-trips) compile-checked only — flagged for a Linux host.")

@yah:ticket(R556-T8, "kamaji: scryer service manifest + lifecycle wiring (per-node yah-scryer)") @yah:status(review) @yah:at(2026-06-30T06:37:34Z) @yah:assignee(agent:bundle-anthropic-ashguard) @yah:phase(P1) @yah:parent(R556) @yah:handoff("LANDED — but NOT in this crate. The annotation is homed here (kamaji owns the service concept) while the implementation lives in app/yah/cli/src/supervisor_unit.rs: render_scryer / render_user_scryer emit yah-scryer.service from the W264 §Process-model fingerprint (root variant is app/yah/cli/resources/yah-scryer.service; the rootless variant strips DynamicUser/capabilities/ProtectSystem=strict because a systemd --user manager rejects them, and binds loopback instead of the tailnet). Scryer is ordered to start last so its listener finds a sane interface. Tests: app/yah/cli/tests/camp_systemd_unit_emit.rs and camp_install_idempotent.rs (quartet + yah-camp = 5 units; rootless write set = kamaji + yubaba + yah-scryer = 3). READ THIS BEFORE CONCLUDING IT IS UNIMPLEMENTED: grepping oss/kamaji for 'scryer' returns only these annotation lines, which reads exactly like dead paperwork. It is not.") @yah:next("Add a scryer service manifest to kamaji (binary: yah-scryer, listen: :6543, data: /var/lib/yah/scryer/, restart: always, health: GET /health -> 200, drop_privileges: yes) per W264 §Process model.") @yah:next("Wire lifecycle (start/restart/drain) through the existing kamaji service path so a node without the manifest cleanly opts out (mesh tolerates absent scryer = best-effort federation).") @yah:next("Tier: Cleric — service-manifest authoring in an existing manifest path; pattern-matches other kamaji-managed services, no novel design.") @arch:see(.yah/docs/working/W264-kamaji-managed-scryer.md)