Adds the four templates called out in docs/teaching_order.md so the formation
pipeline can ratify more than just definitional ontologies:
* composed_relation — Layer 4. Chains are the unit of mastery; each chain of
length >= 2 emits a composed_relations entry with composition_kind
(transitive | lifting), an inferred relation, and chain-break adversarial
probes drawn from counters or canned.
* procedural — ordered state transitions; strict_linear_topo refuses
branches, cycles, and disconnected components at render time.
ordering_hints validated against the linear chain. Canned violation
probes for precondition_violation / step_skip / back_edge.
* falsification — counter-example-driven. Counters move to Phase 2 paired
with coherent alternatives drawn from relations sharing the same head.
Unmatched counters surface in unmatched_counters; false-coherent probes
emitted per pair.
* identity_anchor — Layer 1 seeding. Concepts interpreted as identity axes
ranked by ordering_hints; counters interpreted as override attempts;
canned IDENTITY_OVERRIDE_PROBES always appended.
Common helpers extracted to formation/templates/_common.py: canonical
constants (MAX_VERSOR_CONDITION, RATIFICATION_GATES, PROMOTION_PATH,
IDENTITY_OVERRIDE_PROBES, NORMALIZATION_FORBIDDEN_SITES), deterministic
ordering (sorted_concepts/_counters/_hints, topo_sorted_relations,
strict_linear_topo), payload builders, geometric_dependencies,
maximal_chain_walks, adversarial_block, course_id, subject_payload,
substrate_invariants_payload, phase_5_payload.
formation/templates/__init__.py now dispatches via a lazy-import _REGISTRY
keyed by template_id; registered_template_ids() exposed for callers and
tests. definition.py refactored to use _common verbatim — byte-stability
preserved (existing test_compose.py still passes; test_sha_stable_across_
subprocess unchanged).
Tests: 44 new tests across test_template_{composed_relation,procedural,
falsification,identity_anchor,registry}.py. Each new template gets
determinism, paradigm-structure, error-handling, and cross-subprocess SHA
stability tests; registry test asserts the five known ids and that
identical inputs through different templates produce different SHAs.
Formation suite: 138 -> 182 passing. cognition (121) and smoke (67)
suites unchanged. ratify.py enforcement of the new paradigm-specific
gates (every_composed_relation_replayed, linear_order_strict, etc.)
remains a documented follow-up — templates declare the gates in their
phase_5 body so the ratifier extension is purely additive.
93 lines
3.1 KiB
Python
93 lines
3.1 KiB
Python
"""The ``definition`` template — first and simplest Course YAML template.
|
|
|
|
A Course rendered with this template treats every relation as a definitional
|
|
edge in a concept ontology. It emits the full five-phase body specified in
|
|
``docs/formation_pipeline_plan.md`` (§3 Phase 3).
|
|
|
|
Determinism rules enforced here:
|
|
|
|
* Concepts are sorted by ``(canonical_term, first_source_sha)`` lex.
|
|
* Relations are topologically sorted (Kahn's algorithm); ties broken by the
|
|
``(head, relation, tail)`` triple lex order.
|
|
* Walks are auto-generated from the topo-sorted relation DAG, one walk per
|
|
maximal chain.
|
|
* All numerics are strings — floats are forbidden per
|
|
``formation.hashing._reject_floats`` and ``CLAUDE.md``.
|
|
* Adversarial probes include canned identity-override probes drawn from
|
|
``CLAUDE.md`` "Teaching Safety", plus one probe per ``CounterCandidate``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from formation.course import SubjectSpec, ValidatedTripleSet
|
|
from formation.templates._common import (
|
|
MAX_VERSOR_CONDITION,
|
|
adversarial_block,
|
|
concept_payload,
|
|
course_id,
|
|
geometric_dependencies,
|
|
maximal_chain_walks,
|
|
phase_5_payload,
|
|
relation_payload,
|
|
sorted_concepts,
|
|
sorted_counters,
|
|
subject_payload,
|
|
substrate_invariants_payload,
|
|
topo_sorted_relations,
|
|
)
|
|
|
|
TEMPLATE_ID: str = "definition"
|
|
TEMPLATE_VERSION: str = "1.0.0"
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class DefinitionTemplate:
|
|
"""Template implementation. Stateless; cheap to instantiate."""
|
|
|
|
template_id: str = TEMPLATE_ID
|
|
template_version: str = TEMPLATE_VERSION
|
|
|
|
def render(
|
|
self,
|
|
validated_set: ValidatedTripleSet,
|
|
spec: SubjectSpec,
|
|
source_bundle_sha: str,
|
|
) -> dict[str, object]:
|
|
concepts = sorted_concepts(validated_set.concepts)
|
|
relations = topo_sorted_relations(validated_set.relations)
|
|
counters = sorted_counters(validated_set.counters)
|
|
|
|
body: dict[str, object] = {
|
|
"course_id": course_id(spec, self.template_id, self.template_version),
|
|
"paradigm": "five_phase_versor_formation",
|
|
"template_id": self.template_id,
|
|
"template_version": self.template_version,
|
|
"source_bundle_sha": source_bundle_sha,
|
|
"subject": subject_payload(spec),
|
|
"geometric_dependencies": geometric_dependencies(relations),
|
|
"substrate_invariants": substrate_invariants_payload(),
|
|
"phase_1_ontological_seeding": {
|
|
"concepts": [concept_payload(c) for c in concepts],
|
|
},
|
|
"phase_2_axiomatic_rotor_scaffolding": {
|
|
"relations": [relation_payload(r) for r in relations],
|
|
},
|
|
"phase_3_holonomic_syllabus_walk": {
|
|
"walks": maximal_chain_walks(relations),
|
|
},
|
|
"phase_4_epistemic_boundary_hardening": {
|
|
"adversarial_corrections": adversarial_block(counters),
|
|
},
|
|
"phase_5_ratified_consolidation": phase_5_payload(),
|
|
}
|
|
return body
|
|
|
|
|
|
__all__ = [
|
|
"DefinitionTemplate",
|
|
"MAX_VERSOR_CONDITION",
|
|
"TEMPLATE_ID",
|
|
"TEMPLATE_VERSION",
|
|
]
|