Skip to content

Cover the agent-card split: header, status, details, and actions - #824

Merged
selfcontained merged 2 commits into
mainfrom
agt_8205f4cc4575/job-test-enforcer-5e72c884
Jul 24, 2026
Merged

Cover the agent-card split: header, status, details, and actions#824
selfcontained merged 2 commits into
mainfrom
agt_8205f4cc4575/job-test-enforcer-5e72c884

Conversation

@selfcontained

Copy link
Copy Markdown
Owner

Recurring test-enforcer run for 2026-07-23.

Suite health

Green on the first pass, 5th consecutive run — nothing to fix.

  • pnpm run check clean
  • unit: server 2306 pass / 8 skip, web 314 → 336, browser-extension 60
  • pnpm run test:e2e: 169 pass / 12 skip (tmux-gated), 46s, zero stalls
  • pnpm run finalize:web clean

CI scan of the last 50 GitHub Actions runs found no test flakes. The one new failure (Release run 30041119104) is the publish-release guard correctly refusing to tag after origin/main advanced mid-release — infra, not a test. The four pre-merge PR #808 failures were already classified in an earlier run. The Brain flakes list is empty and stays empty.

Coverage added

PR #803 split agent-card.tsx into four presentational files, none of which had direct unit coverage — that was the queued next_focus. agent-card.test.tsx renders the real AgentCard (only @/lib/api is mocked) and asserts the wiring a split like this is most likely to break:

  • the connected-child override that neutralizes the parent's visual state and drops its selection highlight
  • header row-click routing: attach, detach-and-collapse when already connected, ignore clicks on controls, no-op while stopped
  • the rename prompt's gating, its POST, and the delayed re-arm that stops a double click firing twice
  • setup/archive phase lines, and the latest-event line's terminal-agent and expanded-message branches
  • worktree vs plain working-dir details, full access vs sandboxed, and the copy confirmation surviving a collapse (owned by the card, not the details panel, precisely so it does)
  • pause vs archive routing to their own targets, and persona cards hiding lifecycle actions

Verified non-vacuous by 21 source mutations, 20 caught. The survivor is the startsWith("job-") guard in hasDefaultSessionName, which is unreachable — a job- name can never equal the agent-<id suffix> default the same predicate requires. That is noted in the test file rather than papered over with a test that would pass for the wrong reason.

Review round

One general review agent on this run's diff caught a real false green: the agentVisualState stub mapped archiving to "active", while the real mapper in hooks/use-agents.ts treats anything not running or creating as stopped. That made the status !== "archiving" half of both resume guards untestable — deleting it kept the suite green while the UI would offer Resume on a card mid-teardown. Fixed, with two mutants covering it. Also fixed from that review: fake timers for the two source-defined windows, restorable jsdom globals, a framer-motion mock that spreads the real module, a self-parenting persona fixture, an unscoped count query, and a comment describing a fallback the component does not have.

Source changes

Two lines, both in agent-card-header.tsx: the icon-only resume button had no accessible name at all (lucide SVGs contribute none, and Radix tooltips only supply aria-describedby when open), so it now carries aria-label="Resume session" — distinct from the footer's "Resume" so an expanded stopped card has no ambiguous pair.

🤖 Generated with Claude Code

PR #803 split agent-card.tsx into four presentational files, none of
which had direct unit coverage. Add agent-card.test.tsx, which renders
the real AgentCard (only /lib/api is mocked) and asserts the wiring that
a split like this is most likely to break:
- the connected-child override that neutralizes the parent's visual
state and drops its selection highlight
- header row click routing: attach, detach-and-collapse when already
connected, ignore clicks on controls, no-op while stopped
- the rename prompt's gating and its POST, plus the disabled window that
stops a double click firing twice
- setup/archive phase lines, and the latest-event line's terminal-agent
and expanded-message branches
- worktree vs plain working-dir details, full-access vs sandboxed, and
the copy confirmation surviving a collapse (it is owned by the card,
not the details panel, precisely so it does)
- pause vs archive routing to their own targets, and the persona card
hiding lifecycle actions
Verified non-vacuous: 17 source mutations, 17/17 caught.
framer-motion is mocked out so collapse/expand is synchronous — its exit
animation otherwise leaves the old subtree mounted for an indeterminate
number of frames.
Also gives the header's icon-only resume button an aria-label; it had no
accessible name at all, so assistive tech (and role-based queries) could
not reach it.
The agentVisualState stub mapped `archiving` to "active", but the real
mapper in hooks/use-agents.ts treats anything that is not running or
creating as stopped. That made the `status !== "archiving"` half of both
resume guards untestable — deleting it left the suite green while the
UI would offer Resume on a card that is mid-teardown. The stub now
mirrors production, and two new mutants cover both guards.
Also from the review:
- drive the 1.5s rename re-arm and the 2s copy confirmation with fake
timers instead of racing the wall clock, and assert the re-arm rather
than only the initial disable
- install the jsdom globals through vi.stubGlobal / explicit teardown so
they cannot leak if per-file isolation is ever turned off
- spread the real framer-motion module into the mock, so a descendant
importing anything else from it fails loudly instead of opaquely
- drop a self-parenting persona fixture that silently tested the
fallback branch it appeared to be setting up
- scope the sub-agent count assertion to its own row
- correct a comment claiming the setup phase has a generic fallback
(it does not; the archive phase does, now asserted)
The header's resume button is labelled "Resume session" (matching its
tooltip) rather than "Resume", so it does not collide with the footer's
Resume button on an expanded stopped card.
Mutation battery re-run: 20/21 caught. The survivor is the unreachable
job- guard in hasDefaultSessionName, called out in the test file.
@selfcontained
selfcontained merged commit dcd2d33 into mainJul 24, 2026
1 check passed
@selfcontained
selfcontained deleted the agt_8205f4cc4575/job-test-enforcer-5e72c884 branch July 24, 2026 02:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@selfcontained