feat: 定义NapCat自动化审计契约
This commit is contained in:
parent
32d02b5a8f
commit
efc6f50199
34
prompts/napcat/schemas/runtime-release-readiness.schema.json
Normal file
34
prompts/napcat/schemas/runtime-release-readiness.schema.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"sourceValidation",
|
||||
"imageValidation",
|
||||
"apiPromotionReadiness",
|
||||
"onlineSmokeReadiness",
|
||||
"rollbackPointer"
|
||||
],
|
||||
"properties": {
|
||||
"sourceValidation": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"imageValidation": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"apiPromotionReadiness": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"onlineSmokeReadiness": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"rollbackPointer": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
33
prompts/napcat/schemas/upstream-audit.schema.json
Normal file
33
prompts/napcat/schemas/upstream-audit.schema.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["classification", "reasonCodes", "recommendedAction", "summary"],
|
||||
"properties": {
|
||||
"classification": {
|
||||
"enum": ["safe-candidate", "manual-review", "blocked"]
|
||||
},
|
||||
"reasonCodes": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"enum": [
|
||||
"NO_UPSTREAM_CHANGE",
|
||||
"HOT_ZONE_CHANGED",
|
||||
"FORK_PATCH_OVERLAP",
|
||||
"DRY_MERGE_CONFLICT",
|
||||
"BUILD_GRAPH_CHANGED",
|
||||
"METADATA_UNAVAILABLE",
|
||||
"CODEX_SCHEMA_INVALID"
|
||||
]
|
||||
}
|
||||
},
|
||||
"recommendedAction": {
|
||||
"enum": ["no-op", "create-candidate-branch", "request-human-review", "block"]
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,11 @@ import {
|
||||
findTaskRecordGovernanceFindings,
|
||||
isBenignCredentialReviewValue,
|
||||
} from "./tools/review.js";
|
||||
import {
|
||||
napcatAutomationReasonCodes,
|
||||
parseNapcatAutomationClassification,
|
||||
upstreamAuditOutputSchema,
|
||||
} from "./tools/napcatAutomation.types.js";
|
||||
import {
|
||||
buildBusinessTestPlan,
|
||||
buildNapcatDeviceProfileCheck,
|
||||
@ -54,7 +59,27 @@ import {
|
||||
buildPushPlan,
|
||||
buildRemoteHealthCheck,
|
||||
} from "./tools/workflow.js";
|
||||
/**
|
||||
* Runs ktWorkflow guardrail smoke checks from the CLI self-test entry; writes local evidence under the KT workspace and throws on any broken workflow contract.
|
||||
* @returns A promise that resolves after all contract checks and evidence writing complete.
|
||||
*/
|
||||
export async function runSelfTest(): Promise<void> {
|
||||
const napcatAuditSchemaSmoke = upstreamAuditOutputSchema.safeParse({
|
||||
classification: "manual-review",
|
||||
reasonCodes: ["HOT_ZONE_CHANGED"],
|
||||
recommendedAction: "request-human-review",
|
||||
summary: "Login hot-zone changed.",
|
||||
});
|
||||
if (!napcatAuditSchemaSmoke.success) {
|
||||
throw new Error("NapCat upstream audit schema self-check failed");
|
||||
}
|
||||
if (!napcatAutomationReasonCodes.includes("HOT_ZONE_CHANGED")) {
|
||||
throw new Error("NapCat reason-code list self-check failed");
|
||||
}
|
||||
if (parseNapcatAutomationClassification("manual-review") !== "manual-review") {
|
||||
throw new Error("NapCat classification parser self-check failed");
|
||||
}
|
||||
|
||||
const reviewClassifier = {
|
||||
localizedSecretLabelAllowed: isBenignCredentialReviewValue("密钥"),
|
||||
realTokenRejected: !isBenignCredentialReviewValue(
|
||||
|
||||
72
src/tools/napcatAutomation.types.ts
Normal file
72
src/tools/napcatAutomation.types.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const napcatAutomationClassifications = [
|
||||
'safe-candidate',
|
||||
'manual-review',
|
||||
'blocked',
|
||||
] as const;
|
||||
|
||||
export const napcatAutomationReasonCodes = [
|
||||
'NO_UPSTREAM_CHANGE',
|
||||
'HOT_ZONE_CHANGED',
|
||||
'FORK_PATCH_OVERLAP',
|
||||
'DRY_MERGE_CONFLICT',
|
||||
'BUILD_GRAPH_CHANGED',
|
||||
'METADATA_UNAVAILABLE',
|
||||
'CODEX_SCHEMA_INVALID',
|
||||
] as const;
|
||||
|
||||
export const upstreamAuditOutputSchema = z.object({
|
||||
classification: z.enum(napcatAutomationClassifications),
|
||||
reasonCodes: z.array(z.enum(napcatAutomationReasonCodes)).min(1),
|
||||
recommendedAction: z.enum([
|
||||
'no-op',
|
||||
'create-candidate-branch',
|
||||
'request-human-review',
|
||||
'block',
|
||||
]),
|
||||
summary: z.string().min(1),
|
||||
});
|
||||
|
||||
export type NapcatAutomationClassification =
|
||||
(typeof napcatAutomationClassifications)[number];
|
||||
|
||||
export interface NapcatUpstreamAuditInput {
|
||||
artifactRoot?: string;
|
||||
createCandidateBranch?: boolean;
|
||||
execute?: boolean;
|
||||
forkBranch?: string;
|
||||
forkRepo?: string;
|
||||
lastAcceptedUpstreamBase?: string;
|
||||
upstreamReleaseTag?: string;
|
||||
upstreamRepo?: string;
|
||||
useCodex?: boolean;
|
||||
}
|
||||
|
||||
export interface NapcatAutomationArtifact {
|
||||
path: string;
|
||||
type: 'context' | 'json' | 'jsonl' | 'markdown' | 'script';
|
||||
}
|
||||
|
||||
export interface NapcatAutomationResult {
|
||||
artifacts: NapcatAutomationArtifact[];
|
||||
classification: NapcatAutomationClassification;
|
||||
execute: boolean;
|
||||
recommendedAction: string;
|
||||
summary: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the upstream audit classification emitted by deterministic collectors or Codex.
|
||||
* @param value - Raw classification string from deterministic audit metadata or Codex JSON output; must match the shared NapCat automation taxonomy.
|
||||
* @returns A supported NapCat automation classification for downstream workflow decisions.
|
||||
*/
|
||||
export function parseNapcatAutomationClassification(
|
||||
value: string,
|
||||
): NapcatAutomationClassification {
|
||||
const parsed = z.enum(napcatAutomationClassifications).safeParse(value);
|
||||
if (!parsed.success) {
|
||||
throw new Error(`Unsupported NapCat audit classification: ${value}`);
|
||||
}
|
||||
return parsed.data;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user