Skip to content

Reviewer: senior-staff (fast pass). Scope: /home/ta/projects/monorepo/.

1. packages/components is a phantom package — no site consumes it as a workspace dep

Section titled “1. packages/components is a phantom package — no site consumes it as a workspace dep”
  • What: packages/components/package.json declares @smart-debt/components with exports for ./ui/* and ./layout/*, and contains 22 UI components + a layout/ dir. But zero sites or apps depend on @smart-debt/components in their package.json, and no source file imports from that specifier. Consumption happens via TS path aliases (@components/ui/* in sites/template/tsconfig.json) and Vite resolve aliases (sites/template/astro.config.mjs, sites/sdc/astro.config.mjs) that bypass pnpm entirely and reach into ../../packages/components/src/ directly.
  • Where: packages/components/package.json, sites/template/tsconfig.json, sites/template/astro.config.mjs, sites/sdc/astro.config.mjs.
  • Why it matters: The package’s name, exports, and version are dead metadata — they imply a published/consumable contract that doesn’t exist. New brand sites (e.g. sites/mbr/) won’t get components unless they manually replicate both the tsconfig path and the Vite alias (sdc only configures the Vite alias, not tsconfig — sdc is inconsistent with template). When you eventually extract to a real package or change folder layout, the silent path-alias coupling will break in non-obvious ways.
  • Fix: Pick one model and enforce it. Either (a) make it a real workspace package: add "@smart-debt/components": "workspace:*" to each consumer’s deps, drop the path aliases, and import via @smart-debt/components/ui/Card.astro; or (b) delete the name/exports from packages/components/package.json, treat it as a content folder, and document the alias pattern. Option (a) is the right call — matches the @smart-debt/design-tokens pattern already in use.

2. sdc consumes shared components via Vite alias only — no matching tsconfig path

Section titled “2. sdc consumes shared components via Vite alias only — no matching tsconfig path”
  • What: sites/sdc/astro.config.mjs defines @components resolve alias, but sites/sdc/tsconfig.json does NOT include @components/* paths. Template has both; sdc has only the runtime alias.
  • Where: sites/sdc/tsconfig.json vs sites/sdc/astro.config.mjs:resolve.alias.
  • Why: Editor/astro check will not resolve @components/... imports in sdc — type checks will fail or fall back to any. Pre-production this becomes silent type erosion.
  • Fix: Add the same paths block to sites/sdc/tsconfig.json as in template (and sites/mbr/tsconfig.json if mbr ever consumes shared components).

3. apps/sd-app and packages/sd-api are not wired — polyglot boundary is undefined

Section titled “3. apps/sd-app and packages/sd-api are not wired — polyglot boundary is undefined”
  • What: Grepping apps/sd-app/src/ for sd-api, sd_api, sdApi returns nothing. The SvelteKit PWA does not call the Python FastAPI service. packages/sd-api/ (Python, FastAPI: main.py, router.py, db.py) exists in isolation.
  • Where: apps/sd-app/src/, packages/sd-api/.
  • Why: Either (a) the app duplicates math logic that lives in packages/sd-math/ (Python) — meaning the JS side has its own copy or stubs; or (b) the API is dormant/unused. Either way, there’s no contract (no OpenAPI client, no shared schema package, no fetch wrapper) so when one side moves the other breaks silently.
  • Fix: Decide the boundary now, before prod: (i) Generate a TS client from FastAPI’s OpenAPI schema into a new packages/sd-api-client/, or (ii) if sd-api is not yet used, mark it explicitly as not-yet-wired in packages/sd-api/README.md. Add an integration smoke test that fails loudly if the contract drifts.

4. sites/template/sites/ nested dir — leftover artifact

Section titled “4. sites/template/sites/ nested dir — leftover artifact”
  • What: sites/template/sites/sdc.com/node_modules/sharp/ exists inside the template site. The dir is gitignored (.gitignore line 21) so it’s not committed, but it persists on disk and signals an old pnpm install was run from the wrong cwd, or a prior nested structure.
  • Where: sites/template/sites/sdc.com/.
  • Why: Confuses tooling (find, astro check with broad globs), inflates dev-machine size, and the fact that .gitignore explicitly lists sites/template/sites/ shows this is recurring. Recurring artifacts in .gitignore usually mean a tool config is wrong somewhere.
  • Fix: rm -rf sites/template/sites/. Find what creates it (likely an old script or a Wrangler/Pages config invoking pnpm with wrong cwd) and fix the source. Once fixed, remove the line from .gitignore.

5. README is stale and inflates capability

Section titled “5. README is stale and inflates capability”
  • What: Root README.md claims “92 Components” and “681+ Tests”, lists sdc.com/ as a folder (actual name: sdc/), and uses Template/ capitalization (actual: template/). It does not mention sites/mbr/ (which exists) or packages/{i18n,sd-api,sd-math}/.
  • Where: README.md.
  • Why: Onboarding (yours or future contributor’s) starts from a wrong mental model. The capitalization mismatch (Template/ vs template/) is a real bug on case-sensitive Linux/CI.
  • Fix: Rewrite Project Structure section against ls sites/ apps/ packages/. Replace component/test counts with pnpm commands that report them, or drop the numbers.

6. packages/sd-math/ contains stale planning docs in src root

Section titled “6. packages/sd-math/ contains stale planning docs in src root”
  • What: Six cursor-task-*.md files plus asset-history-design.md and a CLEANUP.md saying “When done, can purge…” live at packages/sd-math/ top level (not in docs/ or archive/).
  • Where: packages/sd-math/cursor-task-*.md, packages/sd-math/CLEANUP.md.
  • Why: Violates your own CLAUDE.md rule (“Specs and design docs go in KB, not repos”). Mixes ephemeral task scaffolding with shippable package source.
  • Fix: Move to KB (D:\FSS\KB\Business\_WorkingOn\Projects\monorepo\archive\) or delete. The CLEANUP.md itself says to purge.

7. AI tooling config sprawl — .cursor, .gemini, .obsidian, .claude, .agent at multiple levels

Section titled “7. AI tooling config sprawl — .cursor, .gemini, .obsidian, .claude, .agent at multiple levels”
  • What: 11 tool-config dirs across the repo, including duplicates at both root and sites/template/ levels (.claude x2, .cursor x2, .obsidian x2). docs/.obsidian and sites/template/.obsidian — Obsidian state inside a code repo.
  • Where: Root, sites/template/, docs/, sites/sdc/.vscode.
  • Why: Two .claude/ dirs means project context can fight (root project memory vs site-level). Obsidian state in docs/ indicates the docs folder is being treated as a vault — fine, but commit hygiene is risky (.obsidian/workspace.json changes on every open).
  • Fix: Decide which configs should be committed vs gitignored. Likely: keep root .claude/ and .cursor/ only; gitignore (and remove if tracked) the per-site duplicates and all .obsidian/. Run git ls-files | grep -E '\.(obsidian|gemini|agent)/' to see what’s tracked.

8. tsconfig drift — root tsconfig.json paths don’t match site tsconfigs

Section titled “8. tsconfig drift — root tsconfig.json paths don’t match site tsconfigs”
  • What: Root tsconfig.json defines "@components/*": ["packages/components/*"] (note: packages/components/*, not packages/components/src/*). Site-level tsconfigs use ["../../packages/components/src/ui/*"]. Root has no extends, no strict, no target — it’s effectively a stub.
  • Where: tsconfig.json (root).
  • Why: If any tool reads the root tsconfig (e.g., ESLint’s parser, IDE in monorepo-wide mode), imports will resolve to the wrong dir. The root tsconfig is doing nothing useful and is misleading.
  • Fix: Either delete the root tsconfig (sites extend astro/tsconfigs/strict directly) or make it the genuine base with shared compilerOptions and consistent paths, and have site configs extends: "../../tsconfig.json".

9. archive/brand-assets-2025-12-22/ in repo

Section titled “9. archive/brand-assets-2025-12-22/ in repo”
  • What: archive/ contains old brand assets. Git log shows 2 commits.
  • Where: archive/.
  • Why: Repo bloat; should live in KB or be a tagged release artifact, not in working tree.
  • Fix: Move to KB or rely on git history; delete from working tree.

10. mbr site does not declare @smart-debt/design-tokens dependency

Section titled “10. mbr site does not declare @smart-debt/design-tokens dependency”
  • What: sites/template and sites/sdc declare "@smart-debt/design-tokens": "workspace:*". sites/mbr does not.
  • Where: sites/mbr/package.json.
  • Why: If mbr ever needs design tokens (likely, given it has brand components), it’ll be a one-off oversight.
  • Fix: Add the workspace dep proactively, or document deliberately that mbr is fully brand-isolated.

11. sd-api package has no package.json-style metadata visible alongside Python tooling

Section titled “11. sd-api package has no package.json-style metadata visible alongside Python tooling”
  • What: packages/sd-api/pyproject.toml exists; good. But pnpm-workspace.yaml includes packages/* — pnpm will scan sd-api and sd-math for package.json and silently skip. Not a bug, just a quirk to be aware of.
  • Where: pnpm-workspace.yaml.
  • Why: Polyglot pnpm workspaces work but obscure intent.
  • Fix: Document in root README that packages/{sd-api,sd-math} are Python (uv) packages, not pnpm.

12. Astro versions aligned (^5.15.3 across template/sdc/mbr) — good

Section titled “12. Astro versions aligned (^5.15.3 across template/sdc/mbr) — good”
  • No action. Note it as a strength.

Biggest issue is #1 — the shared components package is consumed by alias instead of as a proper workspace dep, so its exports contract is fiction. #3 is the strategic risk for production: no defined boundary between the SvelteKit app and the Python API. #5 (stale README) is the lowest-effort, highest-trust fix.