@webpresso/agent-kit 3.3.3 → 3.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/THIRD-PARTY-NOTICES.md +12 -10
  2. package/catalog/agent/rules/changeset-release.md +15 -4
  3. package/catalog/agent/rules/managed-tool-binaries.md +67 -0
  4. package/catalog/agent/rules/parallel-orchestration-quota.md +99 -1
  5. package/catalog/agent/rules/pre-implementation.md +36 -20
  6. package/catalog/agent/rules/rtk-routing.md +22 -16
  7. package/catalog/agent/skills/autopilot/SKILL.md +4 -3
  8. package/catalog/agent/skills/ultragoal/SKILL.md +11 -9
  9. package/dist/esm/audit/agents.js +126 -26
  10. package/dist/esm/audit/hook-surface.js +5 -1
  11. package/dist/esm/audit/repo-guardrails.d.ts +8 -0
  12. package/dist/esm/audit/repo-guardrails.js +71 -1
  13. package/dist/esm/blueprint/core/parser.js +38 -12
  14. package/dist/esm/blueprint/execution/artifacts.js +8 -4
  15. package/dist/esm/blueprint/execution/frontmatter-keys.d.ts +17 -0
  16. package/dist/esm/blueprint/execution/frontmatter-keys.js +24 -0
  17. package/dist/esm/blueprint/execution/metadata.js +8 -4
  18. package/dist/esm/blueprint/lifecycle/audit.d.ts +21 -0
  19. package/dist/esm/blueprint/lifecycle/audit.js +89 -3
  20. package/dist/esm/blueprint/lifecycle/review-provenance.js +63 -10
  21. package/dist/esm/blueprint/lifecycle/rollout-anchor.d.ts +22 -0
  22. package/dist/esm/blueprint/lifecycle/rollout-anchor.js +37 -1
  23. package/dist/esm/blueprint/markdown/blocked-line.d.ts +49 -0
  24. package/dist/esm/blueprint/markdown/blocked-line.js +63 -0
  25. package/dist/esm/blueprint/markdown/helpers.js +10 -4
  26. package/dist/esm/blueprint/tracked-document/parser.js +3 -3
  27. package/dist/esm/blueprint/trust/dossier.js +41 -1
  28. package/dist/esm/blueprint/trust/gate-row.d.ts +55 -0
  29. package/dist/esm/blueprint/trust/gate-row.js +113 -0
  30. package/dist/esm/blueprint/trust/promotion.d.ts +17 -0
  31. package/dist/esm/blueprint/trust/promotion.js +19 -19
  32. package/dist/esm/build/atomic-file-copy.d.ts +32 -0
  33. package/dist/esm/build/atomic-file-copy.js +44 -0
  34. package/dist/esm/build/vendor-oxlint-plugins.d.ts +11 -0
  35. package/dist/esm/build/vendor-oxlint-plugins.js +48 -0
  36. package/dist/esm/cli/commands/blueprint/mutations.d.ts +15 -0
  37. package/dist/esm/cli/commands/blueprint/mutations.js +8 -2
  38. package/dist/esm/cli/commands/compile.d.ts +13 -0
  39. package/dist/esm/cli/commands/compile.js +182 -62
  40. package/dist/esm/cli/commands/format.js +17 -1
  41. package/dist/esm/cli/commands/gain/index.js +10 -3
  42. package/dist/esm/cli/commands/init/gitignore-patcher.js +6 -0
  43. package/dist/esm/cli/commands/init/index.js +32 -52
  44. package/dist/esm/cli/commands/init/mcp-spec.d.ts +48 -13
  45. package/dist/esm/cli/commands/init/mcp-spec.js +86 -30
  46. package/dist/esm/cli/commands/init/merge.js +30 -10
  47. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +56 -31
  48. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +180 -43
  49. package/dist/esm/cli/commands/init/scaffolders/rtk/index.d.ts +17 -5
  50. package/dist/esm/cli/commands/init/scaffolders/rtk/index.js +56 -75
  51. package/dist/esm/cli/commands/init/scaffolders/runtime-check/index.js +7 -6
  52. package/dist/esm/cli/commands/init/untracked-collision.d.ts +12 -1
  53. package/dist/esm/cli/commands/init/untracked-collision.js +23 -1
  54. package/dist/esm/cli/commands/pr-help.js +1 -1
  55. package/dist/esm/cli/commands/pr.js +18 -4
  56. package/dist/esm/cli/commands/review.d.ts +1 -0
  57. package/dist/esm/cli/commands/review.js +137 -7
  58. package/dist/esm/cli/commands/sync.d.ts +8 -6
  59. package/dist/esm/cli/commands/sync.js +11 -9
  60. package/dist/esm/cli/commands/worktree/router-dispatch.d.ts +24 -2
  61. package/dist/esm/cli/commands/worktree/router-dispatch.js +80 -48
  62. package/dist/esm/cli/commands/worktree/router.js +5 -2
  63. package/dist/esm/cli/direct-provider-launch.js +12 -4
  64. package/dist/esm/compiler/flatten.d.ts +10 -1
  65. package/dist/esm/compiler/flatten.js +14 -4
  66. package/dist/esm/compose/admin-blocks-registry-integrity.d.ts +22 -0
  67. package/dist/esm/compose/admin-blocks-registry-integrity.js +90 -0
  68. package/dist/esm/compose/compose.d.ts +8 -0
  69. package/dist/esm/compose/compose.js +115 -8
  70. package/dist/esm/compose/ops-report-schema.js +17 -3
  71. package/dist/esm/compose/registry-resolve.d.ts +17 -0
  72. package/dist/esm/compose/registry-resolve.js +78 -11
  73. package/dist/esm/config/oxlint/graphql-conventions.js +2 -5
  74. package/dist/esm/config/oxlint/import-hygiene.js +21 -8
  75. package/dist/esm/config/oxlint/oxlint-config.fixture.d.ts +1 -1
  76. package/dist/esm/config/oxlint/oxlint-config.fixture.js +2 -3
  77. package/dist/esm/config/oxlint/oxlintrc.d.ts +5 -7
  78. package/dist/esm/config/oxlint/oxlintrc.js +19 -31
  79. package/dist/esm/config/oxlint/path-roles.js +53 -0
  80. package/dist/esm/config/oxlint/query-patterns.js +2 -5
  81. package/dist/esm/content/dispatch.js +4 -0
  82. package/dist/esm/content/loader.d.ts +1 -1
  83. package/dist/esm/content/loader.js +10 -6
  84. package/dist/esm/content/skill-policy.d.ts +11 -0
  85. package/dist/esm/content/skill-policy.js +33 -0
  86. package/dist/esm/daemon/domains/blueprint-exec-ledger.d.ts +86 -0
  87. package/dist/esm/daemon/domains/blueprint-exec-ledger.js +134 -0
  88. package/dist/esm/daemon/domains/blueprint-exec.d.ts +106 -0
  89. package/dist/esm/daemon/domains/blueprint-exec.js +161 -0
  90. package/dist/esm/daemon/domains/launch.d.ts +25 -0
  91. package/dist/esm/daemon/domains/launch.js +30 -1
  92. package/dist/esm/daemon/handlers/blueprints-handlers.d.ts +12 -1
  93. package/dist/esm/daemon/handlers/blueprints-handlers.js +148 -6
  94. package/dist/esm/daemon/handlers/product.d.ts +10 -0
  95. package/dist/esm/daemon/handlers/product.js +10 -1
  96. package/dist/esm/daemon/methods.d.ts +21 -1
  97. package/dist/esm/daemon/methods.js +20 -0
  98. package/dist/esm/daemon/protocol/contract.d.ts +58 -0
  99. package/dist/esm/daemon/protocol/contract.js +38 -0
  100. package/dist/esm/daemon/server.js +7 -0
  101. package/dist/esm/docs-linter/blueprint-plan.js +2 -2
  102. package/dist/esm/errors/wp-error.js +21 -2
  103. package/dist/esm/hooks/doctor.d.ts +11 -0
  104. package/dist/esm/hooks/doctor.js +114 -45
  105. package/dist/esm/hooks/pretool-guard/dev-routing.js +68 -5
  106. package/dist/esm/hooks/pretool-guard/rtk-rewrite.d.ts +24 -0
  107. package/dist/esm/hooks/pretool-guard/rtk-rewrite.js +50 -0
  108. package/dist/esm/hooks/pretool-guard/runner.js +6 -0
  109. package/dist/esm/hooks/pretool-guard/validators/worktree-discipline.js +62 -3
  110. package/dist/esm/hooks/status/index.js +1 -1
  111. package/dist/esm/mcp/blueprint/_shared/lifecycle.js +39 -11
  112. package/dist/esm/mcp/blueprint/handlers/review-log.d.ts +14 -7
  113. package/dist/esm/mcp/blueprint/handlers/review-log.js +46 -22
  114. package/dist/esm/mcp/blueprint/registration.js +1 -1
  115. package/dist/esm/mcp/tools/_shared/redact.d.ts +22 -0
  116. package/dist/esm/mcp/tools/_shared/redact.js +114 -8
  117. package/dist/esm/mcp/tools/gain.js +28 -2
  118. package/dist/esm/mcp/tools/worktree.js +65 -3
  119. package/dist/esm/mcp/tools/wp-ui-compose.js +38 -4
  120. package/dist/esm/mcp/tools/wp-ui-preview.js +14 -7
  121. package/dist/esm/review/authority.js +56 -1
  122. package/dist/esm/review/delivery-verifier.d.ts +4 -0
  123. package/dist/esm/review/delivery-verifier.js +9 -1
  124. package/dist/esm/review/lifecycle-writers.d.ts +76 -0
  125. package/dist/esm/review/lifecycle-writers.js +330 -0
  126. package/dist/esm/review/subject.js +66 -32
  127. package/dist/esm/status/snapshot.d.ts +5 -0
  128. package/dist/esm/status/snapshot.js +27 -2
  129. package/dist/esm/symlinker/consumers.d.ts +3 -1
  130. package/dist/esm/symlinker/consumers.js +7 -1
  131. package/dist/esm/symlinker/unified-sync.d.ts +3 -3
  132. package/dist/esm/symlinker/unified-sync.js +88 -11
  133. package/dist/esm/test/shard-durations.json +0 -2
  134. package/dist/esm/test-helpers/global-setup.js +38 -3
  135. package/dist/esm/tool-runtime/managed-rtk.d.ts +44 -0
  136. package/dist/esm/tool-runtime/managed-rtk.js +275 -0
  137. package/dist/esm/tool-runtime/resolve-runner.js +18 -194
  138. package/dist/esm/utils/package-root.d.ts +32 -0
  139. package/dist/esm/utils/package-root.js +82 -0
  140. package/dist/esm/worktrees/git-metadata.d.ts +41 -0
  141. package/dist/esm/worktrees/git-metadata.js +48 -0
  142. package/package.json +16 -21
  143. package/dist/esm/cli/commands/init/scaffolders/subagents/index.d.ts +0 -6
  144. package/dist/esm/cli/commands/init/scaffolders/subagents/index.js +0 -77
  145. package/dist/esm/config/oxlint/code-safety.d.ts +0 -18
  146. package/dist/esm/config/oxlint/foundation-purity.d.ts +0 -21
  147. package/dist/esm/config/oxlint/graphql-conventions.d.ts +0 -23
  148. package/dist/esm/config/oxlint/import-hygiene.d.ts +0 -34
  149. package/dist/esm/config/oxlint/index.d.ts +0 -22
  150. package/dist/esm/config/oxlint/index.js +0 -28
  151. package/dist/esm/config/oxlint/monorepo-paths.d.ts +0 -22
  152. package/dist/esm/config/oxlint/query-patterns.d.ts +0 -24
  153. package/dist/esm/config/oxlint/testing-quality.d.ts +0 -35
  154. package/dist/esm/config/oxlint/tier-boundaries.d.ts +0 -35
  155. package/dist/esm/output-transforms/rulesync.d.ts +0 -2
  156. package/dist/esm/output-transforms/rulesync.js +0 -79
@@ -34,19 +34,21 @@ otherwise in their frontmatter.
34
34
  These skills document how to invoke external CLIs or packages. Their upstream
35
35
  binaries are **not** bundled in `@webpresso/agent-kit`.
36
36
 
37
- ## Runtime integrations (not bundled)
37
+ ## Runtime integrations
38
38
 
39
- These integrations invoke or install external tools separately; their upstream
40
- binaries are **not** bundled in `@webpresso/agent-kit`. The table below records
41
- whether each integration is part of the current default `wp setup` preset set or
42
- requires explicit `wp setup --with <name>` opt-in. Consumers accept the upstream
39
+ Policy for which upstream CLIs are managed-download vs host-install lives in
40
+ `catalog/agent/rules/managed-tool-binaries.md`. Summary: **rtk** is managed
41
+ (pinned cache download on setup); **vp** / **bun** remain host package-manager
42
+ installs; **actionlint** is probe-only.
43
+
44
+ The table below records default preset vs opt-in. Consumers accept the upstream
43
45
  license separately when an integration is installed.
44
46
 
45
- | Integration | Default behavior | Upstream | License |
46
- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ---------- |
47
- | `playwright-mcp` | Opt-in. | [microsoft/playwright-mcp](https://github.com/microsoft/playwright-mcp) | Apache-2.0 |
48
- | `workflow skill provenance` | Curated Markdown skill assets adapted from an MIT-licensed upstream workflow project; no upstream runtime checkout or binaries bundled. | [garrytan/gstack](https://github.com/garrytan/gstack) | MIT |
49
- | `rtk` | In the default preset set; skipped in CI or when `WP_SKIP_RTK=1`. | [rtk-ai/rtk](https://github.com/rtk-ai/rtk) | Apache-2.0 |
47
+ | Integration | Default behavior | Upstream | License |
48
+ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ---------- |
49
+ | `playwright-mcp` | Opt-in. | [microsoft/playwright-mcp](https://github.com/microsoft/playwright-mcp) | Apache-2.0 |
50
+ | `workflow skill provenance` | Curated Markdown skill assets adapted from an MIT-licensed upstream workflow project; no upstream runtime checkout or binaries bundled. | [garrytan/gstack](https://github.com/garrytan/gstack) | MIT |
51
+ | `rtk` | Managed install (pinned release into Webpresso cache on setup); skipped when `WP_SKIP_RTK=1`. Binary not reimplemented; filters stay upstream. | [rtk-ai/rtk](https://github.com/rtk-ai/rtk) | Apache-2.0 |
50
52
 
51
53
  ## Runtime npm dependencies
52
54
 
@@ -91,9 +91,15 @@ When a feature branch with a `.changeset/<slug>.md` file merges to `main`,
91
91
  2. The action runs `wp run version`, which preserves the canonical version
92
92
  path: `changeset version && wp run sync-marketplace-version`.
93
93
  3. When the Version PR is merged, CI runs `wp run release:publish`, which
94
- calls `npm publish --provenance --access public` inside GitHub Actions using
95
- npm trusted publishing/OIDC. This workflow is the only production npm publish
96
- path for Webpresso packages.
94
+ calls `npm publish --access public` inside GitHub Actions using npm trusted
95
+ publishing/OIDC. This workflow is the only production npm publish path for
96
+ Webpresso packages. **Provenance attestations are not currently produced.**
97
+ npm only issues provenance for a **public source repository**
98
+ (`https://docs.npmjs.com/generating-provenance-statements/`), and
99
+ `webpresso/agent-kit` is private, so `--provenance` was removed from every
100
+ publish call site. **Do not add `--provenance` back while this repo is
101
+ private — npm will reject the publish.** Provenance returns automatically
102
+ through this same OIDC flow if/when the repo becomes public.
97
103
  4. After publish, CI verifies the `v<version>` tag on the mainline version-bump
98
104
  commit and creates `release/v<version>` as the separate dist-carrying
99
105
  compatibility branch for marketplace consumers.
@@ -203,7 +209,12 @@ dist-tag changes, or subsequent versions.
203
209
  Use `.github/workflows/release.yml` — not `ci.agent-kit.yml` and not the
204
210
  artifact-only matrix job names — because the `release` job in `release.yml` is
205
211
  the job that runs `wp run release:publish`, has `id-token: write`, and invokes
206
- `npm publish --provenance --access public`.
212
+ `npm publish --access public` via npm trusted publishing/OIDC. It does **not**
213
+ pass `--provenance`: npm only issues provenance for a public source
214
+ repository (`https://docs.npmjs.com/generating-provenance-statements/`), and
215
+ this repo is private. Do not add `--provenance` while the repo stays private —
216
+ npm will reject the publish. Provenance returns automatically through this
217
+ same OIDC flow once the repo becomes public.
207
218
 
208
219
  ## Required repo files
209
220
 
@@ -0,0 +1,67 @@
1
+ ---
2
+ type: rule
3
+ slug: managed-tool-binaries
4
+ title: Managed third-party tool binaries
5
+ status: active
6
+ scope: repo
7
+ applies_to: [agents]
8
+ related: [rtk-routing]
9
+ created: "2026-07-25"
10
+ last_reviewed: "2026-07-25"
11
+ paths:
12
+ - "src/tool-runtime/**"
13
+ - "src/cli/commands/init/scaffolders/**"
14
+ - "compatible-versions.json"
15
+ - "THIRD-PARTY-NOTICES.md"
16
+ ---
17
+
18
+ # Managed third-party tool binaries
19
+
20
+ Policy for when agent-kit **embeds** (managed download/cache) an upstream CLI
21
+ versus leaving install to the host package manager / user.
22
+
23
+ ## Decision rule (YAGNI)
24
+
25
+ Manage a binary only when **all** of the following hold:
26
+
27
+ 1. **Invisible filter or sidecar** — used on agent/hook hot paths without the
28
+ user intentionally invoking it (e.g. output filtering).
29
+ 2. **Freestanding install creates dual ownership** — PATH/`init` hooks or
30
+ second install stories fight path-stable `wp` surfaces.
31
+ 3. **Small, pinned, capability-probed** — single static binary (or tiny
32
+ archive), Apache/MIT-class license, bounded probe, fail-open degrade.
33
+ 4. **No existing first-class package channel** — if the tool is already the
34
+ workspace package manager or a full runtime (npm/vp/bun), do not invent a
35
+ parallel download channel.
36
+
37
+ Otherwise: **probe + install hint**, or rely on existing global/package install.
38
+
39
+ ## Inventory (current)
40
+
41
+ | Tool | Lane | Why |
42
+ | ---------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
43
+ | **rtk** | **Managed** (`src/tool-runtime/managed-rtk.ts`) | Optional hot-path filter; freestanding PreToolUse hooks were dual/broken; pinned GitHub release; capability probe `gain --help` |
44
+ | **wp** | First-party | Own product binary / runtime staging |
45
+ | **vp** (vite-plus) | **Host / package-manager** | Workspace package manager + global `vp install`; CI uses `voidzero-dev/setup-vp`; `resolveGlobalCapableVpCommand` — not a cache-download sidecar |
46
+ | **bun** | **Host runtime** | JS runtime; install via bun.sh / brew; often co-installed with vite-plus; do not dual-manage |
47
+ | **actionlint** | **Probe-only** | Optional workflow lint; `runtime-check` prints hint only; not on agent PreToolUse hot path |
48
+ | **playwright** / MCP plugins | **Opt-in package** | Explicit setup/MCP install; not silent binary cache |
49
+
50
+ ## Hard rules
51
+
52
+ - Do **not** add managed downloaders for `vp` or `bun` without a product
53
+ decision that retires the package-manager install path (would fork ownership).
54
+ - Do **not** reimplement upstream filter/CLI logic in TypeScript to avoid
55
+ shipping a binary.
56
+ - New managed tools must: pin version in `compatible-versions.json`, document
57
+ license in `THIRD-PARTY-NOTICES.md`, use absolute path resolution (never bare
58
+ PATH as the only source of truth), and degrade fail-open when skip/missing.
59
+ - Freestanding third-party PreToolUse hooks remain forbidden; setup strips
60
+ known RTK freestanding markers.
61
+
62
+ ## Implementation pattern (when adding a managed tool)
63
+
64
+ 1. Single module under `src/tool-runtime/managed-<tool>.ts` (resolve + ensure + probe).
65
+ 2. Setup scaffolder calls `ensure*` only; no brew/cargo as the default lane.
66
+ 3. All runtime call sites import the same resolve helper (DRY).
67
+ 4. Tests: inject downloader; isolate cache via env root; no network in unit tests.
@@ -11,8 +11,9 @@ related:
11
11
  - pre-implementation
12
12
  - engineering-principles
13
13
  - supported-agent-clis
14
+ - workflow-skills-routing
14
15
  created: "2026-07-24"
15
- last_reviewed: "2026-07-24"
16
+ last_reviewed: "2026-07-25"
16
17
  paths:
17
18
  - "blueprints/**"
18
19
  - "catalog/agent/**"
@@ -29,6 +30,17 @@ policy, `cmd-execution.md` for the scoped-command surface,
29
30
  `pre-implementation.md` for the blueprint gate, `engineering-principles.md` for
30
31
  scope filters, `supported-agent-clis.md` for host tiers.
31
32
 
33
+ ## Product mission anchor
34
+
35
+ Webpresso is a product for building websites and agents on webpresso framework
36
+ tooling, and every agent session here exists to move that product loop forward.
37
+ Token economy is a standing constraint on that loop, not an optimization applied
38
+ when convenient: prefer the harnesses and building blocks — `wp_*` tools,
39
+ skills, subagent dispatch — over long free-form context, and spend the fewest
40
+ tokens that still preserve quality. The orchestrator/executor split, the
41
+ one-deliverable brief, and the cheapest-capable-model rule below are all
42
+ instruments of that constraint, not independent preferences.
43
+
32
44
  ## Orchestrator / executor split
33
45
 
34
46
  The session that owns the program is an **orchestrator**: it plans, sequences,
@@ -43,6 +55,56 @@ blueprint's owner worktree.
43
55
  - The orchestrator runs from its own controller worktree cut from
44
56
  `origin/main`, never from the primary checkout.
45
57
 
58
+ ## One deliverable per brief
59
+
60
+ **Brief scope drives executor cost more than model tier does.** A brief listing
61
+ four numbered deliverables buys four investigations. Measured on one program:
62
+ multi-item briefs ran 374K–501K tokens each; the same class of defect briefed as
63
+ a single deliverable ran 117K and landed its PR. Trimming scope mid-flight does
64
+ **not** recover the spend — the exploration already happened.
65
+
66
+ - State **one** deliverable. Secondary polish is `only if trivial`, or omitted.
67
+ - Apply DRY/KISS/YAGNI to the **brief**, before dispatch — not to the diff after.
68
+ Ask "what is the single smallest change that fixes this?" and brief only that.
69
+ - **Prefer deletion-shaped fixes.** Removing a behavior usually beats adding a
70
+ mechanism to describe it. Deletion-shaped fixes are cheaper to brief,
71
+ implement, and review, and they close a defect class rather than narrowing it —
72
+ which also removes the hedged "narrowed, not closed" wording a partial fix
73
+ forces into its docs.
74
+ - Give the executor the diagnosis you already hold. Re-deriving a known root
75
+ cause is pure duplicated cost.
76
+
77
+ ## Never await — poll
78
+
79
+ An executor that ends its turn to "wait for" a background job **deadlocks**: the
80
+ completion signal has usually already fired, so it idles indefinitely. Measured
81
+ on one program: four executors × 3–5 rounds ≈ 2M tokens for zero landed work.
82
+ Nudges did not break the loop; only orchestrator takeover did.
83
+
84
+ - Executors **poll in a loop**. Never end a turn waiting for a notification.
85
+ - Read durable state directly instead of awaiting: a review gate's outcome is in
86
+ `.webpresso/reviews/gates/<gate-id>.json` (`status`, `attempts[]`); CI is
87
+ readable via the PR status surface. Both are cheaper than waiting.
88
+ - If genuinely blocked, **report and stop** — an explicit blocker is recoverable,
89
+ an idle turn is not.
90
+
91
+ ## Verify executor output, not executor reports
92
+
93
+ A report describes intent; the diff is what lands. Read the diff before trusting
94
+ a summary.
95
+
96
+ - **Measure diffs against the fork point** (`git merge-base origin/main HEAD`),
97
+ never `origin/main` directly — a stale branch renders main's newer content as
98
+ deletions, making a five-file change look like a thousand-file catastrophe.
99
+ - Watch for **whole-file rewrites from serializer round-trips**: editing YAML or
100
+ JSON by parsing and re-emitting silently renormalizes quoting and formatting
101
+ across the file, burying the real change and risking semantic drift. Config
102
+ edits are plain-text edits.
103
+ - Orchestrator claims about gate state must be **machine-checked before being
104
+ passed to an executor**. Asserting "gate X approved your work" without
105
+ confirming its `reviewedCommit`/target matches what is being shipped sends the
106
+ executor to land on a stale approval.
107
+
46
108
  ## Model tier by intrinsic difficulty
47
109
 
48
110
  Pick the **cheapest model that can do the job**, judged by the hardest task in
@@ -66,6 +128,42 @@ work does not. A technically-correct but badly-judged UI passes every check and
66
128
  still has to be redone, so the cheaper tier is not actually cheaper. Backend and
67
129
  mechanical work keeps the cheapest-capable rule above.
68
130
 
131
+ ## Operator model ladder (reviewed 2026-07-25)
132
+
133
+ The tier table above is host-agnostic. This section records how an operator maps
134
+ it onto the hosts actually installed today. It is a **dated operator default,
135
+ revisable per operator and per host** — agent-kit does not own model selection
136
+ or agent hosting, only the dispatch-cost discipline for the work agents hand
137
+ off.
138
+
139
+ - **Cheap and mid tiers are the default lanes, and they run wide.** Mechanical
140
+ S/XS work and ordinary M work fan out across several concurrent executors;
141
+ that parallelism is where the throughput comes from, so it is the normal case,
142
+ not an exceptional one.
143
+ - **The premium reasoning tier is narrow and deliberate** (e.g. the Claude Opus
144
+ class): L/XL blueprints, design/UI/frontend work, security- and
145
+ trust-boundary changes, and anything digest-, wire-format-, or
146
+ protocol-bearing. If one hard task is the only reason a blueprint wants this
147
+ tier, re-home that task — do not upgrade the whole lane.
148
+ - **The frontier gating tier is rare and human-invoked** (e.g. the Claude
149
+ Fable/Mythos class). Its job is milestone approval on one-way doors — a schema
150
+ or wire format that cannot be un-shipped, a security-posture change, an
151
+ irreversible migration — not execution. It never enters routine dispatch and is
152
+ never the default for a sized blueprint.
153
+ - **On a Codex host the operator's configured default model handles routine
154
+ checks**, with a premium family member reserved for the rare deep check. The
155
+ configuration owns that identity, not this document: read
156
+ `~/.codex/config.toml` (`model`), `CODEX_REVIEW_MODEL`, and
157
+ `CLAUDE_REVIEW_MODEL`. Never hardcode a model id or a preference ordering into
158
+ a plan, brief, or skill — the ids move faster than the prose does.
159
+
160
+ Two orderings deliberately live elsewhere and are **not** restated here: the
161
+ OpenCode reviewer purpose→family ordering, which is rendered into the
162
+ [`opencode-go` skill](../skills/opencode-go/SKILL.md) from the committed
163
+ reviewer policy and drift-gated by CI, and the agent-CLI tiers in
164
+ [`supported-agent-clis.md`](./supported-agent-clis.md). Read those; a second
165
+ copy is a second thing to update, and the stale copy is the one an agent reads.
166
+
69
167
  ## Quota awareness across hosts
70
168
 
71
169
  Provider subscriptions are the budget. Treat weekly quota as a shared,
@@ -162,11 +162,17 @@ lifecycle-valid, but they have no sibling review authority; run
162
162
  `wp blueprint canonicalize <slug>` before recording review ledgers, artifacts,
163
163
  Ultragoal events, or approval frontmatter.
164
164
 
165
- - **Gate input = committed in-folder review authority.** The preferred path is a
166
- content-addressed v2 `review-events.jsonl` event produced by `wp review gate`.
167
- The legacy path is `_overview.md` frontmatter `approvals:` backed by a matching
168
- committed `reviews.md` structured entry and separate tracked artifact. The
169
- markdown `## Approvals` checklist is only a human-readable mirror.
165
+ - **Gate input = committed in-folder review authority.** The only path for new
166
+ blueprints is a content-addressed v2 `review-events.jsonl` event produced by
167
+ `wp review gate` (or `wp review override`). The legacy path `_overview.md`
168
+ frontmatter `approvals:` backed by a matching committed `reviews.md` structured
169
+ entry and separate tracked artifact **carries no content binding** (it never
170
+ reads or hashes the blueprint body), so it is accepted only for blueprints
171
+ grandfathered at `LEGACY_APPROVAL_LEG_ANCHOR_COMMIT`. On any blueprint created
172
+ after that anchor, a frontmatter `approvals:` entry does not satisfy the gate no
173
+ matter which reviewer it names; the audit says so explicitly rather than
174
+ reporting a bare "0 approvals". The markdown `## Approvals` checklist is only a
175
+ human-readable mirror.
170
176
  - **Durable record = committed in-folder review history.** V2 events bind the
171
177
  verdict to the reviewed subject digest and artifact hash. Legacy frontmatter
172
178
  entries count only with matching `wp:review-entry` provenance and a tracked
@@ -182,8 +188,10 @@ Ultragoal events, or approval frontmatter.
182
188
  Enforced by `wp audit blueprint-lifecycle`, the promotion command, and
183
189
  changed-completed blueprint CI audits.
184
190
  - **Recording a review entry is MCP-first**: use the `wp_blueprint_review_log`
185
- MCP tool to write the artifact, the matching `reviews.md` structured entry,
186
- and the corresponding `approvals:` frontmatter entry in one call. It is
191
+ MCP tool to write the artifact and the matching `reviews.md` structured entry
192
+ in one call (plus the `approvals:` frontmatter entry for `reject`/`no-verdict`
193
+ attribution — it never writes an `approve`/`approve-with-nits` entry there,
194
+ because that field is the unbound legacy leg). It is
187
195
  **not** the same as this CLI's own `wp review log` subcommand — that writes
188
196
  only the machine ledger (`review-events.jsonl`) and requires `--provider`
189
197
  plus a `human` reviewer for any approval verdict; treat the two as distinct,
@@ -199,14 +207,14 @@ Ultragoal events, or approval frontmatter.
199
207
  restriction exactly. It cannot mint a `claude`/`codex`/`grok`/OpenCode-Go
200
208
  frontmatter approval: no caller-supplied pointer can prove a named non-human
201
209
  reviewer actually produced an artifact, so the tool does not accept one.
202
- Use it for `reject`/`no-verdict` entries from any reviewer, or a
203
- human-adjudicated `approve`/`approve-with-nits`. Satisfying the
210
+ Use it for `reject`/`no-verdict` entries from any reviewer, or to record a
211
+ human-adjudicated `approve`/`approve-with-nits` in `reviews.md`. Satisfying the
204
212
  strong-reviewer promotion gate for a `claude`/`codex`/`grok`/OpenCode-Go identity
205
- still requires either a converged `wp review gate` run (ledger-backed,
206
- requires no frontmatter at all) or a maintainer directly authoring the
207
- `approvals:` frontmatter with first-hand knowledge that reviewer actually
208
- produced that verdict — there is intentionally no MCP-reachable shortcut
209
- around that.
213
+ requires a converged `wp review gate` run (ledger-backed, requires no
214
+ frontmatter at all). Hand-authoring `approvals:` frontmatter is no longer an
215
+ option on a post-anchor blueprint — the gate does not read that leg there — so
216
+ there is neither an MCP-reachable nor a hand-edited shortcut around the
217
+ content-bound ledger.
210
218
  - **`wp review override <slug> --reason "…" --confirm` is the gated CLI escape
211
219
  hatch for a genuinely un-convergeable gate** — a strong reviewer legitimately
212
220
  rejected the subject but its sole remaining blocker is physically
@@ -342,16 +350,24 @@ scaffold a draft only to exempt it. For multi-file exempt follow-ups, use a
342
350
  `wp worktree new` — never `bp/<slug>`, which pre-claims the owner branch and
343
351
  collides with `wp blueprint start`.
344
352
 
345
- When the primary checkout has user-owned edits or is still on a topic branch,
346
- prefer:
353
+ `--switch-primary` (the current flag name; `--stash-primary` is accepted as a
354
+ deprecated alias and no longer stashes anything) is **not** a way to preserve
355
+ "user-owned edits" on the primary checkout — it never stashes primary state at
356
+ all. A **dirty** primary always refuses merge-cleanup, unconditionally, naming
357
+ the offending files, with or without this flag:
347
358
 
348
359
  ```bash
349
- cd <primary-checkout> && wp worktree merge-cleanup <merged-worktree-or-branch> --base origin/main --stash-primary
360
+ cd <primary-checkout> && wp worktree merge-cleanup <merged-worktree-or-branch> --base origin/main --switch-primary
350
361
  ```
351
362
 
352
- That preserves the existing primary-checkout state in a named git stash,
353
- switches the primary to the expected branch, and then performs the normal
354
- remove + fast-forward cleanup.
363
+ The flag bypasses only the OTHER refusal: a **clean** primary sitting on the
364
+ wrong branch. In that case it switches the primary to the expected branch and
365
+ then performs the normal remove + fast-forward cleanup — switching a clean
366
+ checkout is harmless, there is nothing uncommitted to lose. If the primary
367
+ checkout has uncommitted work — human-owned edits, a topic branch you're mid
368
+ way through, or leftover blueprint draft scaffold — commit it, `git stash` it
369
+ yourself, or run `wp blueprint abandon <slug> --confirm` first. Do not expect
370
+ `--switch-primary`/`--stash-primary` to preserve it for you.
355
371
 
356
372
  ## PR-level blueprint coverage gate
357
373
 
@@ -5,9 +5,9 @@ title: RTK Tool Routing
5
5
  status: active
6
6
  scope: repo
7
7
  applies_to: [agents]
8
- related: []
8
+ related: [managed-tool-binaries]
9
9
  created: "2026-05-07"
10
- last_reviewed: "2026-05-07"
10
+ last_reviewed: "2026-07-25"
11
11
  paths:
12
12
  - "**/*"
13
13
  ---
@@ -17,25 +17,26 @@ paths:
17
17
  `rtk *` and the `wp_*` MCP tools are independent lanes. Webpresso-owned dev
18
18
  workflows route to the matching `wp_*` MCP tool — each tool's `description`
19
19
  states when to use it, and `pretool-guard` denies the common raw equivalents.
20
- There is no injected routing block; the tool descriptions plus AGENTS.md are the
21
- source of routing guidance.
22
-
23
- Use `rtk *` for shell-tool output filtering on the long-tail command surface
24
- that webpresso does not own.
25
20
 
26
21
  ## Ownership boundary
27
22
 
28
- - webpresso owns `wp_*` dev-workflow routing and MCP-shaped deny wording
29
- - rtk owns shell-tool output filtering for the long-tail surface (`git`, `gh`,
30
- `kubectl`, `cargo`, `pytest`, `ruff`, and similar non-quality-engine tools)
31
- - `wp_*` and `rtk *` are independent lanes; prefer the `wp_*` MCP tool for
32
- webpresso-owned workflows
23
+ See also `managed-tool-binaries` for why only rtk is managed-download (not vp/bun).
24
+
25
+ - webpresso owns **managed packaging** of the upstream `rtk` binary (pinned
26
+ download into the Webpresso cache on setup), PreToolUse rewrite routing, and
27
+ wrapping of quality-engine runners when filtering is enabled
28
+ - rtk owns shell-tool **output filtering** (implementation stays upstream;
29
+ Apache-2.0; never reimplemented in TypeScript)
30
+ - freestanding consumer hooks (`rtk-rewrite.sh`, `rtk hook claude`) are
31
+ **retired** — never re-introduce them
32
+ - consumers **do not** brew/cargo install rtk for Webpresso workflows
33
33
 
34
34
  ## Hard rules
35
35
 
36
36
  - Never reimplement upstream rtk filters in webpresso.
37
37
  - Never wrap the `rtk` prefix behind `wp rtk`.
38
- - Keep `wp_*` and `rtk *` as independent lanes.
38
+ - Never install freestanding RTK PreToolUse groups in managed project settings.
39
+ - Prefer managed absolute rtk path from setup; do not require a global PATH install.
39
40
 
40
41
  ## Lane 4: Webpresso workflow/browser skills
41
42
 
@@ -45,6 +46,11 @@ Keep these as an independent lane from the `wp_*` MCP tools.
45
46
 
46
47
  ## Subprocess coverage note
47
48
 
48
- wp*\* tools shelling out via child_process.spawn own their own filtering; rtk PreToolUse hook
49
- only fires for top-level Bash calls and does NOT reach into wp*\* internals. CLI verbs
50
- (wp <verb> from a shell) ARE rewritten by rtk.
49
+ wp* tools shelling out via child_process.spawn own their own filtering via
50
+ managed rtk when available. pretool-guard may rewrite exact `git status` to the
51
+ managed rtk binary when present. When rtk is skipped (`WP_SKIP_RTK=1`) or
52
+ unavailable, commands passthrough unfiltered.
53
+
54
+ Long-tail RTK filtering beyond exact `git status` requires an explicit
55
+ `rtk …` invocation (or the managed absolute binary path); pretool-guard
56
+ does not auto-rewrite the rest of the rtk command surface.
@@ -20,7 +20,7 @@ using `wp_ultragoal_run` / `wp ultragoal run` and the current handoff.
20
20
 
21
21
  ## Outside-voice (required)
22
22
 
23
- After each ultragoal **phase or plan-gate milestone**, run an **OpenCode Go** outside-voice review and pick the model by purpose (plan critique DeepSeek Pro; coding quality Kimi Code first; cheap recheck DeepSeek Flash). Resolve IDs from live `opencode models opencode-go`. Lifecycle authority only via converged `wp review gate` — never self-approve. Full protocol: the `ultragoal` skill. Respect `review_budget` (default one sequential path; no multi-host stampede).
23
+ After each ultragoal **phase or plan-gate milestone**, run an **OpenCode Go** outside-voice review and pick the model by purpose. The purposefamily ordering lives in one place the committed reviewer policy rendered into the `opencode-go` skill — so follow that skill and do not restate the ordering here. Resolve IDs from live `opencode models opencode-go`. Lifecycle authority only via converged `wp review gate` — never self-approve. Full protocol: the `ultragoal` skill. Respect `review_budget` (default owned by `workflow-skills-routing.md`): one sequential path, no multi-host stampede.
24
24
 
25
25
  ## Vague gate
26
26
 
@@ -34,8 +34,9 @@ A brief is anchored when it includes a file path, symbol, issue number, test nam
34
34
  A leading `force:` is the only explicit bypass; strip it before creating the goal and
35
35
  record the bypass in the blueprint.
36
36
 
37
- Default budgets if the user omits them: `concurrency=4`, `fix_budget=1`,
38
- `review_budget=1`, no `/loop`. See `ultragoal` skill.
37
+ Default budgets if the user omits them: `concurrency=4`, `fix_budget=1`, no
38
+ `/loop`; `review_budget` per `workflow-skills-routing.md`. See `ultragoal`
39
+ skill.
39
40
 
40
41
  ## Tooling map
41
42
 
@@ -21,12 +21,12 @@ multi-agent swarms.
21
21
 
22
22
  ## Default budgets (override only when the user sets them)
23
23
 
24
- | Budget | Default | Meaning |
25
- | --------------- | --------- | ---------------------------------------------------------- |
26
- | `concurrency` | 4 (max 8) | Parallel ready tasks / implementer lanes |
27
- | `fix_budget` | 1 | Pre-existing issues fixable via `/fix` this phase |
28
- | `review_budget` | 1 | Outside-voice reviewers for merge-ready (0 for local work) |
29
- | `loop` | off | Do not run `/loop` or unbounded stop-hooks |
24
+ | Budget | Default | Meaning |
25
+ | --------------- | -------------------------------- | -------------------------------------------------- |
26
+ | `concurrency` | 4 (max 8) | Parallel ready tasks / implementer lanes |
27
+ | `fix_budget` | 1 | Pre-existing issues fixable via `/fix` this phase |
28
+ | `review_budget` | see `workflow-skills-routing.md` | Outside-voice reviewer paths, local vs merge-ready |
29
+ | `loop` | off | Do not run `/loop` or unbounded stop-hooks |
30
30
 
31
31
  Reject unbudgeted sleep-mode briefs (“complete all”, “full autopilot”, “go to sleep”)
32
32
  unless they name a blueprint/slug, budgets, and a stop condition. Route vague briefs
@@ -66,7 +66,8 @@ Fallback to `wp …` CLI only when the matching MCP tool is unavailable. Prefer
66
66
  6. **Opportunistic `/fix`:** at most `fix_budget` pre-existing issues per phase, each with
67
67
  named invariant + failing proof. Excess → handoff backlog (do not expand epic).
68
68
  7. **Validate / land:** local proof with `wp_qa` / targeted tools; outside review only when
69
- merge-ready and within `review_budget` (default **exactly 1** sequential outside voice).
69
+ merge-ready and within `review_budget` **exactly one sequential** outside voice unless
70
+ the user sets N (the default value lives in `workflow-skills-routing.md`).
70
71
  Prefer `wp review gate` for lifecycle authority. Use `wp_pr_*` for PR babysit — no
71
72
  multi-sleep poll loops; no parallel multi-reviewer stampede.
72
73
  8. Stop on `complete`, `cancelled`, blocked guard exhaustion, or `WP_ULTRAGOAL_DISABLE=1`.
@@ -87,7 +88,7 @@ primary checkout.
87
88
 
88
89
  Autopilot and agent-driven ultragoal loops **must** request an **OpenCode Go** outside-voice review after each **goal/phase milestone**, and must pick the model by purpose. Direct `wp review run` output is advisory only. Lifecycle authority that can satisfy promotion/completion gates comes only from a converged **`wp review gate`** (content-addressed ledger + bound artifact).
89
90
 
90
- Count each milestone review against `review_budget` for merge-ready claims: **exactly one sequential** reviewer path unless the user sets N. Prefer purpose-matched OpenCode Go first; do not fan out multi-host review swarms.
91
+ Count each milestone review against `review_budget` for merge-ready claims: **exactly one sequential** reviewer path unless the user sets N; the default value is owned by `workflow-skills-routing.md`. Prefer purpose-matched OpenCode Go first; do not fan out multi-host review swarms.
91
92
 
92
93
  ### Milestones that require a review
93
94
 
@@ -147,7 +148,8 @@ Use `--purpose plan` for plan-phase promotion and `--purpose delivery` for imple
147
148
  - If no PR-bound green CI is available, fall back to local **`wp_qa`**.
148
149
  - Open a PR early so CI can satisfy QA. Do **not** raise timeouts.
149
150
  - **Land** still requires a **MERGED** PR with green required checks bound to the projected
150
- source snapshot. Use `/verify --merge-ready` (review_budget=1), not default local verify.
151
+ source snapshot. Use `/verify --merge-ready` (merge-ready `review_budget`, per
152
+ `workflow-skills-routing.md`), not default local verify.
151
153
 
152
154
  ## Snapshot / dirty worktree
153
155