feat(archdev-skill): install harness hooks from the skill bootstrap through the CLI - #33
Merged
Merged
Conversation
…ode plugin The monitor contract reached an agent only if the model chose to load the skill, and the skill's bootstrap only refreshed hooks that already existed, so a user who never ran the Map phase had none. One operator session sent about ten PRs without review annotations that way. Bootstrap (sh and ps1) now detects the harness running it (CLAUDECODE=1, CODEX_THREAD_ID, GROK_SESSION_ID) and runs `repo hook setup --harness <h>` when that harness has no archdev hooks, then refreshes as before. It skips Claude settings hooks when the archdev plugin is installed for the user and enabled, and installs only on a CLI that lists `repo hook plugin-hooks-json`, the Track 1 release whose `--uninstall` records an opt-out, so no released CLI can undo a deliberate uninstall. Failures stay non-blocking. The repository root is now the `archastro` Claude Code marketplace and the `archdev` plugin: plugin.json serves ./archdev and ./tasks in place, and hooks/hooks.json runs the CLI's Claude wiring behind a `command -v archdev` guard. README documents the install; SKILL.md says the hooks deliver the contract without the skill. A new workflow runs the bootstrap suites against a fake archdev, validates the plugin with `claude plugin validate`, and installs it into a temporary Claude config to watch its hooks fire. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… PowerShell The PowerShell suite only ran under pwsh on Linux, so the path SKILL.md actually uses on Windows (`powershell -File bootstrap.ps1`, USERPROFILE, archdev.cmd resolution) was untested. On Windows the suite now wraps the fake CLI in an archdev.cmd that runs it through Git Bash and runs the bootstrap with Windows PowerShell; a windows-latest job runs it. A .gitattributes entry keeps the Bash scripts LF on Windows checkouts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… bootstrap cases Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
firstlanding#15419 (Track 1) raises HOOK_SPEC to 4, prints the plugin hooks with `repo hook plugin-hooks-json --harness claude`, and makes the Claude stop and subagent-stop hooks hold once per pushed PR head without review annotations. hooks/hooks.json is now that command's output, byte for byte, so every handler passes --spec 4. The plugin check pins spec 4 and the generated description, and still diffs against the CLI once the archdev on PATH provides the command. The install test expects --spec 4. Bootstrap plugin detection now uses the CLI's claudePluginInstall rule: an archdev@<any marketplace> install at user, managed or no scope whose key enabledPlugins sets to true. Both bootstrap suites cover the mirror marketplace, unscoped version-1 records, a missing enabledPlugins entry and a similarly named plugin. monitor.md drops "The hooks never block a stop", says which stops Claude holds and who is exempt, and says the hooks deliver the contract at session and subagent start; map.md lists the subagent events. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…CACHE_DIR CLAUDE_CODE_PLUGIN_CACHE_DIR moves Claude Code's whole plugins root, installed_plugins.json included, so a relocated plugin install looked absent to the bootstrap, which then wrote settings.json hooks on top of the plugin's and every hook ran twice. Both bootstraps now resolve the plugins root with the CLI's claudePluginsRoot rule (firstlanding#15419): the variable when set and non-empty, with `~` or a leading `~/` expanded to the home directory, a relative value (including `~user/`, which is not expanded) resolved against the working directory, and otherwise <config dir>/plugins. enabledPlugins is still read from <config dir>/settings.json. Both suites run each case from its own working directory and add six cases: absolute, `~/`, relative and `~user/` roots are detected; an empty value falls back to the default root; a variable pointing at a root without a record ignores the record under the default root. Against the previous scripts five of the six fail; expanding every `~` prefix fails the `~user/` case. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…aps hooks Per the repo owner, ArchDev ships no Claude Code plugin: the archdev CLI installs skills and hooks, and the skill documents how. - Remove .claude-plugin/, hooks/hooks.json, the plugin CI job, and the plugin check and install scripts. - Bootstrap runs `repo hook setup --harness <h>` for the harness running it (CLAUDECODE / CODEX_THREAD_ID / GROK_SESSION_ID) and leaves every decision (current, stale, opted out) to the CLI; no plugin or hook-file parsing. Skip the install in Factory and daemon sessions. Require CLI 0.46.6, the first release that keeps the --uninstall opt-out. - SKILL.md, references, and README name the CLI as the single setup path with exact commands, the opt-out rules, and how subagents and spawned agents get the archdev skill. - Fake-CLI bootstrap suites cover the new rule; test-skill-bootstrap-cli.sh runs the bootstrap against the released CLI in CI. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
No ArchDev Claude Code plugin was ever released, so the README and skill need not say there isn't one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Review on ArchCode
Problem and author intent
ArchDev's contract (read the room, post lifecycle moments, store PR review annotations after every push) reaches an agent in two ways: the
archdevskill, and the harness hooks thatarchdev repo hook setupinstalls. Before this PR, both depended on something the agent or user had to do first:Observed: in one operator session the skill was never loaded and about ten PRs went out without review annotations.
archdev repo statuson that machine reportedhooks:claude missingeven though ArchDev was installed and logged in.The broken invariant: once ArchDev is installed for a harness, that harness's sessions (and, in Claude Code, their subagents) should receive the contract without anyone choosing to load a skill or run
repo hook setup. This PR is Track 2 of that fix: the skill bootstrap installs hooks for the harness running it.What changed
Bootstrap installs, not only refreshes (
archdev/scripts/bootstrap.sh,bootstrap.ps1)main):repo hook setup --refresh, which touches only harnesses that already have ArchDev hooks. A harness with none stays without hooks.CLAUDECODE=1→ claude,CODEX_THREAD_ID→ codex,GROK_SESSION_ID→ grok) and runsarchdev repo hook setup --harness <h>, thenrepo hook setup --refreshas before. The CLI makes every decision:setup --harness <h>without--forceleaves current hooks alone, replaces stale ones, and skips a harness the user removed with--uninstall(recorded in~/.archdev/hook-opt-out.json). The bootstrap no longer reads any harness config file.ARCHDEV_FACTORY_AGENT_ROLE,ARCHDEV_JOB_ID, orARCHDEV_STEP_IDset) the bootstrap installs nothing and only refreshes, matching the CLI self-heal's rule that the host owns those sessions' harness config.repo hook setup --harnesshas no such guard of its own, so the bootstrap carries it.SKILL.md, andreferences/bootstrap.md. 0.46.6 is the first release with the opt-out record and the self-healing install (firstlanding0d7743c67d); against 0.46.5,setup --harness <h>would undo a deliberate uninstall. An older CLI is upgraded by the existing bootstrap upgrade path, so the capability probe is gone.then run: archdev repo hook setup --harness <h>) and never block the skill; stdout is still only the archdev path.Skill docs (
archdev/SKILL.md,references/map.md,references/monitor.md,references/bootstrap.md,README.md)archdev setup(first run: login, repo, skills, and hooks for every harness),archdev setup --skills(skills only, vianpx skills add ArchAstro/archdev --skill '*' --global --agent <detected>),archdev repo hook setup(every harness),archdev repo hook setup --harness <h>(one harness), andarchdev repo statusto verify (hooks:<harness>missing/stale).archdevcommands run inside Claude Code or Codex reinstall that harness's missing or stale hooks (notsetup,repo hook …,--help/--version, or Factory/daemon sessions), and the opt-out rules:--uninstallrecords it; fullsetup, the self-heal,setup --harness,--refresh, and the bootstrap respect it; a barerepo hook setupor--forceclears it.repo statusstill reports an opted-out harness ashooks:<h> missing, and the skill tells the agent not to "fix" that.SKILL.md. What the CLI hooks already do (checked against CLI 0.46.8 and firstlandingharnesses.ts): Claude gets SessionStart, UserPromptSubmit, PostToolUse, Stop, SubagentStart, and SubagentStop; Codex gets the first four; Grok gets SessionStart, PostToolUse, Stop. In a Git checkout,repo hook subagent-startinjectsadditionalContextthat says "Load thearchdevskill now … and follow it", the annotation rule, and "You are a subagent: do not post to the team room."subagent-stopholds the subagent once for a PR head it pushed without annotations. Harnesses without a subagent event (Codex, Grok) and Claude without hooks get nothing in spawned agents, so the section tells the parent to put the instruction in the spawned agent's prompt and to stay responsible for room posts and annotation checks.monitor.mdstill documents the Claude stop and subagent-stop annotation hold;map.mddescribes the simplified bootstrap and the opt-out semantics.Unchanged: the skill description's session-start trigger,
npx skills addas whatarchdev setup --skillsruns,tasks/scripts/bootstrap.*(still refresh-only), and the CLI itself.Scope and risk
archdev repo hook setup --harness <h>for the harness running it, which is the same installarchdev setupand the CLI self-heal already perform. Raising the minimum to 0.46.6 means bootstrap upgrades 0.46.5 installs on next skill load (the same upgrade path used for every previous minimum bump).User impact
archdevskill in Claude Code, Codex, or Grok gets that harness's hooks without running the Map phase; later sessions and Claude subagents get the contract even if they never load the skill.archdev setup/archdev repo hook setupas the setup path.Testing
Canonical end-to-end proof:
scripts/test-skill-bootstrap-cli.sh. Actors: the realarchdev/scripts/bootstrap.sh, the releasedarchdevCLI on PATH (CI installs the latest release with./install.sh), and a throwaway HOME per case underenv -i. It asserts:CLAUDECODE=1and an empty~/.claude, bootstrap prints only the archdev path andsettings.jsongets archdev hooks for exactly PostToolUse, SessionStart, Stop, SubagentStart, SubagentStop, UserPromptSubmit (thehooks:claude missingstate is fixed).settings.jsonand run in a Git checkout, both print "Load thearchdevskill".settings.jsonbyte-identical.archdev repo hook setup --uninstall --harness claude, another bootstrap leaves no archdev hooks (opt-out respected).CLAUDECODE=1 ARCHDEV_FACTORY_AGENT_ROLE=worker, no Claude hooks are written.CODEX_THREAD_ID,~/.codex/hooks.jsongets PostToolUse, SessionStart, Stop, UserPromptSubmit.Control: with the bootstrap's install step disabled, 5 of the checks fail. All 8 pass locally against CLI 0.46.8.
Unit-level, fake CLI (
scripts/fake-archdev, which records everyrepo hook setupargv and prints to stdout to catch leaks):scripts/test-skill-bootstrap.sh(10 checks) andscripts/test-skill-bootstrap.ps1(9 cases): Claude/Codex/Grok markers →setup --harness <h>then--refresh;CLAUDECODE=0, no marker, and each ofARCHDEV_FACTORY_AGENT_ROLE/ARCHDEV_JOB_ID/ARCHDEV_STEP_ID→--refreshonly; failing setup → bootstrap exits 0, still refreshes, prints the path, and (bash) names the remediation command. Every case requires stdout to be exactly the archdev path. Control: with the install step disabled, both suites fail. Both pass locally (PowerShell 7.6.6 on Linux).bootstrap.ps1under pwsh against real CLI 0.46.8 withCLAUDECODE=1: all six Claude hook events installed, stdout only the path.bash -non every script.CI: workflow
Skill Bootstrap Checks(.github/workflows/skill-bootstrap-checks.yml), on every PR and push to main. Jobs:skill-bootstrap(bash and pwsh fake-CLI suites on ubuntu),skill-bootstrap-windows(PowerShell suite under Windows PowerShell 5.1 with the fake CLI via Git Bash), andskill-bootstrap-cli(latest release +scripts/test-skill-bootstrap-cli.sh). The Windows PowerShell 5.1 job was not run locally. An independent review pass found the Factory/daemon install, the opt-out remediation loop in the docs, and several overstated doc claims; all are fixed here.Follow-ups and known issues
0d7743c67d; ArchAstro/firstlanding#15536 removes it. No ArchDev plugin was ever released, so nothing depends on it.repo hook setup --uninstallon 0.46.5 or earlier has no opt-out record, so the first bootstrap after upgrading reinstalls their hooks.repo hook setup --uninstall --harness <h>on 0.46.6+ records it.GROK_SESSION_ID, which Grok documents for hook processes; that it is also set in the shell tool's environment is unverified. A missed detection falls back to--refresh.0d7743c67d).--harness piis documented for manual setup).archdev repo statusreports an opted-out harness asmissingwith a remediation that a barerepo hook setupwould apply; a distinct opted-out state belongs in the CLI (firstlanding).SKILL.md).tasks/scripts/bootstrap.sh|ps1still only refresh.🤖 Generated with Claude Code