@piagent/platform 1.6.0 → 1.6.1

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 (213) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +17 -14
  3. package/README.vi.md +26 -1
  4. package/benchmarks/production-v1/spend-control.v1.json +27 -3
  5. package/benchmarks/production-v1/suite.json +5 -1
  6. package/catalog/capabilities.json +16 -16
  7. package/docs/authority-manifest.md +1 -1
  8. package/docs/auto-delegation-policy.md +38 -73
  9. package/docs/command-reference-vietnamese.md +23 -31
  10. package/docs/context-engine.md +5 -3
  11. package/docs/context-window-policy.md +37 -1
  12. package/docs/distribution-standard.md +7 -7
  13. package/docs/en/architecture.md +26 -13
  14. package/docs/languages.json +4 -4
  15. package/docs/operator-manual-vietnamese.md +21 -41
  16. package/docs/publishing-for-teams.md +5 -0
  17. package/docs/quality-benchmark.md +179 -23
  18. package/docs/release-install-policy.md +6 -6
  19. package/docs/runtime-harness-standard.md +3 -3
  20. package/docs/security-threat-model.md +1 -1
  21. package/docs/subagent-orchestration-capabilities.md +19 -51
  22. package/docs/subagents-and-multiagent.md +21 -47
  23. package/docs/task-implementation-contract.md +3 -3
  24. package/docs/task-lifecycle-vietnamese.md +1 -1
  25. package/docs/team-onboarding.md +2 -2
  26. package/docs/vi/architecture.md +26 -13
  27. package/docs-site/architecture.html +1 -1
  28. package/docs-site/benchmark.html +89 -95
  29. package/docs-site/commands.html +1 -1
  30. package/docs-site/content/benchmark.html +88 -94
  31. package/docs-site/content/en/benchmark.html +134 -90
  32. package/docs-site/content/en/index.html +19 -19
  33. package/docs-site/content/en/runtime.html +4 -4
  34. package/docs-site/content/en/whats-new.html +12 -1
  35. package/docs-site/content/en/workflows.html +2 -2
  36. package/docs-site/content/index.html +19 -19
  37. package/docs-site/content/runtime.html +4 -4
  38. package/docs-site/content/whats-new.html +12 -1
  39. package/docs-site/content/workflows.html +2 -2
  40. package/docs-site/context-engine.html +1 -1
  41. package/docs-site/en/architecture.html +1 -1
  42. package/docs-site/en/benchmark.html +135 -91
  43. package/docs-site/en/commands.html +1 -1
  44. package/docs-site/en/context-engine.html +1 -1
  45. package/docs-site/en/index.html +20 -20
  46. package/docs-site/en/mcp-approval.html +1 -1
  47. package/docs-site/en/mcp-auth.html +1 -1
  48. package/docs-site/en/mcp-servers.html +1 -1
  49. package/docs-site/en/mcp.html +1 -1
  50. package/docs-site/en/permissions.html +1 -1
  51. package/docs-site/en/profiles.html +1 -1
  52. package/docs-site/en/quickstart.html +1 -1
  53. package/docs-site/en/runtime.html +5 -5
  54. package/docs-site/en/scope.html +1 -1
  55. package/docs-site/en/security.html +1 -1
  56. package/docs-site/en/team.html +1 -1
  57. package/docs-site/en/whats-new.html +13 -2
  58. package/docs-site/en/workflows.html +3 -3
  59. package/docs-site/index.html +20 -20
  60. package/docs-site/mcp-approval.html +1 -1
  61. package/docs-site/mcp-auth.html +1 -1
  62. package/docs-site/mcp-servers.html +1 -1
  63. package/docs-site/mcp.html +1 -1
  64. package/docs-site/permissions.html +1 -1
  65. package/docs-site/profiles.html +1 -1
  66. package/docs-site/quickstart.html +1 -1
  67. package/docs-site/runtime.html +5 -5
  68. package/docs-site/scope.html +1 -1
  69. package/docs-site/security.html +1 -1
  70. package/docs-site/team.html +1 -1
  71. package/docs-site/whats-new.html +13 -2
  72. package/docs-site/workflows.html +3 -3
  73. package/evals/fixtures/benchmark-assurance-evidence.invalid.json +1 -1
  74. package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
  75. package/evals/fixtures/codex-relative-efficiency-v1.invalid.json +4 -0
  76. package/evals/fixtures/codex-relative-efficiency-v1.valid.json +94 -0
  77. package/evals/fixtures/helper-request.invalid.json +1 -1
  78. package/evals/fixtures/helper-request.valid.json +1 -1
  79. package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +7 -0
  80. package/evals/fixtures/task-authority-snapshot.valid.json +4 -4
  81. package/evals/fs4-readiness-matrix.v1.json +2 -2
  82. package/evals/fs5-causal-arm.v1.json +2 -2
  83. package/evals/fs5-pilot-protocol.v1.json +3 -3
  84. package/evals/fs5-pilot-protocol.v2.json +8 -8
  85. package/evals/fs5-pilot-protocol.v3.json +8 -8
  86. package/evals/fs5-pilot-protocol.v4.json +6 -6
  87. package/evals/fs5-pilot-protocol.v5.json +7 -6
  88. package/evals/private-holdout-v1/public-exposure.v1.json +1 -1
  89. package/evals/runtime-conformance-v1/README.md +43 -0
  90. package/evals/runtime-conformance-v1/evaluate-paid-canary.mjs +198 -0
  91. package/evals/runtime-conformance-v1/lane.json +57 -0
  92. package/evals/runtime-conformance-v1/paid-canary.json +31 -0
  93. package/evals/runtime-conformance-v1/runner.mjs +456 -0
  94. package/package.json +1 -1
  95. package/packages/piagent-core/README.md +13 -4
  96. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +698 -0
  97. package/packages/piagent-core/benchmark/benchmark-core.js +4 -3
  98. package/packages/piagent-core/benchmark/benchmark-forensics.js +4 -2
  99. package/packages/piagent-core/benchmark/benchmark-preflight.js +3 -1
  100. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +345 -0
  101. package/packages/piagent-core/benchmark/benchmark-record-validation.js +74 -5
  102. package/packages/piagent-core/benchmark/benchmark-report.js +15 -1
  103. package/packages/piagent-core/benchmark/benchmark-runtime-causal.js +244 -0
  104. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +201 -4
  105. package/packages/piagent-core/benchmark/benchmark-suite.js +22 -1
  106. package/packages/piagent-core/benchmark/benchmark-summary-support.js +4 -0
  107. package/packages/piagent-core/benchmark/benchmark-usage.js +15 -4
  108. package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
  109. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +806 -0
  110. package/packages/piagent-core/extensions/acceptance-receipt.js +89 -48
  111. package/packages/piagent-core/extensions/context-engine.js +1 -11
  112. package/packages/piagent-core/extensions/context-index-policy.js +4 -0
  113. package/packages/piagent-core/extensions/context-query-paths.js +57 -0
  114. package/packages/piagent-core/extensions/criterion-context-pack.js +16 -3
  115. package/packages/piagent-core/extensions/criterion-graph.js +4 -1
  116. package/packages/piagent-core/extensions/fallback-base-policy.ts +101 -0
  117. package/packages/piagent-core/extensions/guard-types.ts +4 -0
  118. package/packages/piagent-core/extensions/piagent-guard.ts +194 -226
  119. package/packages/piagent-core/extensions/task-lifecycle.js +32 -0
  120. package/packages/piagent-core/extensions/task-state.js +69 -8
  121. package/packages/piagent-core/extensions/verification-intelligence.js +49 -12
  122. package/packages/piagent-core/extensions/workspace-evidence-roots.js +52 -16
  123. package/packages/piagent-core/package.json +1 -1
  124. package/packages/piagent-core/policies/base-policy.json +42 -2
  125. package/packages/piagent-core/policy/authority-manifest.v1.json +3 -3
  126. package/packages/piagent-core/prompts/be-to-fe.md +2 -8
  127. package/packages/piagent-core/prompts/plan.md +1 -1
  128. package/packages/piagent-core/prompts/platform-improve.md +2 -6
  129. package/packages/piagent-core/prompts/review.md +2 -7
  130. package/packages/piagent-core/prompts/scout.md +1 -1
  131. package/packages/piagent-core/prompts/task.md +4 -3
  132. package/packages/piagent-core/runtime/hooks/completion-hook.ts +7 -6
  133. package/packages/piagent-core/runtime/hooks/input-hook.ts +6 -0
  134. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +100 -1
  135. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +58 -72
  136. package/packages/piagent-core/runtime/hooks/tool-result-value-helpers.ts +66 -0
  137. package/packages/piagent-core/runtime/inspection/bounded-emission-guard.ts +286 -0
  138. package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +37 -7
  139. package/packages/piagent-core/runtime/inspection/task-subagent-tree.ts +27 -4
  140. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +20 -3
  141. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +47 -11
  142. package/packages/piagent-core/runtime/orchestration/helper-lifecycle.ts +16 -12
  143. package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +71 -0
  144. package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +28 -20
  145. package/packages/piagent-core/runtime/orchestration/role-policy.ts +27 -9
  146. package/packages/piagent-core/runtime/orchestration/subagent-tool-policy.ts +329 -0
  147. package/packages/piagent-core/runtime/policy/block-remedy.ts +0 -4
  148. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +3 -0
  149. package/packages/piagent-core/runtime/quality/edit-freshness-guard.ts +102 -0
  150. package/packages/piagent-core/runtime/quality/exact-output-contract.ts +20 -10
  151. package/packages/piagent-core/runtime/quality/performance-assurance.ts +3 -3
  152. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +1 -1
  153. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +4 -1
  154. package/packages/piagent-core/runtime/recovery/pristine-task-policy-refresh.ts +91 -0
  155. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +7 -4
  156. package/packages/piagent-core/runtime/recovery/resume-state.ts +112 -14
  157. package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +7 -13
  158. package/packages/piagent-core/runtime/recovery/task-evidence-coverage-refresh.ts +217 -0
  159. package/packages/piagent-core/runtime/registration/context-commands.ts +16 -2
  160. package/packages/piagent-core/runtime/registration/knowledge-tools.ts +9 -5
  161. package/packages/piagent-core/runtime/registration/operator-request-intake.ts +49 -0
  162. package/packages/piagent-core/runtime/registration/policy-tools.ts +4 -4
  163. package/packages/piagent-core/runtime/registration/session-commands.ts +1 -1
  164. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +12 -9
  165. package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +21 -12
  166. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +19 -13
  167. package/packages/piagent-core/runtime/registration/task-start-manifest.ts +54 -0
  168. package/packages/piagent-core/runtime/registration/task-start-tool.ts +57 -57
  169. package/packages/piagent-core/runtime/runtime-limits.ts +16 -2
  170. package/packages/piagent-core/runtime/session/adaptive-context-analysis.ts +461 -0
  171. package/packages/piagent-core/runtime/session/adaptive-context-governor.ts +464 -0
  172. package/packages/piagent-core/runtime/session/adaptive-context-ledger.ts +265 -0
  173. package/packages/piagent-core/runtime/session/message-signals.ts +7 -3
  174. package/packages/piagent-core/runtime/session/operator-request-carry.ts +44 -0
  175. package/packages/piagent-core/runtime/session/runtime-state.ts +11 -7
  176. package/packages/piagent-core/runtime/session/source-checkout-read-grants.ts +35 -0
  177. package/packages/piagent-core/runtime/session/system-prompt.ts +76 -14
  178. package/packages/piagent-core/runtime/session/task-contract-presentation.ts +39 -0
  179. package/packages/piagent-core/runtime/tools/phase-tools.ts +8 -8
  180. package/packages/piagent-core/runtime/tools/tool-groups.ts +12 -2
  181. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +101 -0
  182. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +164 -0
  183. package/packages/piagent-core/runtime/workflows/task-intake.ts +167 -39
  184. package/packages/piagent-core/subagents/piagent-oracle.md +5 -3
  185. package/packages/piagent-core/subagents/piagent-planner.md +6 -4
  186. package/packages/piagent-core/subagents/piagent-reviewer.md +5 -3
  187. package/packages/piagent-core/subagents/piagent-scout.md +4 -2
  188. package/packages/piagent-core/subagents/piagent-worker.md +6 -4
  189. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-CxeZqTte.js → MarkdownMessage-B4XehTCU.js} +1 -1
  190. package/packages/piagent-webui/dist/client/assets/{index-DynIMe8I.js → index-CgOEyRPG.js} +4 -4
  191. package/packages/piagent-webui/dist/client/index.html +1 -1
  192. package/packages/piagent-webui/extension/piagent-webui.ts +3 -1
  193. package/packages/piagent-webui/extension/same-session-bridge.ts +1 -1
  194. package/packages/piagent-webui/extension/session-stream-adapter.ts +33 -10
  195. package/packages/piagent-webui/gateway/gateway-session-stream.ts +37 -21
  196. package/packages/piagent-webui/gateway/session-operation-lifecycle.ts +237 -0
  197. package/packages/piagent-webui/gateway/session-operation-retry-control.ts +38 -0
  198. package/packages/piagent-webui/gateway/session-operation-watchdog.ts +9 -2
  199. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +8 -7
  200. package/packages/piagent-webui/ownership/session-lease-store.ts +5 -2
  201. package/packages/piagent-webui/server/core-inspection-provider.ts +2 -1
  202. package/packages/piagent-webui/server/transcript-projection.ts +91 -5
  203. package/schemas/codex-relative-efficiency-v1.schema.json +155 -0
  204. package/schemas/piagent-webui/runtime-event-v2.schema.json +15 -5
  205. package/schemas/piagent-webui/subagent-tree-v1.schema.json +11 -1
  206. package/schemas/project-profile.schema.json +1 -1
  207. package/schemas/task-contract.schema.json +15 -0
  208. package/scripts/benchmark-runner-core.mjs +14 -6
  209. package/scripts/benchmark-runner-finalization.mjs +4 -0
  210. package/scripts/configure-subagents.sh +42 -34
  211. package/scripts/helper-evaluation.mjs +1 -1
  212. package/scripts/team-doctor.sh +1 -1
  213. package/scripts/verify-local.sh +5 -0
@@ -0,0 +1,244 @@
1
+ import path from "node:path";
2
+
3
+ const MAXIMUM_AGGREGATE = 1_000_000_000;
4
+ const adaptiveContextEvents = new Set([
5
+ "context_governor_projection",
6
+ "context_governor_projection_noop",
7
+ "context_governor_compaction_cancelled",
8
+ "context_governor_deterministic_compaction",
9
+ "context_governor_deterministic_compaction_skipped"
10
+ ]);
11
+
12
+ function boundedInteger(value) {
13
+ return Number.isSafeInteger(value) && value >= 0 && value <= MAXIMUM_AGGREGATE;
14
+ }
15
+
16
+ function normalizePath(value) {
17
+ if (typeof value !== "string" || !value || value.length > 4_096) return null;
18
+ const normalized = path.posix.normalize(value.replaceAll("\\", "/").replace(/^\.\/+/, "").replace(/\/+/g, "/"));
19
+ if (!normalized || normalized === "." || path.posix.isAbsolute(normalized)
20
+ || normalized === ".." || normalized.startsWith("../")) return null;
21
+ return normalized;
22
+ }
23
+
24
+ function section(coverageStatus, observedEvents, aggregate, evidenceSource = "context-telemetry") {
25
+ return { coverageStatus, observedEvents, evidenceSource, aggregate };
26
+ }
27
+
28
+ function unavailableWebUiSection() {
29
+ return section("not-observed", 0, null, "provider-free-runtime-conformance");
30
+ }
31
+
32
+ function savingsAccounting(event) {
33
+ const accounting = event?.accounting;
34
+ if (!accounting || typeof accounting !== "object" || Array.isArray(accounting)
35
+ || !boundedInteger(accounting.estimatedSavingsTokens)
36
+ || !boundedInteger(accounting.minimumSavingsTokens)
37
+ || typeof accounting.minimumSavingsMet !== "boolean") return null;
38
+ return {
39
+ estimated: accounting.estimatedSavingsTokens,
40
+ minimum: accounting.minimumSavingsTokens,
41
+ met: accounting.minimumSavingsMet
42
+ };
43
+ }
44
+
45
+ function projectionAccounting(event) {
46
+ if (!boundedInteger(event?.estimatedSavingsTokens)
47
+ || !boundedInteger(event?.minimumSavingsTokens)
48
+ || !boundedInteger(event?.accounting?.billedTraffic?.governorProviderCalls)) return null;
49
+ return {
50
+ estimated: event.estimatedSavingsTokens,
51
+ minimum: event.minimumSavingsTokens,
52
+ met: event.estimatedSavingsTokens >= event.minimumSavingsTokens,
53
+ providerCalls: event.accounting.billedTraffic.governorProviderCalls
54
+ };
55
+ }
56
+
57
+ function protocolFailure(event) {
58
+ const protocol = event?.protocol;
59
+ if (protocol && typeof protocol === "object" && !Array.isArray(protocol)
60
+ && protocol.intact === false && Array.isArray(protocol.orphanCallIds) && Array.isArray(protocol.orphanResultIds)
61
+ && protocol.orphanCallIds.length <= MAXIMUM_AGGREGATE
62
+ && protocol.orphanResultIds.length <= MAXIMUM_AGGREGATE) {
63
+ return { calls: protocol.orphanCallIds.length, results: protocol.orphanResultIds.length };
64
+ }
65
+ const codes = Array.isArray(event?.reasonCodes) ? event.reasonCodes : [];
66
+ const count = (prefix) => {
67
+ const match = codes.find((code) => typeof code === "string" && code.startsWith(prefix));
68
+ const value = match ? Number.parseInt(match.slice(prefix.length), 10) : 0;
69
+ return boundedInteger(value) ? value : null;
70
+ };
71
+ const calls = count("orphan-calls:"), results = count("orphan-results:");
72
+ return calls === null || results === null ? null : { calls, results };
73
+ }
74
+
75
+ function adaptiveContextSection(visible) {
76
+ const events = visible.filter((event) => adaptiveContextEvents.has(event.event));
77
+ if (events.length === 0) return section("not-observed", 0, null);
78
+ const aggregate = {
79
+ projected: 0,
80
+ noOp: 0,
81
+ cancelled: 0,
82
+ deterministicCompactions: 0,
83
+ hostSummaryFallbacks: 0,
84
+ estimatedSavingsTokens: 0,
85
+ minimumSavingsTokens: 0,
86
+ minimumSavingsMet: 0,
87
+ minimumSavingsNotMet: 0,
88
+ governorProviderCalls: 0,
89
+ deterministicCompactionProviderCalls: 0,
90
+ protocolIntegrity: { checks: 0, intact: 0, failed: 0, orphanCalls: 0, orphanResults: 0 },
91
+ definition: "adaptive-context-runtime-receipt-v1"
92
+ };
93
+ let complete = true;
94
+ const add = (key, value) => {
95
+ const next = aggregate[key] + value;
96
+ if (!boundedInteger(value) || !boundedInteger(next)) complete = false;
97
+ else aggregate[key] = next;
98
+ };
99
+ const addProtocol = (intact, failure = { calls: 0, results: 0 }, checks = 1) => {
100
+ const protocol = aggregate.protocolIntegrity;
101
+ for (const [key, value] of Object.entries({
102
+ checks,
103
+ intact: intact ? checks : 0,
104
+ failed: intact ? 0 : checks,
105
+ orphanCalls: failure.calls,
106
+ orphanResults: failure.results
107
+ })) {
108
+ const next = protocol[key] + value;
109
+ if (!boundedInteger(value) || !boundedInteger(next)) complete = false;
110
+ else protocol[key] = next;
111
+ }
112
+ };
113
+ const addSavings = (accounting) => {
114
+ add("estimatedSavingsTokens", accounting.estimated);
115
+ add("minimumSavingsTokens", accounting.minimum);
116
+ add(accounting.met ? "minimumSavingsMet" : "minimumSavingsNotMet", 1);
117
+ };
118
+
119
+ for (const event of events) {
120
+ if (event.event === "context_governor_projection") {
121
+ const accounting = projectionAccounting(event);
122
+ if (!accounting || event.action !== "project" || !accounting.met) { complete = false; continue; }
123
+ aggregate.projected += 1;
124
+ addSavings(accounting);
125
+ add("governorProviderCalls", accounting.providerCalls);
126
+ addProtocol(true, undefined, 2);
127
+ continue;
128
+ }
129
+ if (event.event === "context_governor_projection_noop") {
130
+ const accounting = projectionAccounting(event);
131
+ if (!accounting || event.action !== "passthrough"
132
+ || !["no-safe-boundary", "insufficient-savings", "unsafe-tool-protocol"].includes(event.fallback)) {
133
+ complete = false; continue;
134
+ }
135
+ aggregate.noOp += 1;
136
+ addSavings(accounting);
137
+ add("governorProviderCalls", accounting.providerCalls);
138
+ if (event.fallback === "unsafe-tool-protocol") {
139
+ const failure = protocolFailure(event);
140
+ if (!failure) complete = false;
141
+ else addProtocol(false, failure);
142
+ } else addProtocol(true, undefined, event.fallback === "insufficient-savings" ? 2 : 1);
143
+ continue;
144
+ }
145
+ if (event.event === "context_governor_compaction_cancelled") {
146
+ aggregate.cancelled += 1;
147
+ if (event.fallback === "no-op-unsafe-tool-boundary") {
148
+ const failure = protocolFailure(event);
149
+ if (!failure) complete = false;
150
+ else addProtocol(false, failure);
151
+ } else if (event.fallback === "no-op-insufficient-savings") {
152
+ const accounting = savingsAccounting(event);
153
+ if (!accounting || accounting.met) complete = false;
154
+ else addSavings(accounting);
155
+ addProtocol(true);
156
+ } else complete = false;
157
+ continue;
158
+ }
159
+ if (event.event === "context_governor_deterministic_compaction") {
160
+ const accounting = savingsAccounting(event), billed = event?.accounting?.billedTraffic;
161
+ const zeroBilled = billed?.measured === true && billed?.inputTokens === 0 && billed?.outputTokens === 0
162
+ && billed?.cacheReadTokens === 0 && billed?.scope === "local-deterministic-summary-generation";
163
+ if (!accounting || (!accounting.met && event.minimumSavingsOverride !== "overflow-recovery") || !zeroBilled) {
164
+ complete = false; continue;
165
+ }
166
+ aggregate.deterministicCompactions += 1;
167
+ addSavings(accounting);
168
+ addProtocol(true);
169
+ continue;
170
+ }
171
+ if (event.event === "context_governor_deterministic_compaction_skipped") {
172
+ if (!["host-model-directed-summary", "host-model-overflow-recovery"].includes(event.fallback)) complete = false;
173
+ else aggregate.hostSummaryFallbacks += 1;
174
+ }
175
+ }
176
+ return section(complete ? "complete" : "partial", events.length, complete ? aggregate : null);
177
+ }
178
+
179
+ function freshnessPaths(event) {
180
+ if (!Array.isArray(event?.paths) || event.paths.length === 0 || event.paths.length > 10_000) return null;
181
+ const paths = event.paths.map(normalizePath);
182
+ return paths.some((item) => item === null) ? null : [...new Set(paths)];
183
+ }
184
+
185
+ function editFreshnessSection(visible) {
186
+ const observations = visible.map((event, index) => ({ event, index }))
187
+ .filter(({ event }) => ["edit_freshness_snapshot_observed", "edit_freshness_stale"].includes(event.event));
188
+ if (observations.length === 0) return section("not-observed", 0, null);
189
+ const snapshots = [], stale = [];
190
+ let complete = true;
191
+ for (const item of observations) {
192
+ const paths = freshnessPaths(item.event);
193
+ const taskRunId = typeof item.event.taskRunId === "string" && item.event.taskRunId ? item.event.taskRunId : null;
194
+ if (!paths || !taskRunId) { complete = false; continue; }
195
+ if (item.event.event === "edit_freshness_snapshot_observed") {
196
+ if (!["read", "mutation"].includes(item.event.source)) { complete = false; continue; }
197
+ snapshots.push({ ...item, paths, taskRunId, source: item.event.source });
198
+ } else {
199
+ if (typeof item.event.toolCallId !== "string" || !item.event.toolCallId
200
+ || typeof item.event.enforce !== "boolean") { complete = false; continue; }
201
+ stale.push({ ...item, paths, taskRunId, toolCallId: item.event.toolCallId, enforce: item.event.enforce });
202
+ }
203
+ }
204
+ let staleBlocks = 0, rereadRecoveries = 0, mutationRecoveries = 0;
205
+ const enforced = stale.filter((item) => item.enforce);
206
+ for (const item of enforced) {
207
+ const initialSnapshot = item.paths.every((target) => snapshots.some((snapshot) => snapshot.index < item.index
208
+ && snapshot.taskRunId === item.taskRunId && snapshot.source === "read" && snapshot.paths.includes(target)));
209
+ if (!initialSnapshot) complete = false;
210
+ const decisionIndex = visible.findIndex((event, index) => index > item.index && event.event === "tool_decision"
211
+ && event.toolCallId === item.toolCallId && event.decision === "blocked");
212
+ if (decisionIndex >= 0) staleBlocks += 1;
213
+ const reread = decisionIndex >= 0 && item.paths.every((target) => snapshots.some((snapshot) => snapshot.index > decisionIndex
214
+ && snapshot.taskRunId === item.taskRunId && snapshot.source === "read" && snapshot.paths.includes(target)));
215
+ if (reread) rereadRecoveries += 1;
216
+ const mutation = reread && item.paths.every((target) => snapshots.some((snapshot) => snapshot.index > decisionIndex
217
+ && snapshot.taskRunId === item.taskRunId && snapshot.source === "mutation" && snapshot.paths.includes(target)));
218
+ if (mutation) mutationRecoveries += 1;
219
+ }
220
+ const incompleteRecoveries = enforced.length - rereadRecoveries;
221
+ if (incompleteRecoveries > 0 || staleBlocks !== enforced.length) complete = false;
222
+ const aggregate = {
223
+ snapshotObservations: snapshots.length,
224
+ readSnapshots: snapshots.filter((item) => item.source === "read").length,
225
+ mutationSnapshots: snapshots.filter((item) => item.source === "mutation").length,
226
+ staleDetections: stale.length,
227
+ enforcedStaleDetections: enforced.length,
228
+ staleBlocks,
229
+ rereadRecoveries,
230
+ mutationRecoveries,
231
+ incompleteRecoveries,
232
+ definition: "edit-freshness-runtime-receipt-v1"
233
+ };
234
+ return section(complete ? "complete" : "partial", observations.length, complete ? aggregate : null);
235
+ }
236
+
237
+ export function causalRuntimeEvidence(visible) {
238
+ return {
239
+ adaptiveContext: adaptiveContextSection(visible),
240
+ operationLifecycle: unavailableWebUiSection(),
241
+ boundedEmission: unavailableWebUiSection(),
242
+ editFreshness: editFreshnessSection(visible)
243
+ };
244
+ }
@@ -1,4 +1,6 @@
1
1
  import { benchmarkProviderWireEvidenceMatchesRequest } from "./benchmark-provider-wire.js";
2
+ import { productionProviderFreeEvidenceContextValidationErrors } from "./benchmark-provider-free-evidence.js";
3
+ import { summarizeBenchmarkSubagentBudget } from "./benchmark-codex-relative-efficiency.js";
2
4
  import {
3
5
  benchmarkPricingSnapshotValidationErrors,
4
6
  normalizeBenchmarkUsageCost
@@ -13,6 +15,7 @@ import { atMostWithinFloatingPrecision, geometricMean } from "./benchmark-statis
13
15
  import { pairedOutcomeFloorStop } from "./benchmark-stop-policy.js";
14
16
  import { workflowContinuityEvidenceComplete } from "./benchmark-summary-support.js";
15
17
  import { summarizeBenchmarkTimingDiagnostics } from "./benchmark-timing-diagnostics.js";
18
+ import { exactBenchmarkAttemptUsage } from "./benchmark-usage.js";
16
19
 
17
20
  const TOKEN_FIELDS = Object.freeze(["input", "output", "cacheRead", "cacheWrite", "reasoning", "fresh", "total"]);
18
21
  const PRODUCTION_STAGE_CONTROL_POLICY = "production-v1-provider-spend-v1";
@@ -30,6 +33,11 @@ function validStageBoundaries(stageBoundaries) {
30
33
  && (index === 0 || value > stageBoundaries[index - 1]));
31
34
  }
32
35
 
36
+ export function productionGuardBindingMatches(manifest, spendControl) {
37
+ return JSON.stringify(manifest?.productionGuards ?? null)
38
+ === JSON.stringify(spendControl?.productionGuards ?? null);
39
+ }
40
+
33
41
  export function productionSpendControlValidationErrors(control, {
34
42
  suiteId,
35
43
  expectedSessions,
@@ -89,6 +97,27 @@ export function productionSpendControlValidationErrors(control, {
89
97
  const finalSessions = control.stages.at(-1)?.cumulativeSessions;
90
98
  if (Number.isSafeInteger(expectedSessions) && finalSessions !== expectedSessions) errors.push("final-stage-session-count-mismatch");
91
99
  }
100
+ const guards = control.productionGuards;
101
+ if (suiteId === "production-v1" && (!guards || typeof guards !== "object" || Array.isArray(guards))) errors.push("missing-production-guards");
102
+ else if (guards !== undefined) {
103
+ const subagents = guards.subagents;
104
+ if (subagents?.required !== true
105
+ || subagents.maximumSessionsPerAttempt !== 1
106
+ || subagents.maximumTrafficShare !== 0.05
107
+ || subagents.requireExactAllAttemptEvidence !== true
108
+ || subagents.requireExplainedSessionCount !== true) errors.push("invalid-production-subagent-guard");
109
+ const partial = guards.partialFreshSpend;
110
+ if (partial?.requiredFromCumulativeSessions !== 12
111
+ || partial.maximumPooledFreshRatio !== 1.1
112
+ || partial.maximumObservedFamilyFreshRatio !== 1.25
113
+ || partial.includeExactFailedAttempts !== true) errors.push("invalid-production-partial-fresh-spend-guard");
114
+ const providerFree = guards.providerFreeEvidence;
115
+ if (providerFree?.requiredBeforeFirstPaidSession !== true
116
+ || JSON.stringify(providerFree.requiredLaneIds) !== JSON.stringify(["runtime-conformance-v1", "long-horizon-v1", "webui-parity-v1"])
117
+ || providerFree.requireCleanCommitAndTreeBinding !== true
118
+ || providerFree.requireProductionConfigurationBinding !== true
119
+ || providerFree.requireRunnerAndLaneConfigurationDigests !== true) errors.push("invalid-production-provider-free-evidence-guard");
120
+ }
92
121
  return errors;
93
122
  }
94
123
 
@@ -341,6 +370,90 @@ function pairRatioEvidence(pairRecords, valueFor) {
341
370
  };
342
371
  }
343
372
 
373
+ function allAttemptFreshTokens(run) {
374
+ const failures = Array.isArray(run?.infrastructureFailures) ? run.infrastructureFailures : [];
375
+ const ledgerExact = Number.isSafeInteger(run?.infrastructureRetries)
376
+ && Number.isSafeInteger(run?.infrastructureAttempts)
377
+ && failures.length === run.infrastructureRetries
378
+ && run.infrastructureAttempts === run.infrastructureRetries + 1;
379
+ const attempts = [
380
+ { usage: run?.usage, status: run?.usageStatus ?? "measured" },
381
+ ...failures.map((failure) => ({
382
+ usage: failure?.usage,
383
+ status: failure?.usageStatus ?? "unknown-after-provider-start"
384
+ }))
385
+ ];
386
+ const exact = ledgerExact && attempts.every((attempt) => exactBenchmarkAttemptUsage(attempt.usage, attempt.status));
387
+ return {
388
+ exact,
389
+ attempts: attempts.length,
390
+ fresh: exact ? attempts.reduce((sum, attempt) => sum + Number(attempt.usage?.fresh ?? 0), 0) : null
391
+ };
392
+ }
393
+
394
+ function partialCatastrophicSpendEvidence(pairRecords, {
395
+ maximumPooledFreshRatio,
396
+ maximumObservedFamilyFreshRatio
397
+ }) {
398
+ const records = pairRecords.map(({ pair, candidate, baseline }) => {
399
+ const candidateUsage = allAttemptFreshTokens(candidate);
400
+ const baselineUsage = allAttemptFreshTokens(baseline);
401
+ const exact = candidateUsage.exact && baselineUsage.exact
402
+ && baselineUsage.fresh > 0 && candidateUsage.fresh >= 0;
403
+ return {
404
+ pairId: pair.id,
405
+ scenarioId: pair.scenarioId,
406
+ repeat: pair.repeat,
407
+ exact,
408
+ baselineFresh: exact ? baselineUsage.fresh : null,
409
+ candidateFresh: exact ? candidateUsage.fresh : null,
410
+ baselineAttempts: baselineUsage.attempts,
411
+ candidateAttempts: candidateUsage.attempts
412
+ };
413
+ });
414
+ const exact = records.length > 0 && records.every((record) => record.exact);
415
+ const baselineFresh = exact ? records.reduce((sum, record) => sum + record.baselineFresh, 0) : null;
416
+ const candidateFresh = exact ? records.reduce((sum, record) => sum + record.candidateFresh, 0) : null;
417
+ const pooledRatio = exact && baselineFresh > 0 ? candidateFresh / baselineFresh : null;
418
+ const byFamily = new Map();
419
+ for (const record of records) {
420
+ const family = byFamily.get(record.scenarioId) ?? { scenarioId: record.scenarioId, records: [] };
421
+ family.records.push(record);
422
+ byFamily.set(record.scenarioId, family);
423
+ }
424
+ const families = [...byFamily.values()].map((family) => {
425
+ const familyExact = family.records.length > 0 && family.records.every((record) => record.exact);
426
+ const baseline = familyExact ? family.records.reduce((sum, record) => sum + record.baselineFresh, 0) : null;
427
+ const candidate = familyExact ? family.records.reduce((sum, record) => sum + record.candidateFresh, 0) : null;
428
+ return {
429
+ scenarioId: family.scenarioId,
430
+ observedPairs: family.records.length,
431
+ exact: familyExact,
432
+ ratio: familyExact && baseline > 0 ? candidate / baseline : null
433
+ };
434
+ }).sort((left, right) => left.scenarioId.localeCompare(right.scenarioId));
435
+ const familyFailures = families.filter((family) => !family.exact
436
+ || !Number.isFinite(family.ratio)
437
+ || !atMostWithinFloatingPrecision(family.ratio, maximumObservedFamilyFreshRatio));
438
+ const passed = exact
439
+ && Number.isFinite(pooledRatio)
440
+ && atMostWithinFloatingPrecision(pooledRatio, maximumPooledFreshRatio)
441
+ && familyFailures.length === 0;
442
+ return {
443
+ schemaVersion: 1,
444
+ exactUsageIncludingFailedAttempts: exact,
445
+ maximumPooledFreshRatio,
446
+ maximumObservedFamilyFreshRatio,
447
+ pooledRatio,
448
+ baselineFresh,
449
+ candidateFresh,
450
+ familyFailures,
451
+ families,
452
+ records,
453
+ passed
454
+ };
455
+ }
456
+
344
457
  function candidateOutcomeFailures(pairRecords, floor) {
345
458
  return pairRecords.map(({ pair, candidate }) => {
346
459
  const failures = [];
@@ -499,6 +612,27 @@ export function buildBenchmarkStageDiagnostic({
499
612
  const causalContextAvailableRuns = causalContextSummary.currentAvailableRuns;
500
613
  const causalContextPassed = !causalContextRequired
501
614
  || causalContextSummary.currentCoverageStatus === "complete";
615
+ const providerFreeGuard = manifest?.productionGuards?.providerFreeEvidence;
616
+ const providerFreeEvidenceRequired = providerFreeGuard?.requiredBeforeFirstPaidSession === true;
617
+ const providerFreeEvidenceErrors = providerFreeEvidenceRequired
618
+ ? productionProviderFreeEvidenceContextValidationErrors(manifest?.providerFreeEvidence, {
619
+ source: manifest?.sourceIdentity,
620
+ candidateProvenance: manifest?.candidateProvenance,
621
+ configurationDigest: manifest?.configurationDigest
622
+ })
623
+ : [];
624
+ const providerFreeObservedLaneIds = Array.isArray(manifest?.providerFreeEvidence?.lanes)
625
+ ? manifest.providerFreeEvidence.lanes.map((lane) => lane?.id)
626
+ : [];
627
+ const providerFreeEvidencePassed = !providerFreeEvidenceRequired
628
+ || (providerFreeEvidenceErrors.length === 0
629
+ && Array.isArray(providerFreeGuard.requiredLaneIds)
630
+ && JSON.stringify(providerFreeObservedLaneIds) === JSON.stringify(providerFreeGuard.requiredLaneIds));
631
+ const adaptiveContextStatuses = piRuns.map((run) => run?.causalContextReceipt?.aggregates?.runtimeCausal?.adaptiveContext?.coverageStatus ?? "not-observed");
632
+ const partialAdaptiveContextRuns = adaptiveContextStatuses.filter((status) => status === "partial").length;
633
+ const notObservedAdaptiveContextRuns = adaptiveContextStatuses.filter((status) => status === "not-observed").length;
634
+ const adaptiveContextCoveragePassed = !providerFreeEvidenceRequired || (partialAdaptiveContextRuns === 0
635
+ && (notObservedAdaptiveContextRuns === 0 || providerFreeEvidencePassed));
502
636
 
503
637
  const freshEfficiency = pairRatioEvidence(pairRecords, ({ candidate, baseline }) => ({
504
638
  baseline: baseline?.usage?.fresh,
@@ -508,6 +642,27 @@ export function buildBenchmarkStageDiagnostic({
508
642
  && freshEfficiency.incomparablePairs.length === 0
509
643
  && freshEfficiency.pairRegressions.length === 0
510
644
  && freshEfficiency.familyRegressions.length === 0;
645
+ const guardPolicy = manifest?.productionGuards;
646
+ const subagentGuard = guardPolicy?.subagents;
647
+ const subagentBudget = summarizeBenchmarkSubagentBudget(acceptedRuns, {
648
+ candidateSurface,
649
+ policy: {
650
+ schemaVersion: 1,
651
+ id: "production-subagent-budget-v1",
652
+ maximumSubagentSessionsPerAttempt: subagentGuard?.maximumSessionsPerAttempt,
653
+ maximumSubagentTrafficShare: subagentGuard?.maximumTrafficShare
654
+ }
655
+ });
656
+ const subagentBudgetRequired = subagentGuard?.required === true;
657
+ const partialGuard = guardPolicy?.partialFreshSpend;
658
+ const partialSpendRequired = Number.isSafeInteger(partialGuard?.requiredFromCumulativeSessions)
659
+ && acceptedRuns.length >= partialGuard.requiredFromCumulativeSessions
660
+ && acceptedRuns.length < expectedRuns.length;
661
+ const partialSpend = partialCatastrophicSpendEvidence(pairRecords, {
662
+ maximumPooledFreshRatio: partialGuard?.maximumPooledFreshRatio,
663
+ maximumObservedFamilyFreshRatio: partialGuard?.maximumObservedFamilyFreshRatio
664
+ });
665
+ const partialSpendPassed = !partialSpendRequired || partialSpend.passed;
511
666
 
512
667
  const pricingSnapshot = suite?.pricingSnapshot;
513
668
  const pricingSnapshotErrors = benchmarkPricingSnapshotValidationErrors(pricingSnapshot);
@@ -643,8 +798,35 @@ export function buildBenchmarkStageDiagnostic({
643
798
  piagentRuns: piRuns.length,
644
799
  unavailableRuns: piRuns.length - causalContextAvailableRuns
645
800
  }),
801
+ diagnosticCheck("source-bound-provider-free-evidence", providerFreeEvidencePassed, {
802
+ required: providerFreeEvidenceRequired,
803
+ expectedLaneIds: providerFreeGuard?.requiredLaneIds ?? [],
804
+ observedLaneIds: providerFreeObservedLaneIds,
805
+ errors: providerFreeEvidenceErrors
806
+ }),
807
+ diagnosticCheck("adaptive-context-runtime-coverage", adaptiveContextCoveragePassed, {
808
+ partialRuns: partialAdaptiveContextRuns,
809
+ notObservedRuns: notObservedAdaptiveContextRuns,
810
+ notObservedCoveredBySameSourceProviderFreeLane: providerFreeEvidencePassed
811
+ }),
646
812
  diagnosticCheck("no-infrastructure-retry", retryGatePassed, { retries: infrastructureRetries }),
647
813
  diagnosticCheck("no-unknown-attempt-usage", unknownUsagePassed, { unknownUsageAttempts }),
814
+ diagnosticCheck("production-subagent-budget", !subagentBudgetRequired || subagentBudget.passed, {
815
+ required: subagentBudgetRequired,
816
+ attempts: subagentBudget.attempts,
817
+ exactAttempts: subagentBudget.exactAttempts,
818
+ maximumObservedSessionsPerAttempt: subagentBudget.maximumObservedSessionsPerAttempt,
819
+ trafficShare: subagentBudget.trafficShare,
820
+ failures: subagentBudget.failures
821
+ }),
822
+ diagnosticCheck("partial-stage-catastrophic-fresh-spend", partialSpendPassed, {
823
+ required: partialSpendRequired,
824
+ pooledRatio: partialSpend.pooledRatio,
825
+ maximumPooledFreshRatio: partialSpend.maximumPooledFreshRatio,
826
+ familyFailures: partialSpend.familyFailures,
827
+ maximumObservedFamilyFreshRatio: partialSpend.maximumObservedFamilyFreshRatio,
828
+ exactUsageIncludingFailedAttempts: partialSpend.exactUsageIncludingFailedAttempts
829
+ }),
648
830
  diagnosticCheck("no-observed-fresh-token-regression", freshEfficiencyPassed, {
649
831
  incomparablePairs: freshEfficiency.incomparablePairs.length,
650
832
  pairRegressions: freshEfficiency.pairRegressions.length,
@@ -741,6 +923,19 @@ export function buildBenchmarkStageDiagnostic({
741
923
  piagentRuns: piRuns.length,
742
924
  ...causalContextSummary
743
925
  },
926
+ providerFreeEvidence: {
927
+ required: providerFreeEvidenceRequired,
928
+ passed: providerFreeEvidencePassed,
929
+ errors: providerFreeEvidenceErrors,
930
+ expectedLaneIds: providerFreeGuard?.requiredLaneIds ?? [],
931
+ observedLaneIds: providerFreeObservedLaneIds
932
+ },
933
+ adaptiveContextRuntimeCoverage: {
934
+ passed: adaptiveContextCoveragePassed,
935
+ partialRuns: partialAdaptiveContextRuns,
936
+ notObservedRuns: notObservedAdaptiveContextRuns,
937
+ delegatedToProviderFreeEvidence: notObservedAdaptiveContextRuns > 0 && providerFreeEvidencePassed
938
+ },
744
939
  infrastructure: {
745
940
  retryGatePassed,
746
941
  retryEvidenceFailures,
@@ -756,9 +951,11 @@ export function buildBenchmarkStageDiagnostic({
756
951
  hostReadiness: hostReadinessHistory,
757
952
  timingDiagnostics: summarizeBenchmarkTimingDiagnostics(acceptedRuns),
758
953
  spendFutilityReview: {
759
- rule: "observed-pair-and-observed-family-point-ratios-must-not-exceed-1; this-is-not-the-final-40-percent-claim-gate",
760
- passed: freshEfficiencyPassed && normalizedCostPassed && durationEfficiencyPassed,
954
+ rule: "partial-stages-from-the-frozen-boundary-enforce-exact-all-attempt-pooled-and-family-fresh-spend-ceilings; this-is-not-the-final-40-percent-claim-gate",
955
+ passed: partialSpendPassed && (!subagentBudgetRequired || subagentBudget.passed),
761
956
  freshTokens: { passed: freshEfficiencyPassed, ...freshEfficiency },
957
+ partialStageCatastrophicFreshSpend: { required: partialSpendRequired, ...partialSpend },
958
+ subagentBudget,
762
959
  normalizedApiEquivalentTextTokenCost: {
763
960
  billedCost: false,
764
961
  scope: "model-text-token-input-cache-output-only",
@@ -773,8 +970,8 @@ export function buildBenchmarkStageDiagnostic({
773
970
  blockingReasons,
774
971
  stageAdvanceAllowed: blockingReasons.length === 0,
775
972
  decisionContract: {
776
- blocking: "quality-model-parity-task-continuity-and-exact-usage-only",
777
- finalOnly: ["fresh-token-reduction"],
973
+ blocking: "quality-model-parity-task-continuity-exact-usage-subagent-budget-and-partial-stage-catastrophic-fresh-spend",
974
+ finalOnly: ["0.60-upper95-fresh-token-reduction"],
778
975
  observational: ["normalized-api-equivalent-text-token-cost", "duration", "host-load"]
779
976
  },
780
977
  claimBoundary: "Provider-free partial-run diagnostic only. Intermediate token measurements cannot make a claim; cost, duration, and host load are observational and non-blocking."
@@ -19,7 +19,8 @@ const RELEASE_GATE_FIELDS = new Set([
19
19
  "maximumNormalizedCostRatioUpper95", "maximumBandNormalizedCostRatio", "maximumFamilyNormalizedCostRatio",
20
20
  "maximumInfrastructureRetries", "primaryEfficiencyEstimand", "requireEfficiencyClaim", "requireFullSuiteForClaim",
21
21
  "requireStableProviderWireSurface", "requireNormalizedCostClaim", "requireHostReadinessForClaim",
22
- "requireCausalContextReceipt"
22
+ "requireCausalContextReceipt", "requireSubagentBudget", "maximumSubagentSessionsPerAttempt",
23
+ "maximumSubagentTrafficShare", "requireProviderFreeEvidence"
23
24
  ]);
24
25
  const EXECUTION_CONTRACT_FIELDS = new Set(["surfaces", "model", "thinking", "codexMode"]);
25
26
  const THINKING_LEVELS = new Set(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
@@ -163,6 +164,26 @@ export function benchmarkSuiteValidationErrors(input) {
163
164
  if (input.releaseGate.requireCausalContextReceipt !== undefined && typeof input.releaseGate.requireCausalContextReceipt !== "boolean") {
164
165
  errors.push("releaseGate.requireCausalContextReceipt must be a boolean");
165
166
  }
167
+ if (input.releaseGate.requireSubagentBudget !== undefined && typeof input.releaseGate.requireSubagentBudget !== "boolean") {
168
+ errors.push("releaseGate.requireSubagentBudget must be a boolean");
169
+ }
170
+ if (input.releaseGate.requireProviderFreeEvidence !== undefined && typeof input.releaseGate.requireProviderFreeEvidence !== "boolean") {
171
+ errors.push("releaseGate.requireProviderFreeEvidence must be a boolean");
172
+ }
173
+ const maximumSubagentSessions = input.releaseGate.maximumSubagentSessionsPerAttempt;
174
+ if (maximumSubagentSessions !== undefined
175
+ && (!Number.isSafeInteger(maximumSubagentSessions) || maximumSubagentSessions < 0 || maximumSubagentSessions > 10)) {
176
+ errors.push("releaseGate.maximumSubagentSessionsPerAttempt must be between 0 and 10");
177
+ }
178
+ const maximumSubagentTrafficShare = input.releaseGate.maximumSubagentTrafficShare;
179
+ if (maximumSubagentTrafficShare !== undefined
180
+ && (!Number.isFinite(maximumSubagentTrafficShare) || maximumSubagentTrafficShare < 0 || maximumSubagentTrafficShare > 1)) {
181
+ errors.push("releaseGate.maximumSubagentTrafficShare must be between 0 and 1");
182
+ }
183
+ if (input.releaseGate.requireSubagentBudget === true) {
184
+ if (maximumSubagentSessions === undefined) errors.push("releaseGate.maximumSubagentSessionsPerAttempt is required when requireSubagentBudget is true");
185
+ if (maximumSubagentTrafficShare === undefined) errors.push("releaseGate.maximumSubagentTrafficShare is required when requireSubagentBudget is true");
186
+ }
166
187
  }
167
188
  }
168
189
  if (input.pricingSnapshot !== undefined) {
@@ -30,6 +30,10 @@ export const RELEASE_FAILURE_MESSAGES = Object.freeze({
30
30
  "efficiency-category-coverage": "Comparable token evidence does not cover every required category.",
31
31
  "failure-aware-efficiency": "Tokens per resolved outcome exceed the suite limit or failed-attempt usage is unknown.",
32
32
  "primary-efficiency": "The predeclared primary efficiency estimand lacks complete family/category evidence or its upper 95% ratio exceeds the suite limit.",
33
+ "codex-relative-efficiency": "The fixed-workload Piagent/Codex CLI comparison lacks exact parity or quality evidence, exceeds 0.70 total token traffic or API-equivalent cost at the point/upper-95 bound, or exceeds the subagent budget.",
34
+ "production-subagent-budget": "Production Piagent attempts lack exact child-session accounting, exceed one subagent per attempt, or spend more than 5% of candidate provider traffic on subagents.",
35
+ "provider-free-evidence": "The production run lacks same-source clean-commit runtime-conformance, long-horizon, or WebUI-parity evidence bound to exact lane configuration and runner bytes.",
36
+ "adaptive-context-runtime-coverage": "At least one Piagent runtime receipt reports partial adaptive-context evidence, or not-observed evidence lacks a same-source provider-free coverage lane.",
33
37
  "repeat-count": "The run used fewer repeats than the suite minimum.",
34
38
  "efficiency-confidence": "The upper 95% token-ratio bound exceeds the suite limit.",
35
39
  "efficiency-band-ratio": "At least one category, profile, lifecycle, or difficulty fresh-token ratio exceeds the suite limit.",
@@ -20,8 +20,8 @@ function plainObject(value) {
20
20
 
21
21
  export function exactBenchmarkMeasuredUsage(usage) {
22
22
  return usage?.usageCompleteness === "exact"
23
- && Number.isInteger(usage?.sessions) && usage.sessions > 0
24
- && TOKEN_FIELDS.every((field) => Number.isFinite(usage?.[field]) && usage[field] >= 0)
23
+ && Number.isSafeInteger(usage?.sessions) && usage.sessions > 0
24
+ && TOKEN_FIELDS.every((field) => Number.isSafeInteger(usage?.[field]) && usage[field] >= 0)
25
25
  && usage.fresh === usage.input + usage.output
26
26
  && usage.total === usage.input + usage.cacheRead + usage.cacheWrite + usage.output
27
27
  && usage.reasoning <= usage.output;
@@ -29,8 +29,10 @@ export function exactBenchmarkMeasuredUsage(usage) {
29
29
 
30
30
  function knownPreProviderZero(usage, status) {
31
31
  return status === "known-pre-provider-zero"
32
- && Number(usage?.sessions ?? 0) === 0
33
- && TOKEN_FIELDS.every((field) => Number(usage?.[field] ?? 0) === 0);
32
+ && Number.isSafeInteger(usage?.sessions ?? 0)
33
+ && (usage?.sessions ?? 0) === 0
34
+ && TOKEN_FIELDS.every((field) => Number.isSafeInteger(usage?.[field] ?? 0)
35
+ && (usage?.[field] ?? 0) === 0);
34
36
  }
35
37
 
36
38
  export function exactBenchmarkAttemptUsage(usage, status) {
@@ -107,6 +109,7 @@ export function benchmarkInfrastructureFailureLedgerIssues(runs) {
107
109
 
108
110
  export function aggregateSessionUsage(sessions) {
109
111
  const totals = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, total: 0, cost: 0 };
112
+ const subagentTokens = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, total: 0 };
110
113
  const models = new Set();
111
114
  const thinkingLevels = new Set();
112
115
  const toolNames = {};
@@ -115,6 +118,9 @@ export function aggregateSessionUsage(sessions) {
115
118
  const contextSnapshots = [];
116
119
  for (const session of sessions) {
117
120
  for (const key of Object.keys(totals)) totals[key] += Number(session.tokens?.[key] ?? 0);
121
+ if (session.isSubagent) {
122
+ for (const key of Object.keys(subagentTokens)) subagentTokens[key] += Number(session.tokens?.[key] ?? 0);
123
+ }
118
124
  if (session.modelId || session.provider) models.add(`${session.provider || "unknown"}/${session.modelId || "unknown"}`);
119
125
  if (session.thinkingLevel) thinkingLevels.add(session.thinkingLevel);
120
126
  toolCalls += Number(session.messages?.toolCalls ?? 0);
@@ -136,6 +142,10 @@ export function aggregateSessionUsage(sessions) {
136
142
  fresh: totals.input + totals.output,
137
143
  sessions: sessions.length,
138
144
  subagentSessions: sessions.filter((session) => session.isSubagent).length,
145
+ subagentTokens: {
146
+ ...subagentTokens,
147
+ fresh: subagentTokens.input + subagentTokens.output
148
+ },
139
149
  toolCalls,
140
150
  toolNames: Object.fromEntries(Object.entries(toolNames).sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0]))),
141
151
  messages,
@@ -231,6 +241,7 @@ function finishCodexUsage(state) {
231
241
  usageCompleteness: "exact",
232
242
  sessions: 1,
233
243
  subagentSessions: 0,
244
+ subagentTokens: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, fresh: 0, total: 0 },
234
245
  toolCalls: Object.values(sortedTools).reduce((sum, value) => sum + value, 0),
235
246
  toolNames: sortedTools,
236
247
  messages: state.messages,
@@ -4,6 +4,7 @@ import path from "node:path";
4
4
  export const CORE_RUNTIME_INTEGRITY_FILES = Object.freeze([
5
5
  "packages/piagent-core/runtime/context/adaptive-planner.ts",
6
6
  "packages/piagent-core/runtime/context/retrieval-route-policy.ts",
7
+ "packages/piagent-core/extensions/acceptance-behavior-proof.js",
7
8
  "packages/piagent-core/extensions/acceptance-contract-semantics.js",
8
9
  "packages/piagent-core/extensions/acceptance-executable-evidence.js",
9
10
  "packages/piagent-core/extensions/acceptance-language-adapters.js",
@@ -133,6 +134,7 @@ export const CORE_RUNTIME_INTEGRITY_FILES = Object.freeze([
133
134
  "packages/piagent-core/runtime/runtime-limits.ts",
134
135
  "packages/piagent-core/runtime/session/message-signals.ts",
135
136
  "packages/piagent-core/runtime/session/model-authorship-state.ts",
137
+ "packages/piagent-core/runtime/session/operator-request-carry.ts",
136
138
  "packages/piagent-core/runtime/session/performance-review-state.ts",
137
139
  "packages/piagent-core/runtime/session/runtime-state.ts",
138
140
  "packages/piagent-core/runtime/session/system-prompt.ts",
@@ -154,6 +156,7 @@ export const CORE_RUNTIME_INTEGRITY_FILES = Object.freeze([
154
156
  "packages/piagent-core/runtime/tools/phase-tools.ts",
155
157
  "packages/piagent-core/runtime/tools/phase-tool-runtime.ts",
156
158
  "packages/piagent-core/runtime/workflows/input-routing.ts",
159
+ "packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts",
157
160
  "packages/piagent-core/runtime/workflows/task-intake.ts",
158
161
  "scripts/piagent-cli.mjs",
159
162
  "scripts/register-typescript-loader.mjs",