productive / slow
A gate has passed, or nothing unproductive has fired yet. Time alone never escalates a slow-but-honest WU to stagnating.
LumenFlow’s position is that the agent loop cannot judge itself: governance, evidence, and completion authority sit outside any single client or model. Liveness detectors answer “is the agent alive?” — checkpoints, commits, and signals within a threshold. Trajectory supervision answers a harder, separate question: “is the agent getting anywhere?” An agent re-running the same failing gate with byte-identical output for hours looks perfectly healthy to every liveness check.
Every gate execution wu:prep, wu:done, and a bare gates run inside a
claimed worktree appends one gate_attempt event per gate to the WU event
log — gate id, outcome, lifecycle stage, a normalised failure signature, a
diff hash, and duration. The event is non-load-bearing: it can never change a
WU’s status, but it gives the classifier durable per-attempt history that did
not exist before.
A pure, deterministic function reads a WU’s gate-attempt ledger, lane-branch commits, and checkpoint/signal evidence and returns one of six classes, with no wall-clock term:
productive / slow
A gate has passed, or nothing unproductive has fired yet. Time alone never escalates a slow-but-honest WU to stagnating.
stagnating
The same gate fails repeatedly with an identical failure signature and no diff change, or a run
of wu:prep attempts shows no pass and no diff movement.
thrashing
The same file set is edited and reverted (net change ~0) while the failing signature holds, or gate attempts/commits blow past the WU’s own declared sizing estimate with no pass and no checkpoint.
awaiting-wake
The WU’s last recorded event is a passing prep gate, a subagent-stop checkpoint, or a delegation completion, with nothing after it and no done stamp — the designed prep-to-done pause, but the wake never arrived.
unknown — empty or conflicting evidence — is a first-class output and is
never escalated.
When the class is stagnating, thrashing, or awaiting-wake,
orchestrate:monitor emits one signal (trajectory:stagnating,
trajectory:thrashing, or trajectory:awaiting-wake) to the orchestrator
identity, visible to the worker too through its normal inbox. Two or more
active WUs failing the same gate with the same signature collapse into a
single trajectory:shared-failure signal instead of one per WU.
Two response surfaces make the evidence impossible to miss without ever taking action on their own authority:
wu:brief renders a Trajectory redirect block above the acceptance
criteria for a WU with an unresolved signal — gate, attempt count,
signature prefix, last diff delta, and the one-line redirect — so a worker
resuming from a brief sees it before its first tool call.orchestrate:monitor --recover lists a copyable
mem:signal --to <worker> --intent PROPOSE command and a wu:block
alternative beside the existing stuck-delegation suggestions.A signal counts as acknowledged — and the redirect block disappears — once a
later reply on its thread carries A2A intent AGREE or REJECT, never by
guessing from message text.
For every done WU with ledger evidence, the metrics layer computes an
efficiency ratio against the WU’s own declared sizing_estimate — the
gate-attempt count, commit count, and (when available) token total, each
scored against a baseline and combined by geometric mean into a 0..1
efficiency and a completion × efficiency trajectory score. It is
informational: surfaced in metrics:snapshot and flow:report, not a gate.
flow:report output.