refactor: 리펙토링

This commit is contained in:
DongHyeonka
2026-08-01 19:39:59 +09:00
parent 9c959ea2a5
commit c6da03369c
171 changed files with 20329 additions and 782 deletions
+48 -1
View File
@@ -71,6 +71,45 @@ for (const [gateId, gate] of Object.entries(document.gates)) {
if (!gate.steps?.length || !gate.evidence?.length || !gate.retentionClass) {
failures.push(`${gateId} lacks command, evidence, or retention wiring`);
}
for (const [index, step] of (gate.steps ?? []).entries()) {
if (!isRecord(step) || (step.expect !== "pass" && step.expect !== "fail")) {
failures.push(`${gateId}[${index}] has an invalid step expectation`);
continue;
}
if (step.expect === "pass") {
if (
step.expectedExitCode !== undefined ||
step.expectedDiagnosticId !== undefined
) {
failures.push(
`${gateId}[${index}] passing step declares a negative fixture identity`,
);
}
continue;
}
if (
typeof step.expectedExitCode !== "number" ||
!Number.isSafeInteger(step.expectedExitCode) ||
step.expectedExitCode < 1 ||
step.expectedExitCode > 255
) {
failures.push(`${gateId}[${index}] lacks an exact expected exit code`);
}
const diagnosticId = step.expectedDiagnosticId;
if (
typeof diagnosticId !== "string" ||
diagnosticId.trim().length === 0 ||
diagnosticId.length > 256 ||
["\r", "\n", "\0"].some(
(character) =>
typeof diagnosticId === "string" && diagnosticId.includes(character),
)
) {
failures.push(
`${gateId}[${index}] lacks a bounded expected diagnostic identity`,
);
}
}
}
const runbookGateEvidence = Object.freeze({
@@ -107,7 +146,6 @@ if (
const forbiddenWorkflowPatterns = [
/continue-on-error\s*:/,
/retention-days\s*:/,
/timeout-minutes\s*:/,
/allow_failure\s*:/,
];
for (const pattern of forbiddenWorkflowPatterns) {
@@ -115,6 +153,13 @@ for (const pattern of forbiddenWorkflowPatterns) {
failures.push(`workflow contains forbidden downgrade/unsupported setting ${pattern}`);
}
}
const jobTimeoutCount = workflow.match(/timeout-minutes:\s*45/g)?.length ?? 0;
if (jobTimeoutCount !== 5) {
failures.push("every CI gate job must declare timeout-minutes: 45");
}
if (/if-no-files-found:\s*warn/.test(workflow)) {
failures.push("CI evidence upload must fail when artifacts are absent");
}
for (const requiredToken of [
"merge_gate:",
"release_gate:",
@@ -144,6 +189,8 @@ for (const requiredToken of [
"SOURCE_DATE_EPOCH",
'"--format=%H%n%ct"',
"env: gateEnvironment",
"classifyGateStepResult",
"timeout: step.timeoutMs ?? DEFAULT_STEP_TIMEOUT_MS",
]) {
if (!gateRunner.includes(requiredToken)) {
failures.push(`CI gate runner missing ${requiredToken}`);