fix: 将调度重试归为基础设施进展

This commit is contained in:
root
2026-07-12 18:42:18 +02:00
parent 2ae4b891dc
commit 08f0cb8bc9
2 changed files with 23 additions and 1 deletions
+1 -1
View File
@@ -976,7 +976,7 @@ function hasNoBusinessProgress(run: RunRecord, command: CommandRecord, commands:
if (isoMs(run.createdAt) > cutoff || isoMs(command.createdAt) > cutoff) return false;
if (commands.length !== 1 || commands[0]?.id !== command.id) return false;
if (events.length === 0 || events.length >= 500) return false;
const allowedPhases = new Set(["run-created", "command-created", "runner-job-created", "runner-dispatch-completed"]);
const allowedPhases = new Set(["run-created", "command-created", "runner-dispatch-retry", "runner-job-created", "runner-dispatch-completed"]);
const userMessages = events.filter((event) => event.type === "user_message");
if (userMessages.length > 1) return false;
const phases = events.flatMap((event) => {
@@ -120,6 +120,7 @@ const selfTest: SelfTestCase = async (context) => {
try {
await assertTwentyStalePendingSelectsOnlyOldest({ fixturePath, statePath, kubectlCommand });
await assertLegacyNoUserMessageCandidate({ fixturePath, statePath, kubectlCommand });
await assertDispatchRetryIsInfrastructureProgress({ fixturePath, statePath, kubectlCommand });
await assertEventOnlyFailedMountCandidate({ fixturePath, statePath, kubectlCommand });
await assertTerminalClaimDriftCandidate({ fixturePath, statePath, kubectlCommand });
await assertTerminalCommandClaimDriftCandidate({ fixturePath, statePath, kubectlCommand });
@@ -155,6 +156,7 @@ const selfTest: SelfTestCase = async (context) => {
"stale-pending-typed-candidate",
"formal-user-message-is-not-runner-progress",
"legacy-no-user-message-candidate",
"dispatch-retry-is-not-business-progress",
"user-message-command-binding-protected",
"incoming-selects-only-oldest",
"no-incoming-does-not-delete",
@@ -320,6 +322,26 @@ async function assertLegacyNoUserMessageCandidate(input: { fixturePath: string;
assert.equal(firstSummary(summary, "selected").candidateKind, "stale-pending");
}
async function assertDispatchRetryIsInfrastructureProgress(input: { fixturePath: string; statePath: string; kubectlCommand: string }): Promise<void> {
const fact = pendingFact(108, new Date(Date.now() - 60 * 60_000).toISOString());
fact.events.splice(3, 0, runEvent(fact.run.id, 4, fact.run.createdAt, "backend_status", {
phase: "runner-dispatch-retry",
commandId: fact.command.id,
reason: "runner retention retry self-test",
valuesPrinted: false,
}));
fact.events = fact.events.map((event, index) => ({ ...event, id: `evt-${fact.run.id}-${index + 1}`, seq: index + 1 }));
await writeFixture(input, {
jobs: [runnerJob(fact, 108)],
pods: [runnerPod(fact, 108, "failed-config")],
});
const summary = await enforceRunnerRetentionBeforeCreate({ store: new RetentionFactStore([fact]), options: retentionOptions(input.kubectlCommand, 1), incomingRunnerCount: 0 });
assert.equal(summary.inactiveCandidateCount, 1);
const candidate = firstSummary(summary, "inactiveCandidates");
assert.equal(candidate.candidateKind, "stale-pending");
assert.equal(candidate.classificationReason, "stale-pending-no-business-progress");
}
async function assertEventOnlyFailedMountCandidate(input: { fixturePath: string; statePath: string; kubectlCommand: string }): Promise<void> {
const fact = pendingFact(90, new Date(Date.now() - 60 * 60_000).toISOString());
const fixture = {