import assert from "node:assert/strict"; import { randomUUID } from "node:crypto"; import { readFileSync } from "node:fs"; import { spawnSync } from "node:child_process"; import { fileURLToPath } from "node:url"; import test from "node:test"; import { closeLocalPostgresDataPool, createLocalPostgresDataClient } from "../src/lib/db/local-postgres-client-core.ts"; import { resolveActiveSkillPackage, resolveExactSkillPackage } from "../src/lib/skill-package-registry.ts"; import { excludeEmptyConsultations } from "../src/lib/session-list-filter.ts"; import { openRectificationCase } from "../src/lib/rectification-agentic/v9/case-service.ts"; import { runV9CandidateScore, type V9EngineEvent } from "../src/lib/rectification-agentic/v9/engine-client.ts"; import { buildProductCaseInferenceState } from "../src/lib/rectification-agentic/v9/product-inference.ts"; import { asInferenceState } from "../src/lib/rectification-agentic/core/compose-receipt.ts"; import { refinementFromDecisionReceipt } from "../src/lib/rectification-agentic/v9/refinement-packet.ts"; import { applyRectificationChoice } from "../src/lib/rectification-agentic/v9/answer-choice.ts"; import { CHOICE_ACTION } from "../src/lib/rectification-agentic/v9/choice-action.ts"; import { buildChoiceFrame } from "../src/lib/rectification-agentic/v9/choice-card.ts"; import type { MethodFollowup } from "../src/lib/rectification-agentic/v9/method-followup.ts"; import { persistServerOwnedFocus } from "../src/lib/rectification-agentic/v9/server-focus.ts"; import { insertV9SkillRunReceipt, loadV9CaseDossier, loadV9CaseSkillIdentity, persistV9Candidate } from "../src/lib/rectification-agentic/v9/tool-service.ts"; import { startPostgresFixture } from "./helpers/postgres-fixture.ts"; const golden = JSON.parse(readFileSync(new URL("./fixtures/varga-api-response.golden.json", import.meta.url), "utf8")); const docker = spawnSync("docker", ["version"], { stdio: "ignore" }).status === 0; const runner = fileURLToPath(new URL("../scripts/db-migrate.mjs", import.meta.url)); // A historically bound Case seeded explicitly, not a new-opening bypass or an engine-policy fixture. // Scoring/probes are unmodified public-AA API captures; user/session ownership is fictional. test("post-bump historical exact Skill survives real PostgreSQL list, session open, cached result, choice and run receipt", { skip: !docker && "docker unavailable" }, async () => { const fixture = startPostgresFixture(); const url = fixture.connectionUrl("service_runtime", "service-runtime-test-password"); const authenticatedUrl = fixture.connectionUrl("app_runtime", "app-runtime-test-password"); const previousFetch = globalThis.fetch; try { const migrated = spawnSync(process.execPath, [runner], { encoding: "utf8", env: { ...process.env, SCHEMA_DATABASE_URL: fixture.connectionUrl("schema_owner", "schema-owner-test-password"), } }); assert.equal(migrated.status, 0, migrated.stderr); const active = resolveActiveSkillPackage("jyotish-birth-time-rectification"); const old = resolveExactSkillPackage(active.name, "10.0.32", "c2cab1364542e96290be416bb3d445c8c2baa90a52371aff2067b4d338184cee"); assert.equal(active.version, "10.0.33"); assert.equal(old.status, "deprecated"); const req = golden.request, intervals = golden.response.decision_receipt.candidate_intervals; const range = { start_time: req.start_time, end_time: req.end_time, candidate_intervals: intervals }; const reported = new Date((Date.parse(`${intervals[0].start_at}:00Z`) + Date.parse(`${intervals[0].end_at}:00Z`)) / 2).toISOString().slice(11, 16); const snapshot = { birth_date: req.birth_date, reported_birth_time: reported, active_birth_time: null, birth_time_source: "approximate", birth_time_period: null, uncertainty_before_minutes: 15, uncertainty_after_minutes: 15, latitude: req.lat, longitude: req.lon, timezone_id: "America/Los_Angeles", timezone_offset: req.tz }; const userId = randomUUID(), sessionId = randomUUID(), caseId = randomUUID(); const closedSessionId = randomUUID(), closedCaseId = randomUUID(), emptyConsultationId = randomUUID(); fixture.psqlAs("identity_runtime", "identity-runtime-test-password", `insert into identity.users(id,name,email,email_verified) values('${userId}','Fictional Historical Skill Owner','${userId}@example.invalid',true)`); fixture.psql(`update public.profiles set birth_date='${req.birth_date}',reported_birth_time='${reported}',birth_time_source='approximate',birth_time_status='reported', uncertainty_before_minutes=15,uncertainty_after_minutes=15,latitude=${req.lat},longitude=${req.lon},timezone_id='America/Los_Angeles',timezone_offset=${req.tz} where id='${userId}'; insert into public.chat_sessions(id,user_id,title,theme,session_type,messages) values ('${sessionId}','${userId}','Fictional historical active','general','birth_time_rectification','[]'), ('${closedSessionId}','${userId}','Fictional historical readonly','general','birth_time_rectification','[]'), ('${emptyConsultationId}','${userId}','Fictional empty consultation','general','consultation','[]'); insert into public.agentic_rectification_cases(id,user_id,session_id,status,skill_name,skill_version,skill_sha256,skill_source_commit,baseline_profile_fingerprint,baseline_birth_snapshot,candidate_range,completed_at) values ('${caseId}','${userId}','${sessionId}','candidate_ready','${old.name}','${old.version}','${old.sha256}',${old.sourceCommit ? `'${old.sourceCommit}'` : "null"},'${"a".repeat(64)}','${JSON.stringify(snapshot)}','${JSON.stringify(range)}',null), ('${closedCaseId}','${userId}','${closedSessionId}','closed','${old.name}','${old.version}','${old.sha256}',${old.sourceCommit ? `'${old.sourceCommit}'` : "null"},'${"a".repeat(64)}','${JSON.stringify(snapshot)}','${JSON.stringify(range)}',now())`); const service = createLocalPostgresDataClient(url, null, "service_role"); const authenticated = createLocalPostgresDataClient(authenticatedUrl, { id: userId, email: null }, "authenticated"); const listed = await excludeEmptyConsultations(authenticated.from("chat_sessions") .select("id,session_type,rectification_case_id,messages").eq("user_id", userId).eq("pinned", false) .is("archived_at", null).or("chart_profile_id.is.null,chart_profile_id.eq.self")) .order("updated_at", { ascending: false }).order("id", { ascending: false }).limit(21); assert.equal(listed.error, null, JSON.stringify(listed.error)); const rows = listed.data as { id: string; messages: unknown[] }[]; assert.deepEqual(new Set(rows.map(row => row.id)), new Set([sessionId, closedSessionId])); assert.ok(rows.every(row => row.messages.length === 0), "production filter keeps history whose messages live in the Case ledger"); for (const [id, expectedCase, disposition] of [[sessionId, caseId, "resumed"], [closedSessionId, closedCaseId, "readonly"]] as const) { // Production session path reads the old identity first, then calls the old eleven-argument overload. // Any permission refusal is a test failure; no grants, direct replacement open or twelve-argument retry. const opened = await openRectificationCase( service as unknown as Parameters[0], userId, { intent: "session", sessionId: id, requestId: randomUUID() }, ); assert.equal(opened.caseId, expectedCase); assert.equal(opened.sessionId, id); assert.equal(opened.skillVersion, old.version); assert.equal(opened.disposition, disposition); assert.equal(opened.shouldStartOpening, false); } const bound = await loadV9CaseSkillIdentity(service, userId, caseId); assert.deepEqual(bound, { name: old.name, version: old.version, sha256: old.sha256, sourceCommit: old.sourceCommit }); assert.equal(resolveExactSkillPackage(bound.name, bound.version, bound.sha256).sha256, old.sha256); globalThis.fetch = (async (endpoint: unknown) => new Response(JSON.stringify(String(endpoint).includes("versions") ? { algorithm_version: golden.response.algorithm_version, decision_policy_version: golden.response.decision_policy_version } : golden.response), { status: 200 })) as typeof fetch; const score = await runV9CandidateScore({ baselineBirthSnapshot: snapshot, candidateRange: range, events: req.events as V9EngineEvent[] }); const probes = refinementFromDecisionReceipt(score.decisionReceipt).discriminating_event_probes; const inference = buildProductCaseInferenceState({ range, candidates: score.candidates, evidence: [], probes }, null); assert.equal(inference.segment_targets, undefined, "nullable historical identity does not opt into the product scan"); assert.equal(inference.segment_summary, undefined); assert.equal(inference.segment_minutes, undefined); assert.ok(inference.candidates.every(candidate => candidate.signature === undefined && candidate.raw_prior_score === undefined && candidate.raw_posterior_score === undefined && candidate.raw_eliminated === undefined)); const input = { engineResultId: score.engineResultId, algorithmVersion: score.algorithmVersion, evidenceFingerprint: "b".repeat(64), rangeFingerprint: "c".repeat(64), skillVersion: old.version, eventContractVersion: score.eventContractVersion, policyVersion: score.policyVersion, candidateRange: range, candidates: score.candidates, decisionReceipt: { ...score.decisionReceipt, inference_state: inference }, executionLedger: score.executionLedger }; const first = await persistV9Candidate(service, userId, caseId, input); const cached = await persistV9Candidate(service, userId, caseId, input); assert.equal(cached.cached, true); assert.equal(cached.resultId, first.resultId); assert.equal(fixture.psql(`select count(*) from public.agentic_rectification_results where case_id='${caseId}'`), "1"); const loaded = await loadV9CaseDossier(service, userId, caseId); assert.equal(loaded.case.skillVersion, old.version); assert.equal(loaded.case.rectificationDomain, null); assert.equal(loaded.latestResult?.decisionReceipt?.product_delivery, undefined); const before = asInferenceState(loaded.latestResult!.decisionReceipt?.inference_state); assert.ok(before); const probe = probes.find(probe => (probe.information_gain ?? 0) > 0 && probe.year > 0 && probe.expected_outcomes?.some(outcome => outcome.answer_class === "yes" && outcome.supports.length > 0)); assert.ok(probe); const followup = { method_id: "dasha_events", ask_theme: "dated_event", domain: probe.domain, user_prompt_hint: probe.user_meaning, intent: "distinguish_candidates", source: "event_probe", semantic_key: probe.semantic_key, candidate_split_hash: probe.candidate_split_hash, candidate_ids: probe.candidate_ids, expected_outcomes: probe.expected_outcomes, information_gain: probe.information_gain, probe_year: probe.year, ...(probe.choice_kind ? { choice_kind: probe.choice_kind } : {}), ...(probe.style_options ? { style_options: probe.style_options } : {}) }; const frame = buildChoiceFrame(followup, { probes: [probe], birthDate: req.birth_date }); assert.ok(frame); const focus = await persistServerOwnedFocus({ accounting: service, userId, caseId, activeFocus: null, decisionReceipt: loaded.latestResult!.decisionReceipt, followup: { ...followup, choice_frame: frame, must_not_label: [] } as unknown as MethodFollowup }); assert.ok(focus.focus); const actionId = randomUUID(); const chosen = await applyRectificationChoice(service, { userId, caseId, sessionId, actionId, action: CHOICE_ACTION, focusId: focus.focus.id, optionId: "A", expectedRevision: before.revision, deferFollowup: true }); assert.equal(chosen.applied, true); const reloaded = await loadV9CaseDossier(service, userId, caseId); assert.equal(asInferenceState(reloaded.latestResult!.decisionReceipt?.inference_state)?.revision, before.revision + 1); assert.equal(reloaded.case.rectificationDomain, null); assert.equal(asInferenceState(reloaded.latestResult!.decisionReceipt?.inference_state)?.segment_summary, undefined); assert.ok(asInferenceState(reloaded.latestResult!.decisionReceipt?.inference_state)?.candidates.every(candidate => candidate.signature === undefined && candidate.raw_prior_score === undefined && candidate.raw_posterior_score === undefined && candidate.raw_eliminated === undefined)); assert.equal(fixture.psql(`select count(*) from public.agentic_rectification_inference_transitions where case_id='${caseId}'`), "1"); assert.equal(fixture.psql(`select count(*) from public.agentic_rectification_choice_actions where case_id='${caseId}' and status in ('applied','narrated')`), "1"); // Runtime turns use the V10 request-idempotent overload (agent-run-prepare.ts); the V9 // overload behind appendV9Turn is revoked from service_role by 20260814020000. const appended = await service.rpc("append_agentic_rectification_turn", { p_user_id: userId, p_case_id: caseId, p_user_message: "Fictional historical action", p_assistant_message: null, p_model_name: "fictional-history-receipt", p_model_version: null, p_status: "pending", p_request_id: randomUUID() }); assert.equal(appended.error, null, JSON.stringify(appended.error)); const turnId = (appended.data as { turn_id: string }).turn_id; await insertV9SkillRunReceipt(service, userId, caseId, turnId, randomUUID(), "turn", bound); assert.equal(fixture.psql(`select skill_version || ':' || skill_sha256 from public.agentic_rectification_skill_run_receipts where case_id='${caseId}'`), `${old.version}:${old.sha256}`); assert.deepEqual(await loadV9CaseSkillIdentity(service, userId, caseId), bound, "choice/cache/run action never upgrades to active"); } finally { globalThis.fetch = previousFetch; await closeLocalPostgresDataPool(url); await closeLocalPostgresDataPool(authenticatedUrl); fixture.stop(); } });