@jaggerxtrm/specialists 3.17.0 → 3.18.1

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 (255) hide show
  1. package/README.md +268 -134
  2. package/config/mandatory-rules/executor-delivery.md +4 -0
  3. package/config/mandatory-rules/json-only-final-output.md +13 -0
  4. package/config/mandatory-rules/service-skills-diff-scan-mandatory.md +26 -0
  5. package/config/mandatory-rules/service-skills-gitnexus-triage.md +5 -0
  6. package/config/mandatory-rules/test-runner-execution-scope.md +4 -0
  7. package/config/skills/setup-specialists/SKILL.md +556 -0
  8. package/config/skills/specialists-creator/SKILL.md +132 -4
  9. package/config/skills/specialists-creator/scripts/audit-spec-uniformity.mjs +1 -1
  10. package/config/skills/using-specialists-v3/SKILL.md +80 -20
  11. package/config/specialists/bare.specialist.json +3 -3
  12. package/config/specialists/changelog-drafter.specialist.json +5 -4
  13. package/config/specialists/changelog-keeper.specialist.json +7 -6
  14. package/config/specialists/debugger.specialist.json +2 -2
  15. package/config/specialists/executor.specialist.json +2 -2
  16. package/config/specialists/explorer.specialist.json +4 -4
  17. package/config/specialists/memory-processor.specialist.json +3 -3
  18. package/config/specialists/node-coordinator.specialist.json +3 -3
  19. package/config/specialists/obligations-scanner.specialist.json +67 -17
  20. package/config/specialists/overthinker.specialist.json +3 -3
  21. package/config/specialists/planner.specialist.json +4 -4
  22. package/config/specialists/quant-methodologist.specialist.json +145 -0
  23. package/config/specialists/quant-researcher.specialist.json +144 -0
  24. package/config/specialists/researcher.specialist.json +5 -5
  25. package/config/specialists/reviewer.specialist.json +1 -1
  26. package/config/specialists/seconder.specialist.json +2 -2
  27. package/config/specialists/security-auditor.specialist.json +2 -2
  28. package/config/specialists/service-skills-sync.specialist.json +90 -75
  29. package/config/specialists/specialists-creator.specialist.json +4 -4
  30. package/config/specialists/sync-docs.specialist.json +4 -4
  31. package/config/specialists/test-engineer.specialist.json +3 -3
  32. package/config/specialists/test-runner.specialist.json +7 -7
  33. package/config/specialists/transcriber.specialist.json +3 -3
  34. package/config/specialists/xt-merge.specialist.json +4 -4
  35. package/dist/asset-contract.json +22 -3
  36. package/dist/index.js +28711 -18517
  37. package/dist/lib.js +10020 -6150
  38. package/dist/types/cli/console/components.d.ts +83 -0
  39. package/dist/types/cli/console/components.d.ts.map +1 -0
  40. package/dist/types/cli/console/config-source.d.ts +58 -0
  41. package/dist/types/cli/console/config-source.d.ts.map +1 -0
  42. package/dist/types/cli/console/forensic.d.ts +11 -0
  43. package/dist/types/cli/console/forensic.d.ts.map +1 -0
  44. package/dist/types/cli/console/git.d.ts +28 -0
  45. package/dist/types/cli/console/git.d.ts.map +1 -0
  46. package/dist/types/cli/console/help.d.ts +2 -0
  47. package/dist/types/cli/console/help.d.ts.map +1 -0
  48. package/dist/types/cli/console/log.d.ts +13 -0
  49. package/dist/types/cli/console/log.d.ts.map +1 -0
  50. package/dist/types/cli/console/repo-config.d.ts +26 -0
  51. package/dist/types/cli/console/repo-config.d.ts.map +1 -0
  52. package/dist/types/cli/console/repo-discovery.d.ts +12 -0
  53. package/dist/types/cli/console/repo-discovery.d.ts.map +1 -0
  54. package/dist/types/cli/console/runtime.d.ts +12 -0
  55. package/dist/types/cli/console/runtime.d.ts.map +1 -0
  56. package/dist/types/cli/console/subscribe-prototype.d.ts +18 -0
  57. package/dist/types/cli/console/subscribe-prototype.d.ts.map +1 -0
  58. package/dist/types/cli/console/theme.d.ts +91 -0
  59. package/dist/types/cli/console/theme.d.ts.map +1 -0
  60. package/dist/types/cli/console/types.d.ts +231 -0
  61. package/dist/types/cli/console/types.d.ts.map +1 -0
  62. package/dist/types/cli/console/view-model.d.ts +252 -0
  63. package/dist/types/cli/console/view-model.d.ts.map +1 -0
  64. package/dist/types/cli/console.d.ts +2 -0
  65. package/dist/types/cli/console.d.ts.map +1 -0
  66. package/dist/types/cli/db.d.ts.map +1 -1
  67. package/dist/types/cli/doctor.d.ts.map +1 -1
  68. package/dist/types/cli/edit.d.ts.map +1 -1
  69. package/dist/types/cli/epic.d.ts.map +1 -1
  70. package/dist/types/cli/feed.d.ts.map +1 -1
  71. package/dist/types/cli/forensic.d.ts +2 -0
  72. package/dist/types/cli/forensic.d.ts.map +1 -0
  73. package/dist/types/cli/format-helpers.d.ts +4 -2
  74. package/dist/types/cli/format-helpers.d.ts.map +1 -1
  75. package/dist/types/cli/help.d.ts.map +1 -1
  76. package/dist/types/cli/init.d.ts +10 -0
  77. package/dist/types/cli/init.d.ts.map +1 -1
  78. package/dist/types/cli/list.d.ts.map +1 -1
  79. package/dist/types/cli/log.d.ts.map +1 -1
  80. package/dist/types/cli/merge.d.ts.map +1 -1
  81. package/dist/types/cli/metrics.d.ts +2 -0
  82. package/dist/types/cli/metrics.d.ts.map +1 -0
  83. package/dist/types/cli/ps.d.ts.map +1 -1
  84. package/dist/types/cli/result.d.ts.map +1 -1
  85. package/dist/types/cli/run.d.ts +20 -0
  86. package/dist/types/cli/run.d.ts.map +1 -1
  87. package/dist/types/cli/script.d.ts +3 -0
  88. package/dist/types/cli/script.d.ts.map +1 -1
  89. package/dist/types/cli/serve.d.ts.map +1 -1
  90. package/dist/types/cli/setup.d.ts +19 -1
  91. package/dist/types/cli/setup.d.ts.map +1 -1
  92. package/dist/types/cli/status.d.ts.map +1 -1
  93. package/dist/types/cli/version-check.d.ts +1 -0
  94. package/dist/types/cli/version-check.d.ts.map +1 -1
  95. package/dist/types/index.d.ts +1 -1
  96. package/dist/types/pi/session.d.ts +12 -1
  97. package/dist/types/pi/session.d.ts.map +1 -1
  98. package/dist/types/server.d.ts +15 -0
  99. package/dist/types/server.d.ts.map +1 -1
  100. package/dist/types/specialist/benchmarks.d.ts +37 -0
  101. package/dist/types/specialist/benchmarks.d.ts.map +1 -0
  102. package/dist/types/specialist/chain-identity.d.ts +7 -1
  103. package/dist/types/specialist/chain-identity.d.ts.map +1 -1
  104. package/dist/types/specialist/control.d.ts.map +1 -1
  105. package/dist/types/specialist/dead-job-audit.d.ts +20 -0
  106. package/dist/types/specialist/dead-job-audit.d.ts.map +1 -0
  107. package/dist/types/specialist/forensic-events.d.ts +138 -0
  108. package/dist/types/specialist/forensic-events.d.ts.map +1 -0
  109. package/dist/types/specialist/forensic-renderer.d.ts +34 -0
  110. package/dist/types/specialist/forensic-renderer.d.ts.map +1 -0
  111. package/dist/types/specialist/git-diff-evidence.d.ts +28 -0
  112. package/dist/types/specialist/git-diff-evidence.d.ts.map +1 -0
  113. package/dist/types/specialist/global-config.d.ts +389 -0
  114. package/dist/types/specialist/global-config.d.ts.map +1 -0
  115. package/dist/types/specialist/launch.d.ts +9 -0
  116. package/dist/types/specialist/launch.d.ts.map +1 -1
  117. package/dist/types/specialist/live-aggregates.d.ts +46 -0
  118. package/dist/types/specialist/live-aggregates.d.ts.map +1 -0
  119. package/dist/types/specialist/loader.d.ts +50 -1
  120. package/dist/types/specialist/loader.d.ts.map +1 -1
  121. package/dist/types/specialist/model-chain.d.ts +7 -0
  122. package/dist/types/specialist/model-chain.d.ts.map +1 -0
  123. package/dist/types/specialist/model-probes.d.ts +28 -0
  124. package/dist/types/specialist/model-probes.d.ts.map +1 -0
  125. package/dist/types/specialist/node-contract.d.ts +18 -18
  126. package/dist/types/specialist/node-supervisor.d.ts.map +1 -1
  127. package/dist/types/specialist/observability-db.d.ts +1 -1
  128. package/dist/types/specialist/observability-db.d.ts.map +1 -1
  129. package/dist/types/specialist/observability-sqlite.d.ts +101 -0
  130. package/dist/types/specialist/observability-sqlite.d.ts.map +1 -1
  131. package/dist/types/specialist/pr-drift-refresh.d.ts +17 -0
  132. package/dist/types/specialist/pr-drift-refresh.d.ts.map +1 -0
  133. package/dist/types/specialist/preset-resolver.d.ts +56 -0
  134. package/dist/types/specialist/preset-resolver.d.ts.map +1 -0
  135. package/dist/types/specialist/prometheus-projection.d.ts +25 -0
  136. package/dist/types/specialist/prometheus-projection.d.ts.map +1 -0
  137. package/dist/types/specialist/runner.d.ts +29 -1
  138. package/dist/types/specialist/runner.d.ts.map +1 -1
  139. package/dist/types/specialist/schema.d.ts +163 -54
  140. package/dist/types/specialist/schema.d.ts.map +1 -1
  141. package/dist/types/specialist/script-runner.d.ts +5 -1
  142. package/dist/types/specialist/script-runner.d.ts.map +1 -1
  143. package/dist/types/specialist/snapshot-diff.d.ts +8 -0
  144. package/dist/types/specialist/snapshot-diff.d.ts.map +1 -0
  145. package/dist/types/specialist/source-queue.d.ts +13 -0
  146. package/dist/types/specialist/source-queue.d.ts.map +1 -0
  147. package/dist/types/specialist/status-load.d.ts.map +1 -1
  148. package/dist/types/specialist/supervisor.d.ts +25 -1
  149. package/dist/types/specialist/supervisor.d.ts.map +1 -1
  150. package/dist/types/specialist/timeline-events.d.ts +70 -1
  151. package/dist/types/specialist/timeline-events.d.ts.map +1 -1
  152. package/dist/types/tools/specialist/resume_specialist.tool.d.ts +4 -4
  153. package/dist/types/tools/specialist/specialist_status.tool.d.ts +1 -1
  154. package/dist/types/tools/specialist/steer_specialist.tool.d.ts +4 -4
  155. package/dist/types/tools/specialist/use_specialist.tool.d.ts +16 -16
  156. package/docs/ARCHITECTURE.md +1176 -0
  157. package/docs/TODO.md +9 -0
  158. package/docs/architecture.md +11 -0
  159. package/docs/archive/2026-03-13-bd-decision-context-template-plan.md +96 -0
  160. package/docs/archive/AGENT-HANDOFF.md +351 -0
  161. package/docs/archive/PARITY-ANALYSIS.md +296 -0
  162. package/docs/archive/SPECIALISTS_REFACTOR.md.md +30 -0
  163. package/docs/archive/cc-programmatic.md +216 -0
  164. package/docs/archive/claude-agent-sdk.md +594 -0
  165. package/docs/archive/decision-specialist-directory.md +41 -0
  166. package/docs/archive/discoveries.md +148 -0
  167. package/docs/archive/executor-benchmark-protocol.md +198 -0
  168. package/docs/archive/future-features.md +66 -0
  169. package/docs/archive/gzrx-completion-critique.md +183 -0
  170. package/docs/archive/gzrx-research-notes.md +401 -0
  171. package/docs/archive/gzrx-tool-catalog.md +760 -0
  172. package/docs/archive/iron-review-hardening-qa-chain-substrate.md +322 -0
  173. package/docs/archive/iron-review-hardening.html +1004 -0
  174. package/docs/archive/issuetracking.md +312 -0
  175. package/docs/archive/qa-v3.0.2.md +220 -0
  176. package/docs/archive/restructure.md +231 -0
  177. package/docs/archive/script-specialists.md +1254 -0
  178. package/docs/archive/spec-v3.md +792 -0
  179. package/docs/archive/specialist-stats.md +127 -0
  180. package/docs/archive/specialists-friction-audit.md +1347 -0
  181. package/docs/archive/specialists-runtime-critique.md +170 -0
  182. package/docs/archive/specialists-service-evaluation.md +713 -0
  183. package/docs/archive/specialists-substrate-alignment.md +255 -0
  184. package/docs/archive/substrate-review.md +1288 -0
  185. package/docs/archive/test-writer-specialist.md +254 -0
  186. package/docs/archive/using-specialists-v3-improvements-2026-05-09.md +600 -0
  187. package/docs/archive/xtrm-specialists-analysis.md +314 -0
  188. package/docs/authoring.md +701 -0
  189. package/docs/background-jobs.md +203 -0
  190. package/docs/bare-specialists.md +83 -0
  191. package/docs/benchmarks/executor-benchmark-runner.md +66 -0
  192. package/docs/bootstrap.md +161 -0
  193. package/docs/cli-reference.md +1645 -0
  194. package/docs/deploying-alongside.md +155 -0
  195. package/docs/design/README.md +36 -0
  196. package/docs/design/darth-feedor-migration.md +290 -0
  197. package/docs/design/roadmap/README.md +32 -0
  198. package/docs/design/roadmap/chain-templates/README.md +146 -0
  199. package/docs/design/roadmap/chain-templates/code-quick.formula.json +27 -0
  200. package/docs/design/roadmap/chain-templates/code-standard.formula.json +126 -0
  201. package/docs/design/roadmap/chain-templates/code-with-advisors.formula.json +128 -0
  202. package/docs/design/roadmap/chain-templates/code-with-tests.formula.json +76 -0
  203. package/docs/design/roadmap/chain-templates/debug.formula.json +128 -0
  204. package/docs/design/roadmap/chain-templates/doc-sync.formula.json +28 -0
  205. package/docs/design/roadmap/chain-templates/memory-hygiene.formula.json +27 -0
  206. package/docs/design/roadmap/chain-templates/planning.formula.json +27 -0
  207. package/docs/design/roadmap/chain-templates/premortem.formula.json +26 -0
  208. package/docs/design/roadmap/chain-templates/release-prep.formula.json +36 -0
  209. package/docs/design/roadmap/chain-templates/research-only.formula.json +28 -0
  210. package/docs/design/roadmap/chain-templates/restitch.formula.json +125 -0
  211. package/docs/design/roadmap/chain-templates/security-deep.formula.json +161 -0
  212. package/docs/design/roadmap/chain-templates/test-only.formula.json +52 -0
  213. package/docs/design/roadmap/chain-templates/triage.formula.json +35 -0
  214. package/docs/design/roadmap/history/handoff-from-substrate-design.md +87 -0
  215. package/docs/design/roadmap/history/substrate-reconciliation.md +105 -0
  216. package/docs/design/roadmap/specialists-roadmap.md +1261 -0
  217. package/docs/design/sp-console-subscribe-via-materializer.md +231 -0
  218. package/docs/design/sp-console-tui-mock-v2.html +293 -0
  219. package/docs/design/sp-console-tui-mock.html +120 -0
  220. package/docs/design/sp-console-tui.md +340 -0
  221. package/docs/design/specialist-agentops-suite.md +323 -0
  222. package/docs/design/substrate/channels.md +14 -0
  223. package/docs/design/substrate/devops-platform-engineering-prd.md +446 -0
  224. package/docs/design/substrate/html-design-example.md +339 -0
  225. package/docs/design/xtrm-tiers-architecture.svg +132 -0
  226. package/docs/devops/dependency-verdict-materialization.md +46 -0
  227. package/docs/epic-readiness.md +75 -0
  228. package/docs/examples/mercury-atomic-summarizer.specialist.json +26 -0
  229. package/docs/examples/smoke-echo-text-expected-keys.specialist.json +25 -0
  230. package/docs/examples/smoke-echo.specialist.json +25 -0
  231. package/docs/features.md +1577 -0
  232. package/docs/hooks.md +81 -0
  233. package/docs/installation.md +142 -0
  234. package/docs/manifest.md +184 -0
  235. package/docs/mcp-servers.md +73 -0
  236. package/docs/mcp-tools.md +71 -0
  237. package/docs/nodes.md +231 -0
  238. package/docs/observability-metrics.md +152 -0
  239. package/docs/operator/sp-console-v2-walkthrough.md +410 -0
  240. package/docs/overrides-guide.md +306 -0
  241. package/docs/pi-rpc-boundary.md +118 -0
  242. package/docs/pi-session.md +195 -0
  243. package/docs/release.md +22 -0
  244. package/docs/skills.md +132 -0
  245. package/docs/specialists/handoff-schema.md +181 -0
  246. package/docs/specialists-catalog.md +99 -0
  247. package/docs/specialists-service-install.md +226 -0
  248. package/docs/specialists-service.md +363 -0
  249. package/docs/surface-ownership.md +138 -0
  250. package/docs/upgrade-notes/kan-90-global-user-config.md +114 -0
  251. package/docs/upgrade-notes/kan-91-expanded-overrides.md +261 -0
  252. package/docs/workflow.md +114 -0
  253. package/docs/worktree.md +71 -0
  254. package/docs/worktrees.md +309 -0
  255. package/package.json +7 -4
@@ -0,0 +1,760 @@
1
+ # gzrx — Centralized Specialists Manifest + Tool Catalog Design
2
+
3
+ > Status: **DRAFT — design phase**. Implementation tracked under `unitAI-8vb65`.
4
+ > Author: Pi in-pi coding agent (evidence-driven), with research overlay
5
+ > (`gzrx-research-notes.md`) and overthinker critique (`unitAI-o6icy`) folded
6
+ > into §3.0 (precedence), §3.3 (health), §7 (migration), §8 (open questions).
7
+ > Last updated: 2026-05-03.
8
+
9
+ This document is the canonical design for `unitAI-gzrx`. The design is split
10
+ into the **manifest overlay** (transport) and the **tool catalog + capability
11
+ matrix** (content). The original overthinker pass produced the manifest; this
12
+ doc fills in the catalog half on top of firsthand evidence from a pi session
13
+ that can introspect its own toolbox.
14
+
15
+ ---
16
+
17
+ ## 0. Problem statement
18
+
19
+ The current runtime has hardcoded tier→tool mappings in
20
+ `src/pi/session.ts::mapPermissionToTools` (constants `GITNEXUS_READ_TOOLS`,
21
+ `SERENA_READ_TOOLS`, `SERENA_LOW_TOOLS`, `SERENA_WRITE_TOOLS`,
22
+ `GITNEXUS_WRITE_TOOLS`, plus inline native tool literals). The hotfix
23
+ `unitAI-2s7y8` added extension tool names so they are *available* per tier, but:
24
+
25
+ - Native tools (`read`, `grep`, `find`, `ls`, `bash`, `edit`, `write`) and
26
+ extension tools coexist with no policy distinguishing **preferred** from
27
+ **fallback**.
28
+ - There is no concept of "deny native `grep` when GitNexus is loaded" —
29
+ explorer can still reach for `grep` instead of `gitnexus_query`.
30
+ - Specialists cannot override tier policy without forking the JSON config or
31
+ hacking `excludeExtensions`.
32
+ - There is no `sp config show <name> --resolved` to debug what a specialist
33
+ *actually* gets at runtime.
34
+
35
+ This design fixes all four.
36
+
37
+ ---
38
+
39
+ ## 1. Evidence — current state
40
+
41
+ > Evidence was gathered from this pi harness, `src/pi/session.ts`, and the
42
+ > installed `pi-gitnexus` / `pi-serena-tools` packages.
43
+
44
+ ### 1.1 Native tool universe
45
+
46
+ The specialist runtime's native tier universe is exactly the seven names listed
47
+ in `src/pi/session.ts:225-231`:
48
+
49
+ - READ_ONLY native tools: `read`, `grep`, `find`, `ls`
50
+ - LOW adds: `bash`
51
+ - MEDIUM adds: `edit`
52
+ - HIGH adds: `write`
53
+
54
+ This pi harness also exposes orchestration/admin tools to the top-level agent
55
+ outside the specialist permission map (`process`, `structured_return`, `mcp`,
56
+ `interactive_shell`, plus `multi_tool_use.parallel`). Those are not part of
57
+ `mapPermissionToTools` and should not be treated as native specialist tools
58
+ unless a future catalog explicitly models harness-only capabilities.
59
+
60
+ Behavior observed in this session: native `grep` and `bash` are callable even
61
+ while GitNexus and Serena are loaded; native `read` is currently blocked by the
62
+ harness with `Tool 'read' is disabled. Use Serena tools instead.` That block is
63
+ visible to the agent as a normal tool error, not silently hidden.
64
+
65
+ ### 1.2 Serena tool universe (via `pi-serena-tools` extension)
66
+
67
+ `pi-serena-tools` registers these 43 tools in
68
+ `pi-serena-tools/serenaTools.ts:25-695`:
69
+
70
+ - Meta / lifecycle: `serena_list_tools`, `get_current_config`,
71
+ `activate_project`, `remove_project`, `switch_modes`, `open_dashboard`,
72
+ `check_onboarding_performed`, `onboarding`, `initial_instructions`,
73
+ `prepare_for_new_conversation`, `summarize_changes`,
74
+ `think_about_collected_information`, `think_about_task_adherence`,
75
+ `think_about_whether_you_are_done`, `serena_mcp_reset`
76
+ - Symbol/navigation: `find_symbol`, `find_referencing_symbols`, `read_file`,
77
+ `get_symbols_overview`, `jet_brains_get_symbols_overview`,
78
+ `jet_brains_find_symbol`, `jet_brains_find_referencing_symbols`,
79
+ `jet_brains_type_hierarchy`, `search_for_pattern`, `list_dir`, `find_file`
80
+ - Writes/refactors: `insert_after_symbol`, `replace_symbol_body`,
81
+ `insert_before_symbol`, `rename_symbol`, `create_text_file`,
82
+ `replace_content`, `delete_lines`, `replace_lines`, `insert_at_line`,
83
+ `restart_language_server`
84
+ - Shell: `execute_shell_command`
85
+ - Memory: `read_memory`, `write_memory`, `list_memories`, `delete_memory`,
86
+ `rename_memory`, `edit_memory`
87
+
88
+ Comparison with `src/pi/session.ts:164-214`: no drift in tool *names*. The
89
+ source map contains the same 43 names split as 21 READ_ONLY, 1 LOW, and 21
90
+ WRITE tools. The split is policy, not package capability: the extension
91
+ registers the whole surface; `--tools` chooses which names are
92
+ advertised/allowed.
93
+
94
+ The capability-taxonomy grouping above (Meta / Symbol-nav / Writes / Shell /
95
+ Memory) is *not* the same axis as source's READ/LOW/WRITE tier-allowlist
96
+ grouping. The source treats anything that mutates Serena state — including
97
+ admin/lifecycle ops and memory mutators — as WRITE-tier, not READ-tier.
98
+ Capability taxonomy is for manifest design (§2-3); the table below is the
99
+ authoritative source-tier assignment per tool.
100
+
101
+ #### 1.2.1 Source-tier cross-reference
102
+
103
+ Tools where the doc's capability-group differs from the source-tier are
104
+ flagged ⚠. They remain mutating ops in source policy regardless of
105
+ capability label; the design must preserve the source split in default
106
+ output (§7 step 2: byte-equivalent snapshot tests).
107
+
108
+ | Tool | Doc group | Source tier (`pi/session.ts:164-214`) | Note |
109
+ |------|-----------|---------------------------------------|------|
110
+ | `serena_list_tools` | Meta | READ_ONLY | |
111
+ | `get_current_config` | Meta | READ_ONLY | |
112
+ | `activate_project` | Meta | READ_ONLY | |
113
+ | `check_onboarding_performed` | Meta | READ_ONLY | |
114
+ | `initial_instructions` | Meta | READ_ONLY | |
115
+ | `think_about_collected_information` | Meta | READ_ONLY | |
116
+ | `think_about_task_adherence` | Meta | READ_ONLY | |
117
+ | `think_about_whether_you_are_done` | Meta | READ_ONLY | |
118
+ | `remove_project` | Meta | **WRITE** | ⚠ admin/lifecycle treated as mutation |
119
+ | `switch_modes` | Meta | **WRITE** | ⚠ admin/lifecycle |
120
+ | `open_dashboard` | Meta | **WRITE** | ⚠ admin/lifecycle |
121
+ | `onboarding` | Meta | **WRITE** | ⚠ admin/lifecycle |
122
+ | `prepare_for_new_conversation` | Meta | **WRITE** | ⚠ admin/lifecycle |
123
+ | `summarize_changes` | Meta | **WRITE** | ⚠ admin/lifecycle |
124
+ | `serena_mcp_reset` | Meta | **WRITE** | ⚠ admin/lifecycle |
125
+ | `find_symbol` | Symbol/nav | READ_ONLY | |
126
+ | `find_referencing_symbols` | Symbol/nav | READ_ONLY | |
127
+ | `read_file` | Symbol/nav | READ_ONLY | |
128
+ | `get_symbols_overview` | Symbol/nav | READ_ONLY | |
129
+ | `jet_brains_get_symbols_overview` | Symbol/nav | READ_ONLY | |
130
+ | `jet_brains_find_symbol` | Symbol/nav | READ_ONLY | |
131
+ | `jet_brains_find_referencing_symbols` | Symbol/nav | READ_ONLY | |
132
+ | `jet_brains_type_hierarchy` | Symbol/nav | READ_ONLY | |
133
+ | `search_for_pattern` | Symbol/nav | READ_ONLY | |
134
+ | `list_dir` | Symbol/nav | READ_ONLY | |
135
+ | `find_file` | Symbol/nav | READ_ONLY | |
136
+ | `execute_shell_command` | Shell | LOW | |
137
+ | `insert_after_symbol` | Writes | WRITE | |
138
+ | `replace_symbol_body` | Writes | WRITE | |
139
+ | `insert_before_symbol` | Writes | WRITE | |
140
+ | `rename_symbol` | Writes | WRITE | |
141
+ | `restart_language_server` | Writes | WRITE | mutates LSP state |
142
+ | `create_text_file` | Writes | WRITE | |
143
+ | `replace_content` | Writes | WRITE | |
144
+ | `delete_lines` | Writes | WRITE | |
145
+ | `replace_lines` | Writes | WRITE | |
146
+ | `insert_at_line` | Writes | WRITE | |
147
+ | `list_memories` | Memory | READ_ONLY | |
148
+ | `read_memory` | Memory | READ_ONLY | |
149
+ | `write_memory` | Memory | **WRITE** | ⚠ memory mutator |
150
+ | `delete_memory` | Memory | **WRITE** | ⚠ memory mutator |
151
+ | `rename_memory` | Memory | **WRITE** | ⚠ memory mutator |
152
+ | `edit_memory` | Memory | **WRITE** | ⚠ memory mutator |
153
+
154
+ Implication for §3 tier capabilities: `memory` capability cannot be a
155
+ single bucket. It must split into `memory.read` (READ_ONLY+) and
156
+ `memory.write` (WRITE+). The same applies to `admin.serena` — must split
157
+ into read-only meta probes (config/onboarding/think_*) and lifecycle
158
+ mutators (remove_project/switch_modes/open_dashboard/onboarding/
159
+ prepare_for_new_conversation/summarize_changes/serena_mcp_reset).
160
+
161
+ ### 1.3 GitNexus tool universe (via `pi-gitnexus` extension)
162
+
163
+ `pi-gitnexus` registers seven tools in
164
+ `pi-gitnexus/dist/tools.js:86-216`:
165
+
166
+ - READ/analyze: `gitnexus_list_repos`, `gitnexus_query`, `gitnexus_context`,
167
+ `gitnexus_impact`, `gitnexus_detect_changes`
168
+ - WRITE/refactor/admin: `gitnexus_rename`, `gitnexus_cypher`
169
+
170
+ Comparison with `src/pi/session.ts:156-219`: no drift found. The READ array
171
+ contains the first five names, and the WRITE array contains `gitnexus_rename`
172
+ and `gitnexus_cypher`. `gitnexus_query` and `gitnexus_detect_changes` both
173
+ worked in this pi session against the indexed `specialists` repo.
174
+
175
+ ### 1.4 Other extensions observed
176
+
177
+ Source extension loading in `src/pi/session.ts:650-672` currently adds:
178
+
179
+ - directory extension `service-skills` if present under pi's extension dir;
180
+ - directory extension `caveman` if present;
181
+ - npm package extension `pi-gitnexus` if installed and not excluded;
182
+ - npm package extension `pi-serena-tools` if installed and not excluded.
183
+
184
+ In this environment, global npm packages include `pi-gitnexus`,
185
+ `pi-serena-tools`, `pi-interactive-shell`, and `context-mode`. The specialist
186
+ runtime only auto-loads the first two via `src/pi/session.ts:657-672`.
187
+ `pi-interactive-shell` registers `interactive_shell` in its own extension
188
+ (`pi-interactive-shell/index.ts:1072`), but it is top-level harness tooling, not
189
+ part of specialist tier policy. Quality gates in this repo are Claude/pi hooks
190
+ (`.claude/hooks/quality-check.cjs`, `.claude/hooks/quality-check.py`, and
191
+ `.xtrm/hooks/*`), not a pi tool namespace in `mapPermissionToTools`.
192
+
193
+ ### 1.5 Current tier→tool mapping (from source)
194
+
195
+ | Tier | Native | Serena | GitNexus | Notes |
196
+ |------|--------|--------|----------|-------|
197
+ | READ_ONLY | read, grep, find, ls | SERENA_READ_TOOLS (~21) | GITNEXUS_READ_TOOLS (5) | no bash, no writes |
198
+ | LOW | + bash | + SERENA_LOW_TOOLS (execute_shell_command) | (same) | inspect/run, no edits |
199
+ | MEDIUM | + edit | + SERENA_WRITE_TOOLS (~20) | + GITNEXUS_WRITE_TOOLS (rename, cypher) | edit existing files |
200
+ | HIGH | + write | (same) | (same) | full access |
201
+
202
+ > Source: `src/pi/session.ts:225-243` (`mapPermissionToTools`).
203
+
204
+ ### 1.6 Behavioral evidence
205
+
206
+ Observed directly in this pi session:
207
+
208
+ - Native and extension tools coexist. A native `grep` command against
209
+ `src/pi/session.ts` succeeded while GitNexus was loaded; GitNexus then added
210
+ related-symbol context after the grep output. Nothing prevented the native
211
+ search path.
212
+ - Native `read` was visible enough to call, but the harness returned a visible
213
+ error: `Tool 'read' is disabled. Use Serena tools instead.` This proves a
214
+ hard-deny can be surfaced as an explicit tool error to the agent.
215
+ - Serena calls (`read_file`, `serena_list_tools`) succeeded, but the current
216
+ pi UI summarized some Serena results instead of printing full payloads. For
217
+ exact package evidence, source inspection of `pi-serena-tools/serenaTools.ts`
218
+ was more reliable.
219
+ - GitNexus health in this repo is good: `gitnexus_list_repos`,
220
+ `gitnexus_query`, and `gitnexus_detect_changes` are callable. `pi-gitnexus`
221
+ implements a missing-index guard in `dist/tools.js:10-104`: when no repo
222
+ override is provided and no index is found under cwd, read/query tools return
223
+ the visible text `No GitNexus index found. Run: /gitnexus analyze`.
224
+ - Extension packages that are not installed are silently skipped by
225
+ `src/pi/session.ts:657-672`; there is no startup warning in the current code.
226
+ - Serena LSP/index failure behavior is tool-level, not startup-level: the
227
+ extension registers tools up front, then individual tool calls route through
228
+ the Serena MCP client. The design should treat this as `loaded_unhealthy`
229
+ when probes fail, not as `not_installed`.
230
+
231
+ ---
232
+
233
+ ## 2. Capability axes
234
+
235
+ Tools should be classified by *what they do*, not which package they came
236
+ from. Proposed capability tags:
237
+
238
+ | Capability | Description | Examples |
239
+ |------------|-------------|----------|
240
+ | `read` | Open and emit file contents | native `read`, serena `read_file` |
241
+ | `search.text` | Lexical/regex search across files | native `grep`, serena `search_for_pattern` |
242
+ | `search.symbol` | Symbol-aware code search | serena `find_symbol`, gitnexus `gitnexus_context` |
243
+ | `analyze.graph` | Call graph / impact / process flows | gitnexus `gitnexus_impact`, `gitnexus_query`, `gitnexus_detect_changes` |
244
+ | `analyze.refs` | Find references to a symbol | serena `find_referencing_symbols` |
245
+ | `nav.fs` | Filesystem listing/finding | native `ls`, `find`, serena `list_dir`, `find_file` |
246
+ | `shell` | Execute arbitrary commands | native `bash`, serena `execute_shell_command` |
247
+ | `write.text` | Edit existing files (line/text scope) | native `edit`, serena `replace_content`, `replace_lines` |
248
+ | `write.symbol` | Symbol-aware edits | serena `replace_symbol_body`, `insert_after_symbol` |
249
+ | `write.create` | Create new files | native `write`, serena `create_text_file` |
250
+ | `mutate.rename` | Project-wide rename | serena `rename_symbol`, gitnexus `gitnexus_rename` |
251
+ | `mutate.graph` | Mutate the graph store | gitnexus `gitnexus_cypher` (when used as write) |
252
+ | `admin.serena.read` | Read-only Serena meta probes | `get_current_config`, `check_onboarding_performed`, `initial_instructions`, `think_about_*` |
253
+ | `admin.serena.write` | Serena lifecycle mutators | `restart_language_server`, `serena_mcp_reset`, `switch_modes`, `remove_project`, `open_dashboard`, `onboarding`, `prepare_for_new_conversation`, `summarize_changes` |
254
+ | `memory.read` | Serena memory readers | `read_memory`, `list_memories` |
255
+ | `memory.write` | Serena memory mutators | `write_memory`, `delete_memory`, `rename_memory`, `edit_memory` |
256
+ | `meta` | Self-introspection | `serena_list_tools`, `gitnexus_list_repos` |
257
+
258
+ > Decision: model `memory` as a normal READ_ONLY+ capability. It is currently
259
+ > available whenever `pi-serena-tools` is loaded, but explicit cataloging keeps
260
+ > it visible in `sp config show --resolved` and allows future denial if needed.
261
+
262
+ ---
263
+
264
+ ## 3. Tier policy
265
+
266
+ A tier is **a set of capability tags** plus **deny rules**. Concrete tools are
267
+ derived from `(catalog filter capabilities ∩ tier.capabilities) − tier.denied`.
268
+
269
+ ### 3.0 Precedence and conflict resolution
270
+
271
+ Six layers can each express an opinion on a single tool. The resolver merges
272
+ them in this fixed order, lowest-to-highest precedence:
273
+
274
+ 1. **Catalog metadata** — tool exists, capabilities declared.
275
+ 2. **Default tier policy** — `READ_ONLY/LOW/MEDIUM/HIGH` capability sets and
276
+ denied-natives rules.
277
+ 3. **Project manifest tier overrides** — `permissions.<TIER>` block in
278
+ `.specialists/config.json`.
279
+ 4. **Specialist manifest overrides** — `specialists.<name>` block in
280
+ `.specialists/config.json`.
281
+ 5. **Specialist JSON availability** — `execution.extensions.{serena,gitnexus}`,
282
+ `execution.permission` in `config/specialists/<name>.specialist.json`.
283
+ 6. **Runtime health downgrade** — health probes can downgrade `hard` →
284
+ `soft` and restore native fallbacks.
285
+
286
+ Conflict rules:
287
+
288
+ - **Most restrictive wins** for tool inclusion (any layer that denies a tool
289
+ removes it).
290
+ - **Exception:** runtime health degradation (layer 6) **restores** native
291
+ fallbacks even if higher layers denied them, because availability of a
292
+ replacement is the precondition for denying its native equivalent.
293
+ - Hard-deny in layer 4 (specialist override) does **not** override layer 6
294
+ health. If GitNexus is `loaded_unhealthy`, explorer's `hard-deny grep` is
295
+ downgraded to `soft` until GitNexus recovers.
296
+ - Layer attribution is preserved through resolution. `sp config show
297
+ --resolved` (§6) prints which layer set each final value.
298
+
299
+ Inspired by Gemini CLI's `PolicyEngine` priority tiers
300
+ (`packages/core/src/policy/policy.ts`); see `gzrx-research-notes.md`.
301
+
302
+ ### 3.1 Proposed tier capability sets
303
+
304
+ Default policy must be backward-compatible: if no catalog/manifest is present,
305
+ `mapPermissionToTools` output remains byte-for-byte equivalent to
306
+ `src/pi/session.ts:225-243`. The capability policy below is the manifest-driven
307
+ replacement target:
308
+
309
+ ```yaml
310
+ READ_ONLY:
311
+ capabilities:
312
+ - read
313
+ - search.text
314
+ - search.symbol
315
+ - analyze.graph
316
+ - analyze.refs
317
+ - nav.fs
318
+ - memory.read
319
+ - admin.serena.read
320
+ - meta
321
+ denied_natives_when_extension:
322
+ read: [read_file]
323
+ grep: [gitnexus_query, search_for_pattern]
324
+ find: [find_file]
325
+ ls: [list_dir]
326
+ denied_natives_mode: soft
327
+
328
+ LOW:
329
+ inherits: READ_ONLY
330
+ capabilities: [shell]
331
+ denied_natives_when_extension: same-as-READ_ONLY
332
+ # Keep native bash by default. Serena execute_shell_command is useful but not
333
+ # proven equivalent for cwd/env/TTY behavior.
334
+
335
+ MEDIUM:
336
+ inherits: LOW
337
+ capabilities:
338
+ - write.text
339
+ - write.symbol
340
+ - mutate.rename
341
+ - admin.serena.write # restart_language_server, serena_mcp_reset, switch_modes,
342
+ # remove_project, open_dashboard, onboarding,
343
+ # prepare_for_new_conversation, summarize_changes
344
+ - memory.write # write_memory, delete_memory, rename_memory, edit_memory
345
+ denied_natives_when_extension:
346
+ edit: [replace_content, replace_lines, replace_symbol_body]
347
+ denied_natives_mode: soft
348
+
349
+ HIGH:
350
+ inherits: MEDIUM
351
+ capabilities:
352
+ - write.create
353
+ - mutate.graph
354
+ denied_natives_when_extension:
355
+ write: [create_text_file]
356
+ denied_natives_mode: soft
357
+ ```
358
+
359
+ The `memory.write` and `admin.serena.write` capabilities are gated to MEDIUM+
360
+ because their tools live in `SERENA_WRITE_TOOLS` per source policy. Promoting
361
+ them to READ_ONLY would be a behavior change and must not happen by default.
362
+ The byte-equivalent snapshot test in §7 step 2 enforces this.
363
+
364
+ Specialists can opt into harder policy. Recommended first override:
365
+ `explorer.denied_natives_mode = hard` for `grep`, `find`, and `ls` while keeping
366
+ `read` soft until Serena `read_file` output behavior is verified across large
367
+ files and non-code files.
368
+
369
+ Rollout note: explorer hard-deny is isolated in specialist permissions only. Revert by
370
+ removing explorer permissions block; generic deny engine stays unchanged.
371
+
372
+ ### 3.2 "Denied native when extension available" semantics
373
+
374
+ This is the core behavioral change. The explorer-uses-grep problem stems from
375
+ the runtime exposing both `grep` and `gitnexus_query` with no preference
376
+ signal.
377
+
378
+ Two enforcement options:
379
+
380
+ 1. **Hard deny** — strip `grep` from `--tools` when pi-gitnexus is loaded.
381
+ Problem: GitNexus index may be stale and the agent has no fallback.
382
+ 2. **Soft deny via prompt** — both tools available; system-prompt instruction
383
+ tells the agent to prefer GitNexus and reach for grep only on stale-index
384
+ warnings or when scope is outside the indexed tree.
385
+
386
+ Recommended: **soft deny by default, with hard-deny opt-in** per tier. The
387
+ manifest exposes both modes.
388
+
389
+ ### 3.3 Fallback behavior
390
+
391
+ Extension state is **per-capability**, not extension-wide on/off. A single
392
+ extension can have some capabilities healthy and others degraded
393
+ simultaneously (Serena LSP partial outage; GitNexus stale-but-callable).
394
+
395
+ Per-capability state machine:
396
+
397
+ | State | Meaning | Policy |
398
+ |-------|---------|--------|
399
+ | `not_installed` | package/extension path absent | warn in `--resolved`; remove its tools; do not deny native fallbacks |
400
+ | `disabled` | specialist JSON or project manifest excludes it | show disabled source; remove its tools; do not deny native fallbacks |
401
+ | `loaded_healthy` | extension registered and capability probe passed | apply preferred/denied-native policy |
402
+ | `loaded_degraded` | capability probe partially failed (e.g. some Serena tools work, others don't) | keep tools; downgrade hard-deny → soft for affected capabilities; print warning |
403
+ | `loaded_unhealthy` | capability probe failed completely | keep tools if self-recovery possible; downgrade hard-deny → soft; print warning |
404
+ | `version_mismatch` | package installed but version drifts from catalog | treat as `loaded_degraded`; emit catalog-drift warning; defer to drift policy (§6.1) |
405
+
406
+ Specifics:
407
+
408
+ - **GitNexus missing index:** `pi-gitnexus` returns visible text
409
+ `No GitNexus index found. Run: /gitnexus analyze`. Treat as
410
+ `loaded_unhealthy` for `analyze.graph` and `search.symbol` capabilities.
411
+ Native `grep`/`find` remain available unless the specialist explicitly sets
412
+ `fallback_on_extension_failure: error`.
413
+ - **GitNexus stale-but-callable index:** if a tool returns a stale-index
414
+ warning but still produces output, classify as `loaded_degraded` for the
415
+ affected capability. Keep graph tools, add prompt-visible warning, allow
416
+ native fallback for that turn. Do not promote to `loaded_unhealthy` —
417
+ callable-with-warning is materially different from unusable.
418
+ - **Serena LSP offline:** per-capability probes (not extension-wide). Probe
419
+ `find_symbol` for `search.symbol`; probe `read_file` for `read`; probe
420
+ `replace_symbol_body` for `write.symbol`. Each capability gets its own
421
+ state. Native `read`/`grep`/`find`/`ls`/`edit` are not hard-denied while any
422
+ Serena capability is `loaded_unhealthy` or `loaded_degraded`.
423
+ - **Package not installed:** current code silently skips packages via
424
+ `existsSync(...)` in `src/pi/session.ts:657-672`. New resolver makes that
425
+ visible in `sp config show --resolved` and emits a single startup line. Does
426
+ not fail session start unless manifest says
427
+ `fallback_on_extension_failure: error`.
428
+ - **Package version mismatch:** if an installed extension's manifest version
429
+ drifts from the catalog file's `expected_version`, treat as
430
+ `version_mismatch`. Drift detection (§6.1) decides whether to warn-only or
431
+ hard-fail per project policy.
432
+
433
+ ---
434
+
435
+ ## 4. Tool catalog schema
436
+
437
+ Stored at `.specialists/catalog/{native,serena,gitnexus}.json` (or single
438
+ `catalog.json` keyed by source). Editable by hand; loaded at session start.
439
+
440
+ ```json
441
+ {
442
+ "version": 1,
443
+ "source": "pi-gitnexus",
444
+ "tools": [
445
+ {
446
+ "name": "gitnexus_query",
447
+ "capabilities": ["search.symbol", "analyze.graph"],
448
+ "preferred_over": ["grep"],
449
+ "stale_index_behavior": "warn",
450
+ "description": "Find code by concept; returns process-grouped results."
451
+ },
452
+ {
453
+ "name": "gitnexus_impact",
454
+ "capabilities": ["analyze.graph"],
455
+ "description": "Blast radius for a symbol."
456
+ }
457
+ ]
458
+ }
459
+ ```
460
+
461
+ Native tools live in `.specialists/catalog/native.json` shipped with the
462
+ package; extensions can declare their own catalog file in their npm package
463
+ root (`pi-catalog.json`) which the runtime merges.
464
+
465
+ ---
466
+
467
+ ## 5. Manifest extension (on top of existing overthinker design)
468
+
469
+ The existing manifest schema (in `unitAI-gzrx` description) defines:
470
+
471
+ ```json
472
+ "permissions": {
473
+ "READ_ONLY": {
474
+ "extensions": { "mode": "none|allowlist", "allowlist": [...] },
475
+ ...
476
+ }
477
+ }
478
+ ```
479
+
480
+ This is **incomplete** — it specifies extension *availability* but not
481
+ tier *capabilities* or *denied natives*. Extend to:
482
+
483
+ ```json
484
+ "permissions": {
485
+ "READ_ONLY": {
486
+ "capabilities": ["read", "search.text", "search.symbol", ...],
487
+ "denied_natives_when_extension": ["grep", "find", "ls", "read"],
488
+ "denied_natives_mode": "soft|hard",
489
+ "extensions": { "mode": "allowlist", "allowlist": ["pi-gitnexus", "pi-serena-tools"] },
490
+ "fallback_on_extension_failure": "warn|error|silent",
491
+ "beads": { "can_close": false },
492
+ "behavior": { "auto_append_output_to_bead": true }
493
+ }
494
+ }
495
+ ```
496
+
497
+ Per-specialist override extends the same shape:
498
+
499
+ ```json
500
+ "specialists": {
501
+ "explorer": {
502
+ "denied_natives_mode": "hard"
503
+ }
504
+ }
505
+ ```
506
+
507
+ ---
508
+
509
+ ### 5.1 Drift detection
510
+
511
+ Hand-edited JSON catalogs drift from the live extension surface. The resolver
512
+ runs a startup drift check:
513
+
514
+ - For each catalog entry, verify the tool name still exists in the loaded
515
+ extension's registered tool set.
516
+ - For each loaded extension tool, verify it exists in the catalog (warn on
517
+ unknown tools).
518
+ - Compare catalog `expected_version` against the installed package version.
519
+
520
+ Drift policy is set per project in manifest:
521
+
522
+ ```json
523
+ "drift_policy": {
524
+ "mode": "warn|error|ignore",
525
+ "downgrade_hard_deny_on_drift": true
526
+ }
527
+ ```
528
+
529
+ Default `warn`: log to `--resolved` output, downgrade affected hard-denies to
530
+ soft. `error` fails session start. Drift is not the same as `version_mismatch`
531
+ on a single package — drift is a catalog↔extension shape mismatch.
532
+
533
+ ---
534
+
535
+ ## 6. Resolved-debug surface
536
+
537
+ `sp config show <name> --resolved` must print:
538
+
539
+ 1. Effective manifest (defaults + tier policy + specialist override merged).
540
+ 2. Tier policy file path used.
541
+ 3. Extension availability (loaded / not installed / disabled).
542
+ 4. Final `--tools` string passed to pi.
543
+ 5. Native tools denied (with reason: which extension preempts each).
544
+ 6. Per-layer attribution: which value came from which precedence layer.
545
+
546
+ Sample output sketch:
547
+
548
+ ```
549
+ specialist: explorer
550
+ permission_required: READ_ONLY
551
+ sources:
552
+ manifest_defaults: .specialists/config.json
553
+ tier_policy: .specialists/config.json#permissions.READ_ONLY
554
+ specialist_override: .specialists/config.json#specialists.explorer
555
+ specialist_json: config/specialists/explorer.specialist.json
556
+
557
+ extensions:
558
+ pi-gitnexus loaded (via npm global)
559
+ pi-serena-tools loaded (via npm global)
560
+ quality-gates disabled (tier disallows)
561
+
562
+ capabilities (effective):
563
+ read, search.text, search.symbol, analyze.graph, analyze.refs,
564
+ nav.fs, memory, meta
565
+
566
+ natives denied (mode=hard, source=specialist override):
567
+ grep -> preempted by gitnexus_query, search_for_pattern
568
+ find -> preempted by find_file
569
+ ls -> preempted by list_dir
570
+ read -> preempted by read_file (serena)
571
+
572
+ --tools (effective):
573
+ gitnexus_query,gitnexus_context,gitnexus_impact,gitnexus_detect_changes,
574
+ gitnexus_list_repos,find_symbol,find_referencing_symbols,read_file,
575
+ get_symbols_overview,search_for_pattern,list_dir,find_file,
576
+ list_memories,read_memory,serena_list_tools,...
577
+
578
+ behavior:
579
+ auto_append_output_to_bead: true (from tier READ_ONLY)
580
+ ```
581
+
582
+ ---
583
+
584
+ ## 7. Migration plan
585
+
586
+ This ordering is the post-overthinker revision. The original §7 placed runtime
587
+ threading before resolved-debug; that order made the resolver impossible to
588
+ diagnose in production. Resolved-debug and per-capability health probes now
589
+ land **before** runtime threading.
590
+
591
+ Each behavior-changing step has explicit abort criteria. If any criterion
592
+ fires, halt the migration and resolve the regression before continuing.
593
+
594
+ 1. **Specify precedence in design + code comments.** Document the six-layer
595
+ precedence (§3.0) as a header comment in `src/specialist/manifest.ts` and
596
+ in inline commentary on the resolver entry point. No code behavior yet.
597
+
598
+ 2. **Add catalog files + JSON schema validation.**
599
+ - `.specialists/catalog/native.json`
600
+ - `.specialists/catalog/serena.json`
601
+ - `.specialists/catalog/gitnexus.json`
602
+ - Validate tool names, capabilities, source-tier, package/version metadata.
603
+ - Optional package-side `pi-catalog.json` discovery is **deferred** — first
604
+ PR ships hand-edited JSON only.
605
+ - **Abort if** catalog schema fails or any catalog tool's source-tier
606
+ differs from the §1.2.1/§1.3 cross-reference.
607
+
608
+ 3. **Implement resolver as a pure library** (`src/specialist/manifest.ts` or
609
+ `tool-manifest.ts`). Inputs: tier, catalogs, manifest, specialist override,
610
+ specialist exclusions, extension state. Outputs: final `--tools`, denied natives
611
+ with reason, warnings, per-layer attribution. **No `src/pi/session.ts`
612
+ threading yet.**
613
+
614
+ 4. **Tests before integration:**
615
+ - Byte-equivalence snapshots for `READ_ONLY/LOW/MEDIUM/HIGH` (default
616
+ config) vs current `mapPermissionToTools` output.
617
+ - Matrix tests across **(tier × extension health × specialist override ×
618
+ specialist exclusion)**. Per-tier snapshots alone do not catch interaction
619
+ bugs.
620
+ - Invariants:
621
+ - Soft mode never changes final `--tools`.
622
+ - Hard mode restores natives when replacement capability is
623
+ `loaded_unhealthy`, `loaded_degraded`, `version_mismatch`, or unknown.
624
+ - **Abort if** any default tier output differs byte-for-byte from legacy.
625
+
626
+ 5. **Add `sp config show <specialist> --resolved`** in `src/cli/config.ts`.
627
+ Must use the **same** resolver library as the future runtime path. Print
628
+ effective manifest, per-layer attribution, per-capability extension
629
+ health, catalog drift, hard-deny downgrades, denied natives with reason,
630
+ final `--tools`. **Abort if** any tool inclusion/exclusion lacks layer
631
+ attribution.
632
+
633
+ 6. **Add per-capability health probes + drift detection.**
634
+ - GitNexus: missing index, stale-but-callable, callable/degraded.
635
+ - Serena: per-capability probes (`search.symbol`, `read`, `write.symbol`,
636
+ etc.), not extension-wide on/off.
637
+ - Package version vs catalog `expected_version`.
638
+ - Catalog↔extension shape drift (§5.1).
639
+ - Drift or degraded forces hard-deny → soft (per layer 6 in §3.0).
640
+ - **Abort if** drift detector cannot distinguish `loaded_degraded` from
641
+ `loaded_unhealthy`.
642
+
643
+ 7. **Thread resolver into `src/pi/session.ts`** behind a feature flag.
644
+ Flag-off = legacy hardcoded arrays. Flag-on + default config =
645
+ byte-equivalent to legacy. Keep hardcoded arrays as fallback for one
646
+ release. **Abort if** flag-off output differs from legacy in any tier.
647
+
648
+ 8. **Enable `denied_natives_when_extension` in soft mode** for all tiers.
649
+ Tools remain callable; prompts and resolved-debug output express
650
+ preferences. **Abort if** soft mode changes final `--tools` for any tier.
651
+
652
+ 9. **Add hard-deny support in resolver.** Verify natives are removed from
653
+ `--tools` when replacement capability is healthy, and restored when
654
+ unhealthy/degraded/unknown/catalog-incompatible. **Abort if** natives are
655
+ not restored on any unhealthy state.
656
+
657
+ 10. **Enable explorer hard-deny for `grep`/`find`/`ls`.** Keep `read` soft
658
+ pending Serena `read_file` large-file and non-code verification. Gated on
659
+ healthy GitNexus + Serena replacements. Monitor via `--resolved` output
660
+ for one week minimum.
661
+
662
+ 11. **Remove old hardcoded arrays** from `src/pi/session.ts`. **Abort until**
663
+ one release has shipped with parity verified and resolved-debug output
664
+ available in production.
665
+
666
+ ### 7.1 Defer to follow-up beads
667
+
668
+ - Package-side `pi-catalog.json` discovery for arbitrary extensions.
669
+ - Catalog codegen from extension source (first PR ships hand JSON + drift
670
+ detector; codegen is a separate optimization).
671
+ - Full migration of this design to `docs/manifest.md` and cross-link from
672
+ `docs/cli-reference.md`.
673
+ - Hard-deny `read` (waits on Serena large-file/non-code verification).
674
+ - Per-tool health beyond the minimum per-capability probes in step 6.
675
+
676
+ ---
677
+
678
+ ## 8. Open questions and decisions
679
+
680
+ 1. `bash` and `execute_shell_command` should not be marked equivalent yet.
681
+ They share the `shell` capability, but native `bash` is the proven specialist
682
+ LOW-tier tool and may differ in cwd/env/output handling. Keep both when both
683
+ are allowed; prefer native `bash` for operator commands.
684
+ 2. Pi's `--tools` should be treated as an allowlist contract. This session
685
+ showed denied native `read` failing visibly at call time, so hard deny is
686
+ observable to the agent rather than silent. The design should still verify
687
+ this with a specialist subprocess test during implementation.
688
+ 3. Native-tool blocking is visible as a tool error in this harness. That is
689
+ acceptable for hard-deny mode, but the error text should name the preferred
690
+ replacement tool.
691
+ 4. `serena_list_tools` is a meta tool and may report the Serena server's full
692
+ surface rather than the current `--tools` allowlist. `sp config show
693
+ --resolved` must therefore be the authoritative debug surface for effective
694
+ tool access.
695
+ 5. Keep `meta` tools on for READ_ONLY+ by default. They are essential for
696
+ debugging loaded/unhealthy extension states. If security becomes a concern,
697
+ add a separate `meta` deny list rather than hiding them implicitly.
698
+ 6. `loaded_degraded` vs `loaded_unhealthy` boundary is sometimes fuzzy
699
+ (e.g. GitNexus index present but 30+ days stale). Default rule: a tool that
700
+ still returns useful output with a warning is `loaded_degraded`; a tool
701
+ that errors or returns "unavailable" text is `loaded_unhealthy`. Drift
702
+ detector (§5.1) escalation policy refines this per project.
703
+ 7. `version_mismatch` policy default: `warn-only` for catalog-vs-package skew
704
+ on minor/patch; `error` on major skew. Manifest can override per
705
+ extension. Concrete thresholds to be set during step 6 of §7.
706
+
707
+ ### 8.1 Resolved by the post-overthinker revision
708
+
709
+ Items previously open or under-specified that are now closed:
710
+
711
+ - **Precedence order across the six layers** — locked in §3.0.
712
+ - **Per-capability health vs extension-wide** — §3.3 splits state into
713
+ per-capability with explicit `loaded_degraded`.
714
+ - **Drift between hand-edited catalog and live extension surface** — §5.1
715
+ adds startup drift detection with project-level policy.
716
+ - **Order of `--resolved` debug surface vs runtime threading** — §7 step 5
717
+ lands resolved-debug *before* step 7 runtime threading. Original §7 had
718
+ this reversed and would have shipped a resolver with no diagnostic surface.
719
+ - **Snapshot-only test sufficiency** — §7 step 4 requires the
720
+ (tier × health × override × specialist exclusion) matrix; per-tier snapshots alone are
721
+ insufficient.
722
+ - **Soft-vs-hard deny effectiveness** — §3.2 + §7 step 8/9 split: soft
723
+ is preference/debug only and does not change `--tools`; hard is the only
724
+ mode that fixes the explorer-grep problem, gated on replacement health.
725
+
726
+ ---
727
+
728
+ ## 9. Non-goals
729
+
730
+ - No change to specialist JSON schema (`*.specialist.json`) for `model`,
731
+ `prompt`, `output_schema`, metadata.
732
+ - No replacement of the JSON-as-identity model. Manifest is overlay.
733
+ - No new CLI surface beyond `sp config show <name> --resolved` and the
734
+ catalog files.
735
+ - No change to mandatory rules system or beads context loading.
736
+
737
+ ---
738
+
739
+ ## 10. References
740
+
741
+ - `docs/design/gzrx-research-notes.md` — survey of pi-mono, Gemini CLI, Claude
742
+ Code, VS Code, Aider, OpenHands. Source of the precedence-engine pattern
743
+ (Gemini `PolicyEngine`), per-capability health model (Gemini
744
+ `McpClientManager`), and extension-prefixed tool naming (VS Code
745
+ `extensionPrefixedIdentifier`).
746
+ - Bead `unitAI-gzrx` — original design bead (closed).
747
+ - Bead `unitAI-6b821` — researcher chain (closed).
748
+ - Bead `unitAI-o6icy` — overthinker critique that produced the §7 reorder,
749
+ precedence rules, per-capability health, drift detection, and abort
750
+ criteria (closed).
751
+ - Bead `unitAI-8vb65` — implementation bead carrying the same refined
752
+ ordering as the in-doc §7. Notes mirror this doc; the doc is canonical.
753
+
754
+ ---
755
+
756
+ ## 11. Drift policy for this document
757
+
758
+ If §7 ordering or abort criteria change, update this doc **first**, then
759
+ sync `unitAI-8vb65` notes. The bead notes are a copy; the doc is canonical.
760
+ Any executor work that diverges from §7 must amend the doc in the same PR.