DM-** campaign decisions
One entry per decision identifier cited in the code, in campaign
order. Each says what was decided, why, and where it is enforced.
Dates are 2026; the full narratives live in CHANGELOG.md and the
commit messages of the campaign patches.
MATH-B
DM-B0
Adaptive observability reads are direct and typed: the estimator
snapshot carries its own fields, consumers stop duck-reading through
ctx.extra (adaptive_runtime_observer.py).
FIX
DM-F1
The global-stability duck default is fail-closed and identical in
both layers: a host context that never declared
global_stability_action confirms, in the math layer AND the kernel
layer. Pinned by test_global_stability_duck_default.py.
DM-F2
A host that declared no LLM runtime is a quiet, expected
configuration: the missing-binding condition is downgraded from error
noise to a documented state (pipeline_llm_service.py).
DM-F3
The projection margin measures only DANGEROUS bounds: absence of a margin is a designed state meaning no dangerous bound is in play this turn, not a sensor failure. Consumed by DM-H7 (typed absence in the Pi layer).
ALLOW / PROJ
DM-P1
The projection operator's drift REACTION is removed: drift is
observed and journaled, it no longer mutates the operator mid-turn
(math/projection/pi_operator.py).
DM-P2
Projection refresh is a post-hoc attestation, not a silent re-projection: a refreshed view is distinguishable from the view the decision was taken on (pinned by the projection tests).
SEUIL and SURFACE (shared identifier)
DM-S1
Two campaigns used this identifier; both meanings are load-bearing:
- SEUIL DM-S1: the weak-stability threshold is a REGISTERED rate rule
(weak iff
|dW| < max(0.05*W, 0.005)), registered by the owner before the campaign ran; constants live inweak_stability_policy.py; an explicitdelta_w_soft_thresholdon the context stays an absolute host override. - SURFACE DM-S1: the public contract is exactly two surfaces, the
root
arvis(11 symbols) andarvis.host_api;arvis.apiis the internal aggregator; the four deadarvis.apifacades were deleted with their absence pinned.
DM-S2
Production identity reaches both entrypoints: ArvisEngine.run_as
delegates to CognitiveOS.run_as with the exact-type stamp;
host_api exports CognitiveOS, AuthenticatedPrincipal and the
tool-policy objects; examples import only the two supported surfaces
(ratcheted).
DM-S3
The host-side CognitiveControlEngine stays in the repository,
declared for what it is: a control runtime a host may run, never the
producer of the governed verdict. A structural ratchet
(test_control_engine_isolation.py) keeps the kernel from importing
it.
DM-S4
One threading contract: the host reads the next scientific state from
view.next_scientific_state; the extra["scientific_state_next"]
echo is deprecated and kept only through the deprecation window.
DM-S5
Vocabulary is typed without moving a serialized byte: verdict
conversions are total and fail-closed in one module per boundary
(verdict_conversions.py, CognitiveGateVerdict.from_lyapunov), the
gate postures are StrEnums with the historical wire values, the dead
duplicate StabilityView was deleted and REFUS became REFUSAL.
GATE-SEM
DM-G1
The adaptive layer fails CLOSED: the switching margin is computed on
the shared DWELL_TIME_FLOOR, so an empty dwell measures a violated
condition and vetoes instead of silently disappearing;
adaptive_unavailable is a normative reason with a
REQUIRE_CONFIRMATION floor.
DM-G2
The validity envelope refuses adaptive_available=False, and (the
follow-up decision the M10 report records as DM-G2bis) the MEASURED
adaptive margin is what governs ALLOW; the assumed-constant T1
reading stays monitoring, disclosed through
switching_safe_measured.
DM-G3
The gate-kernel acceptance shortcut is reserved for its declared
case, injected scalars without a Lyapunov quadruple (cur_lyap is
None), with the recovery floor applied; the live path always runs
the full lyapunov_gate guards (worst-axis, abstain threshold).
INTEGRITY
DM-I1
api_fingerprint() is computed lazily from the real surface
(sha256 of the sorted root __all__), never the bootstrap constant;
the module __getattr__ keeps the legacy constant name working.
DM-I2
ONE canonical JSON encoder (ir/serialization/canonical_json.py:
sorted keys, compact separators, ASCII, NaN refused) behind
hash_ir, the view's ir_hash, the decision-id mint and the replay
witness; the external-verifier recipe (hash the IR, recompose the
commitment) is pinned end to end.
DM-I3
The stability view stops lying about risk: risk_ucb and
risk_verdict are exposed beside collapse_risk in the view, its
dict and the schema; the trace block separates regime from verdict.
HARDEN
DM-H1
The governed ZIP import never unlinks the host source archive;
keep_zip is an accepted no-op.
DM-H2
has_budget checks the four deterministic dimensions consume
enforces; wall-clock time stays audit-only on both sides.
DM-H3
The analyzer's supported verdict governs the content import: item
kept, content refused, skip recorded under the analyzer's reason.
DM-H4
The interrupt bus's dead pub/sub half is deleted (subscribe half and
per-process subscription set had zero callers); match routes by
explicit target. Reintroducing pub/sub is a future design act.
DM-H5
Governance fingerprints bind module + qualname (homonymous classes
cannot collide) and config_fingerprint includes
confirmation_registry; host_context (provenance, pinned doctrine)
and telemetry_sink (observe-only) are the two deliberate
exclusions, documented where they act.
DM-H6
Ambient configuration is named (ARVIS_-prefixed), lazy, validated
(a malformed value is a typed error naming the variable, never an
import crash), documented in docs/CONFIGURATION.md, and ratcheted:
an environment read outside the registry fails the gate. The
effective ZIP limits are part of config_fingerprint.
DM-H7
The Pi margin is float | None: absence is DM-F3's designed state
and stays neutral; a CERTIFIED 0.0 is the worst state and abstains;
the verdict is monotone over certified margins (the audit's
0.0-allows probe is pinned inverted).
DM-H8
Recorded sensor degradations constrain the verdict: the escalation
predicate (ErrorManager.should_escalate) is consumed by a monotone
REQUIRE_CONFIRMATION floor (sensor_degradation_floor) at the end of
the decision stack. Sensors may fail open individually; the RECORD of
their failures may not fail silent.
DM-H9
The decision constants live in one place, committed to: one kappa
band table (kappa_bands.py), one canonical
DEFAULT_SWITCHING_PARAMS, and policies_fingerprint covers both.
DM-H9c
The bootstrap small-gain check consumes the canonical switching parameters instead of its own declared alpha.
DM-H9d
theoretical_enforcement_mode is a declared, typed, reachable
context posture (MONITOR default, STRICT reachable by a host).
DM-H9e
The three constants named IR_VERSION are renamed by meaning
(envelope, schema, state-adapter payload), wire values unchanged,
compatibility aliases kept on the internal surfaces.