@zhivex-ai/harness 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -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 +36 -36
- package/dist/acp-cli.js +54 -20
- package/dist/approvals/approval-diff.d.ts +2 -1
- package/dist/approvals/approval-preview.d.ts +1 -1
- 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-kvw7ng34.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-entry-75j3r49b.js +484 -0
- package/dist/cli-entry-928p8h41.js +10067 -0
- package/dist/cli-entry-h2yc9x37.js +10350 -0
- package/dist/{cli-entry-20w6nh0k.js → cli-entry-hdtfef27.js} +439 -19
- package/dist/{cli-entry-w0hterjs.js → cli-entry-q8bgkn9m.js} +40 -13
- package/dist/{cli-2h37qyvg.js → cli-vyrytn3m.js} +253 -644
- 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 +1232 -564
- package/dist/{index-8zjmnyw5.js → index-1265j7t2.js} +73 -6
- package/dist/{index-nmjdwd4p.js → index-4gt045j0.js} +109 -1
- package/dist/{index-pdmevfxv.js → index-5zbq9ztj.js} +5 -259
- package/dist/{index-6dft2vev.js → index-63gbp0cz.js} +5 -3
- package/dist/index-6dxrbnxm.js +719 -0
- package/dist/{index-pp474137.js → index-6fp7kdpx.js} +769 -933
- package/dist/{index-61gthdz6.js → index-8sm2a1wa.js} +1 -1
- package/dist/{index-rkbf7dqg.js → index-96ezrvg2.js} +57 -13
- package/dist/index-bt2p8x7r.js +329 -0
- package/dist/index-c39197wq.js +552 -0
- package/dist/{index-m82cfspw.js → index-eps3c3g6.js} +877 -963
- package/dist/{index-s2k2edts.js → index-fqqz1yt8.js} +110 -1544
- package/dist/{index-m34q25jj.js → index-ggstwr0v.js} +192 -838
- package/dist/index-jpdvn09j.js +490 -0
- package/dist/{index-xqxeypt5.js → index-mzydbzp8.js} +76 -4
- package/dist/index-pq3kz1r8.js +269 -0
- package/dist/{index-wg1sd3at.js → index-qfsrrnz6.js} +1 -1
- package/dist/{index-937cb7y8.js → index-vc7yxz50.js} +561 -35
- package/dist/{index-5jhgatga.js → index-vvzc5ezz.js} +7 -6
- package/dist/index-wwthv10a.js +1507 -0
- package/dist/{index-tfzta544.js → index-xfedewpt.js} +17 -9
- package/dist/index-yx52bt4a.js +511 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +93 -77
- package/dist/integrations/mcp-stdio-tools.d.ts +4 -1
- 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/budget-ledger-scope.d.ts +14 -0
- 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-v6qptg9x.js} +400 -305
- package/dist/tools/workspace.d.ts +2 -2
- package/dist/verify-historical-migrations.js +1237 -566
- 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 +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 +59 -7
- 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 +8 -4
- package/docs/FIRST_USE.md +6 -6
- package/docs/MINIMUM_TASK_AUTHORITY.md +3 -3
- package/docs/PROJECT_MEMORY.md +1 -1
- package/docs/PUBLIC_SECURITY.md +14 -1
- package/docs/README.md +6 -1
- package/docs/REPOSITORY_EDITING.md +1 -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/TOOL_POLICY.md +4 -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 +7 -4
- 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 +19 -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
|
@@ -70,8 +70,8 @@ export declare const quarantineFileInputSchema: z.ZodObject<{
|
|
|
70
70
|
export type QuarantineFileInput = z.infer<typeof quarantineFileInputSchema>;
|
|
71
71
|
export declare const restoreFileInputSchema: z.ZodObject<{
|
|
72
72
|
quarantineId: z.ZodString;
|
|
73
|
-
destination: z.
|
|
74
|
-
expectedDigest: z.
|
|
73
|
+
destination: z.ZodString;
|
|
74
|
+
expectedDigest: z.ZodString;
|
|
75
75
|
}, z.core.$strict>;
|
|
76
76
|
export type RestoreFileInput = z.infer<typeof restoreFileInputSchema>;
|
|
77
77
|
export declare const mutationOperationSchema: z.ZodEnum<{
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/** Shared lexical exclusions for workspace access and acceptance preflight.
|
|
1
|
+
/** Shared lexical exclusions for workspace access and acceptance preflight.
|
|
2
|
+
* Comparisons use toLowerCase so a Turkish locale cannot map ASCII I to dotless ı and skip .git or id_rsa. */
|
|
2
3
|
export declare const HARD_IGNORES: Set<string>;
|
|
3
4
|
export declare const isSensitiveName: (name: string) => boolean;
|
|
4
5
|
export declare const isHardIgnored: (relativePath: string) => boolean;
|
|
@@ -214,6 +214,19 @@ export declare class Workspace {
|
|
|
214
214
|
private readInternalRegularFile;
|
|
215
215
|
quarantineFile(input: QuarantineFileInput, assertActive?: () => Promise<void>): Promise<QuarantineFileResult>;
|
|
216
216
|
private quarantineFileLocked;
|
|
217
|
+
private readRestorableQuarantine;
|
|
218
|
+
/** Read-only preview of a pinned restore. Destination and digest are required, and nothing is written. */
|
|
219
|
+
previewRestore(input: unknown): Promise<{
|
|
220
|
+
proposalId: string;
|
|
221
|
+
files: {
|
|
222
|
+
path: string;
|
|
223
|
+
expectedDigest: string;
|
|
224
|
+
before: null;
|
|
225
|
+
after: string;
|
|
226
|
+
afterDigest: string;
|
|
227
|
+
operation: "restore";
|
|
228
|
+
}[];
|
|
229
|
+
}>;
|
|
217
230
|
restoreQuarantined(input: RestoreFileInput): Promise<RestoreFileResult>;
|
|
218
231
|
private restoreQuarantinedLocked;
|
|
219
232
|
runCheck(check: HarnessCheck, expectedScript: string, allowedChecks?: readonly string[]): Promise<CommandResult>;
|
package/dist/zhx.js
CHANGED
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
HARNESS_VERSION,
|
|
4
|
+
NODE_ENGINE_RANGE,
|
|
4
5
|
shortCliHelp
|
|
5
|
-
} from "./cli-entry-
|
|
6
|
+
} from "./cli-entry-q8bgkn9m.js";
|
|
6
7
|
import {
|
|
7
8
|
__require
|
|
8
9
|
} from "./cli-entry-1bx83sw4.js";
|
|
9
10
|
|
|
11
|
+
// src/cli/node-engine.ts
|
|
12
|
+
var nodeEngineError = (version, range) => {
|
|
13
|
+
const minimumMatch = /^>=(\d+)\.(\d+)\.(\d+)$/.exec(range.trim());
|
|
14
|
+
const actualMatch = /^(\d+)\.(\d+)\.(\d+)/.exec(version.trim());
|
|
15
|
+
const failure = `Node.js ${version} does not satisfy the package engine requirement (${range}).
|
|
16
|
+
`;
|
|
17
|
+
if (!minimumMatch || !actualMatch)
|
|
18
|
+
return failure;
|
|
19
|
+
for (let index = 1;index <= 3; index += 1) {
|
|
20
|
+
const actual = Number(actualMatch[index]);
|
|
21
|
+
const minimum = Number(minimumMatch[index]);
|
|
22
|
+
if (actual !== minimum)
|
|
23
|
+
return actual > minimum ? undefined : failure;
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
};
|
|
27
|
+
|
|
10
28
|
// src/cli-entry.ts
|
|
29
|
+
if (!process.versions.bun) {
|
|
30
|
+
const engineError = nodeEngineError(process.versions.node, NODE_ENGINE_RANGE);
|
|
31
|
+
if (engineError) {
|
|
32
|
+
process.stderr.write(engineError);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
11
36
|
var argv = process.argv.slice(2);
|
|
12
37
|
if (argv.length === 1 && ["--version", "-v", "version"].includes(argv[0])) {
|
|
13
38
|
process.stdout.write(`${HARNESS_VERSION}
|
|
@@ -16,6 +41,6 @@ if (argv.length === 1 && ["--version", "-v", "version"].includes(argv[0])) {
|
|
|
16
41
|
process.stdout.write(`${shortCliHelp(HARNESS_VERSION)}
|
|
17
42
|
`);
|
|
18
43
|
} else {
|
|
19
|
-
const { runCli } = await import("./cli-
|
|
44
|
+
const { runCli } = await import("./cli-vyrytn3m.js");
|
|
20
45
|
await runCli(argv);
|
|
21
46
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Audit pack
|
|
2
|
+
|
|
3
|
+
Experimental operator export. It is not part of the stable root API. Import it
|
|
4
|
+
from `@zhivex-ai/harness/audit`. The commands are `export-audit` and
|
|
5
|
+
`verify-audit` on both `zhx` and `zhivex-code`.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
export ZHIVEX_AUDIT_SIGNING_KEY="$(openssl rand -base64 32)"
|
|
9
|
+
zhx export-audit <task-id> --out ./audit-pack
|
|
10
|
+
zhx verify-audit --out ./audit-pack
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`--signing-key-file <path>` overrides the environment variable. The key is 32 to
|
|
14
|
+
4096 bytes. A single trailing newline in the file is ignored. The key is not
|
|
15
|
+
written into the pack. `--out` and `--signing-key-file` are experimental flags
|
|
16
|
+
and are not members of the stable `CLI_OPTION_NAMES` tuple.
|
|
17
|
+
|
|
18
|
+
## What one bundle contains
|
|
19
|
+
|
|
20
|
+
The subject is a run id, or a guided task id. A run id produces one flat
|
|
21
|
+
directory. A guided task id produces one directory whose member runs live under
|
|
22
|
+
`runs/<id>/`. A task with a single recorded run stays flat.
|
|
23
|
+
|
|
24
|
+
| File | Source |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| `manifest.json` | Hashes and the HMAC. Not hashed inside itself. |
|
|
27
|
+
| `governance-report.json` | `exportHarnessGovernanceReport`. Pseudonymous tree projection. |
|
|
28
|
+
| `approvals.json` | Every `approvalDecisionViews` page, up to the governance report's 512-record ceiling, then the same email and common-token redaction policy used by the activity journal. |
|
|
29
|
+
| `policy-decisions.json` | Activity events parsed with `harnessPolicyDecisionEventSchema`. |
|
|
30
|
+
| `redaction.jsonl` | The durable redacted activity journal for that run. This is not a second redactor and not a list of removed tokens. |
|
|
31
|
+
| `usage-ledger.json` | `inspectUsageLedger` on the run metadata, plus `UsageLedger.summary` when the operations database can be opened. |
|
|
32
|
+
|
|
33
|
+
The governance report already walks child runs. Approval, policy, redaction and
|
|
34
|
+
usage files describe the selected run, or each run on the task account. Those
|
|
35
|
+
files and the governance report are taken from one captured snapshot of each
|
|
36
|
+
selected run and its journal. If that snapshot, or the task account that named
|
|
37
|
+
the runs, changes before the manifest is signed, export fails with
|
|
38
|
+
`AUDIT_PACK_STATE_CHANGED` and writes nothing. Export does not call a model,
|
|
39
|
+
execute a tool, or rewrite run state. Opening the usage ledger uses the existing
|
|
40
|
+
`UsageLedger.open` path, which ensures its transport tables exist and does not
|
|
41
|
+
append call rows. Estimates are not invoices.
|
|
42
|
+
|
|
43
|
+
Each payload file is at most 8 MiB. The manifest plus every payload file is at
|
|
44
|
+
most 32 MiB. Verification uses the same total, so a directory that exports can
|
|
45
|
+
be verified. A larger directory fails with `AUDIT_PACK_LIMIT`.
|
|
46
|
+
|
|
47
|
+
Pass `--session <sessionId>` to include the retained activity journal. Without
|
|
48
|
+
it, the redaction log and policy file say `unavailable`. Retention and truncation
|
|
49
|
+
stay explicit. Session ids are not copied into the JSONL; the governance report
|
|
50
|
+
keeps its session pseudonym.
|
|
51
|
+
|
|
52
|
+
The first JSONL line is a `zhivex-redaction-log` header. Later lines are
|
|
53
|
+
`zhivex-redacted-activity` records: sequence, run id, optional time, and the
|
|
54
|
+
stored activity object.
|
|
55
|
+
|
|
56
|
+
## Manifest and HMAC
|
|
57
|
+
|
|
58
|
+
`manifest.json` is schema 1, kind `zhivex-harness-audit-pack`, integrity
|
|
59
|
+
`hmac-sha256`. `files` lists each payload path, byte length, and SHA-256.
|
|
60
|
+
Verification requires the directory to contain exactly those files plus
|
|
61
|
+
`manifest.json`. Paths stay inside the directory. Symlinks are rejected.
|
|
62
|
+
Unknown files, missing files, and hash mismatches fail.
|
|
63
|
+
|
|
64
|
+
The signature covers the canonical form of the manifest with the `signature`
|
|
65
|
+
field removed:
|
|
66
|
+
|
|
67
|
+
- arrays keep their order
|
|
68
|
+
- object keys are sorted lexicographically by UTF-16 code unit
|
|
69
|
+
- `undefined` object entries are omitted
|
|
70
|
+
- strings and numbers use `JSON.stringify`
|
|
71
|
+
- there is no whitespace
|
|
72
|
+
|
|
73
|
+
`signature.keyId` is the first 16 hexadecimal characters of SHA-256 over the
|
|
74
|
+
raw key bytes. `signature.value` is standard base64 of HMAC-SHA256 over the
|
|
75
|
+
canonical UTF-8 bytes. Verification uses a constant-time compare. A different
|
|
76
|
+
key fails with `AUDIT_PACK_KEY_MISMATCH` when the key id does not match, and
|
|
77
|
+
`AUDIT_PACK_SIGNATURE_INVALID` when the key id matches but the MAC does not.
|
|
78
|
+
|
|
79
|
+
HMAC is the mechanism in this repository that an operator can configure without
|
|
80
|
+
a new key format. Change envelopes already bind SHA-256 digests and leave
|
|
81
|
+
producer authenticity unverified. Desktop update manifests use Ed25519 because
|
|
82
|
+
a publisher and a verifier must not share a secret. An audit pack is an
|
|
83
|
+
operator seal of local records: the same party exports and verifies, or shares
|
|
84
|
+
the key out of band. Anyone who has the key can produce a pack that verifies.
|
|
85
|
+
This is integrity against modification by someone who does not have the key. It
|
|
86
|
+
is not a third-party attestation and it does not prove who ran the task.
|
|
87
|
+
|
|
88
|
+
## Commands
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
zhx export-audit <task-id> --out <directory> [--session <id>] [--json]
|
|
92
|
+
zhx verify-audit --out <directory> [--json]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`zhivex-code` accepts the same two commands. Locator flags match other state
|
|
96
|
+
commands. `--json` prints the manifest or the verification document. The
|
|
97
|
+
directory must not already exist for export. Verification reads the directory
|
|
98
|
+
and the signing key only. It does not resolve provider, store, or budget
|
|
99
|
+
configuration, and it does not open the workspace.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Azure OpenAI (provisional)
|
|
2
|
+
|
|
3
|
+
Azure OpenAI is a separate provider (`azure-openai`). It does not reuse
|
|
4
|
+
`OPENAI_API_KEY` or `OPENAI_BASE_URL`. No live Harness certification has been
|
|
5
|
+
run for this route. Prices are not copied from the public OpenAI catalog.
|
|
6
|
+
|
|
7
|
+
Published `@zhivex-ai/azure-openai@0.7.8` is the adapter pinned by this tree.
|
|
8
|
+
It requires Core `^1.34.0`, and this checkout pins `@zhivex-ai/core@1.34.0`.
|
|
9
|
+
Language models report Tier A. Hosted tool gates such as tool search follow
|
|
10
|
+
the model id (`gpt-5.4` and `gpt-6-astra` in this adapter). An opaque
|
|
11
|
+
deployment name does not receive those gates unless a deployment map names
|
|
12
|
+
the base model.
|
|
13
|
+
|
|
14
|
+
Published 0.7.8 accepts a deployments map and a token provider for Microsoft
|
|
15
|
+
Entra ID. This route still authenticates with an API key and does not pass a
|
|
16
|
+
token provider.
|
|
17
|
+
|
|
18
|
+
## Configuration
|
|
19
|
+
|
|
20
|
+
Set `AZURE_OPENAI_ENDPOINT` to an https URL with no user, password, query, or
|
|
21
|
+
fragment. Set `AZURE_OPENAI_API_KEY` in the environment, or store it in the CLI
|
|
22
|
+
keychain or a temporary session. The endpoint is required with a managed key.
|
|
23
|
+
It is not treated as an override that blocks the keychain.
|
|
24
|
+
|
|
25
|
+
`AZURE_OPENAI_API_VERSION` is optional. When it is set, requests use
|
|
26
|
+
`/openai/deployments/{deployment}/chat/completions?api-version=...` and the
|
|
27
|
+
deployment name is not also sent as `model`. When it is omitted, requests use
|
|
28
|
+
`/openai/v1/chat/completions` and the body includes the model id.
|
|
29
|
+
|
|
30
|
+
`AZURE_OPENAI_DEPLOYMENTS` is optional JSON, at most 8192 characters and 32
|
|
31
|
+
entries. Each entry is `"name": "gpt-5.4"` or `"name": { "model": "gpt-5.4" }`.
|
|
32
|
+
Deployment names and model ids are restricted to simple identifier characters.
|
|
33
|
+
Harness passes the map to the adapter. Published 0.7.8 uses the base model for
|
|
34
|
+
capabilities and request shape while the request still uses the deployment
|
|
35
|
+
name. Harness also overlays those capability flags.
|
|
36
|
+
|
|
37
|
+
The published adapter also reads omitted endpoint, key, and API version from
|
|
38
|
+
`process.env`. Harness passes the endpoint and key from the selected
|
|
39
|
+
environment. When that environment omits the API version, Harness hides
|
|
40
|
+
`process.env.AZURE_OPENAI_API_VERSION` for the adapter constructor so a host
|
|
41
|
+
value cannot change the route.
|
|
42
|
+
|
|
43
|
+
## Durable execution
|
|
44
|
+
|
|
45
|
+
Endpoint, API version, and the deployments document are hashed into the durable
|
|
46
|
+
transport binding. The API key is not. Unconfigured Azure OpenAI does not
|
|
47
|
+
change existing provider transport bindings.
|
|
48
|
+
|
|
49
|
+
Provider errors are replaced with a generic message. Numeric status and the
|
|
50
|
+
retryable flag are kept. Response bodies and the API key are dropped.
|
|
51
|
+
|
|
52
|
+
Deterministic tests stub `fetch`. They do not contact Azure and they do not
|
|
53
|
+
check account access.
|
package/docs/BEDROCK.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Amazon Bedrock (provisional)
|
|
2
|
+
|
|
3
|
+
Bedrock is a separate provider (`bedrock`). It is not enabled by the Anthropic
|
|
4
|
+
direct API route. No live Harness certification has been run for this route.
|
|
5
|
+
Pricing and context limits are not inferred.
|
|
6
|
+
|
|
7
|
+
Published `@zhivex-ai/bedrock@2.0.7` is the adapter pinned by this tree. It
|
|
8
|
+
requires Core `^1.34.0`, and this checkout pins `@zhivex-ai/core@1.34.0`.
|
|
9
|
+
This integration reports the installed adapter's labels and does not relabel
|
|
10
|
+
them.
|
|
11
|
+
|
|
12
|
+
## Runtimes
|
|
13
|
+
|
|
14
|
+
`BEDROCK_RUNTIME` is optional. An empty value or `converse` selects the Converse
|
|
15
|
+
API. `openai` selects the OpenAI-compatible runtime. Any other value is rejected.
|
|
16
|
+
|
|
17
|
+
Converse reports Tier B on the published 2.0.7 adapter: reasoning is supported
|
|
18
|
+
and `toolChoiceNone` is true. Approval requests stay false on that runtime.
|
|
19
|
+
Harness reports that installed label.
|
|
20
|
+
|
|
21
|
+
The OpenAI-compatible runtime reports Tier A, including approval requests.
|
|
22
|
+
It needs `BEDROCK_API_KEY` or `AWS_BEARER_TOKEN_BEDROCK`, plus an https
|
|
23
|
+
`BEDROCK_OPENAI_BASE_URL` with no user, password, or fragment. Harness does
|
|
24
|
+
not read `OPENAI_API_KEY` or `OPENAI_BASE_URL` for this route.
|
|
25
|
+
|
|
26
|
+
## Credentials
|
|
27
|
+
|
|
28
|
+
Converse uses the AWS SDK default credential chain: instance roles, SSO,
|
|
29
|
+
shared config, and environment credentials. Set `AWS_REGION` or
|
|
30
|
+
`AWS_DEFAULT_REGION` to a region such as `us-east-1`. `AWS_PROFILE` is part of
|
|
31
|
+
the transport fingerprint. Published 2.0.7 accepts a profile and static
|
|
32
|
+
credentials on the adapter. This route does not pass `AWS_PROFILE`. When
|
|
33
|
+
`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are both set, and no bearer
|
|
34
|
+
token is set, Converse uses that static pair and an optional
|
|
35
|
+
`AWS_SESSION_TOKEN`. Otherwise the AWS SDK default chain applies. Harness
|
|
36
|
+
does not call AWS while checking that the route is configured. Incomplete
|
|
37
|
+
settings, such as a profile or runtime with no region or OpenAI route, stay
|
|
38
|
+
out of the durable transport fingerprint.
|
|
39
|
+
|
|
40
|
+
An explicit `AWS_BEARER_TOKEN_BEDROCK` in the Harness environment selects bearer
|
|
41
|
+
auth for Converse and skips the default chain. The CLI does not store a Converse
|
|
42
|
+
API key. The OpenAI-compatible runtime can use a keychain or temporary
|
|
43
|
+
`BEDROCK_API_KEY` together with the required base URL.
|
|
44
|
+
|
|
45
|
+
## Durable execution
|
|
46
|
+
|
|
47
|
+
Region, default region, profile, runtime, and the OpenAI base URL are hashed
|
|
48
|
+
into the durable transport binding. API keys and bearer tokens are not.
|
|
49
|
+
Unconfigured Bedrock does not change existing provider transport bindings.
|
|
50
|
+
|
|
51
|
+
Provider errors are replaced with a generic message. Numeric status and the
|
|
52
|
+
retryable flag are kept. Response bodies, account identifiers, and credentials
|
|
53
|
+
are dropped.
|
|
54
|
+
|
|
55
|
+
Deterministic tests mock the AWS client and the OpenAI-compatible HTTP call.
|
|
56
|
+
They are not evidence of model access, IAM, or a live region.
|
package/docs/CLI.md
CHANGED
|
@@ -826,6 +826,21 @@ expiry are checked separately. Patch bytes and producer authenticity remain
|
|
|
826
826
|
unverified. No envelope v1 fields are added. Concurrent source changes and hard
|
|
827
827
|
capacity limits reject export; bounded tree/history truncation is reported.
|
|
828
828
|
|
|
829
|
+
### Audit pack (Experimental)
|
|
830
|
+
|
|
831
|
+
`zhx export-audit <task-id> --out <directory>` writes one signed directory for a
|
|
832
|
+
run, or for every run recorded on a guided task account. `zhx verify-audit --out <directory>`
|
|
833
|
+
recomputes the file hashes and the HMAC. It does not resolve provider, store, or
|
|
834
|
+
budget configuration. Both commands also accept the workspace locator options
|
|
835
|
+
(`--workspace`, `--state-dir`, `--store`, `--tenant`, `--user`, `--namespace`)
|
|
836
|
+
and `--json`. Export also accepts `--session <sessionId>` and is the command
|
|
837
|
+
that resolves those options.
|
|
838
|
+
|
|
839
|
+
`--out` and `--signing-key-file` are experimental flags for these commands. They
|
|
840
|
+
are not part of the stable option list. The signing key comes from
|
|
841
|
+
`--signing-key-file` or `ZHIVEX_AUDIT_SIGNING_KEY` and is never written into the
|
|
842
|
+
pack. See [Audit pack](AUDIT_PACK.md).
|
|
843
|
+
|
|
829
844
|
## Experimental project memory (unreleased)
|
|
830
845
|
|
|
831
846
|
`zhx memory` supports `remember`, `list`, `read`, `update`, `forget`, `suggest`, `accept`, `context`, `clear`, `enable` and `disable`. Content is one quoted argument. Updates, acceptance and forgetting require the current revision. `--source` supplies a provenance label; `--no-memory` disables curated retrieval and SDK memory loading/capture for a local run/chat/resume invocation. Existing workspace/tenant/user/namespace flags select scope. See [Project memory](PROJECT_MEMORY.md) for bounds, review, deletion semantics and next-release pairing.
|
package/docs/CLIENT_PROTOCOL.md
CHANGED
|
@@ -91,8 +91,141 @@ or a replacement for the engine's signed approval validation.
|
|
|
91
91
|
| session.rename | projectId, sessionId, expectedRevision, idempotencyKey, title | session | REVISION_CONFLICT |
|
|
92
92
|
| run.start | projectId, sessionId, expectedRevision, idempotencyKey, prompt | run | INVALID_STATE |
|
|
93
93
|
| run.get | projectId, sessionId, runId | run | NOT_FOUND |
|
|
94
|
+
| task.get | projectId, sessionId, runId, projectionVersion: 1 | task | VERSION_UNSUPPORTED / NOT_FOUND |
|
|
94
95
|
| approval.resolve | projectId, sessionId, runId, expectedRevision, idempotencyKey, decisions | run | APPROVAL_MISMATCH |
|
|
95
96
|
| run.cancel | projectId, sessionId, runId, expectedRevision, idempotencyKey | run | REVISION_CONFLICT |
|
|
97
|
+
|
|
98
|
+
## Task projection v1 (HAR-HU-73)
|
|
99
|
+
|
|
100
|
+
Negotiate `task.get` and `task.projection.v1` before using this additive read.
|
|
101
|
+
Protocol major 1 and all legacy commands keep their meaning. Older hosts without
|
|
102
|
+
the capability cannot provide this projection; clients must show it as unavailable.
|
|
103
|
+
The host must already have a task contract and a session binding for its runs.
|
|
104
|
+
This command creates neither a task nor a budget and does not provide a new execution
|
|
105
|
+
or acceptance API. CODE-05 presentation remains separate.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { reduceHarnessTaskProjection } from '@zhivex-ai/harness/protocol';
|
|
109
|
+
|
|
110
|
+
const hello = adapter.negotiate([1]);
|
|
111
|
+
if (!hello.ok || !hello.capabilities.includes('task.projection.v1')) {
|
|
112
|
+
throw new Error('Task projection unavailable');
|
|
113
|
+
}
|
|
114
|
+
const scope = { connectionId: hello.connectionId, projectId: hello.projectId,
|
|
115
|
+
sessionId, runId }; // IDs selected from this host's session index.
|
|
116
|
+
const response = await adapter.dispatch({ protocolVersion: 1, requestId: 'task-read-1',
|
|
117
|
+
connectionId: scope.connectionId,
|
|
118
|
+
command: { method: 'task.get', projectId: scope.projectId, sessionId, runId,
|
|
119
|
+
projectionVersion: 1 } });
|
|
120
|
+
if (response.ok && response.data.kind === 'task') {
|
|
121
|
+
const view = reduceHarnessTaskProjection(null, response.data.projection, scope);
|
|
122
|
+
// Display view.snapshot as untrusted text. This helper never executes anything.
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The same request uses `/command` on the existing authenticated local service.
|
|
127
|
+
Reads remain available while admission is busy or paused. The host checks the full
|
|
128
|
+
task-account run set against the selected session before reading run journals or
|
|
129
|
+
artifacts; mixed-session accounts fail closed. An older requested run identifies
|
|
130
|
+
the task, but `observedRunId` and `historicalRequest` explicitly identify its latest
|
|
131
|
+
recorded run. Missing runs never turn an earlier delivery into the current result.
|
|
132
|
+
|
|
133
|
+
The strict DTO carries:
|
|
134
|
+
|
|
135
|
+
- Contract revision/digest, retained operator objective with provenance, run revision
|
|
136
|
+
and durable execution status. No provider response or hidden reasoning is included.
|
|
137
|
+
- Observed and delivered snapshot digests, contract path labels, and current/stale/
|
|
138
|
+
missing correspondence. No arbitrary file path or artifact-content request exists.
|
|
139
|
+
Artifact references stay under the same project/session/run read boundary.
|
|
140
|
+
- Checks reconciled against the current contract, exact native bytes and completed
|
|
141
|
+
tool journal. `structure: verified` is deterministic evidence only; semantic review
|
|
142
|
+
stays `pending` and final acceptance stays `not_recorded`. Human requirements retain
|
|
143
|
+
their canonical `pending` state. Execution completion is never human acceptance.
|
|
144
|
+
- Authoritative confirmed/reserved/unknown token quantities, remaining allowance,
|
|
145
|
+
frozen limits and account revision. Reservations are admission estimates, not
|
|
146
|
+
confirmed consumption; a separate token estimate is not recorded. Monetary
|
|
147
|
+
confirmed-call estimates, reservations and unknown exposure remain estimates, not
|
|
148
|
+
invoices. Unknown quantities stay null/unknown, never invented zeros.
|
|
149
|
+
- Read-only/recorded/unknown effect counts and missing-evidence flags. Provider stop
|
|
150
|
+
remains unconfirmed. Next action explains wait/reconciliation/review/explicit
|
|
151
|
+
continuation, preserves contract/receipts/budget/effects and never grants execution
|
|
152
|
+
authority or automatic replay. A persisted running status alone does not prove a
|
|
153
|
+
live worker; uncertain finalization requires reconciliation.
|
|
154
|
+
|
|
155
|
+
Genuine legacy contracts without a task account show `legacy_not_enabled` and null
|
|
156
|
+
budget values. An existing account with a missing binding, an unreadable bound
|
|
157
|
+
account, incomplete backup, or conflicting identity is an error, not legacy mode.
|
|
158
|
+
HAR55/56 acceptance, HAR58 evidence principles and HAR70/71/72 ledgers/receipts remain
|
|
159
|
+
the authority; this DTO stores no alternate ledger or acceptance state.
|
|
160
|
+
|
|
161
|
+
Snapshots are derived on demand and revalidated before publication. The host bounds
|
|
162
|
+
the serialized DTO to 64 KiB, each display string to 2,048 UTF-16 code units (with an
|
|
163
|
+
explicit truncation flag), check/review lists to 32 and contract path labels to 256.
|
|
164
|
+
Oversized evidence fails closed. Only allowlisted fields leave the host; roots,
|
|
165
|
+
known secrets and credential patterns are redacted before publication. In-process
|
|
166
|
+
hosts supply `taskProjectionSensitiveValues`; the local service includes its token,
|
|
167
|
+
configured sensitive values and relevant credential environment values. Redaction
|
|
168
|
+
does not make arbitrary workspace text trusted or HTML-safe.
|
|
169
|
+
|
|
170
|
+
### Replay and reconnection
|
|
171
|
+
|
|
172
|
+
`sequence` is assigned at read admission within `connectionId`, not at completion.
|
|
173
|
+
The pure browser-compatible reducer only replaces a snapshot in the caller's
|
|
174
|
+
negotiated connection/project/session/run scope. Duplicate and older responses are
|
|
175
|
+
ignored; conflicting duplicates, unsupported versions and wrong epochs request a
|
|
176
|
+
fresh read. It never adopts a connection ID from an incoming response.
|
|
177
|
+
|
|
178
|
+
Existing activity events are invalidations, not task snapshots or instructions to
|
|
179
|
+
execute. After a relevant page, read `task.get` again. A repeated/out-of-order event
|
|
180
|
+
may cause another harmless read; it cannot recreate effects. When `/events` reports
|
|
181
|
+
`cursorExpired`, discard assumptions derived from missing history and obtain a new
|
|
182
|
+
task snapshot. After service restart, negotiate again, set the expected epoch and
|
|
183
|
+
read durable state; never replay mutations or accept old-epoch snapshots. This is
|
|
184
|
+
snapshot convergence, not a new event store, streaming protocol or delivery guarantee.
|
|
185
|
+
Callers should coalesce refreshes and retry a changing snapshot with a bounded policy.
|
|
186
|
+
|
|
187
|
+
### Finite task errors
|
|
188
|
+
|
|
189
|
+
Task-read errors add `taskDiagnostic` to the existing error envelope, with a finite
|
|
190
|
+
cause, `impact: projection_unavailable`, and the action below. Raw exception text,
|
|
191
|
+
paths, provider payloads and journals are excluded. Malformed command shapes retain
|
|
192
|
+
the existing `INVALID_REQUEST` envelope. Unsupported versions never execute work.
|
|
193
|
+
|
|
194
|
+
| Cause | Client code | Safe action |
|
|
195
|
+
| --- | --- | --- |
|
|
196
|
+
| UNSUPPORTED_VERSION | VERSION_UNSUPPORTED | review_configuration |
|
|
197
|
+
| OUT_OF_SCOPE | NOT_FOUND | review_configuration |
|
|
198
|
+
| UNSUPPORTED_HOST / CONTRACT_UNAVAILABLE | INVALID_STATE | review_configuration |
|
|
199
|
+
| EVIDENCE_UNAVAILABLE | INVALID_STATE | reconcile |
|
|
200
|
+
| SNAPSHOT_CHANGED | REVISION_CONFLICT | retry_read |
|
|
201
|
+
| PAYLOAD_LIMIT | CAPACITY_EXCEEDED | review_configuration |
|
|
202
|
+
|
|
203
|
+
Inside a successful projection, terminal failure/cancellation/timeout and incomplete
|
|
204
|
+
evidence have separate finite diagnostics with `acceptance_not_established` impact.
|
|
205
|
+
No diagnostic recommends replaying an uncertain operation. This cut supports one
|
|
206
|
+
trusted native workspace/SQLite writer and sequential host handoff only. OCI task
|
|
207
|
+
projections, multiagent scope, new document/web adapters and final semantic/human
|
|
208
|
+
acceptance are unsupported; legacy execution APIs are unchanged.
|
|
209
|
+
|
|
210
|
+
### Reproducible installed consumer
|
|
211
|
+
|
|
212
|
+
Build and pack Harness and Code from the same clean candidate following their
|
|
213
|
+
normal build instructions. The existing HAR75 installer accepts an optional sixth
|
|
214
|
+
argument selecting the HAR73 profile; it freezes/rechecks consumer, manifest and
|
|
215
|
+
tarball hashes and verifies Code/service share the installed engine:
|
|
216
|
+
|
|
217
|
+
```sh
|
|
218
|
+
node scripts/task-recovery-lab-installed.mjs /tmp/harness.tgz /tmp/code.tgz \
|
|
219
|
+
/absolute/path/to/node /tmp/projection-node 90000 projection
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Repeat with supported Node 22/24 and Bun. `evaluations/task-projection.json` fixes
|
|
223
|
+
the reused HAR75 fixture and ten consumer scenarios: version negotiation, readonly
|
|
224
|
+
snapshot, redaction, duplicate/out-of-order responses, artifact scope, expired cursor,
|
|
225
|
+
paused admission, fresh-epoch restart, artifact drift and legacy budget. Source
|
|
226
|
+
regressions additionally exercise corrupted/missing bindings and runs, changing
|
|
227
|
+
snapshots, read admission races, active mutations and payload limits. These are offline
|
|
228
|
+
contract tests, not CODE-05 UI acceptance, live-model quality or an external pilot.
|
|
96
229
|
| checkpoint.list | projectId, sessionId | checkpoints | NOT_FOUND |
|
|
97
230
|
| checkpoint.inspect | projectId, sessionId, checkpointId | checkpoint | NOT_FOUND |
|
|
98
231
|
| checkpoint.capture | projectId, sessionId, expectedRevision, idempotencyKey, turnId, paths | checkpoint | EXECUTION_FAILED |
|
|
@@ -273,3 +406,48 @@ It omits command argv, repository output and arbitrary tool payloads.
|
|
|
273
406
|
or human acceptance. Existing status/exit-code and schema-version contracts remain
|
|
274
407
|
unchanged. Code inspection/export derives the same safe projection from completed
|
|
275
408
|
tool-journal entries; the engine inspection API signature is unchanged.
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
## Task controls (CODE-HU-05, experimental)
|
|
412
|
+
|
|
413
|
+
Negotiate `task.control.v1` and each command before showing mutation controls.
|
|
414
|
+
The strict command schema remains protocol v1. The host creates the contract;
|
|
415
|
+
clients cannot supply a contract, receipt, budget ledger or execution grant.
|
|
416
|
+
|
|
417
|
+
| Method | Additional input | Result |
|
|
418
|
+
| --- | --- | --- |
|
|
419
|
+
| `task.start` | session, expectedRevision, idempotencyKey, bounded brief with goal/paths/checks/constraints and explicit input/output/total token limits | run |
|
|
420
|
+
| `task.review` | session, run | taskReview |
|
|
421
|
+
| `task.keep` | session, run, reviewId, idempotencyKey | task + humanDecision |
|
|
422
|
+
| `task.revise` | same review binding + correction (1–500 characters) | task + humanDecision |
|
|
423
|
+
| `task.continue` | same review binding + prompt (1–2000 characters) | run |
|
|
424
|
+
|
|
425
|
+
A taskReview contains a redacted bounded Git diff, fresh projection, allowed
|
|
426
|
+
actions, a `complete` flag, operator-decision status and a five-minute, one-use host token. Tokens
|
|
427
|
+
bind connection, session, run revision, contract, current snapshot, task budget
|
|
428
|
+
revision and Git status/diff identity. The web host additionally binds tokens
|
|
429
|
+
to its authenticated browser identity and workspace. Missing, consumed, expired
|
|
430
|
+
or changed reviews fail closed. Hidden/truncated review content cannot enable keep. A command retry with the same idempotency key
|
|
431
|
+
returns its existing response; a renderer must read state after a lost response,
|
|
432
|
+
never manufacture another mutation key automatically.
|
|
433
|
+
|
|
434
|
+
Keep records `humanDecision` with `explicit_operator_review` provenance under
|
|
435
|
+
task-account exclusion and run CAS. It does not change the projection's semantic
|
|
436
|
+
pending/acceptance-not-recorded fields, commit files or imply independent human
|
|
437
|
+
quality measurement. A changed contract or snapshot makes the record stale.
|
|
438
|
+
Revise appends a bounded pending human requirement without executing work.
|
|
439
|
+
Continue uses the original durable account and rechecks the reviewed admission
|
|
440
|
+
tuple inside runtime continuity; it cannot replenish credit or replay uncertainty.
|
|
441
|
+
Ordinary run.start is rejected in sessions retaining governed task authority.
|
|
442
|
+
|
|
443
|
+
A continuation rejected before admission can have a failed session attempt with
|
|
444
|
+
a host-owned reference to its prior admitted run. Reads resolve this reference
|
|
445
|
+
only within the same session and only when the attempt is absent from the budget
|
|
446
|
+
account. The projection preserves the requested runId, exposes observedRunId and
|
|
447
|
+
historicalRequest, and retains stale/missing checks honestly. New review commands
|
|
448
|
+
must target observedRunId. No budget admission or consumption is fabricated.
|
|
449
|
+
|
|
450
|
+
Migration: fields and commands are additive and experimental. Existing projection
|
|
451
|
+
version 1, legacy chat and exact tool approvals remain intact. Match host and Code
|
|
452
|
+
builds; unsupported hosts display an unavailable task-control state. See
|
|
453
|
+
[Code web tasks](CODE_WEB_TASKS.md) for native workspace limits and offline QA.
|
package/docs/CODE_RELEASE.md
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
# Code release procedure
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Pending patch: 2026-10-16
|
|
4
|
+
|
|
5
|
+
The source version is `1.5.0`, pending publication to `latest`. This checkout
|
|
6
|
+
prepares Harness `1.5.0` and Code `0.4.0` for npm `latest`, with Code pinned
|
|
7
|
+
exactly to the engine and private Desktop bound to the same Harness version.
|
|
8
|
+
Published `latest` is Harness `1.4.1` and Code `0.3.2`. It adds the `v1.5.0`
|
|
9
|
+
representative mapping with the same Meta, Qwen and OpenAI models as `v1.4.1`
|
|
10
|
+
and does not change provider/API tiers. Annotated `v1.5.0` then `code-v0.4.0`
|
|
11
|
+
on the same reviewed main SHA, `channel=latest`, run through the unchanged
|
|
12
|
+
protected workflows and their environment approvals.
|
|
13
|
+
|
|
14
|
+
## Pending patch: 2026-10-14
|
|
15
|
+
|
|
16
|
+
This checkout prepares Code `0.3.1`, pinned exactly to Harness `1.4.1`, for npm
|
|
17
|
+
`latest`. Published Code `0.3.0` and Harness `1.4.0` are the current `latest`
|
|
18
|
+
packages. Published npm `next` is Code `0.3.0-rc.8` and Harness `1.4.0-rc.8`.
|
|
19
|
+
The Vertex transient-failure retry and explicit monetary output caps shipped in
|
|
20
|
+
Code `0.3.0` / Harness `1.4.0`. This patch keeps the narrow composer readable,
|
|
21
|
+
says when you rejected an operation, checks Node before startup, describes
|
|
22
|
+
command reviews as commands, and shows web limits in English. The local browser
|
|
23
|
+
retries reconciliation when a command finishes during reconnect. That patch
|
|
24
|
+
moved Core to 1.33.0 for private-host checks. Unreleased Bedrock and Azure
|
|
25
|
+
OpenAI routes pin Core 1.34.0. Anthropic 0.14.0, OpenAI 0.16.0 and Vertex 1.2.7
|
|
26
|
+
replace the previous adapter pins; Agents, Qwen, Meta and Gemini stay as they
|
|
27
|
+
are on main. Optional `@napi-rs/keyring` is 2.1.1. Approval and transport
|
|
28
|
+
protections and provider/API tiers stay unchanged.
|
|
29
|
+
Desktop stays private alpha with the same engine binding. The 1.4.0 preparation
|
|
30
|
+
below remains historical; its evidence does not certify or authorize `0.3.1`.
|
|
31
|
+
|
|
32
|
+
This preparation creates no tags, paid calls, campaign dispatch or publication.
|
|
33
|
+
After review and user integration, require all four successful exact-main workflows
|
|
34
|
+
(`ci.yml`, `codeql.yml`, `code-journey.yml`, `web.yml`) and direct-main CodeQL.
|
|
35
|
+
New explicit campaign/publication authority is required before any Harness
|
|
36
|
+
`v1.4.1` or Code `code-v0.3.1` tag/dispatch. Harness must first pass its
|
|
37
|
+
unchanged protected exact-artifact, OCI, live and representative gates and actual
|
|
38
|
+
registry integrity/provenance verification. Code's protected OIDC workflow then
|
|
39
|
+
uses the matching reviewed SHA with `channel=latest`, `mode=oidc` and explicit
|
|
40
|
+
confirmation, resolving the actual published Harness dependency without overrides.
|
|
41
|
+
Retained-artifact terminal/web, four-manager acceptance and registry bytes with
|
|
42
|
+
source-bound provenance remain mandatory. Preserve published `next` and all history.
|
|
43
|
+
|
|
44
|
+
## Previous stable preparation: 2026-10-09
|
|
4
45
|
|
|
5
46
|
This checkout prepares Code `0.3.0`, pinned exactly to Harness `1.4.0`, for npm
|
|
6
47
|
`latest`. Published Code `0.2.0` and Harness `1.3.0` on `latest` remain
|
|
@@ -248,9 +289,17 @@ support remain unchanged; estimated budgets are not guaranteed financial caps.
|
|
|
248
289
|
verification as ordered in [the Harness release procedure](https://github.com/Zhivex/zhivex-harness/blob/main/docs/RELEASE.md).
|
|
249
290
|
From a clean checkout of that main commit, create an annotated
|
|
250
291
|
`code-v0.2.0` tag and push it. Never move or overwrite release tags.
|
|
251
|
-
4. Dispatch `release-code.yml` **
|
|
252
|
-
`channel=latest`, `mode=oidc`, and `confirm_publication=true`.
|
|
253
|
-
|
|
292
|
+
4. Dispatch `release-code.yml` **from that exact tag ref**, with input `tag`
|
|
293
|
+
matching it and `channel=latest`, `mode=oidc`, and `confirm_publication=true`.
|
|
294
|
+
A no-permission job is defense in depth, not the trust boundary, because
|
|
295
|
+
GitHub loads it from the dispatched ref. When it still runs, it requires
|
|
296
|
+
`GITHUB_REF` to be exactly `refs/tags/code-v0.2.0`, resolves that annotated
|
|
297
|
+
tag to the workflow commit, and requires the commit to be reachable from
|
|
298
|
+
`main` before provenance OIDC, provider-free validation, or npm publication
|
|
299
|
+
starts. Dispatch from `main` or any other ref is rejected, including when
|
|
300
|
+
the commit matches the tag. Publication still depends on the `npm`
|
|
301
|
+
environment allowing only selected `v*` and `code-v*` tags, and on the tag
|
|
302
|
+
ruleset in [Public repository security](PUBLIC_SECURITY.md).
|
|
254
303
|
|
|
255
304
|
```sh
|
|
256
305
|
gh workflow run release-code.yml --ref code-v0.2.0 \
|
|
@@ -320,10 +369,13 @@ In npm package settings, configure GitHub Actions with organization `Zhivex`,
|
|
|
320
369
|
repository `zhivex-harness`, workflow filename `release-code.yml`, and environment
|
|
321
370
|
`npm`. Enable the allowed action `npm publish`; the OIDC job uses direct
|
|
322
371
|
publishing after GitHub approval, not `npm stage publish`. Preserve the GitHub
|
|
323
|
-
environment's required human approval
|
|
372
|
+
environment's required human approval and the selected-tag deployment rule in
|
|
373
|
+
[Public repository security](PUBLIC_SECURITY.md). That environment rule, with
|
|
374
|
+
the maintainer-only tag ruleset, is the trust boundary. The in-repo resolver is
|
|
375
|
+
defense in depth, not the trust boundary. Then prepare a
|
|
324
376
|
new Code stable or RC version and annotated tag through the same PR and main CI process.
|
|
325
|
-
Dispatch
|
|
326
|
-
`confirm_publication=true`. Stable versions require `latest` and a stable exact
|
|
377
|
+
Dispatch the workflow from that exact tag ref, with the matching channel, `mode=oidc` and
|
|
378
|
+
`confirm_publication=true`. A dispatch from `main` is rejected. Stable versions require `latest` and a stable exact
|
|
327
379
|
Harness dependency; canonical RC versions require `next`. Version/channel drift
|
|
328
380
|
fails before engine downloads. An RC may pin a stable engine. Stable publication
|
|
329
381
|
does not upgrade beta/experimental APIs, provisional providers or Desktop alpha.
|