Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6d20b6e
fix(rag): recover grounded Australian answers
BigSimmo Jul 13, 2026
ae3ef9c
fix(rag): preserve relevant supplementary evidence
BigSimmo Jul 13, 2026
6028307
feat(answer): add safe progress lifecycle
BigSimmo Jul 13, 2026
bf8458a
fix(answer): validate final before completion
BigSimmo Jul 13, 2026
7713b4b
feat(governance): add safe source locality repair
BigSimmo Jul 13, 2026
c5fde11
fix(governance): exclude non-document authority signals
BigSimmo Jul 13, 2026
19e1889
docs(review): record lithium recovery handoff
BigSimmo Jul 13, 2026
2476d24
docs(review): avoid ledger append conflict
BigSimmo Jul 13, 2026
6f5162d
fix(rag): resolve retry and governance review findings
BigSimmo Jul 13, 2026
0d4f87f
fix(rag): narrow uncited numeric fallback evidence
BigSimmo Jul 13, 2026
3e49c05
fix(rag): prefer single-source numeric recovery
BigSimmo Jul 13, 2026
caf7ea5
Merge remote-tracking branch 'origin/main' into codex/lithium-answer-…
BigSimmo Jul 13, 2026
435018c
Merge remote-tracking branch 'origin/main' into codex/lithium-answer-…
BigSimmo Jul 13, 2026
13a3152
fix: retain only cited lithium fallback evidence
BigSimmo Jul 13, 2026
43a385d
Merge remote-tracking branch 'origin/codex/lithium-answer-recovery-pr…
BigSimmo Jul 13, 2026
237d6db
fix: preserve narrowed fallback answer type
BigSimmo Jul 13, 2026
d6d2e17
fix(rag): type cited fallback boundary
BigSimmo Jul 13, 2026
a1e7c23
Merge remote-tracking branch 'origin/codex/lithium-answer-recovery-pr…
BigSimmo Jul 13, 2026
e84baab
Merge remote-tracking branch 'origin/main' into codex/lithium-answer-…
BigSimmo Jul 13, 2026
5bc19c6
Merge remote-tracking branch 'origin/main' into codex/lithium-answer-…
BigSimmo Jul 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/branch-review-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD

| Date | Branch or ref | Reviewed HEAD | Scope | Outcome | Checks |
| ---------- | ------------------------------------------------------ | ---------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2026-07-13 | codex/lithium-answer-recovery-pr | c5fde11e64d8976e1c163d1b8618f58a52e0b8ff | lithium answer recovery and source governance | Fixed the provider-failure path with a grounded Australian source-backed fallback, a public-safe progress lifecycle, centralised Australian authority/context selection, and fail-closed locality repair. The live audit exposed and the branch fixed hierarchy identity false conflicts plus registry projections entering clinical metadata gates. The corrected audit/backfill found zero proposals, so no production write was made. No high-confidence defect remains. Residual risk is provider latency; live generation timed out but the grounded fallback completed. | `npm run verify:pr-local` passed: 1,988 tests passed/1 skipped, build/client scan, 36 fixtures, and 267 offline RAG tests. After review fixes, `npm run verify:cheap` passed with 1,992 tests passed/1 skipped. `npm run check:production-readiness` passed 5/5. `npm run test:e2e:critical` passed 9/9. `node scripts/run-playwright.mjs tests/answer-progress-ui-smoke.spec.ts --project=chromium` passed 2/2. `node scripts/run-eval-safe.mjs scripts/eval-rag.ts --question "Lithium dosing" --expect-australian --fail-on-threshold --json` exited 0 with one grounded FSH citation and no threshold/safety failures. `npm run audit:source-governance` reported 0 gaps/conflicts/proposals across 2,851 rows. `npm run backfill:source-metadata -- --locality-only` reported 0 changes. `git diff --check` passed. Full `npm run verify:ui` was not rerun after the aggregate runner lost its local server. |
| 2026-07-10 | codex/design-ux-review-fixes | 648abfa3f7c91395b5eeca543f70e0b6ea59e9e0 | design-system + UX + design | Five issue groups confirmed; scoped fixes applied in the worktree. | `npm run check:type-scale`; focused Vitest (19/19); `npm run typecheck`; `npm run lint`; `npm run sitemap:check`; browser/API-backed checks awaiting approval |
| 2026-07-11 | codex/design-ux-review-integration | 98093ec7b | branch-integration-review | Replayed the reviewed design and UX fixes onto current `origin/main`, preserved the lightweight evidence-panel boundary, and retained the merged quality fixes. | `npm run check:type-scale`; combined focused Vitest (8 files, 42 tests); runtime/action/sitemap/type-scale/lint stages of `verify:cheap`; typecheck blocked by stale worktree dependencies pending hosted clean install; `git diff --check` |
| 2026-07-09 | example/branch | abc1234 | branch-cleanup | Example: already merged into `main`; no unique patch content. | `git log --right-only --cherry-pick main...example/branch`; `git diff --name-status main...example/branch` |
Expand Down
85 changes: 69 additions & 16 deletions scripts/audit-source-governance.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { readFile } from "node:fs/promises";
import { pathToFileURL } from "node:url";

import * as nextEnv from "@next/env";
import { auditSourceAuthorityDocuments, isRegistryRecordSource } from "@/lib/source-authority-metadata";
import type { DocumentLabel } from "@/lib/types";

const loadEnvConfig =
nextEnv.loadEnvConfig ??
(nextEnv as unknown as { default?: { loadEnvConfig?: typeof nextEnv.loadEnvConfig } }).default?.loadEnvConfig;

if (!loadEnvConfig) throw new Error("Unable to load @next/env loadEnvConfig.");
loadEnvConfig(process.cwd());

type AuditArgs = {
json: boolean;
help: boolean;
Expand Down Expand Up @@ -43,6 +42,7 @@ type DocumentRow = {
id: string;
title: string;
file_name: string;
source_path: string | null;
status: string;
metadata: Record<string, unknown> | null;
};
Expand Down Expand Up @@ -84,7 +84,7 @@ async function loadAdminClient() {
return createAdminClient();
}

function parseArgs(argv: string[]): AuditArgs {
export function parseSourceGovernanceAuditArgs(argv: string[]): AuditArgs {
const args: AuditArgs = { json: false, help: false };
for (let index = 0; index < argv.length; index += 1) {
const token = argv[index];
Expand All @@ -108,6 +108,11 @@ function parseArgs(argv: string[]): AuditArgs {
return args;
}

function loadProjectEnvironment() {
if (!loadEnvConfig) throw new Error("Unable to load @next/env loadEnvConfig.");
loadEnvConfig(process.cwd());
}

function usage() {
return [
"Usage: npm run audit:source-governance -- [options]",
Expand Down Expand Up @@ -243,29 +248,35 @@ async function loadDebtPolicy(path: string): Promise<DebtPolicy> {
};
}

async function main() {
const args = parseArgs(process.argv.slice(2));
export async function main(argv = process.argv.slice(2)) {
const args = parseSourceGovernanceAuditArgs(argv);
if (args.help) {
console.log(usage());
return;
}
loadProjectEnvironment();
const debtPolicy = args.debtPolicyPath ? await loadDebtPolicy(args.debtPolicyPath) : undefined;

const supabase = await loadAdminClient();
const documents = await fetchAll<DocumentRow>(supabase, "documents", "id,title,file_name,status,metadata", (query) =>
query.eq("status", "indexed"),
const documents = await fetchAll<DocumentRow>(
supabase,
"documents",
"id,title,file_name,source_path,status,metadata",
(query) => query.eq("status", "indexed"),
);
const labels = await fetchAll<LabelRow>(supabase, "document_labels", "id,document_id,label_type,source", (query) =>
query.eq("source", "generated"),
);
const clinicalGovernanceDocuments = documents.filter((document) => !isRegistryRecordSource(document));
const registryRecordsExcludedFromClinicalMetadataGate = documents.length - clinicalGovernanceDocuments.length;

const statusCounts = new Map<string, number>();
const validationCounts = new Map<string, number>();
const extractionCounts = new Map<string, number>();
const requiredMissingCounts = new Map<string, number>();
const missingRequiredDocuments: Array<ReturnType<typeof compactDocument> & { missing_keys: string[] }> = [];

for (const document of documents) {
for (const document of clinicalGovernanceDocuments) {
const metadata = metadataRecord(document.metadata);
increment(statusCounts, stringValue(metadata.document_status));
increment(validationCounts, stringValue(metadata.clinical_validation_status));
Expand All @@ -289,6 +300,7 @@ async function main() {
const missingGeneratedLabelDocuments = documents.filter((document) => !generatedLabelDocumentIds.has(document.id));
const missingSmartV2LabelDocuments = documents.filter((document) => !smartV2DocumentIds.has(document.id));
const requiredMetadataMissingTotal = [...requiredMissingCounts.values()].reduce((total, count) => total + count, 0);
const sourceAuthorityAudit = auditSourceAuthorityDocuments(documents);
const debtCounts = {
review_due: statusCounts.get("review_due") ?? 0,
unknown_status: statusCounts.get("unknown") ?? 0,
Expand Down Expand Up @@ -359,6 +371,8 @@ async function main() {
const report = {
mode: "read-only",
indexed_documents: documents.length,
clinical_governance_documents: clinicalGovernanceDocuments.length,
registry_records_excluded_from_clinical_metadata_gate: registryRecordsExcludedFromClinicalMetadataGate,
required_metadata_missing_total: requiredMetadataMissingTotal,
required_metadata_missing_counts: Object.fromEntries(
requiredMetadataKeys.map((key) => [key, requiredMissingCounts.get(key) ?? 0]),
Expand All @@ -375,15 +389,15 @@ async function main() {
indexed_without_smart_v2_labels: missingSmartV2LabelDocuments.length,
},
debt_counts: debtCounts,
sample_review_due_documents: documents
sample_review_due_documents: clinicalGovernanceDocuments
.filter((document) => metadataRecord(document.metadata).document_status === "review_due")
.slice(0, 10)
.map(compactDocument),
sample_unknown_status_documents: documents
sample_unknown_status_documents: clinicalGovernanceDocuments
.filter((document) => metadataRecord(document.metadata).document_status === "unknown")
.slice(0, 10)
.map(compactDocument),
sample_unverified_documents: documents
sample_unverified_documents: clinicalGovernanceDocuments
.filter((document) => metadataRecord(document.metadata).clinical_validation_status === "unverified")
.slice(0, 10)
.map(compactDocument),
Expand All @@ -395,6 +409,8 @@ async function main() {
})),
indexed_document_id_count: indexedDocumentIds.size,
passed_required_metadata_gate: requiredMetadataMissingTotal === 0,
source_authority: sourceAuthorityAudit,
passed_source_authority_gate: sourceAuthorityAudit.passed,
debt_policy: debtPolicy
? {
path: debtPolicy.path,
Expand All @@ -415,6 +431,9 @@ async function main() {
console.log("[Source Governance Audit]");
console.log(`Mode: ${report.mode}`);
console.log(`Indexed documents: ${report.indexed_documents}`);
console.log(
`Clinical governance documents: ${report.clinical_governance_documents} (registry projections excluded: ${report.registry_records_excluded_from_clinical_metadata_gate})`,
);
console.log(`Required metadata missing: ${report.required_metadata_missing_total}`);
console.log(
`Document status: ${Object.entries(report.document_status_counts)
Expand All @@ -437,6 +456,32 @@ async function main() {
console.log(
`Smart-v2 labels: missing=${report.smart_v2_label_coverage.indexed_without_smart_v2_labels}, covered=${report.smart_v2_label_coverage.documents_with_smart_v2_labels}`,
);
console.log(
`Source authority: recognised=${report.source_authority.recognized_documents}, Australian candidates=${report.source_authority.australian_authority_candidates}, conflicts=${report.source_authority.authority_conflict_count}, missing locality=${report.source_authority.missing_australian_locality_count}, safe corrections=${report.source_authority.proposed_locality_correction_count}`,
);
if (report.source_authority.authority_conflict_count) {
console.log(
`Source authority conflict reasons: ${JSON.stringify(report.source_authority.authority_conflict_reason_counts)}`,
);
}
if (report.source_authority.conflicts.length) {
console.log("Source authority conflicts:");
for (const document of report.source_authority.conflicts) {
console.log(`- ${document.title} (${document.file_name}): ${document.conflicts.join(", ")}`);
}
}
if (report.source_authority.missing_australian_locality.length) {
console.log("Australian sources missing locality metadata:");
for (const document of report.source_authority.missing_australian_locality) {
console.log(`- ${document.title} (${document.file_name}): ${document.missing_keys.join(", ")}`);
}
}
if (report.source_authority.proposed_locality_corrections.length) {
console.log("Proposed safe locality corrections:");
for (const document of report.source_authority.proposed_locality_corrections) {
console.log(`- ${document.title} (${document.file_name}): ${JSON.stringify(document.changes)}`);
}
}
if (report.missing_smart_v2_label_documents.length) {
console.log("Documents missing smart-v2 labels:");
for (const document of report.missing_smart_v2_label_documents) {
Expand All @@ -448,6 +493,11 @@ async function main() {
? "PASS: required source governance metadata is complete."
: "FAIL: required source governance metadata has gaps.",
);
console.log(
report.passed_source_authority_gate
? "PASS: recognised source authority metadata is complete and compatible."
: "FAIL: recognised source authority metadata has missing or conflicting locality fields.",
);
if (report.debt_policy) {
console.log(
report.debt_policy.passed
Expand All @@ -459,10 +509,13 @@ async function main() {
}

if (!report.passed_required_metadata_gate) process.exitCode = 1;
if (!report.passed_source_authority_gate) process.exitCode = 1;
if (report.debt_policy && !report.debt_policy.passed) process.exitCode = 1;
}

main().catch((error) => {
console.error(error instanceof Error ? error.message : error);
process.exitCode = 1;
});
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
main().catch((error) => {
console.error(error instanceof Error ? error.message : error);
process.exitCode = 1;
});
}
Loading