--- import { notBuiltFor, assertScopeNonEmpty } from '../data/notBuilt.mjs'; /** * The deliberate absences (PLAN.md §2, D22), rendered for one page's scope. * * §2 describes its absent-features list as "as load-bearing as the rest", and this is the * component that makes that true on a page rather than in a plan. It reads the shared list * so `/features/`, `/integrations/` and `/modules/` cannot drift into telling three * different stories about the same six things. * * --------------------------------------------------------------------------------------- * WHY IT LOOKS LIKE THE REST OF THE PAGE * --------------------------------------------------------------------------------------- * Not a warning box, not a muted footnote, not an accordion. D8's "understated honesty" is * a house style with a specific consequence here: a section that is visually apologetic * teaches a reader that absences are embarrassing, and a section that is visually hidden * teaches them to go looking for the ones you did not mention. These are decisions with * reasons, so they are set as decisions with reasons — the same panels as everything else, * in the same place in the rhythm. * * The one visual difference is the `resolvedBy` line, which every entry carries. An absence * with an exit condition is a position; an absence without one is a hole. D8 gives the * Integration Kit's draft status a defined removal condition and this generalises it. */ interface Props { /** Which page is asking: `features`, `integrations` or `modules`. */ scope: string; /** Section heading. Each page frames the same list for its own reader. */ title: string; } const { scope, title } = Astro.props; assertScopeNonEmpty(scope); const entries = notBuiltFor(scope); ---

Not built

{title}

Every one of these is a decision rather than a backlog item, so each says why. Where the reasoning was written down in the open, it is linked.