ADR-0021 v1 schema land. epistemic_status is a position in the revision
graph, not a source-trust tier — coherence is the only admission signal.
Surfaces:
- teaching/epistemic.py: EpistemicStatus enum (COHERENT, CONTESTED,
SPECULATIVE, FALSIFIED); ADMISSIBLE_AS_EVIDENCE = {COHERENT}.
- PackMutationProposal.epistemic_status (default SPECULATIVE) + immutable
with_status() updater.
- ReviewedTeachingExample.epistemic_status (default SPECULATIVE);
orthogonal to acceptance per ADR §Schema impact.
- LexicalEntry.epistemic_status (default "coherent" for seed; absent in
JSONL is treated as the seed default — no retroactive tagging).
- compute_trace_hash + trace_hash_from_result + pipeline.py fold the
load-bearing proposal's epistemic_status into the trace hash so
replay detects different epistemic frames.
Non-hardening invariant (ADR-0021 §2): tests/test_epistemic_invariants.py
asserts no final/frozen/axiom/permanent flag on PackMutationProposal or
ReviewedTeachingExample, and EpistemicStatus contains no source-trust
tier names.
Docs: docs/runtime_contracts.md gains an Epistemic surface section.
Lanes green: smoke 27/27, teaching 10/10, packs 6/6, runtime 19/19,
cognition eval 100%.
Introduces teaching/ module with three-stage correction pipeline:
1. correction.py — extracts CorrectionCandidate from correction intents,
binding correction text to the prior turn it references
2. review.py — validates candidates: rejects identity overrides (17
marker patterns) and empty corrections; produces ReviewedTeachingExample
with deterministic SHA-256 review hash
3. store.py — bounded FIFO store for accepted examples; emits
PackMutationProposal objects instead of mutating the vocab manifold
directly; retrievable by subject
Design invariants:
- Identity override attempts are rejected at the review gate
- Pack mutations are proposal-only (applied=False by default)
- All traces are deterministic: same input → same candidate_id and review_hash
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>