@bitkyc08/opencodex 2.12.0 → 2.13.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 (173) hide show
  1. package/README.md +1 -1
  2. package/gui/dist/assets/index-BHldBl6_.js +76 -0
  3. package/gui/dist/index.html +1 -1
  4. package/package.json +1 -1
  5. package/src/adapters/anthropic-output-schema.ts +137 -0
  6. package/src/adapters/anthropic.ts +15 -0
  7. package/src/adapters/google-antigravity-replay.ts +269 -5
  8. package/src/adapters/openai-chat.ts +25 -18
  9. package/src/adapters/openai-responses.ts +63 -17
  10. package/src/bridge.ts +11 -5
  11. package/src/claude/inbound.ts +24 -3
  12. package/src/cli/account-api.ts +2 -0
  13. package/src/cli/account-extended.ts +262 -1
  14. package/src/cli/account.ts +3 -1
  15. package/src/cli/dispatch.ts +532 -0
  16. package/src/cli/doctor.ts +26 -21
  17. package/src/cli/help.ts +9 -278
  18. package/src/cli/index.ts +45 -506
  19. package/src/cli/lab.ts +171 -65
  20. package/src/cli/registry.ts +384 -0
  21. package/src/cli/root.ts +86 -0
  22. package/src/cli/status.ts +9 -2
  23. package/src/cli/v2.ts +37 -2
  24. package/src/codex/account-label.ts +14 -1
  25. package/src/codex/account-store.ts +12 -1
  26. package/src/codex/admission.ts +2 -1
  27. package/src/codex/auth-api.ts +3 -2
  28. package/src/codex/catalog/metadata.ts +6 -4
  29. package/src/codex/catalog/parsing.ts +31 -7
  30. package/src/codex/catalog/provider-fetch.ts +2 -1
  31. package/src/codex/catalog/sync.ts +65 -11
  32. package/src/codex/features.ts +437 -31
  33. package/src/codex/history-job.ts +6 -11
  34. package/src/codex/history-provider.ts +10 -9
  35. package/src/codex/inject.ts +14 -1
  36. package/src/codex/native-profile-startup.ts +49 -3
  37. package/src/codex/native-residue.ts +14 -2
  38. package/src/codex/paths.ts +75 -1
  39. package/src/codex/reset-credit-recovery.ts +1044 -0
  40. package/src/codex/shim.ts +876 -16
  41. package/src/codex/sync.ts +27 -2
  42. package/src/config.ts +148 -10
  43. package/src/generated/compatibility-version.json +2572 -0
  44. package/src/images/loop.ts +1 -1
  45. package/src/lab/artifacts/sanitize.ts +3 -3
  46. package/src/lab/automation/budgets.ts +78 -0
  47. package/src/lab/automation/config-persistence.ts +256 -0
  48. package/src/lab/automation/constants.ts +39 -0
  49. package/src/lab/automation/cooldown.ts +103 -0
  50. package/src/lab/automation/dispatch.ts +211 -0
  51. package/src/lab/automation/index.ts +13 -0
  52. package/src/lab/automation/orchestrator.ts +480 -0
  53. package/src/lab/automation/persistence.ts +512 -0
  54. package/src/lab/automation/planner.ts +371 -0
  55. package/src/lab/automation/policy.ts +136 -0
  56. package/src/lab/automation/queue.ts +191 -0
  57. package/src/lab/automation/recovery.ts +24 -0
  58. package/src/lab/automation/route-context.ts +21 -0
  59. package/src/lab/automation/run-key.ts +44 -0
  60. package/src/lab/automation/runs-query.ts +34 -0
  61. package/src/lab/automation/types.ts +160 -0
  62. package/src/lab/conformance/types.ts +23 -0
  63. package/src/lab/events/types.ts +2 -1
  64. package/src/lab/events/validate.ts +2 -1
  65. package/src/lab/fabric/constants.ts +40 -0
  66. package/src/lab/fabric/executor.ts +492 -0
  67. package/src/lab/fabric/index.ts +80 -0
  68. package/src/lab/fabric/manifest.ts +222 -0
  69. package/src/lab/fabric/observe.ts +454 -0
  70. package/src/lab/fabric/patch.ts +79 -0
  71. package/src/lab/fabric/producer-child.ts +139 -0
  72. package/src/lab/fabric/producer-isolate.ts +276 -0
  73. package/src/lab/fabric/producer-protocol.ts +61 -0
  74. package/src/lab/fabric/scratch.ts +439 -0
  75. package/src/lab/fabric/subject.ts +106 -0
  76. package/src/lab/fabric/types.ts +134 -0
  77. package/src/lab/fabric/verifier.ts +98 -0
  78. package/src/lab/index.ts +2 -0
  79. package/src/lab/ledger/store.ts +173 -0
  80. package/src/lab/live/executor.ts +29 -4
  81. package/src/lab/live/transport.ts +3 -1
  82. package/src/lab/observe/from-conformance.ts +12 -57
  83. package/src/lab/observe/from-live.ts +9 -1
  84. package/src/lab/paths.ts +74 -9
  85. package/src/lab/projection/schema.ts +14 -1
  86. package/src/lab/projection/verdicts.ts +89 -53
  87. package/src/lab/projection/verification.ts +83 -3
  88. package/src/lab/query/catalog.ts +34 -5
  89. package/src/lab/query/freshness.ts +53 -0
  90. package/src/lab/query/index.ts +11 -0
  91. package/src/lab/query/latest-observation.ts +59 -0
  92. package/src/lab/query/passive-production.ts +159 -0
  93. package/src/lab/subject/installation-salt.ts +24 -4
  94. package/src/lab/subject/protocol-subject.ts +80 -0
  95. package/src/lab/subject/route-subject.ts +2 -1
  96. package/src/lib/fabric-task-execution-authority.ts +7 -0
  97. package/src/lib/fabric-task-host.ts +29 -0
  98. package/src/lib/lab-live-route-production.ts +130 -0
  99. package/src/lib/local-management-capability.ts +100 -0
  100. package/src/lib/server-resource-ownership.ts +71 -0
  101. package/src/lib/windows-elevation.ts +8 -1
  102. package/src/lib/windows-user-principal.ts +62 -2
  103. package/src/lib/winsw.ts +8 -2
  104. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  105. package/src/oauth/account-import/index.ts +15 -0
  106. package/src/oauth/account-import/parser.ts +83 -0
  107. package/src/oauth/account-import/registry.ts +18 -0
  108. package/src/oauth/account-import/service.ts +75 -0
  109. package/src/oauth/account-import/types.ts +91 -0
  110. package/src/oauth/anthropic.ts +12 -1
  111. package/src/oauth/callback-server.ts +8 -2
  112. package/src/oauth/chatgpt.ts +12 -1
  113. package/src/oauth/google-antigravity.ts +27 -0
  114. package/src/oauth/health.ts +12 -48
  115. package/src/oauth/index.ts +122 -0
  116. package/src/oauth/kimi.ts +16 -2
  117. package/src/oauth/nous.ts +749 -0
  118. package/src/oauth/store.ts +56 -3
  119. package/src/providers/codex-capacity.ts +1 -0
  120. package/src/providers/registry.ts +161 -16
  121. package/src/responses/custom-tool-compat.ts +182 -0
  122. package/src/responses/parser.ts +22 -0
  123. package/src/responses/reasoning-replay-cache.ts +168 -11
  124. package/src/responses/schema.ts +1 -1
  125. package/src/router.ts +5 -20
  126. package/src/routing/capability.ts +9 -3
  127. package/src/routing/compatibility/assemble.ts +159 -0
  128. package/src/routing/compatibility/behavior.ts +224 -0
  129. package/src/routing/compatibility/catalog.ts +99 -0
  130. package/src/routing/compatibility/endpoint.ts +52 -0
  131. package/src/routing/compatibility/policy.ts +181 -0
  132. package/src/routing/compatibility/reader.ts +110 -0
  133. package/src/routing/compatibility/subject.ts +191 -0
  134. package/src/routing/compatibility/types.ts +64 -0
  135. package/src/routing/compatibility/version.ts +104 -0
  136. package/src/routing/evaluator.ts +27 -32
  137. package/src/routing/profile.ts +118 -4
  138. package/src/routing/trace.ts +82 -28
  139. package/src/server/auth-cors.ts +7 -0
  140. package/src/server/background-lifecycle.ts +20 -7
  141. package/src/server/chat-completions.ts +2 -2
  142. package/src/server/claude-messages.ts +6 -3
  143. package/src/server/direct-local-http.ts +343 -0
  144. package/src/server/index.ts +80 -18
  145. package/src/server/lifecycle.ts +12 -4
  146. package/src/server/local-management-read-client.ts +90 -0
  147. package/src/server/management/agent-settings-routes.ts +27 -3
  148. package/src/server/management/lab-automation-routes.ts +206 -0
  149. package/src/server/management/lab-routes.ts +13 -0
  150. package/src/server/management/logs-usage-routes.ts +1 -0
  151. package/src/server/management/oauth-account-routes.ts +57 -1
  152. package/src/server/management/provider-routes.ts +16 -0
  153. package/src/server/management/routing-profile-routes.ts +12 -24
  154. package/src/server/management-api.ts +2 -0
  155. package/src/server/management-auth.ts +68 -3
  156. package/src/server/proxy-liveness.ts +3 -2
  157. package/src/server/request-decompress.ts +9 -3
  158. package/src/server/request-log.ts +53 -4
  159. package/src/server/responses/collaboration.ts +93 -17
  160. package/src/server/responses/compact.ts +3 -0
  161. package/src/server/responses/core.ts +202 -15
  162. package/src/server/responses/policy-fallback.ts +1 -0
  163. package/src/server/responses-custom-tool-repair.ts +280 -0
  164. package/src/server/responses-terminal-repair.ts +342 -0
  165. package/src/server/startup-action-control.ts +8 -1
  166. package/src/service.ts +278 -12
  167. package/src/types.ts +49 -3
  168. package/src/usage/expected-prices.ts +30 -0
  169. package/src/usage/log.ts +30 -4
  170. package/src/usage/summary.ts +153 -2
  171. package/src/web-search/loop.ts +1 -1
  172. package/gui/dist/assets/index-Cw1_mxO8.js +0 -70
  173. package/src/cli/internal-dispatch.ts +0 -20
@@ -0,0 +1,492 @@
1
+ import type { FailureRecordV1, RouteSubjectV1 } from "../events/types";
2
+ import { labSandboxEnvironment, rejectProxyEnvironment } from "../live/sandbox";
3
+ import type { LabDestinationV1, LabRouteContext } from "../live/types";
4
+ import { buildRouteSubjectV1 } from "../subject/route-subject";
5
+ import { isTrustedFabricPatchExecutor } from "../../lib/fabric-task-execution-authority";
6
+ import {
7
+ FABRIC_COMPATIBILITY_VERSION,
8
+ FABRIC_LIMITS,
9
+ FABRIC_TASK_CLASS_ID,
10
+ FABRIC_TASK_CLASS_VERSION,
11
+ FABRIC_VERIFIER_ID,
12
+ SANDBOX_PROFILE_V1,
13
+ SYNTHETIC_AFTER_UTF8,
14
+ SYNTHETIC_BEFORE_UTF8,
15
+ SYNTHETIC_VALUE_PATH,
16
+ } from "./constants";
17
+ import { applySyntheticPatch, parseSyntheticPatchV1 } from "./patch";
18
+ import { fabricProducerIsolationLimits, runIsolatedFabricProducer } from "./producer-isolate";
19
+ import { assertNotUnderUserRepo, createSyntheticScratch, type ScratchTree } from "./scratch";
20
+ import {
21
+ buildTaskSubjectV1,
22
+ sandboxProfileDigest,
23
+ taskFixtureDigest,
24
+ taskSubjectId,
25
+ verifierManifestDigest,
26
+ } from "./subject";
27
+ import type {
28
+ FabricExecutionAuthority,
29
+ FabricHarnessProducerKind,
30
+ FabricTaskOutcomeV1,
31
+ FabricTaskRunResult,
32
+ FabricUsageV1,
33
+ SyntheticPatchV1,
34
+ TrustedFabricPatchExecutor,
35
+ } from "./types";
36
+ import { FabricTaskError } from "./types";
37
+ import { verifyExactTreeDiffV1 } from "./verifier";
38
+
39
+ /** Options for harness-only fabric task runs (not persistable as production evidence). */
40
+ export interface RunFabricTaskHarnessOptions {
41
+ routeSubject: RouteSubjectV1;
42
+ harnessKind: FabricHarnessProducerKind;
43
+ configDir?: string;
44
+ userRepoRoot?: string;
45
+ sourceRefs?: string[];
46
+ now?: () => number;
47
+ }
48
+
49
+ /** Options for authoritative route-bound fabric task execution. */
50
+ export interface RunFabricTaskForRouteOptions {
51
+ routeContext: LabRouteContext;
52
+ destination: LabDestinationV1;
53
+ patchExecutor: TrustedFabricPatchExecutor;
54
+ configDir?: string;
55
+ userRepoRoot?: string;
56
+ sourceRefs?: string[];
57
+ now?: () => number;
58
+ }
59
+
60
+ /** Map a FabricTaskError into a ledger failure record. */
61
+ function failureFromError(error: FabricTaskError): FailureRecordV1 {
62
+ return {
63
+ class: error.code,
64
+ code: error.code,
65
+ retryable: error.code === "timeout" || error.code === "inactivity_timeout" || error.code === "budget_exhausted",
66
+ attribution: error.attribution,
67
+ };
68
+ }
69
+
70
+ /** Map a failure record to the observation outcome kind for persistence. */
71
+ function outcomeFromFailure(failure: FailureRecordV1): FabricTaskOutcomeV1["outcome"] {
72
+ if (failure.class === "behavioral_failure") return "fail";
73
+ if (failure.attribution === "harness") return "inconclusive";
74
+ return "blocked";
75
+ }
76
+
77
+ /** Closed successful patch for deterministic harness injection. */
78
+ export function correctSyntheticPatch(): SyntheticPatchV1 {
79
+ return {
80
+ schemaVersion: 1,
81
+ operations: [{ op: "replace", path: SYNTHETIC_VALUE_PATH, contentUtf8: SYNTHETIC_AFTER_UTF8 }],
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Authoritative CL-07 route-bound fabric task execution.
87
+ * Route identity is derived from routeContext + destination; patch production runs in an isolated child.
88
+ */
89
+ export async function runFabricSyntheticPatchTaskForRoute(
90
+ options: RunFabricTaskForRouteOptions,
91
+ ): Promise<FabricTaskRunResult> {
92
+ if (!isTrustedFabricPatchExecutor(options.patchExecutor)) {
93
+ throw new FabricTaskError("untrusted fabric patch executor", "sandbox_violation", "harness");
94
+ }
95
+ const routeSubject = buildRouteSubjectV1(options.routeContext, options.destination, options.configDir);
96
+ return runFabricSyntheticPatchTaskInternal({
97
+ routeSubject,
98
+ routeContext: options.routeContext,
99
+ destination: options.destination,
100
+ patchExecutor: options.patchExecutor,
101
+ harnessKind: undefined,
102
+ executionAuthority: "trusted_route",
103
+ configDir: options.configDir,
104
+ userRepoRoot: options.userRepoRoot,
105
+ sourceRefs: options.sourceRefs,
106
+ now: options.now,
107
+ });
108
+ }
109
+
110
+ /** Harness-only fabric task execution; outcomes are not persistable as production evidence. */
111
+ export async function runFabricSyntheticPatchTaskHarness(
112
+ options: RunFabricTaskHarnessOptions,
113
+ ): Promise<FabricTaskRunResult> {
114
+ return runFabricSyntheticPatchTaskInternal({
115
+ routeSubject: options.routeSubject,
116
+ harnessKind: options.harnessKind,
117
+ executionAuthority: "harness",
118
+ configDir: options.configDir,
119
+ userRepoRoot: options.userRepoRoot,
120
+ sourceRefs: options.sourceRefs,
121
+ now: options.now,
122
+ });
123
+ }
124
+
125
+ /**
126
+ * @deprecated Use runFabricSyntheticPatchTaskHarness or runFabricSyntheticPatchTaskForRoute.
127
+ */
128
+ export async function runFabricSyntheticPatchTask(
129
+ options: Omit<RunFabricTaskHarnessOptions, "harnessKind"> & {
130
+ producePatch?: never;
131
+ harnessKind?: RunFabricTaskHarnessOptions["harnessKind"];
132
+ },
133
+ ): Promise<FabricTaskOutcomeV1> {
134
+ const result = await runFabricSyntheticPatchTaskHarness({
135
+ routeSubject: options.routeSubject,
136
+ harnessKind: options.harnessKind ?? "deterministic_correct",
137
+ configDir: options.configDir,
138
+ userRepoRoot: options.userRepoRoot,
139
+ sourceRefs: options.sourceRefs,
140
+ now: options.now,
141
+ });
142
+ return result.outcome;
143
+ }
144
+
145
+ async function runFabricSyntheticPatchTaskInternal(input: {
146
+ routeSubject: RouteSubjectV1;
147
+ routeContext?: LabRouteContext;
148
+ destination?: LabDestinationV1;
149
+ patchExecutor?: TrustedFabricPatchExecutor;
150
+ harnessKind?: FabricHarnessProducerKind;
151
+ executionAuthority: FabricExecutionAuthority;
152
+ configDir?: string;
153
+ userRepoRoot?: string;
154
+ sourceRefs?: string[];
155
+ now?: () => number;
156
+ }): Promise<FabricTaskRunResult> {
157
+ rejectProxyEnvironment();
158
+ labSandboxEnvironment();
159
+
160
+ const startedAt = input.now?.() ?? Date.now();
161
+ const fixtureDigest = taskFixtureDigest();
162
+ const verifierDigest = verifierManifestDigest();
163
+ const sandboxDigest = sandboxProfileDigest();
164
+ const taskSubject = buildTaskSubjectV1({
165
+ routeSubject: input.routeSubject,
166
+ taskFixtureDigest: fixtureDigest,
167
+ verifierManifestDigest: verifierDigest,
168
+ sandboxProfileDigest: sandboxDigest,
169
+ fabricCompatibilityVersion: FABRIC_COMPATIBILITY_VERSION,
170
+ });
171
+ const subjectId = taskSubjectId(taskSubject);
172
+
173
+ const usage: FabricUsageV1 = {
174
+ inputBytes: Buffer.byteLength(SYNTHETIC_BEFORE_UTF8, "utf8"),
175
+ outputBytes: 0,
176
+ patchOperations: 0,
177
+ filesTouched: 0,
178
+ artifactBytes: 0,
179
+ elapsedMs: 0,
180
+ inactiveMs: 0,
181
+ };
182
+
183
+ let scratch: ScratchTree | undefined;
184
+ let producerCompletedAt = startedAt;
185
+ let lastActivityAt = startedAt;
186
+
187
+ try {
188
+ scratch = createSyntheticScratch(input.configDir);
189
+ if (input.userRepoRoot) {
190
+ assertNotUnderUserRepo(scratch.root, input.userRepoRoot);
191
+ }
192
+
193
+ const isolation = fabricProducerIsolationLimits();
194
+ const inactivityTimeoutMs =
195
+ input.harnessKind === "infinite_sync"
196
+ ? isolation.totalTimeoutMs + 1_000
197
+ : isolation.inactivityTimeoutMs;
198
+ let patchRaw: unknown;
199
+ try {
200
+ if (input.harnessKind) {
201
+ lastActivityAt = input.now?.() ?? Date.now();
202
+ const isolated = await runIsolatedFabricProducer({
203
+ harnessKind: input.harnessKind,
204
+ scratchRoot: scratch.root,
205
+ totalTimeoutMs: isolation.totalTimeoutMs,
206
+ inactivityTimeoutMs,
207
+ now: input.now,
208
+ });
209
+ patchRaw = isolated.patch;
210
+ lastActivityAt = isolated.lastActivityAt;
211
+ producerCompletedAt = input.now?.() ?? Date.now();
212
+ } else if (input.patchExecutor && input.routeContext && input.destination) {
213
+ lastActivityAt = input.now?.() ?? Date.now();
214
+ const isolated = await runIsolatedFabricProducer({
215
+ executorModulePath: input.patchExecutor.executorModulePath,
216
+ scratchRoot: scratch.root,
217
+ totalTimeoutMs: isolation.totalTimeoutMs,
218
+ inactivityTimeoutMs: isolation.inactivityTimeoutMs,
219
+ executorInput: {
220
+ routeContext: input.routeContext,
221
+ destination: input.destination,
222
+ routeSubject: input.routeSubject,
223
+ scratchRoot: scratch.root,
224
+ reportActivity: () => undefined,
225
+ signal: new AbortController().signal,
226
+ },
227
+ now: input.now,
228
+ });
229
+ patchRaw = isolated.patch;
230
+ lastActivityAt = isolated.lastActivityAt;
231
+ producerCompletedAt = input.now?.() ?? Date.now();
232
+ } else {
233
+ throw new FabricTaskError("fabric task run missing producer", "harness_failure", "harness");
234
+ }
235
+ } catch (error) {
236
+ const completedAt = input.now?.() ?? Date.now();
237
+ usage.elapsedMs = completedAt - startedAt;
238
+ usage.inactiveMs = Math.max(0, completedAt - lastActivityAt);
239
+ if (error instanceof FabricTaskError) {
240
+ const failure = failureFromError(error);
241
+ return {
242
+ executionAuthority: input.executionAuthority,
243
+ outcome: sealOutcome({
244
+ taskSubject,
245
+ subjectId,
246
+ fixtureDigest,
247
+ verifierDigest,
248
+ sandboxDigest,
249
+ startedAt,
250
+ completedAt,
251
+ usage,
252
+ outcome: outcomeFromFailure(failure),
253
+ verifier: infrastructureVerifier(verifierDigest, error.code),
254
+ failure,
255
+ sourceRefs: input.sourceRefs,
256
+ }),
257
+ };
258
+ }
259
+ throw error;
260
+ }
261
+
262
+ let patch;
263
+ let applied;
264
+ try {
265
+ patch = parseSyntheticPatchV1(patchRaw);
266
+ applied = applySyntheticPatch(scratch.root, patch);
267
+ } catch (error) {
268
+ const completedAt = input.now?.() ?? Date.now();
269
+ usage.elapsedMs = completedAt - startedAt;
270
+ usage.inactiveMs = Math.max(0, completedAt - lastActivityAt);
271
+ if (error instanceof FabricTaskError) {
272
+ const failure = failureFromError(error);
273
+ return {
274
+ executionAuthority: input.executionAuthority,
275
+ outcome: sealOutcome({
276
+ taskSubject,
277
+ subjectId,
278
+ fixtureDigest,
279
+ verifierDigest,
280
+ sandboxDigest,
281
+ startedAt,
282
+ completedAt,
283
+ usage,
284
+ outcome: outcomeFromFailure(failure),
285
+ verifier: infrastructureVerifier(verifierDigest, error.code),
286
+ failure,
287
+ sourceRefs: input.sourceRefs,
288
+ }),
289
+ };
290
+ }
291
+ throw error;
292
+ }
293
+ usage.outputBytes = applied.bytesWritten;
294
+ usage.patchOperations = applied.patchOperations;
295
+ usage.filesTouched = applied.filesTouched;
296
+
297
+ let verifier;
298
+ try {
299
+ verifier = verifyExactTreeDiffV1(scratch.root);
300
+ } catch (error) {
301
+ const completedAt = input.now?.() ?? Date.now();
302
+ usage.elapsedMs = completedAt - startedAt;
303
+ usage.inactiveMs = Math.max(0, completedAt - lastActivityAt);
304
+ if (error instanceof FabricTaskError) {
305
+ const failure = failureFromError(error);
306
+ return {
307
+ executionAuthority: input.executionAuthority,
308
+ outcome: sealOutcome({
309
+ taskSubject,
310
+ subjectId,
311
+ fixtureDigest,
312
+ verifierDigest,
313
+ sandboxDigest,
314
+ startedAt,
315
+ completedAt,
316
+ usage,
317
+ outcome: outcomeFromFailure(failure),
318
+ verifier: infrastructureVerifier(verifierDigest, error.code),
319
+ failure,
320
+ sourceRefs: input.sourceRefs,
321
+ }),
322
+ };
323
+ }
324
+ throw error;
325
+ }
326
+
327
+ const completedAt = input.now?.() ?? Date.now();
328
+ usage.elapsedMs = completedAt - startedAt;
329
+ usage.inactiveMs = Math.max(0, completedAt - lastActivityAt);
330
+
331
+ if (verifier.passed) {
332
+ return {
333
+ executionAuthority: input.executionAuthority,
334
+ outcome: sealOutcome({
335
+ taskSubject,
336
+ subjectId,
337
+ fixtureDigest,
338
+ verifierDigest,
339
+ sandboxDigest,
340
+ startedAt,
341
+ completedAt,
342
+ usage,
343
+ outcome: "pass",
344
+ verifier,
345
+ sourceRefs: input.sourceRefs,
346
+ }),
347
+ };
348
+ }
349
+
350
+ const failure: FailureRecordV1 = {
351
+ class: "behavioral_failure",
352
+ code: verifier.reason ?? "verifier_failed",
353
+ retryable: false,
354
+ attribution: "route",
355
+ };
356
+ return {
357
+ executionAuthority: input.executionAuthority,
358
+ outcome: sealOutcome({
359
+ taskSubject,
360
+ subjectId,
361
+ fixtureDigest,
362
+ verifierDigest,
363
+ sandboxDigest,
364
+ startedAt,
365
+ completedAt,
366
+ usage,
367
+ outcome: "fail",
368
+ verifier,
369
+ failure,
370
+ sourceRefs: input.sourceRefs,
371
+ }),
372
+ };
373
+ } catch (error) {
374
+ const completedAt = input.now?.() ?? Date.now();
375
+ usage.elapsedMs = completedAt - startedAt;
376
+ usage.inactiveMs = Math.max(0, completedAt - lastActivityAt);
377
+ if (error instanceof FabricTaskError) {
378
+ const failure = failureFromError(error);
379
+ return {
380
+ executionAuthority: input.executionAuthority,
381
+ outcome: sealOutcome({
382
+ taskSubject,
383
+ subjectId,
384
+ fixtureDigest,
385
+ verifierDigest,
386
+ sandboxDigest,
387
+ startedAt,
388
+ completedAt,
389
+ usage,
390
+ outcome: outcomeFromFailure(failure),
391
+ verifier: infrastructureVerifier(verifierDigest, error.code),
392
+ failure,
393
+ sourceRefs: input.sourceRefs,
394
+ }),
395
+ };
396
+ }
397
+ const failure: FailureRecordV1 = {
398
+ class: "harness_failure",
399
+ code: "harness_failure",
400
+ retryable: false,
401
+ attribution: "harness",
402
+ };
403
+ return {
404
+ executionAuthority: input.executionAuthority,
405
+ outcome: sealOutcome({
406
+ taskSubject,
407
+ subjectId,
408
+ fixtureDigest,
409
+ verifierDigest,
410
+ sandboxDigest,
411
+ startedAt,
412
+ completedAt,
413
+ usage,
414
+ outcome: "inconclusive",
415
+ verifier: infrastructureVerifier(verifierDigest, "harness_failure"),
416
+ failure,
417
+ sourceRefs: input.sourceRefs,
418
+ }),
419
+ };
420
+ } finally {
421
+ scratch?.cleanup();
422
+ }
423
+ }
424
+
425
+ function infrastructureVerifier(manifestDigest: string, reason: string): FabricTaskOutcomeV1["verifier"] {
426
+ return {
427
+ verifierId: FABRIC_VERIFIER_ID,
428
+ manifestDigest,
429
+ passed: false,
430
+ pathSummaries: [],
431
+ reason,
432
+ };
433
+ }
434
+
435
+ /** Assemble an immutable FabricTaskOutcomeV1 from executor state. */
436
+ function sealOutcome(input: {
437
+ taskSubject: FabricTaskOutcomeV1["taskSubject"];
438
+ subjectId: string;
439
+ fixtureDigest: string;
440
+ verifierDigest: string;
441
+ sandboxDigest: string;
442
+ startedAt: number;
443
+ completedAt: number;
444
+ usage: FabricUsageV1;
445
+ outcome: FabricTaskOutcomeV1["outcome"];
446
+ verifier: FabricTaskOutcomeV1["verifier"];
447
+ failure?: FailureRecordV1;
448
+ sourceRefs?: string[];
449
+ }): FabricTaskOutcomeV1 {
450
+ return {
451
+ schemaVersion: 1,
452
+ taskClassId: FABRIC_TASK_CLASS_ID,
453
+ taskClassVersion: FABRIC_TASK_CLASS_VERSION,
454
+ routeSubject: input.taskSubject.routeSubject,
455
+ taskSubject: input.taskSubject,
456
+ subjectId: input.subjectId,
457
+ taskFixtureDigest: input.fixtureDigest,
458
+ verifierManifestDigest: input.verifierDigest,
459
+ fabricCompatibilityVersion: FABRIC_COMPATIBILITY_VERSION,
460
+ sandboxProfileDigest: input.sandboxDigest,
461
+ startedAt: input.startedAt,
462
+ completedAt: input.completedAt,
463
+ limits: { ...FABRIC_LIMITS },
464
+ usage: { ...input.usage },
465
+ outcome: input.outcome,
466
+ verifier: {
467
+ ...input.verifier,
468
+ pathSummaries: [...input.verifier.pathSummaries],
469
+ },
470
+ ...(input.failure ? { failure: { ...input.failure } } : {}),
471
+ artifactDigests: [],
472
+ ...(input.sourceRefs ? { sourceRefs: [...input.sourceRefs] } : {}),
473
+ };
474
+ }
475
+
476
+ /** Declared sandbox policy for the frozen scratch producer (not runtime enforcement). */
477
+ export function fabricDeclaredSandboxPolicy(): {
478
+ network: boolean;
479
+ userMcp: boolean;
480
+ arbitraryShell: boolean;
481
+ userRepository: boolean;
482
+ } {
483
+ return {
484
+ network: SANDBOX_PROFILE_V1.allowNetwork,
485
+ userMcp: SANDBOX_PROFILE_V1.allowUserMcp,
486
+ arbitraryShell: SANDBOX_PROFILE_V1.allowShell,
487
+ userRepository: SANDBOX_PROFILE_V1.allowUserRepository,
488
+ };
489
+ }
490
+
491
+ /** @deprecated Use fabricDeclaredSandboxPolicy. */
492
+ export const fabricScratchCapabilityProbe = fabricDeclaredSandboxPolicy;
@@ -0,0 +1,80 @@
1
+ /** CL-07 fabric module public surface (explicit allowlist re-exports). */
2
+ export {
3
+ FABRIC_SUITE_ID,
4
+ FABRIC_SUITE_VERSION,
5
+ FABRIC_SCENARIO_ID,
6
+ FABRIC_SCENARIO_VERSION,
7
+ FABRIC_TASK_CLASS_ID,
8
+ FABRIC_TASK_CLASS_VERSION,
9
+ FABRIC_COMPATIBILITY_VERSION,
10
+ FABRIC_VERIFIER_ID,
11
+ FABRIC_EVIDENCE_LAYER,
12
+ SYNTHETIC_VALUE_PATH,
13
+ SYNTHETIC_BEFORE_UTF8,
14
+ SYNTHETIC_AFTER_UTF8,
15
+ FABRIC_LIMITS,
16
+ SANDBOX_PROFILE_V1,
17
+ } from "./constants";
18
+ export type {
19
+ FabricOutcomeKind,
20
+ FabricFailureClass,
21
+ FabricExecutionAuthority,
22
+ FabricLimitsV1,
23
+ SyntheticPatchOperationV1,
24
+ SyntheticPatchV1,
25
+ FabricUsageV1,
26
+ ExactTreeDiffPathSummaryV1,
27
+ ExactTreeDiffResultV1,
28
+ FabricTaskOutcomeV1,
29
+ FabricTaskRunResult,
30
+ FabricHarnessProducerKind,
31
+ FabricPatchExecutorInput,
32
+ FabricPatchExecutor,
33
+ TrustedFabricPatchExecutor,
34
+ } from "./types";
35
+ export { FabricTaskError } from "./types";
36
+ export {
37
+ sandboxProfileDigest,
38
+ verifierManifestObject,
39
+ verifierManifestDigest,
40
+ taskFixtureObject,
41
+ taskFixtureDigest,
42
+ buildTaskSubjectV1,
43
+ taskSubjectId,
44
+ } from "./subject";
45
+ export {
46
+ assertSafeRelativePosixPath,
47
+ resolveInsideScratch,
48
+ createSyntheticScratch,
49
+ assertNotUnderUserRepo,
50
+ } from "./scratch";
51
+ export type { ScratchTree, WalkedFile } from "./scratch";
52
+ export { parseSyntheticPatchV1 } from "./patch";
53
+ export { verifyExactTreeDiffV1 } from "./verifier";
54
+ export {
55
+ correctSyntheticPatch,
56
+ runFabricSyntheticPatchTask,
57
+ runFabricSyntheticPatchTaskForRoute,
58
+ runFabricSyntheticPatchTaskHarness,
59
+ fabricDeclaredSandboxPolicy,
60
+ fabricScratchCapabilityProbe,
61
+ } from "./executor";
62
+ export type {
63
+ RunFabricTaskHarnessOptions,
64
+ RunFabricTaskForRouteOptions,
65
+ } from "./executor";
66
+ export {
67
+ loadFabricCaseAuthority,
68
+ discoverFabricScenarios,
69
+ expandFabricScenario,
70
+ expandFabricSuiteManifest,
71
+ fabricScenarioManifestDigest,
72
+ fabricSuiteManifestDigest,
73
+ } from "./manifest";
74
+ export type { FabricCaseAuthority } from "./manifest";
75
+ export {
76
+ assertFabricOutcomeV1,
77
+ observationFromFabricOutcome,
78
+ persistFabricRunResult,
79
+ } from "./observe";
80
+ export type { PersistFabricOptions, PersistedFabricObservation } from "./observe";