projecta-rrr 1.22.1 → 1.22.2

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,40 @@ All notable changes to RRR will be documented in this file.
4
4
 
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.22.2] - 2026-04-19
8
+
9
+ **Patch: dynamic routing now actually fires in Claude Code (Opus 4.7+).**
10
+
11
+ ### Fixed
12
+ - **Phase 83 model-router matcher**: Claude Code (Opus 4.7+) emits subagent dispatches as `tool_name: "Agent"`, not `"Task"`. v1.22.0/.1 hardcoded `"Task"` in both:
13
+ 1. `hooks/model-router.js` internal gate (`if (toolName !== "Task") return emitAllow()`)
14
+ 2. `rrr/lib/install-hooks-wiring.js` matcher (`{ matcher: "Task", ... }`)
15
+ Result: hook never fired for any Agent dispatch in Opus 4.7+ sessions, so dynamic routing was a no-op even with `settings.rrr.model_router: "dynamic"`.
16
+
17
+ v1.22.2 accepts both `Task` and `Agent`. Live UAT verified end-to-end:
18
+ ```
19
+ {"ts":"2026-04-19T05:46:21Z","event":"dispatch","tool_name":"Agent",
20
+ "agent_name":"rrr-explore","tier":"haiku","reason":"dispatch"}
21
+ ```
22
+ Token usage on rrr-explore call: ~10.4k (haiku) vs ~13.2k baseline (general-purpose, sonnet/inherit) — ~21% reduction from tier downgrade alone, on a single dispatch.
23
+
24
+ ### Verified in UAT (v1.21 hosted webhook + Phase 80 App-level)
25
+ - **Hosted Fly app redeployed** with v1.22 code (was running pre-Phase-80 image — `/webhooks/github-app` returned 404 until `fly deploy`).
26
+ - **Phase 80 webhook end-to-end**:
27
+ - Ping: 200 OK
28
+ - Valid HMAC push (with `installation_id` lookup): 202 + `{queued:true, job_id}`
29
+ - Replay (same delivery_id): 200 + `{duplicate:true}` ✓ dedup
30
+ - Bad signature: 401 `signature_invalid`
31
+ - Non-default branch: 200 `{skipped:"non-default-branch"}`
32
+ - Unindexed repo (NULL `github_repo_id`): 200 `{skipped:"unindexed-repo"}`
33
+ - **Neon migration 014 applied**: `installations` table populated with 5 rows from existing `repos.installation_id` data.
34
+ - **`installations` table**: 5 rows under `team_id=pa-ai-team`. Largest installation: 125117864 (29 repos).
35
+
36
+ ### Known followups
37
+ - **Backfill `repos.github_repo_id`** for all 62 repos via `gh api /repos/<full_name>`. Without this, App-level webhook deliveries hit "unindexed-repo" skip path. Operator-actionable.
38
+ - **Postinstall `--hud-only`** still requires separate `npx projecta-rrr install` for full provision. v1.22.x followup.
39
+ - **`tool-disallow` subagent exemption heuristic** uses `input.agent_name` — this field is NOT present in real Claude Code PreToolUse payload (UAT-verified payload schema has `tool_name`, `tool_input`, `session_id`, `transcript_path`, `cwd`, `permission_mode`, `tool_use_id`). Subagent context detection needs different mechanism.
40
+
7
41
  ## [1.22.1] - 2026-04-19
8
42
 
9
43
  **Patch: fixes v1.22.0 fresh install regression.**
@@ -85,9 +85,12 @@ function main() {
85
85
  try { input = JSON.parse(raw); }
86
86
  catch (_e) { return emitAllow('router: stdin not JSON'); }
87
87
 
88
- // Only act on the Task tool — every other tool is pass-through.
88
+ // Only act on the subagent-dispatch tool — every other tool is pass-through.
89
+ // Claude Code uses either "Task" (Anthropic API name, most builds) or "Agent"
90
+ // (Opus 4.7+ builds) for subagent dispatch. Accept both — confirmed via
91
+ // v1.22.2 UAT live-session capture (/tmp/uat-hook-log.jsonl).
89
92
  const toolName = input.tool_name;
90
- if (toolName !== 'Task') return emitAllow();
93
+ if (toolName !== 'Task' && toolName !== 'Agent') return emitAllow();
91
94
 
92
95
  const toolInput = (input.tool_input && typeof input.tool_input === 'object') ? input.tool_input : {};
93
96
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "projecta-rrr",
3
- "version": "1.22.1",
3
+ "version": "1.22.2",
4
4
  "description": "A meta-prompting, context engineering and spec-driven development system for Claude Code by Projecta.ai",
5
5
  "bin": {
6
6
  "projecta-rrr": "bin/install.js",
@@ -210,7 +210,10 @@ function wireToolRedirect({ repoHooksDir, userHooksDir, userSettingsPath, dryRun
210
210
  */
211
211
  function buildModelRouterEntry(hookAbsPath) {
212
212
  return {
213
- matcher: 'Task',
213
+ // Claude Code uses either "Task" (most builds) or "Agent" (Opus 4.7+) as
214
+ // the subagent dispatch tool name. Match both via regex alternation —
215
+ // confirmed via v1.22.2 UAT live-session capture.
216
+ matcher: 'Task|Agent',
214
217
  hooks: [
215
218
  { type: 'command', command: `node ${hookAbsPath}` },
216
219
  ],