The product dossier — the fourth config, and the only one that decides WHAT you are allowed to build. Load it in `cases` mode before writing any code, when the owner says "add a product" / "this is for the shop" / "why is that page here", and whenever you are about to name a folder after a product. Two things here are counter-intuitive and both are load-bearing: the product's `id` means nothing and never changes, while everything you would naturally use as an identifier — the name, the addres...
Installs into .claude/skills of the current project.
Sponsors
SSkills DirectorySkills Directory
Know which skills are safe — weekly.
SSkills DirectorySkills Directory
Is that skill safe to install?
Are you the author of Use Products Config?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/fractera-use-products-config)
---
name: use-products-config
description: >
The product dossier — the fourth config, and the only one that decides WHAT you are allowed to
build. Load it in `cases` mode before writing any code, when the owner says "add a product" / "this
is for the shop" / "why is that page here", and whenever you are about to name a folder after a
product. Two things here are counter-intuitive and both are load-bearing: the product's `id` means
nothing and never changes, while everything you would naturally use as an identifier — the name,
the address, the type — is something the owner edits freely; and what a product HAS built is never
stored, only counted, because a stored list of files disagrees with the files.
---
# use-products-config
> Informational, not binding. **Know a better way for the case in front of you — do it your way and
> say so.** You are trusted with the creative work on this project.
The config contract itself — panel writes, application reads per request, no rebuild, a field lives in
four places — is in `CLAUDE.md` and `use-app-config`. This is about products.
---
## 1. One product, one file
```
PRODUCTS-CONFIG/
registry.json an allocator of permanent ids, and nothing else
p1.json the whole product: record, intake, cases, steps, pages plan, phase, history
p1.quiz.jsonl the intake transcript — raw material, not state
schema.json · defaults.json generated by `npm run build:config-schemas`
```
Read it with `getPublicProducts()` / `getProductById()` (`config/products-config.ts`). **The list of
products is a folder walk**, not an index file — an index would be a second truth that drifts.
## 2. 🔒 `id` means nothing and never changes
`p1`, `p2`. Not `shop`, not `landing`. On it hang the things that cannot move: logic in
`lib/products/<id>/`, tables named `<id>_*`, the product's cases.
**Everything descriptive is editable by the owner** — the title, the description, the route, even the
type. Derive an identifier from any of those and you are one rename away from paths that point at
nothing. This was paid for the same day it was invented: a product called "the company's brain" had
been given the id `store-1`.
## 3. 🔒 Four roots, and each is derived — not chosen
| What | Where | Derived from |
|---|---|---|
| pages | `app/[lang]/(publicLayer)/<segment>/` (or the root group for the owner of `/`) | **the address** — in Next the folder IS the URL segment |
| logic | `lib/products/<id>/` | the eternal id |
| tables | `<id>_*` | the eternal id |
| cases | inside the dossier | the eternal id |
Working on a product, you write inside its roots. Anything shared — the header, the footer, primitives,
helpers — belongs to the PROJECT, lives in `components/` and `lib/`, and **moving something there is
named in the step**, because from that moment another product depends on it.
🔒 **You never touch another product.** Two products never share a page: a page belongs to an address,
an address belongs to one product. What they may share is CODE.
## 4. Surface decides who ever sees it
`public` (its own address on the site) · `private` (a tab in the panel) · `headless` (channels and
schedule, no screen at all). A headless product with a beautiful page is a misunderstanding of the
request, not a bonus.
`published` is **not** a phase: a product can be finished and shown to nobody.
## 5. Phases are a path, and `stage` is computed
`intake` (questions, answers, confirmations) → `decomposition` (cases become steps) → `development`
(steps are executed) → `analysis` (the owner decides what is ready).
`stage` inside a phase is **derived from the dossier itself** — from the questions answered, the cases
confirmed, the steps closed. That is why it does not lie, and why you do not set it by opinion.
🔒 **You cannot write the dossier.** The panel writes it (`bridges/app/lib/product-store.ts`, another
build on another port). Need a phase moved or a case confirmed — ask the owner and say exactly what to
press. Editing the JSON by hand puts the file and the panel into disagreement, and the panel wins.
## 6. 🔒 A step without a case is work nobody ordered
A case is confirmed **only by the owner** — an unconfirmed case is the model's guess. From confirmed
cases come steps, and each step names the cases it serves (`cases: string[]`).
So the honest closing question of a step is not "does it work" but **"what promised in the case is now
true"**. A feature that works perfectly and answers no case is work the owner did not ask for.
## 7. Plan against fact
`pages` in the dossier is the PLAN — what the product should have, proposed from its cases. What is
actually built is **counted by walking the folders, every time it is shown, and never stored**: a
stored list of files is a copy of the file system, and copies drift.
An empty `cases` on a page is legal — a service page serves no scenario — and inventing a link to make
the list look complete is worse than the gap.
## 8. 🔒 The machine layer is English, in one direction only
Every id, slug, file name and JSON key: English. The owner's language lives in exactly one place — the
`title` and the case text he confirmed, because that is what a human reads.
This is not style. This layer is loaded at the start of **every** session; a second language in it is
paid for in tokens forever.
## 9. Before you call it done
1. You named the product's id, and wrote inside its four roots — not next to them.
2. The step names its case, and the case is confirmed by the owner.
3. Nothing shared moved into `components/`/`lib/` silently — it is in the step.
4. You did not edit the dossier by hand; where a change was needed, you told the owner which control.