/** * Versioned Job contract. Input is a JSON file; output is a packet on disk. * v1 is decide-only: mode=implement is accepted and stored, never applied. */ export declare const JOB_SCHEMA_VERSION: 1; export declare const JOB_ISOLATIONS: readonly ["clone", "room"]; export type JobIsolation = (typeof JOB_ISOLATIONS)[number]; export declare const JOB_MODES: readonly ["research", "recommend", "implement"]; export type JobMode = (typeof JOB_MODES)[number]; export declare const JOB_SIDE_EFFECTS: readonly ["read", "mutate"]; export type JobSideEffect = (typeof JOB_SIDE_EFFECTS)[number]; export declare const JOB_AWAITING_USER: "stop"; export type JobAwaitingUser = typeof JOB_AWAITING_USER; export declare const JOB_STATUSES: readonly ["queued", "running", "awaiting-user", "done", "failed", "timeout"]; export type JobStatus = (typeof JOB_STATUSES)[number]; /** * Reserved forbidden defaults. Always merged into actions_forbidden. * actions_allowed may not name any of these. Actions are free strings * otherwise — there is no allowlist enum, so unknown names are kept. */ export declare const DEFAULT_ACTIONS_FORBIDDEN: readonly ["message people", "publish", "spend", "delete", "force-push", "read/write secrets"]; export type DefaultForbiddenAction = (typeof DEFAULT_ACTIONS_FORBIDDEN)[number]; export type JobSource = { /** Named pointer only. No secrets, tokens, or inline credentials. */ name: string; ref?: string; }; export type JobQuietHours = { start: string; end: string; }; export type JobTurn = { speaker: string; text: string; kind?: string; agentId?: string; }; export type JobCompatNote = { status: string; pinned?: string; live?: string | null; note?: string; }; /** * Finished (or paused) packet. Keep it small: status + recommendation + * turns/ref + optional diffs/links/error. `apply` is allowed on the schema * only when mode is implement and actions_allowed is non-empty. v1 never * fills or executes apply. */ export type JobPacket = { status: JobStatus; recommendation?: string; transcript_ref?: string; turns?: JobTurn[]; diffs?: string[]; links?: string[]; error?: string; compat?: JobCompatNote; apply?: unknown; }; export type Job = { schema_version: typeof JOB_SCHEMA_VERSION; job_id: string; idempotency_key: string; goal: string; done_when: string; seats: string[]; isolation: JobIsolation; mode: JobMode; actions_allowed: string[]; actions_forbidden: string[]; sources: JobSource[]; side_effect: JobSideEffect; on_awaiting_user: JobAwaitingUser; deadline?: string; quiet_hours?: JobQuietHours; repo?: string; base_branch?: string; branch_name?: string; test_command?: string; pr?: boolean; implementer?: string; packet?: JobPacket; }; export type JobRecord = Job & { packet: JobPacket; }; export declare class JobValidationError extends Error { constructor(message: string); } export declare function packetMayIncludeApply(job: Pick): boolean; export declare function mergeForbiddenActions(listed: string[] | undefined): string[]; /** Validate and normalize a job file. Applies isolation/mode/forbidden defaults. */ export declare function validateJob(value: unknown): Job; /** JSON Schema for the Job file. Keep in sync with validateJob. */ export declare const JOB_JSON_SCHEMA: { readonly $schema: "https://json-schema.org/draft/2020-12/schema"; readonly $id: "https://github.com/Adam91holt/grokbot-sdk/sdk/src/job/job.schema.json"; readonly title: "Grok Bot Job"; readonly type: "object"; readonly additionalProperties: false; readonly required: readonly ["schema_version", "job_id", "idempotency_key", "goal", "done_when", "seats", "on_awaiting_user"]; readonly properties: { readonly schema_version: { readonly const: 1; }; readonly job_id: { readonly type: "string"; readonly minLength: 1; }; readonly idempotency_key: { readonly type: "string"; readonly minLength: 1; }; readonly goal: { readonly type: "string"; readonly minLength: 1; }; readonly done_when: { readonly type: "string"; readonly minLength: 1; }; readonly seats: { readonly type: "array"; readonly minItems: 1; readonly items: { readonly type: "string"; readonly minLength: 1; }; }; readonly isolation: { readonly type: "string"; readonly enum: readonly ["clone", "room"]; readonly default: "clone"; }; readonly mode: { readonly type: "string"; readonly enum: readonly ["research", "recommend", "implement"]; readonly default: "recommend"; }; readonly actions_allowed: { readonly type: "array"; readonly items: { readonly type: "string"; readonly minLength: 1; }; readonly default: readonly []; readonly description: "The only actions a future implement step may do. Empty = no implement, ever. Free strings; reserved forbidden defaults cannot appear here."; }; readonly actions_forbidden: { readonly type: "array"; readonly items: { readonly type: "string"; readonly minLength: 1; }; readonly default: readonly ["message people", "publish", "spend", "delete", "force-push", "read/write secrets"]; readonly description: "Always includes reserved defaults: message people, publish, spend, delete, force-push, read/write secrets."; }; readonly sources: { readonly type: "array"; readonly items: { readonly type: "object"; readonly additionalProperties: false; readonly required: readonly ["name"]; readonly properties: { readonly name: { readonly type: "string"; readonly minLength: 1; }; readonly ref: { readonly type: "string"; readonly minLength: 1; }; }; }; readonly description: "Named refs only. No secrets inline."; }; readonly side_effect: { readonly type: "string"; readonly enum: readonly ["read", "mutate"]; readonly default: "read"; }; readonly on_awaiting_user: { readonly type: "string"; readonly const: "stop"; }; readonly deadline: { readonly type: "string"; readonly minLength: 1; }; readonly quiet_hours: { readonly type: "object"; readonly additionalProperties: false; readonly required: readonly ["start", "end"]; readonly properties: { readonly start: { readonly type: "string"; readonly minLength: 1; }; readonly end: { readonly type: "string"; readonly minLength: 1; }; }; }; readonly repo: { readonly type: "string"; readonly minLength: 1; }; readonly base_branch: { readonly type: "string"; readonly minLength: 1; }; readonly branch_name: { readonly type: "string"; readonly minLength: 1; }; readonly test_command: { readonly type: "string"; readonly minLength: 1; }; readonly pr: { readonly type: "boolean"; }; readonly implementer: { readonly type: "string"; readonly minLength: 1; }; readonly packet: { readonly $ref: "#/$defs/packet"; }; }; readonly $defs: { readonly packet: { readonly type: "object"; readonly additionalProperties: false; readonly required: readonly ["status"]; readonly properties: { readonly status: { readonly type: "string"; readonly enum: readonly ["queued", "running", "awaiting-user", "done", "failed", "timeout"]; }; readonly recommendation: { readonly type: "string"; }; readonly transcript_ref: { readonly type: "string"; }; readonly turns: { readonly type: "array"; readonly items: { readonly type: "object"; readonly additionalProperties: false; readonly required: readonly ["speaker", "text"]; readonly properties: { readonly speaker: { readonly type: "string"; readonly minLength: 1; }; readonly text: { readonly type: "string"; }; readonly kind: { readonly type: "string"; }; readonly agentId: { readonly type: "string"; }; }; }; }; readonly diffs: { readonly type: "array"; readonly items: { readonly type: "string"; }; }; readonly links: { readonly type: "array"; readonly items: { readonly type: "string"; }; }; readonly error: { readonly type: "string"; }; readonly compat: { readonly type: "object"; readonly additionalProperties: false; readonly required: readonly ["status"]; readonly properties: { readonly status: { readonly type: "string"; }; readonly pinned: { readonly type: "string"; }; readonly live: { readonly type: readonly ["string", "null"]; }; readonly note: { readonly type: "string"; }; }; }; readonly apply: { readonly description: "Allowed only when mode is implement and actions_allowed is non-empty. v1 never applies it."; }; }; }; }; }; //# sourceMappingURL=schema.d.ts.map