Files
Reactive-Resume/plans/README.md
T

172 lines
10 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.
# Implementation Plans
Generated by the `improve` skill (deep audit) on 2026-07-08, against commit
`73daf22b2`. A deep 8-category read-only audit produced 53 raw findings; after
adversarial verification and manual vetting, the user selected the items below
to turn into executor plans.
Each executor: read your plan fully before starting, honor its STOP conditions,
and update your row when done. Plans are self-contained — you do not need the
audit or this repo's history to execute one.
## Execution order & status
| Plan | Title | Priority | Effort | Risk | Depends on | Status |
|------|-------|----------|--------|------|------------|--------|
| 001 | Characterization tests for the resume service | P1 | M | LOW | — | DONE (branch `advisor/resume-service-improvements`) |
| 002 | CSP + framing headers on web pages; gate uploads CORS | P1 | S | LOW | — | DONE (branch `advisor/security-and-docs`) |
| 003 | Fix silent-success mutations; bound bulk-op inputs | P1 | S | LOW | 001 (soft) | DONE (branch `advisor/resume-service-improvements`) |
| 004 | Correct README "Custom CSS" claim | P3 | S | LOW | — | DONE (branch `advisor/security-and-docs`) |
| 005 | Deduplicate public-resume view-count writes | P2 | M | MED | 001 (soft) | DONE (branch `advisor/resume-service-improvements`) |
| 006 | Font-picker options once; defer font payload | P2 | S | LOW | — | DONE (branch `advisor/font-payload`; Step-1 hoist only — build measurement confirmed the payload already loads only with the PDF chunk, so lazy-loading was correctly skipped) |
| 007 | Extract shared template page-shell — spike + pilot | P2 | L | HIGH | 001 (discipline) | REVERTED from integration (user decision) — spike executed & proved the recipe, but full rollout judged not worth it; Pikachu reverted for template uniformity. Work preserved on branch `advisor/template-shell-spike`. |
Status values: TODO | IN PROGRESS | DONE | BLOCKED (one-line reason) | REJECTED (one-line rationale)
### Recommended order
Independent quick wins first (002, 004), then the tests-first foundation (001)
before the behavior change that depends on it (003) and the caller change with
a safety net (005). 006 is independent and low-leverage — do it anytime. 007
(template refactor) is last and is a **spike + one-template pilot that stops for
review**, not a full rollout.
Fastest safe sequence: **002 → 004 → 001 → 003 → 005 → 006 → 007**.
## Execution results (2026-07-08)
All 7 plans were executed by isolated-worktree executor subagents and reviewed
by the advisor (re-ran every done-criterion, scope-checked, read diffs, audited
tests). All **APPROVED**. Four branches, all based on `73daf22b2`:
| Branch | Plans | Package(s) | Verify (re-run by reviewer) |
|--------|-------|------------|------------------------------|
| `advisor/security-and-docs` | 002, 004 | apps/server, README | typecheck 0; `server` static tests 36/36 |
| `advisor/font-payload` | 006 | apps/web | typecheck 0; web suite 457/457; build 0 |
| `advisor/resume-service-improvements` | 001, 003, 005 | packages/api | typecheck 0; api suite 178/178; boundaries clean |
| `advisor/template-shell-spike` | 007 | packages/pdf | typecheck 0; pdf suite 264/264; boundaries clean; parity snapshot byte-identical pre/post refactor |
**Post-execution decision (user, 2026-07-08):** Local integration branch
`improve-integration` created off `main` with plans **001006 merged**. Plan
**007 was reverted** from it (the spike concluded a full 14-template rollout
isn't worth it — the shell only centralizes layout orchestration, not the
per-template style hooks where most recurring edits land; 6 templates are
single-column and don't fit; consistency argues against a partial rollout). The
`advisor/template-shell-spike` branch is kept if 007 is ever revisited.
Known unrelated red: `packages/api/.../storage/service.test.ts` fails on the
pinned **vitest 4.1.9** (`.rejects.toThrow` matcher `TypeError`, fixed in 4.1.10)
— present on base `main` too, in a file no plan touches; the vitest suite isn't
in CI, so it's latent. Bumping vitest to 4.1.10 clears it (a separate base-repo
concern, left untouched).
**Integration notes for the user (merging is your call — the advisor never merges):**
- The four branches touch **disjoint packages**, so they can be merged in any
order with no cross-branch source conflicts. The only shared file is
`pnpm-lock.yaml`, touched **only** by `advisor/template-shell-spike` — no
lockfile conflict between branches.
- **All commits are unsigned** (`--no-gpg-sign`): the executors ran headless and
the repo's 1Password SSH signer needs interactive auth. Re-sign on merge if
branch protection requires signed commits.
- **007 adds test-only devDeps** (`react-dom`, `@types/react-dom`) to
`packages/pdf` + a `vitest.config.ts` transform tweak — both were required to
build the render-parity snapshot the spike depends on (react-test-renderer,
which the plan suggested, is React-19-incompatible). Accept these consciously.
- **007 is a pilot**: only Pikachu is migrated. The executor's recommended
rollout batches for the other 14 templates (each snapshotted first):
1. sidebar-% family (bronzor, ditto, glalie, leafish; likely kakuna, lapras,
meowth, rhyhorn, scizor — verify two-column shape) — trivial, pass
`sidebarColumnStyle={{ width }}`.
2. flexBasis family (azurill, chikorita) — pass `sidebarColumnStyle={{ flexBasis }}`;
the existing seam already covers it.
3. featured-summary family (ditgar, gengar) — needs a new section-rendering
seam; do NOT force into the current shell.
4. single-column/header-on-top (onyx) — needs a separate shell/layout variant;
the current shell hardcodes the two-column scaffold.
## Dependency notes
- **003 depends softly on 001**: 003 flips the three `setLocked`/`setPassword`/
`removePassword` methods from silent-return to throwing `NOT_FOUND`. If 001 is
DONE, its Step 3 assertions must be updated in 003's PR (that test diff is the
intended proof of the behavior change). If 001 is not done, 003 adds a minimal
test itself.
- **005 depends softly on 001**: 001's Step 5 characterizes
`statistics.increment`; 005 changes the *caller* (dedup), not the write body,
so that test should keep passing — a useful regression signal.
- **007 is not technically blocked** by 001 (the PDF layer needs its own render-
parity net, which 007 builds in Step 1), but 001 should be done first as the
characterization-testing exemplar. 007 explicitly does NOT roll out to all 15
templates; rollout is deferred to reviewed follow-up plans.
## Findings considered and rejected
Recorded so they aren't re-audited next run. (Refuted by adversarial
verification or downgraded during manual vetting against the code.)
- **"Production secrets committed to repository"** — FALSE. `.env.production` /
`.env.local` exist in the working tree but are gitignored (`.env*` with an
`.env.example` exception); 0 commits touch them; not in history.
- **"Vulnerable @better-auth/oauth-provider (unbound resource indicators)"** —
the claimed advisory (GHSA-p2fr-6hmx-4528) could not be verified as real, and
the code already configures `validAudiences`. Treat any `@better-auth/*` bump
as routine, not a security fix.
- **Unauthenticated OAuth2 dynamic client registration bypass** — refuted;
three validation layers exist (registration-time, server preflight,
authorization endpoint).
- **bulkUpdate tag-addition race** — refuted; Postgres row-locking serializes
the `UPDATE ... SET tags = <subquery>` correctly.
- **agent `getThread` missing ownership check** — refuted; the `WHERE` clause
filters `userId` and throws `NOT_FOUND` otherwise.
- **Snapshot throttle "bypassed" by AI patches** — deliberate, documented
design; pruning is atomic and bounded at 30 versions, not a reactive overflow.
Not a bug.
- **Missing index on `(user_id, isPublic)`** — no code path filters resumes by
public status; speculative (YAGNI).
- **Stats daily-series "re-queries every 30 days after cache"** — refuted;
TanStack Query 60s staleTime already dedups.
- **Large composite components / sections.tsx / rich-input / custom-styles
"need splitting"** (ARCH-02/05/06/07) — refuted; each is a single-responsibility
internal-only component with no external reuse; a July-2026 audit already chose
not to split `sections.tsx`.
- **Export paths duplicate filtering (ARCH-03)** — refuted; PDF/DOCX/Markdown
have genuinely different filtering needs, not a shared abstraction being
reinvented.
- **`node-html-parser` major-version lag** — refuted; only stable DOM APIs used,
no breaking-change exposure.
- **PORT not validated in server.ts (DX-03)** — refuted; the server *does* read
`process.env.PORT` in production (`apps/server/src/index.ts:13`).
Downgraded to notes (real but low-leverage; not planned unless revisited):
- **Rich-text HTML not sanitized before react-pdf-html** (SEC-07) — PDF-only
surface (browser path uses `stripHtml`; PDFs don't execute scripts), on the
user's own content. Defense-in-depth only.
- **MCP tools don't validate API-key scopes** (SEC-05) — latent; scoped keys
can't be created yet. Revisit if/when scoped API keys ship.
- **Applications attachment cleanup: concurrent-write orphans + swallowed
`Promise.allSettled` failures** (CORRECT-02/03) — real but low severity for
single-user; storage hygiene + observability. Candidate for a future plan.
- **Agent service is 1397 LOC mixing concerns** (ARCH-04) — real tech debt;
large L-effort refactor, deferred.
- **Core deps pinned to prerelease/snapshot** (drizzle-orm/kit rc, drizzle-zod
snapshot hash, TS native-preview dev build) — watch item; de-risk when stable
releases land. Not urgent (not on the CI/production critical path).
- **Vite `chunkSizeWarningLimit: 10MB`** masks bundle bloat — trivial DX nit.
- **Dev-setup docs vs AGENTS.md `dotenvx` drift** (DX-02) — minor docs friction.
- **Applications bulk O(n) in-memory scan** — the input-cap in Plan 003 bounds
abuse; the scan rewrite is deferred.
## Not audited
Honest coverage gaps from this run:
- E2E/Playwright test behavior and flakiness (relied on CI).
- PDF/DOCX template *rendering* correctness beyond structure (no visual-
regression harness exists).
- Email/notification delivery reliability.
- S3 backup/restore and multi-instance storage behavior.
- The AI provider integration layer's retry/streaming internals.
- Lingui extraction/locale-catalog completeness (separate track).
- Deep dependency transitive-tree audit (worked from manifests + lockfile;
`pnpm audit`/`pnpm outdated` network access was not assumed available).