Audit of the one-mutation-path invariant (ADR-0021 §3) found three leaks
where pack authority or session-state writes could substitute for coherence
judgment. All three landed fixes or partial closures in this push.
Leaks closed:
- Leak A: pack vocab defaulted to COHERENT — flipped to SPECULATIVE in
language_packs/{compiler,schema}.py; docstring corrected to align with
ADR-0021 (it was rationalizing the leak).
- Leak B: vault.recall was epistemic-blind — VaultStore.store() now stamps
every entry with EpistemicStatus (default SPECULATIVE); recall(min_status=)
filters to admissible-as-evidence tier. All 4 vault-write sites updated.
- Leak C (write-side): generate/proposition.py:198 stored articulated
propositions unmarked — now stamps SPECULATIVE, breaking the
fabrication-feedback loop in principle. Read-side audit of 5 call sites
is the residual.
New architectural invariants (tests/test_architectural_invariants.py):
- INV-21: one-mutation-path allowlist (caught Leak C on first run)
- INV-22: pack lexicon default is SPECULATIVE (Leak A guard)
- INV-23: vault recall epistemic-aware (Leak B guard)
New eval lanes:
- teaching_injection_resistance — ships GREEN at 1.00/1.00/0 (the
structural anti-injection claim is real and measurable)
- refusal_calibration — honest gap: 0% refusal, 0% fabrication
- contradiction_detection — honest gap: 50% flag via versor-delta heuristic,
100% false-positive; motivates the proper coherence-checker
- articulation_of_status — honest gap: 0% speculative articulation, 60%
false certainty; output-side leak surface
New benchmarks:
- benchmarks/footprint.py — total deployed runtime is 7.06 MiB
(109,358x smaller than Llama 3.1 405B, runs offline, no GPU)
- benchmarks/learning_curve.py — monotonic + replay-deterministic curve
per lane
Documentation:
- docs/truth_seeking_schema.md — foundational architectural commitment,
five rules, mapped to human failure modes, leaks published openly
- evals/CLAIMS.md — five-tier public claims doc; Tier 4.5 publishes
known gaps with named fixes; verification contract at top
- README.md — new pillar between algebraic substrate and language pillar
Includes in-flight formation pipeline scaffolding (formation/, tests/formation/,
docs/formation_pipeline_plan.md) and minor CLI/contracts/gitignore edits
that were already in the working tree at session start.
Verification: 798 passed, 2 skipped, 1 deselected (pre-existing pack-count
test drift unrelated to schema changes).
112 lines
4 KiB
Python
112 lines
4 KiB
Python
"""``MasteredCoursesIndex`` — content-addressed registry of Ratified courses.
|
|
|
|
The index is the gate-keeper consulted by every Stage 0 (Subject Spec) when
|
|
checking ``requires_courses``: a course may only run if all of its
|
|
prerequisites are Ratified.
|
|
|
|
Backing store: a single JSON file (default ``packs/mastered_courses.json``).
|
|
Append-only — entries are never overwritten or deleted by ordinary
|
|
operations. Each entry pins a ``MasteryReport`` by its self-sealing SHA.
|
|
|
|
This is governance metadata, not runtime state — it does not live in
|
|
``vault/`` (exact-recall runtime) and not in ``language_packs/`` (mutable pack
|
|
data). ``packs/mastered_courses.json`` keeps it visible in source control.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from formation.hashing import canonical_json
|
|
|
|
|
|
_INDEX_SCHEMA_VERSION: str = "1.0.0"
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class MasteredCourseEntry:
|
|
course_id: str
|
|
report_sha256: str
|
|
issued_at: str
|
|
course_sha256: str
|
|
validated_set_sha: str
|
|
|
|
|
|
class MasteredCoursesIndex:
|
|
"""JSON-file-backed, append-only registry of Ratified courses."""
|
|
|
|
def __init__(self, path: Path | str) -> None:
|
|
self._path = Path(path).resolve()
|
|
self._by_course_id: dict[str, MasteredCourseEntry] = {}
|
|
self._by_report_sha: dict[str, MasteredCourseEntry] = {}
|
|
if self._path.exists():
|
|
self._load()
|
|
|
|
@property
|
|
def path(self) -> Path:
|
|
return self._path
|
|
|
|
def _load(self) -> None:
|
|
raw = json.loads(self._path.read_text(encoding="utf-8"))
|
|
for row in raw.get("entries", []):
|
|
entry = MasteredCourseEntry(
|
|
course_id=row["course_id"],
|
|
report_sha256=row["report_sha256"],
|
|
issued_at=row["issued_at"],
|
|
course_sha256=row["course_sha256"],
|
|
validated_set_sha=row["validated_set_sha"],
|
|
)
|
|
self._by_course_id[entry.course_id] = entry
|
|
self._by_report_sha[entry.report_sha256] = entry
|
|
|
|
def _persist(self) -> None:
|
|
self._path.parent.mkdir(parents=True, exist_ok=True)
|
|
payload: dict[str, Any] = {
|
|
"schema_version": _INDEX_SCHEMA_VERSION,
|
|
"entries": [
|
|
{
|
|
"course_id": e.course_id,
|
|
"report_sha256": e.report_sha256,
|
|
"issued_at": e.issued_at,
|
|
"course_sha256": e.course_sha256,
|
|
"validated_set_sha": e.validated_set_sha,
|
|
}
|
|
for e in sorted(
|
|
self._by_course_id.values(), key=lambda x: x.course_id
|
|
)
|
|
],
|
|
}
|
|
self._path.write_bytes(canonical_json(payload))
|
|
|
|
def contains_course(self, course_id: str) -> bool:
|
|
return course_id in self._by_course_id
|
|
|
|
def contains_report(self, report_sha256: str) -> bool:
|
|
return report_sha256 in self._by_report_sha
|
|
|
|
def get(self, course_id: str) -> MasteredCourseEntry | None:
|
|
return self._by_course_id.get(course_id)
|
|
|
|
def all_courses(self) -> tuple[MasteredCourseEntry, ...]:
|
|
return tuple(sorted(self._by_course_id.values(), key=lambda x: x.course_id))
|
|
|
|
def add(self, entry: MasteredCourseEntry) -> None:
|
|
"""Register a Ratified course. Idempotent on ``(course_id, report_sha)``.
|
|
|
|
Re-registering a different report SHA for the same course_id raises
|
|
``ValueError`` — supersede paths are explicit and not handled here.
|
|
"""
|
|
existing = self._by_course_id.get(entry.course_id)
|
|
if existing is not None:
|
|
if existing.report_sha256 == entry.report_sha256:
|
|
return # idempotent
|
|
raise ValueError(
|
|
f"course_id {entry.course_id!r} already mastered under "
|
|
f"different report ({existing.report_sha256} != {entry.report_sha256})"
|
|
)
|
|
self._by_course_id[entry.course_id] = entry
|
|
self._by_report_sha[entry.report_sha256] = entry
|
|
self._persist()
|