Skip to content

Confirm herdr 0.8.2 claude starts that time out on readiness (work-system 1.28.2) - #93

Open
gering wants to merge 2 commits into
mainfrom
task/fix-herdr-launch-unverified-on-0-8-2
Open

gering wants to merge 2 commits into
mainfrom
task/fix-herdr-launch-unverified-on-0-8-2

Conversation

@gering

@gering gering commented Oct 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • On herdr 0.8.2, agent start returns only once the agent is idle. A native claude:* worker handed /work-system:continue is busy from the first second, so every such kickoff ended blocked=unverified while the worker ran, and herdr never registered the agent name (agent get <label> → agent_not_found).
  • herdr-launch.sh now confirms a code=timeout start from process state and names the worker; other errors and an undetected worker stay fail-closed.
  • Bundles fix-flaky-herdr-launch-test: seams for the literal 10s probe bounds, pinned in the test harness, plus the residual cause.

Changes

  • Timeout confirmation (timeout code only): bounded poll of pane get (WORK_SYSTEM_HERDR_CONFIRM_SECONDS, 10s) for the expected kind in that pane → moved=yes; nothing or a wrong kind → blocked=unverified. Nothing is retried, no second worker.
  • Naming: agent rename <pane> <label> after confirmation, best-effort (agent_name_taken is reported on stderr, the launch stays confirmed).
  • herdr's timeout error is printed only when confirmation fails.
  • Test seams: WORK_SYSTEM_HERDR_PROBE_SECONDS, WORK_SYSTEM_AGENT_PROBE_SECONDS replace the eight literal run_bounded 10 (production default unchanged); Env.__init__ pins them and HA_CALL_TIMEOUT_SECS to 120s.
  • Hermetic tests: detected → moved+rename, name taken, nothing detected, wrong kind.
  • Knowledge (herdr-kickoff-automation.md): 0.8.2 readiness semantics + the stub-shift gotcha. work-system 1.28.2.

Live measurements (herdr 0.8.2)

  • pane get reports agent=claude 0.6s after the start; agent start --timeout 10000 timed out at 10.4s with the agent working. A start whose /work-system:status turn took 16s returned at 17s — readiness = idle.
  • After the timeout the name is never registered, even once idle; agent rename <pane> <name> fixes it (idempotent).
  • A timeout can also mean nothing was typed (3s start into a still-busy shell → bare prompt) — hence detection, not blanket success.
  • agent_not_ready ("blocked during startup") is CC's trust dialog in an untrusted cwd — stays unverified.
  • End to end, the patched script on a throwaway worktree: herdr error code=timeout → moved=yes, agent reachable by its label.

Flaky test: cause and measurement

  • Not reproducible at current load: baseline 0/12, 0/20, 0/40 concurrent runs before the change.
  • Mechanism, measured: the stub counts the Nth call on entry; a bounded call killed after a stall has already advanced the sequence, so every later answer shifts. One 2s pane get under a 1s bound turns wrapper wrong kind: stops immediately from 1 poll into 2; a 0.15s bound reproduces exactly the five modern --grok assertions seen before (the grok models probe). This explains every assertion in the original report.
  • Ruled out: concurrent herdr calls within one launch (none), the real cc-harness-agents on PATH (not called by resolve).
  • Acceptance after the change: for k in 1 2 3; do <20 concurrent runs>; done → 0/20, 0/20, 0/20 (198–235s each).

Readiness

  • ✅ Version 1.28.2 (plugin.json + marketplace.json)
  • ✅ CHANGELOG
  • ✅ Knowledge
  • ✅ scripts/check-structure.py (incl. plugin tests)
  • ➖ Build (none)

Test plan

  • CI check-structure.py green
  • Next real claude:* kickoff on herdr 0.8.2 returns moved=yes and herdr agent get <label> resolves

🤖 Generated with Claude Code

https://claude.ai/code/session_01FqXCdJZeE2VMqC9dZ1Qnh6

gering and others added 2 commits October 26, 2026 16:34
herdr 0.8.2's `agent start` returns only once the agent is idle; a claude
worker handed /work-system:continue is busy from the first second, so
every native claude:* launch ended blocked=unverified while the worker
ran, and herdr never registered its name.

- On `code=timeout` only, poll `pane get` (CONFIRM_SECONDS, 10s) for the
  expected kind in that pane: found → moved=yes, else unverified as before
- Name the confirmed worker via `agent rename <pane> <label>`;
  best-effort, a refusal is reported on stderr
- Print herdr's timeout error only when confirmation fails
- Hermetic tests for detected / name taken / nothing / wrong kind
- Knowledge: 0.8.2 readiness semantics, measured live

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqXCdJZeE2VMqC9dZ1Qnh6
A bounded read stalled past its 10s bound on a loaded runner is killed
after the herdr stub already counted it, so every later canned answer
shifts by one and the suite failed on a different assertion each run.

- WORK_SYSTEM_HERDR_PROBE_SECONDS / WORK_SYSTEM_AGENT_PROBE_SECONDS
  replace the literal `run_bounded 10` (production default unchanged)
- Env.__init__ pins both plus HA_CALL_TIMEOUT_SECS to 120s
- Knowledge gotcha; work-system 1.28.2 with changelog

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqXCdJZeE2VMqC9dZ1Qnh6
@gering
gering force-pushed the task/fix-herdr-launch-unverified-on-0-8-2 branch from c5697c3 to 35ffcba Compare October 26, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant