Skip to content

ADR 0151: compare frozen diagnostic bundles by finding fingerprint

Date: 2026-09-01 Status: Accepted

A diagnostic bundle freezes sanitized supervisor inputs, findings, timelines, explanations, thresholds, and pressure advice. Replay proves that one bundle still derives the same expected output. It does not explain how two captures differ.

Finding identifiers name incident episodes. The same underlying signal can resolve and later reopen under another identifier, so identifier equality is not a stable comparison key. Raw file or digest differences are also too broad: they reveal that bytes changed without identifying whether pressure worsened, recovered, or merely gained evidence.

Comparison is intended to establish signal quality before any decision gives diagnostics authority over dispatch or remediation. It therefore needs the same frozen-input, bounded-output, and explicit-capability rules as replay.

  • Compare expected-output digests only. A digest is useful for replay identity but cannot tell an operator what changed.
  • Match finding identifiers. Reopened episodes can carry different identifiers even when the source, kind, and scope are the same.
  • Compare a bundle with current live state. The live projection can change during the read and would make the result non-replayable.
  • Treat threshold or capability changes as ordinary finding changes. This can make a policy change look like a machine regression and missing evidence look like recovery.
  • Tune thresholds or enforce advice during comparison. That would combine the evidence gate with the authority decision it is meant to inform.

Harnery compares exactly two independently validated managed diagnostic bundles. It never reads or merges current supervisor state while comparing them.

Comparison schema 1 uses each finding’s stable fingerprint as the signal key. It retains the before and after episode identifiers and frozen finding records as evidence. A signal is added, resolved, or persistent. Persistent signals also report deterministic field changes for severity, state, occurrence count, peak value when units match, attributed owner, and declared workload relationship. Stable ordering is by change class, severity, finding kind, scope, and fingerprint.

The result compares frozen pressure advice, threshold digests, engine builds, and source capabilities. Threshold and capability changes remain explicit comparability warnings. An absent optional source is reported as unavailable; it is never converted to a zero count or healthy state.

New captures may include bounded hook-health and shadow-admission projections. Comparison summarizes only their public scalar contracts. It excludes raw hook payloads, commands, prompts, paths, tool data, error text, workflow transcripts, and child output. Existing schema-3 bundles remain valid and comparable with an explicit optional-source gap.

harn diagnostics compare <before> <after> exposes the comparison contract. The dashboard may render the same frozen result at an opaque two-artifact route. Both inputs retain the existing managed-artifact path and digest validation.

The result is marked observer_only: true. It cannot tune thresholds, deny or delay dispatch, signal processes, restart hooks, or notify people.

This decision belongs to Harnery’s diagnostic bundle, command, and dashboard surfaces. It establishes no generic object-diff protocol and grants no control authority.

Admission enforcement or hook remediation requires a separate decision backed by representative frozen comparisons, explicit host ownership, fail-safe behavior, and a rollback path.

The comparison contract shipped in 576a2ff, the dashboard in 3f1788b, the CLI guide in 7c39074, and the lightweight picker correction in 23fbd7e. Two real bundles produced the same readable and JSON digest: 769c7e6737dca144075e2b333cd35a7bad33fd5e4f8e91d1a9713157dcae2b1d. The frozen hook projection contained 50 completed invocations with no degraded, faulted, slow, high-memory, or retry result. Both shadow-admission projections kept one critical observer-only record with a 105 ms maximum wait.

The first dashboard picker called the generic artifact inventory. That scan calculates tree sizes, Git tracking, liveness, retention, and repository budgets for every managed artifact, so the route took 20 to 35 seconds on the active workspace. The final picker scans bounded bundle headers in about 11 ms and fully validates only the selected pair. Three direct route reads then completed in 4.65 to 5.42 seconds. Selection never bypasses payload digests or schemas: a corrupt candidate can appear in the picker, but comparison refuses it before rendering any result.

Page-QA run bcc9302d-a796-4e0b-b39b-3a6cc232d768 passed desktop and mobile geometry, content, contrast, interaction, and scoped critique checks with no blockers. The critique returned one low and one medium note about the digest at the right edge. The full screenshots show the complete digest inside the page margin, while the clipping and truncation gates report zero issues, so both notes were tile-crop false positives.