@zhivex-ai/harness 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +29 -10
  2. package/README.md +7 -5
  3. package/SUPPORT.md +2 -2
  4. package/contracts/client-protocol-v1.schema.json +593 -0
  5. package/contracts/engine-api.json +156 -0
  6. package/contracts/public-api.json +12 -0
  7. package/contracts/stable-api-signatures.json +33 -33
  8. package/dist/acp-cli.js +54 -20
  9. package/dist/audit/index.d.ts +3 -0
  10. package/dist/audit/index.js +482 -0
  11. package/dist/audit/pack.d.ts +72 -0
  12. package/dist/audit-pack-e4vaq7np.js +532 -0
  13. package/dist/cli/arguments.d.ts +3 -1
  14. package/dist/cli/audit-pack.d.ts +24 -0
  15. package/dist/cli/cli-credentials.d.ts +6 -0
  16. package/dist/cli/cli-profiles.d.ts +4 -2
  17. package/dist/cli/node-engine.d.ts +2 -0
  18. package/dist/{cli-2h37qyvg.js → cli-1cf4dcnj.js} +245 -642
  19. package/dist/{cli-entry-w0hterjs.js → cli-entry-3s63zn4w.js} +40 -13
  20. package/dist/cli-entry-7f0cen32.js +9990 -0
  21. package/dist/cli-entry-a890x3kq.js +10348 -0
  22. package/dist/{cli-entry-20w6nh0k.js → cli-entry-hdtfef27.js} +439 -19
  23. package/dist/cli-entry-rgs6bxmy.js +484 -0
  24. package/dist/cli.js +27 -2
  25. package/dist/client/json-contracts.d.ts +4 -0
  26. package/dist/client/protocol.d.ts +133 -0
  27. package/dist/client/task-control-host.d.ts +400 -0
  28. package/dist/client/task-projection-host.d.ts +12 -0
  29. package/dist/client/task-projection.d.ts +168 -0
  30. package/dist/compat/code-support.js +28 -22
  31. package/dist/{config-qt69hkqj.js → config-r9fdhce6.js} +3 -3
  32. package/dist/{config-j9624t6t.js → config-vyajmksy.js} +1 -1
  33. package/dist/engine/acp.js +15 -11
  34. package/dist/engine/client.js +14 -10
  35. package/dist/engine/desktop-providers-v1.d.ts +2 -0
  36. package/dist/engine/desktop-providers-v1.js +23 -3
  37. package/dist/engine/desktop-state-v1.js +11 -8
  38. package/dist/engine/index.d.ts +3 -0
  39. package/dist/engine/index.js +101 -554
  40. package/dist/engine/mcp-stdio-v1.js +8 -6
  41. package/dist/engine/models.js +76 -4
  42. package/dist/engine/protocol.d.ts +2 -0
  43. package/dist/engine/protocol.js +110 -0
  44. package/dist/engine/service.js +15 -11
  45. package/dist/hostile-repository-demo.js +1095 -505
  46. package/dist/{index-937cb7y8.js → index-02pqtbbg.js} +559 -33
  47. package/dist/{index-pp474137.js → index-0zs2dz26.js} +766 -931
  48. package/dist/{index-8zjmnyw5.js → index-1265j7t2.js} +73 -6
  49. package/dist/index-4fx5f3k5.js +269 -0
  50. package/dist/{index-nmjdwd4p.js → index-4gt045j0.js} +109 -1
  51. package/dist/{index-6dft2vev.js → index-6599mpmy.js} +5 -3
  52. package/dist/{index-tfzta544.js → index-74kkpyqk.js} +9 -7
  53. package/dist/{index-61gthdz6.js → index-8sm2a1wa.js} +1 -1
  54. package/dist/index-c39197wq.js +552 -0
  55. package/dist/{index-5jhgatga.js → index-crta5wzv.js} +7 -6
  56. package/dist/{index-m34q25jj.js → index-d9zkmhz3.js} +143 -824
  57. package/dist/{index-pdmevfxv.js → index-dtb2c6ds.js} +5 -259
  58. package/dist/index-f6mqa5gk.js +1535 -0
  59. package/dist/index-j6zxnc8m.js +490 -0
  60. package/dist/{index-rkbf7dqg.js → index-mv8sb1ns.js} +5 -3
  61. package/dist/{index-xqxeypt5.js → index-mzydbzp8.js} +76 -4
  62. package/dist/{index-wg1sd3at.js → index-qfsrrnz6.js} +1 -1
  63. package/dist/{index-m82cfspw.js → index-sk3cap35.js} +877 -963
  64. package/dist/index-sstgcsr0.js +511 -0
  65. package/dist/index-wm9xeq1n.js +329 -0
  66. package/dist/index-xdbkcccf.js +719 -0
  67. package/dist/{index-s2k2edts.js → index-zxg4ve4j.js} +41 -1548
  68. package/dist/index.d.ts +3 -0
  69. package/dist/index.js +93 -77
  70. package/dist/internal/desktop/providers.d.ts +2 -0
  71. package/dist/models/catalog.d.ts +2 -0
  72. package/dist/persistence/sqlite-database.d.ts +1 -0
  73. package/dist/providers/azure-openai.d.ts +14 -0
  74. package/dist/providers/bedrock.d.ts +23 -0
  75. package/dist/providers/providers.d.ts +1 -1
  76. package/dist/runtime/durable-review-group.d.ts +33 -0
  77. package/dist/runtime/harness.d.ts +11 -0
  78. package/dist/runtime/run-interruption.d.ts +7 -0
  79. package/dist/runtime/shared-budget.d.ts +30 -0
  80. package/dist/runtime/task-continuity.d.ts +300 -77
  81. package/dist/service-cli.js +15 -11
  82. package/dist/{service-client-cli-fn54ev6w.js → service-client-cli-eqrdc9zq.js} +400 -305
  83. package/dist/verify-historical-migrations.js +1095 -505
  84. package/dist/zhx.js +27 -2
  85. package/docs/AUDIT_PACK.md +99 -0
  86. package/docs/AZURE_OPENAI.md +53 -0
  87. package/docs/BEDROCK.md +56 -0
  88. package/docs/CLI.md +15 -0
  89. package/docs/CLIENT_PROTOCOL.md +178 -0
  90. package/docs/CODE_RELEASE.md +31 -1
  91. package/docs/CODE_WEB_TASKS.md +116 -0
  92. package/docs/CONTEXT_ENGINEERING.md +59 -0
  93. package/docs/CREDENTIALS.md +21 -0
  94. package/docs/DURABLE_OPERATIONS.md +93 -1
  95. package/docs/ENGINE_API.md +5 -2
  96. package/docs/EXTENSIBILITY.md +2 -2
  97. package/docs/FIRST_USE.md +6 -6
  98. package/docs/MINIMUM_TASK_AUTHORITY.md +3 -3
  99. package/docs/PROJECT_MEMORY.md +1 -1
  100. package/docs/README.md +6 -1
  101. package/docs/STABILITY.md +3 -1
  102. package/docs/SUPPORT_MATRIX.md +1 -1
  103. package/docs/SUPPORT_MATRIX_1_1.md +1 -1
  104. package/docs/USAGE.md +3 -1
  105. package/docs/VERTEX.md +2 -2
  106. package/docs/WEB_LIMITS.md +4 -3
  107. package/docs/adr/0002-isolated-mcp-stdio.md +6 -3
  108. package/docs/support-matrix-1.1.json +3 -1
  109. package/docs/support-matrix.json +6 -4
  110. package/evaluations/code-task-ui.json +20 -0
  111. package/evaluations/representative-assembly-matrix.json +10 -1
  112. package/evaluations/task-projection.json +10 -0
  113. package/evaluations/task-recovery-lab.json +60 -0
  114. package/examples/README.md +3 -3
  115. package/package.json +23 -13
  116. package/dist/cli-entry-4ngptr62.js +0 -19900
  117. package/dist/index-m49jx72n.js +0 -220
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-w0hterjs.js";
6
+ } from "./cli-entry-3s63zn4w.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-2h37qyvg.js");
44
+ const { runCli } = await import("./cli-1cf4dcnj.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.
@@ -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.
@@ -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.
@@ -1,6 +1,36 @@
1
1
  # Code release procedure
2
2
 
3
- ## Current stable preparation: 2026-10-09
3
+ ## Pending patch: 2026-10-14
4
+
5
+ This checkout prepares Code `0.3.1`, pinned exactly to Harness `1.4.1`, for npm
6
+ `latest`. Published Code `0.3.0` and Harness `1.4.0` are the current `latest`
7
+ packages. Published npm `next` is Code `0.3.0-rc.8` and Harness `1.4.0-rc.8`.
8
+ The Vertex transient-failure retry and explicit monetary output caps shipped in
9
+ Code `0.3.0` / Harness `1.4.0`. This patch keeps the narrow composer readable,
10
+ says when you rejected an operation, checks Node before startup, describes
11
+ command reviews as commands, and shows web limits in English. The local browser
12
+ retries reconciliation when a command finishes during reconnect. That patch
13
+ moved Core to 1.33.0 for private-host checks. Unreleased Bedrock and Azure
14
+ OpenAI routes pin Core 1.34.0. Anthropic 0.14.0, OpenAI 0.16.0 and Vertex 1.2.7
15
+ replace the previous adapter pins; Agents, Qwen, Meta and Gemini stay as they
16
+ are on main. Optional `@napi-rs/keyring` is 2.1.1. Approval and transport
17
+ protections and provider/API tiers stay unchanged.
18
+ Desktop stays private alpha with the same engine binding. The 1.4.0 preparation
19
+ below remains historical; its evidence does not certify or authorize `0.3.1`.
20
+
21
+ This preparation creates no tags, paid calls, campaign dispatch or publication.
22
+ After review and user integration, require all four successful exact-main workflows
23
+ (`ci.yml`, `codeql.yml`, `code-journey.yml`, `web.yml`) and direct-main CodeQL.
24
+ New explicit campaign/publication authority is required before any Harness
25
+ `v1.4.1` or Code `code-v0.3.1` tag/dispatch. Harness must first pass its
26
+ unchanged protected exact-artifact, OCI, live and representative gates and actual
27
+ registry integrity/provenance verification. Code's protected OIDC workflow then
28
+ uses the matching reviewed SHA with `channel=latest`, `mode=oidc` and explicit
29
+ confirmation, resolving the actual published Harness dependency without overrides.
30
+ Retained-artifact terminal/web, four-manager acceptance and registry bytes with
31
+ source-bound provenance remain mandatory. Preserve published `next` and all history.
32
+
33
+ ## Previous stable preparation: 2026-10-09
4
34
 
5
35
  This checkout prepares Code `0.3.0`, pinned exactly to Harness `1.4.0`, for npm
6
36
  `latest`. Published Code `0.2.0` and Harness `1.3.0` on `latest` remain
@@ -0,0 +1,116 @@
1
+ # Code web tasks — CODE-HU-05
2
+
3
+ Canonical story: https://app.notion.com/p/3ef777b104f681309854c8f1e73803f1.
4
+ This screen sits on the experimental task evidence read (`task.get` /
5
+ `task.projection.v1`) and the experimental task controls (`task.control.v1`).
6
+ It extends the existing browser in `packages/web`, packaged by `packages/code`.
7
+ It does not create a second client, an IDE, a file tree, an SDK patch, or a release.
8
+ An operator reviews the host evidence and explicitly accepts that snapshot before
9
+ treating the delivery as acknowledged. Continuation is a separate confirmed
10
+ action on a fresh review ticket; model prose and a completed run are not acceptance.
11
+
12
+ ## Operator flow
13
+
14
+ 1. Open `zhivex-code web`, select an allowed workspace and create an empty session.
15
+ Choose **Define task**. Enter the goal, exact existing editable files, package
16
+ checks and explicit input/output/total token limits for the entire task.
17
+ 2. Review each proposed edit or check through the existing exact approval controls.
18
+ Mark every changed file viewed before approval. Execution, deterministic
19
+ checks, and human acceptance remain separate statuses.
20
+ 3. Open **Result, checks and provenance** for paths, contract/current-byte identity,
21
+ required checks and human requirements. The renderer displays host evidence;
22
+ assistant prose does not establish a passing check or permission.
23
+ 4. Open **Task budget and continuation** for confirmed usage, reservations,
24
+ unknown held exposure and remaining tokens. The account covers all task turns;
25
+ do not add its values to the existing per-run monitor. Missing pricing stays
26
+ unknown; monetary values are estimates, never invoices.
27
+ 5. Choose **Review task** to obtain a bounded fresh Git diff and a five-minute
28
+ review ticket. Explicitly acknowledge the diff and requirements before
29
+ **Accept this snapshot**. This records operator acknowledgement separately
30
+ from engine checks; it does not commit, merge or assert measured quality.
31
+ 6. **Correct requirements** adds a pending requirement without a model call.
32
+ **Continue task** requires another explicit instruction and confirmation.
33
+ Both preserve the original account; continuation may consume its remaining
34
+ credit for model/compaction work, approved edits and checks. Back, Escape,
35
+ Close, reload and reconnect do not execute work.
36
+
37
+ ## Interruption and handoff
38
+
39
+ Cancel initially means requested, not confirmed. A confirmed local cancelled run
40
+ does not prove provider termination. Missing provider usage retains unknown
41
+ exposure and blocks continuation. A lost/failed command response requires reading
42
+ state through Reconnect; it is never automatically retried. Relaunch reopens the
43
+ same durable task, contract, checks, budget and effects without depending on the
44
+ chat transcript or claiming human minutes.
45
+
46
+ The runtime records the first interruption source while relaying its signal;
47
+ nested cancellation signals cannot change a caller cancellation into an
48
+ unclassified failure. It settles local interruption only after the execution
49
+ owner releases its lease. The session index can observe `cancel_requested`
50
+ directly from `created` when busy reads have not yet observed `running`.
51
+ Neither change confirms provider termination or releases unknown exposure.
52
+
53
+ A continuation rejected before admission retains a failed session attempt linked
54
+ to its previous admitted task. The panel explicitly identifies retained evidence;
55
+ checks stale against changed bytes cannot authorize acceptance. The rejected
56
+ attempt does not fabricate budget admission or consumption. A fresh review targets
57
+ the observed admitted run and must satisfy current host checks again.
58
+
59
+ ## Authority and limits
60
+
61
+ - The browser sends a bounded operator brief, never a contract, receipt, policy,
62
+ credential, ledger or execution grant. The host resolves package checks and
63
+ compiles the existing task contract.
64
+ - Initially native Unix workspaces only: clean Git baseline, selected tracked
65
+ visible files (at most 20, each at most 64 KiB), at most eight package checks,
66
+ no subagents. Existing exact edit/check approvals remain mandatory.
67
+ - Reviews bind browser identity/workspace, service connection, session, run
68
+ revision, contract, snapshot, budget revision and Git identity. They are
69
+ one-use and expire after five minutes. Account exclusion plus run CAS protects
70
+ acceptance; continuation rechecks admission after host preparation.
71
+ - Git failure, process-output truncation, oversized review, hidden files,
72
+ missing/changed receipts or uncertain effects fail closed. The diff is plain
73
+ escaped text with host-path/secret redaction. Redacted or truncated review
74
+ content disables acceptance. No arbitrary file-reading route
75
+ or generic browser command dispatcher is added.
76
+ - The existing public projection reducer ignores duplicate/older snapshots,
77
+ rejects changed epochs/scopes and requests refresh for conflicts. Task reads
78
+ are sequential and cancelled on selection changes. Existing activity cursor
79
+ expiry recovery is retained; no activity event grants mutation authority.
80
+ - Ordinary chat remains available in ordinary sessions. Once task authority is
81
+ retained, `run.start` cannot bypass task continuation/accounting. Older hosts
82
+ without negotiated controls show an unsupported state.
83
+
84
+ ## Offline acceptance and reproducibility
85
+
86
+ The frozen HU75 greeting fixture remains SHA256
87
+ `473a9e2144b0042b1b46ef54f915de693045df89d6175bde42a3393d2b083263`.
88
+ `packages/web/scripts/task-browser-journey.mjs` drives actual packaged Code and
89
+ Chromium at desktop/mobile sizes. Its preload replaces provider fetch with a
90
+ synthetic transport and blocks every other fetch; it does not fabricate SDK
91
+ state, tool receipts or check outcomes. `node check.mjs` and exact approvals run
92
+ through the real host/service/engine. This is automated operator input, not a
93
+ human pilot or semantic-quality measurement.
94
+
95
+ The integrated installed runner binds clean source, exact Harness/Code tarball
96
+ hashes and their shared installed engine. It runs the existing recovery/projection
97
+ consumers plus the Code UI journey, then verifies hashes and cleanup. Preserve
98
+ all initial failures separately; only final reports for the exact reviewed SHA
99
+ certify that candidate. Browser fixtures cover normal acceptance, multiple tabs,
100
+ obsolete review, edit/back/Escape, explicit continuation/double click, workspace
101
+ switch, unknown usage on cancellation, reload and process restart. Existing Web
102
+ security/browser gates and projection reducer tests cover host/CSRF/path boundaries,
103
+ expired cursors, stale epochs, reordered/duplicate pages and unavailable evidence.
104
+
105
+ Run the source suites and existing browser regression before the installed runner:
106
+
107
+ ```sh
108
+ node scripts/code-task-ui-installed.mjs /absolute/harness.tgz /absolute/code.tgz /absolute/node /absolute/evidence
109
+ ```
110
+
111
+ The runner requires a clean source checkout and uses an explicit exact candidate
112
+ engine override in its isolated npm consumer; published pins remain unchanged.
113
+ Use `CI=1`, `umask 022` and the repository-required test policy root. Human minutes,
114
+ real quality, real costs and external-team outcomes remain unmeasured. A real
115
+ 3–5-team pilot and any paid provider campaign need separate authorization; this
116
+ change does not authorize HU74, a release or promotion to latest.