@zhivex-ai/harness 1.4.0 → 1.5.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 (128) hide show
  1. package/CHANGELOG.md +32 -10
  2. package/README.md +7 -5
  3. package/SUPPORT.md +2 -2
  4. package/contracts/client-protocol-v1.schema.json +593 -0
  5. package/contracts/engine-api.json +156 -0
  6. package/contracts/public-api.json +12 -0
  7. package/contracts/stable-api-signatures.json +36 -36
  8. package/dist/acp-cli.js +54 -20
  9. package/dist/approvals/approval-diff.d.ts +2 -1
  10. package/dist/approvals/approval-preview.d.ts +1 -1
  11. package/dist/audit/index.d.ts +3 -0
  12. package/dist/audit/index.js +482 -0
  13. package/dist/audit/pack.d.ts +72 -0
  14. package/dist/audit-pack-kvw7ng34.js +532 -0
  15. package/dist/cli/arguments.d.ts +3 -1
  16. package/dist/cli/audit-pack.d.ts +24 -0
  17. package/dist/cli/cli-credentials.d.ts +6 -0
  18. package/dist/cli/cli-profiles.d.ts +4 -2
  19. package/dist/cli/node-engine.d.ts +2 -0
  20. package/dist/cli-entry-75j3r49b.js +484 -0
  21. package/dist/cli-entry-928p8h41.js +10067 -0
  22. package/dist/cli-entry-h2yc9x37.js +10350 -0
  23. package/dist/{cli-entry-20w6nh0k.js → cli-entry-hdtfef27.js} +439 -19
  24. package/dist/{cli-entry-w0hterjs.js → cli-entry-q8bgkn9m.js} +40 -13
  25. package/dist/{cli-2h37qyvg.js → cli-vyrytn3m.js} +253 -644
  26. package/dist/cli.js +27 -2
  27. package/dist/client/json-contracts.d.ts +4 -0
  28. package/dist/client/protocol.d.ts +133 -0
  29. package/dist/client/task-control-host.d.ts +400 -0
  30. package/dist/client/task-projection-host.d.ts +12 -0
  31. package/dist/client/task-projection.d.ts +168 -0
  32. package/dist/compat/code-support.js +28 -22
  33. package/dist/{config-qt69hkqj.js → config-r9fdhce6.js} +3 -3
  34. package/dist/{config-j9624t6t.js → config-vyajmksy.js} +1 -1
  35. package/dist/engine/acp.js +15 -11
  36. package/dist/engine/client.js +14 -10
  37. package/dist/engine/desktop-providers-v1.d.ts +2 -0
  38. package/dist/engine/desktop-providers-v1.js +23 -3
  39. package/dist/engine/desktop-state-v1.js +11 -8
  40. package/dist/engine/index.d.ts +3 -0
  41. package/dist/engine/index.js +101 -554
  42. package/dist/engine/mcp-stdio-v1.js +8 -6
  43. package/dist/engine/models.js +76 -4
  44. package/dist/engine/protocol.d.ts +2 -0
  45. package/dist/engine/protocol.js +110 -0
  46. package/dist/engine/service.js +15 -11
  47. package/dist/hostile-repository-demo.js +1232 -564
  48. package/dist/{index-8zjmnyw5.js → index-1265j7t2.js} +73 -6
  49. package/dist/{index-nmjdwd4p.js → index-4gt045j0.js} +109 -1
  50. package/dist/{index-pdmevfxv.js → index-5zbq9ztj.js} +5 -259
  51. package/dist/{index-6dft2vev.js → index-63gbp0cz.js} +5 -3
  52. package/dist/index-6dxrbnxm.js +719 -0
  53. package/dist/{index-pp474137.js → index-6fp7kdpx.js} +769 -933
  54. package/dist/{index-61gthdz6.js → index-8sm2a1wa.js} +1 -1
  55. package/dist/{index-rkbf7dqg.js → index-96ezrvg2.js} +57 -13
  56. package/dist/index-bt2p8x7r.js +329 -0
  57. package/dist/index-c39197wq.js +552 -0
  58. package/dist/{index-m82cfspw.js → index-eps3c3g6.js} +877 -963
  59. package/dist/{index-s2k2edts.js → index-fqqz1yt8.js} +110 -1544
  60. package/dist/{index-m34q25jj.js → index-ggstwr0v.js} +192 -838
  61. package/dist/index-jpdvn09j.js +490 -0
  62. package/dist/{index-xqxeypt5.js → index-mzydbzp8.js} +76 -4
  63. package/dist/index-pq3kz1r8.js +269 -0
  64. package/dist/{index-wg1sd3at.js → index-qfsrrnz6.js} +1 -1
  65. package/dist/{index-937cb7y8.js → index-vc7yxz50.js} +561 -35
  66. package/dist/{index-5jhgatga.js → index-vvzc5ezz.js} +7 -6
  67. package/dist/index-wwthv10a.js +1507 -0
  68. package/dist/{index-tfzta544.js → index-xfedewpt.js} +17 -9
  69. package/dist/index-yx52bt4a.js +511 -0
  70. package/dist/index.d.ts +3 -0
  71. package/dist/index.js +93 -77
  72. package/dist/integrations/mcp-stdio-tools.d.ts +4 -1
  73. package/dist/internal/desktop/providers.d.ts +2 -0
  74. package/dist/models/catalog.d.ts +2 -0
  75. package/dist/persistence/sqlite-database.d.ts +1 -0
  76. package/dist/providers/azure-openai.d.ts +14 -0
  77. package/dist/providers/bedrock.d.ts +23 -0
  78. package/dist/providers/providers.d.ts +1 -1
  79. package/dist/runtime/budget-ledger-scope.d.ts +14 -0
  80. package/dist/runtime/durable-review-group.d.ts +33 -0
  81. package/dist/runtime/harness.d.ts +11 -0
  82. package/dist/runtime/run-interruption.d.ts +7 -0
  83. package/dist/runtime/shared-budget.d.ts +30 -0
  84. package/dist/runtime/task-continuity.d.ts +300 -77
  85. package/dist/service-cli.js +15 -11
  86. package/dist/{service-client-cli-fn54ev6w.js → service-client-cli-v6qptg9x.js} +400 -305
  87. package/dist/tools/workspace.d.ts +2 -2
  88. package/dist/verify-historical-migrations.js +1237 -566
  89. package/dist/workspace/edit-contracts.d.ts +2 -2
  90. package/dist/workspace/path-policy.d.ts +2 -1
  91. package/dist/workspace/workspace.d.ts +13 -0
  92. package/dist/zhx.js +27 -2
  93. package/docs/AUDIT_PACK.md +99 -0
  94. package/docs/AZURE_OPENAI.md +53 -0
  95. package/docs/BEDROCK.md +56 -0
  96. package/docs/CLI.md +15 -0
  97. package/docs/CLIENT_PROTOCOL.md +178 -0
  98. package/docs/CODE_RELEASE.md +59 -7
  99. package/docs/CODE_WEB_TASKS.md +116 -0
  100. package/docs/CONTEXT_ENGINEERING.md +59 -0
  101. package/docs/CREDENTIALS.md +21 -0
  102. package/docs/DURABLE_OPERATIONS.md +93 -1
  103. package/docs/ENGINE_API.md +5 -2
  104. package/docs/EXTENSIBILITY.md +8 -4
  105. package/docs/FIRST_USE.md +6 -6
  106. package/docs/MINIMUM_TASK_AUTHORITY.md +3 -3
  107. package/docs/PROJECT_MEMORY.md +1 -1
  108. package/docs/PUBLIC_SECURITY.md +14 -1
  109. package/docs/README.md +6 -1
  110. package/docs/REPOSITORY_EDITING.md +1 -1
  111. package/docs/STABILITY.md +3 -1
  112. package/docs/SUPPORT_MATRIX.md +1 -1
  113. package/docs/SUPPORT_MATRIX_1_1.md +1 -1
  114. package/docs/TOOL_POLICY.md +4 -1
  115. package/docs/USAGE.md +3 -1
  116. package/docs/VERTEX.md +2 -2
  117. package/docs/WEB_LIMITS.md +4 -3
  118. package/docs/adr/0002-isolated-mcp-stdio.md +7 -4
  119. package/docs/support-matrix-1.1.json +3 -1
  120. package/docs/support-matrix.json +6 -4
  121. package/evaluations/code-task-ui.json +20 -0
  122. package/evaluations/representative-assembly-matrix.json +19 -1
  123. package/evaluations/task-projection.json +10 -0
  124. package/evaluations/task-recovery-lab.json +60 -0
  125. package/examples/README.md +3 -3
  126. package/package.json +23 -13
  127. package/dist/cli-entry-4ngptr62.js +0 -19900
  128. package/dist/index-m49jx72n.js +0 -220
@@ -0,0 +1,490 @@
1
+ import {
2
+ changeEnvelopeSchema,
3
+ verifyChangeEnvelope
4
+ } from "./index-yx52bt4a.js";
5
+ import {
6
+ APPROVAL_HISTORY_KEY,
7
+ approvalDecisionViews,
8
+ harnessPolicyDecisionEventSchema
9
+ } from "./index-bt2p8x7r.js";
10
+ import {
11
+ TASK_ACCEPTANCE_EVIDENCE_KEY,
12
+ USAGE_LEDGER_KEY,
13
+ inspectRuntimeManifest,
14
+ inspectUsageLedger,
15
+ readTaskAcceptanceLedger
16
+ } from "./index-fqqz1yt8.js";
17
+ import {
18
+ HARNESS_VERSION
19
+ } from "./index-pq3kz1r8.js";
20
+ import {
21
+ taskCheckReceiptSchema
22
+ } from "./index-6dxrbnxm.js";
23
+
24
+ // src/persistence/governance-report.ts
25
+ import { createHash as createHash2 } from "node:crypto";
26
+ import { z as z2 } from "zod";
27
+
28
+ // src/persistence/governance-context.ts
29
+ import { createHash } from "node:crypto";
30
+ import { z } from "zod";
31
+ var digest = z.string().regex(/^sha256:[a-f0-9]{64}$/);
32
+ var count = z.number().int().nonnegative().safe();
33
+ var governanceReference = (kind, value) => "sha256:" + createHash("sha256").update(JSON.stringify([kind, value])).digest("hex");
34
+ var governanceSessionSchema = z.strictObject({ availability: z.enum(["recorded", "unavailable"]), reference: digest.nullable(), revision: count.nullable() });
35
+ var governanceHistorySchema = z.strictObject({
36
+ availability: z.enum(["recorded", "unavailable"]),
37
+ retention: z.enum(["unknown", "retained", "expired"]),
38
+ incomplete: z.boolean(),
39
+ policyDecisions: z.array(z.strictObject({
40
+ runReference: digest,
41
+ sequence: count,
42
+ toolReference: digest,
43
+ phase: z.enum(["approval-request", "tool-entry"]),
44
+ decision: z.enum(["allow", "ask_user", "deny"]),
45
+ policyDigest: digest.nullable(),
46
+ source: z.enum(["operator-file", "application", "baseline"]),
47
+ ruleReferences: z.array(digest).max(128),
48
+ explicitReviewRequired: z.boolean()
49
+ })).max(512)
50
+ });
51
+ var governanceEnvelopeSchema = z.strictObject({
52
+ source: z.literal("caller-supplied"),
53
+ envelopeId: digest.nullable(),
54
+ patchReference: digest.nullable(),
55
+ patchDigest: digest.nullable(),
56
+ linkedRunReferences: z.array(digest).max(64),
57
+ schemaValid: z.boolean(),
58
+ integrity: z.enum(["valid", "invalid"]),
59
+ expiration: z.enum(["unknown", "current", "expired", "not-yet-valid"]),
60
+ checkedAt: z.iso.datetime(),
61
+ expiredApprovals: count,
62
+ authenticity: z.literal("not-verified"),
63
+ patchBytes: z.literal("not-verified")
64
+ });
65
+ async function readGovernanceSession(source, rootRunId, runIds) {
66
+ const session = { availability: "unavailable", reference: null, revision: null };
67
+ const history = { availability: "unavailable", retention: "unknown", incomplete: true, policyDecisions: [] };
68
+ if (!source)
69
+ return { session, history, verify: async () => {} };
70
+ const initial = await source.index.get(source.id);
71
+ if (!initial || initial.sessionId !== source.id || !initial.runs.some((run) => run.runId === rootRunId))
72
+ throw new Error("GOVERNANCE_SESSION_MISMATCH");
73
+ const captured = JSON.stringify(initial);
74
+ session.availability = "recorded";
75
+ session.reference = governanceReference("session", initial.sessionId);
76
+ session.revision = initial.revision;
77
+ const pages = [];
78
+ if (source.history) {
79
+ let cursor = 0;
80
+ history.availability = "recorded";
81
+ history.retention = "retained";
82
+ history.incomplete = false;
83
+ for (let pageIndex = 0;pageIndex < 50; pageIndex++) {
84
+ const page = source.history.replay(source.id, cursor);
85
+ pages.push({ cursor, digest: governanceReference("history-page", JSON.stringify(page)) });
86
+ if (page.schemaVersion !== 1 || !Number.isSafeInteger(page.nextCursor) || page.nextCursor < cursor || page.events.length > 200)
87
+ throw new Error("GOVERNANCE_HISTORY_INVALID");
88
+ if (page.cursorExpired || page.policyEvidenceIncomplete) {
89
+ history.retention = "expired";
90
+ history.incomplete = true;
91
+ }
92
+ let lastSequence = cursor;
93
+ for (const event of page.events) {
94
+ if (event.sessionId !== source.id || !Number.isSafeInteger(event.sequence) || event.sequence <= lastSequence || event.sequence > page.nextCursor)
95
+ throw new Error("GOVERNANCE_HISTORY_INVALID");
96
+ lastSequence = event.sequence;
97
+ if (!runIds.has(event.runId) || event.activity.type !== "policy-decision")
98
+ continue;
99
+ const parsed = harnessPolicyDecisionEventSchema.safeParse(event.activity);
100
+ if (!parsed.success) {
101
+ history.incomplete = true;
102
+ continue;
103
+ }
104
+ if (history.policyDecisions.length === 512) {
105
+ history.incomplete = true;
106
+ continue;
107
+ }
108
+ const value = parsed.data;
109
+ history.policyDecisions.push({
110
+ runReference: governanceReference("run", event.runId),
111
+ sequence: event.sequence,
112
+ toolReference: governanceReference("tool", value.toolName),
113
+ phase: value.phase,
114
+ decision: value.decision,
115
+ policyDigest: value.policyDigest,
116
+ source: value.source,
117
+ ruleReferences: value.ruleIds.map((rule) => governanceReference("rule", rule)),
118
+ explicitReviewRequired: value.explicitReviewRequired
119
+ });
120
+ }
121
+ if (page.cursorExpired || !page.hasMore)
122
+ break;
123
+ if (page.nextCursor === cursor)
124
+ throw new Error("GOVERNANCE_HISTORY_INVALID");
125
+ cursor = page.nextCursor;
126
+ if (pageIndex === 49)
127
+ history.incomplete = true;
128
+ }
129
+ }
130
+ return { session, history, verify: async () => {
131
+ for (const page of pages)
132
+ if (governanceReference("history-page", JSON.stringify(source.history.replay(source.id, page.cursor))) !== page.digest)
133
+ throw new Error("GOVERNANCE_STATE_CHANGED");
134
+ if (JSON.stringify(await source.index.get(source.id)) !== captured)
135
+ throw new Error("GOVERNANCE_STATE_CHANGED");
136
+ } };
137
+ }
138
+ function projectGovernanceEnvelopes(envelopes, patches, now) {
139
+ if (envelopes.length > 32)
140
+ throw new Error("GOVERNANCE_ENVELOPE_LIMIT");
141
+ return envelopes.map((input) => {
142
+ if (Buffer.byteLength(JSON.stringify(input) ?? "") > 256 * 1024)
143
+ throw new Error("GOVERNANCE_ENVELOPE_LIMIT");
144
+ const parsed = changeEnvelopeSchema.safeParse(input);
145
+ const proof = verifyChangeEnvelope(input, { now });
146
+ const envelope = parsed.success ? parsed.data : undefined;
147
+ return governanceEnvelopeSchema.parse({
148
+ source: "caller-supplied",
149
+ envelopeId: envelope?.envelopeId ?? null,
150
+ patchReference: envelope ? governanceReference("patch", envelope.patch.patchId) : null,
151
+ patchDigest: envelope?.patch.patchDigest ?? null,
152
+ linkedRunReferences: envelope ? [...patches.get(envelope.patch.patchId) ?? []] : [],
153
+ schemaValid: parsed.success,
154
+ integrity: proof.integrity.envelopeDigestValid && proof.integrity.evidenceDigestValid ? "valid" : "invalid",
155
+ expiration: !envelope ? "unknown" : proof.expiration.envelopeNotYetValid ? "not-yet-valid" : proof.expiration.envelopeExpired ? "expired" : "current",
156
+ checkedAt: proof.expiration.checkedAt,
157
+ expiredApprovals: proof.expiration.expiredApprovalIds.length,
158
+ authenticity: "not-verified",
159
+ patchBytes: "not-verified"
160
+ });
161
+ });
162
+ }
163
+
164
+ // src/persistence/governance-report.ts
165
+ var digest2 = z2.string().regex(/^sha256:[a-f0-9]{64}$/);
166
+ var version = z2.string().regex(/^\d+\.\d+\.\d+(?:[-+][a-zA-Z0-9.-]+)?$/);
167
+ var bindingSchema = z2.object({ schemaVersion: z2.literal(1), id: z2.literal("zhivex-harness"), version, fingerprint: digest2, algorithm: z2.literal("sha256") });
168
+ var count2 = z2.number().int().nonnegative().safe();
169
+ var status = z2.enum(["created", "running", "waiting_approval", "cancel_requested", "completed", "failed", "cancelled", "timed_out", "unknown"]);
170
+ var availability = z2.enum(["recorded", "unavailable", "invalid"]);
171
+ var providerReason = z2.enum(["empty_arguments", "invalid_json", "arguments_too_large", "incomplete_arguments", "inconsistent_metadata", "response_failed", "response_incomplete", "stream_truncated"]);
172
+ var deliveryReason = z2.enum(["TASK_ACCEPTANCE_NO_DELIVERY_EVIDENCE", "TASK_ACCEPTANCE_SCOPE_VIOLATION", "TASK_ACCEPTANCE_RUN_NOT_COMPLETED", "TASK_ACCEPTANCE_RUN_NOT_FINISHED", "TASK_ACCEPTANCE_IMPORT_UNCONFIRMED", "TASK_ACCEPTANCE_CHECKS_MISSING", "TASK_ACCEPTANCE_DELIVERY_DRIFT", "TASK_ACCEPTANCE_DELIVERY_INSPECTION_FAILED", "TASK_ACCEPTANCE_HUMAN_REVIEW_REQUIRED", "TASK_ACCEPTANCE_VERIFIED"]);
173
+ var deliveryStatus = z2.enum(["pending", "incomplete", "failed", "pending_review", "verified", "unknown"]);
174
+ var checkSchema = z2.strictObject({
175
+ reference: digest2,
176
+ argvDigest: digest2,
177
+ patchId: digest2,
178
+ snapshotDigest: digest2,
179
+ exitCode: z2.number().int(),
180
+ timedOut: z2.boolean(),
181
+ unchanged: z2.boolean()
182
+ });
183
+ var deliverySchema = z2.object({
184
+ schemaVersion: z2.literal(1),
185
+ contractRevision: count2,
186
+ contractDigest: digest2,
187
+ status: deliveryStatus,
188
+ checks: z2.array(taskCheckReceiptSchema).max(32),
189
+ delivery: z2.object({ runId: z2.string().max(512), executionIdentity: z2.string().max(512), patchId: digest2, snapshotDigest: digest2 }).optional()
190
+ });
191
+ var approvalSchema = z2.strictObject({
192
+ reference: digest2,
193
+ toolReference: digest2,
194
+ approved: z2.boolean(),
195
+ origin: z2.enum(["interactive", "automatic", "application", "unknown"]),
196
+ channelReference: digest2,
197
+ policyDigest: digest2.nullable(),
198
+ status: z2.enum(["rejected", "approved", "applied", "succeeded", "failed", "unknown"]),
199
+ proposalId: digest2.nullable(),
200
+ exitCode: z2.number().int().nullable(),
201
+ timedOut: z2.boolean().nullable(),
202
+ effects: z2.array(z2.strictObject({ pathReference: digest2, beforeDigest: digest2.nullable(), afterDigest: digest2.nullable() })).max(50)
203
+ });
204
+ var delegationReason = z2.enum(["valid", "invalid_json", "invalid_schema", "task_mismatch", "incomplete", "duplicate_claim", "path_denied", "evidence_missing", "coverage_missing", "missing_child", "child_identity_unavailable"]);
205
+ var delegationSchema = z2.strictObject({
206
+ taskReference: digest2,
207
+ childReference: digest2.nullable(),
208
+ recordedAcceptance: z2.boolean(),
209
+ reason: delegationReason,
210
+ semanticReview: z2.enum(["pending", "not_requested"]),
211
+ correctionsUsed: count2.nullable()
212
+ });
213
+ var delegationInput = z2.object({ schemaVersion: z2.literal(1), evaluations: z2.array(z2.object({
214
+ taskId: z2.string().max(128),
215
+ childRunId: z2.string().max(512).nullable(),
216
+ childStatus: z2.string().max(32),
217
+ accepted: z2.boolean(),
218
+ reason: delegationReason,
219
+ semanticReview: z2.enum(["pending", "not_requested"]),
220
+ correctionsUsed: count2.optional()
221
+ })).max(64) });
222
+ var runSchema = z2.strictObject({
223
+ reference: digest2,
224
+ parentReference: digest2.nullable(),
225
+ revision: count2.nullable(),
226
+ status,
227
+ finalized: z2.boolean(),
228
+ failure: z2.enum(["run_failed", "cancelled", "timed_out", "not_reported"]).nullable(),
229
+ failureDetails: z2.strictObject({ providerToolReason: providerReason.nullable(), diagnosticReference: digest2.nullable(), deliveryReason: deliveryReason.nullable() }),
230
+ identity: z2.literal("not-verified"),
231
+ runtimePolicy: z2.enum(["assistant-v3-durable-closure"]).nullable(),
232
+ contract: z2.strictObject({
233
+ availability,
234
+ digest: digest2.nullable(),
235
+ revision: count2.nullable(),
236
+ requiredChecks: count2.nullable(),
237
+ humanReviewsPending: count2.nullable(),
238
+ allowedWritePathReferences: z2.array(digest2).max(256),
239
+ protectedPathReferences: z2.array(digest2).max(256),
240
+ checks: z2.array(z2.strictObject({ reference: digest2, argvDigest: digest2, kind: z2.enum(["argv", "package-script"]), backend: z2.enum(["none", "oci"]), approval: z2.literal("required") })).max(32),
241
+ humanReviewReferences: z2.array(digest2).max(32)
242
+ }),
243
+ delivery: z2.strictObject({
244
+ availability,
245
+ status: deliveryStatus,
246
+ patchId: digest2.nullable(),
247
+ snapshotDigest: digest2.nullable(),
248
+ interpretation: z2.literal("recorded-checkpoint-not-current-workspace-verification"),
249
+ checks: z2.array(checkSchema).max(32)
250
+ }),
251
+ approvals: z2.strictObject({ availability, items: z2.array(approvalSchema).max(512) }),
252
+ usage: z2.strictObject({
253
+ availability: z2.enum(["recorded", "unavailable"]),
254
+ calls: count2.nullable(),
255
+ inputTokens: count2.nullable(),
256
+ outputTokens: count2.nullable(),
257
+ complete: z2.boolean().nullable(),
258
+ estimatedUsd: z2.number().finite().nonnegative().nullable(),
259
+ costKind: z2.literal("estimate-not-invoice")
260
+ }),
261
+ journal: z2.strictObject({ availability: z2.enum(["recorded", "unavailable"]), entries: count2, failed: count2, unfinished: count2 }),
262
+ delegations: z2.strictObject({ availability, interpretation: z2.literal("recorded-checkpoint-not-semantic-review"), items: z2.array(delegationSchema).max(64) }),
263
+ children: z2.array(digest2).max(64)
264
+ });
265
+ var harnessGovernanceReportSchema = z2.strictObject({
266
+ schemaVersion: z2.literal(1),
267
+ kind: z2.literal("harness-governance-report"),
268
+ exporterVersion: z2.string().regex(/^\d+\.\d+\.\d+(?:[-+][a-zA-Z0-9.-]+)?$/),
269
+ executionArtifact: z2.strictObject({ version: version.nullable(), digest: z2.null(), availability: z2.enum(["recorded-version", "unavailable"]), configurationFingerprint: digest2.nullable(), authenticity: z2.literal("not-verified") }),
270
+ rootReference: digest2,
271
+ identity: z2.literal("not-verified"),
272
+ referencePolicy: z2.literal("sha256-domain-separated-pseudonyms-not-anonymity"),
273
+ session: governanceSessionSchema,
274
+ eventHistory: governanceHistorySchema,
275
+ changeEnvelopes: z2.array(governanceEnvelopeSchema).max(32),
276
+ runs: z2.array(runSchema).max(64),
277
+ missingChildren: z2.array(digest2).max(64),
278
+ limitations: z2.array(z2.enum(["tree_limit", "missing_child", "invalid_contract", "invalid_delivery", "invalid_approvals", "journal_unavailable"])).max(6)
279
+ });
280
+ var MAX_JOURNAL = 2048;
281
+ var MAX_REPORT_BYTES = 2 * 1024 * 1024;
282
+ var sameScope = (state, scope) => !state.scope || state.scope.tenantId === scope?.tenantId && state.scope.userId === scope?.userId && state.scope.namespace === scope?.namespace;
283
+ function projectRun(state, journal, limitations) {
284
+ const runStatus = status.safeParse(state.status);
285
+ const stateStatus = runStatus.success ? runStatus.data : "unknown";
286
+ let ledger;
287
+ let contractAvailability = "unavailable";
288
+ try {
289
+ ledger = readTaskAcceptanceLedger(state);
290
+ if (ledger)
291
+ contractAvailability = "recorded";
292
+ } catch {
293
+ contractAvailability = "invalid";
294
+ limitations.add("invalid_contract");
295
+ }
296
+ const contract = ledger?.revisions.at(-1);
297
+ const rawDelivery = state.metadata?.[TASK_ACCEPTANCE_EVIDENCE_KEY];
298
+ const parsedDelivery = deliverySchema.safeParse(rawDelivery);
299
+ const bound = parsedDelivery.success && contract && parsedDelivery.data.contractDigest === contract.digest && parsedDelivery.data.contractRevision === contract.revision && (!parsedDelivery.data.delivery || parsedDelivery.data.delivery.runId === state.runId);
300
+ const candidate = bound ? parsedDelivery.data : undefined;
301
+ const verified = candidate?.status === "verified" || candidate?.status === "pending_review";
302
+ const validSuccess = !verified || stateStatus === "completed" && candidate.delivery && contract && contract.contract.requiredChecks.every((required) => candidate.checks.some((check) => check.checkId === required.id && check.runId === state.runId && check.argvDigest === "sha256:" + createHash2("sha256").update(JSON.stringify([required.command, ...required.args])).digest("hex") && check.contractDigest === contract.digest && check.contractRevision === contract.revision && check.exitCode === 0 && !check.timedOut && check.unchanged && check.patchId === candidate.delivery.patchId && check.snapshotDigest === candidate.delivery.snapshotDigest && check.executionIdentity === candidate.delivery.executionIdentity)) && candidate.status === "pending_review" === contract.contract.humanReview.length > 0;
303
+ const delivery = validSuccess ? candidate : undefined;
304
+ if (rawDelivery !== undefined && !delivery)
305
+ limitations.add("invalid_delivery");
306
+ const approvals = { availability: state.metadata?.[APPROVAL_HISTORY_KEY] === undefined ? "unavailable" : "recorded", items: [] };
307
+ try {
308
+ for (let offset = 0;offset < 512; offset += 25) {
309
+ const rows = approvalDecisionViews(state, journal ?? [], offset);
310
+ for (const row of rows)
311
+ approvals.items.push({
312
+ reference: governanceReference("approval", row.approvalId),
313
+ toolReference: governanceReference("tool", row.name),
314
+ approved: row.approved,
315
+ origin: row.provenance?.origin ?? "unknown",
316
+ channelReference: governanceReference("channel", row.provenance?.channel ?? "unknown"),
317
+ policyDigest: row.provenance?.policyDigest ?? null,
318
+ status: row.status,
319
+ proposalId: row.evidence?.proposalId ?? null,
320
+ exitCode: row.evidence?.exitCode ?? null,
321
+ timedOut: row.evidence?.timedOut ?? null,
322
+ effects: (row.evidence?.effects ?? []).map((effect) => ({ pathReference: governanceReference("path", effect.path), beforeDigest: effect.beforeDigest, afterDigest: effect.afterDigest }))
323
+ });
324
+ if (rows.length < 25)
325
+ break;
326
+ }
327
+ } catch {
328
+ approvals.availability = "invalid";
329
+ approvals.items = [];
330
+ limitations.add("invalid_approvals");
331
+ }
332
+ const parsedUsage = inspectUsageLedger(state.metadata?.[USAGE_LEDGER_KEY]);
333
+ const usage = parsedUsage?.runId === state.runId ? parsedUsage : null;
334
+ const rawDelegations = state.metadata?.zhivexDelegationAcceptanceV1;
335
+ const delegations = delegationInput.safeParse(rawDelegations);
336
+ const manifest = inspectRuntimeManifest(state.metadata?.effectiveRuntime);
337
+ return {
338
+ reference: governanceReference("run", state.runId),
339
+ parentReference: state.parentRunId ? governanceReference("run", state.parentRunId) : null,
340
+ revision: count2.safeParse(state.revision).success ? state.revision : null,
341
+ status: stateStatus,
342
+ finalized: ["completed", "failed", "cancelled", "timed_out"].includes(stateStatus),
343
+ failure: stateStatus === "failed" ? "run_failed" : stateStatus === "cancelled" ? "cancelled" : stateStatus === "timed_out" ? "timed_out" : state.error ? "not_reported" : null,
344
+ failureDetails: {
345
+ providerToolReason: providerReason.safeParse(state.error?.reason).success ? state.error.reason : null,
346
+ diagnosticReference: state.error?.diagnosticCode ? governanceReference("diagnostic", state.error.diagnosticCode) : null,
347
+ deliveryReason: deliveryReason.safeParse(rawDelivery && typeof rawDelivery === "object" && !Array.isArray(rawDelivery) ? rawDelivery.reason : undefined).success ? rawDelivery.reason : null
348
+ },
349
+ identity: "not-verified",
350
+ runtimePolicy: manifest?.policyVersion ?? null,
351
+ contract: {
352
+ availability: contractAvailability,
353
+ digest: contract?.digest ?? null,
354
+ revision: contract?.revision ?? null,
355
+ requiredChecks: contract?.contract.requiredChecks.length ?? null,
356
+ humanReviewsPending: contract?.contract.humanReview.length ?? null,
357
+ allowedWritePathReferences: contract?.contract.allowedWritePaths.map((file) => governanceReference("path", file)) ?? [],
358
+ protectedPathReferences: contract?.contract.protectedFiles.map((file) => governanceReference("path", file)) ?? [],
359
+ checks: contract?.contract.requiredChecks.map((check) => ({ reference: governanceReference("check", check.id), argvDigest: "sha256:" + createHash2("sha256").update(JSON.stringify([check.command, ...check.args])).digest("hex"), kind: check.kind, backend: check.execution.backend, approval: check.execution.approval })) ?? [],
360
+ humanReviewReferences: contract?.contract.humanReview.map((review) => governanceReference("review", review.id)) ?? []
361
+ },
362
+ delivery: {
363
+ availability: delivery ? "recorded" : rawDelivery === undefined ? "unavailable" : "invalid",
364
+ status: delivery?.status ?? "unknown",
365
+ patchId: delivery?.delivery?.patchId ?? null,
366
+ snapshotDigest: delivery?.delivery?.snapshotDigest ?? null,
367
+ interpretation: "recorded-checkpoint-not-current-workspace-verification",
368
+ checks: (delivery?.checks ?? []).filter((check) => check.runId === state.runId && check.contractDigest === contract?.digest && check.contractRevision === contract?.revision).map((check) => ({ reference: governanceReference("check", check.checkId), argvDigest: check.argvDigest, patchId: check.patchId, snapshotDigest: check.snapshotDigest, exitCode: check.exitCode, timedOut: check.timedOut, unchanged: check.unchanged }))
369
+ },
370
+ approvals,
371
+ usage: {
372
+ availability: usage ? "recorded" : "unavailable",
373
+ calls: usage?.calls ?? null,
374
+ inputTokens: usage?.inputTokens ?? null,
375
+ outputTokens: usage?.outputTokens ?? null,
376
+ complete: usage?.usageComplete ?? null,
377
+ estimatedUsd: usage?.estimatedUsd ?? null,
378
+ costKind: "estimate-not-invoice"
379
+ },
380
+ journal: {
381
+ availability: journal ? "recorded" : "unavailable",
382
+ entries: journal?.length ?? 0,
383
+ failed: journal?.filter((entry) => entry.status === "failed").length ?? 0,
384
+ unfinished: journal?.filter((entry) => entry.status !== "completed" && entry.status !== "failed").length ?? 0
385
+ },
386
+ delegations: {
387
+ availability: rawDelegations === undefined ? "unavailable" : delegations.success ? "recorded" : "invalid",
388
+ interpretation: "recorded-checkpoint-not-semantic-review",
389
+ items: delegations.success ? delegations.data.evaluations.map((item) => ({
390
+ taskReference: governanceReference("task", item.taskId),
391
+ childReference: item.childRunId ? governanceReference("run", item.childRunId) : null,
392
+ recordedAcceptance: item.accepted,
393
+ reason: item.reason,
394
+ semanticReview: item.semanticReview,
395
+ correctionsUsed: item.correctionsUsed ?? null
396
+ })) : []
397
+ },
398
+ children: (state.childRuns ?? []).slice(0, 64).map((child) => governanceReference("run", child.runId))
399
+ };
400
+ }
401
+ async function exportHarnessGovernanceReport(store, scope, runId, options = {}) {
402
+ const limitations = new Set;
403
+ const runs = [], missingChildren = [];
404
+ const observed = [];
405
+ const queue = [{ id: runId }], seen = new Set;
406
+ while (queue.length && runs.length + missingChildren.length < 64) {
407
+ const item = queue.shift();
408
+ if (seen.has(item.id))
409
+ continue;
410
+ seen.add(item.id);
411
+ const loaded = await store.load(item.id, scope);
412
+ const state = loaded ? structuredClone(loaded) : undefined;
413
+ if (!state || state.runId !== item.id || !sameScope(state, scope) || item.parent !== undefined && state.parentRunId !== item.parent) {
414
+ if (item.parent === undefined)
415
+ throw new Error("GOVERNANCE_RUN_UNAVAILABLE");
416
+ missingChildren.push(governanceReference("run", item.id));
417
+ limitations.add("missing_child");
418
+ continue;
419
+ }
420
+ const loadedJournal = await store.listToolCalls?.(state.runId, scope);
421
+ const journal = loadedJournal ? structuredClone(loadedJournal) : undefined;
422
+ if (journal && journal.length > MAX_JOURNAL)
423
+ throw new Error("GOVERNANCE_JOURNAL_LIMIT");
424
+ if (journal?.some((entry) => entry.runId !== state.runId))
425
+ throw new Error("GOVERNANCE_JOURNAL_SCOPE");
426
+ if (!journal)
427
+ limitations.add("journal_unavailable");
428
+ observed.push({ state, journal });
429
+ runs.push(projectRun(state, journal, limitations));
430
+ if ((state.childRuns?.length ?? 0) > 64)
431
+ limitations.add("tree_limit");
432
+ for (const child of (state.childRuns ?? []).slice(0, 64))
433
+ queue.push({ id: child.runId, parent: state.runId });
434
+ }
435
+ if (queue.length)
436
+ limitations.add("tree_limit");
437
+ const context = await readGovernanceSession(options.session, runId, new Set(observed.map((item) => item.state.runId)));
438
+ for (const { state, journal } of observed) {
439
+ const current = await store.load(state.runId, scope);
440
+ const currentJournal = await store.listToolCalls?.(state.runId, scope);
441
+ if (!current || JSON.stringify(current) !== JSON.stringify(state) || JSON.stringify(currentJournal) !== JSON.stringify(journal))
442
+ throw new Error("GOVERNANCE_STATE_CHANGED");
443
+ }
444
+ await context.verify();
445
+ const patches = new Map;
446
+ for (const run of runs)
447
+ for (const patch of new Set([run.delivery.patchId, ...run.approvals.items.map((row) => row.proposalId)].filter((id) => id !== null)))
448
+ patches.set(patch, [...patches.get(patch) ?? [], run.reference]);
449
+ const binding = bindingSchema.safeParse(observed[0]?.state.harness);
450
+ const report = harnessGovernanceReportSchema.parse({
451
+ schemaVersion: 1,
452
+ kind: "harness-governance-report",
453
+ exporterVersion: HARNESS_VERSION,
454
+ executionArtifact: { version: binding.success ? binding.data.version : null, digest: null, availability: binding.success ? "recorded-version" : "unavailable", configurationFingerprint: binding.success ? binding.data.fingerprint : null, authenticity: "not-verified" },
455
+ rootReference: governanceReference("run", runId),
456
+ identity: "not-verified",
457
+ referencePolicy: "sha256-domain-separated-pseudonyms-not-anonymity",
458
+ session: context.session,
459
+ eventHistory: context.history,
460
+ changeEnvelopes: projectGovernanceEnvelopes(options.changeEnvelopes ?? [], patches, options.now ?? Date.now()),
461
+ runs,
462
+ missingChildren,
463
+ limitations: [...limitations].sort()
464
+ });
465
+ if (Buffer.byteLength(JSON.stringify(report)) > MAX_REPORT_BYTES)
466
+ throw new Error("GOVERNANCE_REPORT_LIMIT");
467
+ return report;
468
+ }
469
+ function renderHarnessGovernanceMarkdown(input) {
470
+ const report = harnessGovernanceReportSchema.parse(input);
471
+ return [
472
+ "# Execution and governance report",
473
+ "",
474
+ `Schema: ${report.schemaVersion}. Exporter: ${report.exporterVersion}.`,
475
+ `Identity: not verified. Recorded execution version: ${report.executionArtifact.version ?? "unavailable"}. Artifact digest: unavailable. Hash references are pseudonyms, not signatures.`,
476
+ "Delivery describes a recorded checkpoint; export does not recheck the workspace.",
477
+ "",
478
+ "| Run reference | Execution | Recorded delivery | Usage |",
479
+ "| --- | --- | --- | --- |",
480
+ ...report.runs.map((run) => `| ${run.reference} | ${run.status} | ${run.delivery.status} | ${run.usage.availability === "unavailable" ? "unavailable" : `${run.usage.inputTokens} input / ${run.usage.outputTokens} output (${run.usage.complete ? "complete" : "incomplete"})`} |`),
481
+ "",
482
+ `Missing children: ${report.missingChildren.length}. Limitations: ${report.limitations.join(", ") || "none detected"}.`,
483
+ `Session: ${report.session.availability}. Event history: ${report.eventHistory.availability}. Retention: ${report.eventHistory.retention}. Incomplete: ${report.eventHistory.incomplete}.`,
484
+ `Change envelopes: ${report.changeEnvelopes.length}. Envelope integrity does not verify patch bytes or authenticity. Estimates are not invoices.`,
485
+ ""
486
+ ].join(`
487
+ `);
488
+ }
489
+
490
+ export { harnessGovernanceReportSchema, exportHarnessGovernanceReport, renderHarnessGovernanceMarkdown };
@@ -3,7 +3,7 @@ import { z } from "zod";
3
3
  // src/models/catalog.json
4
4
  var catalog_default = {
5
5
  schemaVersion: 1,
6
- revision: "2026-09-29-vertex",
6
+ revision: "2026-10-15-bedrock-azure",
7
7
  providers: [
8
8
  {
9
9
  id: "openai",
@@ -768,6 +768,78 @@ var catalog_default = {
768
768
  reason: "Provisional Vertex route; availability depends on project, region and IAM. No live certification."
769
769
  }
770
770
  ]
771
+ },
772
+ {
773
+ id: "bedrock",
774
+ defaultModel: "anthropic.claude-haiku-5-5",
775
+ models: [
776
+ {
777
+ id: "anthropic.claude-haiku-5-5",
778
+ name: "Claude Haiku 5.5 (Bedrock)",
779
+ group: "primary",
780
+ order: 0,
781
+ lifecycle: "unknown",
782
+ validation: "unverified",
783
+ capabilities: ["chat", "tools"],
784
+ reason: "Provisional Bedrock Converse route. Account access, region, and live Harness certification are not verified. No prices or context limits are inferred."
785
+ },
786
+ {
787
+ id: "anthropic.claude-sonnet-5-5",
788
+ name: "Claude Sonnet 5.5 (Bedrock)",
789
+ group: "other",
790
+ order: 1,
791
+ lifecycle: "unknown",
792
+ validation: "unverified",
793
+ capabilities: ["chat", "tools"],
794
+ reason: "Provisional Bedrock model id. Availability depends on the account and region. No live certification."
795
+ },
796
+ {
797
+ id: "amazon.nova-2-lite-v1:0",
798
+ name: "Amazon Nova 2 Lite (Bedrock)",
799
+ group: "other",
800
+ order: 2,
801
+ lifecycle: "unknown",
802
+ validation: "unverified",
803
+ capabilities: ["chat", "tools"],
804
+ reason: "Provisional Bedrock model id. Availability depends on the account and region. No live certification."
805
+ }
806
+ ]
807
+ },
808
+ {
809
+ id: "azure-openai",
810
+ defaultModel: "gpt-5.4",
811
+ models: [
812
+ {
813
+ id: "gpt-5.4",
814
+ name: "GPT-5.4 (Azure OpenAI)",
815
+ group: "primary",
816
+ order: 0,
817
+ lifecycle: "unknown",
818
+ validation: "unverified",
819
+ capabilities: ["chat", "tools"],
820
+ reason: "Provisional Azure OpenAI route. Deployment name, API version, and live Harness certification are not verified. No prices are copied from the OpenAI API."
821
+ },
822
+ {
823
+ id: "gpt-5",
824
+ name: "GPT-5 (Azure OpenAI)",
825
+ group: "other",
826
+ order: 1,
827
+ lifecycle: "unknown",
828
+ validation: "unverified",
829
+ capabilities: ["chat", "tools"],
830
+ reason: "Provisional Azure OpenAI model id. Use AZURE_OPENAI_DEPLOYMENTS when the deployment name differs. No live certification."
831
+ },
832
+ {
833
+ id: "gpt-6-astra",
834
+ name: "GPT-6 Astra (Azure OpenAI)",
835
+ group: "other",
836
+ order: 2,
837
+ lifecycle: "unknown",
838
+ validation: "unverified",
839
+ capabilities: ["chat", "tools"],
840
+ reason: "Provisional Azure OpenAI model id. Account rollout and deployment availability are not verified. No live certification."
841
+ }
842
+ ]
771
843
  }
772
844
  ]
773
845
  };
@@ -830,13 +902,13 @@ var modelCatalogSchema = z.object({
830
902
  schemaVersion: z.literal(1),
831
903
  revision: z.string().min(1).max(80).regex(/^[a-zA-Z0-9._-]+$/),
832
904
  providers: z.array(z.object({
833
- id: z.enum(["openai", "qwen", "gemini", "meta", "anthropic", "vertex"]),
905
+ id: z.enum(["openai", "qwen", "gemini", "meta", "anthropic", "vertex", "bedrock", "azure-openai"]),
834
906
  defaultModel: modelId,
835
907
  models: z.array(catalogModelSchema).min(1).max(500)
836
- }).strict()).length(6)
908
+ }).strict()).length(8)
837
909
  }).strict().superRefine((catalog, ctx) => {
838
910
  const invalid = (message) => ctx.addIssue({ code: "custom", message });
839
- if (new Set(catalog.providers.map((p) => p.id)).size !== 6)
911
+ if (new Set(catalog.providers.map((p) => p.id)).size !== 8)
840
912
  invalid("Duplicate providers");
841
913
  for (const provider of catalog.providers) {
842
914
  const ids = new Set(provider.models.map((m) => m.id));