Skip to content

decompose attempt-exhaustion cannot be attributed: the observer's timeout is recorded but not the producer's run #312

Description

Filed from ChronoAIProject/fkst-packages#3268, which reached blocked with reason wrong-layer after the package-side implementation attempt determined the required fix is engine-owned. The package-side analysis and its citations are reproduced below; the routing decision, not just the symptom, is the reason this is here.

The defect

When a decompose attempt exhausts, the record says that the observer timed out but not what the producer actually did. There is no causal join from an exhausted attempt back to the run that was supposed to satisfy it, so a failure cannot be attributed to anything.

Downstream consequence, observed in the-omega-institute/trureturing: four work items died with

reason_class=decompose-output-obligation-timeout
attempt=3

(#254, #479, #554, #555), and the engine log showed 6 decompose-exhausted events in a single boot. #479 is the decisive case because its task was small and well-specified — reading two Lean declaration names and checking them verbatim against matching Freeze events — so "the work was too hard" does not explain the exhaustion. Nothing recorded says why it failed.

Why this cannot be fixed package-side

fkst-packages records only observer lineage — libraries/devloop/convergence/attempts.lua:105 — and its regression exhausts without a devloop_decompose delivery (packages/github-devloop/tests/liveness_timeout_attempt_issue_test.lua:390). The facts needed for the join are all engine-owned:

fact owner
delivery_id / ACK crates/fkst-framework/src/supervise/consumer.rs:614
worker log_path consumer.rs:1177
publication parent identity consumer.rs:1038
ACK row deletion delivery_store.rs:762

And delivery_observe.rs:265 states explicitly that ACKed history requires a journal. Since the ACK row is deleted, the producer-side record needed to attribute an exhausted attempt is gone by the time the observer times out. A package-only change cannot create the causal join, which is why the package-side attempt declined to fabricate one.

Why this matters beyond one issue

This is a liveness-observability gap, not a difficulty problem. An exhausted attempt currently emits a fact about the watcher rather than the work, so the safety net sees a timeout with no attributable cause. That is the failure shape where a real defect and a merely-slow producer are indistinguishable, and it is what makes decompose-exhausted events uninvestigable after the fact.

What is asked for

Enough producer-side identity retained at (or before) ACK-row deletion that an exhausted decompose attempt can be joined to the run that was meant to satisfy it — at minimum the worker log_path and the publication parent identity, durable past the ACK. The exact shape is the engine's call; this issue does not pre-decide between a journal, a retained tombstone, or carrying the identity onto the exhaustion fact.

ASSUMED-UNVERIFIED: the consumer.rs / delivery_store.rs / delivery_observe.rs line numbers are quoted from the package-side implementation attempt's evidence and were not independently re-checked against this repository's current dev. Verify them before relying on the exact locations; the ownership claim, not the line numbers, is the substance.

Source issue: ChronoAIProject/fkst-packages#3268

⟦AI:FKST⟧

https://claude.ai/code/session_01S79hvgDL45T83MtFJAgk51

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions