small gleam coding and persistent agent daemon with a detachable cli and a canvas ui albedo.sh

Kernel link continues after failed deduplication and outbox persistence writes #164

Open aly.codes
Open opened by aly.codes

Summary #

The detached-kernel link continues as though durability succeeded after some SQLite writes fail. This can invalidate its host-call deduplication and outbound replay guarantees during disk-full/I/O failures.

Reviewed commit: 154c6911d6a491aeeecacf26a06b6ae8c4bc70e1.

Code paths #

  1. src/albedo/harness/extensions/python/link.gleam:805–817: call attempts to insert the host-call identity into kernel_calls, but maps Error(_) to Fresh, authorizing execution without a durable claim.
  2. src/albedo/harness/extensions/python/albedo_python.erl:1299–1312: a fresh decision spawns the host call. An external effect, such as an MCP tool invocation, need not fail merely because the local ledger write failed.
  3. src/albedo/harness/extensions/python/link.gleam:681–685: bound outbound persist and reply callbacks log failures and return Nil rather than propagating failure to the port owner.
  4. src/albedo/harness/extensions/python/albedo_python.erl:1362–1368: host_reply invokes link_reply, writes the envelope, removes the in-memory running-call entry, and advances the outgoing sequence number regardless of whether persistence succeeded.

Failure scenarios to test #

  • Force the call-claim write to fail, allow a side-effecting host call to execute, and end the daemon before it acknowledges the incoming call frame. On replay, no durable claim establishes that the effect may already have happened; it can be admitted as fresh again.
  • Fail outbound persistence, then lose the connection/daemon before delivery completes. The reply/frame has no durable replay copy. If the kernel received an outbound sequence number whose advancement never reached SQLite, restart can also reuse sequence numbers that kernel has already consumed.

These are source-traced failure scenarios, not fault-injection reproductions. They require a storage failure and the relevant connection/restart timing; this report does not claim ordinary successful operation duplicates calls.

Expected behavior #

A failed deduplication claim must not authorize fresh execution. Persistence failures should reach the link owner so it can report unavailability/uncertainty and avoid transmitting frames under a false durable-write assumption. Preserve the existing distinction between known-fresh work and work with an unknown outcome.

Please add storage-failure regression coverage for claim, reply/outbox persistence, reconnect, and restart, using a counted external effect so duplicate execution is observable.

we should have better durability in general but i agree with this

Sign up or Sign in to add to the discussion.