@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
@@ -1,137 +1,138 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- APPROVAL_HISTORY_KEY,
4
3
  ActivityHistory,
5
- CLI_CHANGES_COMMANDS,
6
- CLI_COMMANDS,
7
- CLI_JSON_SCHEMA_VERSION,
8
- CLI_RUNS_COMMANDS,
9
- CLI_SESSIONS_COMMANDS,
10
- CLI_STATE_COMMANDS,
11
4
  CliCredentials,
12
- CliOciRuntimeAdapter,
13
- CliUsageError,
14
5
  ConsoleInput,
15
6
  CredentialSetupError,
16
7
  DEFAULT_HARNESS_CONTEXT_MANIFEST,
17
- FileChangedWhileReadingError,
18
- FileSizeLimitError,
19
- HARNESS_OPERATIONS_SCHEMA_VERSION,
20
8
  HARNESS_RESUME_METADATA_KEY,
21
9
  HARNESS_RESUME_METADATA_SCHEMA_VERSION,
22
- HARNESS_SESSION_SCHEMA_VERSION,
23
- HARNESS_SQLITE_FILE,
24
10
  MAX_HARNESS_CONTEXT_FILE_BYTES,
25
11
  MAX_HARNESS_CONTEXT_TOTAL_BYTES,
26
- SqliteDatabase,
27
- TASK_ACCEPTANCE_EVIDENCE_KEY,
28
- TASK_SOURCE_KEY,
29
- USAGE_LEDGER_KEY,
30
- UnsafeFileTypeError,
31
- Workspace,
32
12
  annotateCliStreamError,
33
13
  appendUserMessage,
34
- applyCliProfile,
35
- approvalDecisionViews,
36
14
  approvalResponses,
37
15
  assertRoutePricingIsSafe,
38
- assertTaskBudgetBackupLinks,
39
- cancelHarnessRun,
40
- canonicalizeChangeEnvelope,
41
- changeEnvelopePreconditionsSchema,
42
- changeEnvelopeSchema,
43
16
  chooseReasoning,
44
- cleanupHarnessExecutionArtifacts,
45
- cleanupHarnessRuns,
46
17
  cliStreamErrorSequence,
47
18
  compactHarnessMessages,
48
- createChangeEnvelope,
49
- createCliProfile,
50
19
  createConfiguredHarness,
51
20
  createHarness,
52
21
  createHarnessResumeMetadata,
53
- createHarnessRouteModels,
54
22
  credentialModel,
55
23
  decodeProjectMemory,
56
- digestChangeEnvelopeArtifact,
57
24
  estimateMessages,
58
- fileDigestSchema,
59
25
  flushToolActivity,
60
26
  formatAppliedFiles,
61
27
  formatConsoleHelp,
62
28
  formatConsoleWelcome,
63
- formatUsageLedger,
64
29
  formatVerificationSummary,
65
30
  harnessConfigInput,
66
- harnessPolicyDecisionEventSchema,
67
- harnessToolExecution,
68
31
  inspectCliPolicy,
69
- inspectHarnessRun,
70
- inspectRuntimeDiagnostics,
71
- inspectRuntimeManifest,
72
- inspectUsageLedger,
73
32
  issueAutomaticApprovalResponses,
74
33
  issueObservedApprovalResponses,
75
- listHarnessRuns,
76
- loadCliProfile,
77
34
  loadHarnessMcpConfiguration,
78
35
  loadHarnessProjectContext,
79
36
  loadModelCatalog,
80
37
  navigateConsole,
81
38
  observeCliPolicy,
82
- openCliSessionStore,
83
- openHarnessActivityStore,
84
- openHarnessPersistence,
85
39
  openHarnessProjectMemory,
86
40
  openWorkspaceCheckpointStore,
87
41
  orchestrationObserver,
88
- parseCliArgs,
89
- parseHarnessModelRoute,
90
42
  persistedCliOptions,
91
43
  printTerminalResult,
92
44
  projectMemoryRecordKey,
93
- publishPendingPolicyDecision,
94
45
  readHarnessResumeConfig,
95
46
  readHarnessResumeRoutes,
96
- readRegularFileChunksNoFollow,
97
- readRegularFileNoFollow,
98
- readTaskAcceptanceLedger,
99
47
  requiresExplicitHostReview,
100
- resolveCliDefaults,
101
- resolveHarnessModelRoutes,
102
- resolvePackageManager,
103
48
  resolvedRouting,
104
49
  resumeCommand,
105
50
  runHarness,
106
51
  runHarnessReviewGroup,
107
- runPortableProcess,
108
52
  runResultDocument,
109
53
  sanitizeTerminalText,
110
- serializeHarnessModelRoutes,
111
- sqliteAdapter,
112
54
  streamSink,
113
55
  summarizeApproval,
114
- taskCheckReceiptSchema,
115
- taskSources,
116
56
  terminalApprovalResolver,
117
57
  terminalContinuationMessages,
118
58
  terminalErrorMessage,
119
59
  terminalRunFailure,
120
60
  terminalSupportsColor,
121
- updateCliProfile,
122
- validateStateDirectory,
123
- verifyChangeEnvelope,
124
61
  withTemporaryHarnessProfiles,
125
62
  workspaceCheckpointSchema,
126
63
  workspaceRestoreOperationSchema
127
- } from "./cli-entry-4ngptr62.js";
64
+ } from "./cli-entry-h2yc9x37.js";
65
+ import {
66
+ exportHarnessGovernanceReport,
67
+ renderHarnessGovernanceMarkdown
68
+ } from "./cli-entry-75j3r49b.js";
69
+ import {
70
+ BUDGET_LEDGER_NAMESPACE,
71
+ BUDGET_OWNER_NAMESPACE_KEY,
72
+ CLI_CHANGES_COMMANDS,
73
+ CLI_COMMANDS,
74
+ CLI_JSON_SCHEMA_VERSION,
75
+ CLI_RUNS_COMMANDS,
76
+ CLI_SESSIONS_COMMANDS,
77
+ CLI_STATE_COMMANDS,
78
+ CliOciRuntimeAdapter,
79
+ CliUsageError,
80
+ FileChangedWhileReadingError,
81
+ FileSizeLimitError,
82
+ HARNESS_OPERATIONS_SCHEMA_VERSION,
83
+ HARNESS_SESSION_SCHEMA_VERSION,
84
+ HARNESS_SQLITE_FILE,
85
+ SqliteDatabase,
86
+ TASK_SOURCE_KEY,
87
+ USAGE_LEDGER_KEY,
88
+ UnsafeFileTypeError,
89
+ Workspace,
90
+ applyCliProfile,
91
+ assertTaskBudgetBackupLinks,
92
+ budgetLedgerNamespace,
93
+ cancelHarnessRun,
94
+ canonicalizeChangeEnvelope,
95
+ changeEnvelopePreconditionsSchema,
96
+ cleanupHarnessExecutionArtifacts,
97
+ cleanupHarnessRuns,
98
+ createChangeEnvelope,
99
+ createCliProfile,
100
+ createHarnessRouteModels,
101
+ digestChangeEnvelopeArtifact,
102
+ fileDigestSchema,
103
+ formatUsageLedger,
104
+ harnessToolExecution,
105
+ inspectHarnessRun,
106
+ inspectRuntimeDiagnostics,
107
+ inspectUsageLedger,
108
+ listHarnessRuns,
109
+ loadCliProfile,
110
+ openCliSessionStore,
111
+ openHarnessActivityStore,
112
+ openHarnessPersistence,
113
+ parseCliArgs,
114
+ parseHarnessModelRoute,
115
+ publishPendingPolicyDecision,
116
+ readRegularFileChunksNoFollow,
117
+ readRegularFileNoFollow,
118
+ resolveCliDefaults,
119
+ resolveHarnessModelRoutes,
120
+ resolvePackageManager,
121
+ runPortableProcess,
122
+ serializeHarnessModelRoutes,
123
+ sqliteAdapter,
124
+ taskSources,
125
+ updateCliProfile,
126
+ validateStateDirectory,
127
+ verifyChangeEnvelope
128
+ } from "./cli-entry-928p8h41.js";
128
129
  import {
129
130
  BUN_ENGINE_RANGE,
130
131
  HARNESS_VERSION,
131
132
  NODE_ENGINE_RANGE,
132
133
  formatCliHelp,
133
134
  shortCliHelp
134
- } from "./cli-entry-w0hterjs.js";
135
+ } from "./cli-entry-q8bgkn9m.js";
135
136
  import {
136
137
  DEFAULT_PROVIDER_REGISTRY,
137
138
  HARNESS_SUBAGENT_PROFILES,
@@ -147,7 +148,7 @@ import {
147
148
  providerDescriptor,
148
149
  reasoningEffortSchema,
149
150
  resolveHarnessConfig
150
- } from "./cli-entry-20w6nh0k.js";
151
+ } from "./cli-entry-hdtfef27.js";
151
152
  import {
152
153
  __require
153
154
  } from "./cli-entry-1bx83sw4.js";
@@ -237,7 +238,7 @@ var initializeCli = async (options, context = {}) => {
237
238
  process.stdout.write([
238
239
  `${options.updateProfile ? "Updated" : "Created"} personal profile ${profileName} at ${created.path}.`,
239
240
  `Provider: ${created.profile.provider} · Model: ${created.profile.model} · Reasoning: ${created.profile.reasoningEffort ?? "default"}`,
240
- provider === "vertex" ? "Vertex uses host ADC. Set GOOGLE_CLOUD_PROJECT and VERTEX_LOCATION; route presence does not verify credentials or model access." : availability?.configured ? "Provider credential detected; no secret value was stored or printed." : `Open zhx to configure a managed key, or set ${availability?.credentialNames.join(" or ") || "the provider credential"} for automation.`,
241
+ provider === "vertex" ? "Vertex uses host ADC. Set GOOGLE_CLOUD_PROJECT and VERTEX_LOCATION; route presence does not verify credentials or model access." : provider === "bedrock" ? "Bedrock Converse uses the AWS credential chain and AWS_REGION or AWS_DEFAULT_REGION. BEDROCK_RUNTIME=openai also needs an https BEDROCK_OPENAI_BASE_URL and BEDROCK_API_KEY or AWS_BEARER_TOKEN_BEDROCK. Route presence does not verify credentials or model access." : provider === "azure-openai" ? "Azure OpenAI needs an https AZURE_OPENAI_ENDPOINT and AZURE_OPENAI_API_KEY. Optional AZURE_OPENAI_API_VERSION and AZURE_OPENAI_DEPLOYMENTS stay in the environment. Route presence does not verify account access." : availability?.configured ? "Provider credential detected; no secret value was stored or printed." : `Open zhx to configure a managed key, or set ${availability?.credentialNames.join(" or ") || "the provider credential"} for automation.`,
241
242
  "Next:",
242
243
  ` ${doctorCommand}`,
243
244
  ` ${runCommand}`,
@@ -247,6 +248,31 @@ var initializeCli = async (options, context = {}) => {
247
248
  `);
248
249
  return true;
249
250
  };
251
+ var providerStatus = (provider, env = process.env) => {
252
+ if (provider.id === "vertex")
253
+ return provider.configured ? "route configured; ADC not checked" : "missing GOOGLE_CLOUD_PROJECT/VERTEX_LOCATION";
254
+ if (provider.id === "bedrock") {
255
+ if (provider.configuration.runtimeValid === false)
256
+ return "invalid BEDROCK_RUNTIME";
257
+ if (provider.configured)
258
+ return "route configured; AWS credentials not checked";
259
+ if (env.BEDROCK_RUNTIME?.trim() === "openai")
260
+ return "missing BEDROCK_API_KEY/AWS_BEARER_TOKEN_BEDROCK or https BEDROCK_OPENAI_BASE_URL";
261
+ return "missing AWS_REGION/AWS_DEFAULT_REGION";
262
+ }
263
+ if (provider.id === "azure-openai") {
264
+ if (!provider.configuration.customEndpoint)
265
+ return "missing AZURE_OPENAI_ENDPOINT";
266
+ if (!provider.configuration.endpointValid || !provider.configuration.endpointSecure)
267
+ return "invalid AZURE_OPENAI_ENDPOINT";
268
+ if (!provider.credentials.some((credential) => credential.present))
269
+ return "missing AZURE_OPENAI_API_KEY";
270
+ if (!provider.configured)
271
+ return "invalid AZURE_OPENAI_API_VERSION or AZURE_OPENAI_DEPLOYMENTS";
272
+ return "configured; account access not checked";
273
+ }
274
+ return provider.configured ? "configured" : `missing ${provider.credentialNames.join("/")}`;
275
+ };
250
276
  var listProviders = (json) => {
251
277
  const document = providersDocument();
252
278
  if (json) {
@@ -255,7 +281,7 @@ var listProviders = (json) => {
255
281
  return;
256
282
  }
257
283
  for (const provider of document.providers) {
258
- process.stdout.write(`${provider.id.padEnd(7)} ${provider.defaultModel.padEnd(22)} ${provider.support.padEnd(11)} ${provider.id === "vertex" ? provider.configured ? "route configured; ADC not checked" : "missing GOOGLE_CLOUD_PROJECT/VERTEX_LOCATION" : provider.configured ? "configured" : `missing ${provider.credentialNames.join("/")}`}
284
+ process.stdout.write(`${provider.id.padEnd(13)} ${provider.defaultModel.padEnd(28)} ${provider.support.padEnd(11)} ${providerStatus(provider)}
259
285
  `);
260
286
  }
261
287
  };
@@ -299,6 +325,8 @@ Advanced operations and automation:
299
325
  zhx state status
300
326
  zhx state export <backup.json>
301
327
  zhx state import <backup.json> [--apply]
328
+ zhx export-audit <task-id> --out <directory>
329
+ zhx verify-audit --out <directory>
302
330
 
303
331
  The long command zhivex-harness remains supported for compatibility.
304
332
 
@@ -378,6 +406,8 @@ Options (automation and advanced configuration):
378
406
  --cascade Cancel a run and its known child runs
379
407
  --final Record terminal cancellation immediately
380
408
  --apply Apply a validated state import (default: dry-run)
409
+ --out <directory> Audit pack directory (export-audit, verify-audit)
410
+ --signing-key-file <path> HMAC key file for an audit pack
381
411
  -h, --help Show this help
382
412
  -v, --version Show the version
383
413
 
@@ -758,6 +788,32 @@ var inspectProjectContext = async (config) => {
758
788
  });
759
789
  }
760
790
  };
791
+ var bedrockDoctorMessage = (provider, configured, env) => {
792
+ if (provider.configuration.runtimeValid === false)
793
+ return "BEDROCK_RUNTIME must be converse or openai.";
794
+ if (provider.configuration.customEndpoint && (!provider.configuration.endpointValid || !provider.configuration.endpointSecure)) {
795
+ return "BEDROCK_OPENAI_BASE_URL must be an https URL without credentials.";
796
+ }
797
+ if (configured)
798
+ return "Amazon Bedrock route configured; AWS credentials and model access have not been checked. Live support is provisional.";
799
+ if (env.BEDROCK_RUNTIME?.trim() === "openai") {
800
+ return "Bedrock OpenAI-compatible runtime requires BEDROCK_API_KEY or AWS_BEARER_TOKEN_BEDROCK and an https BEDROCK_OPENAI_BASE_URL.";
801
+ }
802
+ return "Bedrock Converse requires a valid AWS_REGION or AWS_DEFAULT_REGION. No API key is stored for the AWS credential chain.";
803
+ };
804
+ var azureDoctorMessage = (provider, configured, credential) => {
805
+ if (!provider.configuration.customEndpoint)
806
+ return "Azure OpenAI requires AZURE_OPENAI_ENDPOINT.";
807
+ if (!provider.configuration.endpointValid || !provider.configuration.endpointSecure) {
808
+ return "AZURE_OPENAI_ENDPOINT must be an https URL without credentials or a query.";
809
+ }
810
+ if (!configured && (provider.credentials.some((item) => item.present) || credential?.configured)) {
811
+ return "AZURE_OPENAI_API_VERSION or AZURE_OPENAI_DEPLOYMENTS is invalid.";
812
+ }
813
+ if (!configured)
814
+ return "Azure OpenAI credential is missing. Set AZURE_OPENAI_API_KEY. Account access is not checked.";
815
+ return "Azure OpenAI route configured; account access has not been checked. Live support is provisional.";
816
+ };
761
817
  var createDoctorReport = async (options = {}, context = {}) => {
762
818
  const env = context.env ?? process.env;
763
819
  const config = resolveHarnessConfig({
@@ -824,12 +880,13 @@ var createDoctorReport = async (options = {}, context = {}) => {
824
880
  checks.push(await inspectExecutionEnvironment(config.execution, context.ociRuntimeAdapter));
825
881
  for (const provider of providers) {
826
882
  const invalidRegion = provider.id === "qwen" && provider.configuration.regionValid === false;
827
- const invalidEndpoint = !provider.configuration.endpointValid;
883
+ const invalidRuntime = provider.id === "bedrock" && provider.configuration.runtimeValid === false;
884
+ const invalidEndpoint = !provider.configuration.endpointValid || (provider.id === "bedrock" || provider.id === "azure-openai") && provider.configuration.customEndpoint && !provider.configuration.endpointSecure;
828
885
  const selected = provider.id === selectedProvider?.id;
829
886
  const credential = selected ? context.credentialStatus : undefined;
830
887
  const configured = credential?.configured ?? provider.configured;
831
- const status = invalidRegion || invalidEndpoint || !configured ? selected ? "fail" : "warn" : provider.support === "provisional" ? "warn" : "pass";
832
- const message = provider.id === "vertex" ? configured ? "Vertex project/location configured; host ADC and model access have not been checked. Live support is provisional." : "Vertex requires GOOGLE_CLOUD_PROJECT and VERTEX_LOCATION plus host Application Default Credentials. No API key is stored by zhx." : invalidEndpoint ? `${provider.name} custom endpoint configuration is invalid.` : invalidRegion ? "Qwen region configuration is invalid." : credential ? credential.configured ? `${provider.name} credential present (${credential.source}); account access has not been checked.${provider.support === "provisional" ? " Live support is provisional." : ""}` : credential.source === "blocked" ? `${provider.name} managed credentials require the default endpoint. Remove endpoint overrides or provide an environment key.` : `${provider.name} credential ${credential.source === "unavailable" ? "could not be checked: keychain unavailable or locked" : "is missing"}. Run zhx to configure a key, or set ${provider.credentialNames.join(" or ")} for automation.` : provider.configured ? provider.support === "provisional" ? `${provider.name} credentials are present, but live support is provisional.` : `${provider.name} credentials are present.` : `${provider.name} credentials are missing. Set ${provider.credentialNames.join(" or ")} in the environment and rerun zhx doctor.`;
888
+ const status = invalidRegion || invalidRuntime || invalidEndpoint || !configured ? selected ? "fail" : "warn" : provider.support === "provisional" ? "warn" : "pass";
889
+ const message = provider.id === "vertex" ? configured ? "Vertex project/location configured; host ADC and model access have not been checked. Live support is provisional." : "Vertex requires GOOGLE_CLOUD_PROJECT and VERTEX_LOCATION plus host Application Default Credentials. No API key is stored by zhx." : provider.id === "bedrock" ? bedrockDoctorMessage(provider, configured, env) : provider.id === "azure-openai" ? azureDoctorMessage(provider, configured, credential) : invalidEndpoint ? `${provider.name} custom endpoint configuration is invalid.` : invalidRegion ? "Qwen region configuration is invalid." : credential ? credential.configured ? `${provider.name} credential present (${credential.source}); account access has not been checked.${provider.support === "provisional" ? " Live support is provisional." : ""}` : credential.source === "blocked" ? `${provider.name} managed credentials require the default endpoint. Remove endpoint overrides or provide an environment key.` : `${provider.name} credential ${credential.source === "unavailable" ? "could not be checked: keychain unavailable or locked" : "is missing"}. Run zhx to configure a key, or set ${provider.credentialNames.join(" or ")} for automation.` : provider.configured ? provider.support === "provisional" ? `${provider.name} credentials are present, but live support is provisional.` : `${provider.name} credentials are present.` : `${provider.name} credentials are missing. Set ${provider.credentialNames.join(" or ")} in the environment and rerun zhx doctor.`;
833
890
  checks.push(diagnostic(`provider:${provider.id}`, status, message, {
834
891
  provider: provider.id,
835
892
  selected,
@@ -845,6 +902,17 @@ var createDoctorReport = async (options = {}, context = {}) => {
845
902
  regionConfigured: provider.configuration.regionConfigured,
846
903
  regionValid: provider.configuration.regionValid,
847
904
  workspaceIdConfigured: provider.configuration.workspaceIdConfigured
905
+ } : {},
906
+ ...provider.id === "bedrock" ? {
907
+ runtimeConfigured: provider.configuration.runtimeConfigured === true,
908
+ runtimeValid: provider.configuration.runtimeValid !== false,
909
+ regionConfigured: provider.configuration.regionConfigured === true,
910
+ defaultRegionConfigured: provider.configuration.defaultRegionConfigured === true,
911
+ profileConfigured: provider.configuration.profileConfigured === true
912
+ } : {},
913
+ ...provider.id === "azure-openai" ? {
914
+ apiVersionConfigured: provider.configuration.apiVersionConfigured === true,
915
+ deploymentsConfigured: provider.configuration.deploymentsConfigured === true
848
916
  } : {}
849
917
  }));
850
918
  }
@@ -1383,7 +1451,7 @@ async function handleConsoleCompaction(command, deps) {
1383
1451
  const provider = value.slice(0, separator);
1384
1452
  const model = value.slice(separator + 1);
1385
1453
  if (separator < 1 || !PROVIDERS.includes(provider) || !/^[a-zA-Z0-9][a-zA-Z0-9._:/-]{0,159}$/.test(model)) {
1386
- write("Use /compaction provider:model with openai, qwen, gemini, meta, anthropic or vertex; /compaction off disables model-assisted compaction.");
1454
+ write(`Use /compaction provider:model with ${PROVIDERS.slice(0, -1).join(", ")} or ${PROVIDERS.at(-1)}; /compaction off disables model-assisted compaction.`);
1387
1455
  return true;
1388
1456
  }
1389
1457
  await deps.replaceOptions({ ...deps.options, compactionProvider: provider, compactionModel: model });
@@ -2493,474 +2561,6 @@ ${summarizeApproval(approval)}
2493
2561
 
2494
2562
  // src/cli/governance-report.ts
2495
2563
  import path2 from "node:path";
2496
-
2497
- // src/persistence/governance-report.ts
2498
- import { createHash as createHash3 } from "node:crypto";
2499
- import { z as z2 } from "zod";
2500
-
2501
- // src/persistence/governance-context.ts
2502
- import { createHash as createHash2 } from "node:crypto";
2503
- import { z } from "zod";
2504
- var digest = z.string().regex(/^sha256:[a-f0-9]{64}$/);
2505
- var count = z.number().int().nonnegative().safe();
2506
- var governanceReference = (kind, value) => "sha256:" + createHash2("sha256").update(JSON.stringify([kind, value])).digest("hex");
2507
- var governanceSessionSchema = z.strictObject({ availability: z.enum(["recorded", "unavailable"]), reference: digest.nullable(), revision: count.nullable() });
2508
- var governanceHistorySchema = z.strictObject({
2509
- availability: z.enum(["recorded", "unavailable"]),
2510
- retention: z.enum(["unknown", "retained", "expired"]),
2511
- incomplete: z.boolean(),
2512
- policyDecisions: z.array(z.strictObject({
2513
- runReference: digest,
2514
- sequence: count,
2515
- toolReference: digest,
2516
- phase: z.enum(["approval-request", "tool-entry"]),
2517
- decision: z.enum(["allow", "ask_user", "deny"]),
2518
- policyDigest: digest.nullable(),
2519
- source: z.enum(["operator-file", "application", "baseline"]),
2520
- ruleReferences: z.array(digest).max(128),
2521
- explicitReviewRequired: z.boolean()
2522
- })).max(512)
2523
- });
2524
- var governanceEnvelopeSchema = z.strictObject({
2525
- source: z.literal("caller-supplied"),
2526
- envelopeId: digest.nullable(),
2527
- patchReference: digest.nullable(),
2528
- patchDigest: digest.nullable(),
2529
- linkedRunReferences: z.array(digest).max(64),
2530
- schemaValid: z.boolean(),
2531
- integrity: z.enum(["valid", "invalid"]),
2532
- expiration: z.enum(["unknown", "current", "expired", "not-yet-valid"]),
2533
- checkedAt: z.iso.datetime(),
2534
- expiredApprovals: count,
2535
- authenticity: z.literal("not-verified"),
2536
- patchBytes: z.literal("not-verified")
2537
- });
2538
- async function readGovernanceSession(source, rootRunId, runIds) {
2539
- const session = { availability: "unavailable", reference: null, revision: null };
2540
- const history = { availability: "unavailable", retention: "unknown", incomplete: true, policyDecisions: [] };
2541
- if (!source)
2542
- return { session, history, verify: async () => {} };
2543
- const initial = await source.index.get(source.id);
2544
- if (!initial || initial.sessionId !== source.id || !initial.runs.some((run) => run.runId === rootRunId))
2545
- throw new Error("GOVERNANCE_SESSION_MISMATCH");
2546
- const captured = JSON.stringify(initial);
2547
- session.availability = "recorded";
2548
- session.reference = governanceReference("session", initial.sessionId);
2549
- session.revision = initial.revision;
2550
- const pages = [];
2551
- if (source.history) {
2552
- let cursor = 0;
2553
- history.availability = "recorded";
2554
- history.retention = "retained";
2555
- history.incomplete = false;
2556
- for (let pageIndex = 0;pageIndex < 50; pageIndex++) {
2557
- const page = source.history.replay(source.id, cursor);
2558
- pages.push({ cursor, digest: governanceReference("history-page", JSON.stringify(page)) });
2559
- if (page.schemaVersion !== 1 || !Number.isSafeInteger(page.nextCursor) || page.nextCursor < cursor || page.events.length > 200)
2560
- throw new Error("GOVERNANCE_HISTORY_INVALID");
2561
- if (page.cursorExpired || page.policyEvidenceIncomplete) {
2562
- history.retention = "expired";
2563
- history.incomplete = true;
2564
- }
2565
- let lastSequence = cursor;
2566
- for (const event of page.events) {
2567
- if (event.sessionId !== source.id || !Number.isSafeInteger(event.sequence) || event.sequence <= lastSequence || event.sequence > page.nextCursor)
2568
- throw new Error("GOVERNANCE_HISTORY_INVALID");
2569
- lastSequence = event.sequence;
2570
- if (!runIds.has(event.runId) || event.activity.type !== "policy-decision")
2571
- continue;
2572
- const parsed = harnessPolicyDecisionEventSchema.safeParse(event.activity);
2573
- if (!parsed.success) {
2574
- history.incomplete = true;
2575
- continue;
2576
- }
2577
- if (history.policyDecisions.length === 512) {
2578
- history.incomplete = true;
2579
- continue;
2580
- }
2581
- const value = parsed.data;
2582
- history.policyDecisions.push({
2583
- runReference: governanceReference("run", event.runId),
2584
- sequence: event.sequence,
2585
- toolReference: governanceReference("tool", value.toolName),
2586
- phase: value.phase,
2587
- decision: value.decision,
2588
- policyDigest: value.policyDigest,
2589
- source: value.source,
2590
- ruleReferences: value.ruleIds.map((rule) => governanceReference("rule", rule)),
2591
- explicitReviewRequired: value.explicitReviewRequired
2592
- });
2593
- }
2594
- if (page.cursorExpired || !page.hasMore)
2595
- break;
2596
- if (page.nextCursor === cursor)
2597
- throw new Error("GOVERNANCE_HISTORY_INVALID");
2598
- cursor = page.nextCursor;
2599
- if (pageIndex === 49)
2600
- history.incomplete = true;
2601
- }
2602
- }
2603
- return { session, history, verify: async () => {
2604
- for (const page of pages)
2605
- if (governanceReference("history-page", JSON.stringify(source.history.replay(source.id, page.cursor))) !== page.digest)
2606
- throw new Error("GOVERNANCE_STATE_CHANGED");
2607
- if (JSON.stringify(await source.index.get(source.id)) !== captured)
2608
- throw new Error("GOVERNANCE_STATE_CHANGED");
2609
- } };
2610
- }
2611
- function projectGovernanceEnvelopes(envelopes, patches, now) {
2612
- if (envelopes.length > 32)
2613
- throw new Error("GOVERNANCE_ENVELOPE_LIMIT");
2614
- return envelopes.map((input) => {
2615
- if (Buffer.byteLength(JSON.stringify(input) ?? "") > 256 * 1024)
2616
- throw new Error("GOVERNANCE_ENVELOPE_LIMIT");
2617
- const parsed = changeEnvelopeSchema.safeParse(input);
2618
- const proof = verifyChangeEnvelope(input, { now });
2619
- const envelope = parsed.success ? parsed.data : undefined;
2620
- return governanceEnvelopeSchema.parse({
2621
- source: "caller-supplied",
2622
- envelopeId: envelope?.envelopeId ?? null,
2623
- patchReference: envelope ? governanceReference("patch", envelope.patch.patchId) : null,
2624
- patchDigest: envelope?.patch.patchDigest ?? null,
2625
- linkedRunReferences: envelope ? [...patches.get(envelope.patch.patchId) ?? []] : [],
2626
- schemaValid: parsed.success,
2627
- integrity: proof.integrity.envelopeDigestValid && proof.integrity.evidenceDigestValid ? "valid" : "invalid",
2628
- expiration: !envelope ? "unknown" : proof.expiration.envelopeNotYetValid ? "not-yet-valid" : proof.expiration.envelopeExpired ? "expired" : "current",
2629
- checkedAt: proof.expiration.checkedAt,
2630
- expiredApprovals: proof.expiration.expiredApprovalIds.length,
2631
- authenticity: "not-verified",
2632
- patchBytes: "not-verified"
2633
- });
2634
- });
2635
- }
2636
-
2637
- // src/persistence/governance-report.ts
2638
- var digest2 = z2.string().regex(/^sha256:[a-f0-9]{64}$/);
2639
- var version = z2.string().regex(/^\d+\.\d+\.\d+(?:[-+][a-zA-Z0-9.-]+)?$/);
2640
- var bindingSchema = z2.object({ schemaVersion: z2.literal(1), id: z2.literal("zhivex-harness"), version, fingerprint: digest2, algorithm: z2.literal("sha256") });
2641
- var count2 = z2.number().int().nonnegative().safe();
2642
- var status = z2.enum(["created", "running", "waiting_approval", "cancel_requested", "completed", "failed", "cancelled", "timed_out", "unknown"]);
2643
- var availability = z2.enum(["recorded", "unavailable", "invalid"]);
2644
- var providerReason = z2.enum(["empty_arguments", "invalid_json", "arguments_too_large", "incomplete_arguments", "inconsistent_metadata", "response_failed", "response_incomplete", "stream_truncated"]);
2645
- 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"]);
2646
- var deliveryStatus = z2.enum(["pending", "incomplete", "failed", "pending_review", "verified", "unknown"]);
2647
- var checkSchema = z2.strictObject({
2648
- reference: digest2,
2649
- argvDigest: digest2,
2650
- patchId: digest2,
2651
- snapshotDigest: digest2,
2652
- exitCode: z2.number().int(),
2653
- timedOut: z2.boolean(),
2654
- unchanged: z2.boolean()
2655
- });
2656
- var deliverySchema = z2.object({
2657
- schemaVersion: z2.literal(1),
2658
- contractRevision: count2,
2659
- contractDigest: digest2,
2660
- status: deliveryStatus,
2661
- checks: z2.array(taskCheckReceiptSchema).max(32),
2662
- delivery: z2.object({ runId: z2.string().max(512), executionIdentity: z2.string().max(512), patchId: digest2, snapshotDigest: digest2 }).optional()
2663
- });
2664
- var approvalSchema = z2.strictObject({
2665
- reference: digest2,
2666
- toolReference: digest2,
2667
- approved: z2.boolean(),
2668
- origin: z2.enum(["interactive", "automatic", "application", "unknown"]),
2669
- channelReference: digest2,
2670
- policyDigest: digest2.nullable(),
2671
- status: z2.enum(["rejected", "approved", "applied", "succeeded", "failed", "unknown"]),
2672
- proposalId: digest2.nullable(),
2673
- exitCode: z2.number().int().nullable(),
2674
- timedOut: z2.boolean().nullable(),
2675
- effects: z2.array(z2.strictObject({ pathReference: digest2, beforeDigest: digest2.nullable(), afterDigest: digest2.nullable() })).max(50)
2676
- });
2677
- 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"]);
2678
- var delegationSchema = z2.strictObject({
2679
- taskReference: digest2,
2680
- childReference: digest2.nullable(),
2681
- recordedAcceptance: z2.boolean(),
2682
- reason: delegationReason,
2683
- semanticReview: z2.enum(["pending", "not_requested"]),
2684
- correctionsUsed: count2.nullable()
2685
- });
2686
- var delegationInput = z2.object({ schemaVersion: z2.literal(1), evaluations: z2.array(z2.object({
2687
- taskId: z2.string().max(128),
2688
- childRunId: z2.string().max(512).nullable(),
2689
- childStatus: z2.string().max(32),
2690
- accepted: z2.boolean(),
2691
- reason: delegationReason,
2692
- semanticReview: z2.enum(["pending", "not_requested"]),
2693
- correctionsUsed: count2.optional()
2694
- })).max(64) });
2695
- var runSchema = z2.strictObject({
2696
- reference: digest2,
2697
- parentReference: digest2.nullable(),
2698
- revision: count2.nullable(),
2699
- status,
2700
- finalized: z2.boolean(),
2701
- failure: z2.enum(["run_failed", "cancelled", "timed_out", "not_reported"]).nullable(),
2702
- failureDetails: z2.strictObject({ providerToolReason: providerReason.nullable(), diagnosticReference: digest2.nullable(), deliveryReason: deliveryReason.nullable() }),
2703
- identity: z2.literal("not-verified"),
2704
- runtimePolicy: z2.enum(["assistant-v3-durable-closure"]).nullable(),
2705
- contract: z2.strictObject({
2706
- availability,
2707
- digest: digest2.nullable(),
2708
- revision: count2.nullable(),
2709
- requiredChecks: count2.nullable(),
2710
- humanReviewsPending: count2.nullable(),
2711
- allowedWritePathReferences: z2.array(digest2).max(256),
2712
- protectedPathReferences: z2.array(digest2).max(256),
2713
- 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),
2714
- humanReviewReferences: z2.array(digest2).max(32)
2715
- }),
2716
- delivery: z2.strictObject({
2717
- availability,
2718
- status: deliveryStatus,
2719
- patchId: digest2.nullable(),
2720
- snapshotDigest: digest2.nullable(),
2721
- interpretation: z2.literal("recorded-checkpoint-not-current-workspace-verification"),
2722
- checks: z2.array(checkSchema).max(32)
2723
- }),
2724
- approvals: z2.strictObject({ availability, items: z2.array(approvalSchema).max(512) }),
2725
- usage: z2.strictObject({
2726
- availability: z2.enum(["recorded", "unavailable"]),
2727
- calls: count2.nullable(),
2728
- inputTokens: count2.nullable(),
2729
- outputTokens: count2.nullable(),
2730
- complete: z2.boolean().nullable(),
2731
- estimatedUsd: z2.number().finite().nonnegative().nullable(),
2732
- costKind: z2.literal("estimate-not-invoice")
2733
- }),
2734
- journal: z2.strictObject({ availability: z2.enum(["recorded", "unavailable"]), entries: count2, failed: count2, unfinished: count2 }),
2735
- delegations: z2.strictObject({ availability, interpretation: z2.literal("recorded-checkpoint-not-semantic-review"), items: z2.array(delegationSchema).max(64) }),
2736
- children: z2.array(digest2).max(64)
2737
- });
2738
- var harnessGovernanceReportSchema = z2.strictObject({
2739
- schemaVersion: z2.literal(1),
2740
- kind: z2.literal("harness-governance-report"),
2741
- exporterVersion: z2.string().regex(/^\d+\.\d+\.\d+(?:[-+][a-zA-Z0-9.-]+)?$/),
2742
- executionArtifact: z2.strictObject({ version: version.nullable(), digest: z2.null(), availability: z2.enum(["recorded-version", "unavailable"]), configurationFingerprint: digest2.nullable(), authenticity: z2.literal("not-verified") }),
2743
- rootReference: digest2,
2744
- identity: z2.literal("not-verified"),
2745
- referencePolicy: z2.literal("sha256-domain-separated-pseudonyms-not-anonymity"),
2746
- session: governanceSessionSchema,
2747
- eventHistory: governanceHistorySchema,
2748
- changeEnvelopes: z2.array(governanceEnvelopeSchema).max(32),
2749
- runs: z2.array(runSchema).max(64),
2750
- missingChildren: z2.array(digest2).max(64),
2751
- limitations: z2.array(z2.enum(["tree_limit", "missing_child", "invalid_contract", "invalid_delivery", "invalid_approvals", "journal_unavailable"])).max(6)
2752
- });
2753
- var MAX_JOURNAL = 2048;
2754
- var MAX_REPORT_BYTES = 2 * 1024 * 1024;
2755
- var sameScope = (state, scope) => !state.scope || state.scope.tenantId === scope?.tenantId && state.scope.userId === scope?.userId && state.scope.namespace === scope?.namespace;
2756
- function projectRun(state, journal, limitations) {
2757
- const runStatus = status.safeParse(state.status);
2758
- const stateStatus = runStatus.success ? runStatus.data : "unknown";
2759
- let ledger;
2760
- let contractAvailability = "unavailable";
2761
- try {
2762
- ledger = readTaskAcceptanceLedger(state);
2763
- if (ledger)
2764
- contractAvailability = "recorded";
2765
- } catch {
2766
- contractAvailability = "invalid";
2767
- limitations.add("invalid_contract");
2768
- }
2769
- const contract = ledger?.revisions.at(-1);
2770
- const rawDelivery = state.metadata?.[TASK_ACCEPTANCE_EVIDENCE_KEY];
2771
- const parsedDelivery = deliverySchema.safeParse(rawDelivery);
2772
- const bound = parsedDelivery.success && contract && parsedDelivery.data.contractDigest === contract.digest && parsedDelivery.data.contractRevision === contract.revision && (!parsedDelivery.data.delivery || parsedDelivery.data.delivery.runId === state.runId);
2773
- const candidate = bound ? parsedDelivery.data : undefined;
2774
- const verified = candidate?.status === "verified" || candidate?.status === "pending_review";
2775
- 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:" + createHash3("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;
2776
- const delivery = validSuccess ? candidate : undefined;
2777
- if (rawDelivery !== undefined && !delivery)
2778
- limitations.add("invalid_delivery");
2779
- const approvals = { availability: state.metadata?.[APPROVAL_HISTORY_KEY] === undefined ? "unavailable" : "recorded", items: [] };
2780
- try {
2781
- for (let offset = 0;offset < 512; offset += 25) {
2782
- const rows = approvalDecisionViews(state, journal ?? [], offset);
2783
- for (const row of rows)
2784
- approvals.items.push({
2785
- reference: governanceReference("approval", row.approvalId),
2786
- toolReference: governanceReference("tool", row.name),
2787
- approved: row.approved,
2788
- origin: row.provenance?.origin ?? "unknown",
2789
- channelReference: governanceReference("channel", row.provenance?.channel ?? "unknown"),
2790
- policyDigest: row.provenance?.policyDigest ?? null,
2791
- status: row.status,
2792
- proposalId: row.evidence?.proposalId ?? null,
2793
- exitCode: row.evidence?.exitCode ?? null,
2794
- timedOut: row.evidence?.timedOut ?? null,
2795
- effects: (row.evidence?.effects ?? []).map((effect) => ({ pathReference: governanceReference("path", effect.path), beforeDigest: effect.beforeDigest, afterDigest: effect.afterDigest }))
2796
- });
2797
- if (rows.length < 25)
2798
- break;
2799
- }
2800
- } catch {
2801
- approvals.availability = "invalid";
2802
- approvals.items = [];
2803
- limitations.add("invalid_approvals");
2804
- }
2805
- const parsedUsage = inspectUsageLedger(state.metadata?.[USAGE_LEDGER_KEY]);
2806
- const usage = parsedUsage?.runId === state.runId ? parsedUsage : null;
2807
- const rawDelegations = state.metadata?.zhivexDelegationAcceptanceV1;
2808
- const delegations = delegationInput.safeParse(rawDelegations);
2809
- const manifest = inspectRuntimeManifest(state.metadata?.effectiveRuntime);
2810
- return {
2811
- reference: governanceReference("run", state.runId),
2812
- parentReference: state.parentRunId ? governanceReference("run", state.parentRunId) : null,
2813
- revision: count2.safeParse(state.revision).success ? state.revision : null,
2814
- status: stateStatus,
2815
- finalized: ["completed", "failed", "cancelled", "timed_out"].includes(stateStatus),
2816
- failure: stateStatus === "failed" ? "run_failed" : stateStatus === "cancelled" ? "cancelled" : stateStatus === "timed_out" ? "timed_out" : state.error ? "not_reported" : null,
2817
- failureDetails: {
2818
- providerToolReason: providerReason.safeParse(state.error?.reason).success ? state.error.reason : null,
2819
- diagnosticReference: state.error?.diagnosticCode ? governanceReference("diagnostic", state.error.diagnosticCode) : null,
2820
- deliveryReason: deliveryReason.safeParse(rawDelivery && typeof rawDelivery === "object" && !Array.isArray(rawDelivery) ? rawDelivery.reason : undefined).success ? rawDelivery.reason : null
2821
- },
2822
- identity: "not-verified",
2823
- runtimePolicy: manifest?.policyVersion ?? null,
2824
- contract: {
2825
- availability: contractAvailability,
2826
- digest: contract?.digest ?? null,
2827
- revision: contract?.revision ?? null,
2828
- requiredChecks: contract?.contract.requiredChecks.length ?? null,
2829
- humanReviewsPending: contract?.contract.humanReview.length ?? null,
2830
- allowedWritePathReferences: contract?.contract.allowedWritePaths.map((file) => governanceReference("path", file)) ?? [],
2831
- protectedPathReferences: contract?.contract.protectedFiles.map((file) => governanceReference("path", file)) ?? [],
2832
- checks: contract?.contract.requiredChecks.map((check) => ({ reference: governanceReference("check", check.id), argvDigest: "sha256:" + createHash3("sha256").update(JSON.stringify([check.command, ...check.args])).digest("hex"), kind: check.kind, backend: check.execution.backend, approval: check.execution.approval })) ?? [],
2833
- humanReviewReferences: contract?.contract.humanReview.map((review) => governanceReference("review", review.id)) ?? []
2834
- },
2835
- delivery: {
2836
- availability: delivery ? "recorded" : rawDelivery === undefined ? "unavailable" : "invalid",
2837
- status: delivery?.status ?? "unknown",
2838
- patchId: delivery?.delivery?.patchId ?? null,
2839
- snapshotDigest: delivery?.delivery?.snapshotDigest ?? null,
2840
- interpretation: "recorded-checkpoint-not-current-workspace-verification",
2841
- 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 }))
2842
- },
2843
- approvals,
2844
- usage: {
2845
- availability: usage ? "recorded" : "unavailable",
2846
- calls: usage?.calls ?? null,
2847
- inputTokens: usage?.inputTokens ?? null,
2848
- outputTokens: usage?.outputTokens ?? null,
2849
- complete: usage?.usageComplete ?? null,
2850
- estimatedUsd: usage?.estimatedUsd ?? null,
2851
- costKind: "estimate-not-invoice"
2852
- },
2853
- journal: {
2854
- availability: journal ? "recorded" : "unavailable",
2855
- entries: journal?.length ?? 0,
2856
- failed: journal?.filter((entry) => entry.status === "failed").length ?? 0,
2857
- unfinished: journal?.filter((entry) => entry.status !== "completed" && entry.status !== "failed").length ?? 0
2858
- },
2859
- delegations: {
2860
- availability: rawDelegations === undefined ? "unavailable" : delegations.success ? "recorded" : "invalid",
2861
- interpretation: "recorded-checkpoint-not-semantic-review",
2862
- items: delegations.success ? delegations.data.evaluations.map((item) => ({
2863
- taskReference: governanceReference("task", item.taskId),
2864
- childReference: item.childRunId ? governanceReference("run", item.childRunId) : null,
2865
- recordedAcceptance: item.accepted,
2866
- reason: item.reason,
2867
- semanticReview: item.semanticReview,
2868
- correctionsUsed: item.correctionsUsed ?? null
2869
- })) : []
2870
- },
2871
- children: (state.childRuns ?? []).slice(0, 64).map((child) => governanceReference("run", child.runId))
2872
- };
2873
- }
2874
- async function exportHarnessGovernanceReport(store, scope, runId, options = {}) {
2875
- const limitations = new Set;
2876
- const runs = [], missingChildren = [];
2877
- const observed = [];
2878
- const queue = [{ id: runId }], seen = new Set;
2879
- while (queue.length && runs.length + missingChildren.length < 64) {
2880
- const item = queue.shift();
2881
- if (seen.has(item.id))
2882
- continue;
2883
- seen.add(item.id);
2884
- const loaded = await store.load(item.id, scope);
2885
- const state = loaded ? structuredClone(loaded) : undefined;
2886
- if (!state || state.runId !== item.id || !sameScope(state, scope) || item.parent !== undefined && state.parentRunId !== item.parent) {
2887
- if (item.parent === undefined)
2888
- throw new Error("GOVERNANCE_RUN_UNAVAILABLE");
2889
- missingChildren.push(governanceReference("run", item.id));
2890
- limitations.add("missing_child");
2891
- continue;
2892
- }
2893
- const loadedJournal = await store.listToolCalls?.(state.runId, scope);
2894
- const journal = loadedJournal ? structuredClone(loadedJournal) : undefined;
2895
- if (journal && journal.length > MAX_JOURNAL)
2896
- throw new Error("GOVERNANCE_JOURNAL_LIMIT");
2897
- if (journal?.some((entry) => entry.runId !== state.runId))
2898
- throw new Error("GOVERNANCE_JOURNAL_SCOPE");
2899
- if (!journal)
2900
- limitations.add("journal_unavailable");
2901
- observed.push({ state, journal });
2902
- runs.push(projectRun(state, journal, limitations));
2903
- if ((state.childRuns?.length ?? 0) > 64)
2904
- limitations.add("tree_limit");
2905
- for (const child of (state.childRuns ?? []).slice(0, 64))
2906
- queue.push({ id: child.runId, parent: state.runId });
2907
- }
2908
- if (queue.length)
2909
- limitations.add("tree_limit");
2910
- const context = await readGovernanceSession(options.session, runId, new Set(observed.map((item) => item.state.runId)));
2911
- for (const { state, journal } of observed) {
2912
- const current = await store.load(state.runId, scope);
2913
- const currentJournal = await store.listToolCalls?.(state.runId, scope);
2914
- if (!current || JSON.stringify(current) !== JSON.stringify(state) || JSON.stringify(currentJournal) !== JSON.stringify(journal))
2915
- throw new Error("GOVERNANCE_STATE_CHANGED");
2916
- }
2917
- await context.verify();
2918
- const patches = new Map;
2919
- for (const run of runs)
2920
- for (const patch of new Set([run.delivery.patchId, ...run.approvals.items.map((row) => row.proposalId)].filter((id) => id !== null)))
2921
- patches.set(patch, [...patches.get(patch) ?? [], run.reference]);
2922
- const binding = bindingSchema.safeParse(observed[0]?.state.harness);
2923
- const report = harnessGovernanceReportSchema.parse({
2924
- schemaVersion: 1,
2925
- kind: "harness-governance-report",
2926
- exporterVersion: HARNESS_VERSION,
2927
- 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" },
2928
- rootReference: governanceReference("run", runId),
2929
- identity: "not-verified",
2930
- referencePolicy: "sha256-domain-separated-pseudonyms-not-anonymity",
2931
- session: context.session,
2932
- eventHistory: context.history,
2933
- changeEnvelopes: projectGovernanceEnvelopes(options.changeEnvelopes ?? [], patches, options.now ?? Date.now()),
2934
- runs,
2935
- missingChildren,
2936
- limitations: [...limitations].sort()
2937
- });
2938
- if (Buffer.byteLength(JSON.stringify(report)) > MAX_REPORT_BYTES)
2939
- throw new Error("GOVERNANCE_REPORT_LIMIT");
2940
- return report;
2941
- }
2942
- function renderHarnessGovernanceMarkdown(input) {
2943
- const report = harnessGovernanceReportSchema.parse(input);
2944
- return [
2945
- "# Execution and governance report",
2946
- "",
2947
- `Schema: ${report.schemaVersion}. Exporter: ${report.exporterVersion}.`,
2948
- `Identity: not verified. Recorded execution version: ${report.executionArtifact.version ?? "unavailable"}. Artifact digest: unavailable. Hash references are pseudonyms, not signatures.`,
2949
- "Delivery describes a recorded checkpoint; export does not recheck the workspace.",
2950
- "",
2951
- "| Run reference | Execution | Recorded delivery | Usage |",
2952
- "| --- | --- | --- | --- |",
2953
- ...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"})`} |`),
2954
- "",
2955
- `Missing children: ${report.missingChildren.length}. Limitations: ${report.limitations.join(", ") || "none detected"}.`,
2956
- `Session: ${report.session.availability}. Event history: ${report.eventHistory.availability}. Retention: ${report.eventHistory.retention}. Incomplete: ${report.eventHistory.incomplete}.`,
2957
- `Change envelopes: ${report.changeEnvelopes.length}. Envelope integrity does not verify patch bytes or authenticity. Estimates are not invoices.`,
2958
- ""
2959
- ].join(`
2960
- `);
2961
- }
2962
-
2963
- // src/cli/governance-report.ts
2964
2564
  async function governanceReportCli(options, config, store) {
2965
2565
  let index;
2966
2566
  let history;
@@ -3415,17 +3015,17 @@ async function readBackupTransport(source, legacyMaxBytes) {
3415
3015
  }
3416
3016
 
3417
3017
  // src/persistence/state-backup.ts
3418
- import { createHash as createHash5, randomUUID as randomUUID2 } from "node:crypto";
3018
+ import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
3419
3019
  import { constants as fsConstants2 } from "node:fs";
3420
3020
  import { chmod, link, lstat as lstat2, open, realpath, unlink } from "node:fs/promises";
3421
3021
  import path4 from "node:path";
3422
- import { z as z3 } from "zod";
3022
+ import { z } from "zod";
3423
3023
  import { normalizeAgentRunState } from "@zhivex-ai/agents";
3424
3024
  import { createSqliteAgentRunStore } from "@zhivex-ai/agents/ops";
3425
3025
 
3426
3026
  // src/persistence/sdk-store-identity.ts
3427
- import { createHash as createHash4 } from "node:crypto";
3428
- var sdkCanonicalKey = (kind, scope, value) => `${kind}:v2:${createHash4("sha256").update(JSON.stringify([
3027
+ import { createHash as createHash2 } from "node:crypto";
3028
+ var sdkCanonicalKey = (kind, scope, value) => `${kind}:v2:${createHash2("sha256").update(JSON.stringify([
3429
3029
  JSON.stringify([scope.namespace ?? null, scope.tenantId, scope.userId ?? null]),
3430
3030
  value
3431
3031
  ])).digest("hex")}`;
@@ -3437,128 +3037,128 @@ var HARNESS_STATE_BACKUP_SCHEMA_VERSION = 1;
3437
3037
  var HARNESS_STATE_BACKUP_MAX_BYTES = 64 * 1024 * 1024;
3438
3038
  var terminalRunStatuses = new Set(["completed", "failed", "cancelled", "timed_out"]);
3439
3039
  var terminalSessionStatuses = new Set(["completed", "failed", "cancelled", "timed_out"]);
3440
- var digestSchema = z3.string().regex(/^sha256:[a-f0-9]{64}$/);
3441
- var bindingKeySchema = z3.string().regex(/^[a-f0-9]{64}$/);
3442
- var jsonRecordSchema = z3.record(z3.string(), z3.unknown());
3443
- var durableScopeSchema = z3.object({
3444
- tenantId: z3.string().min(1),
3445
- userId: z3.string().min(1).optional(),
3446
- namespace: z3.string().min(1).optional()
3040
+ var digestSchema = z.string().regex(/^sha256:[a-f0-9]{64}$/);
3041
+ var bindingKeySchema = z.string().regex(/^[a-f0-9]{64}$/);
3042
+ var jsonRecordSchema = z.record(z.string(), z.unknown());
3043
+ var durableScopeSchema = z.object({
3044
+ tenantId: z.string().min(1),
3045
+ userId: z.string().min(1).optional(),
3046
+ namespace: z.string().min(1).optional()
3447
3047
  }).strict();
3448
- var journalEntrySchema = z3.object({
3449
- runId: z3.string().min(1),
3048
+ var journalEntrySchema = z.object({
3049
+ runId: z.string().min(1),
3450
3050
  scope: durableScopeSchema,
3451
- toolCallId: z3.string().min(1),
3452
- toolName: z3.string().min(1),
3453
- status: z3.enum(["pending", "running", "completed", "failed"]),
3454
- idempotencyKey: z3.string().min(1),
3455
- revision: z3.number().int().nonnegative(),
3456
- input: z3.json().optional(),
3457
- output: z3.json().optional(),
3458
- error: z3.object({ message: z3.string() }).strict().optional(),
3459
- startedAt: z3.number().nonnegative().optional(),
3460
- completedAt: z3.number().nonnegative().optional(),
3461
- updatedAt: z3.number().nonnegative()
3051
+ toolCallId: z.string().min(1),
3052
+ toolName: z.string().min(1),
3053
+ status: z.enum(["pending", "running", "completed", "failed"]),
3054
+ idempotencyKey: z.string().min(1),
3055
+ revision: z.number().int().nonnegative(),
3056
+ input: z.json().optional(),
3057
+ output: z.json().optional(),
3058
+ error: z.object({ message: z.string() }).strict().optional(),
3059
+ startedAt: z.number().nonnegative().optional(),
3060
+ completedAt: z.number().nonnegative().optional(),
3061
+ updatedAt: z.number().nonnegative()
3462
3062
  }).passthrough();
3463
- var runRecordSchema = z3.object({
3464
- key: z3.string().min(1).max(1024),
3063
+ var runRecordSchema = z.object({
3064
+ key: z.string().min(1).max(1024),
3465
3065
  state: jsonRecordSchema,
3466
- updatedAt: z3.number().int().nonnegative()
3066
+ updatedAt: z.number().int().nonnegative()
3467
3067
  }).strict();
3468
- var journalRecordSchema = z3.object({
3469
- runKey: z3.string().min(1).max(1024),
3470
- toolCallId: z3.string().min(1).max(1024),
3068
+ var journalRecordSchema = z.object({
3069
+ runKey: z.string().min(1).max(1024),
3070
+ toolCallId: z.string().min(1).max(1024),
3471
3071
  entry: journalEntrySchema,
3472
- revision: z3.number().int().nonnegative(),
3473
- updatedAt: z3.number().int().nonnegative()
3072
+ revision: z.number().int().nonnegative(),
3073
+ updatedAt: z.number().int().nonnegative()
3474
3074
  }).strict();
3475
- var idempotencyRecordSchema = z3.object({
3476
- key: z3.string().min(1).max(1024),
3477
- runKey: z3.string().min(1).max(1024),
3478
- updatedAt: z3.number().int().nonnegative()
3075
+ var idempotencyRecordSchema = z.object({
3076
+ key: z.string().min(1).max(1024),
3077
+ runKey: z.string().min(1).max(1024),
3078
+ updatedAt: z.number().int().nonnegative()
3479
3079
  }).strict();
3480
- var parentRecordSchema = z3.object({
3481
- runKey: z3.string().min(1).max(1024),
3482
- parentRunKey: z3.string().min(1).max(1024),
3483
- updatedAt: z3.number().int().nonnegative()
3080
+ var parentRecordSchema = z.object({
3081
+ runKey: z.string().min(1).max(1024),
3082
+ parentRunKey: z.string().min(1).max(1024),
3083
+ updatedAt: z.number().int().nonnegative()
3484
3084
  }).strict();
3485
- var memoryRecordSchema = z3.object({
3486
- key: z3.string().min(1).max(1024),
3487
- messages: z3.array(z3.unknown()),
3488
- updatedAt: z3.number().int().nonnegative()
3085
+ var memoryRecordSchema = z.object({
3086
+ key: z.string().min(1).max(1024),
3087
+ messages: z.array(z.unknown()),
3088
+ updatedAt: z.number().int().nonnegative()
3489
3089
  }).strict();
3490
3090
  var serializedMemory = (entry) => JSON.stringify(entry.key.startsWith("agent-memory:v2:") ? { schemaVersion: 1, memoryKey: entry.key, messages: entry.messages } : entry.messages);
3491
3091
  var memoryKeysForRuns = (config, runs) => new Set(runs.flatMap(({ state }) => [...new Set([state.runId, state.agentId].filter((id) => typeof id === "string"))].flatMap((id) => [sdkLegacyKey(config.scope, id), sdkCanonicalKey("agent-memory", config.scope, id)])));
3492
- var sessionRecordSchema = z3.object({
3493
- sessionId: z3.string().min(1).max(260),
3092
+ var sessionRecordSchema = z.object({
3093
+ sessionId: z.string().min(1).max(260),
3494
3094
  workspaceKey: bindingKeySchema,
3495
3095
  scopeKey: bindingKeySchema,
3496
- title: z3.string().nullable(),
3497
- parentSessionId: z3.string().nullable(),
3498
- forkedFromTurnId: z3.string().nullable(),
3499
- revision: z3.number().int().nonnegative(),
3500
- activitySequence: z3.number().int().nonnegative(),
3501
- createdAt: z3.number().int().nonnegative(),
3502
- updatedAt: z3.number().int().nonnegative(),
3503
- archivedAt: z3.number().int().nonnegative().nullable(),
3504
- deletedAt: z3.number().int().nonnegative().nullable(),
3505
- metadataBytes: z3.number().int().nonnegative()
3096
+ title: z.string().nullable(),
3097
+ parentSessionId: z.string().nullable(),
3098
+ forkedFromTurnId: z.string().nullable(),
3099
+ revision: z.number().int().nonnegative(),
3100
+ activitySequence: z.number().int().nonnegative(),
3101
+ createdAt: z.number().int().nonnegative(),
3102
+ updatedAt: z.number().int().nonnegative(),
3103
+ archivedAt: z.number().int().nonnegative().nullable(),
3104
+ deletedAt: z.number().int().nonnegative().nullable(),
3105
+ metadataBytes: z.number().int().nonnegative()
3506
3106
  }).strict();
3507
- var sessionRunRecordSchema = z3.object({
3508
- turnId: z3.string().min(1).max(260),
3509
- sourceTurnId: z3.string().nullable(),
3510
- sessionId: z3.string().min(1).max(260),
3511
- ordinal: z3.number().int().nonnegative(),
3512
- runId: z3.string().min(1).max(260),
3513
- provider: z3.string().min(1).max(260),
3514
- model: z3.string().min(1).max(260),
3515
- role: z3.string().nullable(),
3516
- status: z3.string().min(1),
3517
- createdAt: z3.number().int().nonnegative(),
3518
- updatedAt: z3.number().int().nonnegative(),
3519
- completedAt: z3.number().int().nonnegative().nullable(),
3520
- metadataBytes: z3.number().int().nonnegative()
3107
+ var sessionRunRecordSchema = z.object({
3108
+ turnId: z.string().min(1).max(260),
3109
+ sourceTurnId: z.string().nullable(),
3110
+ sessionId: z.string().min(1).max(260),
3111
+ ordinal: z.number().int().nonnegative(),
3112
+ runId: z.string().min(1).max(260),
3113
+ provider: z.string().min(1).max(260),
3114
+ model: z.string().min(1).max(260),
3115
+ role: z.string().nullable(),
3116
+ status: z.string().min(1),
3117
+ createdAt: z.number().int().nonnegative(),
3118
+ updatedAt: z.number().int().nonnegative(),
3119
+ completedAt: z.number().int().nonnegative().nullable(),
3120
+ metadataBytes: z.number().int().nonnegative()
3521
3121
  }).strict();
3522
- var checkpointRecordSchema = z3.discriminatedUnion("kind", [
3523
- z3.object({
3524
- id: z3.string().uuid(),
3122
+ var checkpointRecordSchema = z.discriminatedUnion("kind", [
3123
+ z.object({
3124
+ id: z.string().uuid(),
3525
3125
  workspaceKey: bindingKeySchema,
3526
3126
  scopeKey: bindingKeySchema,
3527
- kind: z3.literal("checkpoint"),
3127
+ kind: z.literal("checkpoint"),
3528
3128
  body: workspaceCheckpointSchema
3529
3129
  }).strict(),
3530
- z3.object({
3531
- id: z3.string().uuid(),
3130
+ z.object({
3131
+ id: z.string().uuid(),
3532
3132
  workspaceKey: bindingKeySchema,
3533
3133
  scopeKey: bindingKeySchema,
3534
- kind: z3.literal("restore"),
3134
+ kind: z.literal("restore"),
3535
3135
  body: workspaceRestoreOperationSchema
3536
3136
  }).strict()
3537
3137
  ]);
3538
3138
  var checkpointTableSql = "CREATE TABLE IF NOT EXISTS zhivex_workspace_checkpoints (id TEXT PRIMARY KEY, workspace_key TEXT NOT NULL, scope_key TEXT NOT NULL, kind TEXT NOT NULL, body TEXT NOT NULL)";
3539
- var stateBackupPayloadSchema = z3.object({
3540
- schemaVersion: z3.literal(HARNESS_STATE_BACKUP_SCHEMA_VERSION),
3541
- kind: z3.literal("state-backup"),
3542
- createdAt: z3.iso.datetime({ precision: 3 }),
3543
- binding: z3.object({
3139
+ var stateBackupPayloadSchema = z.object({
3140
+ schemaVersion: z.literal(HARNESS_STATE_BACKUP_SCHEMA_VERSION),
3141
+ kind: z.literal("state-backup"),
3142
+ createdAt: z.iso.datetime({ precision: 3 }),
3143
+ binding: z.object({
3544
3144
  workspaceKey: bindingKeySchema,
3545
3145
  scopeKey: bindingKeySchema,
3546
- scopePrefix: z3.string().min(1).max(1024)
3146
+ scopePrefix: z.string().min(1).max(1024)
3547
3147
  }).strict(),
3548
- schemas: z3.object({
3549
- operations: z3.literal(HARNESS_OPERATIONS_SCHEMA_VERSION),
3550
- sessions: z3.literal(HARNESS_SESSION_SCHEMA_VERSION)
3148
+ schemas: z.object({
3149
+ operations: z.literal(HARNESS_OPERATIONS_SCHEMA_VERSION),
3150
+ sessions: z.literal(HARNESS_SESSION_SCHEMA_VERSION)
3551
3151
  }).strict(),
3552
- records: z3.object({
3553
- runs: z3.array(runRecordSchema),
3554
- toolJournal: z3.array(journalRecordSchema),
3555
- idempotency: z3.array(idempotencyRecordSchema),
3556
- parents: z3.array(parentRecordSchema),
3557
- memory: z3.array(memoryRecordSchema),
3558
- sessions: z3.array(sessionRecordSchema),
3559
- sessionRuns: z3.array(sessionRunRecordSchema),
3560
- workspaceCheckpoints: z3.array(checkpointRecordSchema).max(100).optional(),
3561
- budgetLedgers: z3.array(runRecordSchema).optional()
3152
+ records: z.object({
3153
+ runs: z.array(runRecordSchema),
3154
+ toolJournal: z.array(journalRecordSchema),
3155
+ idempotency: z.array(idempotencyRecordSchema),
3156
+ parents: z.array(parentRecordSchema),
3157
+ memory: z.array(memoryRecordSchema),
3158
+ sessions: z.array(sessionRecordSchema),
3159
+ sessionRuns: z.array(sessionRunRecordSchema),
3160
+ workspaceCheckpoints: z.array(checkpointRecordSchema).max(100).optional(),
3161
+ budgetLedgers: z.array(runRecordSchema).optional()
3562
3162
  }).strict()
3563
3163
  }).strict();
3564
3164
  var stateBackupBundleSchema = stateBackupPayloadSchema.extend({ checksum: digestSchema }).strict();
@@ -3570,12 +3170,12 @@ var canonicalJson = (value) => {
3570
3170
  return `{${Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(",")}}`;
3571
3171
  };
3572
3172
  var checksumPayload = (payload) => {
3573
- const hash = createHash5("sha256");
3173
+ const hash = createHash3("sha256");
3574
3174
  for (const chunk of canonicalChunks(payload))
3575
3175
  hash.update(chunk);
3576
3176
  return `sha256:${hash.digest("hex")}`;
3577
3177
  };
3578
- var stableKey = (kind, value) => createHash5("sha256").update(kind).update("\x00").update(value).digest("hex");
3178
+ var stableKey = (kind, value) => createHash3("sha256").update(kind).update("\x00").update(value).digest("hex");
3579
3179
  var scopeValue = (config) => `${config.scope.tenantId}\x00${config.scope.userId ?? ""}\x00${config.scope.namespace ?? ""}`;
3580
3180
  var scopePrefix = (config) => `${encodeURIComponent(config.scope.namespace ?? "default")}:${encodeURIComponent(config.scope.tenantId)}:${encodeURIComponent(config.scope.userId ?? "*")}:`;
3581
3181
  var stateMatchesScope = (config, state) => {
@@ -3594,7 +3194,8 @@ var coordinatorIds = (runs) => new Set(runs.flatMap(({ state }) => {
3594
3194
  var validateBudgetLedger = (config, run, identities) => {
3595
3195
  const state = validatedRunState(run.state, `Budget ledger ${run.key}`);
3596
3196
  const identity = state.metadata?.budgetIdentity;
3597
- if (state.scope?.namespace !== "__zhivex_budget__" || state.scope?.tenantId !== config.scope.tenantId || (state.scope?.userId ?? undefined) !== (config.scope.userId ?? undefined) || state.provider !== "zhivex" || state.modelId !== "budget-coordinator" || state.metadata?.budgetCoordinator !== true || typeof identity !== "string" || !identities.has(identity) || !/^budget_[a-f0-9]{64}$/.test(state.runId) || !sdkRunKeyMatches(run.key, state.scope, state.runId)) {
3197
+ const ownerNamespace = config.scope.namespace;
3198
+ if (!ownerNamespace || state.scope?.namespace !== budgetLedgerNamespace(ownerNamespace) || state.metadata?.[BUDGET_OWNER_NAMESPACE_KEY] !== ownerNamespace || state.scope?.tenantId !== config.scope.tenantId || (state.scope?.userId ?? undefined) !== (config.scope.userId ?? undefined) || state.provider !== "zhivex" || state.modelId !== "budget-coordinator" || state.metadata?.budgetCoordinator !== true || typeof identity !== "string" || !identities.has(identity) || !/^budget_[a-f0-9]{64}$/.test(state.runId) || !sdkRunKeyMatches(run.key, state.scope, state.runId)) {
3598
3199
  throw new HarnessStateConflictError("Budget ledger is not bound to an exported run and durable scope.");
3599
3200
  }
3600
3201
  assertTerminalState(state, `Budget ledger ${run.key}`);
@@ -3728,7 +3329,9 @@ var readPayload = async (config, recordedWorkspace, accessLease) => {
3728
3329
  const metadata = state.metadata;
3729
3330
  if (typeof metadata?.budgetIdentity !== "string" || !identities.has(metadata.budgetIdentity)) {
3730
3331
  const scope = state.scope;
3731
- if (scope?.namespace === "__zhivex_budget__" && scope.tenantId === config.scope.tenantId && (scope.userId ?? undefined) === (config.scope.userId ?? undefined)) {
3332
+ const sameTenant = scope?.tenantId === config.scope.tenantId && (scope?.userId ?? undefined) === (config.scope.userId ?? undefined);
3333
+ const boundNamespace = config.scope.namespace ? budgetLedgerNamespace(config.scope.namespace) : undefined;
3334
+ if (sameTenant && (scope?.namespace === BUDGET_LEDGER_NAMESPACE || scope?.namespace === boundNamespace)) {
3732
3335
  throw new HarnessStateConflictError("An unlinked shared budget ledger cannot be safely assigned to this backup scope; retain the original database.");
3733
3336
  }
3734
3337
  return [];
@@ -3778,10 +3381,10 @@ var readPayload = async (config, recordedWorkspace, accessLease) => {
3778
3381
  const memory = database.query("SELECT memory_key, messages_json, updated_at_ms FROM zhivex_agent_memory ORDER BY memory_key").all().filter((row) => memoryKeys.has(row.memory_key)).map((row) => {
3779
3382
  const value = JSON.parse(row.messages_json);
3780
3383
  if (row.memory_key.startsWith("agent-memory:v2:")) {
3781
- const envelope = z3.strictObject({ schemaVersion: z3.literal(1), memoryKey: z3.literal(row.memory_key), messages: z3.array(z3.unknown()) }).parse(value);
3384
+ const envelope = z.strictObject({ schemaVersion: z.literal(1), memoryKey: z.literal(row.memory_key), messages: z.array(z.unknown()) }).parse(value);
3782
3385
  return { key: row.memory_key, messages: envelope.messages, updatedAt: row.updated_at_ms };
3783
3386
  }
3784
- return { key: row.memory_key, messages: z3.array(z3.unknown()).parse(value), updatedAt: row.updated_at_ms };
3387
+ return { key: row.memory_key, messages: z.array(z.unknown()).parse(value), updatedAt: row.updated_at_ms };
3785
3388
  });
3786
3389
  const sessionRows = database.query("SELECT * FROM zhivex_cli_sessions ORDER BY session_id").all().filter((row) => row.workspace_key === binding.workspaceKey && row.scope_key === binding.scopeKey);
3787
3390
  const selectedSessionIds = new Set(sessionRows.map((row) => row.session_id));
@@ -4066,7 +3669,7 @@ var validateBundleBinding = async (config, bundle) => {
4066
3669
  const turn = bundle.records.sessionRuns.find((run) => run.turnId === checkpoint.turnId && run.sessionId === checkpoint.sessionId);
4067
3670
  if (!turn || !terminalSessionStatuses.has(turn.status))
4068
3671
  throw new HarnessStateConflictError("Checkpoint targets a missing terminal turn.");
4069
- if (new Set(checkpoint.files.map((file) => file.path)).size !== checkpoint.files.length || checkpoint.files.some((file) => `sha256:${createHash5("sha256").update(file.content).digest("hex")}` !== file.digest || Buffer.byteLength(file.content) > 65536)) {
3672
+ if (new Set(checkpoint.files.map((file) => file.path)).size !== checkpoint.files.length || checkpoint.files.some((file) => `sha256:${createHash3("sha256").update(file.content).digest("hex")}` !== file.digest || Buffer.byteLength(file.content) > 65536)) {
4070
3673
  throw new HarnessStateConflictError("Checkpoint content identity is invalid.");
4071
3674
  }
4072
3675
  if (record.kind === "restore") {
@@ -4488,7 +4091,7 @@ var main = async (argv = process.argv.slice(2)) => {
4488
4091
  parsedOptions = { ...parsedOptions, prompt: await readStdinTask() };
4489
4092
  }
4490
4093
  if (parsedOptions.serviceFile) {
4491
- const { runServiceCli } = await import("./service-client-cli-fn54ev6w.js");
4094
+ const { runServiceCli } = await import("./service-client-cli-v6qptg9x.js");
4492
4095
  await runServiceCli(parsedOptions, annotateCliStreamError);
4493
4096
  return;
4494
4097
  }
@@ -4551,6 +4154,12 @@ var main = async (argv = process.argv.slice(2)) => {
4551
4154
  case "state":
4552
4155
  await manageState(options);
4553
4156
  return;
4157
+ case "export-audit":
4158
+ case "verify-audit": {
4159
+ const { auditPackCli } = await import("./audit-pack-kvw7ng34.js");
4160
+ await auditPackCli(options);
4161
+ return;
4162
+ }
4554
4163
  case "run":
4555
4164
  await runOnce(options);
4556
4165
  return;