projecta-rrr 1.22.0 → 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,78 @@ 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
+
41
+ ## [1.22.1] - 2026-04-19
42
+
43
+ **Patch: fixes v1.22.0 fresh install regression.**
44
+
45
+ ### Fixed
46
+ - **`scripts/register-mcp.js` postinstall** no longer breaks `npm install -g projecta-rrr`. Two fixes:
47
+ 1. Fallback path corrected — looks at `<pkg>/rrr/mcp-server/index.js` (npm layout) before `<pkg>/mcp-server/index.js` (legacy). v1.22.0 only checked the legacy path, which doesnt exist in the npm tarball, causing the postinstall to exit 1 and abort the entire install.
48
+ 2. Registration failures are now advisory (`process.exit(0)` + warn) instead of fatal (`process.exit(1)`). Re-run `node scripts/register-mcp.js` or `/rrr:doctor` after install if needed.
49
+
50
+ Surfaced via UAT: fresh `HOME=tmp npm install -g projecta-rrr@1.22.0 --prefix=tmp` aborted before `node_modules/projecta-rrr` landed. v1.22.1 installs cleanly.
51
+
52
+ ### Verified in UAT
53
+ - **Hosted MCP latency** (5 samples): 108–142ms (median ~128ms) on /health.
54
+ - **Model-router PreToolUse latency** (10 samples): 30–40ms per Task spawn.
55
+ - **Dynamic routing (Phase 83)** static = no rewrite (v1.21 bit-for-bit); dynamic = `rrr-explore→haiku` rewrite + telemetry row.
56
+ - **Stage-aware routing**: `verify-work` + `rrr-verifier` = sonnet; `plan-phase` execution + `general-purpose` = inherit.
57
+ - **Phase 84 escalation**: `rrr-debugger` iter-3 with state at `<project>/.rrr/state/debug-session.json` → opus + telemetry `reason:"debugger_iter_escalate", retry_count:3, prior_tier:"inherit"`.
58
+ - **Phase 85 tool-disallow**: BLOCKs main-thread Read with exit 2 when flag on; allows when flag off; respects `RRR_TOK_DISALLOW=off` kill switch.
59
+ - **Phase 85 edit-batching-nudge**: 2nd Edit within 30s → "edited foo.js 2× in ~30s" advisory; 3rd silent (lastNudgeMs prevents spam); state at `<project>/.planning/.cache/edit-batching-state.json`.
60
+ - **PUSH-POLICY**: 10/10 RRR command skills include `git push`/`auto-push` reference.
61
+ - **auto-push helper**: graceful failure on no-remote ("non-fatal — your work is committed locally"); `auto_push:false` → `{ran:false, skipped:"settings_disabled"}`.
62
+ - **measure-token-delta + measure-opus-rate**: correctly return INSUFFICIENT_DATA verdict on partial telemetry (13 dispatches, need ≥100). Methodology + min_required documented in JSON output.
63
+ - **/rrr:savings**: reads `<project>/.planning/observations*.jsonl` + `~/.rrr/telemetry/escalations.jsonl`.
64
+ - **doctor**: clean on populated install ("Found 1 command root(s) ✅ active"); reports 0 + SAFE MODE on hud-only install (expected — full provision needs `npx projecta-rrr install`).
65
+ - **Fresh install (v1.22.1)**: `HOME=tmp npm install -g projecta-rrr@1.22.1 --prefix=tmp` succeeds, package lands in node_modules.
66
+
67
+ ### Known UAT findings (followups, not blockers)
68
+ - **edit-batching-nudge state location**: `<project>/.planning/.cache/edit-batching-state.json`. Hook is silent if CWD has no `.planning/` directory — by design (cant infer project context). Document in onboarding.
69
+ - **/rrr:savings input path**: project-root `.planning/observations*.jsonl`, NOT HOME. Reports 0 if v1.19 observation logger never ran in current project.
70
+ - **`tool-disallow` subagent exemption**: heuristic uses `input.agent_name` field; needs validation against real Claude Code PreToolUse payload schema (Phase 85 followup).
71
+ - **Postinstall `--hud-only`**: full command/agent/script provision requires separate `npx projecta-rrr install`. Consider auto-bootstrapping in v1.22.x.
72
+ - **`/metrics/freshness`** hosted endpoint returns 404 — by design; HUD reads freshness via `semantic_search` response payload.
73
+
74
+
75
+ ### Known limitations (followups)
76
+ - `tool-disallow` subagent exemption uses `input.agent_name` heuristic; may need updating when Claude Code PreToolUse payload schema is fully nailed down.
77
+ - Escalation requires per-project state file at `<project>/.rrr/state/debug-session.json` (not HOME). Increments are wired in v1.22 but operator should verify their /rrr:debug session writes to CWD.
78
+
7
79
  ## [1.22.0] - 2026-04-19
8
80
 
9
81
  **Webhook Live Reindex + Dynamic Routing + Token Diet v2.**
@@ -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.0",
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
  ],
@@ -41,8 +41,14 @@ function getMCPServerPath() {
41
41
  return installedPath;
42
42
  }
43
43
 
44
- // Fallback to relative path from script (for source/development)
45
- // scripts/register-mcp.js -> ../mcp-server/index.js
44
+ // Fallback to package-relative path. Try both layouts: published npm package
45
+ // ships the server at <pkg>/rrr/mcp-server/index.js, but the dev repo also
46
+ // has a top-level <pkg>/mcp-server (legacy v1.17 layout).
47
+ // scripts/register-mcp.js → __dirname is <pkg>/scripts
48
+ const npmLayout = path.resolve(__dirname, '..', 'rrr', 'mcp-server', 'index.js');
49
+ if (fs.existsSync(npmLayout)) {
50
+ return npmLayout;
51
+ }
46
52
  return path.resolve(__dirname, '..', 'mcp-server', 'index.js');
47
53
  }
48
54
 
@@ -274,13 +280,20 @@ if (require.main === module) {
274
280
  console.log(`Registered ${MCP_SERVER_ID} with Claude Code (method: ${result.method})`);
275
281
  process.exit(0);
276
282
  } else {
277
- console.error(`Failed to register: ${result.error}`);
278
- process.exit(1);
283
+ // Advisory only — don't fail npm postinstall on registration failure.
284
+ // The MCP server can be registered later via /rrr:doctor or by re-running
285
+ // `node scripts/register-mcp.js`. v1.22.0 shipped exit(1) here, which
286
+ // broke fresh `npm install -g projecta-rrr` (the package never landed
287
+ // because postinstall errored). v1.22.1 makes this advisory.
288
+ console.warn(`[mcp] Registration skipped: ${result.error}`);
289
+ console.warn(`[mcp] Run 'node scripts/register-mcp.js' or '/rrr:doctor' after install to retry.`);
290
+ process.exit(0);
279
291
  }
280
292
  })
281
293
  .catch(err => {
282
- console.error(`Error: ${err.message}`);
283
- process.exit(1);
294
+ console.warn(`[mcp] Registration error: ${err.message}`);
295
+ console.warn(`[mcp] Continuing — re-run registration manually.`);
296
+ process.exit(0);
284
297
  });
285
298
  }
286
299
  }