> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackra.figentra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Member standards

> What every app, package and service must contain, and which check enforces each rule.

A member is anything `pnpm-workspace.yaml` lists: `apps/*`, `packages/<category>/<name>`, `services/*`. The rules on this page apply to all of them. Kind-specific shape lives on [Packages](/standards/packages), [Services](/standards/services) and [Apps](/standards/apps).

## Required files

| File | Holds |
| - | - |
| `package.json` | The manifest fields below; scripts from the [task vocabulary](/guides/tooling) |
| `turbo.jsonc` | `{ "extends": ["//"], "tags": ["tier:<x>"] }` with exactly one tier tag |
| `tsconfig.json` | Extends one `@stackra/typescript-config/<preset>` and nothing else |
| `README.md` | What it is, a tasks table of its scripts, the structure of `src/`, how to run it |
| `AGENTS.md` | Where code goes, rules that fail the build, tasks, and a mandatory `## PII` table |
| `CHANGELOG.md` | `# <package name>` and a note that Changesets writes it; never hand-edited |
| `LICENSE` | A byte-for-byte copy of the root `LICENSE`: a licence travels with the artifact |

A member with a build or tests also carries `vitest.config.ts` (extends a `@stackra/vitest-config` preset) and `tsdown.config.ts` (when `build` is `tsdown`), each starting with the [file contract](/standards/code-style#file-contract). All source lives in `src/`.

### The PII table

`AGENTS.md` always has a `## PII` section with the columns `Data`, `Where`, `Handling`. A member that handles no personal data says so and names the change that would make it revisit the answer:

```md theme={"system"}
## PII

| Data | Where | Handling                                                                    |
| ---- | ----- | --------------------------------------------------------------------------- |
| None | —     | Handles no personal data yet. Revisit when it stores or receives user data. |
```

Presence of the heading is checked; whether the table is still true is a review obligation (security reviewer, see [Security](/constitution/security)).

## `package.json`

| Field | Rule |
| - | - |
| `name` | `@stackra/<name>`; apps `@figentra/<dir>`; services `@figentra/service-<name>` |
| `description` | Non-empty, one sentence |
| `license` | `"MIT"` ([0024](/adr/0024-mit-license-with-exclusions)) |
| `private` | `true` until a package is published |
| `type` | `"module"` |
| `sideEffects` | `false` on every `tier:lib` package |
| `exports` | `tier:lib` only: each module entry is `{ "@stackra/source": "./src/….ts", types: "./dist/….d.mts", default: "./dist/….mjs" }`, source condition first; a plain string entry is a static asset ([0025](/adr/0025-packages-publish-to-private-registry)) |
| dependencies | `catalog:`, `catalog:<name>` or `workspace:*` only: see [Dependencies](/standards/dependencies) |

Key order: `name`, `version`, `private`, `description`, `license`, `files`, `type`, `main` (Expo only), `sideEffects`, `imports`, `exports`, `scripts`, `dependencies`, `devDependencies`. Order is convention, not checked.

## `turbo.jsonc` and tiers

The tag matches the directory:

| Directory | Tag | May depend on |
| - | - | - |
| `packages/tooling/*` | `tier:config` | nothing workspace-local |
| `packages/<category>/<name>` | `tier:lib` | `tier:lib`, `tier:config` |
| `apps/*` | `tier:app` | `tier:lib`, `tier:config` |
| `services/*` | `tier:service` | anything below it |

The direction rule is a law: see [Boundaries](/constitution/boundaries) and [ADR 0003](/adr/0003-tier-dependency-direction).

## Kinds

| Tier | Kinds |
| - | - |
| `tier:app` | `app:console`, `app:mobile`, `app:desktop`, `app:docs` |
| `tier:lib` | `package`, entries-first (see [Packages](/standards/packages), ADR 0126) |
| `tier:config` | `tooling` |
| `tier:service` | `service`: `services/<name>`, entry `src/main.ts`, root module in `stackra.module` (see [Services](/standards/services)) |

## Scaffolding

`pnpm new <kind> <name> [--category <c>] [--entries <list>|none] [--description "<text>"] [--title "<Title>"] [--port <n>] [--repo <path>] [--dry-run]` copies a template from `tools/scaffold/templates`, replaces the tokens, copies the target repo's `LICENSE`, and formats the result. Then run `pnpm install` and `pnpm verify`.

| Kind | Template | Lands in |
| - | - | - |
| `service` | `templates/services/service` | `services/<name>` (`@figentra/service-<name>`) |
| `package` | `templates/packages/package` | `packages/<category>/<name>` (`--category` required) |
| `tooling` | `templates/packages/tooling` | `packages/tooling/<name>` |
| `app:console` | `templates/apps/console` | `apps/<name>` (port from 3710) |
| `app:mobile` | `templates/apps/mobile` | `apps/<name>` (no hyphens in the name) |
| `app:desktop` | `templates/apps/desktop` | `apps/<name>` |
| `app:docs` | `templates/apps/docs` | `apps/<name>` (port from 3334) |

```bash theme={"system"}
pnpm new service billing --description "Billing."
pnpm new package retry --category foundation --entries contracts,testing
pnpm new app:console admin --title "Admin"
pnpm new service billing --repo ../figentra-os --dry-run
```

Shapes: [ADR 0126](/adr/0126-member-shapes-and-scaffold-templates). Flags and tokens: [Scaffolding](/guides/scaffolding).

## What enforces this

| Rule | Check | Status |
| - | - | - |
| `README.md`, `AGENTS.md`, `CHANGELOG.md`, `LICENSE` exist | `validate-repository.mjs` (`checkFiles`) | Yes |
| `AGENTS.md` has a `## PII` heading | `validate-repository.mjs` | Yes |
| `LICENSE` equals the root `LICENSE` | `validate-repository.mjs` | Yes |
| `description` non-empty, `license` is `MIT` | `validate-repository.mjs` | Yes |
| `name` is `@stackra/<name>`, `@figentra/<dir>` or `@figentra/service-<dir>` | `validate-repository.mjs` | Yes |
| Exactly one `tier:*` tag matching the directory; extends `//` | `validate-repository.mjs` (`check`) | Yes |
| `tsconfig.json` extends `@stackra/typescript-config/<preset>` | `validate-repository.mjs` | Yes |
| `sideEffects: false` and the dist + `@stackra/source` exports shape on `tier:lib` | `validate-repository.mjs` | Yes |
| Catalog or workspace versions only; no forbidden dependency | `validate-repository.mjs` + `catalogMode` | Yes |
| Tier direction | `turbo boundaries` (`pnpm boundaries`) | Yes |
| Every member exposes the task-vocabulary scripts | planned: validator check | No |
| `CHANGELOG.md` heading, `package.json` key order, `tsconfig.json` has no extra keys | planned: validator | No |
| `vitest.config.ts` / `tsdown.config.ts` start with the file contract | planned: doc-standard check (see [Code style](/standards/code-style)) | No |

Run it directly with `node tools/scripts/validate-repository.mjs`; it prints nothing when clean.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.