@aeondave/pi-persona 1.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/AGENTS.md +249 -0
  2. package/CHANGELOG.md +260 -0
  3. package/LICENSE +21 -0
  4. package/README.md +172 -0
  5. package/agents/balthasar.md +32 -0
  6. package/agents/casper.md +33 -0
  7. package/agents/evidence-verifier.md +23 -0
  8. package/agents/melchior.md +32 -0
  9. package/agents/operator.md +63 -0
  10. package/agents/research.md +58 -0
  11. package/agents/reviewer.md +49 -0
  12. package/agents/scout.md +23 -0
  13. package/agents/verifier.md +21 -0
  14. package/assets/banner.png +0 -0
  15. package/assets/demo1.gif +0 -0
  16. package/assets/demo1.mp4 +0 -0
  17. package/assets/workflow.png +0 -0
  18. package/contracts/finding.contract.json +9 -0
  19. package/docs/ARCHITECTURE.md +727 -0
  20. package/docs/EXPERIENCE.md +96 -0
  21. package/docs/MONITORS.md +84 -0
  22. package/docs/README.md +53 -0
  23. package/docs/REFERENCE.md +408 -0
  24. package/docs/SPINE.md +152 -0
  25. package/docs/STRATEGIES.md +215 -0
  26. package/docs/TELEMETRY.md +9 -0
  27. package/flows/deep-review.flow.json +8 -0
  28. package/flows/gated-build.flow.json +9 -0
  29. package/package.json +106 -0
  30. package/personas/audit.md +29 -0
  31. package/personas/dev.md +52 -0
  32. package/personas/elite.md +256 -0
  33. package/personas/judge.md +32 -0
  34. package/personas/magi.md +41 -0
  35. package/personas/planner.md +37 -0
  36. package/personas/researcher.md +37 -0
  37. package/personas/swarm.md +38 -0
  38. package/personas/verify.md +31 -0
  39. package/presets/magi-rounds.preset.json +5 -0
  40. package/prompts/spine.md +11 -0
  41. package/prompts/spine.worker.md +9 -0
  42. package/src/agents/agent.ts +78 -0
  43. package/src/bridge.ts +209 -0
  44. package/src/bus/broker/client.ts +379 -0
  45. package/src/bus/broker/framing.ts +43 -0
  46. package/src/bus/broker/host.ts +407 -0
  47. package/src/bus/broker/messages.ts +87 -0
  48. package/src/bus/broker/paths.ts +31 -0
  49. package/src/bus/contact.ts +145 -0
  50. package/src/bus/inproc.ts +279 -0
  51. package/src/bus/peers.ts +114 -0
  52. package/src/core/brief.ts +356 -0
  53. package/src/core/capabilities.ts +114 -0
  54. package/src/core/config.ts +228 -0
  55. package/src/core/contract.ts +391 -0
  56. package/src/core/data-root.ts +260 -0
  57. package/src/core/discovery.ts +33 -0
  58. package/src/core/display-label.ts +47 -0
  59. package/src/core/fence.ts +151 -0
  60. package/src/core/format.ts +13 -0
  61. package/src/core/frontmatter.ts +202 -0
  62. package/src/core/models.ts +192 -0
  63. package/src/core/monitor.ts +415 -0
  64. package/src/core/naming.ts +42 -0
  65. package/src/core/nudge.ts +238 -0
  66. package/src/core/ownership.ts +102 -0
  67. package/src/core/permissions.ts +56 -0
  68. package/src/core/pi-compat.ts +50 -0
  69. package/src/core/seed.ts +770 -0
  70. package/src/core/session-identity.ts +89 -0
  71. package/src/core/time.ts +202 -0
  72. package/src/core/timer.ts +221 -0
  73. package/src/core/types.ts +28 -0
  74. package/src/engine/adapter.ts +257 -0
  75. package/src/engine/async.ts +898 -0
  76. package/src/engine/change-report.ts +143 -0
  77. package/src/engine/child.ts +532 -0
  78. package/src/engine/errors.ts +30 -0
  79. package/src/engine/fallback.ts +57 -0
  80. package/src/engine/handles.ts +21 -0
  81. package/src/engine/inproc.ts +857 -0
  82. package/src/engine/signals.ts +11 -0
  83. package/src/engine/spec-preflight.ts +33 -0
  84. package/src/engine/stream.ts +369 -0
  85. package/src/engine/worktree.ts +144 -0
  86. package/src/exocom/activation.ts +31 -0
  87. package/src/exocom/codes.ts +261 -0
  88. package/src/exocom/envelope.ts +180 -0
  89. package/src/exocom/gate.ts +6 -0
  90. package/src/exocom/guards.ts +45 -0
  91. package/src/exocom/inbound.ts +141 -0
  92. package/src/exocom/install.ts +970 -0
  93. package/src/exocom/ledger.ts +603 -0
  94. package/src/exocom/limits.ts +20 -0
  95. package/src/exocom/paths.ts +35 -0
  96. package/src/exocom/plane.ts +1116 -0
  97. package/src/exocom/registry.ts +307 -0
  98. package/src/exocom/scope.ts +42 -0
  99. package/src/exocom/status.ts +86 -0
  100. package/src/exocom/untrusted.ts +40 -0
  101. package/src/exocom/wait.ts +23 -0
  102. package/src/exocom/write-guard.ts +89 -0
  103. package/src/extension/broker-host.ts +181 -0
  104. package/src/extension/clock.ts +14 -0
  105. package/src/extension/engine.ts +321 -0
  106. package/src/extension/hooks.ts +796 -0
  107. package/src/extension/identity.ts +244 -0
  108. package/src/extension/shared.ts +175 -0
  109. package/src/extension.ts +2221 -0
  110. package/src/loader.ts +218 -0
  111. package/src/monitor/process.ts +116 -0
  112. package/src/monitor/session.ts +61 -0
  113. package/src/orchestration/flow-journal.ts +86 -0
  114. package/src/orchestration/flow-run.ts +301 -0
  115. package/src/orchestration/flow.ts +125 -0
  116. package/src/orchestration/judge.ts +78 -0
  117. package/src/orchestration/model-retry.ts +85 -0
  118. package/src/orchestration/parallel.ts +107 -0
  119. package/src/orchestration/params.ts +23 -0
  120. package/src/orchestration/reducers.ts +123 -0
  121. package/src/orchestration/render.ts +127 -0
  122. package/src/orchestration/roster.ts +133 -0
  123. package/src/orchestration/sdk.ts +326 -0
  124. package/src/orchestration/strategies/compete.ts +182 -0
  125. package/src/orchestration/strategies/council-rounds.ts +124 -0
  126. package/src/orchestration/strategies/critic-loop.ts +168 -0
  127. package/src/orchestration/strategies/debate.ts +126 -0
  128. package/src/orchestration/strategies/fanout.ts +20 -0
  129. package/src/orchestration/strategies/judge.ts +117 -0
  130. package/src/orchestration/strategies/magi.ts +239 -0
  131. package/src/orchestration/strategies/map.ts +327 -0
  132. package/src/orchestration/strategies/pair.ts +72 -0
  133. package/src/orchestration/strategies/pipeline.ts +91 -0
  134. package/src/orchestration/strategies/synthesize.ts +99 -0
  135. package/src/orchestration/strategy.ts +49 -0
  136. package/src/orchestration/types.ts +31 -0
  137. package/src/orchestration/voting.ts +126 -0
  138. package/src/persona/config-store.ts +215 -0
  139. package/src/persona/controller.ts +173 -0
  140. package/src/persona/gating.ts +82 -0
  141. package/src/persona/orchestrate.ts +83 -0
  142. package/src/persona/persona.ts +294 -0
  143. package/src/persona/spine.ts +221 -0
  144. package/src/persona/state.ts +28 -0
  145. package/src/telemetry/contract.ts +244 -0
  146. package/src/telemetry/paths.ts +14 -0
  147. package/src/telemetry/producer.ts +390 -0
  148. package/src/tools/council.ts +200 -0
  149. package/src/tools/delegate-tool.ts +637 -0
  150. package/src/tools/delegate.ts +661 -0
  151. package/src/tools/exocom-work.ts +328 -0
  152. package/src/tools/exocom.ts +476 -0
  153. package/src/tools/flow.ts +117 -0
  154. package/src/tools/intercom-tool.ts +292 -0
  155. package/src/tools/intercom.ts +181 -0
  156. package/src/tools/models.ts +39 -0
  157. package/src/tools/monitor.ts +66 -0
  158. package/src/tools/timer.ts +105 -0
  159. package/src/ui/agent-overlay.ts +526 -0
  160. package/src/ui/agent-tree.ts +307 -0
  161. package/src/ui/live-clock.ts +42 -0
  162. package/src/ui/model-picker.ts +160 -0
  163. package/src/ui/presentation.ts +170 -0
  164. package/src/ui/usage.ts +133 -0
  165. package/teams.yaml +27 -0
package/AGENTS.md ADDED
@@ -0,0 +1,249 @@
1
+ # AGENTS.md — pi-persona
2
+
3
+ A single Pi coding-agent extension for **supervised multi-agent orchestration**: async workers,
4
+ live steering, cross-session collaboration, and switchable personas. Loaded by Pi via tsx/jiti —
5
+ no build step. Design contract (binding on any conflict): [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md);
6
+ the orchestration layer in depth: [`docs/STRATEGIES.md`](docs/STRATEGIES.md);
7
+ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
8
+
9
+ ## Commands
10
+
11
+ - Typecheck (must stay clean): `npm run typecheck` (`tsc --noEmit`, strict)
12
+ - All tests: `npm test` · unit only: `npm run test:unit`
13
+ - One file: `node --import tsx --import ./test/setup/hermetic-env.ts --test test/unit/core/frontmatter.test.ts`
14
+ - The second `--import` is the hermeticity choke point: it strips the whole `PI_PERSONA_*`
15
+ namespace and pins `PI_AGENT_DIR` at a throwaway dir before any test module loads, so a
16
+ variable exported in your shell (or by CI) cannot reconfigure the extension under the suite.
17
+ A test that exercises a variable sets it for itself, after that has run. Drop the flag and you
18
+ are testing your shell, not the code.
19
+ - Live end-to-end (REAL model calls, spends tokens): `npm run drive -- --persona <name> --model <provider/id> "<prompt>"`
20
+ - Control ops: `LIVE_MODEL=<provider/id> node --import tsx scripts/control-test.mjs` (STEER/STOP/RESUME)
21
+ - Models must be **provider-qualified**, e.g. `claude-pro-max-native/claude-opus-4-8` or `.../claude-haiku-4-5`.
22
+
23
+ ## Conventions
24
+
25
+ - **Erasable-syntax-only** TS (no enums / namespaces / parameter-properties) — runs under
26
+ strip-types, tsx, jiti, Bun. `erasableSyntaxOnly` is on; keep it that way.
27
+ - tsconfig is strict + `exactOptionalPropertyTypes` + `noUncheckedIndexedAccess` +
28
+ `noUnusedLocals` + `noUnusedParameters`. Keep `tsc` clean before moving on.
29
+ - `src/core/*` is **pure** (no Pi imports) and unit-tested. Import host packages from
30
+ `@earendil-works/pi-*`; never bundle copies.
31
+ - npm publishes as `@aeondave/pi-persona`. Pi supplies the four `@earendil-works/pi-*` packages
32
+ and `typebox`: keep them as `peerDependencies: "*"` with development-only copies, never runtime
33
+ dependencies. The supported host floor lives in `MIN_PI_VERSION` and the README. Keep the npm
34
+ `files` allowlist explicit for docs/artwork, inspect `npm pack --dry-run`, and never publish drafts.
35
+ - **Cross-OS**: use Pi's spawn/kill/path/temp helpers (`getPiInvocation`, `killProcessTree`), not raw
36
+ `child_process`. Windows kill goes straight to `taskkill /F /T`; always attach an `error` listener.
37
+ - Two engines behind the `StrategyEngine` seam: **InProcessEngine** (`engine/inproc`,
38
+ `createAgentSession`, DEFAULT) and **ChildProcessEngine** (`engine/child`, spawns `pi --mode json -p`,
39
+ the correctness baseline + the path worktree isolation uses). Opt out with `PI_PERSONA_ENGINE=child`.
40
+ BOTH enforce `RUN_LIMITS.timeoutMs` as an **idle window** (no events/output ⇒ abort; the inproc
41
+ watchdog is disabled for coaching children that may legitimately block on a supervisor reply) AND
42
+ `PI_PERSONA_AGENT_MAX_MS` as an **opt-in hard wall-clock cap** (lifetime ceiling armed once, never
43
+ reset — catches a busy loop the idle window never does; OFF by default (0 = unlimited) so a healthy,
44
+ progressing child runs to completion, set `<ms>` to arm it) AND
45
+ `PI_PERSONA_AGENT_STARTUP_MS` as a **startup deadline** (a child that makes ZERO progress — no
46
+ completed turn / tokens / streamed output — within the window is killed as a stalled start; the
47
+ first real progress cancels it, so a slow-but-streaming turn is never touched; default 300000,
48
+ `0` disables). It fast-fails the "never started" case the generous idle window is too slow for —
49
+ notably a headless `mcp: true` leg whose `pi-mcp-adapter` hangs on interactive OAuth; `adapter.ts`
50
+ turns that (turns===0 + `spec.mcp`) into a clear pre-auth remedy instead of an opaque timeout.
51
+ The child engine delivers the task over **stdin** (`pi -p` prepends piped stdin) — never argv,
52
+ which would hit Windows' ~32 KiB command-line cap on flow-phase tasks. Async delegate launches
53
+ share one `maxConcurrency` semaphore (`Semaphore` in `orchestration/parallel.ts`), so an async
54
+ fan-out can't open more concurrent sessions than a sync one.
55
+ Each strategy SDK also gates every `agent()` call through one semaphore, including direct
56
+ `Promise.all` calls; `parallel` overrides cannot raise its concurrency ceiling. Token budgets
57
+ gate admission using completed usage, so already-running legs can overshoot the threshold.
58
+ In-process cancellation and deadlines cover session construction; coaching exemptions apply
59
+ after it finishes. A cancelled factory's late session is disposed, but its ref-counted guard
60
+ stays held until the factory settles because Pi's loader itself cannot be forcibly cancelled.
61
+ - **Cross-process broker** (`src/bus/broker/{paths,framing,messages,host,client}.ts`, on by default,
62
+ spec B1-B7; `PI_PERSONA_BROKER=off` restores pre-broker spawn): session-scoped (POSIX socket /
63
+ Windows named pipe under the session id), supervisor-hosted, lazily started on the FIRST actual
64
+ child-engine build (a `PI_PERSONA_ENGINE=child` run, any `isolation: worktree` leg, or an
65
+ `mcp: true` leg — those ALWAYS use the child engine). It is a RELAY into the local `InProcessBus`:
66
+ a connected child is indistinguishable from an in-process one, so the supervisor side (intercom,
67
+ idle notifier, f9, peek) is unchanged BY CONSTRUCTION. It gives child-process runs
68
+ `contact_supervisor`/`contact_peer` AND **steer** (closing the child-engine steer gap —
69
+ `intercom steer`/f9 `s` work on both engines; a child's steer is follow-up-queued, not mid-turn
70
+ injection). Off ⇒ `deps.broker` is never built, the host never starts, and the child spawns
71
+ byte-identical to pre-broker pi-persona — see
72
+ [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md#the-comm-plane-in-practice).
73
+ - **Provider fallback**: `buildEngine` wraps the engine in `withModelFallback` (`engine/fallback.ts`).
74
+ A provider-qualified `spec.model` is an explicit provider/billing pin and is strict by default:
75
+ a failed `openai-codex/...` leg never silently moves to OpenCode, and a failed
76
+ `claude-pro-max-native/...` leg never silently moves to a metered third-party route. Unpinned/default
77
+ selections may retry the SAME model id only through the data-driven, family-compatible provider
78
+ policy (OpenAI-family → OpenAI providers; Claude-family → the native Claude provider). A caller may
79
+ explicitly opt a pinned run into cross-provider recovery. Only `failureKind === "provider"` reroutes;
80
+ abort/timeout/contract/unknown/agent are terminal.
81
+ Engines classify the cause on the `AgentResult` (`failureKind` + resolved `modelUsed`); keep those
82
+ set when you touch `inproc.ts`/`adapter.ts` or the fallback silently stops working.
83
+ - **Fork-bomb guard**: children run with env `PI_PERSONA_DISABLE=1` so pi-persona self-disables inside
84
+ them. NEVER pass `noExtensions` (it blocks the pi-claude auth provider). The guard is **ref-counted**
85
+ in `inproc.ts` — keep it concurrency-safe (parallel strategies build several sessions at once). Both
86
+ engines also export `PI_PERSONA_LEG=1` for a delegated leg — a **dedicated** marker (unlike the
87
+ user-settable `PI_PERSONA_DISABLE`) so a companion extension can tell a real leg from a disabled
88
+ supervisor; set it in lockstep with the disable guard (in-process guard + child `spawn` env).
89
+ - Three disjoint comm planes: **EngineEvent** (runtime) / **Bus Msg** (semantic, `src/bus`) /
90
+ **ProgressView** (derived UI, never a source of truth). Capabilities are enforced at call time via
91
+ one `EffectiveCapabilities`, never prompt-only. Per-run pinning: `contract@hash` is frozen at start.
92
+ Same principle for retries: async failures are ALWAYS reported to the supervisor (never suppressed);
93
+ blind retry loops are stopped by the runtime `DelegationLedger` (an identical agent+model+task
94
+ delegation that failed twice is vetoed before it spawns).
95
+ - 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. Async runs
97
+ are joined with intercom `wait` (bounded ≤ the bus-ask timeout; collected results are discarded from
98
+ the pending completion follow-up so they are never double-reported). In interactive sessions
99
+ `delegate` is background-by-default (`sync: true` opts a call out; headless `pi -p` defaults to
100
+ sync so the single turn carries the result).
101
+ Message ids and run ids are separate: `intercom message { messageId }` retrieves retained bus
102
+ text, `intercom result { to: runId }` retrieves a settled run. Both explicit and automatic inbox
103
+ drains retain bounded history (256 messages / 256,000 body characters). Ask settlement clears
104
+ unread and buffered prompts; broker errors/cancellation remain correlated to the original request.
105
+ - **Sub-agent output is untrusted** — wrap it with `fenceUntrusted` (in `extension.ts`) before it
106
+ reaches the supervisor as a follow-up or tool result (prompt-injection defense).
107
+ - **Delegation nudges** (`core/nudge.ts`, on by default): a `tool_result` hook watches the supervisor's
108
+ OWN tool stream and, when a delegating persona grinds heavy work by hand (output burn since the
109
+ last `delegate`/`council` crosses a threshold),
110
+ APPENDS a compact labelled checkpoint to that command's result for the model AND emits the same
111
+ checkpoint as a durable, expandable `pi-persona-nudge` TUI-only entry for the operator. It is never
112
+ hidden/context-only: tool renderers may suppress their own `content`, but cannot suppress the
113
+ separate card. This is runtime reinforcement in recent context, where a top-of-prompt persona
114
+ directive has decayed. Pure state machine (`DelegationNudge`); gated to
115
+ personas holding the `delegate` tool; sub-agents run in separate sessions so the hook only sees the
116
+ supervisor. Its counterweight is **`PersistenceNudge`** — a leg that comes back `[BLOCKED]`/`FLAG:
117
+ UNKNOWN` gets a "don't bank it yet" reminder on each of the three delivery paths (sync result,
118
+ background completion, `intercom wait` — the last two via `engine/async.ts`'s `renderCompletion`), but
119
+ they do not scan the same text: `observe` scans the whole sync tool result (which `aggregateResults`
120
+ fills with every leg's body, failures included), while `renderCompletion` scans only `status: "done"`
121
+ runs. A background leg that FAILED while emitting `[BLOCKED]` therefore gets the failure block but no
122
+ persistence note — deliberate (see the `renderCompletion` doc comment), not a bug to "fix" silently.
123
+ `config.nudge` (`PI_PERSONA_NUDGE=off`) silences all of it: the `tool_result` hook (the by-hand
124
+ reminder and the sync-result persistence one) and both `renderCompletion` call sites, which take
125
+ their `scan` through the same gate — so a background/`intercom wait` report carries no note either.
126
+ Its standing counterpart is the **delegation brief** (`core/brief.ts`): `before_agent_start` appends
127
+ a live, capability-filtered roster (agents/teams/flows) + a hand-off default to the
128
+ system-prompt TAIL every turn — discovery that survives context burn.
129
+ - **Sibling peer comm (in-process)**: a strategy can opt a run into direct sibling messaging
130
+ (`AgentRunSpec.peers` — the `debate` strategy does). The child gets a `contact_peer` tool
131
+ (`bus/peers.ts`): `list`/`send`, ONE-WAY only (blocking stays supervisor-only, so peers can
132
+ never deadlock), peer list scoped per engine instance (never the whole bus), send budget 20,
133
+ message body limit 8,000 characters (oversized sends do not consume the budget).
134
+ Delivery: the in-process engine's bridge steers incoming bus messages into the child session,
135
+ fenced with the sender attributed OUTSIDE the fence — the same bridge delivers the supervisor's
136
+ `intercom send` (previously a dead letter). Gated by `EffectiveCapabilities.canUseBus` (OFF iff
137
+ the persona explicitly denies `intercom`). The child engine ignores `peers`.
138
+ Design: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md#the-comm-plane-in-practice) + [`docs/STRATEGIES.md`](docs/STRATEGIES.md).
139
+ On the peer plane: `debate` and `pair` always; `map`/`synthesize` opt-in via `params.peers`.
140
+ `magi`/`judge`/`fanout` stay peer-less BY DESIGN — independence is their bias guard
141
+ (uncorrelated errors; an anonymised ballot cannot survive members who talked) — do not "fix"
142
+ this. `compete` runs its competitors with `isolation: worktree` (REQUIRES a clean git repo; missing
143
+ repo/dirty checkout/worktree failure fails closed and never falls back to the real tree) and returns
144
+ the winning diff for the SUPERVISOR to apply.
145
+ - **exocom** (`src/exocom/*`, `src/tools/exocom*.ts`; opt-in `PI_PERSONA_EXOCOM=1` / `--exocom`,
146
+ capability-gated): a plane apart from everything above — those are all INTERNAL to one supervisor's
147
+ own run (hierarchical, session-keyed children); exocom is FLAT and EXTERNAL, between independent
148
+ top-level pi instances sharing one selected scope, no parent/child relationship. Bare `--exocom`
149
+ keeps the current workspace scope; exact `--exocom=Ab0T` joins that existing workspace's scope from
150
+ another cwd through a persistent, collision-aware, case-sensitive four-character Base62 alias.
151
+ The scope selects registry/transport/ledger/artifacts, while every peer advertises its actual home
152
+ workspace id/code/safe label so external file sets are explicit. A foreign peer is advisory for
153
+ writes: it can inspect its own files and use postcards/ask/answer/wait/progress/release, but
154
+ `exocom_claim` is inactive and rejected because the ledger's paths are repository-relative to the
155
+ scope workspace. The code is a same-host/same-agent-dir join reference, not authentication.
156
+ Postcards remain one-way and non-blocking: `exocom_list`/`exocom_send`
157
+ plus `exocom_name` (a reply is a send with `in_reply_to` set). The separate shared JSONL work
158
+ ledger adds `claim`/`ask`/`answer`/`decline`/non-blocking `wait`/`progress`/`release`: overlapping
159
+ open write sets NACK atomically, and a pending targeted ask gates that participant to answer/decline,
160
+ read-only tools, and `exocom_name` identity metadata. Semantic frames are signed immediate-wake signals; the ledger is authoritative
161
+ if delivery is deferred. This is cooperative runtime coordination, not OS authorization. All ten
162
+ tools remain in `EXOCOM_TOOL_NAMES` (with `claim` withheld for a foreign member), targeted denies win independently, and joining requires
163
+ `canUseBus` plus at least one callable closer (`answer` or `decline`) so a published peer cannot be
164
+ wedged by an obligation it has no way to settle. If `exocom_name` is permitted, an unnamed top-level
165
+ Pi is prompted to invent a task-derived call-sign on its first user or inbound peer turn
166
+ (no catalog or extra model call). Naming is metadata permitted during pending asks, without
167
+ settling them; a targeted deny suppresses the prompt. Session identity is shared with standalone
168
+ `agent_name` and persisted across resume/persona changes. Until a handle is chosen, its actionable
169
+ naming bootstrap is delivered through the `context` hook because custom Exocom wakes can bypass
170
+ `before_agent_start`; after selection the hook stays silent. The session-hash suffix of a qualified target survives renames and telemetry resolves the
171
+ same canonical session.
172
+ Reuses the broker's wire framing
173
+ (`bus/broker/framing.ts`) and the
174
+ core fence (`fenceUntrusted`/`attributeInbound`) — no new trust-sensitive code path; inbound
175
+ attribution is resolved from the registry, never the envelope's self-reported `from_name`.
176
+ Design: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md#exocom--the-external-plane).
177
+
178
+ ## Testing
179
+
180
+ - TDD: write the failing test first for `core/*` and any behavior change; watch it fail, then fix.
181
+ - Done = `npm run typecheck` clean **and** full suite green. The suite has **two** intentional skips,
182
+ both Windows-only — the runner reports `skipped 2` on Windows and `skipped 0` elsewhere (see
183
+ Accepted diagnostics).
184
+ - When touching engines / strategies / the comm plane, also verify with a live `scripts/drive.ts`
185
+ run (concurrency, steer, worktree, and contact_supervisor are not fully provable from unit tests).
186
+
187
+ ## Project structure
188
+
189
+ - Session identity: `src/core/session-identity.ts` defines validated names and session-bound
190
+ persistence; `src/extension/identity.ts` registers `agent_name` and the pre-name context bootstrap.
191
+ Exocom uses that same state. A delegate's optional `AgentRunSpec.name` is leader-assigned
192
+ display identity, propagated to both engines without changing routing ids.
193
+ Runtime metadata guidance belongs in the stable supervisor system prompt, not a new user-like
194
+ acknowledgement message. Keep initial setup/actionable asks working, preserve user-visible history,
195
+ and never re-inject a chosen identity. Progress `tokens` is cumulative input/output usage, not live
196
+ context occupancy; labels must make that distinction explicit.
197
+
198
+ - Session clock and event wakes: `timer now` refreshes the run-start clock snapshot; timer alarms
199
+ require an explicit timezone for absolute times. `monitor` runs bounded event-producing programs
200
+ (`output`) or jobs (`exit`), with both `monitor` and `bash` permissions. Pure lifecycle is in
201
+ `src/core/monitor.ts`, process/delivery adapters in `src/monitor/`; use the existing idle notifier
202
+ and process-tree cleanup. Session-scoped, no restoration on restart. See [`docs/MONITORS.md`](docs/MONITORS.md).
203
+
204
+ - `src/core/` — pure kernel: frontmatter, permissions, contract (+`parseContract`), config, discovery, fence (`fenceUntrusted`), brief (`buildDelegationBrief` — the per-turn roster + standing hand-off default; `buildExocomBrief` — the per-turn exocom peer roster, the peer-vs-sub-agent split, and the relevance bound on a peer exchange), timer (`TimerScheduler` — the alarm engine behind the `timer` tool), types.
205
+ - `src/engine/` — `child.ts`, `inproc.ts` (default), `adapter.ts`, `async.ts` (async tracker/peek), `worktree.ts` (git-worktree isolation), `stream.ts` (event→state).
206
+ - `src/orchestration/` — `sdk.ts` (`agent`/`parallel`/`reduce`), `strategy.ts` (registry), `strategies/*.ts`, `voting.ts`, `flow*.ts` (DAG + JSONL journal + checkpoint gates), `roster.ts` (teams + `rosterSpec`: a roster member is a bare name OR an inline `{ agent, role, model, skills }` that specialises one agent — every strategy runs members through `rosterSpec`).
207
+ - `src/bus/` — `inproc.ts` (handle-based bus: send/ask/reply/onMessage), `contact.ts` (child `contact_supervisor` tool), `peers.ts` (child `contact_peer` sibling tool — one-way, engine-scoped), `broker/` (cross-process relay, on by default: `paths.ts`/`framing.ts`/`messages.ts` pure, `host.ts`/`client.ts` over `node:net`; `PI_PERSONA_BROKER=off` restores pre-broker spawn). `src/bridge.ts` — the child-mode-only wiring loaded when `PI_PERSONA_BUS` is set.
208
+ - `src/persona/` — `persona.ts` (parse + `expandCouncilPreset`), `controller.ts`, `gating.ts`, `orchestrate.ts`, `config-store.ts`.
209
+ - `src/tools/` — `delegate.ts`, `intercom.ts`, `exocom.ts`. `src/ui/` — agent-tree/overlay, model-picker, `presentation.ts` (the collapsed-card compaction/sanitization helpers), `usage.ts`. `src/extension.ts` — the single ExtensionFactory (wires tools/commands/hooks/engines).
210
+ - Bundled data-driven assets (discovery precedence builtin < user `~/.pi/agent/persona` < project `.pi/`):
211
+ `personas/*.md`, `agents/*.md` (personas+agents share a folder, split by `persona: true` — a
212
+ persona and an agent must NOT share a name; e.g. `researcher` is the persona, `research` the agent),
213
+ `teams.yaml`, `flows/*.flow.json`, `contracts/*.contract.json`, `presets/*.preset.json`.
214
+ - Personas/agents load ONLY from the user dir (`~/.pi/agent/persona/agents`) and project `.pi/agents` —
215
+ the bundled `personas/`+`agents/` are a **seed source, not a live discovery layer**, so a fresh
216
+ install shows NO personas until the user installs them. `/persona seed` copies missing defaults
217
+ in, `/persona restore` force-restores originals (`src/core/seed.ts`). First-run auto-install is
218
+ **opt-in**: off by default, enable with `PI_PERSONA_SEED=on` (guarded once by marker
219
+ `.pi-persona-seeded`). Contracts/presets/teams keep a builtin layer (they aren't personas).
220
+ - `scripts/` — `drive.ts` (headless `pi -p` log) + `drive-status.ts` (its pure exit-code/status projection), `control-test.mjs`, `flow-test.ts`, `live-suite.mjs` (every strategy/mode against a real model), `exocom-smoke.mjs` (real socket/pipe round-trip, chat + semantic claim; run via `npm run smoke:exocom`). `test/` — unit + integration.
221
+
222
+ ## Adding a new X (data-driven — usually no core change)
223
+
224
+ 1. **Strategy**: add `src/orchestration/strategies/<name>.ts` (export a `Strategy`), register it in `strategy.ts` `BUILTINS`, add a unit test.
225
+ 2. **Persona**: `personas/<name>.md` — frontmatter `persona: true` + optional `council:` / `orchestration:` / `delegation:` / `coaching: true`; runtime behavior is field-driven, never keyed to a persona name.
226
+ 3. **Agent**: `agents/<name>.md` — optional `tools`, `model`, `isolation: worktree`, `mcp: true`
227
+ (routes the leg through the child engine so `pi-mcp-adapter` initializes and its `mcp*`/direct
228
+ tools work — the default in-process engine leaves them "not initialized"; also settable per-leg
229
+ via `delegate`'s `mcp: true` / `AgentRunSpec.mcp`. Pass a server session id in the task to share
230
+ an HTTP backend's state).
231
+ 4. **Team**: one line in `teams.yaml` (`name: [agent, ...]`), or per-member `- { agent, role, model?, skills? }` to build an ensemble of perspectives from ONE agent (e.g. `review` is one `reviewer` × 3 lens roles). Same-agent members are disambiguated in the live tree by a role hint (`reviewer · SECURITY`) via `rosterNodeKeys`/`roleHint` (`roster.ts`) + the SDK's per-run key (`sdk.ts`), so three lenses show as three steerable nodes — keep the seeding loops and the SDK key derivation in lockstep if you touch either.
232
+ 5. **Flow**: `flows/<name>.flow.json` — phases + `needs`, optional `gate: true` (checkpoint).
233
+ 6. **Contract**: `contracts/<name>.contract.json` (request via `outputContract`). **Preset**: `presets/<name>.preset.json`.
234
+
235
+ ## Boundaries / deferred (do NOT rebuild as "missing")
236
+
237
+ - **`context: fork`** is deliberately deferred: `fresh` is the right child default. The
238
+ **cross-process bus broker** is NO LONGER deferred — see the engine/broker bullet above and
239
+ [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
240
+ - This repo is `D:\Sources\pi-persona`. The separate `D:\Sources\pi-subagents-persona` (flat
241
+ `src/index.ts`, `VALID_THINKING`, …) is a **legacy** package — different project. Always use
242
+ explicit `pi-persona` paths in shells and sub-agent prompts (the env default cwd is the legacy one).
243
+
244
+ ## Accepted diagnostics
245
+
246
+ - Two skipped Windows-only cases in `test/integration/child-engine.test.ts` (force tree-kill and external-signal handling) — intentional, do not "fix".
247
+ - `test/integration/broker.test.ts` (real socket/pipe round-trip) runs UNGATED on every platform,
248
+ Windows named pipes included — it proved reliable across repeated runs; do not add a skip to it
249
+ without first confirming genuine flakiness (see the v0.5 broker task report).
package/CHANGELOG.md ADDED
@@ -0,0 +1,260 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project follows the version scheme
5
+ used in its [GitHub releases](https://github.com/AeonDave/pi-persona/releases).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [1.15.2](https://github.com/AeonDave/pi-persona/releases/tag/v1.15.2) - 2026-09-28
10
+
11
+ ### Distribution
12
+
13
+ - First npm publication on 2026-09-29 as `@aeondave/pi-persona@1.15.2`, with the same runtime
14
+ version. The existing GitHub tag is unchanged; npm adds scoped package metadata and installation
15
+ instructions. The registry's `gitHead` identifies the packaging commit.
16
+ - Declare Pi-provided packages and TypeBox as wildcard peers, with pinned development copies only.
17
+ Explicitly allowlist public documentation and selected artwork; exclude drafts and development
18
+ harnesses from the npm tarball. Add the gallery banner and F8 persona-switching video preview.
19
+ - Lead the README and package description with supervised multi-agent orchestration, live steering,
20
+ and cross-session collaboration; personas configure that workflow.
21
+
22
+ ### Fixed
23
+
24
+ - Add stable supervisor-side runtime guidance against repeated identity/prefetch acknowledgements,
25
+ including resumed sessions and custom/replace personas without the optional spine. The naming
26
+ bootstrap now explicitly ends at the successful tool action. No extra corrective turns are injected,
27
+ no history is rewritten, and explicit user questions or unresolved actions remain actionable.
28
+ - Replace conversational naming confirmations with a neutral saved/unchanged handle receipt, shared
29
+ by the model-facing result and the visible renderer.
30
+ - Label async progress token counts as cumulative input/output rather than leaving them open to
31
+ interpretation as current context usage. Routine updates distinguish status from a new user task.
32
+
33
+ ### Changed
34
+
35
+ - Delegation, failed-hand-off, and persistence nudges are now compact labelled checkpoints with an
36
+ explicit trigger and action. Token counts are identified as estimates, session-bound work is
37
+ separated from delegable work, and each synchronous checkpoint is mirrored from its semantic tool
38
+ result into a durable, expandable TUI-only card. This keeps it visible even when a tool renderer
39
+ suppresses result content without duplicating it into model context or triggering another turn.
40
+ - Refresh the README with a clearer installation guide, the Prism banner, and an illustrated
41
+ supervisor/worker workflow.
42
+
43
+ After updating, let active delegated runs settle, then restart Pi or use `/reload` before the next
44
+ user turn. `/persona reload` refreshes persona definitions, not extension code. Existing chat
45
+ history is preserved; the runtime guidance discourages repetition without filtering model output.
46
+
47
+ ## [1.15.1](https://github.com/AeonDave/pi-persona/releases/tag/v1.15.1) - 2026-09-20
48
+
49
+ ### Changed
50
+
51
+ - Development validation now uses the current Pi `0.85.1` packages, TypeBox `1.3.34`, and the
52
+ current Node 22 tooling line while retaining the supported Pi `>=0.83.0` runtime floor.
53
+ - Release metadata is now guarded as one version set across the package manifest, lockfile,
54
+ telemetry producer, changelog, and README install pin.
55
+
56
+ ### Fixed
57
+
58
+ - A chosen session identity is no longer re-injected as a hidden user-like message before every
59
+ provider request. The context hook now emits only the actionable, pre-name bootstrap, preventing
60
+ tool-loop continuations from narrating repeated identity confirmations.
61
+ - Repeating `agent_name` with the active handle reports it as unchanged instead of announcing a
62
+ fresh identity again.
63
+
64
+ ## [1.15.0](https://github.com/AeonDave/pi-persona/releases/tag/v1.15.0) - 2026-09-18
65
+
66
+ ### Added
67
+
68
+ - Live elapsed-time clock and a stall badge (`⚠ stalled <duration>`) on every running row in the
69
+ agent tree and the F9 overlay; cancelling a worker now marks its row `stopping…` immediately, and
70
+ a stop that cannot be applied says so instead of doing nothing. A row that is only queued (not yet
71
+ running) no longer shows the stall badge.
72
+ - A warning toast announces a provider-fallback reroute (`<agent>: <from> failed, retrying on
73
+ <to>`) instead of switching silently.
74
+ - A non-worktree leg's result now gets a "files changed" report appended: every path `git status`
75
+ saw change while the leg ran, flagging anything outside the leg's own declared `writeSet`. Costs
76
+ two `git status` spawns per leg (down from four — the repository root is resolved once and
77
+ reused, skipping a redundant `rev-parse` gate); `PI_PERSONA_LEG_CHANGE_REPORT=off` disables it.
78
+ - A supported Pi host version floor (0.83) is declared once and enforced consistently:
79
+ `peerDependencies`, `/doctor`'s new `pi: <version> (requires ≥ 0.83.0)` line, and the README.
80
+ - `exocom_status` (tool) and `/exocom` (command) now show who owns what in the current Exocom
81
+ scope: your claims, peers' claims, and asks waiting on either side.
82
+ - A `write`/`edit` whose path lands inside a peer's open Exocom claim is now blocked once with a
83
+ reminder to coordinate (`exocom_ask`) or claim the path first; the identical retry is allowed
84
+ through.
85
+ - The `map` strategy gains two declared params: `ownership` (`"off"`/`"declare"`/`"enforce"` —
86
+ ignore, record, or gate on the splitter's per-item write-set before any worker spawns) and
87
+ `verify` (an opt-in, read-only reviewer pass per completed item), plus an always-on per-item
88
+ status ledger (`structured.items`: `completed`/`failed`/`not-run`) both params report into.
89
+ - `npm run smoke:exocom` runs the Exocom comm-plane smoke script, now checked against
90
+ `InboundDeps` and carrying a semantic-frame check.
91
+
92
+ ### Changed
93
+
94
+ - Agent-tree UI work is now bounded to the terminal's 16 ms frame cadence: structural fan-out and
95
+ streamed progress share one sticky-widget composition, unchanged widget/status publications are
96
+ suppressed, the F9 overlay rebuilds lazily on the next paint, and tree rendering indexes the
97
+ hierarchy once instead of rescanning the whole fan-out for every row. Explicit stop feedback and
98
+ shutdown clearing remain synchronous.
99
+ - The idle and startup watchdogs now stay armed for every child, coaching or not, and consult the
100
+ bus (in-process) or the broker (child-process) for a live pending ask before closing a silent
101
+ leg — re-arming while a supervisor reply is genuinely pending, closing it once the silence is
102
+ real. The hard wall-clock cap (`PI_PERSONA_AGENT_MAX_MS`) remains the one unconditional backstop.
103
+ - `SupervisorBroker` consolidates the supervisor host's lifecycle into one class: a failure now
104
+ warns once instead of repeatedly, children spawn bus-less while the broker is down rather than
105
+ failing outright, and `/doctor` reports the broker's real state.
106
+ - Every Exocom surface that renders a peer-authored field (the status view, the write-guard
107
+ warning) now goes through one shared sanitizer; the write guard also matches an absolute path
108
+ against a claim correctly and bounds how many paths a single warning names.
109
+ - Internal deduplication with no behavior change: `delegate`'s unknown-agent/contract error text,
110
+ the broker client's ask/list reason text, `SupervisorBroker`'s state reads, `AgentTree`'s
111
+ add/update field copy, `spec-preflight`'s failure-result skeleton, the agent overlay's
112
+ hint/notice rendering, and every capped-list rendering now share one helper each; a few dead
113
+ exports and some `/doctor` wording were tidied along the way.
114
+
115
+ ### Fixed
116
+
117
+ - The engine's unknown-agent/unknown-contract preflight is now one shared module; a
118
+ contract-not-found error names the installed contracts, and `delegate` rejects an unknown
119
+ `outputContract` before spawning anything, checked across a whole parallel batch.
120
+ - Worktree git operations now run asynchronously, so an isolated leg can no longer freeze the host
121
+ session; worktree cleanup is also guarded so a cleanup failure cannot take the run down with it.
122
+ - A dropped broker connection now fails fast, and the bridge reports `⇄ offline` instead of hanging
123
+ on the next ask.
124
+ - `exocom_wait` now wakes a waiting supervisor as soon as the peer it was waiting on leaves the
125
+ pool, instead of waiting out the full timeout.
126
+
127
+ ### Removed
128
+
129
+ - `RunLimits.maxDepth` had no runtime reader — nesting depth is actually enforced structurally (a
130
+ child registers no `delegate`/`council`/`orchestrate`/`flow` tool and self-disables under
131
+ `PI_PERSONA_DISABLE`); the docs now state that mechanism directly instead of a limit nothing
132
+ enforced.
133
+ - Dead code: the unread Exocom ledger wake, `waitMatches`, and the `displayNameFor` alias.
134
+
135
+ ## [1.14.2](https://github.com/AeonDave/pi-persona/releases/tag/v1.14.2) - 2026-09-08
136
+
137
+ Pi Persona now prompts sessions to choose a personal name before their first task or incoming
138
+ Exocom request, instead of displaying the persona role as their identity. The README puts
139
+ installation and everyday use first.
140
+
141
+ - Persist session names across persona switches and resume, with distinct provisional handles
142
+ before a name is chosen. Standalone sessions use `agent_name`; Exocom sessions share the same
143
+ identity through `exocom_name`.
144
+ - Cover first-message Exocom wakes, refresh peer presence and outgoing names after renaming, and
145
+ allow identity metadata updates while a work question is pending. Existing tool denials and work
146
+ obligations still apply.
147
+ - Pass supervisor-assigned worker names into the first prompt and peer labels on both in-process
148
+ and child-process engines.
149
+ - Reject an unknown explicit `critic-loop` roster with an actionable error instead of silently
150
+ selecting a different team.
151
+ - Clarify data-preservation, service-impact, and confirmation requirements in the bundled
152
+ assessment and evidence-review prompts.
153
+ - Upgrade exact, untouched 1.14.1 copies of those two prompts on restart, including LF and CRLF
154
+ installations; customized copies remain unchanged.
155
+ - Shorten the README from 488 to 159 lines, add Git URL installation and release pinning, and move
156
+ APIs, configuration, and recipes into `docs/REFERENCE.md`.
157
+
158
+ ## [1.14.1](https://github.com/AeonDave/pi-persona/tree/v1.14.1) - 2026-09-06
159
+
160
+ *No GitHub release was published for this tag; summarized from `git log v1.14.0..v1.14.1` instead
161
+ of `gh release view` (see the task report for detail).*
162
+
163
+ - Rewrote the runtime prompts of the security chain (`elite`, `operator`, `evidence-verifier`,
164
+ `reviewer`, `research`, `scout`) in plain professional language — the method, delegation
165
+ grammar, evidence discipline, target-egress invariant, and verification loop are unchanged, only
166
+ the vocabulary is.
167
+ - Renamed the elite council roster `offensive-assurance` → `evidence-assurance` across the persona,
168
+ `teams.yaml`, the README, and its unit test.
169
+ - Kept the constraints the vocabulary rewrite had softened: authorization/scope statements, the
170
+ named-skills-only public-reference-code rule, the auth-material reuse check across every
171
+ reachable service and principal, and the reviewer's standard injection/SSRF vocabulary. Routing
172
+ targets that had become unresolvable are named again.
173
+ - MAGI cores: rewrapped `melchior`, gave `casper` the same closing rationale as its siblings, and
174
+ clarified that confidence is the core's own 0.0–1.0 certainty rather than a template placeholder.
175
+ - Shortened the README from 604 to 488 lines, table-first, pointing at `docs/` for the long form.
176
+
177
+ ## [1.14.0](https://github.com/AeonDave/pi-persona/releases/tag/v1.14.0) - 2026-09-06
178
+
179
+ Pi Persona can now wake a supervisor when a background job finishes or a program reports an event.
180
+ This release also strengthens delegation cancellation, bounded messaging, and the everyday persona
181
+ experience.
182
+
183
+ ### Event monitoring and time awareness
184
+
185
+ - New `monitor` tool: `exit` mode reports job completion; `output` mode consumes event lines from
186
+ file, log, system, or service adapters. Events are fenced, bounded, coalesced, and delivered at
187
+ an idle turn boundary.
188
+ - Monitor defaults: one event and a ten-minute deadline; limits of eight active watches, twenty
189
+ events per watch, and twenty-four hours. Cancellation stops the owned process tree and removes
190
+ queued wakes. Both `monitor` and `bash` permissions are required.
191
+ - Fresh UTC/local clock context on every run without continually rewriting the cached system
192
+ prefix; `timer now` refreshes the clock during a long run.
193
+ - Timer date-times without a timezone are rejected. Alarm confirmations use the scheduler clock,
194
+ and wake notices distinguish due and observed times.
195
+
196
+ ### Delegation and communication reliability
197
+
198
+ - In-process startup is covered by cancellation and deadlines, including delayed session creation
199
+ and cleanup. The concurrent child guard stays held until outstanding initialization settles.
200
+ - The SDK enforces concurrency admission for every agent call, including direct parallel launches;
201
+ queued and active work respects cancellation and budget checks.
202
+ - Intercom distinguishes retained messages from settled run results. Inbox and retention bounds
203
+ protect outstanding questions; timeout, disconnect, cancellation, and broker ask settlement
204
+ release their resources.
205
+ - Late asks and cancelled waits no longer leave stale notifications. Peer messages have explicit
206
+ size bounds, and communication failures retain useful diagnostics.
207
+ - Overlay regression checks bound the amount of text reprocessed during streaming, keeping the real
208
+ rendering and output checks while removing dependence on CI hardware speed.
209
+
210
+ ### Persona experience
211
+
212
+ - Refined `dev`, `planner`, `researcher`, `swarm`, `audit`, and `verify` defaults, with clearer
213
+ hand-offs, verification, progress reporting, and proportionate scope.
214
+ - Exocom prompt guidance follows each permitted action and distinguishes external workspace
215
+ membership from a denied claim permission.
216
+ - Research workers create durable artifacts when requested or useful for reuse. Exact-pristine seed
217
+ migrations preserve customized persona files.
218
+ - Added the experience and monitor guides, plus a persistent RPC monitor smoke harness.
219
+
220
+ ## [1.13.4](https://github.com/AeonDave/pi-persona/releases/tag/v1.13.4) - 2026-09-05
221
+
222
+ - Opened the tool-start status vocabulary: `tool.started` no longer requires the literal word
223
+ `running` — the wire contract's allowlist became a denylist, so a start event may name its own
224
+ in-flight state, but may not claim to already be over. `tool.finished` stays closed so the
225
+ consumer can always close the call.
226
+ - The shared conformance corpus stays byte-identical with pi-persona-flow; both new cases were
227
+ proven RED against the previous predicate in both repos.
228
+
229
+ ## [1.13.3](https://github.com/AeonDave/pi-persona/releases/tag/v1.13.3) - 2026-09-05
230
+
231
+ Patch release hardening the data-root migration 1.13.2 introduced, after an adversarial pass
232
+ reproduced four defects by running the migration against constructed filesystem states.
233
+
234
+ - The destination side is now `lstat`'d after `mkdirSync`, so a planted or stale link below the
235
+ current root can no longer carry files through it and delete the legacy original.
236
+ - Fixed a false "could not remove" warning per migrated file under concurrency: the source itself
237
+ is asked whether it is still there, instead of trusting an ambiguous Windows errno.
238
+ - The "this is not data loss" branch no longer leaves a silent Exocom outage: a link this run
239
+ created is now undone and the entry reported `kept`, restoring the exact pre-run state.
240
+ - `docs/TELEMETRY.md` now names both roots for v1 flow logs, since the migration relocates that
241
+ subtree with everything else.
242
+
243
+ ## [1.13.2](https://github.com/AeonDave/pi-persona/releases/tag/v1.13.2) - 2026-09-04
244
+
245
+ Patch release that consolidates the agent-dir storage on a single root — Exocom and the broker
246
+ still wrote `<agentDir>/pi-persona` while persona data had long since moved to
247
+ `<agentDir>/persona`.
248
+
249
+ - Moves Exocom's workspace rendezvous (registry, ledger, `agents/`) under
250
+ `<agentDir>/persona/exocom/<workspace-hash>/`, the durable `exocom/codes/` join-code aliases and
251
+ their `.used` reservations, and the POSIX broker socket directory (the Windows named pipe is a
252
+ pipe name, not a path, and is unchanged). Folds an existing `pi-persona` root in once at
253
+ activation, before anything opens the rendezvous or the socket, and reports the result through
254
+ `ui.notify` and a `/doctor` line.
255
+ - Migration is atomic, no-clobber, and resumable per file (link then unlink); a name the new root
256
+ already owns keeps that copy and leaves the legacy copy on disk; non-regular entries (a stale
257
+ socket, a symlink) are never followed, copied, or removed; a filesystem without hard links falls
258
+ back to copy-then-unlink; every failure is a per-entry warning, never a startup throw.
259
+ - Upgrade note: Exocom has no dual-read, so restart every live Pi as part of the upgrade, or old and
260
+ new sessions form two disjoint rendezvous.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dave
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.