feat(ql3): expose fenced copilot diagnosis API

This commit is contained in:
whyour
2026-08-15 23:45:13 +08:00
parent 0a31c3364b
commit 774af4a4c9
10 changed files with 845 additions and 5 deletions
@@ -45,6 +45,11 @@
"require": "./dist/copilot/failure-diagnosis/outputProjectedKeyring.js",
"default": "./dist/copilot/failure-diagnosis/outputProjectedKeyring.js"
},
"./copilot-routes": {
"types": "./dist/copilot/failure-diagnosis/failureDiagnosisRoute.d.ts",
"require": "./dist/copilot/failure-diagnosis/failureDiagnosisRoute.js",
"default": "./dist/copilot/failure-diagnosis/failureDiagnosisRoute.js"
},
"./http": {
"types": "./dist/transport/httpSurface.d.ts",
"require": "./dist/transport/httpSurface.js",
@@ -445,6 +445,13 @@ export async function startProductionClusterAiControlApplication(
capability: promptApplication.promptExecutionOutputs,
},
}),
...(copilotApplication === undefined
? {}
: {
copilotFailureDiagnosis: {
capability: copilotApplication,
},
}),
});
if (controlApplication.status !== 'active') {
throw new Error('AI-enabled cluster-control did not activate');
@@ -61,6 +61,10 @@ import {
} from '../worker-ingress/productionWorkerIngress';
import type { ClusterWorkerIngressApplicationResult } from '../worker-ingress/workerIngressApplication';
import { createClusterControlPluginPackageWorkflowRoutes } from '../plugin-package/workflow/pluginPackageWorkflowRoute';
import {
createClusterControlCopilotFailureDiagnosisRoute,
type ClusterCopilotFailureDiagnosisCapability,
} from '../copilot/failure-diagnosis/failureDiagnosisRoute';
export const PRODUCTION_CLUSTER_CONTROL_ROUTE_OPERATIONS = Object.freeze([
'task.get',
@@ -87,6 +91,7 @@ export const PRODUCTION_CLUSTER_CONTROL_OPTIONAL_ROUTE_OPERATIONS =
'prompt.execution.read',
'prompt.execution.output.read',
'prompt.output.read',
'copilot.failure_diagnosis.execute',
] as const);
export interface ProductionClusterControlAssemblyOptions {
@@ -109,6 +114,9 @@ export interface ProductionClusterControlAssemblyOptions {
readonly promptExecutionOutputRead?: Readonly<{
readonly capability: ClusterPluginPackagePromptExecutionOutputReadCapability;
}>;
readonly copilotFailureDiagnosis?: Readonly<{
readonly capability: ClusterCopilotFailureDiagnosisCapability;
}>;
readonly workerIngress?: Readonly<{
readonly config: EnabledClusterWorkerIngressConfig;
readonly onDiagnostic?: (error: unknown) => void | Promise<void>;
@@ -154,6 +162,9 @@ export interface ProductionClusterControlApplicationOptions
readonly promptExecutionOutputRead?: Readonly<{
readonly capability: ClusterPluginPackagePromptExecutionOutputReadCapability;
}>;
readonly copilotFailureDiagnosis?: Readonly<{
readonly capability: ClusterCopilotFailureDiagnosisCapability;
}>;
readonly workerIngress?: ProductionClusterWorkerIngressOptions;
}
@@ -261,6 +272,13 @@ export function createProductionClusterControlApplicationStack(
options.promptExecutionOutputRead.capability,
),
]),
...(options.copilotFailureDiagnosis === undefined
? []
: [
createClusterControlCopilotFailureDiagnosisRoute(
options.copilotFailureDiagnosis.capability,
),
]),
];
const routes = createClusterControlRouteRegistry(routeDefinitions);
const expectedRouteCount =
@@ -269,7 +287,8 @@ export function createProductionClusterControlApplicationStack(
(options.promptExecution === undefined ? 0 : 1) +
(options.promptExecutionInspection === undefined ? 0 : 1) +
(options.promptOutputRead === undefined ? 0 : 1) +
(options.promptExecutionOutputRead === undefined ? 0 : 1);
(options.promptExecutionOutputRead === undefined ? 0 : 1) +
(options.copilotFailureDiagnosis === undefined ? 0 : 1);
if (routes.size !== expectedRouteCount) {
throw new Error('Production cluster-control route allowlist is incomplete');
}
@@ -359,6 +378,7 @@ export function startProductionClusterControlApplication(
promptExecutionInspection,
promptOutputRead,
promptExecutionOutputRead,
copilotFailureDiagnosis,
...applicationOptions
} = options;
const database = createClusterControlDatabaseBinding(config);
@@ -402,6 +422,9 @@ export function startProductionClusterControlApplication(
...(promptExecutionOutputRead === undefined
? {}
: { promptExecutionOutputRead }),
...(copilotFailureDiagnosis === undefined
? {}
: { copilotFailureDiagnosis }),
...(workerIngress === undefined
? {}
: {
@@ -0,0 +1,297 @@
// Cluster Copilot owns one bounded, Policy-fenced diagnosis admission route.
import type { SecurityPrincipal } from '@qinglong/runtime-core/security';
import type { ClusterControlAdmissionResponse } from '../../transport/httpSurface';
import type {
ClusterControlAuthorizedOperationRequest,
ClusterControlRouteDefinition,
ClusterControlRouteParameters,
} from '../../transport/routeRegistry';
export const CLUSTER_COPILOT_FAILURE_DIAGNOSIS_REQUEST_SCHEMA =
'qinglong/cluster-copilot-failure-diagnosis-request@v1' as const;
export const CLUSTER_COPILOT_FAILURE_DIAGNOSIS_RESPONSE_SCHEMA =
'qinglong/cluster-copilot-failure-diagnosis-response@v1' as const;
export const CLUSTER_CONTROL_COPILOT_FAILURE_DIAGNOSIS_ROUTE = Object.freeze({
method: 'POST' as const,
path: '/api/v3/projects/{projectId}/runs/{runId}/copilot/failure-diagnoses',
operationId: 'copilot.failure_diagnosis.execute',
permission: 'model.invoke',
projectParameter: 'projectId',
});
export interface ClusterCopilotFailureDiagnosisCommand {
readonly requestId: string;
readonly traceId: string;
readonly projectId: string;
readonly sourceRunId: string;
readonly principal: Readonly<SecurityPrincipal>;
}
interface ClusterCopilotFailureDiagnosisOutputReference {
readonly artifactId: string;
readonly artifactDigest: string;
}
export interface ClusterCopilotFailureDiagnosisCapability {
execute(command: Readonly<ClusterCopilotFailureDiagnosisCommand>): Promise<
Readonly<{
readonly admissionStatus: 'created' | 'existing';
readonly admission: Readonly<{
readonly requestId: string;
readonly runId: string;
readonly sourceRunId: string;
}>;
readonly tool: Readonly<{ readonly outcome: string }> | null;
readonly model: Readonly<{
readonly outcome: string;
readonly output: Readonly<ClusterCopilotFailureDiagnosisOutputReference> | null;
}> | null;
readonly terminalization: Readonly<{
readonly stage: string;
readonly reason: string;
readonly outcome: string;
}> | null;
readonly terminalizationRequired: boolean;
}>
>;
}
class InvalidClusterCopilotFailureDiagnosisRequestError extends TypeError {}
const ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
const RUN_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,35}$/;
const DIGEST_PATTERN = /^[0-9a-f]{64}$/;
const OUTCOMES = new Set(['succeeded', 'failed', 'timed_out', 'cancelled']);
const TERMINAL_STAGES = new Set(['tool', 'log', 'deadline', 'cancellation']);
const TERMINAL_REASONS = new Set([
'tool_failed',
'tool_timed_out',
'log_not_found',
'log_pending',
'log_missing',
'log_retired',
'tool_budget_exhausted',
'deadline_exceeded',
'cancellation_requested',
]);
function invalid(): never {
throw new InvalidClusterCopilotFailureDiagnosisRequestError();
}
function response(
statusCode: number,
body: Readonly<Record<string, unknown>>,
): ClusterControlAdmissionResponse {
return Object.freeze({ statusCode, body: Object.freeze(body) });
}
function parseBody(value: unknown): Readonly<{ traceId: string }> {
if (
!value ||
typeof value !== 'object' ||
Array.isArray(value) ||
Object.getPrototypeOf(value) !== Object.prototype ||
Object.keys(value).sort().join('\0') !== ['schema', 'traceId'].join('\0')
) {
return invalid();
}
const body = value as Record<string, unknown>;
if (
body.schema !== CLUSTER_COPILOT_FAILURE_DIAGNOSIS_REQUEST_SCHEMA ||
typeof body.traceId !== 'string' ||
!ID_PATTERN.test(body.traceId)
) {
return invalid();
}
return Object.freeze({ traceId: body.traceId });
}
function errorCode(error: unknown): string | null {
if (
!error ||
typeof error !== 'object' ||
!('code' in error) ||
typeof error.code !== 'string'
) {
return null;
}
return error.code;
}
function executionError(error: unknown): ClusterControlAdmissionResponse {
const code = errorCode(error);
if (
code === 'COPILOT_FAILURE_DIAGNOSIS_APPLICATION_CONFLICT' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_ADMISSION_CONFLICT' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_ADMISSION_NOT_ALLOWED' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_TOOL_EXECUTION_CONFLICT' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_MODEL_EXECUTION_CONFLICT' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_FINALIZATION_CONFLICT' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_MODEL_EXECUTION_IN_PROGRESS' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_MODEL_RESOLUTION_REQUIRED' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_PRE_MODEL_TERMINALIZATION_CONFLICT'
) {
return response(409, { code: 'copilot_failure_diagnosis_conflict' });
}
if (
code === 'TRUSTED_TOOL_EXECUTION_POLICY_DENIED' ||
code === 'TRUSTED_TOOL_EXECUTION_APPROVAL_REQUIRED'
) {
return response(403, { code: 'copilot_failure_diagnosis_forbidden' });
}
if (
code === 'COPILOT_FAILURE_DIAGNOSIS_APPLICATION_BUSY' ||
code === 'MODEL_GATEWAY_BUSY'
) {
return response(429, {
code: 'copilot_failure_diagnosis_capacity_exceeded',
});
}
if (
code === 'MODEL_POLICY_DENIED' ||
code === 'MODEL_BUDGET_EXCEEDED' ||
code === 'COPILOT_MODEL_EGRESS_DENIED' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_BUDGET_EXCEEDED'
) {
return response(422, { code: 'copilot_failure_diagnosis_policy_rejected' });
}
if (
code === 'MODEL_INVOCATION_DEADLINE_EXCEEDED' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_TOOL_EXECUTION_DEADLINE_EXCEEDED'
) {
return response(504, {
code: 'copilot_failure_diagnosis_deadline_exceeded',
});
}
if (code === 'MODEL_INVOCATION_ABORTED') {
return response(408, { code: 'copilot_failure_diagnosis_aborted' });
}
if (
code === 'COPILOT_FAILURE_DIAGNOSIS_APPLICATION_INVALID' ||
code === 'COPILOT_FAILURE_DIAGNOSIS_EXECUTION_PLAN_INVALID'
) {
return response(400, { code: 'invalid_copilot_failure_diagnosis_request' });
}
return response(503, { code: 'copilot_failure_diagnosis_unavailable' });
}
function projectResult(
result: Awaited<
ReturnType<ClusterCopilotFailureDiagnosisCapability['execute']>
>,
requestId: string,
sourceRunId: string,
): ClusterControlAdmissionResponse {
const model = result?.model;
const terminalization = result?.terminalization;
const outcome = model?.outcome ?? terminalization?.outcome;
if (
!result ||
(result.admissionStatus !== 'created' &&
result.admissionStatus !== 'existing') ||
!result.admission ||
result.admission.requestId !== requestId ||
result.admission.sourceRunId !== sourceRunId ||
!RUN_ID_PATTERN.test(result.admission.runId) ||
result.terminalizationRequired !== false ||
(model === null) === (terminalization === null) ||
typeof outcome !== 'string' ||
!OUTCOMES.has(outcome)
) {
return response(503, { code: 'copilot_failure_diagnosis_unavailable' });
}
let stage: string;
let reason: string | null;
let outputArtifact: Readonly<ClusterCopilotFailureDiagnosisOutputReference> | null;
if (model) {
if (
!OUTCOMES.has(model.outcome) ||
(model.outcome === 'succeeded') !== (model.output !== null) ||
(model.output !== null &&
(!ID_PATTERN.test(model.output.artifactId) ||
!DIGEST_PATTERN.test(model.output.artifactDigest)))
) {
return response(503, { code: 'copilot_failure_diagnosis_unavailable' });
}
stage = 'model';
reason = null;
outputArtifact = model.output;
} else {
if (
!terminalization ||
!TERMINAL_STAGES.has(terminalization.stage) ||
!TERMINAL_REASONS.has(terminalization.reason)
) {
return response(503, { code: 'copilot_failure_diagnosis_unavailable' });
}
stage = terminalization.stage;
reason = terminalization.reason;
outputArtifact = null;
}
return response(result.admissionStatus === 'created' ? 201 : 200, {
schema: CLUSTER_COPILOT_FAILURE_DIAGNOSIS_RESPONSE_SCHEMA,
requestId,
status: result.admissionStatus,
replayed: result.admissionStatus === 'existing',
sourceRunId,
diagnosisRunId: result.admission.runId,
outcome,
stage,
reason,
outputArtifact:
outputArtifact === null
? null
: Object.freeze({
artifactId: outputArtifact.artifactId,
artifactDigest: outputArtifact.artifactDigest,
}),
});
}
export function createClusterControlCopilotFailureDiagnosisRoute(
capability: ClusterCopilotFailureDiagnosisCapability,
): Readonly<ClusterControlRouteDefinition> {
if (!capability || typeof capability.execute !== 'function') {
throw new TypeError(
'Cluster-control Copilot failure diagnosis capability is invalid',
);
}
return Object.freeze({
...CLUSTER_CONTROL_COPILOT_FAILURE_DIAGNOSIS_ROUTE,
async handle(
authorized: ClusterControlAuthorizedOperationRequest,
routeParameters: ClusterControlRouteParameters,
) {
let body: Readonly<{ traceId: string }>;
try {
body = parseBody(authorized.request.body);
} catch {
return response(400, {
code: 'invalid_copilot_failure_diagnosis_request',
});
}
const projectId = authorized.projectId;
const sourceRunId = routeParameters.runId;
if (
projectId === null ||
typeof sourceRunId !== 'string' ||
!RUN_ID_PATTERN.test(sourceRunId)
) {
return response(503, { code: 'copilot_failure_diagnosis_unavailable' });
}
try {
const result = await capability.execute({
requestId: authorized.request.requestId,
traceId: body.traceId,
projectId,
sourceRunId,
principal: authorized.principal,
});
return projectResult(result, authorized.request.requestId, sourceRunId);
} catch (error) {
return executionError(error);
}
},
});
}
@@ -117,7 +117,7 @@ async function projectedFile(root, name, bytes) {
await chmod(join(root, name), 0o440);
}
test('Copilot composition is explicit, shares the Prompt gateway and exposes no route', async () => {
test('Copilot composition is explicit, shares the Prompt gateway and injects one route capability', async () => {
const secretRoot = await mkdtemp(join(tmpdir(), 'ql3-cluster-ai-secret-'));
const configRoot = await mkdtemp(join(tmpdir(), 'ql3-copilot-config-'));
const invocationRoot = await mkdtemp(join(tmpdir(), 'ql3-copilot-invocation-'));
@@ -229,7 +229,7 @@ test('Copilot composition is explicit, shares the Prompt gateway and exposes no
assert.equal(created.gateway, gateway);
assert.equal(created.successfulCompletion, registeredSink);
assert.equal(created.artifactStore, artifactStore);
assert.equal('copilot' in controlOptions, false);
assert.equal(controlOptions.copilotFailureDiagnosis.capability, copilot);
assert.equal(await application.stop(), 'stopped');
} finally {
config.fill(0); invocation.fill(0); result.fill(0); output.fill(0);
@@ -0,0 +1,269 @@
const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
CLUSTER_COPILOT_FAILURE_DIAGNOSIS_REQUEST_SCHEMA,
CLUSTER_COPILOT_FAILURE_DIAGNOSIS_RESPONSE_SCHEMA,
CLUSTER_CONTROL_COPILOT_FAILURE_DIAGNOSIS_ROUTE,
createClusterControlCopilotFailureDiagnosisRoute,
} = require('@qinglong/cluster-control/copilot-routes');
function authorized(body, overrides = {}) {
return {
request: {
requestId: 'diagnosis-request-1',
method: 'POST',
path: '/api/v3/projects/project-1/runs/source-run-1/copilot/failure-diagnoses',
query: {},
headers: {},
signal: new AbortController().signal,
body,
},
principal: {
subject: { type: 'api_app', id: 'app-1' },
authenticationId: 'credential-1',
authenticatedAtMs: 1,
expiresAtMs: 10_000,
assurance: 'service',
},
operationId: 'copilot.failure_diagnosis.execute',
permission: 'model.invoke',
projectId: 'project-1',
policyFence: { projectVersion: 3, bindingVersion: 7 },
...overrides,
};
}
function body(overrides = {}) {
return {
schema: CLUSTER_COPILOT_FAILURE_DIAGNOSIS_REQUEST_SCHEMA,
traceId: 'trace-1',
...overrides,
};
}
function succeeded(admissionStatus = 'created') {
return {
admissionStatus,
admission: {
requestId: 'diagnosis-request-1',
runId: 'diagnosis-run-1',
sourceRunId: 'source-run-1',
},
tool: { outcome: 'succeeded', output: { private: 'must not cross' } },
model: {
outcome: 'succeeded',
output: {
artifactId: 'cdo:artifact-1',
artifactDigest: 'a'.repeat(64),
provider: 'private-provider',
},
plaintext: 'private diagnosis',
},
terminalization: null,
terminalizationRequired: false,
};
}
test('defines one exact model.invoke route and binds HTTP request identity', async () => {
let command;
const route = createClusterControlCopilotFailureDiagnosisRoute({
async execute(value) {
command = value;
return succeeded();
},
});
const request = authorized(body());
const result = await route.handle(request, {
projectId: 'project-1',
runId: 'source-run-1',
});
assert.deepEqual(CLUSTER_CONTROL_COPILOT_FAILURE_DIAGNOSIS_ROUTE, {
method: 'POST',
path: '/api/v3/projects/{projectId}/runs/{runId}/copilot/failure-diagnoses',
operationId: 'copilot.failure_diagnosis.execute',
permission: 'model.invoke',
projectParameter: 'projectId',
});
assert.deepEqual(command, {
requestId: 'diagnosis-request-1',
traceId: 'trace-1',
projectId: 'project-1',
sourceRunId: 'source-run-1',
principal: request.principal,
});
assert.equal('policyFence' in command, false);
assert.equal('model' in command, false);
assert.equal('attemptId' in command, false);
assert.equal(result.statusCode, 201);
assert.deepEqual(result.body, {
schema: CLUSTER_COPILOT_FAILURE_DIAGNOSIS_RESPONSE_SCHEMA,
requestId: 'diagnosis-request-1',
status: 'created',
replayed: false,
sourceRunId: 'source-run-1',
diagnosisRunId: 'diagnosis-run-1',
outcome: 'succeeded',
stage: 'model',
reason: null,
outputArtifact: {
artifactId: 'cdo:artifact-1',
artifactDigest: 'a'.repeat(64),
},
});
assert.equal(JSON.stringify(result).includes('private'), false);
});
test('returns a content-free existing receipt for exact replay', async () => {
const route = createClusterControlCopilotFailureDiagnosisRoute({
async execute() {
return succeeded('existing');
},
});
const result = await route.handle(authorized(body()), {
projectId: 'project-1',
runId: 'source-run-1',
});
assert.equal(result.statusCode, 200);
assert.equal(result.body.status, 'existing');
assert.equal(result.body.replayed, true);
});
test('projects pre-Model terminalization without Tool or log content', async () => {
const route = createClusterControlCopilotFailureDiagnosisRoute({
async execute() {
return {
admissionStatus: 'created',
admission: {
requestId: 'diagnosis-request-1',
runId: 'diagnosis-run-1',
sourceRunId: 'source-run-1',
},
tool: { outcome: 'failed', privateLog: 'must not cross' },
model: null,
terminalization: {
stage: 'log',
reason: 'log_retired',
outcome: 'failed',
privateEvidence: 'must not cross',
},
terminalizationRequired: false,
};
},
});
const result = await route.handle(authorized(body()), {
projectId: 'project-1',
runId: 'source-run-1',
});
assert.equal(result.statusCode, 201);
assert.equal(result.body.stage, 'log');
assert.equal(result.body.reason, 'log_retired');
assert.equal(result.body.outcome, 'failed');
assert.equal(result.body.outputArtifact, null);
assert.equal(JSON.stringify(result).includes('private'), false);
});
test('rejects non-exact bodies before invoking the capability', async () => {
let calls = 0;
const route = createClusterControlCopilotFailureDiagnosisRoute({
async execute() {
calls += 1;
return succeeded();
},
});
for (const invalid of [
null,
{},
body({ requestId: 'body-request-must-not-exist' }),
body({ provider: 'caller-selected' }),
body({ traceId: '' }),
Object.assign(Object.create(null), body()),
]) {
const result = await route.handle(authorized(invalid), {
projectId: 'project-1',
runId: 'source-run-1',
});
assert.equal(result.statusCode, 400);
assert.deepEqual(result.body, {
code: 'invalid_copilot_failure_diagnosis_request',
});
}
assert.equal(calls, 0);
});
test('fails closed on capability responses that do not bind the durable identity', async () => {
for (const mutation of [
(value) => ({
...value,
admission: { ...value.admission, requestId: 'other' },
}),
(value) => ({
...value,
admission: { ...value.admission, sourceRunId: 'other' },
}),
(value) => ({ ...value, terminalizationRequired: true }),
(value) => ({ ...value, model: null }),
(value) => ({ ...value, model: { ...value.model, output: null } }),
]) {
const route = createClusterControlCopilotFailureDiagnosisRoute({
async execute() {
return mutation(succeeded());
},
});
const result = await route.handle(authorized(body()), {
projectId: 'project-1',
runId: 'source-run-1',
});
assert.deepEqual(result, {
statusCode: 503,
body: { code: 'copilot_failure_diagnosis_unavailable' },
});
}
});
test('maps internal failures to stable low-sensitive transport codes', async () => {
for (const [internal, statusCode, external] of [
[
'COPILOT_FAILURE_DIAGNOSIS_APPLICATION_CONFLICT',
409,
'copilot_failure_diagnosis_conflict',
],
[
'TRUSTED_TOOL_EXECUTION_POLICY_DENIED',
403,
'copilot_failure_diagnosis_forbidden',
],
[
'COPILOT_FAILURE_DIAGNOSIS_APPLICATION_BUSY',
429,
'copilot_failure_diagnosis_capacity_exceeded',
],
[
'COPILOT_MODEL_EGRESS_DENIED',
422,
'copilot_failure_diagnosis_policy_rejected',
],
[
'MODEL_INVOCATION_DEADLINE_EXCEEDED',
504,
'copilot_failure_diagnosis_deadline_exceeded',
],
['MODEL_INVOCATION_ABORTED', 408, 'copilot_failure_diagnosis_aborted'],
['PRIVATE_STORAGE_FAILURE', 503, 'copilot_failure_diagnosis_unavailable'],
]) {
const route = createClusterControlCopilotFailureDiagnosisRoute({
async execute() {
throw Object.assign(new Error('private internal detail'), {
code: internal,
});
},
});
const result = await route.handle(authorized(body()), {
projectId: 'project-1',
runId: 'source-run-1',
});
assert.equal(result.statusCode, statusCode, internal);
assert.deepEqual(result.body, { code: external });
assert.equal(JSON.stringify(result).includes('private'), false);
}
});
@@ -729,6 +729,7 @@ test('optionally exposes Prompt execution behind shared admission and policy', a
'prompt.execution.read',
'prompt.execution.output.read',
'prompt.output.read',
'copilot.failure_diagnosis.execute',
]);
const response = await invoke(
stack,
@@ -756,6 +757,134 @@ test('optionally exposes Prompt execution behind shared admission and policy', a
assert.equal(events.includes('audit:prompt.execute:allowed'), true);
});
test('optionally exposes Copilot diagnosis behind shared authentication, Policy and audit', async () => {
const { events, input } = fixture();
let command;
const capability = {
async execute(value) {
command = value;
events.push(`diagnose:${value.sourceRunId}`);
return {
admissionStatus: 'created',
admission: {
requestId: value.requestId,
runId: 'diagnosis-run-1',
sourceRunId: value.sourceRunId,
},
tool: { outcome: 'succeeded' },
model: {
outcome: 'succeeded',
output: {
artifactId: 'cdo:artifact-1',
artifactDigest: 'a'.repeat(64),
},
},
terminalization: null,
terminalizationRequired: false,
};
},
};
const stack = createProductionClusterControlApplicationStack(input, {
copilotFailureDiagnosis: { capability },
});
const result = await invoke(
stack,
metadata(
'/api/v3/projects/project-1/runs/run-1/copilot/failure-diagnoses',
'POST',
{
schema: 'qinglong/cluster-copilot-failure-diagnosis-request@v1',
traceId: 'trace-production-1',
},
),
);
assert.equal(result.statusCode, 201);
assert.equal(command.requestId, 'request-production-1');
assert.equal(command.projectId, 'project-1');
assert.equal(command.sourceRunId, 'run-1');
assert.equal(command.principal.subject.id, 'app-production');
assert.equal('policyFence' in command, false);
assert.deepEqual(events.slice(-4), [
'authenticate',
'authorize',
'audit:copilot.failure_diagnosis.execute:allowed',
'diagnose:run-1',
]);
});
test('keeps the Copilot route absent by default and never invokes it after Policy denial', async () => {
const defaultFixture = fixture();
const defaultStack = createProductionClusterControlApplicationStack(
defaultFixture.input,
);
const request = metadata(
'/api/v3/projects/project-1/runs/run-1/copilot/failure-diagnoses',
'POST',
{
schema: 'qinglong/cluster-copilot-failure-diagnosis-request@v1',
traceId: 'trace-production-1',
},
);
await assert.rejects(
defaultStack.admission.prepare(request),
(error) => error?.statusCode === 404 && error?.code === 'route_not_found',
);
let calls = 0;
const deniedFixture = fixture({
policies: {
async resolve() {
deniedFixture.events.push('authorize');
return {
project: {
id: 'project-1',
name: 'Denied Project',
slug: 'denied-project',
status: 'active',
version: 3,
createdAtMs: 1,
updatedAtMs: 2,
},
binding: {
projectId: 'project-1',
subject: { type: 'api_app', id: 'app-production' },
state: 'active',
role: 'viewer',
version: 7,
mutationId: 'binding-denied-1',
changedBy: { type: 'system', id: 'bootstrap' },
createdAtMs: 1,
},
};
},
},
});
const deniedStack = createProductionClusterControlApplicationStack(
deniedFixture.input,
{
copilotFailureDiagnosis: {
capability: {
async execute() {
calls += 1;
},
},
},
},
);
await assert.rejects(
deniedStack.admission.prepare(request),
(error) => error?.statusCode === 403 && error?.code === 'forbidden',
);
assert.equal(calls, 0);
assert.equal(
deniedFixture.events.includes(
'audit:copilot.failure_diagnosis.execute:denied',
),
true,
);
});
test('optionally exposes the redacted Prompt catalog behind shared admission and policy', async () => {
const { events, input } = fixture();
const stack = createProductionClusterControlApplicationStack(input, {