Cross-Pollination Brief — July 26, 2026
A dense migration day at Piper Morgan, with the CIO fully on Amber and HOST in progress. Two findings came out of the live commissioning work: a hook matcher syntax bug that was silently preventing every enforcement hook from firing for 10+ weeks, caught only by a behavioral-gate discipline; and a memory architecture discovery that simplifies per-agent worktree setups — Claude Code keys memory on the git common directory, so worktrees share a pool by construction without any symlink layer.
Letters to xian: have a question for xian about anything here or elsewhere in his work? File question-{from}-{date}-{topic}.md to dispatch mail. AI prompts human; one letter featured at the end of each brief.
Key Insights
Claude Code hook matchers are tool-name-only regex — the permission-rule syntax Bash(git commit*) is silently invalid and causes hooks to never fire
From: Piper Morgan, Pard session log (logs/2026-07-25-pard-log.md, §16:45 "HOOKS ROOT CAUSE"); DinP CLAUDE.md (worktrees §, hookmatchers update, 66d32f6cf)
Relevant to: Klatch, any project using Claude Code hooks
Every PM enforcement hook (check-branch.sh, pre-commit-broad-staging-warn.sh, pre-commit-reconcile-drafts.sh) was configured with "matcher": "Bash(git commit*)" — syntax copied directly from permission-rule conventions, where Bash(git commit*) is valid. In a hook's matcher field it is not: matchers are matched as a regex against the tool name only (the bare string Bash), so Bash(git commit*) — which contains extra characters after Bash — never matches anything. The hooks had been present in the project's .claude/settings.json since they were written. They did nothing. There was no error, no warning, no output — the hooks simply didn't run.
The correct form separates the two pieces: "matcher": "Bash" to select the Bash tool, paired with an "if": "Bash(git commit*)" field to filter to commit invocations. Once rewired, the behavioral verify confirmed it immediately: a mailbox commit staged on a non-main branch was blocked; a non-mail commit on the same branch was allowed.
The deeper pattern: this was a believed-vs-seen failure. The hooks were documented in CLAUDE.md as live enforcement and all agents proceeded as if they were running. Hook configuration appearing correct in settings is not evidence the hook runs — only a behavioral check (watching for a specific output, a blocked action, a sentinel file the hook writes) constitutes evidence. "No error" proves nothing when the configuration silently skips execution.
DinP independently hit the same bug on the same day (Janus/Themis's trigger prompts had also never re-asserted hook identity — 101 commits misattributed, caught by behavioral verification during the Amber migration).
Suggested action: For any project using Claude Code hooks: (1) audit each hook's matcher field — if it reads Bash(git commit*) or similar, replace it with "matcher": "Bash" plus a separate "if": "Bash(git commit*)" filter; (2) verify behaviorally by attempting the exact action the hook is meant to block and confirming it fails. Never trust hook configuration alone; only a successful block or a marker the hook writes constitutes evidence of live enforcement.
Claude Code memory keys on the git common directory — per-agent worktrees share one memory pool by construction, no symlink needed
From: Piper Morgan, CIO session log (dev/2026/07/25/2026-07-25-1053-cio-code-log.md, §Finding 1 — material); Pard session log (logs/2026-07-25-pard-log.md, §CIO standup + §CIO's first-session findings)
Relevant to: Klatch, any project provisioning per-agent git worktrees on a shared host
When PM provisioned CIO's worktree and wired a symlink from the worktree's expected memory path to a shared pool, CIO's first session found the symlink was a no-op — memory was resolving to a different path entirely. The actual memory key is derived from git rev-parse --git-common-dir (the shared .git/ root), not from the process's working directory. A git worktree's .git is a file (not a directory), pointing back to the main repo's object store — so all worktrees off one repo share the same common dir, and therefore share the same memory key automatically.
Pard's initial "live proof" that worktrees split memory (citing Vergil's openlaws-ra-main directory as evidence) turned out to be a category error: openlaws-ra-main/.git is a full directory, making it a separate clone with its own object store — not a worktree. Separate clones do get separate memory keys; worktrees do not. The distinction matters for interpreting any evidence about how memory behaves across paths.
Net result for the PM worktree architecture: shared memory is the default behavior under true worktrees, not an infra problem to solve. The session-start memory-scope verification check PM designed (to catch a silent-split failure mode) was cancelled — the failure mode it was designed to catch doesn't exist. The symlink layer and pm-shared-memory directory were dropped. This is subtraction, which is the better outcome.
Suggested action: When provisioning per-agent git worktrees, verify that each worktree's .git is a file (pointing back to a shared .git/ directory) rather than a full .git/ directory (which indicates a separate clone with its own object store). If it's a file, memory is shared by construction — no symlink layer is needed, and the memory-scope check at session start can be simplified. When citing memory-path behavior as evidence for architecture decisions, confirm first whether you're looking at a worktree or a clone — they are not interchangeable observations.
Sources Read
- Piper Morgan — git log (48h): 30+ commits to watch paths. Key reads: CIO session log
dev/2026/07/25/2026-07-25-1053-cio-code-log.md(first session on Amber — memory scope finding, stale worktree provisioning, hooks findings); Pard session loglogs/2026-07-25-pard-log.md(CIO standup execution, amber-agent worktree mode built + tested, hooks root cause diagnosed + fixed, HOST cutover initiated). Arch session logdev/2026/07/25/2026-07-25-2313-arch-code-log.mdscanned (methodology ruling, migration handoff written — not elevated; operational). - Mediajunkie (Pard) — non-empty log with substantive migration-day work (above).
- Klatch — git log (48h): Janus coordination mail to Calliope (git identity hygiene + Amber migration priority). No new Klatch-internal methodology.
- DinP — Janus + Themis session logs reviewed; CLAUDE.md hook-matcher update confirmed.
- One Job — git log (48h): active code work (gestural grammar audit, per-card menu, sealed-card invariant). Pure implementation commits without cross-pollination narrative — not elevated.
- Secondary repos: globe, weather, cookie-monster — brief delivery + Janus git-identity mail only. nyt-crossword — automated status commits only. atlas, cuneo, optilisten — no commits.
Canonical archive: designinproduct.com/internal — if your local copy is missing or stale, fetch the latest from the hub.