// SF — Product Audit tool registration
//
// Exposes `audit_product` to the LLM. The tool persists a structured
// product-completeness audit (verdict + gaps) to
// `.sf/active/{milestoneId}/PRODUCT-AUDIT.{json,md}`.
import { Type } from "@sinclair/typebox";
import { handleProductAudit } from "../tools/product-audit-tool.js";
export function registerProductAuditTool(pi) {
	pi.registerTool({
		name: "audit_product",
		label: "Product Audit",
		description:
			"Persist a milestone-end product-completeness audit. Compares declared " +
			"product intent against actual code/test/deploy/docs evidence and writes " +
			"structured gaps to .sf/active/{milestoneId}/PRODUCT-AUDIT.{json,md}. " +
			"Soft gate — does not hard-block milestone completion.",
		promptSnippet:
			"Save a milestone product-audit (verdict + gaps with severity and suggested follow-up slices) to .sf/active/{milestoneId}/PRODUCT-AUDIT.{json,md}",
		promptGuidelines: [
			"Call exactly once per milestone audit run.",
			"verdict=no-gaps requires positive evidence for every material capability.",
			"verdict=gaps-found includes at least one gap; critical/high gaps will be turned into follow-up slices downstream.",
			"verdict=contract-underspecified means product docs are too vague to validate; emit one high-severity gap that clarifies the contract.",
			"Every gap must cite concrete sourceDocs (repo-relative paths) and concrete foundEvidence/missingEvidence — no vague TODOs.",
		],
		parameters: Type.Object({
			milestoneId: Type.String({
				description: "Milestone ID this audit belongs to (e.g. M001)",
			}),
			verdict: Type.Union(
				[
					Type.Literal("no-gaps"),
					Type.Literal("gaps-found"),
					Type.Literal("contract-underspecified"),
				],
				{ description: "Overall audit verdict" },
			),
			summary: Type.String({
				description: "Short evidence-based summary of the audit",
			}),
			gaps: Type.Array(
				Type.Object({
					capability: Type.String(),
					expectedEvidence: Type.Array(Type.String()),
					foundEvidence: Type.Array(Type.String()),
					missingEvidence: Type.Array(Type.String()),
					severity: Type.Union([
						Type.Literal("critical"),
						Type.Literal("high"),
						Type.Literal("medium"),
						Type.Literal("low"),
					]),
					suggestedSlice: Type.Object({
						title: Type.String(),
						demo: Type.String(),
						risk: Type.String(),
						depends: Type.Array(Type.String()),
					}),
					confidence: Type.Number({ minimum: 0, maximum: 1 }),
					sourceDocs: Type.Array(Type.String()),
				}),
			),
		}),
		async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
			const result = await handleProductAudit(params, process.cwd());
			if ("error" in result) {
				return {
					content: [
						{
							type: "text",
							text: `Error: ${result.error}`,
						},
					],
					details: { operation: "audit_product", error: result.error },
					isError: true,
				};
			}
			return {
				content: [
					{
						type: "text",
						text:
							`Product audit ${result.milestoneId} saved — verdict=${result.verdict}, ` +
							`gaps=${result.gapCount} (actionable=${result.actionableGapCount}). ` +
							`Wrote ${result.markdownPath} and ${result.jsonPath}.`,
					},
				],
				details: { operation: "audit_product", ...result },
			};
		},
	});
}
