@qadanm/opencode-smart-router 0.4.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +168 -0
- package/CONTRIBUTING.md +7 -0
- package/README.md +89 -5
- package/config.example.json +1 -2
- package/dist/npm/index.js +29 -29
- package/docs/INSTALL.md +35 -4
- package/docs/LIMITATIONS.md +19 -2
- package/docs/SHARED-CORE.md +47 -5
- package/package.json +3 -1
- package/src/core/config.ts +25 -8
- package/src/core/models/registry.ts +1 -0
- package/src/core/models/seed.ts +13 -3
- package/src/core/plans/catalog.ts +6 -0
- package/src/core/policy/eligibility.ts +53 -1
- package/src/core/providers/opendesign-models.ts +33 -7
- package/src/core/quota/ledger.ts +31 -0
- package/src/core/routing/engine.ts +61 -2
- package/src/core/types.ts +46 -5
- package/src/gui/index.tsx +5 -0
- package/src/index.ts +15 -30
- package/src/server/containment.ts +131 -0
- package/src/server/controller.ts +261 -137
- package/src/server/shared-core.ts +32 -2
- package/dist/allowance.js +0 -487
- package/dist/gui-experimental.cjs +0 -1
- package/dist/index.js +0 -11111
- package/dist/tui.js +0 -587
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,174 @@ Notable changes to OpenCode Smart Router. Dates are the day the change landed on
|
|
|
10
10
|
- **Launch kit** (`docs/LAUNCH-KIT.md`): paste-ready copy for Discord, Hacker
|
|
11
11
|
News, X, and the opencode.cafe submission, plus the demo film assets.
|
|
12
12
|
|
|
13
|
+
## 0.6.1 — 2026-11-06
|
|
14
|
+
|
|
15
|
+
A defect in the router can no longer stop the editor.
|
|
16
|
+
|
|
17
|
+
Version 0.6.0 could refuse every prompt, in every mode, until the plugin was
|
|
18
|
+
removed by hand. Two defects compounded to cause it. This release fixes both,
|
|
19
|
+
and adds the missing test layer that would have caught them. The full account is
|
|
20
|
+
in [docs/INCIDENT-2026-11-06-prompt-lockout.md](docs/INCIDENT-2026-11-06-prompt-lockout.md).
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **An inherited shared core is no longer adopted.** The process-wide core in
|
|
25
|
+
`globalThis` is stamped with `SHARED_CORE_API`; a core from a different
|
|
26
|
+
version is replaced rather than reused. A new bundle could previously inherit
|
|
27
|
+
a core built by an older release, whose ledger had no `planPoolSpent()`, and
|
|
28
|
+
every prompt then threw. `init()` also repairs a ledger that is not a
|
|
29
|
+
`LedgerStore` instance.
|
|
30
|
+
- **`routing.failClosed` defaults to `false`.** Blocking is now opt-in and means
|
|
31
|
+
one thing: what to do when this plugin cannot produce a decision. The old
|
|
32
|
+
default escalated an internal `TypeError` into a refusal to serve the prompt,
|
|
33
|
+
including in manual mode. An internal defect now degrades to "do not route",
|
|
34
|
+
which is what would have happened with the plugin uninstalled.
|
|
35
|
+
- **Quota safety is a separate, unconditional gate.** A provider configured for
|
|
36
|
+
probing but with no reading is still refused, regardless of `failClosed`,
|
|
37
|
+
because that is a spending decision rather than a response to plugin failure.
|
|
38
|
+
- **A failed setup installs no prompt hook.** The entry point used to leave a
|
|
39
|
+
"minimal fail-closed hook" behind when `initialize()` threw, turning a failed
|
|
40
|
+
setup into an editor that refused every message. A location whose setup failed
|
|
41
|
+
now has no router.
|
|
42
|
+
- **Hooks cannot throw or hang at the host boundary.** OpenCode does not catch a
|
|
43
|
+
plugin hook that throws and does not time out one that never settles; both
|
|
44
|
+
were verified against a real OpenCode 2.2.5 process. Every hook is wrapped in
|
|
45
|
+
`containHook()`, and routing runs against a 10 second deadline
|
|
46
|
+
(`withDeadline()`), after which the prompt proceeds unrouted.
|
|
47
|
+
- **Routing only considers models the host can serve.** The router offered the
|
|
48
|
+
whole seed catalog as candidates. On a fresh install it switched a session to
|
|
49
|
+
`opencode-go/claude-haiku-5-5`, which that machine did not have, and the next
|
|
50
|
+
step failed with "Model unavailable". Candidates are now filtered to the
|
|
51
|
+
host's own model list, and an empty result means no route rather than an
|
|
52
|
+
unfiltered fallback.
|
|
53
|
+
- **Model discovery is awaited on the first routing decision.** Discovery starts
|
|
54
|
+
in the background, so the first prompt after startup could route against an
|
|
55
|
+
empty list, which is the window in which an unservable model was reachable.
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- `scripts/isolated-e2e.sh`: runs a real OpenCode in a temporary HOME with its
|
|
60
|
+
own config, data, and cache, installs a deliberately broken plugin, and
|
|
61
|
+
asserts only that OpenCode still answers a prompt. It refuses to run if any
|
|
62
|
+
path escapes the sandbox. Seven scenarios pass; two are recorded as host
|
|
63
|
+
limitations because they demonstrate that OpenCode has no defense at that
|
|
64
|
+
boundary. It runs against a loopback model stub that it starts itself, so it
|
|
65
|
+
needs no credentials and cannot be blocked by provider quota. A CI job runs
|
|
66
|
+
it on every push.
|
|
67
|
+
- Regression suites: `test/shared-core-skew.test.ts` and
|
|
68
|
+
`test/shared-core-adoption.test.ts` (a stale core must not be adopted or break
|
|
69
|
+
routing), `test/fail-open-contract.test.ts` (an internal defect must not block
|
|
70
|
+
a prompt), `test/containment.test.ts` (hooks cannot throw or hang),
|
|
71
|
+
`test/setup-failure-never-blocks.test.ts` (a failed setup leaves no router),
|
|
72
|
+
`test/routing-servable-models.test.ts` (only servable models are candidates).
|
|
73
|
+
- Six new entries in the mutation harness, one per corrected property.
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
|
|
77
|
+
- `config.example.json` ships `failClosed: false`. Copying the example used to
|
|
78
|
+
inherit the old blocking default.
|
|
79
|
+
- `scripts/cleanroom-verify.sh` now overlays the working tree onto `HEAD` and
|
|
80
|
+
reports how many uncommitted paths it covered. Before this, a run with work in
|
|
81
|
+
progress verified the previous commit and reported a pass that said nothing
|
|
82
|
+
about the changes being made.
|
|
83
|
+
|
|
84
|
+
### Fixed in CI
|
|
85
|
+
|
|
86
|
+
- The `host-survival` job now installs OpenCode V2 from its release binaries
|
|
87
|
+
instead of Homebrew, which does not exist on Ubuntu runners, and verifies the
|
|
88
|
+
download against the published `SHA256SUMS`. It also asserts the major version
|
|
89
|
+
is 2, so a future change to the installer cannot quietly point the suite at
|
|
90
|
+
OpenCode 1, whose hook surface and CLI differ.
|
|
91
|
+
- `test/history.test.ts` no longer fails on the declared Node 20.12 floor, where
|
|
92
|
+
`node:sqlite` does not exist. The reader already degraded gracefully there; the
|
|
93
|
+
test now asserts that degradation and skips only the two cases that genuinely
|
|
94
|
+
require a real database. The suite passes on 20.12 with two honest skips rather
|
|
95
|
+
than two failures.
|
|
96
|
+
- The eight calibration properties the mutation harness listed as unguarded now
|
|
97
|
+
have `test/calibration-policy.test.ts`. They were not missing guards, they were
|
|
98
|
+
pointed at a file that covers a different module, so the properties were never
|
|
99
|
+
exercised. All 69 mutations are now caught.
|
|
100
|
+
|
|
101
|
+
## 0.6.0 — 2026-11-06
|
|
102
|
+
|
|
103
|
+
Tier-3 work escalates by itself, paid from the plan-model pool.
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
|
|
107
|
+
- **Automatic flagship escalation** (`premium.mode: "auto"`, now the default):
|
|
108
|
+
a tier-3 task routes to the plan-model pool (Claude Sonnet 5.5, GPT-6.1 Sol)
|
|
109
|
+
without a per-task approval prompt while the pool has budget. When the pool
|
|
110
|
+
is spent, escalation degrades to an approval gate and the router serves the
|
|
111
|
+
task with the strongest ordinary model - a routing refusal never fails a
|
|
112
|
+
serviceable task. Tier-1 and tier-2 work always stays on the ordinary pool.
|
|
113
|
+
- **Plan-model pool ledger**: monthly buckets tracking spend against the
|
|
114
|
+
OpenDesign plan-model allowance (Pro: $120/month), persisted across
|
|
115
|
+
restarts, separate from Design Plan credits and from other providers'
|
|
116
|
+
premium spend. The cap is read from the resolved plan catalog.
|
|
117
|
+
- **Per-kind capability evidence**: `ModelRecord.capabilities` (coding,
|
|
118
|
+
debugging, agentic, architecture) from named benchmarks with provenance,
|
|
119
|
+
moving expected success by at most 4 points - enough to break a close
|
|
120
|
+
ranking, never enough to overrule a gate. Unscored models stay neutral:
|
|
121
|
+
absent evidence is unknown, not zero.
|
|
122
|
+
- **Context probes** (`scripts/probe-plan-model-context.py`): end-to-end
|
|
123
|
+
800K-token verification with memorization sentinels and truncation checks.
|
|
124
|
+
|
|
125
|
+
### Changed
|
|
126
|
+
|
|
127
|
+
- GPT-6.1 Sol is scored (intelligence 55, Artificial Analysis v5.0.1) and
|
|
128
|
+
auto-approved for tier-3 escalation along with Sonnet 5.5, both by owner
|
|
129
|
+
instruction 2026-11-06. DeepSeek's observed 39.5 is untouched.
|
|
130
|
+
- Catalog context windows raised from measured (328K/400K) to probed-verified
|
|
131
|
+
800K for both flagships after passed end-to-end probes on 2026-11-06; the
|
|
132
|
+
advertised 1M is deliberately NOT claimed, and Sol's long-context surcharge
|
|
133
|
+
above 272K was confirmed by the billed amounts.
|
|
134
|
+
- MiniMax M3.1 Flash is classified as a Design Plan model. The gateway serves
|
|
135
|
+
it both inside and outside the Design Plan group and OpenDesign has not
|
|
136
|
+
published which applies, so the conservative choice is made: treating an
|
|
137
|
+
ordinary tier-2 workhorse as a plan model keeps routine work from draining
|
|
138
|
+
the escalation pool. Before this, a tier-3 task could land on it as a
|
|
139
|
+
premium model that a tier-2 flag itself made eligible.
|
|
140
|
+
|
|
141
|
+
### Fixed
|
|
142
|
+
|
|
143
|
+
- A partial settings file no longer produces a warning for every key it leaves
|
|
144
|
+
out. Absent and invalid are now distinct: a key you did not write takes its
|
|
145
|
+
default silently, while a key you did write with the wrong type still reports
|
|
146
|
+
the problem. Before this, a config that only set `providers.opendesign.plan`
|
|
147
|
+
emitted around fifty warnings and hid the ones that mattered.
|
|
148
|
+
|
|
149
|
+
## 0.5.0 — 2026-11-06
|
|
150
|
+
|
|
151
|
+
The router stops taking things that are not its to take.
|
|
152
|
+
|
|
153
|
+
### Changed
|
|
154
|
+
|
|
155
|
+
- **The router no longer renames sessions.** The `AUTO · OD · model — name`
|
|
156
|
+
title prefix is gone, for new chats and for every chat going forward. A chat
|
|
157
|
+
title is the owner's name for the work; status belongs in the panel, the
|
|
158
|
+
terminal footer and the decision record. The `ui.titleIndicator` setting is
|
|
159
|
+
removed and ignored if present.
|
|
160
|
+
- `/router-title off` now strips prefixes this plugin wrote in earlier versions
|
|
161
|
+
and reports how many titles it cleaned. Titles that lost their separator are
|
|
162
|
+
left alone rather than rewritten.
|
|
163
|
+
- Existing installs were repaired in place: every prefixed title was restored
|
|
164
|
+
from its separator, or from the session's own first user message when the
|
|
165
|
+
separator was already gone.
|
|
166
|
+
|
|
167
|
+
### Added
|
|
168
|
+
|
|
169
|
+
- Earlier review pass carried in this release: self-heal floor fallback, real
|
|
170
|
+
safety-margin enforcement, task-scoped rejection memory, strict failure joins,
|
|
171
|
+
request-clock threading, and metric-neutral decision notes.
|
|
172
|
+
|
|
173
|
+
### Removed
|
|
174
|
+
|
|
175
|
+
- **Sidebar project grouping (never released on npm).** The desktop app ships
|
|
176
|
+
this natively behind Settings -> Experimental -> Organize vertical sidebar ->
|
|
177
|
+
Projects (upstream commit `2bb4988`, after the installed v2.2.5). A plugin
|
|
178
|
+
copy would duplicate app code and fight the native version. The reasoning and
|
|
179
|
+
the prior-art notes are in `docs/SIDEBAR-GROUPING-TABLED.md`.
|
|
180
|
+
|
|
13
181
|
## 0.4.0 — 2026-11-05
|
|
14
182
|
|
|
15
183
|
Self-healing routing, and npm distribution.
|
package/CONTRIBUTING.md
CHANGED
|
@@ -85,6 +85,13 @@ Explain why, not what. The diff already shows what. A commit that fixes a subtle
|
|
|
85
85
|
bug should say how the bug showed up, because that part is not recoverable from
|
|
86
86
|
the code.
|
|
87
87
|
|
|
88
|
+
## Releasing
|
|
89
|
+
|
|
90
|
+
See [README → Releases](README.md#releases). Publishing happens in CI through npm
|
|
91
|
+
trusted publishing, so a maintainer never handles a long-lived token or relays a
|
|
92
|
+
one-time password. Never publish from a working copy: the workflow checks the tag
|
|
93
|
+
against `package.json` and re-runs the full suite first.
|
|
94
|
+
|
|
88
95
|
## Out of scope
|
|
89
96
|
|
|
90
97
|
Likely to be declined:
|
package/README.md
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
<p>Every other router asks what a token costs. This one asks what your plan allows, what is about to expire, and what you already paid for. MIT licensed.</p>
|
|
8
8
|
|
|
9
9
|
<p>
|
|
10
|
+
<a href="https://www.npmjs.com/package/@qadanm/opencode-smart-router/v/0.4.0"><img src="https://img.shields.io/npm/v/%40qadanm%2Fopencode-smart-router?label=npm&color=cb3837&logo=npm&logoColor=white" alt="npm version"></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/@qadanm/opencode-smart-router"><img src="https://img.shields.io/npm/dm/%40qadanm%2Fopencode-smart-router?label=installs&color=cb3837&logo=npm&logoColor=white" alt="npm monthly installs"></a>
|
|
10
12
|
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
|
|
11
13
|
<img src="https://img.shields.io/badge/OpenCode-2.x-000000.svg" alt="OpenCode 2.x">
|
|
12
14
|
<img src="https://img.shields.io/badge/tests-759%20passing-2ea44f.svg" alt="759 tests">
|
|
@@ -23,6 +25,10 @@
|
|
|
23
25
|
|
|
24
26
|
<br>
|
|
25
27
|
|
|
28
|
+
<a href="assets/smart-router-demo.gif"><img alt="One session, 22 seconds: a prompt arrives, the router shows the decision card with its reasons and blocked candidates, the budget windows fill in, and a rejected turn moves itself to the next best model and continues" src="assets/smart-router-demo.gif" width="880"></a>
|
|
29
|
+
|
|
30
|
+
<br>
|
|
31
|
+
|
|
26
32
|
<picture>
|
|
27
33
|
<source media="(prefers-color-scheme: dark)" srcset="assets/architecture-dark.svg">
|
|
28
34
|
<img alt="Your prompt goes to the smart router, which classifies and prices it against your real quota before OpenCode sends the step to one provider" src="assets/architecture-light.svg" width="880">
|
|
@@ -188,15 +194,44 @@ panel's last decision records what was rejected and what took over.
|
|
|
188
194
|
|
|
189
195
|
- Never buys credits, changes billing, or enables top-ups.
|
|
190
196
|
- Never routes to a provider you did not approve.
|
|
191
|
-
- Never spends
|
|
197
|
+
- Never spends the plan-model pool without the budget you set; in the default
|
|
198
|
+
auto mode tier-3 work escalates to it automatically, and when it runs out the
|
|
199
|
+
router falls back to the strongest ordinary model instead of failing.
|
|
192
200
|
- Never switches a session to a model OpenCode cannot currently resolve.
|
|
193
201
|
- Never fails open on missing quota data when other providers already reported.
|
|
194
202
|
- Never blocks your other work when one provider is at its limit.
|
|
203
|
+
- **Never stops you sending a message.** If the router breaks, it is skipped.
|
|
204
|
+
|
|
205
|
+
### When the plugin is wrong, the editor still works
|
|
206
|
+
|
|
207
|
+
Routing is an optimization. OpenCode works without it, and it keeps working when
|
|
208
|
+
the router is wrong. That is a contract, not a best effort:
|
|
209
|
+
|
|
210
|
+
- an internal defect degrades to "do not route", never to "do not work". The
|
|
211
|
+
prompt is served with the model already selected and the reason is recorded in
|
|
212
|
+
warnings;
|
|
213
|
+
- every hook is wrapped so it cannot throw into OpenCode, and routing runs
|
|
214
|
+
against a deadline so it cannot hold a prompt indefinitely;
|
|
215
|
+
- if setup fails for a location, that location simply has no router;
|
|
216
|
+
- a shared core left behind by a different plugin version is replaced rather
|
|
217
|
+
than reused.
|
|
218
|
+
|
|
219
|
+
Blocking a prompt is available, but it is opt-in through
|
|
220
|
+
`routing.failClosed: true`, and it covers plugin faults only. Quota safety is
|
|
221
|
+
separate and always on: a provider configured for probing with no reading is
|
|
222
|
+
refused, because that is a spending decision rather than a response to failure.
|
|
223
|
+
|
|
224
|
+
This was made a contract the hard way. Version 0.6.0 turned an internal
|
|
225
|
+
`TypeError` into a refusal to send any prompt, in every mode, and the plugin had
|
|
226
|
+
to be removed by hand. The account is in
|
|
227
|
+
[docs/INCIDENT-2026-11-06-prompt-lockout.md](docs/INCIDENT-2026-11-06-prompt-lockout.md),
|
|
228
|
+
and the guarantee is tested against a real OpenCode process by
|
|
229
|
+
`scripts/isolated-e2e.sh`, not only by unit tests.
|
|
195
230
|
|
|
196
231
|
## Status
|
|
197
232
|
|
|
198
|
-
Version 0.
|
|
199
|
-
|
|
233
|
+
Version 0.6.1. Routing runs on the maintainer's machine in automatic mode;
|
|
234
|
+
tier-3 tasks escalate to the plan-model pool automatically within its budget. Current behavior
|
|
200
235
|
and open questions are in
|
|
201
236
|
[docs/PRO-MIGRATION-2026-10-29.md](docs/PRO-MIGRATION-2026-10-29.md).
|
|
202
237
|
|
|
@@ -226,6 +261,7 @@ command panel closed.
|
|
|
226
261
|
| `/router-premium-budget <usd>` | Set the premium budget |
|
|
227
262
|
| `/router-reserve provider monthly weekly fiveHour` | Adjust provider reserves |
|
|
228
263
|
| `/router-reset-metrics --confirm` | Reset metrics and routing state, not conversations |
|
|
264
|
+
| `/router-title off` | Strip prefixes this plugin wrote into titles before 0.5.0 |
|
|
229
265
|
|
|
230
266
|
Selecting a model in the desktop picker is detected and respected. The session
|
|
231
267
|
reports `manual` until you run `/router-auto`.
|
|
@@ -245,7 +281,10 @@ It cannot loosen global restrictions.
|
|
|
245
281
|
Worth knowing:
|
|
246
282
|
|
|
247
283
|
- Mode: `balanced`
|
|
248
|
-
- Premium: `
|
|
284
|
+
- Premium: `auto`, $120/month plan-model pool, one-shot approval available.
|
|
285
|
+
Auto mode escalates tier-3 tasks to the plan-model pool (Sonnet 5.5,
|
|
286
|
+
GPT-6.1 Sol) without asking, and degrades to an approval gate when the pool
|
|
287
|
+
is spent. Tier-1 and tier-2 work always stays on the ordinary pool.
|
|
249
288
|
- Training-enabled and free promotional models: blocked
|
|
250
289
|
- Purchased extra credits: blocked
|
|
251
290
|
- Prompt text storage: disabled
|
|
@@ -287,7 +326,7 @@ npm run verify # clean room: empty HOME, fresh install, typecheck, tests, bui
|
|
|
287
326
|
npm run mutate # prove each safety test fails when its property breaks
|
|
288
327
|
```
|
|
289
328
|
|
|
290
|
-
|
|
329
|
+
822 tests across 75 files cover classification, eligibility, quota parsing,
|
|
291
330
|
credential discovery and its security properties, ledger accounting, pool
|
|
292
331
|
reconciliation, documented peak pricing, cache-aware routing, premium protection,
|
|
293
332
|
purchased-credit blocking, manual overrides, failure classification, configuration
|
|
@@ -330,6 +369,51 @@ A change that alters routing behavior needs a test that fails without it. See
|
|
|
330
369
|
[CONTRIBUTING.md](CONTRIBUTING.md) for conventions, and [SECURITY.md](SECURITY.md)
|
|
331
370
|
for reporting a vulnerability.
|
|
332
371
|
|
|
372
|
+
## Releases
|
|
373
|
+
|
|
374
|
+
Releases are cut from `main` and published by CI, not from a laptop. The package
|
|
375
|
+
is published with [npm trusted publishing](https://docs.npmjs.com/trusted-publishers),
|
|
376
|
+
which exchanges a GitHub Actions identity for a short-lived publish credential, so
|
|
377
|
+
there is no `NPM_TOKEN` in this repository and no one-time password to relay.
|
|
378
|
+
|
|
379
|
+
1. Bump `version` in `package.json` and add the matching `CHANGELOG.md` section.
|
|
380
|
+
2. Run `npm run check`, commit, and push to `main`.
|
|
381
|
+
3. Tag and push the tag:
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
git tag -a v0.6.1 -m "0.6.1: <one line>"
|
|
385
|
+
git push origin main --tags
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
4. `.github/workflows/release.yml` checks the tag against `package.json`,
|
|
389
|
+
re-runs the full suite, and publishes.
|
|
390
|
+
5. Create the GitHub release from the changelog section:
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
gh release create v0.6.1 --title "0.6.1: <one line>" --notes-file notes.md
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
If the tag and `package.json` disagree, the workflow refuses to publish: a
|
|
397
|
+
version that reaches the registry can never be replaced.
|
|
398
|
+
|
|
399
|
+
### One-time npm setup
|
|
400
|
+
|
|
401
|
+
Trusted publishing is authorized on the npm side, not in this repository. On the
|
|
402
|
+
package settings page for `@qadanm/opencode-smart-router`, add a trusted publisher:
|
|
403
|
+
|
|
404
|
+
| Field | Value |
|
|
405
|
+
|---|---|
|
|
406
|
+
| Provider | GitHub Actions |
|
|
407
|
+
| Organization or user | `qadanm` |
|
|
408
|
+
| Repository | `opencode-smart-router` |
|
|
409
|
+
| Workflow filename | `release.yml` |
|
|
410
|
+
| Environment | (leave empty) |
|
|
411
|
+
|
|
412
|
+
Until that entry exists, the release workflow fails at the publish step with a
|
|
413
|
+
`404 Not Found`, which is npm's way of saying the OIDC identity is not on the
|
|
414
|
+
package's trusted list. The check, build, and tag verification still run and
|
|
415
|
+
still gate the release.
|
|
416
|
+
|
|
333
417
|
## License
|
|
334
418
|
|
|
335
419
|
MIT. See [LICENSE](LICENSE).
|
package/config.example.json
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"largeContextHysteresisPct": 35,
|
|
60
60
|
"maxEscalationsPerTask": 2,
|
|
61
61
|
"preferSameProvider": true,
|
|
62
|
-
"failClosed":
|
|
62
|
+
"failClosed": false,
|
|
63
63
|
"protectEscalationPool": true,
|
|
64
64
|
"longContextFloorTokens": 1000000
|
|
65
65
|
},
|
|
@@ -90,7 +90,6 @@
|
|
|
90
90
|
"slowRouteMultiple": 2.5
|
|
91
91
|
},
|
|
92
92
|
"ui": {
|
|
93
|
-
"titleIndicator": false,
|
|
94
93
|
"notifications": true,
|
|
95
94
|
"compactMode": false
|
|
96
95
|
},
|