c48a965640
Window_scan assertions now match the public from_sign/to_sign contract, the staging quick gate runs the rectification Python suite, and compare-candidates rescores when stored policy lags the live engine identity. Co-authored-by: Cursor <cursoragent@cursor.com>
218 lines
7.8 KiB
TypeScript
218 lines
7.8 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import test from "node:test";
|
|
|
|
import { answersFromEvidence } from "../src/lib/rectification-agentic/core/build-state.ts";
|
|
import {
|
|
classifySnapshotStaleReason,
|
|
storedSnapshotIsCurrent,
|
|
type CandidateSnapshotSource,
|
|
} from "../src/lib/rectification-agentic/core/snapshot-source.ts";
|
|
import type { ConflictProbe } from "../src/lib/rectification-agentic/core/types.ts";
|
|
import { contrastPacketFromLatestResult } from "../src/lib/rectification-agentic/v9/decision-from-dossier.ts";
|
|
import {
|
|
cachedEngineScoreIsReusable,
|
|
liveEngineScoringIdentityFromEnv,
|
|
} from "../src/lib/rectification-agentic/v9/engine-client.ts";
|
|
import {
|
|
parseDiscriminatingEventProbes,
|
|
parseProspectiveProbes,
|
|
prospectiveWindowsNarration,
|
|
} from "../src/lib/rectification-agentic/v9/refinement-packet.ts";
|
|
|
|
const OUTCOMES = [
|
|
{ answer_class: "yes" as const, supports: ["05:00"], conflicts: ["05:07"] },
|
|
{ answer_class: "no" as const, supports: ["05:07"], conflicts: ["05:00"] },
|
|
];
|
|
|
|
function source(overrides: Partial<CandidateSnapshotSource> = {}): CandidateSnapshotSource {
|
|
return {
|
|
birthProfileFingerprint: "birth-a",
|
|
scoreableEvidenceFingerprint: "score-a",
|
|
inferenceRevision: 3,
|
|
candidateSetVersion: "set-a",
|
|
scoringPolicyVersion: "rectification-candidate-policy-v3",
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function qualityProbe(overrides: Record<string, unknown> = {}) {
|
|
return {
|
|
year: 2016,
|
|
year_label: "2016 年 9 月",
|
|
domain: "education",
|
|
event_family: "学业或考试发挥失常、压力特别大",
|
|
source: "known_event_quality",
|
|
tracks: ["vimshottari", "narayana"],
|
|
tracks_agree: true,
|
|
unique_minute_claim: false,
|
|
user_meaning: "2016 年 9 月那次上大学,更接近哪一种实际体验。",
|
|
role: "distinguish",
|
|
phase: "candidate_discriminator",
|
|
semantic_key: "education.2016.known_event_quality",
|
|
information_gain: 0.42,
|
|
candidate_split_hash: "quality-split",
|
|
candidate_set_version: "set-a",
|
|
candidate_ids: ["05:00", "05:07"],
|
|
expected_outcomes: OUTCOMES,
|
|
choice_kind: "event_quality",
|
|
question_contract_version: "probe-question-v1",
|
|
target_evidence_id: "00000000-0000-4000-8000-000000000001",
|
|
display_date_label: "2016 年 9 月",
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function walkFiles(root: string, suffixes: readonly string[]): string[] {
|
|
const skip = new Set(["node_modules", ".next", "dist"]);
|
|
const out: string[] = [];
|
|
const visit = (dir: string) => {
|
|
for (const name of readdirSync(dir)) {
|
|
if (skip.has(name)) continue;
|
|
const path = join(dir, name);
|
|
const stat = statSync(path);
|
|
if (stat.isDirectory()) visit(path);
|
|
else if (suffixes.some((suffix) => name.endsWith(suffix))) out.push(path);
|
|
}
|
|
};
|
|
visit(root);
|
|
return out;
|
|
}
|
|
|
|
test("scoring policy version changes stale stored snapshots", () => {
|
|
const current = source();
|
|
const previous = source({ scoringPolicyVersion: "rectification-candidate-policy-v2" });
|
|
assert.equal(classifySnapshotStaleReason(previous, current), "scoring_policy_changed");
|
|
assert.equal(storedSnapshotIsCurrent(previous, current), false);
|
|
assert.equal(storedSnapshotIsCurrent(current, current), true);
|
|
});
|
|
|
|
test("matching fingerprints still rescore when stored policy lags the live engine", () => {
|
|
const fingerprints = {
|
|
evidenceLedgerFingerprint: "b".repeat(64),
|
|
candidateRangeFingerprint: "c".repeat(64),
|
|
};
|
|
const stored = {
|
|
...fingerprints,
|
|
algorithmVersion: "rectification-v5-matrix-scoring-6",
|
|
policyVersion: "rectification-candidate-policy-v2",
|
|
};
|
|
assert.equal(
|
|
cachedEngineScoreIsReusable(stored, fingerprints, {
|
|
algorithmVersion: "rectification-v5-matrix-scoring-6",
|
|
policyVersion: "rectification-candidate-policy-v2",
|
|
}),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
cachedEngineScoreIsReusable(stored, fingerprints, {
|
|
algorithmVersion: "rectification-v5-matrix-scoring-7",
|
|
policyVersion: "rectification-candidate-policy-v3",
|
|
}),
|
|
false,
|
|
);
|
|
const fromEnv = liveEngineScoringIdentityFromEnv({
|
|
RECTIFICATION_ENGINE_VERSION: "rectification-v5",
|
|
RECTIFICATION_DECISION_POLICY_VERSION: "rectification-candidate-policy-v3",
|
|
});
|
|
assert.equal(fromEnv.algorithmVersion, null);
|
|
assert.equal(fromEnv.policyVersion, "rectification-candidate-policy-v3");
|
|
assert.equal(cachedEngineScoreIsReusable(stored, fingerprints, fromEnv), false);
|
|
});
|
|
|
|
test("anchored known_event_quality distinguish probes stay in the public packet", () => {
|
|
const parsed = parseDiscriminatingEventProbes([qualityProbe()]);
|
|
assert.equal(parsed.length, 1);
|
|
assert.equal(parsed[0]?.source, "known_event_quality");
|
|
assert.equal(parsed[0]?.role, "distinguish");
|
|
assert.equal(parsed[0]?.target_evidence_id, "00000000-0000-4000-8000-000000000001");
|
|
|
|
const unanchored = parseDiscriminatingEventProbes([qualityProbe({ target_evidence_id: undefined })]);
|
|
assert.equal(unanchored.length, 0);
|
|
|
|
const packet = contrastPacketFromLatestResult({
|
|
resultId: "result-a",
|
|
decisionReceipt: {
|
|
discriminating_event_probes: [qualityProbe()],
|
|
inference_state: {
|
|
probes: [{
|
|
id: "probe:education.2016.known_event_quality:quality-split",
|
|
semantic_key: "education.2016.known_event_quality",
|
|
candidate_split_hash: "quality-split",
|
|
domain: "education",
|
|
year: 2016,
|
|
question: "2016 年 9 月那次上大学,更接近哪一种实际体验。",
|
|
candidate_ids: ["05:00", "05:07"],
|
|
expected_outcomes: OUTCOMES,
|
|
information_gain: 0.42,
|
|
source: "known_event_quality",
|
|
choice_kind: "event_quality",
|
|
target_evidence_id: "00000000-0000-4000-8000-000000000001",
|
|
}],
|
|
answered_probes: [],
|
|
},
|
|
},
|
|
});
|
|
assert.equal(
|
|
packet.probes.some((item) => (
|
|
item.semanticKey === "education.2016.known_event_quality"
|
|
|| item.choiceKind === "event_quality"
|
|
)),
|
|
true,
|
|
);
|
|
});
|
|
|
|
test("quality answers are not inferred from event existence alone", () => {
|
|
const probe: ConflictProbe = {
|
|
id: "probe-quality",
|
|
semantic_key: "education.2016.known_event_quality",
|
|
candidate_split_hash: "quality-split",
|
|
domain: "education",
|
|
year: 2016,
|
|
question: "那次上大学更接近哪一种体验",
|
|
candidate_ids: ["05:00", "05:07"],
|
|
expected_outcomes: OUTCOMES,
|
|
information_gain: 0.42,
|
|
source: "known_event_quality",
|
|
choice_kind: "event_quality",
|
|
};
|
|
const answers = answersFromEvidence([probe], [{
|
|
id: "00000000-0000-4000-8000-000000000001",
|
|
domain: "education",
|
|
year: 2016,
|
|
precision: "month",
|
|
}]);
|
|
assert.equal(answers.length, 0);
|
|
});
|
|
|
|
test("prospective probes stay out of scoring copy", () => {
|
|
const parsed = parseProspectiveProbes([{
|
|
candidate_label: "A",
|
|
domain: "career",
|
|
window_label: "2027 年 3 月附近",
|
|
user_meaning: "候选 A 预测下一次事业变动更可能在 2027 年 3 月附近。这是预测窗口,不是承诺;下次发生时回来补一条,可进一步分辨。",
|
|
used_for_scoring: false,
|
|
}]);
|
|
assert.equal(parsed.length, 1);
|
|
const copy = prospectiveWindowsNarration(parsed);
|
|
assert.match(String(copy), /预测窗口/);
|
|
assert.equal(parsed[0]?.used_for_scoring, false);
|
|
});
|
|
|
|
test("scripts and frontend contain no answer-key literals", () => {
|
|
const forbidden = ["target" + "_minute", "pl9_" + "1993", "regression" + "_only"];
|
|
const files = [
|
|
...walkFiles(join(process.cwd(), "src"), [".ts", ".tsx", ".js"]),
|
|
...walkFiles(join(process.cwd(), "tests"), [".ts", ".tsx"]),
|
|
];
|
|
const hits: string[] = [];
|
|
for (const file of files) {
|
|
const text = readFileSync(file, "utf8");
|
|
for (const token of forbidden) {
|
|
if (text.includes(token)) hits.push(`${file}:${token}`);
|
|
}
|
|
}
|
|
assert.deepEqual(hits, []);
|
|
});
|