info-tech-canon/infospace/patterns/ExplicitUnsafeDiagnosticMode.md
tegwick e0ca7de63b
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
Close out INFO-WP-0030; record second Emission Cadence declaration
INFO-WP-0030: register practice-pattern/explicit-unsafe-diagnostic-mode
(adapted from coordination-engine's OrwellLoggingDiagnostics candidate,
INFO-DEC-2026-003) at canon 0.13.0, close the assimilation, and notify
coordination-engine for COORDINATION-WP-0004-T02. Workplan finished.

INFO-WP-0029: record activity-core's source-owned declaration (T03/T04
done) with its expected-rate/calendar-schedule incompatibility as
demand/EmissionExpectedRateCalendar.md, and record audit-core's
structural-only observer evaluation of net-kingdom's declaration as a
steward note. No party has yet produced a real observer result against
traffic, so T05 and the workplan stay blocked on external action.

Updated artifact-count and practice-pattern-count assertions in
tests/test_cli.py and tests/test_service.py for the new artifact.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 317218@bnt-lap001
Assistant-Session: a8d6c0ab-c70f-4610-a288-576f44d747d4
2026-09-28 00:06:16 +02:00

11 KiB

id title type scheme status version summary aliases uses related_patterns known_uses
practice-pattern/explicit-unsafe-diagnostic-mode ExplicitUnsafeDiagnosticMode practice-pattern practice-pattern/0.1 candidate 0.1 Keep an unsafe, field-revealing diagnostic capture opt-in per invocation, refused in production, and confined to a local owner-controlled sink.
OrwellLoggingDiagnostics
model/observability
model/data
model/devsecops
tmux-amq-orwell-flag

ExplicitUnsafeDiagnosticMode

Intent

Let a rare local debugging session capture fields that normal logging must omit, without turning that capture into a standing capability: it is selectable only per invocation, refused wherever a production policy applies, written only to a sink the invoking owner controls, and never projected to any remote or shared destination.

Context

Use this pattern where a component's normal Log/LogRecord output (model/observability) must omit fields carrying credentials, message bodies, or other data a DataClassification/Sensitivity policy restricts (model/data), but an engineer diagnosing a specific local failure occasionally needs exactly those fields to see what happened. The component runs, or can run, in more than one EnvironmentPromotion stage (model/devsecops), and at least one of those stages is production or production-adjacent.

Problem

Sensitive-field omission and diagnosability compete. Omitting the fields by default protects them, but it can also hide the one detail that explains a transport or protocol failure. Relaxing omission to help diagnosis risks either leaving the relaxed mode enabled by default, letting it run in production, or letting the captured fields leave the local machine through normal telemetry, log shipping, or shared CI artifacts — at which point the exception has become a standing disclosure.

Forces

  • Diagnosis needs the exact fields normal policy omits, not a summary of them.
  • The unsafe mode must never become the default; defaults drift toward whatever is easiest to leave on.
  • A production environment cannot honor a request to disclose these fields regardless of who or what asks for it.
  • Local-only retention is only useful if it is still discoverable and removable by the person who created it.
  • Any path that projects general logs, metrics, or CI artifacts elsewhere becomes a path this data must not travel, even accidentally.
  • A warning that is easy to miss does not function as a control.

Solution

Therefore, provide a single opt-in diagnostic switch with these properties:

  1. Safe logging is the default at every verbosity. Raising verbosity alone must not disclose fields the classification policy restricts.
  2. An explicit per-invocation option selects the unsafe mode. Configuration files, inherited profile defaults, and background startup must not enable it silently — it is asked for anew, in the invocation, every time.
  3. The production EnvironmentPromotion stage refuses the option outright. Wherever it is accepted, emit a visible warning before any additional field is captured.
  4. The mode writes only to a sink the invoking owner controls, at a permission level that excludes other accounts (for example, a owner-only-readable local file). It is never added to a LogStream, metrics pipeline, State Hub event, or shared CI artifact.
  5. Document precisely which fields the mode can capture. Prefer synthetic reproduction data over live captures. The invoking owner keeps the smallest useful capture and removes it after diagnosis, using whatever procedure that sink's owner defines.
  6. Tests verify default omission, the per-invocation opt-in, refusal or absence of the option in production, sink permissions, and separation from any remote projection.

Structure

Invocation
  -> unsafe-mode option (explicit, per-call)
       -> EnvironmentPromotion check: production? -> refused
       -> visible warning
       -> Logger (model/observability)
            -> default path: LogStream, filtered by DataClassification
            -> unsafe path: local owner-only sink, never a LogStream sink

The environment check and the routing decision happen at the same configuration point the normal logger is built from; there is no second place the unsafe path could be reintroduced.

Dynamics

An operator invokes the component with the unsafe-mode option because a specific failure needs fields normal logs omit. The component checks the current EnvironmentPromotion stage; in production the option is rejected or ignored with an explicit error, and diagnosis proceeds without it. Elsewhere, the component warns, opens the local sink at a restrictive permission mode, and logs at full detail for the remainder of that invocation only — the option does not persist to the next invocation. After diagnosis, the operator reads the local sink directly and removes it; nothing from this path reaches any aggregated or shared destination.

Invariants

  1. The unsafe mode is off by default and cannot be enabled by configuration inheritance, only by an explicit per-invocation option.
  2. A production EnvironmentPromotion stage refuses the option.
  3. Enabling the option always produces a visible warning before capture.
  4. The sink is local, owner-controlled, and restricted to the owner's account (for example, mode 0600).
  5. Nothing captured under the unsafe mode reaches a LogStream, metrics pipeline, State Hub projection, or shared CI artifact.
  6. The captured field set is documented, not open-ended.

Evidence

The practice should produce:

  • a test that the default path omits the restricted fields;
  • a test that the option is per-invocation and does not persist or inherit;
  • a test — or, where the component has no production/non-production distinction at all, an explicit statement of that absence — that the option is refused in production;
  • a test that the sink is created at a restrictive permission mode; and
  • a test or code-path review confirming no remote or shared sink can receive the unsafe-mode output.

A known use that verifies only some of these should say plainly which ones, rather than implying full coverage.

Consequences

Diagnosis gets access to fields it otherwise could not see, without turning that access into a standing capability or a silent default. The cost is one more configuration branch to test, a local file an operator must remember to remove, and — for components with no existing environment distinction — the need to add one before the production refusal invariant can be verified at all.

Failure Modes

  • QuietDefault: the option is honored from a config file or an inherited profile instead of being asked for at each invocation.
  • NoProductionCheck: the component has no way to refuse the option in production because it has no environment distinction to check against.
  • SharedSink: captured output lands in the same file, stream, or aggregator the default logs use.
  • UnboundedCapture: the mode is undocumented as to which fields it reveals, so it grows to cover more than diagnosis needs.
  • SilentWarning: the mode activates without a visible notice, so an operator can leave it running without noticing.

When Not to Use

Do not use this pattern to justify collecting sensitive fields the component could avoid needing in the first place, and do not use it where a component has no local, owner-controlled place to write a sink at all — in that case the safer answer is to improve error messages and structured non-sensitive diagnostics, not to add an unsafe capture mode with nowhere safe to put it.

Known Uses

tmux-amq --orwell flag

tmux-amq implements the option at commit 04de219, in src/tamq/diagnostics.py (the configure() entry point) and src/tamq/cli.py (the global --orwell flag, plumbed through the CLI's configure(args.orwell, ...) call and a matching purge --orwell cleanup subcommand).

tests/test_diagnostics.py::test_orwell_log_is_private observes two of the invariants directly: enabling the option prints a warning containing --orwell, and the resulting log file is created at permission mode 0600 (invariant 3 and invariant 4). The per-invocation opt-in (invariant 1) is observed by construction — configure() takes orwell as a call argument with no persisted state — but has no dedicated negative test.

This known use does not demonstrate invariant 2. tmux-amq has no production/non-production EnvironmentPromotion distinction to refuse the option against; it is a local CLI tool run directly by its operator, and configure() accepts orwell=True unconditionally. Invariant 5 (no remote projection) holds by tmux-amq's general architecture — it has no telemetry export path at all — rather than by a check specific to this mode. Invariant 6 (documented field scope) is not enforced in code; the flag raises the overall log level to DEBUG and adds a file handler rather than gating a named field list.

Because one known use verifies a subset of the invariants and the pattern has not yet been observed in a component with a real production stage to refuse, this pattern stays at candidate. A second known use in a component with an EnvironmentPromotion distinction is the evidence that would test invariant 2 and could support promotion to active.

None yet. A future pattern for field-level redaction policy (which fields a DataClassification restricts, independent of capture mode) would be a natural neighbor once more than one component needs it stated generically.

Adoption Checklist

  • Confirm the component has, or can meaningfully check, a production/non-production distinction.
  • Add the per-invocation option; do not wire it to configuration files.
  • Refuse the option outright when the production stage is detected.
  • Emit a visible warning before capturing any additional field.
  • Route unsafe-mode output only to a local, owner-restricted sink.
  • Document the captured field set.
  • Give the operator a removal procedure for the sink.
  • Test default omission, opt-in scope, production refusal, sink permissions, and absence of remote projection.

Evolution

Version 0.1 generalizes the practice coordination-engine prepared as OrwellLoggingDiagnostics (INFO-DEC-2026-003, disposition adapt) from its one known use in tmux-amq. The name, canon-shape sections, and imports from model/observability, model/data, and model/devsecops are new in this version; the six practice points and the consumer boundary are carried over from the candidate. The next useful evidence is a known use in a component that actually has a production stage to refuse the option against.