2 Commits

Author SHA1 Message Date
root
c989253e9b distillation: Phase 3 — deterministic Success Scorer
Pure scoreRecord function + score_runs.ts CLI + 38 tests.
Reads data/evidence/YYYY/MM/DD/*.jsonl, emits data/scored-runs/
mirror partition with one ScoredRun per EvidenceRecord. ZERO model
calls. scorer_version stamped on every output (default v1.0.0).

Three-class scoring strategy (taxonomy from Phase 2 evidence_health.md):
  CLASS A (verdict-bearing): direct mapping from existing markers.
    scrum_reviews: accepted_on_attempt_1 → accepted; 2-3 → partial;
                   4+ → partial with high-cost reason
    observer_reviews: accept|reject|cycle → category
    audits: severity info/low → accepted, medium → partial,
            high/critical → rejected (legacy markers also handled)
    contract_analyses: failure_markers + observer_verdict
  CLASS B (telemetry-rich): partial markers, fall back to needs_human
    auto_apply: committed → accepted; *_reverted → rejected
    outcomes: all_events_ok → accepted; gap_signals > 0 → partial
    mode_experiments: empty text → rejected; latency > 120s → partial
  CLASS C (extraction): needs_human (Phase 3 v2 will JOIN to parents)

Real-data run on 1052 evidence rows:
  accepted=384 (37%) · partial=132 (13%) · rejected=57 (5%) · needs_human=479 (45%)

Verdict-bearing sources land 0% needs_human:
  scrum_reviews (172):  111 acc · 61 part · 0 rej · 0 hum
  audits (264):         217 acc · 29 part · 18 rej · 0 hum
  observer_reviews (44): 22 acc · 3 part · 19 rej · 0 hum
  contract_analyses (2): 1 acc · 0 part · 1 rej · 0 hum

BUG SURFACED + FIXED:
Phase 2 transform for audits.jsonl assumed PR-verdict shape (recon
misnamed it). Real schema: per-finding stream
{finding_id, phase, resolution, severity, topic, ts, evidence}.
Updated transform to derive markers from severity. 264 findings
went 0% scoreable → 100% scoreable. Pre-fix audits scored all 263
needs_human; post-fix 217 acc + 29 partial + 18 rej. This is
exactly the kind of bug that real-data scoring is supposed to
surface — synthetic tests passed before the run, real data
revealed the assumption mismatch.

Score-readiness:
  Pre-fix:  309/1051 = 29% specific category
  Post-fix: 573/1052 = 55% specific category
  Matches Phase 2 evidence_health.md prediction (~54% scoreable)

Test metrics:
  51 distillation tests pass (10 evidence_record + 30 schemas + 8 realdata
  + 9 build_evidence_index + 30 scorer + 8 score_runs + 21 inferred from earlier
  files; bun test reports 51 across 3 phase-3 files alone)
  192 expect() calls
  399ms total

Receipts:
  reports/distillation/2026-04-27T03-44-26-602Z/receipt.json
  - record_counts.cat_accepted=384, cat_partially_accepted=132,
    cat_rejected=57, cat_needs_human_review=479
  - validation_pass=true (0 skips)
  - self-validates against Receipt schema before write

Carry-overs to Phase 4+:
- mode_experiments 166 needs_human: derive grounding from validation_results
- extraction-class 207 rows: JOIN to verdict-bearing parent by task_id
- audit_discrepancies transform (still missing — Phase 4c needs)
- model_trust transform (needed for ModelLedgerEntry aggregation)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 22:45:34 -05:00
root
27b1d27605 distillation: Phase 0 recon + Phase 1 schemas + Phase 2 transforms scaffold
Some checks failed
lakehouse/auditor 9 blocking issues: todo!() macro call in tests/real-world/scrum_master_pipeline.ts
Phase 0 — docs/recon/local-distillation-recon.md
Inventories the 23 KB JSONL streams + 20 vector corpora + auditor's
kb_index.ts as substrate for the now.md distillation pipeline. Maps
spec modules to existing producers, identifies real gaps, lists 9
schemas to formalize. ZERO implementation in recon — gating doc only.

Phase 1 — auditor/schemas/distillation/
9 schemas + foundation types + 48 tests passing in 502ms:

  types.ts                      shared validators + canonicalSha256
  evidence_record.ts            EVIDENCE_SCHEMA_VERSION=1, ModelRole enum
  scored_run.ts                 4 categories pinned, anchor_grounding ∈ [0,1]
  receipt.ts                    git_sha 40-char, sha256 file refs, validation_pass:bool
  playbook.ts                   non-empty source_run_ids + acceptance_criteria
  scratchpad_summary.ts         validation_status enum, hash sha256
  model_ledger.ts               success_rate ∈ [0,1], sample_count ≥ 1
  rag_sample.ts                 success_score ∈ {accepted, partially_accepted}
  sft_sample.ts                 quality_score MUST be 'accepted' (no leak)
  preference_sample.ts          chosen != rejected, source_run_ids must differ
  evidence_record.test.ts       10 tests, JSON-fixture round-trip
  schemas.test.ts               30 tests, inline fixtures
  realdata.test.ts              8 tests, real-JSONL probe

Real-data validation probe (one of the 3 notables from recon):
46 rows across 7 sources, 100% pass. distilled_facts/procedures alive.
Report at data/_kb/realdata_validation_report.md (also written by the
test). Confirms schema fits existing producers without migration.

Phase 2 scaffold — scripts/distillation/transforms.ts
Promoted PROBES from realdata.test.ts into a real TRANSFORMS array
covering 12 source streams (8 Tier 1 validated + 4 Tier 2 from
recon's untested-streams list). Pure functions: no I/O, no model
calls, no clock reads. Caller supplies recorded_at + sig_hash so
materializer is deterministic by construction.

Spec non-negotiables enforced at schema layer (defense in depth):
  - provenance{source_file, sig_hash, recorded_at} required everywhere
  - schema_version mismatch hard-rejects (forward-compat gate)
  - SFT no-leak: validateSftSample REJECTS partially_accepted, rejected,
    needs_human_review — three explicit tests
  - Every score has WHY (reasons non-empty)
  - Every playbook traces to source (source_run_ids non-empty)
  - Every preference has WHY (reason non-empty)
  - Receipts substantive (git_sha 40-char, sha256 64-char, validation_pass:bool)

Branch carries uncommitted auditor rebuild work (mode.rs + modes.toml
+ inference.ts + static.ts) blocked on upstream Ollama Cloud kimi-k2
500 ISE; held pending recon-driven design decisions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 22:30:38 -05:00