@zhivex-ai/harness 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -10
- package/README.md +7 -5
- package/SUPPORT.md +2 -2
- package/contracts/client-protocol-v1.schema.json +593 -0
- package/contracts/engine-api.json +156 -0
- package/contracts/public-api.json +12 -0
- package/contracts/stable-api-signatures.json +33 -33
- package/dist/acp-cli.js +54 -20
- package/dist/audit/index.d.ts +3 -0
- package/dist/audit/index.js +482 -0
- package/dist/audit/pack.d.ts +72 -0
- package/dist/audit-pack-e4vaq7np.js +532 -0
- package/dist/cli/arguments.d.ts +3 -1
- package/dist/cli/audit-pack.d.ts +24 -0
- package/dist/cli/cli-credentials.d.ts +6 -0
- package/dist/cli/cli-profiles.d.ts +4 -2
- package/dist/cli/node-engine.d.ts +2 -0
- package/dist/{cli-2h37qyvg.js → cli-1cf4dcnj.js} +245 -642
- package/dist/{cli-entry-w0hterjs.js → cli-entry-3s63zn4w.js} +40 -13
- package/dist/cli-entry-7f0cen32.js +9990 -0
- package/dist/cli-entry-a890x3kq.js +10348 -0
- package/dist/{cli-entry-20w6nh0k.js → cli-entry-hdtfef27.js} +439 -19
- package/dist/cli-entry-rgs6bxmy.js +484 -0
- package/dist/cli.js +27 -2
- package/dist/client/json-contracts.d.ts +4 -0
- package/dist/client/protocol.d.ts +133 -0
- package/dist/client/task-control-host.d.ts +400 -0
- package/dist/client/task-projection-host.d.ts +12 -0
- package/dist/client/task-projection.d.ts +168 -0
- package/dist/compat/code-support.js +28 -22
- package/dist/{config-qt69hkqj.js → config-r9fdhce6.js} +3 -3
- package/dist/{config-j9624t6t.js → config-vyajmksy.js} +1 -1
- package/dist/engine/acp.js +15 -11
- package/dist/engine/client.js +14 -10
- package/dist/engine/desktop-providers-v1.d.ts +2 -0
- package/dist/engine/desktop-providers-v1.js +23 -3
- package/dist/engine/desktop-state-v1.js +11 -8
- package/dist/engine/index.d.ts +3 -0
- package/dist/engine/index.js +101 -554
- package/dist/engine/mcp-stdio-v1.js +8 -6
- package/dist/engine/models.js +76 -4
- package/dist/engine/protocol.d.ts +2 -0
- package/dist/engine/protocol.js +110 -0
- package/dist/engine/service.js +15 -11
- package/dist/hostile-repository-demo.js +1095 -505
- package/dist/{index-937cb7y8.js → index-02pqtbbg.js} +559 -33
- package/dist/{index-pp474137.js → index-0zs2dz26.js} +766 -931
- package/dist/{index-8zjmnyw5.js → index-1265j7t2.js} +73 -6
- package/dist/index-4fx5f3k5.js +269 -0
- package/dist/{index-nmjdwd4p.js → index-4gt045j0.js} +109 -1
- package/dist/{index-6dft2vev.js → index-6599mpmy.js} +5 -3
- package/dist/{index-tfzta544.js → index-74kkpyqk.js} +9 -7
- package/dist/{index-61gthdz6.js → index-8sm2a1wa.js} +1 -1
- package/dist/index-c39197wq.js +552 -0
- package/dist/{index-5jhgatga.js → index-crta5wzv.js} +7 -6
- package/dist/{index-m34q25jj.js → index-d9zkmhz3.js} +143 -824
- package/dist/{index-pdmevfxv.js → index-dtb2c6ds.js} +5 -259
- package/dist/index-f6mqa5gk.js +1535 -0
- package/dist/index-j6zxnc8m.js +490 -0
- package/dist/{index-rkbf7dqg.js → index-mv8sb1ns.js} +5 -3
- package/dist/{index-xqxeypt5.js → index-mzydbzp8.js} +76 -4
- package/dist/{index-wg1sd3at.js → index-qfsrrnz6.js} +1 -1
- package/dist/{index-m82cfspw.js → index-sk3cap35.js} +877 -963
- package/dist/index-sstgcsr0.js +511 -0
- package/dist/index-wm9xeq1n.js +329 -0
- package/dist/index-xdbkcccf.js +719 -0
- package/dist/{index-s2k2edts.js → index-zxg4ve4j.js} +41 -1548
- package/dist/index.d.ts +3 -0
- package/dist/index.js +93 -77
- package/dist/internal/desktop/providers.d.ts +2 -0
- package/dist/models/catalog.d.ts +2 -0
- package/dist/persistence/sqlite-database.d.ts +1 -0
- package/dist/providers/azure-openai.d.ts +14 -0
- package/dist/providers/bedrock.d.ts +23 -0
- package/dist/providers/providers.d.ts +1 -1
- package/dist/runtime/durable-review-group.d.ts +33 -0
- package/dist/runtime/harness.d.ts +11 -0
- package/dist/runtime/run-interruption.d.ts +7 -0
- package/dist/runtime/shared-budget.d.ts +30 -0
- package/dist/runtime/task-continuity.d.ts +300 -77
- package/dist/service-cli.js +15 -11
- package/dist/{service-client-cli-fn54ev6w.js → service-client-cli-eqrdc9zq.js} +400 -305
- package/dist/verify-historical-migrations.js +1095 -505
- package/dist/zhx.js +27 -2
- package/docs/AUDIT_PACK.md +99 -0
- package/docs/AZURE_OPENAI.md +53 -0
- package/docs/BEDROCK.md +56 -0
- package/docs/CLI.md +15 -0
- package/docs/CLIENT_PROTOCOL.md +178 -0
- package/docs/CODE_RELEASE.md +31 -1
- package/docs/CODE_WEB_TASKS.md +116 -0
- package/docs/CONTEXT_ENGINEERING.md +59 -0
- package/docs/CREDENTIALS.md +21 -0
- package/docs/DURABLE_OPERATIONS.md +93 -1
- package/docs/ENGINE_API.md +5 -2
- package/docs/EXTENSIBILITY.md +2 -2
- package/docs/FIRST_USE.md +6 -6
- package/docs/MINIMUM_TASK_AUTHORITY.md +3 -3
- package/docs/PROJECT_MEMORY.md +1 -1
- package/docs/README.md +6 -1
- package/docs/STABILITY.md +3 -1
- package/docs/SUPPORT_MATRIX.md +1 -1
- package/docs/SUPPORT_MATRIX_1_1.md +1 -1
- package/docs/USAGE.md +3 -1
- package/docs/VERTEX.md +2 -2
- package/docs/WEB_LIMITS.md +4 -3
- package/docs/adr/0002-isolated-mcp-stdio.md +6 -3
- package/docs/support-matrix-1.1.json +3 -1
- package/docs/support-matrix.json +6 -4
- package/evaluations/code-task-ui.json +20 -0
- package/evaluations/representative-assembly-matrix.json +10 -1
- package/evaluations/task-projection.json +10 -0
- package/evaluations/task-recovery-lab.json +60 -0
- package/examples/README.md +3 -3
- package/package.json +23 -13
- package/dist/cli-entry-4ngptr62.js +0 -19900
- package/dist/index-m49jx72n.js +0 -220
|
@@ -1,137 +1,135 @@
|
|
|
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-
|
|
64
|
+
} from "./cli-entry-a890x3kq.js";
|
|
65
|
+
import {
|
|
66
|
+
exportHarnessGovernanceReport,
|
|
67
|
+
renderHarnessGovernanceMarkdown
|
|
68
|
+
} from "./cli-entry-rgs6bxmy.js";
|
|
69
|
+
import {
|
|
70
|
+
CLI_CHANGES_COMMANDS,
|
|
71
|
+
CLI_COMMANDS,
|
|
72
|
+
CLI_JSON_SCHEMA_VERSION,
|
|
73
|
+
CLI_RUNS_COMMANDS,
|
|
74
|
+
CLI_SESSIONS_COMMANDS,
|
|
75
|
+
CLI_STATE_COMMANDS,
|
|
76
|
+
CliOciRuntimeAdapter,
|
|
77
|
+
CliUsageError,
|
|
78
|
+
FileChangedWhileReadingError,
|
|
79
|
+
FileSizeLimitError,
|
|
80
|
+
HARNESS_OPERATIONS_SCHEMA_VERSION,
|
|
81
|
+
HARNESS_SESSION_SCHEMA_VERSION,
|
|
82
|
+
HARNESS_SQLITE_FILE,
|
|
83
|
+
SqliteDatabase,
|
|
84
|
+
TASK_SOURCE_KEY,
|
|
85
|
+
USAGE_LEDGER_KEY,
|
|
86
|
+
UnsafeFileTypeError,
|
|
87
|
+
Workspace,
|
|
88
|
+
applyCliProfile,
|
|
89
|
+
assertTaskBudgetBackupLinks,
|
|
90
|
+
cancelHarnessRun,
|
|
91
|
+
canonicalizeChangeEnvelope,
|
|
92
|
+
changeEnvelopePreconditionsSchema,
|
|
93
|
+
cleanupHarnessExecutionArtifacts,
|
|
94
|
+
cleanupHarnessRuns,
|
|
95
|
+
createChangeEnvelope,
|
|
96
|
+
createCliProfile,
|
|
97
|
+
createHarnessRouteModels,
|
|
98
|
+
digestChangeEnvelopeArtifact,
|
|
99
|
+
fileDigestSchema,
|
|
100
|
+
formatUsageLedger,
|
|
101
|
+
harnessToolExecution,
|
|
102
|
+
inspectHarnessRun,
|
|
103
|
+
inspectRuntimeDiagnostics,
|
|
104
|
+
inspectUsageLedger,
|
|
105
|
+
listHarnessRuns,
|
|
106
|
+
loadCliProfile,
|
|
107
|
+
openCliSessionStore,
|
|
108
|
+
openHarnessActivityStore,
|
|
109
|
+
openHarnessPersistence,
|
|
110
|
+
parseCliArgs,
|
|
111
|
+
parseHarnessModelRoute,
|
|
112
|
+
publishPendingPolicyDecision,
|
|
113
|
+
readRegularFileChunksNoFollow,
|
|
114
|
+
readRegularFileNoFollow,
|
|
115
|
+
resolveCliDefaults,
|
|
116
|
+
resolveHarnessModelRoutes,
|
|
117
|
+
resolvePackageManager,
|
|
118
|
+
runPortableProcess,
|
|
119
|
+
serializeHarnessModelRoutes,
|
|
120
|
+
sqliteAdapter,
|
|
121
|
+
taskSources,
|
|
122
|
+
updateCliProfile,
|
|
123
|
+
validateStateDirectory,
|
|
124
|
+
verifyChangeEnvelope
|
|
125
|
+
} from "./cli-entry-7f0cen32.js";
|
|
128
126
|
import {
|
|
129
127
|
BUN_ENGINE_RANGE,
|
|
130
128
|
HARNESS_VERSION,
|
|
131
129
|
NODE_ENGINE_RANGE,
|
|
132
130
|
formatCliHelp,
|
|
133
131
|
shortCliHelp
|
|
134
|
-
} from "./cli-entry-
|
|
132
|
+
} from "./cli-entry-3s63zn4w.js";
|
|
135
133
|
import {
|
|
136
134
|
DEFAULT_PROVIDER_REGISTRY,
|
|
137
135
|
HARNESS_SUBAGENT_PROFILES,
|
|
@@ -147,7 +145,7 @@ import {
|
|
|
147
145
|
providerDescriptor,
|
|
148
146
|
reasoningEffortSchema,
|
|
149
147
|
resolveHarnessConfig
|
|
150
|
-
} from "./cli-entry-
|
|
148
|
+
} from "./cli-entry-hdtfef27.js";
|
|
151
149
|
import {
|
|
152
150
|
__require
|
|
153
151
|
} from "./cli-entry-1bx83sw4.js";
|
|
@@ -237,7 +235,7 @@ var initializeCli = async (options, context = {}) => {
|
|
|
237
235
|
process.stdout.write([
|
|
238
236
|
`${options.updateProfile ? "Updated" : "Created"} personal profile ${profileName} at ${created.path}.`,
|
|
239
237
|
`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.`,
|
|
238
|
+
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
239
|
"Next:",
|
|
242
240
|
` ${doctorCommand}`,
|
|
243
241
|
` ${runCommand}`,
|
|
@@ -247,6 +245,31 @@ var initializeCli = async (options, context = {}) => {
|
|
|
247
245
|
`);
|
|
248
246
|
return true;
|
|
249
247
|
};
|
|
248
|
+
var providerStatus = (provider, env = process.env) => {
|
|
249
|
+
if (provider.id === "vertex")
|
|
250
|
+
return provider.configured ? "route configured; ADC not checked" : "missing GOOGLE_CLOUD_PROJECT/VERTEX_LOCATION";
|
|
251
|
+
if (provider.id === "bedrock") {
|
|
252
|
+
if (provider.configuration.runtimeValid === false)
|
|
253
|
+
return "invalid BEDROCK_RUNTIME";
|
|
254
|
+
if (provider.configured)
|
|
255
|
+
return "route configured; AWS credentials not checked";
|
|
256
|
+
if (env.BEDROCK_RUNTIME?.trim() === "openai")
|
|
257
|
+
return "missing BEDROCK_API_KEY/AWS_BEARER_TOKEN_BEDROCK or https BEDROCK_OPENAI_BASE_URL";
|
|
258
|
+
return "missing AWS_REGION/AWS_DEFAULT_REGION";
|
|
259
|
+
}
|
|
260
|
+
if (provider.id === "azure-openai") {
|
|
261
|
+
if (!provider.configuration.customEndpoint)
|
|
262
|
+
return "missing AZURE_OPENAI_ENDPOINT";
|
|
263
|
+
if (!provider.configuration.endpointValid || !provider.configuration.endpointSecure)
|
|
264
|
+
return "invalid AZURE_OPENAI_ENDPOINT";
|
|
265
|
+
if (!provider.credentials.some((credential) => credential.present))
|
|
266
|
+
return "missing AZURE_OPENAI_API_KEY";
|
|
267
|
+
if (!provider.configured)
|
|
268
|
+
return "invalid AZURE_OPENAI_API_VERSION or AZURE_OPENAI_DEPLOYMENTS";
|
|
269
|
+
return "configured; account access not checked";
|
|
270
|
+
}
|
|
271
|
+
return provider.configured ? "configured" : `missing ${provider.credentialNames.join("/")}`;
|
|
272
|
+
};
|
|
250
273
|
var listProviders = (json) => {
|
|
251
274
|
const document = providersDocument();
|
|
252
275
|
if (json) {
|
|
@@ -255,7 +278,7 @@ var listProviders = (json) => {
|
|
|
255
278
|
return;
|
|
256
279
|
}
|
|
257
280
|
for (const provider of document.providers) {
|
|
258
|
-
process.stdout.write(`${provider.id.padEnd(
|
|
281
|
+
process.stdout.write(`${provider.id.padEnd(13)} ${provider.defaultModel.padEnd(28)} ${provider.support.padEnd(11)} ${providerStatus(provider)}
|
|
259
282
|
`);
|
|
260
283
|
}
|
|
261
284
|
};
|
|
@@ -299,6 +322,8 @@ Advanced operations and automation:
|
|
|
299
322
|
zhx state status
|
|
300
323
|
zhx state export <backup.json>
|
|
301
324
|
zhx state import <backup.json> [--apply]
|
|
325
|
+
zhx export-audit <task-id> --out <directory>
|
|
326
|
+
zhx verify-audit --out <directory>
|
|
302
327
|
|
|
303
328
|
The long command zhivex-harness remains supported for compatibility.
|
|
304
329
|
|
|
@@ -378,6 +403,8 @@ Options (automation and advanced configuration):
|
|
|
378
403
|
--cascade Cancel a run and its known child runs
|
|
379
404
|
--final Record terminal cancellation immediately
|
|
380
405
|
--apply Apply a validated state import (default: dry-run)
|
|
406
|
+
--out <directory> Audit pack directory (export-audit, verify-audit)
|
|
407
|
+
--signing-key-file <path> HMAC key file for an audit pack
|
|
381
408
|
-h, --help Show this help
|
|
382
409
|
-v, --version Show the version
|
|
383
410
|
|
|
@@ -758,6 +785,32 @@ var inspectProjectContext = async (config) => {
|
|
|
758
785
|
});
|
|
759
786
|
}
|
|
760
787
|
};
|
|
788
|
+
var bedrockDoctorMessage = (provider, configured, env) => {
|
|
789
|
+
if (provider.configuration.runtimeValid === false)
|
|
790
|
+
return "BEDROCK_RUNTIME must be converse or openai.";
|
|
791
|
+
if (provider.configuration.customEndpoint && (!provider.configuration.endpointValid || !provider.configuration.endpointSecure)) {
|
|
792
|
+
return "BEDROCK_OPENAI_BASE_URL must be an https URL without credentials.";
|
|
793
|
+
}
|
|
794
|
+
if (configured)
|
|
795
|
+
return "Amazon Bedrock route configured; AWS credentials and model access have not been checked. Live support is provisional.";
|
|
796
|
+
if (env.BEDROCK_RUNTIME?.trim() === "openai") {
|
|
797
|
+
return "Bedrock OpenAI-compatible runtime requires BEDROCK_API_KEY or AWS_BEARER_TOKEN_BEDROCK and an https BEDROCK_OPENAI_BASE_URL.";
|
|
798
|
+
}
|
|
799
|
+
return "Bedrock Converse requires a valid AWS_REGION or AWS_DEFAULT_REGION. No API key is stored for the AWS credential chain.";
|
|
800
|
+
};
|
|
801
|
+
var azureDoctorMessage = (provider, configured, credential) => {
|
|
802
|
+
if (!provider.configuration.customEndpoint)
|
|
803
|
+
return "Azure OpenAI requires AZURE_OPENAI_ENDPOINT.";
|
|
804
|
+
if (!provider.configuration.endpointValid || !provider.configuration.endpointSecure) {
|
|
805
|
+
return "AZURE_OPENAI_ENDPOINT must be an https URL without credentials or a query.";
|
|
806
|
+
}
|
|
807
|
+
if (!configured && (provider.credentials.some((item) => item.present) || credential?.configured)) {
|
|
808
|
+
return "AZURE_OPENAI_API_VERSION or AZURE_OPENAI_DEPLOYMENTS is invalid.";
|
|
809
|
+
}
|
|
810
|
+
if (!configured)
|
|
811
|
+
return "Azure OpenAI credential is missing. Set AZURE_OPENAI_API_KEY. Account access is not checked.";
|
|
812
|
+
return "Azure OpenAI route configured; account access has not been checked. Live support is provisional.";
|
|
813
|
+
};
|
|
761
814
|
var createDoctorReport = async (options = {}, context = {}) => {
|
|
762
815
|
const env = context.env ?? process.env;
|
|
763
816
|
const config = resolveHarnessConfig({
|
|
@@ -824,12 +877,13 @@ var createDoctorReport = async (options = {}, context = {}) => {
|
|
|
824
877
|
checks.push(await inspectExecutionEnvironment(config.execution, context.ociRuntimeAdapter));
|
|
825
878
|
for (const provider of providers) {
|
|
826
879
|
const invalidRegion = provider.id === "qwen" && provider.configuration.regionValid === false;
|
|
827
|
-
const
|
|
880
|
+
const invalidRuntime = provider.id === "bedrock" && provider.configuration.runtimeValid === false;
|
|
881
|
+
const invalidEndpoint = !provider.configuration.endpointValid || (provider.id === "bedrock" || provider.id === "azure-openai") && provider.configuration.customEndpoint && !provider.configuration.endpointSecure;
|
|
828
882
|
const selected = provider.id === selectedProvider?.id;
|
|
829
883
|
const credential = selected ? context.credentialStatus : undefined;
|
|
830
884
|
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.`;
|
|
885
|
+
const status = invalidRegion || invalidRuntime || invalidEndpoint || !configured ? selected ? "fail" : "warn" : provider.support === "provisional" ? "warn" : "pass";
|
|
886
|
+
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
887
|
checks.push(diagnostic(`provider:${provider.id}`, status, message, {
|
|
834
888
|
provider: provider.id,
|
|
835
889
|
selected,
|
|
@@ -845,6 +899,17 @@ var createDoctorReport = async (options = {}, context = {}) => {
|
|
|
845
899
|
regionConfigured: provider.configuration.regionConfigured,
|
|
846
900
|
regionValid: provider.configuration.regionValid,
|
|
847
901
|
workspaceIdConfigured: provider.configuration.workspaceIdConfigured
|
|
902
|
+
} : {},
|
|
903
|
+
...provider.id === "bedrock" ? {
|
|
904
|
+
runtimeConfigured: provider.configuration.runtimeConfigured === true,
|
|
905
|
+
runtimeValid: provider.configuration.runtimeValid !== false,
|
|
906
|
+
regionConfigured: provider.configuration.regionConfigured === true,
|
|
907
|
+
defaultRegionConfigured: provider.configuration.defaultRegionConfigured === true,
|
|
908
|
+
profileConfigured: provider.configuration.profileConfigured === true
|
|
909
|
+
} : {},
|
|
910
|
+
...provider.id === "azure-openai" ? {
|
|
911
|
+
apiVersionConfigured: provider.configuration.apiVersionConfigured === true,
|
|
912
|
+
deploymentsConfigured: provider.configuration.deploymentsConfigured === true
|
|
848
913
|
} : {}
|
|
849
914
|
}));
|
|
850
915
|
}
|
|
@@ -1383,7 +1448,7 @@ async function handleConsoleCompaction(command, deps) {
|
|
|
1383
1448
|
const provider = value.slice(0, separator);
|
|
1384
1449
|
const model = value.slice(separator + 1);
|
|
1385
1450
|
if (separator < 1 || !PROVIDERS.includes(provider) || !/^[a-zA-Z0-9][a-zA-Z0-9._:/-]{0,159}$/.test(model)) {
|
|
1386
|
-
write(
|
|
1451
|
+
write(`Use /compaction provider:model with ${PROVIDERS.slice(0, -1).join(", ")} or ${PROVIDERS.at(-1)}; /compaction off disables model-assisted compaction.`);
|
|
1387
1452
|
return true;
|
|
1388
1453
|
}
|
|
1389
1454
|
await deps.replaceOptions({ ...deps.options, compactionProvider: provider, compactionModel: model });
|
|
@@ -2493,474 +2558,6 @@ ${summarizeApproval(approval)}
|
|
|
2493
2558
|
|
|
2494
2559
|
// src/cli/governance-report.ts
|
|
2495
2560
|
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
2561
|
async function governanceReportCli(options, config, store) {
|
|
2965
2562
|
let index;
|
|
2966
2563
|
let history;
|
|
@@ -3415,17 +3012,17 @@ async function readBackupTransport(source, legacyMaxBytes) {
|
|
|
3415
3012
|
}
|
|
3416
3013
|
|
|
3417
3014
|
// src/persistence/state-backup.ts
|
|
3418
|
-
import { createHash as
|
|
3015
|
+
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
3419
3016
|
import { constants as fsConstants2 } from "node:fs";
|
|
3420
3017
|
import { chmod, link, lstat as lstat2, open, realpath, unlink } from "node:fs/promises";
|
|
3421
3018
|
import path4 from "node:path";
|
|
3422
|
-
import { z
|
|
3019
|
+
import { z } from "zod";
|
|
3423
3020
|
import { normalizeAgentRunState } from "@zhivex-ai/agents";
|
|
3424
3021
|
import { createSqliteAgentRunStore } from "@zhivex-ai/agents/ops";
|
|
3425
3022
|
|
|
3426
3023
|
// src/persistence/sdk-store-identity.ts
|
|
3427
|
-
import { createHash as
|
|
3428
|
-
var sdkCanonicalKey = (kind, scope, value) => `${kind}:v2:${
|
|
3024
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
3025
|
+
var sdkCanonicalKey = (kind, scope, value) => `${kind}:v2:${createHash2("sha256").update(JSON.stringify([
|
|
3429
3026
|
JSON.stringify([scope.namespace ?? null, scope.tenantId, scope.userId ?? null]),
|
|
3430
3027
|
value
|
|
3431
3028
|
])).digest("hex")}`;
|
|
@@ -3437,128 +3034,128 @@ var HARNESS_STATE_BACKUP_SCHEMA_VERSION = 1;
|
|
|
3437
3034
|
var HARNESS_STATE_BACKUP_MAX_BYTES = 64 * 1024 * 1024;
|
|
3438
3035
|
var terminalRunStatuses = new Set(["completed", "failed", "cancelled", "timed_out"]);
|
|
3439
3036
|
var terminalSessionStatuses = new Set(["completed", "failed", "cancelled", "timed_out"]);
|
|
3440
|
-
var digestSchema =
|
|
3441
|
-
var bindingKeySchema =
|
|
3442
|
-
var jsonRecordSchema =
|
|
3443
|
-
var durableScopeSchema =
|
|
3444
|
-
tenantId:
|
|
3445
|
-
userId:
|
|
3446
|
-
namespace:
|
|
3037
|
+
var digestSchema = z.string().regex(/^sha256:[a-f0-9]{64}$/);
|
|
3038
|
+
var bindingKeySchema = z.string().regex(/^[a-f0-9]{64}$/);
|
|
3039
|
+
var jsonRecordSchema = z.record(z.string(), z.unknown());
|
|
3040
|
+
var durableScopeSchema = z.object({
|
|
3041
|
+
tenantId: z.string().min(1),
|
|
3042
|
+
userId: z.string().min(1).optional(),
|
|
3043
|
+
namespace: z.string().min(1).optional()
|
|
3447
3044
|
}).strict();
|
|
3448
|
-
var journalEntrySchema =
|
|
3449
|
-
runId:
|
|
3045
|
+
var journalEntrySchema = z.object({
|
|
3046
|
+
runId: z.string().min(1),
|
|
3450
3047
|
scope: durableScopeSchema,
|
|
3451
|
-
toolCallId:
|
|
3452
|
-
toolName:
|
|
3453
|
-
status:
|
|
3454
|
-
idempotencyKey:
|
|
3455
|
-
revision:
|
|
3456
|
-
input:
|
|
3457
|
-
output:
|
|
3458
|
-
error:
|
|
3459
|
-
startedAt:
|
|
3460
|
-
completedAt:
|
|
3461
|
-
updatedAt:
|
|
3048
|
+
toolCallId: z.string().min(1),
|
|
3049
|
+
toolName: z.string().min(1),
|
|
3050
|
+
status: z.enum(["pending", "running", "completed", "failed"]),
|
|
3051
|
+
idempotencyKey: z.string().min(1),
|
|
3052
|
+
revision: z.number().int().nonnegative(),
|
|
3053
|
+
input: z.json().optional(),
|
|
3054
|
+
output: z.json().optional(),
|
|
3055
|
+
error: z.object({ message: z.string() }).strict().optional(),
|
|
3056
|
+
startedAt: z.number().nonnegative().optional(),
|
|
3057
|
+
completedAt: z.number().nonnegative().optional(),
|
|
3058
|
+
updatedAt: z.number().nonnegative()
|
|
3462
3059
|
}).passthrough();
|
|
3463
|
-
var runRecordSchema =
|
|
3464
|
-
key:
|
|
3060
|
+
var runRecordSchema = z.object({
|
|
3061
|
+
key: z.string().min(1).max(1024),
|
|
3465
3062
|
state: jsonRecordSchema,
|
|
3466
|
-
updatedAt:
|
|
3063
|
+
updatedAt: z.number().int().nonnegative()
|
|
3467
3064
|
}).strict();
|
|
3468
|
-
var journalRecordSchema =
|
|
3469
|
-
runKey:
|
|
3470
|
-
toolCallId:
|
|
3065
|
+
var journalRecordSchema = z.object({
|
|
3066
|
+
runKey: z.string().min(1).max(1024),
|
|
3067
|
+
toolCallId: z.string().min(1).max(1024),
|
|
3471
3068
|
entry: journalEntrySchema,
|
|
3472
|
-
revision:
|
|
3473
|
-
updatedAt:
|
|
3069
|
+
revision: z.number().int().nonnegative(),
|
|
3070
|
+
updatedAt: z.number().int().nonnegative()
|
|
3474
3071
|
}).strict();
|
|
3475
|
-
var idempotencyRecordSchema =
|
|
3476
|
-
key:
|
|
3477
|
-
runKey:
|
|
3478
|
-
updatedAt:
|
|
3072
|
+
var idempotencyRecordSchema = z.object({
|
|
3073
|
+
key: z.string().min(1).max(1024),
|
|
3074
|
+
runKey: z.string().min(1).max(1024),
|
|
3075
|
+
updatedAt: z.number().int().nonnegative()
|
|
3479
3076
|
}).strict();
|
|
3480
|
-
var parentRecordSchema =
|
|
3481
|
-
runKey:
|
|
3482
|
-
parentRunKey:
|
|
3483
|
-
updatedAt:
|
|
3077
|
+
var parentRecordSchema = z.object({
|
|
3078
|
+
runKey: z.string().min(1).max(1024),
|
|
3079
|
+
parentRunKey: z.string().min(1).max(1024),
|
|
3080
|
+
updatedAt: z.number().int().nonnegative()
|
|
3484
3081
|
}).strict();
|
|
3485
|
-
var memoryRecordSchema =
|
|
3486
|
-
key:
|
|
3487
|
-
messages:
|
|
3488
|
-
updatedAt:
|
|
3082
|
+
var memoryRecordSchema = z.object({
|
|
3083
|
+
key: z.string().min(1).max(1024),
|
|
3084
|
+
messages: z.array(z.unknown()),
|
|
3085
|
+
updatedAt: z.number().int().nonnegative()
|
|
3489
3086
|
}).strict();
|
|
3490
3087
|
var serializedMemory = (entry) => JSON.stringify(entry.key.startsWith("agent-memory:v2:") ? { schemaVersion: 1, memoryKey: entry.key, messages: entry.messages } : entry.messages);
|
|
3491
3088
|
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 =
|
|
3493
|
-
sessionId:
|
|
3089
|
+
var sessionRecordSchema = z.object({
|
|
3090
|
+
sessionId: z.string().min(1).max(260),
|
|
3494
3091
|
workspaceKey: bindingKeySchema,
|
|
3495
3092
|
scopeKey: bindingKeySchema,
|
|
3496
|
-
title:
|
|
3497
|
-
parentSessionId:
|
|
3498
|
-
forkedFromTurnId:
|
|
3499
|
-
revision:
|
|
3500
|
-
activitySequence:
|
|
3501
|
-
createdAt:
|
|
3502
|
-
updatedAt:
|
|
3503
|
-
archivedAt:
|
|
3504
|
-
deletedAt:
|
|
3505
|
-
metadataBytes:
|
|
3093
|
+
title: z.string().nullable(),
|
|
3094
|
+
parentSessionId: z.string().nullable(),
|
|
3095
|
+
forkedFromTurnId: z.string().nullable(),
|
|
3096
|
+
revision: z.number().int().nonnegative(),
|
|
3097
|
+
activitySequence: z.number().int().nonnegative(),
|
|
3098
|
+
createdAt: z.number().int().nonnegative(),
|
|
3099
|
+
updatedAt: z.number().int().nonnegative(),
|
|
3100
|
+
archivedAt: z.number().int().nonnegative().nullable(),
|
|
3101
|
+
deletedAt: z.number().int().nonnegative().nullable(),
|
|
3102
|
+
metadataBytes: z.number().int().nonnegative()
|
|
3506
3103
|
}).strict();
|
|
3507
|
-
var sessionRunRecordSchema =
|
|
3508
|
-
turnId:
|
|
3509
|
-
sourceTurnId:
|
|
3510
|
-
sessionId:
|
|
3511
|
-
ordinal:
|
|
3512
|
-
runId:
|
|
3513
|
-
provider:
|
|
3514
|
-
model:
|
|
3515
|
-
role:
|
|
3516
|
-
status:
|
|
3517
|
-
createdAt:
|
|
3518
|
-
updatedAt:
|
|
3519
|
-
completedAt:
|
|
3520
|
-
metadataBytes:
|
|
3104
|
+
var sessionRunRecordSchema = z.object({
|
|
3105
|
+
turnId: z.string().min(1).max(260),
|
|
3106
|
+
sourceTurnId: z.string().nullable(),
|
|
3107
|
+
sessionId: z.string().min(1).max(260),
|
|
3108
|
+
ordinal: z.number().int().nonnegative(),
|
|
3109
|
+
runId: z.string().min(1).max(260),
|
|
3110
|
+
provider: z.string().min(1).max(260),
|
|
3111
|
+
model: z.string().min(1).max(260),
|
|
3112
|
+
role: z.string().nullable(),
|
|
3113
|
+
status: z.string().min(1),
|
|
3114
|
+
createdAt: z.number().int().nonnegative(),
|
|
3115
|
+
updatedAt: z.number().int().nonnegative(),
|
|
3116
|
+
completedAt: z.number().int().nonnegative().nullable(),
|
|
3117
|
+
metadataBytes: z.number().int().nonnegative()
|
|
3521
3118
|
}).strict();
|
|
3522
|
-
var checkpointRecordSchema =
|
|
3523
|
-
|
|
3524
|
-
id:
|
|
3119
|
+
var checkpointRecordSchema = z.discriminatedUnion("kind", [
|
|
3120
|
+
z.object({
|
|
3121
|
+
id: z.string().uuid(),
|
|
3525
3122
|
workspaceKey: bindingKeySchema,
|
|
3526
3123
|
scopeKey: bindingKeySchema,
|
|
3527
|
-
kind:
|
|
3124
|
+
kind: z.literal("checkpoint"),
|
|
3528
3125
|
body: workspaceCheckpointSchema
|
|
3529
3126
|
}).strict(),
|
|
3530
|
-
|
|
3531
|
-
id:
|
|
3127
|
+
z.object({
|
|
3128
|
+
id: z.string().uuid(),
|
|
3532
3129
|
workspaceKey: bindingKeySchema,
|
|
3533
3130
|
scopeKey: bindingKeySchema,
|
|
3534
|
-
kind:
|
|
3131
|
+
kind: z.literal("restore"),
|
|
3535
3132
|
body: workspaceRestoreOperationSchema
|
|
3536
3133
|
}).strict()
|
|
3537
3134
|
]);
|
|
3538
3135
|
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 =
|
|
3540
|
-
schemaVersion:
|
|
3541
|
-
kind:
|
|
3542
|
-
createdAt:
|
|
3543
|
-
binding:
|
|
3136
|
+
var stateBackupPayloadSchema = z.object({
|
|
3137
|
+
schemaVersion: z.literal(HARNESS_STATE_BACKUP_SCHEMA_VERSION),
|
|
3138
|
+
kind: z.literal("state-backup"),
|
|
3139
|
+
createdAt: z.iso.datetime({ precision: 3 }),
|
|
3140
|
+
binding: z.object({
|
|
3544
3141
|
workspaceKey: bindingKeySchema,
|
|
3545
3142
|
scopeKey: bindingKeySchema,
|
|
3546
|
-
scopePrefix:
|
|
3143
|
+
scopePrefix: z.string().min(1).max(1024)
|
|
3547
3144
|
}).strict(),
|
|
3548
|
-
schemas:
|
|
3549
|
-
operations:
|
|
3550
|
-
sessions:
|
|
3145
|
+
schemas: z.object({
|
|
3146
|
+
operations: z.literal(HARNESS_OPERATIONS_SCHEMA_VERSION),
|
|
3147
|
+
sessions: z.literal(HARNESS_SESSION_SCHEMA_VERSION)
|
|
3551
3148
|
}).strict(),
|
|
3552
|
-
records:
|
|
3553
|
-
runs:
|
|
3554
|
-
toolJournal:
|
|
3555
|
-
idempotency:
|
|
3556
|
-
parents:
|
|
3557
|
-
memory:
|
|
3558
|
-
sessions:
|
|
3559
|
-
sessionRuns:
|
|
3560
|
-
workspaceCheckpoints:
|
|
3561
|
-
budgetLedgers:
|
|
3149
|
+
records: z.object({
|
|
3150
|
+
runs: z.array(runRecordSchema),
|
|
3151
|
+
toolJournal: z.array(journalRecordSchema),
|
|
3152
|
+
idempotency: z.array(idempotencyRecordSchema),
|
|
3153
|
+
parents: z.array(parentRecordSchema),
|
|
3154
|
+
memory: z.array(memoryRecordSchema),
|
|
3155
|
+
sessions: z.array(sessionRecordSchema),
|
|
3156
|
+
sessionRuns: z.array(sessionRunRecordSchema),
|
|
3157
|
+
workspaceCheckpoints: z.array(checkpointRecordSchema).max(100).optional(),
|
|
3158
|
+
budgetLedgers: z.array(runRecordSchema).optional()
|
|
3562
3159
|
}).strict()
|
|
3563
3160
|
}).strict();
|
|
3564
3161
|
var stateBackupBundleSchema = stateBackupPayloadSchema.extend({ checksum: digestSchema }).strict();
|
|
@@ -3570,12 +3167,12 @@ var canonicalJson = (value) => {
|
|
|
3570
3167
|
return `{${Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(",")}}`;
|
|
3571
3168
|
};
|
|
3572
3169
|
var checksumPayload = (payload) => {
|
|
3573
|
-
const hash =
|
|
3170
|
+
const hash = createHash3("sha256");
|
|
3574
3171
|
for (const chunk of canonicalChunks(payload))
|
|
3575
3172
|
hash.update(chunk);
|
|
3576
3173
|
return `sha256:${hash.digest("hex")}`;
|
|
3577
3174
|
};
|
|
3578
|
-
var stableKey = (kind, value) =>
|
|
3175
|
+
var stableKey = (kind, value) => createHash3("sha256").update(kind).update("\x00").update(value).digest("hex");
|
|
3579
3176
|
var scopeValue = (config) => `${config.scope.tenantId}\x00${config.scope.userId ?? ""}\x00${config.scope.namespace ?? ""}`;
|
|
3580
3177
|
var scopePrefix = (config) => `${encodeURIComponent(config.scope.namespace ?? "default")}:${encodeURIComponent(config.scope.tenantId)}:${encodeURIComponent(config.scope.userId ?? "*")}:`;
|
|
3581
3178
|
var stateMatchesScope = (config, state) => {
|
|
@@ -3778,10 +3375,10 @@ var readPayload = async (config, recordedWorkspace, accessLease) => {
|
|
|
3778
3375
|
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
3376
|
const value = JSON.parse(row.messages_json);
|
|
3780
3377
|
if (row.memory_key.startsWith("agent-memory:v2:")) {
|
|
3781
|
-
const envelope =
|
|
3378
|
+
const envelope = z.strictObject({ schemaVersion: z.literal(1), memoryKey: z.literal(row.memory_key), messages: z.array(z.unknown()) }).parse(value);
|
|
3782
3379
|
return { key: row.memory_key, messages: envelope.messages, updatedAt: row.updated_at_ms };
|
|
3783
3380
|
}
|
|
3784
|
-
return { key: row.memory_key, messages:
|
|
3381
|
+
return { key: row.memory_key, messages: z.array(z.unknown()).parse(value), updatedAt: row.updated_at_ms };
|
|
3785
3382
|
});
|
|
3786
3383
|
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
3384
|
const selectedSessionIds = new Set(sessionRows.map((row) => row.session_id));
|
|
@@ -4066,7 +3663,7 @@ var validateBundleBinding = async (config, bundle) => {
|
|
|
4066
3663
|
const turn = bundle.records.sessionRuns.find((run) => run.turnId === checkpoint.turnId && run.sessionId === checkpoint.sessionId);
|
|
4067
3664
|
if (!turn || !terminalSessionStatuses.has(turn.status))
|
|
4068
3665
|
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:${
|
|
3666
|
+
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
3667
|
throw new HarnessStateConflictError("Checkpoint content identity is invalid.");
|
|
4071
3668
|
}
|
|
4072
3669
|
if (record.kind === "restore") {
|
|
@@ -4488,7 +4085,7 @@ var main = async (argv = process.argv.slice(2)) => {
|
|
|
4488
4085
|
parsedOptions = { ...parsedOptions, prompt: await readStdinTask() };
|
|
4489
4086
|
}
|
|
4490
4087
|
if (parsedOptions.serviceFile) {
|
|
4491
|
-
const { runServiceCli } = await import("./service-client-cli-
|
|
4088
|
+
const { runServiceCli } = await import("./service-client-cli-eqrdc9zq.js");
|
|
4492
4089
|
await runServiceCli(parsedOptions, annotateCliStreamError);
|
|
4493
4090
|
return;
|
|
4494
4091
|
}
|
|
@@ -4551,6 +4148,12 @@ var main = async (argv = process.argv.slice(2)) => {
|
|
|
4551
4148
|
case "state":
|
|
4552
4149
|
await manageState(options);
|
|
4553
4150
|
return;
|
|
4151
|
+
case "export-audit":
|
|
4152
|
+
case "verify-audit": {
|
|
4153
|
+
const { auditPackCli } = await import("./audit-pack-e4vaq7np.js");
|
|
4154
|
+
await auditPackCli(options);
|
|
4155
|
+
return;
|
|
4156
|
+
}
|
|
4554
4157
|
case "run":
|
|
4555
4158
|
await runOnce(options);
|
|
4556
4159
|
return;
|