/** * v3.1.1 Step 0.8 — Job-shape decision recorder. * * The CLI is a *recorder and gate*, not a judge. The LLM makes the * semantic call ("is this a Job?") and writes the verdict via * `peaks code detect-job`; this service persists the verdict to * `.peaks/_runtime//job-shape.json` and refuses downstream * steps that need a decision when the file is missing. * * Karpathy §2 (Simplicity First): ~100 lines, pure validation + fs * writes, NO keyword regex, NO LLM call inside. The LLM is the * source of truth for whether the request is Job-shaped; this file * just enforces that a decision was made at all. * * Decision file lives at `.peaks/_runtime//job-shape.json` * (sibling of `session.json`, NOT under `job//` because no jid * exists yet at the moment of Step 0.8). */ export type JobStrategy = 'single' | 'rotating'; export type JobConfidence = 'high' | 'medium' | 'low'; export interface JobShapeDecision { readonly isJob: boolean; readonly rationale: string; readonly suggestedJobId: string; readonly suggestedStrategy: JobStrategy; readonly confidence: JobConfidence; /** ISO 8601; stamped server-side in `writeJobShapeDecision`. */ readonly decidedAt: string; } export interface JobShapeRecord { readonly sessionId: string; /** sha1 of the user prompt (first 16 hex). */ readonly promptHash: string; readonly decision: JobShapeDecision; readonly schemaVersion: 1; } export declare const JOB_SHAPE_SCHEMA_VERSION: 1; export declare const JOB_SHAPE_FILE_NAME = "job-shape.json"; export declare const JOB_SHAPE_ALREADY_DECIDED: "JOB_SHAPE_ALREADY_DECIDED"; export declare const JOB_SHAPE_NOT_DECIDED: "JOB_SHAPE_NOT_DECIDED"; export declare const JOB_SHAPE_INVALID: "JOB_SHAPE_INVALID"; export declare class JobShapeDecisionError extends Error { readonly code: typeof JOB_SHAPE_NOT_DECIDED | typeof JOB_SHAPE_ALREADY_DECIDED | typeof JOB_SHAPE_INVALID; readonly details?: unknown; constructor(opts: { code: typeof JobShapeDecisionError.prototype.code; message: string; details?: unknown; }); } /** Pure validator; throws on bad input. No fs IO. */ export declare function validateJobShapeDecision(input: unknown): JobShapeDecision; /** Read the canonical record; throws JOB_SHAPE_NOT_DECIDED if absent or malformed. */ export declare function readJobShapeDecision(projectRoot: string, sessionId: string): JobShapeRecord; export interface WriteJobShapeDecisionInput { readonly isJob: boolean; readonly rationale: string; readonly suggestedJobId: string; readonly suggestedStrategy: JobStrategy; readonly confidence: JobConfidence; readonly prompt: string; } /** * Persist a new decision; refuses overwrite unless `force: true`. * Stamps `decidedAt` server-side via `now` (defaults to `new Date()`) * so the LLM cannot back-date. */ export declare function writeJobShapeDecision(projectRoot: string, sessionId: string, decision: WriteJobShapeDecisionInput, opts?: { force?: boolean; now?: () => Date; }): JobShapeRecord;