deckhearth/.convoys/scanner-correctness-polish.md
Randall Stillwell 0918bd0449 fix(security): stop leaking Gemini API key to browsers
Delete the public /api/config/gemini endpoint and remove client auto-load
paths so GEMINI_AI_API_KEY stays server-side only. Add a scan rate-limit
class for the upcoming server-side identify route and a CI gate that blocks
reintroducing config key leaks or new browser LLM URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 08:40:00 -05:00

109 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: scanner-correctness-polish
classification: infra-only
success_metric: |
Mark-Owned is idempotent (in-flight lock per queue row); bulk toolbar no
longer uses setTimeout(..., 100); pages/scanner.js imports lib/use-auth
not legacy auth-context; POST /api/collections/[identifier]/cards calls
logCollectionActivity('card_added', …).
skip:
- ia
- ux
- visual
- a11y
- design
status: open
created: 2026-05-27
---
# Convoy: scanner-correctness-polish
Fix scanner-page correctness bugs without changing UX or visual design.
## Why
The scanner audit surfaced non-security bugs that cause duplicate adds,
racey bulk actions, a stale auth import, and missing activity logs. These
are small fixes with high reliability impact during bulk scanning sessions.
## Scope
### In scope
- **`pages/scanner.js`**
- Line 8: change import from legacy `lib/auth-context` to `lib/use-auth`
(should have been swept by `single-auth-provider`; scanner was missed or
regressed).
- **Mark-Owned idempotency** — in-flight lock per queue row so double-tap
/ double-click cannot duplicate POSTs.
- **Bulk toolbar** — remove `setTimeout(..., 100)` race; await or use
proper batch completion signal.
- **`pages/api/collections/[identifier]/cards.js`** — POST handler calls
`logCollectionActivity(collectionId, userId, 'card_added', details)` per
AGENTS.md convention.
### Out of scope
- **Scanner UX redesign** — convoy `redesign-scanner-flow` (#4).
- **Copy / vocabulary** — convoy `rename-collections-vocabulary` (#5).
- **OCR / identify pipeline** — convoys #2#3.
- **Visual or a11y changes** — none intended; diff should be behavior-only.
## Roles invoked
1. `role-architect` — single brief (lightweight; may be parent-owned given
infra-only classification).
2. `role-implementer` — one brief.
3. `role-reviewer` — post-PR only (design + a11y skipped).
## Todos
- [ ] Architect: brief-1 with exact line targets
- [ ] Fix use-auth import on scanner page
- [ ] Add per-row in-flight lock for Mark-Owned
- [ ] Replace setTimeout bulk-toolbar pattern
- [ ] Wire logCollectionActivity on collection card POST
## Operator action required
**None.**
## Multitask dispatch
Single brief — no implementer fan-out.
**Cross-convoy parallelism:** after #1 merges, run alongside **#2 Brief 1**
and **#5 Brief 1** — disjoint files (`pages/scanner.js` vs migrations vs
copy sweep). Coordinate if both #6 and #5 touch `pages/scanner.js` (IA
should sequence copy sweep after correctness or split files in briefs).
Post-PR audit:
```
/multitask role-reviewer
```
Group id: `audit-scanner-correctness-polish-<pr>`.
## CI impact
| Workflow / job | Behavior |
| --- | --- |
| `ci.yml` | Standard lint + vitest; no new gates. |
| `preview-smoke.yml` | Fires. |
| `visual-diff.yml` | **May fire** if `pages/scanner.js` changes — behavior-only diff should not move pixels; baseline swallow if triggered. |
## Known constraints
- **`logCollectionActivity` import** — use existing helper from
permission-middleware or documented activity module; match sibling handlers.
- **No UX copy changes** — button labels stay as-is until #5 (or avoid
overlapping scanner.js edits between #5 and #6).
## Acceptance criteria
1. `pages/scanner.js` imports from `lib/use-auth` only.
2. Double-click Mark-Owned produces one POST.
3. Bulk toolbar actions complete without setTimeout race.
4. Collection card POST emits activity log row.
5. Vitest 21/21; lint baseline preserved.