test(evals): plan-design-with-ui focus-title rule accepts the comma-less 'dimensions or focus' wording (replayed on the captured CI run, negative controls kept)

This commit is contained in:
garrytan committed 2026-10-03 03:16:50 +00:00
1 parent 987a937b12
commit bc57ca5571
3 files changed
+198 -4

No files matched your search

+185
View File
@@ -0,0 +1,185 @@
{
"provenance": {
"kind": "public native AskUserQuestion calls and answers only (observation.json transcript.calls, byte-exact)",
"runId": 37091743395,
"artifact": "paid-slice-8-a1",
"headSha": "987a937b126d8465d3eddfd73dd18297311c1114",
"testName": "reviews the supplied UI plan through an acknowledged Design finding",
"cliVersion": "2.1.284",
"recordedOutcome": "ceiling_reached",
"recordedReviewCount": 1,
"recordedStep0Count": 4,
"recordedPassed": false,
"note": "The Step 0D focus question was titled 'Review all 7 design dimensions or focus on specific areas?' (no comma); the runner reached the review ceiling on Issue 1 but the focus predicate rejected the title, so the gate failed."
},
"calls": [
{
"preReview": true,
"observedAtMs": 66323,
"call": {
"sessionId": "b7d9de19-26a2-4d99-a3cb-6327a36fb8fb",
"toolUseId": "toolu_01BPAMZE1XNsn7QXv7s8jJWV",
"questions": [
{
"question": "D1 — Add gstack skill routing rules to this project's CLAUDE.md?\nProject/branch/task: gstack-plan-count-aX3JRn on main, starting the design review of the User Dashboard plan.\nELI10: gstack works best when your project's CLAUDE.md includes skill routing rules. Routing rules tell Claude which gstack skill to invoke when you ask for things like a bug fix, a review, or a ship. Without them you invoke skills by name each time.\nStakes if we pick wrong: Nothing breaks either way; you just get fewer automatic skill suggestions. Note: plan mode is active, so if you say yes the CLAUDE.md edit and commit happen after plan mode ends.\nRecommendation: A because routing rules are a one-time append with no runtime cost.\nNote: options differ in kind, not coverage — no completeness score.\nPros / cons:\nA) Add routing rules to CLAUDE.md (recommended)\n ✅ Requests like 'review this diff' or 'ship it' route to the right skill automatically\n ✅ One-time append, committed once, never asked again for this project\n ❌ Adds a short section to CLAUDE.md that you may need to keep in sync with the skill list\nB) No thanks, I'll invoke skills manually\n ✅ CLAUDE.md stays exactly as the fixture seeded it\n ✅ Full manual control over when a skill runs\n ❌ You type skill names yourself and lose proactive suggestions\nNet: a small convenience append versus a pristine CLAUDE.md.",
"header": "Routing",
"multiSelect": false,
"options": [
{
"label": "Add routing rules to CLAUDE.md (recommended)",
"description": "✅ Requests route to the right gstack skill automatically. ✅ One-time append, asked once per project. ❌ Adds a section to CLAUDE.md to keep in sync."
},
{
"label": "No thanks, I'll invoke skills manually",
"description": "✅ CLAUDE.md stays untouched. ✅ Full manual control over skill invocation. ❌ You type skill names yourself and lose proactive suggestions."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D1 — Add gstack skill routing rules to this project's CLAUDE.md?\nProject/branch/task: gstack-plan-count-aX3JRn on main, starting the design review of the User Dashboard plan.\nELI10: gstack works best when your project's CLAUDE.md includes skill routing rules. Routing rules tell Claude which gstack skill to invoke when you ask for things like a bug fix, a review, or a ship. Without them you invoke skills by name each time.\nStakes if we pick wrong: Nothing breaks either way; you just get fewer automatic skill suggestions. Note: plan mode is active, so if you say yes the CLAUDE.md edit and commit happen after plan mode ends.\nRecommendation: A because routing rules are a one-time append with no runtime cost.\nNote: options differ in kind, not coverage — no completeness score.\nPros / cons:\nA) Add routing rules to CLAUDE.md (recommended)\n ✅ Requests like 'review this diff' or 'ship it' route to the right skill automatically\n ✅ One-time append, committed once, never asked again for this project\n ❌ Adds a short section to CLAUDE.md that you may need to keep in sync with the skill list\nB) No thanks, I'll invoke skills manually\n ✅ CLAUDE.md stays exactly as the fixture seeded it\n ✅ Full manual control over when a skill runs\n ❌ You type skill names yourself and lose proactive suggestions\nNet: a small convenience append versus a pristine CLAUDE.md.": "Add routing rules to CLAUDE.md (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-10-03T03:06:01.424Z"
}
},
{
"preReview": true,
"observedAtMs": 111074,
"call": {
"sessionId": "b7d9de19-26a2-4d99-a3cb-6327a36fb8fb",
"toolUseId": "toolu_01KffPWJwJskvFZjJkFWsGc4",
"questions": [
{
"question": "D2 — Review all 7 design dimensions or focus on specific areas?\nProject/branch/task: gstack-plan-count-aX3JRn on main, design review of the User Dashboard Page plan.\nELI10: I've rated this plan 4/10 on design completeness. The biggest gaps are hierarchy (no reading order across the three panels), state design (empty/modal/toast are named but not designed), and responsive/wayfinding (breakpoints only, no mobile layout, no page header). I'll generate visual mockups next, then review all 7 dimensions. Want me to focus on specific areas instead of all 7?\nStakes if we pick wrong: Narrowing skips passes where real gaps hide; going wide costs a few more decision questions.\nRecommendation: A because a 4/10 plan has gaps in every dimension and the full pass is the complete review.\nCompleteness: A=10/10, B=6/10, C=5/10\nPros / cons:\nA) All 7 dimensions (recommended)\n ✅ Every gap gets rated, explained, and resolved with its own decision\n ✅ The plan leaves with no unspecified state, layout, or interaction\n ❌ More decision questions; roughly 10-15 stops before the report\nB) Focus: interaction states + information architecture\n ✅ Hits the two largest gaps first: state design and panel hierarchy\n ✅ Fewer stops; quicker path to a usable plan\n ❌ Responsive, journey, a11y and slop risk stay unreviewed and unrated\nC) Focus: user journey + accessibility\n ✅ Covers login landing, wayfinding, modal/toast a11y end to end\n ✅ Good fit if the visual layout is already decided elsewhere\n ❌ Hierarchy, item anatomy and empty-state design stay as they are\nNet: full rigor on a thin plan versus a faster, narrower pass.",
"header": "Focus",
"multiSelect": false,
"options": [
{
"label": "All 7 dimensions (recommended)",
"description": "✅ Every gap rated, explained, resolved individually. ✅ No unspecified state or layout left. ❌ More decision stops before the report."
},
{
"label": "Focus: states + IA",
"description": "✅ Hits state design and panel hierarchy first. ✅ Fewer stops. ❌ Responsive, journey, a11y, slop risk stay unreviewed."
},
{
"label": "Focus: journey + a11y",
"description": "✅ Covers landing, wayfinding, modal/toast a11y end to end. ✅ Fits if layout is decided elsewhere. ❌ Hierarchy and empty states stay as-is."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D2 — Review all 7 design dimensions or focus on specific areas?\nProject/branch/task: gstack-plan-count-aX3JRn on main, design review of the User Dashboard Page plan.\nELI10: I've rated this plan 4/10 on design completeness. The biggest gaps are hierarchy (no reading order across the three panels), state design (empty/modal/toast are named but not designed), and responsive/wayfinding (breakpoints only, no mobile layout, no page header). I'll generate visual mockups next, then review all 7 dimensions. Want me to focus on specific areas instead of all 7?\nStakes if we pick wrong: Narrowing skips passes where real gaps hide; going wide costs a few more decision questions.\nRecommendation: A because a 4/10 plan has gaps in every dimension and the full pass is the complete review.\nCompleteness: A=10/10, B=6/10, C=5/10\nPros / cons:\nA) All 7 dimensions (recommended)\n ✅ Every gap gets rated, explained, and resolved with its own decision\n ✅ The plan leaves with no unspecified state, layout, or interaction\n ❌ More decision questions; roughly 10-15 stops before the report\nB) Focus: interaction states + information architecture\n ✅ Hits the two largest gaps first: state design and panel hierarchy\n ✅ Fewer stops; quicker path to a usable plan\n ❌ Responsive, journey, a11y and slop risk stay unreviewed and unrated\nC) Focus: user journey + accessibility\n ✅ Covers login landing, wayfinding, modal/toast a11y end to end\n ✅ Good fit if the visual layout is already decided elsewhere\n ❌ Hierarchy, item anatomy and empty-state design stay as they are\nNet: full rigor on a thin plan versus a faster, narrower pass.": "All 7 dimensions (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-10-03T03:06:49.299Z"
}
},
{
"preReview": true,
"observedAtMs": 144795,
"call": {
"sessionId": "b7d9de19-26a2-4d99-a3cb-6327a36fb8fb",
"toolUseId": "toolu_01QJdE2m69TUXzfhsAaPAFrY",
"questions": [
{
"question": "D3 — Want outside design voices before the detailed review?\nProject/branch/task: gstack-plan-count-aX3JRn on main, design review of the User Dashboard Page plan.\nELI10: Outside voices means two extra reviewers look at the plan before I run the 7 passes: Codex scores it against OpenAI's design hard rules and litmus checks, and an independent Claude subagent does a completeness read without seeing my notes. Where they disagree with me, both views show up in the relevant pass.\nStakes if we pick wrong: Skipping it means findings rest on one reviewer; running it adds a few minutes and Codex may not be installed here.\nRecommendation: No, proceed without because the designer is unavailable this round and the plan's gaps are already clear enough to resolve directly.\nNote: options differ in kind, not coverage — no completeness score.\nPros / cons:\nA) Yes, run outside design voices\n ✅ Codex hard-rule + litmus scorecard plus an independent Claude completeness read\n ✅ Disagreements surface with both perspectives in the relevant pass\n ❌ Adds a few minutes; Codex may be missing here, in which case only the Claude voice runs and it's tagged single-model\nB) No, proceed without (recommended)\n ✅ Straight into the 7 passes with the approved mockup as anchor\n ✅ Fewest steps to a fixed plan\n ❌ Findings rest on one reviewer; no cross-model check on slop risk or hierarchy\nNet: a cross-model sanity check versus the shortest path to a fixed plan.",
"header": "Voices",
"multiSelect": false,
"options": [
{
"label": "Yes, run outside design voices",
"description": "✅ Codex hard-rule + litmus scorecard plus an independent Claude completeness read. ✅ Disagreements surface with both perspectives in the relevant pass. ❌ Adds a few minutes; Codex may be missing here, in which case only the Claude voice runs and it's tagged single-model."
},
{
"label": "No, proceed without (recommended)",
"description": "✅ Straight into the 7 passes with the approved mockup as anchor. ✅ Fewest steps to a fixed plan. ❌ Findings rest on one reviewer; no cross-model check on slop risk or hierarchy."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D3 — Want outside design voices before the detailed review?\nProject/branch/task: gstack-plan-count-aX3JRn on main, design review of the User Dashboard Page plan.\nELI10: Outside voices means two extra reviewers look at the plan before I run the 7 passes: Codex scores it against OpenAI's design hard rules and litmus checks, and an independent Claude subagent does a completeness read without seeing my notes. Where they disagree with me, both views show up in the relevant pass.\nStakes if we pick wrong: Skipping it means findings rest on one reviewer; running it adds a few minutes and Codex may not be installed here.\nRecommendation: No, proceed without because the designer is unavailable this round and the plan's gaps are already clear enough to resolve directly.\nNote: options differ in kind, not coverage — no completeness score.\nPros / cons:\nA) Yes, run outside design voices\n ✅ Codex hard-rule + litmus scorecard plus an independent Claude completeness read\n ✅ Disagreements surface with both perspectives in the relevant pass\n ❌ Adds a few minutes; Codex may be missing here, in which case only the Claude voice runs and it's tagged single-model\nB) No, proceed without (recommended)\n ✅ Straight into the 7 passes with the approved mockup as anchor\n ✅ Fewest steps to a fixed plan\n ❌ Findings rest on one reviewer; no cross-model check on slop risk or hierarchy\nNet: a cross-model sanity check versus the shortest path to a fixed plan.": "No, proceed without (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-10-03T03:07:23.020Z"
}
},
{
"preReview": true,
"observedAtMs": 168367,
"call": {
"sessionId": "b7d9de19-26a2-4d99-a3cb-6327a36fb8fb",
"toolUseId": "toolu_01QMVsFHMVbdrkG3MQ3JaJ19",
"questions": [
{
"question": "D4 — Let gstack search learnings from your other projects on this machine?\nProject/branch/task: gstack-plan-count-aX3JRn on main, design review of the User Dashboard Page plan.\nELI10: gstack can search learnings from your other projects on this machine to find patterns that might apply here. This stays local (no data leaves your machine). Recommended for solo developers. Skip if you work on multiple client codebases where cross-contamination would be a concern.\nStakes if we pick wrong: Enabling on a multi-client machine could surface one client's patterns in another's review; disabling just means fewer prior learnings applied here.\nRecommendation: A because learnings stay on this machine and a fresh fixture project has no local history of its own to draw on.\nNote: options differ in kind, not coverage — no completeness score.\nPros / cons:\nA) Enable cross-project learnings (recommended)\n ✅ Design pitfalls found in other projects get applied to this review automatically\n ✅ Everything stays local on this machine; nothing is uploaded anywhere\n ❌ On a machine with multiple client codebases, patterns could cross between clients\nB) Keep learnings project-scoped only\n ✅ Strict isolation between codebases on this machine\n ✅ Simplest mental model: this project only sees its own history\n ❌ This project has zero learnings so far, so no prior insight applies today\nNet: compounding insight across projects versus strict per-project isolation.",
"header": "Learnings",
"multiSelect": false,
"options": [
{
"label": "Enable cross-project learnings (recommended)",
"description": "✅ Pitfalls from other local projects apply here automatically. ✅ Stays local on this machine. ❌ Patterns could cross between client codebases."
},
{
"label": "Keep learnings project-scoped only",
"description": "✅ Strict isolation between codebases. ✅ Simplest model: own history only. ❌ This project has zero learnings today, so nothing applies."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D4 — Let gstack search learnings from your other projects on this machine?\nProject/branch/task: gstack-plan-count-aX3JRn on main, design review of the User Dashboard Page plan.\nELI10: gstack can search learnings from your other projects on this machine to find patterns that might apply here. This stays local (no data leaves your machine). Recommended for solo developers. Skip if you work on multiple client codebases where cross-contamination would be a concern.\nStakes if we pick wrong: Enabling on a multi-client machine could surface one client's patterns in another's review; disabling just means fewer prior learnings applied here.\nRecommendation: A because learnings stay on this machine and a fresh fixture project has no local history of its own to draw on.\nNote: options differ in kind, not coverage — no completeness score.\nPros / cons:\nA) Enable cross-project learnings (recommended)\n ✅ Design pitfalls found in other projects get applied to this review automatically\n ✅ Everything stays local on this machine; nothing is uploaded anywhere\n ❌ On a machine with multiple client codebases, patterns could cross between clients\nB) Keep learnings project-scoped only\n ✅ Strict isolation between codebases on this machine\n ✅ Simplest mental model: this project only sees its own history\n ❌ This project has zero learnings so far, so no prior insight applies today\nNet: compounding insight across projects versus strict per-project isolation.": "Enable cross-project learnings (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-10-03T03:07:46.592Z"
}
},
{
"preReview": false,
"observedAtMs": 250570,
"call": {
"sessionId": "b7d9de19-26a2-4d99-a3cb-6327a36fb8fb",
"toolUseId": "toolu_01WVKYXt2cnKzMhKZfjTVqT4",
"questions": [
{
"question": "D5 — Issue 1: What is the reading order and desktop layout of the dashboard?\nProject/branch/task: gstack-plan-count-aX3JRn on main, Pass 1 (Information Architecture) of the User Dashboard plan.\nELI10: The plan lists activity, notifications, and quick actions but never says what the user should look at first. Without a stated order the engineer ships three equal boxes and the page becomes a card mosaic where nothing wins. Quick actions are two links; they don't earn a whole panel.\nStakes if we pick wrong: Users land after login and have to scan three competing regions to find what needs them; the one actionable item (unread notifications) gets lost.\nRecommendation: 1A because activity is the content that fills the viewport and changes daily, notifications are a short glanceable list whose unread count is the attention cue, and quick actions belong in the header as a utility strip (subtraction default).\nCompleteness: A=10/10, B=9/10, C=5/10\nPros / cons:\n1A) Two-column at lg: Activity primary (left, ~2/3), Notifications rail (right, ~1/3) with unread count in its heading; quick actions as a compact link strip under the page title (recommended)\n ✅ One clear primary region; notifications stay visible without competing for the main column\n ✅ Quick actions stop being a panel and become two links next to the title, removing a box\n ❌ Activity reads before notifications, so unread items rely on the count badge to draw the eye\n1B) Two-column at lg: Notifications primary (left, ~1/2), Activity secondary (right, ~1/2); quick actions as a header strip\n ✅ The actionable list (unread, mark all as read) reads first in left-to-right order\n ✅ Still removes the quick-actions panel\n ❌ Notifications are usually a short list, so the primary column sits mostly empty while activity is cramped\n1C) Keep three equal panels in a row as the plan implies\n ✅ Matches the plan text literally; no layout decision to defend\n ✅ Simplest grid to build\n ❌ Hard-rejection pattern: app UI made of equal cards instead of layout; quick actions panel holds two links\nNet: a stated primary column versus three boxes that compete.",
"header": "Layout",
"multiSelect": false,
"options": [
{
"label": "1A Activity primary, Notifications rail (recommended)",
"description": "✅ One clear primary region; notifications visible without competing. ✅ Quick actions become a header link strip, one less box. ❌ Unread items rely on the count badge to draw the eye."
},
{
"label": "1B Notifications primary, Activity secondary",
"description": "✅ Actionable unread list reads first. ✅ Still removes the quick-actions panel. ❌ Short notification list leaves the primary column mostly empty."
},
{
"label": "1C Three equal panels",
"description": "✅ Matches plan text literally. ✅ Simplest grid. ❌ Hard-rejection pattern: equal cards instead of layout; a panel for two links."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D5 — Issue 1: What is the reading order and desktop layout of the dashboard?\nProject/branch/task: gstack-plan-count-aX3JRn on main, Pass 1 (Information Architecture) of the User Dashboard plan.\nELI10: The plan lists activity, notifications, and quick actions but never says what the user should look at first. Without a stated order the engineer ships three equal boxes and the page becomes a card mosaic where nothing wins. Quick actions are two links; they don't earn a whole panel.\nStakes if we pick wrong: Users land after login and have to scan three competing regions to find what needs them; the one actionable item (unread notifications) gets lost.\nRecommendation: 1A because activity is the content that fills the viewport and changes daily, notifications are a short glanceable list whose unread count is the attention cue, and quick actions belong in the header as a utility strip (subtraction default).\nCompleteness: A=10/10, B=9/10, C=5/10\nPros / cons:\n1A) Two-column at lg: Activity primary (left, ~2/3), Notifications rail (right, ~1/3) with unread count in its heading; quick actions as a compact link strip under the page title (recommended)\n ✅ One clear primary region; notifications stay visible without competing for the main column\n ✅ Quick actions stop being a panel and become two links next to the title, removing a box\n ❌ Activity reads before notifications, so unread items rely on the count badge to draw the eye\n1B) Two-column at lg: Notifications primary (left, ~1/2), Activity secondary (right, ~1/2); quick actions as a header strip\n ✅ The actionable list (unread, mark all as read) reads first in left-to-right order\n ✅ Still removes the quick-actions panel\n ❌ Notifications are usually a short list, so the primary column sits mostly empty while activity is cramped\n1C) Keep three equal panels in a row as the plan implies\n ✅ Matches the plan text literally; no layout decision to defend\n ✅ Simplest grid to build\n ❌ Hard-rejection pattern: app UI made of equal cards instead of layout; quick actions panel holds two links\nNet: a stated primary column versus three boxes that compete.": "1A Activity primary, Notifications rail (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-10-03T03:09:08.798Z"
}
}
]
}
+12 -3
View File
@@ -76,6 +76,10 @@ nativeFinding.nativeCall.questions[0].options = [
{ label: '1B Activity-primary (Codex)', description: 'Activity dominant ~7/12, notifications right rail; primary action beside title. Completeness 10/10.' },
{ label: '1C Three peer regions, decide later', description: 'Keep the plan as written; hard rejection #1 stays open. Completeness 3/10.' },
];
// Run 37091743395 slice 8 (987a937b): the five answered native calls, byte-exact,
// whose comma-less Step 0D title the focus predicate once rejected.
const captured = JSON.parse(fs.readFileSync(${JSON.stringify(path.join(ROOT, 'test/fixtures/design-ui-focus-capture.json'))}, 'utf8'))
.calls.map(({ preReview, observedAtMs, call }) => nativePlanCallFingerprint(call, observedAtMs, preReview));
const unnumberedFinding = fp('unnumbered-finding', "Which region is the dashboard's primary anchor, and how is the page composed?", false);
unnumberedFinding.nativeCall.questions[0].options = nativeFinding.nativeCall.questions[0].options;
const finding = fp('finding', 'Which loading feedback should Save show?', false);
@@ -125,8 +129,10 @@ mock.module(${JSON.stringify(path.join(ROOT, 'test/helpers/claude-pty-runner.ts'
// Census 36633323521 gate-census-7: the same Step 0D menu titled with "specific ones".
expect(opts.isLastStep0AUQ(fp('focus-ones', 'D1 — Review all 7 design dimensions, or focus on specific ones?'))).toBe(true);
if (mode.startsWith('native-')) expect(opts.isLastStep0AUQ(nativeFocus)).toBe(true);
expect(opts.isLastStep0AUQ(captured[1])).toBe(true);
for (const unrelated of ['Review all 4 design passes, or focus?',
'Review all 7 engineering passes, or focus?', 'Review all 7 passes, or focus?',
'Review all 4 design passes or focus?', 'Review all 7 engineering passes or focus?', 'Review all 7 passes or focus?',
'Which plan should receive all 7 design passes?']) {
expect(opts.isLastStep0AUQ(fp('unrelated', unrelated))).toBe(false);
}
@@ -196,7 +202,10 @@ mock.module(${JSON.stringify(path.join(ROOT, 'test/helpers/claude-pty-runner.ts'
expect(() => opts.pickAUQ(unboundBoard, unboundBoard, context)).toThrow('requires an owned native question');
fs.writeFileSync(${JSON.stringify(facts)}, JSON.stringify({ calls, cwd: cwd, seeded: true }));
if (mode === 'throw') throw new Error('controlled UI observation failure');
const observed = mode.startsWith('target-menu') ? [target, fp('other', 'Which artifact should I inspect?', false)]
const observed = mode === 'captured' ? captured
: mode === 'captured-no-focus' ? captured.filter((_, index) => index !== 1)
: mode === 'captured-focus-after-finding' ? [...captured.filter((_, index) => index !== 1), captured[1]]
: mode.startsWith('target-menu') ? [target, fp('other', 'Which artifact should I inspect?', false)]
: mode === 'early-exit' ? [] : mode === 'focus-only' ? [chosenFocus]
: mode === 'native-setup-only' ? [nativeFocus, nativeSetup]
: mode === 'native-voices-only' ? [nativeFocus, declinedVoices]
@@ -239,12 +248,12 @@ await import(${JSON.stringify(path.join(ROOT, 'test/skill-e2e-plan-design-with-u
} finally { fs.rmSync(directory, { recursive: true, force: true }); }
}
test.each(['source', 'paraphrase', 'native-sequence', 'native-unnumbered', 'native-passes'])('UI gate seeds the exact target and accepts Design progress with an unselected no-UI alternative (%s)', mode => {
test.each(['source', 'paraphrase', 'native-sequence', 'native-unnumbered', 'native-passes', 'captured'])('UI gate seeds the exact target and accepts Design progress with an unselected no-UI alternative (%s)', mode => {
const result = exercise(mode);
expect(result.code, result.output).toBe(0);
}, 20_000);
test.each(['target-menu', 'target-menu-design-system', 'focus-only', 'native-setup-only', 'native-voices-only', 'early-exit', 'timeout', 'exited', 'unanswered-finding', 'failed-finding', 'no-native-finding'])('UI gate rejects %s and removes its fixture', mode => {
test.each(['target-menu', 'target-menu-design-system', 'focus-only', 'captured-no-focus', 'captured-focus-after-finding', 'native-setup-only', 'native-voices-only', 'early-exit', 'timeout', 'exited', 'unanswered-finding', 'failed-finding', 'no-native-finding'])('UI gate rejects %s and removes its fixture', mode => {
const result = exercise(mode);
expect(result.code, result.output).toBe(1);
expect(result.output).toContain('plan-design-review with UI scope FAILED');
+1 -1
View File
@@ -29,7 +29,7 @@ const designFocusBoundary = (fp: AskUserQuestionFingerprint): boolean =>
// Require the source Step 0D question or its retained native paraphrase.
// A target menu can mention a design system without reviewing this plan.
return /^I(?:['’]ve| have) rated this plan (?:10(?:\.0+)?|[0-9](?:\.\d+)?)\/10 on design completeness\.[\s\S]*\bWant me to focus on specific areas instead of all 7\?/i.test(text)
|| /^Review all 7 design (?:dimensions|passes), or focus(?: on [^?\n]+)?\?$/i.test(text.split(/\r?\n/, 1)[0]!);
|| /^Review all 7 design (?:dimensions|passes),? or focus(?: on [^?\n]+)?\?$/i.test(text.split(/\r?\n/, 1)[0]!);
});
// Require a choice about the supplied UI, not a workflow offer after focus.