pi-background-tasks 1.0.6 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/TESTING.md +3 -3
- package/TEST_PLAN.md +2 -2
- package/docs/INDEX.md +25 -25
- package/docs/choose-a-workflow.md +4 -4
- package/docs/commands/bg-clear.md +1 -1
- package/docs/commands/bg-update.md +1 -1
- package/docs/commands/bg.md +1 -1
- package/docs/commands/fusion-models.md +1 -1
- package/docs/commands/fusion.md +5 -8
- package/docs/commands/jobs.md +1 -1
- package/docs/commands/kill.md +1 -1
- package/docs/commands/logs.md +1 -1
- package/docs/commands/task-manager.md +2 -2
- package/docs/concepts/completion-delivery.md +1 -0
- package/docs/getting-started.md +1 -1
- package/docs/manifest.json +59 -50
- package/docs/read-before-edit.md +1 -0
- package/docs/reference/runtime-contracts.md +55 -51
- package/docs/reference/shortcuts-and-dock.md +2 -2
- package/docs/subsystems/background-task-runtime.md +7 -1
- package/docs/subsystems/docs-freshness-gate.md +4 -4
- package/docs/subsystems/fusion.md +15 -11
- package/docs/subsystems/host-ui-and-telemetry.md +1 -1
- package/docs/tools/bg_delegate.md +1 -1
- package/docs/tools/bg_kill.md +1 -1
- package/docs/tools/bg_logs.md +1 -1
- package/docs/tools/bg_result.md +14 -10
- package/docs/tools/bg_run.md +1 -1
- package/docs/tools/bg_run_pi_attested.md +1 -1
- package/docs/tools/bg_status.md +1 -1
- package/docs/tools/fusion_investigate.md +6 -4
- package/docs/tools/fusion_reason.md +5 -5
- package/docs/tools/fusion_research.md +6 -2
- package/docs/tools/fusion_validate.md +5 -3
- package/package.json +1 -1
- package/src/core/common.ts +50 -2
- package/src/core/fusion/artifacts.ts +106 -13
- package/src/core/fusion/budget.ts +12 -4
- package/src/core/fusion/evaluation.ts +61 -0
- package/src/core/fusion/orchestrator.ts +270 -73
- package/src/core/fusion/pi-child.ts +6 -0
- package/src/core/fusion/prompts.ts +1 -0
- package/src/core/fusion/result-package.ts +385 -0
- package/src/core/fusion/types.ts +19 -1
- package/src/core/registry.ts +187 -20
- package/src/delegate-extension.ts +130 -24
- package/src/extension.ts +17 -6
- package/src/fusion-extension.ts +308 -154
|
@@ -5,7 +5,7 @@ mode: mixed
|
|
|
5
5
|
review_policy: behavioral
|
|
6
6
|
stability: stable
|
|
7
7
|
covers_surfaces: [renderer:fusion-result, workflow:investigate, workflow:reason, workflow:research, workflow:validate]
|
|
8
|
-
covers_sources: [extensions/fusion-child.ts, src/core/fusion/artifacts.ts, src/core/fusion/budget.ts, src/core/fusion/child-protocol.ts, src/core/fusion/claude-cache.ts, src/core/fusion/clean-context.ts, src/core/fusion/config.ts, src/core/fusion/context.ts, src/core/fusion/evaluation.ts, src/core/fusion/orchestrator.ts, src/core/fusion/pi-child.ts, src/core/fusion/prompts.ts, src/core/fusion/source-policy.ts, src/core/fusion/types.ts, src/core/fusion/web-fetch.ts, src/core/fusion/workflows.ts, src/fusion-child-extension.ts, src/fusion-extension.ts, src/ui/fusion-model-selector.ts]
|
|
8
|
+
covers_sources: [extensions/fusion-child.ts, src/core/fusion/artifacts.ts, src/core/fusion/budget.ts, src/core/fusion/child-protocol.ts, src/core/fusion/claude-cache.ts, src/core/fusion/clean-context.ts, src/core/fusion/config.ts, src/core/fusion/context.ts, src/core/fusion/evaluation.ts, src/core/fusion/orchestrator.ts, src/core/fusion/pi-child.ts, src/core/fusion/prompts.ts, src/core/fusion/result-package.ts, src/core/fusion/source-policy.ts, src/core/fusion/types.ts, src/core/fusion/web-fetch.ts, src/core/fusion/workflows.ts, src/fusion-child-extension.ts, src/fusion-extension.ts, src/ui/fusion-model-selector.ts]
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Fusion subsystem
|
|
@@ -36,7 +36,7 @@ Every public tool schema is closed and has no public capability/mode switch. The
|
|
|
36
36
|
|
|
37
37
|
## Commands
|
|
38
38
|
|
|
39
|
-
`/fusion <prompt>` trims the command text and
|
|
39
|
+
`/fusion <prompt>` trims the command text and starts the reason workflow as a managed background task. `/fusion` with no arguments opens the multiline editor when UI is available; editor cancellation or blank edited text returns without child spawn. Durable preflight and task registration finish before the command returns; no loader remains open and no premature result message is appended. Terminal state uses the standard background notification, and `bg_result` verifies and retrieves the committed result.
|
|
40
40
|
|
|
41
41
|
`/fusion-models` requires TUI mode. It edits five slots (`Candidate 1`, `Candidate 2`, `Candidate 3`, `Evaluator`, `Merger`), allows duplicates, supports `$current`, shows unavailable configured choices, and persists `fusion-models.json` with schema `pi-background-tasks.fusion-models.v1`. Saves are lock-protected, atomic, and revision-safe: if the file changed after load, the selector reports a config conflict instead of overwriting concurrent work.
|
|
42
42
|
|
|
@@ -51,11 +51,13 @@ Investigate, research, and validate receive clean-task canonical input: exactly
|
|
|
51
51
|
All workflows use the same orchestrator shape:
|
|
52
52
|
|
|
53
53
|
1. plan budget and write artifacts before any child exists;
|
|
54
|
-
2.
|
|
55
|
-
3.
|
|
56
|
-
4.
|
|
57
|
-
5. run
|
|
58
|
-
6. run
|
|
54
|
+
2. pause at a no-child-yet readiness barrier while the managed background-task receipt becomes durable;
|
|
55
|
+
3. run three candidate children in parallel;
|
|
56
|
+
4. anonymize candidate identities as A/B/C before evaluation;
|
|
57
|
+
5. run a blind no-tool evaluator;
|
|
58
|
+
6. run one no-tool evaluator-repair child only if the first evaluator JSON is invalid or schema-invalid;
|
|
59
|
+
7. run a no-tool merger;
|
|
60
|
+
8. durably commit `merged.md` plus manifest-bound `result.json`, then publish terminal task state.
|
|
59
61
|
|
|
60
62
|
Do not describe Fusion as unconditionally exactly five model calls. A completed run may use five or six child invocations, while preflight failures use zero; candidate failures, cancellation, spawn retry, output caps, or invalid repair alter observed attempts.
|
|
61
63
|
|
|
@@ -72,7 +74,7 @@ Evaluator, evaluator-repair, and merger always use capability `reason` and empty
|
|
|
72
74
|
|
|
73
75
|
## Validation specifics
|
|
74
76
|
|
|
75
|
-
`fusion_validate` enforces a strict public verification contract: `provided` requires non-empty evidence and no reason; `not_run` requires a reason and empty/omitted evidence. Reviewers return closed candidate-report JSON. The host assigns stable finding ids after anonymization, the evaluator must account for every source finding exactly once, and the host renders the final report from validated accounting after the merger. Validation is advisory and read-only: it never edits files, runs tests, gates a release, or replaces builds, linters, scanners, or human review.
|
|
77
|
+
`fusion_validate` enforces a strict public verification contract: `provided` requires non-empty evidence and no reason; `not_run` requires a reason and empty/omitted evidence. Reviewers return exactly one bare, closed candidate-report JSON object. The host keeps its shared JSON parser strict; a single complete `json` fence can be removed only by the validation-specific audited recovery path, which writes a contract-event artifact and surfaces a limitation. One irrecoverable minority report is also recorded and surfaced as a limitation, while two invalid reports fail the workflow. The host assigns stable finding ids after anonymization, the evaluator must account for every source finding exactly once, and the host renders the final report from validated accounting after the merger. Validation is advisory and read-only: it never edits files, runs tests, gates a release, or replaces builds, linters, scanners, or human review.
|
|
76
78
|
|
|
77
79
|
## Research specifics
|
|
78
80
|
|
|
@@ -96,7 +98,7 @@ Fusion child environments strip session/model/provider variables plus metered cr
|
|
|
96
98
|
|
|
97
99
|
## Budgets and output contracts
|
|
98
100
|
|
|
99
|
-
Budget planning is per route and per stage. Every configured candidate, evaluator, and merger route must have a usable context window. The affine estimator from the shared token-budget layer accounts for byte classes plus a 512-token intercept; backed model-family calibrations are used only where applicable, unknown/unbacked providers are reported in artifacts/result details, and multibyte/dense ASCII diagnostics are preserved.
|
|
101
|
+
Budget planning is per route and per stage. Every configured candidate, evaluator, and merger route must have a usable context window. The affine estimator from the shared token-budget layer accounts for byte classes plus a 512-token intercept; backed model-family calibrations are used only where applicable, unknown/unbacked providers are reported in artifacts/result details, and multibyte/dense ASCII diagnostics are preserved. Post-run calibration compares that one-request forecast only with the first provider request; cumulative agent-loop and cache usage is retained as total usage but is never misclassified as a prompt under-forecast.
|
|
100
102
|
|
|
101
103
|
`budget-plan.json` uses `pi-background-tasks.fusion-budget-plan.v4` and records route capacities, stage forecasts for candidate/evaluation/evaluation-repair/merge, conditional repair reservation, warnings, blockers, empty-request counterfactuals, and remediation. Each route reserves the larger of Fusion's 32,768-token output contract reserve and the resolved model's declared maximum output; a model advertising a 128,000-token maximum therefore receives the full 128,000-token reserve. Fatal preflight blockers launch zero children. High utilization or worst-case reservation pressure is a warning when input still fits. Exact rendered prompt checks happen again immediately before candidate, evaluation, repair, and merge launches.
|
|
102
104
|
|
|
@@ -104,13 +106,15 @@ Output contracts are checked after durable attempt recording: candidate response
|
|
|
104
106
|
|
|
105
107
|
## Artifacts, usage, and lifecycle
|
|
106
108
|
|
|
107
|
-
Run artifacts are private local evidence under `.pi/fusion/<session-id>-<pid>/<run-id>/`. They include `manifest.json`, `canonical-input.json`, `budget-plan.json`, per-attempt prompts/events/stderr/responses, optional partial responses for failed attempts, optional tool-call logs/seals, `blind-candidates.json`, `evaluation.json`, `merged.md`, `error.json`, and workflow-specific context/source-policy artifacts.
|
|
109
|
+
Run artifacts are private local evidence under `.pi/fusion/<session-id>-<pid>/<run-id>/`. They include `manifest.json`, `canonical-input.json`, `budget-plan.json`, per-attempt prompts/events/stderr/responses, optional partial responses for failed attempts, optional tool-call logs/seals, `blind-candidates.json`, `evaluation.json`, `merged.md`, manifest-bound `result.json`, `error.json`, and workflow-specific context/source-policy artifacts. `bg_result` verifies manifest state, fixed artifact references, byte lengths, SHA-256 values, UTF-8, run/workflow identity, and result details before returning merged bytes.
|
|
108
110
|
|
|
109
111
|
Artifact writes use durable private temp-file/fsync/rename. Manifests enforce legal state transitions and record config, resolved models, fixed capabilities, context policy, tool policy, anonymous map, attempts, artifact refs, cumulative usage, and errors. Successful, failed, and cancelled observed attempts preserve complete Pi usage/cost components; public tool results clone the same `Usage` shape.
|
|
110
112
|
|
|
111
113
|
For tool-enabled children, the private audit journal remains open across every low-level `agent_end`, because Pi may still retry, compact and retry, or process a queued continuation. Only terminal `agent_settled` can exclusively publish the complete hash/count/byte seal. Runtime-guard refusal latches process failure, makes that seal incomplete, and forces the result settlement to failed. The child emits one closed `pi-background-tasks.fusion-runtime-guard.v1` stderr frame containing the refusal code, route capacities, request/tool ordinals, exact payload byte count and SHA-256, conservative token estimate, and a bounded message; it never emits the payload itself. The parent validates this frame and reports typed `child_runtime_budget_exceeded` for runtime capacity/loop refusals or `child_cache_policy_invalid` for Claude cache-policy refusal, instead of accepting a later clean-looking result or reducing it to an unexplained exit code. Tool activity after finalization, duplicate settlement, pre-settlement shutdown, extension diagnostics, malformed/duplicate runtime-guard frames, and missing/failed/stale seals are fatal. This lifecycle requires Pi 0.81.1 or newer; older Pi lines do not expose the required terminal event and are not claimed as compatible.
|
|
112
114
|
|
|
113
|
-
|
|
115
|
+
The four public Fusion tools return a background launch receipt after the readiness barrier. Tool-launched runs default to terminal notification plus follow-up wake; `/fusion` uses notification-only. The first successful `bg_result` retrieval durably claims and attaches complete Fusion usage exactly once; repeated retrieval returns the answer without duplicating session accounting. Running retrieval never waits.
|
|
116
|
+
|
|
117
|
+
Cancellation and shutdown are loud and durable when a run store exists. The extension tracks active runs, managed tasks own their abort controllers, `bg_kill` and session shutdown abort them, and terminal task publication waits for workflow settlement. Child processes have a 30 minute wall timeout, 20 minute idle watchdog, SIGTERM grace, SIGKILL wait, process-group kill on POSIX, bounded stdout/stderr, and cleanup-error propagation.
|
|
114
118
|
|
|
115
119
|
## Troubleshooting
|
|
116
120
|
|
|
@@ -40,7 +40,7 @@ A finished badge is cleared when that task's detail view is opened, or when `/bg
|
|
|
40
40
|
|
|
41
41
|
`/tasks`, `/bg-tasks`, and `Shift+Down` open the same overlay. Non-interactive contexts receive an error notification directing users to `/jobs`, `/logs`, `bg_status`, or `bg_logs`.
|
|
42
42
|
|
|
43
|
-
The list view supports selection, paging, stop, confirmed stop-all, history toggle, rerun, output path, and close. The detail view shows task identity, status, runtime, output path, description, task-owned model/context/tokens/tools when reported, command, error, and an output tail.
|
|
43
|
+
The list view supports selection, paging, stop, confirmed stop-all, history toggle, rerun, output path, and close. Rerun is shell-task-only: typed delegate and Fusion tasks fail with guidance to relaunch through their owning tool rather than executing their display command as a shell command. The detail view shows task identity, status, runtime, output path, description, task-owned model/context/tokens/tools when reported, command, error, and an output tail.
|
|
44
44
|
|
|
45
45
|
Detail output semantics:
|
|
46
46
|
|
|
@@ -11,7 +11,7 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-bg_delegate" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Background Delegate**
|
|
14
|
-
- Source: `src/delegate-extension.ts:
|
|
14
|
+
- Source: `src/delegate-extension.ts:292`
|
|
15
15
|
- Description: Launch one background Pi agent seeded with a frozen projection of the current conversation, then return a launch receipt immediately. The child has its own session, a route pinned at launch that is never substituted, and read-only tools. Retrieve its verified answer with bg_result.
|
|
16
16
|
- Root schema: `object`; additionalProperties: `false`
|
|
17
17
|
|
package/docs/tools/bg_kill.md
CHANGED
|
@@ -11,7 +11,7 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-bg_kill" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Background Kill**
|
|
14
|
-
- Source: `src/extension.ts:
|
|
14
|
+
- Source: `src/extension.ts:908`
|
|
15
15
|
- Description: Stop a running background task by ID. Fails loudly if the task is unknown or already finished.
|
|
16
16
|
- Root schema: `object`
|
|
17
17
|
|
package/docs/tools/bg_logs.md
CHANGED
|
@@ -11,7 +11,7 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-bg_logs" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Background Logs**
|
|
14
|
-
- Source: `src/extension.ts:
|
|
14
|
+
- Source: `src/extension.ts:863`
|
|
15
15
|
- Description: Read bounded output from a background task for deliberate inspection; this is not a waiting primitive. Output is capped at 50.0KB for model safety and points to the full output file when truncated.
|
|
16
16
|
- Root schema: `object`
|
|
17
17
|
|
package/docs/tools/bg_result.md
CHANGED
|
@@ -10,15 +10,15 @@ covers_sources: []
|
|
|
10
10
|
# `bg_result`
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-bg_result" generator="scripts/docs/generate.mjs" -->
|
|
13
|
-
- Label: **
|
|
14
|
-
- Source: `src/delegate-extension.ts:
|
|
15
|
-
- Description: Retrieve
|
|
13
|
+
- Label: **Background Result**
|
|
14
|
+
- Source: `src/delegate-extension.ts:453`
|
|
15
|
+
- Description: Retrieve a hash-verified result from a bg_delegate or background Fusion task. Never blocks: a running task returns a typed not-ready result. Oversized answers are never truncated.
|
|
16
16
|
- Root schema: `object`; additionalProperties: `false`
|
|
17
17
|
|
|
18
18
|
| Field | Required | Type | Description | Constraints |
|
|
19
19
|
| --- | --- | --- | --- | --- |
|
|
20
20
|
| `delivery` | no | `string` | inline returns the verified answer text; artifact returns metadata plus the artifact reference. Oversized answers are never truncated. | |
|
|
21
|
-
| `taskId` | yes | `string` |
|
|
21
|
+
| `taskId` | yes | `string` | Background delegate or Fusion task id returned by its launch tool. | |
|
|
22
22
|
|
|
23
23
|
<details>
|
|
24
24
|
<summary>Normalized TypeBox contract</summary>
|
|
@@ -33,7 +33,7 @@ covers_sources: []
|
|
|
33
33
|
"type": "string"
|
|
34
34
|
},
|
|
35
35
|
"taskId": {
|
|
36
|
-
"description": "
|
|
36
|
+
"description": "Background delegate or Fusion task id returned by its launch tool.",
|
|
37
37
|
"type": "string"
|
|
38
38
|
}
|
|
39
39
|
},
|
|
@@ -47,13 +47,13 @@ covers_sources: []
|
|
|
47
47
|
</details>
|
|
48
48
|
<!-- pi-docs:end name="tool-contract-bg_result" -->
|
|
49
49
|
|
|
50
|
-
`bg_result` retrieves the result of a `bg_delegate` task. It never blocks: a running task returns a typed not-ready view, and a terminal task is verified before any answer bytes are returned.
|
|
50
|
+
`bg_result` retrieves the result of a `bg_delegate` or background Fusion task. It never blocks: a running task returns a typed not-ready view, and a terminal task is verified before any answer bytes are returned.
|
|
51
51
|
|
|
52
52
|
## Public arguments
|
|
53
53
|
|
|
54
54
|
Required:
|
|
55
55
|
|
|
56
|
-
- `taskId: string` — task id or unambiguous prefix resolved by the background-task registry. Must be non-empty after trimming.
|
|
56
|
+
- `taskId: string` — delegate or Fusion task id, or an unambiguous prefix resolved by the background-task registry. Must be non-empty after trimming.
|
|
57
57
|
|
|
58
58
|
Optional:
|
|
59
59
|
|
|
@@ -74,7 +74,7 @@ This is not an error and does not wait. End the turn or do other independent wor
|
|
|
74
74
|
|
|
75
75
|
## Verification before return
|
|
76
76
|
|
|
77
|
-
For terminal tasks, the parent evaluates the child artifacts. `result.json` is the child-written commit point. If it is absent, the task has no accepted answer even if the child exited `0`.
|
|
77
|
+
For terminal delegate tasks, the parent evaluates the child artifacts. `result.json` is the child-written commit point. If it is absent, the task has no accepted answer even if the child exited `0`.
|
|
78
78
|
|
|
79
79
|
A present package is accepted only after verifying:
|
|
80
80
|
|
|
@@ -90,6 +90,10 @@ A present package is accepted only after verifying:
|
|
|
90
90
|
|
|
91
91
|
The returned text is decoded from the same aggregate buffer that was hashed. Corruption, stale packages, missing attestations, route drift, or invalid UTF-8 produce typed failures and no answer bytes.
|
|
92
92
|
|
|
93
|
+
## Fusion retrieval
|
|
94
|
+
|
|
95
|
+
A completed Fusion task is accepted only when `manifest.json` is terminal `completed`, its `result.json` and `merged.md` fixed references match, both files match manifest-bound byte lengths and SHA-256 values, run/workflow/artifact identity matches the task, result details carry the current schema, usage is complete, and merged bytes are well-formed UTF-8. The first successful retrieval attaches complete Fusion usage exactly once; later retrievals omit usage to prevent double-counting.
|
|
96
|
+
|
|
93
97
|
## Inline/artifact delivery and no truncation
|
|
94
98
|
|
|
95
99
|
`bg_result` never truncates an answer.
|
|
@@ -102,7 +106,7 @@ Large answers remain complete in `result.json` as base64 blocks plus aggregate h
|
|
|
102
106
|
|
|
103
107
|
## Failure classes users see
|
|
104
108
|
|
|
105
|
-
Common retrieval outcomes:
|
|
109
|
+
Common delegate retrieval outcomes:
|
|
106
110
|
|
|
107
111
|
- `task_unknown` — unknown id/prefix or not a delegate task.
|
|
108
112
|
- `result_unavailable` / `child_exited_without_commit` — terminal task produced no committed result package.
|
|
@@ -113,7 +117,7 @@ Common retrieval outcomes:
|
|
|
113
117
|
- `artifact_read_failed`, `artifact_spill_failed`, `artifact_error` — artifact I/O failure.
|
|
114
118
|
- `result_too_large_for_inline` — explicit inline request exceeded the inline cap.
|
|
115
119
|
|
|
116
|
-
Delegate errors include whether a child process was created, preserved artifact hints when known, and remediation text. Usage missing from the provider is reported as `unavailable`, not synthesized as zero.
|
|
120
|
+
Delegate errors include whether a child process was created, preserved artifact hints when known, and remediation text. Usage missing from the provider is reported as `unavailable`, not synthesized as zero. Fusion retrieval additionally fails on non-completed manifests, identity/schema drift, malformed usage/details, invalid UTF-8, or any manifest/result/merged hash or byte-length mismatch; failed/cancelled runs return their preserved terminal error rather than partial output.
|
|
117
121
|
|
|
118
122
|
## Parent outcome separation
|
|
119
123
|
|
package/docs/tools/bg_run.md
CHANGED
|
@@ -11,7 +11,7 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-bg_run" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Background Run**
|
|
14
|
-
- Source: `src/extension.ts:
|
|
14
|
+
- Source: `src/extension.ts:682`
|
|
15
15
|
- Description: Start a named long-running shell command in the background and return immediately with a task ID and output path. By default, completed, failed, or killed terminal state is delivered automatically as <background-task-notification> and starts a follow-up agent turn; do not sleep or poll merely to wait. Output is written to .pi/tasks and model-visible logs are bounded to 50.0KB.
|
|
16
16
|
- Root schema: `object`
|
|
17
17
|
|
|
@@ -11,7 +11,7 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-bg_run_pi_attested" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Attested Pi Run**
|
|
14
|
-
- Source: `src/extension.ts:
|
|
14
|
+
- Source: `src/extension.ts:767`
|
|
15
15
|
- Description: Opt-in evidence-oriented direct Pi spawn. Launches exactly one `pi --mode json` child, records raw Pi events/stderr, hashes prompt/report/output, observes OAuth through ModelRegistry, and emits a strict attestation sidecar only after successful completion.
|
|
16
16
|
- Root schema: `object`
|
|
17
17
|
|
package/docs/tools/bg_status.md
CHANGED
|
@@ -11,7 +11,7 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-bg_status" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Background Status**
|
|
14
|
-
- Source: `src/extension.ts:
|
|
14
|
+
- Source: `src/extension.ts:832`
|
|
15
15
|
- Description: Inspect one background task or list all running/recent background tasks. This is a point-in-time inspection tool, not a waiting primitive.
|
|
16
16
|
- Root schema: `object`
|
|
17
17
|
|
|
@@ -11,8 +11,8 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-fusion_investigate" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Fusion Investigate**
|
|
14
|
-
- Source: `src/fusion-extension.ts:
|
|
15
|
-
- Description:
|
|
14
|
+
- Source: `src/fusion-extension.ts:1197`
|
|
15
|
+
- Description: Start a five-model Fusion investigation as a tracked background task and return immediately after durable preflight. Retrieve the verified result with bg_result after notification. Candidate children run in clean bounded read-only contexts.
|
|
16
16
|
- Root schema: `object`; additionalProperties: `false`
|
|
17
17
|
|
|
18
18
|
| Field | Required | Type | Description | Constraints |
|
|
@@ -103,9 +103,11 @@ Investigate uses clean-task canonical input (`pi-background-tasks.fusion-input.v
|
|
|
103
103
|
|
|
104
104
|
Candidate children run with the fixed inspect policy: `read`, `grep`, `find`, and `ls` only, with built-in tools disabled and Fusion/background/write/shell tools denied. Evaluator, evaluator-repair, and merger run with no tools.
|
|
105
105
|
|
|
106
|
-
## Execution model
|
|
106
|
+
## Execution and delivery model
|
|
107
107
|
|
|
108
|
-
Three inspect candidates independently re-derive repository facts, a blind evaluator compares anonymous candidate answers, and a merger synthesizes the final answer. One evaluator-repair child is run only when the first evaluator response is invalid JSON or fails the evaluation schema.
|
|
108
|
+
After durable no-child preflight, the tool returns a tracked background task receipt. Three inspect candidates independently re-derive repository facts, a blind evaluator compares anonymous candidate answers, and a merger synthesizes the final answer. One evaluator-repair child is run only when the first evaluator response is invalid JSON or fails the evaluation schema.
|
|
109
|
+
|
|
110
|
+
Wait for the terminal notification, then call `bg_result({taskId})` once. Retrieval verifies the committed result and never truncates. Repository reads are live, so continue only independent work and do not mutate the investigated scope while the task runs.
|
|
109
111
|
|
|
110
112
|
## Failure behavior
|
|
111
113
|
|
|
@@ -11,8 +11,8 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-fusion_reason" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Fusion Reason**
|
|
14
|
-
- Source: `src/fusion-extension.ts:
|
|
15
|
-
- Description:
|
|
14
|
+
- Source: `src/fusion-extension.ts:1179`
|
|
15
|
+
- Description: Start a five-model Fusion reason workflow as a tracked background task and return immediately after durable preflight. Retrieve the verified result with bg_result after notification. Candidate children receive the reason projection and no tools; evaluator and merger also run without tools.
|
|
16
16
|
- Root schema: `object`; additionalProperties: `false`
|
|
17
17
|
|
|
18
18
|
| Field | Required | Type | Description | Constraints |
|
|
@@ -59,11 +59,11 @@ The schema is closed: `prompt` is required, must trim to non-blank text, and no
|
|
|
59
59
|
|
|
60
60
|
Candidate children run with `--no-tools`. The blind evaluator, conditional evaluator-repair, and merger also run with `--no-tools` by stage policy.
|
|
61
61
|
|
|
62
|
-
## Execution model
|
|
62
|
+
## Execution and delivery model
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
The tool freezes its input, completes durable no-child preflight, registers a managed background task, and returns its task/run id immediately. The workflow then starts three candidate children, a blind evaluator, optional evaluator repair, and a merger.
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
Wait for the terminal notification and call `bg_result({taskId})` once. `bg_result` verifies `manifest.json`, `result.json`, and `merged.md` hashes before returning bytes; oversized output becomes an artifact reference, never truncation. Complete Fusion usage is attached to the first successful retrieval exactly once so repeated retrieval cannot double-count session cost.
|
|
67
67
|
|
|
68
68
|
## Limitations
|
|
69
69
|
|
|
@@ -11,8 +11,8 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-fusion_research" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Fusion Research**
|
|
14
|
-
- Source: `src/fusion-extension.ts:
|
|
15
|
-
- Description:
|
|
14
|
+
- Source: `src/fusion-extension.ts:1216`
|
|
15
|
+
- Description: Start a five-model Fusion research workflow as a tracked background task and return immediately after durable preflight. Retrieve the verified result with bg_result after notification. Targeted URL fetch is not web search; fetched pages and URLs are untrusted.
|
|
16
16
|
- Root schema: `object`; additionalProperties: `false`
|
|
17
17
|
|
|
18
18
|
| Field | Required | Type | Description | Constraints |
|
|
@@ -153,6 +153,10 @@ The private `fusion_web_fetch` schema is closed: `{url, extract?: 'text'|'markdo
|
|
|
153
153
|
|
|
154
154
|
Failures use typed error codes such as `invalid_url`, `unsupported_scheme`, `blocked_address`, `dns_failure`, `redirect_limit`, `redirect_blocked`, `response_too_large`, `unsupported_content_type`, `request_timeout`, `network_error`, `extraction_failed`, and `http_error`.
|
|
155
155
|
|
|
156
|
+
## Background delivery
|
|
157
|
+
|
|
158
|
+
After durable no-child preflight, the tool returns a tracked background task receipt. Wait for the terminal notification, then call `bg_result({taskId})` once; retrieval verifies the committed result and never truncates. Repository reads are live, so do not mutate relevant files while the task runs.
|
|
159
|
+
|
|
156
160
|
## Audit
|
|
157
161
|
|
|
158
162
|
Research candidates write sealed per-attempt tool-call logs. Logs persist tool names, byte counts, SHA-256 digests, status, duration, and fetch provenance (`url`/`final_url`/status/bytes/content hash for successful fetches; only a rejected URL hash for rejected fetches). Raw arguments, raw results, and page content are not written to the audit log.
|
|
@@ -11,8 +11,8 @@ covers_sources: []
|
|
|
11
11
|
|
|
12
12
|
<!-- pi-docs:begin name="tool-contract-fusion_validate" generator="scripts/docs/generate.mjs" -->
|
|
13
13
|
- Label: **Fusion Validate**
|
|
14
|
-
- Source: `src/fusion-extension.ts:
|
|
15
|
-
- Description:
|
|
14
|
+
- Source: `src/fusion-extension.ts:1236`
|
|
15
|
+
- Description: Start an advisory, read-only Fusion validation review as a tracked background task and return immediately after durable preflight. Retrieve the verified result with bg_result after notification. It is not a build/test/lint substitute and never modifies files.
|
|
16
16
|
- Root schema: `object`; additionalProperties: `false`
|
|
17
17
|
|
|
18
18
|
| Field | Required | Type | Description | Constraints |
|
|
@@ -197,7 +197,9 @@ Each candidate must return closed JSON (`pi-background-tasks.fusion-validation-c
|
|
|
197
197
|
|
|
198
198
|
After the no-tool merger child runs, the host renders the final validation report from validated accounting so included findings are preserved, duplicate groups are merged deterministically, excluded findings are listed only as exclusions, and candidate labels/source ids are sanitized from rationale text.
|
|
199
199
|
|
|
200
|
-
##
|
|
200
|
+
## Background delivery and advisory limitation
|
|
201
|
+
|
|
202
|
+
After durable no-child preflight, the tool returns a tracked background task receipt. Wait for the terminal notification, then call `bg_result({taskId})` once; retrieval verifies the committed report and never truncates. The repository is read live, so do not mutate the reviewed scope while the task runs.
|
|
201
203
|
|
|
202
204
|
`fusion_validate` never modifies files, never runs builds/tests/linters/security scanners, and does not gate anything. It is an advisory read-only review. Supply real verification evidence when available, and state known limitations/exclusions explicitly.
|
|
203
205
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-background-tasks",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Pi extension for durable background shell tasks, read-only delegated agents, local attested Pi runs, and fixed-purpose Fusion workflows through child Pi processes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "ISC",
|
package/src/core/common.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { extname, isAbsolute, join, win32 } from 'node:path';
|
|
|
4
4
|
import { DEFAULT_MAX_BYTES } from '@earendil-works/pi-coding-agent';
|
|
5
5
|
import type { BackgroundTaskChildProcess } from './registry.js';
|
|
6
6
|
import type { DelegateBudgetRouteSource } from './delegate/types.js';
|
|
7
|
+
import type { FusionResultDetails, FusionUsage, FusionWorkflowId } from './fusion/types.js';
|
|
7
8
|
|
|
8
9
|
export const TASK_STATUS_VALUES = ['running', 'completed', 'failed', 'killed'] as const;
|
|
9
10
|
export const TERMINAL_TASK_STATUS_VALUES = ['completed', 'failed', 'killed'] as const;
|
|
@@ -62,6 +63,7 @@ export interface BgTaskSnapshot {
|
|
|
62
63
|
telemetryUnavailableReason?: string | undefined;
|
|
63
64
|
attestationPath?: string | undefined;
|
|
64
65
|
delegate?: DelegateTaskFacts | undefined;
|
|
66
|
+
fusion?: FusionTaskFacts | undefined;
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
export interface AttestedPiTaskFiles {
|
|
@@ -99,6 +101,25 @@ export interface DelegateTaskOutcome {
|
|
|
99
101
|
toolCalls?: number | undefined;
|
|
100
102
|
}
|
|
101
103
|
|
|
104
|
+
/** Fusion-specific task facts surfaced through snapshots and `bg_result`. */
|
|
105
|
+
export interface FusionTaskFacts {
|
|
106
|
+
runId: string;
|
|
107
|
+
workflow: FusionWorkflowId;
|
|
108
|
+
artifactDir: string;
|
|
109
|
+
artifactDirAbs: string;
|
|
110
|
+
state: string;
|
|
111
|
+
outcome?: FusionTaskOutcome | undefined;
|
|
112
|
+
/** Durable once-only accounting claim made by the first successful bg_result retrieval. */
|
|
113
|
+
usageDelivered: boolean;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface FusionTaskOutcome {
|
|
117
|
+
status: 'committed' | 'failed' | 'cancelled';
|
|
118
|
+
resultDetails?: FusionResultDetails | undefined;
|
|
119
|
+
usage?: FusionUsage | undefined;
|
|
120
|
+
error?: string | undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
102
123
|
export interface BgTask extends Omit<BgTaskSnapshot, 'name'> {
|
|
103
124
|
name: string;
|
|
104
125
|
outputAbsPath: string;
|
|
@@ -129,6 +150,11 @@ export interface BgTask extends Omit<BgTaskSnapshot, 'name'> {
|
|
|
129
150
|
attestationPath?: string | undefined;
|
|
130
151
|
attestedPi?: AttestedPiTaskFiles | undefined;
|
|
131
152
|
delegate?: DelegateTaskFacts | undefined;
|
|
153
|
+
fusion?: FusionTaskFacts | undefined;
|
|
154
|
+
/** Cancellation hook for an in-process managed task such as Fusion. */
|
|
155
|
+
managedCancel?: (() => void) | undefined;
|
|
156
|
+
managedCancelRequested?: boolean | undefined;
|
|
157
|
+
managedStopWaitMs?: number | undefined;
|
|
132
158
|
metadataWriteChain?: Promise<void> | undefined;
|
|
133
159
|
waiters: Array<() => void>;
|
|
134
160
|
}
|
|
@@ -226,6 +252,22 @@ export interface StartTaskOptions {
|
|
|
226
252
|
}
|
|
227
253
|
|
|
228
254
|
/** Prepared delegate launch handed to the registry after preflight has succeeded. */
|
|
255
|
+
export interface StartManagedTaskOptions {
|
|
256
|
+
id: string;
|
|
257
|
+
name: string;
|
|
258
|
+
command: string;
|
|
259
|
+
description?: string | undefined;
|
|
260
|
+
isAgent: boolean;
|
|
261
|
+
completion: Promise<void>;
|
|
262
|
+
cancel: () => void;
|
|
263
|
+
notifyOnCompletion: boolean;
|
|
264
|
+
triggerOnCompletion: boolean;
|
|
265
|
+
fusion: FusionTaskFacts;
|
|
266
|
+
stopWaitMs?: number | undefined;
|
|
267
|
+
/** Prevent terminal publication until the launch receipt handoff is observable. */
|
|
268
|
+
terminalPublicationGate?: Promise<void> | undefined;
|
|
269
|
+
}
|
|
270
|
+
|
|
229
271
|
export interface StartDelegateTaskOptions {
|
|
230
272
|
name: string;
|
|
231
273
|
argv: readonly string[];
|
|
@@ -687,10 +729,15 @@ export function shellInvocation(
|
|
|
687
729
|
failShellInvocation('PI_BG_SHELL must be exactly cmd or bash');
|
|
688
730
|
}
|
|
689
731
|
const explicitPath =
|
|
690
|
-
requestedPath !== undefined
|
|
732
|
+
requestedPath !== undefined
|
|
733
|
+
? validateWindowsShellPath(requestedPath, 'PI_BG_SHELL_PATH')
|
|
734
|
+
: undefined;
|
|
691
735
|
if (requestedShell === 'cmd') {
|
|
692
736
|
const comSpec = env['ComSpec'];
|
|
693
|
-
return cmdShellInvocation(
|
|
737
|
+
return cmdShellInvocation(
|
|
738
|
+
command,
|
|
739
|
+
explicitPath ?? (comSpec && comSpec.length > 0 ? comSpec : 'cmd.exe'),
|
|
740
|
+
);
|
|
694
741
|
}
|
|
695
742
|
return posixShellInvocation(command, explicitPath ?? resolveWindowsBash(env));
|
|
696
743
|
}
|
|
@@ -728,6 +775,7 @@ export function snapshot(task: BgTask): BgTaskSnapshot {
|
|
|
728
775
|
telemetryUnavailableReason: task.telemetryUnavailableReason,
|
|
729
776
|
attestationPath: task.attestationPath,
|
|
730
777
|
delegate: task.delegate,
|
|
778
|
+
fusion: task.fusion,
|
|
731
779
|
};
|
|
732
780
|
}
|
|
733
781
|
|