# The bootstrap algorithm

`farketari bootstrap <target-dir> --example <path> --name <project-name> [--tier <hard|intermediate|easy>]`

Creates a NEW project from the template by REMOVING FEATURES — the inverse of
how the template was built. A project is built one feature at a time; it is
emptied the same way, in reverse. What survives is the architecture (the
bounded contexts with their CQRS split and `event-handlers/` directories, all
three clients with their central API clients and locale infrastructure, the
acceptance harness, the api-server `core/`, the database toolchain, the
Taskfile, the CI pipeline), the INFRASTRUCTURE every project inherits (the
outbox and its SQL, request context, logging, the router shells, the testing
seams), and the KEPT FEATURES with their slices intact. What goes is every
other feature's vertical slice, from its `.feature` file down to its SQL.

## Why feature-shaped, not directory-shaped

Directory-shaped stripping was tried first and failed the same way twice:
directory boundaries do not match feature boundaries. `src/app/` holds the
example app's routes AND the router shell; `queries/` holds its SQL AND the
outbox's. A rule aimed at a directory either eats infrastructure (a hollowed
`PostgresOutbox` that typechecks and then silently drops every event) or
misses app code (banking routes surviving beside the shell). A feature is the
unit the app was actually built in — and the acceptance suites of the KEPT
features are a real check that the removal took the right things, which the
directory rules never had.

## Inputs

- `<target-dir>` — absolute; must not exist, or be an empty directory.
  Bootstrapping never writes into existing work.
- `--example <path>` — the template checkout (same validation as `implement`).
- `--name` — kebab-case; becomes the project's identity everywhere.
- `--tier` *(optional)* — run ALL of the bootstrap's AI steps on one model
  tier: `hard`, `intermediate` or `easy`. Overrides the project's
  farketari.ts policy for this run.

## Steps

1. **COPY** — the whole template tree, minus the copy excludes (VCS state,
   installs, build output, test artifacts, generated native projects).
2. **PLAN** — list every `.feature` file and split it against
   `BootstrapRules.keepFeatures`: the features this project inherits, and the
   ones whose slices go. Keeping nothing to remove is a configuration error,
   not a no-op.
3. **TOOLCHAIN** — install every package's dependencies
   (`toolchain.install`), BEFORE any removal: each removal step needs the
   typecheck to check its own work. Without it a step hand-simulates a
   compiler with grep and scripts and burns its whole turn budget doing what
   `tsc` does in seconds — which is exactly how the first run of this design
   died. A failure here is infrastructure: stop and flag.
4. **REMOVE**, per removed feature:
   - *Deterministic* — every path the feature's NAME owns by convention: the
     `.feature` file, each client's acceptance spec and protocol driver, each
     client's e2e spec, the BFF route directory, and the use-case directory in
     whichever CQRS shape its context uses. Absent paths are normal (a feature
     has a spec only for the clients it targets).
   - *Model step* (`feature-removal`) — the rest of the slice, which does not
     follow the naming convention: the screen or page that rendered it, its
     DSL methods and selector constants, its fake and real backend operations,
     its contract entries, and any domain object, repository method,
     projection, SQL query or schema table that exists ONLY for it. The rule
     is asymmetric — deleting shared code breaks a kept feature and the suites
     catch it; leaving a feature's own code behind is silent — so unclear
     cases are left and reported, never guessed.
5. **STRIP what falls outside the feature grain** — generated output the
   project regenerates from its own contract, the example app's migration
   history (minus the outbox's, which is infrastructure), the hand-written
   smoke journeys, and the template's own descriptor.
6. **IDENTITY** *(model step — `project-identity`)* — the new name in every
   package and title; the global configuration's registrations pruned; the
   shared OpenAPI spec reduced to a valid, empty skeleton; `farketari.ts`
   pointed back at the template. Files that MIX app substance with
   infrastructure (a schema file holding both the app's tables and the
   outbox's) are REDUCED, not emptied.
7. **RECONCILE** *(model fixes, compiler-driven)* — shared wiring
   (Application, UseCaseResolver, route indexes, fake backends, DSL exports)
   still references removed slices. The COMPILER is the worklist: run the
   whole-repo typecheck; while red, remove the dangling reference the output
   names — never by re-creating removed code, and NEVER by hollowing an
   implementation into a no-op that typechecks and then lies at runtime.
   Budgeted (`bootstrapRepairs`).
8. **SWEEP** *(model step — `bootstrap-sweep`)* — fresh eyes hunt what the
   compiler cannot see: the example domain's vocabulary in prose, comments and
   config; orphaned catalogs and selectors. A round's findings are fixed by a
   few PARALLEL sessions — chunked to stay under the turn leash, grouped by
   file so no two sessions own the same file — and every re-sweep receives
   what earlier rounds already handled, so it reports only NEW problems.
   Budgeted (`sweepRounds`, deliberately small).
9. **VERIFY** — the skeleton must be GREEN: the whole-repo typecheck (held by
   step 7), the localization verifier, the backend suite, **the KEPT features'
   own e2e suites**, and every production build. The kept suites are the real
   check: removing something a kept feature needed shows up here as a red
   test, not as a hole a client discovers later.
10. **HAND OFF** — report the location, what survived and what was removed.
    The project's first new feature arrives through `implement`.

During a bootstrap run, catalog commands execute in the target project's root.

## Decisions encoded

- **The operator console is kept; the example app and its iam are not.** The
  feature-flags console is generic infrastructure every project wants, and its
  suites are what prove the bootstrapped skeleton still works. The banking
  features go, and so does the iam login they were built on — a client project
  builds its own users and its own domain. The console's few scenarios that
  needed a product user (allow-user and friends) go with them and return when
  the project implements its own login.
- **Infrastructure is never a leftover, and never faked.** The outbox,
  request context, locale and logging plumbing, database and cache plumbing,
  router shells and testing seams belong to no feature. Every model step in
  the bootstrap is told: delete code, or leave it alone — a body replaced with
  empty arrays, no-ops, zeros or nulls is worse than either.
- **Deterministic where the convention holds, judged where it does not.** The
  naming convention covers most of a slice; the model is spent only on the
  parts that do not follow it, and the compiler plus the kept suites bound it.
