import { type Static, Type } from "typebox"; import type { WorkerClaim } from "../autonomy/contracts.ts"; import type { LaneRecord } from "../autonomy/lane-tracker.ts"; import type { BackgroundToolTaskRef } from "../background-tool-task-controller.ts"; import type { ToolDefinition } from "../extensions/types.ts"; import { type GoalStateRevision } from "../goals/goal-lifecycle.ts"; import { type GoalState } from "../goals/goal-state.ts"; import { type GoalActionName, type OpenTaskStepRef } from "../goals/goal-tool-core.ts"; declare const goalSchema: Type.TObject<{ action: Type.TUnion<[Type.TLiteral<"get">, Type.TLiteral<"start">, Type.TLiteral<"add_requirement">, Type.TLiteral<"satisfy_requirement">, Type.TLiteral<"block_requirement">, Type.TLiteral<"reopen_requirement">, Type.TLiteral<"dispatch_worker">, Type.TLiteral<"add_evidence">, Type.TLiteral<"progress">, Type.TLiteral<"no_progress">, Type.TLiteral<"complete">, Type.TLiteral<"increment">, Type.TLiteral<"block_goal">]>; goalId: Type.TOptional; userGoal: Type.TOptional; tokenBudget: Type.TOptional; requirementId: Type.TOptional; text: Type.TOptional; dependencies: Type.TOptional>; instructions: Type.TOptional; evidenceId: Type.TOptional; evidenceIds: Type.TOptional>; kind: Type.TOptional, Type.TLiteral<"test">, Type.TLiteral<"tool">, Type.TLiteral<"user">, Type.TLiteral<"finding">, Type.TLiteral<"worker">]>>; summary: Type.TOptional; uri: Type.TOptional; reason: Type.TOptional; dispatchTarget: Type.TOptional, Type.TLiteral<"tmux">]>>; }>; export type GoalToolInput = Static; export type GoalToolDefinition = ToolDefinition; export interface GoalToolDetails { action: GoalActionName | "get"; applied: boolean; error?: string; state?: GoalState; /** Set on 'dispatch_worker' when a worker lane actually started; mirrors the requirement's * new `boundLaneId`. The in-process route by default, or a real persistent tmux lane when * `dispatchTarget:"tmux"` was selected and routed -- see {@link GoalToolDependencies.dispatchTmuxWorker}. */ dispatchedLaneId?: string; /** Set on 'dispatch_worker' when no worker was dispatched: a wired dependency declined (e.g. worker * delegation disabled, already at capacity, or an honest tmux skip reason -- see * {@link GoalToolDependencies.dispatchTmuxWorker}), or the indeterminate-binding guard refused a * re-dispatch against an already-bound requirement (`requirement_already_bound`/`bound_lane_indeterminate`). * The binding is recorded (or, for a guard refusal, left exactly as it was) with no NEW laneId. */ dispatchSkipReason?: string; } export interface GoalToolDependencies { /** Read the latest persisted goal state for the active session. */ getGoalState: () => GoalState | undefined; /** Persist a new goal state snapshot to the active session. */ saveGoalState: (state: GoalState, expected?: GoalStateRevision) => void; /** Clock injection for deterministic tests. */ now?: () => string; /** * Check whether `toolCallId` exists in this session's records, for validating kind:"tool" * evidence refs at add_evidence time. When not wired, a "tool" ref cannot be proven and is * recorded as `verified: false` rather than assumed true. */ hasToolCallId?: (toolCallId: string) => boolean; /** * Read the session's live worker lane records, for validating kind:"worker" evidence refs * (the `uri` is a laneId) at add_evidence time and refusing completion while goal-owned work is * queued or running. Read-defensive: when not wired -- exactly like `hasToolCallId` -- a "worker" * ref cannot be proven and is recorded as `verified: false` rather than assumed true. */ getLaneRecords?: () => readonly LaneRecord[]; /** * Read persisted worker claim snapshots (keyed by `WorkerClaim.requestId`, which is the same * id as the dispatching lane's laneId), for validating kind:"worker" evidence refs. See * {@link getLaneRecords}. A matching claim that is `parentReviewRequired && !parentReviewedAt` * verifies `false` -- an unreviewed worker completion must never ungate goal completion through * the existing verified/complete gate. */ getWorkerClaimSnapshots?: () => readonly WorkerClaim[]; /** * Tool-layer side effect for a 'dispatch_worker' action when `dispatchTarget` is 'in_process' * (the default) or when {@link dispatchTmuxWorker} is not wired: dispatches a real in-process * worker lane for the given requirement and returns the resulting laneId to bind onto it. When * the dependency is present but the underlying delegation starter declines (disabled, already at * capacity, etc.), return `{ skipReason }` instead of a laneId -- a real, non-silent skip that * the tool response surfaces, distinct from this dependency being altogether unwired (`undefined` * dep, or the dep returning `undefined`), which records the binding attempt structurally with no * laneId (a no-op). */ startWorkerDelegation?: (args: { requirementId: string; instructions: string; }) => { laneId?: string; skipReason?: string; } | undefined; /** * Tool-layer side effect for a 'dispatch_worker' action when `input.dispatchTarget === "tmux"`: * dispatches a REAL persistent tmux worker via the tmux_agent_manager extension's `fire_task` * action (core structurally invokes the same tool call the model would make; no extension change, * no faked launch or laneId -- see `tmux-dispatch.ts`'s `dispatchTmuxWorker`). Selected ONLY when * BOTH `input.dispatchTarget === "tmux"` AND this dependency is present; otherwise the EXISTING * {@link startWorkerDelegation} in-process path runs, byte-identical to before this field existed. * The honest skip-reason vocabulary this can return: `tmux_extension_not_loaded`, * `tmux_dispatch_failed`, `tmux_dispatch_incomplete`, `lane_correlation_failed`, * `worktree_create_failed` (worktree-sync is enabled but the lane-first `create_lane` call was * refused -- e.g. max lanes reached -- so no fire_task call was ever attempted), * `worker_capability_insufficient` (the model is sub-full class, has an unknown context window, * does not advertise a native tool-call path, or is graded-demoted to text-protocol/none -- see * `model-capability.ts`'s `evaluateLaneWorkerRefusal`; this is the parent's best-effort check * only, refused before any lane/pane side effect -- the dispatched child still refuses * authoritatively at its own startup regardless). */ dispatchTmuxWorker?: (args: { requirementId: string; instructions: string; }) => Promise<{ laneId?: string; skipReason?: string; }>; /** Working directory for resolving kind:"file" evidence ref paths. Defaults to `process.cwd()`. */ cwd?: () => string; /** * Gate agent-facing 'complete' on verified/user evidence backing. Defaults to `true` (on) * when omitted -- the conservative default; set to a function returning `false` to opt out. */ requireVerifiedEvidenceForCompletion?: () => boolean; /** * Read-only open (non-terminal) task_steps steps on the active branch, for the goal⇄task * cross-visibility nudge in the tool response. When omitted, `summarizeGoalState` gets * no task-step context and simply emits no nudge -- goal-tool-core stays pure and never reads * task state itself; this is the only place that supplies it. */ getOpenTaskSteps?: () => readonly OpenTaskStepRef[]; /** Live background tool_task records for kind:"tool" evidence and complete-time re-check. */ getBackgroundToolTasks?: () => readonly BackgroundToolTaskRef[]; /** Active ICM pipeline run for the complete/increment join. */ getActivePipeline?: () => { runId: string; pipelineName: string; goalId?: string; status: string; } | undefined; /** Model-facing budget normalization for the current foreground turn. Omitted by direct owner/test callers. */ authorizeStart?: (input: Pick) => string | number | null | undefined; /** * Live tool-evidence check. When wired, kind:"tool" uses this instead of {@link hasToolCallId} * so a still-running background handoff cannot verify as done. */ resolveToolEvidence?: (uri: string) => boolean; } export declare function createGoalToolDefinition(deps: GoalToolDependencies): GoalToolDefinition; /** * Build the compact Codex-compatible lifecycle surface as adapters over the authoritative legacy * goal executor. The wrappers own no state and duplicate no validation, persistence, accounting, * completion gate, or start-authority rule. */ export declare function createGoalLifecycleToolDefinitions(goalTool: GoalToolDefinition): readonly [ToolDefinition, ToolDefinition, ToolDefinition]; export {}; //# sourceMappingURL=goal.d.ts.map