$DSH_HOME mixes profiles, credentials, presets, Sessions, and machine-wide policy. rc.2 ships config dumps—not a general doctor, repair, or factory-reset command.Classify before changing anything.
default ✓ · effective ✕User layer boundary.Profile patch, home patch, or named overlay. Diagnose each layer in precedence order.
default ✕Bundle boundary.Manifest, ordered Bundle patch, or module resolution failed before activation.
dumps ✓ · boot ✕Activation boundary.Preserve the first plugin, service, app-argument, or runtime-effect failure.
pnpm ✕Dependency transaction.Manifest and lock state may differ. Inspect both before retrying.
mkdir -p ./dsh-recovery-evidence
dsh --version > ./dsh-recovery-evidence/version.txt
dsh --profile web --dump-default-config > ./dsh-recovery-evidence/default.yml
dsh --profile web --dump-config > ./dsh-recovery-evidence/effective.yml
The recovery transaction.
Absolute identity, versions, hashes, file type, permissions, and explicit exclusions.
Read-only evidence identifies the first failed ownership boundary.
Every path, package operation, precondition, and inverse is visible.
Offline composition, cold boot, provider request, and authorized tool call—or exact restore.
They are independent user and security state, not disposable profile cache.
Touch a home-level patch only when the plan names it and captures its exact revision.
Capture four files first.
profiles/<name>/package.json
profiles/<name>/pnpm-lock.yaml
profiles/<name>/cordis.patch.yml
$DSH_HOME/cordis.patch.yml
dsh --profile web --dump-config > before.yml
dsh plugin --profile web add <package>
dsh --profile web --dump-config > after.yml
Compare both dumps, the manifest, and the lockfile before starting the long-lived Web process.
Live does not mean saved.
rc.2 transactional HMR keeps this generation running when a candidate edit fails.
An invalid file can remain on disk even while the old generation serves traffic.
Verify the disk candidate offline before restart. Never label a surviving process as a successful configuration save.
Reconciliation follows installed state.
It joins dsh.profile.bundles.
Its managed bundle layer leaves the list.
It stays installed but adds no layer.
It is not dependency-managed and remains untouched.
A missing entry does not by itself prove that the array was overwritten. Check dependency presence, resolution, and the installed dsh.bundle.patch declaration.
Route the first boot error.
DUPLICATE_ADAPTERKeep one route owner.A provider route has one runtime adapter. Use a distinct route or remove the original owner.
settings namespace not registeredDeclare the service.Use inject: ['settings'] when settings are required during activation.
module / schema / patch errorInspect the first named row.Use --dump-config to identify the source layer before editing.
restart never returnsMove ownership outside.A process cannot reliably run the continuation after terminating its own process tree.
Missing runtime export: choose one compatible closure.
alpha.1 requiredUpdate the plugin.Require a release that imports ToolCallId and explicitly supports the alpha.1 peer surface.
plugin requiredPin the core.Use the last compatible Harness release in a separate pinned installation and profile.
plugin optionalRemove one profile dependency.Use dsh plugin --profile web remove, inspect reconciliation, then cold boot.
compat unknownPreserve and probe.Keep the broken profile as evidence and create a clean control profile.
CallId to alpha.1 ToolCallId. Import success is not behavioral compatibility.Catalog metadata is not route ownership.
registerAdapter()Owns the live provider route and rejects duplicates atomically.
registerConfigurableProviders()Publishes advisory catalog metadata. It does not override an adapter.
Six gates before promotion.
scopeOne profile.No wildcard or whole-home deletion; unrelated state remains excluded.
CASRevision unchanged.Every mutation checks the captured hash or manifest revision first.
composeBoth dumps pass.Default and effective configuration resolve after the repair.
coldEvery row activates.A live HMR survivor is not sufficient verification.
turnOne real request.Provider and authorized tool paths both cross their runtime boundary.
inverseRestore is proven.The exact snapshot cold-boots if repair verification fails.
Report evidence, not the dead screen.
Harness version or commit:
OS and Node/pnpm versions:
Exact plugin spec:
Manifest and lockfile diff:
Bundles before and after:
First dump-config difference:
First boot error:
Clean-profile reproduction:
Primary evidence.
- rc.2 CLI profile and plugin contract
- rc.2 profile and transactional HMR contract
- rc.2 atomic write and lock contract
- Automatic repair and reset request #4735
- Third-party runtime-export mismatch #4827
- alpha.1 ToolCallId runtime brand
Use the complete repair contract.
The canonical guide includes 16 recovery gates, layer precedence, clean-profile controls, rollback semantics, and plugin conflict diagnosis.
Read the runbook