fix(ci): restore full-suite after verification request + lucide mock gaps (#2332)

## Summary

Main Full Suite shards have been red after recent landings. Root causes:

1. **Executor tests** — `execute()` now polls
`getTaskVerificationRequestAsync` (chat-enqueued verification). Shared
`createMockStore()` (and soft-delete inline store) lacked the method, so
nearly every execute-path suite failed with `is not a function`.
2. **TaskDetailModal suites** — `NativeStructurePreview` imports `Map` /
`Lightbulb` / `BarChart3` / `Target` / `CircleAlert` from lucide; the
shared TaskDetail lucide mock omitted them, so suites failed at import.
3. **Grok process-lifecycle** — 15s bound stress timed out under
full-suite load without product-bug evidence → quarantined on sight per
AGENTS.md.

## Test plan

- [x] `executor-task-done-blocked`, `executor-fast-mode-workflows`,
concurrent-execute race
- [x] `executor-step-session`, plan-only scope leak, review-step
indexing
- [x] `TaskDetailModal.create-pr` + `TaskDetail.mobile-transition`
- [ ] Full Suite CI on this PR

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Added `html2canvas` support in the dashboard to enable HTML-to-canvas
rendering needed for visual structure previews.
* **Tests**
* Updated task execution test mocks to handle task verification-request
flows reliably.
* Improved task deletion safeguard coverage and related execution
behavior checks.
* Enhanced test stubs to support structure preview rendering elements
during modal-related tests.
* **Chores**
* Quarantined a timing-sensitive process lifecycle test and refreshed
quarantine tracking to improve full-suite stability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
gsxdsm
2026-07-19 09:50:22 -07:00
committed by GitHub
parent 3bf7f92be0
commit 845d82ec67
7 changed files with 97 additions and 70 deletions

View File

@@ -162,6 +162,17 @@ vi.mock("lucide-react", () => ({
Package: (props: any) => React.createElement("svg", { "data-testid": "package-icon", ...props }),
Download: (props: any) => React.createElement("svg", { "data-testid": "download-icon", ...props }),
User: (props: any) => React.createElement("svg", { "data-testid": "user-icon", ...props }),
/*
FNXC:NativeStructureEmbed 2026-07-19-04:30:
FN-8291/8292/8293 mount NativeStructurePreview from chat/mail surfaces reachable via
StandardChatSurface under TaskDetailModal. Keep Map/Lightbulb/BarChart3/Target/CircleAlert
on this shared mock or every focused TaskDetailModal suite fails at import.
*/
Map: (props: any) => React.createElement("svg", { "data-testid": "map-icon", ...props }),
Lightbulb: (props: any) => React.createElement("svg", { "data-testid": "lightbulb-icon", ...props }),
BarChart3: (props: any) => React.createElement("svg", { "data-testid": "bar-chart-3-icon", ...props }),
Target: (props: any) => React.createElement("svg", { "data-testid": "target-icon", ...props }),
CircleAlert: (props: any) => React.createElement("svg", { "data-testid": "circle-alert-icon", ...props }),
}));
vi.mock("../../hooks/useAgentLogs", () => ({

View File

@@ -133,6 +133,7 @@
"@xyflow/react": "^12.11.0",
"archiver": "^7.0.1",
"express": "^5.1.0",
"html2canvas": "1.4.1",
"i18next": "^26.3.1",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-resources-to-backend": "^1.2.1",

View File

@@ -47,6 +47,12 @@ function createStore(overrides?: { tasks?: Task[] }) {
*/
getAgentLogCount: vi.fn().mockResolvedValue(0),
getAgentLogs: vi.fn().mockResolvedValue([]),
// FNXC:TaskVerificationRequest 2026-07-19-04:30: execute() polls pending verification requests.
getTaskVerificationRequestAsync: vi.fn().mockResolvedValue(null),
claimTaskVerificationRequest: vi.fn().mockResolvedValue(null),
finishTaskVerificationRequest: vi.fn().mockResolvedValue(undefined),
// FNXC:TaskVerificationRequest 2026-07-19-12:00: match createMockStore() in executor-test-helpers.ts.
createTaskVerificationRequest: vi.fn().mockResolvedValue(undefined),
updateTask: vi.fn().mockResolvedValue({}),
} as any;
return store;

View File

@@ -483,6 +483,17 @@ export function createMockStore() {
getAgentLogCount: vi.fn().mockResolvedValue(0),
getAgentLogs: vi.fn().mockResolvedValue([]),
getGlobalSettingsDir: vi.fn().mockReturnValue(undefined),
/*
FNXC:TaskVerificationRequest 2026-07-19-04:30:
Executor execute() claims pending chat-enqueued verification requests via
getTaskVerificationRequestAsync / claim / finish. Default null so existing
execute-path tests keep no-verification behavior; full-suite engine shards
went red without these stubs after the request API landed on main.
*/
getTaskVerificationRequestAsync: vi.fn().mockResolvedValue(null),
claimTaskVerificationRequest: vi.fn().mockResolvedValue(null),
finishTaskVerificationRequest: vi.fn().mockResolvedValue(undefined),
createTaskVerificationRequest: vi.fn().mockResolvedValue(undefined),
};
return store as any;
}

View File

@@ -13,6 +13,8 @@ export default defineConfig({
},
test: {
include: ["src/**/*.test.ts"],
// FNXC:TestQuarantine 2026-07-19-04:30: process-lifecycle bound stress timed out on full-suite shard 4 (run 29671930241); ledger entry in scripts/lib/test-quarantine.json.
exclude: ["src/__tests__/process-lifecycle.test.ts"],
environment: "node",
setupFiles: [fileURLToPath(new URL("../../packages/core/src/__test-utils__/vitest-setup.ts", import.meta.url))],
globalSetup: [fileURLToPath(new URL("../../packages/core/src/__test-utils__/vitest-teardown.ts", import.meta.url))],

129
pnpm-lock.yaml generated
View File

@@ -52,10 +52,10 @@ importers:
dependencies:
'@earendil-works/pi-ai':
specifier: 0.80.10
version: 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)
version: 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)
'@earendil-works/pi-coding-agent':
specifier: 0.80.10
version: 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)
version: 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)
claude-code-cli-acp:
specifier: 0.1.1
version: 0.1.1
@@ -332,6 +332,9 @@ importers:
express:
specifier: ^5.1.0
version: 5.2.1
html2canvas:
specifier: 1.4.1
version: 1.4.1
i18next:
specifier: ^26.3.1
version: 26.3.1(typescript@5.9.3)
@@ -3966,6 +3969,10 @@ packages:
bare-url@2.4.0:
resolution: {integrity: sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==}
base64-arraybuffer@1.0.2:
resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
engines: {node: '>= 0.6.0'}
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
@@ -4448,6 +4455,9 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
css-line-break@2.1.0:
resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
css-tree@3.2.1:
resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
@@ -5494,6 +5504,10 @@ packages:
html-void-elements@3.0.0:
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
html2canvas@1.4.1:
resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
engines: {node: '>=8.0.0'}
http-cache-semantics@4.2.0:
resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
@@ -7520,6 +7534,9 @@ packages:
text-decoder@1.2.7:
resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==}
text-segmentation@1.0.3:
resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
@@ -7795,6 +7812,9 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
utrie@1.0.2:
resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
uuid@10.0.0:
resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
@@ -8168,10 +8188,6 @@ snapshots:
package-manager-detector: 1.6.0
tinyexec: 1.2.4
'@anthropic-ai/sdk@0.91.1':
dependencies:
json-schema-to-ts: 3.1.1
'@anthropic-ai/sdk@0.91.1(zod@3.25.76)':
dependencies:
json-schema-to-ts: 3.1.1
@@ -8930,9 +8946,9 @@ snapshots:
- ws
- zod
'@earendil-works/pi-agent-core@0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)':
'@earendil-works/pi-agent-core@0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)':
dependencies:
'@earendil-works/pi-ai': 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)
'@earendil-works/pi-ai': 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)
ignore: 7.0.5
typebox: 1.1.38
yaml: 2.9.0
@@ -8974,15 +8990,15 @@ snapshots:
'@earendil-works/pi-ai@0.80.10':
dependencies:
'@anthropic-ai/sdk': 0.91.1
'@anthropic-ai/sdk': 0.91.1(zod@4.3.6)
'@aws-sdk/client-bedrock-runtime': 3.1048.0
'@google/genai': 1.52.0
'@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))
'@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0)
'@opentelemetry/api': 1.9.0
'@smithy/node-http-handler': 4.7.3
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
openai: 6.26.0
openai: 6.26.0(ws@8.20.0)(zod@4.3.6)
partial-json: 0.1.7
typebox: 1.1.38
transitivePeerDependencies:
@@ -8993,17 +9009,17 @@ snapshots:
- ws
- zod
'@earendil-works/pi-ai@0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)':
'@earendil-works/pi-ai@0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)':
dependencies:
'@anthropic-ai/sdk': 0.91.1(zod@3.25.76)
'@anthropic-ai/sdk': 0.91.1(zod@4.3.6)
'@aws-sdk/client-bedrock-runtime': 3.1048.0
'@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))
'@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))
'@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0)
'@opentelemetry/api': 1.9.0
'@smithy/node-http-handler': 4.7.3
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
openai: 6.26.0(ws@8.20.0)(zod@3.25.76)
openai: 6.26.0(ws@8.20.0)(zod@4.3.6)
partial-json: 0.1.7
typebox: 1.1.38
transitivePeerDependencies:
@@ -9039,7 +9055,7 @@ snapshots:
dependencies:
'@anthropic-ai/sdk': 0.91.1(zod@3.25.76)
'@aws-sdk/client-bedrock-runtime': 3.1048.0
'@google/genai': 1.52.0
'@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))
'@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0)
'@opentelemetry/api': 1.9.0
'@smithy/node-http-handler': 4.7.3
@@ -9086,10 +9102,10 @@ snapshots:
- ws
- zod
'@earendil-works/pi-coding-agent@0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)':
'@earendil-works/pi-coding-agent@0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)':
dependencies:
'@earendil-works/pi-agent-core': 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)
'@earendil-works/pi-ai': 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)
'@earendil-works/pi-agent-core': 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)
'@earendil-works/pi-ai': 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)
'@earendil-works/pi-tui': 0.80.10
'@silvia-odwyer/photon-node': 0.3.4
chalk: 5.6.2
@@ -9516,30 +9532,6 @@ snapshots:
'@exodus/bytes@1.15.0': {}
'@google/genai@1.52.0':
dependencies:
google-auth-library: 10.6.2
p-retry: 4.6.2
protobufjs: 7.5.8
ws: 8.21.1
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@google/genai@1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))':
dependencies:
google-auth-library: 10.6.2
p-retry: 4.6.2
protobufjs: 7.5.8
ws: 8.21.1
optionalDependencies:
'@modelcontextprotocol/sdk': 1.28.0(zod@3.25.76)
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@google/genai@1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))':
dependencies:
google-auth-library: 10.6.2
@@ -10059,29 +10051,6 @@ snapshots:
- bufferutil
- utf-8-validate
'@modelcontextprotocol/sdk@1.28.0(zod@3.25.76)':
dependencies:
'@hono/node-server': 1.19.12(hono@4.12.9)
ajv: 8.18.0
ajv-formats: 3.0.1(ajv@8.18.0)
content-type: 1.0.5
cors: 2.8.6
cross-spawn: 7.0.6
eventsource: 3.0.7
eventsource-parser: 3.0.6
express: 5.2.1
express-rate-limit: 8.3.1(express@5.2.1)
hono: 4.12.9
jose: 6.2.2
json-schema-typed: 8.0.2
pkce-challenge: 5.0.1
raw-body: 3.0.2
zod: 3.25.76
zod-to-json-schema: 3.25.1(zod@3.25.76)
transitivePeerDependencies:
- supports-color
optional: true
'@modelcontextprotocol/sdk@1.28.0(zod@4.3.6)':
dependencies:
'@hono/node-server': 1.19.12(hono@4.12.9)
@@ -10955,7 +10924,7 @@ snapshots:
obug: 2.1.2
std-env: 4.1.0
tinyrainbow: 3.1.0
vitest: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.5.2)(@vitest/coverage-v8@4.1.8)(happy-dom@20.10.1)(jsdom@29.0.1)(vite@6.4.1(@types/node@25.5.2)(jiti@2.7.0)(tsx@4.21.0)(yaml@2.8.3))
vitest: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.5.2)(@vitest/coverage-v8@4.1.8)(happy-dom@20.10.1)(jsdom@29.0.1)(vite@6.4.1(@types/node@25.5.2)(jiti@2.7.0)(tsx@4.21.0)(yaml@2.9.0))
'@vitest/expect@4.1.8':
dependencies:
@@ -11358,6 +11327,8 @@ snapshots:
dependencies:
bare-path: 3.0.0
base64-arraybuffer@1.0.2: {}
base64-js@1.5.1: {}
baseline-browser-mapping@2.10.10: {}
@@ -11829,6 +11800,10 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
css-line-break@2.1.0:
dependencies:
utrie: 1.0.2
css-tree@3.2.1:
dependencies:
mdn-data: 2.27.1
@@ -13091,6 +13066,11 @@ snapshots:
html-void-elements@3.0.0: {}
html2canvas@1.4.1:
dependencies:
css-line-break: 2.1.0
text-segmentation: 1.0.3
http-cache-semantics@4.2.0: {}
http-errors@2.0.1:
@@ -14338,13 +14318,16 @@ snapshots:
is-docker: 2.2.1
is-wsl: 2.2.0
openai@6.26.0: {}
openai@6.26.0(ws@8.20.0)(zod@3.25.76):
optionalDependencies:
ws: 8.20.0
zod: 3.25.76
openai@6.26.0(ws@8.20.0)(zod@4.3.6):
optionalDependencies:
ws: 8.20.0
zod: 4.3.6
openai@6.26.0(ws@8.21.1)(zod@4.3.6):
optionalDependencies:
ws: 8.21.1
@@ -15492,6 +15475,10 @@ snapshots:
transitivePeerDependencies:
- react-native-b4a
text-segmentation@1.0.3:
dependencies:
utrie: 1.0.2
thenify-all@1.6.0:
dependencies:
thenify: 3.3.1
@@ -15759,6 +15746,10 @@ snapshots:
util-deprecate@1.0.2: {}
utrie@1.0.2:
dependencies:
base64-arraybuffer: 1.0.2
uuid@10.0.0: {}
uuid@14.0.1: {}

View File

@@ -23,7 +23,7 @@
},
{
"file": "packages/dashboard/src/__tests__/dev-server-process.test.ts",
"reason": "Full-suite shard 4 (run 29661202279): clears fallback probe timer when URL is detected from logs — detectedEvents length 0 under dashboard-api-quality-backfill load; known timer/stdout race (prior FN-6722 quarantine, FN-6860 rescue). Re-flaked without product-bug evidence. Quarantine on sight per AGENTS.md. Mirrored in packages/dashboard/vitest.config.ts.",
"reason": "Full-suite shard 4 (run 29661202279): clears fallback probe timer when URL is detected from logs \u2014 detectedEvents length 0 under dashboard-api-quality-backfill load; known timer/stdout race (prior FN-6722 quarantine, FN-6860 rescue). Re-flaked without product-bug evidence. Quarantine on sight per AGENTS.md. Mirrored in packages/dashboard/vitest.config.ts.",
"quarantinedAt": "2026-07-18"
},
{
@@ -40,6 +40,11 @@
"file": "packages/engine/src/__tests__/reliability-interactions/merge-reuse-task-worktree.slow.test.ts",
"reason": "Full-suite engine-slow (run 29663725381): FN-5363 queue-head pollution handoff left leased merge-queue row after merge under load without product-bug evidence. Quarantine on sight per AGENTS.md. Mirrored in packages/engine/vitest.config.ts engine-slow exclude.",
"quarantinedAt": "2026-07-18"
},
{
"file": "plugins/fusion-plugin-grok-runtime/src/__tests__/process-lifecycle.test.ts",
"reason": "Full-suite shard 4 (run 29671930241): process cleanup bound stress test timed out at 15s under package-lane load without product-bug evidence. Quarantine on sight per AGENTS.md. Mirrored in plugins/fusion-plugin-grok-runtime/vitest.config.ts.",
"quarantinedAt": "2026-07-19"
}
]
}