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.
Files changed (72) hide show
  1. package/BACKGROUND-TASKS-INSTRUCTIONS.md +63 -0
  2. package/PUBLISHING.md +43 -29
  3. package/README.md +234 -385
  4. package/TESTING.md +15 -9
  5. package/TEST_PLAN.md +46 -13
  6. package/docs/INDEX.md +157 -0
  7. package/docs/api/eventbus-v1.md +166 -0
  8. package/docs/assets/architecture.svg +78 -0
  9. package/docs/assets/footer-dock.svg +47 -0
  10. package/docs/assets/logo.svg +49 -0
  11. package/docs/attestations.json +189 -0
  12. package/docs/choose-a-workflow.md +98 -0
  13. package/docs/commands/bg-clear.md +70 -0
  14. package/docs/commands/bg-update.md +82 -0
  15. package/docs/commands/bg.md +90 -0
  16. package/docs/commands/fusion-models.md +70 -0
  17. package/docs/commands/fusion.md +69 -0
  18. package/docs/commands/jobs.md +74 -0
  19. package/docs/commands/kill.md +82 -0
  20. package/docs/commands/logs.md +90 -0
  21. package/docs/commands/task-manager.md +109 -0
  22. package/docs/concepts/completion-delivery.md +66 -0
  23. package/docs/concepts/context-projection-and-budgeting.md +79 -0
  24. package/docs/getting-started.md +122 -0
  25. package/docs/manifest.json +1825 -0
  26. package/docs/operations/configuration.md +110 -0
  27. package/docs/operations/releasing.md +67 -0
  28. package/docs/operations/testing.md +101 -0
  29. package/docs/operations/troubleshooting.md +38 -0
  30. package/docs/read-before-edit.md +94 -0
  31. package/docs/reference/runtime-contracts.md +213 -0
  32. package/docs/reference/shortcuts-and-dock.md +70 -0
  33. package/docs/subsystems/attested-pi-runs.md +141 -0
  34. package/docs/subsystems/background-task-runtime.md +85 -0
  35. package/docs/subsystems/child-launch-durability-and-safety.md +57 -0
  36. package/docs/subsystems/delegation.md +190 -0
  37. package/docs/subsystems/docs-freshness-gate.md +26 -0
  38. package/docs/subsystems/fusion.md +121 -0
  39. package/docs/subsystems/host-ui-and-telemetry.md +83 -0
  40. package/docs/tools/bg_delegate.md +193 -0
  41. package/docs/tools/bg_kill.md +114 -0
  42. package/docs/tools/bg_logs.md +133 -0
  43. package/docs/tools/bg_result.md +120 -0
  44. package/docs/tools/bg_run.md +168 -0
  45. package/docs/tools/bg_run_pi_attested.md +170 -0
  46. package/docs/tools/bg_status.md +111 -0
  47. package/docs/tools/fusion_investigate.md +116 -0
  48. package/docs/tools/fusion_reason.md +75 -0
  49. package/docs/tools/fusion_research.md +162 -0
  50. package/docs/tools/fusion_validate.md +206 -0
  51. package/logo.png +0 -0
  52. package/package.json +29 -6
  53. package/src/core/delegate/budget.ts +1 -1
  54. package/src/core/delegate/launch.ts +6 -0
  55. package/src/core/fusion/artifacts.ts +80 -5
  56. package/src/core/fusion/budget.ts +129 -28
  57. package/src/core/fusion/child-protocol.ts +82 -0
  58. package/src/core/fusion/clean-context.ts +91 -0
  59. package/src/core/fusion/config.ts +124 -35
  60. package/src/core/fusion/context.ts +33 -6
  61. package/src/core/fusion/evaluation.ts +392 -15
  62. package/src/core/fusion/orchestrator.ts +274 -25
  63. package/src/core/fusion/pi-child.ts +635 -10
  64. package/src/core/fusion/prompts.ts +167 -6
  65. package/src/core/fusion/source-policy.ts +257 -0
  66. package/src/core/fusion/types.ts +232 -5
  67. package/src/core/fusion/web-fetch.ts +993 -0
  68. package/src/core/fusion/workflows.ts +184 -0
  69. package/src/extension.ts +3 -3
  70. package/src/fusion-child-extension.ts +370 -54
  71. package/src/fusion-extension.ts +625 -125
  72. package/src/testing/normalize.ts +0 -22
@@ -11,14 +11,20 @@ import type {
11
11
  export type FusionThinkingLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
12
12
 
13
13
  export const FUSION_MODEL_CONFIG_SCHEMA_VERSION = 'pi-background-tasks.fusion-models.v1';
14
- export const FUSION_INPUT_SCHEMA_VERSION = 'pi-background-tasks.fusion-input.v4';
14
+ export const FUSION_LEGACY_INPUT_SCHEMA_VERSION = 'pi-background-tasks.fusion-input.v4';
15
+ export const FUSION_INPUT_SCHEMA_VERSION = 'pi-background-tasks.fusion-input.v5';
15
16
  export const FUSION_EVALUATION_SCHEMA_VERSION = 'pi-background-tasks.fusion-evaluation.v1';
16
- export const FUSION_RESULT_SCHEMA_VERSION = 'pi-background-tasks.fusion-result.v3';
17
- export const FUSION_MANIFEST_SCHEMA_VERSION = 'pi-background-tasks.fusion-manifest.v2';
17
+ export const FUSION_VALIDATE_CANDIDATE_SCHEMA_VERSION = 'pi-background-tasks.fusion-validation-candidate.v1';
18
+ export const FUSION_LEGACY_RESULT_SCHEMA_VERSION = 'pi-background-tasks.fusion-result.v4';
19
+ export const FUSION_RESULT_SCHEMA_VERSION = 'pi-background-tasks.fusion-result.v5';
20
+ export const FUSION_LEGACY_MANIFEST_SCHEMA_VERSION = 'pi-background-tasks.fusion-manifest.v3';
21
+ export const FUSION_MANIFEST_SCHEMA_VERSION = 'pi-background-tasks.fusion-manifest.v4';
18
22
  export const FUSION_CONTEXT_LEDGER_SCHEMA_VERSION = 'pi-background-tasks.fusion-context-ledger.v2';
23
+ export const FUSION_SOURCE_POLICY_SCHEMA_VERSION = 'pi-background-tasks.fusion-source-policy.v1';
19
24
  export const FUSION_BUDGET_PLAN_SCHEMA_VERSION = 'pi-background-tasks.fusion-budget-plan.v3';
20
25
  export const FUSION_CALIBRATION_VIOLATION_SCHEMA_VERSION =
21
26
  'pi-background-tasks.fusion-calibration-violation.v1';
27
+ export const FUSION_TOOL_CALL_LOG_SCHEMA_VERSION = 'pi-background-tasks.fusion-tool-call.v1';
22
28
 
23
29
  /**
24
30
  * Conversation-projection transform shared by every Fusion entry point.
@@ -43,6 +49,74 @@ export type FusionCandidateId = (typeof FUSION_CANDIDATE_IDS)[number];
43
49
  export const FUSION_STAGE_VALUES = ['candidate', 'evaluation', 'merge'] as const;
44
50
  export type FusionStage = (typeof FUSION_STAGE_VALUES)[number];
45
51
 
52
+ export const FUSION_CAPABILITY_VALUES = Object.freeze(['reason', 'inspect', 'research'] as const);
53
+ export type FusionCapability = (typeof FUSION_CAPABILITY_VALUES)[number];
54
+
55
+ /** No-tools capability for reason candidates, evaluator, repair, and merger. */
56
+ export const FUSION_NO_TOOLS_CAPABILITY: FusionCapability = 'reason';
57
+ /** Legacy default retained for old type imports only. New workflows never default. */
58
+ export const FUSION_BRAINSTORM_DEFAULT_CAPABILITY: FusionCapability = 'inspect';
59
+ /** @deprecated New v5 workflows have no caller capability default. */
60
+ export const FUSION_DEFAULT_CAPABILITY: FusionCapability = FUSION_BRAINSTORM_DEFAULT_CAPABILITY;
61
+
62
+ export const FUSION_WEB_FETCH_TOOL_NAME = 'fusion_web_fetch' as const;
63
+ export const FUSION_INSPECT_TOOLS = Object.freeze(['read', 'grep', 'find', 'ls'] as const);
64
+ export const FUSION_RESEARCH_TOOLS = Object.freeze([
65
+ 'read',
66
+ 'grep',
67
+ 'find',
68
+ 'ls',
69
+ FUSION_WEB_FETCH_TOOL_NAME,
70
+ ] as const);
71
+
72
+ /**
73
+ * Workflow identities sharing one orchestrator, one context projection, one
74
+ * evaluation schema, and one artifact store. A workflow selects stage framing and
75
+ * capability policy only; it never changes the canonical input schema.
76
+ */
77
+ export const FUSION_WORKFLOW_IDS = Object.freeze([
78
+ 'reason',
79
+ 'investigate',
80
+ 'research',
81
+ 'validate',
82
+ ] as const);
83
+ export type FusionWorkflowId = (typeof FUSION_WORKFLOW_IDS)[number];
84
+ export const FUSION_PUBLIC_WORKFLOW_NAMES = Object.freeze([
85
+ 'fusion_reason',
86
+ 'fusion_investigate',
87
+ 'fusion_research',
88
+ 'fusion_validate',
89
+ ] as const);
90
+ export type FusionPublicWorkflowName = (typeof FUSION_PUBLIC_WORKFLOW_NAMES)[number];
91
+ export type FusionContextKind = 'session_projection' | 'clean_task';
92
+
93
+ /**
94
+ * The single capability the validate workflow ever runs candidates with.
95
+ *
96
+ * Deliberately separate from the caller-selectable brainstorm default. Although
97
+ * both workflows currently give candidates read-only inspection, validation pins
98
+ * that capability as fixed policy rather than exposing a caller override.
99
+ */
100
+ export const FUSION_VALIDATE_CAPABILITY: FusionCapability = 'inspect';
101
+
102
+ export const FUSION_FORBIDDEN_TOOLS = Object.freeze([
103
+ 'bash',
104
+ 'edit',
105
+ 'write',
106
+ 'fusion_brainstorm',
107
+ 'fusion_reason',
108
+ 'fusion_investigate',
109
+ 'fusion_research',
110
+ 'fusion_validate',
111
+ 'bg_delegate',
112
+ 'bg_result',
113
+ 'bg_run',
114
+ 'bg_kill',
115
+ 'bg_status',
116
+ 'bg_logs',
117
+ 'bg_run_pi_attested',
118
+ ] as const);
119
+
46
120
  /**
47
121
  * Prompt-expansion stages guarded by deterministic size accounting. `evaluation`
48
122
  * and `evaluation_repair` share the evaluator model but render different prompts.
@@ -261,15 +335,73 @@ export interface FusionConversationProjectionV4 {
261
335
 
262
336
  export type FusionConversationProjectionV3 = FusionConversationProjectionV4;
263
337
 
264
- export interface FusionCanonicalInputV4 {
338
+ export interface FusionDeclaredSourceV1 {
339
+ url: string;
340
+ canonical_url: string;
341
+ purpose: string;
342
+ sha256: string;
343
+ }
344
+
345
+ export interface FusionCleanTaskContextV1 {
346
+ kind: 'clean_task';
347
+ policy_id: 'fusion-clean-task-v1';
348
+ declared_sources: readonly FusionDeclaredSourceV1[];
349
+ }
350
+
351
+ export interface FusionSessionProjectionContextV1 {
352
+ kind: 'session_projection';
353
+ policy_id: 'fusion-session-projection-v1';
354
+ system_prompt: string;
355
+ conversation_projection: FusionConversationProjectionV4;
356
+ }
357
+
358
+ export interface FusionCanonicalInputV5Base {
265
359
  schema_version: typeof FUSION_INPUT_SCHEMA_VERSION;
360
+ workflow?: FusionWorkflowId | undefined;
361
+ cwd: string;
362
+ request: FusionCanonicalRequestV3;
363
+ }
364
+
365
+ export interface FusionSessionProjectionCanonicalInputV5 extends FusionCanonicalInputV5Base {
366
+ workflow?: FusionWorkflowId | undefined;
367
+ /** @deprecated v4 readability alias. Present only for session-projection inputs at runtime. */
368
+ system_prompt: string;
369
+ /** @deprecated v4 readability alias. Present only for session-projection inputs at runtime. */
370
+ conversation_projection: FusionConversationProjectionV4;
371
+ context?: FusionSessionProjectionContextV1 | undefined;
372
+ }
373
+
374
+ export interface FusionCleanTaskCanonicalInputV5 extends FusionCanonicalInputV5Base {
375
+ workflow: Exclude<FusionWorkflowId, 'reason'>;
376
+ context: FusionCleanTaskContextV1;
377
+ }
378
+
379
+ export type FusionCanonicalInputV5 =
380
+ | FusionSessionProjectionCanonicalInputV5
381
+ | FusionCleanTaskCanonicalInputV5;
382
+
383
+ /** Legacy v4 shape retained for frozen golden fixtures/readability only. */
384
+ export interface FusionCanonicalInputV4 {
385
+ schema_version: typeof FUSION_LEGACY_INPUT_SCHEMA_VERSION;
266
386
  cwd: string;
267
387
  system_prompt: string;
268
388
  request: FusionCanonicalRequestV3;
269
389
  conversation_projection: FusionConversationProjectionV4;
270
390
  }
271
391
 
272
- export type FusionCanonicalInputV3 = FusionCanonicalInputV4;
392
+ export type FusionCanonicalInputV3 = FusionCanonicalInputV5;
393
+
394
+ export interface FusionSourcePolicyV1 {
395
+ schema_version: typeof FUSION_SOURCE_POLICY_SCHEMA_VERSION;
396
+ workflow: 'research';
397
+ cwd: string;
398
+ sources: readonly FusionDeclaredSourceV1[];
399
+ root_sha256: string;
400
+ }
401
+
402
+ export interface FusionSourcePolicyArtifactRef extends FusionArtifactRef {
403
+ root_sha256: string;
404
+ }
273
405
 
274
406
  export interface CandidateAssessment {
275
407
  candidate_id: FusionCandidateId;
@@ -302,12 +434,56 @@ export interface FusionSynthesisPlan {
302
434
  must_avoid: readonly string[];
303
435
  }
304
436
 
437
+ export type FusionValidationSeverity = 'critical' | 'high' | 'minor';
438
+
439
+ export interface FusionValidationFindingRecord {
440
+ id: string;
441
+ candidate_id: FusionCandidateId;
442
+ severity: FusionValidationSeverity;
443
+ location: string;
444
+ evidence: string;
445
+ impact: string;
446
+ summary: string;
447
+ }
448
+
449
+ export interface FusionValidationFindingDecision {
450
+ source_id: string;
451
+ disposition: 'include' | 'exclude';
452
+ rationale: string;
453
+ group_id?: string | undefined;
454
+ }
455
+
456
+ export interface FusionValidationFindingGroup {
457
+ group_id: string;
458
+ source_ids: readonly string[];
459
+ severity: FusionValidationSeverity;
460
+ location: string;
461
+ evidence: string;
462
+ impact: string;
463
+ summary: string;
464
+ rationale: string;
465
+ }
466
+
467
+ export interface FusionValidationFindingAccounting {
468
+ findings: readonly FusionValidationFindingRecord[];
469
+ decisions: readonly FusionValidationFindingDecision[];
470
+ groups: readonly FusionValidationFindingGroup[];
471
+ }
472
+
473
+ export interface FusionValidationCandidateReportV1 {
474
+ schema_version: typeof FUSION_VALIDATE_CANDIDATE_SCHEMA_VERSION;
475
+ findings: readonly Omit<FusionValidationFindingRecord, 'id' | 'candidate_id'>[];
476
+ verified: readonly string[];
477
+ limitations: readonly string[];
478
+ }
479
+
305
480
  export interface FusionEvaluationV1 {
306
481
  schema_version: typeof FUSION_EVALUATION_SCHEMA_VERSION;
307
482
  candidate_assessments: readonly [CandidateAssessment, CandidateAssessment, CandidateAssessment];
308
483
  agreements: readonly string[];
309
484
  conflicts: readonly FusionConflict[];
310
485
  synthesis_plan: FusionSynthesisPlan;
486
+ validation_accounting?: FusionValidationFindingAccounting | undefined;
311
487
  }
312
488
 
313
489
  /** Exact Pi usage contract used at the child, artifact, and host tool-result boundaries. */
@@ -376,8 +552,11 @@ export interface FusionResultBudgetDetails {
376
552
  export interface FusionResultDetails {
377
553
  schema_version: typeof FUSION_RESULT_SCHEMA_VERSION;
378
554
  run_id: string;
555
+ workflow: FusionWorkflowId;
379
556
  source: FusionSource;
380
557
  status: 'completed';
558
+ context: { kind: FusionContextKind; policy_id: string };
559
+ tool_policy: { candidate_tools: readonly string[]; evaluation_tools: readonly []; merge_tools: readonly [] };
381
560
  artifact_dir: string;
382
561
  models: {
383
562
  candidates: readonly [string, string, string];
@@ -541,6 +720,39 @@ export interface FusionChildUsage extends FusionUsage {
541
720
  qualifiedId: string;
542
721
  }
543
722
 
723
+ export type FusionToolCallLogStatus = 'ok' | 'error';
724
+
725
+ export interface FusionToolCallLogRecord {
726
+ schema_version: typeof FUSION_TOOL_CALL_LOG_SCHEMA_VERSION;
727
+ ordinal: number;
728
+ tool_name: string;
729
+ arguments_sha256: string;
730
+ arguments_bytes: number;
731
+ result_bytes: number;
732
+ result_sha256: string;
733
+ status: FusionToolCallLogStatus;
734
+ duration_ms: number;
735
+ url?: string | undefined;
736
+ /** SHA-256 of a rejected attempted fetch URL; raw rejected URLs are never persisted. */
737
+ rejected_url_sha256?: string | undefined;
738
+ final_url?: string | undefined;
739
+ http_status?: number | undefined;
740
+ response_bytes?: number | undefined;
741
+ content_sha256?: string | undefined;
742
+ }
743
+
744
+ export interface FusionToolCallLogSummary {
745
+ count: number;
746
+ total_result_bytes: number;
747
+ trace_complete: boolean;
748
+ }
749
+
750
+ export interface FusionToolCallTrace {
751
+ bytes: Buffer;
752
+ records: readonly FusionToolCallLogRecord[];
753
+ summary: FusionToolCallLogSummary;
754
+ }
755
+
544
756
  export interface FusionChildRunResult {
545
757
  stage: FusionStage;
546
758
  slot?: 1 | 2 | 3;
@@ -554,6 +766,7 @@ export interface FusionChildRunResult {
554
766
  stderr: Buffer;
555
767
  exitCode: number;
556
768
  signal: NodeJS.Signals | null;
769
+ toolCallTrace?: FusionToolCallTrace;
557
770
  }
558
771
 
559
772
  export interface FusionAttemptArtifactRecord {
@@ -566,6 +779,8 @@ export interface FusionAttemptArtifactRecord {
566
779
  stderr_path?: string;
567
780
  response_path?: string;
568
781
  partial_response_path?: string;
782
+ tool_calls_path?: string;
783
+ tool_calls?: FusionToolCallLogSummary;
569
784
  provider?: string;
570
785
  model?: string;
571
786
  qualifiedId?: string;
@@ -582,6 +797,7 @@ export interface FusionArtifactRef {
582
797
  export interface FusionArtifactManifest {
583
798
  schema_version: typeof FUSION_MANIFEST_SCHEMA_VERSION;
584
799
  run_id: string;
800
+ workflow: FusionWorkflowId;
585
801
  source: FusionSource;
586
802
  state: FusionState;
587
803
  created_at: string;
@@ -594,6 +810,13 @@ export interface FusionArtifactManifest {
594
810
  merger: string;
595
811
  thinking_level: string;
596
812
  };
813
+ capabilities: {
814
+ candidate: FusionCapability;
815
+ evaluation: FusionCapability;
816
+ merge: FusionCapability;
817
+ };
818
+ context: { kind: FusionContextKind; policy_id: string; ledger_artifact?: string; source_policy_artifact?: string };
819
+ tool_policy: { candidate_tools: readonly string[]; evaluation_tools: readonly []; merge_tools: readonly [] };
597
820
  usage: FusionUsage;
598
821
  attempts: readonly FusionAttemptArtifactRecord[];
599
822
  artifacts: Readonly<Record<string, FusionArtifactRef>>;
@@ -674,6 +897,10 @@ export interface FusionBudgetEmptyRequestVerdict {
674
897
 
675
898
  export interface FusionBudgetPlanV1 {
676
899
  schema_version: typeof FUSION_BUDGET_PLAN_SCHEMA_VERSION;
900
+ workflow: FusionWorkflowId;
901
+ context: { kind: FusionContextKind; policy_id: string };
902
+ fixed_candidate_policy: { capability: FusionCapability; tools: readonly string[] };
903
+ tool_policy: { candidate_tools: readonly string[]; evaluation_tools: readonly []; merge_tools: readonly [] };
677
904
  policy: FusionBudgetPolicyDescriptor;
678
905
  routes: readonly FusionRouteCapacity[];
679
906
  stages: readonly FusionStageBudgetPlanEntry[];