Merge pull request #3698 from Tibsfox/fix/allow-skipped-validation-completion

fix(gsd): allow milestone completion when validation skipped by preference
This commit is contained in:
Jeremy McSpadden 2026-04-07 06:56:41 -05:00 committed by GitHub
commit 627510695c
2 changed files with 44 additions and 1 deletions

View file

@ -693,6 +693,10 @@ export const DISPATCH_RULES: DispatchRule[] = [
if (validationPath) {
const validationContent = await loadFile(validationPath);
if (validationContent) {
// Allow completion when validation was intentionally skipped by
// preference/budget profile (#3399, #3344).
const skippedByPreference = /skip(?:ped)?[\s\-]+(?:by|per|due to)\s+(?:preference|budget|profile)/i.test(validationContent);
// Accept either the structured template format (table with MET/N/A/SATISFIED)
// or prose evidence patterns the validation agent may emit.
const structuredMatch =
@ -700,7 +704,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
(validationContent.includes("MET") || validationContent.includes("N/A") || validationContent.includes("SATISFIED"));
const proseMatch =
/[Oo]perational[\s\S]{0,500}?(?:✅|pass|verified|confirmed|met|complete|true|yes|addressed|covered|satisfied|partially|n\/a|not[\s-]+applicable)/i.test(validationContent);
const hasOperationalCheck = structuredMatch || proseMatch;
const hasOperationalCheck = skippedByPreference || structuredMatch || proseMatch;
if (!hasOperationalCheck) {
return {
action: "stop" as const,

View file

@ -0,0 +1,39 @@
/**
* Regression test for #3698 allow milestone completion when validation
* was skipped by preference
*
* When validation is skipped due to user preference (e.g. budget profile),
* auto-dispatch should recognize the "skipped by preference" pattern and
* allow completion instead of treating it as a missing validation.
*/
import { describe, test } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const autoDispatchSrc = readFileSync(
join(__dirname, '..', 'auto-dispatch.ts'),
'utf-8',
);
describe('skipped validation completion (#3698)', () => {
test('skippedByPreference regex detection exists', () => {
assert.match(autoDispatchSrc, /skippedByPreference/,
'skippedByPreference variable should exist in auto-dispatch.ts');
});
test('regex matches skip-by-preference patterns', () => {
assert.match(autoDispatchSrc, /skip\(\?:ped\)\?\[\\s\\-\]\+\(\?:by\|per\|due to\)/,
'should have regex matching "skipped by/per/due to" patterns');
});
test('skippedByPreference feeds into operational check', () => {
assert.match(autoDispatchSrc, /hasOperationalCheck\s*=\s*skippedByPreference/,
'skippedByPreference should be part of hasOperationalCheck');
});
});