# Compatibility and reviewed baseline

v0.3.0 has one reviewed/tested baseline: the published
`@deepseek-ai/dsh-base@0.1.0-rc.6` and
`@deepseek-ai/dsh-web-app@0.1.0-rc.6` `cordis.patch.yml` artifacts. The
baseline captures the roster, unique ids, exact package identity, and reviewed
declared `inject` values. `pnpm verify:baseline <base-patch> <web-patch>`
rechecks those mechanical claims.

The safe-leaf `provides`/consumer conclusion is intentionally a human review:
the current public Loader seam does not publish a complete consumer graph.
Automation must not upgrade that absence into a proof.

## Updating a reviewed release

1. Obtain the two published npm artifacts and preserve their exact versions.
2. Run the baseline verifier, investigate every roster/package/inject change,
   and separately re-review each candidate leaf's service and consumer impact.
   Manually re-review the copied, security-sensitive browser trust-fence
   semantics against the reviewed DSH release before accepting it.
3. Keep new official capability IDs `unknown` and locked until a separate
   architecture/security review explicitly changes the evidence and policy.
4. An allowlist expansion is never a compatibility update; it requires that
   independent review even if the new row looks like a UI plugin.

Later public releases may still install or run, but are not automatically a
supported/reviewed baseline. The compatibility workflow runs its reviewed rc.6 gate on pull requests,
schedule, and manual dispatch. It exercises frozen artifacts, this PR's actual
package tarball, legacy/v1 APIs, force/restart/restore state transitions, and
the local package gate. The current-public lane compares the corresponding
published base/web patch roster, package identities, and inject declarations
to the reviewed baseline and uploads a machine-readable difference report. It
is early-warning observation only, not an automatic support upgrade, baseline
change, or allowlist change. GitHub source/master is likewise not support
evidence.

`verified` means a Host-owned runtime identity and all reviewed structural
evidence match. `drifted` means a direct structural difference or a trusted
identity mismatch. `unverified` means no difference was observed but the proof
is incomplete (for example, the Host exposes no bindable release identity).
The API's entry counts count entry assertions only; composition identity is
reported separately and is never fabricated as an entry. A live Host without
that stable public runtime identity remains `unverified`; it must not be
upgraded by package resolution, private Loader fields, or a guessed version.

Duplicate detection is scoped by the Loader's public `Entry.id` (the
tree-owner-qualified identity). The published base/web patches and a
per-session Agent Preset legitimately share bare ids (`tool-bash`,
`plan-mode`, …); those rows live in different composition scopes
(`include:tool-bash` vs `include:agent-presets:tool-bash`) and are not
`duplicate_runtime_id`. A repeated `scopeId`, or two Host rows claiming the
same bare id, is a genuine collision: it stays `drifted` and fail-closed for
mutation. Per-session Agent Preset rows are runtime augmentations, not Host
release evidence: they never satisfy or violate the reviewed baseline and are
not counted as `new_official_entry`. The inspection DTO also locks them at the
server: a preset row always projects `policy=locked` (reason
`agent-preset`) and `mutationEligibility=ineligible` (reason
`agent_preset_scope`); the client additionally hides controls for non-Host
rows as defense in depth. The v1 `profileOverride.state` /
`profilePersistence.status` value domains stay closed: a preset row
conservatively projects `unavailable`/`unwritable`, and the additive
`configuration.profileApplicability` field (`"applicable"` /
`"not-applicable"`) carries the real "not governed by the Web profile"
semantics, which anomalies-only treats as non-anomalous.
