Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
226 commits
Select commit Hold shift + click to select a range
a03423e
test: make the suite engine-independent and guard the client boundary
claude Oct 22, 2026
6ac740f
fix(lifecycle): contain the internal-route mount and follow reloads i…
claude Oct 22, 2026
aa3c01b
fix: price, list and key requests on the plane they belong to; isolat…
claude Oct 22, 2026
54a5b19
fix(store): mount the inspection remote, and read legacy keys per int…
claude Oct 22, 2026
8a5e95f
docs: describe the tree that exists, and the guarantees the suite now…
claude Oct 22, 2026
52f175f
docs: add the improvement plan from the architecture review
claude Oct 22, 2026
603d378
docs(plan): the approved refactor plan, with the host's own contracts
claude Oct 22, 2026
0a0dbb0
docs(plan): route every mode through the user's own provider
claude Oct 23, 2026
d4e3067
docs(plan): the plugin owns the plane routes, measured on pi 1.1.0
claude Oct 23, 2026
a38259c
docs(plan): fold the reviewed design and the build order into the plan
claude Oct 23, 2026
cd3107e
fix: repair what shipped broken in 1.4.1
claude Oct 23, 2026
73d60e4
docs(plan): P1a is in review
claude Oct 23, 2026
2bbb673
chore: remove dead code and tighten the repository's gates
claude Oct 23, 2026
e8944cc
feat: a smaller public API
claude Oct 23, 2026
f276902
build: pin the host the plugin runs on
claude Oct 23, 2026
6182886
test: a harness that is the real host
claude Oct 24, 2026
9ccdeb3
refactor: one way to patch a host method
claude Oct 24, 2026
813e6f3
chore: refresh the generated catalog and limits tables
claude Oct 24, 2026
a3d096b
Merge branch 'claude/vigilant-mendel-bctz9n' into p1a
claude Oct 24, 2026
2339c48
Merge branch 'claude/vigilant-mendel-bctz9n-p1a' into p1b
claude Oct 24, 2026
8b6cde6
Merge branch 'claude/vigilant-mendel-bctz9n-p1b' into p2
claude Oct 24, 2026
fb23df4
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1a' into p-t1b
claude Oct 24, 2026
9cd81de
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1b' into p-h
claude Oct 24, 2026
1a568f9
Merge branch 'claude/vigilant-mendel-bctz9n-p2' into p-t1a
claude Oct 24, 2026
c7121a3
feat: the plugin owns the opencode and opencode-go routes
claude Oct 24, 2026
50d39f5
Merge branch 'claude/vigilant-mendel-bctz9n-p-h' into p-r1
claude Oct 24, 2026
2728666
test: measure which endpoint families the gateway serves
claude Oct 24, 2026
4c491fe
Merge branch 'claude/vigilant-mendel-bctz9n-p-r1' into p-r2
claude Oct 24, 2026
1c11d22
feat: Settings offers the catalog's models pi does not list
claude Oct 24, 2026
2ebaffc
chore: refresh the generated catalog and limits tables
claude Oct 26, 2026
d51a3e6
test: skip free models the gateway has withdrawn in the live suite
claude Oct 26, 2026
409b5e1
fix: address the second review of P-T1b
claude Oct 26, 2026
aec8c1a
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1b' into p-h
claude Oct 26, 2026
0dd1b9c
Merge branch 'claude/vigilant-mendel-bctz9n' into p1a
claude Oct 26, 2026
1f5ed90
Merge branch 'claude/vigilant-mendel-bctz9n-p1a' into p1b
claude Oct 26, 2026
05faa93
Merge branch 'claude/vigilant-mendel-bctz9n-p1b' into p2
claude Oct 26, 2026
73db37b
Merge branch 'claude/vigilant-mendel-bctz9n-p2' into p-t1a
claude Oct 26, 2026
9f7e8e2
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1a' into p-t1b
claude Oct 26, 2026
1f48272
test: follow the vendor catalog refresh
claude Oct 26, 2026
3cfacd9
fix: address the second review of P-H
claude Oct 26, 2026
bffd3a4
Merge branch 'claude/vigilant-mendel-bctz9n-p-h' into p-r1
claude Oct 26, 2026
8ab5d65
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1b' into p-h
claude Oct 26, 2026
25dc182
Merge branch 'claude/vigilant-mendel-bctz9n-p-h' into p-r1
claude Oct 26, 2026
9cf8372
test: follow the vendor catalog refresh
claude Oct 26, 2026
0cceb81
fix: address the second review of P-R1
claude Oct 27, 2026
9f694bf
Merge branch 'claude/vigilant-mendel-bctz9n-p-r1' into p-r2
claude Oct 27, 2026
059236a
ci: gate freshness only on a pull request's own generator changes
claude Oct 27, 2026
d13cbe2
chore: refresh the generated catalog after Zen retired deepseek-v4-flash
claude Oct 27, 2026
32f2d71
Merge branch 'claude/vigilant-mendel-bctz9n' into claude/vigilant-men…
claude Oct 27, 2026
64c8acc
Merge branch 'claude/vigilant-mendel-bctz9n-p1a' into claude/vigilant…
claude Oct 27, 2026
6988e7a
Merge branch 'claude/vigilant-mendel-bctz9n-p1b' into claude/vigilant…
claude Oct 27, 2026
aba2c4a
Merge branch 'claude/vigilant-mendel-bctz9n-p2' into claude/vigilant-…
claude Oct 27, 2026
c6d8965
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1a' into claude/vigila…
claude Oct 27, 2026
c6077be
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1b' into claude/vigila…
claude Oct 27, 2026
3d7cb38
test: give the freshness walk's dynamic import a script-local target
claude Oct 27, 2026
e4aa0c9
Merge branch 'claude/vigilant-mendel-bctz9n' into claude/vigilant-men…
claude Oct 27, 2026
94c3a22
Merge branch 'claude/vigilant-mendel-bctz9n-p1a' into claude/vigilant…
claude Oct 27, 2026
14c1544
Merge branch 'claude/vigilant-mendel-bctz9n-p1b' into claude/vigilant…
claude Oct 27, 2026
8ee4245
Merge branch 'claude/vigilant-mendel-bctz9n-p2' into claude/vigilant-…
claude Oct 27, 2026
5133c0c
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1a' into claude/vigila…
claude Oct 27, 2026
b518061
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1b' into claude/vigila…
claude Oct 27, 2026
3ccd70c
fix: address the second review of P-R2
claude Oct 27, 2026
79d0036
Merge branch 'claude/vigilant-mendel-bctz9n-p-r2' into p3
claude Oct 27, 2026
29b43ca
chore: refresh the generated catalog after Zen retired deepseek-v4-flash
claude Oct 27, 2026
4891c07
test: follow the vendor catalog refresh
claude Oct 27, 2026
4dbd22e
fix: send Google's thinking level to Gemini models the catalog gives …
claude Oct 27, 2026
d8821f0
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p-…
claude Oct 27, 2026
dec00c8
docs: correct the Go shape count, the README date and the install range
claude Oct 27, 2026
be649da
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p-…
claude Oct 27, 2026
d16a600
docs: date the refreshed model count and correct three stale figures
claude Oct 27, 2026
f8a4af3
Merge branch 'claude/vigilant-mendel-bctz9n' into claude/vigilant-men…
claude Oct 27, 2026
cb3cdda
Merge branch 'claude/vigilant-mendel-bctz9n-p1a' into claude/vigilant…
claude Oct 27, 2026
3d461c2
Merge branch 'claude/vigilant-mendel-bctz9n-p1b' into claude/vigilant…
claude Oct 27, 2026
659b0f3
Merge branch 'claude/vigilant-mendel-bctz9n-p2' into claude/vigilant-…
claude Oct 27, 2026
fa6a5bd
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1a' into claude/vigila…
claude Oct 27, 2026
c82fa3e
Merge branch 'claude/vigilant-mendel-bctz9n-p-t1b' into claude/vigila…
claude Oct 27, 2026
a583874
Merge branch 'claude/vigilant-mendel-bctz9n-p-h' into claude/vigilant…
claude Oct 27, 2026
72852fb
Merge branch 'claude/vigilant-mendel-bctz9n-p-r1' into claude/vigilan…
claude Oct 27, 2026
dbe995e
fix: address the second review of P3
claude Oct 27, 2026
61e2c5d
docs: close the audit's remaining findings on P-R1
claude Oct 27, 2026
1c91312
Merge remote-tracking branch 'origin/main' into claude/vigilant-mende…
claude Nov 2, 2026
854a337
chore: follow the vendor's retirement of nemotron-3-ultra-free
claude Nov 2, 2026
b0f0bdc
test: walk past a model the gateway answers ModelDeprecated for
claude Nov 2, 2026
15e6236
test: install the plane-lookup world before each test
claude Nov 2, 2026
2454609
test(scripts): move the generated-table skip into the CLI-version rules
claude Nov 2, 2026
beae0ca
test(e2e): read an upstream's 400 "Model is unavailable" as a retirement
claude Nov 2, 2026
1d4aaab
docs(testing): describe the suite this branch keeps
claude Nov 2, 2026
4b0ebea
test(e2e): keep the free-tier case's narrowing in the subject picker
claude Nov 2, 2026
979ea27
chore(vendor): follow opencode 1.19.5
claude Nov 2, 2026
28fee8d
docs(plan): restack the plan onto 1.8.0 and the alpha host
claude Nov 2, 2026
8b9da84
build: raise the client bundle ceiling to 136 KB
claude Nov 2, 2026
281fc9f
docs: complete the restack of P0
claude Nov 2, 2026
6812723
docs: close the restack review of P0
claude Nov 2, 2026
7cd12d3
docs: hold the meter's allowance figures to the generated table
claude Nov 3, 2026
e3216d1
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n' i…
claude Nov 3, 2026
73d5465
style: lint and format the merged purge row and token test
claude Nov 3, 2026
2ecf689
fix: complete the restack of P1a
claude Nov 3, 2026
252d0f8
docs: state the measured meter-scan reasons and P1a's refusal test cases
claude Nov 3, 2026
bf5717b
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p1…
claude Nov 3, 2026
5e60c1b
test: one catalogue fixture, behind the one door
claude Nov 3, 2026
f3697a5
docs: describe debugFile by the gate main chose (D24)
claude Nov 3, 2026
074c834
style: satisfy main's promise lint in the retry test
claude Nov 3, 2026
19f05e6
docs(plan): record P1b's restack
claude Nov 3, 2026
8e9f36e
test: keep the fallback case's comment free of a model name
claude Nov 3, 2026
7136ca0
fix: complete the restack of P1b
claude Nov 3, 2026
786de90
docs: name the setup file in the door rule and count the fixture's en…
claude Nov 3, 2026
239d635
docs(plan): record the both-channel host question for P-T1a
claude Nov 3, 2026
bab4fc8
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p1…
claude Nov 3, 2026
521b98f
test: route main's new tests through the one door
claude Nov 3, 2026
737a49d
docs(testing): drop the wrapper forwarder P2 retires again
claude Nov 3, 2026
c15aca0
docs: stop the count sweep record asserting a superseded catalog
claude Nov 3, 2026
798ba2e
chore: refresh the generated catalog for pulse-alpha-free
claude Nov 3, 2026
749669c
Merge branch 'claude/vigilant-mendel-bctz9n' into claude/vigilant-men…
claude Nov 3, 2026
835c793
Merge branch 'claude/vigilant-mendel-bctz9n-p1a' into claude/vigilant…
claude Nov 3, 2026
0563db6
chore: merge the parent's catalog refresh into P2
claude Nov 3, 2026
394e892
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p2…
claude Nov 3, 2026
d65ed21
build: switch the dev install between the harness channels
claude Nov 3, 2026
f595d2d
test: fail if src reads what the desktop's patched pi changes
claude Nov 3, 2026
ea228a6
ci: run the unit and mock suites on both harness channels
claude Nov 3, 2026
90048d7
docs: record the both-channel, no-patch host policy
claude Nov 3, 2026
bcae61f
docs: keep the plan's D14'' row one table cell
claude Nov 3, 2026
44a6d5b
docs: complete the restack of P-T1a
claude Nov 3, 2026
bce1863
test: hold the relock's lockfile strip and name the channel switch's …
claude Nov 3, 2026
4679c1d
fix: report harness channel drift nightly and complete the restack of…
claude Nov 3, 2026
6310663
fix: keep Dependabot and the rc lockfile inside the channel-bump rule…
claude Nov 3, 2026
fb6a686
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p-…
claude Nov 3, 2026
0101239
test: characterize the real host on both harness channels, newest and…
claude Nov 3, 2026
017adad
ci: boot each channel's published binary, as npm installs it and at t…
claude Nov 3, 2026
e1d775c
docs: describe the host cells and the per-channel binary e2e
claude Nov 3, 2026
4871d87
test: name the host cell each row and dispatch set belongs to
claude Nov 3, 2026
79ef58a
test: record the alpha host's broken save as a host limitation
claude Nov 3, 2026
8688046
fix: pin the e2e-host floor cell to the shipped tree and narrow its h…
claude Nov 4, 2026
c1fca83
fix: hold the cordis family to the declared range floors
claude Nov 4, 2026
ec38185
fix: hold the cordis family at the record's floors through a relock
claude Nov 4, 2026
011b99e
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p-…
claude Nov 4, 2026
d001586
docs: pair the reload bullet in the Chinese README
claude Nov 4, 2026
ff2db1d
docs: retitle P-H as the fix it ships
claude Nov 4, 2026
58ba532
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p-…
claude Nov 4, 2026
4a66384
fix: leave the Google thinking control to the host's pi
claude Nov 4, 2026
7ed93a7
fix: route by the plugin's own endpoint table, never pi's catalog
claude Nov 4, 2026
34d6959
fix: size undescribed models with pi-ai's own defaults, not a copy
claude Nov 4, 2026
fa53d8e
docs: cite both channels' host lines and correct the session header c…
claude Nov 4, 2026
db81e7e
test: size the adapter's toggle case through pi-ai's own Config
claude Nov 4, 2026
48776d2
test: hold every remote codec's two parser doors to one parser
claude Nov 4, 2026
0a165d6
test: record the floor's budget refusal in the dispatch cases
claude Nov 4, 2026
2701c88
test: record where the route claim cannot engage on the alpha npm host
claude Nov 4, 2026
76d11e0
fix: complete the restack of P-R1
claude Nov 4, 2026
8bb7b7f
docs: record the withdrawn thinking-level rewrite and finish the P-R1…
claude Nov 4, 2026
26d1e74
docs: complete the restack review of P-R1
claude Nov 4, 2026
7fec19d
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p-…
claude Nov 4, 2026
53388e2
test(mock): the mock serves every dispatched request and no root one
claude Nov 4, 2026
67faee7
test: record the refusal, header and family shapes the community plug…
claude Nov 4, 2026
b9bff93
test: the dispatch derivation reads the root shape P-R2 probes
claude Nov 4, 2026
7322b8b
test: the endpoint-family pins use stand-in route defaults
claude Nov 4, 2026
6c4c643
fix: read ModelDeprecated as gone in every probe classifier and finis…
claude Nov 4, 2026
24fcf00
fix: name the session gate a capped free walk met, and close P-R2's p…
claude Nov 4, 2026
de9bfc0
Merge remote-tracking branch 'origin/claude/vigilant-mendel-bctz9n-p-…
claude Nov 4, 2026
da3dec9
docs: record what the restack changed for P3 in the plan
claude Nov 4, 2026
f006ce6
fix: offer Settings fetch's catalog complement only once the route cl…
claude Nov 4, 2026
38f19dc
test: a harness that is the real host
claude Nov 12, 2026
9cc5cd6
test: pin the host contracts for both internal/config call shapes
claude Nov 12, 2026
2db6e7b
test: re-measure the host cells on rc 0.2.2-rc.2 and alpha 0.2.2-alpha.3
claude Nov 12, 2026
d4723c2
test: pin the bridges' route-level api set per channel, and state bot…
claude Nov 12, 2026
0a000c5
docs: put P-T1b on main 1.9.2 and name the cores and owners the revie…
claude Nov 12, 2026
6786ee2
Merge the pre-rebase tip of claude/vigilant-mendel-bctz9n-p-t1b (hist…
claude Nov 12, 2026
0b2cf31
fix: disabling or reloading the plugin restores the host methods it w…
claude Nov 12, 2026
bea5722
docs: cite the new cordis core for the shadow-method trap, and name t…
claude Nov 12, 2026
da01f95
Merge the pre-rebase tip of claude/vigilant-mendel-bctz9n-p-h (histor…
claude Nov 12, 2026
57b0851
Merge origin/main (#168) into claude/vigilant-mendel-bctz9n-p-t1b
claude Nov 12, 2026
b1d8e29
Merge claude/vigilant-mendel-bctz9n-p-t1b (#110's head, with main #16…
claude Nov 12, 2026
e13848d
Merge origin/main (#110 squash) into claude/vigilant-mendel-bctz9n-p-h
claude Nov 12, 2026
d90f066
feat: the plugin owns the opencode and opencode-go routes
claude Nov 12, 2026
0ab3fa7
fix: the route claim speaks both internal/config call shapes
claude Nov 12, 2026
9ba2290
fix: plane profiles carry pi-ai's image bounds where pi-ai defines them
claude Nov 12, 2026
d4f6557
test: the binary e2e expects the claim on both host cores
claude Nov 12, 2026
5f82bd1
test: the route claim through a pi-ai row the loader removed first
claude Nov 12, 2026
bbd924d
docs: record the new host core and the claim on both shapes
claude Nov 12, 2026
aa70a43
fix: the route claim's re-append never throws into pi-ai's status emit
claude Nov 12, 2026
1f80a51
docs: mark P-T1b and P-H merged, and put P-R1 on main 1.9.2
claude Nov 12, 2026
0b6fc99
docs: the plan's summaries say P0 to P-H are merged
claude Nov 12, 2026
974b43a
Merge the pre-rebase tip of claude/vigilant-mendel-bctz9n-p-r1 (histo…
claude Nov 12, 2026
b54b1de
test: measure which endpoint families the gateway serves
claude Nov 12, 2026
a706d44
docs: record P-R2's dispatch set re-measured on the new host core
claude Nov 12, 2026
af1de77
Merge the pre-rebase tip of claude/vigilant-mendel-bctz9n-p-r2 (histo…
claude Nov 12, 2026
e04e719
Merge claude/vigilant-mendel-bctz9n-p-h (this PR's base) into claude/…
claude Nov 12, 2026
3eb8541
feat: Settings offers the catalog's models pi does not list
claude Nov 12, 2026
60f6552
test: the F21 restart case finds pi-ai's fiber by uid on the new core
claude Nov 12, 2026
c35e6a4
test: Settings' fetch follows the claim's engagement on the new core
claude Nov 12, 2026
40bb655
test: the binary e2e's Settings fetch rows run in every cell of both …
claude Nov 12, 2026
cbca50a
docs: P3's guard on the new core, and its e2e rows in every cell
claude Nov 12, 2026
6c172fe
test: name the pi versions host-discovery's capacity check is measure…
claude Nov 12, 2026
a7cb95a
test: drive Settings' fetch guard through states the host cores reach
claude Nov 13, 2026
33925ef
Merge origin/main (#170, #159) into claude/vigilant-mendel-bctz9n-p-r1
claude Nov 13, 2026
77f538b
fix: Settings' fetch answers the catalog through a handover's restart
claude Nov 13, 2026
96789b4
docs: the plan's patch-method section reads claiming() as the other r…
claude Nov 13, 2026
fdd1ec8
Merge the pre-rebase tip of claude/vigilant-mendel-bctz9n-p3 (history…
claude Nov 13, 2026
71dae39
docs: the plan's P3 rebase note counts four cases and says which chan…
claude Nov 13, 2026
5ecc037
fix: the route claim steps aside for a plane another plugin owns
claude Nov 13, 2026
e21f99d
docs: D27, and the routes OpenCode Console serves
claude Nov 13, 2026
6527780
fix: keep the plugin off every stepped-aside plane, by realm or marker
claude Nov 13, 2026
d63a24c
docs: D27 names the realm by what each context resolves, and covers t…
claude Nov 13, 2026
a1db1d2
fix: a live change of pi-ai's realm alone moves its planes, with one …
claude Nov 13, 2026
51f4626
fix: the purge never rewrites a plane entry another plugin owns
claude Nov 13, 2026
7052ab0
test: pin the step-aside's multi-row branches and the save check on a…
claude Nov 13, 2026
574604e
docs: D27 covers a realm-only live edit and the purge
claude Nov 13, 2026
140c9c9
fix: a live realm change on the plugin's own row or a group moves the…
claude Nov 13, 2026
3c85d97
fix: a marker saved beside a second pi-ai row releases the plane in t…
claude Nov 13, 2026
d58994b
test: perform the discovery and meter step-aside through the applied …
claude Nov 13, 2026
b2d5a86
docs: D27 covers every row's realm edit and the second-row release; t…
claude Nov 13, 2026
219263f
Merge claude/vigilant-mendel-bctz9n-p-r1 (D27 step-aside, main #170/#…
claude Nov 13, 2026
d563282
test: the endpoint setting never moves a plane another plugin owns
claude Nov 13, 2026
25c8c9e
Merge claude/vigilant-mendel-bctz9n-p-r2 (D27 step-aside, main #170/#…
claude Nov 13, 2026
c1d9e86
fix: Settings leaves a stepped-aside plane's list to pi-ai
claude Nov 13, 2026
8b2fa44
fix: Settings leaves a foreign-realm row's undeclared plane to pi-ai
claude Nov 13, 2026
5c3854b
chore: refresh the generated catalog and limits tables
github-actions[bot] Nov 13, 2026
586c6b8
chore: follow the catalog refresh through the docs and tests
claude Nov 13, 2026
7534edc
docs: point the routes module header at the per-SDK counts instead of…
claude Nov 13, 2026
ff2f0d6
docs: say where the per-SDK counts live without claiming a single copy
claude Nov 13, 2026
152d0c0
docs: replace the retired muse-spark-1.3-contributor-free id in both …
claude Nov 13, 2026
37bcf0c
Merge the catalog refresh (#171) into claude/vigilant-mendel-bctz9n-p-r1
claude Nov 13, 2026
ce889ef
chore: follow the catalog refresh through P-R1's tests and docs
claude Nov 13, 2026
65b8443
Merge claude/vigilant-mendel-bctz9n-p-r1 (catalog refresh #171) into …
claude Nov 13, 2026
285aeaf
Merge claude/vigilant-mendel-bctz9n-p-r2 (catalog refresh #171) into …
claude Nov 13, 2026
3c79027
Merge main (#113) into claude/vigilant-mendel-bctz9n-p-r2 (history only)
claude Nov 13, 2026
5faf253
Merge claude/vigilant-mendel-bctz9n-p-r2 (main #113, history only) in…
claude Nov 13, 2026
da8927d
Merge main (#114) into claude/vigilant-mendel-bctz9n-p3 (history only)
claude Nov 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ It is the same trick `scripts/check.ts` already uses for the client bundle, at f
- `src/stream-hook.ts` · `src/fetch-patch.ts` · `src/tool-fallback.ts` — the `llm/stream` hook, the fetch interceptor, and the free-tier `read`/`bash` fallback.
- `src/utils/request-shape.ts` — the fetch patch's PURE decisions, extracted so each branch is unit-testable on its own: which plane a URL belongs to, which credential header a protocol reads, the URL and header source of a `fetch` input, the model id and tool names a JSON body carries, and the Anthropic version constant. Everything here is a function of its arguments — no context, no globals, no I/O. The rule it encodes: **a predicate that lives in a closure cannot be exercised alone**, so its branches survive until some integration path happens to take them. `hasSessionHeader` and `isOpenCodeRequest` were exported and tested; their six private siblings were not, and that was the difference.
- `src/key-capture.ts` · `src/go-discovery.ts` · `src/usage.ts` · `src/usage-contract.ts` — credential extraction, quota discovery, the usage service, and the shared shape.
- `src/catalog-data.ts` · `src/models-catalog.ts` · `src/models-discovery.ts` — the generated static shim, the OpenCode-catalog parser with SWR refresh, and discovery decoration. `catalog-data.ts` is **generated**; never hand-edit it.
- `src/catalog-data.ts` · `src/models-catalog.ts` · `src/models-discovery.ts` — the generated static shim, the OpenCode-catalog parser with SWR refresh, and the Settings discovery wrapper (behind `enrichModels`; off, Fetch is pi's list and `NO_DISCOVERY` passes through): on a plane the plugin serves, Settings → Models → Fetch answers pi's list plus the catalog's servable, non-deprecated models pi lacks (D3, P3), and the catalog alone while pi-ai restarts. `catalog-data.ts` is **generated**; never hand-edit it.
- A note on the sweep that found the two entries around here, because it nearly produced a false one: grepping for a symbol's callers while EXCLUDING the file that defines it makes every same-file call look like no call at all. `resolveGoKeyForRef` reads as unreferenced that way and is not — `resolveGoApiKey` calls it, and the usage service calls that. (An earlier version of this line said that is "how the Go endpoint keeps Zen keys away from itself"; there is no such exclusion, and the note below records why.) Check the defining file too before believing an export is dead.

**The general form, because this shape recurred twice in one session**: a sweep that resolves a name in the wrong CONTEXT reports a clean tree as broken. Grepping for callers without the defining file makes same-file calls look absent; resolving a doc's relative links from the repository root instead of from the file's own directory makes every link look dead. Both produced a list of confident findings and both were entirely wrong. A third instance is reading a UTC timestamp as local time and concluding that a workflow had not run since the previous evening, when it had run twenty minutes earlier — same shape, wrong context, confident conclusion. Before acting on a sweep, check that the thing being searched is the thing the claim is about, including the clock it is written in.
Expand Down
7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ The e2e files, one job each:

## The real-host harness

`test/support/host.ts` builds the host from the packages this repository installs: the harness channel `test/support/host-versions.ts` selects (the `@deepseek-ai` cluster at that channel's published tag), with pi unpatched at the newest version the bridge's range admits, or at the range's floor after `scripts/use-channel.ts <channel> --floor`. The routing work is judged against it: the contract tests pin the host facts the design rests on that the host can answer in-process (`docs/improvement-plan.md`: F1, F2, F4, F5, F8, F10–F16, F18 and F20, each by number; F6 and F19's auth half (constructing a `PiAiAdapter`) are first exercised by P-R1; F19's export half is pinned in `host-shapes` (`recordKeyFor`); F17 is honoured, not pinned — tier B fixes the apply order and the binary e2e infers it; F9 is a fact about opencode's own client, outside this host), and the characterization rows record what today's plugin does.
`test/support/host.ts` builds the host from the packages this repository installs: the harness channel `test/support/host-versions.ts` selects (the `@deepseek-ai` cluster at that channel's published tag), with pi unpatched at the newest version the bridge's range admits, or at the range's floor after `scripts/use-channel.ts <channel> --floor`. The routing work is judged against it: the contract tests pin the host facts the design rests on that the host can answer in-process (`docs/improvement-plan.md`: F1, F2, F4, F5, F8, F10–F16, F18 and F20, each by number; F6 and F19's auth half (constructing a `PiAiAdapter`) are first exercised by P-R1; F19's export half is pinned in `host-shapes` (`recordKeyFor`); F17 is honoured, not pinned — tier B fixes the apply order and the binary e2e infers it; F9 is a fact about opencode's own client, outside this host; F21 is pinned by P3 in `host-discovery`, the pi-ai restart and contract cases), and the characterization rows record what today's plugin does.

**Host cells.** The rows are measured on three cells (`HostCell` in `host.ts`): `newest`, either channel's default install (pi 1.5.2 today, one pi for both channels, so one column; a fixture case fails the day the two records disagree), and `rc-floor` and `alpha-floor` (pi 1.3.0 on both, since both bridges declare `^1.3.0`), the pi the desktop app ships. The two floors share one table today (`S0_FLOOR`, `FLOOR_CATALOG`) and stay two cells because CI and the binary e2e install each channel's floor. Where the cells differ, a row carries one expectation per cell (`forHost`, keyed by the cell's role, never by a pi version) or per channel (`forChannel`, for what the `@deepseek-ai` cluster decides: today only the route-level `api` set, below), and every tier file runs on whichever cell is installed. CI runs the unit suite, tiers A and B included, on both channels' `newest` install on every pull request and on both floors nightly and on dispatch; locally, `scripts/use-channel.ts` switches the install and the same run reads the cell from the marker it leaves. The cells differ today in pi's catalog bases (the root `/inference(/go)/v1` on 1.3.0, per-protocol roots on 1.5, whose catalog counts moved again on 1.5.2) and in which S0 ids pi can place (`PI_GAPS_BY_CELL`: 1.5 places both Go gap ids). Every supported pi's Go provider carries Google (F10's pi 1.1.0 row is gone with the rc `0.2.1` floor), and both bridges resolve the same pi-ai defaults (1_000_000 / 128_000, and `maxRequestImages` 50) but not the same route-level `api` set: rc's bridge serves `google-generative-ai` on a route, alpha's refuses it at the schema (`host-shapes`, a `[HOST_LIMITATION]` row on alpha, D26). Since P-R1 none of that moves what the plugin routes: it builds every model's protocol and base from its own catalog and endpoint table, so a characterization row differs by cell only where the host itself decides — pi-ai's defaults for an id no catalog describes (the plugin restates none) and the route-level `api` set.

Two tiers, both in-process:

- **Tier A — `mountTierA`.** A bare cordis `Context`, `LlmRuntime`, and `dsh-llm-pi-ai` mounted as a plugin with `{ providers }` (and optionally this plugin). No loader and no files. Use it for the `internal/config` waterfall and pi-ai's credential paths — anything that needs a fiber and the registry and nothing that reads a profile (`host-waterfall`, `host-shapes`, `host-credentials`). Mounted here (`plugin`), this plugin is the real one: tier A has no loader, so `mountTierA` swaps the plugin's host-module source for `hostModulesForTests` through the seam in `src/cordis-context.ts` (`replaceHostModuleSource`), restores it on dispose, and the route claim serves both planes as it does on the real host (`host-harness`, `host-planes`). pi-ai is mounted first there, so the claim restarts it once. Characterize the plugin as it ships in tier B, which keeps the default source.
- **Tier B — `bootTierB`.** dsh-app-boot's `boot()` with a temporary HOME, a test bundle and a profile patch, the way the harness's own composition tests boot one. Use it for the config editor, `settings.describe`, the loader's volatile commit and the characterization of the plugin as it ships (`host-editor-contracts`, `host-characterization`). Its rows carry **package names**, resolved by a stub module loader, not `cordis:` builtins: the plugin's default host-module source finds pi-ai's entry by `options.name === "@deepseek-ai/dsh-llm-pi-ai"` (`piAiEntry` in `src/host/host-modules.ts`), so a builtin-named row would leave the route claim without pi-ai's module. The loader starts rows in parallel, so tier B makes the order explicit: `order: "plugin-first"` (the default, and what the published binary does) or `"pi-ai-first"`. `realm: { label, credentials }` puts pi-ai's row in a `credentials` realm of its own beside a row of `realmCredentialsPlugin` that provides that fake there, the shape another plugin's setup writes (D27, `host-planes-foreign`); the plugin's row stays outside it.
- **Tier A — `mountTierA`.** A bare cordis `Context`, `LlmRuntime`, and `dsh-llm-pi-ai` mounted as a plugin with `{ providers }` (and optionally this plugin). No loader and no files. Use it for the `internal/config` waterfall and pi-ai's credential paths — anything that needs a fiber and the registry and nothing that reads a profile (`host-waterfall`, `host-shapes`, `host-credentials`). Mounted here (`plugin`), this plugin is the real one: tier A has no loader, so `mountTierA` swaps the plugin's host-module source for `hostModulesForTests` through the seam in `src/cordis-context.ts` (`replaceHostModuleSource`), restores it on dispose, and the route claim serves both planes as it does on the real host (`host-harness`, `host-planes`). pi-ai is mounted first there, so the claim restarts it once. Pass `hostModules: null` to keep the plugin's default source instead: with no loader it cannot find pi-ai's module, so the claim stands down and pi-ai keeps the planes (`host-discovery`'s stood-down case). Characterize the plugin as it ships in tier B, which keeps the default source.
- **Tier B — `bootTierB`.** dsh-app-boot's `boot()` with a temporary HOME, a test bundle and a profile patch, the way the harness's own composition tests boot one. Use it for the config editor, `settings.describe`, the loader's volatile commit and the characterization of the plugin as it ships (`host-editor-contracts`, `host-characterization`, `host-discovery`). Its rows carry **package names**, resolved by a stub module loader, not `cordis:` builtins: the plugin's default host-module source finds pi-ai's entry by `options.name === "@deepseek-ai/dsh-llm-pi-ai"` (`piAiEntry` in `src/host/host-modules.ts`), so a builtin-named row would leave the route claim without pi-ai's module. The loader starts rows in parallel, so tier B makes the order explicit: `order: "plugin-first"` (the default, and what the published binary does) or `"pi-ai-first"`. `realm: { label, credentials }` puts pi-ai's row in a `credentials` realm of its own beside a row of `realmCredentialsPlugin` that provides that fake there, the shape another plugin's setup writes (D27, `host-planes-foreign`); the plugin's row stays outside it.

What every case does:

Expand All @@ -83,6 +83,7 @@ What every case does:
`.github/workflows/ci.yml`'s `e2e-host` job installs each channel's published `@deepseek-ai/dsh` (its record's `dsh`) into a throwaway prefix with npm, the way a user installs it, builds this checkout, and runs `test/e2e/host-binary.e2e.ts`. That file creates a temporary HOME whose profile links this checkout and the probe bundle (`test/e2e/host/`) through relative `link:` paths, stores dummy keys in the temporary home's credentials document (`$DSH_HOME/.credentials.yaml`, shared by every profile under that home), boots `dsh --profile e2e --no-open --port 0`, and reads what `test/e2e/host/probe-plugin.mjs` measured. It asserts the rows `S0_TODAY_BY_CELL` records for its cell, which P-R1 flipped to the plugin owning both planes.

- **Cells, per channel, pi unpatched in both.** `npm` is the published host exactly as npm resolves it, cordis and pi included, what an npm user runs, and asserts the `newest` rows while its pi is the channel record's; a pi published since the record still has to sit in the bridge's range, but the per-model rows (a newer pi's own entry can still move a model's metadata where the catalog states none) are skipped with a warning, and the nightly `host-drift` job names the new pi. The listings before and after a turn, the save rows (the catalog-unknown id is accepted on the first try) and the row that the plane provider is built from the host prefix's own pi are asserted in every cell, since the plugin owns both planes there on either host core and none of them depends on which ids pi describes; a `[BASELINE]` row asserts that both planes are the plugin's `PlaneAdapter` whichever `internal/config` call shape the host dispatched (next bullet). `floor` is the tree the desktop app ships: npm `overrides` (`floorOverrides` in `host-versions.ts`) force the channel's whole cordis family (cordis, the loader, the include, group and timer plugins, cosmokit, schemastery) at the record's versions, which are the floors of the `~` ranges the published cluster declares (what the harness vendors at the tag), and pi with its telemetry package at the range's floor; the job and the e2e assert that npm applied each one, and the cell asserts every row of the channel's floor cell. In both cells the e2e also holds each cordis-family field to the floor of the range the installed published package declares for it, which no override rewrites, with one rule for cosmokit: its declarer is cordis, so it is checked only where the installed cordis is the record's, and elsewhere only the nightly drift report checks it (measured 2026-11-12, every cell's installed cordis is its record's, so cosmokit is checked in all four). It is cached by channel, `dsh` and a hash of those overrides, so a cache filled before the record or its overrides moved is never reused; the rest of the tree is what npm resolved when the cache was filled. The installed `dsh` must be the channel record's, so a prefix of the wrong channel fails by name. The save rows skip only where the host itself cannot save (next bullet).
- **Settings' fetch.** The probe also records what Settings → Models → Fetch offers on each plane, through the gateway's Remote face. Every cell asserts the whole servable catalog, each id once, in the Remote's five fields, and the order: the list the prefix's own pi exports (`getBuiltinModels`, read from the prefix, not the checkout) first, then the catalog models that pi lacks. The wrapper complements a fetch only while the route claim has engaged (`RouteClaim.claiming()`), which it does on both host cores, so each row first asserts both planes on the plugin's `PlaneAdapter`. It reads engaged through a handover's window too, while the newly served row's restart is in flight: the fetch is complemented until the row unloads and the plane's catalog alone while it does, as in the mount's restart. Only a served row whose restart has settled still holding a plane (a call shape the claim's listener does not speak) leaves the fetch pi's own list.
- **The host's own failures are recorded, not worked around.** Only the `npm` cell lets cordis float, as the published host's `~` ranges do for a user, and the job reports what it resolved. Where that leaves the host unable to run its own save path, the run records a `[HOST_LIMITATION]` row (titled with the channel and the `dsh`) and skips the save rows. It is detected from what the host answered, never from a version (D26): the plane edit and a control edit no plugin's listener reads (the probe's own entry) both fail with the same `TypeError` thrown by `@deepseek-ai/dsh-app-boot`; where the host saves, the row skips and a `[BASELINE]` row asserts the control was accepted. It was alpha's `0.2.2-alpha.2` as npm installed it: cordis `4.0.6-alpha.2` calls `internal/update` in a new shape while that `dsh-app-boot` registered its listener in the old one, so every config-editor save threw `next is not a function`. `0.2.2-alpha.3` and `0.2.2-rc.2` ship the cordis core their `dsh-app-boot` was written for: measured 2026-11-12, all four cells (both channels, `npm` and `floor`) save the control edit, so the row skips everywhere and the save rows run. The same core hands `internal/config` listeners the fiber and reads the config from `next()`, where the older one bound the fiber as `this` and passed the config; the route claim speaks both (`src/utils/config-run.ts`). The probe records the shape of every dispatch (`configHook`, the first; `configHooks`, a count per shape) with the claim's own fiber predicate, and a `[BASELINE]` row requires one known shape throughout and both planes on the plugin's `PlaneAdapter`. It was a `[KNOWN_DEFECT]` row asserting that pi-ai served both planes on the new core, with the rows that need the claim skipping by name, until the claim spoke that shape.
- **Triggers.** Dispatch and the nightly run take both cells of both channels. A pull request takes the `npm` cell of both channels, and only when it touches the host seam — `src/host/**` (the route claim, the plane adapter, the Settings graft, the host-module loaders) and the modules whose behaviour depends on the real loader and apply order beside it, `src/lifecycle.ts`, `src/identity.ts`, `src/cordis-context.ts` and `src/models-discovery.ts`, and the two modules that still install host-level patches until they move under `src/host/` (`src/fetch-patch.ts`, the global fetch wrapper whose order the probe reads, and `src/stream-hook.ts`) (every other row producer, such as the pure plane model and profile in `src/utils/`, `src/key-capture.ts`, `src/models-catalog.ts` or `src/config.ts`, is covered on each pull request by the in-process characterization of the same rows, and by the nightly run), `cordis.patch.yml`, `test/e2e/host/**`, `test/e2e/host-binary.e2e.ts`, `test/support/host.ts` (the rows the binary e2e asserts), `test/support/host-versions.ts` (what the job installs), `scripts/host-drift.ts` (the family table the binary e2e asserts against the installed manifests), `.github/workflows/ci.yml`, `vitest.e2e.config.ts` or `vite.config.ts` (the job's own steps and runner config; `vite.config.ts` also holds the pack config that builds `lib/index.mjs`, the bundle only this job loads into a real host, and the test settings the e2e config inherits) (scoped by a step: a workflow-level path filter would silence every other job; a diff the step cannot compute fails it rather than skipping the job). `package.json` is left out because every dependency bump touches it, so a change to its `test:e2e:host` script alone is exercised only by the nightly run. It needs no secret.

Expand Down
Loading
Loading