archik 0.12.11 → 0.12.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,96 +5,61 @@ description: Use whenever .archik/main.archik.yaml or architecture.archik.yaml e
5
5
 
6
6
  # Archik — the project's shared map
7
7
 
8
- The archik file (under `.archik/` or as legacy `architecture.archik.yaml`) is **the user's source of truth for what the system looks like**. The browser canvas is a stateless projection of this file — when the user says "the orders service" or "the events queue", they mean the entity with that `id` in the YAML.
9
-
10
- You don't need to read or memorise the YAML's shape. The CLI is your interface to everything: structure, schema, proposals, lifecycle.
8
+ ## Mental model (read this first)
9
+
10
+ - **The YAML is the source of truth.** `.archik/main.archik.yaml` (and any `*.archik.yaml` sub-files) describe the system the user is building. The browser canvas is just a stateless projection of that file.
11
+ - **The CLI is your only interface to it.** You never read, write, or edit archik files directly. Every read goes through `npx archik q ...`; every write goes through `npx archik suggest set` → user accepts via `/archik:accept`.
12
+ - **Two command surfaces:** the user types `/archik:*` slash commands; you run `npx archik ...` directly. They're not interchangeable — see the tables below.
13
+
14
+ ## Command surfaces
15
+
16
+ ### The user types these (slash commands)
17
+
18
+ These are the user's entry points. They're triggered by the user typing `/archik:<name>` in chat. When you see one, it's the user's authorisation to run the corresponding workflow now — skip the "want me to update the YAML?" question.
19
+
20
+ | Slash command | What the user is asking for |
21
+ | ----------------------- | ----------------------------------------------------------------- |
22
+ | `/archik:spawn` | Bootstrap a diagram by mirroring the source tree (descriptive) |
23
+ | `/archik:evolve` | Propose a cleaner bounded-context refactor (prescriptive) |
24
+ | `/archik:suggest <…>` | Apply one feature-sized change from a description (targeted) |
25
+ | `/archik:describe <id>` | Explain a node and its connections |
26
+ | `/archik:dev` | Open the live canvas |
27
+ | `/archik:accept` | Apply the pending sidecar suggestion |
28
+ | `/archik:reject` | Discard the pending sidecar suggestion |
29
+
30
+ The full protocol for each lives at `.claude/commands/archik/<name>.md`. Follow it when invoked.
31
+
32
+ ### You run these (`npx archik` CLI)
33
+
34
+ These are the verbs you reach for during the loop. Default to `npx archik` (no global install needed).
35
+
36
+ | Need | Command |
37
+ | --------------------------------- | --------------------------------------------- |
38
+ | Get the document schema | `npx archik schema` |
39
+ | Inspect the current diagram | `npx archik q list \| edges \| stats` |
40
+ | Look up one node | `npx archik q describe <id>` |
41
+ | Find dependencies / impact | `npx archik q deps \| dependents \| impact <id>` |
42
+ | Validate a file | `npx archik validate <path>` |
43
+ | Stage a proposed change | `npx archik suggest set --note '…' - <<'YAML' … YAML` |
44
+ | Show / accept / reject pending | `npx archik suggest show \| accept \| reject` |
45
+ | Render an SVG | `npx archik render --out diagram.svg` |
46
+ | Diff two files | `npx archik diff a.yaml b.yaml` |
47
+ | Detect drift vs source tree | `npx archik drift` |
48
+ | Open the live canvas (foreground) | `npx archik dev` |
49
+ | Open the canvas (detached) | `npx archik start` / `stop` / `status` |
50
+ | Per-command help | `npx archik <cmd> --help` |
11
51
 
12
52
  ## Hard rule: the CLI is the only interface to archik files
13
53
 
14
- You MUST NOT use `Read`, `Write`, or `Edit` against any file under `.archik/`, any `*.archik.yaml`, any sidecar, or `architecture.archik.yaml`. The `npx archik` CLI is the contract — it owns reads, writes, validation, schema, lifecycle.
15
-
16
- | Need | Use |
17
- | ---------------------------- | ----------------------------------------- |
18
- | Schema (kinds, fields, …) | `npx archik schema` |
19
- | Inspect structure | `npx archik q ...` |
20
- | Validate | `npx archik validate <path>` |
21
- | Propose a change | `npx archik suggest set` (stdin heredoc) |
22
- | Apply / discard a suggestion | `npx archik suggest accept | reject` |
23
- | Render or diff | `npx archik render` / `npx archik diff` |
24
- | Help on any command | `npx archik <cmd> --help` |
25
-
26
- `.archik/main.archik.yaml` is the user's source of truth — only `npx archik suggest accept` may mutate it. Sidecars (`*.archik.suggested.yaml`) are owned by the CLI too — only `suggest set` writes them, only `accept` / `reject` consumes them.
54
+ You MUST NOT use `Read`, `Write`, or `Edit` against any file under `.archik/`, any `*.archik.yaml`, any sidecar (`*.archik.suggested.yaml`), or `architecture.archik.yaml`. The CLI owns reads, writes, validation, schema, and lifecycle.
27
55
 
28
56
  If `npx archik` is unreachable (offline, sandboxed, missing), STOP and tell the user. Do NOT fall back to reading or editing YAML by hand.
29
57
 
30
- ## File modes — two modes, picked by filename
31
-
32
- | Suffix | Mode | When to use | sourcePath rule |
33
- | ---------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
34
- | `*.archik.yaml` | **normal** | The canonical architecture of code that exists. | Required for code-bearing kinds; **must exist on disk** (validated). |
35
- | `*.archik.suggested.yaml` | **suggested**| A pending change to a normal file. Owned by `suggest set`. Becomes normal on `suggest accept`. | Same rules as normal — it'll become normal when accepted. |
36
-
37
- There is **no separate "discussion" file mode**. Greenfield / exploratory work — a node you want in the diagram before its code exists — is expressed via `status: proposed` on the affected nodes (and edges); see the next section. The diagram stays the canonical architecture.
38
-
39
- **Code-bearing kinds** (those that must declare `sourcePath`): `service`, `function`, `worker`, `module`, `page`, `component`, `store`, `hook`. Other kinds (`external`, `cloud`, `prompt`, `llm`, `route`, `interface`, `adapter`, `port`, `database`, `cache`, `queue`, `topic`, `stream`, `gateway`, `cdn`, `agent`, `frontend`, `vectordb`, `storage`, `auth`, `observability`, `tool`, `custom`) are exempt.
40
-
41
- If `suggest set` rejects your draft with a `sourcePath` error, the right answer is usually one of: (a) fix the path to point at real code, (b) use a non-code-bearing kind (e.g., `external` for a third-party service), or (c) mark the node `status: proposed` if it's a planned-but-not-built component (see "Lifecycle status" below).
42
-
43
- ## Required `description` — every node, every time
44
-
45
- `description` is **required** on every node — empty strings rejected, missing values rejected. The description must explain **what the node does** — its responsibility, the work it performs, why it exists — not just restate its `kind` or `name`.
46
-
47
- > Bad: *"A service."* *"The orders module."* *"Frontend."*
48
- > Good: *"Owns order placement and status — accepts cart payloads, validates inventory, writes to `orders` and emits `order.placed` to the stream."*
49
-
50
- Two reasons it's enforced:
51
- 1. The diagram is the shared map between you and the user. A node without a description is a black box neither of you can reason about.
52
- 2. When the user asks *"what does X do?"*, you should be answering from `npx archik q describe X`, not from intuition. That answer is only useful if the description was written with care.
53
-
54
- ## Lifecycle status — `proposed`, `active`, `deprecated` (nodes AND edges)
55
-
56
- Both **nodes and edges** carry an optional `status` field — same enum, same defaults, same visual treatment. Use it to keep the canonical diagram honest about what's built vs. what's planned vs. what's going away.
57
-
58
- | status | When | sourcePath rule (nodes only) | Visual |
59
- | ------------------------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------- |
60
- | absent / `active` | Built and live (default). | Required for code-bearing kinds, must exist on disk. | Standard solid stroke. |
61
- | `proposed` | Planned for the next iteration — belongs in the canonical map but isn't built yet. | Optional. If you supply one, it must still exist on disk. | Dashed indigo border, reduced opacity. |
62
- | `deprecated` | Being phased out; reads/writes shouldn't depend on it going forward. | Optional. Same on-disk rule as `proposed` if you set one. | Dashed amber border + strikethrough on the name. |
63
-
64
- For edges, `status: proposed` expresses "this dependency is planned" (e.g. *"orders-api will start subscribing to `payments.completed` next sprint"* — set the new edge's `status: proposed` until the code lands). `archik drift` and the validator both respect the lifecycle so proposed nodes don't trigger missing-source warnings before they're built.
65
-
66
- ## Other validation rules worth pre-empting
67
-
68
- - **No duplicate edges by `(from, to, relationship)`**. Two edges between the same pair with the same relationship render as overlapping strokes and bloat the diagram silently. The validator rejects the second occurrence and points at the first by id. If you genuinely need to express two different concerns between the same pair (e.g. `service → db` for both `reads` and `writes`), use distinct relationships.
69
- - **Parent / child `sourcePath` containment**. When a parent and a child both declare `sourcePath` and the parent's path is a directory, the child's `sourcePath` MUST be inside the parent's. `module: src/orders` → `function: src/orders/api.ts` is fine; `module: src/orders` → `function: src/payments/api.ts` is rejected because the diagram's containment claim contradicts the source tree. The check skips parents whose `sourcePath` is a single file (a file can't contain anything on disk) and parents without `sourcePath` at all.
70
-
71
- ## Slash commands (user-facing entry points)
72
-
73
- | Command | Purpose |
74
- | --------------------------- | --------------------------------------------- |
75
- | `/archik:spawn` | Bootstrap a diagram from the source tree |
76
- | `/archik:evolve` | Propose a cleaner bounded-context refactor |
77
- | `/archik:suggest <…>` | Propose changes from a feature description |
78
- | `/archik:describe <id>` | Explain a node and its connections |
79
- | `/archik:accept` | Apply the pending suggestion |
80
- | `/archik:reject` | Discard the pending suggestion |
81
- | `/archik:dev` | Open the live canvas |
82
-
83
- Slash commands are typed **by the user**, not by you. You always run `npx archik` directly. When a workflow internally needs `suggest accept` (e.g. spawn's sub-file step — the parent draft references sub-files via `archikFile:` and `suggest set` validates target-on-disk), narrate the rationale so the user can tell you are not bypassing their `/archik:accept` review on the main draft. The main draft is always left as a sidecar.
84
-
85
- When a user types `/archik:suggest`, `/archik:spawn`, or `/archik:evolve`, treat it as direct authorisation to run the sidecar workflow now — skip "want me to update the YAML?". Each command's body file under `.claude/commands/archik/` has the full protocol; follow it.
86
-
87
- Distinction:
88
- - **`spawn`** = descriptive (mirror the source tree as it is)
89
- - **`evolve`** = prescriptive (propose a cleaner shape, then discuss before accepting)
90
- - **`suggest`** = targeted (apply one feature-sized change from a description)
58
+ **Exception:** sequence diagrams (`*.archik.seq.yaml`) have **no sidecar workflow** — create or edit them directly with `Write` / `Edit`, then validate via `npx archik validate`. See "Sequence diagrams" below.
91
59
 
92
60
  ## The engineering loop (how archik fits into delivering work)
93
61
 
94
- Archik is the front of a five-phase loop that turns intent into
95
- working, reviewed, validated code. **Every structural change runs the
96
- loop.** Don't skip phases; don't silently retry on rejection; don't
97
- paper over a wrong design mid-build — go back.
62
+ Every structural change runs the loop. Don't skip phases; don't silently retry on rejection; don't paper over a wrong design mid-build — go back.
98
63
 
99
64
  ```
100
65
  ┌────────────┐ q stats / list / source tree.
@@ -121,162 +86,231 @@ paper over a wrong design mid-build — go back.
121
86
  └────────────┘ don't end on "done".
122
87
  ```
123
88
 
124
- | Phase | Driver | Output / tool |
125
- | -------- | ------------ | ---------------------------------------------------------- |
126
- | Discover | Claude | `npx archik q ...` + source-tree `ls` |
127
- | Design | Claude → User | sidecar via `suggest set`, after 1–3 clarifying Qs (HITL) |
128
- | Decide | User | `/archik:accept` or `/archik:reject` (HITL gate) |
129
- | Build | Claude → User | numbered plan (HITL approval), then small commits |
130
- | Verify | Claude | `npx archik validate` + tests + drift + SVG regen |
131
-
132
- **Two non-obvious feedback edges** (the things real loops have that flat
133
- lists miss):
134
-
135
- 1. **Decide → Design on reject.** A rejection is information; ask one
136
- specific question (boundary? relationship? scope? naming?
137
- composition? lifecycle?), treat the answer as a hard constraint,
138
- re-stage. Never silently retry the same draft.
139
- 2. **Build → Design on invalidation.** If implementation reveals the
140
- accepted diagram is wrong (a missing port, a hidden dependency, a
141
- boundary that doesn't hold), STOP coding. Open a fresh
142
- `/archik:suggest` to fix the diagram first, then resume. Code that
143
- silently contradicts the diagram is drift before it's even merged.
144
-
145
- ### Design heuristics — apply these in the DESIGN phase
146
-
147
- Before staging a sidecar, run the candidate through this checklist.
148
- Each item is a yellow flag; flag them out loud in your rationale
149
- rather than hiding them.
150
-
151
- - **One reason to change.** Each new node has a single responsibility
152
- expressible in one sentence. If `description` rambles, decompose.
153
- - **Bounded contexts.** Name the context this change belongs to. A
154
- change spanning two contexts is a yellow flag — usually means a
155
- missing third (orchestrator, port, gateway).
156
- - **Async at context boundaries.** Default cross-context coupling to
157
- `publishes` / `subscribes` over a stream/queue. `http_call` across
158
- contexts is allowed but should be justified (sync-required RPC,
159
- query for read-side data).
160
- - **Composition over sprawl.** Group related nodes under a `module`
161
- parent via `parentId`. Flat top-level lists past ~8 nodes are a
162
- smell.
163
- - **Ports & adapters at the edge.** External integrations sit behind
164
- an `external` node, never inline inside a service. A port (interface)
165
- + adapter (concrete) pair is preferred when the integration could
166
- swap.
167
- - **Public traffic → gateway/auth upstream.** Anything user-facing
168
- routes through a `gateway`/`auth` node, not directly to a service.
169
- - **Failure modes.** Async producers imply DLQ/retry on the consumer;
170
- `http_call` implies timeout + circuit. Don't draw the happy path
171
- alone.
172
- - **Lifecycle honesty.** Code-bearing node without code on disk →
173
- `status: proposed`. About to be removed → `status: deprecated`. The
174
- diagram should track reality, not aspiration.
175
-
176
- ### Optional sharpening — `superpowers:*` skills (if installed)
177
-
178
- The loop is self-contained, but these skills sharpen specific phases
179
- when the user has them. Check the available-skills list at session
180
- start; never assume they exist.
89
+ | Phase | Driver | Tool you reach for |
90
+ | -------- | ------------- | --------------------------------------------------- |
91
+ | Discover | Claude | `npx archik q ...` + source-tree `ls` |
92
+ | Design | Claude → User | sidecar via `suggest set`, after 1–3 clarifying Qs |
93
+ | Decide | User | `/archik:accept` or `/archik:reject` (HITL gate) |
94
+ | Build | Claude → User | numbered plan (HITL approval), then small commits |
95
+ | Verify | Claude | `npx archik validate` + tests + `drift` + SVG regen |
181
96
 
182
- | Phase | Skill |
183
- | ------- | ---------------------------------------------- |
184
- | Design | `superpowers:brainstorming` |
185
- | Build | `superpowers:writing-plans`, |
186
- | | `superpowers:test-driven-development`, |
187
- | | `superpowers:requesting-code-review` |
188
- | Verify | `superpowers:verification-before-completion` |
97
+ **Two non-obvious feedback edges:**
189
98
 
190
- ## Protocol — three rules
99
+ 1. **Decide → Design on reject.** A rejection is information; ask one specific question (boundary? relationship? scope? naming? composition? lifecycle?), treat the answer as a hard constraint, re-stage. Never silently retry the same draft.
100
+ 2. **Build → Design on invalidation.** If implementation reveals the accepted diagram is wrong (a missing port, hidden dependency, boundary that doesn't hold), STOP coding. Open a fresh `/archik:suggest` to fix the diagram first, then resume.
191
101
 
192
- 1. **Before** answering structural questions, query via `npx archik q ...`. Never `cat` or `Read` the YAML.
193
- 2. **Before** authoring a draft for `suggest set`, run `npx archik schema` once to lock in the exact field shape. The CLI is the schema; the prose below is the workflow.
194
- 3. **After** every `suggest set`, the CLI has already validated. If it exited non-zero, fix the YAML you piped and re-run — never edit the sidecar. After every `suggest accept`, propose follow-up steps (see "Follow-ups" below).
102
+ ## Worked examples
195
103
 
196
- ## Grounding (do this once per session, before structural work)
104
+ ### 1. Answer a question about the architecture
197
105
 
198
- The archik diagram tells you *what* exists. The source tree tells you *where* it lives. Use the CLI for the first half:
106
+ User asks "what writes to the orders DB?":
199
107
 
108
+ ```bash
109
+ npx archik q dependents orders-db --rel writes
200
110
  ```
201
- npx archik q stats # node + edge counts, kind histogram, file count
202
- npx archik q list # every node with kind, parent, file
203
- npx archik q edges # every edge with relationship and endpoints
111
+
112
+ Other common queries:
113
+
114
+ ```bash
115
+ npx archik q describe orders-api # node detail + edges
116
+ npx archik q deps orders-api # what does this node depend on?
117
+ npx archik q impact payments-db # what would break if this is removed?
118
+ npx archik q list --kind service # all services
119
+ npx archik q list --kind queue # all queues
120
+ npx archik q stats # node + edge counts, kind histogram
204
121
  ```
205
122
 
206
- Then `ls -F . src/ services/ packages/ apps/ 2>/dev/null` for the source tree. Build the mapping in your head; mismatches are where new code most often needs a YAML update.
123
+ If `q` returns empty for an id, the YAML doesn't have it — say so and offer to add it via `/archik:suggest`.
207
124
 
208
- When the user asks "where would I add X?", you should already have the answer because you ran the queries above.
125
+ ### 2. Stage a sidecar suggestion (the standard write path)
209
126
 
210
- **Every code-bearing node you propose for a normal/suggested file must declare a `sourcePath` that you have verified exists on disk** (e.g. `ls src/payments/worker.ts` before authoring `sourcePath: src/payments/worker.ts`). The validator rejects fabricated paths — and the rejection is non-negotiable, exactly so hallucinated nodes can't slip into the canonical architecture. If the source doesn't exist yet, mark the node `status: proposed` and omit `sourcePath` (or set one that points where the code WILL live, but it has to actually exist by the time you flip the status to active).
127
+ When work introduces, removes, or rewires components, you propose a sidecar. The user reviews on the canvas and accepts/rejects.
211
128
 
212
- ## Authoring drafts (sidecar workflow)
129
+ ```bash
130
+ # Step A — get the schema (always start here when authoring)
131
+ npx archik schema
213
132
 
214
- When work introduces, removes, or rewires components, you stage a proposal as a sidecar via the CLI. The user reviews on the canvas and accepts / rejects.
133
+ # Step B — pipe the FULL proposed end-state (every node, every edge —
134
+ # not a delta) straight into `suggest set` via heredoc. No temp files.
135
+ npx archik suggest set --note "add payments worker" - <<'YAML'
136
+ version: "1.0"
137
+ name: My Architecture
138
+ nodes:
139
+ - id: orders-api
140
+ kind: service
141
+ name: Orders API
142
+ description: Owns order placement and status — accepts cart payloads, validates inventory, writes to orders, emits order.placed.
143
+ sourcePath: services/orders/api
144
+ - id: order-events
145
+ kind: stream
146
+ name: order-events
147
+ description: Stream of domain events emitted by orders-api (placed, cancelled, fulfilled).
148
+ - id: payments-worker
149
+ kind: worker
150
+ name: Payments worker
151
+ description: Subscribes to order.placed, charges via Stripe, writes payment records.
152
+ sourcePath: services/payments/worker
153
+ edges:
154
+ - id: orders-emits
155
+ from: orders-api
156
+ to: order-events
157
+ relationship: publishes
158
+ - id: payments-subscribes
159
+ from: payments-worker
160
+ to: order-events
161
+ relationship: subscribes
162
+ YAML
163
+ ```
215
164
 
216
- **Step 1 — get the schema.** Before authoring, run:
165
+ The CLI parses, schema-validates, checks cross-file references, stamps `metadata.suggestion`, and atomically writes the sidecar. If it exits non-zero, the error includes a hint pointing at the wrong field — fix the heredoc and re-run. **Never edit the sidecar by hand.**
217
166
 
167
+ ```bash
168
+ # Step C — surface the canvas URL so the user can review the diff overlay
169
+ # (added/removed/changed get green/red/amber frames).
170
+ # Or terminal: `npx archik suggest show | accept | reject`.
218
171
  ```
219
- npx archik schema
172
+
173
+ ### 3. Verify before declaring done
174
+
175
+ ```bash
176
+ npx archik validate .archik/main.archik.yaml # schema + cross-file checks
177
+ npx archik drift # diagram vs source tree
178
+ npx archik render --out docs/architecture.svg # if the project commits an SVG
220
179
  ```
221
180
 
222
- That prints every required field, every type ("array of string" vs "string"), every kind, every relationship, every constraint. Use it. **Do not write archik YAML from intuition.**
181
+ ### 4. Sub-architecture (a brand-new `archikFile`)
223
182
 
224
- **Step 2 — pipe the draft straight into `suggest set` via heredoc.** No temp files, no `/tmp/` paths:
183
+ If a node needs its own diagram, author both the parent change AND the new sub-file. **Order matters** — the parent's `archikFile:` pointer is validated against on-disk existence:
225
184
 
226
185
  ```bash
227
- npx archik suggest set --note "<one-liner>" - <<'YAML'
186
+ # 1. Stage + accept the new sub-file (orphan, parent doesn't exist yet)
187
+ npx archik suggest set --main .archik/payments.archik.yaml \
188
+ --allow-orphan \
189
+ --note "spawn: payments internals" - <<'YAML'
190
+ version: "1.0"
191
+ name: Payments internals
192
+ nodes: [ ... ]
193
+ edges: [ ... ]
194
+ YAML
195
+ npx archik suggest accept .archik/payments.archik.yaml
196
+
197
+ # 2. Now the file is real on disk; stage the parent change
198
+ npx archik suggest set --note "link payments sub-architecture" - <<'YAML'
228
199
  version: "1.0"
229
200
  name: My Architecture
230
201
  nodes:
231
- # full proposed end-state — every node, not just the delta
202
+ - id: payments
203
+ ...
204
+ archikFile: .archik/payments.archik.yaml
205
+ ... (every other node)
232
206
  edges:
233
- # full proposed end-state — every edge, not just the delta
207
+ ... (every edge)
234
208
  YAML
235
209
  ```
236
210
 
237
- The CLI parses, schema-validates, checks cross-file references, stamps `metadata.suggestion`, and atomically writes the sidecar. If it exits non-zero, the error includes a hint pointing at the field that's wrong — fix the heredoc and re-run.
238
-
239
- **Step 3 — surface the canvas URL** so the user can review the diff overlay (added/removed/changed get green/red/amber frames). Or terminal: `npx archik suggest show | accept | reject`.
211
+ When you auto-accept the sub-file, **narrate the rationale** so the user can tell you're not bypassing their `/archik:accept` review on the main draft. The main draft is always left as a sidecar.
240
212
 
241
- ### Sub-architectures (a brand-new `archikFile`)
213
+ ### 5. Sequence diagrams (direct-write, no sidecar)
242
214
 
243
- If a node needs its own diagram, you'll author both the parent change AND the new sub-file. Order matters because the parent's `archikFile:` pointer is validated against on-disk existence:
215
+ Sequence diagrams live in `.archik/` as `*.archik.seq.yaml` files and document a specific runtime flow at the call level. They are the **only** archik file mode you write directly.
244
216
 
245
217
  ```bash
246
- # 1. Stage + accept the new sub-file (orphan, parent doesn't exist yet)
247
- npx archik suggest set --main .archik/<id>.archik.yaml \
248
- --allow-orphan \
249
- --note "spawn: <id> internals" - <<'YAML'
250
- ...
251
- YAML
252
- npx archik suggest accept .archik/<id>.archik.yaml
218
+ # 1. Write the seq file directly with the Write tool
219
+ # 2. Validate (this also checks every seqFiles reference)
220
+ npx archik validate .archik/main.archik.yaml
253
221
 
254
- # 2. Now the file is real on disk; stage the parent change
255
- npx archik suggest set --note "..." - <<'YAML'
256
- ... (with archikFile: .archik/<id>.archik.yaml on the relevant node)
222
+ # 3. Link it from an architecture node via `suggest set` (sidecar workflow)
223
+ npx archik suggest set --note "link login-flow seq diagram to api-gateway" - <<'YAML'
224
+ version: "1.0"
225
+ name: My Architecture
226
+ nodes:
227
+ - id: api-gateway
228
+ ...
229
+ seqFiles:
230
+ - .archik/login-flow.archik.seq.yaml
231
+ ... (every other node)
232
+ edges: [ ... ]
257
233
  YAML
234
+
235
+ # 4. Render to SVG (optional, useful for CI / docs)
236
+ npx archik render --seq .archik/login-flow.archik.seq.yaml --out login-flow.svg
258
237
  ```
259
238
 
260
- **Rules:**
261
- - Write the *full proposed document*, not a patch. The diff is computed by archik between main and sidecar.
262
- - Don't `Write`/`Edit` archik files. The CLI owns `.archik/`.
263
- - If a sidecar already exists, `suggest set` overwrites it. Mention to the user that you replaced their previous pending suggestion.
264
- - Renaming an `id` is forbidden — remove the old node and add a new one. Renames break diff and require manual re-link in code.
265
- - Don't drop user-authored `description`, `responsibilities`, or `notes` fields when carrying a node forward.
239
+ `seqFiles` is a non-empty array of relative paths from project root. The validator checks each path exists.
240
+
241
+ The seq schema (UML subset) is documented at the bottom of this file under "Sequence diagram schema reference".
266
242
 
267
- ## When to consult the YAML (via `q`)
243
+ ## File modes — two modes, picked by filename
268
244
 
269
- - "What does X do?" / "What's its responsibility?" → `npx archik q describe X`
270
- - "What writes to / reads from / publishes to Y?" → `npx archik q dependents Y --rel writes` etc.
271
- - "What depends on Z?" → `npx archik q dependents Z`
272
- - "What would break if I remove Z?" → `npx archik q impact Z`
273
- - "What services exist?" / "Is there a queue / cache / gateway already?" → `npx archik q list --kind <kind>`
245
+ | Suffix | Mode | When to use |
246
+ | --------------------------- | ------------- | ----------------------------------------------------------------------------------- |
247
+ | `*.archik.yaml` | **normal** | The canonical architecture of code that exists. |
248
+ | `*.archik.suggested.yaml` | **suggested** | A pending change to a normal file. Owned by `suggest set`. Becomes normal on accept. |
249
+ | `*.archik.seq.yaml` | **sequence** | A runtime flow diagram. Direct-write. No sidecar. |
274
250
 
275
- If `q` returns empty for an id, the YAML doesn't have it — say so and offer to add it via `/archik:suggest`.
251
+ There is no separate "discussion" file mode. Greenfield / exploratory work is expressed via `status: proposed` on the affected nodes and edges (see Lifecycle below). The diagram stays canonical.
276
252
 
277
- ## When to propose updates
253
+ ## Required fields and validation rules
278
254
 
279
- Proactively suggest a sidecar (don't silently apply) when work changes shape:
255
+ These rules are enforced by the validator. Pre-empt them when authoring.
256
+
257
+ ### Every node needs a `description`
258
+
259
+ Empty strings rejected, missing values rejected. Explain what the node **does** — its responsibility, the work it performs, why it exists — not just its `kind` or `name`.
260
+
261
+ > Bad: *"A service."* *"The orders module."*
262
+ > Good: *"Owns order placement and status — accepts cart payloads, validates inventory, writes to `orders` and emits `order.placed` to the stream."*
263
+
264
+ ### Code-bearing kinds need a `sourcePath`
265
+
266
+ These kinds MUST declare a `sourcePath` that exists on disk: `service`, `function`, `worker`, `module`, `page`, `component`, `store`, `hook`.
267
+
268
+ Other kinds are exempt: `external`, `cloud`, `prompt`, `llm`, `route`, `interface`, `adapter`, `port`, `database`, `cache`, `queue`, `topic`, `stream`, `gateway`, `cdn`, `agent`, `frontend`, `vectordb`, `storage`, `auth`, `observability`, `tool`, `custom`.
269
+
270
+ If `suggest set` rejects with a `sourcePath` error, you have three options:
271
+ 1. Fix the path to point at real code (verify with `ls` first).
272
+ 2. Use a non-code-bearing kind (e.g. `external` for a third-party service).
273
+ 3. Mark the node `status: proposed` if it's planned-but-not-built (see Lifecycle).
274
+
275
+ **Never paste a path you haven't seen on disk.** The validator rejects fabricated paths so hallucinated nodes can't slip into the canonical architecture.
276
+
277
+ ### Lifecycle status — `proposed`, `active`, `deprecated`
278
+
279
+ Both **nodes and edges** carry an optional `status`. Same enum, same defaults, same visual treatment.
280
+
281
+ | status | When | sourcePath rule (nodes) | Visual |
282
+ | ------------------- | --------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------- |
283
+ | absent / `active` | Built and live (default). | Required for code-bearing kinds; must exist on disk. | Standard solid stroke. |
284
+ | `proposed` | Planned for next iteration — belongs in the canonical map but isn't built yet. | Optional; if supplied, must exist on disk. | Dashed indigo border, reduced opacity. |
285
+ | `deprecated` | Being phased out; new work shouldn't depend on it. | Optional; same on-disk rule as `proposed`. | Dashed amber border + strikethrough on the name. |
286
+
287
+ For edges, `status: proposed` expresses "this dependency is planned" (e.g. *"orders-api will start subscribing to `payments.completed` next sprint"*). `archik drift` and the validator both respect lifecycle so proposed nodes don't trigger missing-source warnings before they're built.
288
+
289
+ ### Other rules worth pre-empting
290
+
291
+ - **No duplicate edges by `(from, to, relationship)`.** The validator rejects the second occurrence and points at the first by id. If you genuinely need two concerns between the same pair (e.g. `service → db` for both `reads` and `writes`), use distinct relationships.
292
+ - **Parent / child `sourcePath` containment.** When a parent and a child both declare `sourcePath` and the parent's path is a directory, the child's path MUST be inside the parent's. `module: src/orders` → `function: src/orders/api.ts` is fine; `module: src/orders` → `function: src/payments/api.ts` is rejected.
293
+ - **No coordinates** (`x`, `y`, `width`, `height`, `viewport`). Layout is computed by ELK on every render. The schema rejects them.
294
+ - **No empty arrays.** `notes`, `responsibilities`, `interfaces` — either include real entries or omit the field.
295
+ - **Renaming an `id` is forbidden.** Remove the old node and add a new one. Renames break diff and require manual re-link in code.
296
+ - **Don't drop user-authored fields.** `description`, `responsibilities`, `notes` carried forward must stay intact.
297
+
298
+ ## Design heuristics — apply these in DESIGN
299
+
300
+ Run a candidate through this checklist before staging a sidecar. Each item is a yellow flag — flag them in your rationale rather than hiding them.
301
+
302
+ - **One reason to change.** Each new node has a single responsibility expressible in one sentence. If `description` rambles, decompose.
303
+ - **Bounded contexts.** Name the context this change belongs to. A change spanning two contexts usually means a missing third (orchestrator, port, gateway).
304
+ - **Async at context boundaries.** Default cross-context coupling to `publishes` / `subscribes` over a stream/queue. `http_call` across contexts is allowed but should be justified (sync-required RPC, query for read-side data).
305
+ - **Composition over sprawl.** Group related nodes under a `module` parent via `parentId`. Flat top-level lists past ~8 nodes are a smell.
306
+ - **Ports & adapters at the edge.** External integrations sit behind an `external` node, never inline in a service. Port (interface) + adapter (concrete) is preferred when the integration could swap.
307
+ - **Public traffic → gateway/auth upstream.** Anything user-facing routes through a `gateway`/`auth` node, not directly to a service.
308
+ - **Failure modes.** Async producers imply DLQ/retry on the consumer; `http_call` implies timeout + circuit. Don't draw the happy path alone.
309
+ - **Lifecycle honesty.** Code-bearing node without code on disk → `status: proposed`. About to be removed → `status: deprecated`.
310
+
311
+ ## When to propose, when to defer
312
+
313
+ **Propose a sidecar (don't silently apply) when work changes shape:**
280
314
 
281
315
  - New service, function, worker, frontend, queue, DB, etc.
282
316
  - New dependency between existing components.
@@ -284,13 +318,13 @@ Proactively suggest a sidecar (don't silently apply) when work changes shape:
284
318
  - Removing or renaming a component.
285
319
  - Splitting one component into several, or merging several into one.
286
320
 
287
- Frame it as: *"This adds a `payments-worker` reading from the `order-events` queue. Want me to stage that as an archik suggestion?"* — wait for the user to confirm or for them to type `/archik:suggest`.
321
+ Frame it as: *"This adds a `payments-worker` reading from the `order-events` queue. Want me to stage that as an archik suggestion?"* — wait for confirmation or for the user to type `/archik:suggest`.
288
322
 
289
- ## When to defer
323
+ **Leave the diagram alone for:**
290
324
 
291
- - Pure refactors that don't change the component graph → leave the diagram alone.
292
- - Local file moves / renames → leave it alone.
293
- - Bug fixes inside an existing node → leave it alone.
325
+ - Pure refactors that don't change the component graph.
326
+ - Local file moves / renames.
327
+ - Bug fixes inside an existing node.
294
328
 
295
329
  The diagram tracks **shape**, not implementation detail.
296
330
 
@@ -298,67 +332,47 @@ The diagram tracks **shape**, not implementation detail.
298
332
 
299
333
  After a suggestion is accepted, the diagram has changed. Don't just stop — propose what's natural next. Pick whichever fits:
300
334
 
301
- 1. **Implement the change.** If the suggestion added a new node (e.g. a worker, a queue), the code for it doesn't exist yet. Offer to scaffold it: *"The diagram now shows `payments-worker` subscribing to `order-events`. Want me to scaffold `src/workers/payments/` with a stub consumer?"*
302
- 2. **Improve.** If the change was small but exposed bigger architectural smells (a god service, a missing port/adapter pair, a leaky boundary), suggest `/archik:evolve` to clean it up: *"Worth running `/archik:evolve` on the `orders` module? It's now wired to four downstream services and might want a clearer port."*
303
- 3. **Diff vs reality.** Offer to spot-check the source tree against the new diagram: *"Should I scan `src/` to confirm the diagram still matches the code?"*
304
- 4. **Render.** If the project commits a rendered SVG (`docs/architecture.svg`), regenerate it: `npx archik render --out docs/architecture.svg`. Offer to do this if such a file exists.
335
+ 1. **Implement the change.** If the suggestion added a new node (e.g. a worker, a queue), the code doesn't exist yet. Offer to scaffold it: *"The diagram now shows `payments-worker` subscribing to `order-events`. Want me to scaffold `src/workers/payments/` with a stub consumer?"*
336
+ 2. **Improve.** If the change exposed bigger architectural smells (a god service, a missing port/adapter pair, a leaky boundary), suggest `/archik:evolve`: *"Worth running `/archik:evolve` on the `orders` module? It's now wired to four downstream services and might want a clearer port."*
337
+ 3. **Diff vs reality.** Offer to spot-check the source tree against the new diagram: `npx archik drift`.
338
+ 4. **Render.** If the project commits a rendered SVG (`docs/architecture.svg`), regenerate it: `npx archik render --out docs/architecture.svg`.
305
339
 
306
- After a rejection, **never go silent and never silently retry the same draft**. Ask a question pinned to one of these axes — the answer becomes a constraint when you regenerate:
340
+ After a rejection, **never go silent and never silently retry the same draft.** Ask a question pinned to one of these axes — the answer becomes a constraint when you regenerate:
307
341
 
308
- - **Boundary** — *"Did the wrong context own a node? e.g. should `payments-worker` live under `orders` or under `billing`?"*
309
- - **Relationship** — *"Was a sync `http_call` wrong where you wanted `publishes`/`subscribes`?"*
342
+ - **Boundary** — *"Did the wrong context own a node? Should `payments-worker` live under `orders` or `billing`?"*
343
+ - **Relationship** — *"Was a sync `http_call` wrong where you wanted `publishes` / `subscribes`?"*
310
344
  - **Scope** — *"Too big? Want me to try a smaller delta that only touches the queue, not the worker?"*
311
345
  - **Naming** — *"Was the id/name unclear? What would you call it?"*
312
346
  - **Composition** — *"Should this be one node, or split into a port + adapter pair?"*
347
+ - **Lifecycle** — *"Should this be `status: proposed` for now and flipped to `active` once the code lands?"*
313
348
 
314
- Then loop back to step 2 (Clarify) of the engineering loop with the rejection reason as a hard constraint on the next draft.
315
-
316
- The goal: every accepted change ends with the user knowing what's next, not "ok, accepted". Every rejection ends with one specific question, not silence.
317
-
318
- ## Sequence diagrams
319
-
320
- Sequence diagrams live alongside architecture files in `.archik/` as `*.archik.seq.yaml` files. Each one documents a specific runtime flow (e.g. a request path, an event chain, an auth handshake) at the call level, using a subset of UML.
321
-
322
- ### How they connect to architecture nodes
323
-
324
- A node in the architecture YAML declares which flows it participates in via the `seqFiles` field:
325
-
326
- ```yaml
327
- - id: api-gateway
328
- kind: gateway
329
- label: API Gateway
330
- description: ...
331
- seqFiles:
332
- - .archik/login-flow.archik.seq.yaml
333
- - .archik/checkout-flow.archik.seq.yaml
334
- ```
335
-
336
- `seqFiles` is a **non-empty array of relative paths** (at least one entry required) from the project root. The validator checks each path exists on disk. Nodes without `seqFiles` are unaffected.
337
-
338
- **UI effect:** nodes with `seqFiles` get clickable diagram links in the node inspector. The toolbar shows a "glow" button that highlights all nodes with seq diagrams so they're easy to spot on large canvases.
349
+ Then loop back to DESIGN with the rejection reason as a hard constraint.
339
350
 
340
- ### Authoring rule — seq files are direct-write (not `suggest set`)
351
+ ## Optional sharpening — `superpowers:*` skills (if installed)
341
352
 
342
- `suggest set` is for architecture files only. Seq files have **no sidecar workflow** — create or edit them directly with `Write` / `Edit`. Then validate:
353
+ The loop is self-contained, but these sharpen specific phases when the user has them. Check the available-skills list at session start; never assume they exist.
343
354
 
344
- ```bash
345
- npx archik validate .archik/main.archik.yaml # validates seq files referenced by seqFiles fields too
346
- ```
355
+ | Phase | Skill |
356
+ | ------- | ---------------------------------------------- |
357
+ | Design | `superpowers:brainstorming` |
358
+ | Build | `superpowers:writing-plans`, |
359
+ | | `superpowers:test-driven-development`, |
360
+ | | `superpowers:requesting-code-review` |
361
+ | Verify | `superpowers:verification-before-completion` |
347
362
 
348
- ### Seq YAML schema
363
+ ## Sequence diagram schema reference
349
364
 
350
365
  ```yaml
351
366
  version: "1.0" # required, literal
352
367
  name: "Login flow" # required, non-empty
353
368
  description: "..." # optional
354
369
 
355
- participants: # required, at least one
370
+ participants: # required, at least one
356
371
  - id: browser # participant ref id (used in steps)
357
372
  nodeId: frontend # architecture node id this participant maps to
358
- # the node's kind (gateway, service, database…) is
359
- # automatically applied to the participant header icon/color
373
+ # node's kind drives the participant header icon/color
360
374
  label: Browser # optional display label (defaults to nodeId)
361
- status: proposed # optional — proposed | active | deprecated (header/lifeline dim + dashed border)
375
+ status: proposed # optional — proposed | active | deprecated
362
376
 
363
377
  steps: # ordered list of messages, notes, groups
364
378
  # --- message ---
@@ -369,7 +383,7 @@ steps: # ordered list of messages, notes, groups
369
383
  label: POST /login
370
384
  arrow: sync # sync | async | return | create | destroy
371
385
  activate: true # optional — draws activation box on receiver
372
- status: proposed # optional — proposed | active | deprecated
386
+ status: proposed # optional
373
387
 
374
388
  # --- note ---
375
389
  - type: note
@@ -407,85 +421,36 @@ steps: # ordered list of messages, notes, groups
407
421
  - type: group
408
422
  id: g2
409
423
  kind: ref
410
- label: "checkout flow" # display label inside the frame
424
+ label: "checkout flow"
411
425
  seqFile: .archik/checkout-flow.archik.seq.yaml
412
- # relative path to the linked seq file
413
- # makes the frame clickable in the UI →
414
- # navigates to that diagram
415
- branches: [] # branches must be present (can be empty for ref)
426
+ # makes the frame clickable in the UI
427
+ branches: [] # required (can be empty for ref)
416
428
  ```
417
429
 
418
430
  **Arrow types:**
419
- | arrow | meaning |
420
- |-------|---------|
421
- | `sync` | synchronous call (solid line, filled arrowhead) |
422
- | `async` | fire-and-forget (solid line, open arrowhead) |
423
- | `return` | return value (dashed line, open arrowhead) |
424
- | `create` | object creation (dashed line, filled arrowhead + `«create»` label prefix) |
425
- | `destroy` | object destruction (solid line, × marker at target) |
426
431
 
427
- **Group kinds:** `alt` (conditional), `opt` (optional), `loop`, `par` (parallel), `break`, `ref` (reference)
428
-
429
- ### Linking a new seq file (full workflow)
432
+ | arrow | meaning |
433
+ | --------- | ----------------------------------------------------------- |
434
+ | `sync` | synchronous call (solid line, filled arrowhead) |
435
+ | `async` | fire-and-forget (solid line, open arrowhead) |
436
+ | `return` | return value (dashed line, open arrowhead) |
437
+ | `create` | object creation (dashed line, filled arrowhead + `«create»`) |
438
+ | `destroy` | object destruction (solid line, × marker at target) |
430
439
 
431
- ```bash
432
- # 1. Write the seq file directly
433
- # (use Write tool — no suggest set for seq files)
434
-
435
- # 2. Validate the seq file is well-formed
436
- npx archik validate .archik/main.archik.yaml
437
-
438
- # 3. Add seqFiles to the relevant architecture node via suggest set
439
- npx archik suggest set --note "link login-flow seq diagram to api-gateway" - <<'YAML'
440
- version: "1.0"
441
- name: My Architecture
442
- nodes:
443
- - id: api-gateway
444
- ...
445
- seqFiles:
446
- - .archik/login-flow.archik.seq.yaml
447
- ... (all other nodes)
448
- edges:
449
- ... (all edges)
450
- YAML
451
-
452
- # 4. Validate again — now checks the seqFiles path exists
453
- npx archik validate .archik/main.archik.yaml
454
-
455
- # 5. User accepts on canvas → node gets seq diagram link in inspector
456
- ```
457
-
458
- ### What the validator checks for seq diagrams
459
-
460
- - All seq files referenced in `seqFiles` exist on disk
461
- - Each seq file parses as valid YAML
462
- - Each seq file matches the seq schema (version, participants, steps structure)
463
- - Participant `nodeId` fields reference real node ids from the architecture
464
- - No duplicate step ids within a seq file
465
-
466
- ### CLI render
467
-
468
- ```bash
469
- npx archik render --seq .archik/login-flow.archik.seq.yaml --out login-flow.svg
470
- # optionally: --theme dark|light (default: dark)
471
- ```
472
-
473
- Renders a headless SVG of the sequence diagram. Useful for CI or docs. Participant icons/colors are automatically resolved from the architecture node kinds when a root arch doc is present in the same project root.
474
-
475
- ## Verification workflow
476
-
477
- After every `suggest set` or `suggest accept`:
440
+ **Group kinds:** `alt` (conditional), `opt` (optional), `loop`, `par` (parallel), `break`, `ref` (reference)
478
441
 
479
- 1. `suggest set` already validated schema + cross-file existence. If errors fired, the message includes a hint — fix the heredoc and re-run. Don't reach for `Write`/`Edit` on the sidecar.
480
- 2. If `archik dev` is running, the file watcher broadcasts the change to the canvas automatically. Surface the URL so the user can click through.
481
- 3. If `docs/architecture.svg` is committed, regenerate it (see Follow-ups).
442
+ **Validator checks for seq diagrams:**
443
+ - All seq files referenced in `seqFiles` exist on disk.
444
+ - Each seq file parses as valid YAML and matches the seq schema.
445
+ - Participant `nodeId` fields reference real node ids from the architecture.
446
+ - No duplicate step ids within a seq file.
482
447
 
483
- ## CLI reference (run `<cmd> --help` for full surface)
448
+ ## Full CLI reference
484
449
 
485
- The CLI ships as the `archik` npm package; default to `npx archik` (works in fresh repos, no global install needed).
450
+ Run `npx archik <cmd> --help` for the per-command surface.
486
451
 
487
452
  ```
488
- npx archik schema # the document shape (always start here when authoring)
453
+ npx archik schema # the document shape (start here when authoring)
489
454
  --json # structured shape for piping into jq
490
455
  --seq # seq diagram schema instead of arch schema
491
456
 
@@ -496,8 +461,9 @@ npx archik q describe <id> | deps <id> | dependents <id>
496
461
 
497
462
  npx archik validate <path> [--json] # schema + cross-file check (CI-friendly)
498
463
  npx archik render --out diagram.svg --theme light|dark
499
- render --seq <path> --out seq.svg --theme light|dark # render a seq diagram to SVG
464
+ render --seq <path> --out seq.svg --theme light|dark
500
465
  npx archik diff a.yaml b.yaml [--out diff.svg] [--json]
466
+ npx archik drift [--json] [--ignore <file>] # diagram vs source tree
501
467
 
502
468
  npx archik suggest show [--json]
503
469
  suggest set <draft|-> # validate + stage a sidecar
@@ -513,13 +479,13 @@ npx archik init # scaffold + install skill + slash comma
513
479
  npx archik skill | commands # refresh the skill / slash commands
514
480
  ```
515
481
 
516
- Per-command help: `npx archik <cmd> --help`.
517
-
518
482
  ## Things to avoid
519
483
 
520
- - Don't `cat`, `Read`, `Write`, or `Edit` archik files.
484
+ - Don't `cat`, `Read`, `Write`, or `Edit` archik architecture files (`.archik/`, `*.archik.yaml`, sidecars). The CLI owns them.
521
485
  - Don't author drafts from memory; run `npx archik schema` first.
522
- - Don't add coordinates (`x`, `y`, `width`, `height`, `viewport`) — layout is computed by ELK on every render. The schema rejects them.
523
- - Don't add empty `notes` / `responsibilities` / `interfaces` lists — either include real entries or omit the field.
486
+ - Don't add coordinates (`x`, `y`, `width`, `height`, `viewport`).
487
+ - Don't add empty `notes` / `responsibilities` / `interfaces` — either include real entries or omit the field.
524
488
  - Don't blow away user-authored fields when carrying a node forward.
525
489
  - Don't bulk-restructure as a side effect of a small edit. Make the minimal change that captures what changed.
490
+ - Don't silently retry a rejected draft. Ask one specific question, treat the answer as a hard constraint, then re-stage.
491
+ - Don't end on "done" after `accept`. Propose the natural next step (implement, evolve, drift-check, render).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archik",
3
- "version": "0.12.11",
3
+ "version": "0.12.12",
4
4
  "description": "The shared vocabulary between you and Claude Code, at the engineering level. Plain-YAML architecture diagrams with a live browser canvas, headless SVG render in CI, and an installable Claude skill so the model treats the diagram as the spec.",
5
5
  "keywords": [
6
6
  "architecture",