Add lane registry: lanes.sh + herdr-agent.sh wrapper#48
Open
gering wants to merge 3 commits into
Open
Conversation
Foundation for the Manager/Worker orchestration (Wave 1) — a derived-live view of the repo's lanes plus a tested wrapper over the herdr agent primitives every later task will call. - herdr-agent.sh: guarded wrappers over `herdr agent list|get|read|wait` (robust python3 JSON validate, degrade-not-block exit codes, bounded wait). Centralizes the realpath cwd↔worktree match as $HERDR_MATCH_PRELUDE (match_roots/classify_cwd), the ONE place both consumers share. - lanes.sh: joins `ws-statusline.sh states --cached` (backlog state) with `herdr agent list` (liveness), one row per active worktree, keyed by worktree path. TSV/JSON. Degrades to states-only outside herdr; fail-closed `unverified` on an empty/malformed list (mirrors worktree-tab-state). - herdr-tab-glyph.sh: now sources herdr-agent.sh and consumes the shared prelude instead of its own inline match — byte-identical output verified against a live snapshot. herdr-teardown.sh left as-is (its 1:1 cwd==target lookup is a distinct operation, not the 1:N classify). - test_lanes.py + test_herdr_agent.py: join / degraded / unverified / first-wins / exclusion, and the primitives + degrade + bounded wait. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R8crYp6tzRKMiwW63Zt3GG
Add features/lane-registry.md: the herdr-agent.sh wrapper + centralized $HERDR_MATCH_PRELUDE, lanes.sh's worktree-path-keyed states⨝liveness join, the worktree-tab-state degrade tri-state, and the env test-seams. Index updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R8crYp6tzRKMiwW63Zt3GG
Apply the agreed findings from a local swarm review (11 ✅ + 1 🟨; the 3 ❌ — a feature version bump, a README inventory line, and a per-subcommand python3 guard — were deliberately left, see the PR discussion). herdr-agent.sh: - Bound herdr list/get/read with a wall-clock timeout (_ha_bounded: timeout → gtimeout → perl alarm), honouring the header's "never a hang" promise. wait stays governed by its own --timeout. (#6) - ha_wait now detects the --timeout=MS form too, so a caller's explicit bound in either spelling is honoured and no duplicate flag is appended. (#7) - A missing <target> returns usage code 2, not 4 (server-unreachable), so a programmer error is not mistaken for a transient outage. (#12) - set -u is enabled only on the executed-CLI path, never at source time, so sourcing for the prelude/helpers no longer mutates the caller's shell. (#13) - classify_cwd returns the resolved path as a third tuple element, so a caller keying by full path reuses it instead of a second realpath. (#14) lanes.sh: - Scrub tab/CR/LF from every TSV cell: agent-derived fields are untrusted, and an embedded tab/newline would forge columns/rows. Mirrors herdr-tab-glyph. (#1) - Guard the agent loop against non-dict (null) elements → never crash, always exit 0. (#2) - flush() now calls the shared classify_cwd instead of re-open-coding the task rule, so the classification can't drift between the two consumers. (#15) - Resolve SCRIPT_DIR via BASH_SOURCE (robust to bare-name invocation). (#5) - Header wording: exit-0 scope clarified; --json emits [] when no lanes. (#3, #8) herdr-tab-glyph.sh: consume classify_cwd's new 3-tuple; same BASH_SOURCE fix (#5). herdr-tab-glyphs.md: point at $HERDR_MATCH_PRELUDE as the shared match SoT. (#10) Tests extended: null-element + TSV-injection (lanes); --timeout= + missing-target exit 2 (herdr-agent). Regression: herdr-tab-glyph output byte-identical vs a live snapshot. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R8crYp6tzRKMiwW63Zt3GG
gering
force-pushed
the
task/add-lane-registry
branch
from
July 25, 2026 12:59
25ee166 to
4f29afb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
herdr-agent.sh: the one wrapper overherdr agent list|get|read|wait(robust python3 validate, degrade-not-block exit codes, bounded wait) and the single home of the realpath cwd↔worktree match, exposed as$HERDR_MATCH_PRELUDE.lanes.sh: joins backlog state with herdr liveness, one row per active worktree, keyed by worktree path.Changes
herdr-agent.sh(new) — guarded primitive wrappers;readbest-effort (no schema),waitinjects a default--timeout(no busy loop); exit codes 3=tools-absent / 4=herdr-failed / 5=malformed. Centralizesmatch_roots/classify_cwdas$HERDR_MATCH_PRELUDE, sourced side-effect-free (BASH_SOURCE == $0guard).lanes.sh(new) —ws-statusline states --cached⨝herdr agent list, keyed by worktree_path (never pane/tab ids). TSV/JSON. Degrade tri-state mirrorsworktree-tab-state: outside herdr → blank; inside + unreachable/empty/malformed list → fail-closedunverified; populated-but-unmatched → confidently blank.herdr-tab-glyph.sh— now sourcesherdr-agent.shand consumes the shared prelude instead of its own inline match. Output verified byte-identical against a live herdr snapshot (it has no unit test).herdr-teardown.shleft as-is: its 1:1cwd==targetlookup is a distinct operation.test_lanes.py/test_herdr_agent.py(new) — join / degraded / unverified / first-wins / exclusion, and the primitives + degrade + bounded wait. Both run undercheck-structure.py's plugin-test check.features/lane-registry.mddocuments the above.Readiness
features/lane-registry.mdaddedcheck-structure.pygreen (incl. 2 new test files)Test plan
python3 scripts/check-structure.pyis greenlanes.shinside herdr shows one row per worktree with correct liveness; outside herdr shows blank livenessherdr-tab-glyph.sh refreshstill stamps glyphs identically (no regression)🤖 Generated with Claude Code