Shay
|
7f0bad3e20
|
feat(register): R5 — operator-visible register telemetry + tour demo
ADR-0072 ratified + implemented. Closes the register subsystem
inside-out arc (R1 ADR-0068 → R5 ADR-0072): the presentation axis is
now operator-visible, CI-falsifiable, and audit-traceable.
Telemetry extension
- TurnEvent + ChatResponse gain register_id + register_variant_id
(12-char SHA-256 prefix of selected (opening, closing) pair;
empty string for UNREGISTERED / no-decoration registers).
- serialize_turn_event surfaces both fields in every audit JSONL
line. Pre-R5 callers stay byte-identical (defaults are "").
Decoration result widened
- chat/register_variation.py: decorate_surface now returns
DecorationResult(surface, opening, closing, variant_id).
- decorate_surface_str alias preserves the pre-R5 string-only API
for off-runtime callers.
- chat/runtime.py updated at both call sites (stub + main).
Operator surface
- core chat --register REGISTER_ID threads into
RuntimeConfig.register_pack_id via _runtime_config_from_args.
- Invalid id ⇒ RegisterPackError caught at cmd_chat and surfaced
as a clean _die(...) before the REPL launches.
Narrative demo
- evals/register_tour/run_tour.py walks 4 prompts × 3 ratified
registers ({default_neutral_v1, terse_v1, convivial_v1}) and
asserts three load-bearing seam claims:
* all_grounding_sources_identical
* all_trace_hashes_identical (ADR-0069 invariant C, falsifiable)
* surfaces_vary_at_least_once (ADR-0071 seeded variation lift)
- core demo register-tour exit code = 0 iff every claim holds.
Tests
- tests/test_register_telemetry.py (6) — TurnEvent default,
serializer keys, runtime emits register_id/variant_id for
convivial/terse/unregistered, ChatResponse mirrors event fields.
- tests/test_register_cli.py (7) — _runtime_config_from_args
threading, invalid-id fail-fast, parser wires --register.
- tests/test_register_tour_demo.py (7) — three seam claims pinned
individually + all_claims_supported + per-cell register_id +
variant_id discipline (empty for neutral/terse, non-empty for
convivial).
- tests/test_register_variation.py extended (4 new) — DecorationResult
shape, decorate_surface_str alias, variant_id stability,
bijection between non-trivial marker pairs and variant_ids.
Lane evidence
- Full lane: 2632 passed / 4 skipped / 1 pre-existing failure
(tests/test_cli_demo.py::test_all_preamble_explains_combined_run,
unrelated to R5).
- Cognition eval byte-identical: public 100 / 100 / 91.7 / 100.
Trust boundaries (per CLAUDE.md)
- --register flag does not bypass ratification; loader validates the
pack id through _find_pack and the ratify gate at load time.
- variant_id is content-addressed; no raw markers leak into audit.
- Telemetry stays redact-safe — register_id and variant_id are
identifiers, not content, so include_content=False emits them
unconditionally.
- No new mutation surface; pack files on disk are not modified.
|
2026-05-19 19:03:07 -07:00 |
|
Shay
|
6207b5fd0e
|
feat(register): R1–R4 register pack subsystem — deterministic surface variation
Introduces the presentation axis as a fourth pack class (sibling to identity /
safety / ethics), orthogonal to the truth path. Same input + same packs +
same register ⇒ bit-for-bit reproducible surface; varying any of the three ⇒
genuinely different output. No stochastic sampling.
ADR-0068 (R1): RegisterPack frozen dataclass, loader, ratify script, seam test.
- default_neutral_v1 ratified as null register.
ADR-0069 (R2): realizer register parameter threaded through 9 composer entry
points; RuntimeConfig.register_pack_id; three byte-identity invariants
(A: None ≡ pre-R2 unregistered; B: None ≡ default_neutral_v1; C: trace_hash
invariant under register). Amended to default-with-lint after 167-call-site
scout: composers default to UNREGISTERED, AST lint enforces explicit
register= at runtime call sites.
ADR-0070 (R3): terse_v1 register, first non-neutral pack. realizer_overrides
schema with known-keys allow-list (disclosure_domain_count ∈ {1,2,3}).
build_pack_surface_candidate reads override with fail-soft clamp. New
invariant register_invariant_grounding asserts grounding_source +
trace_hash byte-identical across {None, neutral, terse}.
ADR-0071 (R4): seeded surface variation via convivial_v1.
chat/register_variation.py applies SHA-256-seeded marker selection from
bounded discourse-marker buckets. ChatResponse.pre_decoration_surface routes
truth-path surface to core/cognition/pipeline.py so trace_hash stays
invariant under register (the load-bearing architectural fix — initially
invariant C failed under convivial because decoration was leaking into
trace_hash via response.surface). Empty-string marker entries now
legitimate ("no marker this turn" is a valid seed pick). realizer_overrides
schema widened with per_intent nested block (validated against IntentTag
whitelist; wired but not exercised by convivial). Two new invariants:
seeded_variation_replay_equivalence (fresh runtimes → byte-identical) and
seeded_variation_turn_distinct (same prompt across turns → ≥2 distinct
surfaces).
ADR-0072 (R5, draft): telemetry + operator surface — TurnEvent gains
register_id and register_variant_id, core chat --register flag, core demo
register-tour. Status: Proposed; not yet implemented.
Three ratified register packs ship: default_neutral_v1 (null), terse_v1
(disclosure_domain_count=1), convivial_v1 (3 openings × 3 closings).
Verification:
- 84 register tests pass + 1 documented skip
- Curated lanes green: smoke 67, cognition 120+1s, teaching 17, packs 6,
runtime 19, algebra 132
- Cognition eval byte-identical to pre-register baseline:
public 100/100/91.7/100, holdout 100/100/83.3/100
- Full lane: 2608 passed, 4 skipped, 1 failed (pre-existing
test_cli_demo.py "Combined Demo" → "Run Every Demo" rename, unrelated)
Truth-path isolation: chat/register_variation.py is realizer-side; the seam
test (tests/test_register_pack_seam.py) refuses imports of packs.register
from intent classification, propagation, vault recall, trace hashing, and
algebra.
|
2026-05-19 16:52:36 -07:00 |
|