Skip to content

Automate /kickoff worktree launch inside herdr - #17

Merged
gering merged 5 commits into
mainfrom
task/automate-kickoff-in-herdr
Jun 24, 2026
Merged

Automate /kickoff worktree launch inside herdr#17
gering merged 5 commits into
mainfrom
task/automate-kickoff-in-herdr

Conversation

@gering

@gering gering commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • Inside a herdr session, /kickoff now automates the worktree session launch instead of printing manual "open a terminal yourself" instructions: it opens a named background tab in the same workspace, with the worktree as cwd, and starts Claude there.
  • The tab launches claude -n "<label>" "/continue" — the same command the manual block already uses — so the real Claude session is named (propagating into the title herdr reads) and /continue auto-runs on startup. No input injection, no ready-match wait.
  • One short LABEL names the tab, the herdr agent, and the session, so the sidebar shows one clear entry per task. The task/<name> branch is untouched, so /continue still resolves the task.
  • Outside herdr (or on a broken socket despite HERDR_ENV), the unchanged manual block is shown — graceful fallback.

Changes

  • plugins/work-system/skills/kickoff/SKILL.md — step 12 split into a herdr-automated path and the manual path; gated on HERDR_ENV=1 + command -v herdr. Includes a readiness handshake (echo a sentinel, herdr wait output --match on its output, then launch) so a slow shell init or an interactive startup prompt (e.g. oh-my-zsh's update prompt) can't swallow the launch keystrokes.
  • plugins/work-system/README.md — new ## herdr integration section with a ### /kickoff opens a named tab subsection (room left for a future close subsection).
  • README.md — brief mention + link in the Work System entry.
  • .claude/knowledge/features/herdr-kickoff-automation.md (+ index) — curated design + the handshake gotcha.
  • Version — work-system 1.3.11.4.0 (plugin.json + marketplace.json).

Readiness

  • ✅ Structure check (check-structure.py): 0 errors (2 pre-existing, unrelated warnings)
  • ✅ READMEs updated (work-system + root)
  • ✅ Version bumped + synced (1.4.0)
  • ✅ Knowledge entry added
  • ➖ Changelog / lint / build: N/A (build-less Markdown plugin repo)
  • ✅ Rebase: 0 commits behind main

Test plan

  • Live end-to-end in a herdr session: named background tab, herdr agent rename, claude -n "<label>" "/continue", handshake survived shell startup, /continue auto-ran, session shown as the label in the status bar (verified this session)
  • Outside herdr: confirm the manual block still renders unchanged
  • Broken/missing socket despite HERDR_ENV: confirm graceful fallback to the manual block

🤖 Generated with Claude Code

gering and others added 5 commits June 24, 2026 10:38
- Inside a herdr session, /kickoff now opens a named background tab in the
  same workspace with the worktree as cwd and starts
  `claude -n "<label>" "/continue"` — naming the real session and auto-running
  the resume flow without input injection or a ready-match wait.
- Use one short, sidebar-friendly LABEL for the tab, the herdr agent
  (`herdr agent rename`), and the Claude session, so the sidebar shows one
  clear name per task; the task/<name> branch is unchanged so /continue still
  resolves the task.
- Guard the launch with a readiness handshake: echo a sentinel and wait for
  its output before sending `claude`, so a slow shell init or an interactive
  startup prompt (e.g. oh-my-zsh's update prompt) can't swallow the keystrokes.
- Degrade gracefully to the manual block when herdr is unavailable or the
  socket is broken; the manual block is unchanged outside herdr.
- Document the herdr integration in the work-system README and link it from
  the repo-root README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LizXEJVxXcZjgPZ9mjRNep
Capture the durable design (claude -n "<label>" "/continue" launch — no input
injection; one LABEL for tab/agent/session; --workspace mandatory; graceful
fallback) and the readiness-handshake gotcha (input into a fresh herdr pane
races shell startup; oh-my-zsh's update prompt ate the leading keystroke).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LizXEJVxXcZjgPZ9mjRNep
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LizXEJVxXcZjgPZ9mjRNep
Addresses the code-review findings on the herdr launch automation.

- Replace `tab create` + `pane run "claude …"` + the readiness handshake with
  `herdr agent start "<label>" … -- claude -n "<label>" "/continue"` (argv exec)
  followed by `herdr pane move "<pane>" --new-tab`. Spawning Claude as argv
  removes the shell-startup keystroke race structurally — no handshake, no
  sentinel, no agent rename. (agent start splits the caller's tab, hence the
  pane move into a dedicated tab.)
- Add the missing empty-`$pane` guard so a failed herdr call actually falls back
  to the manual block (previously only a comment).
- Gate also requires a non-empty `$HERDR_WORKSPACE_ID` and `python3` on PATH.
- READMEs: tab/session is named after a shortened sidebar label (not the raw
  task name); `/kickoff` (not "the skills") automates; fix the root README
  anchor link to `README.md#herdr-integration`.
- Knowledge: update the entry to the argv-exec design; keep the shell-typing
  race as the rationale for it.

Verified live end-to-end in herdr: named background tab, agent detected,
/continue auto-ran.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LizXEJVxXcZjgPZ9mjRNep
Addresses the second code-review pass on the herdr launch automation.

- Move the deterministic launch (agent start -> robust pane-id parse ->
  pane move -> exit code) into plugins/work-system/scripts/herdr-launch.sh,
  per the project's helper-script convention. kickoff now derives the label
  and calls the helper; the fragile shell-as-prose is gone.
- Robust parsing fixes the inline bugs the review found: a JSON-null pane id
  no longer prints "None" and defeats the guard; python tracebacks are
  suppressed (2>/dev/null + try/except) so a malformed response degrades to
  the manual block instead of dumping a stack trace; a failed pane move now
  reports moved=no (Claude running in the caller's tab) rather than claiming
  a tab that does not exist.
- Docs: README/knowledge state the full activation gate (workspace id +
  python3, not just HERDR_ENV); note the herdr session name can differ from
  the manual block's; point to the skill for the label rule instead of
  duplicating it; trim the index line.

The helper is reusable by a future /adopt herdr automation.

Verified: bash -n, structure check, and a live end-to-end run in herdr plus
the failure paths (missing args / bad worktree / no herdr -> exit 1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LizXEJVxXcZjgPZ9mjRNep
@gering
gering merged commit cae0d81 into main Jun 24, 2026
1 check passed
@gering
gering deleted the task/automate-kickoff-in-herdr branch June 24, 2026 11:57
@gering gering mentioned this pull request Jun 24, 2026
4 tasks
gering added a commit that referenced this pull request Jul 16, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 17, 2026
Swarm loop round 3 — 3 findings, all in the probe. Rather than patch a probe
that had a security jail bolted on (rounds 1-3 all fixed jail-adjacent bugs),
this removes the jail: a readiness check passes no untrusted diff, so it never
needed one — the sibling `codex login status` in ready_check is unjailed too.

- Run `grok models` directly, not through sandboxed(). This roots out the
  round-3 CRITICAL (#18): the jail's `_init_sandbox` builds its deny profile
  with python3, so routing the probe through it made python3 a hard dependency
  of the formerly-local `ready`/`list` paths — and a missing python3 then
  misreported as "grok models failed (rc=65)". No jail, no python3 dep, honest
  reasons.
- Bound with `timeout -k 3` (#17): plain `timeout` only SIGTERMs, so a grok
  that ignores SIGTERM (or forks a stdout-inheriting child) kept the command
  substitution blocking past the deadline — the "must never hang" hole. `-k`
  SIGKILLs after a grace period. rc 124 (SIGTERM at the deadline) reports as
  "timed out"; rc 137 (SIGKILL) reports as "killed" — almost always our own
  `-k`, but an OOM/external kill shares the code, so the message doesn't assert
  a timeout that may not have happened.
- Take only the FIRST id per bullet line (#19): scanning the whole line also
  matched a grok-4.5 mentioned in prose on another model's line
  ("* grok-5 (successor to grok-4.5)"), reporting a retired model as offered.
- Fold _build_jail back into sandboxed(). It existed ONLY to share the jail
  with the probe; with the probe unjailed, the split — and the shared-warning
  (#12) and per-backend-memo (#15) fixes it forced last round — are moot.
  sandboxed() is back to its pre-split shape; _init_sandbox keeps the backend
  key (harmless, strictly more correct).
- Fix a stale swarm-review.js input-contract comment ("subset of the three" →
  codex, grok).
- Docs (header/README/CHANGELOG/knowledge) drop the jail claim. The knowledge
  entry records the real lesson: five rounds of patching a jailed probe ended
  the moment the jail was deleted — a feature added to be safe that generates
  every round's bugs is a shape problem; cut it, don't harden it. The composer
  removal (the PR's subject) drew zero findings across all five rounds.

Verified: live grok ready; SIGTERM-ignoring grok bounded by -k in ~5s, reported
as killed; SIGTERM-obeying grok reported as timed out; model-gone → honest hint,
no warning; probe rc=1 → warn + trust-auth; NO python3 invoked on the ready
path; review path still fully jailed (sandbox-exec + AWS/GH secret stripping);
end-to-end review returns a schema-valid finding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gering added a commit that referenced this pull request Jul 17, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 17, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
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