diff --git a/.claude/.claude-plugin/README.md b/.claude/.claude-plugin/README.md index ef34b41..8707c72 100644 --- a/.claude/.claude-plugin/README.md +++ b/.claude/.claude-plugin/README.md @@ -6,11 +6,16 @@ that ship to downstream installs are what runs the live self-hosted PR loop here ## Dual command invocation - **In-repo (dogfooding):** commands run as project-level slash commands, e.g. `/pr-loop`, - `/pr-loop-self`, `/harden`, `/setup-orchestrator`, `/test-pr`. + `/harden`, `/setup-orchestrator`, `/sync-orchestrator`, `/test-pr`. - **Installed as a plugin:** Claude Code auto-namespaces commands under the plugin `name` (`orchestrator`), so the same commands become `/orchestrator:pr-loop`, - `/orchestrator:pr-loop-self`, etc. No file renames are needed for this — the namespace comes + `/orchestrator:harden`, etc. No file renames are needed for this — the namespace comes from `name` in `plugin.json`, not from filenames. +- `plugin.json` carries an explicit `commands` allowlist (issue #76) so only consumer-facing + commands ship downstream. `.claude/self/pr-loop-self.md` — this repo's own self-hosting loop + prompt — is deliberately excluded: it lives under `.claude/self/` (not `.claude/commands/`), so + it is never auto-discovered as a project slash command either. See `.claude/self/README.md` for + how to run it in-repo. ## The `${CLAUDE_PLUGIN_ROOT:-.claude}` fallback Agent/command prompts invoke scripts as: @@ -23,12 +28,16 @@ shipped `scripts/` resolve there. In-repo, the variable is unset, so the fallbac the live self-hosting loop is unaffected. ## What's plugin-distributable (phase 1 scope) -Auto-discovered from the plugin root: `commands/`, `agents/`, `hooks/hooks.json`, `scripts/`. +Auto-discovered from the plugin root: `agents/`, `hooks/hooks.json`, `scripts/`. `commands/` is +instead scoped by `plugin.json`'s explicit `commands` allowlist, which lists only the +consumer-facing command files — this disables the default directory-wide auto-discovery for +`commands/` so an in-repo-only file added under `.claude/commands/` wouldn't ship by accident. Not distributed by this plugin (repo-scaffolded, project-specific): - `.claude/workflows/*.js` — deterministic fan-out workflows, not plugin-portable. -- `.claude/self/*` — this repo's OWN self-hosting adapter (gates, checks), not for downstream - projects; downstream adopters get the placeholder `.claude/gates.json` instead. +- `.claude/self/*` — this repo's OWN self-hosting adapter (gates, checks, and the + `pr-loop-self.md` loop prompt), not for downstream projects; downstream adopters get the + placeholder `.claude/gates.json` instead. ## Enabling in a consuming project diff --git a/.claude/.claude-plugin/plugin.json b/.claude/.claude-plugin/plugin.json index 2baf4b6..4d3d594 100644 --- a/.claude/.claude-plugin/plugin.json +++ b/.claude/.claude-plugin/plugin.json @@ -2,5 +2,12 @@ "name": "orchestrator", "version": "0.1.3", "description": "Multi-agent orchestration harness: fan out sub-tasks to isolated worktree implementers, gate them, and route results through reviewers.", - "author": { "name": "Roberto Cano" } + "author": { "name": "Roberto Cano" }, + "commands": [ + "./commands/harden.md", + "./commands/pr-loop.md", + "./commands/setup-orchestrator.md", + "./commands/sync-orchestrator.md", + "./commands/test-pr.md" + ] } diff --git a/.claude/self/README.md b/.claude/self/README.md index d07e4b3..7ecb8b4 100644 --- a/.claude/self/README.md +++ b/.claude/self/README.md @@ -39,13 +39,19 @@ To have the autonomous loop work this repo's own `module:*` backlog: **`.claude/self/gates.json`** as its adapter (module map + gates) for this repo. The generic agents/scripts otherwise behave identically — worker boundaries come from this file's `modules`, gates from its `gates`. -The durable, first-class way to do this is **`/pr-loop-self`** (`.claude/commands/pr-loop-self.md`) — it -mirrors `/pr-loop` exactly (arm/re-arm cron, adaptive cadence, poll → merge → address-feedback → advance) but -carries `GATES_FILE=.claude/self/gates.json` through every gate call and every spawned agent, and adapts on -the self modules (`module:docs`/`module:harness`/`module:examples`/`module:ci`) instead of the project's own +The durable, first-class way to do this is **`.claude/self/pr-loop-self.md`** — it mirrors `/pr-loop` exactly +(arm/re-arm cron, adaptive cadence, poll → merge → address-feedback → advance) but carries +`GATES_FILE=.claude/self/gates.json` through every gate call and every spawned agent, and adapts on the self +modules (`module:docs`/`module:harness`/`module:examples`/`module:ci`) instead of the project's own `gates.json`. It uses a distinct cron identity marker ("self-hosted autonomous PR loop") so it never collides with a `/pr-loop` job in the same session. +This file lives under `.claude/self/` (not `.claude/commands/`) so it is **not** shipped to downstream plugin +consumers — see `.claude/.claude-plugin/plugin.json`'s explicit `commands` allowlist (issue #76). It is +therefore not a registered `/pr-loop-self` slash command; to (re)arm the self-hosted loop, ask Claude to read +and follow the instructions in `.claude/self/pr-loop-self.md` directly (e.g. "read and run +`.claude/self/pr-loop-self.md`"). + ## Self-hosting promotion (the one gotcha) Agent-definition / `settings.json` / hook changes only take effect on a **fresh session**. So when the loop changes the harness itself, treat it like a compiler compiling its successor: land the change on a branch, diff --git a/.claude/commands/pr-loop-self.md b/.claude/self/pr-loop-self.md similarity index 95% rename from .claude/commands/pr-loop-self.md rename to .claude/self/pr-loop-self.md index 2c649c3..392c899 100644 --- a/.claude/commands/pr-loop-self.md +++ b/.claude/self/pr-loop-self.md @@ -31,4 +31,4 @@ Prompt to use (the tick logic, with adaptive STEP 0): ## 2. Run one tick now Execute steps 1–5 above immediately so the loop doesn't wait for the next cron fire. Report what happened (polled items, merges, feedback addressed, issue advanced — or "no actionable activity"). -Notes: requires the bot machine account set up per docs/USAGE.md (`GH_BOT_TOKEN` in `.env`, bot is a write collaborator) so PRs are bot-authored and the owner can formally Approve them. Cadence is adaptive and biased toward cheap ticks (each tick is a fresh full-context session): FAST (every minute) only while the loop has actionable work — unaddressed PR feedback, or a `planned` self `module:*` issue ready to advance with no PR in flight; WATCH (every 5 minutes) while PRs wait on human review/CI; IDLE (every 15 minutes) otherwise. New work is picked up within one WATCH/IDLE interval. For a tighter in-session cadence you can also run `/loop 5m /pr-loop-self`. +Notes: requires the bot machine account set up per docs/USAGE.md (`GH_BOT_TOKEN` in `.env`, bot is a write collaborator) so PRs are bot-authored and the owner can formally Approve them. Cadence is adaptive and biased toward cheap ticks (each tick is a fresh full-context session): FAST (every minute) only while the loop has actionable work — unaddressed PR feedback, or a `planned` self `module:*` issue ready to advance with no PR in flight; WATCH (every 5 minutes) while PRs wait on human review/CI; IDLE (every 15 minutes) otherwise. New work is picked up within one WATCH/IDLE interval. This file lives under `.claude/self/` (not `.claude/commands/`, see issue #76), so it is not a registered slash command — for a tighter in-session cadence, ask Claude to re-read and re-run this file's instructions on the interval you want instead of `/loop 5m /pr-loop-self`. diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md index 79be7e2..b406938 100644 --- a/docs/MIGRATION.md +++ b/docs/MIGRATION.md @@ -12,8 +12,10 @@ If you haven't installed the plugin yet, do that first — see [`GETTING_STARTED Remove the copied harness that the plugin now carries — it's generic, not project-specific, and staying on a frozen copy means you never get fixes/improvements: - `.claude/agents/` — orchestrator, implementer, reviewer, test-runner. -- `.claude/commands/` — `pr-loop.md`, `pr-loop-self.md`, `harden.md`, `setup-orchestrator.md`, `test-pr.md`, - etc. (they resolve as namespaced `/orchestrator:*` commands once the plugin is enabled). +- `.claude/commands/` — `pr-loop.md`, `harden.md`, `setup-orchestrator.md`, `test-pr.md`, etc. (they resolve + as namespaced `/orchestrator:*` commands once the plugin is enabled). Note: `pr-loop-self.md` is **not** + among these — it lives under `.claude/self/` (not `.claude/commands/`) and is not plugin-distributed; see + `.claude/self/README.md` if your repo has a self-hosting setup of its own. - `.claude/skills/` — e.g. the `setup` skill. - `.claude/hooks/` — `hooks.json` (the lint/test-affected wiring is now shipped by the plugin and resolves via `${CLAUDE_PLUGIN_ROOT}` automatically). diff --git a/docs/USAGE.md b/docs/USAGE.md index 24e8bd8..195e026 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -165,10 +165,13 @@ labelled it `planned`. Commenting "approved" on an issue does nothing — nothin > Historical note: before the `planned` label existed, the `module:*` label alone was the opt-in queue. > If a repo predates the split, treat `module:*`-only issues as `backlog` until the owner adds `planned`. -**Self-hosting this repo's own backlog?** **`/orchestrator:pr-loop-self`** (`.claude/commands/pr-loop-self.md`) runs the +**Self-hosting this repo's own backlog?** **`.claude/self/pr-loop-self.md`** runs the same loop mechanics self-hosted, against this repo's own `.claude`/`docs`/`examples`/`.github` backlog, using **`.claude/self/gates.json`** as the adapter (module map, gates, review lenses) instead of the placeholder -`.claude/gates.json` above. See `.claude/self/README.md` for the self-adapter contract. +`.claude/gates.json` above. This file lives under `.claude/self/`, not `.claude/commands/`, so it is **not** +shipped to downstream plugin consumers and is not a registered slash command — ask Claude to read and follow +it directly (e.g. "read and run `.claude/self/pr-loop-self.md`"). See `.claude/self/README.md` for the full +self-adapter contract. New project? Wire this up with the **[new-project configuration checklist](GETTING_STARTED.md#new-project-configuration-checklist)**.