distillation: fix 7 grounding bugs found by Kimi audit

Kimi For Coding (api.kimi.com, kimi-for-coding) ran a forensic audit on
distillation v1.0.0 with full file content. 7/7 flags verified real on
grep. Substrate now matches what v1.0.0 claimed: deterministic, no
schema bypasses, Rust tests compile.

Fixes:
- mode.rs:1035,1042  matrix_corpus Some/None -> vec![..]/vec![]; cargo
                     check --tests now compiles (was silently broken;
                     only bun tests were running)
- scorer.ts:30       SCORER_VERSION env override removed - identical
                     input now produces identical version stamp, not
                     env-dependent drift
- transforms.ts:181  auto_apply wall-clock fallback (new Date()) ->
                     deterministic recorded_at fallback
- replay.ts:378      recorded_run_id Date.now() -> sha256(recorded_at);
                     replay rows now reproducible given recorded_at
- receipts.ts:454,495  input_hash_match hardcoded true was misleading
                       telemetry; bumped DRIFT_REPORT_SCHEMA_VERSION 1->2,
                       field is now boolean|null with honest null when
                       not computed at this layer
- score_runs.ts:89-100,159  dedup keyed only on sig_hash made
                            scorer-version bumps invisible. Composite
                            sig_hash:scorer_version forces re-scoring
- export_sft.ts:126  (ev as any).contractor bypass emitted "<contractor>"
                     placeholder for every contract_analyses SFT row.
                     Added typed EvidenceRecord.metadata bucket;
                     transforms.ts populates metadata.contractor;
                     exporter reads typed value

Verification (all green):
  cargo check -p gateway --tests   compiles
  bun test tests/distillation/     145 pass / 0 fail
  bun acceptance                   22/22 invariants
  bun audit-full                   16/16 required checks

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-04-27 05:34:31 -05:00
co-authored by Claude Opus 4.7
parent d11632a6fa
commit d77622fc6b
9 changed files with 72 additions and 21 deletions
+8 -1
View File
@@ -100,6 +100,9 @@ export const TRANSFORMS: TransformDef[] = [
cost_usd: typeof row.cost === "number" ? row.cost / 1_000_000 : undefined,
latency_ms: row.duration_ms,
text: row.analysis,
metadata: typeof row.contractor === "string" && row.contractor.length > 0
? { contractor: row.contractor }
: undefined,
}),
},
{
@@ -178,7 +181,11 @@ export const TRANSFORMS: TransformDef[] = [
// even though the text field is empty.
source_file_relpath: "data/_kb/auto_apply.jsonl",
transform: ({ row, line_offset, source_file_relpath, recorded_at, sig_hash }) => {
const ts: string = row.ts ?? new Date().toISOString();
// Deterministic fallback: use the source-file's recorded_at when
// the row itself lacks a ts. Wall-clock (new Date()) leaked here
// pre-2026-04-27 — broke bit-identical reproducibility on rows
// that historically wrote without a ts field.
const ts: string = row.ts ?? recorded_at;
const action = String(row.action ?? "unknown");
const success = action === "committed";
const reverted = action.includes("reverted");