--- name: ctxinit description: Initialize a project's engineering foundation and knowledge hub, and manage its Architecture Decision Records (ADRs). Use whenever the user types /ctxinit, or asks to bootstrap/scaffold a new project's structure, set up a context/ knowledge folder, engineering rules, or security rules. /ctxinit interviews the user about the project's surfaces (admin panel, portal, landing, mobile app, API), then generates a complete context/ hub — rules, docs, plans, decisions (ADR), technical-debt registry, map — plus thin agent entry-point files (CLAUDE.md, AGENTS.md, .cursor stubs) that REFERENCE context/ instead of copying it. /ctxinit --sync (re)generates context/map.md and the component-reuse registry by scanning the current codebase — also use --sync when the user says "update the map", "sync the context", or "list the components". Once a project has a context/decisions/ log, this skill also RECORDS, QUERIES, and SUPERSEDES its ADRs — trigger on "record this decision", "why did we decide X", "did we already decide this", "on what basis...", or "we're reversing/replacing an old decision", not just on /ctxinit. --- # ctxinit — Project Foundation Initializer + Decision Log Bootstraps the **`context/` knowledge hub** for a project: binding engineering rules, security law, component-architecture law, docs, plans, an ADR decision log, and a technical-debt registry — all in **one place, single-source, never duplicated**. Then wires every AI coding agent (Claude Code, Codex, Cursor, …) to that one source via thin pointer files. Because the decision log it scaffolds is a living thing, not a one-time file drop, ctxinit also owns recording, querying, and superseding the ADRs inside it — that's not a separate skill, it's the same service. Three modes: | Invocation | Mode | What it does | | --- | --- | --- | | `/ctxinit` | **Init** | Interview the user → generate `context/` + agent entry points | | `/ctxinit --sync` | **Sync** | Scan the codebase → regenerate `context/map.md` + component-reuse registry | | `/ctxinit adr …` (or natural language) | **ADR** | Record / query / supersede decisions in `context/decisions/` | Everything generated is in **English**, regardless of the language the user speaks to you in. --- ## Mode 1 — `/ctxinit` (Init) ### Step 1 — Interview the user Before writing anything, find out what the project is. Ask (use AskUserQuestion when available, otherwise plain chat — in the user's language): 1. **Surfaces** (multi-select): Does the project have… - an **Admin panel**? - a **Client portal**? - a **Landing / marketing site**? - a **Mobile app**? - an **API / backend**? 2. **Or a free-form description** — the user may prefer to just describe the project; derive the surfaces from the description and confirm your reading back to them. 3. **One-liner** — what the product *is*, in one sentence (becomes the opening of rule 00). 4. **Repo shape** — monorepo (one repo, one folder per surface) or multi-repo? Default: monorepo. 5. **Anything already decided?** — existing stack constraints, existing code, target market, compliance needs. If the folder already has code, scan it first and don't ask what you can see. Read `references/interview.md` for the full question flow and how to map a free-form description to surfaces. Don't over-interview: 1–2 rounds of questions, then confirm the plan and build. ### Step 2 — Pick the architecture Apply the house defaults (full rationale + repo layouts in `references/architectures.md`): | Surface | Default stack | | --- | --- | | Mobile app | **Flutter** | | API / backend | **NestJS** (TypeScript) | | Web — landing, admin panel, portal | **Next.js** (App Router, TypeScript) | | Database | **PostgreSQL** — one datastore, no second DB without an ADR | These are defaults, not dogma: if the user names a different stack, use theirs — but record the departure as ADR 0001 so the "why" survives. ### Step 3 — Generate `context/` Create this tree at the project root (or per-repo in multi-repo setups — see architectures.md): ``` context/ ├── README.md ← the map of the map (from templates/context-README.md) ├── rules/ ← binding engineering rules, numbered 00–06 │ ├── 00-project-foundation.md │ ├── 01-component-architecture.md │ ├── 02-data-forms-and-state.md │ ├── 03-documentation-and-workflow.md │ ├── 04-plan-storage.md │ ├── 05-security-and-secrets.md │ └── 06-testing.md ├── docs/ ← durable reference, seeded per surface (architecture/, design/, features/, components/) ├── plans/ ← one plan file per task (empty at init, .gitkeep) ├── decisions/ ← ADR log: README.md + template.md + ADRs 0001… ├── debt/ ← technical-debt registry: README.md with the TD table └── map.md ← where-is-it index (generated by --sync; at init, a stub) ``` Work from the files in `templates/` — they are complete, generic templates with `{{PLACEHOLDER}}` markers. **Fill every placeholder from the interview; delete sections for surfaces the project doesn't have.** The templates encode the non-negotiables; keep them intact: - **Component-based UI + reuse before creation** — base → composite → feature layering; search for an existing component before building; one implementation per capability; every shared component gets a doc in `docs/components/` (rule 01). - **Security law** (rule 05) — auth-first on every non-public route, server-side validation everywhere, tenancy scoping in the query, no secrets in source, no fallback secrets, uploads validated by content not extension, rate limiting on auth endpoints. OWASP ASVS L2 baseline. - **Testing** (rule 06) — colocated unit tests, tests required for money/auth/data-integrity logic, lint + typecheck + tests pass before a task is "done". - **Technical debt is logged, never extended** (debt/README.md) — known shortcuts get a TD-ID, a severity, and a status; touching nearby code must not copy the bad pattern. - **Decisions get ADRs** (decisions/) — architectural calls are recorded with alternatives and a supersede chain, so nobody silently re-litigates them. - **Docs updated in the same task** (rule 03) — a change without its doc update is incomplete. Seed `docs/` with real starting content, not empty folders: `docs/architecture/stack.md` (chosen stacks + why), `docs/architecture/database.md` (Postgres conventions), `docs/design/style-guide.md` (design-token skeleton), one `docs/features/` stub per surface. Also record **ADR 0001 — initial stack and repo shape** through the ADR CLI (Mode 3, below) rather than hand-writing it — that keeps id numbering, the index, and the file itself generated from one source from the very first decision onward. Resolve the script relative to this `SKILL.md` (`/scripts/adr.py`) and run it with the project root as the working directory: ```bash python3 /scripts/adr.py init --dir context/decisions python3 /scripts/adr.py new "Initial stack and repo shape" \ --status Accepted --tags architecture,stack --dir context/decisions ``` Then open the created file and fill Context / Decision / Alternatives / Consequences with the interview's outcome — the house defaults chosen (or the user's override) and why. ### Step 4 — Wire the agents (single-source law) **This is the most important rule of the whole skill:** the generated `context/rules/` is the ONE canonical copy. Every agent entry-point file is a **thin pointer** to it — *never* a copy of the rule text. When any model (Claude, Codex, Cursor, or anything future) processes this project and wants its own instruction file, it must **generate a pointer file that references `context/`**, not paste the rules in. Copies drift; that drift is the disease this structure exists to cure. Generate from `templates/agents/`: - `CLAUDE.md` — points to `context/README.md`, imports rules via `@context/rules/…` references. - `AGENTS.md` — for Codex and any AGENTS.md-reading agent; references `context/rules/` by path. - `.cursor/rules/context.mdc` — a stub whose only body is "follow `context/rules/*` — canonical copy lives there" (kept only because Cursor needs a file to glob). Each pointer file also carries the instruction forward: *"If you are an AI agent creating your own config/instruction file for this repo, reference `context/` by path — do not copy its contents."* ### Step 5 — Finish - Run `/ctxinit --sync` behavior (below) once if the project already has code, so `map.md` and the component registry reflect reality from day one. - Summarize for the user: surfaces chosen, stacks chosen, what was generated, and the start-of-task checklist from `context/README.md`. --- ## Mode 2 — `/ctxinit --sync` (Sync) Read `references/sync.md` for the full procedure. In short: 1. **Scan the codebase** (respect .gitignore; skip node_modules, build output, lockfiles). 2. **Regenerate `context/map.md`** — a *where-is-it* structural index: top-level layout, routes/ screens, API surface, data layer, shared components, scripts. Pointers into `docs/`, never duplicated content. Stamp `Last generated: `. 3. **Regenerate the component registry** inside `context/rules/01-component-architecture.md` (between the `` / `:end` markers): list every shared component by layer (base / composite / domain-shared), with path, one-line purpose, and how to reuse it (variants/props). Flag near-duplicates you find as candidates for consolidation — and log any confirmed duplicate as a TD entry in `debt/README.md`. 4. **Do not touch** anything else — sync never rewrites rules, docs, decisions, or debt (except appending newly found debt). If `context/` doesn't exist yet, say so and offer to run init first. --- ## Mode 3 — ADR (record / query / supersede decisions) `context/decisions/` isn't a one-time file drop from Init — it's a living log, and keeping it truthful is part of this same service. Trigger this mode on `/ctxinit adr …` **and** on plain language: "record this decision", "why did we decide X", "did we already decide this", "on what basis…", "we're reversing/replacing an old decision", or a message that just states a choice was made and should be remembered. A dependency-free CLI ships at `scripts/adr.py` (Python 3.8+, standard library only). It makes numbering, templating, frontmatter edits, and index regeneration **deterministic**, so the log never drifts — use it whenever it's available. Resolve its path relative to this `SKILL.md` (`/scripts/adr.py`) and always run it with the target project's root as the working directory. It shares `templates/decisions/template.md` with Init Mode 1 — one template, not two. Read `references/adr/adr-format.md` before writing your first ADR in a session (frontmatter schema, status lifecycle, numbering, slugs) and `references/adr/workflows.md` for the detailed steps below. `references/adr/examples/` has a fully populated sample log, including a supersede chain. ### Locate the log `context/decisions/` is the default and first autodetect target (Init always creates it there). If a project used a different layout before adopting ctxinit, `python3 /scripts/adr.py locate` finds it (`docs/decisions/`, `docs/adr/`, etc.) — exit code 3 means none exists, i.e. this is an **init** (offer to scaffold one, defaulting to `context/decisions/`, even outside the full `/ctxinit` flow). ### Record a decision 1. **Gather substance.** A good ADR needs *context* (what forced the choice), the *decision* (stated actively — "We do X"), the *alternatives* rejected and why, and the *consequences*. Infer what you safely can from the code, diffs, and discussion; then ask at most 2–3 targeted questions for what is genuinely missing — especially the rejected alternatives. An ADR with no rejected alternative is usually a fact, not a decision; say so and reconsider whether it belongs. 2. **Create it deterministically:** ```bash python3 /scripts/adr.py new "Adopt X for Y" --status Accepted \ --tags data,architecture --deciders "team" --dir context/decisions ``` Assigns the next zero-padded id, slugifies the title, stamps today's date, writes the file from the template, and regenerates the index. Prints the new path. 3. **Fill the body.** Open the created file and complete every section (Context, Decision, Alternatives, Consequences, Links). Keep it tight — a few short paragraphs; it captures *why*, not a design doc. 4. **Detect conflicts** before finishing: scan existing ADRs for one that governs the same area. If this decision overturns it, run the supersede flow below. If it *contradicts* a still-live `Accepted` ADR but the user isn't intending to replace it, STOP and surface the conflict — quote the prior ADR and ask whether this supersedes it or needs reconciling. Never let two live `Accepted` ADRs silently disagree. 5. **Report** the path, id, status, and any supersede/conflict recorded. Manual fallback (no script execution available): read `references/adr/adr-format.md`, take `max(existing id) + 1`, copy `templates/decisions/template.md`, fill it, and add the row to the index by hand. ### Query the log 1. `python3 /scripts/adr.py list --dir context/decisions` (optionally `--status Accepted`), or read `context/decisions/README.md`. Select the relevant ADR(s) by title/tags and read those files in full. 2. Answer with: **the decision**, **its rationale** (Context + why the alternatives lost), its **status**, and whether it was **superseded** — follow the chain (`superseded_by`) to the current ADR. Cite ids and link the files. 3. If the log has nothing on the topic, say so plainly — do **not** invent a rationale. Offer to check commit history or open a new ADR if a real but unlogged decision exists. ### Supersede / change status - Supersede one ADR with a new one: ```bash python3 /scripts/adr.py new "Replace Y with Z" --supersedes 0007 \ --status Accepted --dir context/decisions ``` Creates the new ADR with `supersedes: [0007]`, flips `0007` to `status: Superseded` with `superseded_by: []`, and regenerates the index — atomically. - Change a status in place (e.g. Proposed → Accepted, or → Deprecated): ```bash python3 /scripts/adr.py status 0012 Accepted --dir context/decisions ``` - Regenerate the index/chains after any manual edit: ```bash python3 /scripts/adr.py index --dir context/decisions ``` Never rewrite an old decision's history to change it — write a *new* ADR that supersedes it. The only edits to an existing ADR are flipping it to `Superseded`/`Deprecated` and filling `superseded_by`. --- ## Boundaries - ctxinit sets up **structure and law**, not application code. Scaffolding the actual Next/Nest/ Flutter projects (`create-next-app`, `nest new`, `flutter create`) is offered as a follow-up, not done silently. - Never overwrite an existing `context/` wholesale. If one exists, diff-and-fill: add missing files, leave existing content alone, and report what was skipped. - Project-specific content from any *other* project (including Zentra) never leaks into a new project's context — the templates are generic on purpose.