triss-coworker 0.43.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/ARCHITECTURE.md +5 -0
  2. package/CHANGELOG.md +128 -1
  3. package/README.md +52 -20
  4. package/bin/triss.js +20 -12
  5. package/docs/adr/2026-09-05-user-choice-and-easy-setup.md +98 -0
  6. package/docs/adr/README.md +5 -0
  7. package/docs/cli-reference.md +63 -0
  8. package/docs/configuration.md +55 -7
  9. package/docs/data-flows.md +1 -1
  10. package/docs/engines/crush.md +38 -4
  11. package/docs/engines/index.md +1 -1
  12. package/docs/engines/omp.md +8 -0
  13. package/docs/engines/opencode-go.md +1 -1
  14. package/docs/engines/opencode2.md +8 -0
  15. package/docs/getting-started.md +25 -11
  16. package/docs/mcp.md +20 -8
  17. package/docs/reliable-delegation-contract.md +16 -3
  18. package/docs/security-model.md +63 -15
  19. package/package.json +7 -4
  20. package/src/coder-credential-proxy.js +341 -5
  21. package/src/coder-engines/crush.js +96 -58
  22. package/src/coder-engines/omp.js +15 -7
  23. package/src/coder-providers.js +70 -95
  24. package/src/commands/ask.js +5 -0
  25. package/src/commands/chat.js +2 -1
  26. package/src/commands/coder.js +772 -282
  27. package/src/commands/commit-msg.js +2 -1
  28. package/src/commands/config.js +29 -429
  29. package/src/commands/init.js +26 -12
  30. package/src/commands/review.js +3 -1
  31. package/src/commands/status.js +48 -8
  32. package/src/commands/write.js +2 -1
  33. package/src/integrations/_contract.js +2 -1
  34. package/src/mcp/handlers.js +26 -7
  35. package/src/mcp/server.js +9 -1
  36. package/src/mcp/tools.js +2 -2
  37. package/src/migration/migrate.js +30 -0
  38. package/src/model-engine-adapters.js +26 -1
  39. package/src/model-projection-policy.js +37 -16
  40. package/src/model-runtime.js +18 -1
  41. package/src/model-selection.js +46 -3
  42. package/src/provider-config.js +6 -0
  43. package/src/provider-model-transport.js +290 -0
  44. package/src/provider-registry.js +6 -0
  45. package/src/secrets.js +205 -2
  46. package/src/setup/configuration.js +1052 -0
  47. package/src/setup/engines.js +637 -0
  48. package/src/setup/plan.js +589 -0
  49. package/src/setup/readiness.js +102 -0
  50. package/src/setup/wizard.js +1112 -0
  51. package/src/transport-registry.js +8 -1
  52. package/src/transports/openai-chat.js +2 -1
  53. package/src/transports/openai-responses.js +14 -1
  54. package/templates/claude-full.md +12 -9
  55. package/templates/claude.md +4 -4
  56. package/templates/codex-full.md +8 -5
  57. package/templates/codex.md +5 -5
package/ARCHITECTURE.md CHANGED
@@ -36,3 +36,8 @@ behavior change. Priority candidates are coder orchestration, model management,
36
36
  updater installation, MCP installation, and MCP handlers.
37
37
 
38
38
  Architecture decisions that change trust boundaries belong in `docs/adr/`.
39
+
40
+ The accepted owner decision on
41
+ [user choice, best-effort execution, and easy setup](docs/adr/2026-09-05-user-choice-and-easy-setup.md)
42
+ governs provider/engine availability and wizard design. Existing runtime gates
43
+ are not product requirements when they conflict with that decision.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,133 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - All execution engines now run non-coder model projections (`ask`, `review`,
13
+ `chat`, `write`, `commit-msg`): `opencode` keeps its verified read-only
14
+ projection; `opencode2`, `omp`, and `crush` execute best-effort and attach a
15
+ warning naming the concrete limitation that is not verified, instead of
16
+ rejecting the run before launch.
17
+ - `triss config wizard` now opens the Easy path directly (provider + key,
18
+ assistant hosts, summary, first command) and preserves existing explicit
19
+ choices on rerun. `--advanced` exposes the full sections; an optional target
20
+ argument accepts a canonical provider id, `coder`, or an integration name;
21
+ `--yes`, `--agent`, and `--install` support headless apply; `triss init
22
+ --setup` delegates to the same wizard after writing agent rules.
23
+ - New persisted fields: `TRISS_CODER_PROVIDER`, `TRISS_DEFAULT_EFFORT`,
24
+ `TRISS_CODER_EFFORT`, `TRISS_PROTECT_CREDENTIALS`, and
25
+ `TRISS_CODER_PROTECT_CREDENTIALS` (credential protection is a tri-state:
26
+ absent, true, or false — the string `"false"` is never a truthy opt-in) and
27
+ `TRISS_MODEL_TRANSPORTS` (exact-model direct transport override map).
28
+ - The `direct` engine now serves `opencode-zen` and `opencode-go` models
29
+ through audited per-model transports (OpenAI Chat, OpenAI Responses,
30
+ Anthropic Messages); a model without resolvable direct metadata fails with
31
+ the stable `TRISS_DIRECT_ENGINE_REQUIRED` code and an actionable
32
+ `TRISS_MODEL_TRANSPORTS` remedy instead of a generic registry error.
33
+ - `--protect-credentials` / `--no-protect-credentials` on model-backed
34
+ commands: the former requests the parent-owned proxy and falls back to a
35
+ warned best-effort raw run when a protected route is unavailable; the latter
36
+ overrides a persisted protection choice for one run. MCP forwards
37
+ `protect_credentials` as the same tri-state.
38
+
39
+ ### Changed
40
+
41
+ - Crush is provider-neutral: any canonical provider projects onto a run-scoped
42
+ config with `$ENV` credential references. Protected mode remains the crush
43
+ default; an explicit `--no-protect-credentials` runs crush raw through the
44
+ same run-scoped config as a disclosed best-effort choice. Responses-protocol
45
+ models ride a bounded chat→responses bridge in the credential proxy
46
+ (message-only; tool rounds are refused with a precise error).
47
+ - `triss ask`, `triss review`, and other model-backed commands no longer
48
+ require engine-specific provider restrictions: provider and engine are
49
+ independent choices, honored as selected with truthful warnings for
50
+ best-effort routes.
51
+ - The setup wizard no longer resets an existing provider/engine selection or
52
+ installs a Claude MCP server implicitly; Easy and Advanced share one setup
53
+ and resolution path.
54
+
55
+ ## [0.44.0] — 2026-09-08
56
+
57
+ ### Added
58
+
59
+ - `triss config wizard` opens the Easy path directly: pick any canonical
60
+ provider, paste its key, choose which assistant host to connect (Claude
61
+ Code, Codex, both, or skip host wiring), review the summary before apply,
62
+ and finish with a first command to try. Reruns reuse the existing
63
+ configuration instead of resetting it.
64
+ - `triss config wizard --advanced` exposes the full tuning sections —
65
+ providers, execution (engine, effort, tri-state credential protection),
66
+ connections (MCP and agent rules selectable independently), integrations
67
+ (keep/unset with effective-source display), runtime (including pricing),
68
+ and in-place engine version pins.
69
+ - Targeted wizard setups configure one piece:
70
+ `triss config wizard <provider-id>`, `triss config wizard coder` (with
71
+ `--coder-provider`, `--coder-engine`, `--coder-protect-credentials`), or an
72
+ integration name.
73
+ - Headless apply: `triss config wizard --yes --agent none [--install]`
74
+ assembles a complete configuration from existing files, the environment,
75
+ and explicit flags; missing requirements exit non-zero before writing.
76
+ `triss init --setup` delegates to the same wizard after writing agent
77
+ rules.
78
+ - Every execution engine now serves every canonical provider: crush runs any
79
+ provider through a run-scoped config with `$ENV` credential references
80
+ (provider block seeded before `crush models use`), and opencode2, omp, and
81
+ crush execute non-coder projections (`ask`, `review`, `chat`, `write`,
82
+ `commit-msg`) best-effort with structured warnings naming the unverified
83
+ limitation.
84
+ - `--protect-credentials` / `--no-protect-credentials` on model-backed
85
+ commands; MCP forwards `protect_credentials` as the same tri-state and
86
+ carries credential mode and disclosures in the run envelope.
87
+ - `TRISS_CODER_EFFORT` and `TRISS_DEFAULT_EFFORT` knobs, honored by every
88
+ engine (crush discloses when a provider declares no effort support).
89
+
90
+ ### Changed
91
+
92
+ - Credential protection is a verbatim tri-state (absent/true/false) across
93
+ the CLI, MCP, and persisted configuration: `TRISS_PROTECT_CREDENTIALS` and
94
+ `TRISS_CODER_PROTECT_CREDENTIALS` persist explicit choices, and an explicit
95
+ false overrides a persisted true.
96
+ - The setup wizard no longer resets an existing provider/engine selection or
97
+ installs a Claude MCP server implicitly; Easy and Advanced share one setup
98
+ and resolution path, integrations gate readiness only when selected, and
99
+ readiness is re-derived from post-apply state.
100
+ - Engine installers run with a minimal environment allowlist (provider and
101
+ integration tokens never reach npm lifecycle scripts or downloaded
102
+ installers), curl|sh installers run as two argv spawns instead of a shell
103
+ string, and the exact install command is shown before Apply.
104
+ - Env-file writes are atomic (0600 temp file + rename after the CAS check);
105
+ host-plan status is tracked per concrete target; `config set` validates
106
+ provider and engine values; `triss status` reads `TRISS_CODER_ENGINE`
107
+ through the layered setup state.
108
+ - Migration gates the wizard on a `blocked` preflight state instead of
109
+ writing schema-2 over a conflict.
110
+
111
+ ### Fixed
112
+
113
+ - A debug path in the wizard's readiness diagnostics could print full
114
+ credentials to stderr; it is removed and privacy tests now guard the
115
+ route, the preserved value, and both former exposure points.
116
+ - MCP `protect_credentials: false` was indistinguishable from absent and
117
+ could not override a persisted true.
118
+ - OMP runs discarded usage/cost records; the coder transport protocol now
119
+ resolves from the same captured snapshot as the model, and child stderr
120
+ echoed in errors is masked.
121
+ - `triss init --setup` works in non-TTY shells (`--yes` registered).
122
+ - Root-endpoint provider URLs no longer gain a silent `/v1` in protected
123
+ runs; unverified cleanup no longer fails closed on a recycled pgid.
124
+
125
+
126
+ ### Artifact integrity (0.44.0)
127
+
128
+ - `triss-dsh-provider-bundle-0.44.0.tgz` — sha256
129
+ `c2e8ce70bb5964cdbcc16a42c574b6f85c142c36d905d066e042c0150f50b935`
130
+ — `sha512-l8rIL6i7vgukA7efR8Q2PvG8YBnAVRdnlWL338FgZmNt9r+/Efz8OgujnkFb39KLK1qe/sdHY+HntvcLZ9GrQw==`
131
+ (computed with npm pack; the output is byte-deterministic).
132
+ - Root `triss-coworker-0.44.0.tgz` sha256 is reproducible via `npm pack` at
133
+ tag `v0.44.0`; the root tarball ships `CHANGELOG.md`, so its hash cannot be
134
+ recorded inside this file. Registry verification compares the packed
135
+ artifact with the published tarball byte-for-byte.
136
+
10
137
  ## [0.43.0] — 2026-09-05
11
138
 
12
139
  ### Changed
@@ -39,7 +166,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
39
166
  effort, but help prose is not a compatibility gate. Capability errors now
40
167
  name missing options separately from below-minimum versions. Pre-suffixed
41
168
  public/configured OpenCode 2 models are rejected before engine side effects.
42
- - Added `TRISS_DEFAULT_ENGINE` so model-backed commands can persist a direct or verified OpenCode route. OpenCode projections install and verify an active primary agent pinned as `default_agent`; its deny-by-default context-only policy provides no ambient file, delegation, skill, or executable tools, and the final merged agent state is audited before credentials are forwarded. Engine warnings remain structured across MCP model tools, explicit credential protection is available, and unverified OpenCode 2, OMP, and Crush projections are rejected before launch.
169
+ - Added `TRISS_DEFAULT_ENGINE` so model-backed commands can persist a direct or verified OpenCode route. OpenCode projections install and verify an active primary agent pinned as `default_agent`; its deny-by-default context-only policy provides no ambient file, delegation, skill, or executable tools, and the final merged agent state is audited before credentials are forwarded. Engine warnings remain structured across MCP model tools, and explicit credential protection is available on every engine.
43
170
  - `triss_coder_run` retains the documented `protectCredentials` MCP spelling
44
171
  as a deprecated compatibility alias. It is OR-merged with
45
172
  `protect_credentials`, so either truthy spelling selects protected
package/README.md CHANGED
@@ -39,9 +39,30 @@ Delegation can reduce primary-agent context and inference costs, but savings dep
39
39
  npm install -g triss-coworker
40
40
  ```
41
41
 
42
- **Claude Code or Codex:** run `triss config wizard --standard`. The current Standard path configures the `openai-compatible` API key, main model, and small model, then asks whether to connect Claude Code, Codex, or both. It installs MCP and agent rules for your selection; this version has no Skip option in Standard. Use `triss config wizard --advanced` for another provider or granular setup.
42
+ `triss config wizard` opens the Easy path directly: pick a provider, paste its
43
+ key, choose the assistant hosts to register, and run your first command. It
44
+ reuses existing configuration instead of resetting it. `--advanced` exposes the
45
+ full sections (providers, execution, connections, integrations, runtime), and a
46
+ target argument (`triss config wizard opencode-go`, `triss config wizard coder`,
47
+ `triss config wizard jira`) sets up just that piece. Non-interactive shells add
48
+ `--yes` to apply a complete configuration assembled from existing files, the
49
+ environment, and explicit flags:
43
50
 
44
- **Terminal only:** configure the same profile without installing host integration. Omit values to enter them interactively; secret input is masked:
51
+ ```bash
52
+ triss config wizard --yes --agent none
53
+ ```
54
+
55
+ Connect Claude Code, Codex, or both:
56
+
57
+ ```bash
58
+ triss init --target claude --global --setup # writes rules, then runs the wizard
59
+ triss init --target codex --global
60
+ triss mcp install --target claude --global
61
+ triss mcp install --target codex --global
62
+ ```
63
+
64
+ **Terminal only:** configure the same profile without installing host
65
+ integration. Omit values to enter them interactively; secret input is masked:
45
66
 
46
67
  ```bash
47
68
  triss config set -g TRISS_OPENAI_COMPATIBLE_API_KEY
@@ -102,12 +123,12 @@ Every provider has an endpoint, credential, `model` role, and `smallModel` role.
102
123
  4. global `~/.config/triss/.env`;
103
124
  5. registry defaults.
104
125
 
105
- `TRISS_DEFAULT_PROVIDER` selects the provider when a request omits one; `TRISS_DEFAULT_ENGINE` selects `direct`, `opencode`, `opencode2`, `omp`, or `crush` when it omits an engine. Direct CLI and MCP commands accept a native model id. Coder model options use `<provider>/<model-id>`. Read-only non-coder projection is currently verified only for `opencode`; `opencode2`, `omp`, and `crush` fail before launch instead of running a write-capable agent.
126
+ `TRISS_DEFAULT_PROVIDER` selects the provider when a request omits one; `TRISS_DEFAULT_ENGINE` selects `direct`, `opencode`, `opencode2`, `omp`, or `crush` when it omits an engine. Direct CLI and MCP commands accept a native model id. Coder model options use `<provider>/<model-id>`. Every engine can execute non-coder model projections (`ask`, `review`, `chat`, …); what differs per engine is the available protection, not permission to run. `opencode` and `direct` have a verified read-only projection; `opencode2` runs the same deny-everything projection agent through its run-scoped config surface, `omp` uses its run-private policy overlay, and `crush` runs single-agent with the restrict allowlist. Engines without a verified projection report their concrete limitation as a warning on the result — never as a refusal.
106
127
 
107
128
  Shared reasoning effort values:
108
129
 
109
130
  ```text
110
- minimal | low | medium | high | max
131
+ low | medium | high | xhigh | max
111
132
  ```
112
133
 
113
134
  Examples:
@@ -127,8 +148,11 @@ Omit `--model` to use the command's provider role. There are no public model pre
127
148
  ## Configuration
128
149
 
129
150
  ```bash
130
- triss config wizard
131
- triss config wizard --local
151
+ triss config wizard # Easy setup (provider + key + hosts)
152
+ triss config wizard --advanced # full sections
153
+ triss config wizard opencode-go # targeted provider setup
154
+ triss config wizard coder --coder-engine omp --coder-provider moonshot
155
+ triss config wizard coder --coder-protect-credentials # persist TRISS_CODER_PROTECT_CREDENTIALS=true (proxy mode instead of default best-effort raw)
132
156
  triss config set TRISS_DEFAULT_PROVIDER zai
133
157
  triss config set TRISS_DEFAULT_ENGINE direct
134
158
  triss config get TRISS_ZAI_MODEL
@@ -152,16 +176,24 @@ triss ask --paths 'src/**/*.js' --question "Find correctness defects"
152
176
  triss review
153
177
  ```
154
178
 
155
- Explicit request flags still win. OpenCode-backed non-coder calls install and
156
- verify a run-scoped active primary `triss-readonly-projection` agent and pin
157
- `default_agent` to it before forwarding the selected credential. Its permission
158
- contract denies every tool by default because the complete request context is
159
- already supplied in the prompt; it never gains ambient file, shell, edit,
160
- skill, or delegation access. The process still runs as the current OS user and
161
- is not a filesystem sandbox. Add `--protect-credentials` to a model command
162
- when the selected credential can be kept behind the parent-owned proxy;
163
- raw-mode warnings are preserved in MCP structured results for every
164
- model-backed tool.
179
+ Explicit request flags still win. Engine-backed non-coder calls receive the
180
+ complete request context in the prompt. OpenCode installs and verifies a
181
+ run-scoped active primary `triss-readonly-projection` agent pinned as
182
+ `default_agent`; its permission contract denies every tool by default, so it
183
+ never gains ambient file, shell, edit, skill, or delegation access. The other
184
+ engines apply their best-effort equivalents (run-scoped config surface,
185
+ run-private policy overlay, or the restrict allowlist) and attach a warning
186
+ that names exactly what is not verified. The process still runs as the current
187
+ OS user and is not a filesystem sandbox. Add `--protect-credentials` to a model
188
+ command when the selected credential can be kept behind the parent-owned proxy
189
+ (it falls back to a best-effort raw run with a warning when a protected route
190
+ is unavailable); `--no-protect-credentials` overrides a persisted
191
+ `TRISS_PROTECT_CREDENTIALS=true` choice for one run. For coder runs configured
192
+ through the wizard, `--coder-protect-credentials` / `--coder-no-protect-credentials`
193
+ persist `TRISS_CODER_PROTECT_CREDENTIALS=true` / `=false` (cannot be combined);
194
+ the coder-specific value takes precedence over the shared
195
+ `TRISS_PROTECT_CREDENTIALS`. Raw-mode and engine
196
+ warnings are preserved in MCP structured results for every model-backed tool.
165
197
 
166
198
  Provider fields:
167
199
 
@@ -206,7 +238,7 @@ Supported engines:
206
238
 
207
239
  - `opencode` — default OpenCode engine
208
240
  - `opencode2` — OpenCode 2 beta, current-or-newer compatibility
209
- - `crush` — Z.A.I-only engine
241
+ - `crush` — provider-neutral single-envelope engine (any canonical provider)
210
242
  - `omp` — native Oh My Pi adapter
211
243
 
212
244
  OpenCode 2 has a supported floor of `0.0.0-beta-19059` and accepts every newer
@@ -219,8 +251,8 @@ Setup examples:
219
251
  ```bash
220
252
  triss coder init --engine opencode --provider openai-compatible
221
253
  triss coder init --engine opencode2 --provider opencode-zen
222
- triss coder init --engine crush --provider zai
223
- triss coder init --engine omp --provider opencode-go
254
+ triss coder init --engine crush --provider opencode-go
255
+ triss coder init --engine omp --provider moonshot
224
256
  ```
225
257
 
226
258
  Run examples:
@@ -237,7 +269,7 @@ triss coder run --isolate --session auth-fix \
237
269
  "Fix the authentication bug and run focused checks"
238
270
  ```
239
271
 
240
- Each run forwards only the selected provider credential. Protected routes use parent-owned loopback credential mediation and fail closed when an engine projection or endpoint cannot be audited. `--isolate` uses `.triss/wt/<slug>` for a reviewable worktree.
272
+ Each run forwards only the selected provider credential. Protected routes use parent-owned loopback credential mediation and fail closed when a protected route cannot actually contain the real key; an explicit `--no-protect-credentials` runs crush raw through the same run-scoped config with the selected credential (best-effort, warned). `--isolate` uses `.triss/wt/<slug>` for a reviewable worktree.
241
273
 
242
274
  The `opencode` V1 engine preserves native OpenCode routing for Zen and Go. In
243
275
  protected mode, only `User-Agent` plus session, request, and client identity
package/bin/triss.js CHANGED
@@ -107,21 +107,23 @@ function addModelSelectionOptions(command) {
107
107
  .option('-m, --model <id>', 'provider-qualified model id, or a bare id with --provider')
108
108
  .option('--engine <id>', 'execution engine (direct, opencode, opencode2, omp, or crush)')
109
109
  .option('--protect-credentials', MODEL_PROTECT_HELP)
110
+ .option('--no-protect-credentials', 'override a persisted TRISS_PROTECT_CREDENTIALS=true choice for this run')
110
111
  .option('-e, --effort <level>', 'reasoning effort: low, medium, high, xhigh, or max', parseEffort);
111
112
  }
112
113
 
113
114
  // Shared help text for model-backed credential protection.
114
115
  const MODEL_PROTECT_HELP =
115
- 'Use the parent-owned credential proxy for the OpenCode model projection.\n' +
116
- 'Fails closed when protected credential isolation cannot be enforced.\n' +
117
- 'OpenCode2, OMP, and Crush are rejected for model-backed commands.';
116
+ 'Use the parent-owned credential proxy for the model projection.\n' +
117
+ 'Falls back to a best-effort raw run with a warning when a verified\n' +
118
+ 'protected route is unavailable for the selected engine.';
118
119
 
119
120
  // Shared help text for the credential-mode flag (`coder init` and `coder run`;
120
121
  // `triss exec --code` forwards it under its own shorter description).
121
122
  const PROTECT_HELP =
122
- 'Use the parent-owned credential proxy and strict executable-surface gates.\n' +
123
- 'Fails closed when protected credential isolation cannot be enforced.\n' +
124
- 'OpenCode, OpenCode2, and OMP support this option; Crush is always protected.';
123
+ 'Use the parent-owned credential proxy and strict executable-surface gates\n' +
124
+ 'where the selected engine supports them; otherwise run best-effort with a\n' +
125
+ 'warning. An explicit --no-protect-credentials overrides a persisted\n' +
126
+ 'TRISS_*_PROTECT_CREDENTIALS=true choice for this run.';
125
127
 
126
128
  const program = new Command();
127
129
  program
@@ -149,6 +151,7 @@ program
149
151
  .option('-t, --target <agent>', 'target agent (claude | codex | both); omit for an interactive prompt')
150
152
  .option('-f, --force', 'force-replace an existing triss block without diffing')
151
153
  .option('-s, --setup', 'after writing CLAUDE.md, run `triss config wizard` to fill in credentials')
154
+ .option('--yes', 'with --setup: non-interactive apply of a complete headless configuration (required outside a TTY)')
152
155
  .action(wrap(runInit));
153
156
 
154
157
  addModelSelectionOptions(
@@ -240,6 +243,7 @@ program
240
243
  .option('--no-isolate', 'disable coder isolation')
241
244
  .option('--allow-best-effort-caller-worktree', 'forward coder isolation downgrade')
242
245
  .option('--protect-credentials', 'forward protected credential mode for model-backed and coder routes')
246
+ .option('--no-protect-credentials', 'override a persisted TRISS_PROTECT_CREDENTIALS=true choice for this run')
243
247
  .option('--restrict', 'forward coder restriction')
244
248
  .option('--no-restrict', 'disable coder restriction')
245
249
  .option('--cwd <path>', 'forward coder working directory')
@@ -329,15 +333,19 @@ const config = program
329
333
 
330
334
  config
331
335
  .command('wizard [target]')
332
- .description('Interactive setup. Optional target: deepseek | jira | linear | …')
336
+ .description('Interactive setup (Easy by default, Advanced by choice). Optional target: a canonical provider id, coder, or an integration name (jira | linear | …)')
333
337
  .option('-g, --global', 'save to ~/.config/triss/.env (default if not asked)')
334
338
  .option('-l, --local', 'save to ./.triss.env (project-local override)')
335
- .option('-f, --force', 're-prompt for keys that are already set')
336
- .option('--standard', 'API key + one model only — skip the standard/advanced prompt')
337
- .option('--advanced', 'full wizard with presets, base URL, integrations — skip the prompt')
339
+ .option('-f, --force', 're-prompt for values that are already set')
340
+ .option('--standard', 'explicit Easy path (same as the default interactive flow)')
341
+ .option('--advanced', 'full Advanced wizard — providers, execution, connections, integrations, runtime')
342
+ .option('--yes', 'non-interactive apply of a complete configuration assembled from existing files, the environment, and explicit flags')
343
+ .option('--agent <agent>', 'headless host intent: claude | codex | both | none (non-TTY default: none)')
344
+ .option('--install', 'allow installing missing engines in a headless run (without it, missing dependencies are reported)')
338
345
  .option('--coder-engine <name>', 'coder target only: coding engine to configure (opencode default, opencode2 beta, crush, or omp — see docs/engines/omp.md). `coder init` uses --engine')
339
346
  .option('--coder-provider <name>', 'coder target only: canonical provider id. `coder init` uses --provider')
340
347
  .option('--coder-protect-credentials', 'coder target only: configure the parent-owned credential proxy mode instead of the default best_effort_raw. `coder init` uses --protect-credentials')
348
+ .option('--coder-no-protect-credentials', 'coder target only: persist/forward an explicit unprotected choice that overrides TRISS_PROTECT_CREDENTIALS=true')
341
349
  .action(wrap(runWizard));
342
350
 
343
351
  config
@@ -393,9 +401,8 @@ coder
393
401
  .option('-l, --local', 'save to the project scope (./.triss.env, ./opencode.json)')
394
402
  .option('--engine <name>', 'coding engine to configure: opencode (default), opencode2 (beta — shares the opencode.json config; see docs/engines/opencode2.md), crush, or omp (see docs/engines/omp.md)')
395
403
  .option('--provider <name>', 'canonical model provider id')
396
- .option('--allow-unverified', 'requires explicit --provider opencode-go: allow the built-in fallback only after a temporary network or HTTP 408/429/500/502/503/504 catalogue failure (never bypasses 401/403, empty, or invalid responses)')
397
- .option('--allow-unsafe-bash', 'proceed even if an existing opencode.json has no deny-first bash policy (the agent runs with --auto)')
398
404
  .option('--protect-credentials', PROTECT_HELP)
405
+ .option('--no-protect-credentials', 'override a persisted TRISS_PROTECT_CREDENTIALS=true choice for this setup/run')
399
406
  .action(wrap(runCoderInit));
400
407
 
401
408
  coder
@@ -416,6 +423,7 @@ coder
416
423
  .option('--timeout <sec>', 'kill the engine after this many seconds', parsePositiveNumber, 900)
417
424
  .option('--allow-best-effort-caller-worktree', 'allow downgrade to caller worktree when isolated isolation cannot be enforced (default off — fails before spawn without it)')
418
425
  .option('--protect-credentials', PROTECT_HELP)
426
+ .option('--no-protect-credentials', 'override a persisted TRISS_PROTECT_CREDENTIALS=true choice for this run')
419
427
  .option('--stdin', 'read the prompt from piped stdin instead of the [prompt] argument')
420
428
  .option('--json', 'no-op — the envelope is always JSON; kept for symmetry with other commands')
421
429
  .action((prompt, opts) => wrap(runCoderRun)(prompt, opts));
@@ -0,0 +1,98 @@
1
+ # User choice, best-effort execution, and easy setup
2
+
3
+ - Status: Accepted; binding owner decision.
4
+ - Date: 2026-09-05.
5
+ - Scope: CLI, MCP, provider runtime, coding engines, config wizard, tests, and documentation.
6
+
7
+ ## Context
8
+
9
+ Triss has a shared provider runtime, but some execution paths reject engines
10
+ because a verified read-only projection or isolation guarantee is unavailable.
11
+ The wizard redesign initially treated those existing gates as product requirements
12
+ and proposed a large first-run settings menu. The owner explicitly rejected both.
13
+ Existing implementation restrictions are not evidence that users should lose a
14
+ choice. Ordinary users should be able to install Triss and start using it without
15
+ understanding its internal architecture.
16
+
17
+ ## Decision
18
+
19
+ ### Users choose providers, models, and engines
20
+
21
+ - All Triss providers and execution engines must be available for coding and
22
+ non-coding tasks. Do not create task-specific allowlists merely because a
23
+ route lacks a verified read-only projection or complete safety guarantees.
24
+ - Provider and engine are separate choices. Implement the adapters and transport
25
+ mappings needed to support those choices; a missing adapter is implementation
26
+ work, not a permanent product prohibition.
27
+ - Do not silently substitute a different provider, model, or engine. Recommended
28
+ defaults help users start; they do not remove alternatives or override an
29
+ existing selection.
30
+ - Distinguish actual inability to execute from incomplete safety guarantees.
31
+ Missing credentials, an unavailable executable, or an API that cannot perform
32
+ the requested operation must be reported accurately with an actionable remedy.
33
+ Do not invent support, fabricate success, or label a policy preference as a
34
+ technical impossibility.
35
+
36
+ ### Incomplete guarantees mean best effort and disclosure, not a ban
37
+
38
+ - When execution is possible but full safety or isolation cannot be guaranteed,
39
+ use the available best-effort path and explain the concrete limitation. The
40
+ user decides whether to use it; do not impose a blanket prohibition.
41
+ - Keep working protections enabled. Best effort is not a reason to discard
42
+ protections that are available or to expose unrelated credentials.
43
+ - Warnings must identify what is not guaranteed and its practical consequence,
44
+ without claiming verified isolation or read-only enforcement that is absent.
45
+ Keep them concise and actionable; expose them in CLI output and structured
46
+ MCP results, not only in hidden logs.
47
+ - Honor explicit user choices about execution and protection. Never silently
48
+ downgrade a guarantee the user specifically required. Offer the best-effort
49
+ alternative with its limitations instead of choosing on the user's behalf.
50
+ - Do not introduce extra mandatory confirmation loops or an opt-in flag solely
51
+ because a route is best effort. Surface the limitation without turning normal
52
+ setup into a sequence of alarming security prompts.
53
+ - This decision supersedes older documentation and tests that require rejecting
54
+ a provider or engine solely for incomplete safety guarantees. It does not
55
+ authorize secret disclosure, disregard of user intent, or unrelated removal
56
+ of input validation and release-integrity checks.
57
+
58
+ ### Easy by default; Advanced by choice
59
+
60
+ - The default wizard path is Easy: minimal choices, sensible recommendations,
61
+ reuse of existing configuration, and a direct path to the first usable setup.
62
+ - Do not open first-run setup with a large settings dashboard, an exhaustive
63
+ provider/engine matrix, or a list of environment variables.
64
+ - Ask only for information needed to complete the user's selected setup. Infer
65
+ what can be established reliably; do not require users to understand model
66
+ roles, execution projections, endpoints, or isolation internals just to start.
67
+ - Offer Advanced as an optional path for complete supported configuration,
68
+ including providers, models, engines, scopes, integrations, and operational
69
+ settings. Users can enter it immediately or revisit it after Easy setup.
70
+ - Easy and Advanced must share resolution, setup, persistence, and verification
71
+ logic. They differ in the detail exposed, not in correctness or user choice.
72
+ - Explain consequential actions and concrete execution limitations briefly when
73
+ relevant. Keep technical detail available without overwhelming the main flow.
74
+ - Re-running Easy must preserve explicit existing choices unless the user asks
75
+ to change them. Report incomplete setup honestly rather than printing a
76
+ misleading success message.
77
+
78
+ ## Consequences and implementation status
79
+
80
+ This is the required direction for implementation and review, not a claim that
81
+ all routes already work. At acceptance, non-coder projections still reject
82
+ OpenCode 2, OMP, and Crush; registry providers lack a direct transport; and the
83
+ wizard retains its existing Standard/Advanced behavior. Those limitations must
84
+ be addressed as implementation gaps, not carried forward as product policy.
85
+ This documentation change does not itself remove runtime gates.
86
+
87
+ Changes must be judged against user-observable behavior: selected routes are
88
+ honored, executable best-effort paths remain available with truthful warnings,
89
+ and Easy reaches a usable setup without an administration menu. Tests that
90
+ encode arbitrary bans must change with the implementation, not preserve the bans.
91
+
92
+ ## Alternatives rejected
93
+
94
+ - Treating current engine allowlists as immutable security requirements.
95
+ - Blocking executable routes until every safety property can be verified.
96
+ - Hiding unsupported guarantees behind a silent fallback or a false success.
97
+ - Making a comprehensive settings dashboard the default first-run experience.
98
+ - Maintaining separate setup implementations for Easy and Advanced.
@@ -0,0 +1,5 @@
1
+ # Architecture decision records
2
+
3
+ Record decisions that change public contracts, trust boundaries, persistence,
4
+ or release architecture. Each ADR should state context, decision,
5
+ consequences, alternatives, and status.
@@ -8,3 +8,66 @@ integrations, configuration, usage accounting, and updates.
8
8
  Machine consumers should prefer documented JSON modes and treat their schema
9
9
  version as part of the contract. Human-readable output may evolve without a
10
10
  schema migration.
11
+
12
+ ## `triss config wizard`
13
+
14
+ Interactive setup, Easy by default; Advanced is an explicit choice. Both paths
15
+ share the same resolution, persistence, and verification logic.
16
+
17
+ ```bash
18
+ triss config wizard # Easy: provider + key, assistant hosts, summary, first command
19
+ triss config wizard --advanced # full sections: providers, execution, connections, integrations, runtime
20
+ triss config wizard --standard # explicit Easy path (alias of the default interactive flow)
21
+ triss config wizard <target> # a canonical provider id, `coder`, or an integration name (jira | linear | …)
22
+ triss config wizard --local|--global # project ./.triss.env or global ~/.config/triss/.env
23
+ triss config wizard --yes # non-interactive apply of a complete configuration from files + env + flags
24
+ triss config wizard --agent <agent> # headless host intent: claude | codex | both | none (non-TTY default: none)
25
+ triss config wizard --install # allow installing missing engines in a headless run
26
+ triss config wizard coder --coder-protect-credentials # persist TRISS_CODER_PROTECT_CREDENTIALS=true: proxy mode instead of the default best-effort raw
27
+ triss config wizard coder --coder-no-protect-credentials # persist TRISS_CODER_PROTECT_CREDENTIALS=false: explicit raw; overrides TRISS_PROTECT_CREDENTIALS=true
28
+ ```
29
+
30
+ Headless notes: `--yes` never turns a missing required key into a fake
31
+ success — required keys are validated before anything is written, so a run
32
+ that is incomplete at that point exits non-zero without writing. A run can
33
+ still end incomplete after writing: engine setup runs after the env file and
34
+ host configuration have been applied, so a skipped (no `--install`) or failed
35
+ engine install is reported on top of the already-written configuration, and
36
+ the run exits non-zero with that configuration preserved for a rerun. Engines
37
+ are installed in a headless run only with `--install`; otherwise missing
38
+ dependencies are reported. Reruns preserve existing explicit choices instead
39
+ of resetting them. The wizard's coder-target flags are `--coder-engine <name>`,
40
+ `--coder-provider <name>`, `--coder-protect-credentials`, and
41
+ `--coder-no-protect-credentials` (the last two cannot be combined).
42
+
43
+ ## `triss init --setup`
44
+
45
+ `triss init` writes the delegation block into agent rule files. With
46
+ `-s, --setup` it hands control to `triss config wizard` BEFORE any rules
47
+ write: the wizard owns which host files change, and its host actions invoke
48
+ the rules pass with the agent/scope intent resolved during setup, so one
49
+ command still produces a working setup. The wizard asks its own scope (or
50
+ defaults silently to global in non-TTY).
51
+
52
+ ## Credential protection flags
53
+
54
+ Model-backed commands (`ask`, `chat`, `write`, `review`, `fetch`,
55
+ `commit-msg`) and coder commands accept:
56
+
57
+ - `--protect-credentials` — request the parent-owned credential proxy. When a
58
+ verified protected route is unavailable for the selected engine, the run
59
+ falls back to best-effort raw execution with a warning (MCP results carry it
60
+ in structured `warnings`).
61
+ - `--no-protect-credentials` — override a persisted
62
+ `TRISS_PROTECT_CREDENTIALS=true` (or `TRISS_CODER_PROTECT_CREDENTIALS=true`)
63
+ choice for one run. For crush this is the explicit raw exit from its
64
+ protected default.
65
+
66
+ `triss config wizard` accepts the coder-target pair
67
+ `--coder-protect-credentials` / `--coder-no-protect-credentials`. They persist
68
+ `TRISS_CODER_PROTECT_CREDENTIALS=true` (configure the parent-owned credential
69
+ proxy mode instead of the default best-effort raw) or `=false` (persist an
70
+ explicit unprotected choice; the coder-specific value takes precedence over a
71
+ persisted `TRISS_PROTECT_CREDENTIALS=true`). The two flags cannot be combined.
72
+
73
+ See [configuration.md](configuration.md) for the persisted tri-state semantics.
@@ -26,8 +26,10 @@ Configuration is read once per command or MCP request into an immutable snapshot
26
26
  `process.env` always wins. Project configuration overrides global configuration. Provider selection, model roles, endpoint, credential, and provenance are resolved together.
27
27
 
28
28
  ```bash
29
- triss config wizard # guided global setup
29
+ triss config wizard # Easy setup: provider + key, assistant hosts, first command
30
+ triss config wizard --advanced # full Advanced sections (providers, execution, connections, integrations, runtime)
30
31
  triss config wizard --local # guided project setup
32
+ triss config wizard <target> # canonical provider id, coder, or integration name
31
33
  triss config set KEY [value] # global by default
32
34
  triss config set KEY [value] --local
33
35
  triss config get KEY
@@ -68,8 +70,46 @@ Global runtime fields:
68
70
  | `TRISS_CONFIG_SCHEMA` | `2` | Persisted configuration schema |
69
71
  | `TRISS_DEFAULT_PROVIDER` | `openai-compatible` | Provider selected when a request omits `provider` |
70
72
  | `TRISS_DEFAULT_ENGINE` | `direct` | Execution engine selected when a model request omits `engine` |
73
+ | `TRISS_DEFAULT_EFFORT` | unset | Effort for model tasks when a request omits `effort`; absence keeps the provider default |
74
+ | `TRISS_CODER_PROVIDER` | unset | Coding provider default; when absent it inherits `TRISS_DEFAULT_PROVIDER` |
75
+ | `TRISS_CODER_EFFORT` | unset | Coding effort override; when absent it inherits `TRISS_DEFAULT_EFFORT` |
76
+ | `TRISS_PROTECT_CREDENTIALS` | unset (tri-state) | Persisted credential-protection choice for model-backed and coder routes |
77
+ | `TRISS_CODER_PROTECT_CREDENTIALS` | unset (tri-state) | Coding-only override of `TRISS_PROTECT_CREDENTIALS` |
78
+ | `TRISS_MODEL_TRANSPORTS` | unset | Exact-model direct transport override map |
71
79
  | `TRISS_REQUEST_TIMEOUT_MS` | SDK default | Model request timeout |
72
80
 
81
+ `TRISS_CODER_PROVIDER` selects the provider profile for coding runs only; it
82
+ never rewrites `TRISS_DEFAULT_PROVIDER`, so `triss ask` / `triss review`
83
+ defaults are unaffected by coder configuration.
84
+
85
+ ### Credential protection tri-state
86
+
87
+ `TRISS_PROTECT_CREDENTIALS` and `TRISS_CODER_PROTECT_CREDENTIALS` accept three
88
+ meaningful states — absent, `true`, or `false` — and the string `"false"` is
89
+ never treated as a truthy opt-in. Resolution order: an explicit per-run flag
90
+ (`--protect-credentials` / `--no-protect-credentials`) wins; otherwise
91
+ `TRISS_CODER_PROTECT_CREDENTIALS` (coder runs) or `TRISS_PROTECT_CREDENTIALS`
92
+ applies. `true` selects the parent-owned credential proxy; `false` explicitly
93
+ selects a best-effort raw run (warned). When no choice is expressed, each route
94
+ uses its recommended default — `crush` defaults to the protected proxy; the
95
+ other engines default to best-effort raw handling — so an explicit `false`
96
+ means something different from an unset value.
97
+
98
+ ### Model transport overrides
99
+
100
+ `TRISS_MODEL_TRANSPORTS` is a JSON map of exact `"canonical-provider/native-model"`
101
+ selectors to direct transport ids (`openai-chat`, `openai-responses`,
102
+ `anthropic-messages`):
103
+
104
+ ```bash
105
+ triss config set TRISS_MODEL_TRANSPORTS '{"opencode-go/muse-spark-1.3-contributor": "openai-responses"}'
106
+ ```
107
+
108
+ It is an expert protocol clarification for specific models — never an allowlist
109
+ of permitted models. OpenCode Zen and Go models resolve through their audited
110
+ per-model transport catalogue first; the override pins the transport for an
111
+ exact model when the catalogue cannot.
112
+
73
113
  ## Model roles and request selection
74
114
 
75
115
  Model-backed commands declare either the `model` role or the `smallModel` role. Each provider owns both native model ids.
@@ -78,15 +118,23 @@ Model-backed commands declare either the `model` role or the `smallModel` role.
78
118
  - `model` is a native model id for direct CLI/MCP commands.
79
119
  - `engine` selects `direct`, `opencode`, `opencode2`, `omp`, or `crush`; when omitted, `TRISS_DEFAULT_ENGINE` applies.
80
120
  - coder `--model` accepts a canonical `<provider>/<model-id>` selector; the small role comes from that provider's `*_SMALL_MODEL` field.
81
- - `effort` accepts `minimal`, `low`, `medium`, `high`, or `max`.
121
+ - `effort` accepts `low`, `medium`, `high`, `xhigh`, or `max`.
82
122
  - `max_tokens` remains a separate output cap.
83
123
 
84
124
  There are no public model presets. Omit `model` to use the selected provider role.
85
125
 
86
- Provider and engine defaults resolve independently. Registry-backed providers
87
- such as `opencode-go` require an engine-backed default instead of `direct`.
88
- Read-only model projection is currently verified only for `opencode`;
89
- `opencode2`, `omp`, and `crush` are rejected before launch for non-coder tasks.
126
+ Provider and engine defaults resolve independently. The `direct` engine serves
127
+ providers with native HTTP transport metadata: `openai-compatible`, `zai`,
128
+ `moonshot`, and `kimi-for-coding` natively, and `opencode-zen` / `opencode-go`
129
+ models through audited per-model transports (OpenAI Chat, OpenAI Responses, or
130
+ Anthropic Messages). A model without resolvable direct metadata fails with the
131
+ stable `TRISS_DIRECT_ENGINE_REQUIRED` error and an actionable remedy: set a
132
+ `TRISS_MODEL_TRANSPORTS` entry for that exact model or run it on a native
133
+ engine (`opencode`, `opencode2`, `omp`, or `crush`).
134
+
135
+ Every engine can execute non-coder model projections (`ask`, `review`, `chat`,
136
+ …); engines without a verified read-only projection report their concrete
137
+ limitation as a warning on the execution result, never as a refusal.
90
138
 
91
139
  Examples:
92
140
 
@@ -123,7 +171,7 @@ retained in the execution result and MCP structured output.
123
171
  ```bash
124
172
  triss coder init --engine opencode --provider zai
125
173
  triss coder init --engine opencode2 --provider opencode-zen
126
- triss coder init --engine crush --provider zai
174
+ triss coder init --engine crush --provider moonshot
127
175
  triss coder init --engine omp --provider opencode-go
128
176
  ```
129
177