clinkx 1.1.0 → 1.1.2

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 (162) hide show
  1. package/CHANGELOG.md +39 -1
  2. package/README.md +210 -177
  3. package/clinkx-workflows/dist/architecture-comparison/admission.d.ts +5 -0
  4. package/clinkx-workflows/dist/architecture-comparison/admission.js +50 -0
  5. package/clinkx-workflows/dist/architecture-comparison/admission.js.map +1 -0
  6. package/clinkx-workflows/dist/architecture-comparison/contract.d.ts +995 -0
  7. package/clinkx-workflows/dist/architecture-comparison/contract.js +149 -0
  8. package/clinkx-workflows/dist/architecture-comparison/contract.js.map +1 -0
  9. package/clinkx-workflows/dist/architecture-comparison/runtime.d.ts +29 -0
  10. package/clinkx-workflows/dist/architecture-comparison/runtime.js +387 -0
  11. package/clinkx-workflows/dist/architecture-comparison/runtime.js.map +1 -0
  12. package/clinkx-workflows/dist/contained-file.js +1 -1
  13. package/clinkx-workflows/dist/contained-file.js.map +1 -1
  14. package/clinkx-workflows/dist/council-execution-policy.d.ts +4 -2
  15. package/clinkx-workflows/dist/council-execution-policy.js +5 -1
  16. package/clinkx-workflows/dist/council-execution-policy.js.map +1 -1
  17. package/clinkx-workflows/dist/dashboard/activity-contract.d.ts +72 -72
  18. package/clinkx-workflows/dist/dashboard/contracts.d.ts +1564 -122
  19. package/clinkx-workflows/dist/dashboard/contracts.js +4 -0
  20. package/clinkx-workflows/dist/dashboard/contracts.js.map +1 -1
  21. package/clinkx-workflows/dist/dashboard/progress-report-contract.d.ts +12 -12
  22. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.d.ts +8 -8
  23. package/clinkx-workflows/dist/dashboard/scanner.d.ts +3 -0
  24. package/clinkx-workflows/dist/dashboard/scanner.js +27 -0
  25. package/clinkx-workflows/dist/dashboard/scanner.js.map +1 -1
  26. package/clinkx-workflows/dist/dashboard/session-log-contract.d.ts +48 -48
  27. package/clinkx-workflows/dist/dashboard/session-log-redaction.d.ts +2 -0
  28. package/clinkx-workflows/dist/dashboard/session-log-redaction.js +4 -0
  29. package/clinkx-workflows/dist/dashboard/session-log-redaction.js.map +1 -1
  30. package/clinkx-workflows/dist/dashboard/verified-repair-contract.d.ts +191 -0
  31. package/clinkx-workflows/dist/dashboard/verified-repair-contract.js +28 -0
  32. package/clinkx-workflows/dist/dashboard/verified-repair-contract.js.map +1 -0
  33. package/clinkx-workflows/dist/dashboard-ui/assets/index-BdpmbPps.js +115 -0
  34. package/clinkx-workflows/dist/dashboard-ui/assets/style-Im5i1iAs.css +1 -0
  35. package/clinkx-workflows/dist/dashboard-ui/index.html +2 -2
  36. package/clinkx-workflows/dist/engine.d.ts +6 -0
  37. package/clinkx-workflows/dist/engine.js +78 -7
  38. package/clinkx-workflows/dist/engine.js.map +1 -1
  39. package/clinkx-workflows/dist/index.d.ts +3 -0
  40. package/clinkx-workflows/dist/index.js +3 -2
  41. package/clinkx-workflows/dist/index.js.map +1 -1
  42. package/clinkx-workflows/dist/reducers/index.d.ts +9 -1
  43. package/clinkx-workflows/dist/reducers/index.js +22 -0
  44. package/clinkx-workflows/dist/reducers/index.js.map +1 -1
  45. package/clinkx-workflows/dist/state.js +17 -7
  46. package/clinkx-workflows/dist/state.js.map +1 -1
  47. package/clinkx-workflows/dist/validators/architecture-comparison.d.ts +2 -0
  48. package/clinkx-workflows/dist/validators/architecture-comparison.js +12 -0
  49. package/clinkx-workflows/dist/validators/architecture-comparison.js.map +1 -0
  50. package/clinkx-workflows/dist/validators/index.js +4 -0
  51. package/clinkx-workflows/dist/validators/index.js.map +1 -1
  52. package/clinkx-workflows/dist/validators/verified-repair.d.ts +2 -0
  53. package/clinkx-workflows/dist/validators/verified-repair.js +12 -0
  54. package/clinkx-workflows/dist/validators/verified-repair.js.map +1 -0
  55. package/clinkx-workflows/dist/verification-proof.d.ts +254 -0
  56. package/clinkx-workflows/dist/verification-proof.js +195 -0
  57. package/clinkx-workflows/dist/verification-proof.js.map +1 -0
  58. package/clinkx-workflows/dist/verified-repair/admission.d.ts +72 -0
  59. package/clinkx-workflows/dist/verified-repair/admission.js +63 -0
  60. package/clinkx-workflows/dist/verified-repair/admission.js.map +1 -0
  61. package/clinkx-workflows/dist/verified-repair/contract.d.ts +1910 -0
  62. package/clinkx-workflows/dist/verified-repair/contract.js +127 -0
  63. package/clinkx-workflows/dist/verified-repair/contract.js.map +1 -0
  64. package/clinkx-workflows/dist/verified-repair/host.d.ts +32 -0
  65. package/clinkx-workflows/dist/verified-repair/host.js +2 -0
  66. package/clinkx-workflows/dist/verified-repair/host.js.map +1 -0
  67. package/clinkx-workflows/dist/verified-repair/prompts.d.ts +12 -0
  68. package/clinkx-workflows/dist/verified-repair/prompts.js +58 -0
  69. package/clinkx-workflows/dist/verified-repair/prompts.js.map +1 -0
  70. package/clinkx-workflows/dist/verified-repair/result.d.ts +16 -0
  71. package/clinkx-workflows/dist/verified-repair/result.js +102 -0
  72. package/clinkx-workflows/dist/verified-repair/result.js.map +1 -0
  73. package/clinkx-workflows/dist/verified-repair/runtime.d.ts +28 -0
  74. package/clinkx-workflows/dist/verified-repair/runtime.js +186 -0
  75. package/clinkx-workflows/dist/verified-repair/runtime.js.map +1 -0
  76. package/clinkx-workflows/dist/workflow-tools.d.ts +3 -0
  77. package/clinkx-workflows/dist/workflow-tools.js +148 -14
  78. package/clinkx-workflows/dist/workflow-tools.js.map +1 -1
  79. package/clinkx-workflows/dist/workflow-verification-contract.d.ts +539 -0
  80. package/clinkx-workflows/dist/workflow-verification-contract.js +52 -0
  81. package/clinkx-workflows/dist/workflow-verification-contract.js.map +1 -0
  82. package/clinkx-workflows/dist/workflow-verification.d.ts +15 -0
  83. package/clinkx-workflows/dist/workflow-verification.js +218 -0
  84. package/clinkx-workflows/dist/workflow-verification.js.map +1 -0
  85. package/clinkx-workflows/templates/architecture-comparison/candidate.txt +29 -0
  86. package/clinkx-workflows/templates/architecture-comparison/judge.txt +31 -0
  87. package/clinkx-workflows/templates/verified-repair/investigate.txt +20 -0
  88. package/clinkx-workflows/templates/verified-repair/repair.txt +11 -0
  89. package/clinkx-workflows/templates/verified-repair/review.txt +18 -0
  90. package/clinkx-workflows/workflows/architecture-comparison.yaml +133 -0
  91. package/clinkx-workflows/workflows/verified-repair.yaml +104 -0
  92. package/dist/allowed-roots.js +4 -1
  93. package/dist/allowed-roots.js.map +1 -1
  94. package/dist/codex/app-server-client.d.ts +1 -0
  95. package/dist/codex/app-server-client.js +3 -2
  96. package/dist/codex/app-server-client.js.map +1 -1
  97. package/dist/context-builder/diagnostics.d.ts +1 -0
  98. package/dist/context-builder/diagnostics.js +1 -1
  99. package/dist/context-builder/diagnostics.js.map +1 -1
  100. package/dist/context-builder/discovery.d.ts +18 -1
  101. package/dist/context-builder/discovery.js +69 -1
  102. package/dist/context-builder/discovery.js.map +1 -1
  103. package/dist/context-builder/handler.js +8 -1
  104. package/dist/context-builder/handler.js.map +1 -1
  105. package/dist/context-builder/lifecycle-contract.d.ts +24 -24
  106. package/dist/context-builder/refine-handler.js +16 -1
  107. package/dist/context-builder/refine-handler.js.map +1 -1
  108. package/dist/context-builder/secrets.d.ts +11 -0
  109. package/dist/context-builder/secrets.js +81 -1
  110. package/dist/context-builder/secrets.js.map +1 -1
  111. package/dist/context-builder/versions.d.ts +5 -2
  112. package/dist/context-builder/versions.js +5 -2
  113. package/dist/context-builder/versions.js.map +1 -1
  114. package/dist/dashboard-cli.js +10 -3
  115. package/dist/dashboard-cli.js.map +1 -1
  116. package/dist/dashboard-gateway/main.js +8 -3
  117. package/dist/dashboard-gateway/main.js.map +1 -1
  118. package/dist/index.d.ts +2 -0
  119. package/dist/index.js +8 -2
  120. package/dist/index.js.map +1 -1
  121. package/dist/project-verification/contract.d.ts +537 -0
  122. package/dist/project-verification/contract.js +40 -0
  123. package/dist/project-verification/contract.js.map +1 -0
  124. package/dist/project-verification/files.d.ts +23 -0
  125. package/dist/project-verification/files.js +80 -0
  126. package/dist/project-verification/files.js.map +1 -0
  127. package/dist/project-verification/process.d.ts +7 -0
  128. package/dist/project-verification/process.js +115 -0
  129. package/dist/project-verification/process.js.map +1 -0
  130. package/dist/project-verification/runner.d.ts +35 -0
  131. package/dist/project-verification/runner.js +185 -0
  132. package/dist/project-verification/runner.js.map +1 -0
  133. package/dist/project-verification/service.d.ts +37 -0
  134. package/dist/project-verification/service.js +151 -0
  135. package/dist/project-verification/service.js.map +1 -0
  136. package/dist/provider-doctor.d.ts +22 -0
  137. package/dist/provider-doctor.js +22 -0
  138. package/dist/provider-doctor.js.map +1 -0
  139. package/dist/server.js +29 -1
  140. package/dist/server.js.map +1 -1
  141. package/dist/verification-tools.d.ts +90 -0
  142. package/dist/verification-tools.js +120 -0
  143. package/dist/verification-tools.js.map +1 -0
  144. package/dist/verified-repair/files.d.ts +22 -0
  145. package/dist/verified-repair/files.js +114 -0
  146. package/dist/verified-repair/files.js.map +1 -0
  147. package/dist/verified-repair/host.d.ts +14 -0
  148. package/dist/verified-repair/host.js +612 -0
  149. package/dist/verified-repair/host.js.map +1 -0
  150. package/docs/configuration.md +493 -0
  151. package/docs/engineering-recipes.md +415 -0
  152. package/docs/security.md +293 -0
  153. package/docs/verification/README.md +59 -0
  154. package/docs/verification/dashboard-real-disk.md +436 -0
  155. package/docs/verification/project-checks.example.json +14 -0
  156. package/docs/verification/project-checks.md +444 -0
  157. package/docs/verification/workflow-handoff.md +113 -0
  158. package/package.json +13 -6
  159. package/scripts/provider-doctor-core.mjs +364 -0
  160. package/scripts/provider-doctor-probe.mjs +34 -0
  161. package/clinkx-workflows/dist/dashboard-ui/assets/index-JPHQVtn9.js +0 -106
  162. package/clinkx-workflows/dist/dashboard-ui/assets/style-DOMHk-j6.css +0 -1
package/CHANGELOG.md CHANGED
@@ -1,6 +1,44 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 1.1.2 — 2026-10-09
4
+
5
+ ### Added
6
+
7
+ - Built-in `architecture-comparison` through `run_workflow`: two parallel authors receive the same bounded frozen packet, a fresh judge receives a separate semantic view with candidate aliases, and a deterministic reducer writes a strict owner-facing comparison record. References, output bounds, retained artifact digests, route bindings, and resume inputs are checked; incomplete evidence stays incomplete. The record preserves independent owner acceptance and states the limits of caller-declared source identity and free-text anonymity.
8
+ - Native `workflow_verification_attach` re-inspects project proof with the owner's original expectations digest and retains a bounded, separately versioned inspection history on a workflow run. MCP status and dashboard detail expose inspected-at applicability, required coverage, check failures and safe digest references, with retention and owner acceptance kept separate. Progress-report test counts remain caller-reported.
9
+ - Native MCP tools `provider_doctor`, `verification_run`, and `verification_inspect` work from an npm installation without a ClinkX clone or client shell access. Readiness is structured and authentication probes are explicit. Project verification runs reviewed argv commands within allowed roots, binds required checks to declared input and verifier identities, and retains private evidence for inspection with the owner's original expectations digest. The proposed standalone doctor/verifier npm CLI entry points were withdrawn before release. No Git or browser is required for project checks.
10
+ - Packaged engineering-recipe wiring, verification overview, project-check guide, and example manifest. Recipe instructions remain in the separately installed companion `chief-of-staff` skill; ClinkX's dashboard and workflow-handoff regression fixtures remain source-only.
11
+ - A source-checkout workflow-handoff verification procedure using the real YAML loader, MCP child session, workflow engine, validators, and artifact store. A host coverage evaluator checks frozen requirements and retained evidence; offline inspection requires the owner's original expectations digest and ignores cached success claims.
12
+ - `scripts/provider-doctor.mjs` remains a source-checkout JSONL wrapper over the shared provider-doctor core. The MCP tool returns structured adapter readiness and a final verdict; all diagnostics are credential-redacted. Documented in `docs/configuration.md`.
13
+ - A real-disk doctor (`clinkx-workflows/dashboard-ui/e2e/real-disk-doctor.mjs`) gates the dashboard real-disk e2e procedure: `preflight` checks node, dist freshness, chromium, the test-child seam, and an isolated `EVIDENCE_ROOT` before exercising the real fixture, `classify` maps a finished run to passed / blocked / not_run / harness_drift / failed_assertion / failed_fixture, and `identity` binds a run to its checkout and built artifacts. `docs/verification/dashboard-real-disk.md` documents the repeatable procedure.
14
+ - A "Verified bug fix" recipe in `docs/engineering-recipes.md`.
15
+
16
+ ### Fixed
17
+
18
+ - Dashboard-doctor Chromium preflight now removes only its owned profile and artifact directory, preserving other concurrent Playwright runs.
19
+ - Provider-doctor interruption stops all concurrent version checks and cancels active authentication probes with their owned descendants before exiting.
20
+ - Provider-doctor probes enforce their own 120-second cancellation deadline regardless of an adapter's timeout floor and require an exit-zero stdout or validated result-contract-file result with the exact trimmed `OK` answer before reporting authentication success.
21
+ - Workflow-handoff inspection preserves independently observed execution, consumer, and cleanup failures when source/build identity has drifted.
22
+ - Secret-redaction warnings deduplicate line numbers with a `Set`, preserving their ordering and bounded output without quadratic array scans.
23
+ - `context_builder` opt-out secret redaction (`allow_secrets:false`) can no longer gut ordinary code: a quote inside a regex literal or a mid-value `key: quote` no longer opens a redaction span that runs to the end of the file, an in-place redaction that would move line breaks or span more than three lines omits the body fail-closed instead of shipping it redacted, and remaining redactions surface as one aggregate `content_secret_redacted` warning. `CONTEXT_DISCOVERY_ALGORITHM_VERSION` advances to 6.
24
+ - A repeated SIGTERM no longer kills the dashboard, dashboard gateway, and server mid-shutdown: SIGTERM/SIGHUP handlers stay installed for repeats, teardown exits explicitly, and the dashboard and gateway close under an 8-second deadline that forces exit if closing stalls.
25
+ - Codex app-server diagnostics now redact hyphenated vendor tokens (`sk-ant-`, `sk-proj-`, `sk-or-`) in stderr and recent-failure text.
26
+
27
+ ### Docs
28
+
29
+ - Recipe wiring pins the merged three-recipe companion revision and records the completed evaluation and settled secret-policy decision.
30
+ - The pstack integration evaluation for ClinkX (reports, three-arm evaluation protocol, and implementation plan under `.ai/plans/`), the dashboard verification runbook (`docs/verification/`), and the opt-out redaction bound in the context-builder notes.
31
+
32
+ ## 1.1.1 — 2026-10-05
33
+
34
+ ### Changed
35
+
36
+ - The npm package now ships `docs/configuration.md` and `docs/security.md`, and the README is rewritten as a self-contained, install-facing page in Simplified Technical English. `package.json` `homepage` points at the npm package page and `bugs` is removed, because the source repository is private.
37
+
38
+ ### Fixed
39
+
40
+ - `context_builder` secret scanning (`allow_secrets:false`) on large bodies is 6-8x faster on Node 24: comment masking now returns the input string when nothing is masked, so memo lookups no longer compare a distinct but equal copy of the whole body. Output is unchanged.
41
+ - npm publish confirmation now waits up to about eight minutes for npm to expose the new version instead of failing after a few seconds; 1.1.0's automated publish succeeded but failed confirmation and needed a manual re-run to go green.
4
42
 
5
43
  ## 1.1.0 — 2026-10-03
6
44
 
package/README.md CHANGED
@@ -1,146 +1,204 @@
1
1
  # ClinkX
2
2
 
3
- An MCP STDIO server with local tools for CLI delegation and workflow orchestration.
3
+ ClinkX is an MCP server that connects your AI coding assistant to other command-line AI agents. It runs Codex, Claude Code, agy, GLM, or Grok as child processes and returns their output as MCP tool results. You can send one task to one agent. You can run a council of many agents on one question. You can also build a context bundle for a later task.
4
4
 
5
- - `clink` runs a configured CLI adapter (agy, Codex, Claude, Grok, or anything you add) as a subprocess and returns the output.
6
- - `context_builder` writes a persisted context bundle from allowed local roots. Selection is deterministic by default. You can also run explicit curator and finalizer adapters, then the server validates and materializes locally.
7
- - `list_workflows`, `resume_workflow`, and `run_workflow` run multi-stage workflows.
5
+ ClinkX uses MCP over STDIO. It works with any MCP client that can start a local command.
8
6
 
9
- Adapters come from config. There is no hardcoded CLI allowlist. Field-level PAL compatibility is intentional.
7
+ ## Requirements
10
8
 
11
- ## Quick start
9
+ - Node.js 24.0.0 or later.
10
+ - At least one of these command-line tools on your `PATH`: `codex`, `claude`, `agy`, or `grok`. The `glm` adapter also uses the `claude` command.
11
+ - The `codex` command, if you run workflows. Workflows use Codex to select repository context before the first stage. See [Workflows](#workflows) for the opt-out switch.
12
12
 
13
- Node.js >= 24, plus at least one CLI adapter.
13
+ ## Installation
14
14
 
15
- ```bash
16
- npm install
17
- npm run build:all
18
- node dist/index.js
19
- ```
20
-
21
- stdout is MCP JSON-RPC only (one JSON object per line). Logs go to stderr.
22
-
23
- Reviewed version bumps publish through CI after main checks pass. See
24
- [npm releases](docs/npm-releases.md) for trusted publisher setup, release policy,
25
- artifact verification, and recovery.
26
-
27
- Both STDIO servers detect parent death even when stdin never delivers EOF.
28
- Idle shutdown is separately opt-in: `CLINKX_SERVER_IDLE_TIMEOUT_SECONDS=1800`
29
- enables a 30-minute idle lifetime, while the default `0` preserves quiet
30
- sessions. Active work and response delivery prevent idle expiry. Enable it only
31
- for hosts that can reconnect; restart loses process-local session aliases and
32
- logs. See [STDIO server lifetime](docs/configuration.md#stdio-server-lifetime)
33
- for shutdown reasons and parent-wrapper limitations.
34
-
35
- ## Local workflow dashboard
36
-
37
- After `npm run build:all`:
15
+ Add ClinkX to the MCP server list of your client. The exact file and format depend on the client. This is the common JSON shape:
38
16
 
39
- ```bash
40
- node dist/dashboard-cli.js --port 0
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "clinkx": {
21
+ "command": "npx",
22
+ "args": ["-y", "clinkx@latest"],
23
+ "env": {
24
+ "CLINKX_ALLOWED_ROOTS": "/path/to/your/workspace",
25
+ "CLINKX_WORKFLOWS_WORKSPACE_ROOT": "/path/to/your/workspace"
26
+ }
27
+ }
28
+ }
29
+ }
41
30
  ```
42
31
 
43
- Passkey auth is the default. The process binds `127.0.0.1` and `::1` on the same port and prints `http://localhost:<port>`. An empty credential store also prints one enrollment code. Register a passkey with that code, then sign in as a separate step. Credentials live under `CLINKX_WORKFLOWS_DASHBOARD_CREDENTIAL_DIR` (default `${CLINKX_WORKFLOWS_STATE_DIR}/dashboard/webauthn`). Sessions die on restart.
44
-
45
- Screens: Runs, Single Calls, Context Runs, Workflows, Adapters, Artifacts. They show retained workflow state, direct-call lifecycle, standalone/refine context-builder lifecycle, persisted pre-dispatch workflow input, final outputs and errors, validated JSON artifacts, and the launch-time workflow/adapter catalogs. Runs, Single Calls, and Context Runs have their own path routes. The persisted-call inspector is an overlay that still shows up as a nested route in history.
46
-
47
- Workflow-call, activity, and context-run detail pages also have local session logs (observability only). Timeline and Conversation are chronological; order comes from the log sequence. Each lane is fenced to one immutable parent generation (run, activity, or context) plus the matching attempt, turn, or curator/finalizer execution. Pages are at most 500 events. A lane stops at 100,000 events. Events are normalized and pattern-redacted. They are not raw provider payloads, a session browser, or a live tail.
48
-
49
- Live tool arguments, sanitized argument-derived summaries, and `redaction.coverage: "pattern_best_effort"` require `CLINKX_SESSION_LOG_TOOL_ARGUMENTS_PERSISTENCE_ENABLED=true` (exact value, default off, read once per producer at creation). Disabled producers omit those additions; Claude keeps `"Tool invocation"` and Codex/agy keep legacy summaries. Deploy capable backend and browser readers first; readers always accept extended events. Rollback disables producers first and keeps capable readers until extended journals age out. Flag-off does not make existing gate-on journals old-reader-safe. Redaction hardening remains unconditional; coverage and match counts do not prove cleanliness. See [rollout configuration](docs/configuration.md#session-log-tool-arguments-rollout) and [detector scope](docs/security.md#dashboard-session-logs).
50
-
51
- The [native projection foundation](clinkx-workflows/src/dashboard/native-transcript/README.md) is unwired and persists nothing, independently of that gate. It handles JSON and text results, preserves source-file/component order, and scopes unverified synthesized identity to the affected call/result pair. Native capture, workers, storage, routes, and UI remain unfinished; #56 stays open.
32
+ Set the two paths to the directory that tool calls can reference. Use absolute paths.
52
33
 
53
- The dashboard has no SSE, filesystem watch, worker-health inference, cross-process cancellation, or run-creation form. Session logs cannot replay, approve, cancel, or otherwise control a run. Copied action objects are MCP tool handoffs, not JSON-RPC requests.
54
-
55
- Point the dashboard at the same `CLINKX_WORKFLOWS_STATE_DIR` as the workflow process or you will see a different (often empty) run set. Successful sync and async runs are kept for one day by default so you can inspect them. `CLINKX_WORKFLOWS_RETAIN_SUCCEEDED_DAYS=0` or `CLINKX_WORKFLOWS_RETAIN_ASYNC_DAYS=0` means keep that class forever, which can fill the disk.
56
-
57
- Workflow and activity session logs follow retention of that exact parent generation. Context session logs follow the parent context-run/manual lifecycle. There is no separate context-run pruner yet.
58
-
59
- Persisted inputs, outputs, errors, and artifact bytes can be sensitive. Access is loopback-only and passkey-gated. That is a shared-account boundary, not isolation from other processes as the same OS user. Redaction strips high-confidence credentials and user-home paths before write. Prompts, outputs, tool summaries, and reasoning can still be sensitive after that. Per-run state admission defaults to 16 MiB (configurable 1–64 MiB via `CLINKX_WORKFLOWS_DASHBOARD_MAX_STATE_BYTES`). Raw result/call reads use smaller fixed caps.
60
-
61
- For local Docker, `compose.dashboard-local.yml` runs the real UI + API over plain HTTP. Caddy publishes on `127.0.0.1` and `::1`. The browser uses `http://localhost:<port>`. Caddy shares the dashboard network namespace and proxies IPv4 to Node at `127.0.0.1:4180`. The same Node process also listens on `::1:4180`. See `docs/dashboard-local-compose.md`.
62
-
63
- Hosted passkey topology is one UI+API service behind Traefik on a private Docker network. See `deploy/dashboard-cloud/README.md`. The older gateway/companion and split-origin paths exist only as a temporary bearer rollback until local and live cloud passkey ceremonies pass the proof-gated cutover.
64
-
65
- To build the local CLI as one host-native executable, use an official Node 25.5+ runtime with SEA support:
34
+ To install ClinkX globally, run this command. Then set `"command": "clinkx"` with no `args`:
66
35
 
67
36
  ```bash
68
- npm run build:dashboard:standalone -- \
69
- --node-executable /absolute/path/to/official-node \
70
- --output ./artifacts/clinkx-dashboard
37
+ npm install -g clinkx
71
38
  ```
72
39
 
73
- The binary embeds the dashboard UI, bundled configuration, workflows, and templates. At runtime it still reads state, context runs, and the inspected workspace from the usual environment paths.
40
+ Restart your MCP client after you change its configuration. To control when upgrades happen, replace `clinkx@latest` with a fixed version.
74
41
 
75
- ## Configuration
76
-
77
- Adapter JSON is discovered in this order:
78
-
79
- 1. `CLINKX_CONFIG_PATH` (file or directory). This replaces the whole search path. Shipped adapters are not loaded.
80
- 2. `${XDG_CONFIG_HOME:-~/.config}/clinkx/adapters/*.json`. First-wins on `name`.
81
- 3. Packaged `conf/adapters/*.json` next to the installed package (`import.meta.url`). Not `process.cwd()`.
42
+ ## First call
82
43
 
83
- A `conf/adapters/*.json` file in the current working directory is ignored unless `CLINKX_CONFIG_PATH` points at it. Full reference: `docs/configuration.md`.
84
-
85
- Per-call model and effort are optional and require support declared by the resolved adapter:
44
+ Ask your assistant to use the `clink` tool. This is the smallest valid request:
86
45
 
87
46
  ```json
88
- {"cli_name":"codex","prompt":"Summarize the module boundaries without editing files.","model":"gpt-5.4","effort":"low"}
47
+ {
48
+ "cli_name": "codex",
49
+ "prompt": "Summarize the module boundaries in this project. Do not edit files.",
50
+ "absolute_file_paths": ["/path/to/your/workspace/src/server.ts"]
51
+ }
89
52
  ```
90
53
 
91
- Omit either field to retain that CLI setting. Unsupported overrides fail with MCP `-32602` before spawning; XDG adapter files must declare their own override support.
54
+ ClinkX starts the Codex CLI, sends the prompt and the file references, and returns the final answer. You can run many `clink` calls at the same time, up to the concurrency limit.
92
55
 
93
- Dashboard deployment controls:
56
+ ## Tools
94
57
 
95
- | Setting | Contract |
58
+ | Tool | Function |
96
59
  |---|---|
97
- | `CLINKX_WORKFLOWS_DASHBOARD_CREDENTIAL_DIR` | Optional absolute, non-root credential directory. Host default: `${CLINKX_WORKFLOWS_STATE_DIR}/dashboard/webauthn`. Compose pins the writable `/data/dashboard-credentials` volume. |
98
- | `DASHBOARD_DEPLOYMENT_SLUG` | Required Compose identity, `^[a-z][a-z0-9-]{0,31}$`. Local and cloud names keep distinct stack-kind prefixes. |
99
- | `DASHBOARD_CREDENTIAL_BOOTSTRAP_MODE` | Required Compose state assertion. First start is `bootstrap`. Flip to `existing-enrolled` right after enrollment, before restart. |
60
+ | `clink` | Runs one task on one configured CLI and returns the result. |
61
+ | `context_builder` | Selects a bounded set of files from permitted roots and writes a reusable context bundle to disk. |
62
+ | `refine_context_run` | Makes a new bundle from an earlier one. You can add, remove, promote, or demote files, or set their slices. |
63
+ | `provider_doctor` | Checks provider configuration, executables, and startup readiness. Optional explicit probes make real authentication calls. |
64
+ | `verification_run` | Runs a reviewed project-check manifest and retains private evidence with a digest for later inspection. |
65
+ | `verification_inspect` | Reassesses retained evidence using the original owner-held digest, without running project commands. |
66
+ | `workflow_verification_attach` | Re-inspects proof with the original owner-held digest and records its historical coverage on a workflow run. |
67
+ | `list_workflows` | Lists the available workflows, CLIs, and roster presets. |
68
+ | `run_workflow` | Starts a multi-stage workflow. Runs in blocking mode by default, or in the background with `async: true`. |
69
+ | `workflow_run_status` | Reports the progress and result of a workflow run. |
70
+ | `resume_workflow` | Continues a workflow run that stopped before completion. |
71
+ | `cancel_workflow` | Cancels a workflow run. |
72
+ | `progress_report_start`, `progress_report_update`, `progress_report_get`, `progress_report_list` | Keep a live progress report that the dashboard shows. |
73
+
74
+ Two more tool groups are off by default:
75
+
76
+ - `clink_agent_run` and `clink_agent_manage` control a stateful Codex app-server session with approvals. Set `CLINKX_APP_SERVER_ENABLED=true` to publish them.
77
+ - `clink_elaris_run` and `clink_elaris_manage` start remote Elaris agent sessions over HTTPS. Set `CLINKX_ELARIS_ENABLED=true` and the Elaris connection variables to publish them.
78
+
79
+ Each tool publishes its full input schema through MCP. MCP clients can show the schema with the tool description.
80
+
81
+ Readiness and project verification are available through the same npm-installed
82
+ MCP connection; no ClinkX checkout or client shell access is needed. See
83
+ [provider readiness](docs/configuration.md#provider-readiness-doctor) and
84
+ [project checks](docs/verification/project-checks.md) for tool calls, authorized
85
+ project/evidence roots, and evidence limits. Project execution v1 supports
86
+ macOS/Linux and runs trusted manifest commands with the server account's permissions.
87
+
88
+ ## Supported CLIs
89
+
90
+ An adapter file tells ClinkX how to start one CLI, how to pass the prompt, and how to read the output. These adapters are included:
91
+
92
+ | `cli_name` | Command (short form) | Notes |
93
+ |---|---|---|
94
+ | `codex` | `codex exec --json` | Default curator and finalizer for workflow context. |
95
+ | `claude` | `claude -p --output-format stream-json` | |
96
+ | `agy` | `agy --output-format stream-json` | Use an agy build that emits stream-json (1.1.8 or later). |
97
+ | `glm` | `claude -p ... --model glm-5.3[1m]` | Runs GLM through the Claude Code CLI. |
98
+ | `grok` | `grok --output-format streaming-messages-json` | |
99
+
100
+ All included adapters accept the optional `model` and `effort` fields on each call:
100
101
 
101
- Passkey challenge capacity is 96 login slots and 32 registration/add-passkey slots, with 8 concurrent verifications. Saturation returns 503 `auth_busy` and `Retry-After: 1`. Live challenges are not evicted. Local session and challenge cookie names are port-scoped. WebAuthn still uses the shared bare `localhost` RP ID.
102
+ ```json
103
+ { "cli_name": "codex", "prompt": "...", "model": "gpt-5.4", "effort": "low" }
104
+ ```
105
+
106
+ If you omit a field, ClinkX uses the adapter setting or the CLI default. If the adapter does not declare the field or the value, ClinkX returns MCP error `-32602` and does not start the process.
102
107
 
103
- On browser startup, a valid same-origin passkey status beats provisional bearer state. The only bearer fallback is the split-origin static server's exact no-store 404 `{"error":{"code":"not_found"}}`. Malformed or ambiguous status, and uncertain logout, fail closed. Bearer is the explicit tested rollback.
108
+ The `conf/adapters/hapi/` directory in the package holds optional templates that start each CLI through a `hapi` gateway. These templates are not ready to use. You must set the gateway URL and credentials in your copy.
104
109
 
105
- Dashboard shutdown closes listeners first, then auth/gateway resources. Cleanup failures are aggregated across both.
110
+ ## Configuration
106
111
 
107
- ## Council roster presets
112
+ ### Adapter files
108
113
 
109
- `run_workflow.roster` names a JSON preset instead of passing `members`, `chairman`, or `cb_delegate`. Council workflows only. Combining `roster` with any of those fields (or a non-empty `cb_delegate`) is MCP `-32602` and creates no run.
114
+ ClinkX reads adapter JSON files from these locations, in this order. ClinkX uses the first file with a given `name`.
110
115
 
111
- Discovery is first-wins by file stem, same as adapters:
116
+ 1. `CLINKX_CONFIG_PATH`, a file or a directory. When you set it, ClinkX reads only this location and does not load the included adapters. The location must also contain a `codex` adapter with a `json` role, or you must set `CLINKX_WORKFLOWS_CONTEXT_PREFLIGHT_ENABLED=false`.
117
+ 2. `${XDG_CONFIG_HOME:-~/.config}/clinkx/adapters/*.json`.
118
+ 3. The `conf/adapters/` directory inside the installed package.
112
119
 
113
- 1. `CLINKX_ROSTERS_PATH` (file or directory). Replaces the rest when set.
114
- 2. `${XDG_CONFIG_HOME:-~/.config}/clinkx/rosters/*.json`
115
- 3. Packaged `conf/rosters/*.json` on the root server only. Standalone `createWorkflowServer` loads env/user only.
120
+ To change an included adapter, copy its file to `~/.config/clinkx/adapters/` and edit the copy. The copy replaces the included file completely. ClinkX does not merge the two files. After you upgrade ClinkX, compare your copy with the new included file. Copy the new file again if necessary.
116
121
 
117
- Put a user preset at `~/.config/clinkx/rosters/<name>.json`. The file stem is the name (`^[a-z0-9][a-z0-9_-]{0,63}$`). Schema is Zod-strict `clinkx-roster-v1`; at least one of `members`, `chairman`, or `delegate` is required. Shipped `conf/rosters/default-council.json`:
122
+ To add a CLI that is not included, write a new file in the same directory. This example adapter returns the prompt unchanged:
118
123
 
119
124
  ```json
120
125
  {
121
- "schema_version": "clinkx-roster-v1",
122
- "description": "Three-member council with a Codex chairman and an enabled curator/finalizer delegate.",
123
- "members": [
124
- { "cli_name": "codex" },
125
- { "cli_name": "claude" },
126
- { "cli_name": "glm" }
127
- ],
128
- "chairman": { "cli_name": "codex" },
129
- "delegate": {
130
- "enabled": true,
131
- "curator": { "cli_name": "codex", "role": "json" },
132
- "finalizer": {
133
- "cli_name": "codex",
134
- "role": "json-codereviewer",
135
- "enabled": true,
136
- "min_score": 8.5
137
- },
138
- "failure_policy": "fail"
139
- }
126
+ "name": "echo",
127
+ "command": "node",
128
+ "args": ["-e", "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>process.stdout.write(d));"],
129
+ "parser": "text",
130
+ "prompt_mode": "stdin",
131
+ "timeout_seconds": 60
140
132
  }
141
133
  ```
142
134
 
143
- Call `run_workflow` with the preset name:
135
+ ### Environment variables
136
+
137
+ These are the variables that most installations set. Every variable has a default.
138
+
139
+ | Variable | Default | Function |
140
+ |---|---|---|
141
+ | `CLINKX_ALLOWED_ROOTS` | Current directory of the server process | Comma-separated list of directories that tool calls can reference. Set it so path checks do not depend on the directory in which the client starts ClinkX. |
142
+ | `CLINKX_WORKFLOWS_WORKSPACE_ROOT` | Current directory of the server process | Workspace for workflows. Set it to the same directory as the allowed root. |
143
+ | `CLINKX_WORKFLOWS_STATE_DIR` | `${XDG_STATE_HOME:-~/.local/state}/clinkx-workflows` | Directory for workflow runs, progress reports, and dashboard state. |
144
+ | `CLINKX_CONTEXT_BUILDER_RUNS_DIR` | `${XDG_STATE_HOME:-~/.local/state}/clinkx/context-builder/runs` | Directory for `context_builder` runs and bundles. |
145
+ | `CLINKX_CONFIG_PATH` | not set | Replaces the adapter search path. See [Adapter files](#adapter-files). |
146
+ | `CLINKX_ROSTERS_PATH` | not set | Replaces the roster-preset search path. See [Workflows](#workflows). |
147
+ | `CLINKX_MAX_CONCURRENT` | `5` | Maximum number of `clink` processes at one time. ClinkX returns an error when the limit is reached. It does not queue requests. |
148
+ | `CLINKX_TIMEOUT_SECONDS` | `600` | Default time limit for one child process. |
149
+ | `CLINKX_MAX_RESPONSE_CHARS` | `20000` | Maximum number of characters in one tool result. |
150
+ | `CLINKX_LOG_LEVEL` | `info` | Log level. Logs go to stderr. |
151
+ | `CLINKX_CONTEXT_ALLOW_SECRETS` | `true` | When `true`, `context_builder` copies secret material into bundles as written. See [Safety](#safety). |
152
+ | `CLINKX_WORKFLOWS_CONTEXT_PREFLIGHT_ENABLED` | `true` | Set to `false` to run workflows without the Codex context step. |
153
+ | `CLINKX_WORKFLOWS_RETAIN_SUCCEEDED_DAYS` | `1` | Days to keep completed blocking workflow runs on disk. `0` keeps them without limit. |
154
+ | `CLINKX_WORKFLOWS_RETAIN_ASYNC_DAYS` | `1` | Days to keep completed background workflow runs on disk. `0` keeps them without limit. |
155
+ | `CLINKX_SERVER_IDLE_TIMEOUT_SECONDS` | `0` | Seconds of inactivity after which the server exits. `0` disables the timer. Active tool calls, workflows, and Codex turns reset it. |
156
+ | `CLINKX_APP_SERVER_ENABLED` | `false` | Set to `true` to publish the Codex app-server tools. |
157
+ | `CLINKX_ELARIS_ENABLED` | `false` | Set to `true` to publish the Elaris tools. |
158
+
159
+ ClinkX writes only MCP JSON-RPC to stdout. All logs go to stderr. The server detects the exit of its parent process and stops.
160
+
161
+ ## Workflows
162
+
163
+ A workflow runs many CLI calls in stages and returns one result. A council workflow asks each member for an independent answer. The members then review each other. A chairman writes the final answer. These workflows are included:
164
+
165
+ | Workflow | Purpose |
166
+ |---|---|
167
+ | `architecture-comparison` | Compare two designs using frozen shared input and a fresh judge with candidate aliases. |
168
+ | `verified-repair` | Repair declared existing files in place, reproduce the defect, and prove the fix through native checks and independent causal verification. |
169
+ | `council-answer` | Answer one hard question. |
170
+ | `council-code-review` | Review a change set. |
171
+ | `council-debug` | Find the cause of a defect. |
172
+ | `council-discover` | Inspect a codebase or a design space. |
173
+ | `council-plan-review` | Review a plan document. |
174
+ | `council-default` | General-purpose council. |
175
+ | `plan-review-receipts` | Typed plan review that returns receipt candidates for an external approval process. |
176
+
177
+ Before the first stage, ordinary workflows run `context_builder` with Codex as curator and finalizer. This step selects the repository files that the members receive. The `codex` command must be on your `PATH`. To skip this step, set `CLINKX_WORKFLOWS_CONTEXT_PREFLIGHT_ENABLED=false`. `verified-repair` uses its host-frozen declared inputs instead of this context preflight.
178
+
179
+ Select `architecture-comparison` explicitly and provide `user_request`,
180
+ `source_identity`, and optional `context_files` in `variables`. Its built-in
181
+ templates and validators ship in the npm package. Two authors receive the same
182
+ frozen packet; the independent judge receives a separate view with candidate
183
+ aliases. The result reports comparison completeness and leaves owner acceptance
184
+ unrecorded. See [engineering recipes](docs/engineering-recipes.md) for an example,
185
+ route settings, bounds, and evidence limits.
186
+
187
+ For a bug fix, invoke the companion `verified-repair` skill in Claude Code,
188
+ Codex, or another connected MCP agent. It prepares the repair contract and
189
+ native manifests, then calls `run_workflow` with
190
+ `workflow: "verified-repair"`. The workflow needs three explicit provider routes
191
+ and separate authorized project, evidence and verification-copy locations on
192
+ the MCP host. It preserves unrelated changes and retains applied edits on
193
+ failure; qualification never records owner acceptance. See the
194
+ [paste-ready agent prompt and MCP calls](docs/engineering-recipes.md#using-verified-repair-from-an-agent-runtime)
195
+ and [minimal contract and manifests](docs/verification/project-checks.md#native-verified-repair).
196
+ The dashboard's **Verified repair** prompt-builder target prepares this caller
197
+ skill invocation for copying; it does not execute the repair or authorize host paths.
198
+
199
+ ### Roster presets
200
+
201
+ A roster preset names the members, the chairman, and the context delegate of a council in one file. Pass the preset name as `roster` in place of `members`, `chairman`, and `cb_delegate`:
144
202
 
145
203
  ```json
146
204
  {
@@ -150,106 +208,81 @@ Call `run_workflow` with the preset name:
150
208
  }
151
209
  ```
152
210
 
153
- `list_workflows` still returns `available_cli_names`. The root server also returns `available_clis` (per-adapter model/effort template support, not value validity; `app_server` excluded) and `available_rosters` (`{name, source}` with `source` `env` | `user` | `builtin`). A council run's requested seats and delegate appear as `resolved_roster` on the async ack, a trailing sync content block, and `workflow_run_status`. `provider_spawns` is `2N+1` (ranking is a reducer, not a spawn).
211
+ The included `default-council` preset uses Codex, Claude, and GLM as members and Codex as chairman. ClinkX reads these locations in this order and uses the first file with a given name:
154
212
 
155
- ## Context bundles
213
+ 1. `CLINKX_ROSTERS_PATH`, a file or a directory. When you set it, ClinkX reads only this location.
214
+ 2. `${XDG_CONFIG_HOME:-~/.config}/clinkx/rosters/*.json`.
215
+ 3. The `conf/rosters/` directory inside the installed package.
216
+
217
+ To write your own preset, copy `conf/rosters/default-council.json` to `~/.config/clinkx/rosters/<name>.json` and edit the copy. The file name is the preset name. The preset name must match `^[a-z0-9][a-z0-9_-]{0,63}$`. A request that gives `roster` together with `members`, `chairman`, `chairman_model`, `chairman_effort`, or a non-empty `cb_delegate` returns error `-32602` and starts no run.
156
218
 
157
- Use `context_builder` when a later `clink` call needs curated repo context and you do not want that source inlined in the first tool response. You must pass a bounded anchor: at least one `focus_paths` entry or a nonblank `search_terms` entry. `include_globs` only narrows the scan when those anchors exist. It does not select context by itself.
219
+ ### Background runs
158
220
 
159
- The tool writes a durable run directory (`manifest.json`, `artifacts/bundle.md`) and returns one minified JSON receipt. The receipt includes `recommended_clink.absolute_file_paths`. Pass those as `absolute_file_paths` on a later `clink` call. The handoff files are the persisted `artifacts/bundle.md` and `manifest.json`.
221
+ Pass `async: true` to `run_workflow` to get a `run_id` immediately. Call `workflow_run_status` with that `run_id` to see the stage progress. Pass `include_result: true` to get the final result. Use `cancel_workflow` to stop a run. Completed runs stay on disk for the retention period given above.
222
+
223
+ ## Context bundles
160
224
 
161
- Delegate mode needs an explicit request shape and explicit providers:
225
+ Use `context_builder` when a later call needs a selected part of the repository. Then the first tool result does not contain that content. You must give at least one anchor: a `focus_paths` entry or a non-blank `search_terms` entry.
162
226
 
163
227
  ```json
164
228
  {
165
229
  "task": "Collect context for the server tool registration",
166
- "roots": ["/path/to/workspace"],
230
+ "roots": ["/path/to/your/workspace"],
167
231
  "focus_paths": ["src/server.ts"],
168
- "delegate": {
169
- "enabled": true,
170
- "curator": {
171
- "cli_name": "<curator-cli>",
172
- "role": "<curator-role>"
173
- },
174
- "finalizer": {
175
- "cli_name": "<finalizer-cli>",
176
- "role": "<finalizer-role>",
177
- "min_score": 8.5
178
- },
179
- "failure_policy": "fallback",
180
- "timeout_seconds": 120,
181
- "max_response_chars": 20000
182
- }
232
+ "search_terms": ["ListToolsRequestSchema"]
183
233
  }
184
234
  ```
185
235
 
186
- There are no built-in curator or finalizer provider defaults. Provider output is advisory. The server checks strict JSON, rebuilds accepted content from local candidates, reapplies budgets and secret checks, and does not persist raw provider output. `failure_policy:"fallback"` publishes deterministic local selection as a partial v2 run if delegate curation fails. `failure_policy:"fail"` returns an error and does not publish a manifest.
236
+ The tool writes the bundle to the context-runs directory and returns a short JSON receipt. The receipt contains `recommended_clink.absolute_file_paths`. Pass that list as `absolute_file_paths` on the next `clink` call.
187
237
 
188
- ### Adding an adapter
238
+ By default the selection is deterministic. You can also set `delegate.enabled: true` and name a curator and a finalizer CLI. The curator makes a selection and the finalizer scores it. ClinkX checks the selection and rebuilds the bundle from local files. It applies the budgets again and writes only content that it checked itself. Provider output is an input that ClinkX checks, not a result.
189
239
 
190
- Put the JSON in `${XDG_CONFIG_HOME:-~/.config}/clinkx/adapters/`. Or set `CLINKX_CONFIG_PATH` to a directory that also contains every shipped adapter you still need. That env var replaces the search path.
240
+ ## Dashboard
191
241
 
192
- ```json
193
- {
194
- "name": "echo",
195
- "command": "node",
196
- "args": ["-e", "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>process.stdout.write(d));"],
197
- "parser": "text",
198
- "prompt_mode": "stdin",
199
- "timeout_seconds": 60
200
- }
242
+ The package includes a local, read-only web dashboard. It shows workflow runs, single calls, context runs, progress reports, the workflow catalog, the adapter catalog, and the saved artifacts. Start it with the second command that the package installs:
243
+
244
+ ```bash
245
+ npx -p clinkx clinkx-workflows-dashboard --port 4180
201
246
  ```
202
247
 
203
- ## MCP client config
248
+ The dashboard listens on `127.0.0.1` and `::1` and prints `http://localhost:<port>`. Passkey sign-in is the default. On the first start, the dashboard prints one enrollment code. Register a passkey with that code, then sign in. For local tests only, `CLINKX_WORKFLOWS_DASHBOARD_AUTH_MODE=none` disables sign-in.
204
249
 
205
- The exact shape depends on the client.
250
+ Point the dashboard at the same `CLINKX_WORKFLOWS_STATE_DIR` as the ClinkX server. If the two directories differ, the dashboard shows a different run set, often an empty one. If you set `CLINKX_CONTEXT_BUILDER_RUNS_DIR` for the server, set the same value for the dashboard.
206
251
 
207
- Via npx (recommended):
252
+ The dashboard does not start, cancel, or approve anything. The data that it shows can contain prompts, outputs, and file contents from your workspace. Access is local and needs a passkey, but any process that runs as the same OS user can read the state directory.
208
253
 
209
- ```json
210
- {
211
- "mcpServers": {
212
- "clinkx": {
213
- "command": "npx",
214
- "args": ["-y", "clinkx@latest"],
215
- "env": {
216
- "CLINKX_ALLOWED_ROOTS": "/path/to/your/workspace",
217
- "CLINKX_WORKFLOWS_WORKSPACE_ROOT": "/path/to/your/workspace"
218
- }
219
- }
220
- }
221
- }
222
- ```
254
+ ## Safety
223
255
 
224
- From a local clone:
256
+ ClinkX checks request paths and passes only a small set of environment variables to the child process. It does not sandbox the child process.
225
257
 
226
- ```json
227
- {
228
- "mcpServers": {
229
- "clinkx": {
230
- "command": "node",
231
- "args": ["/path/to/clink-mcp/dist/index.js"],
232
- "env": {
233
- "CLINKX_ALLOWED_ROOTS": "/path/to/your/workspace",
234
- "CLINKX_WORKFLOWS_WORKSPACE_ROOT": "/path/to/your/workspace"
235
- }
236
- }
237
- }
238
- }
239
- ```
258
+ **WARNING: A child process has the same permissions as the user who started ClinkX.** The included adapters start each CLI with no sandbox and with approval prompts turned off or set to accept file edits. The child process can edit and delete files in your workspace and can run commands. Give each prompt clear limits. Do not run ClinkX as root or as an administrator.
240
259
 
241
- ## Safety
260
+ **WARNING: `context_builder` copies secrets by default.** The default is `allow_secrets: true`. With this default, ClinkX copies API keys, private keys, tokens, and files such as `.env` and `id_rsa` into bundles. The CLIs that receive the bundle also receive the secrets. To make ClinkX omit or redact common secret forms, set one of these:
261
+
262
+ - `allow_secrets: false` on the `context_builder` call.
263
+ - `cb_allow_secrets: false` on the `run_workflow` call.
264
+ - `CLINKX_CONTEXT_ALLOW_SECRETS=false` in the server environment.
265
+
266
+ This filter is a best-effort check, not a security boundary.
242
267
 
243
- ClinkX validates request paths, environment variables, and argument policy. It does not sandbox the spawned process.
268
+ `CLINKX_ALLOWED_ROOTS` limits the paths that tool calls can reference. It does not limit the child process. Set it in all installations so that the limit does not depend on the start directory of the client.
244
269
 
245
- `CLINKX_ALLOWED_ROOTS` limits which file paths the tool accepts. Default is `process.cwd()`. It is required only if the MCP host starts ClinkX with cwd at `/`. Set it anyway so path admission does not depend on whatever cwd the host chose. The subprocess has the same permissions as whoever started ClinkX.
270
+ Only the `council-plan-review` and `plan-review-receipts` prompts tell the members not to edit files. This is an instruction to the model, not a mechanical control. The other workflows give no such instruction.
246
271
 
247
- Set `CLINKX_WORKFLOWS_WORKSPACE_ROOT` to the same workspace. If you omit it, workflows use `process.cwd()` and warn on stderr.
272
+ ## Documentation
248
273
 
249
- `context_builder` validates roots and blocks symlink escapes. Secret material (API keys, private keys, tokens, `.env` / `.pem` / `id_rsa` / `credentials.json`) is included as written by default (`allow_secrets:true`) so delegates can probe. Opt out with `allow_secrets:false`, `cb_allow_secrets:false`, or `CLINKX_CONTEXT_ALLOW_SECRETS=false`. Bundle artifacts are not a sandbox and not an access-control boundary.
274
+ The installed package contains these files. After `npm install clinkx`, find them in `node_modules/clinkx/`.
250
275
 
251
- See `docs/security.md`.
276
+ | File | Content |
277
+ |---|---|
278
+ | `docs/configuration.md` | Reference for adapter files, invocation overrides, and environment variables. |
279
+ | `docs/security.md` | Trust boundaries, redaction scope, and the limits of each safety control. |
280
+ | `CHANGELOG.md` | Changes, upgrade notes, and new flags for each release. |
281
+
282
+ Read the upgrade notes before you upgrade a server that has unfinished workflow runs.
252
283
 
253
284
  ## License
254
285
 
255
- Copyright (c) 2026 jim380. All rights reserved. Proprietary package (`license: UNLICENSED`). See `LICENSE`.
286
+ Copyright (c) 2026 jim380. All rights reserved.
287
+
288
+ ClinkX is free to use but not open source. You may install and run the published npm package for your own use. You may not copy, change, redistribute, or sell it. The `package.json` license field is `UNLICENSED`. See the `LICENSE` file in the package for the full text.
@@ -0,0 +1,5 @@
1
+ import type { NormalizedWorkflowDefinition } from "../definition-normalizer.js";
2
+ export declare function materializeArchitectureRoutes(definition: NormalizedWorkflowDefinition, variables: Readonly<Record<string, unknown>>, available?: readonly string[], validateOverrides?: (cli: string, knobs: {
3
+ model?: string;
4
+ effort?: string;
5
+ }) => void): NormalizedWorkflowDefinition;
@@ -0,0 +1,50 @@
1
+ import { getMaxPromptBytes } from "../config.js";
2
+ import { DEFAULT_RESERVE_BYTES } from "../prompt-budget.js";
3
+ import { ARCHITECTURE_WORKFLOW, MAX_JUDGE_BYTES, MAX_VIEW_BYTES, RouteSchema } from "./contract.js";
4
+ const ROUTE_VARIABLES = { "candidates.author_a": "candidate_a", "candidates.author_b": "candidate_b", "judge.judge": "judge" };
5
+ export function materializeArchitectureRoutes(definition, variables, available, validateOverrides) {
6
+ if (definition.name !== ARCHITECTURE_WORKFLOW)
7
+ return definition;
8
+ for (const name of ["user_request", "source_identity"]) {
9
+ const value = variables[name];
10
+ const cap = name === "user_request" ? 16 * 1024 : 2000;
11
+ if (typeof value !== "string" || value.trim() === "" || Buffer.byteLength(value, "utf8") > cap)
12
+ throw new Error(`${name} must be nonblank and at most ${cap} UTF-8 bytes`);
13
+ }
14
+ const contextFiles = variables["context_files"] ?? [];
15
+ if (!Array.isArray(contextFiles) || contextFiles.length > 32 || new Set(contextFiles).size !== contextFiles.length)
16
+ throw new Error("context_files must contain at most 32 distinct source files");
17
+ const judge = definition.stages.find((stage) => stage.id === "judge")?.calls[0];
18
+ const worstCase = MAX_VIEW_BYTES + MAX_JUDGE_BYTES + DEFAULT_RESERVE_BYTES + Buffer.byteLength(judge?.prompt ?? "", "utf8");
19
+ if (worstCase > getMaxPromptBytes())
20
+ throw new Error(`architecture worst-case judge input and response reserve (${worstCase} bytes) exceeds workflow prompt budget`);
21
+ const tokenLimit = variables["judge_prompt_token_limit"];
22
+ if (tokenLimit !== undefined && (!Number.isSafeInteger(tokenLimit) || tokenLimit < worstCase))
23
+ throw new Error(`judge_prompt_token_limit must cover the conservative byte-token upper bound ${worstCase}; shorten the contract or use a larger route`);
24
+ const materialized = {
25
+ ...definition,
26
+ stages: definition.stages.map((stage) => ({ ...stage, calls: stage.calls.map((call) => {
27
+ const prefix = ROUTE_VARIABLES[`${stage.id}.${call.id}`];
28
+ if (prefix === undefined)
29
+ return call;
30
+ const cli = variables[`${prefix}_cli`];
31
+ const model = variables[`${prefix}_model`];
32
+ const effort = variables[`${prefix}_effort`];
33
+ const route = RouteSchema.parse({ cli_name: typeof cli === "string" ? cli.trim() : cli, ...(model !== undefined ? { model } : {}), ...(effort !== undefined ? { effort } : {}) });
34
+ if (!/^[A-Za-z0-9_-]+$/.test(route.cli_name))
35
+ throw new Error(`invalid ${prefix}_cli`);
36
+ if (route.model !== undefined && !/^[^\s\u0000-][^\s\u0000]*$/.test(route.model))
37
+ throw new Error(`invalid ${prefix}_model`);
38
+ if (route.effort !== undefined && !/^[a-z0-9][a-z0-9_-]*$/.test(route.effort))
39
+ throw new Error(`invalid ${prefix}_effort`);
40
+ if (available !== undefined && !available.includes(route.cli_name))
41
+ throw new Error(`${prefix}_cli ${route.cli_name} is not an available JSON-capable route`);
42
+ validateOverrides?.(route.cli_name, { ...(route.model !== undefined ? { model: route.model } : {}), ...(route.effort !== undefined ? { effort: route.effort } : {}) });
43
+ const { model: _model, effort: _effort, ...base } = call;
44
+ return { ...base, ...route, role: "json" };
45
+ }) })),
46
+ };
47
+ const judgeCli = String(variables["judge_cli"]);
48
+ return { ...materialized, stages: materialized.stages.map((stage) => ({ ...stage, calls: stage.calls.map((call) => call.reducer === undefined ? call : { ...call, cli_name: judgeCli }) })) };
49
+ }
50
+ //# sourceMappingURL=admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission.js","sourceRoot":"","sources":["../../src/architecture-comparison/admission.ts"],"names":[],"mappings":"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"}