@zhivex-ai/harness 1.2.0 → 1.3.0-rc.7
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 +64 -0
- package/README.md +9 -10
- package/contracts/engine-api.json +2921 -0
- package/contracts/public-api.json +267 -1
- package/contracts/stable-api-signatures.json +43 -43
- package/dist/acp-cli.js +137 -15002
- package/dist/approvals/approval-history.d.ts +22 -0
- package/dist/approvals/explicit-review.d.ts +24 -0
- package/dist/approvals/host-policy-identity.d.ts +3 -0
- package/dist/cli/arguments.d.ts +6 -2
- package/dist/cli/checkpoints.d.ts +230 -0
- package/dist/cli/cli-options.d.ts +2 -41
- package/dist/cli/cli-profiles.d.ts +4 -2
- package/dist/cli/cli-stream.d.ts +2 -167
- package/dist/cli/governance-report.d.ts +5 -0
- package/dist/cli/policy-decisions.d.ts +9 -0
- package/dist/cli/policy.d.ts +5 -0
- package/dist/cli/presentation.d.ts +3 -1
- package/dist/cli/run-document.d.ts +2 -91
- package/dist/cli/terminal/terminal-continuation.d.ts +2 -3
- package/dist/cli/terminal/terminal-ui.d.ts +4 -0
- package/dist/{cli-entry-c2f58zj2.js → cli-entry-ae7x44d4.js} +14969 -10731
- package/dist/{cli-entry-427869g9.js → cli-entry-d5788aay.js} +388 -47
- package/dist/cli-entry-ev76ezcd.js +656 -0
- package/dist/{cli-3jmy4h5h.js → cli-t7hrhayq.js} +918 -2223
- package/dist/cli.js +3 -5
- package/dist/client/acp-mcp-admission.d.ts +32 -0
- package/dist/client/acp-mcp-host.d.ts +19 -0
- package/dist/client/acp-mcp-session.d.ts +14 -0
- package/dist/client/acp-stdio.d.ts +2 -0
- package/dist/client/acp.d.ts +4 -1
- package/dist/client/adapter.d.ts +13 -1
- package/dist/client/continuation.d.ts +3 -0
- package/dist/client/json-contracts.d.ts +107 -4
- package/dist/client/local-service.d.ts +2 -0
- package/dist/client/protocol.d.ts +127 -1
- package/dist/client/run-document.d.ts +91 -0
- package/dist/client/service-events.d.ts +4 -0
- package/dist/client/stream.d.ts +167 -0
- package/dist/compat/cli-options.d.ts +53 -0
- package/dist/compat/code-support.d.ts +22 -0
- package/dist/compat/code-support.js +74 -0
- package/dist/{config-1k9t4jhh.js → config-c002f06f.js} +1 -1
- package/dist/config-j3jga5wh.js +61 -0
- package/dist/context/adaptive-compaction.d.ts +1 -0
- package/dist/context/compaction.d.ts +1 -1
- package/dist/context/request-measurements.d.ts +17 -0
- package/dist/context/request-projection.d.ts +10 -0
- package/dist/context/task-memory.d.ts +1 -0
- package/dist/engine/acp.d.ts +6 -0
- package/dist/engine/acp.js +205 -0
- package/dist/engine/client.d.ts +6 -0
- package/dist/engine/client.js +28 -0
- package/dist/engine/desktop-providers-v1.d.ts +4 -0
- package/dist/engine/desktop-providers-v1.js +18 -0
- package/dist/engine/desktop-state-v1.d.ts +10 -0
- package/dist/engine/desktop-state-v1.js +168 -0
- package/dist/engine/index.d.ts +73 -0
- package/dist/engine/index.js +977 -0
- package/dist/engine/mcp-stdio-v1.d.ts +11 -0
- package/dist/engine/mcp-stdio-v1.js +108 -0
- package/dist/engine/models.d.ts +3 -0
- package/dist/engine/models.js +894 -0
- package/dist/engine/protocol.d.ts +7 -0
- package/dist/engine/protocol.js +182 -0
- package/dist/engine/service.d.ts +5 -0
- package/dist/engine/service.js +28 -0
- package/dist/execution/acceptance-snapshot.d.ts +2 -0
- package/dist/execution/execution-environment.d.ts +10 -0
- package/dist/execution/mcp-oci-channel.d.ts +11 -0
- package/dist/execution/mcp-oci-server.d.ts +38 -0
- package/dist/execution/mcp-oci-workspace.d.ts +23 -0
- package/dist/execution/mcp-resource-recovery.d.ts +19 -0
- package/dist/execution/mcp-workspace-snapshot.d.ts +20 -0
- package/dist/hostile-repository-demo.js +3368 -1304
- package/dist/index-1bx83sw4.js +4 -0
- package/dist/index-2gz7jv7g.js +549 -0
- package/dist/{cli-entry-b1mfvmxe.js → index-2jrdcj6b.js} +72 -115
- package/dist/index-3ah1f369.js +356 -0
- package/dist/index-42gp2hy8.js +1555 -0
- package/dist/index-4jw3tvy8.js +301 -0
- package/dist/index-8705zxpr.js +145 -0
- package/dist/index-8vm2m34s.js +2080 -0
- package/dist/index-8zzhggxv.js +477 -0
- package/dist/index-a97bezbz.js +1073 -0
- package/dist/index-gq9xagx2.js +1343 -0
- package/dist/index-h0mqx2ed.js +1373 -0
- package/dist/index-jgrx804e.js +5589 -0
- package/dist/index-qfpz5y2v.js +174 -0
- package/dist/index-t60rva31.js +1004 -0
- package/dist/index-wg1sd3at.js +80 -0
- package/dist/index-xqxeypt5.js +888 -0
- package/dist/index-yb239ghk.js +961 -0
- package/dist/index-z0qxmkm2.js +3389 -0
- package/dist/index-z4e8d0ph.js +1768 -0
- package/dist/index.js +251 -18649
- package/dist/integrations/mcp-host-session.d.ts +26 -0
- package/dist/integrations/mcp-stdio-admission.d.ts +54 -0
- package/dist/integrations/mcp-stdio-client.d.ts +44 -0
- package/dist/integrations/mcp-stdio-framing.d.ts +18 -0
- package/dist/integrations/mcp-stdio-launch.d.ts +20 -0
- package/dist/integrations/mcp-stdio-session.d.ts +7 -0
- package/dist/integrations/mcp-stdio-tools.d.ts +12 -0
- package/dist/internal/desktop/catalog.d.ts +2 -0
- package/dist/internal/desktop/persistence.d.ts +2 -3
- package/dist/internal/desktop/providers.d.ts +1 -0
- package/dist/models/catalog.d.ts +2 -0
- package/dist/persistence/governance-context.d.ts +126 -0
- package/dist/persistence/governance-report.d.ts +299 -0
- package/dist/persistence/host-database-backup.d.ts +28 -0
- package/dist/persistence/mcp-execution-journal.d.ts +19 -0
- package/dist/persistence/mcp-reconciliation.d.ts +33 -0
- package/dist/persistence/mcp-resource-journal.d.ts +54 -0
- package/dist/persistence/workspace-checkpoints.d.ts +138 -0
- package/dist/providers/anthropic-continuation.d.ts +5 -0
- package/dist/providers/providers.d.ts +1 -1
- package/dist/providers/vertex-auth.d.ts +27 -0
- package/dist/runtime/delegation-contracts.d.ts +9 -0
- package/dist/runtime/delegation-correction.d.ts +9 -0
- package/dist/runtime/delegation-result.d.ts +73 -0
- package/dist/runtime/error-diagnostics.d.ts +86 -0
- package/dist/runtime/harness.d.ts +11 -1
- package/dist/runtime/policy-decisions.d.ts +66 -0
- package/dist/runtime/policy-inspection.d.ts +52 -0
- package/dist/runtime/provider-diagnostics.d.ts +1 -0
- package/dist/runtime/runtime-instructions.d.ts +8 -0
- package/dist/runtime/task-acceptance-checks.d.ts +103 -0
- package/dist/runtime/task-acceptance-delivery.d.ts +107 -0
- package/dist/runtime/task-acceptance-host.d.ts +20 -0
- package/dist/runtime/task-acceptance-record.d.ts +107 -0
- package/dist/runtime/task-acceptance-validation.d.ts +25 -0
- package/dist/runtime/task-acceptance.d.ts +47 -0
- package/dist/runtime/time-to-safe-fix.d.ts +83 -0
- package/dist/runtime/tool-policy-file.d.ts +23 -0
- package/dist/runtime/tool-policy-paths.d.ts +5 -0
- package/dist/runtime/tool-policy.d.ts +6 -0
- package/dist/service-cli.js +19 -14504
- package/dist/{service-client-cli-yx56n0hc.js → service-client-cli-kns4mf57.js} +307 -248
- package/dist/verify-historical-migrations.js +3314 -1251
- package/dist/workspace/path-policy.d.ts +4 -0
- package/dist/zhx.js +3 -5
- package/docs/ACP.md +14 -2
- package/docs/ANTHROPIC.md +33 -0
- package/docs/CLI.md +132 -0
- package/docs/CLIENT_PROTOCOL.md +45 -0
- package/docs/CODE_RELEASE.md +93 -0
- package/docs/ENGINE_API.md +319 -0
- package/docs/EXTENSIBILITY.md +46 -3
- package/docs/FIRST_USE.md +6 -6
- package/docs/LOCAL_SERVICE.md +13 -0
- package/docs/MCP_STDIO.md +20 -0
- package/docs/README.md +6 -0
- package/docs/STABILITY.md +9 -1
- package/docs/SUPPORT_MATRIX.md +1 -1
- package/docs/TOOL_POLICY.md +81 -0
- package/docs/VERTEX.md +50 -0
- package/docs/adr/0002-isolated-mcp-stdio.md +135 -0
- package/docs/fixtures/mcp-stdio-contract-v1.json +189 -0
- package/docs/support-matrix.json +2 -0
- package/evaluations/representative-assembly-matrix.json +64 -1
- package/evaluations/task-acceptance-routes.json +7 -0
- package/examples/README.md +1 -1
- package/package.json +74 -12
- package/dist/cli-entry-64pdp3k5.js +0 -17
package/dist/zhx.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
HARNESS_VERSION,
|
|
3
4
|
shortCliHelp
|
|
4
|
-
} from "./cli-entry-
|
|
5
|
-
import {
|
|
6
|
-
HARNESS_VERSION
|
|
7
|
-
} from "./cli-entry-64pdp3k5.js";
|
|
5
|
+
} from "./cli-entry-ev76ezcd.js";
|
|
8
6
|
import {
|
|
9
7
|
__require
|
|
10
8
|
} from "./cli-entry-1bx83sw4.js";
|
|
@@ -18,6 +16,6 @@ if (argv.length === 1 && ["--version", "-v", "version"].includes(argv[0])) {
|
|
|
18
16
|
process.stdout.write(`${shortCliHelp(HARNESS_VERSION)}
|
|
19
17
|
`);
|
|
20
18
|
} else {
|
|
21
|
-
const { runCli } = await import("./cli-
|
|
19
|
+
const { runCli } = await import("./cli-t7hrhayq.js");
|
|
22
20
|
await runCli(argv);
|
|
23
21
|
}
|
package/docs/ACP.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The harness provides an experimental Agent Client Protocol v1 **subset** for an editor or other local client: initialization, new sessions, text prompts, one-time permissions and cancellation. It runs over JSON-RPC 2.0, one JSON message per line on stdio.
|
|
4
4
|
|
|
5
|
-
This is not full ACP conformance.
|
|
5
|
+
This is not full ACP conformance. Client-supplied stdio MCP servers require the explicit host integration below; the default CLI rejects them. Test compatibility with your editor before relying on it. The negotiation response marks the subset in `_meta.zhivex` and advertises `clientMcp` only when a host admission provider is attached.
|
|
6
6
|
|
|
7
7
|
## Launch
|
|
8
8
|
|
|
@@ -41,7 +41,7 @@ Only one prompt executes at a time per connection. Other simultaneous prompts re
|
|
|
41
41
|
|
|
42
42
|
- Host owns the workspace, provider, model, credentials, policies and tools. `session/new.cwd` must match the configured workspace.
|
|
43
43
|
- Text prompts only; no image, audio or embedded resources.
|
|
44
|
-
-
|
|
44
|
+
- Client stdio MCP only through explicit host rules and OCI admission. HTTP/SSE MCP, client filesystem operations and client terminals are unsupported.
|
|
45
45
|
- No session load/resume, model switching, modes, or authentication protocol. Durable sessions remain accessible through existing harness interfaces.
|
|
46
46
|
- Frames are limited to 1 MiB, prompts to 64 KiB, concurrent protocol handlers to 64 and sessions to 256 per connection. Oversized frames or handler floods terminate the connection and cancel work.
|
|
47
47
|
- A transport connection should belong to a single trusted local client. This is not an unauthenticated network service.
|
|
@@ -52,4 +52,16 @@ Create the existing `createHarnessClientAdapter(harness)`, then call `createAcpC
|
|
|
52
52
|
|
|
53
53
|
`serveAcpStdio(adapter, { workspace, input, output })` supplies framing and permission-response correlation for Node readable/writable streams.
|
|
54
54
|
|
|
55
|
+
### Client MCP with host admission
|
|
56
|
+
|
|
57
|
+
The experimental `@zhivex-ai/harness/acp` export `createAcpMcpHost` composes the durable adapter and per-run isolated MCP lifecycle. Supply `harness` options with explicit tenant/user identity, `rules: AcpMcpHostRule[]`, an admission `authority`, immutable `provisionerImageId`, `hostId` and `resolveSecret`. Admission authorities come from `@zhivex-ai/harness/mcp/stdio/v1`; see [isolated MCP](MCP_STDIO.md).
|
|
58
|
+
|
|
59
|
+
Each rule matches a client's exact name, absolute command and arguments, and maps them to a host-owned OCI launch proposal. Image, executable, limits and tool allowlist belong to the host. `environmentBindings` explicitly maps client variables to admitted `ZHIVEX_MCP_*` names; their values are treated as sensitive. Configuration from the workspace cannot create these rules or grant admission.
|
|
60
|
+
|
|
61
|
+
Pass the returned `adapter`, `workspace` and `mcpSessionProvider` to `serveAcpStdio`, or to `createAcpConnection` with your transport callbacks. Always await `host.close()` in a `finally` block after transport shutdown. The provider is bound to that adapter; another adapter or a fabricated provider is rejected.
|
|
62
|
+
|
|
63
|
+
Registration is per ACP session. Before every run and approval continuation, the host snapshots the workspace, obtains fresh admission and starts the mapped servers in isolated Docker containers. Up to eight servers share the run while retaining independent receipts and tool namespaces. Tool effects still require client permission; admitting a server does not approve its tools. A partial startup failure closes previously started members. Cancellation while admission is pending prevents a late approval from launching a process.
|
|
64
|
+
|
|
65
|
+
Client descriptors live only in the host's memory and expire when it closes. This integration does not enable ACP session loading across restarts. A restarted client must create a new session. Durable effect journals and resource recovery still protect against uncertain outcomes; cancellation cannot undo effects already committed.
|
|
66
|
+
|
|
55
67
|
Protocol references: [initialization](https://agentclientprotocol.com/protocol/v1/initialization), [session setup](https://agentclientprotocol.com/protocol/v1/session-setup), [prompt lifecycle and cancellation](https://agentclientprotocol.com/protocol/v1/prompt-turn), [permissions](https://agentclientprotocol.com/protocol/v1/tool-calls).
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Anthropic direct API (provisional)
|
|
2
|
+
|
|
3
|
+
HAR-HU-41 adds `anthropic` through `@zhivex-ai/anthropic@0.12.4`. CLI and
|
|
4
|
+
Desktop use the same registry and curated catalogue. Set `ANTHROPIC_API_KEY` or
|
|
5
|
+
use the client's secure credential setup. Diagnostics expose presence and endpoint
|
|
6
|
+
validity only. `ANTHROPIC_BASE_URL` is optional and must be a trusted HTTPS API base including `/v1` (default `https://api.anthropic.com/v1`).
|
|
7
|
+
An unset, empty or whitespace-only endpoint uses that explicit default, without
|
|
8
|
+
inheriting another endpoint from the host process environment. The CLI does not
|
|
9
|
+
send a stored key to an overridden endpoint without setup consent.
|
|
10
|
+
OAuth, Vertex and Bedrock are separate routes and are not enabled by this integration.
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
zhx run --provider anthropic --model claude-sonnet-5 "Inspect this repository"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The default is an explicit catalogue choice, not a discovery or account-access
|
|
17
|
+
claim. Other curated choices are `claude-haiku-4-5` and `claude-opus-5-5`; an explicit
|
|
18
|
+
model ID can be supplied. IDs were checked against [Anthropic's model overview](https://platform.claude.com/docs/en/models/overview)
|
|
19
|
+
on 2026-09-28. All entries remain unverified in Harness; limits/pricing remain
|
|
20
|
+
unknown until curated evidence is added. A missing/unavailable model is an error,
|
|
21
|
+
not an automatic fallback.
|
|
22
|
+
|
|
23
|
+
Harness reconstructs the SDK 0.12.4 thinking/signature SSE deltas into bounded signed blocks before durable history. Orphan, unsigned and oversized blocks fail closed.
|
|
24
|
+
The integration retains signed provider-specific continuation content, tool call IDs and
|
|
25
|
+
receipts, input/output usage, typed HTTP errors and abort signals. Contract tests
|
|
26
|
+
exercise both generation and streaming without live requests. Adding the route
|
|
27
|
+
with its default endpoint preserves the existing registry transport fingerprint;
|
|
28
|
+
changing its endpoint changes the binding and prevents stale durable resumes.
|
|
29
|
+
|
|
30
|
+
Anthropic remains **provisional** pending HAR-HU-45's installed-artifact live
|
|
31
|
+
certification. The [common task suite](https://github.com/Zhivex/zhivex-harness/blob/main/docs/TASK_ACCEPTANCE.md) is available for that
|
|
32
|
+
campaign; local mocks do not certify the provider. No new release is published by
|
|
33
|
+
this implementation.
|
package/docs/CLI.md
CHANGED
|
@@ -663,3 +663,135 @@ Activity shows phase and total elapsed time. Preparing edits, waiting for approv
|
|
|
663
663
|
applied file changes and verification are distinct states. `/diff` reviews workspace
|
|
664
664
|
changes, including changes outside the current run; file receipts identify mutations
|
|
665
665
|
recorded by this harness.
|
|
666
|
+
## Trusted tool policy
|
|
667
|
+
|
|
668
|
+
For an additional host-owned tool policy, use `--tool-policy <absolute-policy.json>`
|
|
669
|
+
on run, chat, review or resume. The policy is experimental and must be outside the
|
|
670
|
+
repository with private ownership/permissions. See [tool policy semantics](TOOL_POLICY.md).
|
|
671
|
+
Clients using `--service` cannot supply this option; configure the service host.
|
|
672
|
+
|
|
673
|
+
## Reviewed workspace checkpoints
|
|
674
|
+
|
|
675
|
+
Use `zhx checkpoints capture <sessionId> <turnId> <path> [paths...]` to capture
|
|
676
|
+
explicit files at an existing terminal conversation turn. Discover turn IDs with
|
|
677
|
+
`zhx sessions inspect <sessionId>`. Capture stores the current contents; it does
|
|
678
|
+
not reconstruct historical file versions. Checkpoints cover only the selected
|
|
679
|
+
existing UTF-8 text files, at most 20 files of 64 KiB each. Creation, deletion,
|
|
680
|
+
binary files and permission rollback are excluded. This is not a full snapshot.
|
|
681
|
+
|
|
682
|
+
Capture is opt-in at the idle boundary between turns: wait for all source runs
|
|
683
|
+
to terminate, select the files, capture, and only then start the next task or
|
|
684
|
+
external edit. Capture does not start a run or authorize changes. If capture
|
|
685
|
+
fails, no checkpoint was established; resolve the error before proceeding with
|
|
686
|
+
work that needs a recovery point. There is no automatic capture on each turn.
|
|
687
|
+
The stored manifest records the selected paths, digests, contents and modes;
|
|
688
|
+
inspection reports file sizes, coverage and unsupported current files.
|
|
689
|
+
|
|
690
|
+
```sh
|
|
691
|
+
zhx checkpoints list <sessionId>
|
|
692
|
+
zhx checkpoints inspect <checkpointId>
|
|
693
|
+
zhx checkpoints prepare <checkpointId>
|
|
694
|
+
zhx checkpoints review <operationId>
|
|
695
|
+
# After reviewing the exact before/after diff:
|
|
696
|
+
zhx checkpoints apply <operationId> <reviewedProposalId>
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
Preparation binds the current file digests without changing files. Apply requires
|
|
700
|
+
the exact proposal identifier printed in the review; `--yes` cannot replace it.
|
|
701
|
+
The digest is an identity check, not proof of human review. Read the diff before
|
|
702
|
+
invoking apply. Subsequent file or permission changes cause a conflict. Missing,
|
|
703
|
+
protected, binary or oversized files are shown as unavailable and are not recreated.
|
|
704
|
+
|
|
705
|
+
Apply preserves the original conversation and returns its derivative. On an
|
|
706
|
+
interactive terminal it opens that derivative in the console. With `--json`, it
|
|
707
|
+
returns a versioned document containing the derivative session; noninteractive
|
|
708
|
+
text output prints the command to open it later. These commands use local state
|
|
709
|
+
without constructing a model or requiring provider credentials. Use the same
|
|
710
|
+
`--workspace`, `--state-dir`, `--tenant`, `--user` and `--namespace` as the source.
|
|
711
|
+
They currently do not support `--service`.
|
|
712
|
+
|
|
713
|
+
After an interruption, list the source session's checkpoints and review the saved
|
|
714
|
+
operation. Repeating apply for a completed operation returns the existing derivative.
|
|
715
|
+
If its stage is `forking`, inspect the source's child conversations and reconcile
|
|
716
|
+
the exact child titled `restore:<operationId>` using
|
|
717
|
+
`zhx checkpoints recover <operationId> <existingForkSessionId>`. Recovery does not
|
|
718
|
+
apply files; review and apply separately. Partial filesystem changes or a conflicting
|
|
719
|
+
base require manual recovery and are never silently overwritten.
|
|
720
|
+
|
|
721
|
+
### Checkpoint capacity and reviewed removal
|
|
722
|
+
|
|
723
|
+
`zhx checkpoints storage` reports the current workspace/scope policy and capacity.
|
|
724
|
+
The limit is 100 combined checkpoint and restore records, at most 2 MiB per
|
|
725
|
+
serialized record. A capture uses one slot; preparing a restore uses another.
|
|
726
|
+
Updating an existing restore can finish at capacity. There is no automatic
|
|
727
|
+
eviction: a full store rejects new records while preserving existing evidence.
|
|
728
|
+
Serialized bytes are logical record sizes, not SQLite file size or free disk space.
|
|
729
|
+
|
|
730
|
+
Free slots by explicitly reviewing exact IDs; no age-based or implicit selection
|
|
731
|
+
is performed. List a session to find its checkpoint and restore IDs. A checkpoint
|
|
732
|
+
referenced by any retained restore cannot be removed. Pending restore evidence
|
|
733
|
+
cannot be removed, even when the store is full. Completed restore records can be
|
|
734
|
+
selected explicitly together with their checkpoint, after all references have
|
|
735
|
+
been resolved.
|
|
736
|
+
|
|
737
|
+
```sh
|
|
738
|
+
zhx checkpoints storage
|
|
739
|
+
zhx checkpoints prune-review checkpoint:<checkpointId> restore:<completedRestoreId>
|
|
740
|
+
# Read the records, scope and counts in the review, then reuse that exact selection:
|
|
741
|
+
zhx checkpoints prune-apply <reviewedPlanId> checkpoint:<checkpointId> restore:<completedRestoreId>
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
The review writes nothing and works at capacity. Apply requires the returned
|
|
745
|
+
SHA-256 plan identity and checks the entire scoped inventory again in a SQLite
|
|
746
|
+
transaction. Any inventory change requires a new review. A failed deletion rolls
|
|
747
|
+
back the whole selection. Removal is permanent for those stored records; it does
|
|
748
|
+
not delete workspace files, conversations or the restored derivative. The plan
|
|
749
|
+
hash checks identity; it is not proof that a person reviewed the selection.
|
|
750
|
+
|
|
751
|
+
State export preserves retained captures and completed restore records and
|
|
752
|
+
refuses pending restore authority. Export/import never prune to fit capacity.
|
|
753
|
+
Import accepts an empty destination or an identical prior import, not a merge
|
|
754
|
+
with changed checkpoint history. These administrative retention commands run
|
|
755
|
+
locally; Desktop can continue using the same retained checkpoints afterward.
|
|
756
|
+
|
|
757
|
+
### Inspect the configured policy
|
|
758
|
+
|
|
759
|
+
`zhx policy --json` returns the versioned `policy-inspection` document for a locally
|
|
760
|
+
constructed host. It accepts the host's runtime settings, including `--tool-policy`.
|
|
761
|
+
`zhx policy --service <credentials.json> --json` queries the existing host instead;
|
|
762
|
+
runtime overrides are rejected in service mode. Omit `--json` for a readable
|
|
763
|
+
summary. Neither form starts an agent run or authorizes a pending approval.
|
|
764
|
+
The local form uses normal host initialization; the service form does not create
|
|
765
|
+
a session. Backend and limits describe configuration, not successful OCI execution.
|
|
766
|
+
|
|
767
|
+
`run`, `resume`, and local `chat` display policy explanations on stderr in text mode.
|
|
768
|
+
In chat, `/approve` shows the explanation and opens complete review when the host
|
|
769
|
+
requires it, including after restarting a pending conversation. The run/resume JSON
|
|
770
|
+
final document includes `policyEvidence` scoped to the current invocation: at most
|
|
771
|
+
64 events and 256 KiB, with `observed` and `truncated` indicating omitted evidence.
|
|
772
|
+
JSONL emits policy decisions as versioned `run-event` records in the same sequence
|
|
773
|
+
as other events. A service-backed run uses the same event projection and bounded
|
|
774
|
+
final evidence. These observations do not replace durable tool execution receipts.
|
|
775
|
+
|
|
776
|
+
### Portable governance report (Experimental)
|
|
777
|
+
|
|
778
|
+
`zhx runs report <runId> [envelope.json] [--session <sessionId>] [--json]`
|
|
779
|
+
exports a bounded projection from durable runs and their journals. Default output
|
|
780
|
+
is Markdown; `--json` emits strict versioned `harness-governance-report` JSON.
|
|
781
|
+
The existing `runs export` inspection format is unchanged. The command does not
|
|
782
|
+
construct a provider, execute tools, resume runs, or inspect current workspace
|
|
783
|
+
bytes. The optional envelope file is read as bounded regular-file JSON.
|
|
784
|
+
|
|
785
|
+
Session selection verifies that the root run belongs to that session and includes
|
|
786
|
+
retained policy decisions. Activity replay applies the existing retention policy;
|
|
787
|
+
expired or truncated history is explicitly incomplete. The report excludes
|
|
788
|
+
prompts, arguments, outputs, free-form errors and arbitrary metadata. Identifiers
|
|
789
|
+
and paths become domain-separated hash references: pseudonyms, not anonymity.
|
|
790
|
+
|
|
791
|
+
Execution completion, recorded delivery and pending semantic review are separate.
|
|
792
|
+
Missing usage stays null; partial usage is labelled incomplete; costs are estimates,
|
|
793
|
+
not invoices. The exporter version is not evidence of the execution artifact.
|
|
794
|
+
An envelope link matches the recorded patch identifier; envelope integrity and
|
|
795
|
+
expiry are checked separately. Patch bytes and producer authenticity remain
|
|
796
|
+
unverified. No envelope v1 fields are added. Concurrent source changes and hard
|
|
797
|
+
capacity limits reject export; bounded tree/history truncation is reported.
|
package/docs/CLIENT_PROTOCOL.md
CHANGED
|
@@ -85,6 +85,38 @@ or a replacement for the engine's signed approval validation.
|
|
|
85
85
|
| run.get | projectId, sessionId, runId | run | NOT_FOUND |
|
|
86
86
|
| approval.resolve | projectId, sessionId, runId, expectedRevision, idempotencyKey, decisions | run | APPROVAL_MISMATCH |
|
|
87
87
|
| run.cancel | projectId, sessionId, runId, expectedRevision, idempotencyKey | run | REVISION_CONFLICT |
|
|
88
|
+
| checkpoint.list | projectId, sessionId | checkpoints | NOT_FOUND |
|
|
89
|
+
| checkpoint.inspect | projectId, sessionId, checkpointId | checkpoint | NOT_FOUND |
|
|
90
|
+
| checkpoint.capture | projectId, sessionId, expectedRevision, idempotencyKey, turnId, paths | checkpoint | EXECUTION_FAILED |
|
|
91
|
+
| restore.prepare | projectId, sessionId, checkpointId, expectedRevision, idempotencyKey, expected (path/digest map) | restore | REVISION_CONFLICT |
|
|
92
|
+
| restore.get | projectId, sessionId, operationId | restore | NOT_FOUND |
|
|
93
|
+
| restore.apply | projectId, sessionId, operationId, expectedRevision, idempotencyKey, reviewedProposalId | restore | EXECUTION_FAILED |
|
|
94
|
+
| restore.recoverFork | projectId, sessionId, operationId, expectedRevision, idempotencyKey, forkSessionId | restore | EXECUTION_FAILED |
|
|
95
|
+
|
|
96
|
+
Checkpoint mutations use the source session revision. Checkpoint/restore IDs must
|
|
97
|
+
belong to that session and the host workspace/scope. Capture requires an existing
|
|
98
|
+
terminal turn and explicit paths (at most twenty existing text files, 64 KiB each).
|
|
99
|
+
Inspection reports unavailable files and mode conflicts and explicitly excludes
|
|
100
|
+
creation, deletion, binary files, mode rollback and full workspace snapshots.
|
|
101
|
+
|
|
102
|
+
Prepare uses the exact digests observed during inspection and returns the prepared
|
|
103
|
+
operation plus a diff. Clients must show that diff and obtain explicit review before
|
|
104
|
+
sending its `reviewedProposalId` to apply. A digest identifies content; it is not proof
|
|
105
|
+
of a human decision. Hosts must enforce their UI review boundary. The Desktop generic
|
|
106
|
+
command IPC does not accept apply/recover requests; its dedicated review flow is required.
|
|
107
|
+
Local CLI checkpoint commands use the same engine API. Desktop exposes checkpoint
|
|
108
|
+
review through dedicated host-issued tickets; generic IPC cannot apply or reconcile
|
|
109
|
+
a restore. The CLI does not yet route checkpoint commands through `--service`.
|
|
110
|
+
|
|
111
|
+
Restore responses contain operation metadata and an available/unavailable preview,
|
|
112
|
+
without duplicating the captured contents. Successful apply includes the derivative
|
|
113
|
+
session to open and preserves the original. Listing includes interrupted and completed
|
|
114
|
+
operations. After reconnecting, query the same operation before resuming: completion
|
|
115
|
+
is durable and applying again returns the existing derivative. An uncertain fork must
|
|
116
|
+
be reconciled with its exact existing child ID via `restore.recoverFork`; this does not
|
|
117
|
+
apply files or authorize a subsequent restore. Stale contents, missing files, mode
|
|
118
|
+
changes and partial filesystem outcomes fail closed. Apply/recovery also reject source
|
|
119
|
+
conversations with unfinished durable runs.
|
|
88
120
|
|
|
89
121
|
Session documents contain sessionId, revision, optional title and ordered runId/status
|
|
90
122
|
references. Lists use the existing bounded session store (default 50; no pagination
|
|
@@ -210,3 +242,16 @@ The local-service constructor optionally accepts a trusted `approvalNow` clock.
|
|
|
210
242
|
It is not a client command or IPC capability. Desktop expiry tests advance only
|
|
211
243
|
the service clock to prove server-side rejection while the review receipt remains
|
|
212
244
|
unexpired in the main process.
|
|
245
|
+
|
|
246
|
+
### Experimental policy inspection
|
|
247
|
+
|
|
248
|
+
`policy.get` takes only `projectId` and returns `{ kind: "policy", policy }`.
|
|
249
|
+
The versioned policy document is the same host snapshot returned by
|
|
250
|
+
`inspectHarnessPolicy` from `@zhivex-ai/harness/engine`. It contains configuration,
|
|
251
|
+
not proof of tool or OCI execution. Clients cannot supply policy overrides in
|
|
252
|
+
this command. The read remains available while mutation admission is paused or
|
|
253
|
+
a run is active, and does not create a session, authorize an approval or execute
|
|
254
|
+
a tool. Rule paths and host filesystem locations are omitted.
|
|
255
|
+
While a host-prepared runtime is active, the query reflects that runtime. Before
|
|
256
|
+
preparation and after release it reflects the base host; decision events retain
|
|
257
|
+
the digest and backend of the runtime that evaluated them.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Code release procedure
|
|
2
|
+
|
|
3
|
+
Code is released independently of Harness. The initial candidate is
|
|
4
|
+
`@zhivex-ai/code@0.1.0-rc.2`, with the sole binary `zhivex-code`, npm tag `next`,
|
|
5
|
+
and the exact dependency `@zhivex-ai/harness@1.3.0-rc.7`. Harness must first be
|
|
6
|
+
published and verified through its protected release workflow. This document
|
|
7
|
+
records preparation, not successful publication.
|
|
8
|
+
|
|
9
|
+
## Release preparation
|
|
10
|
+
|
|
11
|
+
1. Merge the Code release PR after required review and successful checks.
|
|
12
|
+
2. Wait for the latest `ci.yml` and `codeql.yml` **push runs on main** to succeed
|
|
13
|
+
for the exact commit. Keep the Code manifest, version and engine pin unchanged
|
|
14
|
+
after selecting that commit.
|
|
15
|
+
3. From a clean checkout of that main commit, create an annotated
|
|
16
|
+
`code-v0.1.0-rc.2` tag and push it. Never move or overwrite release tags.
|
|
17
|
+
4. Dispatch `release-code.yml` **at that tag**, with input `tag` matching it and
|
|
18
|
+
`mode=bootstrap`. Dispatching main while supplying a different tag is rejected.
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
gh workflow run release-code.yml --ref code-v0.1.0-rc.2 \
|
|
22
|
+
-f tag=code-v0.1.0-rc.2 -f mode=bootstrap -f confirm_publication=false
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The workflow validates tag identity, main ancestry, exact CI/CodeQL, Code source
|
|
26
|
+
and package boundaries. It downloads the pinned Harness version from npm and
|
|
27
|
+
verifies its integrity; missing publication or provenance stops the release.
|
|
28
|
+
It builds Code once, inspects package contents, installs it against the actual
|
|
29
|
+
registry dependency without overrides, and tests the retained Code and Harness
|
|
30
|
+
artifacts with npm, pnpm, Yarn and Bun. The paired matrix uses explicit engine
|
|
31
|
+
artifact overrides; the separate standalone installation proves npm resolution.
|
|
32
|
+
This does not claim every future engine version or installation order is certified.
|
|
33
|
+
|
|
34
|
+
The workflow generates genuine npm/Sigstore provenance using pinned npm 11.6.1
|
|
35
|
+
inside the GitHub-hosted build job. It retains `code.tgz`, `code.sigstore.json`,
|
|
36
|
+
`SHA512SUMS`, and installed acceptance in `code-release-<full-source-sha>`.
|
|
37
|
+
Bootstrap mode **does not publish**. No npm token is copied into GitHub.
|
|
38
|
+
|
|
39
|
+
## First publication
|
|
40
|
+
|
|
41
|
+
npm requires the package to exist before configuring its trusted publisher;
|
|
42
|
+
staged publishing also requires an existing package. An authenticated scope
|
|
43
|
+
owner performs the first publication using the successful workflow's retained
|
|
44
|
+
artifact and provenance bundle. Do not rebuild the tarball locally.
|
|
45
|
+
|
|
46
|
+
Download the artifact from the exact successful run, then verify it in a clean
|
|
47
|
+
checkout of its annotated Code tag. `CODE_EXPECTED_SHA` must be that tag's full
|
|
48
|
+
commit SHA. Install npm 11.6.1 into an isolated tools directory and set
|
|
49
|
+
`CODE_PROVENANCE_NPM_ROOT` to its `node_modules/npm` directory.
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
(cd release-code-artifacts && shasum -a 512 -c SHA512SUMS)
|
|
53
|
+
bun run scripts/code-release.ts inspect release-code-artifacts/code.tgz
|
|
54
|
+
CODE_EXPECTED_SHA="$(git rev-list -n 1 code-v0.1.0-rc.2)" \
|
|
55
|
+
node scripts/code-bootstrap-provenance.cjs verify \
|
|
56
|
+
release-code-artifacts/code.tgz release-code-artifacts/code.sigstore.json
|
|
57
|
+
node "$CODE_PROVENANCE_NPM_ROOT/bin/npm-cli.js" publish \
|
|
58
|
+
./release-code-artifacts/code.tgz --ignore-scripts --access public \
|
|
59
|
+
--tag next --provenance-file ./release-code-artifacts/code.sigstore.json
|
|
60
|
+
bun run scripts/code-release.ts verify release-code-artifacts/code.tgz
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The provenance verifier checks the Sigstore signature, GitHub issuer, exact
|
|
64
|
+
workflow/tag identity, source commit and tarball digest. Complete any npm 2FA
|
|
65
|
+
challenge directly; do not put a one-time code into documentation or logs. If npm
|
|
66
|
+
accepts publication but verification fails, inspect registry state and retry
|
|
67
|
+
verification with the same retained bytes. An existing different digest is a
|
|
68
|
+
hard failure; never attempt to replace that version.
|
|
69
|
+
|
|
70
|
+
## Subsequent releases with Trusted Publishing
|
|
71
|
+
|
|
72
|
+
In npm package settings, configure GitHub Actions with organization `Zhivex`,
|
|
73
|
+
repository `zhivex-harness`, workflow filename `release-code.yml`, and environment
|
|
74
|
+
`npm`. Enable the allowed action `npm publish`; the OIDC job uses direct
|
|
75
|
+
publishing after GitHub approval, not `npm stage publish`. Preserve the GitHub
|
|
76
|
+
environment's required human approval. Then prepare a
|
|
77
|
+
new Code RC/version and annotated tag through the same PR and main CI process.
|
|
78
|
+
Dispatch its tag with `mode=oidc` and `confirm_publication=true`.
|
|
79
|
+
|
|
80
|
+
All Code tags share one workflow concurrency group. Before publishing, the
|
|
81
|
+
registry gate also rejects moving `next` back to an older RC, including when
|
|
82
|
+
GitHub schedules queued workflows out of order.
|
|
83
|
+
|
|
84
|
+
The publish job downloads the validated artifact without rebuilding it,
|
|
85
|
+
rechecks identity and digest after protected approval, and uses npm OIDC plus
|
|
86
|
+
provenance. It verifies registry tarball bytes, the `next` distribution tag and
|
|
87
|
+
SLSA source/workflow identity. A successful dispatch or tag is not publication;
|
|
88
|
+
only successful registry verification confirms the release. When a run has
|
|
89
|
+
already published, rerun only the failed publish job to retain original bytes.
|
|
90
|
+
|
|
91
|
+
Official references: [npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers/),
|
|
92
|
+
[npm provenance](https://docs.npmjs.com/generating-provenance-statements/), and
|
|
93
|
+
[npm staged publishing](https://docs.npmjs.com/staged-publishing/).
|