@jaggerxtrm/specialists 3.16.0 → 3.18.0

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 (257) hide show
  1. package/README.md +268 -132
  2. package/config/mandatory-rules/json-only-final-output.md +13 -0
  3. package/config/mandatory-rules/research-tool-routing.md +4 -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 +1 -1
  7. package/config/skills/setup-specialists/SKILL.md +556 -0
  8. package/config/skills/specialists-creator/SKILL.md +160 -5
  9. package/config/skills/specialists-creator/scripts/audit-spec-uniformity.mjs +1 -1
  10. package/config/skills/using-specialists-auto/SKILL.md +1 -1
  11. package/config/skills/using-specialists-v2/SKILL.md +7 -7
  12. package/config/skills/using-specialists-v3/SKILL.md +223 -147
  13. package/config/specialists/bare.specialist.json +3 -3
  14. package/config/specialists/changelog-drafter.specialist.json +9 -6
  15. package/config/specialists/changelog-keeper.specialist.json +10 -7
  16. package/config/specialists/debugger.specialist.json +8 -6
  17. package/config/specialists/executor.specialist.json +9 -7
  18. package/config/specialists/explorer.specialist.json +8 -6
  19. package/config/specialists/memory-processor.specialist.json +7 -5
  20. package/config/specialists/node-coordinator.specialist.json +7 -5
  21. package/config/specialists/obligations-scanner.specialist.json +149 -0
  22. package/config/specialists/overthinker.specialist.json +7 -5
  23. package/config/specialists/planner.specialist.json +8 -6
  24. package/config/specialists/quant-methodologist.specialist.json +145 -0
  25. package/config/specialists/quant-researcher.specialist.json +144 -0
  26. package/config/specialists/researcher.specialist.json +14 -9
  27. package/config/specialists/reviewer.specialist.json +11 -9
  28. package/config/specialists/seconder.specialist.json +170 -0
  29. package/config/specialists/security-auditor.specialist.json +6 -4
  30. package/config/specialists/service-skills-sync.specialist.json +93 -0
  31. package/config/specialists/specialists-creator.specialist.json +9 -7
  32. package/config/specialists/sync-docs.specialist.json +6 -4
  33. package/config/specialists/test-engineer.specialist.json +134 -0
  34. package/config/specialists/test-runner.specialist.json +11 -9
  35. package/config/specialists/transcriber.specialist.json +59 -0
  36. package/config/specialists/xt-merge.specialist.json +7 -5
  37. package/dist/asset-contract.json +39 -8
  38. package/dist/index.js +37083 -26912
  39. package/dist/lib.js +9850 -6147
  40. package/dist/types/cli/console/components.d.ts +83 -0
  41. package/dist/types/cli/console/components.d.ts.map +1 -0
  42. package/dist/types/cli/console/config-source.d.ts +58 -0
  43. package/dist/types/cli/console/config-source.d.ts.map +1 -0
  44. package/dist/types/cli/console/forensic.d.ts +11 -0
  45. package/dist/types/cli/console/forensic.d.ts.map +1 -0
  46. package/dist/types/cli/console/git.d.ts +28 -0
  47. package/dist/types/cli/console/git.d.ts.map +1 -0
  48. package/dist/types/cli/console/help.d.ts +2 -0
  49. package/dist/types/cli/console/help.d.ts.map +1 -0
  50. package/dist/types/cli/console/log.d.ts +13 -0
  51. package/dist/types/cli/console/log.d.ts.map +1 -0
  52. package/dist/types/cli/console/repo-config.d.ts +26 -0
  53. package/dist/types/cli/console/repo-config.d.ts.map +1 -0
  54. package/dist/types/cli/console/repo-discovery.d.ts +12 -0
  55. package/dist/types/cli/console/repo-discovery.d.ts.map +1 -0
  56. package/dist/types/cli/console/runtime.d.ts +12 -0
  57. package/dist/types/cli/console/runtime.d.ts.map +1 -0
  58. package/dist/types/cli/console/subscribe-prototype.d.ts +18 -0
  59. package/dist/types/cli/console/subscribe-prototype.d.ts.map +1 -0
  60. package/dist/types/cli/console/theme.d.ts +91 -0
  61. package/dist/types/cli/console/theme.d.ts.map +1 -0
  62. package/dist/types/cli/console/types.d.ts +231 -0
  63. package/dist/types/cli/console/types.d.ts.map +1 -0
  64. package/dist/types/cli/console/view-model.d.ts +252 -0
  65. package/dist/types/cli/console/view-model.d.ts.map +1 -0
  66. package/dist/types/cli/console.d.ts +2 -0
  67. package/dist/types/cli/console.d.ts.map +1 -0
  68. package/dist/types/cli/db.d.ts.map +1 -1
  69. package/dist/types/cli/doctor.d.ts.map +1 -1
  70. package/dist/types/cli/edit.d.ts.map +1 -1
  71. package/dist/types/cli/epic.d.ts.map +1 -1
  72. package/dist/types/cli/feed.d.ts.map +1 -1
  73. package/dist/types/cli/forensic.d.ts +2 -0
  74. package/dist/types/cli/forensic.d.ts.map +1 -0
  75. package/dist/types/cli/format-helpers.d.ts +4 -2
  76. package/dist/types/cli/format-helpers.d.ts.map +1 -1
  77. package/dist/types/cli/help.d.ts.map +1 -1
  78. package/dist/types/cli/init.d.ts +10 -0
  79. package/dist/types/cli/init.d.ts.map +1 -1
  80. package/dist/types/cli/list.d.ts.map +1 -1
  81. package/dist/types/cli/log.d.ts +2 -0
  82. package/dist/types/cli/log.d.ts.map +1 -0
  83. package/dist/types/cli/metrics.d.ts +2 -0
  84. package/dist/types/cli/metrics.d.ts.map +1 -0
  85. package/dist/types/cli/ps.d.ts.map +1 -1
  86. package/dist/types/cli/result.d.ts.map +1 -1
  87. package/dist/types/cli/resume.d.ts.map +1 -1
  88. package/dist/types/cli/run.d.ts +1 -0
  89. package/dist/types/cli/run.d.ts.map +1 -1
  90. package/dist/types/cli/script.d.ts +3 -0
  91. package/dist/types/cli/script.d.ts.map +1 -1
  92. package/dist/types/cli/serve.d.ts.map +1 -1
  93. package/dist/types/cli/setup.d.ts +19 -1
  94. package/dist/types/cli/setup.d.ts.map +1 -1
  95. package/dist/types/cli/status.d.ts.map +1 -1
  96. package/dist/types/cli/steer.d.ts.map +1 -1
  97. package/dist/types/cli/version-check.d.ts +1 -0
  98. package/dist/types/cli/version-check.d.ts.map +1 -1
  99. package/dist/types/index.d.ts +1 -1
  100. package/dist/types/pi/session.d.ts +11 -1
  101. package/dist/types/pi/session.d.ts.map +1 -1
  102. package/dist/types/server.d.ts +15 -0
  103. package/dist/types/server.d.ts.map +1 -1
  104. package/dist/types/specialist/benchmarks.d.ts +37 -0
  105. package/dist/types/specialist/benchmarks.d.ts.map +1 -0
  106. package/dist/types/specialist/chain-identity.d.ts +7 -1
  107. package/dist/types/specialist/chain-identity.d.ts.map +1 -1
  108. package/dist/types/specialist/control.d.ts.map +1 -1
  109. package/dist/types/specialist/forensic-events.d.ts +138 -0
  110. package/dist/types/specialist/forensic-events.d.ts.map +1 -0
  111. package/dist/types/specialist/forensic-renderer.d.ts +34 -0
  112. package/dist/types/specialist/forensic-renderer.d.ts.map +1 -0
  113. package/dist/types/specialist/git-diff-evidence.d.ts +28 -0
  114. package/dist/types/specialist/git-diff-evidence.d.ts.map +1 -0
  115. package/dist/types/specialist/global-config.d.ts +389 -0
  116. package/dist/types/specialist/global-config.d.ts.map +1 -0
  117. package/dist/types/specialist/job-file-output.d.ts +2 -0
  118. package/dist/types/specialist/job-file-output.d.ts.map +1 -1
  119. package/dist/types/specialist/launch.d.ts +1 -0
  120. package/dist/types/specialist/launch.d.ts.map +1 -1
  121. package/dist/types/specialist/live-aggregates.d.ts +46 -0
  122. package/dist/types/specialist/live-aggregates.d.ts.map +1 -0
  123. package/dist/types/specialist/loader.d.ts +50 -1
  124. package/dist/types/specialist/loader.d.ts.map +1 -1
  125. package/dist/types/specialist/model-chain.d.ts +7 -0
  126. package/dist/types/specialist/model-chain.d.ts.map +1 -0
  127. package/dist/types/specialist/model-probes.d.ts +28 -0
  128. package/dist/types/specialist/model-probes.d.ts.map +1 -0
  129. package/dist/types/specialist/node-contract.d.ts +18 -18
  130. package/dist/types/specialist/node-supervisor.d.ts.map +1 -1
  131. package/dist/types/specialist/observability-db.d.ts +1 -1
  132. package/dist/types/specialist/observability-db.d.ts.map +1 -1
  133. package/dist/types/specialist/observability-sqlite.d.ts +25 -0
  134. package/dist/types/specialist/observability-sqlite.d.ts.map +1 -1
  135. package/dist/types/specialist/preset-resolver.d.ts +56 -0
  136. package/dist/types/specialist/preset-resolver.d.ts.map +1 -0
  137. package/dist/types/specialist/prometheus-projection.d.ts +25 -0
  138. package/dist/types/specialist/prometheus-projection.d.ts.map +1 -0
  139. package/dist/types/specialist/runner.d.ts +29 -1
  140. package/dist/types/specialist/runner.d.ts.map +1 -1
  141. package/dist/types/specialist/schema.d.ts +181 -63
  142. package/dist/types/specialist/schema.d.ts.map +1 -1
  143. package/dist/types/specialist/script-runner.d.ts +5 -1
  144. package/dist/types/specialist/script-runner.d.ts.map +1 -1
  145. package/dist/types/specialist/snapshot-diff.d.ts +8 -0
  146. package/dist/types/specialist/snapshot-diff.d.ts.map +1 -0
  147. package/dist/types/specialist/source-queue.d.ts +13 -0
  148. package/dist/types/specialist/source-queue.d.ts.map +1 -0
  149. package/dist/types/specialist/supervisor.d.ts +39 -2
  150. package/dist/types/specialist/supervisor.d.ts.map +1 -1
  151. package/dist/types/specialist/timeline-events.d.ts +88 -2
  152. package/dist/types/specialist/timeline-events.d.ts.map +1 -1
  153. package/dist/types/tools/specialist/resume_specialist.tool.d.ts +4 -4
  154. package/dist/types/tools/specialist/specialist_status.tool.d.ts +1 -1
  155. package/dist/types/tools/specialist/steer_specialist.tool.d.ts +4 -4
  156. package/dist/types/tools/specialist/use_specialist.tool.d.ts +16 -16
  157. package/docs/ARCHITECTURE.md +1176 -0
  158. package/docs/TODO.md +9 -0
  159. package/docs/architecture.md +11 -0
  160. package/docs/archive/2026-03-13-bd-decision-context-template-plan.md +96 -0
  161. package/docs/archive/AGENT-HANDOFF.md +351 -0
  162. package/docs/archive/PARITY-ANALYSIS.md +296 -0
  163. package/docs/archive/SPECIALISTS_REFACTOR.md.md +30 -0
  164. package/docs/archive/cc-programmatic.md +216 -0
  165. package/docs/archive/claude-agent-sdk.md +594 -0
  166. package/docs/archive/decision-specialist-directory.md +41 -0
  167. package/docs/archive/discoveries.md +148 -0
  168. package/docs/archive/executor-benchmark-protocol.md +198 -0
  169. package/docs/archive/future-features.md +66 -0
  170. package/docs/archive/gzrx-completion-critique.md +183 -0
  171. package/docs/archive/gzrx-research-notes.md +401 -0
  172. package/docs/archive/gzrx-tool-catalog.md +760 -0
  173. package/docs/archive/iron-review-hardening-qa-chain-substrate.md +322 -0
  174. package/docs/archive/iron-review-hardening.html +1004 -0
  175. package/docs/archive/issuetracking.md +312 -0
  176. package/docs/archive/qa-v3.0.2.md +220 -0
  177. package/docs/archive/restructure.md +231 -0
  178. package/docs/archive/script-specialists.md +1254 -0
  179. package/docs/archive/spec-v3.md +792 -0
  180. package/docs/archive/specialist-stats.md +127 -0
  181. package/docs/archive/specialists-friction-audit.md +1347 -0
  182. package/docs/archive/specialists-runtime-critique.md +170 -0
  183. package/docs/archive/specialists-service-evaluation.md +713 -0
  184. package/docs/archive/specialists-substrate-alignment.md +255 -0
  185. package/docs/archive/substrate-review.md +1288 -0
  186. package/docs/archive/test-writer-specialist.md +254 -0
  187. package/docs/archive/using-specialists-v3-improvements-2026-05-09.md +600 -0
  188. package/docs/archive/xtrm-specialists-analysis.md +314 -0
  189. package/docs/authoring.md +701 -0
  190. package/docs/background-jobs.md +203 -0
  191. package/docs/bare-specialists.md +83 -0
  192. package/docs/benchmarks/executor-benchmark-runner.md +66 -0
  193. package/docs/bootstrap.md +161 -0
  194. package/docs/cli-reference.md +1645 -0
  195. package/docs/deploying-alongside.md +155 -0
  196. package/docs/design/README.md +36 -0
  197. package/docs/design/darth-feedor-migration.md +290 -0
  198. package/docs/design/roadmap/README.md +32 -0
  199. package/docs/design/roadmap/chain-templates/README.md +146 -0
  200. package/docs/design/roadmap/chain-templates/code-quick.formula.json +27 -0
  201. package/docs/design/roadmap/chain-templates/code-standard.formula.json +126 -0
  202. package/docs/design/roadmap/chain-templates/code-with-advisors.formula.json +128 -0
  203. package/docs/design/roadmap/chain-templates/code-with-tests.formula.json +76 -0
  204. package/docs/design/roadmap/chain-templates/debug.formula.json +128 -0
  205. package/docs/design/roadmap/chain-templates/doc-sync.formula.json +28 -0
  206. package/docs/design/roadmap/chain-templates/memory-hygiene.formula.json +27 -0
  207. package/docs/design/roadmap/chain-templates/planning.formula.json +27 -0
  208. package/docs/design/roadmap/chain-templates/premortem.formula.json +26 -0
  209. package/docs/design/roadmap/chain-templates/release-prep.formula.json +36 -0
  210. package/docs/design/roadmap/chain-templates/research-only.formula.json +28 -0
  211. package/docs/design/roadmap/chain-templates/restitch.formula.json +125 -0
  212. package/docs/design/roadmap/chain-templates/security-deep.formula.json +161 -0
  213. package/docs/design/roadmap/chain-templates/test-only.formula.json +52 -0
  214. package/docs/design/roadmap/chain-templates/triage.formula.json +35 -0
  215. package/docs/design/roadmap/history/handoff-from-substrate-design.md +87 -0
  216. package/docs/design/roadmap/history/substrate-reconciliation.md +105 -0
  217. package/docs/design/roadmap/specialists-roadmap.md +1193 -0
  218. package/docs/design/sp-console-subscribe-via-materializer.md +231 -0
  219. package/docs/design/sp-console-tui-mock-v2.html +293 -0
  220. package/docs/design/sp-console-tui-mock.html +120 -0
  221. package/docs/design/sp-console-tui.md +340 -0
  222. package/docs/design/specialist-agentops-suite.md +323 -0
  223. package/docs/design/substrate/channels.md +14 -0
  224. package/docs/design/substrate/devops-platform-engineering-prd.md +446 -0
  225. package/docs/design/substrate/html-design-example.md +339 -0
  226. package/docs/design/xtrm-tiers-architecture.svg +132 -0
  227. package/docs/devops/dependency-verdict-materialization.md +46 -0
  228. package/docs/epic-readiness.md +75 -0
  229. package/docs/examples/mercury-atomic-summarizer.specialist.json +26 -0
  230. package/docs/examples/smoke-echo-text-expected-keys.specialist.json +25 -0
  231. package/docs/examples/smoke-echo.specialist.json +25 -0
  232. package/docs/features.md +1577 -0
  233. package/docs/hooks.md +81 -0
  234. package/docs/installation.md +142 -0
  235. package/docs/manifest.md +184 -0
  236. package/docs/mcp-servers.md +73 -0
  237. package/docs/mcp-tools.md +71 -0
  238. package/docs/nodes.md +231 -0
  239. package/docs/observability-metrics.md +152 -0
  240. package/docs/operator/sp-console-v2-walkthrough.md +410 -0
  241. package/docs/overrides-guide.md +306 -0
  242. package/docs/pi-rpc-boundary.md +118 -0
  243. package/docs/pi-session.md +195 -0
  244. package/docs/release.md +22 -0
  245. package/docs/skills.md +132 -0
  246. package/docs/specialists/handoff-schema.md +181 -0
  247. package/docs/specialists-catalog.md +99 -0
  248. package/docs/specialists-service-install.md +226 -0
  249. package/docs/specialists-service.md +363 -0
  250. package/docs/surface-ownership.md +138 -0
  251. package/docs/upgrade-notes/kan-90-global-user-config.md +114 -0
  252. package/docs/upgrade-notes/kan-91-expanded-overrides.md +261 -0
  253. package/docs/workflow.md +114 -0
  254. package/docs/worktree.md +71 -0
  255. package/docs/worktrees.md +309 -0
  256. package/package.json +17 -12
  257. package/config/specialists/code-sanity.specialist.json +0 -108
@@ -0,0 +1,306 @@
1
+ # Global user overrides guide
2
+
3
+ This guide is the canonical reference for `~/.config/specialists/user.json`, created by `sp init --global`. The global user layer lets each user tune environment-specific fields without forking shipped specialists. Specialist identity and safety fields remain blocked.
4
+
5
+ ## Overview
6
+
7
+ The global override surface includes:
8
+
9
+ - KAN-91 allowlisted user-environment fields: `prompt.system_prompt_mode`, `execution.extensions.serena`, `execution.extensions.gitnexus`, `notes_mode`, `output_file`, `execution.prompt_limit_bytes`, and `execution.stdout_limit_bytes`.
10
+ - Additional runtime-default knobs: `execution.interactive` (default keep-alive behavior) and `stall_detection.waiting_auto_close_ms` (opt-in waiting auto-close threshold).
11
+ - Fallback chains via `execution.fallback_models` while keeping legacy `execution.fallback_model`.
12
+ - Preset references like `@preset/cheap` for model and fallback entries.
13
+ - A top-level `_doc` sentinel in generated `user.json` pointing back to this guide. Keys starting with `_` are metadata, not specialist names.
14
+
15
+ The examples below are delta snippets to add inside an existing specialist entry from `sp init --global`; they are not complete standalone `user.json` files. Keep the surrounding generated entry shape, including its `execution`, `prompt`, `stall_detection`, `beads_write_notes`, and `skills` keys, and change only the highlighted field.
16
+
17
+ ## Per-field reference
18
+
19
+ ### `prompt.system_prompt_mode`
20
+
21
+ - Type: `"append" | "replace" | null`
22
+ - Default semantics: `null` inherits the shipped specialist value, normally `append`.
23
+ - Example:
24
+
25
+ ```json
26
+ {
27
+ "executor": {
28
+ "prompt": { "system_prompt_mode": "replace" }
29
+ }
30
+ }
31
+ ```
32
+
33
+ Pitfall: this controls composition mode only. It does not let `user.json` replace `prompt.system`; prompt content remains blocked.
34
+
35
+ ### `execution.interactive`
36
+
37
+ - Type: `boolean | null`
38
+ - Default semantics: `null` inherits the merged specialist default. This is the default keep-alive/resume behavior when the operator does **not** pass `--keep-alive` or `--no-keep-alive`.
39
+ - Example:
40
+
41
+ ```json
42
+ {
43
+ "reviewer": {
44
+ "execution": { "interactive": false }
45
+ }
46
+ }
47
+ ```
48
+
49
+ Pitfall: CLI flags still win. Effective precedence is `--no-keep-alive` > `--keep-alive` > merged `execution.interactive`.
50
+
51
+ ### `execution.extensions.serena`
52
+
53
+ - Type: `boolean | null`
54
+ - Default semantics: `null` inherits the shipped extension setting.
55
+ - Example:
56
+
57
+ ```json
58
+ {
59
+ "executor": {
60
+ "execution": { "extensions": { "serena": false } }
61
+ }
62
+ }
63
+ ```
64
+
65
+ Pitfall: extension overrides are per-key overlays. Setting `serena: false` does not change `gitnexus`.
66
+
67
+ ### `execution.extensions.gitnexus`
68
+
69
+ - Type: `boolean | null`
70
+ - Default semantics: `null` inherits the shipped extension setting.
71
+ - Example:
72
+
73
+ ```json
74
+ {
75
+ "executor": {
76
+ "execution": { "extensions": { "gitnexus": false } }
77
+ }
78
+ }
79
+ ```
80
+
81
+ Pitfall: disabling GitNexus removes graph tooling from that specialist run. Use only when project indexing is unavailable or too expensive.
82
+
83
+ ### `stall_detection.waiting_auto_close_ms`
84
+
85
+ - Type: `number | null`
86
+ - Default semantics: `null` inherits or disables the behavior. `0` also means disabled.
87
+ - Example:
88
+
89
+ ```json
90
+ {
91
+ "reviewer": {
92
+ "stall_detection": { "waiting_auto_close_ms": 3600000 }
93
+ }
94
+ }
95
+ ```
96
+
97
+ Pitfall: this is **opt-in** and applies only after a specialist is already in `waiting`. The runtime attempts graceful close first; forced termination is fallback-only if the session refuses to exit.
98
+
99
+ ### `notes_mode`
100
+
101
+ - Type: `"full-trail" | "final-only" | null`
102
+ - Default semantics: `null` inherits the specialist default. `full-trail` appends turn handoffs; `final-only` keeps final handoff only.
103
+ - Example:
104
+
105
+ ```json
106
+ {
107
+ "researcher": {
108
+ "notes_mode": "final-only"
109
+ }
110
+ }
111
+ ```
112
+
113
+ Pitfall: `final-only` is quieter but removes intermediate turn notes from bead history.
114
+
115
+ ### `output_file`
116
+
117
+ - Type: `string | null`
118
+ - Default semantics: `null` inherits the specialist default or no file mirror.
119
+ - Example:
120
+
121
+ ```json
122
+ {
123
+ "researcher": {
124
+ "output_file": "./.specialists/researcher-result.md"
125
+ }
126
+ }
127
+ ```
128
+
129
+ Pitfall: paths are not expanded by the loader. `~/result.md` stays literal and is not converted to your home directory.
130
+
131
+ ### `execution.prompt_limit_bytes`
132
+
133
+ - Type: `number | null`
134
+ - Default semantics: `null` inherits the shipped prompt input limit.
135
+ - Example:
136
+
137
+ ```json
138
+ {
139
+ "executor": {
140
+ "execution": { "prompt_limit_bytes": 8388608 }
141
+ }
142
+ }
143
+ ```
144
+
145
+ Pitfall: raising this limit can increase token spend or provider rejection risk.
146
+
147
+ ### `execution.stdout_limit_bytes`
148
+
149
+ - Type: `number | null`
150
+ - Default semantics: `null` inherits the shipped stdout capture limit.
151
+ - Example:
152
+
153
+ ```json
154
+ {
155
+ "executor": {
156
+ "execution": { "stdout_limit_bytes": 67108864 }
157
+ }
158
+ }
159
+ ```
160
+
161
+ Pitfall: raising this limit can produce very large logs and result files.
162
+
163
+ ### `execution.fallback_model`
164
+
165
+ - Type: `string | null`
166
+ - Default semantics: legacy single fallback. `null` means no singular fallback from this layer.
167
+ - Example:
168
+
169
+ ```json
170
+ {
171
+ "executor": {
172
+ "execution": { "fallback_model": "openai-codex/gpt-5.4-mini" }
173
+ }
174
+ }
175
+ ```
176
+
177
+ Pitfall: if `fallback_models` is also set, plural wins.
178
+
179
+ ### `execution.fallback_models`
180
+
181
+ - Type: `string[] | null`
182
+ - Default semantics: `null` inherits lower layers. Array values replace the singular fallback chain for that layer.
183
+ - Example:
184
+
185
+ ```json
186
+ {
187
+ "executor": {
188
+ "execution": {
189
+ "fallback_models": [
190
+ "openai-codex/gpt-5.4-mini",
191
+ "nano-gpt/moonshotai/kimi-k2.5"
192
+ ]
193
+ }
194
+ }
195
+ }
196
+ ```
197
+
198
+ Pitfall: fallback walk is transient-failure-only. Auth failures, prompt rejections, and other logical failures do not advance to the next provider.
199
+
200
+ ## Preset reference syntax
201
+
202
+ Write a preset reference as an exact string inside the existing generated specialist entry:
203
+
204
+ ```json
205
+ {
206
+ "executor": {
207
+ "execution": {
208
+ "model": "@preset/cheap",
209
+ "fallback_models": ["@preset/medium", "openai-codex/gpt-5.4-mini"]
210
+ }
211
+ }
212
+ }
213
+ ```
214
+
215
+ Package presets live in `config/presets.json`. Current shipped names are `cheap`, `medium`, and `power`. User-defined preset files and repo-level preset shadowing are not part of this global override surface.
216
+
217
+ Preset references resolve transitively with depth cap 4. Cycles raise `SpecialistPresetCycleError` with the visited preset list. Unknown names raise `SpecialistPresetNotFoundError` and list known presets. Malformed preset payloads raise `SpecialistPresetTypeError` before the loader writes the resolved value into the merged specialist spec.
218
+
219
+ Only allowlisted override fields accept preset references. A blocked field such as `prompt.system` cannot smuggle a preset reference through `user.json`.
220
+
221
+ ## Fallback chain semantics
222
+
223
+ Runtime model order is:
224
+
225
+ 1. Primary `execution.model`.
226
+ 2. `execution.fallback_models` entries when plural is present.
227
+ 3. Legacy `execution.fallback_model` only when plural is absent.
228
+
229
+ Plural wins over singular in the same layer. A plural override in a higher layer replaces the lower layer's singular fallback chain because mixing singular and plural fallbacks across layers is ambiguous.
230
+
231
+ Each fallback step emits `fallback_step` telemetry with specialist, attempt number, tried model, error class, and whether the step was terminal. Chain walk only happens for transient failures such as rate limits, network errors, timeouts, and 5xx-class provider failures.
232
+
233
+ ## `auto_commit` is fork-only by design
234
+
235
+ `auto_commit` is intentionally blocked from `user.json`. The package default is `checkpoint_on_waiting` for `executor` and `debugger`, which checkpoints work before these long-running specialists enter `waiting`. Silent loss is the failure mode this default prevents: a specialist can produce useful edits, pause for review, then be resumed or terminated before manual staging captures the work.
236
+
237
+ Change `auto_commit` only by forking the specialist into `.specialists/user/<name>.specialist.json` and editing that fork:
238
+
239
+ ```bash
240
+ mkdir -p .specialists/user
241
+ cp config/specialists/executor.specialist.json .specialists/user/executor.specialist.json
242
+ # edit .specialists/user/executor.specialist.json and set auto_commit intentionally
243
+ ```
244
+
245
+ Repo/user forks are explicit because `auto_commit` changes repository-write behavior for everyone using that fork.
246
+
247
+ ## Initialization and strict JSON
248
+
249
+ Existing `~/.config/specialists/user.json` files auto-extend on the next `sp init --global` run. Existing values are preserved. Missing fields are filled with `null` defaults, and `_doc` points at `./overrides-guide.md`.
250
+
251
+ Generated files stay strict JSON. `sp init --global` does not write comments; it writes `_doc` as a top-level metadata key and writes this guide as `overrides-guide.md` next to `user.json`.
252
+
253
+ ## Complete example (validates against `GlobalUserConfigSchema`)
254
+
255
+ This is a complete `user.json` shape, not a delta snippet. It keeps every required key from `sp init --global` and exercises `system_prompt_mode`, fallback chains, extension opt-out, and `@preset/<name>` references.
256
+
257
+ ```json
258
+ {
259
+ "_doc": "./overrides-guide.md",
260
+ "executor": {
261
+ "execution": {
262
+ "model": "@preset/cheap",
263
+ "fallback_model": null,
264
+ "fallback_models": [
265
+ "@preset/medium",
266
+ "openai-codex/gpt-5.4-mini"
267
+ ],
268
+ "timeout_ms": null,
269
+ "stall_timeout_ms": null,
270
+ "interactive": true,
271
+ "thinking_level": null,
272
+ "max_retries": null,
273
+ "prompt_limit_bytes": 8388608,
274
+ "stdout_limit_bytes": null,
275
+ "extensions": {
276
+ "serena": false,
277
+ "gitnexus": null
278
+ }
279
+ },
280
+ "prompt": {
281
+ "system_prompt_mode": "replace"
282
+ },
283
+ "stall_detection": {
284
+ "waiting_auto_close_ms": 3600000
285
+ },
286
+ "beads_write_notes": null,
287
+ "notes_mode": "final-only",
288
+ "output_file": null,
289
+ "skills": {
290
+ "paths": []
291
+ }
292
+ }
293
+ }
294
+ ```
295
+
296
+ ## Cross-references
297
+
298
+ - Historical KAN-91 delta: `docs/upgrade-notes/kan-91-expanded-overrides.md`
299
+ - Origin doc: `docs/upgrade-notes/kan-90-global-user-config.md`
300
+ - KAN-91 epic: `unitAI-gp7nq`
301
+ - Phase 0 override machinery: `unitAI-gp7nq.1`
302
+ - Phase 1 user-environment fields: `unitAI-gp7nq.2`
303
+ - Phase 2 fallback chains: `unitAI-gp7nq.3`
304
+ - Phase 3 preset references: `unitAI-gp7nq.4`
305
+ - Follow-up reference-doc update: `unitAI-aav4w`
306
+ - Follow-up stale 4-layer wording fix: `unitAI-v4i0j`
@@ -0,0 +1,118 @@
1
+ ---
2
+ title: pi/rpc Boundary
3
+ description: Canonical ownership boundary between pi/rpc protocol surfaces and Specialists runtime adaptation.
4
+ synced_at: 4e7a6b4a
5
+ version: 3
6
+ updated: 2026-05-15
7
+ ---
8
+
9
+ # pi/rpc Boundary
10
+
11
+ This document defines ownership boundaries so protocol changes stay in the right layer.
12
+
13
+ References:
14
+ - `pi/rpc/` — canonical protocol implementation and types
15
+ - `docs/pi-rpc-boundary.md` — this ownership-boundary guide
16
+ - `pi/rpc/rpc-types.ts`
17
+ - `pi/rpc/rpc-client.ts`
18
+ - `pi/rpc/rpc-mode.ts`
19
+ - `pi/rpc/jsonl.ts`
20
+ - `src/pi/session.ts`
21
+ - `src/specialist/supervisor.ts`
22
+ - `src/specialist/timeline-events.ts`
23
+
24
+ ## 1) Canonical pi/rpc (source of truth)
25
+
26
+ Own this in `pi/rpc/*` and treat as canonical protocol contract:
27
+
28
+ - Command/response/event schema and names (`prompt`, `steer`, `follow_up`, `agent_end`, `message_update`, `tool_execution_*`, etc.)
29
+ - Wire-level command typing and response typing
30
+ - Extension UI sub-protocol (`extension_ui_request` / `extension_ui_response`)
31
+ - RPC mode command dispatch semantics (`rpc-mode.ts`)
32
+ - JSONL framing semantics (`jsonl.ts`): LF-delimited records, strict line splitting behavior
33
+ - Request/response correlation by `id`
34
+
35
+ If a behavior is represented in `pi/rpc/*.ts`, Specialists should adapt to it, not redefine it. This document records the ownership boundary; the protocol implementation remains the source of truth.
36
+
37
+ ## 2) Specialists-owned boundary (adapter + orchestration)
38
+
39
+ Own this in Specialists runtime code:
40
+
41
+ - `src/pi/session.ts` as adapter from canonical pi/rpc events into Specialists callbacks and lifecycle hooks
42
+ - Mapping raw pi event stream into Specialists event labels (`message_start_assistant`, `turn_start`, `tool_execution_start`, etc.)
43
+ - Runtime liveness/operational policy: stall watchdog, process lifecycle, kill/abort behavior, **test-aware stall timeout extension**
44
+ - Supervisor durability model (DB-first: `specialist_results` table, with file output env-gated since 3.9) and job lifecycle decisions
45
+ - Specialists timeline abstraction in `src/specialist/timeline-events.ts`
46
+
47
+ Specialists may transform/aggregate events for its own APIs, but must not invent conflicting meanings for existing pi/rpc event names.
48
+
49
+ ## 3) Transport-only concerns (non-semantic)
50
+
51
+ Transport-only concerns are implementation mechanics, not business semantics:
52
+
53
+ - stdin/stdout subprocess wiring
54
+ - JSONL encode/decode and buffering across chunk boundaries
55
+ - newline normalization (`\n`, optional trailing `\r` handling)
56
+ - request timeout handling and pending request maps
57
+ - low-level process termination mechanics
58
+
59
+ Changes here must preserve canonical protocol meaning; they should not alter runtime semantics defined by pi/rpc.
60
+
61
+ ## 4) Practical decision rule
62
+
63
+ When deciding where a change belongs:
64
+
65
+ - **pi/rpc change** if it introduces/renames/removes protocol fields, commands, or event semantics.
66
+ - **Specialists change** if it changes orchestration, persistence, timeline modeling, or job lifecycle policy while consuming the same pi/rpc contract.
67
+ - **transport-only change** if it only affects framing, buffering, or subprocess I/O mechanics without semantic changes.
68
+
69
+ ## 5) Specialists-owned stall detection
70
+
71
+ The stall timeout mechanism is entirely Specialists-owned:
72
+
73
+ - **Base timeout**: configured via `execution.stall_timeout_ms` in specialist YAML, passed to PiAgentSession
74
+ - **Test-aware extension**: PiAgentSession detects test command patterns (vitest, bun test, npm test, pnpm test, yarn test, jest, pytest) and extends the stall window to 300s during tool execution
75
+ - **Session kills**: StallTimeoutError thrown by PiAgentSession when no activity is detected within the effective timeout
76
+ - **Supervisor staleness**: Separate mechanism (running_silence_warn_ms, waiting_stale_ms) that emits timeline events but does not kill the session
77
+
78
+ This distinction matters: pi/rpc provides the event stream, but Specialists determines when "no activity" becomes a timeout. The test-aware extension is a Specialists policy decision, not a protocol feature.
79
+
80
+ ---
81
+
82
+ ## 7) Specialists-owned Pi extensions
83
+
84
+ Specialists can inject Pi extensions at session spawn time for policy enforcement. These extensions live in `$TMPDIR/specialists-pi-extensions/` and are passed to Pi via `-e <path>` arguments.
85
+
86
+ **What's OK to inject:**
87
+
88
+ - Pre-tool-call hooks (`pi.on('tool_call', ...)`) — for write-boundary enforcement, tool filtering, argument validation
89
+ - Event listeners (`pi.on('message_update', ...)`, etc.) — for logging, metrics, custom event handling
90
+ - Post-tool-call hooks — for result filtering, error handling wrappers
91
+
92
+ **What's NOT OK:**
93
+
94
+ - Pi protocol changes — extension cannot modify the command/event schema, add new RPC commands, or change wire-level semantics
95
+ - Competing with Supervisor lifecycle — extension should not emit `run_complete` or alter job state
96
+ - Cross-session state — extension is per-session, cannot persist state across Pi invocations
97
+
98
+ The RPC boundary remains unchanged: Pi's command/response/event contract is identical whether or not extensions are injected. Extensions are a **policy layer**, not a protocol extension.
99
+
100
+ **Example: worktree write-boundary enforcement**
101
+
102
+ The primary use case is blocking write tools (`edit`, `write`, `multiEdit`, `notebookEdit`) from writing outside a declared worktree boundary. The extension:
103
+
104
+ 1. Hooks `tool_call` events
105
+ 2. Extracts `path`/`file_path` argument from tool input
106
+ 3. Validates against the boundary (via `SPECIALISTS_WORKTREE_BOUNDARY` env var)
107
+ 4. Returns `{ block: true, reason: '...' }` for out-of-bounds paths
108
+
109
+ The boundary path is passed to the extension via `SPECIALISTS_WORKTREE_BOUNDARY` env var. This enforcement happens entirely inside the Pi process — the Specialists Supervisor does not need to intercept or validate tool calls itself.
110
+
111
+ ---
112
+
113
+ ## 6) Invariants
114
+
115
+ - `pi/rpc/*.ts` remains the canonical protocol surface.
116
+ - `src/pi/session.ts` remains an adapter, not a competing protocol definition.
117
+ - Supervisor remains the durable source of run lifecycle state for Specialists.
118
+ - Any divergence from `pi/rpc/*.ts` must be treated as a bug or an explicit upstream protocol update.
@@ -0,0 +1,195 @@
1
+ ---
2
+ title: Pi Subprocess Isolation
3
+ scope: pi-session
4
+ category: reference
5
+ version: 1.3.0
6
+ updated: 2026-06-24
7
+ synced_at: bf6baf7a
8
+ description: Why specialists spawns Pi with isolation flags and which extensions are selectively re-enabled.
9
+ source_of_truth_for:
10
+ - "src/pi/session.ts"
11
+ domain:
12
+ - pi
13
+ - architecture
14
+ ---
15
+
16
+ <!-- INDEX: auto-generated by validate_doc.py — do not edit manually -->
17
+ | Section | Summary |
18
+ |---|---|
19
+ | [Why `--no-extensions`](#why-no-extensions) | Pi auto-discovers xtrm extensions on startup from `~/ |
20
+ | [Selective re-enable policy](#selective-re-enable-policy) | After disabling all extensions, `src/pi/session |
21
+ | [How it maps from specialist YAML](#how-it-maps-from-specialist-yaml) | The specialist's `execution |
22
+ | [Serena-pool integration](#serena-pool-integration) | Pre-spawn hook that starts/reuses a shared Serena daemon via `ensureSerenaForRootInSubprocess` |
23
+ | [Telemetry bridging](#telemetry-bridging) | AgentOps-style metrics — token usage schema, `reasoning_tokens`, `tool_tokens`, `usage_source` |
24
+ | [Code location](#code-location) | `src/pi/session.ts` — `start()` method, extension resolution section |
25
+ | [Installing the selectively-loaded extensions](#installing-the-selectively-loaded-extensions) | Specialists does not install these — it only loads them if present |
26
+ | [See also](#see-also) | - [pi-rpc |
27
+ <!-- END INDEX -->
28
+
29
+ # Pi Subprocess Isolation
30
+
31
+ > **Alias:** `sp` is a shorter alias for `specialists` — `sp run`, `sp list`, `sp feed` etc. work identically.
32
+
33
+ Specialists spawns Pi in `--rpc` mode as a subprocess. Every package-class specialist run starts Pi with `--no-extensions`, `--offline`, `--no-context-files`, `--no-prompt-templates`, and `--no-themes`, then selectively re-enables a small allowlist of extensions. This page explains why.
34
+
35
+ ## Why `--no-extensions`
36
+
37
+ Pi auto-discovers xtrm extensions on startup from `~/.pi/agent/extensions/`. In an interactive session these extensions provide useful workflow enforcement — but in a specialist subprocess they cause silent failures.
38
+
39
+ The critical case is the **beads** extension. It blocks file edits unless a `claimed:<sessionId>` KV entry exists for the active Pi session ID. The orchestrating Claude session holds the claim; the specialist subprocess has a different, unrelated session ID. Without `--no-extensions`, every file write the specialist attempts silently fails the beads edit gate.
40
+
41
+ Other extensions (`session-flow`, `xt-end` reminder, UI/UX helpers) are similarly irrelevant or harmful in a headless subprocess context. The runner also disables Pi startup discovery surfaces with `--offline`, `--no-context-files`, `--no-prompt-templates`, and `--no-themes` so specialist subprocesses do not perform startup network checks or inherit human-session context files, prompt templates, or themes.
42
+
43
+ ## Selective re-enable policy
44
+
45
+ After disabling all extensions, `src/pi/session.ts` re-enables a small allowlist using `-e <path>`:
46
+
47
+ | Extension | Loaded in specialist Pi? | Condition | Reason |
48
+ |-----------|--------------------------|-----------|--------|
49
+ | `beads` | ❌ Never | — | Blocks edits — subprocess session ID has no claim |
50
+ | `session-flow` | ❌ Never | — | Stop gate and xt-end reminder are irrelevant in subprocess |
51
+ | `quality-gates` | ✅ If installed | `permission_required` ≠ `READ_ONLY` | Lint/typecheck enforcement on specialist edits |
52
+ | `service-skills` | ✅ If installed | Always (if installed) | Territory-aware routing is useful in any session |
53
+ | `caveman` | ✅ If installed | Always (if installed) | Terse output for agent-to-agent communication |
54
+ | `pi-gitnexus` (npm) | ✅ If installed, unless opted out | Not in `excludeExtensions` | Code intelligence tools |
55
+ | `pi-serena-tools` (npm) | ✅ If installed, unless opted out | Not in `excludeExtensions` | Serena integration tools |
56
+ | All other extensions | ❌ Never | — | UI/UX only; not relevant headlessly |
57
+
58
+ ## How it maps from specialist YAML
59
+
60
+ The specialist's `execution.permission_required` field controls whether `quality-gates` loads:
61
+
62
+ ```yaml
63
+ execution:
64
+ permission_required: READ_ONLY # → quality-gates NOT loaded (read-only; no edits to lint)
65
+ permission_required: LOW # → quality-gates loaded if installed
66
+ permission_required: MEDIUM # → quality-gates loaded if installed
67
+ permission_required: HIGH # → quality-gates loaded if installed
68
+ ```
69
+
70
+ `service-skills` loads regardless of permission level if the extension is installed.
71
+
72
+ ## Extension opt-out
73
+
74
+ Specialists can opt out of specific npm extensions via `execution.extensions` in their config:
75
+
76
+ ```json
77
+ {
78
+ "execution": {
79
+ "extensions": {
80
+ "serena": false,
81
+ "gitnexus": false
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ When `false`, the extension is excluded from the `-e` args passed to Pi spawn. This is useful for specialists where Serena or GitNexus tools add overhead without value.
88
+
89
+ ## Caveman extension
90
+
91
+ The caveman extension (`~/.pi/agent/extensions/caveman`) is loaded automatically when present. It enforces terse output style for agent-to-agent communication. The runner also sets `CAVEMAN_LEVEL=full` in the Pi process environment.
92
+
93
+ ## Code location
94
+
95
+ `src/pi/session.ts` — `start()` method, extension resolution section:
96
+
97
+ ```typescript
98
+ const args = [
99
+ '--mode', 'rpc',
100
+ '--no-extensions',
101
+ ...providerArgs,
102
+ '--no-session',
103
+ '--offline',
104
+ '--no-context-files',
105
+ '--no-prompt-templates',
106
+ '--no-themes',
107
+ ];
108
+
109
+ // Selectively re-enable extensions
110
+ const piExtDir = join(homedir(), '.pi', 'agent', 'extensions');
111
+ const excludedExtensions = new Set(this.options.excludeExtensions ?? []);
112
+
113
+ // Quality-gates (edit-capable only)
114
+ const permLevel = (this.options.permissionLevel ?? '').toUpperCase();
115
+ if (permLevel !== 'READ_ONLY') {
116
+ const qgPath = join(piExtDir, 'quality-gates');
117
+ if (existsSync(qgPath)) args.push('-e', qgPath);
118
+ }
119
+
120
+ // Service-skills (always)
121
+ const ssPath = join(piExtDir, 'service-skills');
122
+ if (existsSync(ssPath)) args.push('-e', ssPath);
123
+
124
+ // Caveman (always)
125
+ const cavemanPath = join(piExtDir, 'caveman');
126
+ if (existsSync(cavemanPath)) args.push('-e', cavemanPath);
127
+
128
+ // npm package extensions (with opt-out)
129
+ const npmGlobalDir = resolveGlobalNodeModulesDir();
130
+ if (npmGlobalDir) {
131
+ if (!excludedExtensions.has('pi-gitnexus')) {
132
+ const gitnexusPath = join(npmGlobalDir, 'pi-gitnexus');
133
+ if (existsSync(gitnexusPath)) args.push('-e', gitnexusPath);
134
+ }
135
+ if (!excludedExtensions.has('pi-serena-tools')) {
136
+ const serenaPath = join(npmGlobalDir, 'pi-serena-tools');
137
+ if (existsSync(serenaPath)) args.push('-e', serenaPath);
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### serena-pool
143
+
144
+ When `pi-serena-tools` is enabled, `session.ts` runs a **pre-spawn hook** to start or reuse a shared Serena MCP daemon for the same repo root:
145
+
146
+ 1. It locates the globally-installed `serena-pool` extension at `@jaggerxtrm/pi-extensions/extensions/serena-pool/index.ts`.
147
+ 2. If found, it calls `ensureSerenaForRootInSubprocess` (a Bun/Node `execFileSync`-wrapped helper that dynamic-imports the pool module and returns a deterministic TCP port).
148
+ 3. The resulting port is injected into the Pi process environment as `SERENA_MCP_PORT`.
149
+
150
+ Because `pi-serena-tools` reads `SERENA_MCP_PORT` at **extension construction time** (not at session-start), the env must be set **before** Pi spawns. This avoids duplicate Serena daemons on random ports.
151
+
152
+ | Property | Value |
153
+ |---|---|
154
+ | Pool extension path | `<global_node_modules>/@jaggerxtrm/pi-extensions/extensions/serena-pool/index.ts` |
155
+ | Port determinism | Hash-based on `projectRoot` |
156
+ | State file | `~/.local/share/pi-serena-pool/<hash>.json` |
157
+ | Fallback if pool fails | Pi falls back to spawning its own Serena (may incur per-worktree overhead) |
158
+
159
+ If the pool extension is not installed, or the specialist opts out with `"extensions": { "serena": false }`, Pi spawns its own Serena directly (or skips it entirely for read-only specialists).
160
+
161
+ ### agentops telemetry bridge
162
+
163
+ `session.ts` collates streaming RPC events into structured **session metrics** consumed by the AgentOps telemetry bridge:
164
+
165
+ - **`SessionRunMetrics`** — `events`, `tokens`, `tool_calls`, `tool_tokens`, `stall_warnings`, `execution_time_ms`, `cost_usd`.
166
+ - **`SessionTokenUsage`** — `input_tokens`, `output_tokens`, `cache_creation_tokens`, `cache_read_tokens`, **`reasoning_tokens`**, **`tool_tokens`**, `total_tokens`, `usage_source`.
167
+
168
+ `usage_source` tells downstream dashboards how reliable the token numbers are:
169
+
170
+ | Value | Meaning |
171
+ |---|---|
172
+ | `provider_usage` | Exact numbers from the LLM provider (OpenAI / Anthropic usage block) |
173
+ | `runtime_estimate` | Approximated from streaming chunk sizes when no provider usage arrived |
174
+ | `local_estimate` | Fallback heuristic (e.g. character-count ÷ 4) |
175
+ | `unknown` | No data available |
176
+
177
+ Cost is derived from the mapped `backend` + `model` in the telemetry layer, not inside `session.ts`.
178
+
179
+ `onMeta` callback now also receives `sessionId` so the telemetry bridge can correlate the Pi session with the specialist run record.
180
+
181
+ ## Installing the selectively-loaded extensions
182
+
183
+ Specialists does not install these — it only loads them if present. To enable them:
184
+
185
+ ```bash
186
+ nextpi install quality-gates
187
+ nextpi install service-skills
188
+ ```
189
+
190
+ Both live at `~/.pi/agent/extensions/`. Run `specialists status` to see which extensions are active in a running job.
191
+
192
+ ## See also
193
+
194
+ - [pi-rpc-boundary.md](pi-rpc-boundary.md) — RPC ownership boundary and lifecycle adaptation notes
195
+ - [background-jobs.md](background-jobs.md) — Background job monitoring
@@ -0,0 +1,22 @@
1
+ # Release inputs
2
+
3
+ `xt release` now reads two synthesis inputs:
4
+
5
+ 1. closed beads + git range signals
6
+ 2. xt session reports from `.xtrm/reports/` for same release window
7
+
8
+ `sp release prepare` / `sp release publish` remain as deprecated aliases for backward compatibility. They proxy to the same release logic and print a deprecation notice on every invocation.
9
+
10
+ The report layer is the higher-signal source. It captures intent, attempted approaches, discarded ideas, and post-mortem context. Use it to write WHY-grounded release bullets instead of file-diff summaries.
11
+
12
+ ## Report bundle cap
13
+
14
+ Report injection is capped at about 50k bytes/tokens. If range is larger, oldest reports are dropped and a cap note is prepended. Release still runs.
15
+
16
+ ## Operator range
17
+
18
+ Default range is previous tag..HEAD. Backfill runs may pass explicit `--from` / `--to` refs, and report selection follows that same range.
19
+
20
+ ## Result
21
+
22
+ Keep-a-Changelog markdown still comes out unchanged. Only input quality changes.