Skip to content

feat(console): the bulk intake panel — upload, the real report, the four-eyes gate - #71

Merged
omercelikdev merged 2 commits into
mainfrom
feat/u3-bulk-panel
Jul 26, 2026
Merged

feat(console): the bulk intake panel — upload, the real report, the four-eyes gate#71
omercelikdev merged 2 commits into
mainfrom
feat/u3-bulk-panel

Conversation

@omercelikdev

Copy link
Copy Markdown
Owner

U3 slice 1: the bulk intake panel, capability-lit like the rest of the console.

What the panel does

  • Definitions lead with what is waiting at the gate and how long it has waited.
  • Upload posts the file as a RAW body (curl --data-binary's shape) — the console adds no format the API does not already accept.
  • Batches filter by STATE only: the frozen surface has no definition parameter, so the panel does not send one.
  • Validation report walks by keyset on afterRow — the one genuinely cursor-paged surface here.
  • The gate offers approve/reject only where the engine allows a decision; reject's note is mandatory, and every refusal is surfaced verbatim.

Kit changes the gate needed

  • VerbButton can collect an evidence note in its confirm step; a required note blocks the verb until the reason exists.
  • quiet suppresses the button's own outcome strip for verbs whose control legitimately unmounts when the verb lands — approving a batch was destroying the very message it produced (the U2 teardown lesson, found again).
  • Approved joins the standard state map (info: the work is still ahead).

Proof

scripts/console-smoke.sh — 3/3 green locally. The smoke host now composes bulk, so Playwright:

  1. uploads a file with a structurally broken line,
  2. reads the report the engine wrote ("expected 2 fields (per the header) but found 3"),
  3. is refused by the engine when the invalid row blocks approval,
  4. rejects with the mandatory reason and sees it recorded,
  5. uploads a clean file and approves it — the decision becomes a server fact.

Unit: kit 55, console 34.

Docs updated in the same PR: console RFC phase table (U3 bulk MET, three panels open), RFC index, ai-sdlc-status.md, CLAUDE.md status, the nightly job comment.

🤖 Generated with Claude Code

…our-eyes gate

U3 slice 1. The panel is a client of the frozen bulk surface: definitions and their
awaiting-approval age lead the screen, the batch list filters by STATE only (the
contract has no definition filter, so the panel does not send one), the validation
report walks by keyset on `afterRow`, and the gate offers approve/reject exactly
where the engine allows a decision.

Kit changes the gate needed:
- `VerbButton` can collect an EVIDENCE note in its confirm step; a required note
  blocks the verb until the reason exists (the contract makes reject's note
  mandatory — it is what the next uploader reads).
- `quiet` suppresses the button's own outcome strip for verbs whose control
  legitimately unmounts when the verb lands; the composite renders the outcome
  instead. Without it, approving a batch destroyed the very message it produced.
- `Approved` joins the standard state map (info: the work is still ahead).

The exit gate is real: the console smoke host now composes bulk, and Playwright
uploads a file with a broken line, reads the report THE ENGINE wrote, is refused
by the engine when invalid rows block approval, rejects with the mandatory reason,
then uploads a clean file and approves it — 3/3 green locally.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@omercelikdev

Copy link
Copy Markdown
Owner Author

Review agent v1 — 1 finding(s). The human decides; hard-stop labels need explicit resolution.

  • R3 (medium) ui/console/src/adminClient.ts:244 — The doc comment on bulkBatches() claims the panel narrows results by definition client-side, but BulkPanel.tsx has no definition filter and no such client-side narrowing anywhere — the Batches table shows all definitions mixed under the State filter only.
    • evidence: adminClient.ts:238-244 comment vs BulkPanel.tsx Batches section (only a State , no definition scoping/messaging) · action: Either implement the client-side definition narrowing the comment describes, or rewrite the comment to match the actual STATE-only behavior so it doesn't mislead future maintainers. Calibration: mark each finding accepted/dismissed in a reply — dismiss rate >40%/class revises that class (strategy §5).

The comment promised a client-side narrow by definition that the panel does not do —
and should not do: narrowing one take-bounded page would read as "no batches" while
more exist server-side. The honest fix is the server-side filter, tracked in #72.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@omercelikdev

Copy link
Copy Markdown
Owner Author

R3 accepted — the comment described a client-side definition narrow the panel deliberately does not do (narrowing one take-bounded page would read as "no batches" while more exist server-side). Comment rewritten to the contract's actual STATE-only behaviour; the real fix is the server-side filter, filed as #72.

@omercelikdev
omercelikdev merged commit 1d3b311 into main Jul 26, 2026
3 checks passed
@omercelikdev
omercelikdev deleted the feat/u3-bulk-panel branch July 26, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant