Skip to content

fix: always sync agent-runner source on container spawn#18

Merged
aviadr1 merged 2 commits intomainfrom
feat/fix-agent-runner-sync
Mar 16, 2026
Merged

fix: always sync agent-runner source on container spawn#18
aviadr1 merged 2 commits intomainfrom
feat/fix-agent-runner-sync

Conversation

@aviadr1
Copy link
Copy Markdown

@aviadr1 aviadr1 commented Mar 16, 2026

Summary

  • Agent-runner MCP source was only copied to session dirs on first run (!fs.existsSync guard)
  • New tools added by PRs (like create_case from feat: wire up case lifecycle — prune IPC + auto-prune #14) were never picked up by existing groups
  • The mandatory cases policy told agents to use mcp__nanoclaw__create_case — but that tool didn't exist in the running container
  • Fix: always sync from repo source on every container spawn

Kaizen

Level: 3 (mechanistic) — this silently broke a user-facing feature (cases never created)
Root cause: One-time copy logic that didn't account for tool evolution
Prevention: Sync always, not just on first run

Test plan

  • TypeScript builds clean
  • All 274 tests pass
  • After merge + build + restart, verify create_case tool appears in agent container
  • Trigger agent and confirm a case is created in the DB

🤖 Generated with Claude Code

aviadr1 and others added 2 commits March 16, 2026 17:35
Previously, agent-runner source was only copied to the session dir on
first run (!fs.existsSync check). This meant new MCP tools added by
PRs (like create_case) were never picked up by existing groups — the
mandatory cases policy told agents to use a tool that didn't exist.

Now syncs from repo source on every spawn so agents always have the
latest tools.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ensures cpSync is called for agent-runner source on every container
spawn, even when the session directory already exists.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aviadr1 aviadr1 merged commit b680ed3 into main Mar 16, 2026
1 check failed
@aviadr1 aviadr1 deleted the feat/fix-agent-runner-sync branch March 16, 2026 15:47
aviadr1 added a commit that referenced this pull request Mar 17, 2026
Extract pure/testable functions from the monolithic index.ts into lib.ts
and validation.ts, enabling unit testing without SDK or container deps.
Set up vitest with 72 tests covering: transcript parsing, filename
sanitization, policy loading, IPC drain/sentinel, SDK config building,
schedule validation, and MessageStream async iteration.

Resolves Garsson-io/kaizen#18

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aviadr1 added a commit that referenced this pull request Mar 17, 2026
* feat: add test infrastructure for agent-runner (kaizen #18)

Extract pure/testable functions from the monolithic index.ts into lib.ts
and validation.ts, enabling unit testing without SDK or container deps.
Set up vitest with 72 tests covering: transcript parsing, filename
sanitization, policy loading, IPC drain/sentinel, SDK config building,
schedule validation, and MessageStream async iteration.

Resolves Garsson-io/kaizen#18

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: remove unused vi import from lib.test.ts

Self-review round 1: found unused vitest vi import.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aviadr1 added a commit that referenced this pull request Mar 20, 2026
…ls (kaizen #223)

Phase 1-2 of the hook language boundaries epic:
- Decision framework doc (docs/hook-language-boundaries.md) with complexity
  taxonomy (L1-L4), migration candidates, and aspirational roadmap
- Shared test utils (scripts/tests/lib/test-utils.sh) — DRY up duplicated
  assert_eq/assert_contains/run_capturing across test-worktree-du.sh and
  test-resolve-cli-kaizen.sh
- CLAUDE.md policy #18: L1-L2 bash, L3-L4 TypeScript

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aviadr1 added a commit that referenced this pull request Mar 20, 2026
…ls (kaizen #223) (#221)

* docs: hook language boundaries — decision framework + shared test utils (kaizen #223)

Phase 1-2 of the hook language boundaries epic:
- Decision framework doc (docs/hook-language-boundaries.md) with complexity
  taxonomy (L1-L4), migration candidates, and aspirational roadmap
- Shared test utils (scripts/tests/lib/test-utils.sh) — DRY up duplicated
  assert_eq/assert_contains/run_capturing across test-worktree-du.sh and
  test-resolve-cli-kaizen.sh
- CLAUDE.md policy #18: L1-L2 bash, L3-L4 TypeScript

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: update worktree lock for case 260320-1835-hook-language-boundaries-prd-p

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aviadr1 added a commit that referenced this pull request Mar 21, 2026
…licy (qwibitai#332)

- Add wrapper-smoke.test.ts: 9 tests verifying the full bash→tsx→hook chain
  for all 3 migrated hooks (pr-review-loop, pr-kaizen-clear, kaizen-reflect)
- Fix wrapper path resolution: use `git rev-parse --show-toplevel` instead of
  `git worktree list` — the old approach resolved to main checkout where the
  TS hooks don't exist yet in other worktrees
- Use randomized PR numbers + isolated STATE_DIR to prevent smoke test state
  from leaking into production state dir (incident: PR 99999 gate blocked session)
- Add policy #18: "Smoke tests ship WITH the feature — never after"
  to .claude/kaizen/policies.md, CLAUDE.md, and /review-pr skill

Closes Garsson-io/kaizen#332

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aviadr1 added a commit that referenced this pull request Mar 21, 2026
…ke tests & policy (qwibitai#320, qwibitai#332)

Builds on the kaizen-reflect migration (already in main) to complete Phase 3:
- pr-review-loop.ts: multi-round PR self-review state machine (452→240 lines)
- pr-kaizen-clear.ts: kaizen gate validation + clearing (290→370 lines, with kaizen #198 waiver elimination)
- wrapper-smoke.test.ts: 9 end-to-end smoke tests for bash→tsx→hook chain
- resolve-project-root.sh: DRY shared lib for TS wrapper path resolution

Both hooks use main's patterns: extracted processHookInput() for testability,
async readHookInput from hook-io.ts, import guard, explicit stateDir params.

Policy changes:
- Policy #18: "Smoke tests ship WITH the feature — never after"
- Priority labels (priority:critical, priority:high) in issue taxonomy
- /pick-work and /make-a-dent updated to prefer priority-labeled issues

129 tests across 6 files, all passing.

Closes Garsson-io/kaizen#320
Closes Garsson-io/kaizen#332

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aviadr1 added a commit that referenced this pull request Mar 21, 2026
…wibitai#320, qwibitai#332) (#268)

* feat: migrate L3-L4 bash hooks to TypeScript — Phase 3 of #223 (kaizen qwibitai#320)

Migrate the three highest-complexity hooks from bash to TypeScript:
- pr-review-loop.sh (452 lines) → src/hooks/pr-review-loop.ts
- pr-kaizen-clear.sh (290 lines) → src/hooks/pr-kaizen-clear.ts
- kaizen-reflect.sh (197 lines) → src/hooks/kaizen-reflect.ts

Shared infrastructure:
- src/hooks/hook-utils.ts — stdin JSON parsing, git helpers
- src/hooks/parse-command.ts — command parsing (port of lib/parse-command.sh)
- src/hooks/state-utils.ts — atomic state writes, typed objects, no stat portability
- src/hooks/telegram-ipc.ts — Telegram notification via IPC

Improvements over bash:
- Atomic state writes (temp file + rename) prevent race conditions
- Native JSON parsing (no jq pipelines or sed extraction)
- No pipe-splitting corruption (IFS='|' read bug)
- No stat portability issues (fs.statSync works everywhere)
- Proper typed validation with clear error messages
- 115 vitest tests covering all state machine paths

Also:
- Add priority:critical and priority:high labels to issue taxonomy
- Update /pick-work and /make-a-dent to prefer high-priority issues
- Old bash hooks deactivated with migration comments
- Filed qwibitai#331 (worktree-du migration), qwibitai#332 (CI smoke tests), qwibitai#333 (shared lib retirement)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* style: format hook files with Prettier

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: smoke tests for TS hook wrappers + "tests ship with feature" policy (qwibitai#332)

- Add wrapper-smoke.test.ts: 9 tests verifying the full bash→tsx→hook chain
  for all 3 migrated hooks (pr-review-loop, pr-kaizen-clear, kaizen-reflect)
- Fix wrapper path resolution: use `git rev-parse --show-toplevel` instead of
  `git worktree list` — the old approach resolved to main checkout where the
  TS hooks don't exist yet in other worktrees
- Use randomized PR numbers + isolated STATE_DIR to prevent smoke test state
  from leaking into production state dir (incident: PR 99999 gate blocked session)
- Add policy #18: "Smoke tests ship WITH the feature — never after"
  to .claude/kaizen/policies.md, CLAUDE.md, and /review-pr skill

Closes Garsson-io/kaizen#332

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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