@zhivex-ai/harness 1.4.1 → 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.
- package/CHANGELOG.md +3 -0
- package/README.md +1 -1
- package/SUPPORT.md +1 -1
- package/contracts/stable-api-signatures.json +7 -7
- package/dist/acp-cli.js +10 -10
- package/dist/approvals/approval-diff.d.ts +2 -1
- package/dist/approvals/approval-preview.d.ts +1 -1
- package/dist/audit/index.js +6 -6
- package/dist/{audit-pack-e4vaq7np.js → audit-pack-kvw7ng34.js} +3 -3
- package/dist/{cli-entry-rgs6bxmy.js → cli-entry-75j3r49b.js} +2 -2
- package/dist/{cli-entry-7f0cen32.js → cli-entry-928p8h41.js} +135 -58
- package/dist/{cli-entry-a890x3kq.js → cli-entry-h2yc9x37.js} +7 -5
- package/dist/{cli-entry-3s63zn4w.js → cli-entry-q8bgkn9m.js} +1 -1
- package/dist/{cli-1cf4dcnj.js → cli-vyrytn3m.js} +14 -8
- package/dist/cli.js +2 -2
- package/dist/compat/code-support.js +8 -8
- package/dist/engine/acp.js +11 -11
- package/dist/engine/client.js +10 -10
- package/dist/engine/desktop-state-v1.js +6 -6
- package/dist/engine/index.js +15 -15
- package/dist/engine/mcp-stdio-v1.js +5 -5
- package/dist/engine/service.js +11 -11
- package/dist/hostile-repository-demo.js +138 -60
- package/dist/{index-dtb2c6ds.js → index-5zbq9ztj.js} +2 -2
- package/dist/{index-6599mpmy.js → index-63gbp0cz.js} +3 -3
- package/dist/{index-xdbkcccf.js → index-6dxrbnxm.js} +2 -2
- package/dist/{index-0zs2dz26.js → index-6fp7kdpx.js} +10 -9
- package/dist/{index-mv8sb1ns.js → index-96ezrvg2.js} +55 -13
- package/dist/{index-wm9xeq1n.js → index-bt2p8x7r.js} +1 -1
- package/dist/{index-sk3cap35.js → index-eps3c3g6.js} +1 -1
- package/dist/{index-zxg4ve4j.js → index-fqqz1yt8.js} +77 -4
- package/dist/{index-d9zkmhz3.js → index-ggstwr0v.js} +53 -18
- package/dist/{index-j6zxnc8m.js → index-jpdvn09j.js} +5 -5
- package/dist/{index-4fx5f3k5.js → index-pq3kz1r8.js} +1 -1
- package/dist/{index-02pqtbbg.js → index-vc7yxz50.js} +10 -10
- package/dist/{index-crta5wzv.js → index-vvzc5ezz.js} +4 -4
- package/dist/{index-f6mqa5gk.js → index-wwthv10a.js} +11 -39
- package/dist/{index-74kkpyqk.js → index-xfedewpt.js} +12 -6
- package/dist/{index-sstgcsr0.js → index-yx52bt4a.js} +1 -1
- package/dist/index.js +14 -14
- package/dist/integrations/mcp-stdio-tools.d.ts +4 -1
- package/dist/runtime/budget-ledger-scope.d.ts +14 -0
- package/dist/service-cli.js +11 -11
- package/dist/{service-client-cli-eqrdc9zq.js → service-client-cli-v6qptg9x.js} +4 -4
- package/dist/tools/workspace.d.ts +2 -2
- package/dist/verify-historical-migrations.js +143 -62
- package/dist/workspace/edit-contracts.d.ts +2 -2
- package/dist/workspace/path-policy.d.ts +2 -1
- package/dist/workspace/workspace.d.ts +13 -0
- package/dist/zhx.js +2 -2
- package/docs/CODE_RELEASE.md +28 -6
- package/docs/CODE_WEB_TASKS.md +1 -1
- package/docs/ENGINE_API.md +1 -1
- package/docs/EXTENSIBILITY.md +6 -2
- package/docs/FIRST_USE.md +6 -6
- package/docs/PROJECT_MEMORY.md +1 -1
- package/docs/PUBLIC_SECURITY.md +14 -1
- package/docs/REPOSITORY_EDITING.md +1 -1
- package/docs/TOOL_POLICY.md +4 -1
- package/docs/adr/0002-isolated-mcp-stdio.md +1 -1
- package/evaluations/representative-assembly-matrix.json +10 -1
- package/examples/README.md +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,9 @@ The project follows Semantic Versioning. During `0.x`, minor releases may change
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 1.5.0 - 2026-10-16
|
|
10
|
+
|
|
11
|
+
- Prepare minor Harness 1.5.0 and Code 0.4.0 for npm `latest`. The minor covers the new experimental audit pack, provisional Bedrock and Azure OpenAI routes, and Code web task control; stable root exports and command contracts are unchanged. It ships with the exact Code engine pin, private Desktop binding and an additive representative mapping for `v1.5.0` using the unchanged Meta, Qwen and OpenAI models. Published `latest` is Harness 1.4.1 and Code 0.3.2. Tags and publication follow only through the protected release workflows.
|
|
9
12
|
- Add provisional Amazon Bedrock and Azure OpenAI routes. Bedrock pins `@zhivex-ai/bedrock@2.0.7` (Converse uses the AWS credential chain and region and reports Tier B; `BEDROCK_RUNTIME=openai` is the Tier A path). Azure OpenAI pins `@zhivex-ai/azure-openai@0.7.8` (https endpoint, API key, optional API version and deployments map). Core is `@zhivex-ai/core@1.34.0`, which those adapters require. An incomplete Bedrock or Azure environment stays out of the durable transport fingerprint. Desktop forwards the selected route's environment credentials through the worker bootstrap. These routes are uncertified: no live calls, no default certification cohort, and no publish or tags.
|
|
10
13
|
- Add an experimental audit pack on `@zhivex-ai/harness/audit`. `zhx export-audit <task-id> --out <directory>` writes one directory per run, or one directory containing every run on a guided task account. The pack reuses the governance report, every approval decision page up to 512 records, the durable redacted activity journal as JSONL, and the usage ledger projection plus transport summary. Approvals, usage, and the governance report come from one captured run snapshot. A change to that run, its journal, or the task account before signing fails with `AUDIT_PACK_STATE_CHANGED` and writes nothing. The 32 MiB limit includes `manifest.json`. `zhx verify-audit --out <directory>` checks the manifest hashes and an HMAC-SHA256 seal without resolving provider, store, or budget configuration. The signing key is `ZHIVEX_AUDIT_SIGNING_KEY` or `--signing-key-file` and is not stored in the pack. Stable root exports, stable declaration signatures, and existing command option contracts are unchanged. This note does not publish a release.
|
|
11
14
|
- Add experimental Code web task definition, bounded exact delivery review, explicit human acceptance, requirement correction, and budgeted continuation through additive host-owned client commands. Keep check verification, human decisions, and provider usage uncertainty distinct. Failed pre-admission continuations retain scoped previous evidence without inventing budget admissions; ordinary chat cannot bypass a governed task's budget.
|
package/README.md
CHANGED
|
@@ -159,6 +159,6 @@ Contracts, stability tiers, and the experimental ACP and MCP entry points are in
|
|
|
159
159
|
|
|
160
160
|
## Releases
|
|
161
161
|
|
|
162
|
-
Version `1.4.
|
|
162
|
+
Version `1.4.1` is the current public npm release. The paired Code package on npm `latest` is `0.3.2`. This checkout prepares Version `1.5.0` and Code `0.4.0` for `latest`. That publication is pending, so the quick start above follows the published `latest` tag. npm `next` is Harness `1.4.0-rc.8` and Code `0.3.0-rc.8`. Confirm dist-tags on the [Code versions](https://www.npmjs.com/package/@zhivex-ai/code?activeTab=versions) and [Harness versions](https://www.npmjs.com/package/@zhivex-ai/harness?activeTab=versions) pages before you install a prerelease.
|
|
163
163
|
|
|
164
164
|
Release channels, publication, and certification records are in the [release procedure](https://github.com/Zhivex/zhivex-harness/blob/main/docs/RELEASE.md). Releases are verified with npm provenance. Source in this checkout can be newer than the public package. See the [changelog](CHANGELOG.md) and the [repository release status](https://raw.githubusercontent.com/Zhivex/zhivex-harness/main/release-status.json).
|
package/SUPPORT.md
CHANGED
|
@@ -13,7 +13,7 @@ The 1.1 support scope is tracked in the [machine-readable support matrix](./docs
|
|
|
13
13
|
- the provider/model combinations marked certified in the package documentation; and
|
|
14
14
|
- HTTPS or explicitly allowed loopback-HTTP MCP endpoints using the documented bounded JSON-RPC subset.
|
|
15
15
|
|
|
16
|
-
Only the most recent published stable minor receives routine fixes. The exact `v1.3.0` tag passed the protected artifact, six-provider live and 42-case representative release jobs. Harness 1.3.x and Code 0.2.x are the supported stable lines until 1.
|
|
16
|
+
Only the most recent published stable minor receives routine fixes. The exact `v1.3.0` tag passed the protected artifact, six-provider live and 42-case representative release jobs. Harness 1.3.x and Code 0.2.x are the supported stable lines until 1.5.0 and Code 0.4.0 complete verified publication. Gemini, Anthropic and Vertex remain provisional despite the release-bound live gates; the representative repository matrix covers only Meta, Qwen and OpenAI. Live provider evidence is account-, model-, endpoint-, artifact-, and date-dependent; see [docs/LIVE_CERTIFICATION.md](https://github.com/Zhivex/zhivex-harness/blob/main/docs/LIVE_CERTIFICATION.md).
|
|
17
17
|
|
|
18
18
|
## Installation diagnostics
|
|
19
19
|
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
"name": "Workspace",
|
|
128
|
-
"sha256": "sha256:
|
|
128
|
+
"sha256": "sha256:42b53815d22e2734371ae5360f059779516f7304bc9a1941dc208d12b67f6a60"
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
131
|
"name": "appendUserMessage",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"name": "createHarness",
|
|
168
|
-
"sha256": "sha256:
|
|
168
|
+
"sha256": "sha256:0bf4f22db95c409dfa85fce488984f06efa84491fc7d4ef2351a053ea32701f3"
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
171
|
"name": "createHarnessMcpTools",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
175
|
"name": "createHarnessOciExecutionEnvironment",
|
|
176
|
-
"sha256": "sha256:
|
|
176
|
+
"sha256": "sha256:6ae2d5238e49299c4c0ee9d9b5f0ddae4de86db9387c8469f7fd6f4518e20e6e"
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
179
|
"name": "createHarnessStateBackup",
|
|
@@ -273,7 +273,7 @@
|
|
|
273
273
|
},
|
|
274
274
|
{
|
|
275
275
|
"name": "runHarness",
|
|
276
|
-
"sha256": "sha256:
|
|
276
|
+
"sha256": "sha256:82a768885893267b4c24aae1923726ae59c048f73c34ce1e92d0355981c6d46a"
|
|
277
277
|
},
|
|
278
278
|
{
|
|
279
279
|
"name": "serializeStreamEvent",
|
|
@@ -427,7 +427,7 @@
|
|
|
427
427
|
},
|
|
428
428
|
{
|
|
429
429
|
"name": "HarnessExecutionSession",
|
|
430
|
-
"sha256": "sha256:
|
|
430
|
+
"sha256": "sha256:15843c59747ef8d072a66f19c88031a2a2981be3cdebf3aabb836132b6f7c4b9"
|
|
431
431
|
},
|
|
432
432
|
{
|
|
433
433
|
"name": "HarnessMcpConfiguration",
|
|
@@ -487,8 +487,8 @@
|
|
|
487
487
|
},
|
|
488
488
|
{
|
|
489
489
|
"name": "ZhivexHarness",
|
|
490
|
-
"sha256": "sha256:
|
|
490
|
+
"sha256": "sha256:2911bde71fdae2dff26f766d068c560375757fb6575f5aaec02ff3346c46ab94"
|
|
491
491
|
}
|
|
492
492
|
],
|
|
493
|
-
"digest": "sha256:
|
|
493
|
+
"digest": "sha256:50be2a81cd0e7601d5610008081c406cecf9855c5ffd42d2faffba521b08873e"
|
|
494
494
|
}
|
package/dist/acp-cli.js
CHANGED
|
@@ -11,14 +11,14 @@ import {
|
|
|
11
11
|
} from "./index-3ah1f369.js";
|
|
12
12
|
import {
|
|
13
13
|
createHarnessClientAdapter
|
|
14
|
-
} from "./index-
|
|
15
|
-
import"./index-
|
|
14
|
+
} from "./index-vc7yxz50.js";
|
|
15
|
+
import"./index-63gbp0cz.js";
|
|
16
16
|
import {
|
|
17
17
|
createHarness
|
|
18
|
-
} from "./index-
|
|
19
|
-
import"./index-
|
|
20
|
-
import"./index-
|
|
21
|
-
import"./index-
|
|
18
|
+
} from "./index-6fp7kdpx.js";
|
|
19
|
+
import"./index-wwthv10a.js";
|
|
20
|
+
import"./index-5zbq9ztj.js";
|
|
21
|
+
import"./index-ggstwr0v.js";
|
|
22
22
|
import {
|
|
23
23
|
HARNESS_REQUIRED_CAPABILITIES,
|
|
24
24
|
HARNESS_SUBAGENT_PROFILES,
|
|
@@ -31,17 +31,17 @@ import {
|
|
|
31
31
|
} from "./index-1265j7t2.js";
|
|
32
32
|
import"./index-c39197wq.js";
|
|
33
33
|
import"./index-mzydbzp8.js";
|
|
34
|
-
import"./index-
|
|
34
|
+
import"./index-bt2p8x7r.js";
|
|
35
35
|
import {
|
|
36
36
|
usagePricingSchema
|
|
37
|
-
} from "./index-
|
|
38
|
-
import"./index-
|
|
37
|
+
} from "./index-fqqz1yt8.js";
|
|
38
|
+
import"./index-pq3kz1r8.js";
|
|
39
39
|
import {
|
|
40
40
|
FileChangedWhileReadingError,
|
|
41
41
|
FileSizeLimitError,
|
|
42
42
|
UnsafeFileTypeError,
|
|
43
43
|
readRegularFileNoFollow
|
|
44
|
-
} from "./index-
|
|
44
|
+
} from "./index-6dxrbnxm.js";
|
|
45
45
|
import"./index-4gt045j0.js";
|
|
46
46
|
import {
|
|
47
47
|
HarnessConfigError,
|
|
@@ -14,6 +14,7 @@ declare const file: z.ZodObject<{
|
|
|
14
14
|
operation: z.ZodOptional<z.ZodEnum<{
|
|
15
15
|
create: "create";
|
|
16
16
|
delete: "delete";
|
|
17
|
+
restore: "restore";
|
|
17
18
|
update: "update";
|
|
18
19
|
}>>;
|
|
19
20
|
}, z.core.$strict>;
|
|
@@ -37,7 +38,7 @@ export declare function captureApprovalDiffs(state: AgentRunState, run: HarnessC
|
|
|
37
38
|
afterDigest: string | null;
|
|
38
39
|
beforeMode?: number | undefined;
|
|
39
40
|
afterMode?: number | undefined;
|
|
40
|
-
operation?: "create" | "delete" | "update" | undefined;
|
|
41
|
+
operation?: "create" | "delete" | "restore" | "update" | undefined;
|
|
41
42
|
}[];
|
|
42
43
|
}[];
|
|
43
44
|
/** Only expose saved content when exact journal effects certify every file. */
|
|
@@ -10,7 +10,7 @@ export interface ApprovalPreviewFile {
|
|
|
10
10
|
afterDigest: string | null;
|
|
11
11
|
beforeMode?: number;
|
|
12
12
|
afterMode?: number;
|
|
13
|
-
operation?: "create" | "update" | "delete";
|
|
13
|
+
operation?: "create" | "update" | "delete" | "restore";
|
|
14
14
|
}
|
|
15
15
|
export type ApprovalFilePreview = {
|
|
16
16
|
status: "complete";
|
package/dist/audit/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
exportHarnessGovernanceReport,
|
|
3
3
|
harnessGovernanceReportSchema
|
|
4
|
-
} from "../index-
|
|
5
|
-
import"../index-
|
|
4
|
+
} from "../index-jpdvn09j.js";
|
|
5
|
+
import"../index-yx52bt4a.js";
|
|
6
6
|
import {
|
|
7
7
|
APPROVAL_HISTORY_KEY,
|
|
8
8
|
approvalDecisionViews,
|
|
9
9
|
harnessPolicyDecisionEventSchema
|
|
10
|
-
} from "../index-
|
|
10
|
+
} from "../index-bt2p8x7r.js";
|
|
11
11
|
import {
|
|
12
12
|
TASK_BUDGET_ACCOUNT_KEY,
|
|
13
13
|
TaskBudget,
|
|
14
14
|
USAGE_LEDGER_KEY,
|
|
15
15
|
UsageLedger,
|
|
16
16
|
inspectUsageLedger
|
|
17
|
-
} from "../index-
|
|
17
|
+
} from "../index-fqqz1yt8.js";
|
|
18
18
|
import {
|
|
19
19
|
HARNESS_VERSION
|
|
20
|
-
} from "../index-
|
|
20
|
+
} from "../index-pq3kz1r8.js";
|
|
21
21
|
import {
|
|
22
22
|
readRegularFileNoFollow
|
|
23
|
-
} from "../index-
|
|
23
|
+
} from "../index-6dxrbnxm.js";
|
|
24
24
|
import"../index-bpc596v3.js";
|
|
25
25
|
import"../index-fm84men1.js";
|
|
26
26
|
import"../index-1bx83sw4.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
exportHarnessGovernanceReport,
|
|
3
3
|
harnessGovernanceReportSchema
|
|
4
|
-
} from "./cli-entry-
|
|
4
|
+
} from "./cli-entry-75j3r49b.js";
|
|
5
5
|
import {
|
|
6
6
|
APPROVAL_HISTORY_KEY,
|
|
7
7
|
CliUsageError,
|
|
@@ -17,10 +17,10 @@ import {
|
|
|
17
17
|
openHarnessPersistence,
|
|
18
18
|
readRegularFileNoFollow,
|
|
19
19
|
validateStateDirectory
|
|
20
|
-
} from "./cli-entry-
|
|
20
|
+
} from "./cli-entry-928p8h41.js";
|
|
21
21
|
import {
|
|
22
22
|
HARNESS_VERSION
|
|
23
|
-
} from "./cli-entry-
|
|
23
|
+
} from "./cli-entry-q8bgkn9m.js";
|
|
24
24
|
import {
|
|
25
25
|
resolveHarnessConfig
|
|
26
26
|
} from "./cli-entry-hdtfef27.js";
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
readTaskAcceptanceLedger,
|
|
11
11
|
taskCheckReceiptSchema,
|
|
12
12
|
verifyChangeEnvelope
|
|
13
|
-
} from "./cli-entry-
|
|
13
|
+
} from "./cli-entry-928p8h41.js";
|
|
14
14
|
import {
|
|
15
15
|
HARNESS_VERSION
|
|
16
|
-
} from "./cli-entry-
|
|
16
|
+
} from "./cli-entry-q8bgkn9m.js";
|
|
17
17
|
|
|
18
18
|
// src/persistence/governance-report.ts
|
|
19
19
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
CLI_OPTION_DEFINITIONS,
|
|
3
3
|
resolveHelpTopic,
|
|
4
4
|
validateCliCommandOptions
|
|
5
|
-
} from "./cli-entry-
|
|
5
|
+
} from "./cli-entry-q8bgkn9m.js";
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_PROVIDER_REGISTRY,
|
|
8
8
|
HARNESS_EXECUTION_POLICY_VERSION,
|
|
@@ -3656,8 +3656,8 @@ var quarantineFileInputSchema = z10.strictObject({
|
|
|
3656
3656
|
});
|
|
3657
3657
|
var restoreFileInputSchema = z10.strictObject({
|
|
3658
3658
|
quarantineId: z10.string().min(1).max(200).regex(/^[A-Za-z0-9._:-]+$/),
|
|
3659
|
-
destination: workspaceFilePathSchema.
|
|
3660
|
-
expectedDigest: fileDigestSchema.
|
|
3659
|
+
destination: workspaceFilePathSchema.describe("Required workspace path for the quarantined bytes. Restore does not fall back to the original path."),
|
|
3660
|
+
expectedDigest: fileDigestSchema.describe("Required sha256 of the quarantined bytes the operator reviewed.")
|
|
3661
3661
|
});
|
|
3662
3662
|
var mutationOperationSchema = z10.enum(["create", "update", "move", "quarantine", "restore"]);
|
|
3663
3663
|
var mutationAuditEntrySchema = z10.strictObject({
|
|
@@ -3997,10 +3997,10 @@ var runPortableProcess = async (command, options = {}) => {
|
|
|
3997
3997
|
// src/workspace/path-policy.ts
|
|
3998
3998
|
var HARD_IGNORES = new Set([".git", ".next", ".turbo", ".zhivex-harness", "coverage", "dist", "node_modules"]);
|
|
3999
3999
|
var isSensitiveName = (name) => {
|
|
4000
|
-
const normalized = name.
|
|
4000
|
+
const normalized = name.toLowerCase();
|
|
4001
4001
|
return normalized === ".env" || normalized.startsWith(".env.") && normalized !== ".env.example" || normalized === ".npmrc" || normalized === "id_rsa" || normalized === "id_ed25519" || [".key", ".pem", ".p12", ".pfx"].some((extension) => normalized.endsWith(extension));
|
|
4002
4002
|
};
|
|
4003
|
-
var isHardIgnored = (relativePath) => relativePath.split("/").some((segment) => HARD_IGNORES.has(segment.
|
|
4003
|
+
var isHardIgnored = (relativePath) => relativePath.split("/").some((segment) => HARD_IGNORES.has(segment.toLowerCase()) || isSensitiveName(segment));
|
|
4004
4004
|
|
|
4005
4005
|
// src/workspace/workspace.ts
|
|
4006
4006
|
var IGNORE_FILES = [".gitignore", ".zhivex-harnessignore"];
|
|
@@ -4280,7 +4280,7 @@ class Workspace {
|
|
|
4280
4280
|
throw new HarnessWorkspaceError(`The path escapes the workspace: ${relativePath}`);
|
|
4281
4281
|
const relative = wirePath(path11.relative(this.root, candidate));
|
|
4282
4282
|
if (relative && isHardIgnored(relative)) {
|
|
4283
|
-
const blocked = relative.split("/").find((segment) => HARD_IGNORES.has(segment.
|
|
4283
|
+
const blocked = relative.split("/").find((segment) => HARD_IGNORES.has(segment.toLowerCase()) || isSensitiveName(segment));
|
|
4284
4284
|
throw new HarnessWorkspaceError(`The path is protected by the harness policy: ${blocked}`);
|
|
4285
4285
|
}
|
|
4286
4286
|
return candidate;
|
|
@@ -5263,30 +5263,65 @@ class Workspace {
|
|
|
5263
5263
|
const audit = await this.audit({ operation: "quarantine", path: parsed.path, beforeDigest: source.digest, quarantineId });
|
|
5264
5264
|
return { quarantineId, path: parsed.path, digest: source.digest, audit };
|
|
5265
5265
|
}
|
|
5266
|
-
async
|
|
5267
|
-
return withWorkspaceMutation(this.root, () => this.restoreQuarantinedLocked(input));
|
|
5268
|
-
}
|
|
5269
|
-
async restoreQuarantinedLocked(input) {
|
|
5270
|
-
const parsed = restoreFileInputSchema.parse(input);
|
|
5271
|
-
this.checkAuditCapacity();
|
|
5266
|
+
async readRestorableQuarantine(quarantineId) {
|
|
5272
5267
|
const directory = await this.secureQuarantineDirectory(false);
|
|
5273
5268
|
let manifest;
|
|
5274
5269
|
try {
|
|
5275
|
-
const manifestFile = await this.readInternalRegularFile(path11.join(directory, `${
|
|
5270
|
+
const manifestFile = await this.readInternalRegularFile(path11.join(directory, `${quarantineId}.json`), "Quarantine manifest", 64 * 1024);
|
|
5276
5271
|
manifest = JSON.parse(manifestFile.contents.toString("utf8"));
|
|
5277
5272
|
} catch {
|
|
5278
|
-
throw new HarnessWorkspaceError(`Quarantine entry was not found: ${
|
|
5273
|
+
throw new HarnessWorkspaceError(`Quarantine entry was not found: ${quarantineId}.`);
|
|
5279
5274
|
}
|
|
5280
|
-
if (manifest.schemaVersion !== 1 || manifest.quarantineId !==
|
|
5281
|
-
throw new HarnessWorkspaceError(`Quarantine entry is not restorable: ${
|
|
5275
|
+
if (manifest.schemaVersion !== 1 || manifest.quarantineId !== quarantineId || manifest.status !== "quarantined") {
|
|
5276
|
+
throw new HarnessWorkspaceError(`Quarantine entry is not restorable: ${quarantineId}.`);
|
|
5282
5277
|
}
|
|
5283
|
-
const dataPath = path11.join(directory, `${
|
|
5278
|
+
const dataPath = path11.join(directory, `${quarantineId}.data`);
|
|
5284
5279
|
const dataFile = await this.readInternalRegularFile(dataPath, "Quarantine payload", MAX_FILE_BYTES);
|
|
5285
5280
|
const digest3 = digestBytes(dataFile.contents);
|
|
5286
|
-
if (digest3 !== manifest.digest
|
|
5281
|
+
if (digest3 !== manifest.digest) {
|
|
5282
|
+
throw new HarnessWorkspaceError(`Quarantine digest mismatch: ${quarantineId}.`);
|
|
5283
|
+
}
|
|
5284
|
+
return { manifest, dataPath, dataFile, digest: digest3 };
|
|
5285
|
+
}
|
|
5286
|
+
async previewRestore(input) {
|
|
5287
|
+
const parsed = restoreFileInputSchema.parse(input);
|
|
5288
|
+
const quarantined = await this.readRestorableQuarantine(parsed.quarantineId);
|
|
5289
|
+
if (parsed.expectedDigest !== quarantined.digest) {
|
|
5290
|
+
throw new HarnessWorkspaceError(`Quarantine digest mismatch: ${parsed.quarantineId}.`);
|
|
5291
|
+
}
|
|
5292
|
+
const destination = await this.safePath(parsed.destination, { allowMissing: true });
|
|
5293
|
+
if (destination.exists)
|
|
5294
|
+
throw new HarnessWorkspaceError(`Restore destination already exists: ${parsed.destination}.`);
|
|
5295
|
+
let after;
|
|
5296
|
+
try {
|
|
5297
|
+
after = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(quarantined.dataFile.contents);
|
|
5298
|
+
} catch {
|
|
5299
|
+
throw new HarnessWorkspaceError("Preview requires valid UTF-8 text.");
|
|
5300
|
+
}
|
|
5301
|
+
return {
|
|
5302
|
+
proposalId: parsed.expectedDigest,
|
|
5303
|
+
files: [{
|
|
5304
|
+
path: parsed.destination,
|
|
5305
|
+
expectedDigest: parsed.expectedDigest,
|
|
5306
|
+
before: null,
|
|
5307
|
+
after,
|
|
5308
|
+
afterDigest: quarantined.digest,
|
|
5309
|
+
operation: "restore"
|
|
5310
|
+
}]
|
|
5311
|
+
};
|
|
5312
|
+
}
|
|
5313
|
+
async restoreQuarantined(input) {
|
|
5314
|
+
return withWorkspaceMutation(this.root, () => this.restoreQuarantinedLocked(input));
|
|
5315
|
+
}
|
|
5316
|
+
async restoreQuarantinedLocked(input) {
|
|
5317
|
+
const parsed = restoreFileInputSchema.parse(input);
|
|
5318
|
+
this.checkAuditCapacity();
|
|
5319
|
+
const quarantined = await this.readRestorableQuarantine(parsed.quarantineId);
|
|
5320
|
+
if (parsed.expectedDigest !== quarantined.digest) {
|
|
5287
5321
|
throw new HarnessWorkspaceError(`Quarantine digest mismatch: ${parsed.quarantineId}.`);
|
|
5288
5322
|
}
|
|
5289
|
-
const
|
|
5323
|
+
const { manifest, dataPath, dataFile, digest: digest3 } = quarantined;
|
|
5324
|
+
const destinationPath = parsed.destination;
|
|
5290
5325
|
const destination = await this.safePath(destinationPath, { allowMissing: true });
|
|
5291
5326
|
if (destination.exists)
|
|
5292
5327
|
throw new HarnessWorkspaceError(`Restore destination already exists: ${destinationPath}.`);
|
|
@@ -6511,7 +6546,7 @@ var importPatch = async (runId, expectedPatchId, host, base, current2, maxFileWr
|
|
|
6511
6546
|
const rollbackErrors = [];
|
|
6512
6547
|
for (const item of [...quarantined].reverse()) {
|
|
6513
6548
|
try {
|
|
6514
|
-
await host.restoreQuarantined({ quarantineId: item.quarantineId, expectedDigest: item.digest });
|
|
6549
|
+
await host.restoreQuarantined({ quarantineId: item.quarantineId, destination: item.path, expectedDigest: item.digest });
|
|
6515
6550
|
} catch (rollbackError) {
|
|
6516
6551
|
rollbackErrors.push(rollbackError);
|
|
6517
6552
|
}
|
|
@@ -7885,6 +7920,79 @@ import { createAgentRunLedger } from "@zhivex-ai/agents/control-plane";
|
|
|
7885
7920
|
import { AsyncLocalStorage as AsyncLocalStorage5 } from "node:async_hooks";
|
|
7886
7921
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
7887
7922
|
import { z as z17 } from "zod";
|
|
7923
|
+
|
|
7924
|
+
// src/runtime/budget-ledger-scope.ts
|
|
7925
|
+
var BUDGET_LEDGER_NAMESPACE = "__zhivex_budget__";
|
|
7926
|
+
var BUDGET_OWNER_NAMESPACE_KEY = "budgetOwnerNamespace";
|
|
7927
|
+
var isReservedBudgetNamespace = (namespace) => namespace === BUDGET_LEDGER_NAMESPACE || (namespace?.startsWith(`${BUDGET_LEDGER_NAMESPACE}:`) ?? false);
|
|
7928
|
+
var budgetLedgerNamespace = (namespace) => {
|
|
7929
|
+
if (!namespace || isReservedBudgetNamespace(namespace)) {
|
|
7930
|
+
throw new HarnessStateConflictError("The budget ledger namespace is reserved.");
|
|
7931
|
+
}
|
|
7932
|
+
return `${BUDGET_LEDGER_NAMESPACE}:${namespace}`;
|
|
7933
|
+
};
|
|
7934
|
+
var budgetLedgerScope = (scope) => {
|
|
7935
|
+
if (scope.namespace && isReservedBudgetNamespace(scope.namespace)) {
|
|
7936
|
+
throw new HarnessStateConflictError("The budget ledger namespace is reserved.");
|
|
7937
|
+
}
|
|
7938
|
+
return {
|
|
7939
|
+
tenantId: scope.tenantId,
|
|
7940
|
+
...scope.userId ? { userId: scope.userId } : {},
|
|
7941
|
+
namespace: scope.namespace ? budgetLedgerNamespace(scope.namespace) : `${BUDGET_LEDGER_NAMESPACE}:`
|
|
7942
|
+
};
|
|
7943
|
+
};
|
|
7944
|
+
var sameIdentity = (left, right) => left?.tenantId === right.tenantId && (left.userId ?? undefined) === (right.userId ?? undefined);
|
|
7945
|
+
var bindBudgetLedgerStore = (primary, scope, budget = primary) => {
|
|
7946
|
+
const bound = budgetLedgerScope(scope);
|
|
7947
|
+
const ownerNamespace = scope.namespace ?? "";
|
|
7948
|
+
const isSdkBudget = (value) => sameIdentity(value, bound) && value?.namespace === BUDGET_LEDGER_NAMESPACE;
|
|
7949
|
+
const isBoundBudget = (value) => sameIdentity(value, bound) && value?.namespace === bound.namespace;
|
|
7950
|
+
const assertId = (id) => {
|
|
7951
|
+
if (!/^budget_[a-f0-9]{64}$/.test(id))
|
|
7952
|
+
throw new HarnessStateConflictError("Invalid budget ledger identity.");
|
|
7953
|
+
};
|
|
7954
|
+
const bindState = (state) => {
|
|
7955
|
+
const metadata = { ...state.metadata ?? {} };
|
|
7956
|
+
const owner = metadata[BUDGET_OWNER_NAMESPACE_KEY];
|
|
7957
|
+
if (owner !== undefined && owner !== ownerNamespace) {
|
|
7958
|
+
throw new HarnessStateConflictError("Budget ledger is bound to another namespace.");
|
|
7959
|
+
}
|
|
7960
|
+
return {
|
|
7961
|
+
...state,
|
|
7962
|
+
scope: bound,
|
|
7963
|
+
metadata: { ...metadata, [BUDGET_OWNER_NAMESPACE_KEY]: ownerNamespace }
|
|
7964
|
+
};
|
|
7965
|
+
};
|
|
7966
|
+
const assertStored = (state) => {
|
|
7967
|
+
if (!state)
|
|
7968
|
+
return state;
|
|
7969
|
+
const owner = state.metadata?.[BUDGET_OWNER_NAMESPACE_KEY];
|
|
7970
|
+
if (state.scope?.namespace !== bound.namespace || owner !== ownerNamespace) {
|
|
7971
|
+
throw new HarnessStateConflictError("Budget ledger is not bound to this namespace.");
|
|
7972
|
+
}
|
|
7973
|
+
return state;
|
|
7974
|
+
};
|
|
7975
|
+
return {
|
|
7976
|
+
...primary,
|
|
7977
|
+
load: async (id, requestedScope) => {
|
|
7978
|
+
if (!isSdkBudget(requestedScope) && !isBoundBudget(requestedScope))
|
|
7979
|
+
return primary.load(id, requestedScope);
|
|
7980
|
+
assertId(id);
|
|
7981
|
+
return assertStored(await budget.load(id, bound));
|
|
7982
|
+
},
|
|
7983
|
+
save: async (state, options) => {
|
|
7984
|
+
if (!isSdkBudget(state.scope) && !isBoundBudget(state.scope))
|
|
7985
|
+
return primary.save(state, options);
|
|
7986
|
+
assertId(state.runId);
|
|
7987
|
+
if (state.provider !== "zhivex" || state.modelId !== "budget-coordinator" || state.metadata?.budgetCoordinator !== true) {
|
|
7988
|
+
throw new HarnessStateConflictError("Only SDK budget ledger states may use the reserved namespace.");
|
|
7989
|
+
}
|
|
7990
|
+
return budget.save(bindState(state), options);
|
|
7991
|
+
}
|
|
7992
|
+
};
|
|
7993
|
+
};
|
|
7994
|
+
|
|
7995
|
+
// src/runtime/task-budget.ts
|
|
7888
7996
|
import {
|
|
7889
7997
|
createAgentBudgetCoordinator,
|
|
7890
7998
|
fingerprintAgentHarness as fingerprintAgentHarness2,
|
|
@@ -8003,10 +8111,10 @@ class TaskBudget {
|
|
|
8003
8111
|
this.accountRunId = TaskBudget.accountId(scope, taskId);
|
|
8004
8112
|
this.policy = structuredClone(account.policy);
|
|
8005
8113
|
const budgetId = this.accountRunId;
|
|
8006
|
-
this.coordinator = createAgentBudgetCoordinator({ store, scope, budgetId, limits: this.policy.limits });
|
|
8114
|
+
this.coordinator = createAgentBudgetCoordinator({ store: bindBudgetLedgerStore(store, scope), scope, budgetId, limits: this.policy.limits });
|
|
8007
8115
|
this.coordinatorId = this.coordinator.id;
|
|
8008
8116
|
this.budgetRunId = `budget_${fingerprintAgentHarness2({ budgetId, scope }).slice("sha256:".length)}`;
|
|
8009
|
-
this.budgetScope =
|
|
8117
|
+
this.budgetScope = budgetLedgerScope(scope);
|
|
8010
8118
|
}
|
|
8011
8119
|
static accountId(scope, taskId) {
|
|
8012
8120
|
return `task_budget_${fingerprintAgentHarness2({ scope, taskId }).slice("sha256:".length)}`;
|
|
@@ -8521,37 +8629,7 @@ class TaskBudget {
|
|
|
8521
8629
|
}
|
|
8522
8630
|
|
|
8523
8631
|
// src/persistence/operations.ts
|
|
8524
|
-
var
|
|
8525
|
-
tenantId: config.scope.tenantId,
|
|
8526
|
-
...config.scope.userId ? { userId: config.scope.userId } : {},
|
|
8527
|
-
namespace: "__zhivex_budget__"
|
|
8528
|
-
});
|
|
8529
|
-
var withBudgetLedgerStore = (primary, budget, config) => {
|
|
8530
|
-
const scope = budgetScopeFor(config);
|
|
8531
|
-
const budgetScope = (value) => value?.namespace === scope.namespace && value.tenantId === scope.tenantId && (value.userId ?? undefined) === (scope.userId ?? undefined);
|
|
8532
|
-
const assertId = (id) => {
|
|
8533
|
-
if (!/^budget_[a-f0-9]{64}$/.test(id))
|
|
8534
|
-
throw new HarnessStateConflictError("Invalid budget ledger identity.");
|
|
8535
|
-
};
|
|
8536
|
-
return {
|
|
8537
|
-
...primary,
|
|
8538
|
-
load: async (id, requestedScope) => {
|
|
8539
|
-
if (!budgetScope(requestedScope))
|
|
8540
|
-
return primary.load(id, requestedScope);
|
|
8541
|
-
assertId(id);
|
|
8542
|
-
return budget.load(id, requestedScope);
|
|
8543
|
-
},
|
|
8544
|
-
save: async (state, options) => {
|
|
8545
|
-
if (!budgetScope(state.scope))
|
|
8546
|
-
return primary.save(state, options);
|
|
8547
|
-
assertId(state.runId);
|
|
8548
|
-
if (state.provider !== "zhivex" || state.modelId !== "budget-coordinator" || state.metadata?.budgetCoordinator !== true) {
|
|
8549
|
-
throw new HarnessStateConflictError("Only SDK budget ledger states may use the reserved namespace.");
|
|
8550
|
-
}
|
|
8551
|
-
return budget.save(state, options);
|
|
8552
|
-
}
|
|
8553
|
-
};
|
|
8554
|
-
};
|
|
8632
|
+
var withBudgetLedgerStore = (primary, budget, config) => bindBudgetLedgerStore(primary, config.scope, budget);
|
|
8555
8633
|
var HARNESS_SQLITE_FILE = "operations.sqlite";
|
|
8556
8634
|
var HARNESS_OPERATIONS_SCHEMA_VERSION = 1;
|
|
8557
8635
|
var TERMINAL_RUN_STATUSES = ["completed", "failed", "cancelled", "timed_out"];
|
|
@@ -8806,13 +8884,12 @@ var migrateLegacyFileRuns = async (directory, target, config) => {
|
|
|
8806
8884
|
return result;
|
|
8807
8885
|
};
|
|
8808
8886
|
var openHarnessPersistence = async (config, options = {}) => {
|
|
8809
|
-
|
|
8810
|
-
throw new HarnessStateConflictError("The budget ledger namespace is reserved.");
|
|
8887
|
+
const budgetScope = budgetLedgerScope(config.scope);
|
|
8811
8888
|
await validateStateDirectory(config.workspace, config.stateDirectory);
|
|
8812
8889
|
await ensurePrivateStateDirectory(config.stateDirectory);
|
|
8813
8890
|
await protectStateFromGit(config.workspace, config.stateDirectory);
|
|
8814
8891
|
if (config.storeBackend === "file") {
|
|
8815
|
-
const store = withBudgetLedgerStore(createFileAgentRunStore({ directory: config.stateDirectory, scope: config.scope }), createFileAgentRunStore({ directory: config.stateDirectory, scope:
|
|
8892
|
+
const store = withBudgetLedgerStore(createFileAgentRunStore({ directory: config.stateDirectory, scope: config.scope }), createFileAgentRunStore({ directory: config.stateDirectory, scope: budgetScope }), config);
|
|
8816
8893
|
const migration = shouldMigrateLegacyRuns(config, options.migrateLegacyFileStore) ? await migrateLegacyFileRuns(config.stateDirectory, store, config) : emptyMigration();
|
|
8817
8894
|
return {
|
|
8818
8895
|
backend: "file",
|
|
@@ -8857,7 +8934,7 @@ var openHarnessPersistence = async (config, options = {}) => {
|
|
|
8857
8934
|
database.exec("PRAGMA foreign_keys = ON");
|
|
8858
8935
|
await chmod3(databasePath, 384);
|
|
8859
8936
|
const databaseLike = sqliteAdapter(database);
|
|
8860
|
-
const store = withBudgetLedgerStore(createSqliteAgentRunStore({ db: databaseLike, scope: config.scope, history: "incremental" }), createSqliteAgentRunStore({ db: databaseLike, scope:
|
|
8937
|
+
const store = withBudgetLedgerStore(createSqliteAgentRunStore({ db: databaseLike, scope: config.scope, history: "incremental" }), createSqliteAgentRunStore({ db: databaseLike, scope: budgetScope }), config);
|
|
8861
8938
|
database.exec(`CREATE TRIGGER IF NOT EXISTS zhivex_task_budget_retain_run
|
|
8862
8939
|
BEFORE DELETE ON zhivex_agent_runs
|
|
8863
8940
|
WHEN json_type(OLD.state_json, '$.metadata.zhivexTaskBudgetAccountV1') IS NOT NULL
|
|
@@ -9987,4 +10064,4 @@ var verifyChangeEnvelope = (input, options = {}) => {
|
|
|
9987
10064
|
};
|
|
9988
10065
|
};
|
|
9989
10066
|
|
|
9990
|
-
export { UnsafeFileTypeError, FileSizeLimitError, FileChangedWhileReadingError, statRegularFileNoFollow, readRegularFileNoFollow, readRegularFileChunksNoFollow, loadCliProfile, createCliProfile, updateCliProfile, applyCliProfile, resolveCliDefaults, parseHarnessModelRoute, resolveHarnessModelRoutes, createHarnessRouteModels, serializeHarnessModelRoutes, CLI_COMMANDS, CLI_RUNS_COMMANDS, CLI_SESSIONS_COMMANDS, CLI_CHANGES_COMMANDS, CLI_STATE_COMMANDS, CliUsageError, parseCliArgs, SqliteDatabase, validateStateDirectory, HARNESS_SESSION_SCHEMA_VERSION, TERMINAL_SESSION_RUN_STATUSES, ensurePrivateDatabase, openCliSessionStore, inspectRuntimeDiagnostics, inspectRuntimeManifest, estimateContextTokens, measureContext, MODEL_BUDGET_KEY, estimateRequestTokens, workBudgetReached, createModelBudget, USAGE_LEDGER_KEY, usagePricingSchema, inspectUsageLedger, formatUsageLedger, runUsageLedgerWithPolicy, UsageLedger, inspectTaskMonetaryUsage, CLI_JSON_SCHEMA_VERSION, CLI_EVENT_SCHEMA_VERSION, serializeStreamEvent, serializeStreamResult, MAX_EDIT_CHANGES, MAX_EDIT_FILE_BYTES, fileDigestSchema, workspaceFilePathSchema, editProposalInputSchema, applyEditProposalInputSchema, moveFileInputSchema, quarantineFileInputSchema, restoreFileInputSchema, createEditProposal, validateEditProposal, editContractDocument, APPROVAL_HISTORY_KEY, approvalInputDigest, readApprovalDecisions, approvalDecisionViews, createHarnessToolPolicy, applyHarnessToolPolicy, bindHarnessPolicyInspection, inspectHarnessPolicy, withRuntimeInstruction, withFreshSystemInstructions, TASK_BUDGET_KEY, TASK_BUDGET_ACCOUNT_KEY, inspectTaskBudgetSummary, assertTaskBudgetBackupLinks, TaskBudget, compileTaskAcceptanceContract, taskCheckReceiptSchema, createTaskAcceptanceChecks, withTaskAcceptanceDelivery, taskAcceptanceChecks, confirmTaskAcceptanceImport, TASK_ACCEPTANCE_KEY, TASK_ACCEPTANCE_EVIDENCE_KEY, readTaskAcceptanceLedger, nextTaskAcceptanceLedger, taskAcceptanceCheckpointStore, TASK_SOURCE_KEY, ASSISTANT_RESPONSE_KEY, assistantResponses, captureAssistantResponses, taskSources, captureTaskSources, createTaskTools, replacementEditSchema, EnvironmentPatchDriftError, harnessToolExecution, effectiveRuntimeBudget, createRuntimeBudget, runtimeManifest, childRuntimeSafety, createCheckpointTokenCap, withWorkspaceMutation, boundedBatches, resolvePackageManager, resolvePackageCheckCommand, runPortableProcess, isHardIgnored, Workspace, CliOciRuntimeAdapter, harnessExecutionSession, createHarnessOciExecutionEnvironment, cleanupHarnessExecutionArtifacts, executionFingerprintInput, createRepairController, createRepairProgress, RUNTIME_DIAGNOSTICS_KEY, assistantResponseCheckpointStore, runtimeCheckpointStore, tokenUsageCheckpointStore, HARNESS_SQLITE_FILE, HARNESS_OPERATIONS_SCHEMA_VERSION, listHarnessRuns, inspectHarnessRun, cancelHarnessRun, cleanupHarnessRuns, sqliteAdapter, openHarnessPersistence, harnessPolicyDecisionEventSchema, observeHarnessPolicyDecisions, publishHarnessPolicyDecision, observeBaselineToolPolicy, publishPendingPolicyDecision, createPolicyDecisionEvidence, changeEnvelopeSchema, digestChangeEnvelopeArtifact, createChangeEnvelope, canonicalizeChangeEnvelope, changeEnvelopePreconditionsSchema, verifyChangeEnvelope, openHarnessActivityStore };
|
|
10067
|
+
export { UnsafeFileTypeError, FileSizeLimitError, FileChangedWhileReadingError, statRegularFileNoFollow, readRegularFileNoFollow, readRegularFileChunksNoFollow, loadCliProfile, createCliProfile, updateCliProfile, applyCliProfile, resolveCliDefaults, parseHarnessModelRoute, resolveHarnessModelRoutes, createHarnessRouteModels, serializeHarnessModelRoutes, CLI_COMMANDS, CLI_RUNS_COMMANDS, CLI_SESSIONS_COMMANDS, CLI_CHANGES_COMMANDS, CLI_STATE_COMMANDS, CliUsageError, parseCliArgs, SqliteDatabase, validateStateDirectory, HARNESS_SESSION_SCHEMA_VERSION, TERMINAL_SESSION_RUN_STATUSES, ensurePrivateDatabase, openCliSessionStore, inspectRuntimeDiagnostics, inspectRuntimeManifest, estimateContextTokens, measureContext, MODEL_BUDGET_KEY, estimateRequestTokens, workBudgetReached, createModelBudget, USAGE_LEDGER_KEY, usagePricingSchema, inspectUsageLedger, formatUsageLedger, runUsageLedgerWithPolicy, UsageLedger, inspectTaskMonetaryUsage, CLI_JSON_SCHEMA_VERSION, CLI_EVENT_SCHEMA_VERSION, serializeStreamEvent, serializeStreamResult, MAX_EDIT_CHANGES, MAX_EDIT_FILE_BYTES, fileDigestSchema, workspaceFilePathSchema, editProposalInputSchema, applyEditProposalInputSchema, moveFileInputSchema, quarantineFileInputSchema, restoreFileInputSchema, createEditProposal, validateEditProposal, editContractDocument, APPROVAL_HISTORY_KEY, approvalInputDigest, readApprovalDecisions, approvalDecisionViews, createHarnessToolPolicy, applyHarnessToolPolicy, bindHarnessPolicyInspection, inspectHarnessPolicy, BUDGET_LEDGER_NAMESPACE, BUDGET_OWNER_NAMESPACE_KEY, isReservedBudgetNamespace, budgetLedgerNamespace, withRuntimeInstruction, withFreshSystemInstructions, TASK_BUDGET_KEY, TASK_BUDGET_ACCOUNT_KEY, inspectTaskBudgetSummary, assertTaskBudgetBackupLinks, TaskBudget, compileTaskAcceptanceContract, taskCheckReceiptSchema, createTaskAcceptanceChecks, withTaskAcceptanceDelivery, taskAcceptanceChecks, confirmTaskAcceptanceImport, TASK_ACCEPTANCE_KEY, TASK_ACCEPTANCE_EVIDENCE_KEY, readTaskAcceptanceLedger, nextTaskAcceptanceLedger, taskAcceptanceCheckpointStore, TASK_SOURCE_KEY, ASSISTANT_RESPONSE_KEY, assistantResponses, captureAssistantResponses, taskSources, captureTaskSources, createTaskTools, replacementEditSchema, EnvironmentPatchDriftError, harnessToolExecution, effectiveRuntimeBudget, createRuntimeBudget, runtimeManifest, childRuntimeSafety, createCheckpointTokenCap, withWorkspaceMutation, boundedBatches, resolvePackageManager, resolvePackageCheckCommand, runPortableProcess, isHardIgnored, Workspace, CliOciRuntimeAdapter, harnessExecutionSession, createHarnessOciExecutionEnvironment, cleanupHarnessExecutionArtifacts, executionFingerprintInput, createRepairController, createRepairProgress, RUNTIME_DIAGNOSTICS_KEY, assistantResponseCheckpointStore, runtimeCheckpointStore, tokenUsageCheckpointStore, HARNESS_SQLITE_FILE, HARNESS_OPERATIONS_SCHEMA_VERSION, listHarnessRuns, inspectHarnessRun, cancelHarnessRun, cleanupHarnessRuns, sqliteAdapter, openHarnessPersistence, harnessPolicyDecisionEventSchema, observeHarnessPolicyDecisions, publishHarnessPolicyDecision, observeBaselineToolPolicy, publishPendingPolicyDecision, createPolicyDecisionEvidence, changeEnvelopeSchema, digestChangeEnvelopeArtifact, createChangeEnvelope, canonicalizeChangeEnvelope, changeEnvelopePreconditionsSchema, verifyChangeEnvelope, openHarnessActivityStore };
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
inspectTaskMonetaryUsage,
|
|
60
60
|
inspectUsageLedger,
|
|
61
61
|
isHardIgnored,
|
|
62
|
+
isReservedBudgetNamespace,
|
|
62
63
|
measureContext,
|
|
63
64
|
moveFileInputSchema,
|
|
64
65
|
nextTaskAcceptanceLedger,
|
|
@@ -96,10 +97,10 @@ import {
|
|
|
96
97
|
withWorkspaceMutation,
|
|
97
98
|
workBudgetReached,
|
|
98
99
|
workspaceFilePathSchema
|
|
99
|
-
} from "./cli-entry-
|
|
100
|
+
} from "./cli-entry-928p8h41.js";
|
|
100
101
|
import {
|
|
101
102
|
HARNESS_VERSION
|
|
102
|
-
} from "./cli-entry-
|
|
103
|
+
} from "./cli-entry-q8bgkn9m.js";
|
|
103
104
|
import {
|
|
104
105
|
DEFAULT_PROVIDER_REGISTRY,
|
|
105
106
|
HARNESS_CONFIG_SCHEMA_VERSION,
|
|
@@ -6394,7 +6395,7 @@ var projectMemoryBinding = (workspace, scope) => {
|
|
|
6394
6395
|
segment(scope.userId);
|
|
6395
6396
|
if (scope.namespace !== undefined)
|
|
6396
6397
|
segment(scope.namespace);
|
|
6397
|
-
if (scope.namespace
|
|
6398
|
+
if (isReservedBudgetNamespace(scope.namespace))
|
|
6398
6399
|
throw new HarnessConfigError("Reserved memory namespace.");
|
|
6399
6400
|
const key = (kind, value) => createHash10("sha256").update(kind).update("\x00").update(value).digest("hex");
|
|
6400
6401
|
const workspaceKey = key("workspace", workspace);
|
|
@@ -6720,7 +6721,8 @@ var resolvers = {
|
|
|
6720
6721
|
const parsed = moveFileInputSchema.parse(input);
|
|
6721
6722
|
return [parsed.source, parsed.destination];
|
|
6722
6723
|
},
|
|
6723
|
-
quarantine_file: (input) => [quarantineFileInputSchema.parse(input).path]
|
|
6724
|
+
quarantine_file: (input) => [quarantineFileInputSchema.parse(input).path],
|
|
6725
|
+
restore_file: (input) => [restoreFileInputSchema.parse(input).destination]
|
|
6724
6726
|
};
|
|
6725
6727
|
var validateBuiltinToolPolicy = (policy, tools) => {
|
|
6726
6728
|
for (const rule of policy.rules)
|
|
@@ -8153,7 +8155,7 @@ var createWorkspaceTools = (workspace, allowedChecks) => ({
|
|
|
8153
8155
|
}),
|
|
8154
8156
|
restore_file: tool4({
|
|
8155
8157
|
name: "restore_file",
|
|
8156
|
-
description: "Restore a quarantined file to
|
|
8158
|
+
description: "Restore a quarantined file to the required destination after the reviewed expectedDigest matches the quarantined bytes. Restore does not fall back to the original path and never overwrites an existing file.",
|
|
8157
8159
|
schema: restoreFileInputSchema,
|
|
8158
8160
|
...mutationApproval,
|
|
8159
8161
|
execute: async (input, context) => serializeJsonValue6(editContractDocument("restore-result", await (harnessExecutionSession(context)?.workspace ?? workspace).restoreQuarantined(input)))
|
|
@@ -444,7 +444,7 @@ Use zhx help all for the full reference and exit codes.`;
|
|
|
444
444
|
// package.json
|
|
445
445
|
var package_default = {
|
|
446
446
|
name: "@zhivex-ai/harness",
|
|
447
|
-
version: "1.
|
|
447
|
+
version: "1.5.0",
|
|
448
448
|
description: "Governed, provider-portable runtime for coding agents with durable approvals and isolated repository execution.",
|
|
449
449
|
type: "module",
|
|
450
450
|
license: "MIT",
|