DSH plugin runtime invariants: InvariantInstaller checks

Concepts & ArchitecturePublished 2026-10-17Author: DeepSeek Plugin Market
DeepSeek HarnessDSH pluginInvariantInstallerruntime invariantsself-checkinvariants
How DSH plugin runtime invariants work: InvariantInstaller, package-name reservation and rollback, regex allow/block lists, and empty installers.

A DSH plugin runtime invariant is a rule a package sets for itself about what must always hold while it runs, registered and attributed through ctx.invariants. It is explicitly not a three-package capability seam and not part of the agent loop mainline: it is a support-group service where the registry handles selection, name reservation, child-fiber lifetime and package-attributed failure, while each workspace package publishes a ./invariant companion that registers under its exact npm name. The easiest thing to get wrong is what to check: official convention allows assertions over authoritative event streams or mutable data, and never checks for the existence of services or methods — that belongs to load time.

DSH plugin runtime invariants: what to assert and what not to

Bottom line: invariants guard relationships between data and events, not whether objects exist; existence belongs to dependency declarations.

  1. Assert: ordering that must never occur in an authoritative event stream, structural relationships in mutable data, cross-event count consistency.
  2. Do not assert: whether a service is registered, whether a method exists, whether a package is loaded.
  3. Violations fail: call fail() instead of logging and continuing.
  4. One companion per package: publishing and registration are exhaustive, but whether to install checks is the package's decision.

DSH plugin invariant selection: enabled plus two regex lists

Bottom line: the service is on by default; a package is selected only if the allowlist is empty or matches and the blocklist does not.

OptionMeaningDefault
enabledGlobal switchtrue
package_allowlistCase-sensitive regex sources; empty admits allempty
package_blocklistExcludes after the allowlist, with priorityempty
  1. Compilation: entries use new RegExp(source); unanchored by default, so add ^ and $ for exact matches.
  2. No /pattern/flags parsing: express flags with inline groups instead of slashes.
  3. Fail at startup: blank, whitespace-padded, duplicate or invalid entries throw instead of being skipped.
  4. May match nothing: a valid pattern can match no currently loaded package, keeping later loads and HMR deterministic.
  5. Fixed for the lifetime: do not expect filters to change while the service runs.

Writing a DSH plugin InvariantInstaller: ctx, fail and inject

Bottom line: an installer is a (ctx, fail) function; declare inject for the services you need, and synchronous or asynchronous checks both work.

ts
type InvariantFailure = (message: string) => never

interface InvariantInstaller {
  (ctx: Context, fail: InvariantFailure): void | Promise<void>
  readonly inject?: Inject
}
  1. Declare inject first: only declared services are reachable.
  2. Check in the body: call fail('...') describing which package contract was violated; the framework adds the invariant violated by "<package>": … prefix.
  3. Async is allowed: registration waits for the installer to settle, synchronously or asynchronously, before succeeding.
  4. fail returns never: reporting a violation is throwing.
  5. Verify: force one violation and confirm the message carries the right package name and code.

DSH plugin registration: reservation, child fiber and rollback

Bottom line: registration reserves one slot per full npm name; the installer runs in its own child fiber, and failure rolls back atomically.

  1. Register:
ts
ctx.invariants.register(packageName, installer)
// returns an effect-scoped disposer
  1. Reservation is strict: it holds even when filtering keeps the installer inactive, so two plugins can never claim the same name silently.
  2. Duplicates throw: repeated, blank or whitespace-containing names fail.
  3. Runs in a child fiber: enabled installers run in a dedicated Cordis child fiber, and installer.inject decides which services it can reach.
  4. Failure rolls back: a failed installer atomically disposes the child fiber and releases the reservation, so a reload can register again.
  5. Two-sided cleanup: the registration fiber belongs to the service while the returned disposer belongs to the companion plugin's fiber; unloading either side removes listeners, trace state and the reservation.

DSH plugin companion convention: empty installers need reasons

Bottom line: every package needs ./invariant; with nothing to check, the empty installer must explain why.

  1. Layout and publishing: each workspace package owns a ./invariant companion with complete export, publish, dependency and packaging wiring.
  2. Install checks only when there is an observable relationship.
  3. Otherwise write an empty installer: the leading comment must start with No runtime invariant: and explain the package specifically.
  4. Mechanical validation: pnpm run verify-package-invariants rejects generated-file markers, unexplained empty installers, non-empty installers that ignore the reporter, wrong registration names and incomplete publishing wiring.
  5. Do not invent checks to pass validation: an honest empty installer beats a fake assertion.

DSH plugin invariant troubleshooting

Bottom line: read the package attribution first, then separate a real violation from a wrong check.

  1. Package attribution: invariant violated by "<package>" points directly at the owner.
  2. Check the check: overly strict conditions — unanchored regexes, cross-event counts — report normal states as violations.
  3. Reservation conflict: two plugins registered the same npm name.
  4. Filter changes not taking effect: filters are fixed for the service lifetime; restart or recompose.
  5. Empty-installer errors: confirm the comment prefix and explanation are present.
  6. Repair status, stated honestly: selection rules, installer signature, reservation and rollback semantics come from the official Runtime invariants page and the dsh-invariants README; confirm validation commands and package conventions against the official repository.

Sources: Runtime invariants, dsh-invariants README, Plugins and lifecycle.

FAQ

What should a DSH plugin runtime invariant assert, and what must it never check?

A DSH plugin runtime invariant asserts relationships over authoritative event streams or mutable data, never whether services or methods exist. Existence is a load-time concern handled by dependency declarations and startup logs; invariants guard data states that must stay true while running.

What does the DSH plugin InvariantInstaller fail parameter do, and why does it throw?

In a DSH plugin, the InvariantInstaller fail parameter is a reporter bound to the registering package name; calling it throws an InvariantError carrying a stable code and the package name. It throws rather than returning a boolean so a violation interrupts immediately and stays attributable.

Does a failed DSH plugin invariant leave any residual registration behind?

No: a failed DSH plugin installer atomically disposes its child fiber and releases the package-name reservation. The companion plugin can therefore reload and register the same name again after a fix.

Which wins in a DSH plugin invariant config, allowlist or blocklist, and do regexes need anchors?

In DSH plugin invariant selection, blocklist matches take priority over allowlist matches, and an empty allowlist admits everything. Entries compile with new RegExp(source), so patterns are unanchored unless you write ^ and $ yourself.

Is a DSH plugin companion still required when a package has no invariants to check?

Yes, the DSH plugin companion convention requires a ./invariant for every package; with nothing to check, export an empty installer. Its leading comment must start with No runtime invariant: and explain why the package has no checks.

Related Terms

runtime invariant
A runtime invariant is a condition a DSH plugin asserts over authoritative event streams or mutable data that must always hold while running. The package publishes its own checks; the registry only selects, reserves and attributes failures.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/invariants
InvariantInstaller
InvariantInstaller is the check-installation function a package provides, typed (ctx, fail) => void | Promise<void>, optionally declaring inject for the services it needs. It runs in a dedicated child fiber and registration is not considered successful until it finishes.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/invariants
InvariantError
InvariantError is thrown when an invariant is violated; it extends Error with a stable code INVARIANT, the owning packageName, and a message prefixed invariant violated by "<package>". It keeps violations attributable without the registry importing product packages.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/invariants
package_allowlist / package_blocklist
These options are regex sources deciding which packages' invariants are enabled, matched case-sensitively and compiled with new RegExp(source). Blocklist takes priority over allowlist, and filters stay fixed for the service lifetime.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/invariants

Sources