route-group-decisionlisted
Install: claude install-skill voidcorp-core/void-harness
# route-group-decision
Use when adding any new route in `app/`, or when refactoring an existing flat `app/` into groups. Route groups (folders named `(name)`) don't affect URL but DO affect layout and convention scope.
## The void-harness convention
```
app/
├── (api|actions)/ # trust boundaries (Server Actions, route handlers)
│ ├── (actions)/<feature>/
│ └── (api)/<resource>/route.ts
├── (marketing)/ # public, statically rendered, no auth
│ ├── layout.tsx # marketing nav + footer
│ ├── page.tsx # /
│ ├── pricing/page.tsx # /pricing
│ └── blog/[slug]/page.tsx
├── (app)/ # authenticated app
│ ├── layout.tsx # auth gate + app shell
│ ├── dashboard/page.tsx
│ └── settings/page.tsx
└── api/webhooks/<source>/route.ts # webhooks NOT in (api|actions) — different lifecycle
```
The principle: **group by trust boundary and rendering model, not by visual section**.
## Why these specific groups
- `(api|actions)` — every file inside is a trust boundary. The skill `harness-server:server-action` applies. The "no fetch in components" rule applies in reverse: these files MUST fetch / mutate.
- `(marketing)` — statically renderable (Cache Components opted in by default), no auth, indexable by search engines. Different layout (marketing nav vs app shell).
- `(app)` — authenticated. Layout checks session, redirects to login if absent. All routes inside trust the layout's auth gate.
- `api/webhooks/<source>/` — NOT