Download scripts/eval_verifier.ts from Ryukijano/conjugate: direct link, hf CLI and curl.
- Browser
- Download file 12.6 kB
-
https://huggingface.co/spaces/Ryukijano/conjugate/resolve/main/scripts/eval_verifier.ts
- Command line
-
hf download hf://spaces/Ryukijano/conjugate/scripts/eval_verifier.ts
-
curl -L -o eval_verifier.ts https://huggingface.co/spaces/Ryukijano/conjugate/resolve/main/scripts/eval_verifier.ts
12.6 kB
| import { readFileSync, writeFileSync } from 'node:fs'; | |
| import { pathToFileURL } from 'node:url'; | |
| import { runInNewContext } from 'node:vm'; | |
| import ts from 'typescript'; | |
| import { EvidencePolicySchema, ResearchQuestionSchema, type ResearchDraft, type ResearchReceipt, type ResearchRequest } from '@her2/shared'; | |
| import { auditResearchDraft } from '../apps/api/src/research.js'; | |
| import { allowedTools, DATASET_SHA256, derivedSourceId, expectedClaim, labelSourceId, readResearchTool, receiptIntegrity, workbookSourceId } from '../apps/api/src/research-evidence.js'; | |
| import { openFdaSourceId } from '../apps/api/src/research-openfda.js'; | |
| import { fingerprint, HARNESS_CODE_SHA256 } from '../apps/api/src/research-harness.js'; | |
| export const STUDY_SEEDS = [17, 29, 43] as const; | |
| export const studyScopes: ResearchRequest[] = (['DRG0CYMEB', 'DRG0ERKBH'] as const).flatMap(product_id => | |
| ResearchQuestionSchema.options.flatMap(question_id => EvidencePolicySchema.options.map(evidence_policy => | |
| ({ product_id, question_id, evidence_policy, engine: 'evidence' as const, integrity_drill: 'none' as const, synthetic_confirmed: true as const })))); | |
| export function shuffle<T>(values: T[], seed: number) { | |
| const copy = [...values]; let state = seed; | |
| for (let i = copy.length - 1; i > 0; i--) { | |
| state = (Math.imul(state, 1664525) + 1013904223) >>> 0; | |
| const j = state % (i + 1); [copy[i], copy[j]] = [copy[j]!, copy[i]!]; | |
| } | |
| return copy; | |
| } | |
| export function studyManifest(script: string) { | |
| return { code_sha256: HARNESS_CODE_SHA256, dataset_sha256: DATASET_SHA256, | |
| evaluation_sha256: fingerprint(readFileSync(new URL(script, import.meta.url), 'utf8')), | |
| design_sha256: fingerprint(readFileSync(new URL('../docs/EVALUATION_DESIGN.md', import.meta.url), 'utf8')), | |
| lockfile_sha256: fingerprint(readFileSync(new URL('../package-lock.json', import.meta.url), 'utf8')), | |
| node: process.version, seeds: STUDY_SEEDS, scopes: studyScopes.length }; | |
| } | |
| export const CHECKS = ['product_identity', 'source_allowlist', 'exact_source_claim_pairing', 'source_eligibility', 'evidence_availability', 'unique_claims', 'omitted_claim_ids', 'receipt_integrity'] as const; | |
| const source = readFileSync(new URL('../apps/api/src/research.ts', import.meta.url), 'utf8'); | |
| const parsed = ts.createSourceFile('research.ts', source, ts.ScriptTarget.ES2022, true); | |
| const functions = parsed.statements.filter(node => ts.isFunctionDeclaration(node) && ['sameIds', 'auditResearchDraft'].includes(node.name?.text ?? '')); | |
| if (functions.length !== 2) throw new Error('Verifier source extraction failed.'); | |
| const extracted = functions.map(node => node.getText(parsed)).join('\n'); | |
| export function compiledVerifier(disabled: readonly string[], alwaysAccept = false): typeof auditResearchDraft { | |
| if (new Set(disabled).size !== disabled.length) throw new Error('Mutant target did not match exactly once.'); | |
| const file = ts.createSourceFile('verifier.ts', extracted, ts.ScriptTarget.ES2022, true); | |
| const hits = new Map<string, number>(); | |
| const transform: ts.TransformerFactory<ts.SourceFile> = context => { | |
| const visit: ts.Visitor = node => { | |
| if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'add' | |
| && ts.isStringLiteral(node.arguments[0]!) && disabled.includes(node.arguments[0]!.text)) { | |
| const id = node.arguments[0]!.text; hits.set(id, (hits.get(id) ?? 0) + 1); | |
| return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, | |
| [node.arguments[0]!, ts.factory.createTrue(), ...node.arguments.slice(2)]); | |
| } | |
| if (alwaysAccept && ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === 'accepted') { | |
| hits.set('always_accept', (hits.get('always_accept') ?? 0) + 1); | |
| return ts.factory.updateVariableDeclaration(node, node.name, node.exclamationToken, node.type, ts.factory.createTrue()); | |
| } | |
| return ts.visitEachChild(node, visit, context); | |
| }; | |
| return root => ts.visitNode(root, visit) as ts.SourceFile; | |
| }; | |
| const result = ts.transform(file, [transform]); | |
| let changed: string; | |
| try { changed = ts.createPrinter().printFile(result.transformed[0]!); } finally { result.dispose(); } | |
| if ([...disabled, ...(alwaysAccept ? ['always_accept'] : [])].some(id => hits.get(id) !== 1)) throw new Error('Mutant target did not match exactly once.'); | |
| const js = ts.transpileModule(changed, { compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.CommonJS } }).outputText; | |
| const exports: { auditResearchDraft?: typeof auditResearchDraft } = {}; | |
| runInNewContext(js, { exports, expectedClaim, labelSourceId, workbookSourceId, derivedSourceId, openFdaSourceId, receiptIntegrity }, { timeout: 1000 }); | |
| if (!exports.auditResearchDraft) throw new Error('Verifier compilation failed.'); | |
| return exports.auditResearchDraft; | |
| } | |
| type Fault = { id: string; draft: ResearchDraft; receipts: ResearchReceipt[] }; | |
| export function faultCases(request: ResearchRequest, receipts: ResearchReceipt[], draft: ResearchDraft) { | |
| const cases: Fault[] = []; const excluded: string[] = []; | |
| const add = (id: string, change: (copy: Fault) => void) => { const copy = { id, draft: structuredClone(draft), receipts: structuredClone(receipts) }; change(copy); cases.push(copy); }; | |
| add('wrong_product', copy => { copy.draft.product_id = request.product_id === 'DRG0ERKBH' ? 'DRG0CYMEB' : 'DRG0ERKBH'; }); | |
| add('missing_claim', copy => { copy.draft.claims = []; }); | |
| add('duplicate_claim', copy => { copy.draft.claims.push(structuredClone(copy.draft.claims[0]!)); }); | |
| add('extra_claim', copy => { copy.draft.claims.push({ ...structuredClone(copy.draft.claims[0]!), claim_id: 'UNSUPPORTED-SOFTWARE-CLAIM' }); }); | |
| add('invented_citation', copy => { copy.draft.claims[0]!.source_ids = ['INVENTED-SOFTWARE-SOURCE']; }); | |
| add('cross_product_citation', copy => { copy.draft.claims[0]!.source_ids = [labelSourceId(request.product_id === 'DRG0ERKBH' ? 'DRG0CYMEB' : 'DRG0ERKBH')]; }); | |
| add('receipt_text_edit', copy => { const target = copy.receipts.find(receipt => receipt.kind === 'derived') ?? copy.receipts[0]!; target.title += ' SYNTHETIC SOFTWARE FAULT'; }); | |
| const derived = receipts.find(receipt => receipt.kind === 'derived'); | |
| if (derived) add('derived_as_primary', copy => { copy.draft.claims[0]!.source_ids = [derived.id]; }); else excluded.push('derived_as_primary:no_derived_receipt'); | |
| const first = draft.claims[0]!.source_ids[0]; | |
| if (first) { | |
| add('duplicate_citation', copy => { copy.draft.claims[0]!.source_ids.push(first); }); | |
| add('missing_primary_receipt', copy => { copy.receipts = copy.receipts.filter(receipt => receipt.id !== first); }); | |
| } else excluded.push('duplicate_citation:no_primary_ids', 'missing_primary_receipt:no_primary_ids'); | |
| if (request.evidence_policy === 'workbook_only') add('withheld_source', copy => { copy.receipts.push(...readResearchTool('read_label', { ...request, evidence_policy: 'all' })); }); | |
| else excluded.push('withheld_source:policy_all'); | |
| return { cases, excluded }; | |
| } | |
| export function runVerifierStudy() { | |
| const variants = [{ name: 'unmodified_compiled', disabled: [] as string[], always: false }, | |
| ...CHECKS.map(id => ({ name: id, disabled: [id], always: false })), | |
| { name: 'citation_defenses_removed', disabled: ['source_allowlist', 'exact_source_claim_pairing', 'source_eligibility', 'evidence_availability'], always: false }, | |
| { name: 'always_accept', disabled: [], always: true }]; | |
| const auditors = variants.map(variant => ({ ...variant, audit: compiledVerifier(variant.disabled, variant.always) })); | |
| const rows: { scope: string; case_id: string; kind: 'control' | 'fault'; healthy_accepted: boolean; accepted_by: string[]; caught_by: string[] }[] = []; | |
| const exclusions: { scope: string; reason: string }[] = []; | |
| let compiledAgrees = true; let controlSemanticsHold = true; | |
| for (const request of studyScopes) { | |
| const scope = `${request.product_id}/${request.question_id}/${request.evidence_policy}`; | |
| const receipts = allowedTools(request).flatMap(tool => readResearchTool(tool, request)); | |
| const expected = expectedClaim(request, receipts); | |
| const draft: ResearchDraft = { product_id: request.product_id, claims: [{ claim_id: request.question_id, source_ids: expected.source_ids }] }; | |
| const baseline = auditResearchDraft(request, draft, receipts); | |
| const semantics = (audit: typeof baseline) => fingerprint({ accepted: audit.accepted, verdict: audit.expected.verdict, | |
| source_ids: [...audit.expected.source_ids].sort(), omitted: [...audit.omitted_claim_ids].sort() }); | |
| const controls = [{ id: 'exact_control', draft, receipts }, ...STUDY_SEEDS.map(seed => ({ id: `harmless_order_${seed}`, | |
| draft: { ...draft, claims: draft.claims.map(claim => ({ ...claim, source_ids: shuffle(claim.source_ids, seed) })) }, | |
| receipts: shuffle(receipts, seed).map(receipt => Object.fromEntries(Object.entries(receipt).reverse()) as ResearchReceipt) }))]; | |
| const faults = faultCases(request, receipts, draft); | |
| exclusions.push(...faults.excluded.map(reason => ({ scope, reason }))); | |
| for (const [kind, cases] of [['control', controls], ['fault', faults.cases]] as const) for (const input of cases) { | |
| const healthy = auditResearchDraft(request, input.draft, input.receipts); | |
| const decisions = auditors.map(variant => ({ name: variant.name, accepted: variant.audit(request, input.draft, input.receipts).accepted })); | |
| if (fingerprint(auditors[0]!.audit(request, input.draft, input.receipts)) !== fingerprint(healthy)) compiledAgrees = false; | |
| if (kind === 'control' && semantics(healthy) !== semantics(baseline)) controlSemanticsHold = false; | |
| rows.push({ scope, case_id: input.id, kind, healthy_accepted: healthy.accepted, | |
| accepted_by: decisions.filter(item => item.accepted).map(item => item.name), caught_by: healthy.challenges.filter(check => check.outcome === 'caught').map(check => check.code) }); | |
| } | |
| } | |
| const controls = rows.filter(row => row.kind === 'control'); const faults = rows.filter(row => row.kind === 'fault'); | |
| const mutants = variants.slice(1).map(variant => { | |
| const escapes = faults.filter(row => !row.healthy_accepted && row.accepted_by.includes(variant.name)); | |
| return { name: variant.name, disabled_checks: variant.disabled, detected: escapes.length > 0, escaped_faults: escapes.length, | |
| faults: faults.length, controls_accepted: controls.filter(row => row.accepted_by.includes(variant.name)).length, controls: controls.length, | |
| examples: escapes.slice(0, 3).map(row => ({ scope: row.scope, case_id: row.case_id })) }; | |
| }); | |
| const required = ['product_identity', 'exact_source_claim_pairing', 'unique_claims', 'omitted_claim_ids', 'receipt_integrity', 'citation_defenses_removed', 'always_accept']; | |
| const passed = compiledAgrees && controlSemanticsHold && controls.every(row => row.healthy_accepted) && faults.every(row => !row.healthy_accepted) | |
| && mutants.every(row => row.controls_accepted === row.controls) && required.every(name => mutants.some(row => row.name === name && row.detected)); | |
| return { kind: 'developer_authored_verifier_sensitivity_not_clinical', generated_at: new Date().toISOString(), manifest: studyManifest('./eval_verifier.ts'), | |
| verifier_function_sha256: fingerprint(extracted), passed, compiled_agrees: compiledAgrees, control_semantics_hold: controlSemanticsHold, scope_count: studyScopes.length, | |
| controls_accepted: controls.filter(row => row.healthy_accepted).length, control_count: controls.length, | |
| faults_rejected: faults.filter(row => !row.healthy_accepted).length, fault_count: faults.length, | |
| mutants_detected: mutants.filter(row => row.detected).length, mutant_count: mutants.length, mutants, exclusions, rows, | |
| limits: ['Mutants change the real verifier function in memory only, never the app.', 'Overlapping checks can leave individual mutants surviving; survivors are shown.', 'Known fixtures, not an unseen clinical holdout.', 'No model calls; counts are finite software coverage, not a probability of safety.'] }; | |
| } | |
| if (process.argv[1] && pathToFileURL(process.argv[1]).href === import.meta.url) { | |
| const out = runVerifierStudy(); | |
| writeFileSync(new URL('../evals/verifier-study.json', import.meta.url), JSON.stringify(out, null, 2) + '\n'); | |
| console.log(JSON.stringify({ passed: out.passed, mutants_detected: out.mutants_detected, mutants: out.mutant_count, | |
| controls: `${out.controls_accepted}/${out.control_count}`, faults: `${out.faults_rejected}/${out.fault_count}` })); | |
| if (!out.passed) process.exitCode = 1; | |
| } | |