--- phase: 08-stack-upgrade-backend-decomposition plan: 08 type: execute wave: 3 depends_on: [08-04, 08-05, 08-06, 08-07] files_modified: - frontend/package.json - frontend/package-lock.json - frontend/tailwind.config.js - backend/requirements.txt autonomous: false requirements: [PERF-01] tags: [dependencies, perf, requirements-pinning, vite-6, tailwind-forms] user_setup: - service: npm-registry-verification why: "Two PERF-01 packages are install-only verified; the rest must be manually verified on npmjs.com because slopcheck was unavailable at research time" dashboard_config: - task: "Verify @vueuse/core, @vueuse/integrations, sortablejs, @tailwindcss/forms, rollup-plugin-visualizer, @types/sortablejs, vite, @vitejs/plugin-vue on npmjs.com — each must show legitimate maintainer, weekly downloads > 10k, and no recent malware advisories" location: "npmjs.com/package/{name}" must_haves: truths: - "frontend/package.json declares all PERF-01 packages at the locked version constraints" - "frontend/tailwind.config.js wires the @tailwindcss/forms plugin so VISUAL-02 in Phase 11 can rely on its base styles" - "frontend/vite.config.js works with vite@^6.4.3 (no breaking changes apply per RESEARCH.md analysis)" - "backend/requirements.txt uses exact == pins for every package (no floating >= ranges)" - "cd backend && pytest -v exits 0 (no regression from pinning)" - "cd frontend && npm install completes cleanly with no peer-dep warnings on vite ↔ @vitejs/plugin-vue" - "cd frontend && npm run build succeeds with the new Vite 6" artifacts: - path: "frontend/package.json" provides: "Updated dependency manifest with PERF-01 packages" contains: "@vueuse/core" - path: "frontend/tailwind.config.js" provides: "Tailwind config with @tailwindcss/forms plugin wired" contains: "@tailwindcss/forms" - path: "backend/requirements.txt" provides: "Exact-pinned backend dependency list per D-17" contains: "fastapi==" key_links: - from: "frontend/tailwind.config.js" to: "@tailwindcss/forms" via: "plugins array" pattern: "plugins:.*forms" - from: "frontend/package.json" to: "vite, @vitejs/plugin-vue, @vueuse/core, sortablejs, @tailwindcss/forms, rollup-plugin-visualizer" via: "dependencies / devDependencies" pattern: "(vite|@vueuse|sortablejs|@tailwindcss/forms|rollup-plugin-visualizer)" --- Land PERF-01: bump Vite 5 → 6 (and its plugin), install the new frontend packages (`@vueuse/core`, `@vueuse/integrations`, `sortablejs`, `@tailwindcss/forms`, `rollup-plugin-visualizer`, `@types/sortablejs`), wire `@tailwindcss/forms` into `tailwind.config.js`, and pin `backend/requirements.txt` from floating `>=` ranges to exact `==` pins per D-17. Includes a blocking human checkpoint to manually verify the 8 npm packages on npmjs.com because slopcheck was unavailable at research time. Purpose: PERF-01 plus the reproducibility benefit of exact pinning. Tailwind plugin wiring is required NOW so Phase 11's VISUAL-02 can rely on `@tailwindcss/forms` base styles being active. Output: Updated `package.json`, `package-lock.json`, `tailwind.config.js`, and `requirements.txt`. @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/08-stack-upgrade-backend-decomposition/08-CONTEXT.md @.planning/phases/08-stack-upgrade-backend-decomposition/08-RESEARCH.md @frontend/package.json @frontend/vite.config.js @frontend/tailwind.config.js @backend/requirements.txt PERF-01 package set (locked): dependencies (production): vue ^3.5.0 (currently 3.5.34 — already satisfies; no install needed but bump declared range) @vueuse/core ^14.3.0 (install) @vueuse/integrations ^14.3.0 (install) sortablejs ^1.15.7 (install) @tailwindcss/forms ^0.5.11 (install + wire in tailwind.config.js) devDependencies: vite ^6.4.3 (upgrade from ^5.2.0) @vitejs/plugin-vue ^6.0.7 (upgrade from ^5.0.0 — required for Vite 6 compatibility) rollup-plugin-visualizer ^7.0.1 (install — Phase 11 wires it into vite.config.js for PERF-02 bundle analysis) @types/sortablejs latest (install — TypeScript types for sortablejs) tailwind.config.js wiring (per @tailwindcss/forms docs): /** @type {import('tailwindcss').Config} */ import forms from '@tailwindcss/forms' export default { content: ['./index.html', './src/**/*.{vue,js}'], theme: { extend: {} }, plugins: [forms], } backend/requirements.txt: convert every `>=` constraint to `==` using the currently installed version per D-17. RESEARCH.md confirmed installed versions for: fastapi==0.128.8, anthropic==0.104.0, sqlalchemy[asyncio]==2.0.49, psycopg[binary]==3.2.13, alembic==1.16.5 (note: lower than the previous floating min of 1.18.4 — pin to INSTALLED per D-17), celery[redis]==5.6.3, PyJWT==2.13.0, cryptography==48.0.0, structlog==25.5.0. All other packages tagged [ASSUMED] in RESEARCH.md — discover their installed version via `pip show ` during execution. Task 1: Package Legitimacy Checkpoint — manually verify 8 npm packages on npmjs.com The researcher tagged all 8 PERF-01 npm packages as [ASSUMED] because slopcheck was unavailable in the research environment. Before any install runs, manually verify on npmjs.com that each package is legitimate. For each package below, open the link, check (a) maintainer is a known org or individual not a fresh account, (b) weekly downloads > 10,000, (c) no malware advisory banner, (d) most recent publish date is reasonable (not "1 day ago" for an established lib), (e) the GitHub repo linked in "Repository" exists and is active: 1. https://www.npmjs.com/package/vite — expect: vitejs maintainer org; millions of weekly downloads 2. https://www.npmjs.com/package/@vitejs/plugin-vue — expect: vitejs org; millions of weekly downloads 3. https://www.npmjs.com/package/@vueuse/core — expect: antfu/vueuse maintainer; millions of weekly downloads 4. https://www.npmjs.com/package/@vueuse/integrations — expect: antfu/vueuse maintainer 5. https://www.npmjs.com/package/sortablejs — expect: SortableJS org; millions of weekly downloads 6. https://www.npmjs.com/package/@tailwindcss/forms — expect: tailwindlabs org 7. https://www.npmjs.com/package/rollup-plugin-visualizer — expect: btd/btmurrell maintainer; hundreds of thousands weekly 8. https://www.npmjs.com/package/@types/sortablejs — expect: DefinitelyTyped org If any package fails any check, ABORT and re-evaluate the package choice with the project owner. Type "approved" to proceed with installs, or list any rejected package by name. Task 2: Install PERF-01 frontend packages and wire @tailwindcss/forms frontend/package.json, frontend/package-lock.json, frontend/tailwind.config.js - frontend/package.json (current dependency versions) - frontend/tailwind.config.js (currently `plugins: []` with no extensions) - frontend/vite.config.js (confirm it has no custom `resolve.conditions` — RESEARCH.md verified Vite 6 migration is clean for this minimal config) Run two npm install commands in `frontend/`: cd frontend && npm install vue@^3.5.0 @vueuse/core@^14.3.0 @vueuse/integrations@^14.3.0 sortablejs@^1.15.7 @tailwindcss/forms@^0.5.11 cd frontend && npm install -D vite@^6.4.3 @vitejs/plugin-vue@^6.0.7 rollup-plugin-visualizer@^7.0.1 @types/sortablejs These two commands update both `package.json` (declared ranges) and `package-lock.json` (resolved exact versions). Do NOT install `vue@^3.5.0` separately if npm warns the existing 3.5.34 satisfies the new range — the bump-then-deduplicate behavior is automatic. After npm install completes, modify `frontend/tailwind.config.js` to wire the forms plugin. The CURRENT file uses ESM with `export default`. Update it to: /** @type {import('tailwindcss').Config} */ import forms from '@tailwindcss/forms' export default { content: ['./index.html', './src/**/*.{vue,js}'], theme: { extend: {} }, plugins: [forms], } Do NOT modify `frontend/vite.config.js` — RESEARCH.md verified the existing config is compatible with Vite 6 (no `resolve.conditions`, no Sass, no library mode). `rollup-plugin-visualizer` is installed but NOT wired into `vite.config.js` yet — Phase 11's PERF-02 will wire it when bundle measurements are taken. After config wiring: run `cd frontend && npm test` to confirm tests still pass on Vite 6, then `cd frontend && npm run build` to confirm a clean production build. If either fails, diagnose and fix before proceeding. cd frontend && grep -c '"vite": "\\^6' package.json && grep -c '"@vitejs/plugin-vue": "\\^6' package.json && grep -c '"@vueuse/core": "\\^14' package.json && grep -c '"sortablejs"' package.json && grep -c '"@tailwindcss/forms"' package.json && grep -c '"rollup-plugin-visualizer"' package.json && grep -c "@tailwindcss/forms" tailwind.config.js && grep -c "plugins: \\[forms\\]" tailwind.config.js && npm test 2>&1 | tail -5 && npm run build 2>&1 | tail -5 - `grep -c '"vite": "\^6' frontend/package.json` returns 1 - `grep -c '"@vitejs/plugin-vue": "\^6' frontend/package.json` returns 1 - `grep -c '"@vueuse/core": "\^14' frontend/package.json` returns 1 - `grep -c '"@vueuse/integrations": "\^14' frontend/package.json` returns 1 - `grep -c '"sortablejs": "\^1.15' frontend/package.json` returns 1 - `grep -c '"@tailwindcss/forms": "\^0.5' frontend/package.json` returns 1 - `grep -c '"rollup-plugin-visualizer": "\^7' frontend/package.json` returns 1 - `grep -c '"@types/sortablejs"' frontend/package.json` returns 1 - `grep -c "import forms from '@tailwindcss/forms'" frontend/tailwind.config.js` returns 1 - `grep -c "plugins: \[forms\]" frontend/tailwind.config.js` returns 1 - `cd frontend && npm test` exits 0 - `cd frontend && npm run build` exits 0 - `cd frontend && npm list vite | grep -c "vite@6"` returns at least 1 All PERF-01 packages installed; tailwind forms plugin wired; tests + production build pass on Vite 6. Task 3: Pin backend/requirements.txt to exact installed versions (D-17) backend/requirements.txt - backend/requirements.txt (current floating-range constraints) - .planning/phases/08-stack-upgrade-backend-decomposition/08-RESEARCH.md §"requirements.txt: Exact Pinning (D-17)" (already-verified versions: fastapi==0.128.8, anthropic==0.104.0, sqlalchemy[asyncio]==2.0.49, psycopg[binary]==3.2.13, alembic==1.16.5, celery[redis]==5.6.3, PyJWT==2.13.0, cryptography==48.0.0, structlog==25.5.0) For each package in `backend/requirements.txt` that is tagged [ASSUMED] in RESEARCH.md (uvicorn, python-multipart, pydantic-settings, pydantic, openai, PyMuPDF, python-docx, pytesseract, Pillow, aiofiles, httpx, pytest, pytest-asyncio, minio, redis, aiosqlite, pwdlib, pyotp, slowapi, google-auth-oauthlib, google-api-python-client, msal, webdavclient3, cachetools), run `cd backend && pip show 2>/dev/null | grep '^Version:'` to capture the installed version. If a package returns no output (not installed in the local env), run `cd backend && python -c "import importlib.metadata as m; print(m.version(''))"` as a fallback. Record each version. Then rewrite `backend/requirements.txt` so every line uses an exact `==` pin. Preserve the existing section comments (e.g. "# Cloud Storage Backends (Phase 5)", "# Observability (Phase 6 — D-01)"). For the already-verified packages from RESEARCH.md, use the locked versions: fastapi==0.128.8, anthropic==0.104.0, sqlalchemy[asyncio]==2.0.49, psycopg[binary]==3.2.13, alembic==1.16.5, celery[redis]==5.6.3, PyJWT==2.13.0, cryptography==48.0.0, structlog==25.5.0. For everything else, use the version captured by `pip show`. If `alembic` is shown as 1.16.5 (lower than the previous floating min of 1.18.4), pin to 1.16.5 per D-17 — but also append a single-line comment immediately before the alembic line: `# alembic pinned to currently-installed 1.16.5 (was >=1.18.4); D-17 mandates pinning to installed`. After rewriting, run `cd backend && pip install -r requirements.txt --dry-run 2>&1 | tail -20` to confirm pip considers the file valid and all pins are satisfiable. Then run `cd backend && pytest -v` to confirm no regression from re-resolving deps. cd backend && grep -cE '>=' requirements.txt; cd backend && grep -cE '==' requirements.txt; cd backend && pip install -r requirements.txt --dry-run 2>&1 | tail -5; cd backend && pytest -v --tb=no -q 2>&1 | tail -5 - `grep -c '^[^#].*>=' backend/requirements.txt` returns 0 (every non-comment line uses == or is bare) - `grep -cE '^[a-zA-Z][a-zA-Z0-9_.\\[\\]-]*==' backend/requirements.txt` returns at least 30 (count of pinned packages — file has ~32 packages) - `grep -c "^fastapi==0.128.8" backend/requirements.txt` returns 1 - `grep -c "^alembic==1.16.5" backend/requirements.txt` returns 1 - `grep -c "^sqlalchemy\\[asyncio\\]==2.0.49" backend/requirements.txt` returns 1 - `grep -c "^PyJWT==2.13.0" backend/requirements.txt` returns 1 - `grep -c "^cryptography==48.0.0" backend/requirements.txt` returns 1 - `grep -c "alembic pinned to currently-installed" backend/requirements.txt` returns 1 - `cd backend && pytest -v` exits 0 with no new failures vs. baseline - `cd backend && pip install -r requirements.txt --dry-run` reports no resolution conflicts (exit 0) requirements.txt fully pinned with == ; alembic discrepancy commented; pytest still green. ## Trust Boundaries | Boundary | Description | |----------|-------------| | npmjs.com → frontend node_modules | Supply chain: any of the 8 packages could be malicious if a name was typosquatted or a maintainer account was compromised | | pypi.org → backend venv | Same supply-chain consideration for any unpinned package; D-17 pinning narrows the attack window | | Vite 6 build pipeline → bundled JS | Major version bump may introduce regressions; npm test + production build verify integrity | ## STRIDE Threat Register | Threat ID | Category | Component | Disposition | Mitigation Plan | |-----------|----------|-----------|-------------|-----------------| | T-08-08-01 | Supply Chain (Tampering) | 8 npm package installs | mitigate | Blocking human checkpoint (task 1) requires manual npmjs.com verification because slopcheck was unavailable; gate flagged blocking-human and never auto-approvable. T-{phase}-SC retained per Package Legitimacy Gate protocol. | | T-08-08-02 | Tampering | Vite 6 migration breaking behavior | mitigate | RESEARCH.md analyzed all Vite 5→6 breaking changes against the project's `vite.config.js` and confirmed none apply (no custom `resolve.conditions`, no Sass, no library mode); npm test + npm run build acceptance criteria verify post-install. | | T-08-08-03 | Information Disclosure | requirements.txt leaks installed versions | accept | Versions are not secrets; reproducibility benefit outweighs disclosure | | T-08-08-04 | Denial of Service | alembic 1.16.5 lower than 1.18.4 | mitigate | D-17 mandates pinning to installed; the inline comment documents the discrepancy so a future developer can decide to bump deliberately | | T-08-08-05 | Tampering | @vitejs/plugin-vue peer-dep mismatch | mitigate | Both vite@^6 and @vitejs/plugin-vue@^6 installed in same `npm install -D` command per RESEARCH.md §Pitfall 6 | | T-08-08-SC | Supply Chain | npm packages [ASSUMED] | mitigate | Blocking human checkpoint (task 1) is the gate; checkpoint is blocking-human and cannot be auto-approved | - `cd frontend && npm test` — zero failures - `cd frontend && npm run build` — succeeds with Vite 6 - `cd frontend && npm list vite @vitejs/plugin-vue @vueuse/core @vueuse/integrations sortablejs @tailwindcss/forms rollup-plugin-visualizer @types/sortablejs` — all listed - `cd backend && pytest -v` — zero failures - `cd backend && pip install -r requirements.txt --dry-run` — no resolution errors - `grep -v '^#' backend/requirements.txt | grep -cE '>='` returns 0 (no remaining floating constraints in production-package lines) - 8 PERF-01 packages installed and verified - `@tailwindcss/forms` wired in tailwind.config.js (ready for Phase 11 VISUAL-02) - Vite 6 production build succeeds - backend/requirements.txt fully `==` pinned per D-17 - All tests pass - Human checkpoint approved on npm package legitimacy Create `.planning/phases/08-stack-upgrade-backend-decomposition/08-08-SUMMARY.md` when done. Include: (a) before/after `package.json` dependency table, (b) full pinned `requirements.txt` content, (c) the human checkpoint approval timestamp and any package that required follow-up.