Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
201 lines
18 KiB
TypeScript
201 lines
18 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { randomUUID } from "node:crypto";
|
|
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 { buildInferenceState } from "../src/lib/rectification-agentic/core/build-state.ts";
|
|
import { clearAdoptedChartTierCache, loadAdoptedChartTiers } from "../src/lib/rectification-adopted-chart-tiers.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));
|
|
|
|
// Explicitly fictional SQL permission-boundary fixture, not a calibrated engine golden.
|
|
for (const timezoneId of ["America/New_York", null]) {
|
|
test(`segment adoption persists a noncandidate midnight minute atomically without relaxing confirmation${timezoneId === null ? " (offset-only)" : ""}`, { skip: !docker && "docker unavailable" }, async () => {
|
|
const fixture = startPostgresFixture();
|
|
const url = fixture.connectionUrl("service_runtime", "service-runtime-test-password");
|
|
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 userId = randomUUID(), sessionId = randomUUID(), caseId = randomUUID();
|
|
const snapshot = { birth_date: "2000-06-14", reported_birth_time: "23:59", active_birth_time: null,
|
|
birth_time_source: "family_exact", birth_time_period: null, uncertainty_before_minutes: 15, uncertainty_after_minutes: 15,
|
|
latitude: 40, longitude: -74, timezone_id: timezoneId, timezone_offset: -4 };
|
|
const intervals = [{ start_at: "2000-06-14T23:55", end_at: "2000-06-15T00:25" }];
|
|
const range = { start_time: "23:55", end_time: "00:25", candidate_intervals: intervals };
|
|
const candidates = [0, 16].map((offset, i) => {
|
|
const at = new Date(Date.parse("2000-06-14T23:55:00Z") + offset * 60000).toISOString().slice(0, 16);
|
|
return { time: at.slice(11), candidate_date: at.slice(0, 10), window_index: offset, window_offset_minutes: offset, segment_index: 0,
|
|
id: at.slice(11), rank: i + 1, relative_support: 50, raw_score: 10, tied_minute_count: 1, cluster_times: [at.slice(11)],
|
|
cluster_intervals: [{ segment_index: 0, start_index: offset, end_index: offset, start_offset_minutes: offset, end_offset_minutes: offset,
|
|
start_at: at, end_at: at }] };
|
|
});
|
|
const minutes = Array.from({ length: 31 }, (_, offset) => {
|
|
const at = new Date(Date.parse("2000-06-14T23:55:00Z") + offset * 60000).toISOString().slice(0, 16);
|
|
return { offset, date: at.slice(0, 10), time: at.slice(11), signs: { D1: 1 } };
|
|
});
|
|
const inference = buildInferenceState({ range_start: range.start_time, range_end: range.end_time,
|
|
candidates, events: [], probes: [], segment_minutes: minutes, segment_targets: ["D1"], segment_scan_complete: true });
|
|
assert.equal(inference.segment_summary?.adoption_minute?.time, "00:10");
|
|
fixture.psqlAs("identity_runtime", "identity-runtime-test-password", `
|
|
insert into identity.users(id,name,email,email_verified) values ('${userId}','Synthetic Segment Fixture','${userId}@example.invalid',true);
|
|
`);
|
|
fixture.psql(`
|
|
update public.profiles set birth_date='2000-06-14',reported_birth_time='23:59',birth_time_source='family_exact',birth_time_status='reported',
|
|
uncertainty_before_minutes=15,uncertainty_after_minutes=15,latitude=40,longitude=-74,timezone_id=${timezoneId ? `'${timezoneId}'` : "null"},timezone_offset=-4 where id='${userId}';
|
|
insert into public.chat_sessions(id,user_id,title,theme,session_type,messages)
|
|
values('${sessionId}','${userId}','Synthetic segment boundary','general','birth_time_rectification','[]');
|
|
insert into public.agentic_rectification_cases(id,user_id,session_id,status,skill_name,skill_version,baseline_profile_fingerprint,baseline_birth_snapshot,candidate_range)
|
|
values('${caseId}','${userId}','${sessionId}','candidate_ready','jyotish-birth-time-rectification','9.0.0','${"a".repeat(64)}','${JSON.stringify(snapshot)}','${JSON.stringify(range)}');
|
|
`);
|
|
const service = createLocalPostgresDataClient(url, null, "service_role");
|
|
const persisted = await service.rpc("persist_agentic_rectification_candidate_v2", {
|
|
p_user_id: userId, p_case_id: caseId, p_engine_result_id: "synthetic-segment-boundary",
|
|
p_evidence_ledger_fingerprint: "b".repeat(64), p_candidate_range_fingerprint: "c".repeat(64),
|
|
p_skill_version: "9.0.0", p_algorithm_version: "synthetic-boundary-v1", p_event_contract_version: "rectification-event-contract-v2",
|
|
p_decision_policy_version: "rectification-candidate-policy-v2", p_candidate_range: range, p_candidates: candidates,
|
|
p_decision_receipt: { display_allowed: true, accept_allowed: true, confirm_allowed: true,
|
|
representative_time: "23:55", overall_confidence: "low", margin_percent: 1,
|
|
candidate_window_contract: "dated-v1", candidate_intervals: intervals, candidate_timezone_offset: -4,
|
|
candidate_timezone_id: timezoneId, inference_state: inference },
|
|
p_execution_ledger: [{ phase: "candidate.score", status: "completed", engine: "synthetic-boundary" }],
|
|
});
|
|
assert.equal(persisted.error, null, JSON.stringify(persisted.error));
|
|
const row = persisted.data as { result_id: string; candidates: { time: string; candidate_id: string }[] };
|
|
const candidateId = row.candidates.find(c => c.time === "23:55")!.candidate_id;
|
|
const accept = (requestId = randomUUID(), owner = userId) => service.rpc("accept_agentic_rectification_segment_for_case_v1", {
|
|
p_user_id: owner, p_case_id: caseId, p_result_id: row.result_id, p_candidate_id: candidateId, p_request_id: requestId,
|
|
});
|
|
const before = fixture.psql(`select coalesce(active_birth_time::text,'null') from public.profiles where id='${userId}'`);
|
|
const tampered = structuredClone(inference);
|
|
(tampered.segment_summary!.adoption_minute as { time: string }).time = "00:09";
|
|
fixture.psql(`update public.agentic_rectification_results set decision_receipt=jsonb_set(decision_receipt,'{inference_state}','${JSON.stringify(tampered)}') where id='${row.result_id}'`);
|
|
assert.ok((await accept()).error, "server summary midpoint must be recomputed");
|
|
assert.equal(fixture.psql(`select coalesce(active_birth_time::text,'null') from public.profiles where id='${userId}'`), before, "rejected summary makes no partial writes");
|
|
fixture.psql(`update public.agentic_rectification_results set decision_receipt=jsonb_set(decision_receipt,'{inference_state}','${JSON.stringify(inference)}') where id='${row.result_id}'`);
|
|
assert.ok((await accept(randomUUID(), randomUUID())).error, "owner checked before receipt access");
|
|
const requestId = randomUUID();
|
|
const adopted = await accept(requestId);
|
|
assert.equal(adopted.error, null, JSON.stringify(adopted.error));
|
|
assert.equal((adopted.data as Record<string, unknown>).saved_time, "00:10");
|
|
assert.equal((adopted.data as Record<string, unknown>).saved_date, "2000-06-15");
|
|
assert.equal((adopted.data as Record<string, unknown>).day_offset, 1);
|
|
const selectedIdentity = await service.rpc("get_agentic_rectification_segment_selection_v1", {
|
|
p_user_id: userId, p_case_id: caseId, p_result_id: row.result_id,
|
|
});
|
|
assert.equal(selectedIdentity.error, null);
|
|
assert.deepEqual(selectedIdentity.data, { result_id: row.result_id, candidate_id: candidateId,
|
|
date: "2000-06-15", time: "00:10", contract: "segment-v1" });
|
|
const wrongOwnerIdentity = await service.rpc("get_agentic_rectification_segment_selection_v1", {
|
|
p_user_id: randomUUID(), p_case_id: caseId, p_result_id: row.result_id,
|
|
});
|
|
assert.equal(wrongOwnerIdentity.data, null);
|
|
// BUG-1138/1139: reports and chat read this adoption's chart tiers through the
|
|
// service client: profile provenance (column grant) + case dossier RPC.
|
|
const provenanceRow = await service.from("profiles").select("active_birth_provenance").eq("id", userId).maybeSingle();
|
|
assert.equal(provenanceRow.error, null);
|
|
clearAdoptedChartTierCache();
|
|
assert.deepEqual(await loadAdoptedChartTiers(service, {
|
|
userId, provenance: (provenanceRow.data as Record<string, unknown>).active_birth_provenance,
|
|
}, () => assert.fail("tier read must not warn")), { source: "segment-v1", resultMatch: "adopted", unreliable: [] });
|
|
assert.equal(fixture.psql(`select birth_time || ':' || active_birth_time || ':' || active_birth_date || ':' ||
|
|
(active_birth_provenance->>'candidate_time') || ':' || (active_birth_provenance->>'candidate_date') from public.profiles where id='${userId}'`), "00:10:00:00:10:00:2000-06-15:00:10:2000-06-15");
|
|
assert.equal(fixture.psql(`select selected_time || ':' || representative_time from public.agentic_rectification_results where id='${row.result_id}'`), "00:10:00:23:55:00");
|
|
assert.equal(fixture.psql(`select accepted_time || ':' || (adopted_credible_range->>'representative_time') || ':' || (adopted_credible_range->>'representative_date') from public.agentic_rectification_cases where id='${caseId}'`), "00:10:00:00:10:2000-06-15");
|
|
assert.equal((await accept(requestId)).error, null, "same request is idempotent");
|
|
const selectionBeforeRetry = fixture.psql(`select r.selected_at::text || ':' || p.active_birth_provenance::text
|
|
from public.agentic_rectification_results r join public.profiles p on p.id=r.user_id where r.id='${row.result_id}'`);
|
|
const retried = await accept();
|
|
assert.equal(retried.error, null, "new request reuses unchanged accepted selection");
|
|
assert.equal((retried.data as Record<string, unknown>).idempotent, true);
|
|
assert.equal((retried.data as Record<string, unknown>).saved_date, "2000-06-15");
|
|
assert.equal(fixture.psql(`select r.selected_at::text || ':' || p.active_birth_provenance::text
|
|
from public.agentic_rectification_results r join public.profiles p on p.id=r.user_id where r.id='${row.result_id}'`), selectionBeforeRetry);
|
|
const turnId = randomUUID();
|
|
fixture.psql(`insert into public.agentic_rectification_turns(id,case_id,model_name,user_message,assistant_message,status)
|
|
values('${turnId}','${caseId}','synthetic','Confirm synthetic segment boundary','Synthetic acknowledgment','completed')`);
|
|
assert.equal(fixture.psql(`select r.confirmation_allowed::text || ':' || c.is_representative::text || ':' ||
|
|
(r.representative_time=c.candidate_time)::text || ':' || (r.invalidated_at is null and r.expires_at>now())::text
|
|
from public.agentic_rectification_results r join public.agentic_rectification_candidates c on c.result_id=r.id
|
|
where r.id='${row.result_id}' and c.id='${candidateId}'`), "true:true:true:true", "frozen confirmation prerequisites are open");
|
|
const selectionSnapshot = () => fixture.psql(`select jsonb_build_object(
|
|
'profile',(select to_jsonb(p) from public.profiles p where id='${userId}'),
|
|
'case',(select to_jsonb(c) from public.agentic_rectification_cases c where id='${caseId}'),
|
|
'result',(select to_jsonb(r) from public.agentic_rectification_results r where id='${row.result_id}'),
|
|
'decisions',(select jsonb_agg(to_jsonb(d) order by created_at,id) from public.agentic_rectification_candidate_decisions d where case_id='${caseId}'))`);
|
|
const beforeConfirmation = selectionSnapshot();
|
|
const confirmed = await service.rpc("confirm_agentic_rectification_candidate_for_case_v2", {
|
|
p_user_id: userId, p_case_id: caseId, p_result_id: row.result_id, p_candidate_id: candidateId,
|
|
p_request_id: randomUUID(), p_source_turn_id: turnId, p_consent_quote: "Confirm synthetic segment boundary",
|
|
});
|
|
assert.equal(confirmed.error?.message, "agentic_rectification_candidate_selection_blocked",
|
|
"noncandidate selected civil minute, not permission or consent, blocks old confirmation");
|
|
assert.equal(selectionSnapshot(), beforeConfirmation, "rejected confirmation writes none of profile/case/result/decisions");
|
|
|
|
// The same server scan may legitimately deliver the real candidate minute.
|
|
// Keep the old confirmation function and its exact gate; do not add a segment confirmation shortcut.
|
|
const exactInference = buildInferenceState({ range_start: range.start_time, range_end: range.end_time,
|
|
candidates: [candidates[0]], events: [], probes: [], segment_minutes: minutes, segment_targets: ["D1"], segment_scan_complete: true });
|
|
assert.equal(exactInference.segment_summary?.adoption_minute?.time, "23:55");
|
|
const exactCaseId = randomUUID();
|
|
// A fresh owner's baseline is required: use a new fixture user rather than resetting adopted profile state.
|
|
const exactUserId = randomUUID();
|
|
fixture.psqlAs("identity_runtime", "identity-runtime-test-password", `insert into identity.users(id,name,email,email_verified)
|
|
values('${exactUserId}','Synthetic Exact Segment Fixture','${exactUserId}@example.invalid',true)`);
|
|
const exactSessionId = randomUUID();
|
|
fixture.psql(`update public.profiles set birth_date='2000-06-14',reported_birth_time='23:59',birth_time_source='family_exact',birth_time_status='reported',
|
|
uncertainty_before_minutes=15,uncertainty_after_minutes=15,latitude=40,longitude=-74,timezone_id=${timezoneId ? `'${timezoneId}'` : "null"},timezone_offset=-4 where id='${exactUserId}';
|
|
insert into public.chat_sessions(id,user_id,title,theme,session_type,messages)
|
|
values('${exactSessionId}','${exactUserId}','Synthetic exact segment','general','birth_time_rectification','[]');
|
|
insert into public.agentic_rectification_cases(id,user_id,session_id,status,skill_name,skill_version,baseline_profile_fingerprint,baseline_birth_snapshot,candidate_range)
|
|
values('${exactCaseId}','${exactUserId}','${exactSessionId}','candidate_ready','jyotish-birth-time-rectification','9.0.0','${"a".repeat(64)}','${JSON.stringify(snapshot)}','${JSON.stringify(range)}')`);
|
|
const exactPersisted = await service.rpc("persist_agentic_rectification_candidate_v2", {
|
|
p_user_id: exactUserId, p_case_id: exactCaseId, p_engine_result_id: "synthetic-exact-segment-boundary",
|
|
p_evidence_ledger_fingerprint: "b".repeat(64), p_candidate_range_fingerprint: "c".repeat(64),
|
|
p_skill_version: "9.0.0", p_algorithm_version: "synthetic-boundary-v1", p_event_contract_version: "rectification-event-contract-v2",
|
|
p_decision_policy_version: "rectification-candidate-policy-v2", p_candidate_range: range, p_candidates: [candidates[0]],
|
|
p_decision_receipt: { display_allowed: true, accept_allowed: true, confirm_allowed: true,
|
|
representative_time: "23:55", overall_confidence: "low", margin_percent: 1,
|
|
candidate_window_contract: "dated-v1", candidate_intervals: intervals, candidate_timezone_offset: -4,
|
|
candidate_timezone_id: timezoneId, inference_state: exactInference },
|
|
p_execution_ledger: [{ phase: "candidate.score", status: "completed", engine: "synthetic-boundary" }],
|
|
});
|
|
assert.equal(exactPersisted.error, null, JSON.stringify(exactPersisted.error));
|
|
const exactRow = exactPersisted.data as { result_id: string; candidates: { candidate_id: string }[] };
|
|
const exactCandidateId = exactRow.candidates[0].candidate_id;
|
|
assert.equal((await service.rpc("accept_agentic_rectification_segment_for_case_v1", {
|
|
p_user_id: exactUserId, p_case_id: exactCaseId, p_result_id: exactRow.result_id,
|
|
p_candidate_id: exactCandidateId, p_request_id: randomUUID(),
|
|
})).error, null);
|
|
const exactTurnId = randomUUID();
|
|
fixture.psql(`insert into public.agentic_rectification_turns(id,case_id,model_name,user_message,assistant_message,status)
|
|
values('${exactTurnId}','${exactCaseId}','synthetic','Confirm synthetic exact segment','Synthetic acknowledgment','completed')`);
|
|
const exactConfirmed = await service.rpc("confirm_agentic_rectification_candidate_for_case_v2", {
|
|
p_user_id: exactUserId, p_case_id: exactCaseId, p_result_id: exactRow.result_id, p_candidate_id: exactCandidateId,
|
|
p_request_id: randomUUID(), p_source_turn_id: exactTurnId, p_consent_quote: "Confirm synthetic exact segment",
|
|
});
|
|
assert.equal(exactConfirmed.error, null, JSON.stringify(exactConfirmed.error));
|
|
assert.equal((exactConfirmed.data as Record<string, unknown>).status, "confirmed");
|
|
assert.equal(fixture.psql(`select birth_time_status || ':' || active_birth_date || ':' || active_birth_time from public.profiles where id='${exactUserId}'`), "confirmed:2000-06-14:23:55:00");
|
|
assert.equal((await service.rpc("get_agentic_rectification_segment_selection_v1", {
|
|
p_user_id: exactUserId, p_case_id: exactCaseId, p_result_id: exactRow.result_id,
|
|
})).data, null, "confirmed identity is no longer an accepted-only segment identity");
|
|
fixture.psql(`update public.profiles set active_birth_time='00:12' where id='${userId}'`);
|
|
assert.ok((await accept()).error, "new request cannot overwrite a manually changed profile");
|
|
assert.equal((await service.rpc("get_agentic_rectification_segment_selection_v1", {
|
|
p_user_id: userId, p_case_id: caseId, p_result_id: row.result_id,
|
|
})).data, null, "manual edits cannot appear as this result's adopted segment");
|
|
assert.equal((await accept(requestId)).error, null, "old request returns its original receipt without rewriting the profile");
|
|
assert.equal(fixture.psql(`select active_birth_time from public.profiles where id='${userId}'`), "00:12:00");
|
|
assert.equal(fixture.psql(`select has_function_privilege('authenticated','public.accept_agentic_rectification_segment_for_case_v1(uuid,uuid,uuid,uuid,uuid)','execute')::text`), "f");
|
|
} finally {
|
|
await closeLocalPostgresDataPool(url);
|
|
fixture.stop();
|
|
}
|
|
});
|
|
}
|