The three release sequences shipped with publishConfig.access: restricted, so
nothing in the @deepseek-ai scope was installable from outside the organization.
A restricted dependency is what actually blocks a public consumer: every harness
package declares the vendored framework as a peerDependency, and
dsh-sandbox-local declares the Landlock entry as a dependency. Those two
sequences therefore go public first — the nine vendor/* packages and the three
native/landlock-run packages — while the dsh family stays restricted until its
own sequence is opened deliberately. No public package requires a restricted one
in this arrangement.
Access is now per sequence, so no publish path can pass --access: one flag
cannot express two levels and would override the manifest that owns the fact.
publish.ts stops passing it, matching the native workflow, and
check-workspace-constraints holds each manifest to its own sequence's level,
which is what stops the scope from drifting one package at a time.
Harness consumers reference the Landlock entry as workspace:^ instead of
workspace:*, so a published harness package accepts the entry's patch and minor
releases. The entry keeps workspace:* for its platform packages, where the
binary must match the entry version exactly.
Two rationales that named a private registry no longer describe the vendored
sequence; they now state the durable reason, which is that the verification must
not depend on the registry already carrying matching versions.
The Codex and Claude Code subagent providers were production dependencies of
@deepseek-ai/dsh-base and mounted by its Cordis composition, so every install of
the base bundle carried two providers that only some products want.
Drop both from the base bundle's dependencies and composition. The examples keep
them as explicit dependencies, base's tests lock their absence, and the product
preset e2e mounts the providers it needs explicitly.
Cherry-picked from #2387 (two commits squashed into one).
pi-ai resolves an OAuth provider from a stored OAuth credential alone, and
this adapter builds its Models collection with no credential store and runs
no login flow. `openai-codex` — the one installed provider declaring
`auth.oauth` with no `auth.apiKey` — was therefore offered on the Models page
with the keyless placeholder every pi-ai route carries, and every request on
it failed `Provider is not configured` before going out.
`catalogProviderTakesApiKey()` answers whether pi-ai's installed provider for
a route declares the one method this adapter can supply, and the directory
skips the catalog routes that fail it. Catalog membership is unchanged, so
`declared` still answers what pi-ai ships; the profile half of the union stays
unconditional, so a route a settings document already names keeps its entry
and can be edited or deleted.
Resolution is untouched: a profile naming `apiKeyEnv` on such a route still
builds a working provider.
The shipped bundles keep ctx.sessionQuery mounted but set the new
session-query-sqlite `openAt: never` phase: searchSessions/searchEvents
fail with the typed SESSION_QUERY_SEARCH_DISABLED code before any request
normalization, node:sqlite is never imported or opened, and no source
observation or reconciliation runs. Every inherited exact read, filter,
and trace — session export descendants, subagent-fork Workspace
inheritance, title reads — keeps working, and the Web sidebar search
degrades to its designed local title/workspace matching. Enabling content
search is a one-line openAt override in a later patch layer; the web e2e
scaffold keeps it enabled as the assembled opt-in coverage.
The transport schema requires both `code` and `description`, but the tool
description and both SDK instruction flavors described the call as passing a
program. `description` was reachable only through the parameter schema, so a
model following the prose emitted `{code}` alone and lost the whole written
program to an INVALID_ARGS rejection.
The length and format guidance stays in RUN_CODE_DESCRIPTION_PARAM_DESCRIPTION
alone, so the schema and the prompt cannot drift.
Fixes#2426
- stateVersion starts at 1: the package is new, no persisted rows predate it
- pendingCalls pairs by own key so a provider callId naming a prototype
property cannot fold toolMs to NaN on an unmatched crash-recovery result
- StatsLine folds the window fallback only when no sessionStats value is
served, and gates the token group on actual token activity instead of
steps, so failed-only sessions drop the zero-token group
- correct the crash-step counting semantics in the README and Agent Note:
recovery closes interrupted steps with a synthetic step/end on reload
- reword the window-scoped alternative as a plain rejected option and name
isTokenDelta's home beside the StreamChunk type
cancel-in-progress is evaluated against the newly triggered run, so
exempting push means one master merge does not cancel the drill still
running from the previous one — not that a drill always finishes. A
benchmark dispatched on master shares the group and does cancel a
mid-flight drill. Record that bound in the runbook and drop the
overstated wording from the workflow comment and the spec name.
Also repair two gates that fail on master and block every pull request:
the telemetry note referenced an SDK proposal deleted in 408721954a,
and the ui-settings-general README pair carried stale recorded hashes
after both sides were updated together in aa1ec02bc6.
The two self-hosted standby drills each run their complete unsharded
aggregate with one gate worker, which takes longer than the interval
between master merges, so unconditional cancel-in-progress supersedes a
drill before it reaches a verdict and the lane yields no readiness
evidence for the failover runbook to point a responder at.
Exempt push and nothing else. This has to be decided at workflow level:
cancellation applies to the whole superseded run, so a job-level
concurrency group cannot exempt its job. The negated form is
load-bearing — naming pull_request alone would also stop cancelling
workflow_dispatch, and each runner benchmark fans out to twelve larger
runners for up to fifteen minutes in this same group on master, so a
re-dispatch would queue ahead of a drill instead of replacing a stale
measurement. It does not promise every push run finishes: a newer
pending run still displaces an older one, only that the lanes
periodically reach a verdict.
A master push carries only wine-apt-cache and the two drills; every other
job is pull-request-gated, workflow_dispatch-gated, or if: false. The
spec pins that set and classifies by exact condition, since a negated
event test mentions the event it excludes.