/** * The `/api/v1/governance/steering/*` surface (STEERING program) — the management wire behind * the studio's top-level Steering nav: batch IMPORT of steering docs/rules, and "add with chat" * AUTHORING as a governed run. Per-rule CRUD deliberately lives elsewhere — this module adds no * second door: `GET/POST /governance/rules` (now steering-aware: `?type=` facet, * `?include_retired=`, steering-field writes) and `DELETE /governance/rules/:id` in * `api/routes.ts` ARE the steering-rule CRUD, because a steering rule IS a conformance rule * (the wiki/rules model and the old policy model merged into one). * * Thin by design, like `campaigns/routes.ts`: validation is zod (strict, unknown keys named — * the FINDING-031 doctrine); import normalization/validation is the ENGINE's ingest path on the * single-writer actor (fail-closed per entry — the daemon never opens the store for writes); * authoring is the EXISTING run machinery (`launchRun` + the `steering-author` drop-in workflow * + the standard `POST /runs/:id/gate` HITL flow) — no new chat stack. Error posture mirrors the * campaign surface: a build whose engine addon predates the steering model answers 501 * (`SteeringUnsupportedError` — "upgrade the engine"), never 400 ("fix your request"). * * estate's MCP surface stays READ-ONLY on rules; every steering WRITE flows through here (the * governed operator path) — the AW-11 "no rules.write on estate" invariant is a design input of * this module, not a coincidence. */ import type { FastifyInstance, FastifyRequest } from 'fastify'; import { z } from 'zod'; import { type CoreAdapter } from '../core/adapter.js'; import type { Actor } from '../core/types.js'; import type { AuditLog } from './audit.js'; import { type RunTimingIndex } from './run-timing-index.js'; /** * The steering-type vocabulary (`wicked-crew-api-types::SteeringType`) — enum-as-string, the * engine's serde default is `architecture`. ONE spelling, exported: `api/routes.ts` reads it for * the `?type=` browse facet so the two surfaces can never disagree about what a type is. */ export declare const STEERING_TYPE_VALUES: readonly ["architecture", "development", "security", "testing", "operations", "compliance", "design-ux"]; export declare const STEERING_TYPES: ReadonlySet; /** The engine's serde default for a rule row that predates (or omits) `steering_type`. */ export declare const DEFAULT_STEERING_TYPE = "architecture"; /** Per-entry ceiling on an import doc / rule payload (UTF-8 bytes) — mirrors the run-files cap. */ export declare const STEERING_ENTRY_MAX_BYTES: number; /** Batch ceiling — an import is a page action, not a bulk-migration channel. */ export declare const STEERING_IMPORT_MAX_ENTRIES = 200; /** Authoring intent is operator prose, not a document store (the guidance-cap doctrine). */ export declare const STEERING_INSTRUCTIONS_MAX_BYTES: number; export declare const SteeringImportSchema: z.ZodObject<{ type: z.ZodOptional>; entries: z.ZodArray; name: z.ZodOptional; content: z.ZodString; }, "strict", z.ZodTypeAny, { content: string; kind: "doc"; name?: string | undefined; }, { content: string; kind: "doc"; name?: string | undefined; }>, z.ZodObject<{ kind: z.ZodLiteral<"rule">; rule: z.ZodType; }, "strict", z.ZodTypeAny, { kind: "rule"; rule: import("wicked-crew-api-types").ConformanceRule; }, { kind: "rule"; rule: import("wicked-crew-api-types").ConformanceRule; }>]>, "many">; }, "strict", z.ZodTypeAny, { entries: ({ content: string; kind: "doc"; name?: string | undefined; } | { kind: "rule"; rule: import("wicked-crew-api-types").ConformanceRule; })[]; type?: "architecture" | "development" | "security" | "testing" | "operations" | "compliance" | "design-ux" | undefined; }, { entries: ({ content: string; kind: "doc"; name?: string | undefined; } | { kind: "rule"; rule: import("wicked-crew-api-types").ConformanceRule; })[]; type?: "architecture" | "development" | "security" | "testing" | "operations" | "compliance" | "design-ux" | undefined; }>; export declare const SteeringAuthorSchema: z.ZodObject<{ instructions: z.ZodString; type: z.ZodOptional>; paths: z.ZodOptional>; documents: z.ZodOptional, "many">>; repoRef: z.ZodOptional; sessionId: z.ZodOptional; }, "strict", z.ZodTypeAny, { instructions: string; sessionId?: string | undefined; repoRef?: string | undefined; type?: "architecture" | "development" | "security" | "testing" | "operations" | "compliance" | "design-ux" | undefined; paths?: string[] | undefined; documents?: { content: string; name: string; }[] | undefined; }, { instructions: string; sessionId?: string | undefined; repoRef?: string | undefined; type?: "architecture" | "development" | "security" | "testing" | "operations" | "compliance" | "design-ux" | undefined; paths?: string[] | undefined; documents?: { content: string; name: string; }[] | undefined; }>; /** * Where the author route lands inline documents so the run can read them: a per-run inbox on the * daemon host — the existing run file mechanism (runs read the daemon's filesystem; the paths * ride the problem statement, never the prompt-fattening content itself). */ export declare function steeringInboxDir(runId: string): string; /** * The proposed-rules file in {@link steeringInboxDir} that the post-approval landing * (`api/steering-landing.ts`) reads first when it exists (crew#388). Since #789 no worker is asked * to write it — the propose phase replies with the array and the landing reads the stored output — * so it is present only for runs launched before that, or put there by hand. */ export declare const STEERING_PROPOSAL_FILENAME = "proposed-rules.json"; export interface SteeringRoutesDeps { audit: AuditLog; actorOf: (req: FastifyRequest & { actor?: Actor; }) => Actor; /** The default council roster for the authoring run (already parsed). */ roster: () => unknown[]; /** The run→launch-time index (home command-center run metrics) — so the steering-author run's * `run.launched` entry stamps `created_at` LIVE, not only after a restart re-hydrates the trail * (Copilot #466). Optional so route-unit tests can omit it; `registerRoutes` always supplies it. */ runTimingIndex?: RunTimingIndex; } export declare function registerGovernanceSteeringRoutes(app: FastifyInstance, adapter: CoreAdapter, deps: SteeringRoutesDeps): void; //# sourceMappingURL=governance-steering.d.ts.map