feat(api): define v1 control-plane contract
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import type { PageEnvelope, PageQuery } from './instances.js';
|
||||
|
||||
export const RISK_LEVELS = ['R0', 'R1', 'R2', 'R3'] as const;
|
||||
export const PREPARATION_STATUSES = ['prepared', 'consumed', 'expired', 'invalidated'] as const;
|
||||
export type RiskLevel = (typeof RISK_LEVELS)[number];
|
||||
export type PreparationStatus = (typeof PREPARATION_STATUSES)[number];
|
||||
/** Safe registry metadata; it never exposes an arbitrary HTTP method, path, host, or port. */
|
||||
export interface OperationCatalogEntry {
|
||||
readonly operationId: string;
|
||||
readonly title: string;
|
||||
readonly risk: RiskLevel;
|
||||
readonly capability: string;
|
||||
readonly batchable: boolean;
|
||||
readonly parameterSchemaId: string;
|
||||
}
|
||||
export interface ParameterSchemaRef {
|
||||
readonly parameterSchemaId: string;
|
||||
}
|
||||
export interface OperationTarget {
|
||||
readonly instanceId: string;
|
||||
readonly revision?: number;
|
||||
}
|
||||
export type RegisteredParameterValue =
|
||||
| { readonly fieldId: string; readonly kind: 'string'; readonly value: string }
|
||||
| { readonly fieldId: string; readonly kind: 'number'; readonly value: number }
|
||||
| { readonly fieldId: string; readonly kind: 'boolean'; readonly value: boolean }
|
||||
| { readonly fieldId: string; readonly kind: 'string-list'; readonly value: readonly string[] }
|
||||
| { readonly fieldId: string; readonly kind: 'number-list'; readonly value: readonly number[] }
|
||||
| { readonly fieldId: string; readonly kind: 'null'; readonly value: null };
|
||||
|
||||
/**
|
||||
* Structured fields validated against the immutable registry schema. Unknown field IDs and kind
|
||||
* mismatches are rejected; callers cannot submit an arbitrary JSON object or transport target.
|
||||
*/
|
||||
export interface RegisteredParameters extends ParameterSchemaRef {
|
||||
readonly fields: readonly RegisteredParameterValue[];
|
||||
}
|
||||
export interface PrepareOperationRequest {
|
||||
readonly operationId: string;
|
||||
readonly targets: readonly OperationTarget[];
|
||||
readonly parameters: RegisteredParameters;
|
||||
}
|
||||
export interface Preparation {
|
||||
readonly id: string;
|
||||
readonly status: PreparationStatus;
|
||||
readonly operationId: string;
|
||||
readonly risk: RiskLevel;
|
||||
readonly expiresAt: string;
|
||||
/** Opaque, short-lived, one-time value returned only by prepare and consumed by execute. */
|
||||
readonly confirmationToken: string;
|
||||
readonly confirmationPrompt: string;
|
||||
readonly targetCount: number;
|
||||
}
|
||||
export interface ExecuteOperationRequest {
|
||||
readonly preparationId: string;
|
||||
readonly confirmationToken: string;
|
||||
}
|
||||
export interface OperationFilters {
|
||||
readonly risk?: RiskLevel;
|
||||
readonly capability?: string;
|
||||
readonly batchable?: boolean;
|
||||
readonly search?: string;
|
||||
}
|
||||
export type OperationPageQuery = PageQuery<'operationId' | 'risk' | 'capability'> &
|
||||
OperationFilters;
|
||||
export type OperationPage = PageEnvelope<OperationCatalogEntry>;
|
||||
Reference in New Issue
Block a user