Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
id: bugfix-1110
title: bugfix-artifact-canvas-test-su
protocol: bugfix
phase: pr
plan_phases: []
current_plan_phase: null
gates:
pr:
status: pending
requested_at: '2026-06-28T06:00:05.286Z'
iteration: 1
build_complete: false
history: []
started_at: '2026-06-28T05:52:25.996Z'
updated_at: '2026-06-28T06:00:05.287Z'
pr_ready_for_human: true
40 changes: 40 additions & 0 deletions codev/state/bugfix-1110_thread.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# bugfix-1110 thread

## Investigate

Issue #1110: flaky test `surfaces a synchronous FileAdapter.watch() failure via onError without throwing (D2)`
in `packages/artifact-canvas/src/components/__tests__/artifact-canvas.test.tsx`.

Verified root cause against source (lines 157-166):
- Line 163: `await waitFor(() => expect(onError).toHaveBeenCalled());`
- Line 164: bare synchronous `expect(document.querySelector('p[data-line]')).not.toBeNull();`

The async `read()` render can resolve after `onError` fires; under CI load the DOM query at
line 164 lands before the paragraph is in the tree. Race → intermittent failure.

Sibling test (line 171) uses the correct pattern: `await waitFor(() => expect(...).not.toBeNull())`.

Fix: wrap line 164's assertion in `waitFor`. One-line semantic-preserving change. Confirmed
BUGFIX scope (trivial, mechanical, no production code change).

## Fix

Applied the one-line change (line 164 wrapped in `waitFor`). Verified:
- `pnpm --filter @cluesmith/codev-artifact-canvas test` → 56/56 pass
- D2 test stress-run 5× in isolation → 5/5 pass
- porch checks: build ✓ (5.2s), tests ✓ (20.7s)
Committed `[Bugfix #1110]`, advanced to PR phase.

## PR

PR #1111 opened (https://github.com/cluesmith/codev/pull/1111).
Running CMAP (gemini/codex/claude) — consult needs `--issue 1110` to disambiguate
the many projects visible in this worktree's `codev/projects/`.

CMAP verdicts: gemini=APPROVE, codex=APPROVE, claude=APPROVE.
Claude flagged the identical bare-assertion race in the sibling D2 adapter-error
test (line 133) — the issue invited this ride-along, so applied the same waitFor
wrap (commit 846b53dc). 56/56 pass. Posted CMAP results as PR comment.

`pr` gate requested via `porch done`. Notified architect. **Waiting for human
approval** — will merge only after `porch approve bugfix-1110 pr`.
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe('ArtifactCanvas (Phase 3)', () => {
const err = vi.spyOn(console, 'error').mockImplementation(() => {});
render(<ArtifactCanvas uri="x" {...host} onAddComment={vi.fn()} onError={onError} />);
await waitFor(() => expect(onError).toHaveBeenCalled());
expect(document.querySelector('p[data-line]')).not.toBeNull(); // still rendered, no throw
await waitFor(() => expect(document.querySelector('p[data-line]')).not.toBeNull()); // still rendered, no throw
err.mockRestore();
});

Expand Down Expand Up @@ -161,7 +161,7 @@ describe('ArtifactCanvas (Phase 3)', () => {
const err = vi.spyOn(console, 'error').mockImplementation(() => {});
expect(() => render(<ArtifactCanvas uri="x" {...host} onAddComment={vi.fn()} onError={onError} />)).not.toThrow();
await waitFor(() => expect(onError).toHaveBeenCalled());
expect(document.querySelector('p[data-line]')).not.toBeNull(); // read succeeded → content still renders
await waitFor(() => expect(document.querySelector('p[data-line]')).not.toBeNull()); // read succeeded → content still renders
err.mockRestore();
});

Expand Down
Loading