docs: add next stage cicd dispatch matrix
This commit is contained in:
+104
-4
@@ -12,6 +12,7 @@ const defaultTasksLimit = 20;
|
||||
const maxTasksLimit = 100;
|
||||
const steerPromptPreviewChars = 320;
|
||||
const minimaxSubmitModel = "minimax-m2.7";
|
||||
const deepseekSubmitModel = "deepseek-chat";
|
||||
const gptSubmitModel = "gpt-5.5";
|
||||
const submitLockWaitMs = 60_000;
|
||||
const submitLockPollMs = 250;
|
||||
@@ -58,7 +59,7 @@ interface CodexSubmitOptions {
|
||||
dryRun: boolean;
|
||||
}
|
||||
|
||||
type SubmitRoute = "minimax-opencode" | "gpt-5.5-codex" | "commander-human-only";
|
||||
type SubmitRoute = "minimax-opencode" | "deepseek-codex" | "gpt-5.5-codex" | "commander-human-only";
|
||||
type SubmitRouteSignalSeverity = "info" | "warning" | "block";
|
||||
|
||||
interface SubmitRouteSignal {
|
||||
@@ -80,7 +81,9 @@ interface SubmitRoutingRecommendation {
|
||||
promptSelfContained: boolean;
|
||||
issueIsNotOnlySource: boolean;
|
||||
noProdRestartSecretOrDbWrite: boolean;
|
||||
noRuntimeCoreOrReleaseWork: boolean;
|
||||
evidenceRequiredByPrompt: boolean;
|
||||
mediumComplexityCandidate: boolean;
|
||||
commanderMustReviewUnread: true;
|
||||
};
|
||||
explicitRequest: {
|
||||
@@ -92,6 +95,27 @@ interface SubmitRoutingRecommendation {
|
||||
dryRunOnly: true;
|
||||
doesNotChangeSubmittedPayload: true;
|
||||
prodMiniMaxAssumedAvailable: false;
|
||||
prodDeepSeekAssumedAvailable: false;
|
||||
runtimeAdmissionUnchanged: true;
|
||||
};
|
||||
policyContract: {
|
||||
selectionPrinciples: string[];
|
||||
concurrency: {
|
||||
gpt55Routine: number;
|
||||
gpt55BurstMax: number;
|
||||
minimaxSimpleMax: number;
|
||||
deepseekMediumDefault: number;
|
||||
};
|
||||
modelTiers: Array<{
|
||||
model: string;
|
||||
runner: "opencode" | "codex";
|
||||
taskRisk: string;
|
||||
requiredGuards: string[];
|
||||
}>;
|
||||
externalProvider429: {
|
||||
commanderAction: string;
|
||||
interveneWhen: string[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -579,6 +603,7 @@ function normalizeSubmitModel(value: string | null | undefined): string {
|
||||
const lower = raw.toLowerCase();
|
||||
const leaf = lower.includes("/") ? lower.split("/").at(-1) ?? lower : lower;
|
||||
if (leaf === minimaxSubmitModel || leaf === "m2.7") return minimaxSubmitModel;
|
||||
if (leaf === deepseekSubmitModel || leaf === "deepseek") return deepseekSubmitModel;
|
||||
return raw;
|
||||
}
|
||||
|
||||
@@ -606,7 +631,7 @@ function regexEvidenceWithoutNegatedContext(text: string, patterns: RegExp[], li
|
||||
for (const match of text.matchAll(pattern)) {
|
||||
const index = match.index ?? 0;
|
||||
const context = text.slice(Math.max(0, index - 36), Math.min(text.length, index + String(match[0] ?? "").length + 36));
|
||||
if (/(?:禁止|不要|不得|不能|不应|请勿|严禁|avoid|forbid|forbidden|do not|don't|must not|no\s+)/iu.test(context)) continue;
|
||||
if (/(?:禁止|不要|不得|不能|不应|不触碰|不修改|不涉及|不处理|不更改|请勿|严禁|avoid|forbid|forbidden|do not|don't|must not|no\s+)/iu.test(context)) continue;
|
||||
const value = String(match[0] ?? "").trim().replace(/\s+/gu, " ");
|
||||
if (value.length > 0 && !evidence.includes(value)) evidence.push(value);
|
||||
if (evidence.length >= limit) return evidence;
|
||||
@@ -619,6 +644,47 @@ function routeSignal(id: string, severity: SubmitRouteSignalSeverity, evidence:
|
||||
return { id, severity, matched: evidence.length > 0, evidence, message };
|
||||
}
|
||||
|
||||
function submitPolicyContract(): SubmitRoutingRecommendation["policyContract"] {
|
||||
return {
|
||||
selectionPrinciples: [
|
||||
"Use GPT-5.5 for high-risk, runtime/core, security, CI/CD, deploy, release, and final quality calls.",
|
||||
"Use DeepSeek for self-contained medium-complexity work with limited write scope and verifiable tests.",
|
||||
"Use MiniMax only for simple, low-risk, self-contained work with external evidence and commander review.",
|
||||
"Keep prod restart, secret access, DB writes, destructive Git, and running-task control with the commander or human.",
|
||||
],
|
||||
concurrency: {
|
||||
gpt55Routine: 5,
|
||||
gpt55BurstMax: 10,
|
||||
minimaxSimpleMax: 10,
|
||||
deepseekMediumDefault: 5,
|
||||
},
|
||||
modelTiers: [
|
||||
{
|
||||
model: gptSubmitModel,
|
||||
runner: "codex",
|
||||
taskRisk: "high-risk-or-complex",
|
||||
requiredGuards: ["bounded ownership", "multi-signal verification", "no implicit prod rollout"],
|
||||
},
|
||||
{
|
||||
model: deepseekSubmitModel,
|
||||
runner: "codex",
|
||||
taskRisk: "medium-complexity",
|
||||
requiredGuards: ["self-contained prompt", "limited write scope", "contract/unit verification", "commander review"],
|
||||
},
|
||||
{
|
||||
model: minimaxSubmitModel,
|
||||
runner: "opencode",
|
||||
taskRisk: "simple-low-risk",
|
||||
requiredGuards: ["issue is auxiliary only", "evidence required", "no prod/secrets/DB writes", "diff and test review"],
|
||||
},
|
||||
],
|
||||
externalProvider429: {
|
||||
commanderAction: "wait-while-exponential-backoff-is-healthy",
|
||||
interveneWhen: ["heartbeat expired", "retry state machine stuck", "task lost", "retry attempts exhausted"],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRoutingRecommendation {
|
||||
const prompt = options.prompt;
|
||||
const lower = prompt.toLowerCase();
|
||||
@@ -633,7 +699,7 @@ function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRouting
|
||||
/\bsecret\b|\btoken\b|\bapi[_-]?key\b|\bcredential\b/gu,
|
||||
/\bpostgres(?:ql)?\b|\bpsql\b|\bdatabase\b|\bdb\b|\bsql\b|\bmigration\b/gu,
|
||||
]);
|
||||
const runtimeCore = regexEvidence(lower, [
|
||||
const runtimeCore = regexEvidenceWithoutNegatedContext(lower, [
|
||||
/\bcode[- ]queue\s+(?:runtime|scheduler|backend|execution|runner)\b/gu,
|
||||
/\bbackend-core\b/gu,
|
||||
/\bprovider-gateway\b/gu,
|
||||
@@ -672,6 +738,14 @@ function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRouting
|
||||
/文档/gu,
|
||||
/轻量/gu,
|
||||
]);
|
||||
const mediumComplexityEvidence = regexEvidence(lower, [
|
||||
/\bfront[- ]?end\b|\bfrontend\b|\breact\b|\btsx\b|\bcss\b|\bui\b|\bcomponent\b/gu,
|
||||
/\buser[- ]service\b|\bservice\s+module\b/gu,
|
||||
/\blocal\s+(?:module|helper|cli|tool)\b/gu,
|
||||
/\bbounded\s+(?:bug\s*)?fix\b|\bsmall\s+(?:bug\s*)?fix\b/gu,
|
||||
/\bunit\s+test\b|\bcontract\s+guard\b/gu,
|
||||
/中等复杂|中等风险|前端|组件|样式|局部(?:模块|修复)|用户服务|契约守卫/gu,
|
||||
]);
|
||||
const evidenceRequest = regexEvidence(lower, [
|
||||
/\bevidence\b/gu,
|
||||
/\bverification\b|\bverified\b|\bvalidate\b|\bvalidation\b/gu,
|
||||
@@ -699,7 +773,7 @@ function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRouting
|
||||
/\btruncate\s+table\b/gu,
|
||||
/\bdelete\s+from\b/gu,
|
||||
]);
|
||||
const crossModule = regexEvidence(lower, [
|
||||
const crossModule = regexEvidenceWithoutNegatedContext(lower, [
|
||||
/\bcross[- ]module\b/gu,
|
||||
/\barchitecture\b|\barchitectural\b/gu,
|
||||
/\brelease\/v1\b/gu,
|
||||
@@ -714,13 +788,21 @@ function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRouting
|
||||
const promptSelfContained = prompt.length >= 700 || selfContainedHints.length >= 3;
|
||||
const issueIsNotOnlySource = issueReference.length === 0 || issueAuxiliaryGuard.length > 0 || issueOnly.length === 0 && prompt.length >= 500;
|
||||
const noProdRestartSecretOrDbWrite = prodOrStateMutation.length === 0 && destructiveWords.length === 0;
|
||||
const noRuntimeCoreOrReleaseWork = runtimeCore.length === 0 && crossModule.length === 0;
|
||||
const evidenceRequiredByPrompt = evidenceRequest.length > 0;
|
||||
const mediumComplexityCandidate = promptSelfContained
|
||||
&& issueIsNotOnlySource
|
||||
&& noProdRestartSecretOrDbWrite
|
||||
&& noRuntimeCoreOrReleaseWork
|
||||
&& evidenceRequiredByPrompt
|
||||
&& mediumComplexityEvidence.length > 0;
|
||||
const signals = [
|
||||
routeSignal("prod-state-secret-db-write", "block", [...prodOrStateMutation, ...destructiveWords], "Mentions production/state mutation, restart, secrets, DB writes, or destructive commands."),
|
||||
routeSignal("runtime-core", "warning", runtimeCore, "Touches Code Queue runtime, backend-core, provider-gateway, k3s adapter, or active run behavior."),
|
||||
routeSignal("issue-source-risk", "warning", issueOnly, "Prompt appears to rely on GitHub issue reading as task context."),
|
||||
routeSignal("issue-auxiliary-source-guard", "info", issueAuxiliaryGuard, "Prompt explicitly says GitHub issue is auxiliary and not the only source."),
|
||||
routeSignal("cross-module-release", "warning", crossModule, "Mentions cross-module architecture, CI/CD rollout, release line, or rollback work."),
|
||||
routeSignal("medium-complexity-verifiable", "info", mediumComplexityEvidence, "Mentions bounded medium-complexity work such as frontend, local CLI/helper, user-service module, or contract guard changes."),
|
||||
routeSignal("low-risk-verifiable", "info", lowRiskEvidence, "Mentions low-risk or verifiable work such as docs, read-only checks, dry-run, preflight, or contract tests."),
|
||||
routeSignal("evidence-requested", "info", evidenceRequest, "Prompt asks for tests, validation, commit, or evidence."),
|
||||
routeSignal("self-contained-hints", "info", selfContainedHints, "Prompt includes explicit task sections that make it easier to verify without reading an issue."),
|
||||
@@ -742,6 +824,18 @@ function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRouting
|
||||
route = "gpt-5.5-codex";
|
||||
confidence = "high";
|
||||
reason = "This task touches runtime/core/cross-module or release-governance surfaces, so it should stay on GPT-5.5.";
|
||||
} else if (mediumComplexityCandidate) {
|
||||
route = "deepseek-codex";
|
||||
recommendedRunner = "codex";
|
||||
recommendedModel = deepseekSubmitModel;
|
||||
confidence = "high";
|
||||
reason = "The prompt looks self-contained, medium-complexity, and verifiable without production/state privileges; it is a DeepSeek/Codex candidate after commander review.";
|
||||
} else if (mediumComplexityEvidence.length > 0 && issueIsNotOnlySource && noProdRestartSecretOrDbWrite && noRuntimeCoreOrReleaseWork) {
|
||||
route = "deepseek-codex";
|
||||
recommendedRunner = "codex";
|
||||
recommendedModel = deepseekSubmitModel;
|
||||
confidence = "medium";
|
||||
reason = "The prompt has medium-complexity signals, but the commander should tighten self-contained context, write scope, and verification requirements before relying on DeepSeek.";
|
||||
} else if (promptSelfContained && issueIsNotOnlySource && evidenceRequiredByPrompt && lowRiskEvidence.length > 0) {
|
||||
route = "minimax-opencode";
|
||||
recommendedRunner = "opencode";
|
||||
@@ -773,7 +867,9 @@ function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRouting
|
||||
promptSelfContained,
|
||||
issueIsNotOnlySource,
|
||||
noProdRestartSecretOrDbWrite,
|
||||
noRuntimeCoreOrReleaseWork,
|
||||
evidenceRequiredByPrompt,
|
||||
mediumComplexityCandidate,
|
||||
commanderMustReviewUnread: true,
|
||||
},
|
||||
explicitRequest: {
|
||||
@@ -785,7 +881,10 @@ function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRouting
|
||||
dryRunOnly: true,
|
||||
doesNotChangeSubmittedPayload: true,
|
||||
prodMiniMaxAssumedAvailable: false,
|
||||
prodDeepSeekAssumedAvailable: false,
|
||||
runtimeAdmissionUnchanged: true,
|
||||
},
|
||||
policyContract: submitPolicyContract(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2495,6 +2594,7 @@ function codexSubmitTask(args: string[]): unknown {
|
||||
commands: {
|
||||
submitAsRequested: "remove --dry-run to submit exactly this payload",
|
||||
minimaxCandidate: `bun scripts/cli.ts codex submit --prompt-file <path> --model ${minimaxSubmitModel} --dry-run`,
|
||||
deepseekCandidate: `bun scripts/cli.ts codex submit --prompt-file <path> --model ${deepseekSubmitModel} --dry-run`,
|
||||
gptCandidate: `bun scripts/cli.ts codex submit --prompt-file <path> --model ${gptSubmitModel} --dry-run`,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user