pi-background-tasks 0.7.7 → 1.0.3
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/BACKGROUND-TASKS-INSTRUCTIONS.md +63 -0
- package/PUBLISHING.md +43 -29
- package/README.md +234 -385
- package/TESTING.md +15 -9
- package/TEST_PLAN.md +46 -13
- package/docs/INDEX.md +157 -0
- package/docs/api/eventbus-v1.md +166 -0
- package/docs/assets/architecture.svg +78 -0
- package/docs/assets/footer-dock.svg +47 -0
- package/docs/assets/logo.svg +49 -0
- package/docs/attestations.json +189 -0
- package/docs/choose-a-workflow.md +98 -0
- package/docs/commands/bg-clear.md +70 -0
- package/docs/commands/bg-update.md +82 -0
- package/docs/commands/bg.md +90 -0
- package/docs/commands/fusion-models.md +70 -0
- package/docs/commands/fusion.md +69 -0
- package/docs/commands/jobs.md +74 -0
- package/docs/commands/kill.md +82 -0
- package/docs/commands/logs.md +90 -0
- package/docs/commands/task-manager.md +109 -0
- package/docs/concepts/completion-delivery.md +66 -0
- package/docs/concepts/context-projection-and-budgeting.md +79 -0
- package/docs/getting-started.md +122 -0
- package/docs/manifest.json +1825 -0
- package/docs/operations/configuration.md +110 -0
- package/docs/operations/releasing.md +67 -0
- package/docs/operations/testing.md +101 -0
- package/docs/operations/troubleshooting.md +38 -0
- package/docs/read-before-edit.md +94 -0
- package/docs/reference/runtime-contracts.md +213 -0
- package/docs/reference/shortcuts-and-dock.md +70 -0
- package/docs/subsystems/attested-pi-runs.md +141 -0
- package/docs/subsystems/background-task-runtime.md +85 -0
- package/docs/subsystems/child-launch-durability-and-safety.md +57 -0
- package/docs/subsystems/delegation.md +190 -0
- package/docs/subsystems/docs-freshness-gate.md +26 -0
- package/docs/subsystems/fusion.md +121 -0
- package/docs/subsystems/host-ui-and-telemetry.md +83 -0
- package/docs/tools/bg_delegate.md +193 -0
- package/docs/tools/bg_kill.md +114 -0
- package/docs/tools/bg_logs.md +133 -0
- package/docs/tools/bg_result.md +120 -0
- package/docs/tools/bg_run.md +168 -0
- package/docs/tools/bg_run_pi_attested.md +170 -0
- package/docs/tools/bg_status.md +111 -0
- package/docs/tools/fusion_investigate.md +116 -0
- package/docs/tools/fusion_reason.md +75 -0
- package/docs/tools/fusion_research.md +162 -0
- package/docs/tools/fusion_validate.md +206 -0
- package/logo.png +0 -0
- package/package.json +29 -6
- package/src/core/delegate/budget.ts +1 -1
- package/src/core/delegate/launch.ts +6 -0
- package/src/core/fusion/artifacts.ts +80 -5
- package/src/core/fusion/budget.ts +129 -28
- package/src/core/fusion/child-protocol.ts +82 -0
- package/src/core/fusion/clean-context.ts +91 -0
- package/src/core/fusion/config.ts +124 -35
- package/src/core/fusion/context.ts +33 -6
- package/src/core/fusion/evaluation.ts +392 -15
- package/src/core/fusion/orchestrator.ts +274 -25
- package/src/core/fusion/pi-child.ts +635 -10
- package/src/core/fusion/prompts.ts +167 -6
- package/src/core/fusion/source-policy.ts +257 -0
- package/src/core/fusion/types.ts +232 -5
- package/src/core/fusion/web-fetch.ts +993 -0
- package/src/core/fusion/workflows.ts +184 -0
- package/src/extension.ts +3 -3
- package/src/fusion-child-extension.ts +370 -54
- package/src/fusion-extension.ts +625 -125
- package/src/testing/normalize.ts +0 -22
package/README.md
CHANGED
|
@@ -1,476 +1,325 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="logo.png" alt="pi-background-tasks logo: a futuristic dispatcher coordinating parallel work nodes into a completed result" width="144" height="144">
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
# pi-background-tasks
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
**Keep Pi moving while long jobs, delegated investigations, and fixed-purpose multi-model Fusion work run in the background.**
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
[](https://www.npmjs.com/package/pi-background-tasks)
|
|
9
|
+
[](https://github.com/earendil-works/pi-coding-agent)
|
|
10
|
+
[](package.json)
|
|
11
|
+
[](LICENSE)
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
</div>
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
pi install npm:pi-background-tasks@0.7.7
|
|
13
|
-
```
|
|
15
|
+
`pi-background-tasks` adds background jobs, delegated agents, and multi-model Fusion for Pi:
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
- **Run long work without blocking**: start named shell jobs, keep talking to Pi, and get durable completion notifications when they finish.
|
|
18
|
+
- **Delegate context-aware investigation**: launch one route-pinned, inspect-only child Pi agent seeded with a frozen projection of the current conversation, then retrieve a hash-verified result.
|
|
19
|
+
- **Combine model perspectives through fixed-purpose Fusion**: run three candidate children, blind evaluation, optional bounded evaluator repair, and merger for reasoning, investigation, targeted URL research, or validation review.
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
<p align="center">
|
|
22
|
+
<img src="docs/assets/architecture.svg" alt="Architecture diagram showing Pi session, background task registry, delegated child agent, and Fusion candidate/evaluator/merger flow" width="760">
|
|
23
|
+
</p>
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
<!-- pi-docs:begin name="readme-package-facts" generator="scripts/docs/generate.mjs" -->
|
|
26
|
+
| Fact | Value |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| Package | `pi-background-tasks` |
|
|
29
|
+
| Version | `1.0.3` |
|
|
30
|
+
| Node engine | `>=22.19.0` |
|
|
31
|
+
| Pi entrypoint | `./extensions/background-tasks.ts` |
|
|
32
|
+
| Package image | [logo.png](https://raw.githubusercontent.com/ismailsaleekh/pi-background-tasks/main/logo.png) |
|
|
33
|
+
<!-- pi-docs:end name="readme-package-facts" -->
|
|
22
34
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
35
|
+
<!-- pi-docs:begin name="readme-public-surfaces" generator="scripts/docs/generate.mjs" -->
|
|
36
|
+
| Surface kind | Count |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| command | 10 |
|
|
39
|
+
| tool | 11 |
|
|
40
|
+
| shortcut | 2 |
|
|
41
|
+
| renderer | 2 |
|
|
42
|
+
| eventbus | 1 |
|
|
43
|
+
| workflow | 4 |
|
|
26
44
|
|
|
27
|
-
|
|
45
|
+
Public commands: `/bg`, `/bg-clear`, `/bg-tasks`, `/bg-update`, `/fusion`, `/fusion-models`, `/jobs`, `/kill`, `/logs`, `/tasks`.
|
|
28
46
|
|
|
29
|
-
|
|
30
|
-
- `/jobs` — list running and recent completed/failed/killed tasks.
|
|
31
|
-
- `/logs <id> [maxBytes]` — show bounded tail output and full output path.
|
|
32
|
-
- `/kill <id>` — stop a running task.
|
|
33
|
-
- `/tasks` or `/bg-tasks` — fallback command to open the task manager UI.
|
|
34
|
-
- `/bg-clear` — clear finished background-task footer notices.
|
|
35
|
-
- `/bg-update` — print update instructions when a newer published version exists (instruct-only; never self-installs).
|
|
36
|
-
- `/fusion <prompt>` — run three candidate child Pi final-text calls, one blind evaluator, and one merger, then append the merged answer directly as a visible `fusion-result` custom message without asking the parent model to rewrite it. Running `/fusion` without arguments opens a multiline editor in UI-capable modes; cancelling the editor does not spawn children.
|
|
37
|
-
- `/fusion-models` — TUI-only five-slot global model selector (`Candidate 1`, `Candidate 2`, `Candidate 3`, `Evaluator`, `Merger`). It supports duplicate selections, `$current` defaults, slash-containing model ids, atomic saves to `fusion-models.json`, and rejects non-TUI modes immediately.
|
|
47
|
+
Public tools: `bg_delegate`, `bg_kill`, `bg_logs`, `bg_result`, `bg_run`, `bg_run_pi_attested`, `bg_status`, `fusion_investigate`, `fusion_reason`, `fusion_research`, `fusion_validate`.
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
Full owner map and generated contracts live in [docs/INDEX.md](docs/INDEX.md).
|
|
50
|
+
<!-- pi-docs:end name="readme-public-surfaces" -->
|
|
40
51
|
|
|
41
|
-
When tasks are active or unseen completions/failures exist, Pi shows a compact footer status:
|
|
42
52
|
|
|
43
|
-
```text
|
|
44
|
-
bg 2 running · Shift↓
|
|
45
|
-
bg 1 running · 1 failed · Shift↓ · /bg-clear
|
|
46
|
-
bg 2 done · Shift↓ · /bg-clear
|
|
47
|
-
```
|
|
48
53
|
|
|
49
|
-
Press `Shift+Down` to open the focused bottom dock. Arrow keys are captured only while the dock is focused. Each task row shows the latest context-window usage reported by that specific background task, for example `ctx 21.0%/200k`; tasks that do not report their own context show `ctx —` rather than the parent Pi session's usage. Background Pi-agent tasks also surface the LLM model they ran (`model gpt-5.5` in the compact row, fully-qualified such as `openai-codex/gpt-5.5` in the detail view), cumulative token usage (`tok 1.6k`), and tool-use counts (`tools 2/1 failed`) in the dock and detail view; missing model/token/tool telemetry is omitted in rows and shown as “not reported by this background task” in details. When a background command is explicitly marked as an agent and invokes a print/json child agent such as `pi -p ...` through the normal shell command name, the extension wraps that child Pi process with `--mode json`, parses real assistant usage/tool execution events, and emits task-owned telemetry automatically — including the model reported by the child assistant turns.
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
## Why use it?
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Finished-task badges intentionally remain visible until acknowledged. The reliable clear path is `/bg-clear`, which works in every terminal and clears finished background-task footer notices without opening the dock. `Ctrl+Alt+C` is still registered as an optional terminal-dependent fallback shortcut, but the footer advertises `/bg-clear` because some macOS terminals do not transmit `Ctrl+Alt+C` distinctly.
|
|
56
|
-
|
|
57
|
-
Dock controls:
|
|
58
|
-
|
|
59
|
-
| Key | Action |
|
|
57
|
+
| You want to... | Use this package because... |
|
|
60
58
|
|---|---|
|
|
61
|
-
| `
|
|
62
|
-
|
|
|
63
|
-
| `
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
| `Enter` / `→` | Inspect logs/details |
|
|
67
|
-
| `←` | Return from details to list |
|
|
68
|
-
| `h` | Toggle recent history |
|
|
69
|
-
| `k` | Stop selected running task |
|
|
70
|
-
| `a` / `K` | Stop all running tasks, with confirmation |
|
|
71
|
-
| `r` | Refresh detail tail |
|
|
72
|
-
| `R` | Rerun selected command |
|
|
73
|
-
| `c` | Show copyable output path |
|
|
74
|
-
| `x` / `Esc` / `q` | Close dock |
|
|
75
|
-
| `/bg-update` | Print update instructions when a newer version is published |
|
|
76
|
-
|
|
77
|
-
In the detail view the **Output tail** is scrollable: `↑`/`↓` and `PageUp`/`PageDown` move through the loaded output (a generous bounded window, not just the last lines). Scrolling up pauses the live tail and freezes the view so it stays stable as new output arrives; the status line shows your position (e.g. `lines 46–57 of 60`). Scrolling back to the bottom (or pressing `r`) resumes live tailing.
|
|
78
|
-
|
|
79
|
-
### Update-available notice
|
|
59
|
+
| Start a dev server, watch build, migration dry run, or long check | `bg_run` and `/bg` return immediately, write durable output files, show a footer dock, and notify on terminal state. |
|
|
60
|
+
| Let Pi keep working instead of sleeping or polling | Default `bg_run` completion delivery sends a durable terminal notification and can wake a follow-up turn. |
|
|
61
|
+
| Ask a second agent to inspect the repo with the current conversation as context | `bg_delegate` starts one isolated child with read/search/list tools only; `bg_result` verifies the committed result before returning it. |
|
|
62
|
+
| Compare model perspectives without exposing arbitrary parent context | Fusion children receive only the workflow input and fixed tool policy; no silent route substitution or fallback is used on delegate/Fusion paths. |
|
|
63
|
+
| Produce local evidence for a direct Pi run | `bg_run_pi_attested` records local same-user-writable artifacts and hashes after a successful structured child Pi task. |
|
|
80
64
|
|
|
81
|
-
|
|
65
|
+
## Install
|
|
82
66
|
|
|
83
|
-
|
|
84
|
-
bg 1 running · 1 failed · Shift↓ · /bg-clear · ⬆ v0.7.0 /bg-update
|
|
85
|
-
```
|
|
67
|
+
Version information comes from [`package.json`](package.json). Use npm `@latest` for normal installs; use git `main` only when you intentionally want the current repository state.
|
|
86
68
|
|
|
87
|
-
|
|
69
|
+
```bash
|
|
70
|
+
# Global install from npm
|
|
71
|
+
pi install npm:pi-background-tasks@latest
|
|
88
72
|
|
|
89
|
-
|
|
73
|
+
# Project-local install from npm
|
|
74
|
+
pi install npm:pi-background-tasks@latest -l
|
|
90
75
|
|
|
91
|
-
|
|
76
|
+
# Git main branch; not a release tag
|
|
77
|
+
pi install git:github.com/ismailsaleekh/pi-background-tasks@main
|
|
92
78
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
- `bg_result` — retrieve a `bg_delegate` answer, hash-verified before it is returned.
|
|
96
|
-
- `bg_run_pi_attested` — opt-in structured direct-spawn Pi agent task that emits a strict local attestation sidecar after successful completion.
|
|
97
|
-
- `bg_status` — inspect one task or all recent tasks.
|
|
98
|
-
- `bg_logs` — read bounded task output.
|
|
99
|
-
- `bg_kill` — stop a running task.
|
|
100
|
-
- `fusion_brainstorm({prompt})` — always-active tool that runs the Fusion workflow and returns the exact merged text as the tool result for the parent agent to consume, with the exact Pi `Usage` shape attached when the host supports tool-result usage: token fields plus complete `cost.input`, `cost.output`, `cost.cacheRead`, `cost.cacheWrite`, and `cost.total`. Its closed public schema has exactly one required parameter, `prompt`; extra keys are rejected. It has no eligibility, quota, routine, or justification gate. Tool context capture excludes the current assistant tool-call leaf when Pi is executing that `fusion_brainstorm` call, so the nested children do not see the in-progress tool call or sibling calls. Children receive the documented conversation projection described under [Conversation context policy](#conversation-context-policy): visible user/assistant text verbatim, with thinking and tool payloads replaced by explicit hash-accounted omission receipts. Because the prompt is composed by the parent agent, it is treated as authoritative and self-contained.
|
|
79
|
+
# Project-local git main install
|
|
80
|
+
pi install git:github.com/ismailsaleekh/pi-background-tasks@main -l
|
|
101
81
|
|
|
102
|
-
|
|
82
|
+
# Local checkout/package path, run from this package directory
|
|
83
|
+
pi install .
|
|
84
|
+
pi install . -l
|
|
85
|
+
```
|
|
103
86
|
|
|
104
|
-
|
|
87
|
+
Local paths are loaded from disk without copying; use the path to this package from your current directory.
|
|
105
88
|
|
|
106
|
-
|
|
89
|
+
## Quick start: useful in under five minutes
|
|
107
90
|
|
|
91
|
+
1. Install and start Pi in a project.
|
|
92
|
+
2. Launch a background command:
|
|
108
93
|
|
|
109
|
-
|
|
94
|
+
```text
|
|
95
|
+
/bg --name "Typecheck watch" npm run typecheck -- --watch
|
|
96
|
+
```
|
|
110
97
|
|
|
111
|
-
`
|
|
112
|
-
empty** context) and `fusion_brainstorm` (your current context, but synchronous
|
|
113
|
-
and five-model). It is one agent, one prompt, seeded with the current session's
|
|
114
|
-
context, non-blocking. `bg_result` retrieves its answer safely. They ship
|
|
115
|
-
together: a delegate without a safe retrieval path could not return its work.
|
|
98
|
+
`/bg` starts a tracked shell task and returns the task id plus output path. User-launched `/bg` tasks notify in the UI but do not automatically wake a follow-up model turn.
|
|
116
99
|
|
|
117
|
-
|
|
118
|
-
bg_delegate({ name, prompt }) → launch receipt, immediately
|
|
119
|
-
… the parent keeps working; the terminal notification wakes it …
|
|
120
|
-
bg_result({ taskId }) → hash-verified answer
|
|
121
|
-
```
|
|
100
|
+
3. Open the footer dock with **Shift↓** or list tasks:
|
|
122
101
|
|
|
123
|
-
|
|
102
|
+
```text
|
|
103
|
+
/jobs
|
|
104
|
+
```
|
|
124
105
|
|
|
125
|
-
|
|
126
|
-
is projected with the same frozen `visible-conversation-ledger-v2` transform
|
|
127
|
-
Fusion uses (see [Conversation context policy](#conversation-context-policy)),
|
|
128
|
-
frozen as an immutable seed, and the child is given its **own** `--session-id`
|
|
129
|
-
and a task-owned `--session-dir`. Conceptually it has your context; physically it
|
|
130
|
-
can never open or mutate the parent session.
|
|
106
|
+
4. Read bounded output only when you need it:
|
|
131
107
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
| Assistant text | included verbatim, never clipped |
|
|
136
|
-
| User image blocks | marker only, never raw bytes |
|
|
137
|
-
| Assistant thinking | excluded; recorded as a hash-accounted omission receipt |
|
|
138
|
-
| Tool-call arguments | excluded; recorded as a hash-accounted omission receipt |
|
|
139
|
-
| Tool-result payloads | excluded; recorded as a hash-accounted omission receipt |
|
|
140
|
-
| The in-flight `bg_delegate` call and its sibling calls | scope-excluded from the branch |
|
|
141
|
-
|
|
142
|
-
The assistant message carrying the in-flight call is excluded as a whole, so when
|
|
143
|
-
several `bg_delegate` calls share one assistant message **every** sibling call is
|
|
144
|
-
excluded for **every** child: two delegates launched together receive identical
|
|
145
|
-
projected history and neither can observe the other's arguments.
|
|
146
|
-
|
|
147
|
-
The seed is canonical-JSON, SHA-256'd, and persisted. The persisted bytes are the
|
|
148
|
-
exact bytes the child reads, and the child re-verifies that hash **before its
|
|
149
|
-
first model call**. Repeated construction from the same session is
|
|
150
|
-
byte-identical.
|
|
151
|
-
|
|
152
|
-
**Documented limitation:** facts that exist only inside omitted parent tool
|
|
153
|
-
output are **not** available to the child. The child is told this explicitly and
|
|
154
|
-
instructed to say so plainly rather than guess. Restate any such finding in the
|
|
155
|
-
`prompt`.
|
|
156
|
-
|
|
157
|
-
### Route pinning
|
|
158
|
-
|
|
159
|
-
The route is pinned at launch — by default the parent's current effective
|
|
160
|
-
provider/model, or an explicit `route {provider, model}`. It is **never**
|
|
161
|
-
substituted, never falls back, and is never retried on a different route. An
|
|
162
|
-
unavailable route or one with no declared context window is a typed refusal
|
|
163
|
-
before anything is created. The child additionally asserts that every assistant
|
|
164
|
-
message it produced came from the pinned route; a mismatch prevents the run from
|
|
165
|
-
committing an answer at all.
|
|
166
|
-
|
|
167
|
-
### Inspect-only capability boundary
|
|
168
|
-
|
|
169
|
-
v1 supports exactly one capability, `inspect`. The child is launched with
|
|
170
|
-
`--tools read,grep,find,ls,delegate_read_artifact`, `--no-builtin-tools`, an
|
|
171
|
-
explicit `--exclude-tools` denylist, and no ambient extensions, skills, prompt
|
|
172
|
-
templates, themes, or context files. **The boundary is enforced by argv and the
|
|
173
|
-
child's tool registry, not by prompt text.** There is no shell, no network, no
|
|
174
|
-
edit/write, no recursive delegation, and no Fusion from the child. Writable
|
|
175
|
-
profiles are deliberately out of scope.
|
|
176
|
-
|
|
177
|
-
### Budgets, spilling, and limits
|
|
178
|
-
|
|
179
|
-
Admission is checked **before** the child process, the child session, or the
|
|
180
|
-
artifact directory exists, so a refusal leaves **zero** children and **zero**
|
|
181
|
-
artifacts. Inside the child, every model call is measured before dispatch; a call
|
|
182
|
-
that would exceed the pinned route's allowance is refused and the run terminates
|
|
183
|
-
with a typed `provider_context_budget_exhausted`.
|
|
184
|
-
|
|
185
|
-
A tool result larger than the per-result transcript cap is written **in full** to
|
|
186
|
-
a hashed artifact and replaced in the transcript by an explicit receipt naming
|
|
187
|
-
the artifact, its exact byte count, its SHA-256, and how to read a bounded range.
|
|
188
|
-
The raw payload never enters the transcript and **nothing is truncated**. The
|
|
189
|
-
bounded `delegate_read_artifact` tool returns exactly the requested range or
|
|
190
|
-
fails; a request past end-of-file is refused rather than silently shortened.
|
|
191
|
-
Turn, tool-call, aggregate-output, and wall-clock limits are enforced and
|
|
192
|
-
reported.
|
|
193
|
-
|
|
194
|
-
### Retrieving the answer
|
|
195
|
-
|
|
196
|
-
The child commits exactly one self-contained result package by temp-write,
|
|
197
|
-
`fsync`, rename, directory `fsync`. **The rename is the commit point**: a package
|
|
198
|
-
present under its final name is complete, and its absence means no answer was
|
|
199
|
-
accepted — whatever the process exit code was. A child that exits `0` without
|
|
200
|
-
committing is a typed `child_exited_without_commit`, never a silent empty
|
|
201
|
-
success. A run that degraded anything latches terminal state and **cannot**
|
|
202
|
-
commit a success package, so a hash-valid answer can never be built on silently
|
|
203
|
-
mutilated context.
|
|
204
|
-
|
|
205
|
-
`bg_result` verifies the package identity, seed hash, route, every per-block
|
|
206
|
-
SHA-256, and the aggregate SHA-256 before returning a single byte, and returns
|
|
207
|
-
bytes from the buffer it verified. A running task returns a typed *not ready*
|
|
208
|
-
result and **never blocks or polls**. An answer over the inline cap degrades to
|
|
209
|
-
an artifact reference **explicitly**; requesting `delivery:"inline"` for it is a
|
|
210
|
-
typed `result_too_large_for_inline` failure naming the artifact. It is **never**
|
|
211
|
-
truncated to fit. `autoDeliver` (`never` | `when_small` | `always`) defaults to
|
|
212
|
-
`never`: completion notifications carry metadata, and the answer is fetched
|
|
213
|
-
deliberately with `bg_result`.
|
|
214
|
-
|
|
215
|
-
### Failure taxonomy
|
|
216
|
-
|
|
217
|
-
Every delegate failure is typed and states what happened, what was preserved, and
|
|
218
|
-
what the operator can do. Admission codes
|
|
219
|
-
(`delegate_hook_contract_unsupported`, `delegate_isolation_unsupported`,
|
|
220
|
-
`route_unresolved`, `route_capacity_unknown`, `seed_projection_failed`,
|
|
221
|
-
`seed_budget_exceeded`, `seed_persist_failed`, `invalid_arguments`) always report
|
|
222
|
-
`childCreated: false`. Execution and integrity codes include `child_spawn_failed`,
|
|
223
|
-
`child_timeout`, `child_cancelled`, `child_turn_limit`, `child_tool_call_limit`,
|
|
224
|
-
`child_exited_without_commit`, `provider_context_budget_exhausted`,
|
|
225
|
-
`aggregate_tool_output_cap`, `child_result_invalid`,
|
|
226
|
-
`child_result_encoding_invalid`, `route_attestation_missing`, `route_mismatch`,
|
|
227
|
-
`seed_hash_mismatch`, `answer_hash_mismatch`, `artifact_spill_failed`, and
|
|
228
|
-
`artifact_read_failed`. Retrieval states are `result_not_ready`,
|
|
229
|
-
`result_unavailable`, `result_too_large_for_inline`, and `task_unknown`.
|
|
230
|
-
|
|
231
|
-
Usage that the provider did not report is recorded as explicitly `unavailable`,
|
|
232
|
-
never as zero.
|
|
233
|
-
|
|
234
|
-
### Proven Pi hook contract
|
|
235
|
-
|
|
236
|
-
The child-side guard depends on runtime Pi behaviour, which is **proven by
|
|
237
|
-
execution** rather than read from type declarations. The
|
|
238
|
-
`npm run test:hook-contract` gate drives a real Pi agent loop and records what it
|
|
239
|
-
observed. On Pi 0.83 it establishes that `context` fires once before every model
|
|
240
|
-
call in extension load order and that returned messages reach the provider; that
|
|
241
|
-
**throwing** from a `context` handler does **not** block the call (Pi catches it
|
|
242
|
-
and dispatches anyway); that `ctx.abort()` does not skip the provider call site
|
|
243
|
-
but hands it an already-aborted signal and terminates the run; and that
|
|
244
|
-
`tool_result` fires before the result enters the transcript, chains in load order,
|
|
245
|
-
and preserves tool-call id, role, and error flag across replacement.
|
|
246
|
-
|
|
247
|
-
Because neither a throw nor an abort is a hard admission gate on its own, the
|
|
248
|
-
guard uses abort as the barrier **and** removes the oversized content from the
|
|
249
|
-
outgoing message set, so the request cannot carry it even if a provider ignored
|
|
250
|
-
the aborted signal. If a Pi build cannot provide the required guarantees,
|
|
251
|
-
`bg_delegate` refuses to spawn with a typed
|
|
252
|
-
`delegate_hook_contract_unsupported`; the guard is never weakened to fit.
|
|
253
|
-
|
|
254
|
-
Delegate artifacts are written under:
|
|
255
|
-
|
|
256
|
-
```text
|
|
257
|
-
.pi/delegate/<session-id>-<pid>/<task-id>/
|
|
258
|
-
```
|
|
108
|
+
```text
|
|
109
|
+
/logs b12ab34c 20000
|
|
110
|
+
```
|
|
259
111
|
|
|
260
|
-
|
|
261
|
-
child over stdin, never a shell or positional argument),
|
|
262
|
-
`context-omission-ledger.json`, `budget-plan.json`, `manifest.json`, the
|
|
263
|
-
task-owned `child-session/`, any `spill/` artifacts, `result.json` once the child
|
|
264
|
-
commits, and `outcome.json` once the parent adjudicates the run.
|
|
112
|
+
5. Let a child agent inspect while you continue:
|
|
265
113
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
114
|
+
```json
|
|
115
|
+
{"name":"Config reader","prompt":"Inspect the repository configuration files and report where background task settings are documented. Include file paths and quote only the relevant lines.","capability":"inspect"}
|
|
116
|
+
```
|
|
269
117
|
|
|
270
|
-
|
|
118
|
+
Call this with `bg_delegate`. When its terminal notification arrives, retrieve the answer deliberately:
|
|
271
119
|
|
|
272
|
-
|
|
120
|
+
```json
|
|
121
|
+
{"taskId":"<task id from bg_delegate>","delivery":"inline"}
|
|
122
|
+
```
|
|
273
123
|
|
|
274
|
-
|
|
124
|
+
Call this with `bg_result`. Retrieval is hash-verified and never silently truncated.
|
|
275
125
|
|
|
276
|
-
|
|
126
|
+
6. For a self-contained synthesis, ask Fusion:
|
|
277
127
|
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
```
|
|
128
|
+
```json
|
|
129
|
+
{"prompt":"Compare the tradeoffs between a watcher, a one-shot build, and a delegated repo inspection for a large refactor."}
|
|
130
|
+
```
|
|
281
131
|
|
|
282
|
-
|
|
132
|
+
Call this with `fusion_reason`, or use `/fusion <prompt>` interactively.
|
|
283
133
|
|
|
284
|
-
|
|
134
|
+
More walkthrough detail: [Getting started](docs/getting-started.md).
|
|
285
135
|
|
|
286
|
-
|
|
136
|
+
## Pick the right workflow
|
|
287
137
|
|
|
288
|
-
|
|
138
|
+
| Workflow | Blocking? | Context | Tools/network/write boundary | Best for | Expected behavior |
|
|
139
|
+
|---|---:|---|---|---|---|
|
|
140
|
+
| Ordinary foreground Pi work | Yes | Full current session | Whatever tools the active session has | Short reads/edits/commands where you want live back-and-forth | Pi waits for the work before responding. |
|
|
141
|
+
| `/bg` | No | No model child unless your command starts one | Runs your shell command; **not sandboxed** | User-started local commands, servers, watches | UI notification and footer tracking; `/bg` uses notification-only by default. |
|
|
142
|
+
| `bg_run` | No | No model child unless command starts one | Runs your shell command; **not sandboxed** | Agent-started long commands | Returns task id/output path; defaults to notification plus automatic follow-up wake. |
|
|
143
|
+
| `bg_delegate` + `bg_result` | No launch; retrieval is point-in-time | Frozen visible conversation projection | Inspect-only child: read, grep, find, ls, artifact read; no shell, writes, network, recursion | Context-aware read-only investigation while parent continues | Launch returns immediately; result is committed by child and hash-verified by retrieval. |
|
|
144
|
+
| `bg_run_pi_attested` | No | Prompt passed to one direct child Pi run | Direct `pi --mode json`; no shell command; writes requested report path | Evidence-oriented direct Pi task | Emits local attestation sidecar only after successful completion. |
|
|
145
|
+
| `/fusion` / `fusion_reason` | Synchronous | Versioned conversation projection plus prompt | Candidates/evaluator/repair/merger run with no tools | Self-contained reasoning and synthesis | Three candidates → blind evaluator → optional bounded repair if evaluator JSON is invalid → merger. |
|
|
146
|
+
| `fusion_investigate` | Synchronous | Clean task input only | Candidate read-only repo tools; evaluator/repair/merger no tools | Independent repo investigation | Restate all needed facts in fields; parent hidden/tool context is not visible. |
|
|
147
|
+
| `fusion_research` | Synchronous | Clean task input only | Candidate read-only repo tools plus targeted fetch of caller-supplied public URLs only | URL-backed synthesis | Targeted URL retrieval, **not web search**. |
|
|
148
|
+
| `fusion_validate` | Synchronous | Clean task input only | Advisory read-only validation review | Second-opinion review of completed work | Not a replacement for tests, builds, linters, security scans, or human review. |
|
|
289
149
|
|
|
290
|
-
|
|
150
|
+
See [Choose a workflow](docs/choose-a-workflow.md) for a decision tree and tradeoffs.
|
|
291
151
|
|
|
292
|
-
|
|
293
|
-
|---|---|
|
|
294
|
-
| User text | included verbatim, never clipped |
|
|
295
|
-
| Assistant text | included verbatim, never clipped |
|
|
296
|
-
| User image blocks | `[Image omitted from fusion text transcript: <mime-type>]` marker |
|
|
297
|
-
| Assistant thinking | excluded; recorded as an omission receipt |
|
|
298
|
-
| Tool-call arguments | excluded; recorded as an omission receipt |
|
|
299
|
-
| Tool-result payloads | excluded; recorded as an omission receipt |
|
|
300
|
-
| Tool-result images | excluded; recorded as an omission receipt (never raw bytes) |
|
|
301
|
-
| Active `fusion_brainstorm` call and its sibling calls | scope-excluded from the branch |
|
|
152
|
+
## Copy-paste examples
|
|
302
153
|
|
|
303
|
-
|
|
154
|
+
### `bg_run`: start long shell work
|
|
304
155
|
|
|
305
156
|
```json
|
|
306
|
-
|
|
307
|
-
|
|
157
|
+
{
|
|
158
|
+
"name": "Docs preview",
|
|
159
|
+
"command": "npm run docs:dev",
|
|
160
|
+
"isAgent": false,
|
|
161
|
+
"timeoutSeconds": 3600
|
|
162
|
+
}
|
|
308
163
|
```
|
|
309
164
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
Two entry points share the transform but differ in request authority:
|
|
313
|
-
|
|
314
|
-
| Entry point | Policy id | `request.authority` |
|
|
315
|
-
|---|---|---|
|
|
316
|
-
| `fusion_brainstorm({prompt})` | `fusion-tool-explicit-v2` | `explicit_text` — the prompt is authoritative and self-contained |
|
|
317
|
-
| `/fusion [prompt]` | `fusion-command-conversation-v2` | `directive_over_projected_conversation` |
|
|
318
|
-
|
|
319
|
-
**Documented limitation:** facts that exist only inside omitted tool output are not available to Fusion children. Restate any required finding as visible conversation text, or include it in the `fusion_brainstorm` prompt. Children are instructed to say so plainly rather than guess. No model-generated summarization is used as hidden preprocessing.
|
|
320
|
-
|
|
321
|
-
### Stage budgets
|
|
322
|
-
|
|
323
|
-
Every prompt-expansion stage — candidate, evaluator, evaluation repair, and merger — is size-checked **before any child process is created**, and each stage is checked against **its own configured route**, so a large-context slot cannot hide a small-context sibling and a small slot cannot veto stages it never serves.
|
|
324
|
-
|
|
325
|
-
Input forecasting uses the shared affine estimator `estimateInputTokens({family, segments})`: additive integer byte-class accounting plus a 512-token affine intercept. Calibrated normal-ASCII rates are used only for backed exact model IDs, measured prompts at or above 50 KiB, and prompts that pass the low-whitespace dense-ASCII gate. That gate records the measured whitespace fraction in `budget-plan.json` and falls back conservatively for out-of-distribution near-zero-whitespace payloads; it is a heuristic token-density proxy, not a bound. Multibyte UTF-8 uses the conservative 2.0 B/tok fatal rate while persisting the provable 1.00 B/tok ceiling as advisory. The calibration basis is 882 real large Fusion prompts: Anthropic observed floor 2.047 B/tok (shipped `r=1.73`) and Codex observed floor 3.400 B/tok (shipped `r=2.89`); unknown providers and unbacked model IDs use the unbacked 1.00 B/tok floor and are surfaced in artifacts and result details.
|
|
326
|
-
|
|
327
|
-
Each stage is forecast with its **real prompt builder**, rendered with empty embedded-output slots, plus the enforced output contracts for whatever that stage will embed:
|
|
328
|
-
|
|
329
|
-
| Stage | Embeds | Mandatory |
|
|
330
|
-
|---|---|---|
|
|
331
|
-
| `candidate` | canonical input only | yes, once per slot |
|
|
332
|
-
| `evaluation` | + 3 candidate answers | yes |
|
|
333
|
-
| `evaluation_repair` | + 3 candidates, invalid evaluator output, diagnostics | conditional, still budgeted |
|
|
334
|
-
| `merge` | + 3 candidates, validated evaluation | yes |
|
|
335
|
-
|
|
336
|
-
`evaluation_repair` only runs when the evaluator returns schema-invalid JSON, but it is budgeted unconditionally: "uncommon" is not a reliability contract.
|
|
337
|
-
|
|
338
|
-
Output sizes are guaranteed by **enforced contracts**, not assumptions. Each stage has a maximum response size measured in *JSON-rendered transfer bytes* — the bytes the response actually costs once a later stage embeds it, escaping included (candidate 48 KiB, evaluator 64 KiB, merger 64 KiB, repair diagnostics 8 KiB). Measuring the rendered form removes any escaping guess: quotes, backslashes, and newlines expand 2x and control characters up to 6x. A response over its contract is a loud `child_output_cap` failure; it is preserved in the run artifacts and is never sliced, truncated, or forwarded.
|
|
165
|
+
Expected: returns immediately with a task id, PID when available, and `.pi/tasks/...output`. The command runs as an ordinary local shell command with your user permissions; it can invoke networked tools or paid services if the command itself does so.
|
|
339
166
|
|
|
340
|
-
|
|
167
|
+
### `bg_delegate`: context-seeded read-only investigation
|
|
341
168
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
## Extension EventBus API
|
|
351
|
-
|
|
352
|
-
Version `0.7.0` exposes a real extension-to-extension service over Pi's documented `pi.events` bus. This is not a `ctx` method and it does not call a second task manager: requests route to the same `BackgroundTaskRegistry` used by `bg_run`, `bg_status`, `bg_logs`, and `bg_kill`.
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"name": "Route audit",
|
|
172
|
+
"prompt": "Inspect the package source and identify where delegate route pinning is enforced. Return file paths, function names, and a short explanation. If a fact exists only in omitted parent tool output, say it is unavailable rather than guessing.",
|
|
173
|
+
"capability": "inspect",
|
|
174
|
+
"autoDeliver": "never"
|
|
175
|
+
}
|
|
176
|
+
```
|
|
353
177
|
|
|
354
|
-
|
|
178
|
+
Then retrieve:
|
|
355
179
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
| Response schema | `pi-background-tasks.extension-response.v1` |
|
|
363
|
-
| Terminal schema | `pi-background-tasks.extension-terminal.v1` |
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"taskId": "<delegate task id>",
|
|
183
|
+
"delivery": "inline"
|
|
184
|
+
}
|
|
185
|
+
```
|
|
364
186
|
|
|
365
|
-
|
|
187
|
+
Expected: `bg_delegate` returns a launch receipt immediately. `bg_result` returns a typed not-ready result while running; after commit it verifies package identity, seed hash, route, block hashes, and aggregate hash before returning bytes. Oversized answers become explicit artifact references, not truncated inline text.
|
|
366
188
|
|
|
367
|
-
`
|
|
189
|
+
### `bg_run_pi_attested`: local evidence for one Pi child
|
|
368
190
|
|
|
369
191
|
```json
|
|
370
|
-
{
|
|
192
|
+
{
|
|
193
|
+
"name": "Migration report",
|
|
194
|
+
"provider": "openai-codex",
|
|
195
|
+
"model": "gpt-5.5",
|
|
196
|
+
"prompt": "Inspect the repository and write a concise migration report to reports/migration.md.",
|
|
197
|
+
"reportPath": "reports/migration.md",
|
|
198
|
+
"timeoutSeconds": 1800
|
|
199
|
+
}
|
|
371
200
|
```
|
|
372
201
|
|
|
373
|
-
|
|
202
|
+
Expected: launches exactly one direct `pi --mode json` child using structured provider/model fields. It rejects direct API-key/auth-file launch arguments and only writes the attestation sidecar after successful completion and durable hashes. The attestation is local evidence, not cryptographic proof against a compromised machine or provider.
|
|
374
203
|
|
|
375
|
-
|
|
204
|
+
### Fusion tools
|
|
376
205
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
Task output and metadata are written under the current project:
|
|
380
|
-
|
|
381
|
-
```text
|
|
382
|
-
.pi/tasks/<session-id>-<pid>/<task-id>.output
|
|
383
|
-
.pi/tasks/<session-id>-<pid>/<task-id>.json
|
|
206
|
+
```json
|
|
207
|
+
{"prompt":"Design a rollback strategy for a risky database migration. Include assumptions and failure modes."}
|
|
384
208
|
```
|
|
385
209
|
|
|
386
|
-
|
|
210
|
+
Use with `fusion_reason` for self-contained synthesis.
|
|
387
211
|
|
|
388
|
-
```
|
|
389
|
-
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"objective": "Find how background task output is capped and surfaced.",
|
|
215
|
+
"background": ["We are evaluating pi-background-tasks behavior for long-running commands."],
|
|
216
|
+
"deliverable": "File paths, constants, defaults, and user-visible behavior.",
|
|
217
|
+
"scope": ["src"],
|
|
218
|
+
"constraints": ["Read-only inspection only."]
|
|
219
|
+
}
|
|
390
220
|
```
|
|
391
221
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
For attested Pi tasks only, the task id is `b` plus 32 random hex characters (128 bits) and additional flat siblings are written in the same directory:
|
|
222
|
+
Use with `fusion_investigate`.
|
|
395
223
|
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
.
|
|
399
|
-
.
|
|
400
|
-
.
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"objective": "Summarize the installation syntax Pi documents for packages.",
|
|
227
|
+
"background": ["We need package README install examples to match Pi package docs."],
|
|
228
|
+
"deliverable": "A short summary with caveats.",
|
|
229
|
+
"sources": [
|
|
230
|
+
{"url":"https://github.com/earendil-works/pi-coding-agent","purpose":"Pi package documentation repository"}
|
|
231
|
+
]
|
|
232
|
+
}
|
|
401
233
|
```
|
|
402
234
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
## Durability model
|
|
406
|
-
|
|
407
|
-
All task metadata, task output/events/stderr, attestation sidecars, Fusion artifacts, and the global `fusion-models.json` are written through one shared primitive in `src/core/durable-fs.ts`.
|
|
408
|
-
|
|
409
|
-
The invariant is: **open the file once with write intent, write and `fsync` through that same writable handle, then close.** A pathname is never reopened merely to flush it. This is required for Windows correctness — `FlushFileBuffers` needs a handle with write access, so flushing through a reopened read-only handle fails with `EPERM: operation not permitted, fsync` and previously broke every background task on Windows.
|
|
235
|
+
Use with `fusion_research`. Only declared public `http(s)` URLs may be fetched; this is not a search tool.
|
|
410
236
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"objective": "Review whether a documentation-only change is ready to ship.",
|
|
240
|
+
"background": ["The change edits README and package-local docs only."],
|
|
241
|
+
"changeSummary": "Replaced monolithic README with landing page and moved operational details into docs.",
|
|
242
|
+
"scope": ["README.md", "docs/getting-started.md", "docs/choose-a-workflow.md"],
|
|
243
|
+
"acceptanceCriteria": ["Install commands are accurate", "Safety limitations are explicit", "Examples match public schemas"],
|
|
244
|
+
"verification": {
|
|
245
|
+
"status": "provided",
|
|
246
|
+
"evidence": [{"check":"Focused link check", "outcome":"All local README links resolve"}]
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
421
250
|
|
|
422
|
-
|
|
251
|
+
Use with `fusion_validate` for advisory read-only review.
|
|
423
252
|
|
|
424
|
-
|
|
425
|
-
- Fusion inference is isolated to direct child `pi --mode text` invocations with tools/skills/session/context files disabled and only the package-owned compact metadata extension explicitly loaded; no direct completion API, API-key argument, or model fallback is used.
|
|
426
|
-
- Attested Pi tasks are a local, unsigned, same-user-writable attestation path for downstream gates. They bind source bytes and observed Pi/ModelRegistry facts; they are not cryptographic proof against a malicious local user, compromised Pi binary, or compromised provider.
|
|
427
|
-
- stdout/stderr are captured to task output files.
|
|
428
|
-
- Model-visible logs are bounded and point to full output files.
|
|
429
|
-
- POSIX process groups are used for process-tree kill where possible, with child-process fallback.
|
|
430
|
-
- On Windows, process-tree termination uses `%SystemRoot%\\System32\\taskkill.exe` directly (never `PATH`) with a two-stage `/T` then `/T /F` flow. Stage one is a logical Windows termination request, not SIGTERM and not a guaranteed graceful shutdown: console processes may ignore it, and re-parented descendants can escape the tree. Strong containment would require Windows Job Objects via a native component, which is out of scope.
|
|
431
|
-
- Running tasks are cleaned up on Pi session shutdown/reload.
|
|
432
|
-
- Child Pi processes are never launched through a shell. On Windows the npm `pi.cmd` shim is deliberately not executed, because a batch shim cannot preserve argument bytes safely; the package resolves the Pi package's own CLI entry and launches it with `process.execPath` instead. Batch, PowerShell, and extensionless launch targets are rejected loudly rather than executed, and a launch target resolving outside the Pi package root is rejected.
|
|
433
|
-
- Cross-Pi-restart process reattachment and Ctrl+B backgrounding of already-running foreground tools are intentionally out of scope.
|
|
253
|
+
## Footer dock
|
|
434
254
|
|
|
435
|
-
|
|
255
|
+
<p align="center">
|
|
256
|
+
<img src="docs/assets/footer-dock.svg" alt="Illustration of the pi-background-tasks footer dock with running and completed tasks" width="760">
|
|
257
|
+
</p>
|
|
436
258
|
|
|
437
|
-
|
|
259
|
+
When tasks are running or unseen completions exist, the footer shows a compact `bg ...` segment. Press **Shift↓** to open the focused bottom dock. Use `/bg-clear` to acknowledge finished-task footer notices in any terminal.
|
|
438
260
|
|
|
439
|
-
|
|
261
|
+
| Control | Action |
|
|
262
|
+
|---|---|
|
|
263
|
+
| `Shift↓` | Open the dock |
|
|
264
|
+
| `/bg-clear` | Clear finished-task notices |
|
|
265
|
+
| `↑` / `↓`, `PageUp` / `PageDown` | Move through list or scroll output tail |
|
|
266
|
+
| `Enter` / `→` | Inspect details |
|
|
267
|
+
| `←` | Return to list |
|
|
268
|
+
| `k` | Stop selected running task |
|
|
269
|
+
| `R` | Rerun selected command |
|
|
270
|
+
| `c` | Show copyable output path |
|
|
271
|
+
| `x` / `Esc` / `q` | Close dock |
|
|
440
272
|
|
|
441
|
-
|
|
273
|
+
Agent tasks launched through `pi -p ...` or `pi --mode json ...` and marked `isAgent:true` can show task-owned model/context/token/tool telemetry. Missing child telemetry is shown as unavailable, not synthesized as zero.
|
|
442
274
|
|
|
443
|
-
|
|
275
|
+
<a id="commands"></a>
|
|
276
|
+
<a id="footer-dock-ux"></a>
|
|
277
|
+
<a id="update-available-notice"></a>
|
|
278
|
+
<a id="llm-tools"></a>
|
|
279
|
+
<a id="delegated-background-agents"></a>
|
|
280
|
+
<a id="fusion-workflow"></a>
|
|
281
|
+
<a id="conversation-context-policy"></a>
|
|
282
|
+
<a id="extension-eventbus-api"></a>
|
|
283
|
+
<a id="runtime-files"></a>
|
|
284
|
+
<a id="durability-model"></a>
|
|
285
|
+
<a id="safety-model"></a>
|
|
286
|
+
<a id="windows-shell-and-telemetry"></a>
|
|
444
287
|
|
|
445
|
-
##
|
|
288
|
+
## Architecture, trust, and safety
|
|
446
289
|
|
|
447
|
-
|
|
290
|
+
- Runtime task files live under `.pi/tasks/<session-id>-<pid>/`; Fusion artifacts under `.pi/fusion/...`; delegate artifacts under `.pi/delegate/...`.
|
|
291
|
+
- Shell jobs are tracked by the package, but they are not sandboxed. Treat commands as local processes with your permissions and credentials.
|
|
292
|
+
- Delegate and Fusion child Pi processes are route-pinned where applicable; delegate/Fusion paths do not silently substitute routes.
|
|
293
|
+
- Fusion uses direct child `pi --mode text` processes, not direct completion APIs. Frontier Fusion routes are admitted only through Pi Anthropic or Codex subscription OAuth; metered frontier API credentials are rejected before child creation.
|
|
294
|
+
- Fusion research fetches only caller-supplied public `http(s)` URLs with bounded retrieval. It is not web search and not a secret-exfiltration boundary.
|
|
295
|
+
- Attestation sidecars are local, unsigned, same-user-writable evidence. They are useful for downstream local gates, but not cryptographic proof against local compromise, a compromised Pi binary, or a compromised provider.
|
|
296
|
+
- Metadata, attestations, delegate/Fusion artifacts, and configuration replacements use write/fsync/rename durability patterns. Ordinary task output is closed and drained before terminal publication but is not explicitly fsynced. POSIX directory entries are fsynced after atomic replacement; Windows lacks the same portable directory-entry crash-durability guarantee.
|
|
448
297
|
|
|
449
|
-
|
|
450
|
-
npm run test
|
|
451
|
-
```
|
|
298
|
+
Detailed operations: [Configuration](docs/operations/configuration.md).
|
|
452
299
|
|
|
453
|
-
|
|
300
|
+
## EventBus and Autopilot integration
|
|
454
301
|
|
|
455
|
-
|
|
456
|
-
npm run smoke
|
|
457
|
-
npm run pack:dry-run
|
|
458
|
-
npm run test:compat
|
|
459
|
-
```
|
|
302
|
+
Other Pi extensions can control the same `BackgroundTaskRegistry` through Pi's `events` bus instead of shelling out or maintaining a second task manager. The public channels are:
|
|
460
303
|
|
|
461
|
-
|
|
304
|
+
| Purpose | Channel |
|
|
305
|
+
|---|---|
|
|
306
|
+
| Request | `pi-background-tasks:request:v1` |
|
|
307
|
+
| Response | `pi-background-tasks:response:v1` |
|
|
308
|
+
| Terminal task event | `pi-background-tasks:terminal:v1` |
|
|
462
309
|
|
|
463
|
-
|
|
464
|
-
npm run test:full
|
|
465
|
-
```
|
|
310
|
+
Operations are `capabilities`, `run`, `status`, `logs`, and `kill`. This is the integration point for orchestrators such as Autopilot that need non-blocking package-managed work with bounded logs and correlated terminal events. Consumers must deduplicate terminal frames by `task.id`: an EventBus listener failure can cause a retried publication.
|
|
466
311
|
|
|
467
|
-
|
|
312
|
+
## Documentation map
|
|
468
313
|
|
|
469
|
-
|
|
314
|
+
| Need | Read |
|
|
315
|
+
|---|---|
|
|
316
|
+
| First install and first task | [Getting started](docs/getting-started.md) |
|
|
317
|
+
| Which workflow/tool to choose | [Choose a workflow](docs/choose-a-workflow.md) |
|
|
318
|
+
| Environment variables, shells, output caps, model config, offline behavior | [Configuration](docs/operations/configuration.md) |
|
|
319
|
+
| Package QA expectations | [TESTING.md](TESTING.md) and [TEST_PLAN.md](TEST_PLAN.md) |
|
|
320
|
+
| Publishing notes | [PUBLISHING.md](PUBLISHING.md) |
|
|
321
|
+
| License | [LICENSE](LICENSE) |
|
|
470
322
|
|
|
471
|
-
|
|
323
|
+
## Contributing
|
|
472
324
|
|
|
473
|
-
-
|
|
474
|
-
- [`../EXTENSION_TESTING_PLAYBOOK.md`](../EXTENSION_TESTING_PLAYBOOK.md)
|
|
475
|
-
- [`TEST_PLAN.md`](TEST_PLAN.md)
|
|
476
|
-
- [`TESTING.md`](TESTING.md)
|
|
325
|
+
Keep user-facing claims tied to source. If you change public schemas, command behavior, durability, model routing, or environment variables, update these package-local docs in the same change and run focused checks appropriate to the edit.
|