Repository navigation
Conversation
Add an in-process harness that runs the plugin inside the real host,
so the routing work that follows can be measured against today's
behaviour rather than against fakes. Additive only: no src/ change.
test/support/host.ts gives two tiers. Tier A is a bare cordis Context
with LlmRuntime and llm-pi-ai mounted with { providers }, for the
config waterfall and pi-ai's credential paths. Tier B is dsh-app-boot's
boot() with a temporary HOME, a test bundle, a fake credentials service
and a launch-environment snapshot, for the config editor,
settings.describe and the volatile commit. Tier B's rows carry package
names through a stub module loader, and it fixes the apply order,
because the loader starts rows in parallel.
On top of it:
- contract tests for the waterfall, the profile and Config shapes,
credentials, and the config editor (host-waterfall, host-shapes,
host-credentials, host-editor-contracts), plus a tier A smoke test;
- a characterization of today's behaviour on pi 1.1.0, each row tagged
where P-R1 is expected to flip it, with S0_TODAY shared by the
binary e2e;
- the keyless 401-vs-404 matrix: a pure classifier, its unit test and
a gated live run;
- a binary e2e gated on DSH_HOST_E2E=1 with its probe bundle, the
e2e-host CI job (a pinned, patched cell on PRs that touch the host
seams or vite.config.ts, and a floating cell nightly and on
dispatch), and the test:e2e:host script.
The binary e2e now reports why a run failed: a timeout only when its
own deadline killed the host, the signal for a crash, and the probe's
fatal message whenever there is one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
|
The fix is the nightly scheduled run on Generated by Claude Code |
The review ran three rounds through the correctness, rules and matrix lenses. What it found, and what changed: - The binary e2e's beforeAll budget was smaller than the blocking subprocess deadlines it serializes. Each plugin install now has its own deadline, the hook's budget is derived from the installs and the boot, and afterAll stops a host a failed hook left running. - providerWithApiKey claimed to be a line-for-line restatement but skipped upstream's credentialRef(ref) check. It now throws the same TypeError for a ref outside the grammar (a host-editor-contracts case pins it), and its comment names the deliberate differences. - The pinned e2e-host cell let cordis and the loader float at patch level. The overrides now force both, the cache key includes them, and the job asserts them against HOST_VERSIONS. - The pi-ai-first characterization asserted every facet under one KNOWN_DEFECT title. Each apply order now generates one test per row and facet, titled with that order's own tags. - CONTRIBUTING said the contract tests pin F11-F20, and the plan said P-T1 pins every fact. Both now give the same accounting: which facts are pinned by number, which P-R1 exercises first, and why F9 and F17 are not pinned. - CONTRIBUTING put the e2e's dummy keys in the profile's credentials file; they are in the temporary home's credentials document. - F5 had no real-host pin: host-shapes now pins that a route-level api and baseURL collapse pi's protocols onto one. F6 is recorded as first exercised by P-R1. - The credential-mapping row pinned only the api-key branch of toPiCredential. host-credentials now covers all three branches, and the env branch is asserted through pi's Models.getAuth, so the case fails without it. - The plan's reason for restating hasProviderApiKey was inaccurate; it now says no installed copy reaches the function. - The new credential cases cited toPiCredential at the wrong lines; they now cite auth.ts:74-84. - F4's listing and dispatch halves were pinned only by KNOWN_DEFECT rows P-R1 flips. A plugin-less tier-A case in host-shapes now pins that an id pi cannot place is not listed and that a turn on it is INVALID_CONFIG with no request; the save and deferred-read halves are tagged F4 too. - The one facet that depends on the apply order lost its tag when the pi-ai-first block was split. The fixture case now checks only structure (the facets whose value moves are the facets whose tag moves), and the exact pin is its own KNOWN_DEFECT case that boots no host. CONTRIBUTING and the plan say P-R1 drops todayRowsFor's override and turns that case into a BASELINE check in the same diff. Nothing under src/ changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
|
This phase's first reviews ran on the general reviewer because the dedicated reviewer was unavailable. It has now had the dedicated review. Rounds (by lens: correctness, rules, matrix)
All upheld findings were low severity. Fixed
Declined No upheld finding was declined. The other findings (4 in round 1, 1 in round 2) did not survive verification, so they were left alone. Nothing under Commit: 409b5e1 Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
The vendor renamed the Go plane's Gemini model from gemini-4-argon-contributor to gemini-4-argon. The tier-B fixtures (S0_PROFILE, S0_TODAY, CHARACTERIZED_PROFILE through S0, and todayRowsFor's pi-ai-first override) declared the old id as the Go gap id: one the plugin's catalog describes and pi 1.1.0 cannot place. After the refresh the catalog no longer described it. They now name the renamed id, which still plays that role because pi 1.1.0's opencode-go table has no gemini-4-argon either. The host-shapes and editor-contract cases follow the same fixture. The pi 1.3.0 note in mount-protocols names that pi's own row, so it stays as it is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
…nt-mendel-bctz9n-p-t1b # Conflicts: # CONTRIBUTING.md
…nt-mendel-bctz9n-p-t1b
…nt-mendel-bctz9n-p-t1b
…t1a' into claude/vigilant-mendel-bctz9n-p-t1b Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
… floor The rows were measured on pi 1.1.0 with the harness patch, a host no npm user runs. Each tier file now runs on whichever host cell is installed (either channel's newest pi, or a channel's floor), and a row carries one expectation per cell where the hosts differ: pi's catalog bases, the ids pi can place, F10 and pi-ai's own defaults. Facets pi 1.5.0 already serves the way P-R1 keeps are BASELINE on that cell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
…he floor The e2e-host job installed one host with pi forced to the harness pin and patched. It now runs per channel with pi unpatched: the npm cell on pull requests touching the host seam, the floor cell nightly and on dispatch, each asserting its own cell's rows. A pi newer than the channel record skips only the pi-dependent rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
CONTRIBUTING, the repo map and the plan still described one pinned, patched pi and a floating cell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
Review outcomes of the two-channel restack, without a channel bump: TODAY_DISPATCH is the rc floor's (the desktop app's pi 1.1.0) and NEXT_DISPATCH is where both channels' npm install already sends completions; the decoration case asserts per cell and route whether the wire went to the repaired base instead of an always-true comparison; the characterization header, the plan and CONTRIBUTING name the per-cell tables and the HOST_LIMITATION tag, which no P-T1b row carries; the probe artifact keeps a seven-day retention. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
The alpha channel's npm install of 0.2.2-alpha.2 now resolves cordis 4.0.6-alpha.2, whose new internal/update call shape breaks the host's own dsh-app-boot listener: every config-editor save throws before any plugin runs, so both alpha cells of the binary e2e failed their save rows. The plugin cannot fix that (D26). The probe now names the error class and the package that threw it, and the e2e records a HOST_LIMITATION row and skips the save rows when the host's own code throws, detected from the answer and never from a version, so a fixed host runs them again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
…ost-limitation check The review of the P-T1b restack upheld fifteen findings; each outcome: - both-kept-1-F1 (fixed): the floor cell is now the tree the desktop app ships. The channel records name the whole cordis family (cordis, the loader, the include/group/timer plugins, cosmokit, schemastery), and `floorOverrides` forces it with pi at the range floor through npm `overrides`. The report step and the e2e assert every member on the floor cell; the npm cell stays fully npm-resolved. harness-channel holds each lockfile to the record's family (timer is the one member no lockfile resolves; the floor cell asserts it). Measured: with the pinned family the alpha floor saves, so the limitation is npm-only. - resolutions-1-T1B-R3 (fixed, with F1): the floor cache key is the channel, its dsh and a hash of the overrides, so a fill never freezes cordis. - both-kept-1-F2 (fixed): the detector matches only a TypeError thrown by dsh-app-boot, and HOST_LIMITATION needs a control to fail the same way: the probe now also edits its own entry, which no plugin listener reads. A mutant whose control saves while the plane edits fail turns both save rows red on the alpha npm cell. - resolutions-1-T1B-R2 (fixed): the row is titled as the limitation (channel, dsh, cell), skips where the host saves, and a BASELINE row asserts the control is accepted there. - both-kept-1-F3, resolutions-1-T1B-R1, rules-docs-1-PT1B-DOCS-1 (fixed in one edit): release step 3, D22'' and P-T3's two rows say a bump is data only while tiers A/B and the binary e2e stay green; one that turns them red re-measures the newest tables or adapts the tier listeners in its own reviewed pull request. The cordis alpha.1 to alpha.2 example is replaced, and the alpha.3 bump is named as the first such case. - both-kept-1-F4, rules-docs-1-PT1B-DOCS-3 (fixed): plan step 5 says no in-process row carries the tag and the binary e2e records one host-code defect; RowTag in host.ts holds the one definition, and the plan's tags bullet, CONTRIBUTING and host-characterization point to it. - both-kept-1-F5, rules-docs-1-PT1B-DOCS-2 (fixed): the two e2e-host bullets are rewritten, with no duplicate and no "always run"; the local floor snippet writes the record's overrides. - resolutions-1-T1B-R4 (fixed): the P-T1b restack row describes what landed: per-cell rows, pi-ai's defaults per channel, INVALID_CONFIG for the unknown id on every cell. - rules-docs-1-PT1B-DOCS-4 (fixed): the F10 row and the test list say per host cell. - rules-docs-1-PT1B-DOCS-5 (fixed): CONTRIBUTING and WHOLE_CATALOG's doc state the measured net change. - rules-docs-1-PT1B-DOCS-6 (fixed): the restack's comments name the ids by role or constant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
The record's cordis family meant two things: what the cluster's `~` ranges resolve on npm (the field docs, the drift report, release step 3) and the tree the desktop app ships (the e2e-host floor cell's overrides). They already disagree for alpha. The fields now have one meaning, the floor of the range the published cluster declares, which is what the harness vendors at the tag, what package.json pins and the lockfile holds, and what the floor cell forces. The family moves only with dsh. - fixed: both-kept-2-R2-F1, resolutions-2-T1B-R2-1, rules-docs-2-R2-RD-1. scripts/host-drift.ts compares every family member with the floor of the range its published declarer declares (FAMILY_DECLARERS: the bridge for cordis, the loader and schemastery; dsh for include and timer; dsh-app-boot for group; cordis at the cordis floor for cosmokit), not the newest patch inside it. host-drift.test.ts has a known answer for today's registry (alpha.2 patches inside alpha.2's ranges: no line), the next cut (eight lines, one per moved field) and the timer case. The test failed before the change. Docs follow in host-versions.ts, ci.yml, CONTRIBUTING (release step 3: a family patch under an unchanged dsh is not a bump), D22'' and AGENTS.md. - fixed: both-kept-2-R2-F2, resolutions-2-T1B-R2-2. The record is no longer its own witness. The binary e2e, in both cells, holds each family value to the floor of the range the installed published package declares (a mutated timer fails it). harness-channel.test.ts holds the five members the cluster peers on to the lockfile's declared peer ranges, and the drift report checks the timer plugin nightly. The comments now say what each check asserts. - fixed: both-kept-2-R2-F3, resolutions-2-T1B-R2-3. CONTRIBUTING and the plan make ci.yml's narrower cache claim: a cache filled before the record or its overrides moved is never reused, and the rest of the tree is what npm resolved at the fill. There is no time component in the key. floorOverrides also pins @earendil-works/pi-telemetry at piFloor, so the rc floor cell runs the desktop's pi pair (1.1.0/1.1.0) instead of 1.1.0 with telemetry 1.5.0. - fixed: rules-docs-2-R2-RD-2. Release step 3 and D22'' say a bump that moves piFloor or a family field is green only after a workflow_dispatch run on its branch, which adds the floor cells. The re-measure list names the floor tables (S0_RC_FLOOR/S0_ALPHA_FLOOR and the floor columns of WHOLE_CATALOG and PI_GAPS_BY_CELL), and P-T3's bump-PR row dispatches the floors. The PR matrix stays as decision (3) sets it. - fixed: rules-docs-2-R2-RD-3. RowTag, CONTRIBUTING's Tags paragraph and the plan's tags bullet scope HOST_LIMITATION by channel and install: a host cell for an in-process row, an e2e-host cell (npm or floor) for the binary e2e. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
A relock re-resolves include, group and cosmokit, which arrive only transitively, at the newest patch their `~` ranges admit; once the harness publishes one, the lockfile family case fails on the next routine dependency change. Measured: a fresh resolve of the alpha lockfile with the release-age window lifted takes the alpha.2 patches. - fixed: rules-docs-3-RD3-2 - package.json pins include, group and cosmokit like cordis, the loader and schemastery, and pinFor moves each with the channel; pnpm resolves those peers from the root pins and dedupes cosmokit onto its pin, so a fresh resolve now holds the floors (overrides were tried and rejected: pnpm rewrites the lockfile's peer ranges with them, which would make the peer-floor witness compare the record with itself). A new harness-channel case requires every resolved member to be a direct pin (failed on both lockfiles before), and use-channel.test.ts holds the new rules. Both lockfiles relocked; only importer entries changed. CONTRIBUTING (relock rule, release step 3), AGENTS.md and D22'' say a relock keeps the family at the floors. - fixed: rules-docs-3-RD3-5 - the host-versions.ts and host-drift.ts headers say package.json pins every member the install resolves (all but the timer plugin), so each lockfile holds the floors by construction. - fixed: both-kept-3-R3-1 - the harness-channel timer comment names the binary e2e and the drift report, not "the next case"; the cosmokit rule (checked only where the installed cordis is the record's, otherwise only by the drift report; today not on alpha's npm cell) is stated in CONTRIBUTING, plan step 1 and the e2e header. - fixed: resolutions-3-T1B-R3-4, rules-docs-3-RD3-4 - same edit; "each record value" narrowed to "each cordis-family field". - fixed: both-kept-3-R3-2, resolutions-3-T1B-R3-2, rules-docs-3-RD3-3 - scripts/host-drift.ts added to the e2e-host scope regex, with its reason in the comment, CONTRIBUTING's Triggers and the plan's "When it runs". - fixed: resolutions-3-T1B-R3-1, rules-docs-3-RD3-1 - the docs/testing.md row states the floor rule for all seven members and the known answers. - fixed: resolutions-3-T1B-R3-3 - the FAMILY_DECLARERS doc says the drift report reads the dist-tagged cluster and the e2e the record's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141fKp5k6hiaJcP5ovhGtSD
|
Restacked onto main 1.8.0. This branch now carries Conflicts and how they were resolvedDocs
Code (the merge had no textual conflict but was wrong)
Dropped
Review rounds
Round 3's main fixes:
Live re-measures still owed
Follow-ups
The dedicated reviewer was unavailable, so all twelve review and verify passes ran on the general reviewer: Generated by Claude Code |
Phase P-T1b of docs/improvement-plan.md, stacked on #109.
An in-process harness that runs the plugin inside the real host, so the routing phases that follow (P-H, P-R1, P-R2) are measured against today's behaviour rather than against fakes. Additive only: no
src/change.What changed
test/support/host.tsContextwithLlmRuntimeanddsh-llm-pi-aimounted with{ providers }, for theinternal/configwaterfall and pi-ai's credential paths.test/support/host.tsboot()with a temporary HOME, a test bundle (llm,llm-pi-ai,editor: ConfigEditor,settings: Settings, the plugin), a fake credentials service and a launch-environment snapshot. Rows carry package names through a stub module loader, because the plugin finds pi-ai byoptions.name. The apply order is fixed (plugin-first, as the binary does it, orpi-ai-first), because the loader starts rows in parallel. It also rebuildshasProviderApiKeyasproviderWithApiKey.test/host-waterfall.test.ts,test/host-shapes.test.ts,test/host-credentials.test.ts,test/host-editor-contracts.test.tsprependputs it outermost,raw === _configholds for_reload/update/_commitVolatilebut not for the editor candidate (F14), and a deep-frozen input is never mutated while the fiber keeps the return value (F12). Shapes: the profile shape, theConfigdefaults snapshot,recordKeyFor, no secret-role nodes, the loader's interpolation and pi's public exports. Credentials. Editor:configEditor.editwritesrawbeside the YAML,_commitVolatilere-resolves through a prepended listener, andsettings.describeandhasProviderApiKeyget baselines.test/host-harness.test.tslistProviders()equals pi-ai's keys (F11), and each builder option is exercised once.test/host-characterization.test.tsKNOWN_DEFECTorINTENDED_CHANGEwhere P-R1 is expected to flip it.S0_TODAYis shared with the binary e2e.test/support/keyless-matrix.ts,test/keyless-matrix.test.ts,test/e2e/keyless-matrix.e2e.tstest/e2e/host-binary.e2e.ts,test/e2e/host/DSH_HOST_E2E=1and readingDSH_HOST_PREFIX..github/workflows/ci.yml,package.jsone2e-hostjob. Cell a: pi 1.1.0, pinned and patched, on PRs that touch the host seams,cordis.patch.ymlorvite.config.ts. Cell b: whatever npm installs, nightly and on dispatch. Adds thetest:e2e:hostscript.AGENTS.md,CONTRIBUTING.md,docs/improvement-plan.md,test/support/src.ts,vite.config.tsin review), the test door, and the e2e config base.Behaviour changes
src/changes.e2e-hostjob also runs on pull requests that touchvite.config.ts. That file holds the pack config forlib/index.mjsand the test settings that the e2e config inherits.dshinstall helper reports spawn errors and signals instead of "exited null".Review
Three lenses (correctness, tests, repo rules), three rounds. No reviewer was missing in any round.
Each round's upheld findings were fixed before the next round ran. Round 3's four findings are fixed in this commit:
endpoint: legacywording is narrowed. Go's Google traffic stays on the modern cell under every family.whyRunFailedseparates timeouts, signal deaths and fatal probe results.vite.config.tsis added to the e2e-host scope.hasProviderApiKey.Verification
pnpm run checkvp test runvp test run --config vitest.mock.config.tspnpm run buildscripts/check.tsvp test run --coveragesk-hit is the fixturesk-ambient-go-not-a-key. A canary file gave the expected hits, so the scan did read its input.The first five rows were run again right before the commit. The rest come from the implementation run on the same tree.
Note: the
catalog freshnesscheck fails on every branch until the vendor-catalog refresh lands onmain. That failure is unrelated to this PR.Restacked onto main 1.8.0
The branch now carries
main1.8.0 through its parent, P-T1a (#109), merged in atfb6a686. Head:ec38185.New scope
A harness that is the real host, on both harness channels.
test/support/host.ts), the contract tests and the tagged characterization run on whichever channel install is selected. On every PR they run on alpha and rc newest (pi 1.5.0), through P-T1a's CI matrix. Each channel's floor (pi 1.3.0 on alpha, 1.1.0 on rc, unpatched) runs nightly.S0_TODAY_BY_CELL,forHost,forChannel). The rows that differ: pi's catalog bases, the ids pi can place, F10 (pi wires Go's Google protocol natively from 1.3), and pi-ai's default window and max tokens (these follow the bridge, so they are keyed by channel).TODAY_DISPATCHis the rc floor's: legacy/zen(/go)/v1completions plus the modern Responses, Messages and Google routes.NEXT_DISPATCHis what npm installs already reach: modern/inference(/go)/openai/v1completions.e2e-hostjob boots each channel's published binary the way npm installs it. Thenpmcell runs on PRs that touch the host seam. Thefloorcell runs nightly and on dispatch, pinned to the recorded cordis family. No cell applies a pi patch.package.json, and the channel switch moves the pins. A relock therefore keeps each lockfile at the record's floors. A newharness-channelcase requires every family member the lockfile resolves to be a direct pin.[HOST_LIMITATION]row. The row is detected from the host's answer, never from a version. Today there is one: on alpha0.2.2-alpha.2, npm resolves cordis4.0.6-alpha.2, and under it no config-editor save succeeds. The two save rows skip on both alpha cells.Dropped because main or the parent now covers it
pinnede2e-hostcell (pi forced to 1.1.0, harness patch applied withpatch -p1, cordis and loader overrides, cache key onpatches/*.patch) and thefloatingcell. Under D14'' they are replaced by the per-channelnpmandfloorcells, both with unpatched pi.patches/line in the AGENTS.md repo map and thepatch -p1step in the CONTRIBUTING local-run snippet. There is no pi patch (D14'').0.2.2-alpha.3bump and the cordis waterfall-shape rewrite of the tier listeners. They came from an earlier, unpushed attempt. The records stay at alpha.2, as P-T1a has them, and the bump is a follow-up (see below).Decisions applied
patches/line exist.test/support/host-versions.ts. The rows read their cell from the record, and the plan text was returned to P-T1a's version wherever the earlier attempt had moved it to alpha.3.HOST_LIMITATIONrow, and why the row is detected from the host's answer rather than from a version.src/, which this phase does not touch, so neither applies here.Live re-measures CI must confirm
e2ejob (keyless matrix, every PR): no path-gone verdict onTODAY_DISPATCHor onNEXT_DISPATCH.e2e-hostnightly or dispatch: both floor cells (rc pi 1.1.0, alpha pi 1.3.0) and bothnpmcells on the CI runner. The alpha cells must still record theHOST_LIMITATION, or stop recording it once the host is fixed. npm must still resolve cordis4.0.6-alpha.2for dsh0.2.2-alpha.2.host-driftjob: it should now report dsh alpha0.2.2-alpha.3(and cordis, loader and schemastery alpha.2) against the alpha record.Generated by Claude Code