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).
159 lines
4.4 KiB
Python
159 lines
4.4 KiB
Python
"""Frozen dataclasses for every Formation Pipeline artifact.
|
|
|
|
These are pure data carriers — no behavior, no IO. Each carries a
|
|
``schema_version`` so future migrations can detect mismatch at load time.
|
|
|
|
Serialization is via canonical JSON (``formation.hashing.canonical_json``).
|
|
SHA-256 of the canonical form is the content address.
|
|
|
|
Trust regions, left to right:
|
|
OreBundle (UNTRUSTED)
|
|
ValidatedTripleSet (REVIEWED — passed the Forge)
|
|
CourseYAML (REVIEWED — composed from validated triples)
|
|
FormationPlan (REVIEWED — compiled from CourseYAML)
|
|
MasteryReport (RATIFIED — self-sealed; only this authorizes promote)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
from formation.candidate import (
|
|
ConceptCandidate,
|
|
CounterCandidate,
|
|
OrderingHint,
|
|
RelationCandidate,
|
|
)
|
|
|
|
SCHEMA_VERSION: str = "1.0.0"
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class SubjectSpec:
|
|
"""The one human-authored artifact in the chain.
|
|
|
|
Generated by ``core formation new <subject_id>`` as a YAML stub; edited
|
|
by the user; loaded into this dataclass for everything downstream.
|
|
"""
|
|
|
|
subject_id: str
|
|
title: str
|
|
target_depth: str # e.g. "introductory", "working", "expert"
|
|
requires_courses: tuple[str, ...] = ()
|
|
anti_requisites: tuple[str, ...] = ()
|
|
identity_axis_constraints: tuple[str, ...] = ()
|
|
schema_version: str = SCHEMA_VERSION
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class OreEntry:
|
|
"""A single mined source: URL, bytes-SHA, retrieval metadata."""
|
|
|
|
source_sha: str
|
|
url: str
|
|
adapter: str
|
|
retrieved_at: str # ISO-8601 UTC
|
|
byte_length: int
|
|
citation: str = ""
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class OreBundle:
|
|
"""The output of Stage 1 (Mining). Untrusted material."""
|
|
|
|
subject_id: str
|
|
entries: tuple[OreEntry, ...]
|
|
schema_version: str = SCHEMA_VERSION
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class ValidatedTripleSet:
|
|
"""The output of Stage 3 (Forge). First artifact the rest of CORE can lawfully see.
|
|
|
|
Every entry here has passed every Forge rule and carries
|
|
``EpistemicStatus.SPECULATIVE`` once handed to the teaching layer.
|
|
"""
|
|
|
|
subject_id: str
|
|
concepts: tuple[ConceptCandidate, ...]
|
|
relations: tuple[RelationCandidate, ...]
|
|
counters: tuple[CounterCandidate, ...]
|
|
ordering_hints: tuple[OrderingHint, ...]
|
|
quarantined: tuple[RelationCandidate, ...] = ()
|
|
schema_version: str = SCHEMA_VERSION
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class CourseYAML:
|
|
"""The output of Stage 4 (Compose). Deterministic, byte-stable."""
|
|
|
|
course_id: str
|
|
yaml_bytes: bytes
|
|
course_sha256: str
|
|
source_bundle_sha: str
|
|
validated_set_sha: str
|
|
template_id: str
|
|
template_version: str
|
|
schema_version: str = SCHEMA_VERSION
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class PlanStep:
|
|
"""One step of a FormationPlan.
|
|
|
|
``step_type`` is one of:
|
|
"seed_concept", "introduce_relation", "walk_step",
|
|
"adversarial_probe", "replay_assertion".
|
|
``payload`` is a JSON-serializable dict; floats are forbidden.
|
|
"""
|
|
|
|
step_type: str
|
|
payload: dict[str, object]
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class FormationPlan:
|
|
"""The output of Stage 5 (Compile). Deterministic given the same CourseYAML."""
|
|
|
|
course_id: str
|
|
course_sha256: str
|
|
steps: tuple[PlanStep, ...]
|
|
plan_sha256: str
|
|
schema_version: str = SCHEMA_VERSION
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class GateMeasurement:
|
|
"""One gate's outcome at ratification time.
|
|
|
|
Numeric values are stringified to keep canonical JSON deterministic.
|
|
"""
|
|
|
|
name: str
|
|
passed: bool
|
|
measurement: str # stringified numeric or descriptor
|
|
threshold: str = ""
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class MasteryReport:
|
|
"""The output of Stage 7 (Ratify). Self-sealed cryptographic receipt.
|
|
|
|
``report_sha256`` is the SHA over the JSON body with ``report_sha256``
|
|
blanked. See ``formation.hashing.self_seal`` / ``verify_seal``.
|
|
"""
|
|
|
|
course_id: str
|
|
source_bundle_sha: str
|
|
validated_set_sha: str
|
|
course_sha256: str
|
|
plan_sha256: str
|
|
gates: tuple[GateMeasurement, ...]
|
|
trace_hashes: tuple[str, ...]
|
|
ratified: bool
|
|
report_sha256: str = ""
|
|
schema_version: str = SCHEMA_VERSION
|
|
issued_at: str = "" # ISO-8601 UTC, set at emission
|
|
|
|
# Failure reasons accumulate when ``ratified`` is False; empty otherwise.
|
|
failure_reasons: tuple[str, ...] = field(default_factory=tuple)
|