Repository navigation
Description
Problem
The maintainer wants /pr-review to find as much as pr-review-toolkit does, without vendoring it. There are two ways a Box could use the toolkit: spawn its agents by subagent_type, or invoke /pr-review-toolkit:review-pr from a node. #547's resolution, § Broadening /pr-review, not decided here compares the two.
Neither way works unless an Archon node can reach a plugin that is enabled in the repository, and nobody has measured that. On Archon v0.10.1 three facts are measured. A project skill reaches a node only through skills:. An MCP server reaches it only through mcp:. A node reads CLAUDE.md but not AGENTS.md. See docs/agents/agent-tool-traps.md § Archon, #521 and #425. Two runs before v0.9.0 called the toolkit's agents and recorded no result.
This spike measures reach only. It changes no Box and does not touch the reviewer, so it does not disturb #501's baseline or #502's seal.
Acceptance criteria
- The probe runs in a scratch repository outside every clone, with
pr-review-toolkit@claude-plugins-officialenabled in that repository's.claude/settings.json, on the Archon version the Consumer runs. The result names that version and the Claude Code version the nodes ran. - The result states, for each of the following, whether it reached the node and how that was shown: a toolkit agent spawned by
subagent_typefrom a node,/pr-review-toolkit:review-prinvoked from a node, and a plugin skill invoked from a node. - Each result that is "reached" carries a marker the reached component could only have produced. A result that is "not reached" shows that the node attempted the call. A probe that cannot fail scores as not run.
- The result states whether any node field, such as
skills:or a settings source, changes reach, and names each field that was tried. - The result is posted on this issue with the workflow YAML and the commands that produced it. Each finding that is a tool trap goes to
docs/agents/agent-tool-traps.md§ Archon.
Notes
/prototypeis installed at the maintainer's user scope, not in this repository. A spike that uses it depends on one machine, and no Archon node or teammate has it by default. The probe needs no branch here.- The broadening itself is a separate issue, blocked by this one.
Activity
orioltf commentedon Sep 29, 2026
Trap for the command form of the probe
/pr-review-toolkit:review-prtakes its scope fromgit diff --name-onlyand looks for the pull request withgh pr view(itscommands/review-pr.md, step 3, in plugin cachefbe07fb6ce7d). Two things follow for this spike:git diff --name-onlylists uncommitted changes in the working tree, not a branch against its merge-base. A node in a scratch repository with a clean tree gives the command no files. That empty review looks like a command that never ran. Give the probe an uncommitted change, or pass the scope explicitly, and record which one it used. Otherwise a "not reached" result for the command form is not evidence.gh pr viewworks on GitHub only. On an Azure DevOps repository the command finds no pull request. This does not change reach, but feat(unic-archon-dlc): /pr-review finds as much as pr-review-toolkit, without vendoring it #629 has to account for it.Reported by the
e2e-suiteseat's wayfinder and checked byunic-sdlc-orchestrator-4against the command file, 2026-09-29. The #547 resolution records the same two facts.orioltf commentedon Sep 29, 2026
Opener for #628, written 2026-09-29 by
unic-sdlc-orchestrator-4at dispatch.What it produces
A measured answer, posted on this issue, to one question. Can an Archon node reach three things from a plugin: an agent through
subagent_type, a command such as/pr-review-toolkit:review-pr, and a skill? And does it matter whether the plugin is enabled at user scope or at project scope?You are already in
/wayfinder 498 628. That resolves one ticket: post the answer, close #628, and add it to #498's Decisions so far. Do not start #629. It is blocked by this ticket, #501 and #502, and it is grilled later.Read order
/pr-review, not decided here". It says why the two forms matter. Read the table, not the history.docs/agents/agent-tool-traps.md§ Archon, the entries from "A node getsCLAUDE.mdand nothing else by default" to "A probe proves the items it called and nothing beside them". The probe builds on them, and they already name the setup traps.The one trap: this machine enables the toolkit at user scope
~/.claude/settings.jsonon this machine setspr-review-toolkit@claude-plugins-official: true, and so dounic-archon-dlc,code-reviewand others. The measured trap says a subagent sees every skill the host has, plugin skills included. So a probe that finds the toolkit reachable may be measuring the maintainer's machine, not what a Consumer teammate gets from the repository's.claude/settings.json. That positive would be real and useless.Report every result with the scope that enabled it. A result that holds only while the plugin is enabled at user scope says nothing about a Consumer.
The decision this ticket does not make
How to separate user scope from project scope. Two competent implementers would differ here:
.claude/settings.jsonand never at user scope. It holds one agent, one command and one skill, and each writes a marker nothing else could produce. This needs no change to any of the maintainer's files, and it is what I recommend. Whether a project-scope local marketplace installs in a headless node is part of what it measures.Run the real toolkit as well, and label its result "enabled at user and project scope".
Other traps
--no-worktree, or add a dummy remote unique to this run.git diff --name-onlylists only uncommitted changes. Give the command form an uncommitted change, or pass the scope, and say which. An empty review looks like a command that never ran.Skillor anAgentcall still finishes green. Judge by the marker, never by the run status.pr-review-toolkitagents are expensive. Point them at a diff of a few lines.gitorghcommand. The scratch repository needs no client name.The bar that proves it
For each of the three forms, a positive result is a marker file the reached component wrote. A negative result is the node's own tool result, showing the attempted call and its error. A form with neither was not tested, so report it as not run, never as "not reached". The marker-plugin result is the one that answers #629. The real-toolkit result only confirms that the marker plugin behaves like a published one.
On landing
/wayfinder.docs/agents/agent-tool-traps.md§ Archon, in the entry style it already uses, dated, with the versions. Do it on afeature/unic-archon-dlc/628-plugin-reach-from-nodebranch, in a worktree outside the clone, created withgit worktree add --no-track -b <branch> <path> origin/develop, then runpnpm install --frozen-lockfilethere. Open the PR as a draft todevelopwithCloses #628left out, because/wayfindercloses the ticket. Tell me the PR number. The maintainer merges.Report-back clause
Review and handover
This ticket ends in a posted result, not a merge. I read the result against the bar before #629 counts it. For the traps PR, run
pnpm checkand judge it by its exit code, then leave the PR in draft for me.orioltf commentedon Sep 29, 2026
Result: a node reaches a plugin agent, command and skill, with conditions
Measured on 2026-09-29 with Archon CLI v0.10.1 (git commit
9820785c, darwin-arm64). Every node ran Claude Code 2.1.284: Archon logged"binaryPath":"/Users/oriol.torrent/.local/bin/claude","source":"env", and that symlink points atversions/2.1.284.The scratch repository is
/Users/oriol.torrent/Sites/scratch-628-plugin-reach. It has one dummy remote,https://example.invalid/probe-628-3784ce0a.git. Every run used--no-worktree. The marker pluginreach-markerlives in a directory marketplace outside it,/Users/oriol.torrent/Sites/scratch-628-marker-marketplace. Its agent, its command and its skill each append a line with a random token tomarkers/<form>.txt, and no node prompt holds a token. The 362 run events inarchon.dbhold noRead,GreporGlobcall, and no event names the marketplace path or the plugin cache. So every marker below comes from the component itself. Every node finished green, including the ones that failed their call, so the scores below come from markers and tool results only.Answer for #629
Once the plugin is installed on the machine at project scope, and enabled only there:
settingSources: [project]skills: [<plugin>:<name>]subagent_type: reach-marker:marker-agentAGENT-… agent-defaultAGENT-… agent-project-only/reach-marker:marker-command label=…COMMAND-… label=command-literalreach-marker:marker-commandSkill reach-marker:marker-command is not in this session's skills allowlistCOMMAND-… label=command-declaredreach-marker:marker-skillSkill reach-marker:marker-skill is not in this session's skills allowlistSKILL-… skill-declared, and withsettingSources: [project]too, markerSKILL-… skill-declared-project-onlySo:
subagent_typewith no declaration. That holds with user scope switched off.skills:and calls it with the Skill tool. Without the declaration, the Skill tool refuses it.skills:. This matches the measured rule for project skills.Before installation, nothing reaches a node
Phase 1 ran with the repository's
.claude/settings.jsonalone:extraKnownMarketplacesnaming the directory marketplace, andenabledPluginsenablingreach-marker@reach-marker-628. Nothing had been installed on the machine. All five calls failed. The agent calls returnedAgent type 'reach-marker:marker-agent' not found, the Skill calls returnedUnknown skill: …, and the literal command prompt was not expanded. No marker file appeared. So a headless node does not install a marketplace or a plugin that the committed settings only declare. Somebody has to runclaude plugin install <plugin>@<marketplace> --scope projecton that machine first. It wrote no line to~/.claude/settings.json. It added the marketplace to~/.claude/plugins/known_marketplaces.jsonand the install to~/.claude/plugins/installed_plugins.json, tagged"scope": "project"with this repository's path. Whether an interactive session installs from the same settings is not measured here.What
settingSources: [project]changesOn v0.10.1 the Claude provider takes
settingSourcesfrom the node, then fromassistants.claude.settingSources, then falls back to["project","user"]. So by default a node loads user-scope plugins. Two controls show thatsettingSources: [project]on the node removes them:unic-pr-review:*agents, which only user settings enable. The error of thesettingSources: [project]node did not list them, but still listedpr-review-toolkit:*, which the scratch repository enables.code-review@claude-plugins-officialis enabled only at user scope. A default node callingcode-review:code-reviewgotSkill code-review:code-review is not in this session's skills allowlist, so the skill was loaded and only refused. The same node withsettingSources: [project]gotUnknown skill: code-review:code-review, so the skill was not loaded.The two errors tell the cases apart. "Not in this session's skills allowlist" means the skill is loaded and the node did not declare it. "Unknown skill" means the skill is not loaded at all.
Node fields tried:
settingSources: [project]andskills:. Not tried: inlineagents:,assistants.claude.settingSourcesin.archon/config.yaml, andsettingSources: [user].The real toolkit, enabled at project scope only
The maintainer set
pr-review-toolkit@claude-plugins-officialtofalsein~/.claude/settings.json. The file's mtime is 2026-09-29T10:45:16Z. Phase 1 started at 10:45:03Z, so phase 1 ran with the toolkit enabled at user and project scope. Every toolkit run below started at 10:47:03Z, with the toolkit enabled at project scope only. The probe gave the command an uncommitted one-line change toapp.js, which turns its comment into a false one. It passed no scope.subagent_type: pr-review-toolkit:comment-analyzer, default nodeapp.js:1settingSources: [project]/pr-review-toolkit:review-pr comments# PR review summary (comments)format, found the false comment, and reported no PR because the remote is not GitHub. It reviewed the one-line diff itself and launched no agentpr-review-toolkit:review-pr, not declaredSkill pr-review-toolkit:review-pr is not in this session's skills allowlistThis matches the marker plugin form for form. The toolkit markers are weaker than the plugin's tokens, because they are review text. They only confirm that the marker plugin behaves like a published one.
One probe defect, corrected
The phase 2
skill-declarednode loaded the skill (Launching skill: reach-marker:marker-skill) but wrote no marker. Its rules said "Do not run any marker command yourself", and the skill runs inside the node's own agent. I scored it as not run and ran it again in phase 3 with rules that let the node follow the skill. Those results are the ones in the first table.Commands
The tool results and markers of every phase are in
/Users/oriol.torrent/Sites/scratch-628-results/, with the logs next to it (scratch-628-phase{1,2,3}.log). Run ids:2cdce522(phase 1),64c1901f,403a6461,6945b67c,0c9599fd(phase 2) and75465d8d(phase 3).probe-628-marker.yamlprobe-628-declared.yamlprobe-628-toolkit.yamlprobe-628-control.yamlMarker plugin
agents/marker-agent.mdcommands/marker-command.mdskills/marker-skill/SKILL.mdThe tokens are left out here. They are in the plugin files and in
/Users/oriol.torrent/Sites/scratch-628-tokens.txt.