@aeondave/pi-persona 1.15.2 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +32 -6
- package/CHANGELOG.md +97 -0
- package/README.md +27 -8
- package/SECURITY.md +42 -0
- package/docs/ARCHITECTURE.md +52 -7
- package/docs/EXPERIENCE.md +21 -5
- package/docs/README.md +2 -0
- package/docs/REFERENCE.md +84 -14
- package/docs/STRATEGIES.md +58 -31
- package/docs/TELEMETRY.md +14 -0
- package/package.json +18 -11
- package/src/bus/broker/paths.ts +3 -2
- package/src/core/brief.ts +1 -1
- package/src/core/nudge.ts +3 -4
- package/src/core/pi-compat.ts +3 -3
- package/src/engine/adapter.ts +11 -6
- package/src/engine/async.ts +12 -6
- package/src/engine/inproc.ts +14 -6
- package/src/extension/engine.ts +25 -4
- package/src/extension/hooks.ts +68 -21
- package/src/extension.ts +233 -57
- package/src/orchestration/model-retry.ts +32 -61
- package/src/orchestration/params.ts +27 -1
- package/src/orchestration/roster.ts +80 -3
- package/src/orchestration/sdk.ts +150 -36
- package/src/orchestration/strategies/compete.ts +14 -8
- package/src/orchestration/strategies/council-rounds.ts +8 -1
- package/src/orchestration/strategies/critic-loop.ts +25 -11
- package/src/orchestration/strategies/judge.ts +18 -9
- package/src/orchestration/strategies/magi.ts +42 -93
- package/src/orchestration/strategies/map.ts +41 -19
- package/src/orchestration/strategies/pipeline.ts +2 -2
- package/src/orchestration/strategies/synthesize.ts +18 -11
- package/src/orchestration/types.ts +15 -0
- package/src/persona/model-participants.ts +240 -0
- package/src/persona/orchestrate.ts +44 -2
- package/src/persona/persona.ts +86 -14
- package/src/telemetry/contract.ts +1 -1
- package/src/telemetry/producer.ts +241 -8
- package/src/tools/council.ts +36 -8
- package/src/tools/delegate-tool.ts +162 -24
- package/src/tools/intercom-tool.ts +119 -32
- package/src/ui/agent-overlay.ts +15 -6
- package/src/ui/agent-tree.ts +39 -2
package/AGENTS.md
CHANGED
|
@@ -30,8 +30,18 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
30
30
|
`@earendil-works/pi-*`; never bundle copies.
|
|
31
31
|
- npm publishes as `@aeondave/pi-persona`. Pi supplies the four `@earendil-works/pi-*` packages
|
|
32
32
|
and `typebox`: keep them as `peerDependencies: "*"` with development-only copies, never runtime
|
|
33
|
-
dependencies. The supported host floor
|
|
33
|
+
dependencies. The supported host floor is Pi ≥ 1.0.0 (`MIN_PI_VERSION` and the README); Node.js
|
|
34
|
+
must be ≥ 22.19 to match that host. Keep the npm
|
|
34
35
|
`files` allowlist explicit for docs/artwork, inspect `npm pack --dry-run`, and never publish drafts.
|
|
36
|
+
- Supply-chain controls: pin every GitHub Action to a verified full commit SHA; keep top-level
|
|
37
|
+
token permissions read-only, grant write permissions only to the reporting job that needs them,
|
|
38
|
+
and disable persisted checkout credentials. Dependabot proposes updates; it does not auto-merge.
|
|
39
|
+
Keep the four Pi development packages in one update group so their APIs stay aligned.
|
|
40
|
+
Match `@types/node` to the oldest supported Node major, including in CI; upgrade them together.
|
|
41
|
+
Keep security overrides scoped to the affected development dependency and version; remove them
|
|
42
|
+
when upgrading Pi if the new dependency graph no longer needs them.
|
|
43
|
+
Run the full dependency audit (including development dependencies), tests and typecheck after
|
|
44
|
+
lockfile updates. A development override does not patch a user's installed Pi host.
|
|
35
45
|
- **Cross-OS**: use Pi's spawn/kill/path/temp helpers (`getPiInvocation`, `killProcessTree`), not raw
|
|
36
46
|
`child_process`. Windows kill goes straight to `taskkill /F /T`; always attach an `error` listener.
|
|
37
47
|
- Two engines behind the `StrategyEngine` seam: **InProcessEngine** (`engine/inproc`,
|
|
@@ -78,6 +88,11 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
78
88
|
policy (OpenAI-family → OpenAI providers; Claude-family → the native Claude provider). A caller may
|
|
79
89
|
explicitly opt a pinned run into cross-provider recovery. Only `failureKind === "provider"` reroutes;
|
|
80
90
|
abort/timeout/contract/unknown/agent are terminal.
|
|
91
|
+
Strategy/council/flow runs disable that provider search and use SDK-level main-only recovery:
|
|
92
|
+
`provider`/`unknown-model` may retry ONCE on the current supervisor model, including a saved or
|
|
93
|
+
inline-pinned choice (explicit user-authorized exception). Never borrow a peer model, never restart
|
|
94
|
+
a stopped/timed-out/contract-failed leg, and charge each attempt to child/token limits and usage.
|
|
95
|
+
Ordinary delegate pins remain strict. Recovery must remain visible in metadata/UI and MAGI rulings.
|
|
81
96
|
Engines classify the cause on the `AgentResult` (`failureKind` + resolved `modelUsed`); keep those
|
|
82
97
|
set when you touch `inproc.ts`/`adapter.ts` or the fallback silently stops working.
|
|
83
98
|
- **Fork-bomb guard**: children run with env `PI_PERSONA_DISABLE=1` so pi-persona self-disables inside
|
|
@@ -93,11 +108,13 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
93
108
|
blind retry loops are stopped by the runtime `DelegationLedger` (an identical agent+model+task
|
|
94
109
|
delegation that failed twice is vetoed before it spawns).
|
|
95
110
|
- Dynamic sub-agents: `delegate` shapes an on-the-fly specialist with `role` (extra system prompt,
|
|
96
|
-
appended to the agent's own) + `skills` — prompt-level only, capabilities stay the gate.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
appended to the agent's own) + `skills` — prompt-level only, capabilities stay the gate. Intercom
|
|
112
|
+
`wait` snapshots already-settled reports by default in interactive/RPC sessions; `sync: true` opts
|
|
113
|
+
into a bounded join (≤ the bus-ask timeout). Headless waits default to joining; `sync: false` takes
|
|
114
|
+
a snapshot. Collected reports are discarded from the pending completion follow-up so they are
|
|
115
|
+
never double-reported; snapshots leave running children active. In interactive sessions `delegate`
|
|
116
|
+
is background-by-default (`sync: true` opts a call out; headless `pi -p` defaults to sync so the
|
|
117
|
+
single turn carries the result). An explicit `async` flag takes precedence over `sync` and the default.
|
|
101
118
|
Message ids and run ids are separate: `intercom message { messageId }` retrieves retained bus
|
|
102
119
|
text, `intercom result { to: runId }` retrieves a settled run. Both explicit and automatic inbox
|
|
103
120
|
drains retain bounded history (256 messages / 256,000 body characters). Ask settlement clears
|
|
@@ -120,6 +137,10 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
120
137
|
fills with every leg's body, failures included), while `renderCompletion` scans only `status: "done"`
|
|
121
138
|
runs. A background leg that FAILED while emitting `[BLOCKED]` therefore gets the failure block but no
|
|
122
139
|
persistence note — deliberate (see the `renderCompletion` doc comment), not a bug to "fix" silently.
|
|
140
|
+
Nested reports from codemode's `ctx.executeTool` retain bounded provenance through Pi's explicit
|
|
141
|
+
`parentToolCallId`; never infer nesting from the call-id string. Only an outer result that relays
|
|
142
|
+
the surrender marker gets the note/card. Nested programmatic data is never patched with a reminder,
|
|
143
|
+
and discarded reports never generate an invisible one. Relay state clears at turn/session settlement.
|
|
123
144
|
`config.nudge` (`PI_PERSONA_NUDGE=off`) silences all of it: the `tool_result` hook (the by-hand
|
|
124
145
|
reminder and the sync-result persistence one) and both `renderCompletion` call sites, which take
|
|
125
146
|
their `scan` through the same gate — so a background/`intercom wait` report carries no note either.
|
|
@@ -177,6 +198,8 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
177
198
|
|
|
178
199
|
## Testing
|
|
179
200
|
|
|
201
|
+
- Offline SDK harnesses must await `session_shutdown` before SDK `dispose()` and temporary-profile
|
|
202
|
+
deletion. `dispose()` disconnects SDK listeners; it does not join extension-owned writers.
|
|
180
203
|
- TDD: write the failing test first for `core/*` and any behavior change; watch it fail, then fix.
|
|
181
204
|
- Done = `npm run typecheck` clean **and** full suite green. The suite has **two** intentional skips,
|
|
182
205
|
both Windows-only — the runner reports `skipped 2` on Windows and `skipped 0` elsewhere (see
|
|
@@ -190,6 +213,9 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
190
213
|
persistence; `src/extension/identity.ts` registers `agent_name` and the pre-name context bootstrap.
|
|
191
214
|
Exocom uses that same state. A delegate's optional `AgentRunSpec.name` is leader-assigned
|
|
192
215
|
display identity, propagated to both engines without changing routing ids.
|
|
216
|
+
Async launch/control cards use that alias, with persisted tool-result snapshots for history.
|
|
217
|
+
Keep run IDs for routing/diagnostics, not primary display identity; disambiguate duplicate aliases.
|
|
218
|
+
Steering cards preview the accepted message and expose all of it with Pi's expand-key binding.
|
|
193
219
|
Runtime metadata guidance belongs in the stable supervisor system prompt, not a new user-like
|
|
194
220
|
acknowledgement message. Keep initial setup/actionable asks working, preserve user-visible history,
|
|
195
221
|
and never re-inject a chosen identity. Progress `tokens` is cumulative input/output usage, not live
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,103 @@ used in its [GitHub releases](https://github.com/AeonDave/pi-persona/releases).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.16.1](https://github.com/AeonDave/pi-persona/releases/tag/v1.16.1) - 2026-10-06
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Publish the real pending-supervisor-ask state as `agent.updated` telemetry for Flow. Refresh it on
|
|
14
|
+
ask delivery and reply/timeout/cancellation settlement, without duplicate events or text-based
|
|
15
|
+
guesses; queued and terminal state remain authoritative.
|
|
16
|
+
- Make the native offline codemode harness await extension shutdown before deleting its temporary
|
|
17
|
+
profile; SDK `dispose()` alone does not flush the extension's telemetry writer.
|
|
18
|
+
|
|
19
|
+
### Packaging
|
|
20
|
+
|
|
21
|
+
- Add the npm author and focused Pi gallery keywords; align the banner preview and pinned install
|
|
22
|
+
examples with this release.
|
|
23
|
+
|
|
24
|
+
## [1.16.0](https://github.com/AeonDave/pi-persona/releases/tag/v1.16.0) - 2026-10-03
|
|
25
|
+
|
|
26
|
+
### Compatibility
|
|
27
|
+
|
|
28
|
+
- Require Pi ≥ 1.0.0 and Node.js ≥ 22.19. Update the development cohort to Pi 1.0's four coordinated
|
|
29
|
+
host-package pins and qualify its SDK and tool lifecycle. Pre-1.0 Pi hosts are no longer supported;
|
|
30
|
+
the host packages and TypeBox remain wildcard peers supplied by Pi, not bundled runtime copies.
|
|
31
|
+
- Update the live control harness to use Pi 1.0's session `modelRuntime` through the public
|
|
32
|
+
`ModelRegistry` facade instead of the removed session registry property.
|
|
33
|
+
- An authored `council.members` field is now validated. Older malformed fields that were ignored
|
|
34
|
+
must be corrected or removed; council calls fail with the field diagnostic instead of selecting
|
|
35
|
+
an unrelated fallback panel.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- Reserve mandatory downstream child slots before optional model recovery in `map`, `pipeline`,
|
|
40
|
+
`critic-loop`, and `council-rounds`. Provider outages no longer spend the slots needed by later
|
|
41
|
+
workers, verifiers, steps, or rounds and turn completed work into a run-fatal admission error.
|
|
42
|
+
- Pass live supervisor-ask state to the `intercom peek` tool, including untargeted peeks; a child
|
|
43
|
+
waiting for its supervisor is not reported as stuck. Collapsed steer receipts identify the run.
|
|
44
|
+
- Honor members-only council profiles for active and explicitly selected personas, including their
|
|
45
|
+
params when MAGI is selected explicitly as the same default strategy. Evaluate each configured
|
|
46
|
+
agent-model lookup once.
|
|
47
|
+
- Carry persistence checkpoints through nested codemode reports when their `[BLOCKED]`/`FLAG:
|
|
48
|
+
UNKNOWN` marker is relayed to the model. Suppressed nested output stays unchanged; only the outer
|
|
49
|
+
visible result receives the checkpoint and its expandable card.
|
|
50
|
+
- Surface telemetry cleanup/write diagnostics without requiring debug mode; diagnostics remain
|
|
51
|
+
non-fatal. Failed admission removes only the empty directories created by that attempt.
|
|
52
|
+
- Release a telemetry writer lease after its terminal writes finish without waiting for the shared
|
|
53
|
+
retention sweep over unrelated sessions; explicit maintenance joins remain available.
|
|
54
|
+
- Harden the exported council-preset expansion boundary with normalized strategy names and the
|
|
55
|
+
same strategy/roster/params allowlist as the JSON loader; validated authored members remain intact.
|
|
56
|
+
- Resolve live tree and telemetry model labels for auxiliary actors through the same role-specific
|
|
57
|
+
participants as the picker, including inline model pins and repeated SDK keys. Ambiguous short
|
|
58
|
+
role hints omit an uncertain model rather than attributing a different participant's choice.
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
|
|
62
|
+
- Make general council guidance proportionate while preserving MAGI and Judge's specialized focus;
|
|
63
|
+
all eleven strategies remain available through the same tool. Add ephemeral inline council members
|
|
64
|
+
and specialized external actors without creating persona/team files.
|
|
65
|
+
- Include role-specific members and external arbiters in model selection; respect configured models
|
|
66
|
+
and remember prompts per participant rather than suppressing later teams for the whole persona.
|
|
67
|
+
- Recover model/provider failures across strategies and flows once on the supervisor's current model,
|
|
68
|
+
including unavailable saved or pinned choices. Remove MAGI's peer-model substitution; report the
|
|
69
|
+
switch, account both attempts, and preserve child/token limits and cancellation.
|
|
70
|
+
- Use worker aliases in async launch cards and targeted Intercom call headers, matching the live tree.
|
|
71
|
+
Persist display identity in tool results so history remains readable after reload or tracker eviction;
|
|
72
|
+
routing still uses run IDs, with a secondary ID shown when aliases collide.
|
|
73
|
+
- Show the accepted steering message as a compact preview, with Pi's expand-key hint for the full
|
|
74
|
+
message and diagnostic run ID. Replace repetitive soft-request/cancellation boilerplate with a
|
|
75
|
+
concise queued receipt; steering remains a request, not proof of execution or cancellation.
|
|
76
|
+
- Make context-burn checkpoints aware of Pi's nested-tool metadata: raw inner results do not
|
|
77
|
+
consume the model-visible output budget or receive invisible reminders. Permission gates,
|
|
78
|
+
telemetry and genuine successful hand-off resets still apply inside codemode.
|
|
79
|
+
- Show an immediate async completion banner with the worker's display name, including successful
|
|
80
|
+
runs. The semantic report still arrives once through the idle-gated completion path, and a failed
|
|
81
|
+
UI notification cannot swallow it.
|
|
82
|
+
- Replace the child watchdog test's load-sensitive kill-latency assertion with an observed blocked →
|
|
83
|
+
released → idle-timeout barrier; preserve the two intentional Windows-only skips.
|
|
84
|
+
- Clarify that automatic background completion follow-ups and end-turn guidance are the intended
|
|
85
|
+
async default: continue independent work, and do not monitor or join all workers when they are the
|
|
86
|
+
only remaining work. `intercom wait` now snapshots without blocking by default in interactive/RPC
|
|
87
|
+
sessions; `sync: true` opts into its bounded join, while headless remains blocking by default and
|
|
88
|
+
`sync: false` opts out. Snapshots collect only already-settled reports, leaving running work active.
|
|
89
|
+
Queued steering does not preempt an explicitly blocking join. A real Pi 1.0 SDK test with a local faux provider characterizes steering becoming
|
|
90
|
+
dormant when delayed input hooks outlast the active run. No unsafe input-triggered join abort ships.
|
|
91
|
+
- A council call that switches strategy no longer inherits unrelated profile params; params continue
|
|
92
|
+
to merge when the selected strategy is unchanged, and unknown explicit keys still warn.
|
|
93
|
+
- Show live supervisor asks as `waiting for supervisor`, rather than stalled, in the tree, F9 and
|
|
94
|
+
peek; refresh council parent clocks on child progress. A waiting worker becomes eligible for
|
|
95
|
+
stall detection again when its ask settles. Steering an already-settled run points to its result.
|
|
96
|
+
- Add age-based telemetry cleanup with a 30-day default; see
|
|
97
|
+
[`docs/TELEMETRY.md`](docs/TELEMETRY.md) for the retention contract.
|
|
98
|
+
- Reuse one tree snapshot per F9 list redraw for rows, selection and waiting state; remove an
|
|
99
|
+
unreachable delegate-title branch and distinguish event liveness from proof of useful progress.
|
|
100
|
+
- Align the README and technical guides on async snapshots/joins, steering delivery, model-selection
|
|
101
|
+
precedence, members-only councils, and automatic `map` verifier headroom.
|
|
102
|
+
|
|
103
|
+
After updating, let active workers settle and restart Pi (or use `/reload`). `/persona reload`
|
|
104
|
+
refreshes definitions, not extension code. Existing custom personas and provider pins are preserved.
|
|
105
|
+
|
|
9
106
|
## [1.15.2](https://github.com/AeonDave/pi-persona/releases/tag/v1.15.2) - 2026-09-28
|
|
10
107
|
|
|
11
108
|
### Distribution
|
package/README.md
CHANGED
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
<img src="assets/banner.png" alt="pi-persona — supervised multi-agent orchestration for Pi">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
+
[](https://github.com/AeonDave/pi-persona/actions/workflows/test.yml) [](https://scorecard.dev/viewer/?uri=github.com/AeonDave/pi-persona) [](https://www.npmjs.com/package/@aeondave/pi-persona) [](LICENSE)
|
|
8
|
+
|
|
7
9
|
**Give Pi a supervised team.**
|
|
8
|
-
`pi-persona`
|
|
9
|
-
async workers, live steering, cross-session collaboration, and switchable personas.
|
|
10
|
+
`pi-persona` adds supervised multi-agent orchestration to [Pi](https://github.com/earendil-works/pi):
|
|
11
|
+
async workers, live steering, cross-session collaboration, and switchable personas. It builds on
|
|
12
|
+
Pi's native SDK and tool hooks; the extension adds worker supervision and coordination.
|
|
10
13
|
Describe the outcome. A supervisor delegates work, gathers results, and checks the outcome;
|
|
11
14
|
you can inspect workers, redirect them, or stop a run while it is in progress.
|
|
12
15
|
|
|
@@ -14,7 +17,7 @@ you can inspect workers, redirect them, or stop a run while it is in progress.
|
|
|
14
17
|
|
|
15
18
|
## Install
|
|
16
19
|
|
|
17
|
-
Requires **Pi ≥ 0.
|
|
20
|
+
Requires **Pi ≥ 1.0.0**, **Node.js ≥ 22.19**, and **Git**. Configure a model provider in Pi first.
|
|
18
21
|
|
|
19
22
|
Run in your terminal:
|
|
20
23
|
|
|
@@ -36,9 +39,9 @@ your customizations.
|
|
|
36
39
|
| Install option | Command |
|
|
37
40
|
|---|---|
|
|
38
41
|
| This project only | `pi install -l npm:@aeondave/pi-persona` |
|
|
39
|
-
| Pin this release | `pi install npm:@aeondave/pi-persona@1.
|
|
42
|
+
| Pin this release | `pi install npm:@aeondave/pi-persona@1.16.1` |
|
|
40
43
|
| Update an unpinned install | `pi update npm:@aeondave/pi-persona` |
|
|
41
|
-
| Git alternative | `pi install git:github.com/AeonDave/pi-persona@v1.
|
|
44
|
+
| Git alternative | `pi install git:github.com/AeonDave/pi-persona@v1.16.1` |
|
|
42
45
|
|
|
43
46
|
Restart Pi after updating. For a pinned install, install the new version or tag explicitly.
|
|
44
47
|
If switching from a Git install, remove that source first with
|
|
@@ -69,8 +72,12 @@ For example, specialists can investigate code paths, tests, and the API contract
|
|
|
69
72
|
Their findings return to the **same supervisor**, which integrates them, verifies the fix, and reports
|
|
70
73
|
the outcome. This is one possible workflow, not a fixed pipeline; dependent steps run in order.
|
|
71
74
|
|
|
72
|
-
Interactive delegation runs in the background by default.
|
|
73
|
-
|
|
75
|
+
Interactive delegation runs in the background by default. Results return automatically when the
|
|
76
|
+
supervisor is free; you can inspect or redirect a worker at any point.
|
|
77
|
+
|
|
78
|
+
Launch and control cards show the worker's name. Steering receipts preview the message sent;
|
|
79
|
+
expand with `Ctrl+O` (the default binding) to read it in full. A queued message is not proof that
|
|
80
|
+
the worker has acted on it.
|
|
74
81
|
|
|
75
82
|
| Key or command | Action |
|
|
76
83
|
|---|---|
|
|
@@ -135,6 +142,13 @@ everyday coding, or choose one for the work ahead.
|
|
|
135
142
|
These are editable starting points. Browse the bundled [personas](personas) and [worker agents](agents),
|
|
136
143
|
or read the [practical guide](docs/EXPERIENCE.md) for help choosing a workflow.
|
|
137
144
|
|
|
145
|
+
Strategies are not restricted to the similarly named persona: `council` can select `judge`, `magi`,
|
|
146
|
+
`debate`, `critic-loop`, or another installed shape when it adds value. Temporary `members` allow
|
|
147
|
+
custom role-based groups without team files. Model selection includes external arbiters. In councils
|
|
148
|
+
and flows, a provider failure or unavailable model can recover once on the supervisor's model, with
|
|
149
|
+
the switch visible and both attempts accounted; ordinary delegates keep explicit provider pins strict.
|
|
150
|
+
See [the reference](docs/REFERENCE.md) for an inline council example and recovery limits.
|
|
151
|
+
|
|
138
152
|
## Make it yours
|
|
139
153
|
|
|
140
154
|
Edit installed personas and agents in `~/.pi/agent/persona/agents/`, or add project-specific
|
|
@@ -169,4 +183,9 @@ npm test
|
|
|
169
183
|
```
|
|
170
184
|
|
|
171
185
|
Pi loads the TypeScript extension directly; there is no build step.
|
|
172
|
-
|
|
186
|
+
The [CI workflow](https://github.com/AeonDave/pi-persona/actions/workflows/test.yml) runs strict
|
|
187
|
+
typechecking, dependency auditing and the test suite on Linux and Windows. The OpenSSF badge links to the project's
|
|
188
|
+
scored supply-chain checks; it is not a certification that the code is free of vulnerabilities.
|
|
189
|
+
|
|
190
|
+
See [AGENTS.md](AGENTS.md) for contribution conventions and the [security policy](SECURITY.md)
|
|
191
|
+
for private vulnerability reporting. Licensed under [MIT](LICENSE).
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Security fixes target the latest published version of
|
|
6
|
+
[`@aeondave/pi-persona`](https://www.npmjs.com/package/@aeondave/pi-persona).
|
|
7
|
+
Older versions do not have a guaranteed backport policy. Check the
|
|
8
|
+
[release notes](https://github.com/AeonDave/pi-persona/releases) for fixes and
|
|
9
|
+
upgrade instructions. Keep your Pi host and Node.js runtime updated as well.
|
|
10
|
+
|
|
11
|
+
## Reporting a vulnerability
|
|
12
|
+
|
|
13
|
+
Use [GitHub private vulnerability reporting](https://github.com/AeonDave/pi-persona/security/advisories/new).
|
|
14
|
+
Do not open a public issue with exploit details, credentials, private session
|
|
15
|
+
logs, or other sensitive material. Ordinary bugs can use the public issue tracker.
|
|
16
|
+
|
|
17
|
+
Include the affected package version or commit, Pi and Node.js versions, operating
|
|
18
|
+
system, relevant configuration, expected security boundary, actual behavior, and
|
|
19
|
+
a minimal reproduction with synthetic data. Explain the impact and any safe
|
|
20
|
+
workaround you have verified. Do not test against other users' sessions or systems
|
|
21
|
+
without their permission.
|
|
22
|
+
|
|
23
|
+
Follow-up and disclosure coordination happen in the private advisory. This is a
|
|
24
|
+
maintainer-run project, with no guaranteed response or remediation deadline and
|
|
25
|
+
no paid bug bounty. Agree on public disclosure after triage so users can receive
|
|
26
|
+
a fix or mitigation before exploit details are published.
|
|
27
|
+
|
|
28
|
+
## Security boundaries
|
|
29
|
+
|
|
30
|
+
Pi extensions and installed persona/agent definitions are trusted local code and
|
|
31
|
+
configuration, not an OS sandbox. Capability checks and Exocom's cooperative file
|
|
32
|
+
claims do not isolate a malicious local process. A workspace join code is a
|
|
33
|
+
same-host routing reference, not an authentication secret. See the
|
|
34
|
+
[architecture](docs/ARCHITECTURE.md) for the actual trust boundaries.
|
|
35
|
+
|
|
36
|
+
Reports of capability bypasses, broker/Exocom trust violations, unsafe handling of
|
|
37
|
+
untrusted worker output, or unintended disclosure of session data are welcome.
|
|
38
|
+
Use synthetic credentials and payloads in reproductions.
|
|
39
|
+
|
|
40
|
+
The npm package uses Pi-provided peer dependencies rather than shipping another
|
|
41
|
+
Pi runtime. Development lockfile fixes do not update an installed user's host;
|
|
42
|
+
host vulnerabilities must also be addressed by updating Pi itself.
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -54,6 +54,10 @@ rejected with the run id to wait on, so a later call cannot slip past the in-bat
|
|
|
54
54
|
- **L3 — flow file.** `flows/<name>.flow.json` composes strategies into a resumable DAG.
|
|
55
55
|
|
|
56
56
|
You climb only when you want determinism, structure, or reuse. Nothing forces the higher tiers.
|
|
57
|
+
The `council` tool is a gateway to all installed strategies, not a universal instruction to vote on
|
|
58
|
+
routine work. Choose a strategy when its topology adds value; MAGI and Judge retain their specialized
|
|
59
|
+
persona focus. A caller can supply ephemeral `members` with inline roles/models/skills instead of a
|
|
60
|
+
named team, without persisting a team or switching personas.
|
|
57
61
|
|
|
58
62
|
## Binding invariants (I1–I7)
|
|
59
63
|
|
|
@@ -193,7 +197,8 @@ engine, telemetry, UI, and tool surfaces; it is not part of the transport/domain
|
|
|
193
197
|
constrained-turn allowlist), `install.ts` (the feature's composition adapter: session-scoped plane +
|
|
194
198
|
ledger + wait/tool/hook wiring).
|
|
195
199
|
- **`src/telemetry/`** — a generic, versioned observer/export contract for future plugins: projected
|
|
196
|
-
lifecycle metadata only, never an agent-message router or control surface.
|
|
200
|
+
lifecycle metadata only, never an agent-message router or control surface. See
|
|
201
|
+
[`TELEMETRY.md`](./TELEMETRY.md) for privacy, retention, writer leases, and shutdown behavior.
|
|
197
202
|
- **`src/persona/`** — identity: `persona.ts` (parse + `expandCouncilPreset` + `composeSystemPrompt`),
|
|
198
203
|
`controller.ts`, `gating.ts`, `orchestrate.ts`, `config-store.ts`, `state.ts` (last-selected persona),
|
|
199
204
|
`spine.ts` (the shared behavioral layer's SOURCE resolution — docs/SPINE.md; composition sits in
|
|
@@ -282,6 +287,19 @@ prevents an explicitly selected OpenAI or native Claude leg from silently moving
|
|
|
282
287
|
provider. (`"verification"` is a further terminal value that never appears on an `AgentResult` — see
|
|
283
288
|
`map`'s `verify` param in [`docs/STRATEGIES.md`](./STRATEGIES.md).)
|
|
284
289
|
|
|
290
|
+
Strategy/council/flow runs use a different, explicitly authorized recovery policy: the selected model
|
|
291
|
+
is tried first without arbitrary provider reroutes, then `makeSDK` may retry a `provider` or
|
|
292
|
+
`unknown-model` failure ONCE on the supervisor's current model. This main-only exception also applies
|
|
293
|
+
to saved and inline-pinned assignments; ordinary delegate provider pins remain strict. Missing main
|
|
294
|
+
models, repeated same-model attempts, stop/timeout/contract/agent/infrastructure failures, and exhausted
|
|
295
|
+
child/token budgets do not recover. Both attempts are accounted, and a warning plus result metadata
|
|
296
|
+
identify the switch. A per-role model assignment can supplement the legacy per-agent assignment;
|
|
297
|
+
preflight model selection includes external arbiters and other declared agent-valued parameters.
|
|
298
|
+
Live tree and telemetry labels use those participant identities for auxiliary actors too, with
|
|
299
|
+
inline model pins taking precedence. If distinct full roles share a short display hint, the display
|
|
300
|
+
keeps the hint (with `#N` suffixes for repeated node keys) but omits the uncertain model label rather
|
|
301
|
+
than borrowing another role's choice. Routing still resolves the full role key, not the display hint.
|
|
302
|
+
|
|
285
303
|
### MCP (and other `session_start`-scoped extensions) in sub-agents
|
|
286
304
|
|
|
287
305
|
**A sub-agent does NOT share the supervisor's MCP session, and an in-process sub-agent gets NO MCP at
|
|
@@ -403,7 +421,9 @@ never simultaneously a telemetry event, a routed message, and a UI source of tru
|
|
|
403
421
|
- **ProgressView** — a derived, read-only UI view computed *from* EngineEvents. Never authored, never
|
|
404
422
|
a source of truth. The `f9` agent tree and `peek` digest are ProgressViews.
|
|
405
423
|
|
|
406
|
-
Steering is
|
|
424
|
+
Steering is a supervisor-to-child control action, distinct from semantic Bus messages; requesting
|
|
425
|
+
steering does not establish that an active blocking join has been interrupted. The peek digest is
|
|
426
|
+
always a read-only ProgressView.
|
|
407
427
|
|
|
408
428
|
External telemetry is not a fourth communication plane: it is a generic observer/export contract that
|
|
409
429
|
future plugins may consume or produce, not an exclusive pi-persona protocol. It observes projected
|
|
@@ -459,6 +479,12 @@ for the supervisor and for explicit retrieval; the default TUI projection is del
|
|
|
459
479
|
failed legs first, a failed council/flow card leads with the cause in its title, and an
|
|
460
480
|
`intercom wait` card leads with the `N settled — X done, Y failed` tally (per-leg causes sit in the
|
|
461
481
|
body, below the preview cut, so `wait`'s own success doesn't get a `failed` prefix);
|
|
482
|
+
- async launch cards and targeted Intercom call headers use the worker's canonical alias/model,
|
|
483
|
+
matching the tree rather than promoting its routing ID to display identity. Launch/control receipts
|
|
484
|
+
persist identity snapshots for history rendering; aliases never become routing keys. Colliding
|
|
485
|
+
aliases carry a secondary ID, and legacy receipts without a recoverable name retain their ID fallback.
|
|
486
|
+
Accepted steering receipts retain the exact sent message: collapsed cards preview it, expansion
|
|
487
|
+
shows all sanitized text and the diagnostic ID. A queued receipt does not prove the worker acted;
|
|
462
488
|
- follow-up cards (`pi-persona`, exocom) retain their complete semantic content but render a bounded
|
|
463
489
|
preview until expanded; terminal escape/control sequences are removed from the visible projection;
|
|
464
490
|
- the sticky agent and exocom widgets have fixed row budgets — F9/`/agents` and paginated
|
|
@@ -606,15 +632,29 @@ a local process able to modify that directory is already inside the trust bounda
|
|
|
606
632
|
|
|
607
633
|
- **sync** — the supervisor actively blocks on the delegate/strategy call (results still stream); no
|
|
608
634
|
idle/peek/steer.
|
|
609
|
-
- **async** —
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
635
|
+
- **async** — interactive delegation is background-first; headless execution remains synchronous
|
|
636
|
+
by default. The prompt/runtime guidance is to continue independent work and, when only background
|
|
637
|
+
children remain, end the turn for automatic completion follow-ups rather than monitor or join the
|
|
638
|
+
whole batch. `intercom wait` collects a snapshot without blocking by default in interactive/RPC
|
|
639
|
+
sessions; settled results are reported and running children continue. Use `sync: true` for an
|
|
640
|
+
intentional bounded join. Headless sessions preserve the blocking default; `sync: false` requests a
|
|
641
|
+
snapshot. A snapshot does not wait, start timers/input hooks, or cancel children. Queued steering
|
|
642
|
+
does not release an explicitly active join. Input-triggered join interruption is
|
|
643
|
+
deliberately not implemented: a real Pi 1.0 SDK characterization shows steering can remain dormant
|
|
644
|
+
if delayed input hooks outlast the active run; no supported post-admission ordering guarantee
|
|
645
|
+
has been established. The supervisor otherwise returns control and
|
|
646
|
+
goes idle until a wake; the **peek watchdog** fires while async children run but stays SILENT unless
|
|
647
|
+
there is something to act on — a healthy background run should not interrupt. It surfaces on two independent
|
|
613
648
|
signals: a **fast** wakeup (`PI_PERSONA_PEEK_MS`, ~30s, `0` disables) when a child NEWLY crosses the
|
|
614
649
|
`STALL_FLAG_MS` (90s) stall window (a focused *possibly stuck* alert, framed patience-first — ask the
|
|
615
650
|
leg, don't probe its environment) or messages the supervisor; and a **slow routine check-in**
|
|
616
651
|
(`PI_PERSONA_CHECKIN_MS`, ~5 min, `0` disables) delivering the compact ProgressView digest — never
|
|
617
|
-
full transcripts — so the supervisor can catch a leg going off-track early.
|
|
652
|
+
full transcripts — so the supervisor can catch a leg going off-track early. Live supervisor asks
|
|
653
|
+
are derived from the exact engine handle's optional `isWaitingForSupervisor` predicate: tree/F9/peek
|
|
654
|
+
show waiting, and the watchdog suppresses false stalls until the ask settles. Parent clocks advance
|
|
655
|
+
with child engine events (liveness, not proof of useful work); parents are waiting only when every
|
|
656
|
+
live descendant branch is waiting.
|
|
657
|
+
Both let an idle
|
|
618
658
|
supervisor steer/stop a wedged or drifting child even with NO completion fired; the enforcing
|
|
619
659
|
backstop is the engines' hard wall-clock cap (above). The full digest is also on demand via `/peek`.
|
|
620
660
|
Progress tokens are labelled **cumulative input/output**, not context occupancy; cache-read/write
|
|
@@ -649,6 +689,11 @@ a persona directive lives at the TOP of the prompt and its pull decays as recent
|
|
|
649
689
|
only `status === "done"` runs by design — a failed background/`wait` leg already gets a failure
|
|
650
690
|
block, so a `[BLOCKED]` marker there doesn't also get the persistence note. Same marker, same leg,
|
|
651
691
|
different counterweight depending on how it was collected.
|
|
692
|
+
Nested calls through codemode's `ctx.executeTool` leave their programmatic result untouched.
|
|
693
|
+
Pi's explicit `parentToolCallId` supplies the parent identity; call-id string shapes are never
|
|
694
|
+
used to infer nesting. A bounded set of parent call ids carries report provenance through wrappers
|
|
695
|
+
only while their output relays a surrender marker; the outer model-visible result alone gets the
|
|
696
|
+
note/card. Suppressed reports produce neither, and turn/session settlement clears abandoned relay state.
|
|
652
697
|
- **The off switch covers every path.** `PI_PERSONA_NUDGE=off` silences DelegationNudge entirely and
|
|
653
698
|
PersistenceNudge on every collection path (sync result, background notifier, `intercom wait`).
|
|
654
699
|
|
package/docs/EXPERIENCE.md
CHANGED
|
@@ -40,20 +40,36 @@ ask for a monitor. Pi runs a small event-producing program and brings the result
|
|
|
40
40
|
supervisor is free. Keep the session open, and cancel a watch when its purpose ends. See
|
|
41
41
|
[time and event wakes](MONITORS.md) for examples and limits.
|
|
42
42
|
|
|
43
|
-
- **F9** opens the agent tree.
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
- **F9** opens the agent tree. Queued rows have not started their clocks. Live supervisor asks show
|
|
44
|
+
`waiting for supervisor`, not a stall; running rows otherwise show elapsed time and switch to
|
|
45
|
+
`⚠ stalled <duration>` after 90 seconds without progress — a suspicion, not proof of a deadlock.
|
|
46
|
+
Council parent clocks refresh on child engine events; that indicates liveness, not useful work.
|
|
47
|
+
A parent is waiting only when all its live descendant branches are waiting. Enter opens a selectable worker's output; `s` sends a course correction;
|
|
46
48
|
`x` requests cancellation and appears only when the run can actually be stopped, marking the row
|
|
47
49
|
`stopping…` at once; a stop that can't be applied says so instead of doing nothing. Escape goes
|
|
48
50
|
back or closes the panel.
|
|
49
51
|
- **`/peek`** gives a compact progress view. A quiet worker is a reason to inspect its last
|
|
50
52
|
progress and current activity, not to launch a duplicate immediately.
|
|
51
53
|
- **Background results arrive automatically.** A supervisor can continue independent work while
|
|
52
|
-
they run.
|
|
54
|
+
they run. When only background workers remain, end the turn and let completion follow-ups return
|
|
55
|
+
their results; do not monitor or poll healthy workers or automatically join the whole batch.
|
|
56
|
+
`intercom wait` snapshots immediately by default in interactive/RPC sessions; use `sync: true` for
|
|
57
|
+
an intentional bounded join when the next step depends on those results. Headless waits remain
|
|
58
|
+
blocking by default; pass `sync: false` for a snapshot.
|
|
53
59
|
- **Answer a waiting worker before joining it.** A coaching worker may need a decision from its
|
|
54
60
|
supervisor before it can finish. An unanswered question is actionable work.
|
|
55
61
|
- **Steering is a request.** Check the subsequent output to see whether the worker incorporated
|
|
56
|
-
it.
|
|
62
|
+
it. In-process workers can receive guidance mid-run; child-engine workers (including MCP/worktree
|
|
63
|
+
runs) receive it as a queued follow-up. Neither promises to interrupt arbitrary tool work, and
|
|
64
|
+
steering does not preempt an explicitly blocking `intercom wait`. End the supervisor turn rather
|
|
65
|
+
than join merely to idle. Check the terminal result after requesting cancellation; changes already
|
|
66
|
+
made are not undone.
|
|
67
|
+
|
|
68
|
+
Launch cards and targeted Intercom calls show the same worker alias as the live tree. A steering
|
|
69
|
+
receipt previews the message that was actually queued; expand it (`Ctrl+O` by default, or your
|
|
70
|
+
configured key) to read the full message and diagnostic run ID. Aliases are display names, not
|
|
71
|
+
addresses: tools still route by run ID, and duplicate aliases show a secondary ID to distinguish them.
|
|
72
|
+
Saved launch/control receipts keep their display names even after the runtime tracker is gone.
|
|
57
73
|
|
|
58
74
|
A truncated message includes a message id. The supervisor can retrieve its retained body with
|
|
59
75
|
`intercom { action: "message", messageId: "m1" }`. A worker's final report has a run id instead:
|
package/docs/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# pi-persona documentation
|
|
2
2
|
|
|
3
3
|
This folder contains the long-form documentation that defines how the project is designed and run.
|
|
4
|
+
It follows the current checkout; consult the [changelog](../CHANGELOG.md) for the release that
|
|
5
|
+
introduced a behavior. An `Unreleased` entry is not yet part of a published release.
|
|
4
6
|
|
|
5
7
|
## Canonical docs
|
|
6
8
|
|