Seen on the canonical's first boot on 0.5.211 (cirisbridge-us, ciris-server:0.5.211, 2026-09-18):
WARN ciris_server::backend: blob puller NOT spawned — no shared Edge handle yet error=edge runtime not initialized (call init_edge_runtime first)
Cause
backend::spawn_blob_puller (0.5.211, CIRISServer#602 item 5) resolved the Edge through ciris_edge::current_edge(). That process-global handle is published only by the #221 embedded fold (init_edge_runtime, the agent path). The standalone binary — the canonical, every ciris-server container — builds its own Arc<Edge> in compose and never publishes it. So the puller spawned on every agent node and on no standalone node, and both mesh ladders stayed green because both roles there are embedded.
Effect
On a standalone node nothing pulls a blob: an attestation carrying a BlobPointer in the node's audience is admitted but never fetched, so every far member's chat body reads NotFetched forever, and the revocation wiring (register + evictor) is absent with it. Trace delivery and receipts are unaffected (no blobs on that plane).
Fix (0.5.212)
spawn_blob_puller takes compose's Arc<Edge>; start_replication_runtime / setup_peer_replication thread it through (the fold path already passed an Arc).
- Gate
tests/blob_puller_uses_compose_edge.rs: the shim never resolves the global; compose passes its own handle.
- Chat ladder gains a
pulling stage: both standalone nodes must log blob puller spawned and never NOT spawned.
Also observed on the same boot, designed behavior, not a defect: consent re-sign as owner failed — … no software seed for that key … A hardware-custodied owner must sign consent on the client (2-phase …). The canonical's owner is hardware-custodied, so its grants stay machine-authored legacy rows (still counted by the fold). The 2-phase client-signed door is the open item on #599; the canonical is its first customer.
Seen on the canonical's first boot on 0.5.211 (cirisbridge-us,
ciris-server:0.5.211, 2026-09-18):Cause
backend::spawn_blob_puller(0.5.211, CIRISServer#602 item 5) resolved the Edge throughciris_edge::current_edge(). That process-global handle is published only by the #221 embedded fold (init_edge_runtime, the agent path). The standalone binary — the canonical, everyciris-servercontainer — builds its ownArc<Edge>in compose and never publishes it. So the puller spawned on every agent node and on no standalone node, and both mesh ladders stayed green because both roles there are embedded.Effect
On a standalone node nothing pulls a blob: an attestation carrying a
BlobPointerin the node's audience is admitted but never fetched, so every far member's chat body readsNotFetchedforever, and the revocation wiring (register + evictor) is absent with it. Trace delivery and receipts are unaffected (no blobs on that plane).Fix (0.5.212)
spawn_blob_pullertakes compose'sArc<Edge>;start_replication_runtime/setup_peer_replicationthread it through (the fold path already passed anArc).tests/blob_puller_uses_compose_edge.rs: the shim never resolves the global; compose passes its own handle.pullingstage: both standalone nodes must logblob puller spawnedand neverNOT spawned.Also observed on the same boot, designed behavior, not a defect:
consent re-sign as owner failed — … no software seed for that key … A hardware-custodied owner must sign consent on the client (2-phase …). The canonical's owner is hardware-custodied, so its grants stay machine-authored legacy rows (still counted by the fold). The 2-phase client-signed door is the open item on #599; the canonical is its first customer.