Replies: 3 comments 2 replies
|
Strong +1 on the problem framing — with field data from 0.7.3, and from shipping the closest approximation of your annotation that today's API allows. We run a Claude Code fleet on herdr daily and hit this class constantly. Two pieces of evidence that may help evaluate the design: 1. On 0.7.3 the display state is decided by a single screen signal, and nothing agent-side can influence it. 2. We shipped the nearest available approximation — display-only state labels — and its gaps map exactly onto what the lease adds. Our hook relabels done/idle →
Happy to port our hook to |
|
Agree this is a real problem, and the OSC title-spinner case illustrates why display-layer signals shouldn't be conflated with actual completion. The orthogonal wait-lease + TTL looks like the right shape: it stays evidence-based and doesn't force idle/working into a new enum. My one open question is who acquires the lease for a stock CLI like Claude Code that has no concept of herdr. If the tool itself has to announce "I'm waiting," most CLIs won't today, so the lease sits unused and we're back to inferring wait state from output — the guesswork #1217 is trying to escape. Could the herdr side acquire and renew the lease from signals it already holds (child process alive, no new manifest activity), with a true tool-emitted lease as the stronger signal when available? That way adoption doesn't hinge on every CLI cooperating, and the design avoids leaning on the same title/spinner heuristics it's meant to replace. |
PR 1 scope amendmentsI've kept stress-testing the proposal since posting it. Same design goal — these amendments close holes that would otherwise freeze into the schema. Add to PR 1:
Deferred to a follow-up: the per-job-ref-chain absolute unattended-authorization limit (kept distinct from the delegation ceiling — one is a fuse, the other a grant); progress-token escalation (K identical renewals → page, which catches zombies faster than any lifetime bound); a measured-TTL suggester fed by the ledger; multi-lease-per-pane semantics (I'd argue for a set keyed by job-ref, the pane counting as waiting while any valid lease exists). Deliberately out of herdr: window issuance and its authentication, spend envelopes, admission control, end-of-window ramps, checkpoint dispositions. Those belong to the operator's policy layer; herdr's job ends at the clamp. One open plumbing question before the schema freezes: how does the pane token reach hooks (env injection, e.g. |
Uh oh!
There was an error while loading. Please reload this page.
Problem
When an agent parks waiting for background work (a watched detached job, a long provider call), its screen goes quiet and herdr reports
idle/complete(#1217 — we reproduced this across Claude Code, Codex, Hermes and Grok Build sessions). Operators and stall-detection tooling then misread a healthy wait as a stall; in our fleet this nearly caused a forced teardown of a billing GPU pod that was mid-generation.Extending the state enum (an
awaitingstate) or making self-report/screen-detection precedence configurable both looked attractive and both fail review:awaitingis not an exclusive agent state (it overlaps idle/working), precedence knobs exist only because two signals are forced to fight over one slot, and push-style self-reports drop under load (#1049, #1323).Proposed design: an orthogonal wait-lease
A lease is a time-boxed, verifiable claim that sits next to the display state and never changes it:
idle (awaiting: issue150-gen, 12m left), plus a one-shotlease expired 3m agonotice — which is exactly the signal a human needs to distinguish healthy waits from stalls.Renewal must verify the awaited target (not the agent, not a hook)
Agent-event-driven renewal is structurally wrong: while an agent blocks on background work, no events fire — that is the whole reason it is waiting — so leases would expire mid-healthy-wait by default, and the expired-lease display would then relabel the same false stall with higher confidence. And a naive keep-alive sidecar proves only the sidecar's liveness. Renewal should therefore be allowed only when the awaited target itself re-verifies:
Consumer contract (normative, not advisory)
A lease must gate suppression of stall alarms, never authorize kills. For destructive/expensive automation (e.g. tearing down billed resources), require all of: (a) lease absent/expired, (b) independent job-side heartbeat stale, (c) a policy time floor. Display state alone, lease state alone, or their AND must not trigger teardown.
Minimal first PR (what we'd propose to land first)
wait-lease.jsonschema +acquire/releaseonly, atomic file, session/generation binding, token-conditional writes, daemon-owned monotonic expirypane get/pane header: active lease remaining, one-shot expired noticeDeferred to follow-ups:
hold/renewal with target verification, compact tab-bar UI, per-agent hooks.Relation to existing issues
We run a multi-agent fleet on herdr daily and are happy to prototype the client side (our job wrapper already tracks job pid + heartbeat, so
hold-style renewal maps 1:1), test builds, and iterate on the schema.(Originally filed as #1417; moved here per the issue-tracker policy — issues are for reproducible bugs only.)
All reactions