/** * The one human gate left in the pipeline, and the only one worth having. * * Everything else the pipeline checks is fact-shaped: a dependency either * exists or it does not, a spec section is either present or absent, a verify * command either exits zero or it does not. Those settle themselves. * Acceptance criteria are different — they encode what "done" means, which is * a scoping decision, and no amount of model review substitutes for the * person who owns the outcome saying "yes, that is what I asked for". * * Two design choices follow from that. It is **batched**: every criterion in * the program is pulled into one document, reviewed in one pass, rather than * asked about workstream by workstream. And approval is **keyed to a content * hash** of the criteria themselves, so editing a criterion after approval * lapses that approval automatically instead of leaving a stale sign-off * attached to text nobody agreed to. * * The gate sits after convergence, not before it: the loop edits specs, and * approving criteria that a later round then rewrites would mean re-approving * after every round. */ export interface WorkstreamCriteria { id: string; name: string; taskFile: string; scopeSummary?: string; /** Undefined when the spec has no Acceptance Criteria section. */ criteria?: string; } export interface CriteriaApproval { hash: string; approvedAt: string; } export interface CriteriaStatus { programId: string; workstreams: WorkstreamCriteria[]; hash: string; approval?: CriteriaApproval; /** Approval exists and still matches the criteria as they stand. */ approved: boolean; /** Approval exists but the criteria changed under it. */ lapsed: boolean; /** Workstreams whose spec has no Acceptance Criteria section. */ missing: string[]; } export type CriteriaOutcome = "APPROVED" | "REVIEW_REQUIRED" | "ABORTED"; export interface CriteriaResult { programId: string; result: CriteriaOutcome; reason?: string; documentPath?: string; hash?: string; approvedAt?: string; lapsed?: boolean; missing?: string[]; } export interface CriteriaOptions { cwd: string; programId: string; /** Record approval for the criteria exactly as they stand right now. */ approve?: boolean; now?: () => Date; onProgress?: (line: string) => void; } /** * Identity of the criteria set. Sorted by workstream id so manifest order * cannot change the hash, and computed from the criteria text alone — a * reworded goal or a new implementation step is not a change to what "done" * means, and must not invalidate a sign-off. */ export declare function criteriaHash(workstreams: WorkstreamCriteria[]): string; export declare function manifestPathFor(root: string, programId: string): string; export declare function documentPathFor(root: string, programId: string): string; /** Read every workstream's Acceptance Criteria section from its spec. */ export declare function collectCriteria(root: string, programId: string): Promise; export declare function renderCriteriaDocument(status: CriteriaStatus): string; export declare function reviewCriteria(options: CriteriaOptions): Promise; /** * Gate helper for the build runner: is the current criteria set approved? * Returns the reason it is not, or undefined when it is. */ export declare function criteriaGateFailure(root: string, programId: string): Promise; //# sourceMappingURL=criteria.d.ts.map