/** * `cleo goal close` — record the evidence a goal run produced against the * CLEO acceptance criteria its criteria `prove`. * * Honesty rules (epic T13791, agreed with CLEO Goal): * 1. The outcome must match the contract bytes (sha256 lock), and its head * (and base) commit must exist, or nothing is recorded. * 2. The outcome's `pass`, exit codes and verdicts are claims. Everything CLEO * can check it re-checks before recording: * - `file` / `contains` / `absent` re-run against the head commit's tree * → `implemented`: `commit:;files:`; * - a test report must hash to `reportSha256` → `testsPassed`: `test-run:`; * - the project's typecheck / lint command → `qaPassed`: `tool:typecheck` / * `tool:lint`, run by CLEO's own tool runner, never from the exit code; * - a drafted `cleo verify --run --req ` check and a human sign-off * write nothing: the AC counts only when CLEO's own typed-gate or manual * record maps it (`cleo done --plan`); * - a verifier verdict (quotes re-read at head) and a diff guard never * satisfy a gate. * 3. Evidence goes through `validateGateVerify` (the `cleo verify` / `cleo * done` write), with `satisfies:#`, and * never replaces a gate already recorded. * 4. A task is `ready` only when `cleo done --plan` maps every one of its * criteria; the caller then completes it through the `cleo done` path. * * Re-running with the same outcome writes nothing new. * * @epic T13791 * @task T13794 */ import type { VerificationGate } from '@cleocode/contracts'; import { type EngineResult } from '../engine-result.js'; import { type ChangeSetDeps } from '../tasks/change-set.js'; /** One acceptance criterion a close left open, and why. */ export interface GoalCloseOpenAc { /** Criterion alias (`AC`). */ alias: string; /** What blocks it. */ blocker: string; } /** What a close did for one task. */ export interface GoalCloseTask { /** Task id. */ taskId: string; /** The task was already done; nothing was recorded. */ alreadyDone: boolean; /** Gates this close recorded (empty on a re-run). */ recordedGates: VerificationGate[]; /** Criteria `cleo done --plan` maps after the close. */ satisfied: string[]; /** Criteria still open, each with its blocker. */ open: GoalCloseOpenAc[]; /** Every criterion is mapped: the caller completes it through `cleo done`. */ ready: boolean; /** * The commit `cleo done --commit` completes it from (T13799): the outcome's * head commit, set only when that commit has landed on the default branch * and no PR, branch or document gives the task a change set of its own. */ completionCommit?: string; } /** Result of {@link closeGoal}. */ export interface GoalCloseResult { /** Goal slug. */ goal: string; /** Verified contract lock (sha256 of goal.yaml). */ lock: string; /** Verified head commit. */ headCommit: string; /** Per-task result, in contract order. */ tasks: GoalCloseTask[]; } /** Options for {@link closeGoal}. */ export interface CloseGoalOptions { /** Project root (default: resolved). */ projectRoot?: string; /** Path of the GoalOutcome JSON file. */ outcomePath: string; /** Change-set lookups for the readiness plan (tests inject these). */ deps?: ChangeSetDeps; } /** * Close a goal: verify the outcome, record per-AC evidence, report each task. * * @param slug - Goal slug; the contract is `.opencode/goals//goal.yaml`. * @param opts - Project root, outcome path and test seams. * @returns Per-task results, or a refusal when the outcome does not match. * @example * ```ts * const r = await closeGoal('t123', { outcomePath: 'outcome.json' }); * if (r.success) r.data.tasks.filter((t) => t.ready); // complete via cleo done * ``` */ export declare function closeGoal(slug: string, opts: CloseGoalOptions): Promise>; //# sourceMappingURL=close.d.ts.map