@piagent/platform 1.5.4 → 1.6.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.
Files changed (230) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/README.md +9 -8
  3. package/README.vi.md +9 -5
  4. package/adapters/web-frontend/profile.json +2 -4
  5. package/architecture/layers.json +18 -3
  6. package/benchmarks/deep-logic-v1/SPECIALIST_PROTOCOL.vi.md +122 -0
  7. package/benchmarks/deep-logic-v1/grade.mjs +272 -10
  8. package/benchmarks/deep-logic-v1/project/apps/admin/src/billing-summary.js +3 -0
  9. package/benchmarks/deep-logic-v1/project/benchmark-contract/public-smoke.test.js +166 -0
  10. package/benchmarks/deep-logic-v1/project/package.json +1 -1
  11. package/benchmarks/deep-logic-v1/project/packages/billing/src/close-period.js +3 -0
  12. package/benchmarks/deep-logic-v1/project/packages/billing/src/plan-timeline.js +3 -0
  13. package/benchmarks/deep-logic-v1/project/test/smoke.test.js +7 -1
  14. package/benchmarks/deep-logic-v1/prompts/budgeted-context-graph.md +2 -0
  15. package/benchmarks/deep-logic-v1/prompts/fair-dependency-scheduler.md +2 -0
  16. package/benchmarks/deep-logic-v1/prompts/layered-policy-resolution.md +2 -0
  17. package/benchmarks/deep-logic-v1/prompts/resumable-stream-assembly.md +3 -1
  18. package/benchmarks/deep-logic-v1/prompts/revision-event-reconciliation.md +2 -0
  19. package/benchmarks/deep-logic-v1/prompts/temporal-usage-billing-close.md +123 -0
  20. package/benchmarks/deep-logic-v1/prompts/transactional-config-merge.md +2 -0
  21. package/benchmarks/deep-logic-v1/suite.json +51 -3
  22. package/benchmarks/deep-logic-v1/variant.mjs +22 -1
  23. package/benchmarks/production-v1/spend-control.v1.json +68 -0
  24. package/benchmarks/production-v1/suite.json +42 -3
  25. package/catalog/capabilities.json +6 -6
  26. package/docs/command-reference-vietnamese.md +6 -6
  27. package/docs/context-engine.md +7 -1
  28. package/docs/distribution-standard.md +7 -7
  29. package/docs/en/architecture.md +1 -0
  30. package/docs/languages.json +4 -4
  31. package/docs/model-options.md +8 -5
  32. package/docs/operator-manual-vietnamese.md +13 -11
  33. package/docs/project-adapters.md +2 -2
  34. package/docs/publishing-for-teams.md +9 -0
  35. package/docs/quality-benchmark.md +271 -62
  36. package/docs/release-install-policy.md +10 -9
  37. package/docs/runtime-policy-design.md +4 -4
  38. package/docs/runtime-quality-baseline.md +13 -6
  39. package/docs/security-threat-model.md +2 -2
  40. package/docs/task-lifecycle-vietnamese.md +2 -2
  41. package/docs/team-onboarding.md +2 -2
  42. package/docs/usage-observability.md +7 -2
  43. package/docs/vi/architecture.md +1 -0
  44. package/docs-site/architecture.html +1 -1
  45. package/docs-site/benchmark.html +1 -1
  46. package/docs-site/commands.html +1 -1
  47. package/docs-site/context-engine.html +1 -1
  48. package/docs-site/en/architecture.html +1 -1
  49. package/docs-site/en/benchmark.html +1 -1
  50. package/docs-site/en/commands.html +1 -1
  51. package/docs-site/en/context-engine.html +1 -1
  52. package/docs-site/en/index.html +1 -1
  53. package/docs-site/en/mcp-approval.html +1 -1
  54. package/docs-site/en/mcp-auth.html +1 -1
  55. package/docs-site/en/mcp-servers.html +1 -1
  56. package/docs-site/en/mcp.html +1 -1
  57. package/docs-site/en/permissions.html +1 -1
  58. package/docs-site/en/profiles.html +1 -1
  59. package/docs-site/en/quickstart.html +1 -1
  60. package/docs-site/en/runtime.html +1 -1
  61. package/docs-site/en/scope.html +1 -1
  62. package/docs-site/en/security.html +1 -1
  63. package/docs-site/en/team.html +1 -1
  64. package/docs-site/en/whats-new.html +1 -1
  65. package/docs-site/en/workflows.html +1 -1
  66. package/docs-site/index.html +1 -1
  67. package/docs-site/mcp-approval.html +1 -1
  68. package/docs-site/mcp-auth.html +1 -1
  69. package/docs-site/mcp-servers.html +1 -1
  70. package/docs-site/mcp.html +1 -1
  71. package/docs-site/permissions.html +1 -1
  72. package/docs-site/profiles.html +1 -1
  73. package/docs-site/quickstart.html +1 -1
  74. package/docs-site/runtime.html +1 -1
  75. package/docs-site/scope.html +1 -1
  76. package/docs-site/security.html +1 -1
  77. package/docs-site/team.html +1 -1
  78. package/docs-site/whats-new.html +1 -1
  79. package/docs-site/workflows.html +1 -1
  80. package/evals/fixtures/benchmark-assurance-evidence.invalid.json +1 -1
  81. package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
  82. package/evals/fixtures/piagent-webui/session-live-state-v1.invalid.json +18 -0
  83. package/evals/fixtures/piagent-webui/session-live-state-v1.valid.json +27 -0
  84. package/evals/fs4-readiness-matrix.v1.json +2 -2
  85. package/evals/fs5-causal-arm.v1.json +2 -2
  86. package/evals/fs5-pilot-protocol.v1.json +2 -2
  87. package/evals/fs5-pilot-protocol.v4.json +6 -5
  88. package/evals/fs5-pilot-protocol.v5.json +7 -6
  89. package/evals/private-holdout-v1/public-exposure.v1.json +1 -1
  90. package/package.json +3 -1
  91. package/packages/piagent-core/benchmark/benchmark-assurance.js +4 -1
  92. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +91 -9
  93. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +38 -7
  94. package/packages/piagent-core/benchmark/benchmark-cli.js +7 -7
  95. package/packages/piagent-core/benchmark/benchmark-codex.js +3 -1
  96. package/packages/piagent-core/benchmark/benchmark-comparison.js +271 -2
  97. package/packages/piagent-core/benchmark/benchmark-core.js +732 -661
  98. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +7 -5
  99. package/packages/piagent-core/benchmark/benchmark-forensics.js +439 -4
  100. package/packages/piagent-core/benchmark/benchmark-host-readiness.js +639 -0
  101. package/packages/piagent-core/benchmark/benchmark-matrix.js +22 -4
  102. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +317 -0
  103. package/packages/piagent-core/benchmark/benchmark-preflight.js +3 -1
  104. package/packages/piagent-core/benchmark/benchmark-process.js +6 -5
  105. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +126 -0
  106. package/packages/piagent-core/benchmark/benchmark-record-validation.js +183 -0
  107. package/packages/piagent-core/benchmark/benchmark-report.js +116 -12
  108. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +14 -0
  109. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +26 -0
  110. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +782 -0
  111. package/packages/piagent-core/benchmark/benchmark-statistics.js +64 -0
  112. package/packages/piagent-core/benchmark/benchmark-stop-policy.js +8 -5
  113. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +31 -0
  114. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +13 -9
  115. package/packages/piagent-core/benchmark/benchmark-suite.js +128 -2
  116. package/packages/piagent-core/benchmark/benchmark-summary-support.js +376 -0
  117. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +971 -0
  118. package/packages/piagent-core/benchmark/benchmark-usage.js +311 -0
  119. package/packages/piagent-core/benchmark/benchmark-workflow.js +166 -0
  120. package/packages/piagent-core/docs/context-efficiency-improvement-plan.md +1080 -0
  121. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +83 -69
  122. package/packages/piagent-core/extensions/acceptance-error-classes.js +160 -0
  123. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +12 -9
  124. package/packages/piagent-core/extensions/acceptance-receipt.js +34 -11
  125. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +518 -0
  126. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +60 -0
  127. package/packages/piagent-core/extensions/context-efficiency-metrics.js +302 -0
  128. package/packages/piagent-core/extensions/context-efficiency-report.js +167 -0
  129. package/packages/piagent-core/extensions/context-engine.js +148 -145
  130. package/packages/piagent-core/extensions/context-evidence.js +48 -0
  131. package/packages/piagent-core/extensions/context-import-links.js +296 -0
  132. package/packages/piagent-core/extensions/context-telemetry-integrity.js +65 -0
  133. package/packages/piagent-core/extensions/criterion-context-pack.js +422 -7
  134. package/packages/piagent-core/extensions/criterion-graph.js +78 -8
  135. package/packages/piagent-core/extensions/guard-types.ts +3 -0
  136. package/packages/piagent-core/extensions/javascript-regex-evidence.js +32 -0
  137. package/packages/piagent-core/extensions/piagent-guard.ts +250 -43
  138. package/packages/piagent-core/extensions/policy-core.js +1 -1
  139. package/packages/piagent-core/extensions/task-contract-view.js +17 -3
  140. package/packages/piagent-core/extensions/task-lifecycle.js +7 -2
  141. package/packages/piagent-core/extensions/task-state.js +40 -134
  142. package/packages/piagent-core/extensions/verification-intelligence.js +3 -1
  143. package/packages/piagent-core/extensions/workspace-evidence-roots.js +157 -0
  144. package/packages/piagent-core/package.json +1 -1
  145. package/packages/piagent-core/policies/base-policy.json +3 -0
  146. package/packages/piagent-core/runtime/context/context-delivery.ts +103 -0
  147. package/packages/piagent-core/runtime/context/context-delta-shadow.ts +53 -0
  148. package/packages/piagent-core/runtime/context/context-efficiency-format.ts +47 -0
  149. package/packages/piagent-core/runtime/context/context-evidence-qualification.ts +32 -0
  150. package/packages/piagent-core/runtime/context/prefix-telemetry.ts +47 -0
  151. package/packages/piagent-core/runtime/context/repository-memory-hints.ts +27 -0
  152. package/packages/piagent-core/runtime/hooks/agent-prompt-telemetry.ts +56 -0
  153. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +162 -102
  154. package/packages/piagent-core/runtime/hooks/completion-hook.ts +5 -6
  155. package/packages/piagent-core/runtime/hooks/input-hook.ts +11 -1
  156. package/packages/piagent-core/runtime/hooks/session-hooks.ts +22 -2
  157. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +7 -2
  158. package/packages/piagent-core/runtime/hooks/tool-result-content-guards.ts +95 -0
  159. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +84 -102
  160. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +9 -3
  161. package/packages/piagent-core/runtime/inspection/activity-recovery.ts +104 -0
  162. package/packages/piagent-core/runtime/inspection/approval-broker.ts +29 -5
  163. package/packages/piagent-core/runtime/inspection/task-compaction-history.ts +1 -1
  164. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +1 -1
  165. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +53 -0
  166. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +34 -6
  167. package/packages/piagent-core/runtime/model/authenticated-catalog.ts +17 -9
  168. package/packages/piagent-core/runtime/model/openai-codex-reasoning.ts +83 -0
  169. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +238 -0
  170. package/packages/piagent-core/runtime/orchestration/role-policy.ts +1 -1
  171. package/packages/piagent-core/runtime/product/activity-inspector.ts +7 -2
  172. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +4 -2
  173. package/packages/piagent-core/runtime/quality/exact-output-contract.ts +2 -1
  174. package/packages/piagent-core/runtime/quality/performance-assurance-signals.ts +23 -0
  175. package/packages/piagent-core/runtime/quality/performance-assurance.ts +6 -2
  176. package/packages/piagent-core/runtime/recovery/edit-recovery-context.ts +113 -0
  177. package/packages/piagent-core/runtime/recovery/edit-recovery-delivery.ts +42 -0
  178. package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +55 -2
  179. package/packages/piagent-core/runtime/recovery/semantic-repair-runtime.ts +55 -2
  180. package/packages/piagent-core/runtime/registration/context-commands.ts +66 -5
  181. package/packages/piagent-core/runtime/registration/policy-tools.ts +46 -11
  182. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +49 -16
  183. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +163 -0
  184. package/packages/piagent-core/runtime/registration/task-start-retry-helpers.ts +37 -0
  185. package/packages/piagent-core/runtime/registration/task-start-tool.ts +67 -62
  186. package/packages/piagent-core/runtime/session/runtime-state.ts +154 -2
  187. package/packages/piagent-core/runtime/session/system-prompt.ts +4 -4
  188. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +500 -0
  189. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +2 -1
  190. package/packages/piagent-core/runtime/workflows/task-intake.ts +43 -2
  191. package/packages/piagent-core/security/sensitive-data.js +13 -218
  192. package/packages/piagent-core/security/sensitive-project-file.js +42 -0
  193. package/packages/piagent-core/security/sensitive-source-expression.js +330 -0
  194. package/packages/piagent-core/security/sensitive-source-formats.js +394 -0
  195. package/packages/piagent-core/security/sensitive-text.js +234 -0
  196. package/packages/piagent-core/subagents/piagent-worker.md +1 -1
  197. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-rD9WJKxs.js → MarkdownMessage-CxeZqTte.js} +1 -1
  198. package/packages/piagent-webui/dist/client/assets/index-DynIMe8I.js +176 -0
  199. package/packages/piagent-webui/dist/client/index.html +1 -1
  200. package/packages/piagent-webui/gateway/gateway-events.ts +109 -5
  201. package/packages/piagent-webui/gateway/gateway-service.ts +3 -0
  202. package/packages/piagent-webui/gateway/gateway-session-stream.ts +93 -7
  203. package/packages/piagent-webui/gateway/session-command-controller.ts +18 -3
  204. package/packages/piagent-webui/gateway/session-effective-options.ts +47 -0
  205. package/packages/piagent-webui/gateway/session-live-state.ts +21 -0
  206. package/packages/piagent-webui/gateway/session-operation-start.ts +5 -1
  207. package/packages/piagent-webui/gateway/session-operation-watchdog.ts +158 -0
  208. package/packages/piagent-webui/gateway/session-runtime-factory.ts +45 -0
  209. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +139 -120
  210. package/packages/piagent-webui/server/loopback-server.ts +8 -0
  211. package/packages/piagent-webui/server/transcript-projection.ts +22 -4
  212. package/packages/piagent-webui/shared/text-visibility.ts +10 -0
  213. package/schemas/piagent-webui/catalog-v1.json +9 -0
  214. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +53 -3
  215. package/schemas/piagent-webui/session-live-state-v1.schema.json +76 -0
  216. package/schemas/task-contract.schema.json +12 -1
  217. package/scripts/benchmark-runner-core.mjs +355 -359
  218. package/scripts/benchmark-runner-finalization.mjs +309 -0
  219. package/scripts/benchmark-runner-host-readiness.mjs +94 -0
  220. package/scripts/benchmark-runner-support.mjs +200 -0
  221. package/scripts/benchmark-session.mjs +95 -41
  222. package/scripts/configure-model-scope.sh +4 -3
  223. package/scripts/helper-evaluation.mjs +1 -1
  224. package/scripts/install-global.sh +2 -2
  225. package/scripts/pi-usage-history.mjs +37 -10
  226. package/scripts/piagent-dashboard.mjs +13 -1
  227. package/scripts/setup.sh +2 -2
  228. package/scripts/verify-local.sh +5 -1
  229. package/templates/global/settings.json +2 -1
  230. package/packages/piagent-webui/dist/client/assets/index-BZRFw1u6.js +0 -174
@@ -1,5 +1,7 @@
1
+ import crypto from "node:crypto";
1
2
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
3
 
4
+ import { isRuntimeOwnedContextEvidenceEntry } from "../../extensions/context-evidence.js";
3
5
  import { toolResultFingerprint } from "../../extensions/context-engine.js";
4
6
  import { workingTreeSnapshot } from "../../extensions/task-state.js";
5
7
  import type { TaskContract } from "../../extensions/guard-types.ts";
@@ -38,6 +40,39 @@ export type InjectedContextPack = {
38
40
  paths: string[];
39
41
  };
40
42
 
43
+ export type ContextInjectionItem = {
44
+ path: string;
45
+ estimatedTokens: number;
46
+ sources?: string[];
47
+ links?: Array<{ kind: string; path: string }>;
48
+ fileContentHash?: string;
49
+ sanitizedContentDigest?: string;
50
+ payloadHash?: string;
51
+ representation?: string;
52
+ ranges?: Array<{ start: number; end: number }>;
53
+ generation?: number;
54
+ sensitiveContentRedacted?: boolean;
55
+ };
56
+
57
+ export type ContextInjectionTelemetry = {
58
+ source: string;
59
+ queryHash: string;
60
+ confidence: string;
61
+ estimatedTokens: number;
62
+ selectedItems: ContextInjectionItem[];
63
+ };
64
+
65
+ export type PendingContextDelivery = {
66
+ deliveryId: string;
67
+ taskRunId: string;
68
+ turnId?: string;
69
+ entries: ObservedTaskContext[];
70
+ pack?: InjectedContextPack & { retrievalKey: string };
71
+ injection?: ContextInjectionTelemetry;
72
+ };
73
+
74
+ export type RuntimeTurn = { turnId: string; promptHash: string };
75
+
41
76
  function evictOldest<K, V>(map: Map<K, V>, maximum: number): void {
42
77
  while (map.size > maximum) map.delete(map.keys().next().value as K);
43
78
  }
@@ -48,6 +83,8 @@ export class RuntimeSessionState {
48
83
  readonly #seenToolResults = new Map<string, { outputHash: string; recordedAt: string }>();
49
84
  readonly #autoPackedPrompts = new Set<string>();
50
85
  readonly #injectedContextPacks = new Map<string, InjectedContextPack>();
86
+ readonly #pendingContextDeliveries = new Map<string, PendingContextDelivery>();
87
+ readonly #turnBySession = new Map<string, RuntimeTurn>();
51
88
  readonly #modelAuthorship = new ModelAuthorshipState();
52
89
  readonly #performanceReview = new PerformanceReviewState();
53
90
  readonly #recoveryHistoryByTask = new Map<string, RecoveryHistoryEntry[]>();
@@ -55,6 +92,8 @@ export class RuntimeSessionState {
55
92
  readonly #deliveredResumeContexts = new Set<string>();
56
93
  readonly #taskIdentityBySession = new Map<string, { taskId: string; taskRunId: string }>();
57
94
  readonly #observedContextBySession = new Map<string, Map<string, ObservedTaskContext>>();
95
+ readonly #preTaskContextBySession = new Map<string, { turnId: string; entries: Map<string, ObservedTaskContext> }>();
96
+ readonly #qualifiedContextEvidenceByTask = new Map<string, Map<string, ObservedTaskContext>>();
58
97
  readonly #shellMutationSnapshots = new Map<string, Record<string, string>>();
59
98
 
60
99
  constructor(options: { maxObservedContext: number }) {
@@ -76,6 +115,21 @@ export class RuntimeSessionState {
76
115
  return this.#taskIdentityBySession.get(this.sessionKey(ctx));
77
116
  }
78
117
 
118
+ beginTurn(ctx: ExtensionContext, promptHash: string): RuntimeTurn {
119
+ const turn = { turnId: crypto.randomUUID(), promptHash };
120
+ const sessionKey = this.sessionKey(ctx);
121
+ this.#turnBySession.set(sessionKey, turn);
122
+ this.#preTaskContextBySession.set(sessionKey, { turnId: turn.turnId, entries: new Map() });
123
+ evictOldest(this.#turnBySession, 100);
124
+ evictOldest(this.#preTaskContextBySession, 100);
125
+ return { ...turn };
126
+ }
127
+
128
+ currentTurn(ctx: ExtensionContext, promptHash?: string): RuntimeTurn | undefined {
129
+ const turn = this.#turnBySession.get(this.sessionKey(ctx));
130
+ return turn && (!promptHash || turn.promptHash === promptHash) ? { ...turn } : undefined;
131
+ }
132
+
79
133
  hasAdvisedTool(ctx: ExtensionContext, toolName: string): boolean {
80
134
  return this.#advisedTools.has(`${this.sessionKey(ctx)}\u0000${toolName}`);
81
135
  }
@@ -103,8 +157,66 @@ export class RuntimeSessionState {
103
157
  return [...(this.#observedContextBySession.get(this.sessionKey(ctx))?.values() ?? [])];
104
158
  }
105
159
 
160
+ rememberPreTaskContext(ctx: ExtensionContext, entry: ObservedTaskContext): void {
161
+ const turn = this.currentTurn(ctx);
162
+ const epoch = this.#preTaskContextBySession.get(this.sessionKey(ctx));
163
+ if (!turn || !epoch || epoch.turnId !== turn.turnId || !isRuntimeOwnedContextEvidenceEntry(entry)) return;
164
+ epoch.entries.set(entry.path, structuredClone(entry));
165
+ evictOldest(epoch.entries, this.#maxObservedContext);
166
+ }
167
+
168
+ preTaskContext(ctx: ExtensionContext): ObservedTaskContext[] {
169
+ const turn = this.currentTurn(ctx);
170
+ const epoch = this.#preTaskContextBySession.get(this.sessionKey(ctx));
171
+ if (!turn || !epoch || epoch.turnId !== turn.turnId) return [];
172
+ return [...epoch.entries.values()].map((entry) => structuredClone(entry));
173
+ }
174
+
175
+ promotePreTaskContext(ctx: ExtensionContext, taskRunId: string, selected: ObservedTaskContext[]): void {
176
+ const eligible = new Map(this.preTaskContext(ctx).map((entry) => [entry.path, entry]));
177
+ for (const entry of selected) {
178
+ const observed = eligible.get(entry.path);
179
+ if (observed) this.rememberQualifiedContextEvidence(ctx, taskRunId, observed);
180
+ }
181
+ const epoch = this.#preTaskContextBySession.get(this.sessionKey(ctx));
182
+ if (epoch) epoch.entries.clear();
183
+ }
184
+
185
+ qualifiedTaskContext(ctx: ExtensionContext): ObservedTaskContext[] {
186
+ const taskRunId = this.taskIdentity(ctx)?.taskRunId;
187
+ return taskRunId ? this.qualifiedContextEvidence(ctx, taskRunId) : [];
188
+ }
189
+
106
190
  clearObservedContext(ctx: ExtensionContext): void {
107
- this.#observedContextBySession.delete(this.sessionKey(ctx));
191
+ const sessionKey = this.sessionKey(ctx);
192
+ this.#observedContextBySession.delete(sessionKey);
193
+ this.#preTaskContextBySession.delete(sessionKey);
194
+ const prefix = `${sessionKey}\u0000`;
195
+ for (const key of this.#qualifiedContextEvidenceByTask.keys()) {
196
+ if (key.startsWith(prefix)) this.#qualifiedContextEvidenceByTask.delete(key);
197
+ }
198
+ }
199
+
200
+ rememberQualifiedContextEvidence(
201
+ ctx: ExtensionContext,
202
+ taskRunId: string,
203
+ entry: ObservedTaskContext
204
+ ): void {
205
+ if (!taskRunId || !entry.path) return;
206
+ const key = `${this.sessionKey(ctx)}\u0000${taskRunId}`;
207
+ let evidence = this.#qualifiedContextEvidenceByTask.get(key);
208
+ if (!evidence) {
209
+ evidence = new Map();
210
+ this.#qualifiedContextEvidenceByTask.set(key, evidence);
211
+ }
212
+ evidence.set(entry.path, structuredClone(entry));
213
+ evictOldest(evidence, this.#maxObservedContext);
214
+ evictOldest(this.#qualifiedContextEvidenceByTask, 100);
215
+ }
216
+
217
+ qualifiedContextEvidence(ctx: ExtensionContext, taskRunId: string): ObservedTaskContext[] {
218
+ const key = `${this.sessionKey(ctx)}\u0000${taskRunId}`;
219
+ return [...(this.#qualifiedContextEvidenceByTask.get(key)?.values() ?? [])].map((entry) => structuredClone(entry));
108
220
  }
109
221
 
110
222
  #shellMutationSnapshotKey(ctx: ExtensionContext, toolName: string, input: unknown): string {
@@ -153,6 +265,18 @@ export class RuntimeSessionState {
153
265
  return this.#injectedContextPacks.get(`${this.sessionKey(ctx)}\u0000${key}`);
154
266
  }
155
267
 
268
+ stageContextDelivery(ctx: ExtensionContext, delivery: PendingContextDelivery): void {
269
+ this.#pendingContextDeliveries.set(`${this.sessionKey(ctx)}\u0000${delivery.deliveryId}`, structuredClone(delivery));
270
+ evictOldest(this.#pendingContextDeliveries, 100);
271
+ }
272
+
273
+ takeContextDelivery(ctx: ExtensionContext, deliveryId: string): PendingContextDelivery | undefined {
274
+ const key = `${this.sessionKey(ctx)}\u0000${deliveryId}`;
275
+ const delivery = this.#pendingContextDeliveries.get(key);
276
+ this.#pendingContextDeliveries.delete(key);
277
+ return delivery ? structuredClone(delivery) : undefined;
278
+ }
279
+
156
280
  performanceReviewCheckpoint(taskRunId: string): PerformanceReviewCheckpoint | undefined {
157
281
  return this.#performanceReview.checkpoint(taskRunId);
158
282
  }
@@ -300,6 +424,7 @@ export class RuntimeSessionState {
300
424
  this.#recoveryHistoryByTask.delete(taskId);
301
425
  this.#resumeStateByTaskRun.delete(taskRunId);
302
426
  this.#deliveredResumeContexts.delete(`${this.sessionKey(ctx)}\u0000${taskRunId}`);
427
+ this.#qualifiedContextEvidenceByTask.delete(`${this.sessionKey(ctx)}\u0000${taskRunId}`);
303
428
  this.clearShellMutationSnapshots(ctx);
304
429
  }
305
430
 
@@ -319,12 +444,39 @@ export class RuntimeSessionState {
319
444
  evictOldest(this.#seenToolResults, 500);
320
445
  }
321
446
 
447
+ clearTaskBoundary(ctx: ExtensionContext, taskRunId: string): void {
448
+ const sessionKey = this.sessionKey(ctx);
449
+ const prefix = `${sessionKey}\u0000`;
450
+ const taskIdentity = this.#taskIdentityBySession.get(sessionKey);
451
+ if (taskIdentity && taskIdentity.taskRunId !== taskRunId) return;
452
+ this.#taskIdentityBySession.delete(sessionKey);
453
+ this.#observedContextBySession.delete(sessionKey);
454
+ this.#preTaskContextBySession.delete(sessionKey);
455
+ this.clearShellMutationSnapshots(ctx);
456
+ this.#performanceReview.clearTask(taskRunId);
457
+ this.#modelAuthorship.clear(taskRunId);
458
+ this.#deliveredResumeContexts.delete(`${prefix}${taskRunId}`);
459
+ this.#qualifiedContextEvidenceByTask.delete(`${prefix}${taskRunId}`);
460
+ for (const values of [this.#autoPackedPrompts, this.#deliveredResumeContexts]) {
461
+ for (const key of values) {
462
+ if (key.startsWith(prefix)) values.delete(key);
463
+ }
464
+ }
465
+ for (const values of [this.#seenToolResults, this.#injectedContextPacks, this.#pendingContextDeliveries]) {
466
+ for (const key of values.keys()) {
467
+ if (key.startsWith(prefix)) values.delete(key);
468
+ }
469
+ }
470
+ }
471
+
322
472
  clearSession(ctx: ExtensionContext): void {
323
473
  const sessionKey = this.sessionKey(ctx);
324
474
  const prefix = `${sessionKey}\u0000`;
325
475
  const taskIdentity = this.#taskIdentityBySession.get(sessionKey);
326
476
  this.#taskIdentityBySession.delete(sessionKey);
477
+ this.#turnBySession.delete(sessionKey);
327
478
  this.#observedContextBySession.delete(sessionKey);
479
+ this.#preTaskContextBySession.delete(sessionKey);
328
480
  this.clearShellMutationSnapshots(ctx);
329
481
  if (taskIdentity) {
330
482
  this.#performanceReview.clearTask(taskIdentity.taskRunId);
@@ -335,7 +487,7 @@ export class RuntimeSessionState {
335
487
  if (key.startsWith(prefix)) values.delete(key);
336
488
  }
337
489
  }
338
- for (const values of [this.#seenToolResults, this.#injectedContextPacks]) {
490
+ for (const values of [this.#seenToolResults, this.#injectedContextPacks, this.#pendingContextDeliveries, this.#qualifiedContextEvidenceByTask]) {
339
491
  for (const key of values.keys()) {
340
492
  if (key.startsWith(prefix)) values.delete(key);
341
493
  }
@@ -8,9 +8,9 @@ const RUNTIME_MANAGED_PROJECT_INSTRUCTIONS = [
8
8
  "Piagent runtime-managed task flow:",
9
9
  "1. Runtime creates the task contract automatically for a bounded source-changing request before the model starts.",
10
10
  "2. Only when runtime intake pauses for broad, high-risk, or ambiguous scope, call `piagent_task_start` exactly once with project-relative path/glob scope; reuse an active contract.",
11
- "3. Read the narrow target and nearest relevant test, then use ordinary read/edit/bash tools.",
12
- "4. Run every exact runtime-provided verifier after the latest mutation. Automatic tasks need no management calls.",
13
- "5. Runtime hooks enforce policy and record context, changes, current-tree verification, trace and final gate. Diagnostic groups appear only for explicit requests or manual high-risk checkpoints."
11
+ "3. Use complete runtime-delivered source directly; do not reread it normally. On edit drift/oldText mismatch, use attached recovery; otherwise reread the affected region once. Never retry guessed anchors. Otherwise read only missing source or a concrete criterion-linked focused test. Globs/directories grant scope, not file targets. When creating an explicitly requested new path, do not probe that destination with read first; create it, then read back or verify it. If existence matters, use a non-erroring existence check.",
12
+ "4. Preserve every runtime-provided verifier exactly and keep commands separate. Run the exact verifier set once on the final tree; rerun only after a later mutation or a runtime-authorized same-tree infrastructure retry. Automatic tasks need no management calls.",
13
+ "5. Treat the current source and durable Task Contract as authoritative. Keep one writer, bound helper delegation, preserve the user's exact scope, and report unresolved risk. Runtime hooks enforce policy and record context, changes, current-tree verification, trace and final gate. Diagnostic groups appear only for explicit requests or manual high-risk checkpoints."
14
14
  ].join("\n");
15
15
 
16
16
  export function rewriteLegacyProjectInstructions(systemPrompt: string): {
@@ -34,7 +34,7 @@ export function compactManagedProjectInstructions(
34
34
  ): { systemPrompt: string; compacted: boolean } {
35
35
  const concise = mode === "protected"
36
36
  ? "Piagent protected-path policy: do not read, disclose, or mutate protected content. Refuse without tool calls."
37
- : "Piagent runtime task is injected below. Root project instructions are already loaded; do not re-read root AGENTS.md. Use task-relevant source/tests and ordinary tools, run the exact verifier after final edits, and make no task-management calls.";
37
+ : "Piagent runtime task is injected below. Root project instructions are already loaded; do not re-read root AGENTS.md. Treat current source and the durable Task Contract as authoritative; preserve the user's exact scope, keep one writer, bound helpers, and report unresolved risk. Use complete runtime-delivered source directly without rereading it normally. On edit drift/oldText mismatch, use attached recovery; otherwise reread the affected region once. Never retry guessed anchors. Otherwise read only missing source or a concrete criterion-linked focused test. Globs/directories grant scope, not file targets. For an explicitly requested new path, create it without a speculative read, then read back or verify it. Preserve every runtime verifier exactly and keep commands separate. Run the exact verifier set once on the final tree; rerun only after a later mutation or a runtime-authorized same-tree infrastructure retry. Make no task-management calls.";
38
38
  const markerStart = "<!-- piagent-managed:start -->";
39
39
  const markerEnd = "<!-- piagent-managed:end -->";
40
40
  const start = systemPrompt.indexOf(markerStart);