Personal Claude Code configuration for forks: subagents, slash commands, skills, and dispatch scripts with a stable installer.
This repository is designed for a single maintainer working on their own adaptation. It is source-available for reading and forking, while remaining explicitly private-maintainer scoped for this operational track.
Start here
- Getting started — install, verify, first
/pmrun - Core concepts — the orchestration model and why it is shaped this way
Reference
- Platform support — per-OS install model (symlink / copy mode)
- Executor contract —
full/minimalprofile + PM handoff abstraction - Host manifest contract —
hosts/<name>/host.yamlschema v1 (host axis, capability declarations) - Dispatch brief schema — required brief fields +
self_verifymacros - Model tier policy — sonnet-default, Opus escalation rules
- Memory system — memory persistence layer: on-disk layout and recall lifecycle
- Context retrieval — repo index + prior-art scan before dispatching
- Task lifecycle —
pmctl tasksubcommands (claim/dispatch/status/review) - Review model — four-layer rigor model (pre-impl → pr-gate → machine verify)
- pr-gate handover schema — deprecated
pr-gate-handover_v1block format
Primary working language is Mandarin Chinese. Commit messages and code identifiers are English. Issue threads may be bilingual; non-Mandarin contributors are welcome and should expect bilingual responses.
Examples use ${PM_DISPATCH_REPO} to refer to your local clone root. If unset, hosts/claude/bin/install-guards.sh derives it automatically from the git toplevel with:
repo_root="${PM_DISPATCH_REPO:-$(cd "$SCRIPT_DIR/../../.." && pwd -P)}"
Cross-repository operations use ${PM_DISPATCH_REPOS_ROOT} when set, otherwise the parent directory of ${PM_DISPATCH_REPO}. Per-command --repos-root flags take precedence.
agents/ → ~/.claude/agents/ subagents callable via the Agent tool
commands/ → ~/.claude/commands/ /slash commands
runtime/ shared CLI, hooks, state, memory, context, and gate runtime
hosts/<host>/ host-owned install, doctor, hooks, and configuration adapters
adapters/<name>/ executor-specific dispatch and model policy
tests/ registered test harness, suites, and fixtures
tools/ static lint and authoring helpers
ops/ maintainer setup, release, diagnostics, backlog, and usage tools
scripts/ compatibility shims only; no canonical implementation
→ ~/.claude/scripts/ selected stable helper names are installed by install.sh
pm/ → ~/.claude/.pm/ cross-repo PM schema, scripts, templates
settings/ settings fragments to merge into ~/.claude/settings.json by hand
docs/ guides, schemas, and policy documents
Cross-repo project-management schema and tooling consumed by project-pm and BACKLOG.md / DECISIONS.md authoring across the user's repos. install.sh symlinks ~/.claude/.pm/ to this directory so canonical path references (e.g., the rollup.sh --out default, prose mentions in memory) keep working.
Contents:
schema.md— pm-schema v1.2 definition.templates/{BACKLOG,DECISIONS}.md— bootstrap templates.scripts/rollup.sh,scripts/validate.sh— portable shell tooling (pure stdlib).scripts/test/— fixture-driven test suite for the scripts above.
Runtime artifacts (.agent-trace/, rollup/PORTFOLIO.md) are gitignored.
The canonical PM path is now ~/.claude/.pm/, installed as a symlink to pm-dispatch/pm/.
bash "${PM_DISPATCH_REPO}/install.sh"— Expected:link $HOME/.claude/.pm -> .../pm-dispatch/pm. Exit code 0.readlink ~/.claude/.pm— Should print the path underpm-dispatch/pm/. If it doesn't, stop; do not use rollup.sh / validate.sh until the symlink is confirmed.
Legacy PM directories or symlinks under the old github checkout location are not used by the installer. If one is present, install.sh leaves it untouched and emits no warning about it; inspect and remove it manually only after confirming all active references use ~/.claude/.pm.
Prerequisite: jq must be on $PATH. Supported hosts are Linux/WSL2; install it with sudo apt install jq.
./install.sh --dry-run # preview
./install.sh # apply (auto-detect profile)
./install.sh --profile minimal # skip adapter bash guards
./install.sh --profile full # wire all hooks (no adapter ships a bash guard today)
./install.sh --enable-host codex # opt in to the Codex host command guard
./install.sh --enable-host opencode # opt in to OpenCode /pm + native Bash policy
CLAUDE_CONFIG_DIR=/tmp/sandbox ./install.sh # alternate Claude config rootThe install destination defaults to ~/.claude; CLAUDE_CONFIG_DIR is the canonical override shared by the Claude runtime, installer, uninstaller, doctor, and guards. CLAUDE_HOME remains a backward-compatible installer alias for older sandbox scripts. If both variables are explicitly set they must be identical, otherwise install/uninstall fail before mutation.
Idempotent — re-run safely after adding files. Per-file symlinks so other tools' agents in ~/.claude/agents/ are not clobbered. If a destination already exists and is not our symlink, it is skipped with a CONFLICT warning.
Supported platforms (core-development phase): Linux and WSL2 only (WSL2 is treated as Linux). Native Windows Git Bash is not officially supported right now — platform-hardening is deferred until the core stabilizes (CC-370); run under WSL2 instead. See
docs/platform-support.md.
On platforms without symlink support (e.g. native Windows Git Bash, best-effort only), the installer falls back to copy mode: managed directories are created as directory junctions and helper scripts are copied — re-run install.sh after git pull to refresh changed copies. See docs/platform-support.md for the per-platform install model.
install.sh also makes the pmctl CLI discoverable. On Linux and WSL2
it creates a symlink from ${PMCTL_BIN_DIR:-$HOME/.local/bin}/pmctl to
cli/pmctl and prints an export PATH=... note if that bin directory is not
already on $PATH. On Windows Git Bash it does not copy pmctl; add
<repo>/cli to $PATH manually so pmctl runs in place and can resolve its
repo-local libraries.
Profile: selects whether to wire adapter bash guards (adapters/<name>/bash-guard.sh, manifest-driven via needs_bash_guard). No adapter ships a bash guard today (codex's was retired with the codex-executor agent), so full and minimal currently wire the same hook set; the flag is retained for forward compatibility with future adapters that declare one. Auto-detect runs command -v codex — if found, full; otherwise minimal. See docs/executor-contract.md for the executor profile model.
Optional hosts: --enable-host codex and --enable-host opencode are explicit because they modify global host configuration. OpenCode wiring refuses to overwrite an existing permission.bash policy; integrate such a policy manually instead. Its receipt-based uninstall restores the exact prior config only while managed files remain unchanged. The legacy --enable-codex-command-guard flag remains an alias for --enable-host codex.
After installing, verify the environment is healthy:
bash runtime/bin/doctor.shdoctor.sh checks that claude, jq, and pmctl are on $PATH, hooks are wired into ~/.claude/settings.json, the memory directory exists, scripts are executable, and frontmatter passes lint — each failing check prints a concrete remediation command.
bash tests/bin/run-tests.sh --base origin/main # optional direct-impact iteration (not final sign-off)
bash tests/bin/run-tests.sh --base origin/main --list # explain selected suites without running
bash tests/bin/run-all-tests.sh # authoritative full suite for this checkout
bash tests/bin/run-all-tests.sh --list # show registered suites without running
bash tests/bin/run-all-tests.sh --skip test-codex-dispatch # skip one suite
bash tests/bin/run-tests.sh --verify-full .pm-dispatch/test-results/latest-full.jsonRequires a complete developer checkout — any registered suite that is missing or
not executable causes the aggregator to exit non-zero. Use --skip <name> to
opt out of environment-specific suites (e.g., test-codex-dispatch if the Codex
CLI is not installed).
run-tests.sh is intentionally iteration-only: it selects direct regression
suites and reports unmapped paths, but does not claim transitive coverage. The
pm-dispatch maintainer workflow may inject it into PR-gate for fast feedback,
then runs and verifies the full suite outside the gate before opening this
project's PR. release-verify.sh performs and verifies another fresh full run
as a mandatory pm-dispatch release check. These are this repository's delivery
policies, not requirements imposed on users of the generic gate tool: other
repos may choose tests, a gate, both, or neither. See
the test runner contract.
install.sh --verify delegates to this script.
The CLI is self-documenting: run pmctl --help, pmctl help <area>, or
pmctl help <area> <command>. The machine-readable inventory is available as
pmctl commands --json. The block below is mechanically checked against the
router and cli/commands.tsv.
adapter generate— Scaffold an adapter from the canonical adapter manifest. [experimental; JSON: false; mutating: true]backlog view— Show the active backlog. [experimental; JSON: false; mutating: false]backlog lint— Validate backlog structure and policy. [experimental; JSON: false; mutating: false]backlog archive— Archive completed backlog entries. [experimental; JSON: false; mutating: true]guard check— Evaluate a registered guard policy. [experimental; JSON: false; mutating: false]dispatch run— Launch an adapter run from a validated brief. [experimental; JSON: false; mutating: true]dispatch wait— Wait for a detached dispatch run to finish. [experimental; JSON: false; mutating: true]dispatch cancel— Cancel an in-flight detached dispatch run (no resume). [experimental; JSON: false; mutating: true]dispatch status— List in-flight and terminal detached runs for a work dir. [experimental; JSON: false; mutating: false]dispatch reconcile— Diagnose and converge stale/orphaned detached runs to a conservative terminal state. [experimental; JSON: false; mutating: true]artifacts list— List managed artifacts. [experimental; JSON: false; mutating: false]artifacts show— Show one managed artifact. [experimental; JSON: false; mutating: false]artifacts gc— Remove expired managed artifacts. [experimental; JSON: false; mutating: true]artifacts migrate— Migrate legacy artifacts into managed storage. [experimental; JSON: false; mutating: true]state status— Report state-store compatibility: layout version, entity schema versions, migration availability. [experimental; JSON: true; mutating: false]worktree create— Create a managed ticket worktree. [experimental; JSON: false; mutating: true]worktree list— List managed worktrees. [experimental; JSON: true; mutating: false]worktree remove— Remove a managed worktree. [experimental; JSON: false; mutating: true]worktree gc— Remove stale managed worktree records. [experimental; JSON: false; mutating: true]ship— Run the ticket delivery workflow. [experimental; JSON: false; mutating: true]ship prepare— Prepare a ticket delivery run. [experimental; JSON: false; mutating: true]ship finish— Finish a prepared ticket delivery run. [experimental; JSON: false; mutating: true]ship --parallel— Run multiple ticket delivery workflows. [experimental; JSON: false; mutating: true]ship status— Show and refresh a parallel ship run. [experimental; JSON: true; mutating: true]ship list— List and refresh completed parallel ship runs. [experimental; JSON: true; mutating: true]ship cancel— Cancel a ship parent operation and only its recorded child runs. [experimental; JSON: false; mutating: true]ship reconcile— Reconcile a ship operation from trusted child terminal claims. [experimental; JSON: false; mutating: true]trace tail— Read normalized project events. [experimental; JSON: true; mutating: false]task list— List tasks. [experimental; JSON: true; mutating: false]task show— Show one task. [experimental; JSON: true; mutating: false]task create— Create a task. [experimental; JSON: false; mutating: true]task update— Update task metadata or state. [experimental; JSON: false; mutating: true]task claim— Claim an available task. [experimental; JSON: false; mutating: true]task dispatch— Record task dispatch metadata. [experimental; JSON: false; mutating: true]task status— Show task lifecycle status. [experimental; JSON: true; mutating: false]task review— Record a task review result. [experimental; JSON: false; mutating: true]safe bash— Run a shell command through guard policy. [experimental; JSON: false; mutating: true]validate brief— Validate a dispatch brief. [experimental; JSON: false; mutating: false]decision add— Append a structured decision. [experimental; JSON: true; mutating: true]gate run— Start the pull-request gate. [experimental; JSON: false; mutating: true]gate verify— Assess artifact validity, subject freshness, and consumer applicability. [experimental; JSON: true; mutating: false]gate wait— Wait for a detached gate run. [experimental; JSON: false; mutating: true]gate cancel— Stop the verified gate producer process tree, then cancel only its recorded child runs; partial termination stays indeterminate. [experimental; JSON: false; mutating: true]gate reconcile— Reconcile a gate operation from trusted child terminal claims. [experimental; JSON: false; mutating: true]context index— Build the repository context index. [experimental; JSON: false; mutating: true]context update— Update the repository context index. [experimental; JSON: false; mutating: true]context status— Show context index status. [experimental; JSON: true; mutating: false]context query— Query indexed project context. [experimental; JSON: false; mutating: true]context pack— Build a bounded JSON context pack. [experimental; JSON: true; mutating: true]context reuse-scan— Scan indexed context for prior art. [experimental; JSON: false; mutating: true]context prompt-scan— Scan a prompt for context references. [experimental; JSON: false; mutating: true]memory dir— Print the canonical project memory directory. [experimental; JSON: false; mutating: false]memory resolve— Resolve canonical project memory configuration. [experimental; JSON: true; mutating: false]memory config— Read or update memory configuration. [experimental; JSON: true; mutating: true]memory append-episode— Append a canonical memory episode. [experimental; JSON: true; mutating: true]memory doctor— Diagnose canonical memory configuration; exits 0 healthy, 1 issues found, 2 usage error. [experimental; JSON: true; mutating: false]memory shard— Build memory retrieval shards. [experimental; JSON: false; mutating: true]memory rebuild-summary— Rebuild the memory summary index. [experimental; JSON: false; mutating: true]pre-release audit— Audit a milestone before release. [experimental; JSON: false; mutating: false]pm prepare— Prepare a bounded PM execution plan. [experimental; JSON: true; mutating: true]pm run— Run a prepared PM batch. [experimental; JSON: true; mutating: true]commands— List the canonical command registry. [experimental; JSON: true; mutating: false]
Orchestration
- project-pm — PM across repos under the configured repositories root. Triages requests, decomposes work, writes briefs (main thread dispatches), synthesizes PR-gate reviews, and maintains canonical per-project memory.
Executors (codex, claude, opencode, grok) are not subagents — the main thread dispatches each as an independent CLI subprocess via pmctl dispatch run --adapter <name>, then verifies via git diff and dispatch-post-verify.sh.
Reviewers (advisors — PM may override with reasoning)
- critic — Adversarial review of plan / diff. Scope creep, incompleteness, convention drift.
- architecture-reviewer — Layer / coupling / abstraction fit. Does the change respect the existing design.
Reviewers (HARD GATES — only the user can override a block)
- security-reviewer — OWASP-style security review for any implementation change. Auth, injection, secrets, deps, deserialization, etc.
- risk-reviewer — Blast radius, reversibility, migration safety, fail mode, observability. Distinct from security.
- qa-tester — Owns the testing phase. Loads
${QA_RULES_DIR}/${QA_RULES_ENTRY:-AGENT.md}as Tier 1 source of truth for test categories, layer choice, and anti-patterns. Red-line violations are blocking. Any QA rules directory with a Tier 1 entry point works; setQA_RULES_DIRand optionallyQA_RULES_ENTRYto use your own.
Project ID in memory paths is derived from the sanitized absolute path of your working directory. Run
ls ~/.claude/projects/to find the directory name on your machine.
- /pm
<request>— Routes a free-form request to theproject-pmagent. - /pr-gate
[context]— Explicitly runs the full review pipeline before opening a PR.
All reviewer agent spawns use model: "sonnet" by default. Opus is only used
when all three escalation conditions hold (full tier + diff > 1000 lines +
sensitive path). See docs/model-tier-policy.md
for the full decision rules, implementation-task guidance, and token tracking
usage.
- QA rules directory (
$QA_RULES_DIR, default<repos-root>/qa-testing-rules/). Any directory with anAGENT.mdTier 1 entry point works — theqa-testing-rulesrepo is the reference implementation, but you can substitute your own. SetQA_RULES_ENTRYto override the entry point filename if your rules repo uses a different convention.
- cli/pmctl — Runtime CLI spine.
install.shsymlinks it into${PMCTL_BIN_DIR:-$HOME/.local/bin}on Linux/WSL2. Key sub-commands:pmctl pm prepare/pmctl pm run(batch-only PM coordinator for non-Claude hosts);pmctl dispatch run --adapter <codex|claude|opencode|grok> --brief-file <path>(preferred dispatch path);pmctl task create/show/list/update/claim/dispatch/status/review(task CRUD + lifecycle; seedocs/pmctl-task.md);pmctl decision add;pmctl trace tail(readsevents.jsonl+ archives with--kind/--task/--since/--until/--jsonfilters);pmctl context index/update/query/pack/reuse-scan(repo index + prior-art scan; seedocs/context-retrieval.md);pmctl validate brief;pmctl gate run;pmctl guard check --role <pm|executor|reviewer> --runtime <codex|claude>;pmctl safe bash;pmctl adapter generate <name>(scaffoldsadapters/<name>/adapter.yamland support files).adapter.yamlis the source of truth and must stay out ofgenerated_files; regenerate only the files listed there. - runtime/bin/pm-prep-snapshot.sh — Captures branch/PR/backlog/tooling state before PM-agent spawn and writes a typed snapshot for PM consumption.
- ops/diagnostics/codex-watch.sh — Tails
.agent-trace/latest.jsonland prints a one-line human summary per event ([turn.started],[cmd] exit=0 …,[msg] …,[turn.completed] tokens: …). Run from another terminal during a long dispatch to see real-time progress. - runtime/hooks/guard-pm-write.sh —
PreToolUsehook (matcherEdit|Write). Blocksproject-pmfrom editing/writing outside~/.claude/projects/<claude-project-id>/memory/. Asserts absolute paths and normalizes... No-op for any other agent or the main thread. Bypass (logged):PM_GUARD_PM_WRITE=off. Requiresjqandrealpath. - runtime/hooks/guard-executor-write.sh — the unified executor write-guard, surfaced via
pmctl guard check --role executor(cli-only — no livePreToolUsehook, since the brief is authored by trusted main-thread code). It derives the runtime fromagent_typeand enforces that runtime'swrite_guard_mode. Bypass (logged):PM_GUARD_<RUNTIME>_WRITE=off. Requiresjqandrealpath. - hosts/claude/hooks/save-rate-limits.sh —
StatusLinehook that saves Claude rate-limit payloads to~/.claude/rate-limits.jsonfortoken-usage.sh --remaining. If a previousstatusLine.commandexisted during install, it is saved to~/.claude/statusline-chain.confand invoked after the rate-limit file is updated. - hosts/claude/bin/install-guards.sh / uninstall-guards.sh — Idempotent
jq-based splice into~/.claude/settings.json.--dry-runshows the diff without applying. Each apply backs upsettings.jsontosettings.json.bak.<timestamp>. - tests/shell/test-guards.sh — Regression suite for the managed hook scripts (~200+ cases: happy paths, boundary, per-metachar isolated coverage, quote /
../ glob / read-root / git -C /--flag=pathbypass attempts, destructive git, stash subverbs, audit-log content assertions, env-var bypass, type-confusion, and StatusLine rate-limit capture). Exit 0 on all pass.VERBOSE=1prints every case. Run byinstall.shand isolates audit logs viaPM_GUARD_LOG_DIR. - tools/lint/lint-scripts.sh — Local entrypoint hygiene check that also invokes the shared ShellCheck contract. CI uses
--hygiene-onlybecause its separateshellcheckjob owns the canonical scan. Run byinstall.sh. - tools/lint/lint-shellcheck.sh — CI/local ShellCheck entrypoint. It discovers
.shfiles fromshellcheck-domains.tsvacrossruntime/,tests/,tools/,ops/,hosts/, and boundedscripts/compatibility shims; code-scoped canonical-path exceptions require a reason inshellcheck-ignores.tsv. It defaults to two CPU-bound workers; setPM_DISPATCH_SHELLCHECK_JOBSto an explicit value from 1 through 8 to tune concurrency. - tools/lint/lint-frontmatter.sh — Validates YAML frontmatter in
agents/,commands/, andskills/against PyYAML flow-collection semantics (dq-escape whitelist, adjacent-quote, tab-indent, and empty-entry detection across all four collection paths). Run by CI anddoctor.sh. - tests/bin/run-tests.sh — pm-dispatch-specific, direct-impact iteration planner. It can be supplied explicitly to generic
pr-gate --test-cmd; it is not final sign-off evidence. - tests/bin/run-all-tests.sh — Authoritative full-suite entrypoint.
install.sh --verifyuses it;--listand--skip <name>remain available in full mode. - runtime/bin/doctor.sh — Environment health check: verifies
claude/jq/pmctlare on$PATH, hooks are wired into~/.claude/settings.json, the memory directory exists, scripts are executable, and frontmatter passes lint.--profile minimal|full|autoscopes which hook checks apply. Each failing check prints a concrete remediation command. - token-usage.sh — Multi-pool token usage estimator (Claude / Codex / Spark). Reads
~/.pm-dispatch/usage-tracker.jsonlby default; setPM_DISPATCH_USAGE_LOG_FILEto retain an existing tracker elsewhere. Symlinked to~/.claude/scripts/token-usage.shbyinstall.sh. Usage:bash ~/.claude/scripts/token-usage.sh [--today|--all].--remaining(no arg) auto-reads~/.claude/rate-limits.jsonif the StatusLine hook is installed;--remaining Naccepts manual dashboard value. - log-usage.sh — Appends one entry to
~/.pm-dispatch/usage-tracker.jsonlby default; setPM_DISPATCH_USAGE_LOG_FILEto retain an existing tracker elsewhere. Symlinked to~/.claude/scripts/log-usage.shbyinstall.sh. Usage:bash ~/.claude/scripts/log-usage.sh <type> <tokens> [note]. Call after any significant agent operation; standard types in the script header. - usage-weekly.sh — Weekly Markdown report from
~/.claude/stats-cache.json(Claude internal cache) and Codex session JSONL files. Read-only. Run manually or from a cron job.
Dependencies (runtime): jq and realpath (coreutils) must be on $PATH. Hooks fail closed (exit 2) if either is missing — they log to stderr and Claude Code surfaces the message.
Audit log: every hook firing that targets the matched subagent appends one line to $PM_GUARD_LOG_DIR/hooks.log; without that explicit binding it uses the product-owned state log root ($PM_DISPATCH_STATE_ROOT/logs, then XDG state). No-ops for other agents are not logged. Format: <ISO8601> <hook-name> agent=<type> tool=<name> decision=<allow|deny|bypass> reason=<...> target=<path-or-cmd>. reason and target are printf %q-escaped so the log is safely re-parseable. The PM_GUARD_LOG_DIR env var lets the test suite redirect to a sandbox dir without polluting the live log.
Rollback: to disable hooks system-wide, run hosts/claude/bin/uninstall-guards.sh (creates a backup, splices out PreToolUse entries pointing at this repo). To restore a specific prior settings file, copy from ~/.claude/settings.json.bak.<timestamp>. The hook scripts in this repo are inert without the settings.json wiring.
- Subagents cannot spawn subagents. Claude Code intentionally restricts nested
Agenttool calls regardless of frontmatter declaration (Agent SDK docs). The main thread orchestrates: it spawns subagents (PM, reviewers) and relays outputs between them, and dispatches executors as CLI subprocesses. PM produces briefs and synthesizes verdicts; it does not dispatch. Reviewers run in parallel from the main thread, not from PM. Never includeAgentin any subagent'stools:frontmatter —tools/lint/lint-agents.shenforces this. - Hooks enforce hard rules; prose alone leaks. CLAUDE.md compliance for "never do X" rules sits around 70% in the public research, so structural enforcement matters for invariants. The live
PreToolUsehook in~/.claude/settings.jsonisguard-pm-write.sh: project-pm cannot edit canonical memory directly, and may write only the narrow task-brief/spike handoff paths. Canonical memory mutations go through thepmctlwriter surfaces. Executor write policy is enforced by the unifiedguard-executor-write.shviapmctl guard check(cli-only — the brief is authored by trusted main-thread code, so no live write hook is needed). All guards no-op for the main thread and other subagents.- Threat model: defends against accidental misuse and prompt-injected misuse by the targeted subagent. Specifically not a defense against the user's main thread, which has full tool access by design.
- Failure mode: fail-closed on missing
jq/realpath, malformed input JSON, or empty/non-absolute paths. Fail-open (no-op) only when the firing agent is not the targeted subagent, or when the bypass env var is the literal stringoff(anything else, including empty string and case variants, does not bypass — bypasses are logged). - Bypass:
PM_GUARD_PM_WRITE=off/PM_GUARD_<RUNTIME>_WRITE=off(e.g.PM_GUARD_CODEX_WRITE=off). Each bypass appends a line to the product-owned guard log. - Tests:
tests/shell/test-guards.shexercises ~150+ cases including per-metacharacter isolation, quoted-path /..-traversal /git -C/--flag=PATH/ bundled-short-flag (-rf/path,-n5/path) bypass attempts, destructive-git forms, and audit-log content assertions. Run byinstall.shwith audit logs sandboxed viaPM_GUARD_LOG_DIR. - Known overrestriction: short-flag-attached values containing
/after letter/digit chars are treated as paths and validated against read roots — sogrep -ipath/to/regexis denied even whenpath/to/regexis intended as a regex pattern, not a file. Workaround: pass the pattern as a separate token (grep -i path/to/regex file) or use-e/ positional form. Same for paths with embedded/that legitimately need to escape the read root: use the bypass env var.
- PM thinks, Codex implements.
project-pmwrites the brief; the codex executor (a CLI subprocess) implements it, it does not design. Architecture, scope, and acceptance criteria stay with the PM. - Definitions in repo, state on disk. Agent and command definitions are version-controlled here. Per-project state (memory, traces) lives in
~/.claude/and stays out of this repo. - Decoupled from agent-playbook-template. The playbook is a methodology framework; this repo is a personal config. They evolve independently.
MIT. See LICENSE.
- New agent: drop a
name.md(with frontmatter) intoagents/, re-runinstall.sh. Don't includeAgentintools:—tools/lint/lint-agents.shwill reject the install. - New command: drop a
name.mdintocommands/, re-runinstall.sh. - New shared guard: add it under
runtime/hooks/; a host-specific guard belongs underhosts/<host>/hooks/. Add the corresponding manifest/installer binding and re-runinstall.sh; don't hand-edit host settings if it can be avoided. Add test cases undertests/shell/— security-relevant scripts ship with regression coverage. - Settings allowlist additions: edit
~/.claude/settings.jsondirectly; don't try to symlink settings.
Schema and reusable self-verify macros: docs/dispatch-brief.md. All briefs dispatched to executor adapters must include working_dir, goal, files, and acceptance; executors reject briefs missing those fields.
self_verify— required for file-writing briefs (any brief whosefiles:block contains an entry taggedwrite:ornew:, or any entry without an explicitread:tag; when in doubt, treat as file-writing). Optional only for read-only briefs where everyfiles:entry is explicitly taggedread:. Seedocs/dispatch-brief.mdfor the canonical definition.
Codex briefs that touch many files can run 10–30 minutes. The background dispatch keeps running while you watch its trace. Two patterns:
-
External tail (any session, no Claude Code involvement). From another terminal:
"${PM_DISPATCH_REPO}/ops/diagnostics/codex-watch.sh" --cd /path/to/projectPrints one line per codex event as it streams. Works whether the dispatcher was launched from Claude Code, the CLI, or a CI job.
-
Background dispatch from main thread. The canonical route already runs
pmctl dispatch runas a background Bash command (run_in_background: true), so the main thread stays responsive.Monitor(or periodicallyBashwithtail -n 5 .agent-trace/latest.jsonl) the trace file for progress, then checkgit diffand the post-verify verdict when the completion notification arrives.
If a dispatch exits 124, codex hit the timeout — almost always a silent startup hang. The wrapper banner + closing line in .agent-trace/latest.stderr is the post-mortem: re-dispatching usually clears the hang. Extend --timeout (or $CODEX_DISPATCH_TIMEOUT) only when codex is genuinely doing more work than the default 20 minutes.
Claude Code is a product of Anthropic. This project is an independent personal configuration for Claude Code and is not affiliated with, sponsored by, or endorsed by Anthropic. "Claude" and "Claude Code" are trademarks of Anthropic; references in this repository are descriptive use only.
Similarly, Codex CLI is a product of OpenAI; this project integrates with it but is not affiliated with OpenAI.