const WORKFLOW_CHAIN: Record = { discussing: "research-slice", researching: "plan-slice", planning: null, executing: "verify-slice", verifying: "ship-slice", reviewing: "ship-slice", shipping: null, closed: null, }; const HUMAN_GATES = new Set(["planning", "shipping"]); /** * User-facing command suggestion per slice status. * * Aligns with @references/next-steps.md. Unlike {@link nextWorkflow} (which * returns the internal workflow id used for auto-transitions), this returns the * slash command the user should run to advance from the current status. * * For `closed`, the current slice is done — the suggestion moves to the NEXT * slice, which always starts in `discussing`. */ const SUGGESTED_COMMAND: Record = { discussing: "/tff:discuss", researching: "/tff:research", planning: "/tff:plan", executing: "/tff:execute", verifying: "/tff:verify", reviewing: "/tff:ship", shipping: "/tff:complete-milestone", closed: "/tff:discuss", }; export function nextWorkflow(currentStatus: string): string | null { return WORKFLOW_CHAIN[currentStatus] ?? null; } /** * Return the suggested user-facing `/tff:` for the given slice status. * Returns null for unknown statuses. */ export function suggestedCommand(currentStatus: string): string | null { return SUGGESTED_COMMAND[currentStatus] ?? null; } export function shouldAutoTransition( currentStatus: string, autonomyMode: "guided" | "plan-to-pr", ): boolean { if (autonomyMode === "guided") return false; if (HUMAN_GATES.has(currentStatus)) return false; return WORKFLOW_CHAIN[currentStatus] !== null; } /** * Milestone-level next-step suggestion. * * When all slices are closed, the next step depends on whether an audit has * recorded a passing verdict. Without one, the user (or orchestrator) should * run `/tff:audit-milestone` first; only after a `ready` verdict should * `/tff:complete-milestone` be suggested. */ export function suggestedMilestoneCommand(opts: { allSlicesClosed: boolean; auditVerdict: "ready" | "not_ready" | null; }): string | null { if (!opts.allSlicesClosed) return null; if (opts.auditVerdict !== "ready") return "/tff:audit-milestone"; return "/tff:complete-milestone"; }