* feat(#247): runtime-neutral phase uat-passed predicate from HUMAN-UAT results Wire the already-reserved `phase.uat-passed` alias (subcommand `uat-passed`, mutation:false) into the phase command router with a new markdown-aware predicate that evaluates HUMAN-UAT results and reports pass only when every required check passes. Post-SDK-retirement (ADR-0174/#174) successor to the SDK-framed #70, with no SDK-specific API surface. New pure module src/uat-predicate.cts: - stripFalsePositiveContexts: frontmatter -> HTML-comment -> CommonMark-style fenced-block state machine (tracks delimiter char+length) -> blockquote, each a small composable step, so a `result: passed` inside frontmatter, a fenced/~~~ block (incl. ~~~ nested in a ``` fence), a comment, or a blockquote is never counted. - parseUatResultItems: heading-block parser, column-0-anchored same-line result; a heading with no result -> `missing` (fail-closed). - analyzeMarkdown: unterminated fence/comment detection (malformed -> blocker). - evaluateUatPassed: allowlist pass/verification semantics; passed = no blockers && >=1 check && all passing; no_uat_artifacts discriminator (no vacuous pass); optional requireVerification policy hook. Thin cmdPhaseUatPassed handler in phase.cts; router closure rejects unknown flags via makeInvalidArgs. Hardened across two Codex adversarial passes (vacuous pass, dropped failing tests, permissive verification status, nested-fence escape, cross-line result value, masked unterminated comment) — all fixed fail-closed. New unit + CLI-integration suites incl. a fast-check property test; docs, CONTEXT glossary, inventory, and changeset updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#247): backfill changeset PR number (#1063) * fix(#247): indexOf paired-scan for unterminated-comment detection CodeQL js/incomplete-multi-character-sanitization (high) flagged the `raw.replace(/<!--[\s\S]*?-->/g,'')`-then-`.includes('<!--')` detection in analyzeMarkdown as incomplete sanitization (a single regex pass can leave a residual `<!--`). Replace it with a paired left-to-right indexOf scan that contains no `.replace()` of the comment token — CodeQL-clean and strictly more correct (a closed earlier comment can never mask a later unterminated one). Behaviour unchanged; 98 predicate tests + scoped docker run green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ interface PhaseHandlers {
|
||||
cmdPhaseInsert: (cwd: string, pos: string | undefined, desc: string, raw: boolean) => void;
|
||||
cmdPhaseRemove: (cwd: string, phaseNum: string, opts: { force: boolean }, raw: boolean) => void;
|
||||
cmdPhaseComplete: (cwd: string, phaseNum: string | undefined, raw: boolean) => void;
|
||||
cmdPhaseUatPassed: (cwd: string, phaseNum: string | undefined, raw: boolean, opts?: { policy?: { requireVerification?: boolean } }) => void;
|
||||
}
|
||||
|
||||
interface RoutePhaseCommandOptions {
|
||||
@@ -164,6 +165,23 @@ function routePhaseCommand({ phase, args, cwd, raw, error }: RoutePhaseCommandOp
|
||||
phase.cmdPhaseComplete(cwd, args[2], raw);
|
||||
return { ok: true as const, data: null };
|
||||
},
|
||||
'uat-passed': (_ctx: Record<string, unknown>): { ok: true; data: null } => {
|
||||
let requireVerification = false;
|
||||
const positional: string[] = [];
|
||||
for (const token of args.slice(2)) {
|
||||
if (token === '--require-verification') {
|
||||
requireVerification = true;
|
||||
} else if (token === '--raw') {
|
||||
// --raw is handled by the outer CLI layer; accepted here silently
|
||||
} else if (token.startsWith('--')) {
|
||||
return makeInvalidArgs(token, `phase uat-passed does not support ${token}`) as never;
|
||||
} else {
|
||||
positional.push(token);
|
||||
}
|
||||
}
|
||||
phase.cmdPhaseUatPassed(cwd, positional[0], raw, { policy: { requireVerification } });
|
||||
return { ok: true as const, data: null };
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user