import type { Finding } from "../hub/finding.js"; import type { FactStore } from "../state/facts.js"; import type { PromotionRef } from "./types.js"; /** * Do-bridge view of a Finding where promotesTo is a parsed PromotionRef * object rather than the raw string stored on disk. * * FindingSchema.promotesTo is z.string().optional() — the hub schema is NOT * modified. This type is owned by the do-bridge port layer; serialization * and deserialization happen inside the adapters below. */ export type DoFinding = Omit & { promotesTo?: PromotionRef; }; /** * Narrow port for finding lookup and promotion state writes. * Returns DoFinding (promotesTo as structured object) so callers never * touch the raw JSON string stored on disk. */ export interface FindingStore { /** Read a finding by id. Returns null if not found. */ readFinding(id: string): Promise; /** * Set promotesTo = ref AND transition status open->in-progress in one call. * Returns the updated DoFinding, or null if the id does not exist. */ setPromotion(id: string, ref: PromotionRef, opts: { now: string; }): Promise; /** Return all findings that currently carry a PromotionRef (promotesTo defined). */ listPromoted(): Promise; /** * Transition a finding to an arbitrary status AND overwrite its promotesTo ref, * in one supersede-aware write. Used by reconcile for done/open outcomes. * Returns the updated DoFinding, or null if the id does not exist. */ applyOutcome(id: string, status: Finding["status"], ref: PromotionRef, opts: { now: string; }): Promise; } /** * FactStore-backed adapter for FindingStore. * * readFinding: delegates to readFindings() (hub's canonical read path) and * converts the string promotesTo to a PromotionRef object. * * setPromotion: serializes the ref to a JSON string, delegates to * transitionFinding() (hub's supersede-aware UPDATE path) so bitemporal * history is preserved, then converts the result back to DoFinding. */ export declare class FactStoreFindingStore implements FindingStore { private readonly store; constructor(store: FactStore); readFinding(id: string): Promise; setPromotion(id: string, ref: PromotionRef, { now }: { now: string; }): Promise; listPromoted(): Promise; applyOutcome(id: string, status: Finding["status"], ref: PromotionRef, { now }: { now: string; }): Promise; } /** * In-memory fake for tests — backed by a Map. * * setPromotion stores the PromotionRef OBJECT directly (no serialization) * so tests can assert promotesTo.runId / promotesTo.status on the result of * readFinding without JSON.parse. * * `writes` records every setPromotion call: * - sc-2-2/2-3: assert writes.length === 1 on approve * - sc-2-4: assert writes.length === 0 on reject */ export declare class InMemoryFindingStore implements FindingStore { private readonly map; /** Records every setPromotion write. Tests assert .length for mutation count. */ readonly writes: DoFinding[]; constructor(seed?: Finding[]); readFinding(id: string): Promise; setPromotion(id: string, ref: PromotionRef, _opts: { now: string; }): Promise; listPromoted(): Promise; applyOutcome(id: string, status: Finding["status"], ref: PromotionRef, _opts: { now: string; }): Promise; } //# sourceMappingURL=finding-port.d.ts.map