Pre-spawn freshness hook — auto-fetch main before agent spawn #193

Closed
opened 2026-03-28 04:38:43 +00:00 by forgejo_admin · 1 comment
Contributor

Type

Feature

Lineage

Standalone — scoped during worktree lifecycle enforcement brainstorm (2026-03-28).
Spec: pal-e-platform/docs/superpowers/specs/2026-03-28-worktree-lifecycle-enforcement-design.md
Plan: pal-e-platform/docs/superpowers/plans/2026-03-28-worktree-lifecycle-enforcement.md — Task 1

Repo

forgejo_admin/claude-custom

User Story

As a session operator,
I want local main to be automatically fresh before every agent spawn,
So that worktrees never branch from stale code.

Context

Claude Code's isolation: worktree branches from local HEAD. If local main is behind remote, the worktree starts with stale code. Incident 2026-03-06: agent PR would have destroyed production resources (40K+ tokens wasted, caught in review). Current mitigation is discipline-based (Betty Sue must remember git fetch && git pull). This doesn't scale. Hook enforcement eliminates the discipline dependency.

File Targets

Files the agent should create:

  • hooks/pre-spawn-freshness.sh — new PreToolUse hook

Files the agent should modify:

  • settings.json — add hook to PreToolUse Task matcher alongside check-agent-spawn.sh

Files the agent should NOT touch:

  • hooks/check-agent-spawn.sh — existing hook, must not be altered

Acceptance Criteria

  • Hook runs on every agent spawn (PreToolUse Task matcher)
  • Detects repo remote (forgejo if exists, else origin)
  • Fetches and fast-forwards local main via git update-ref
  • Never blocks — only fixes (always exit 0)
  • Logs when main was advanced: [pre-spawn-freshness] Updated local main to <sha>
  • Silent when main is already fresh
  • Ignores non-spawn Task calls (no prompt field)

Test Expectations

  • Manual: pipe valid spawn JSON, verify fetch + fast-forward runs
  • Manual: pipe non-spawn JSON (no prompt), verify silent exit 0
  • Manual: pipe JSON with non-git CWD, verify silent exit 0
  • Run command: echo '{"tool_input":{"prompt":"test","subagent_type":"dev"},"cwd":"/home/ldraney/claude-custom"}' | bash hooks/pre-spawn-freshness.sh

Constraints

  • Must not interfere with check-agent-spawn.sh (runs on same matcher)
  • set -euo pipefail for correctness
  • Best-effort: network failures exit 0 silently
  • Follow existing hook patterns (INPUT=$(cat), jq parsing)

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • project-pal-e-agency — agent infrastructure project
  • worktree-workflow — SOP this enforces
### Type Feature ### Lineage Standalone — scoped during worktree lifecycle enforcement brainstorm (2026-03-28). Spec: `pal-e-platform/docs/superpowers/specs/2026-03-28-worktree-lifecycle-enforcement-design.md` Plan: `pal-e-platform/docs/superpowers/plans/2026-03-28-worktree-lifecycle-enforcement.md` — Task 1 ### Repo `forgejo_admin/claude-custom` ### User Story As a session operator, I want local main to be automatically fresh before every agent spawn, So that worktrees never branch from stale code. ### Context Claude Code's `isolation: worktree` branches from local HEAD. If local main is behind remote, the worktree starts with stale code. Incident 2026-03-06: agent PR would have destroyed production resources (40K+ tokens wasted, caught in review). Current mitigation is discipline-based (Betty Sue must remember `git fetch && git pull`). This doesn't scale. Hook enforcement eliminates the discipline dependency. ### File Targets Files the agent should create: - `hooks/pre-spawn-freshness.sh` — new PreToolUse hook Files the agent should modify: - `settings.json` — add hook to PreToolUse Task matcher alongside `check-agent-spawn.sh` Files the agent should NOT touch: - `hooks/check-agent-spawn.sh` — existing hook, must not be altered ### Acceptance Criteria - [ ] Hook runs on every agent spawn (PreToolUse Task matcher) - [ ] Detects repo remote (`forgejo` if exists, else `origin`) - [ ] Fetches and fast-forwards local main via `git update-ref` - [ ] Never blocks — only fixes (always exit 0) - [ ] Logs when main was advanced: `[pre-spawn-freshness] Updated local main to <sha>` - [ ] Silent when main is already fresh - [ ] Ignores non-spawn Task calls (no `prompt` field) ### Test Expectations - [ ] Manual: pipe valid spawn JSON, verify fetch + fast-forward runs - [ ] Manual: pipe non-spawn JSON (no `prompt`), verify silent exit 0 - [ ] Manual: pipe JSON with non-git CWD, verify silent exit 0 - Run command: `echo '{"tool_input":{"prompt":"test","subagent_type":"dev"},"cwd":"/home/ldraney/claude-custom"}' | bash hooks/pre-spawn-freshness.sh` ### Constraints - Must not interfere with `check-agent-spawn.sh` (runs on same matcher) - `set -euo pipefail` for correctness - Best-effort: network failures exit 0 silently - Follow existing hook patterns (INPUT=$(cat), jq parsing) ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `project-pal-e-agency` — agent infrastructure project - `worktree-workflow` — SOP this enforces
Author
Contributor

Scope Review: READY

Review note: review-507-2026-03-27
Ticket is well-scoped: all template sections present, traceability complete (story:pm-scope, arch:worktree, issue open), file targets verified against codebase, 2 files / 1 repo / ~30 lines of new code following established update-ref pattern from post-merge-rebase.sh. No decomposition needed.

## Scope Review: READY Review note: `review-507-2026-03-27` Ticket is well-scoped: all template sections present, traceability complete (story:pm-scope, arch:worktree, issue open), file targets verified against codebase, 2 files / 1 repo / ~30 lines of new code following established `update-ref` pattern from `post-merge-rebase.sh`. No decomposition needed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/claude-custom#193
No description provided.