@zhivex-ai/harness 1.1.1 → 1.2.0-rc.13

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 (119) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/README.md +14 -7
  3. package/SECURITY.md +1 -1
  4. package/SUPPORT.md +3 -3
  5. package/benchmarks/README.md +17 -0
  6. package/contracts/public-api.json +95 -5
  7. package/contracts/stable-api-signatures.json +38 -38
  8. package/dist/acp-cli.d.ts +2 -0
  9. package/dist/acp-cli.js +15938 -0
  10. package/dist/cli/arguments.d.ts +7 -1
  11. package/dist/cli/cli-credentials.d.ts +6 -1
  12. package/dist/cli/cli-options.d.ts +1 -1
  13. package/dist/cli/cli-profiles.d.ts +15 -0
  14. package/dist/cli/cli-stream.d.ts +3 -3
  15. package/dist/cli/console/console-budget.d.ts +9 -0
  16. package/dist/cli/console/console-commands.d.ts +3 -3
  17. package/dist/cli/console/console-compaction.d.ts +18 -0
  18. package/dist/cli/console/console-input.d.ts +22 -3
  19. package/dist/cli/console/console-navigation.d.ts +3 -0
  20. package/dist/cli/console/console-presentation.d.ts +9 -2
  21. package/dist/cli/console/console-progress.d.ts +6 -0
  22. package/dist/cli/console/console-reasoning.d.ts +3 -0
  23. package/dist/cli/doctor.d.ts +2 -2
  24. package/dist/cli/presentation.d.ts +8 -1
  25. package/dist/cli/qwen-connection.d.ts +23 -0
  26. package/dist/cli/run-document.d.ts +4 -4
  27. package/dist/cli/terminal/activity-history.d.ts +15 -0
  28. package/dist/cli/terminal/session-grants.d.ts +4 -0
  29. package/dist/cli/terminal/terminal-markdown.d.ts +7 -4
  30. package/dist/cli/terminal/terminal-table.d.ts +6 -0
  31. package/dist/cli/terminal/terminal-ui.d.ts +3 -0
  32. package/dist/cli/terminal/tool-activity.d.ts +21 -10
  33. package/dist/cli/tool-execution.d.ts +1 -0
  34. package/dist/cli-3jmy4h5h.js +5798 -0
  35. package/dist/cli-entry-1bx83sw4.js +4 -0
  36. package/dist/cli-entry-427869g9.js +2009 -0
  37. package/dist/cli-entry-64pdp3k5.js +17 -0
  38. package/dist/cli-entry-b1mfvmxe.js +376 -0
  39. package/dist/cli-entry-c2f58zj2.js +13602 -0
  40. package/dist/cli-entry.d.ts +2 -0
  41. package/dist/cli.d.ts +1 -0
  42. package/dist/cli.js +15 -19168
  43. package/dist/client/acp-stdio.d.ts +9 -0
  44. package/dist/client/acp.d.ts +18 -0
  45. package/dist/client/index.d.ts +2 -0
  46. package/dist/client/json-contracts.d.ts +22 -8
  47. package/dist/config-1k9t4jhh.js +59 -0
  48. package/dist/context/adaptive-compaction.d.ts +2 -0
  49. package/dist/context/compaction.d.ts +3 -1
  50. package/dist/context/qwen-reasoning.d.ts +5 -0
  51. package/dist/context/scoped-context.d.ts +61 -0
  52. package/dist/context/semantic-compaction.d.ts +21 -0
  53. package/dist/context/task-memory.d.ts +13 -8
  54. package/dist/execution/execution-environment.d.ts +5 -0
  55. package/dist/execution/oci-observability.d.ts +2 -0
  56. package/dist/execution/patch-diagnostics.d.ts +6 -0
  57. package/dist/hostile-repository-demo.js +4614 -1930
  58. package/dist/index.d.ts +13 -1
  59. package/dist/index.js +16435 -12486
  60. package/dist/integrations/mcp.d.ts +23 -3
  61. package/dist/models/catalog.d.ts +76 -0
  62. package/dist/models/compaction-recommendations.d.ts +28 -0
  63. package/dist/models/sdk-catalog-adapter.d.ts +7 -0
  64. package/dist/persistence/operations.d.ts +10 -6
  65. package/dist/persistence/state-backup-stream.d.ts +4 -0
  66. package/dist/persistence/state-backup.d.ts +52 -0
  67. package/dist/persistence/state-gitignore.d.ts +2 -0
  68. package/dist/persistence/workspace-checkpoints.d.ts +149 -0
  69. package/dist/providers/meta-continuation.d.ts +1 -1
  70. package/dist/providers/meta-errors.d.ts +2 -0
  71. package/dist/providers/meta-replay.d.ts +2 -0
  72. package/dist/providers/qwen-context.d.ts +2 -0
  73. package/dist/providers/qwen-hosted-policy.d.ts +5 -0
  74. package/dist/providers/reasoning.d.ts +18 -0
  75. package/dist/runtime/config.d.ts +12 -3
  76. package/dist/runtime/context-runtime.d.ts +12 -0
  77. package/dist/runtime/error-diagnostics.d.ts +641 -0
  78. package/dist/runtime/harness.d.ts +13 -4
  79. package/dist/runtime/model-edit-references.d.ts +8 -0
  80. package/dist/runtime/oci-delivery.d.ts +17 -0
  81. package/dist/runtime/progress-monitor.d.ts +33 -0
  82. package/dist/runtime/provider-diagnostics.d.ts +35 -0
  83. package/dist/runtime/runtime-checkpoints.d.ts +3 -0
  84. package/dist/runtime/runtime-diagnostics.d.ts +5 -5
  85. package/dist/runtime/runtime-policy.d.ts +14 -6
  86. package/dist/runtime/time-to-safe-fix.d.ts +308 -1
  87. package/dist/runtime/tool-execution.d.ts +11 -0
  88. package/dist/runtime/tool-policy.d.ts +55 -0
  89. package/dist/runtime/tool-scheduling.d.ts +5 -0
  90. package/dist/runtime/usage-ledger.d.ts +1 -0
  91. package/dist/service-cli.js +9422 -6622
  92. package/dist/service-client-cli-yx56n0hc.js +1086 -0
  93. package/dist/tools/dependency-read.d.ts +63 -0
  94. package/dist/tools/execution.d.ts +8 -8
  95. package/dist/tools/workspace.d.ts +31 -15
  96. package/dist/verify-historical-migrations.js +5272 -2437
  97. package/dist/workspace/file-security.d.ts +6 -0
  98. package/dist/zhx.js +15 -19168
  99. package/docs/ACP.md +55 -0
  100. package/docs/CLI.md +292 -29
  101. package/docs/CONTEXT_ENGINEERING.md +184 -20
  102. package/docs/CREDENTIALS.md +38 -6
  103. package/docs/DURABLE_OPERATIONS.md +10 -0
  104. package/docs/EXTENSIBILITY.md +101 -4
  105. package/docs/FIRST_USE.md +7 -5
  106. package/docs/MODEL_CATALOG.md +52 -1
  107. package/docs/README.md +1 -0
  108. package/docs/REPOSITORY_EDITING.md +42 -0
  109. package/docs/STABILITY.md +2 -0
  110. package/docs/SUPPORT_MATRIX_1_1.md +17 -0
  111. package/docs/USAGE.md +9 -0
  112. package/docs/WORKSPACE_CHECKPOINTS.md +27 -0
  113. package/docs/images/cli-conversation.png +0 -0
  114. package/docs/support-matrix-1.1.json +29 -0
  115. package/evaluations/golden-expectations.json +5 -0
  116. package/evaluations/representative-assembly-matrix.json +145 -1
  117. package/evaluations/representative-repositories-v2.jsonl +7 -0
  118. package/examples/README.md +2 -2
  119. package/package.json +19 -13
package/docs/ACP.md ADDED
@@ -0,0 +1,55 @@
1
+ # Experimental ACP text sessions
2
+
3
+ The harness provides an experimental Agent Client Protocol v1 **subset** for an editor or other local client: initialization, new sessions, text prompts, one-time permissions and cancellation. It runs over JSON-RPC 2.0, one JSON message per line on stdio.
4
+
5
+ This is not full ACP conformance. In particular, ACP requires support for client-supplied stdio MCP servers; this adapter rejects them. Test compatibility with your editor before relying on it. The negotiation response marks the subset in `_meta.zhivex`.
6
+
7
+ ## Launch
8
+
9
+ From a source checkout:
10
+
11
+ ```sh
12
+ bun src/acp-cli.ts --workspace /absolute/project --provider openai --model YOUR_MODEL
13
+ ```
14
+
15
+ After building:
16
+
17
+ ```sh
18
+ node dist/acp-cli.js --workspace /absolute/project --provider openai --model YOUR_MODEL
19
+ ```
20
+
21
+ Use existing host configuration flags and environment credentials. `--profile` loads an existing CLI profile. The service does not open interactive credential prompts. It writes only protocol messages to stdout; startup failures and help go to stderr. SIGINT, SIGTERM and closing stdin request cancellation and close the adapter and harness.
22
+
23
+ The client must wait for each setup response:
24
+
25
+ ```json
26
+ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{}}}
27
+ {"jsonrpc":"2.0","id":2,"method":"session/new","params":{"cwd":"/absolute/project","mcpServers":[]}}
28
+ ```
29
+
30
+ Use the returned `sessionId` in subsequent `session/prompt` requests with `prompt: [{"type":"text","text":"Your task"}]`. Completed assistant text arrives as a `session/update` notification before the prompt response. This implementation buffers output until the durable run completes; it does not stream individual tokens or tool updates.
31
+
32
+ ## Permissions and cancellation
33
+
34
+ A durable pending approval produces a `session/request_permission` request. The client can select only `allow_once` or `reject_once`, or return a cancelled outcome. The adapter translates that decision using the pending approval's exact ID, digest and run revision. The existing harness verifies expiration, revision and file digests before execution. Approval requests expose the pending action as `toolCall.rawInput`; clients should render that action for review.
35
+
36
+ `session/cancel` is a notification. It stops an active run or pending permission request and returns the original prompt with `stopReason: "cancelled"`. Permission responses time out after 15 minutes and cancel the pending run. Closing the connection also cancels outstanding work. A cancellation does not undo effects already committed.
37
+
38
+ Only one prompt executes at a time per connection. Other simultaneous prompts receive a busy error. Unknown sessions, stale approvals and invalid permission choices cannot authorize operations.
39
+
40
+ ## Supported boundary
41
+
42
+ - Host owns the workspace, provider, model, credentials, policies and tools. `session/new.cwd` must match the configured workspace.
43
+ - Text prompts only; no image, audio or embedded resources.
44
+ - No client-provided MCP servers, client filesystem operations or client terminals.
45
+ - No session load/resume, model switching, modes, or authentication protocol. Durable sessions remain accessible through existing harness interfaces.
46
+ - Frames are limited to 1 MiB, prompts to 64 KiB, concurrent protocol handlers to 64 and sessions to 256 per connection. Oversized frames or handler floods terminate the connection and cancel work.
47
+ - A transport connection should belong to a single trusted local client. This is not an unauthenticated network service.
48
+
49
+ ## Embedding
50
+
51
+ Create the existing `createHarnessClientAdapter(harness)`, then call `createAcpConnection(adapter, { workspace, notify, requestPermission })`. Pass decoded requests into `handle`; route returned responses back to the client. `requestPermission(params, signal)` should cancel its pending client request when the signal aborts. Call `cancelActive()` before closing a connection. The host remains responsible for `adapter.close()` and `harness.close()`.
52
+
53
+ `serveAcpStdio(adapter, { workspace, input, output })` supplies framing and permission-response correlation for Node readable/writable streams.
54
+
55
+ Protocol references: [initialization](https://agentclientprotocol.com/protocol/v1/initialization), [session setup](https://agentclientprotocol.com/protocol/v1/session-setup), [prompt lifecycle and cancellation](https://agentclientprotocol.com/protocol/v1/prompt-turn), [permissions](https://agentclientprotocol.com/protocol/v1/tool-calls).
package/docs/CLI.md CHANGED
@@ -72,6 +72,12 @@ Start with `zhx`. Use `/help` inside the conversation. For scripting, use `zhx r
72
72
 
73
73
  ### Interactive daily workflow
74
74
 
75
+ The Focus layout keeps a single conversation column in terminal scrollback. Model
76
+ and reasoning appear above the input, with approval state and selected attachments.
77
+ An empty draft shows a muted task hint. Shortcuts sit below the complete draft,
78
+ adapt to terminal width, and give way to command and history searches. Sending or
79
+ cancelling removes these editor hints before model output or approval questions.
80
+
75
81
  The console opens with the Zhivex logo and a compact welcome panel. Project/model context sits beside the logo when space permits. Before each task, the composer shows the model, approval mode, pending approval state and attachment count. Long labels are bounded to the terminal width; full configuration remains available through `/status`. Type `/` to open the command menu; keep typing to search names and descriptions, use Up/Down to select, Tab to insert, and Enter to submit. Escape dismisses the menu. Enter on a partial command inserts its selection; a separate Enter submits it, including approval commands. Only commands supported by the connected runtime appear. Narrow terminals use a compact logo; `NO_COLOR` disables logo color. The console completes slash-command prefixes with Tab. `/paste` captures a bounded
76
82
  multiline draft: finish with `.end` on a separate line, review the preview, then type
77
83
  `send` at the separate confirmation prompt. Slash commands inside the draft remain
@@ -89,14 +95,17 @@ Ctrl+R searches that in-memory history. Type a filter, use Up/Down to choose, th
89
95
  Left/Right and Home/End edit the draft in the supported Node terminal runtime;
90
96
  resizing the terminal preserves it. Ctrl+C discards the current draft (including
91
97
  an unfinished paste), or cancels the active operation and returns after cleanup.
92
- During an operation, typed input is ignored without echoing over the stream.
98
+ During an operation, typed input is retained as a background draft; Enter queues a
99
+ literal task for the next turn. Draft previews appear in the transient activity line.
100
+ Approval questions require fresh input and never consume the task queue.
93
101
 
94
102
  Text streams progressively, including partial lines during provider pauses. Activity,
95
103
  approval requests and completion remain separate labelled events. Partial output is
96
104
  flushed before errors or returning to the prompt, and terminal controls from the
97
105
  provider are escaped. After a provider error, Up recalls the submitted task for
98
- editing/retry; history stays in memory only. Markdown styling is best effort when
99
- a provider pauses inside markup; text is never replayed to restyle it.
106
+ editing/retry; history stays in memory only. Markdown emphasis and inline code wait for a matching closing marker within a bounded
107
+ span. Unclosed markers are preserved literally when interrupted, at a newline, or
108
+ at the size limit. Ordinary text is coalesced into short frames and never replayed.
100
109
 
101
110
  Reproduce this flow offline with `bun run build` followed by
102
111
  `python3 scripts/console-pty-smoke.py` (Python 3 and Node on macOS/Linux). The PTY
@@ -130,7 +139,11 @@ their status. Review groups retain the status reported by their group runtime.
130
139
  `/diff` colors additions, removals, and hunk headers on eligible terminals, respects
131
140
  `NO_COLOR`, and escapes untrusted terminal controls. Model text also escapes terminal
132
141
  controls and renders bounded Markdown headings, emphasis, and fenced code on a
133
- TTY; JSON/JSONL retain their existing data contracts.
142
+ TTY. Tables with leading pipes and a Markdown separator row render with aligned
143
+ borders and wrapped cells at the current terminal width; narrow terminals use
144
+ stacked labels and values. Table blocks buffer up to 128 lines (8 KiB per line)
145
+ before rendering; incomplete or oversized syntax stays readable as literal text.
146
+ Redirected output and JSON/JSONL retain their existing data contracts.
134
147
 
135
148
  Contributor validation: `bun run smoke:package` also runs a real PTY workflow
136
149
  against the installed CLI, including approval recovery after process restart.
@@ -200,7 +213,9 @@ For the rationale and reference patterns, see [Console UX](https://github.com/Zh
200
213
 
201
214
  `/resume` opens the searchable conversation menu; `/resume last` and `/resume <id>` remain shortcuts. `TERM=dumb` and non-TTY selection fall back to numbered lists. The service console offers navigation for conversations and session tools; provider/model policy remains with the service host.
202
215
 
203
- Activity is compact in the direct console: tool actions, approvals, errors and final run status remain visible; repeated provider and per-step transport notices are hidden. `/verbose` toggles full activity for that console process. One-shot and JSON/JSONL outputs retain their contracts.
216
+ Activity is compact in the direct console: tool actions appear only as a temporary TTY status; approvals, errors and final run status remain visible; repeated provider and per-step transport notices are hidden. `/verbose` toggles full activity for that console process. One-shot and JSON/JSONL outputs retain their contracts.
217
+
218
+ The agent is instructed to give brief progress updates unless the requested output format or silent execution prevents them; their frequency depends on the model. Model text is shown in compact mode too. Direct CLI runs and continuations return unknown tool names as error receipts so the model can select an exposed tool. Unknown tools are never executed or aliased, and error/step budgets and approval requirements still apply. Library callers retain their configured tool-error policy.
204
219
 
205
220
  Each console session is a scoped, durable chain of immutable run IDs. The session index stores provider/model/status metadata and never stores prompts, model messages, tool payloads, or provider data; those remain in the governed run store. `zhx chat --continue` opens the latest session and `--session <id>` selects one explicitly.
206
221
 
@@ -319,21 +334,24 @@ Personal CLI profile schema `1` is separate from resolved Harness configuration
319
334
 
320
335
  The default state directory is `<workspace>/.zhivex-harness/runs` and the default backend is scoped SQLite at `operations.sqlite`. Explicit external state directories are supported, but the workspace root, filesystem root, sensitive workspace paths, regular files, and symbolic-link targets are rejected before the run store is created. See [DURABLE_OPERATIONS.md](./DURABLE_OPERATIONS.md) for state migration and operations, and [EXTENSIBILITY.md](./EXTENSIBILITY.md) for capability, MCP, subagent, and review-group configuration.
321
336
 
322
- ### Runtime repair policy
337
+ ### Required verified delivery
323
338
 
324
- `--agent-profile <strict|repair>` selects the runtime policy (default `strict`;
325
- `ZHIVEX_HARNESS_AGENT_PROFILE` provides the environment default). `repair` enables
326
- bounded schema/tool recovery, cumulative model accounting, exploration controls,
327
- and up to two retries of recoverable approved verifier failures. A successful
339
+ The assistant uses one general-purpose execution loop with bounded schema/tool
340
+ recovery and cumulative accounting. `--require-verified-delivery` adds an explicit
341
+ completion obligation, exploration controls and up to two retries of recoverable
342
+ approved verifier failures. A successful
328
343
  approved verification/import can finish from its durable receipt. It does not
329
344
  auto-approve tools, bypass checks, or recover cancellations/integrity violations.
330
- The selected profile is persisted in resume configuration and the harness binding.
345
+ The delivery requirement is persisted in resume configuration and the harness binding.
346
+ The former `--agent-profile`, `agentProfile` and `ZHIVEX_HARNESS_AGENT_PROFILE`
347
+ configuration have been removed; there is no profile alias. Saved connection
348
+ profiles (`--profile`) and optional subagent roles are independent and unchanged.
331
349
 
332
350
  ```sh
333
- bun run src/cli.ts run "Fix the regression and verify it" --agent-profile repair --execution oci
351
+ bun run src/cli.ts run "Fix the regression and verify it" --require-verified-delivery --execution oci
334
352
  ```
335
353
 
336
- Library callers select `agentProfile: "repair"` in `createHarness` and can observe
354
+ Library callers select `requireVerifiedDelivery: true` in `createHarness` and can observe
337
355
  bounded timings/accounting with `runHarness(..., { onDiagnostics })`. Telemetry
338
356
  observer exceptions do not alter the execution result. A stricter caller can
339
357
  explicitly override tool-error behavior or terminal receipt settings.
@@ -373,10 +391,14 @@ into a new CLI result. Approval output remains untrusted repository text.
373
391
 
374
392
  ### Compact tool activity
375
393
 
376
- Interactive chat groups tool activity between assistant messages into one summary.
377
- On a TTY, a single bounded line updates while tools run; redirected output receives
378
- plain summaries without cursor controls. `/verbose` restores individual events.
379
- Tool failures, check receipts, and approval requests remain individually visible.
394
+ Interactive chat keeps successful tool bookkeeping out of the conversation.
395
+ On a TTY, one temporary line shows Reading files, Exploring the project, or Thinking
396
+ and is erased before the next assistant text. Redirected compact output omits this
397
+ status entirely. Reads, searches and listings accumulate into one summary when
398
+ the run finishes or requests approval, rather than interrupting every assistant
399
+ message. Edits, check receipts and failures remain visible; known tool failures
400
+ show a short actionable reason without dumping their payload. `/verbose` restores
401
+ individual tool events for subsequent activity. Approval requests remain visible.
380
402
  Budget and step-limit failures show their known runtime cause; arbitrary provider
381
403
  error payloads are not printed in activity events.
382
404
 
@@ -388,15 +410,256 @@ subsequent model calls, rather than guaranteeing a pre-request input-token ceili
388
410
 
389
411
  ### Runs without cumulative token budgets
390
412
 
391
- Use `zhx --no-token-budget` for the interactive console or
392
- `zhx run --no-token-budget "Your task"` for a single task. This explicitly disables
393
- cumulative input, output, and total token ceilings for the main run and all its
394
- subagents, including the repair controller's token closure reserve. Usage is still
395
- measured and persisted; the setting survives approval resume and conversation continuation.
396
- Numeric token settings remain stored but inactive while this mode is enabled.
397
- Default token budgets are unchanged for runs without this flag.
398
-
399
- Compaction, per-request model/provider limits, cost budgets, step/tool limits,
400
- timeouts, and approvals still apply. This is not an unlimited context window or
401
- an unlimited single response. Library callers use `unlimitedTokens: true` in
402
- `HarnessConfigInput`; `false` restores enforcement of the numeric token budgets.
413
+ New local interactive sessions (`zhx` or `zhx chat`) have no cumulative token
414
+ ceiling by default. Automatic compaction continues, and usage is measured and
415
+ persisted. This avoids ending a repository analysis solely because repeated
416
+ requests have consumed 100,000 input tokens.
417
+
418
+ `zhx run`, `zhx review`, SDK callers and service hosts retain their bounded
419
+ defaults. Use `--token-budget` in the local console to opt into those budgets.
420
+ Explicit numeric token flags or token-limit environment variables also enable
421
+ bounded console execution unless `--no-token-budget` is explicitly supplied.
422
+ Saved conversations retain their stored policy, including older bounded sessions;
423
+ start a new session to use the new default.
424
+
425
+ `--no-token-budget` disables cumulative input, output and total token ceilings for
426
+ the main run and children, including token closure reserves. Numeric settings remain
427
+ stored but inactive. Step/tool limits, timeouts, monetary limits and approvals still
428
+ apply. Library callers use `unlimitedTokens: true`; `false` restores token limits.
429
+
430
+ `--context-tokens <n>` sets the estimated context compaction threshold independently
431
+ of cumulative usage. The default is 40,000. It can be adjusted for the selected model;
432
+ it does not change the provider's actual context window. The local catalog does not
433
+ yet declare verified model context windows, so the harness does not infer larger
434
+ windows from model names. Saved sessions preserve this threshold.
435
+
436
+ `/context` shows the estimated retained conversation size (excluding additional
437
+ request instructions and tool schemas), compaction settings and budget mode.
438
+ `/usage` shows the latest run's cumulative input/output usage and remaining budget
439
+ separately from the transport ledger. Unknown usage is not reported as zero.
440
+
441
+ Examples:
442
+
443
+ ```sh
444
+ zhx
445
+ zhx --token-budget --max-input-tokens 200000 --max-total-tokens 230000
446
+ zhx --context-tokens 100000
447
+ zhx run --max-input-tokens 200000 --max-total-tokens 230000 "Analyze the repository"
448
+ zhx run --no-token-budget "Analyze the repository"
449
+ ```
450
+
451
+ ### Conversation preview
452
+
453
+ ![Interactive conversation with temporary tool activity](./images/cli-conversation.png)
454
+
455
+ This image is rendered from the real CLI's PTY screen with an offline provider
456
+ fixture and real read-only workspace tools. It is a presentation test, not live
457
+ Qwen certification. Reproduce it after `bun run build` with Python 3, `pyte==0.8.2`
458
+ and Pillow installed:
459
+
460
+ ```sh
461
+ python3 scripts/capture-console-ux.py /tmp/cli-conversation.png
462
+ ```
463
+
464
+ The capture writes a PNG and its raw ANSI transcript next to it; both contain only
465
+ the disposable fixture session. No provider request leaves the process.
466
+
467
+ ### Approval modes
468
+
469
+ Local `zhx` and `zhx run` accept `--approval-mode ask|auto|restricted`:
470
+
471
+ - `ask` (default): ordinary permitted reads run directly; approval-gated actions
472
+ prompt in a terminal and remain pending without a terminal.
473
+ - `auto`: approves actions within the existing workspace, command and execution
474
+ policies. `--yes` remains its alias. Neither option removes protected paths.
475
+ - `restricted`: rejects approval requests without prompting; the agent can use
476
+ already permitted tools and report what it could not complete.
477
+
478
+ `--approval-mode` and `--yes` cannot be combined. Service clients cannot override
479
+ host approval configuration with this option.
480
+
481
+ `read_dependency` inspects one installed package without a separate approval,
482
+ like other permitted read-only tools. It supports `action: "list"` to discover
483
+ package-relative paths, `action: "search"` for literal text, and `action: "read"`
484
+ (the default) for UTF-8 source, documentation, manifests and declarations. Use
485
+ `package` to select the package; never pass a `node_modules` path to ordinary
486
+ workspace tools. Discover files before reading guessed paths.
487
+
488
+ Reads and discovery are bounded and cannot execute dependency scripts or write
489
+ files. Traversal, links, nested packages and protected content remain denied.
490
+ Treat dependency contents as untrusted source material. Errors give guidance for
491
+ listing the package when a path does not exist. Linked package-manager layouts
492
+ remain subject to the filesystem boundary.
493
+
494
+ In the console, `run` command, SDK harness and delegated runs, tool errors, including protected reads and denied approvals, return
495
+ evidence to the model so it can choose another permitted strategy. Existing
496
+ tool-error, step and time budgets bound recovery. Validation and security
497
+ checks still reject the underlying action. Invalid arguments and unknown tool
498
+ names produce structured error receipts; neither is executed. This recovery is
499
+ independent of the optional `repair` controller, so a normal coding session does
500
+ not need a verifier plan for every task. Library callers that need fail-fast
501
+ behavior can explicitly pass `toolExecution: { stopOnError: true,
502
+ validationErrorMode: "throw", unknownToolMode: "throw" }`.
503
+ The client protocol's `approval.resolve` command remains fail-fast for the
504
+ specific reviewed effect, so denial or stale content cannot be acknowledged as
505
+ a successful decision. A subsequent turn can continue from that failed attempt.
506
+
507
+ ```sh
508
+ zhx --approval-mode ask
509
+ zhx --approval-mode auto
510
+ zhx run --approval-mode restricted "Analyze this repository without additional permissions"
511
+ ```
512
+
513
+ ### Interactive connection and approval settings
514
+
515
+ Use `/menu` → Credentials to configure Qwen Standard API or QwenCloud Token Plan,
516
+ with the matching region and hidden key. `/connection` optionally tests the current
517
+ model with a small billable request. See [credentials](CREDENTIALS.md).
518
+
519
+ `/approvals` opens the mode picker; `/approvals ask`, `/approvals auto`, and
520
+ `/approvals restricted` switch directly. The composer and `/status` show the active
521
+ mode. Auto approves gated actions within existing workspace and execution policies.
522
+ Bounded dependency inspection runs without a separate approval in every mode.
523
+ Restricted denies gated actions. Mode changes apply only to this CLI process and are blocked
524
+ while work is active or awaiting approval; use `/pending`, `/approve`, or `/deny`
525
+ first. Service-connected consoles retain host-controlled policy.
526
+
527
+ ### Conversation presentation and step limits
528
+
529
+ The local console groups transient tool activity on one line and shows approval
530
+ cards with a keyboard picker. Check approvals retain the exact script and workspace;
531
+ IDs and input hashes are available through **View technical details**. Reviewed
532
+ edits retain their complete payload. Cancelling the picker leaves the batch pending.
533
+ `/verbose` retains the detailed event view; JSONL output retains its event contract.
534
+
535
+ New local conversations, API runs, automation, and service runs default to a finite
536
+ limit of 50 model iterations per turn. Explicit
537
+ `--max-steps` and `ZHIVEX_HARNESS_MAX_STEPS` take precedence. Saved runs retain their
538
+ limits. `/limits` opens a picker and `/limits 100` sets the limit for subsequent
539
+ turns. Step limits accept any positive safe integer, with no separate ceiling of 50.
540
+ Explicit parent and child step/tool-call budgets can exceed the former configuration
541
+ ceilings; defaults remain finite and tool calls still accept zero to prohibit calls.
542
+ Active runs and pending
543
+ approvals must be resolved first. More steps can increase API costs; other budgets
544
+ still apply. A failed run reaching its step limit now shows the persisted cause
545
+ and the current/maximum counts. Continue with a new message after adjusting the
546
+ limit; this does not rewrite the failed run or certify unfinished work.
547
+
548
+ Compact activity remains visible while the model is silent: the terminal shows
549
+ its current step and elapsed wait, followed by grouped counts of completed tool
550
+ operations. Successful reads and searches remain in the transcript instead of
551
+ being erased. Tool arguments, file contents, and private reasoning are not printed
552
+ in these progress summaries. Checks and errors retain their separate receipts.
553
+
554
+ ### Interactive continuity and session permissions
555
+
556
+ New local `chat` sessions default to 50 model steps, 200 tool calls, 20 tool
557
+ errors and 60 minutes per run. Explicit CLI/environment limits and saved run
558
+ policies take precedence. Automation and service share the 50-step default but
559
+ retain their separate tool, token and time budgets.
560
+ `/usage` shows all these ceilings separately from cumulative token usage.
561
+
562
+ After an interrupted or failed turn, `/continue` starts a new run with retained
563
+ messages and recorded results. The previous run keeps its actual terminal status
564
+ for diagnostics. Pending approvals must be resolved first. Missing tool receipts
565
+ are marked as unknown outcomes: continuation must inspect state before proposing
566
+ another action. Continuation is explicit, including when the previous run reached
567
+ a configured token or cost budget; it starts a fresh per-run budget.
568
+
569
+ In the approval picker, **Allow this exact check for this session** remembers the
570
+ workspace, provider, child agent, check name and exact expected script. A changed
571
+ script prompts again; executor script validation still applies. Grants live only
572
+ in the CLI process and are not saved with conversations. Bounded dependency
573
+ inspection does not require a grant. Leaving a batch pending discards its new grants.
574
+
575
+ Three consecutive failed calls with the same tool request stop the local turn;
576
+ a different request or successful tool result resets the counter. This tolerates
577
+ ordinary exploratory errors while bounding unproductive loops. New chat turns
578
+ allow two SDK transport retries with 500 ms initial backoff. This does not restart
579
+ an agent run or automatically replay executed tools or interrupted streams.
580
+
581
+ Context remains a separate limit. Use `--context-tokens 100000` when the selected
582
+ model and endpoint support the full request plus output reserve. The current
583
+ catalog has no verified context-window metadata, so the fallback remains 40000
584
+ estimated conversation tokens; no model capacity is guessed. Qwen reasoning
585
+ fragments are normalized losslessly before estimation, followed by adaptive
586
+ compaction at safe tool/approval boundaries. Identical unsigned final reasoning
587
+ summaries are deduplicated against their streamed text. The compaction target
588
+ has a floor for instructions and the newest complete interaction so that a
589
+ target alone cannot abort useful work. Actual context admission and configured
590
+ run budgets remain authoritative; protected groups are never silently discarded.
591
+ ## Configurable model-assisted compaction
592
+
593
+ Automatic compaction remains deterministic unless explicitly selected. Use
594
+ `--compaction-model <id>` and optionally `--compaction-provider <provider>` on
595
+ `zhx run` or `zhx chat`. The provider defaults to the primary provider. Example:
596
+
597
+ ```sh
598
+ zhx chat --provider openai --compaction-provider openai --compaction-model gpt-6-luna
599
+ ```
600
+
601
+ In the direct console, `/compaction` shows the selection, `/compaction recommend`
602
+ shows evidence-backed advice, `/compaction provider:model` selects a route, and
603
+ `/compaction off` restores deterministic compaction. Changes require no active or
604
+ pending turn and apply to subsequent turns in this CLI session. A paused run keeps
605
+ its exact original route. Custom model IDs are accepted; account access and summary
606
+ quality are not implied. Recommendations check credential presence, not live access.
607
+ Advice reserves 8,000 input and 1,024 output tokens and reports price scope, evidence
608
+ dates and unknown/stale metadata; it never changes the selected model automatically.
609
+
610
+ The selected provider receives bounded, redacted user/assistant excerpts, local
611
+ read/search code excerpts, diagnostic observations and deterministic context.
612
+ Code and diagnostic excerpts are untrusted data for summarization, not permission
613
+ or proof of correctness. Arbitrary tool objects, external-tool payloads and raw
614
+ provider responses are excluded. All excerpts share the existing input and byte
615
+ reservation limits.
616
+ Calls use the run's budgets and per-model usage ledger, including rejected summaries
617
+ and partial usage. Unknown usage stops continuation. Use per-route `--pricing-file`
618
+ and `--usage-limit-usd` for monetary caps; the legacy single-price cost budget cannot
619
+ be combined with a utility model. Manual `/compact` remains deterministic.
620
+
621
+ The experimental `zhx-acp` binary exposes text sessions to ACP clients; see
622
+ [ACP](ACP.md) for supported methods and limitations.
623
+
624
+ ## Model reasoning
625
+
626
+ The interactive model picker continues to a reasoning picker. Escape returns to the
627
+ model list without changing the active configuration. `/reasoning` adjusts the
628
+ current model; `/reasoning low` and `--reasoning low` select an explicit level.
629
+ Supported values are `default`, `none`, `minimal`, `low`, `medium`, `high`, `xhigh`
630
+ and `max`, but only adapter-declared levels are offered or accepted for that model.
631
+ `default` sends no override. Adapters without an explicit level inventory show
632
+ only `default`; a generic reasoning capability does not establish supported levels.
633
+ Higher effort can increase latency and token consumption. No effort is silently
634
+ lowered. The composer displays the setting. Onboarding stores it in the personal
635
+ profile; conversation runs persist it for resume. Switching models resets the
636
+ selection unless a new level is chosen. Explicit CLI configuration wins over a
637
+ profile. Active or approval-pending runs retain their original configuration.
638
+
639
+ Reviewed edits with missing read references can reuse a rejected candidate via
640
+ `retryToolCallId` after a successful reread, optionally specifying `createPaths`
641
+ for genuinely new files. The runtime rebinds references and requests approval for
642
+ the complete edit. Candidates are bounded to four / 1 MiB per invocation; durable
643
+ validation-failed calls seed recovery on resume. Unknown or unavailable candidates
644
+ require a fresh proposal. Explicit digests are never silently refreshed, and
645
+ stale files remain rejected. No edit occurs merely by retaining a candidate.
646
+
647
+ Qwen requests replay the local conversation instead of retaining a remote response
648
+ chain. This makes compacted context and current system guidance authoritative.
649
+ Reasoning and tool payloads remain intact; local replay does not guarantee a
650
+ particular cache hit rate or response latency.
651
+
652
+ ### Activity and queued tasks
653
+
654
+ `/activity` shows a bounded in-memory history of tool outcomes, approvals and applied
655
+ file receipts; `/activity clear` clears it. `/queue` lists tasks submitted while the
656
+ agent was busy, and `/queue clear` clears tasks and the unsent draft. Enter queues,
657
+ Alt+Enter adds a newline, Up retrieves the last queued task from an empty background
658
+ draft, and Ctrl+C cancels the operation and clears the queue. Queued slash text is
659
+ always a literal task, never an approval command. Pending approvals pause delivery.
660
+ The queue is limited to eight tasks / 256 KiB; each draft is limited to 64 KiB.
661
+
662
+ Activity shows phase and total elapsed time. Preparing edits, waiting for approval,
663
+ applied file changes and verification are distinct states. `/diff` reviews workspace
664
+ changes, including changes outside the current run; file receipts identify mutations
665
+ recorded by this harness.