import assert from "node:assert/strict"; import { randomUUID } from "node:crypto"; import { spawnSync } from "node:child_process"; import { readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; import test from "node:test"; import { closeLocalPostgresDataPool, createLocalPostgresDataClient } from "../src/lib/db/local-postgres-client-core.ts"; import { resolveActiveSkillPackage } from "../src/lib/skill-package-registry.ts"; import { buildSegmentSummary, targetChartsForDomain } from "../src/lib/rectification-agentic/core/segment-summary.ts"; import { finalizeSuccessfulTurnExit } from "../src/lib/rectification-agentic/v9/turn-exit.ts"; import { prepareCaseSegmentChecks } from "../src/lib/rectification-agentic/v9/segment-checks.ts"; import { candidateRangeFingerprint, loadV9CaseDossier } from "../src/lib/rectification-agentic/v9/tool-service.ts"; import { dossierResponse } from "../src/lib/rectification-agentic/v9/case-dossier-response.ts"; import { startPostgresFixture } from "./helpers/postgres-fixture.ts"; const docker = spawnSync("docker", ["version"], { stdio: "ignore" }).status === 0; const runner = fileURLToPath(new URL("../scripts/db-migrate.mjs", import.meta.url)); const golden = JSON.parse(readFileSync(new URL("./fixtures/varga-api-response.golden.json", import.meta.url), "utf8")); test("segment opening PostgreSQL owns stable domain, full original checks and one shared-exit turn without adopting a minute", { skip: !docker && "docker unavailable" }, async () => { const fixture = startPostgresFixture(); const url = fixture.connectionUrl("service_runtime", "service-runtime-test-password"); const previousFetch = globalThis.fetch; try { const migration = spawnSync(process.execPath, [runner], { encoding: "utf8", env: { ...process.env, SCHEMA_DATABASE_URL: fixture.connectionUrl("schema_owner", "schema-owner-test-password"), } }); assert.equal(migration.status, 0, migration.stderr); const service = createLocalPostgresDataClient(url, null, "service_role"); const skill = resolveActiveSkillPackage("jyotish-birth-time-rectification"); const userId = randomUUID(); fixture.psqlAs("identity_runtime", "identity-runtime-test-password", `insert into identity.users(id,name,email,email_verified) values('${userId}','Synthetic Opening Control','${userId}@example.invalid',true)`); // Explicitly fictional complete-window permission control, not an engine calibration golden. const snapshot = { birth_date: "2000-06-14", reported_birth_time: "09:10", active_birth_time: null, birth_time_source: "family_exact", latitude: 40, longitude: -74, timezone_id: null, timezone_offset: -4 }; const range = { start_time: "09:00", end_time: "09:20", candidate_intervals: [{ start_at: "2000-06-14T09:00", end_at: "2000-06-14T09:20" }] }; const minutes = Array.from({ length: 21 }, (_, offset) => ({ offset, date: "2000-06-14", time: `09:${String(offset).padStart(2, "0")}`, signs: { D1: 1, D9: 2, D10: 3 } })); const args = { p_user_id: userId, p_request_id: randomUUID(), p_intent: "new", p_session_id: null, p_skill_name: skill.name, p_skill_version: skill.version, p_skill_sha256: skill.sha256, p_skill_source_commit: skill.sourceCommit, p_baseline_profile_fingerprint: "a".repeat(64), p_baseline_birth_snapshot: snapshot, p_candidate_range: range, p_product_domain: "relationship" }; const opened = await service.rpc("open_agentic_rectification_case_v2", args); assert.equal(opened.error, null, JSON.stringify(opened.error)); const caseId = (opened.data as { case_id: string }).case_id; assert.equal((await loadV9CaseDossier(service, userId, caseId)).case.rectificationDomain, "relationship"); const retry = await service.rpc("open_agentic_rectification_case_v2", { ...args, p_product_domain: "career" }); assert.equal(retry.error, null); assert.equal((retry.data as { should_start_opening: boolean }).should_start_opening, true, "unstarted new-case retry still runs its opening"); assert.equal((await loadV9CaseDossier(service, userId, caseId)).case.rectificationDomain, "relationship", "retry cannot drift product domain"); const write = (checks: unknown, candidateRange: unknown = range, owner = userId) => service.rpc("write_agentic_rectification_segment_checks_v1", { p_user_id: owner, p_case_id: caseId, p_candidate_range: candidateRange, p_checks: checks, }); const checks = { contract: "segment-opening-v1", domain: "relationship", range_fingerprint: candidateRangeFingerprint(range, "a".repeat(64)), status: "complete", summary: buildSegmentSummary({ minutes, candidates: [], targets: targetChartsForDomain("relationship"), windowMinutes: 21, scanComplete: true }) }; const before = fixture.psql(`select to_jsonb(c)::text from public.agentic_rectification_cases c where id='${caseId}'`); assert.ok((await write(checks, range, randomUUID())).error); assert.ok((await write(checks, { ...range, end_time: "09:10" })).error); const shortened = buildSegmentSummary({ minutes: minutes.slice(0, 11), candidates: [], targets: ["D1", "D9"], windowMinutes: 11, scanComplete: true }); assert.ok((await write({ ...checks, summary: shortened })).error, "short credible width is not the original full window"); const d1Only = buildSegmentSummary({ minutes, candidates: [], targets: ["D1"], windowMinutes: 21, scanComplete: true }); assert.ok((await write({ ...checks, summary: d1Only })).error, "no D1-only product opt-out"); assert.equal(fixture.psql(`select to_jsonb(c)::text from public.agentic_rectification_cases c where id='${caseId}'`), before, "invalid checks leave no partial write"); const unavailable = await write({ ...checks, status: "unavailable", summary: null, range_fingerprint: "c".repeat(64) }); assert.equal(unavailable.error, null); assert.ok((await service.rpc("finalize_agentic_rectification_segment_consistency_v1", { p_user_id: userId, p_case_id: caseId, p_range_fingerprint: "c".repeat(64), p_narration: "Synthetic control", })).error, "unavailable scan cannot finalize"); // Different fingerprint replaces the unavailable proof; callers cannot invent delivery identity. assert.equal((await write({ ...checks, delivered_turn_id: randomUUID() })).error, null); assert.equal(fixture.psql(`select checks ? 'delivered_turn_id' from public.agentic_rectification_cases where id='${caseId}'`), "f"); const profileBefore = fixture.psql(`select to_jsonb(p)::text from public.profiles p where id='${userId}'`); const exit = await finalizeSuccessfulTurnExit({ accounting: service, userId, caseId, action: "opening", segmentOpening: true }); assert.ok(exit?.segmentConsistency); const after = fixture.psql(`select to_jsonb(c)::text from public.agentic_rectification_cases c where id='${caseId}'`); const again = await finalizeSuccessfulTurnExit({ accounting: service, userId, caseId, action: "opening", segmentOpening: true }); assert.equal(again?.turnId, exit.turnId); assert.equal(fixture.psql(`select to_jsonb(c)::text from public.agentic_rectification_cases c where id='${caseId}'`), after, "retry does not refresh timestamps/checks"); assert.equal(fixture.psql(`select to_jsonb(p)::text from public.profiles p where id='${userId}'`), profileBefore, "consistency is neither adopt nor confirm"); assert.equal(fixture.psql(`select count(*) from public.agentic_rectification_turns where case_id='${caseId}'`), "1"); assert.equal(fixture.psql(`select count(*) from public.agentic_rectification_conversation_focuses where case_id='${caseId}'`), "0"); const dossier = await loadV9CaseDossier(service, userId, caseId); assert.equal(dossier.case.status, "closed"); const publicView = dossierResponse(dossier, [], { status: "current", requiresSkillAdoption: false } as never); assert.equal(publicView.current_question, null); assert.equal(publicView.choice_card, null); assert.equal(publicView.step_state.headline, "盘型一致,不用校正"); assert.equal(publicView.next_user_action.id, "start_consultation"); assert.ok(publicView.turns.some(turn => "segment_consistency" in turn)); assert.equal(publicView.case.accepted_time, null); assert.equal(publicView.case.confirmed_time, null); for (const signature of ["agentic_rectification_opening_pending_v1(uuid,uuid)", "initialize_agentic_rectification_domain_v1(uuid,uuid,text)", "write_agentic_rectification_segment_checks_v1(uuid,uuid,jsonb,jsonb)", "finalize_agentic_rectification_segment_consistency_v1(uuid,uuid,text,text)", "open_agentic_rectification_case_v2(uuid,uuid,text,uuid,text,text,text,text,text,jsonb,jsonb,text)"]) { assert.equal(fixture.psql(`select has_function_privilege('authenticated','public.${signature}','execute')::text`), "f"); } // BUG-1131: the product-domain open wrapper runs as the service caller, never as the owner. assert.equal(fixture.psql("select prosecdef::text from pg_proc where oid='public.open_agentic_rectification_case_v2(uuid,uuid,text,uuid,text,text,text,text,text,jsonb,jsonb,text)'::regprocedure"), "f"); // Real captured native API scan is a separate nonunique production contract. const req = golden.request; const realRange = { start_time: req.start_time, end_time: req.end_time, candidate_intervals: golden.response.decision_receipt.candidate_intervals }; const real = await service.rpc("open_agentic_rectification_case_v2", { ...args, p_request_id: randomUUID(), p_product_domain: "general", p_candidate_range: realRange, p_baseline_birth_snapshot: { birth_date: req.birth_date, latitude: req.lat, longitude: req.lon, timezone_offset: req.tz, birth_time_source: "family_exact" } }); assert.equal(real.error, null); const realCaseId = (real.data as { case_id: string }).case_id; globalThis.fetch = (async () => Response.json(golden.scan)) as typeof fetch; const realChecks = await prepareCaseSegmentChecks({ accounting: service, userId, caseId: realCaseId }); assert.equal(realChecks?.status, "complete"); assert.equal(realChecks?.summary?.no_rectification_needed, false); assert.equal(await finalizeSuccessfulTurnExit({ accounting: service, userId, caseId: realCaseId, action: "opening", segmentOpening: true }), undefined); assert.equal(fixture.psql(`select count(*) from public.agentic_rectification_turns where case_id='${realCaseId}'`), "0"); // Disjoint and 1441-minute controls cannot masquerade as the shorter original window. for (const invalidRange of [ { start_time: "09:00", end_time: "09:20", candidate_intervals: [ { start_at: "2000-06-14T09:00", end_at: "2000-06-14T09:09" }, { start_at: "2000-06-14T09:11", end_at: "2000-06-14T09:20" }] }, { start_time: "09:00", end_time: "09:00", candidate_intervals: [{ start_at: "2000-06-14T09:00", end_at: "2000-06-15T09:00" }] }, ]) { const control = await service.rpc("open_agentic_rectification_case_v2", { ...args, p_request_id: randomUUID(), p_candidate_range: invalidRange }); assert.equal(control.error, null); const controlId = (control.data as { case_id: string }).case_id; const rejected = await service.rpc("write_agentic_rectification_segment_checks_v1", { p_user_id: userId, p_case_id: controlId, p_candidate_range: invalidRange, p_checks: checks, }); assert.ok(rejected.error); assert.equal(fixture.psql(`select checks is null from public.agentic_rectification_cases where id='${controlId}'`), "t"); } const missingDomain = await service.rpc("open_agentic_rectification_case_v2", { ...args, p_request_id: randomUUID(), p_product_domain: "D1" }); assert.ok(missingDomain.error); // Historical caller remains nullable and does not acquire the new opening contract. const oldArgs: Partial = { ...args }; delete oldArgs.p_product_domain; const legacy = await service.rpc("open_agentic_rectification_case_v2", { ...oldArgs, p_request_id: randomUUID() }); assert.equal(legacy.error, null); const legacyId = (legacy.data as { case_id: string }).case_id; assert.equal((await loadV9CaseDossier(service, userId, legacyId)).case.rectificationDomain, null); assert.equal(await prepareCaseSegmentChecks({ accounting: service, userId, caseId: legacyId }), null); } finally { globalThis.fetch = previousFetch; await closeLocalPostgresDataPool(url); fixture.stop(); } });