archik 0.7.3 → 0.7.5

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.
@@ -1,767 +1,216 @@
1
1
  ---
2
2
  name: archik
3
- description: Use whenever .archik/main.archik.yaml or architecture.archik.yaml exists in the project, or the user asks about the system's architecture, services, dependencies, or data flow. The YAML is the shared map between the user and Claude. Interact with it ONLY through the `npx archik` CLI — `q` for queries, `suggest set` for proposals, `validate` after every change. Never read, write, or edit archik files manually.
3
+ description: Use whenever .archik/main.archik.yaml or architecture.archik.yaml exists in the project, or the user asks about architecture, services, dependencies, or data flow. The YAML is the shared map between user and Claude. Interact with it ONLY through the `npx archik` CLI — `q` for queries, `schema` for shape, `suggest set` for proposals, `validate` after every change. Never read, write, or edit archik files manually.
4
4
  ---
5
5
 
6
6
  # Archik — the project's shared map
7
7
 
8
- The archik file is **the user's source of truth for what the system
9
- looks like**. It lists every meaningful node (services, databases,
10
- queues, frontends, external APIs, …) and the edges between them.
11
- The canvas in the browser is a stateless projection of this file —
12
- when the user says "the orders service" or "the events queue", they
13
- mean the entity with that `id` in the YAML.
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.
14
9
 
15
- The file lives in one of two places, in this order of preference:
16
-
17
- 1. `.archik/main.archik.yaml` — the new convention. Keeps the
18
- project root tidy and leaves room for sub-architectures (other
19
- `.archik/*.archik.yaml` files for individual components).
20
- 2. `architecture.archik.yaml` — the legacy root location, still
21
- fully supported.
22
-
23
- Run `npx archik validate` (or check both paths) to find which one the
24
- project uses. Don't assume — small differences here matter.
25
-
26
- Treat the file as a shared vocabulary. It exists so the user and
27
- you can talk about the system without re-explaining it every time.
10
+ You don't need to read or memorise the YAML's shape. The CLI is your interface to everything: structure, schema, proposals, lifecycle.
28
11
 
29
12
  ## Hard rule: the CLI is the only interface to archik files
30
13
 
31
- You MUST NOT use `Read`, `Write`, `Edit`, or any other file-touching
32
- tool against `.archik/main.archik.yaml`, `architecture.archik.yaml`,
33
- any `*.archik.yaml` sub-file, or any sidecar. The `npx archik` CLI is
34
- the contract — it owns reads, writes, validation, and lifecycle.
35
-
36
- | Need | Use |
37
- | ----------------------------- | ----------------------------------------- |
38
- | Inspect structure | `npx archik q ...` |
39
- | Validate | `npx archik validate <path>` |
40
- | Propose a change | `npx archik suggest set <draft>` |
41
- | Apply / discard a suggestion | `npx archik suggest accept | reject` |
42
- | Render or diff | `npx archik render` / `npx archik diff` |
43
-
44
- `.archik/main.archik.yaml` is the user's source of truth — only
45
- `npx archik suggest accept` is allowed to mutate it. The sidecar
46
- `.archik/main.archik.suggested.yaml` is owned by the CLI too — only
47
- `npx archik suggest set` (writes it) and `accept` / `reject`
48
- (consumes it) may touch it.
49
-
50
- If `npx archik` is unreachable (offline, sandboxed, missing), STOP
51
- and tell the user. Do NOT fall back to reading or editing YAML by
52
- hand — that breaks the contract and silently desyncs the canvas.
53
-
54
- The user-facing slash commands are thin shims over this same CLI:
55
-
56
- | Command | Purpose |
57
- | ---------------------- | --------------------------------------------- |
58
- | `/archik:spawn` | Bootstrap a diagram from the source tree |
59
- | `/archik:evolve` | Propose a cleaner bounded-context refactor |
60
- | `/archik:suggest <…>` | Propose changes from a feature description |
61
- | `/archik:describe <id>`| Explain a node and its connections |
62
- | `/archik:accept` | Apply the pending suggestion |
63
- | `/archik:reject` | Discard the pending suggestion |
64
- | `/archik:dev` | Start the live canvas |
65
-
66
- When a user types `/archik:suggest <description>`, `/archik:spawn`,
67
- or `/archik:evolve`, treat it as direct authorisation to run the
68
- sidecar workflow now — skip the "want me to update the YAML?"
69
- question. Each command's body file under `.claude/commands/archik/`
70
- has the detailed protocol for that specific verb; follow it.
71
-
72
- Three things separate the proposal commands:
73
-
74
- - **`spawn`** is *descriptive* — mirror the source tree as it is.
75
- - **`evolve`** is *prescriptive* — propose a cleaner shape, then
76
- wait for the user to discuss before they accept. Never
77
- auto-accepts.
78
- - **`suggest`** is *targeted* — apply one feature-sized change
79
- from a user description.
80
-
81
- ## Protocol
82
-
83
- 1. **Before** answering structural questions — *"what does X do?",
84
- "what depends on Y?", "where does data flow when …?"* — query
85
- the diagram with `npx archik q ...` (see CLI section). The CLI
86
- walks the root file plus every `.archik/*.archik.yaml` sub-file
87
- and returns focused, deterministic answers. Don't guess from
88
- filenames or memory, and don't read the YAML directly — see the
89
- hard rule above.
90
- 2. **When** work introduces, removes, or rewires components, author
91
- the proposed end-state in a workspace temp file (e.g.
92
- `/tmp/archik-draft-<id>.yaml`) and stage it as the sidecar with
93
- `npx archik suggest set <tmp> --note "<one-liner>"`. Do NOT
94
- write `.archik/main.archik.suggested.yaml` directly — the CLI is
95
- the only thing allowed to put files in `.archik/`. The user
96
- reviews and accepts in the canvas or via
97
- `npx archik suggest accept`.
98
- 3. **After** every `suggest set`, the CLI has already validated for
99
- you — schema, cross-file existence, the lot. If it exits non-zero,
100
- fix the temp draft and re-run; never patch the sidecar directly.
101
- For files outside `.archik/` (none, in a normal flow), use
102
- `npx archik validate <path>`.
103
-
104
- The sections below are the detailed reference behind these three
105
- rules — *when* to consult, *when* to propose, schema, taxonomy,
106
- relationship vocabulary, and CLI.
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.
107
15
 
108
- ## Grounding (do this once per session, before structural work)
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` |
109
25
 
110
- The archik file tells you *what* exists. The source tree tells you
111
- *where* it lives. The mapping between the two is the whole reason
112
- the file is valuable — without it you just know there's "an Orders
113
- service" but not where to go to read or edit it. So:
114
-
115
- 1. **Pull the diagram shape from the CLI.** Don't `cat` the YAML —
116
- use the query CLI:
117
- ```
118
- npx archik q stats # files, node and edge counts, kind histogram
119
- npx archik q list # every node, with kind and parent
120
- npx archik q edges # every edge, with relationship and endpoints
121
- ```
122
- That gives you the same picture as reading the file, without
123
- touching it.
124
- 2. **List the source tree.** A single `ls` of the top-level project
125
- directory plus the most likely source roots is usually enough:
126
- `ls -F . src/ services/ packages/ apps/ 2>/dev/null`. (`ls
127
- .archik/` is fine for *finding out which sub-architectures
128
- exist*; don't open the YAMLs themselves — query them via
129
- `npx archik q list --file <name>`.)
130
- 3. **Build the mapping in your head.** Most projects follow one of
131
- two patterns: each top-level archik node id matches a folder
132
- under `src/` (or `services/` / `packages/`), or the `stack` /
133
- `description` field hints at the location. Note the mismatches
134
- — those are the places where moving a folder will outgrow the
135
- diagram, and where new code is most likely to need a YAML
136
- update too.
137
- 4. **Cross-check the source tree** when answering structural
138
- questions: most projects keep one folder per top-level node under
139
- `src/` (or `services/` / `packages/`). Mismatches are where
140
- moving code will outgrow the diagram and where new code most
141
- often needs a YAML update too.
142
-
143
- When the user asks "where would I add X?" or "what's the right
144
- place for Y?", you should already have the answer because step 3
145
- gave it to you. When they ask "what would `archik render` show?",
146
- run `npx archik render --out /tmp/preview.svg` and describe it.
147
-
148
- ## Suggesting changes (the sidecar workflow)
149
-
150
- The archik file is the user's source of truth. You don't mutate it
151
- directly, and you don't write the sidecar directly either — both are
152
- under `.archik/` and only the CLI is allowed to touch that
153
- directory (see the hard rule).
154
-
155
- The flow is always the same:
156
-
157
- 1. Author the *full proposed end-state* document in a workspace temp
158
- file outside `.archik/`. Pick a path like
159
- `/tmp/archik-draft-<short-id>.yaml`.
160
- 2. Run `npx archik suggest set <tmp> --note "<one-liner>"`. The CLI
161
- parses, schema-validates, checks cross-file references, stamps
162
- `metadata.suggestion`, and atomically renames the draft into
163
- place as `.archik/main.archik.suggested.yaml` (or the legacy
164
- `architecture.archik.suggested.yaml`).
165
- 3. If `set` exits non-zero, fix the temp file based on the reported
166
- errors and re-run. Never patch the sidecar with `Edit`/`Write`.
167
-
168
- A minimal draft looks exactly like a normal archik document — the
169
- CLI fills in the suggestion marker for you, so you don't have to:
170
-
171
- ```yaml
172
- version: "1.0"
173
- name: My Architecture
174
- nodes:
175
- # ... entire proposed end-state, not just the delta
176
- edges:
177
- # ...
178
- ```
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.
179
27
 
180
- Once `suggest set` has succeeded:
28
+ If `npx archik` is unreachable (offline, sandboxed, missing), STOP and tell the user. Do NOT fall back to reading or editing YAML by hand.
181
29
 
182
- * The canvas shows a **📝 Suggestion pending** banner with `Review`,
183
- `Accept`, `Reject` buttons. Review **toggles an in-canvas overlay
184
- on the same page** — added nodes/edges get green frames, removed
185
- ones get red dashed frames and dim out, changed ones get amber
186
- frames, and each gets a `+` / `−` / `~` badge. Accept renames the
187
- sidecar over the main file; Reject deletes the sidecar.
188
- * From the terminal: `npx archik suggest show | accept | reject`.
30
+ ## Slash commands (user-facing entry points)
189
31
 
190
- If the user has no canvas open and asks "apply it", run
191
- `npx archik suggest accept` for them (only after they've explicitly
192
- asked).
32
+ | Command | Purpose |
33
+ | --------------------------- | --------------------------------------------- |
34
+ | `/archik:spawn` | Bootstrap a diagram from the source tree |
35
+ | `/archik:evolve` | Propose a cleaner bounded-context refactor |
36
+ | `/archik:suggest <…>` | Propose changes from a feature description |
37
+ | `/archik:describe <id>` | Explain a node and its connections |
38
+ | `/archik:accept` | Apply the pending suggestion |
39
+ | `/archik:reject` | Discard the pending suggestion |
40
+ | `/archik:dev` | Open the live canvas |
193
41
 
194
- **Key rules:**
42
+ 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.
195
43
 
196
- * Write the *full proposed document*, not a patch. The diff is
197
- computed by archik between the main file and the sidecar.
198
- * Don't call `Write`/`Edit` against `.archik/main.archik.suggested.yaml`
199
- or any peer file under `.archik/`. The CLI owns that directory.
200
- * If a suggestion sidecar already exists, `npx archik suggest set`
201
- overwrites it. Tell the user you're replacing their previous
202
- pending suggestion.
44
+ 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.
203
45
 
204
- ## When to consult the YAML
46
+ Distinction:
47
+ - **`spawn`** = descriptive (mirror the source tree as it is)
48
+ - **`evolve`** = prescriptive (propose a cleaner shape, then discuss before accepting)
49
+ - **`suggest`** = targeted (apply one feature-sized change from a description)
205
50
 
206
- Read it **before answering** any of these:
51
+ ## Protocol — three rules
207
52
 
208
- - "What does X do?" / "What's the responsibility of X?"
209
- - "What writes to / reads from / publishes to Y?"
210
- - "Where does data flow when …?"
211
- - "What services exist?" / "What's in the architecture?"
212
- - "What depends on Z?" / "What would break if I remove Z?"
213
- - "Is there a queue / cache / gateway already?"
53
+ 1. **Before** answering structural questions, query via `npx archik q ...`. Never `cat` or `Read` the YAML.
54
+ 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.
55
+ 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).
214
56
 
215
- Don't guess. The YAML has the answer or it doesn't — if it doesn't, say
216
- so and offer to add it.
57
+ ## Grounding (do this once per session, before structural work)
217
58
 
218
- ## When to propose updates to the YAML
59
+ The archik diagram tells you *what* exists. The source tree tells you *where* it lives. Use the CLI for the first half:
219
60
 
220
- Proactively suggest edits (don't silently apply them — the user owns
221
- this file) when the work you're doing changes the structure:
61
+ ```
62
+ npx archik q stats # node + edge counts, kind histogram, file count
63
+ npx archik q list # every node with kind, parent, file
64
+ npx archik q edges # every edge with relationship and endpoints
65
+ ```
222
66
 
223
- - Adding a new service, function, worker, frontend, queue, DB, etc.
224
- - Introducing a new dependency between existing components.
225
- - Adding a new external API integration.
226
- - Removing or renaming a component.
227
- - Splitting one component into several, or merging several into one.
67
+ 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.
228
68
 
229
- Frame it as: *"This adds a `payments-worker` that reads from the
230
- `order-events` queue and writes to `payments-db`. Want me to update
231
- the archik file to capture that?"*
69
+ When the user asks "where would I add X?", you should already have the answer because you ran the queries above.
232
70
 
233
- ## When to defer
71
+ ## Authoring drafts (sidecar workflow)
234
72
 
235
- - Pure refactors that don't change the component graph → leave it alone.
236
- - Local file moves / renames → leave it alone.
237
- - Bug fixes inside an existing node → leave it alone.
73
+ 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.
238
74
 
239
- The YAML tracks **shape**, not implementation detail.
240
-
241
- ## Hard rules for editing
242
-
243
- The schema enforces these — `npx archik validate` will reject the file
244
- if you break any of them, so don't bother trying.
245
-
246
- - **Never put coordinates** (`x`, `y`, `width`, `height`, `viewport`) in
247
- the YAML. Layout is computed by ELK on every render. The schema
248
- rejects unknown keys at root, node, edge, and metadata levels.
249
- - **Every id matches** `^[a-z][a-z0-9-]*$` — lowercase, starts with a
250
- letter, hyphens allowed.
251
- - **Node ids and edge ids are unique** within their respective lists.
252
- Duplicates fail validation.
253
- - **Edges reference existing nodes**. If `from` or `to` doesn't match
254
- a node id, the document fails to load.
255
- - **No self-loop edges** — `from === to` isn't meaningful for an
256
- architecture diagram and the schema rejects it.
257
- - **`parentId` references an existing node** (any kind — typically a
258
- `module` or `custom` container, but any node-with-children renders
259
- as a container).
260
- - **No `parentId` cycles** — a → b → a, or a node with itself as parent.
261
- - **Any node with children is rendered as a container** regardless of
262
- kind. So you can have a `frontend` "Web App" containing `module`
263
- sub-areas, or a `service` containing `adapter` children — the icon
264
- and KIND tag in the header still reflect the node's own kind.
265
- - **Don't rename a node id**. Remove the old node and re-add it with
266
- the new id, then fix every edge / parentId that referenced it.
267
- - **Don't change `version`** — it's `"1.0"`.
268
-
269
- ## Schema (top-level)
270
-
271
- ```yaml
272
- version: "1.0" # literal — must be "1.0"
273
- name: My Architecture # required
274
- description: ... # optional
275
- nodes: [ ... ] # required, may be empty
276
- edges: [ ... ] # required, may be empty
277
- metadata: # optional
278
- createdAt: "..."
279
- updatedAt: "..."
280
- ```
75
+ **Step 1 — get the schema.** Before authoring, run:
281
76
 
282
- ## Node fields
283
-
284
- ```yaml
285
- - id: orders # required, kebab-case
286
- kind: service # required, see taxonomy below
287
- name: Orders # required, human-readable
288
- description: ... # optional, free text
289
- stack: Go + Postgres # optional, technology label shown under name
290
- responsibilities: # optional, string list
291
- - place orders
292
- - track shipments
293
- interfaces: # optional, list of contract specs
294
- - name: POST /orders
295
- protocol: http
296
- description: ... # optional
297
- notes: # optional, list of free-text notes
298
- - "Migrated from monolith in 2024."
299
- parentId: platform # optional, must reference a real node
300
- archikFile: .archik/orders.archik.yaml # optional drill-down
301
- metadata: # optional, free record
302
- team: fulfillment
77
+ ```
78
+ npx archik schema
303
79
  ```
304
80
 
305
- ### Cross-file edges (`fromFile` / `toFile`)
81
+ 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.**
306
82
 
307
- Edges can also point at a node that lives in a peer file. Set
308
- `toFile` (or `fromFile`) to that file's relative path; the canvas
309
- won't draw the edge itself but will hang an "↗" badge on the local
310
- endpoint, with the target file in the tooltip. Click → navigate.
83
+ **Step 2 — pipe the draft straight into `suggest set` via heredoc.** No temp files, no `/tmp/` paths:
311
84
 
312
- ```yaml
85
+ ```bash
86
+ npx archik suggest set --note "<one-liner>" - <<'YAML'
87
+ version: "1.0"
88
+ name: My Architecture
89
+ nodes:
90
+ # full proposed end-state — every node, not just the delta
313
91
  edges:
314
- - id: api-pays
315
- from: api # local node
316
- to: charge-handler
317
- toFile: .archik/payments.archik.yaml # peer file
318
- relationship: http_call
319
- label: charge
92
+ # full proposed end-state — every edge, not just the delta
93
+ YAML
320
94
  ```
321
95
 
322
- Constraints (the schema enforces them):
323
-
324
- - The cross-file path follows the same rules as `archikFile` (relative,
325
- forward slashes, no `..`, ends in `.archik.yaml`).
326
- - The path is resolved against the **project root** (parent of
327
- `.archik/` under the new layout, the doc's own directory under the
328
- legacy one) — same rule as `archikFile`. `npx archik validate` exits
329
- 1 if the file isn't on disk.
330
- - The *local* endpoint id must still match a node in this file.
331
- - An edge with **both** `fromFile` and `toFile` is rejected — author
332
- it inside one of the two referenced files instead.
333
-
334
- ### Drilling into a sub-architecture (`archikFile`)
335
-
336
- A node can point at *its own* archik file via `archikFile`. The
337
- canvas shows a small "↓ open" badge on those nodes; clicking it
338
- loads the linked file and adds a breadcrumb so the user can come
339
- back. Use it when a component is meaty enough to deserve its own
340
- diagram (a service with internal modules, a frontend with several
341
- panes, etc.).
342
-
343
- Constraints (the schema enforces them):
344
- - Relative path only — no leading `/`, no Windows drive letter.
345
- - Must use forward slashes; `..` segments are rejected.
346
- - Must end in `.archik.yaml` (the suggestion sidecar is derived
347
- automatically as `<stem>.suggested.yaml` next to it).
348
- - **Resolved against the project root**, not the file's own
349
- directory. With the new layout the project root is the parent of
350
- `.archik/`, so a sibling sub-file is `.archik/orders.archik.yaml`
351
- (with the prefix), NOT `orders.archik.yaml`. `npx archik validate`
352
- exits 1 if the target file isn't on disk — catch it there instead
353
- of as a 404 in the canvas.
354
- - Cycles aren't checked at parse time (each file validates on its
355
- own); if you wire a loop the canvas just lets the user navigate
356
- in and out.
357
-
358
- Conventional layout: keep sub-files under `.archik/` next to
359
- `main.archik.yaml`, and reference them with the `.archik/` prefix:
96
+ 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.
360
97
 
361
- ```
362
- .archik/main.archik.yaml # entry point
363
- .archik/orders.archik.yaml # Orders service internals
364
- .archik/payments.archik.yaml # Payments service internals
365
- ```
98
+ **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`.
366
99
 
367
- ```yaml
368
- # in .archik/main.archik.yaml
369
- nodes:
370
- - id: orders
371
- kind: service
372
- name: Orders
373
- archikFile: .archik/orders.archik.yaml # ✅ project-root relative
374
- # archikFile: orders.archik.yaml # ❌ validate fails
375
- ```
100
+ ### Sub-architectures (a brand-new `archikFile`)
376
101
 
377
- ## Node kinds (27 total, grouped by purpose)
378
-
379
- | Group | Kinds |
380
- | ----------- | --------------------------------- |
381
- | Compute | `service`, `function`, `worker`, `agent` |
382
- | Data | `database`, `cache`, `vectordb`, `storage` |
383
- | Messaging | `queue`, `topic`, `stream` |
384
- | Networking | `gateway`, `cdn`, `route` |
385
- | Hexagonal | `interface`, `adapter`, `port` |
386
- | AI / ML | `llm`, `prompt`, `tool` |
387
- | Identity | `auth` |
388
- | Observability | `observability` |
389
- | Cloud | `cloud` |
390
- | UI | `frontend` |
391
- | External | `external` |
392
- | Structural | `module`, `custom` |
393
-
394
- Picking the right kind:
395
-
396
- - A long-running HTTP service → `service`
397
- - A serverless function / lambda → `function`
398
- - A background job consumer → `worker`
399
- - An autonomous AI agent driving tools → `agent`
400
- - Postgres / DynamoDB / etc → `database`
401
- - Redis / Memcached → `cache`
402
- - Pinecone / pgvector / Weaviate → `vectordb`
403
- - S3 / GCS / blob → `storage`
404
- - SQS / RabbitMQ work queue → `queue`
405
- - SNS / Kafka pub/sub topic → `topic`
406
- - Kafka / Kinesis stream-of-events → `stream`
407
- - API gateway, ingress, edge proxy → `gateway`
408
- - CloudFront / Fastly → `cdn`
409
- - A specific HTTP route / URL endpoint (e.g. `POST /v1/orders`) → `route`
410
- - An abstract contract → `interface`
411
- - A concrete impl of an interface → `adapter`
412
- - A hexagonal-architecture port → `port`
413
- - An LLM API (OpenAI, Anthropic) → `llm`
414
- - A reusable prompt template → `prompt`
415
- - An LLM-callable tool → `tool`
416
- - Auth0 / Clerk / IDP → `auth`
417
- - Datadog / Grafana / OTEL collector → `observability`
418
- - A managed cloud service that doesn't fit → `cloud`
419
- - Browser / mobile / CLI → `frontend`
420
- - Third-party API you don't run → `external`
421
- - A logical grouping container (component, module) → `module`
422
- - Anything that doesn't fit and you want a custom shape → `custom`
423
-
424
- **Distinct visual shapes** (not just an icon — the *outline* differs):
425
-
426
- | Kind | Shape |
427
- | ---- | ----- |
428
- | `database` | classic UML cylinder |
429
- | `cloud` | cumulus cloud silhouette |
430
- | `queue` | rounded capsule (pill) |
431
- | `external` | dashed-border card |
432
- | `module` / `custom` (with children) | container panel with header + tinted body |
433
-
434
- Every other kind renders as the standard rounded card — the kind icon
435
- in the header and the KIND label do the visual lifting. Don't expect
436
- each kind to have its own outline; the icon + KIND tag is the
437
- identity.
438
-
439
- **Containers**: any node with children (declared via other nodes'
440
- `parentId`) renders as a container, regardless of kind. So
441
- `frontend` "Web App" can contain `module` sub-areas, a `service`
442
- can contain hexagonal `port`/`adapter` children, etc. The kind of
443
- the container itself controls the icon + accent colour shown in the
444
- header bar.
445
-
446
- ## Edge fields
447
-
448
- ```yaml
449
- - id: api-db # required, kebab-case
450
- from: api # required, must be a node id
451
- to: db # required, must be a node id
452
- relationship: writes # required, see vocabulary below
453
- label: "create order" # optional, shows on the canvas
454
- description: ... # optional
455
- protocol: http # optional
456
- color: "#f97316" # optional, any CSS color (hex / named / var())
457
- ```
102
+ 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:
458
103
 
459
- ## Relationships (17 total)
460
-
461
- | Category | Relationship | Visual signature |
462
- | -------------- | ------------ | ---------------- |
463
- | Sync wire | `http_call` | dotted, animated, filled-triangle arrow |
464
- | | `grpc` | thicker dashed, animated, **double-tick chevron** arrow |
465
- | | `invokes` | dotted, animated, filled-triangle arrow |
466
- | | `routes_to` | solid, no animation |
467
- | Bidirectional | `websocket` | dashed, **fast** animation, **arrows on both ends** |
468
- | Async callback | `webhook` | long-dash dashed, animated, hollow-triangle arrow |
469
- | Data access | `reads` | dotted, animated, hollow-triangle arrow |
470
- | | `writes` | thicker dotted, animated, filled-triangle arrow |
471
- | Messaging | `publishes` | dotted, animated, **circle** arrow head |
472
- | | `subscribes` | dotted, animated, filled-triangle arrow |
473
- | | `streams_to` | long-dash, **fast** animation, filled-triangle |
474
- | UML structural | `implements` | dashed, **hollow-triangle** at the interface end (UML realisation) |
475
- | | `extends` | solid, **hollow-triangle** at parent end (UML inheritance) |
476
- | | `composes` | solid, **filled-diamond at the owner (source) end** (UML composition) |
477
- | Loose deps | `depends_on` | dashed, hollow-triangle arrow |
478
- | | `has_a` | solid, filled-triangle (informal composition) |
479
- | | `uses` | short-dash, hollow-triangle (lightest dependency) |
480
-
481
- Picking the right relationship:
482
-
483
- **Wire-protocol calls** (something is going over the network *now*):
484
- - Generic HTTP / REST call → `http_call`
485
- - Typed RPC (protobuf, Connect, Twirp) → `grpc`
486
- - Function / agent / lambda invocation → `invokes`
487
- - Gateway / ingress routing → `routes_to`
488
- - Long-lived bidirectional connection (chat, live trading, collab) → `websocket`
489
- - Async callback the *other party* pushes to *us* (Stripe webhook, GitHub event) → `webhook`
490
-
491
- **Data access**:
492
- - DB read query → `reads`
493
- - DB write / mutation → `writes`
494
-
495
- **Messaging**:
496
- - Emitting an event / message → `publishes`
497
- - Consuming an event / message → `subscribes`
498
- - Continuous stream of records (Kafka, Kinesis, log shipping) → `streams_to`
499
-
500
- **UML class-diagram structural** (drawn in the same style as a UML class diagram, so the visual matches what an engineer expects on a board):
501
- - Adapter realises an abstract interface → `implements`
502
- - Subclass / subtype inherits → `extends`
503
- - Whole owns the part's lifecycle (component composition) → `composes`
504
-
505
- **Looser architectural** (not UML-strict — for "X depends on Y" without claiming a specific relationship):
506
- - Package / build-level dependency → `depends_on`
507
- - Informal "has a" without lifecycle ownership → `has_a`
508
- - Lightest weight: "X uses Y somewhere" → `uses`
509
-
510
- ## Common editing patterns
511
-
512
- **Adding a service that writes to a database**:
513
-
514
- ```yaml
515
- nodes:
516
- - id: payments
517
- kind: service
518
- name: Payments
519
- stack: Go
520
- - id: payments-db
521
- kind: database
522
- name: Payments DB
523
- stack: Postgres 16
524
- edges:
525
- - id: payments-writes-db
526
- from: payments
527
- to: payments-db
528
- relationship: writes
104
+ ```bash
105
+ # 1. Stage + accept the new sub-file (orphan, parent doesn't exist yet)
106
+ npx archik suggest set --main .archik/<id>.archik.yaml \
107
+ --allow-orphan \
108
+ --note "spawn: <id> internals" - <<'YAML'
109
+ ...
110
+ YAML
111
+ npx archik suggest accept .archik/<id>.archik.yaml
112
+
113
+ # 2. Now the file is real on disk; stage the parent change
114
+ npx archik suggest set --note "..." - <<'YAML'
115
+ ... (with archikFile: .archik/<id>.archik.yaml on the relevant node)
116
+ YAML
529
117
  ```
530
118
 
531
- **Adding an LLM agent with tools**:
119
+ **Rules:**
120
+ - Write the *full proposed document*, not a patch. The diff is computed by archik between main and sidecar.
121
+ - Don't `Write`/`Edit` archik files. The CLI owns `.archik/`.
122
+ - If a sidecar already exists, `suggest set` overwrites it. Mention to the user that you replaced their previous pending suggestion.
123
+ - Renaming an `id` is forbidden — remove the old node and add a new one. Renames break diff and require manual re-link in code.
124
+ - Don't drop user-authored `description`, `responsibilities`, or `notes` fields when carrying a node forward.
532
125
 
533
- ```yaml
534
- nodes:
535
- - id: support-agent
536
- kind: agent
537
- name: Support Agent
538
- description: Handles tier-1 customer questions.
539
- - id: openai
540
- kind: llm
541
- name: GPT-4o
542
- - id: lookup-orders
543
- kind: tool
544
- name: Lookup orders
545
- edges:
546
- - id: agent-llm
547
- from: support-agent
548
- to: openai
549
- relationship: invokes
550
- - id: agent-uses-tool
551
- from: support-agent
552
- to: lookup-orders
553
- relationship: uses
554
- ```
126
+ ## When to consult the YAML (via `q`)
555
127
 
556
- **Grouping nodes inside a module**:
128
+ - "What does X do?" / "What's its responsibility?" → `npx archik q describe X`
129
+ - "What writes to / reads from / publishes to Y?" → `npx archik q dependents Y --rel writes` etc.
130
+ - "What depends on Z?" → `npx archik q dependents Z`
131
+ - "What would break if I remove Z?" → `npx archik q impact Z`
132
+ - "What services exist?" / "Is there a queue / cache / gateway already?" → `npx archik q list --kind <kind>`
557
133
 
558
- ```yaml
559
- nodes:
560
- - id: orders-module
561
- kind: module
562
- name: Orders
563
- - id: orders-api
564
- kind: service
565
- name: Orders API
566
- parentId: orders-module
567
- - id: orders-db
568
- kind: database
569
- name: Orders DB
570
- parentId: orders-module
571
- ```
134
+ If `q` returns empty for an id, the YAML doesn't have it — say so and offer to add it via `/archik:suggest`.
572
135
 
573
- ELK will nest them visually inside the module's container.
136
+ ## When to propose updates
574
137
 
575
- **Adding a hexagonal port + adapter**:
138
+ Proactively suggest a sidecar (don't silently apply) when work changes shape:
576
139
 
577
- ```yaml
578
- nodes:
579
- - id: payment-port
580
- kind: port
581
- name: Payment Port
582
- - id: stripe-adapter
583
- kind: adapter
584
- name: Stripe Adapter
585
- edges:
586
- - id: stripe-implements-port
587
- from: stripe-adapter
588
- to: payment-port
589
- relationship: implements
590
- ```
140
+ - New service, function, worker, frontend, queue, DB, etc.
141
+ - New dependency between existing components.
142
+ - New external API integration.
143
+ - Removing or renaming a component.
144
+ - Splitting one component into several, or merging several into one.
591
145
 
592
- **Modelling a real-time chat with WebSocket + a Stripe webhook**:
146
+ 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`.
593
147
 
594
- ```yaml
595
- nodes:
596
- - id: web
597
- kind: frontend
598
- name: Web App
599
- - id: api
600
- kind: service
601
- name: Chat API
602
- - id: stripe
603
- kind: external
604
- name: Stripe
605
- edges:
606
- - id: web-api-ws
607
- from: web
608
- to: api
609
- relationship: websocket # bidirectional, fast animation
610
- label: messages
611
- - id: stripe-api-webhook
612
- from: stripe
613
- to: api
614
- relationship: webhook # async callback
615
- label: payment.succeeded
616
- ```
148
+ ## When to defer
617
149
 
618
- **gRPC between two Go services + UML class hierarchy**:
150
+ - Pure refactors that don't change the component graph → leave the diagram alone.
151
+ - Local file moves / renames → leave it alone.
152
+ - Bug fixes inside an existing node → leave it alone.
619
153
 
620
- ```yaml
621
- nodes:
622
- - id: orders
623
- kind: service
624
- name: Orders
625
- - id: payments
626
- kind: service
627
- name: Payments
628
- - id: order
629
- kind: interface
630
- name: Order
631
- - id: subscription-order
632
- kind: interface
633
- name: SubscriptionOrder
634
- - id: cart
635
- kind: custom
636
- name: Cart
637
- edges:
638
- - id: orders-payments-grpc
639
- from: orders
640
- to: payments
641
- relationship: grpc # double-tick chevron
642
- label: ChargeRequest
643
- - id: subscription-extends-order
644
- from: subscription-order
645
- to: order
646
- relationship: extends # UML hollow triangle
647
- - id: cart-composes-order
648
- from: cart
649
- to: order
650
- relationship: composes # UML filled diamond at Cart
651
- ```
154
+ The diagram tracks **shape**, not implementation detail.
652
155
 
653
- ## CLI
156
+ ## Follow-ups (do this after every accept / reject)
654
157
 
655
- The CLI is the agent-friendly bridge to archik. Prefer it over
656
- re-reading the YAML when answering structural questions — the answers
657
- are deterministic, focused, and don't pollute your context with the
658
- whole diagram.
158
+ After a suggestion is accepted, the diagram has changed. Don't just stop — propose what's natural next. Pick whichever fits:
659
159
 
660
- ### Running the CLI
160
+ 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?"*
161
+ 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."*
162
+ 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?"*
163
+ 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.
661
164
 
662
- The CLI ships as the `archik` npm package. Two equivalent ways to
663
- invoke any command:
165
+ After a rejection, ask one clarifying question — *"Want me to try a smaller change that only touches X?"* — instead of going silent.
664
166
 
665
- ```
666
- npx archik <command> # works without installing — caches after first use
667
- archik <command> # if the user has run `npm i -g archik`
668
- ```
167
+ The goal: every accepted change ends with the user knowing what's next, not "ok, accepted".
669
168
 
670
- **Default to `npx archik` in your suggestions and shell calls.** It
671
- just works in fresh repos, doesn't require a global install, and
672
- falls through to the cached binary on subsequent runs. Suggest
673
- `npm i -g archik` only when the user wants the live canvas
674
- (`archik dev`) on a fast keystroke.
169
+ ## Verification workflow
675
170
 
676
- If neither form is reachable (offline, sandboxed shell), fall back to
677
- reading the YAML directly with the same schema documented above —
678
- the file is always the source of truth.
171
+ After every `suggest set` or `suggest accept`:
679
172
 
680
- ### Without a positional path
173
+ 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.
174
+ 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.
175
+ 3. If `docs/architecture.svg` is committed, regenerate it (see Follow-ups).
681
176
 
682
- Every read command resolves the archik file in this order:
683
- `.archik/main.archik.yaml` (preferred), then
684
- `architecture.archik.yaml` (legacy). If both exist the command errors
685
- and asks the user to pick one.
177
+ ## CLI reference (run `<cmd> --help` for full surface)
686
178
 
687
- ### Querying the diagram (use this for structural questions)
179
+ The CLI ships as the `archik` npm package; default to `npx archik` (works in fresh repos, no global install needed).
688
180
 
689
181
  ```
690
- npx archik q describe <id> # node + its incoming/outgoing edges
691
- npx archik q deps <id> # outgoing edges (what this node uses)
692
- npx archik q dependents <id> # incoming edges (what uses this node)
693
- npx archik q list # all nodes
694
- --kind <k> # filter by kind (service, function, …)
695
- --parent <id> # filter by container
696
- --file <p> # filter by file (substring match)
697
- npx archik q edges # all edges
698
- --from <id> # filter by source
699
- --to <id> # filter by target
700
- --rel <name> # filter by relationship
701
- npx archik q impact <id> # what would break if this node were removed
702
- npx archik q stats # files, nodes, edges, kind histogram
703
- ```
182
+ npx archik schema # the document shape (always start here when authoring)
183
+ --json # structured shape for piping into jq
704
184
 
705
- Add `--json` to any `q` subcommand for a stable machine-readable
706
- shape (object on stdout). Exit codes: `0` found, `1` empty / unknown
707
- id, `2` could not load. Walks the root file plus every
708
- `.archik/*.archik.yaml` sub-file. Cross-file id collisions error
709
- rather than silently picking — surface the ambiguity.
185
+ npx archik q describe <id> | deps <id> | dependents <id>
186
+ list | edges | impact <id> | stats
187
+ --json # stable machine-readable shape
710
188
 
711
- ### Authoring & lifecycle
189
+ npx archik validate <path> [--json] # schema + cross-file check (CI-friendly)
190
+ npx archik render --out diagram.svg --theme light|dark
191
+ npx archik diff a.yaml b.yaml [--out diff.svg] [--json]
712
192
 
713
- ```
714
- npx archik validate # schema + cross-file existence (CI-friendly, exit 1 on error)
715
- npx archik validate --json # structured { ok, file, nodes, edges, errors }
716
- npx archik render --out diagram.svg
717
- --theme light # "dark" (default) or "light"
718
- npx archik diff a.yaml b.yaml # text summary
719
- npx archik diff a.yaml b.yaml --out diff.svg
720
- npx archik diff a.yaml b.yaml --json
721
- npx archik suggest show # summary of pending sidecar (default)
722
- --json # structured output
723
- npx archik suggest set <draft> # validate a draft YAML and stage it as the sidecar
724
- --note '<text>' # set metadata.suggestion.note
725
- --main <path> # override main file detection
726
- --json # structured output
727
- - # draft path "-" reads from stdin
728
- npx archik suggest accept # apply the sidecar over the main file
729
- npx archik suggest reject # discard the sidecar
730
- npx archik watch # re-render SVG on save
731
- npx archik dev # open the live editor in the browser
732
- npx archik start | stop | status # detached canvas server lifecycle
733
- npx archik init # scaffold a starter file + install skill + slash commands
734
- npx archik skill # install/refresh the Claude skill in cwd
735
- npx archik commands # install/refresh the /archik:* slash commands in cwd
736
- ```
193
+ npx archik suggest show [--json]
194
+ suggest set <draft|-> # validate + stage a sidecar
195
+ --note '<text>' # set metadata.suggestion.note
196
+ --main <path> # override main file detection
197
+ --allow-orphan # permit a sidecar with no main on disk
198
+ --json # structured output
199
+ suggest accept | reject
737
200
 
738
- ## Verification workflow
201
+ npx archik dev | start | stop | status # canvas server lifecycle
202
+ npx archik watch # re-render to SVG on save
203
+ npx archik init # scaffold + install skill + slash commands
204
+ npx archik skill | commands # refresh the skill / slash commands
205
+ ```
739
206
 
740
- After **every** `npx archik suggest set` or `npx archik suggest
741
- accept`:
742
-
743
- 1. The CLI has already validated the schema and cross-file references
744
- for you — `set` refuses to write a broken sidecar, `accept` runs
745
- over a sidecar that was validated when it was staged. If `set`
746
- reported errors, fix them in the temp draft and re-run; never
747
- reach for `Write`/`Edit` on the sidecar.
748
- 2. If the project has an `archik dev` server running, the file
749
- watcher broadcasts the change to the canvas automatically — no
750
- restart needed. Surface the URL so the user can click through.
751
- 3. If the project commits a rendered SVG (e.g.
752
- `docs/architecture.svg`), regenerate it with `npx archik render
753
- --out docs/architecture.svg` so the committed picture matches the
754
- YAML.
207
+ Per-command help: `npx archik <cmd> --help`.
755
208
 
756
209
  ## Things to avoid
757
210
 
758
- - Don't invent kinds or relationships outside the lists above — the
759
- Zod schema rejects them.
760
- - Don't add visual properties (colors, sizes, positions) to nodes.
761
- Only edges have `color`. Everything else comes from the renderer.
762
- - Don't add empty `notes` / `responsibilities` / `interfaces` lists —
763
- either include real entries or omit the field entirely.
764
- - Don't blow away `description`, `responsibilities`, or `notes` the
765
- user wrote unless they ask you to. They're encoded context.
766
- - Don't bulk-restructure the file as a side effect of a small edit.
767
- Make the minimal change that captures what changed.
211
+ - Don't `cat`, `Read`, `Write`, or `Edit` archik files.
212
+ - Don't author drafts from memory; run `npx archik schema` first.
213
+ - Don't add coordinates (`x`, `y`, `width`, `height`, `viewport`) — layout is computed by ELK on every render. The schema rejects them.
214
+ - Don't add empty `notes` / `responsibilities` / `interfaces` lists — either include real entries or omit the field.
215
+ - Don't blow away user-authored fields when carrying a node forward.
216
+ - Don't bulk-restructure as a side effect of a small edit. Make the minimal change that captures what changed.