Verify substrate before proposing new

Verify substrate before proposing new

Before proposing a new table, type, capability, epic, or substrate concept — grep the live codebase + the live backlog for the noun. DPF’s architecture is denser than first reads suggest; the most common reflex of “we’ll need a new X” is wrong because X already exists.

What to grep for, where

When tempted to propose a new substrate:

  1. Prisma schema: grep -n "model NameOfThing" packages/db/prisma/schema.prisma. Many candidate “new tables” turn out to be columns or relations on existing models.
  2. Type unions / enums: grep -rn "type NameOfThing\|enum NameOfThing" packages/types/ apps/web/lib/. Some “new states” are already values in existing string-union types.
  3. Backlog: query the live backlog via mcp__dpf__query_backlog or psql for Epic.title / BacklogItem.title keyword matches. “New” epics often duplicate work already in flight.
  4. Capability registry (packages/db/data/... JSON files): new “we need a capability for X” is usually a column / flag on existing Capability / ServiceOffering / ModelProvider rows.
  5. Spec frontmatter: search docs/superpowers/specs/ for the noun. Frequently the design decision has already been resolved in an APPROVED spec months ago.

Why this exists

Concrete examples:

The contract

Before writing a spec / plan that proposes new substrate:

  1. Grep first, write second.
  2. Note the closest existing fit in the spec — even if you’re rejecting it, the reader needs to know why a new substrate is warranted.
  3. If existing substrate fits with minor extension (a new column, a new enum variant, a new association table) — propose the extension, not a parallel substrate.
  4. If the existing fit is misnamed for the new use, prefer renaming + extending over duplicating. Naming churn is cheap; parallel substrates are expensive forever.

Anti-pattern