@jaggerxtrm/specialists 3.17.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.
- package/README.md +268 -134
- package/config/mandatory-rules/json-only-final-output.md +13 -0
- package/config/mandatory-rules/service-skills-diff-scan-mandatory.md +26 -0
- package/config/mandatory-rules/service-skills-gitnexus-triage.md +5 -0
- package/config/skills/setup-specialists/SKILL.md +556 -0
- package/config/skills/specialists-creator/SKILL.md +132 -4
- package/config/skills/specialists-creator/scripts/audit-spec-uniformity.mjs +1 -1
- package/config/specialists/bare.specialist.json +3 -3
- package/config/specialists/changelog-drafter.specialist.json +5 -4
- package/config/specialists/changelog-keeper.specialist.json +7 -6
- package/config/specialists/debugger.specialist.json +2 -2
- package/config/specialists/executor.specialist.json +2 -2
- package/config/specialists/explorer.specialist.json +4 -4
- package/config/specialists/memory-processor.specialist.json +3 -3
- package/config/specialists/node-coordinator.specialist.json +3 -3
- package/config/specialists/obligations-scanner.specialist.json +67 -17
- package/config/specialists/overthinker.specialist.json +3 -3
- package/config/specialists/planner.specialist.json +4 -4
- package/config/specialists/quant-methodologist.specialist.json +145 -0
- package/config/specialists/quant-researcher.specialist.json +144 -0
- package/config/specialists/researcher.specialist.json +5 -5
- package/config/specialists/reviewer.specialist.json +1 -1
- package/config/specialists/seconder.specialist.json +2 -2
- package/config/specialists/security-auditor.specialist.json +2 -2
- package/config/specialists/service-skills-sync.specialist.json +90 -75
- package/config/specialists/specialists-creator.specialist.json +4 -4
- package/config/specialists/sync-docs.specialist.json +4 -4
- package/config/specialists/test-engineer.specialist.json +3 -3
- package/config/specialists/test-runner.specialist.json +7 -7
- package/config/specialists/transcriber.specialist.json +3 -3
- package/config/specialists/xt-merge.specialist.json +4 -4
- package/dist/asset-contract.json +21 -2
- package/dist/index.js +25704 -16376
- package/dist/lib.js +9849 -6147
- package/dist/types/cli/console/components.d.ts +83 -0
- package/dist/types/cli/console/components.d.ts.map +1 -0
- package/dist/types/cli/console/config-source.d.ts +58 -0
- package/dist/types/cli/console/config-source.d.ts.map +1 -0
- package/dist/types/cli/console/forensic.d.ts +11 -0
- package/dist/types/cli/console/forensic.d.ts.map +1 -0
- package/dist/types/cli/console/git.d.ts +28 -0
- package/dist/types/cli/console/git.d.ts.map +1 -0
- package/dist/types/cli/console/help.d.ts +2 -0
- package/dist/types/cli/console/help.d.ts.map +1 -0
- package/dist/types/cli/console/log.d.ts +13 -0
- package/dist/types/cli/console/log.d.ts.map +1 -0
- package/dist/types/cli/console/repo-config.d.ts +26 -0
- package/dist/types/cli/console/repo-config.d.ts.map +1 -0
- package/dist/types/cli/console/repo-discovery.d.ts +12 -0
- package/dist/types/cli/console/repo-discovery.d.ts.map +1 -0
- package/dist/types/cli/console/runtime.d.ts +12 -0
- package/dist/types/cli/console/runtime.d.ts.map +1 -0
- package/dist/types/cli/console/subscribe-prototype.d.ts +18 -0
- package/dist/types/cli/console/subscribe-prototype.d.ts.map +1 -0
- package/dist/types/cli/console/theme.d.ts +91 -0
- package/dist/types/cli/console/theme.d.ts.map +1 -0
- package/dist/types/cli/console/types.d.ts +231 -0
- package/dist/types/cli/console/types.d.ts.map +1 -0
- package/dist/types/cli/console/view-model.d.ts +252 -0
- package/dist/types/cli/console/view-model.d.ts.map +1 -0
- package/dist/types/cli/console.d.ts +2 -0
- package/dist/types/cli/console.d.ts.map +1 -0
- package/dist/types/cli/db.d.ts.map +1 -1
- package/dist/types/cli/doctor.d.ts.map +1 -1
- package/dist/types/cli/edit.d.ts.map +1 -1
- package/dist/types/cli/epic.d.ts.map +1 -1
- package/dist/types/cli/feed.d.ts.map +1 -1
- package/dist/types/cli/forensic.d.ts +2 -0
- package/dist/types/cli/forensic.d.ts.map +1 -0
- package/dist/types/cli/format-helpers.d.ts +4 -2
- package/dist/types/cli/format-helpers.d.ts.map +1 -1
- package/dist/types/cli/help.d.ts.map +1 -1
- package/dist/types/cli/init.d.ts +10 -0
- package/dist/types/cli/init.d.ts.map +1 -1
- package/dist/types/cli/list.d.ts.map +1 -1
- package/dist/types/cli/log.d.ts.map +1 -1
- package/dist/types/cli/metrics.d.ts +2 -0
- package/dist/types/cli/metrics.d.ts.map +1 -0
- package/dist/types/cli/ps.d.ts.map +1 -1
- package/dist/types/cli/result.d.ts.map +1 -1
- package/dist/types/cli/run.d.ts +1 -0
- package/dist/types/cli/run.d.ts.map +1 -1
- package/dist/types/cli/script.d.ts +3 -0
- package/dist/types/cli/script.d.ts.map +1 -1
- package/dist/types/cli/serve.d.ts.map +1 -1
- package/dist/types/cli/setup.d.ts +19 -1
- package/dist/types/cli/setup.d.ts.map +1 -1
- package/dist/types/cli/status.d.ts.map +1 -1
- package/dist/types/cli/version-check.d.ts +1 -0
- package/dist/types/cli/version-check.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/pi/session.d.ts +11 -1
- package/dist/types/pi/session.d.ts.map +1 -1
- package/dist/types/server.d.ts +15 -0
- package/dist/types/server.d.ts.map +1 -1
- package/dist/types/specialist/benchmarks.d.ts +37 -0
- package/dist/types/specialist/benchmarks.d.ts.map +1 -0
- package/dist/types/specialist/chain-identity.d.ts +7 -1
- package/dist/types/specialist/chain-identity.d.ts.map +1 -1
- package/dist/types/specialist/control.d.ts.map +1 -1
- package/dist/types/specialist/forensic-events.d.ts +138 -0
- package/dist/types/specialist/forensic-events.d.ts.map +1 -0
- package/dist/types/specialist/forensic-renderer.d.ts +34 -0
- package/dist/types/specialist/forensic-renderer.d.ts.map +1 -0
- package/dist/types/specialist/git-diff-evidence.d.ts +28 -0
- package/dist/types/specialist/git-diff-evidence.d.ts.map +1 -0
- package/dist/types/specialist/global-config.d.ts +389 -0
- package/dist/types/specialist/global-config.d.ts.map +1 -0
- package/dist/types/specialist/launch.d.ts +1 -0
- package/dist/types/specialist/launch.d.ts.map +1 -1
- package/dist/types/specialist/live-aggregates.d.ts +46 -0
- package/dist/types/specialist/live-aggregates.d.ts.map +1 -0
- package/dist/types/specialist/loader.d.ts +50 -1
- package/dist/types/specialist/loader.d.ts.map +1 -1
- package/dist/types/specialist/model-chain.d.ts +7 -0
- package/dist/types/specialist/model-chain.d.ts.map +1 -0
- package/dist/types/specialist/model-probes.d.ts +28 -0
- package/dist/types/specialist/model-probes.d.ts.map +1 -0
- package/dist/types/specialist/node-contract.d.ts +18 -18
- package/dist/types/specialist/node-supervisor.d.ts.map +1 -1
- package/dist/types/specialist/observability-db.d.ts +1 -1
- package/dist/types/specialist/observability-db.d.ts.map +1 -1
- package/dist/types/specialist/observability-sqlite.d.ts +25 -0
- package/dist/types/specialist/observability-sqlite.d.ts.map +1 -1
- package/dist/types/specialist/preset-resolver.d.ts +56 -0
- package/dist/types/specialist/preset-resolver.d.ts.map +1 -0
- package/dist/types/specialist/prometheus-projection.d.ts +25 -0
- package/dist/types/specialist/prometheus-projection.d.ts.map +1 -0
- package/dist/types/specialist/runner.d.ts +26 -1
- package/dist/types/specialist/runner.d.ts.map +1 -1
- package/dist/types/specialist/schema.d.ts +163 -54
- package/dist/types/specialist/schema.d.ts.map +1 -1
- package/dist/types/specialist/script-runner.d.ts +5 -1
- package/dist/types/specialist/script-runner.d.ts.map +1 -1
- package/dist/types/specialist/snapshot-diff.d.ts +8 -0
- package/dist/types/specialist/snapshot-diff.d.ts.map +1 -0
- package/dist/types/specialist/source-queue.d.ts +13 -0
- package/dist/types/specialist/source-queue.d.ts.map +1 -0
- package/dist/types/specialist/supervisor.d.ts +15 -1
- package/dist/types/specialist/supervisor.d.ts.map +1 -1
- package/dist/types/specialist/timeline-events.d.ts +68 -1
- package/dist/types/specialist/timeline-events.d.ts.map +1 -1
- package/dist/types/tools/specialist/resume_specialist.tool.d.ts +4 -4
- package/dist/types/tools/specialist/specialist_status.tool.d.ts +1 -1
- package/dist/types/tools/specialist/steer_specialist.tool.d.ts +4 -4
- package/dist/types/tools/specialist/use_specialist.tool.d.ts +16 -16
- package/docs/ARCHITECTURE.md +1176 -0
- package/docs/TODO.md +9 -0
- package/docs/architecture.md +11 -0
- package/docs/archive/2026-03-13-bd-decision-context-template-plan.md +96 -0
- package/docs/archive/AGENT-HANDOFF.md +351 -0
- package/docs/archive/PARITY-ANALYSIS.md +296 -0
- package/docs/archive/SPECIALISTS_REFACTOR.md.md +30 -0
- package/docs/archive/cc-programmatic.md +216 -0
- package/docs/archive/claude-agent-sdk.md +594 -0
- package/docs/archive/decision-specialist-directory.md +41 -0
- package/docs/archive/discoveries.md +148 -0
- package/docs/archive/executor-benchmark-protocol.md +198 -0
- package/docs/archive/future-features.md +66 -0
- package/docs/archive/gzrx-completion-critique.md +183 -0
- package/docs/archive/gzrx-research-notes.md +401 -0
- package/docs/archive/gzrx-tool-catalog.md +760 -0
- package/docs/archive/iron-review-hardening-qa-chain-substrate.md +322 -0
- package/docs/archive/iron-review-hardening.html +1004 -0
- package/docs/archive/issuetracking.md +312 -0
- package/docs/archive/qa-v3.0.2.md +220 -0
- package/docs/archive/restructure.md +231 -0
- package/docs/archive/script-specialists.md +1254 -0
- package/docs/archive/spec-v3.md +792 -0
- package/docs/archive/specialist-stats.md +127 -0
- package/docs/archive/specialists-friction-audit.md +1347 -0
- package/docs/archive/specialists-runtime-critique.md +170 -0
- package/docs/archive/specialists-service-evaluation.md +713 -0
- package/docs/archive/specialists-substrate-alignment.md +255 -0
- package/docs/archive/substrate-review.md +1288 -0
- package/docs/archive/test-writer-specialist.md +254 -0
- package/docs/archive/using-specialists-v3-improvements-2026-05-09.md +600 -0
- package/docs/archive/xtrm-specialists-analysis.md +314 -0
- package/docs/authoring.md +701 -0
- package/docs/background-jobs.md +203 -0
- package/docs/bare-specialists.md +83 -0
- package/docs/benchmarks/executor-benchmark-runner.md +66 -0
- package/docs/bootstrap.md +161 -0
- package/docs/cli-reference.md +1645 -0
- package/docs/deploying-alongside.md +155 -0
- package/docs/design/README.md +36 -0
- package/docs/design/darth-feedor-migration.md +290 -0
- package/docs/design/roadmap/README.md +32 -0
- package/docs/design/roadmap/chain-templates/README.md +146 -0
- package/docs/design/roadmap/chain-templates/code-quick.formula.json +27 -0
- package/docs/design/roadmap/chain-templates/code-standard.formula.json +126 -0
- package/docs/design/roadmap/chain-templates/code-with-advisors.formula.json +128 -0
- package/docs/design/roadmap/chain-templates/code-with-tests.formula.json +76 -0
- package/docs/design/roadmap/chain-templates/debug.formula.json +128 -0
- package/docs/design/roadmap/chain-templates/doc-sync.formula.json +28 -0
- package/docs/design/roadmap/chain-templates/memory-hygiene.formula.json +27 -0
- package/docs/design/roadmap/chain-templates/planning.formula.json +27 -0
- package/docs/design/roadmap/chain-templates/premortem.formula.json +26 -0
- package/docs/design/roadmap/chain-templates/release-prep.formula.json +36 -0
- package/docs/design/roadmap/chain-templates/research-only.formula.json +28 -0
- package/docs/design/roadmap/chain-templates/restitch.formula.json +125 -0
- package/docs/design/roadmap/chain-templates/security-deep.formula.json +161 -0
- package/docs/design/roadmap/chain-templates/test-only.formula.json +52 -0
- package/docs/design/roadmap/chain-templates/triage.formula.json +35 -0
- package/docs/design/roadmap/history/handoff-from-substrate-design.md +87 -0
- package/docs/design/roadmap/history/substrate-reconciliation.md +105 -0
- package/docs/design/roadmap/specialists-roadmap.md +1193 -0
- package/docs/design/sp-console-subscribe-via-materializer.md +231 -0
- package/docs/design/sp-console-tui-mock-v2.html +293 -0
- package/docs/design/sp-console-tui-mock.html +120 -0
- package/docs/design/sp-console-tui.md +340 -0
- package/docs/design/specialist-agentops-suite.md +323 -0
- package/docs/design/substrate/channels.md +14 -0
- package/docs/design/substrate/devops-platform-engineering-prd.md +446 -0
- package/docs/design/substrate/html-design-example.md +339 -0
- package/docs/design/xtrm-tiers-architecture.svg +132 -0
- package/docs/devops/dependency-verdict-materialization.md +46 -0
- package/docs/epic-readiness.md +75 -0
- package/docs/examples/mercury-atomic-summarizer.specialist.json +26 -0
- package/docs/examples/smoke-echo-text-expected-keys.specialist.json +25 -0
- package/docs/examples/smoke-echo.specialist.json +25 -0
- package/docs/features.md +1577 -0
- package/docs/hooks.md +81 -0
- package/docs/installation.md +142 -0
- package/docs/manifest.md +184 -0
- package/docs/mcp-servers.md +73 -0
- package/docs/mcp-tools.md +71 -0
- package/docs/nodes.md +231 -0
- package/docs/observability-metrics.md +152 -0
- package/docs/operator/sp-console-v2-walkthrough.md +410 -0
- package/docs/overrides-guide.md +306 -0
- package/docs/pi-rpc-boundary.md +118 -0
- package/docs/pi-session.md +195 -0
- package/docs/release.md +22 -0
- package/docs/skills.md +132 -0
- package/docs/specialists/handoff-schema.md +181 -0
- package/docs/specialists-catalog.md +99 -0
- package/docs/specialists-service-install.md +226 -0
- package/docs/specialists-service.md +363 -0
- package/docs/surface-ownership.md +138 -0
- package/docs/upgrade-notes/kan-90-global-user-config.md +114 -0
- package/docs/upgrade-notes/kan-91-expanded-overrides.md +261 -0
- package/docs/workflow.md +114 -0
- package/docs/worktree.md +71 -0
- package/docs/worktrees.md +309 -0
- package/package.json +6 -3
|
@@ -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
|
package/docs/release.md
ADDED
|
@@ -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.
|