core/docs/adr/ADR-0157-revision-mismatch-warning.md
Shay 54e6bfc0d0
docs: reorganize docs landscape
Implements the 4-phase documentation reorganization master plan.

- Consolidation: Merged brief/, handoff/, planning/, and decisions/ into briefs/, handoffs/, plans/, and adr/ respectively (101 ADRs relocated)
- Root Cleanup: Relocated HANDOFF-gpt55-*.md and key top-level docs (runtime_contracts.md, etc.) to canonical folders. Added superseded alerts.
- Indices & Navigation: Created docs/README.md navigation document, docs/sessions/README.md index, docs/adr/README.md index
- Note: Also includes prior commit adding ADR-0200+ corpus hygiene governance (ADR-0225, dependency map, backfilled cross-references)
2026-06-30 16:59:36 -07:00

2.9 KiB

ADR-0157 — Revision-mismatch warning on engine-state load (W-023 / L10b.2)

Status: accepted Date: 2026-05-26

Context

ADR-0146 §Risks line 127 specified:

"Compare written_at_revision in manifest.json with the current git SHA. If they mismatch, log a warning but continue startup (do not refuse to start, as a reboot is recovery, not control flow)."

W-008 and W-022 implemented the manifest write path but never implemented the read-side comparison. After a git pull or a branch switch the engine silently loads a checkpoint written by a different code version, which can produce confusing behaviour if serialization formats changed.

Decision

Inside EngineStateStore.load_manifest(), after parsing the JSON:

  1. Read manifest["written_at_revision"] (stored revision).
  2. Call _git_revision() to obtain the current HEAD short SHA.
  3. If both values are non-empty and not "unknown", and they differ, emit warnings.warn(..., RuntimeWarning, stacklevel=2).
  4. Always return the manifest — never raise, never clear state.

The warning message names both revisions and suggests clearing engine_state/ if unexpected behaviour is observed.

Why warnings.warn not logging

warnings is already used in the codebase (core/physics/identity.py). It is testable via pytest.warns without logger configuration, fits RuntimeWarning semantics (a recoverable runtime anomaly), and respects the standard Python warning filter so operators can suppress or escalate it via -W flags or PYTHONWARNINGS.

Why suppress when either side is "unknown"

_git_revision() returns "unknown" when git is unavailable (CI containers, packaged builds, offline environments). Storing "unknown" or comparing against it would always trigger a spurious warning in those environments. Suppressing when either side is unknown is the lowest-surprise behaviour.

Invariants pinned by tests

tests/test_adr_0157_revision_mismatch_warning.py (8 tests):

  • Matching revision → no RuntimeWarning
  • Mismatched revision → RuntimeWarning emitted, manifest returned intact
  • Warning message contains both the stored and current revisions
  • written_at_revision: "unknown" in stored manifest → no warning
  • _git_revision() returns "unknown" → no warning
  • Missing manifest file → None returned, no warning
  • Empty manifest file → None returned, no warning

Out of scope

  • Schema-version migration. A schema_version bump requires a migration or clear-slate fallback (ADR-0146 §Risks line 125). That is separate from the revision warning and deferred to a future ADR when _SCHEMA_VERSION is actually incremented.
  • reboot_event audit trail entry — L10b.3 / W-024.

Validation

  • tests/test_adr_0157_revision_mismatch_warning.py (8 passed)
  • tests/test_adr_0146_engine_state.py (8 passed — round-trip regression guard)
  • core test --suite smoke (67 passed)