Skip to content

FE-674: Agent classifier UI on pending review rows#124

Draft
kostandinang wants to merge 10 commits into
ka/fe-674-card-4-polishfrom
ka/fe-674-card-6-agent-client-ui
Draft

FE-674: Agent classifier UI on pending review rows#124
kostandinang wants to merge 10 commits into
ka/fe-674-card-4-polishfrom
ka/fe-674-card-6-agent-client-ui

Conversation

@kostandinang
Copy link
Copy Markdown
Contributor

@kostandinang kostandinang commented May 11, 2026

What

Closes FE-674 V3.1 end-to-end: agent classifier UI, per-class actions, and bulk affordances. Built on the classifier backend shipped at 5c3a70c.

Stacked on #121. Draft.

Visibility

  • New POST .../needs/:needId/reset-agent: clears the row's agent state and re-dispatches the classifier.
  • New <ClassificationChip> with six variants: queued / classifying / auto-confirm / auto-edit / substantive / failed. Failed surfaces the agent's reason as tooltip.
  • Pending review header gains Run agent (shown when ≥1 need has no classification), inline M of N classified progress strip, and 1s polling only while in flight.
  • Per-row ↻ Re-run on classified/failed rows.

Per-class actions

  • auto-confirmConfirm
  • auto-editView (DiffPopover) + Apply (edit + resolve) + Skip
  • substantiveOpen side-chat

Bulk

Header buttons next to Run agent:

  • Confirm all (N) and Apply all suggested (N) — both serial so cascade opens stay predictable when Apply triggers hard-impact downstream needs.

Misc

  • Listing endpoint joins each need against its target item, so the substantive handoff has a full pinnable item without a second fetch.

Test plan

  • npm run verify passes
  • Dense spec → hard-impact edit → ≥4 mixed-kind needs queued
  • Run agent → chips cycle queued → classifying → terminal within ~5s; polling stops at rest
  • One auto-confirm Confirm; one auto-edit View / Apply; one substantive Open side-chat
  • Confirm all then Apply all suggested — serial dispatch
  • Re-run a classified row and a failed row

kostandinang and others added 8 commits May 11, 2026 14:46
Per-row Re-run endpoint: resets one need's agent_status / classification
/ proposal back to null, then re-dispatches the same classifier pipeline
used by the spec-level run-agent route on just that row. The reset half
is idempotent.

Inner-loop refactor extracts the per-need classify body of
handleRunReconciliationAgent into classifyClaimedNeed so both the
spec-level loop and per-row Re-run use one path through the I114
lifecycle (queued → classifying → classified | failed).

Eight new test cases on reconciliation-agent-route.test.ts cover:
- reclassify a previously classified row
- reclassify a previously failed row
- record failed outcome when model throws on re-run
- idempotent reset on a row already at null
- 404 unknown spec
- 404 unknown need
- 404 wrong-spec need
- 400 non-numeric ids

Wire registered in app.ts via registerPost on the new path family.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New ClassificationChip component renders six variants
(queued / classifying / auto-confirm / auto-edit / substantive / failed)
following the kind-chip layout from Card 4. The failed variant carries
the agent_proposal text as its tooltip.

PendingReviewSection header gains a Run agent button (visible only when
at least one open need has agent_status null) and an inline progress
strip ("Agent: M of N classified") while classification is in flight.
Run agent is disabled mid-flight to prevent double-dispatch.

Each row gains a classification chip next to the kind chip and, when
agent_status is classified or failed, a Re-run button that calls
POST .../:needId/reset-agent. Re-run also disables the row's Resolve
and Edit buttons while in flight.

useSpecificationOpenReconciliationNeeds now polls at 1s while any need
is queued or classifying; otherwise polling is off.

edit-api.ts gains runReconciliationAgentRequest and
resetReconciliationNeedAgentRequest wrappers matching the server
response shapes.

Twenty new test cases: 12 over ClassificationChip variants and the
variantFor helper, 10 over the run-agent button / progress strip /
classification chips per row / Re-run button / disabled state
composition.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ef code

The pending-review listing endpoint now joins each need against its
target knowledge_item to expose target_item_kind and target_reference_code,
read-time only. Closes Card 4's deferred follow-up: the substantive
Open-side-chat affordance in Card 7 can hand useSideChat() a full
SideChatPinnableItem without a second fetch.

Shared ReconciliationNeedRecord type gains the two nullable fields;
makeNeed fixture defaults both to null so existing tests stay green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per-row buttons keyed off agent_classification:
- auto-confirm: Confirm (single resolve call)
- auto-edit: View proposal (opens DiffPopover with target_current vs
  agent_proposal), Apply (edit + resolve), Skip (resolve only)
- substantive: Open side-chat (calls useSideChat().openFor with target
  kind / id / referenceCode / content); hidden when no SideChatHost is
  mounted (useSideChat returns null)

Header bulk buttons next to Run agent:
- Confirm all (N): serially resolves each auto-confirm row
- Apply all suggested (N): serially edits + resolves each auto-edit row
  with a non-null agent_proposal

Bulk operations serialize rather than parallelize so cascade-opening
stays predictable when an Apply triggers hard-impact downstream needs.

DiffPopover state now carries a mode discriminator (source-diff vs
agent-proposal) so the same primitive renders both popovers.

Nine new test cases cover per-class affordances, bulk visibility,
serial dispatch, and the null-side-chat-context guard. Existing tests
stay green (38 total).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/client/components/pending-review-section.tsx Outdated
Comment thread src/client/components/pending-review-section.tsx Outdated
Comment thread src/client/components/pending-review-section.tsx Outdated
kostandinang and others added 2 commits May 11, 2026 15:34
Semgrep flagged dynamic interpolation of need ids into console.error
template literals as a format-string injection risk. Convert all six
call sites to constant format string + separate args.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kostandinang kostandinang changed the title FE-674: V3.1 agent UI — chips + per-class actions + bulk (Cards 6+7) FE-674: Agent classifier UI on pending review rows May 11, 2026
Sign up for free to 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