Introduce deterministic practice-memory infrastructure that adapts sealed scout output into compact, retention-gated ExperienceRecords with family, hazard, and promotion-candidate summaries. No serving, corpus, pack, or report.json mutation — measurement-only adapter for future sprint reuse.
6 KiB
GSM8K Experience Flywheel PR-1 — Lookback (2026-06-17)
1. Problem statement
Capability Paradigm Sprint 5 proved that sealed practice/scout evidence can discover reusable reasoning organs before serving promotion (10/40/0 → 12/38/0). The next layer must make that loop systematic and programmatic without saving garbage, bloating memory, or letting SPECULATIVE practice artifacts masquerade as reviewed knowledge.
PR-1 adds a bounded, deterministic experience artifact layer — not serving promotion, not corpus mutation, not auto-accept.
2. Trust boundary summary
| Boundary | PR-1 behavior |
|---|---|
| Serving path | Unchanged; wrong=0 preserved |
| report.json | Read-only; mtime tests prove no write |
| Sealed practice artifacts | Unchanged |
| Teaching corpus / packs | No mutation |
| DiscoveryCandidate / proposals | No auto-emission; bridge documented for PR-2 |
| Contemplation findings | Remain SPECULATIVE; experience records are parallel diagnostic memory |
| Output | Explicit --out only; never default-writes into repo |
Experience records are structured evidence for operators, not active memory. Promotion into serving or teaching still requires reviewed gates.
3. Artifact schema
Module: evals/gsm8k_math/train_sample/v1/experience.py
ExperienceRecord (pre-compaction):
record_id— SHA-256 of load-bearing fieldscase_id,serving_status,sealed_status,gold_answer,sealed_answerserving_refusal_family,sealed_failure_family,candidate_familyfirst_missing_primitive,arithmetic_chain_signaturepositive_evidence_refs,negative_evidence_refs,hazard_tagsrecommended_action,promotion_statussource_run_id,source_report_hash,schema_version
CompactedExperienceRecord (case-level output):
- Dedupe key over
(case_id, candidate_family, arithmetic_chain_signature, hazard_tags) count,first_seen_run_id,last_seen_run_id,status_transitions
Experience report adds:
family_summaries— per-family lift/block counts and recommended next actionhazard_summaries— hazard tag → case_idspromotion_candidates— families marked candidate or blocked_by_wrong_riskexperience_report_hash— self-sealing digest
CLI: scripts/gsm8k_experience_flywheel.py
4. Retention gates
Keep:
lift_refused_to_correct(refused→correct delta)elimination_refused_to_wrongand sealed-wrong surfaces- Serving-wrong (if any)
already_servedcorrect (regression preservation set)serving_conservative_win(conservative boundary evidence)- High-frequency
joint_refusalclusters (≥3 cases share failure_family)
Drop:
- Low-signal isolated
joint_refusal(no cluster, no new family info) - Duplicate signatures within a run (compacted)
- Raw problem text / full traces (never stored)
5. Compaction logic
Within a run and across runs (--prior):
- Group by dedupe key
- Collapse to one
CompactedExperienceRecordwithcount, seen run IDs, status transitions - Latest serving/sealed status wins for the compacted row
6. Promotion candidate rules
A family is candidate only when:
- At least one refused_to_correct record exists in the family group
first_missing_primitiveandcandidate_familyare explicit- No
blocked_by_wrong_riskrecords in the same family group - No unblocked
unbound_targethazard on lift rows
7. Blocked-by-wrong-risk rules
Marked blocked_by_wrong_risk when:
elimination_refused_to_wrongor sealed_status=wrong- Serving-wrong delta kinds
- Hazard tags include
sealed_elimination,wrong_risk,serving_wrong_boundary - Family summary has both lift candidates and blocked records
8. Determinism proof
record_id,source_run_id,source_report_hash,experience_report_hashare SHA-256 over canonical JSON (formation.hashing)- No clock, no randomness, no floats in hashed payloads
test_live_experience_report_determinism— identical reports on repeated live runstest_canonical_json_roundtrip— stable serialization
9. Mutation-boundary proof
test_report_json_mtime_unchanged_by_experience_import- No imports of
VaultStore.store, teaching corpus writers, or pack mutators - Scout adapter is read-only over existing
build_scout_summaryoutput
10. Tests run
git diff --check origin/main...HEAD
pytest tests/test_gsm8k_experience_flywheel.py -q # 18 passed
pytest tests/test_gsm8k_sealed_attempt_scout.py -q
pytest tests/test_contemplation_loop.py -q
pytest tests/test_contemplation_pipeline_convergence.py -q
pytest tests/test_architectural_invariants.py -q # 123 total passed
core test --suite smoke -q
11. Live artifact snapshot (train_sample, post-#815)
From build_experience_report() on current main:
- Serving: 12 correct / 38 refused / 0 wrong
- Retained records: high-signal lift, sealed-wrong, promoted regression set
- Low-signal joint refusals dropped unless clustered
question_bound_product_aggregatefamily appears aspromoted_in_prfor 0003/0021
12. Future PRs
| PR | Scope |
|---|---|
| PR-2 | Wire high-confidence promotion_candidates → DiscoveryCandidate / proposal draft (no auto-accept) |
| PR-3 | Operator review workbench over experience + contemplation streams |
| PR-4 | Sprint-to-sprint automatic candidate ranking from compacted history |
| PR-5 | Use accepted experience records to prioritize next capability paradigm sprint |
Proposal bridge (PR-2 sketch):
- Map
family_summarieswithpromotion_status=candidatetoDiscoveryCandidatewithtrigger=would_have_groundedor a new typed trigger - Attach
positive_evidence_refsasContemplationEvidenceRef-compatible pointers - Route through existing
TeachingChainProposalreview gate only
13. Non-goals
- No serving lift required
- No auto corpus / pack mutation
- No auto-accept proposal
- No broad product_bridge re-enable
- No report.json rebaseline
- No sealed artifact movement
- No background daemon
- No unbounded logging / raw trace persistence