Skip to content

dogfood: scaffold guidance should prune unused files/folders, not keep everything #818

Description

@vivek7405

Problem

Asking an agent (via crisp) for a "simple HTML-only single-page hello world, frontend only" produced a working page, but the delivered app tree still carried the ENTIRE full-stack scaffold: the whole db/ layer + drizzle.config.ts + dev.db + db/migrations/, the shadcn UI kit (components/ui/{alert,badge,button,card,input,label,separator}.ts + components.json + components/theme-toggle.ts), lib/utils/{cn,ui}.ts, an empty modules/, the opt-in service worker (public/sw.js + public/offline.html), the example test/ (which tests the now-replaced scaffold page), and the db:* package scripts. None of it is used by a static hello world.

The scaffold is full-stack by design, so it ships all of this wired up. The gap is that nothing tells the agent to PRUNE what the requested app does not use, and worse, the scaffold's own guidance actively says to KEEP it:

packages/cli/templates/CONVENTIONS.md item 6: "Keep: the Drizzle setup, the test config, ... db/connection.server.ts + db/columns.server.ts ..."

That contradicts the rule two paragraphs above ("the delivered app must contain only what the user asked for, never leftover scaffold code"). For a frontend-only app the "keep the Drizzle setup / test config" instruction is exactly wrong. This affects EVERY agent/platform, not just crisp, so it belongs in the scaffold guidance (a crisp-side prompt reinforcement is filed separately).

Note: elision only strips SHIPPED bytes from the browser, not on-disk files, so it does not address this; the delivered file TREE is what the user sees.

Design / approach

Pruning does not remove the agent's how-to-use-webjs context, and this must be stated in the guidance. The scaffold teaches webjs through two layers: (1) DURABLE KNOWLEDGE (AGENTS.md, CONVENTIONS.md, the per-agent rule files, the MCP) which is in the KEEP list and is never pruned, so a pruned app still ships the full how-to-use-webjs context for the next iteration; and (2) EXAMPLE CODE, which is reference to mimic and then replace/prune. Pruning only ever removes unused layer-2 example code, never layer-1 knowledge. So this issue and the scaffold-as-context work (see the umbrella issue this links to) are complementary, not in tension. Two ordering rules the guidance must make explicit: prune AFTER the agent has read/used the examples as reference (never delete blindly up front), and NEVER prune the knowledge surfaces (they are the durable context).

Reframe the keep-vs-prune guidance from "keep the infrastructure" to "keep the infrastructure the app USES; delete the rest (files AND folders)." Give a concrete prune map keyed on what the app needs:

  • No persistence -> delete db/ (schema, connection, columns, migrations/, dev.db), drizzle.config.ts, the db:* scripts in package.json, and the webjs.dev.before / webjs.start.before webjs db migrate step.
  • No shadcn UI kit used -> delete components/ui/, components.json, and lib/utils/cn.ts + lib/utils/ui.ts (only the UI kit consumes them).
  • No theme picker -> delete components/theme-toggle.ts.
  • No PWA -> delete public/sw.js + public/offline.html.
  • Empty modules/ -> remove the empty folder (or, per dogfood: close first-pass friction found building a full-stack app #817, replace the seeded example) rather than shipping an empty dir.
  • The example test/ tests the scaffold page; replace it with the app's real tests or remove it.
  • Keep: public/tailwind-browser.js if Tailwind classes are used, the design tokens in app/layout.ts, the agent config files, tsconfig.json, and the deploy files (Dockerfile / compose.yaml).

Optional tooling angle (higher leverage than docs alone): a webjs doctor advisory that flags likely-unused scaffold artifacts, e.g. db/ present but no .server.ts query/action imports it, components/ui/* present but never imported, public/sw.js present but not registered, an empty modules/. That gives the agent a concrete removable checklist instead of relying on it to remember.

Do NOT add a new "static/SPA" template (frontend-only SPA is deliberately deferred, #462); the fix is prune-guidance + optional advisory on the existing full-stack default.

Implementation notes (for the implementing agent)

  • Edit the keep/prune guidance in lockstep across all 5 prose surfaces: packages/cli/templates/CONVENTIONS.md (item 6 "Keep:" -> a keep-what-you-use + prune-the-rest map), packages/cli/templates/AGENTS.md (the scaffold-reference paragraph, ~L10-29), and the three per-agent rule files (.cursorrules, .github/copilot-instructions.md, .agents/rules/workflow.md), which each carry the "scaffold is reference" bullet.
  • Landmine: keep the guidance UI/persistence-CONDITIONAL. Do not tell an agent building a real full-stack app to delete db/; the prune is "delete what THIS app does not use." The current item 6 is unconditional-keep; the fix is conditional.
  • Landmine (invariant 11): prose-punctuation rules apply to all edits.
  • If adding the webjs doctor advisory: the elision/report machinery lives in packages/server/src/elision-report.js + component-elision.js; a "likely-unused scaffold artifact" advisory is a NEW, separate report (a static-file + import-graph check), with a test in packages/server/test/ (or packages/cli/test/ if implemented in the CLI). Report-only, never auto-delete (webjs does not delete app files).
  • Docs surfaces to sync: the docs site getting-started/scaffold page if it restates the keep guidance; agent-docs/*.md if any mention it. Related: dogfood: close first-pass friction found building a full-stack app #817 (first-pass friction) touches the same scaffold-guidance surfaces, so coordinate wording.
  • Related: crisp build-agent prompt reinforcement is a separate issue on vivek7405/crisp (linked from here once filed).

Acceptance criteria

  • The scaffold guidance tells agents to keep only the infrastructure the app uses and delete the rest (files AND folders), with a concrete prune map, in all 5 prose surfaces in lockstep.
  • The "Keep: the Drizzle setup / test config" unconditional wording is replaced with a conditional keep-what-you-use version.
  • (Optional) webjs doctor flags likely-unused scaffold artifacts (db/components-ui/sw/empty-modules) with a test + counterfactual.
  • A real full-stack app is NOT told to delete db/ (the prune is conditional on non-use).
  • Scaffold + template tests still pass.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions