Generated by the improve skill on 2026-06-11 against commit 635fc3c (branch feat/dashboard-mvp). Execute in the order below unless dependencies say otherwise. Each executor: read the plan fully before starting, honor its STOP conditions, and update your row when done.
| Plan | Title | Priority | Effort | Depends on | Status |
|---|---|---|---|---|---|
| 001 | Make tsc --noEmit pass; add typecheck script + CI |
P1 | S | — | IN PROGRESS (bun run typecheck passes; no CI workflow yet) |
| 002 | Paginate Google Workspace user listing (>300 users = wrongful org removals) | P1 | S | 001 | DONE |
| 003 | Sync-job pipeline reliability (stuck running jobs, atomic claim, NOTIFY fix) |
P1 | M | 001 | DONE (NOTIFY dropped for 5s polling; stale-job cleanup shared via findActiveJob) |
| 004 | Fix merged activity-feed pagination | P1 | S | 001 | DONE |
| 005 | Stop leaking internal error details from the BFF error handler | P1 | S | 001 | IN PROGRESS (superseded by HttpApi typed errors; GitHub/Google error messages still returned in 502 bodies) |
| 006 | Require authentication for the BFF API and the dashboard | P1 | M | 001, 005 | DONE |
| 007 | Characterization tests for Atlassian suspend/delete logic | P2 | M | 001 | TODO |
| 008 | Integration tests for the BFF routes | P2 | M | 001 (best after 003, 004) | TODO |
| 009 | Centralize job types/statuses/API types in shared | P2 | S | 001 (after 003) | IN PROGRESS (API types/statuses live in shared/api; 'github_sync' still a literal in BFF + worker) |
| 010 | Rewrite stale README + add .env.example |
P2 | S | — (after 006 if possible) | DONE |
| 011 | Consolidate duplicated Google/GitHub services into shared | P3 | M | 002 (hard), 008; 007 recommended | TODO |
| 012 | Cut N+1 GitHub API storms on user-detail endpoints | P3 | M | 001; 008 recommended | TODO |
Status values: TODO | IN PROGRESS | DONE | BLOCKED (with one-line reason) | REJECTED (with one-line rationale)
- 001 first, always — it's the verification baseline; every other plan gates on
bun run typecheck, which fails today. - 002 before 011 (hard dependency) — consolidating the services before the pagination fix lands would re-spread the >300-users truncation bug.
- 003 before 009 — both edit
packages/bff/src/routes/sync.tsandpackages/worker/src/services/sync-job-repo.ts; 003 changes logic, 009 then swaps literals for constants. - 005 before 006 — 006's 401s flow through the rewritten error handler and its tests reuse it.
- 003/004 before 008 — route tests should lock in the fixed behavior, not the bugs.
- 007 and 008 before 011 — they are the safety net that makes the consolidation refactor verifiable.
- 006 before 010 if possible — 010's
.env.exampleshould include 006's new auth variables (010 is written to pick up whatever the live config schemas contain).
Recorded so future audits don't re-litigate them:
- "Jobs double-completed after failure" (sync-engine catchAll) — false positive: the catchAll path returns empty
invited/removed, making the completion condition false. The real defect is the stuck-runningjob, covered by plan 003. - "
status as 400hardcodes all error responses to 400" — false positive: a TypeScript cast doesn't change runtime values. The cast is removed incidentally by plan 005. - "Audit-log inserts not awaited (silent failures)" — false positive: every
db.insert(auditLog)inroutes/{users,teams,repos}.tsisawaited. - "Atlassian delete URL malformed" (
api-client.ts:234) —https://api.atlassian.com/users/{account_id}/manage/lifecycle/deleteis the documented Atlassian user-management lifecycle endpoint; not a bug. - Sync-endpoint DoS via unbounded job creation — mostly mitigated: the 409 dedupe check caps the queue at one pending/running job per type. Auth (plan 006) closes the rest.
- Stale Google auth singleton in BFF routes —
google.auth.GoogleAuthrefreshes tokens automatically; not a real defect. - PII (emails/usernames) in logs and Slack notifications — intentional product behavior for an internal admin/audit tool; not worth doing.
- "Invite race when a user is deleted mid-sync" — already handled gracefully (error accumulated, sync continues); noise.
- No actor identity in
audit_log(noperformed_bycolumn; activity feed hardcodestrigger: 'dashboard') — blocked on per-user auth; revisit after plan 006 ships and if/when OIDC replaces Basic Auth. Noted in plan 006's maintenance notes. - No runtime validation of API request bodies (
c.req.json<T>()casts; Zod available but unused at boundaries) — moderate value; natural to add per-route once route tests (008) exist. repos.tsroute tests — deferred from plan 008 to keep it a day-ish; mirrorteams.test.ts.- Direction options surfaced to the maintainer (not planned): GitHub-sync dry-run/preview endpoint (the diff logic already computes lists before acting); surfacing
sync_history.detailsin the dashboard; Atlassian visibility in the dashboard.