diff --git a/prompts/napcat/remote-dev-handoff.md b/prompts/napcat/remote-dev-handoff.md new file mode 100644 index 0000000..b899d0d --- /dev/null +++ b/prompts/napcat/remote-dev-handoff.md @@ -0,0 +1,41 @@ +# NapCat Remote Dev Handoff + +You are summarizing a supplied remote development context packet for the next human-controlled step. + +Do not edit files. +Do not run merge, commit, push, deploy, or Docker mutation commands. +Use only the supplied context packet. +Return JSON that matches the requested schema. + +## Handoff Scope + +Summarize only packet evidence for: + +- repository branches and dirty status +- artifact directories and notable generated outputs +- Jenkins status, build numbers, commit/image pointers, and unknown deployment state +- blockers, missing evidence, or unsafe assumptions +- safe next commands that are read-only or dry-run oriented + +Do not ask Codex to modify files. Do not include merge, commit, push, deploy, Docker mutation, or destructive cleanup commands as next commands. + +## Requested Schema + +Return only this JSON object: + +```json +{ + "repoStates": [ + { + "repo": "Repository path or label.", + "branch": "Current branch or unknown.", + "dirtyStatus": "clean | dirty | unknown", + "head": "Commit hash or unknown." + } + ], + "artifactDirectories": ["Artifact directory or missing evidence note."], + "jenkinsStatus": "Jenkins status summary or missing evidence note.", + "blockers": ["Blocker or missing evidence note."], + "safeNextCommands": ["Read-only or dry-run command."] +} +``` diff --git a/prompts/napcat/runtime-release-readiness.md b/prompts/napcat/runtime-release-readiness.md new file mode 100644 index 0000000..103764c --- /dev/null +++ b/prompts/napcat/runtime-release-readiness.md @@ -0,0 +1,34 @@ +# NapCat Runtime Release Readiness + +You are reviewing a supplied NapCat runtime release packet before a human promotes an image/profile into the API runtime. + +Do not edit files. +Do not run merge, commit, push, deploy, or Docker mutation commands. +Use only the supplied context packet. +Return JSON that matches the requested schema. + +## Readiness Checks + +Base every section on packet evidence: + +- source validation: branch, commit, upstream base, fork patch marker, and dirty status +- image validation: image tag, image inspect/build evidence, marker evidence, and runtime asset presence +- API promotion readiness: explicit image/profile values, configuration alignment, and Jenkins/API promotion prerequisites +- online smoke readiness: QQBot/NapCat login, WebUI, command smoke, and rollback smoke expectations +- rollback pointer: last known good branch, commit, image tag, profile, and API runtime values + +If any section lacks evidence, state the missing evidence plainly. + +## Requested Schema + +Return only this JSON object: + +```json +{ + "sourceValidation": "Evidence-backed source validation status.", + "imageValidation": "Evidence-backed image validation status.", + "apiPromotionReadiness": "Evidence-backed API promotion readiness status.", + "onlineSmokeReadiness": "Evidence-backed online smoke readiness status.", + "rollbackPointer": "Specific rollback pointer or the missing evidence needed to name one." +} +``` diff --git a/prompts/napcat/sync-candidate-review.md b/prompts/napcat/sync-candidate-review.md new file mode 100644 index 0000000..a0408ca --- /dev/null +++ b/prompts/napcat/sync-candidate-review.md @@ -0,0 +1,43 @@ +# NapCat Sync Candidate Review + +You are reviewing a supplied NapCat candidate branch context packet before a human decides whether to continue the sync. + +Do not edit files. +Do not run merge, commit, push, deploy, or Docker mutation commands. +Use only the supplied context packet. +Return JSON that matches the requested schema. + +## Review Scope + +Review only evidence present in the packet. Cover these areas: + +- login service reset behavior and stale native login service state +- QR refresh, stale QR prevention, QR expiry, and scan confirmation state +- WebUI login runtime state, reconciled QQ online state, and false online signals +- captcha and new-device boundaries, including pending state preservation +- package, shell, framework, webui build output, and runtime asset layout +- test gaps, missing smoke evidence, and unverified online behavior + +## Finding Rules + +Flag only actionable risks grounded in packet evidence. If evidence is missing, report it as a test gap or blocked review item instead of guessing. + +## Requested Schema + +Return only this JSON object: + +```json +{ + "decision": "approve | manual-review | block", + "summary": "Short review summary.", + "findings": [ + { + "severity": "critical | important | minor", + "area": "login-reset | qr-refresh | webui-runtime | captcha-new-device | package-build | test-gap", + "evidence": "Packet evidence for the finding.", + "requiredAction": "Human-readable action before promotion." + } + ], + "testGaps": ["Missing validation evidence."] +} +``` diff --git a/prompts/napcat/upstream-audit.md b/prompts/napcat/upstream-audit.md new file mode 100644 index 0000000..e129bb4 --- /dev/null +++ b/prompts/napcat/upstream-audit.md @@ -0,0 +1,53 @@ +# NapCat Upstream Audit + +You are reviewing a supplied NapCat upstream release context packet for KT automation. Decide whether the upstream release can become a candidate branch, needs manual review, or is blocked. + +Do not edit files. +Do not run merge, commit, push, deploy, or Docker mutation commands. +Use only the supplied context packet. +Return JSON that matches the requested schema. + +## Inputs + +Use the packet sections for upstream release metadata, fork patch range, changed files, dry-merge result, build graph diff, and Codex parser status. Treat missing packet sections as unavailable metadata. + +## Classification Rules + +Choose exactly one `classification`: + +- `safe-candidate`: no upstream change exists, or upstream changes are outside hot zones, do not overlap fork patches, dry merge is clean, build graph is stable, and metadata is available. +- `manual-review`: upstream changed login/runtime/build-adjacent areas or fork-adjacent code, but the packet does not prove a hard blocker. +- `blocked`: dry merge conflicts, build graph changes that require maintainer action, missing required metadata, or invalid Codex output schema. + +Use one or more `reasonCodes` from this exact list: + +- `NO_UPSTREAM_CHANGE` +- `HOT_ZONE_CHANGED` +- `FORK_PATCH_OVERLAP` +- `DRY_MERGE_CONFLICT` +- `BUILD_GRAPH_CHANGED` +- `METADATA_UNAVAILABLE` +- `CODEX_SCHEMA_INVALID` + +## Hot Zones + +Treat these as NapCat login/runtime hot zones: + +- login service reset and native login service state +- QR refresh, stale QR, QR expiry, and scan confirmation state +- WebUI login runtime state and reconciled QQ online state +- captcha and new-device verification boundaries +- package, shell, framework, webui build graph or output layout + +## Requested Schema + +Return only this JSON object: + +```json +{ + "classification": "safe-candidate | manual-review | blocked", + "reasonCodes": ["NO_UPSTREAM_CHANGE"], + "recommendedAction": "no-op | create-candidate-branch | request-human-review | block", + "summary": "Short evidence-based decision." +} +``` diff --git a/src/selfTest.ts b/src/selfTest.ts index be6012c..d7f653e 100644 --- a/src/selfTest.ts +++ b/src/selfTest.ts @@ -40,6 +40,10 @@ import { parseNapcatAutomationClassification, upstreamAuditOutputSchema, } from "./tools/napcatAutomation.types.js"; +import { + loadNapcatAutomationPrompt, + napcatAutomationPromptNames, +} from "./tools/napcatAutomation.prompts.js"; import { buildBusinessTestPlan, buildNapcatDeviceProfileCheck, @@ -89,6 +93,12 @@ export async function runSelfTest(): Promise { if (parseNapcatAutomationClassification("manual-review") !== "manual-review") { throw new Error("NapCat classification parser self-check failed"); } + for (const promptName of napcatAutomationPromptNames) { + const promptText = loadNapcatAutomationPrompt(promptName); + if (!promptText.includes("Do not edit files")) { + throw new Error(`NapCat prompt safety contract missing: ${promptName}`); + } + } const reviewClassifier = { localizedSecretLabelAllowed: isBenignCredentialReviewValue("密钥"), diff --git a/src/tools/napcatAutomation.prompts.ts b/src/tools/napcatAutomation.prompts.ts new file mode 100644 index 0000000..d6b1179 --- /dev/null +++ b/src/tools/napcatAutomation.prompts.ts @@ -0,0 +1,30 @@ +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +export const napcatAutomationPromptNames = [ + 'upstream-audit', + 'sync-candidate-review', + 'runtime-release-readiness', + 'remote-dev-handoff', +] as const; + +export type NapcatAutomationPromptName = + (typeof napcatAutomationPromptNames)[number]; + +const promptsRoot = path.resolve( + fileURLToPath(new URL('../..', import.meta.url)), + 'prompts', + 'napcat', +); + +/** + * Loads a source-controlled NapCat automation prompt by stable prompt name. + * @param name - Prompt identifier from `napcatAutomationPromptNames`; because it is an enum value rather than a user-supplied path, callers cannot escape `prompts/napcat`. + * @returns UTF-8 prompt text used by Codex CLI automation. + */ +export function loadNapcatAutomationPrompt( + name: NapcatAutomationPromptName, +): string { + return readFileSync(path.join(promptsRoot, `${name}.md`), 'utf8'); +}