@zhivex-ai/harness 1.4.0-rc.6 → 1.4.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.
Files changed (92) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +124 -71
  3. package/SECURITY.md +1 -1
  4. package/SUPPORT.md +2 -2
  5. package/contracts/engine-api.json +55 -0
  6. package/contracts/stable-api-signatures.json +33 -33
  7. package/dist/acp-cli.js +18 -15
  8. package/dist/cli/arguments.d.ts +3 -0
  9. package/dist/cli/console/console-budget.d.ts +8 -2
  10. package/dist/{cli-s1rs15vv.js → cli-2h37qyvg.js} +34 -15
  11. package/dist/{cli-entry-d5788aay.js → cli-entry-20w6nh0k.js} +359 -21
  12. package/dist/{cli-entry-9c2k0zwz.js → cli-entry-4ngptr62.js} +2902 -1482
  13. package/dist/{cli-entry-4k1cf0m3.js → cli-entry-w0hterjs.js} +8 -5
  14. package/dist/cli.js +2 -2
  15. package/dist/client/json-contracts.d.ts +95 -2
  16. package/dist/client/local-service.d.ts +2 -2
  17. package/dist/client/protocol.d.ts +3 -0
  18. package/dist/client/stream.d.ts +2 -1
  19. package/dist/compat/code-support.d.ts +6 -0
  20. package/dist/compat/code-support.js +29 -6
  21. package/dist/{config-c002f06f.js → config-j9624t6t.js} +1 -1
  22. package/dist/{config-j3jga5wh.js → config-qt69hkqj.js} +4 -2
  23. package/dist/engine/acp.js +14 -12
  24. package/dist/engine/client.js +11 -10
  25. package/dist/engine/desktop-providers-v1.js +2 -1
  26. package/dist/engine/desktop-state-v1.js +9 -9
  27. package/dist/engine/index.js +48 -46
  28. package/dist/engine/mcp-stdio-v1.js +7 -6
  29. package/dist/engine/protocol.js +30 -2
  30. package/dist/engine/service.js +12 -11
  31. package/dist/hostile-repository-demo.js +4773 -3027
  32. package/dist/{index-49ys3s4q.js → index-5jhgatga.js} +35 -16
  33. package/dist/{index-wq2tax80.js → index-61gthdz6.js} +1 -1
  34. package/dist/index-6dft2vev.js +343 -0
  35. package/dist/{index-gq9xagx2.js → index-8zjmnyw5.js} +25 -138
  36. package/dist/index-937cb7y8.js +705 -0
  37. package/dist/index-bpc596v3.js +154 -0
  38. package/dist/index-fm84men1.js +239 -0
  39. package/dist/{index-e6r04a18.js → index-m34q25jj.js} +1127 -170
  40. package/dist/index-m49jx72n.js +220 -0
  41. package/dist/{index-dj5z774k.js → index-m82cfspw.js} +35 -16
  42. package/dist/{index-qfpz5y2v.js → index-nmjdwd4p.js} +8 -2
  43. package/dist/{index-0g939pfs.js → index-pdmevfxv.js} +10 -7
  44. package/dist/{index-4j1h4j8c.js → index-pp474137.js} +1598 -973
  45. package/dist/{index-2tgb2b4e.js → index-rkbf7dqg.js} +3 -5
  46. package/dist/index-s2k2edts.js +3778 -0
  47. package/dist/{index-z6br6qdn.js → index-tfzta544.js} +28 -11
  48. package/dist/index.js +44 -42
  49. package/dist/persistence/operations.d.ts +3 -0
  50. package/dist/providers/vertex-auth.d.ts +5 -1
  51. package/dist/runtime/config.d.ts +8 -0
  52. package/dist/runtime/context-runtime.d.ts +1 -0
  53. package/dist/runtime/error-diagnostics.d.ts +8 -0
  54. package/dist/runtime/errors.d.ts +10 -0
  55. package/dist/runtime/harness.d.ts +9 -0
  56. package/dist/runtime/policy-inspection.d.ts +1 -0
  57. package/dist/runtime/provider-transient.d.ts +33 -0
  58. package/dist/runtime/runtime-diagnostics.d.ts +3 -0
  59. package/dist/runtime/runtime-policy.d.ts +8 -10
  60. package/dist/runtime/task-acceptance-host.d.ts +1 -1
  61. package/dist/runtime/task-budget-host.d.ts +217 -0
  62. package/dist/runtime/task-budget.d.ts +147 -0
  63. package/dist/runtime/task-continuity.d.ts +434 -0
  64. package/dist/runtime/task-telemetry.d.ts +63 -0
  65. package/dist/runtime/task-transport.d.ts +3 -0
  66. package/dist/runtime/task-usage-context.d.ts +13 -0
  67. package/dist/runtime/time-to-safe-fix.d.ts +8 -0
  68. package/dist/runtime/usage-ledger.d.ts +17 -0
  69. package/dist/service-cli.js +12 -11
  70. package/dist/{service-client-cli-b52c67hx.js → service-client-cli-fn54ev6w.js} +18 -7
  71. package/dist/verify-historical-migrations.js +2426 -652
  72. package/dist/zhx.js +2 -2
  73. package/docs/CLI.md +38 -8
  74. package/docs/CLIENT_PROTOCOL.md +9 -1
  75. package/docs/CODE_RELEASE.md +118 -1
  76. package/docs/DURABLE_OPERATIONS.md +1 -1
  77. package/docs/EXTENSIBILITY.md +1 -1
  78. package/docs/FIRST_USE.md +6 -6
  79. package/docs/MINIMUM_OFFLINE_EVALS.md +31 -0
  80. package/docs/MINIMUM_TASK_AUTHORITY.md +395 -0
  81. package/docs/PROJECT_MEMORY.md +1 -1
  82. package/docs/README.md +2 -0
  83. package/docs/STABILITY.md +1 -1
  84. package/docs/WEB_LIMITS.md +117 -0
  85. package/evaluations/representative-assembly-matrix.json +28 -1
  86. package/examples/README.md +5 -5
  87. package/package.json +8 -5
  88. package/dist/index-8705zxpr.js +0 -145
  89. package/dist/index-a1q355va.js +0 -600
  90. package/dist/index-r0tdj04h.js +0 -976
  91. package/dist/index-rd0s3gqj.js +0 -1669
  92. package/dist/index-vtqfjnab.js +0 -1626
@@ -0,0 +1,395 @@
1
+ # Minimum task authority (Experimental, unreleased)
2
+
3
+ The direct Code `/task` flow has one native writer: objective and exact scope,
4
+ bounded execution, interruption/resume, declared checks, fresh local review, and
5
+ an explicit human keep/revise decision. The task identifier owns the frozen token
6
+ and monetary policies across run identifiers, new turns, revise and restarts.
7
+ Ordinary runs keep their existing per-run policy and retry behavior. Web task
8
+ flows, review groups, parallel writers and new provider support are outside this
9
+ change.
10
+
11
+ ## Durable admission and recovery
12
+
13
+ The SDK token coordinator is the sole token allocation authority. Primary,
14
+ tool-result continuation and semantic compaction requests reserve from that
15
+ owner before dispatch. Task middleware disables SDK retries and admits one
16
+ provider request per reservation. Full remaining input/total ceilings are held
17
+ because a local context estimate is not a billing bound. Confirmed usage settles
18
+ the reservation; incomplete outcomes retain it and close admission. A complete
19
+ late receipt still charges the owner. Thirty percent of the ceiling is reserved
20
+ for tool-free closure; verified repair also uses the frozen task ceiling and
21
+ confirmed consumption from earlier runs.
22
+
23
+ The task control record freezes limits and price policy, records run membership,
24
+ and holds an invocation marker until every admitted tool effect finishes. A
25
+ lease fences new requests, tools and checkpoints. SQLite triggers atomically
26
+ protect marker transitions and retention because the pinned SDK's save path
27
+ does not enforce `leaseOwnerId`. If a process crashes or its lease expires while
28
+ an invocation is pending, another process cannot take over, reset credit, or
29
+ silently clear that marker. This version has no automatic uncertain-outcome
30
+ reconciliation. A local abort requests cooperative stopping; it cannot prove
31
+ external cancellation or exactly-once execution of an arbitrary API.
32
+
33
+ Only the native SQLite host is supported. File/custom stores and non-native
34
+ execution backends cannot establish this authority. Legacy tasks without a
35
+ budget remain inspectable but cannot dispatch another model call. Task control
36
+ records and linked token ledgers resist ordinary cleanup, including direct SDK
37
+ SQLite deletion. Ordinary unrelated runs can still be pruned.
38
+
39
+ Logical JSON state backup validates task links but deliberately omits transport
40
+ monetary tables. Importing it into an empty host cannot resume a task and fails
41
+ closed with `USAGE_LEDGER_MISSING`. Preserve a consistent complete operations
42
+ database, including required SQLite journal state. Uncertain token usage or a
43
+ pending invocation also blocks logical backup. A token snapshot cannot replace
44
+ the monetary authority or prove that an external effect finished.
45
+
46
+ ## Transport capability matrix
47
+
48
+ These contracts are verified against the installed pinned adapters using
49
+ synthetic HTTP and credentials in [transport tests](https://github.com/Zhivex/zhivex-harness/blob/11f4a038ca4f6d1d04985af135f792f712163930/tests/task-transport.test.ts)
50
+ and host admission tests, without live provider calls. They establish local
51
+ dispatch/cap behavior, not provider billing guarantees or model quality.
52
+
53
+ | Route | Direct guided task | Verified wire cap and dispatch boundary |
54
+ | --- | --- | --- |
55
+ | Built-in OpenAI (`@zhivex-ai/openai` 0.14.1) | Supported | Responses `max_output_tokens`; Chat `max_tokens` without reasoning or `max_completion_tokens` with reasoning; `maxRetries=0`, `maxProviderRequests=1` |
56
+ | Built-in Anthropic API key (`@zhivex-ai/anthropic` 0.13.2) | Supported | Messages `max_tokens`; non-refreshable built-in credentials; `maxRetries=0` |
57
+ | Built-in Gemini (`@zhivex-ai/gemini` 0.13.0) | Supported | `generationConfig.maxOutputTokens`; `maxRetries=0` |
58
+ | Built-in Vertex (`@zhivex-ai/vertex` 1.2.4) | Supported | `generationConfig.maxOutputTokens`; real ADC callback, synthetic credential source in tests; `maxRetries=0` |
59
+ | Qwen (`@zhivex-ai/qwen` 0.16.4) | Blocked as Code primary | Explicit Chat-mode middleware tested with capped `max_tokens`; Code has no explicit mode selector and Responses rejects `maxTokens` |
60
+ | Meta | Blocked | Harness continuation fetch can replay a 400 response outside SDK retry admission |
61
+ | Injected/custom adapters, refreshable Anthropic OAuth | Blocked | No vetted transport provenance; OAuth transport can replay a 401 after refresh outside ordinary retry admission |
62
+ | Mock | Offline tests only | Synthetic usage is never billing evidence |
63
+
64
+ The built-in factory marks vetted adapters with a private runtime symbol;
65
+ serialized model metadata cannot establish provenance. Task middleware checks
66
+ explicit Qwen Chat mode before downstream provider policy mutation. Both
67
+ generate and streaming requests, primary and compaction lanes, verify a single
68
+ 503 dispatch and held unknown consumption. Separate tests verify ordinary
69
+ configured retries still dispatch twice.
70
+
71
+ Source boundaries: `src/runtime/config.ts` factory provenance,
72
+ `src/runtime/task-budget-host.ts` admission,
73
+ `src/runtime/task-budget.ts` request reservation,
74
+ `src/providers/providers.ts` API-key construction,
75
+ `src/providers/meta-continuation.ts` receipt replay, and pinned adapter files
76
+ `node_modules/@zhivex-ai/{openai,anthropic,gemini,vertex,qwen}/dist/index.js`.
77
+ Anthropic's `DirectAnthropicMessagesTransport` 401-refresh branch and Qwen's Responses
78
+ validation explain their unsupported cases. No SDK source or dependency version
79
+ is changed here.
80
+
81
+ To extend parity, a separately reviewed SDK contract must expose a durable
82
+ before-dispatch reservation/after-dispatch receipt hook for **every** internal
83
+ retry, OAuth refresh replay and continuation fallback, including aborted and
84
+ partial receipts; each hook must carry stable attempt identity and fenced
85
+ cancellation admission. Meta's harness wrapper must use that same hook. Qwen
86
+ also needs explicit mode/output-cap capability admission on the Code host.
87
+ SQLite SDK save should atomically enforce lease ownership. These are proposals,
88
+ not guarantees implemented by this PR.
89
+
90
+ The original PR187 assessment used Core 1.30.1/Agents 1.10.3. The HU70 integration uses main pins Core 1.31.0/Agents 1.11.0; the same store-boundary limitation remains. Cross-host takeover is outside the ratified topology; concurrent admissions within one writer host still require atomic reservations.
91
+ In `node_modules/@zhivex-ai/core/dist/agent-store/sqlite.js`, the `save(state,
92
+ saveOptions)` branch checks `expectedRevision` and calls `saveStatement.run`
93
+ inside `BEGIN IMMEDIATE`, but never reads `saveOptions.leaseOwnerId`. Revision
94
+ checks therefore accept a delayed save after lease takeover when the new owner
95
+ has not yet written a revision. This is an SDK contract gap, not generic lease
96
+ fencing supplied by Harness. The local triggers apply only to application task
97
+ invocation transitions and task draft INSERT/UPDATE records; unrelated SDK
98
+ checkpoints retain their published behavior.
99
+
100
+ [Task authority regressions](https://github.com/Zhivex/zhivex-harness/blob/11f4a038ca4f6d1d04985af135f792f712163930/tests/task-budget.test.ts) pause a task-root
101
+ clear save, transfer the lease without a revision write, and verify atomic
102
+ rejection. [Draft host regressions](https://github.com/Zhivex/zhivex-harness/blob/11f4a038ca4f6d1d04985af135f792f712163930/tests/task-budget-host.test.ts) cover both
103
+ first INSERT and existing UPDATE after expiry or takeover, while an ordinary
104
+ checkpoint with an unowned `leaseOwnerId` still writes. Draft logical import
105
+ uses only a transient lease within its exclusive import transaction, retains
106
+ active-destination-lease refusal, and leaves no lease after commit or rollback.
107
+ It does not restore the omitted monetary tables or grant task execution credit.
108
+
109
+ ## Telemetry and local measurements
110
+
111
+ Bounded numeric telemetry records preparation milestones, context initialization,
112
+ primary model transports, separate semantic compaction transports, persistence,
113
+ tools, render observations and total wall time. `prepare-start` to `prepare-end`
114
+ covers task acceptance setup and budget-owner lookup/resume validation; invocation
115
+ lease admission and runtime context initialization follow that milestone.
116
+ The `context` spans measure scoped-context runtime initialization and, separately,
117
+ each request's pending discovery wait, scoped-file refresh, progress check and
118
+ instruction injection. They end before the model transport starts. They do not
119
+ cover full prompt tokenization or scoped discovery inside tool execution.
120
+ The `compaction` lane measures auxiliary model transport and consumption,
121
+ not deterministic summary assembly. The terminal renderer marks first visible text when
122
+ it actually writes; a host text event is a different timestamp. Overlapping
123
+ spans are not summed into total latency. Observer failures cannot suppress
124
+ mandatory audit/persistence failures. Payloads omit prompts, arguments, paths
125
+ and free-form errors.
126
+
127
+ On one M4/16 GiB machine, Bun 1.4.0, three alternating RC6/candidate trials with
128
+ the same 100,000-row foreign-scope fixture reduced median ledger summary time
129
+ from 4.4577 ms to 0.06429 ms. Empty-history median was 0.15417 ms versus
130
+ 0.06558 ms. The compound index costs 55.47–56.56 ms to create and **9,048,064
131
+ additional SQLite allocated bytes** for the long-key fixture; reopening took
132
+ 2.07–2.63 ms versus 0.99–1.51 ms on RC6. These local numbers do not establish
133
+ general workload speedups. Reproduce with
134
+ `bun scripts/benchmark-usage-ledger.ts --baseline-root /path/to/clean-rc6`.
135
+
136
+ Prepared activity statement reuse reduced the local 1.5 MiB retention median
137
+ from 0.89075 ms to 0.78838 ms; that roughly 11.5% observation does not satisfy a
138
+ 30% critical-path improvement target. SQL predicates, transactions, retention
139
+ and mandatory errors are unchanged. No context pruning, batching or parallel
140
+ writers are introduced.
141
+
142
+ [Offline evaluation preparation](MINIMUM_OFFLINE_EVALS.md) freezes twelve
143
+ synthetic JS/TS tasks and a separate development split. Identical scripted RC6
144
+ and candidate runs pass the twelve oracle checks; empty patches pass none.
145
+ This validates fixture/runtime behavior only. Real private task selection,
146
+ independent human acceptance and an approved paid campaign remain necessary
147
+ before any model-quality, cost-per-accepted-result or benchmark claim.
148
+
149
+ ## HAR-HU-70 integration delta
150
+
151
+ One task owns one frozen token coordinator and one transport monetary owner. Task revisions, new runs, explicit retries and restarts retain both identities and original policies. This experimental cut supports one native SQLite writer host; children are refused before dispatch rather than charged to independent pools. Review-group helpers are not evidence of a budgeted parent. Existing unsupported provider routes remain unsupported.
152
+
153
+ The task admission context reserves conservative input exposure, the output cap and the existing closure fraction before transport. The same frozen fraction protects the monetary work allowance when an explicit USD limit is configured. Closure can use the retained remainder; this is not a guarantee that any particular final answer fits it. A monetary refusal before dispatch settles only that proven undispatched token reservation to zero. Exceptions after dispatch retain unknown exposure. All requests, including auxiliary compaction, are classified in the same transport ledger; independent runs and cumulative SDK usage are never added again.
154
+
155
+ Inspection separates confirmed-call estimated USD, pending reservations, retained unknown exposure and late receipt counts. A complete late receipt is counted once and cannot reopen task admission. Partial or absent usage stays unknown; unknown estimates do not become zero. A missing/stale rate refuses monetary-limited dispatch; an unpriced non-monetary task reports unknown cost. Rates remain operator estimates, not invoices; cached/reasoning-rate specialization and the inherited explicit-cap correction are not new claims of this increment. External tool/service fees are not covered by this model-transport ledger.
156
+
157
+ The transport table gains additive category and late-receipt columns; existing rows read as legacy. Stable run statuses, signatures and the existing usage-summary JSON remain unchanged. The extended task inspection is Experimental and host-only; public web projection belongs to HAR73. No generic reconciliation UI is introduced: an unknown result remains held until an authoritative complete receipt is available, and a crashed invocation with unresolved effects remains blocked. A later authorized recovery design must not silently clear it.
158
+
159
+ Interactive chat retains no accumulated cap by default. To opt into a TASK budget while chat remains unlimited, include exact limits in the task brief:
160
+
161
+ ```text
162
+ /task start {"goal":"Fix greeting punctuation","paths":["greeting.mjs"],"checks":["test"],"budget":{"inputTokens":60000,"outputTokens":8192,"totalTokens":68192}}
163
+ ```
164
+
165
+ Without this explicit object on an unlimited host, creation fails with `TASK_BUDGET_FINITE_LIMITS_REQUIRED` before model dispatch. Existing explicitly bounded host configuration remains usable. Inspection/reopening reads the original task policy; changing host defaults does not mint credit. Monetary `/budget` configuration for future tasks remains separate. Ordinary chat, after leaving the task, does not inherit a hidden finite token override.
166
+
167
+ Offline regressions in `tests/task-budget-accounting.test.ts` exercise three overlapping primary/compaction admissions against real SQLite, monetary closure exhaustion, pre-dispatch refusal, late abort receipts, partial usage and retained policy across reopen. Existing task host/crash/backup tests remain applicable. No paid calls, external pilot, cross-host takeover, SDK patch, merge or publication is authorized by these tests.
168
+
169
+ Continuation also verifies the correspondence between task operation IDs in the
170
+ SDK token allocations and transport receipts, in both directions. An existing
171
+ initializer cannot recreate a missing monetary policy; retaining only the policy
172
+ cannot hide deleted receipts, and retaining receipts cannot hide deleted token
173
+ allocations. This detects missing records, not arbitrary tampering with matching
174
+ records. An inspection during the token-reserve/transport-insert transition can
175
+ report a transient missing receipt; retry after the invocation settles before
176
+ diagnosing permanent loss. It never grants new credit.
177
+
178
+ Consumed experimental PR187 accounts created before operation binding use random
179
+ transport IDs and cannot be continued or inspected through the combined task API.
180
+ Preserve their original database and inspect the separate historical ledgers;
181
+ there is no automatic migration based on row order or approximate totals. Ordinary
182
+ published run accounting and its legacy receipt rows retain their existing API.
183
+ After a process crash, transport rows may remain `pending` while the task is
184
+ blocked with uncertain effects. Their full exposure remains held; this increment
185
+ does not claim automatic conversion of every crashed row to `unknown`.
186
+
187
+ ## HAR-HU-71 cancellation contract
188
+
189
+ Cancellation has three independent outcomes: a durable request closes task
190
+ admission; native tool callbacks may subsequently drain; provider termination
191
+ remains unconfirmed. Neither a local abort nor a timeout establishes remote
192
+ termination. Completed work, terminal run states, tool effects and accounting
193
+ receipts are retained. Cancellation never grants human acceptance or rolls back
194
+ an already written file. Code's task recap displays the latest cancellation next
195
+ to confirmed, reserved and unknown consumption; its Ctrl-C message describes a
196
+ local request rather than a confirmed provider stop. Web task projection remains
197
+ a separate increment.
198
+
199
+ The Experimental `@zhivex-ai/harness/code-support` entrypoint exposes:
200
+
201
+ ```ts
202
+ import {
203
+ requestHarnessTaskCancellation,
204
+ inspectHarnessTaskBudget
205
+ } from '@zhivex-ai/harness/code-support';
206
+
207
+ // Use the original SQLite writer host, task identity and run identity.
208
+ const requested = await requestHarnessTaskCancellation(host, taskId, runId);
209
+ // requestOutcome is requested (durable closure) or already_terminal (no-op).
210
+ // Neither outcome confirms that a provider stopped.
211
+ const evidence = await inspectHarnessTaskBudget(host, taskId);
212
+ // evidence.cancellations: runId, origin, requestedAt,
213
+ // optional localToolsDrainedAt, localExecution, remoteExecution.
214
+ ```
215
+
216
+ The host control installs a synchronous local admission barrier, serializes the
217
+ closure with the invocation claim/cleanup, persists it under the task lease and
218
+ only then sends its cooperative abort and acknowledges the request. A final
219
+ synchronous check at monetary admission repeats the local barrier after any
220
+ await inside checkpoint-token middleware, before reserving money or handing
221
+ off to the provider. A refusal there releases only proven undispatched tokens. An external
222
+ AbortSignal cannot delay its own delivery: its listener queues durable closure
223
+ and invocation cleanup waits for that write. A crash before the closure commits
224
+ can therefore leave the already durable invocation marker without a cancellation
225
+ record; it still blocks a new invocation. A failed write is not a successful
226
+ durable acknowledgement. Concurrent closure/cleanup shares one promise. An old
227
+ run's request cannot cancel a newer invocation of the same task.
228
+
229
+ | Route | Demonstrated guarantee | Remaining limit |
230
+ | --- | --- | --- |
231
+ | Same-host TASK request | Durable closure before acknowledgement/abort; no further guarded model/tool admissions | An already admitted request or tool may still finish |
232
+ | Ctrl-C / external abort / timeout | Closure after the queued invocation claim; cleanup awaits persistence | Local signal delivery is not a remote cancellation receipt |
233
+ | Waiting approval | Task closes before run cancellation; stale and reloaded approvals cannot execute | Effects that occurred before the request remain |
234
+ | Native tool/process | Invocation retained until tracked callbacks settle; `native_tools_drained` after that point | Detached descendants or remote effects are not proven stopped; an uncooperative callback can remain pending without a five-second promise |
235
+ | Stream / semantic compaction | Late complete usage remains charged once; missing usage retains exposure | Provider completion and latency are unmeasured; `remoteExecution` stays `unconfirmed` |
236
+ | Restart / SIGKILL | Durable intent, invocation and reserved exposure survive | No cross-host takeover or automatic reconciliation of unknown effects |
237
+ | Run cancellation / cascade | Terminal states and receipts survive each CAS retry; returned summary reloads durable state | No atomic cross-run cancellation, spawn barrier or exactly-once claim |
238
+ | Adapter preparation | If no run exists yet, wait for preparation outcome persistence before acknowledging | A preparation hook that ignores abort may keep the request pending |
239
+
240
+ `localToolsDrainedAt` proves only that this invocation's tracked native tool
241
+ callbacks drained. It does not assert that all provider callbacks or remote work
242
+ stopped. A retained invocation produces `TASK_BUDGET_INVOCATION_UNCERTAIN`;
243
+ a different active writer produces `TASK_BUDGET_ACTIVE`. Missing binding produces
244
+ `TASK_BUDGET_RUN_BINDING_MISSING`; a request for an older inactive run produces
245
+ `TASK_BUDGET_STALE_RUN`. Closed admission produces `TASK_BUDGET_CANCELLED`.
246
+ Persistence failure during adapter preparation produces
247
+ `CLIENT_CANCELLATION_NOT_PERSISTED`. None of these errors mints new credit.
248
+
249
+ For unresolved work, preserve the database and inspect the prior run, native
250
+ process/effect evidence and transport receipts. Complete authoritative receipts
251
+ can settle consumption through the existing ledger path. Explicit continuation
252
+ requires no pending invocation and complete consumption; it uses a new run ID
253
+ and retains cancellation history. There is no operator API in this increment to
254
+ clear an orphan invocation or guess missing usage. Stop and review unresolved
255
+ effects; do not delete control fields, refund reservations or replay effects to
256
+ get past a refusal. A full logical backup refuses pending invocations; preserve
257
+ the stopped host's complete database when that gate applies.
258
+
259
+ The new reader accepts existing HU70 account payload version 1 without rewriting
260
+ it. An uncancelled account remains version 1 and remains readable by HU70. The
261
+ first cancellation write explicitly upgrades only the Experimental account
262
+ payload to `schemaVersion: 2`; run state and token-summary versions stay at 1.
263
+ The discovery key `zhivexTaskBudgetAccountV1` stays fixed. Complete logical
264
+ backups preserve the payload version and cancellation history.
265
+
266
+ HU70's frozen strict decoder rejects version 2 with a schema-version diagnostic
267
+ (`expected 1`) before it can run or rewrite the account. It also reports the
268
+ unknown cancellation field; this is a safe low-level validation error, not a
269
+ new friendly diagnostic retrofitted into the old binary. No task content is
270
+ included in that error. HU71 rejects unsupported future versions with the static
271
+ `TASK_BUDGET_ACCOUNT_VERSION_UNSUPPORTED` diagnostic; malformed known payloads
272
+ use `TASK_BUDGET_ACCOUNT_INVALID`. Both refuse without writing control state.
273
+
274
+ Downgrade after a cancellation is unsupported. Preserve the complete database
275
+ and use the HU71 reader to inspect it. Restoring a pre-cancellation backup would
276
+ also discard newer effects and consumption, so it is not a safe automatic
277
+ rollback. Do not strip fields, relabel version 2 as 1, clear invocation, or refund
278
+ credit to force opening. The unpublished HU71 Library-v0 candidate wrote history
279
+ under version 1; the new reader accepts it read-only and upgrades it to version 2
280
+ on the next owned write, retaining all history. HU70 already rejects that v0
281
+ history field. Ordinary run status and token-summary shapes remain unchanged.
282
+ Child TASK execution remains refused by the existing
283
+ single-native-writer gate, so optional child creation is outside this cut.
284
+
285
+ `tests/task-cancellation.test.ts`, `tests/task-cancellation-host.test.ts`,
286
+ `tests/task-cancellation-transport.test.ts` and
287
+ `tests/client-run-runtime.test.ts` cover deterministic save barriers, independent
288
+ SQLite workers, SIGKILL, a real native process, approval, stream, compaction,
289
+ restart and import. `scripts/har-hu-71-installed-consumer.mjs` exercises the
290
+ installed Experimental export on an exact candidate tarball. These are offline
291
+ fixtures; there is no measured provider-stop SLA, paid campaign, external pilot,
292
+ SDK fix, publication or release claim.
293
+
294
+ ## HAR-HU-72 continuity (Experimental, unreleased)
295
+
296
+ `inspectHarnessTaskContinuity(host, taskId)` from `code-support` reads existing
297
+ task membership, acceptance revision chains, operator-source digests, approval
298
+ history, tool journals, native snapshots and the original token/monetary owner.
299
+ It creates no second task record, ledger or store. Each run has its durable ID
300
+ and revision; each journal effect has its journal ID/revision. The report retains
301
+ the exact current contract, objective/constraints, artifact/check bindings,
302
+ recorded decisions, missing evidence and unknown effects. Approval history may
303
+ be unavailable: a recorded result does not fabricate approval provenance.
304
+ Recovered assistant prose remains explicitly untrusted and unverified. This is
305
+ an application-host API, not a public web protocol or the complete UI planned for
306
+ HAR73/CODE-05. Do not expose its local task content to an unrelated client.
307
+
308
+ ```ts
309
+ import { inspectHarnessTaskContinuity } from '@zhivex-ai/harness/code-support';
310
+
311
+ const recovery = await inspectHarnessTaskContinuity(host, taskId);
312
+ // Inspect recovery.currentContract, recovery.runs, recovery.budget and reasons.
313
+ // nextAction is a diagnostic, not execution or approval authority.
314
+ // automaticEffectReplay is always false; authorization is always 'none'.
315
+ ```
316
+
317
+ Only the existing single native SQLite writer is supported. For sequential
318
+ handoff, first prove termination of the previous host/process, preserve its
319
+ complete database and then open the new host. A pending invocation remains
320
+ blocked even when a lease has expired; this increment provides no takeover,
321
+ orphan-marker clearing, provider-stop proof or uncertain-effect reconciliation
322
+ API. Inspect external/native effects independently before deciding what work is
323
+ safe; a diagnostic never establishes that such reconciliation occurred.
324
+
325
+ New task turns retain the latest durable acceptance ledger and operator sources.
326
+ A stale Code brief cannot replace an authorized contract revision. Resume must
327
+ address the latest run and matching durable budget binding; old approval state
328
+ cannot restore prior restrictions. The task account revision is checked under
329
+ its invocation lease before claim. Immediately before execution, the observed
330
+ run/journal read set and native snapshot digests are checked again. Operator
331
+ revisions of a budgeted task acquire its existing account lease and cannot
332
+ revise an older run. These are local admission checks, not cross-host fencing
333
+ or a lock against subsequent filesystem edits; executable tools retain their
334
+ existing digest, scope, approval and budget checks.
335
+
336
+ Code `/task revise` persists the authorized contract revision before using its
337
+ new brief. If the process stops before the draft is saved, restart reconstructs
338
+ only an append-only Code human correction from that revision history; any
339
+ scope/check change or incompatible brief still refuses. Baseline, budget owner
340
+ and remaining credit are preserved; recovered keep decisions are cleared.
341
+ Inherited transcript calls retain their original run's journal provenance. A
342
+ call generated again in the current run still requires its own current receipt.
343
+
344
+ | Evidence/state | Recovery interpretation | Next action |
345
+ | --- | --- | --- |
346
+ | Completed journal effect | Recorded outcome; never automatically replayed | Inspect current artifacts and independent obligations |
347
+ | Interrupted idempotent read | No effect claim | An explicit fresh read within the same remaining budget |
348
+ | Missing journal, unfinished/failed effect, or missing finalization | Missing or unknown, not zero/success | Block continuation and reconcile externally |
349
+ | Matching check receipt, current snapshot and journal | Confirmed check at the inspected snapshot | Human review only after run completion |
350
+ | Changed native snapshot | Earlier check is stale | Explicit scoped continuation; revalidate affected checks |
351
+ | Cancelled or uncertain spending/invocation | Original HU70/71 closure and retained exposure | Inspect; no automatic reopening or refund |
352
+ | Missing account, monetary authority, malformed version/digest/scope | Incomplete/unreadable authority | Restore valid complete evidence; never initialize replacement credit |
353
+
354
+ Known-outcome cancellation still supports HU71's separate explicit continuation
355
+ on a new run ID (`taskBudgetContinue`); mere inspection/reconnect/resume never
356
+ reopens it. New-run continuation does not claim to reuse old check execution as
357
+ new-run delivery evidence. It does not automatically run a check, edit or model.
358
+ Repository checks can have effects and are never classified as idempotent reads.
359
+
360
+ An authorized human-requirement change preserves independent check receipts.
361
+ Changing a check invalidates that check. Changing the exact write/protected file
362
+ set invalidates all checks that depended on its aggregate snapshot. Every reuse
363
+ still verifies the original journal, exact argv, current contract binding and
364
+ current native snapshot. New policy/host authority is evaluated through existing
365
+ runtime fingerprint, approval and dispatch checks; recovered decisions grant no
366
+ permissions. Code keep now revalidates current journal-backed evidence before
367
+ and after human confirmation, in addition to its existing Git/snapshot checks.
368
+
369
+ Static diagnostics include `TASK_CONTINUITY_CONTRACT_CONFLICT`,
370
+ `TASK_CONTINUITY_STALE_RUN`, `TASK_CONTINUITY_BINDING_CONFLICT`,
371
+ `TASK_CONTINUITY_CHANGED`, `TASK_CONTINUITY_SOURCE_INVALID`,
372
+ `TASK_CONTINUITY_SOURCE_MISSING`, `TASK_CONTINUITY_RUN_MISSING`,
373
+ `TASK_CONTINUITY_EFFECT_UNCERTAIN`, `TASK_CONTINUITY_EFFECT_EVIDENCE_MISSING`,
374
+ `TASK_CONTINUITY_CHECK_EVIDENCE_MISSING`, `TASK_CONTINUITY_ARTIFACT_UNAVAILABLE`,
375
+ `TASK_CONTINUITY_FINALIZATION_UNCONFIRMED` and `TASK_CONTINUITY_CAPACITY`.
376
+ The read projection is bounded to 256 runs, 2048 journal rows per run and 2 MiB;
377
+ exceeding a bound refuses rather than presenting a complete-looking partial view.
378
+ Missing required evidence blocks with its reason; no result is invented.
379
+
380
+ No persisted format or Stable API changes. HU70 v1 and HU71 v1/v2 account rules,
381
+ including explicit cancellation-version downgrade refusal, remain intact. Old
382
+ readers can read unchanged continuity source formats but do not gain these new
383
+ admission checks. Preserve a compatible host for continuation. Logical JSON
384
+ backup still omits monetary tables and cannot establish resume authority. A
385
+ complete database copy after host shutdown is tested; an arbitrary partial copy
386
+ is not a complete backup. Existing linked-record retention protection is reused,
387
+ not an eternal retention guarantee. Matching malicious deletion of every source
388
+ is not detectable merely from hashes; this is local durable evidence, not signed
389
+ external attestation or exactly-once execution.
390
+
391
+ Offline continuity tests cover stale briefs/approvals, real compaction, restart,
392
+ journal loss, before/after effect receipts, an injected `ENOSPC` at final save,
393
+ full stopped-host copy and partial logical restore. Human handoff minutes and
394
+ repeat-work measurements remain HAR74 work; no external pilot or paid campaign
395
+ is implied.
@@ -7,7 +7,7 @@ generated automatically; hosts may submit a suggestion for operator review.
7
7
 
8
8
  ## CLI
9
9
 
10
- Use `zhx` or `zhivex-code` with Harness 1.4.0-rc.6 (Code 0.3.0-rc.6), pending publication. Commands
10
+ Use `zhx` or `zhivex-code` with Harness 1.4.0 (Code 0.3.0), pending publication. Commands
11
11
  print bounded JSON, including the selected workspace/scope hashes. Quote content
12
12
  as one argument. Memory commands do not start a model or read credentials.
13
13
 
package/docs/README.md CHANGED
@@ -42,3 +42,5 @@ and are excluded from the npm package. Published validation applies to the exact
42
42
  release artifact, not automatically to later source changes.
43
43
 
44
44
  - [Project memory](PROJECT_MEMORY.md): experimental explicit notes, review, retrieval budgets and deletion semantics.
45
+
46
+ - [Optional Web limits and interactive defaults](WEB_LIMITS.md)
package/docs/STABILITY.md CHANGED
@@ -12,7 +12,7 @@ for the published 1.3.0 release and were available in the published RC7; they ar
12
12
 
13
13
  Stable means removal, incompatible signature/type change, semantic change, or stricter accepted input requires the next major release, except for a documented urgent security correction. Additive observational JSON fields are compatible. Digest-bound and signed-style documents use strict parsers: adding a field requires a new schema because unknown bytes change canonical identity.
14
14
 
15
- The schema-1 observational parsers preserve unknown additive fields and distinguish rich `run-result` JSON from compact `run-stream-result` JSONL. Stable error documents intentionally exclude messages and causes; only `code`, `category`, and `retryable` are contractual. State-backup bundles are strict, checksummed, and workspace/scope-bound rather than observational.
15
+ The schema-1 observational parsers preserve unknown additive fields and distinguish rich `run-result` JSON from compact `run-stream-result` JSONL. Stable error documents intentionally exclude messages and causes. `code`, `category`, and `retryable` are contractual; optional `providerDiagnostic` preserves the closed Qwen stream contract (`provider`, `transport`, `diagnosticCode`, `reason`, `retryable`) without provider payloads. State-backup bundles are strict, checksummed, and workspace/scope-bound rather than observational.
16
16
 
17
17
  Beta APIs may change in a minor with changelog and migration guidance. Experimental APIs may change without a deprecation window and must not be the sole supported route for a stable operation. Human-readable terminal text and error messages are not contracts; command identity, exit codes, structured document schemas, and `HarnessError.code/category/retryable` are.
18
18
 
@@ -0,0 +1,117 @@
1
+ # Optional Web limits
2
+
3
+ New interactive Web/terminal tasks have no accumulated spend, token, step,
4
+ tool-call or duration cap unless configured. This change uses the published SDK contract from
5
+ Zhivex/zhivex-ai-sdk PR 142 (Core/SDK 1.31.0, Agents 1.11.0). Direct Harness, Code
6
+ and Web Core/Agents pins and the root Core override use those verified releases.
7
+ Provider package pins, headless policies and release gates remain unchanged.
8
+
9
+ The Web header opens the approved gradual configuration modal. Next task settings
10
+ override project settings once, including an empty override. Project settings
11
+ persist for future tasks in that workspace and tenant/user/namespace scope.
12
+ Settings are snapshotted on admission; changing them never rewrites an active run,
13
+ its recorded consumption, its approvals or its engine budget. A failed/rejected
14
+ submission is never automatically retried.
15
+
16
+ Tokens use reported SDK usage; steps count completed model iterations; tools count
17
+ unique tool-result receipts. Active duration excludes time parked for approval.
18
+ Unknown usage/pricing is shown as unavailable. Cost uses advisory model catalog
19
+ rates or explicit host rates; cached-input differences are conservatively estimated.
20
+ Unsupported pricing tiers and unaccounted auxiliary usage make the estimate
21
+ unavailable. The price source is visible on the run. No money is reserved and this
22
+ is not a guaranteed financial cap.
23
+
24
+ **Avisar** records a notice and lets the run continue. **Detener** requests the
25
+ existing active-run cancellation once, after observing the threshold. An in-flight
26
+ operation or final response can exceed it; completed work is not rolled back.
27
+ Consumption and durable effects remain recorded. Cancellation produces a cancelled
28
+ run, not a resumable pause; a subsequent user-submitted task carries the normal
29
+ bounded conversation context. There is no automatic replay. Observation/storage
30
+ failures remain visible; a known active stop policy requests cancellation, while
31
+ notification-only failures do not replace engine results with observer errors.
32
+
33
+ Thresholds are finite positive numbers; token/step/tool counts are integers.
34
+ Empty fields mean no user threshold. Cost/duration accept decimal comma or dot.
35
+ Steps and tools are separate controls. Exact revisions protect concurrent writes;
36
+ an uncertain save requires closing and reopening to inspect persisted settings.
37
+ The modal supports native dialog semantics, Escape, keyboard focus containment,
38
+ focus restoration, invalid-input messages and a scrollable mobile layout.
39
+
40
+ Preferences and per-run snapshots live in a private `web-limits` child directory
41
+ of the existing state directory, separate from SDK run JSON files. Files are
42
+ owner-private and regular with no symlink/hardlink traversal. Browser actions use
43
+ the same pairing, CSRF, Origin, loopback and workspace/session admission controls.
44
+ Admission commits the initial run snapshot and one-shot consumption with one
45
+ atomic preference-file rename. The private document reads legacy v1 and writes v2;
46
+ the browser preference contract remains v1. That initial snapshot survives restart
47
+ before the first event, and a later admission preserves the previous run record.
48
+ Elapsed time is persisted on events/checkpoints; a periodic timer runs only for an
49
+ enabled duration threshold. Snapshot read failures surface through the normal
50
+ poll error path; a successful legacy `null` snapshot remains a healthy read.
51
+ Permission policy, sandbox, state-size/model/context limits, operation timeouts,
52
+ tool-error/anti-loop controls and release gates remain independent.
53
+ Web retains its existing four-tool-error guard; terminal retains its existing
54
+ 20-error policy. Explicit host/profile/environment settings remain authoritative.
55
+
56
+ ## Host flags and legacy restart
57
+
58
+ `unlimitedTokens`, `unlimitedSteps`, `unlimitedToolCalls` and `unlimitedDuration`
59
+ are explicit opt-in engine flags. Numeric values remain stored and are inactive
60
+ only when their corresponding flag is true. Explicit numbers/environment values
61
+ prevent interactive default activation; explicit programmatic flags take precedence.
62
+ `unlimitedDuration` omits both the SDK policy timeout and the default invocation
63
+ deadline. An explicit per-invocation `timeoutMs` and caller cancellation remain
64
+ authoritative, alongside the existing per-operation timeouts.
65
+ SDK/headless/certification defaults remain bounded. Child step/tool/deadline policy
66
+ is unchanged. `/limits <steps>` explicitly enables the requested finite console ceiling.
67
+
68
+ The SDK receives `Agent.maxSteps = "unlimited"`, omits step/tool budget fields and
69
+ gets a new policy without the accumulated `timeoutMs`. Finite model-request and
70
+ tool-execution timeouts still apply. JSON state/stream documents preserve the
71
+ literal `"unlimited"`; null, Infinity and large numeric sentinels are not used.
72
+ Flags survive runtime manifests and CLI resume metadata. Saved metadata without
73
+ flags restores bounded execution.
74
+
75
+ On Web startup, the original host acquires exclusive ownership before the complete
76
+ scoped run store is inspected through paged reads (the browser session list is
77
+ truncated and cannot prove completeness). Pending legacy, mixed, unknown, malformed
78
+ or mismatched policies keep the original host. Finish/cancel explicitly, then
79
+ restart Web to adopt new defaults. There is no automatic transition mid-session.
80
+ Pending tasks from this version may reopen only when their complete canonical
81
+ configuration matches the known candidate: CLI resume metadata or a session-bound
82
+ Web snapshot stores that recognition digest. No runtime is reconstructed from it;
83
+ SDK fingerprint, identity and admission checks remain authoritative and unchanged.
84
+
85
+ ## Validation fixture
86
+
87
+ The versioned SDK bundle has Library ID
88
+ `libfile_bf9693683d9881918b80acaab54ba766`, source
89
+ `dfa34a68a13e3a3442f904b01f9e98925489b223`, SHA256
90
+ `30ca7ee2a8c7702b691162f8f93f169c187649b77978625708df7795262d85e5`.
91
+ The final SDK head `7c89f382bd88b47a7c5462797f74ad04f1f12e3f` artifact
92
+ 11450387906 from CI 37545700729 has ZIP SHA256
93
+ `db641b05c83d4765eed1215fc6983ed4ff2e4fcfac37f8ec3d0911be933c6b3b`.
94
+ Its Core/Agents/SDK `dist` files were compared byte for byte against that bundle.
95
+ Installed consumer scripts accept `ZHIVEX_SDK_FIXTURE` only for explicit local
96
+ fixtures, verify package SHA256/SHA512 and record provenance without changing
97
+ repository pins or installing scripts. No provider requests are authorized by it.
98
+
99
+ ## Published dependency verification
100
+
101
+ The actual npm Core 1.31.0, Agents 1.11.0 and SDK 1.31.0 tarballs were verified
102
+ against registry SHA512 integrity and SHA1 shasums. Their attestation subjects
103
+ match those bytes; all provenance points to release commit
104
+ `a7905584074340a905e40b93ad79c19873cdeb27`, workflow 37547891151.
105
+ Core/Agents/SDK dist trees (620/24/108 files) are byte-identical to the initial
106
+ versioned fixture. SDK PR 143 (stream diagnostics) remains outside this release.
107
+ SDK is not a direct Harness dependency, so no unnecessary SDK pin was added.
108
+
109
+ Tarball SHA256: Core `0e01913a29b90a6c0e55fb4fb0e3c759a3f40de9dc1008b721444dbb325bcb89`;
110
+ Agents `7afed703128d6281ea56b77c778658289066887ac1d824e220dae5c5542ca812`;
111
+ SDK `b344e2b6b0990dc5358d773ec0c97dd89dd2b770ca15de4ed1ed5bd50afee84c`.
112
+ Final validation uses npm publications without `ZHIVEX_SDK_FIXTURE`.
113
+ The official `npm audit signatures` check succeeds (5 registry signatures and
114
+ 4 attestations across the isolated three-package installation and dependencies).
115
+ Web offline test setup links only this checkout's built public engine exports,
116
+ preserving a registry dependency as a local backup and refusing another checkout's
117
+ link. Product installation/build never invokes that test setup.
@@ -59,7 +59,10 @@
59
59
  "v1.4.0-rc.3",
60
60
  "v1.4.0-rc.4",
61
61
  "v1.4.0-rc.5",
62
- "v1.4.0-rc.6"
62
+ "v1.4.0-rc.6",
63
+ "v1.4.0-rc.7",
64
+ "v1.4.0-rc.8",
65
+ "v1.4.0"
63
66
  ],
64
67
  "expectedModels": [
65
68
  {
@@ -525,6 +528,30 @@
525
528
  "qwen": "qwen3.8-flash",
526
529
  "openai": "gpt-6-luna"
527
530
  }
531
+ },
532
+ {
533
+ "releaseTag": "v1.4.0-rc.7",
534
+ "models": {
535
+ "meta": "muse-spark-1.3-contributor",
536
+ "qwen": "qwen3.8-flash",
537
+ "openai": "gpt-6-luna"
538
+ }
539
+ },
540
+ {
541
+ "releaseTag": "v1.4.0-rc.8",
542
+ "models": {
543
+ "meta": "muse-spark-1.3-contributor",
544
+ "qwen": "qwen3.8-flash",
545
+ "openai": "gpt-6-luna"
546
+ }
547
+ },
548
+ {
549
+ "releaseTag": "v1.4.0",
550
+ "models": {
551
+ "meta": "muse-spark-1.3-contributor",
552
+ "qwen": "qwen3.8-flash",
553
+ "openai": "gpt-6-luna"
554
+ }
528
555
  }
529
556
  ],
530
557
  "expectedCases": [
@@ -1,22 +1,22 @@
1
- # Examples for Zhivex Harness 1.3
1
+ # Examples for Zhivex Harness 1.4
2
2
 
3
3
  ## Isolated Bun installation
4
4
 
5
- Requirements: Bun 1.4.0+, Node.js 22.13.0+, and Git on macOS or Linux. After protected RC publication, this installs the 1.4.0-rc.6 candidate artifact in a temporary consumer, without building the source checkout or changing global tools:
5
+ Requirements: Bun 1.4.0+, Node.js 22.13.0+, and Git on macOS or Linux. After protected stable publication, this installs the 1.4.0 artifact in a temporary consumer, without building the source checkout or changing global tools:
6
6
 
7
7
  ```bash
8
8
  harness_demo_dir=$(mktemp -d)
9
9
  cd "$harness_demo_dir"
10
10
  printf '{"name":"harness-first-run","private":true}\n' > package.json
11
- bun add --exact --ignore-scripts @zhivex-ai/harness@1.4.0-rc.6
11
+ bun add --exact --ignore-scripts @zhivex-ai/harness@1.4.0
12
12
  ./node_modules/.bin/zhx --version
13
13
  ./node_modules/.bin/zhx --help
14
14
  ./node_modules/.bin/zhx doctor --provider openai --json
15
15
  ```
16
16
 
17
- Version must print `1.4.0-rc.6`; help lists commands. Doctor does not contact a provider. Without `OPENAI_API_KEY`, it reports the missing credential and exits with code `3`; inspect the JSON checks before proceeding. A directory without Git initialization can also produce a diagnostic warning. No paid model call is required for these checks. Both `zhx` and `zhivex-harness` are installed aliases; Bun manages installation, and their shebang runs Node.
17
+ Version must print `1.4.0`; help lists commands. Doctor does not contact a provider. Without `OPENAI_API_KEY`, it reports the missing credential and exits with code `3`; inspect the JSON checks before proceeding. A directory without Git initialization can also produce a diagnostic warning. No paid model call is required for these checks. Both `zhx` and `zhivex-harness` are installed aliases; Bun manages installation, and their shebang runs Node.
18
18
 
19
- To continue in your actual project, use the [global installation and credential setup](../README.md#installation), then `zhx init --profile daily --provider openai` and `zhx doctor --profile daily`. Real tasks require the selected provider credential in the process environment. Profiles store provider/model choices, never credentials. See [CLI](../docs/CLI.md) and [support](../SUPPORT.md).
19
+ To continue in your actual project, use the [global installation and credential setup](../README.md#quick-start), then `zhx init --profile daily --provider openai` and `zhx doctor --profile daily`. Real tasks require the selected provider credential in the process environment. Profiles store provider/model choices, never credentials. See [CLI](../docs/CLI.md) and [support](../SUPPORT.md).
20
20
 
21
21
  ## Configuration and change examples
22
22