The widened 100-pack tour surfaced four packs whose closings bucket
included a bare '.' entry: assertive_v1, blunt_v1, dry_v1, and
mathematical_v1. Seeded variation selects from buckets uniformly, so
roughly 1/N of turns would emit a '..'-style surface artefact
(e.g. 'Truth is what is true..') when '.' was selected and appended
to a surface CORE's deterministic realizer already terminated with
'.'.
This commit:
* Strips the bare '.' entry from the four affected packs' closings.
The remaining entries (e.g. ' — qed.', ' — that's it.', '') all
carry their own leading separator, so concatenation produces a
clean surface.
* Re-runs scripts/ratify_register_packs.py to re-seal each pack's
mastery_report.json with a fresh pack_source_sha256 and
self_seal_sha256 — these companion files are part of the diff
because pack content changed.
* Adds _validate_discourse_markers_shape() to
scripts/ratify_register_packs.py as defense in depth. The new
R4-tier gate refuses any closing entry whose first character is
bare sentence-final punctuation ('.', '!', '?', ';', ':') or an
alphanumeric — both classes would produce concatenation artefacts.
Ellipsis ('...', '…') is explicitly exempt as a legitimate
stylistic ending.
Verified:
* core eval cognition byte-identical (the eval runs unregistered)
* tests/test_cognition_eval_register_matrix.py: 801 passed in 5:23
(100 registers × 8 projection invariants + meta-test), confirming
the closing fix did not perturb ADR-0072 trace_hash invariance
or any per-case projection.
* Hand-verification across {assertive,blunt,dry,mathematical}_v1
× 4 prompts = 16 surfaces: 0 remaining double-period artefacts.
* Re-running ratify against a re-introduced bad closing produces
SystemExit with the new gate's diagnostic message.
mathematical_v1 now reads beautifully under "What is light?":
"Lemma: Light is visible medium that reveals truth. — qed."
464 lines
16 KiB
Python
464 lines
16 KiB
Python
"""Ratify register packs (ADR-0068, Plan Phase R1).
|
|
|
|
For each pack in ``packs/register/<register_id>.json``:
|
|
|
|
1. Verify schema fields are present and well-shaped (delegated to the
|
|
loader, run with ``require_ratified=False``).
|
|
2. Compute the canonical ``pack_source_sha`` (SHA-256 of the pack with
|
|
``mastery_report_sha256`` blanked) — self-referential provenance.
|
|
3. Apply the R1 gate: only **null registers** (empty
|
|
``realizer_overrides`` + empty ``discourse_markers``) are ratifiable
|
|
through this script. R3 will widen this gate to cover non-null
|
|
registers with their own ratification method.
|
|
4. Build a self-sealed ``MasteryReport``-shaped dict capturing the
|
|
evidence claim (``byte_identity_null_lift``).
|
|
5. Write ``<register_id>.mastery_report.json``.
|
|
6. Update the pack's ``mastery_report_sha256`` field to match.
|
|
|
|
Idempotent: re-running on an already-ratified pack produces
|
|
byte-identical files. Run whenever a register pack changes.
|
|
|
|
Trust boundary
|
|
--------------
|
|
This script writes to ``packs/register/`` on disk. It is operator-only
|
|
(no runtime entrypoint). Pack-id sanitisation, schema validation, and
|
|
seal verification all flow through ``packs/register/loader.py`` — see
|
|
``ADR-0051`` doctrine.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Any, Callable
|
|
|
|
from formation.hashing import self_seal
|
|
from packs.register.loader import (
|
|
RegisterPackError,
|
|
load_register_pack,
|
|
)
|
|
|
|
PACKS_DIR = Path(__file__).resolve().parents[1] / "packs" / "register"
|
|
ISSUED_AT = "2026-05-20T00:00:00Z"
|
|
REGISTER_IDS: tuple[str, ...] = (
|
|
"default_neutral_v1",
|
|
"terse_v1",
|
|
"convivial_v1",
|
|
"pedagogical_v1",
|
|
"precise_v1",
|
|
"formal_v1",
|
|
"socratic_v1",
|
|
"succinct_v1",
|
|
"expansive_v1",
|
|
"exhaustive_v1",
|
|
"warm_v1",
|
|
"cool_v1",
|
|
"casual_v1",
|
|
"intense_v1",
|
|
"playful_v1",
|
|
"calm_v1",
|
|
"urgent_v1",
|
|
"serene_v1",
|
|
"dramatic_v1",
|
|
"sober_v1",
|
|
"clinical_v1",
|
|
"colloquial_v1",
|
|
"literary_v1",
|
|
"journalistic_v1",
|
|
"poetic_v1",
|
|
"assertive_v1",
|
|
"hedged_v1",
|
|
"inviting_v1",
|
|
"exploratory_v1",
|
|
"didactic_v1",
|
|
"dialectic_v1",
|
|
"probing_v1",
|
|
"affirming_v1",
|
|
"curious_v1",
|
|
"skeptical_v1",
|
|
"confident_uncertain_v1",
|
|
"peer_v1",
|
|
"mentor_v1",
|
|
"student_v1",
|
|
"expert_v1",
|
|
"scholar_v1",
|
|
"practitioner_v1",
|
|
"novice_v1",
|
|
"narrator_v1",
|
|
"journalist_v1",
|
|
"elder_v1",
|
|
"academic_v1",
|
|
"conversational_v1",
|
|
"executive_v1",
|
|
"technical_v1",
|
|
"legal_v1",
|
|
"medical_v1",
|
|
"scientific_v1",
|
|
"philosophical_v1",
|
|
"devotional_v1",
|
|
"mathematical_v1",
|
|
"engineering_v1",
|
|
"plainspoken_v1",
|
|
"cosmopolitan_v1",
|
|
"diplomatic_v1",
|
|
"blunt_v1",
|
|
"aristocratic_v1",
|
|
"folksy_v1",
|
|
"urbane_v1",
|
|
"timeless_v1",
|
|
"contemporary_v1",
|
|
"classic_v1",
|
|
"neoteric_v1",
|
|
"lyrical_v1",
|
|
"cheerful_v1",
|
|
"somber_v1",
|
|
"melancholic_v1",
|
|
"awed_v1",
|
|
"grave_v1",
|
|
"light_v1",
|
|
"wry_v1",
|
|
"dry_v1",
|
|
"gentle_v1",
|
|
"earnest_v1",
|
|
"documentary_v1",
|
|
"instructional_v1",
|
|
"persuasive_v1",
|
|
"conciliatory_v1",
|
|
"clarifying_v1",
|
|
"summarizing_v1",
|
|
"critiquing_v1",
|
|
"comparing_v1",
|
|
"elaborating_v1",
|
|
"exemplifying_v1",
|
|
"tutorial_v1",
|
|
"interview_v1",
|
|
"briefing_v1",
|
|
"deposition_v1",
|
|
"lecture_v1",
|
|
"memo_v1",
|
|
"review_v1",
|
|
"story_v1",
|
|
"elegy_v1",
|
|
"epigram_v1",
|
|
"manifesto_v1",
|
|
)
|
|
|
|
#: Valid IntentTag names for ``per_intent`` keys (ADR-0071, R4). This
|
|
#: is the trust-boundary whitelist — operators cannot ship unknown
|
|
#: intent names. Sourced from ``generate.intent.IntentTag``.
|
|
def _valid_intent_names() -> frozenset[str]:
|
|
from generate.intent import IntentTag
|
|
return frozenset(t.name for t in IntentTag)
|
|
|
|
# Known realizer_overrides keys (ADR-0070, Phase R3 + R6). The allow-list
|
|
# is the trust boundary against arbitrary operator-authored data driving
|
|
# realizer dispatch. Each entry maps a key name to a validator that
|
|
# returns True iff the value is in-bounds.
|
|
#
|
|
# R6 boolean knobs (drop_provenance_tag, compress_gloss, drop_articles,
|
|
# append_semantic_domain_clause): validated as strict bool only. The
|
|
# realizer dispatch code that *reads* these keys lands with R6; the gate
|
|
# must accept them before that merge so packs can ratify cleanly.
|
|
_KNOWN_OVERRIDE_KEYS: dict[str, Callable[[Any], bool]] = {
|
|
"disclosure_domain_count": lambda v: isinstance(v, int)
|
|
and not isinstance(v, bool)
|
|
and v in (1, 2, 3),
|
|
# R6 boolean knobs — strict bool, no int coercion
|
|
"drop_provenance_tag": lambda v: isinstance(v, bool),
|
|
"compress_gloss": lambda v: isinstance(v, bool),
|
|
"drop_articles": lambda v: isinstance(v, bool),
|
|
"append_semantic_domain_clause": lambda v: isinstance(v, bool),
|
|
}
|
|
|
|
|
|
def _canonical_pack_bytes_for_hashing(pack: dict) -> bytes:
|
|
"""Serialize the pack with ``mastery_report_sha256`` blanked."""
|
|
cleaned = dict(pack)
|
|
cleaned["mastery_report_sha256"] = ""
|
|
return json.dumps(
|
|
cleaned, sort_keys=True, separators=(",", ":")
|
|
).encode("utf-8")
|
|
|
|
|
|
def _pack_source_sha(pack: dict) -> str:
|
|
return hashlib.sha256(_canonical_pack_bytes_for_hashing(pack)).hexdigest()
|
|
|
|
|
|
def _is_null_register(pack: dict) -> bool:
|
|
overrides = pack.get("realizer_overrides", {})
|
|
markers = pack.get("discourse_markers", {})
|
|
if not isinstance(overrides, dict) or overrides:
|
|
return False
|
|
if not isinstance(markers, dict):
|
|
return False
|
|
for bucket in ("openings", "transitions", "closings"):
|
|
if markers.get(bucket):
|
|
return False
|
|
return True
|
|
|
|
|
|
def _validate_overrides_known_keys(pack: dict, register_id: str) -> None:
|
|
"""R4 gate — allow-list known realizer_overrides keys + per_intent
|
|
nested block. Unknown keys are refused.
|
|
"""
|
|
overrides = pack.get("realizer_overrides", {})
|
|
if not isinstance(overrides, dict):
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: realizer_overrides is not a dict"
|
|
)
|
|
valid_intents = _valid_intent_names()
|
|
for k, v in overrides.items():
|
|
if k == "per_intent":
|
|
_validate_per_intent_block(v, register_id, valid_intents)
|
|
continue
|
|
validator = _KNOWN_OVERRIDE_KEYS.get(k)
|
|
if validator is None:
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: unknown realizer_overrides "
|
|
f"key {k!r}. Known keys: "
|
|
f"{sorted(list(_KNOWN_OVERRIDE_KEYS) + ['per_intent'])}"
|
|
)
|
|
if not validator(v):
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: realizer_overrides[{k!r}]"
|
|
f"={v!r} out of bounds"
|
|
)
|
|
|
|
|
|
def _validate_per_intent_block(
|
|
block: object, register_id: str, valid_intents: frozenset[str],
|
|
) -> None:
|
|
"""R4 gate — per_intent intents must be valid IntentTag names; each
|
|
sub-dict's keys must be in the same allow-list as flat keys.
|
|
"""
|
|
if not isinstance(block, dict):
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: realizer_overrides.per_intent "
|
|
"must be a dict"
|
|
)
|
|
for intent_name, sub in block.items():
|
|
if intent_name not in valid_intents:
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: realizer_overrides"
|
|
f".per_intent[{intent_name!r}] is not a valid IntentTag. "
|
|
f"Valid intents: {sorted(valid_intents)}"
|
|
)
|
|
if not isinstance(sub, dict):
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: realizer_overrides"
|
|
f".per_intent[{intent_name!r}] must be a dict"
|
|
)
|
|
for sub_k, sub_v in sub.items():
|
|
validator = _KNOWN_OVERRIDE_KEYS.get(sub_k)
|
|
if validator is None:
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: realizer_overrides"
|
|
f".per_intent[{intent_name!r}] unknown key {sub_k!r}. "
|
|
f"Known keys: {sorted(_KNOWN_OVERRIDE_KEYS)}"
|
|
)
|
|
if not validator(sub_v):
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: realizer_overrides"
|
|
f".per_intent[{intent_name!r}][{sub_k!r}]={sub_v!r} "
|
|
"out of bounds"
|
|
)
|
|
|
|
|
|
_BARE_SENTENCE_FINAL_PUNCT: frozenset[str] = frozenset(".!?;:")
|
|
"""Closing entries beginning with one of these characters concatenate
|
|
directly onto a surface that already ends in ``.`` (CORE's deterministic
|
|
realizer always emits a trailing period) and produce double-punctuation
|
|
artefacts like ``true..``. Ellipsis (``...`` / ``…``) is exempt — that
|
|
is a legitimate stylistic ending in its own right.
|
|
"""
|
|
|
|
|
|
def _validate_discourse_markers_shape(pack: dict, register_id: str) -> None:
|
|
"""Reject discourse-marker shapes that would produce surface
|
|
artefacts when concatenated to a sentence-final surface.
|
|
|
|
Catches the class of authoring bug discovered during the 100-pack
|
|
widened tour: a bare ``"."`` closing yields ``..`` when seeded
|
|
variation picks it. Defense in depth — pack authors should not
|
|
have to remember the realizer's trailing-period convention.
|
|
|
|
Rules (closings only — openings always lead the surface with a
|
|
space separator inserted by the composer):
|
|
* ``""`` is always legal (no-op closing)
|
|
* Entries starting with bare ``.``, ``!``, ``?``, ``;``, ``:``
|
|
are refused — they double-punctuate. Ellipsis (``"..."`` /
|
|
``"…"``) is exempt and remains legal.
|
|
* Entries starting with an alphanumeric character are refused —
|
|
they would join with no separator, e.g. ``"true.holds."``.
|
|
"""
|
|
markers = pack.get("discourse_markers", {})
|
|
if not isinstance(markers, dict):
|
|
return # shape-only — schema validator owns dict-vs-not
|
|
closings = markers.get("closings", [])
|
|
if not isinstance(closings, list):
|
|
return
|
|
for entry in closings:
|
|
if not isinstance(entry, str) or entry == "":
|
|
continue
|
|
first = entry[0]
|
|
if entry.startswith(("...", "…")):
|
|
continue
|
|
if first in _BARE_SENTENCE_FINAL_PUNCT:
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: discourse_markers."
|
|
f"closings[{entry!r}] starts with bare sentence-final "
|
|
f"punctuation. CORE's realizer always emits a trailing "
|
|
f"'.', so {entry!r} concatenates to '..'-style "
|
|
f"artefacts. Either drop the entry or prefix it with a "
|
|
f"separator (e.g. ' — note.')."
|
|
)
|
|
if first.isalnum():
|
|
raise SystemExit(
|
|
f"R4 gate refuses {register_id!r}: discourse_markers."
|
|
f"closings[{entry!r}] starts with an alphanumeric "
|
|
f"character. Closings concatenate directly to the "
|
|
f"surface — prefix with a space or punctuation "
|
|
f"separator (e.g. ' note.' or ' — note.')."
|
|
)
|
|
|
|
|
|
def _markers_have_content(pack: dict) -> bool:
|
|
"""True iff openings or closings has at least one entry (R4 needs
|
|
one of these populated for a marker-using ratification).
|
|
|
|
Empty-string entries count as content — the seed may legitimately
|
|
pick "no marker this turn" from a bucket like ``["", "So,"]``.
|
|
"""
|
|
markers = pack.get("discourse_markers", {})
|
|
if not isinstance(markers, dict):
|
|
return False
|
|
for bucket in ("openings", "closings"):
|
|
items = markers.get(bucket, [])
|
|
if isinstance(items, list) and len(items) >= 1:
|
|
return True
|
|
return False
|
|
|
|
|
|
def _ratify_one(pack_path: Path, register_id: str) -> tuple[dict, dict[str, Any]]:
|
|
"""Returns (updated_pack_dict, mastery_report_dict). Does not write."""
|
|
pack = json.loads(pack_path.read_text(encoding="utf-8"))
|
|
|
|
load_register_pack(
|
|
register_id,
|
|
search_paths=(pack_path.parent,),
|
|
require_ratified=False,
|
|
)
|
|
|
|
pack_source_sha = _pack_source_sha(pack)
|
|
|
|
# R4 gate: realizer_overrides must contain only known keys
|
|
# (including the per_intent nested block); discourse markers may
|
|
# be populated, but a register claiming non-null marker status
|
|
# must have at least one of openings/closings populated. Null
|
|
# registers pass trivially.
|
|
_validate_overrides_known_keys(pack, register_id)
|
|
_validate_discourse_markers_shape(pack, register_id)
|
|
|
|
null_register = _is_null_register(pack)
|
|
overrides = pack.get("realizer_overrides", {}) or {}
|
|
markers = pack.get("discourse_markers", {}) or {}
|
|
markers_used = _markers_have_content(pack)
|
|
transitions_reserved = bool(
|
|
isinstance(markers, dict) and markers.get("transitions")
|
|
)
|
|
|
|
if markers_used:
|
|
ratification_method = "seeded_variation_replay_equivalence"
|
|
elif null_register:
|
|
ratification_method = "byte_identity_null_lift"
|
|
else:
|
|
ratification_method = "known_key_overrides_invariant_grounding"
|
|
|
|
bucket_sizes = {
|
|
b: (
|
|
len(markers.get(b, []))
|
|
if isinstance(markers, dict)
|
|
and isinstance(markers.get(b, []), list)
|
|
else 0
|
|
)
|
|
for b in ("openings", "transitions", "closings")
|
|
}
|
|
|
|
report: dict[str, Any] = {
|
|
"register_id": register_id,
|
|
"schema_version": "1.0.0",
|
|
"issued_at": ISSUED_AT,
|
|
"pack_source_sha256": pack_source_sha,
|
|
"ratification_method": ratification_method,
|
|
"ratified": True,
|
|
"evidence": {
|
|
"realizer_overrides_empty": not bool(overrides),
|
|
"realizer_overrides_keys": sorted(overrides.keys()),
|
|
"discourse_markers_empty": not markers_used
|
|
and not transitions_reserved,
|
|
"marker_bucket_sizes": bucket_sizes,
|
|
"transitions_reserved": transitions_reserved,
|
|
"depth_preference": str(pack.get("depth_preference", "")),
|
|
},
|
|
"failure_reasons": [],
|
|
"report_sha256": "",
|
|
}
|
|
sealed = self_seal(report, sha_field="report_sha256")
|
|
|
|
pack["mastery_report_sha256"] = sealed["report_sha256"]
|
|
return pack, sealed
|
|
|
|
|
|
def main() -> int:
|
|
updated = 0
|
|
skipped = 0
|
|
for register_id in REGISTER_IDS:
|
|
pack_path = PACKS_DIR / f"{register_id}.json"
|
|
if not pack_path.is_file():
|
|
print(f"skip: {pack_path} not found", file=sys.stderr)
|
|
continue
|
|
try:
|
|
pack_after, report_dict = _ratify_one(pack_path, register_id)
|
|
except RegisterPackError as exc:
|
|
print(f"refused: {register_id} — {exc}", file=sys.stderr)
|
|
return 1
|
|
|
|
report_path = PACKS_DIR / f"{register_id}.mastery_report.json"
|
|
report_text = json.dumps(
|
|
report_dict, indent=2, sort_keys=True, ensure_ascii=False,
|
|
) + "\n"
|
|
prior_report = (
|
|
report_path.read_text(encoding="utf-8")
|
|
if report_path.is_file()
|
|
else ""
|
|
)
|
|
prior_pack = json.loads(pack_path.read_text(encoding="utf-8"))
|
|
if (
|
|
prior_pack.get("mastery_report_sha256")
|
|
== pack_after["mastery_report_sha256"]
|
|
and prior_report == report_text
|
|
):
|
|
print(
|
|
f"idempotent: {register_id} already ratified at "
|
|
f"{pack_after['mastery_report_sha256'][:12]}\u2026"
|
|
)
|
|
skipped += 1
|
|
continue
|
|
pack_path.write_text(
|
|
json.dumps(pack_after, indent=2, ensure_ascii=False) + "\n",
|
|
encoding="utf-8",
|
|
)
|
|
report_path.write_text(report_text, encoding="utf-8")
|
|
print(
|
|
f"ratified: {register_id} \u2192 "
|
|
f"{pack_after['mastery_report_sha256'][:12]}\u2026"
|
|
)
|
|
updated += 1
|
|
print(f"\nratified {updated} pack(s); {skipped} already current")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|