chiltepin 0.47.0

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/dist/bin.js +3582 -0
  4. package/dist/bin.js.map +1 -0
  5. package/package.json +93 -0
  6. package/templates/chiltepin.config.json +5 -0
  7. package/templates/demo.md +2161 -0
  8. package/templates/docs/getting-started.md +155 -0
  9. package/templates/docs/tutorial.md +559 -0
  10. package/templates/skill/SKILL.md +172 -0
  11. package/templates/skill/reference/blocks/INDEX.md +141 -0
  12. package/templates/skill/reference/blocks/agentic.md +63 -0
  13. package/templates/skill/reference/blocks/algorithms.md +49 -0
  14. package/templates/skill/reference/blocks/api.md +40 -0
  15. package/templates/skill/reference/blocks/architecture.md +94 -0
  16. package/templates/skill/reference/blocks/business.md +70 -0
  17. package/templates/skill/reference/blocks/charts-overviews.md +74 -0
  18. package/templates/skill/reference/blocks/data-model.md +34 -0
  19. package/templates/skill/reference/blocks/design-system.md +50 -0
  20. package/templates/skill/reference/blocks/flows.md +74 -0
  21. package/templates/skill/reference/blocks/narrative.md +65 -0
  22. package/templates/skill/reference/blocks/planning.md +74 -0
  23. package/templates/skill/reference/blocks/quality.md +43 -0
  24. package/templates/skill/reference/blocks/tables-data.md +55 -0
  25. package/templates/skill/reference/check.md +62 -0
  26. package/templates/skill/reference/decks.md +198 -0
  27. package/templates/skill/reference/exemplars/adr.md +87 -0
  28. package/templates/skill/reference/exemplars/agent-system.md +113 -0
  29. package/templates/skill/reference/exemplars/api-reference.md +110 -0
  30. package/templates/skill/reference/exemplars/backend-arch.md +117 -0
  31. package/templates/skill/reference/exemplars/data-pipeline.md +107 -0
  32. package/templates/skill/reference/exemplars/frontend-arch.md +93 -0
  33. package/templates/skill/reference/exemplars/incident-postmortem.md +93 -0
  34. package/templates/skill/reference/exemplars/migration-plan.md +95 -0
  35. package/templates/skill/reference/exemplars/onboarding.md +78 -0
  36. package/templates/skill/reference/exemplars/product-spec.md +81 -0
  37. package/templates/skill/reference/intake.md +140 -0
  38. package/templates/skill/reference/mermaid.md +216 -0
  39. package/templates/skill/reference/organizing.md +118 -0
  40. package/templates/skill/reference/patterns-design.md +59 -0
  41. package/templates/skill/reference/patterns.md +167 -0
  42. package/templates/skill/reference/recipes.md +153 -0
  43. package/templates/skill/reference/style-ste.md +119 -0
  44. package/templates/skill/reference/system-design.md +161 -0
  45. package/templates/skill/reference/writing.md +132 -0
@@ -0,0 +1,167 @@
1
+ # Messaging and event patterns — which blocks draw them
2
+
3
+ Part of the **chiltepin** skill (the hub is `SKILL.md`, one folder up). Read
4
+ this when the request is about events, queues, streams, fan-out, or making a
5
+ write reliable across two systems. Each pattern names the reader question,
6
+ the block stack that answers it, and the trap. Fields: `chiltepin block <type>`.
7
+
8
+ Three rules hold for every pattern here:
9
+
10
+ - Topology at rest is a `block` with `preset: event`. Producers are `kind:
11
+ producer`, subscribers `kind: consumer`, brokers `kind: topic` (fan-out)
12
+ or `kind: queue` (one taker), streams `kind: stream`. The single
13
+ `producer` takes the accent; put the fan-out in one column so the topic
14
+ reads as the hub.
15
+ - One event's contract is an `eventcontract`, never a `table` row: it
16
+ carries producers, consumers, delivery, ordering, the partition `key`,
17
+ and retention, which is exactly what a consumer needs to be safe.
18
+ - Time and failure are `sequence` (async arrows `-->` for the broker hop,
19
+ an `alt` frame for the failure branch) or `flow` (retry loops, decisions).
20
+ A `block` shows who is wired to whom; it cannot show a retry.
21
+
22
+ ## Publish / subscribe (fan-out to many)
23
+
24
+ Question: when X happens, who reacts, and does the producer know them?
25
+ Stack: `block` (`preset: event`) → `eventcontract` for the event → prose on
26
+ delivery and ordering. Trap: a `sequence` with one arrow per subscriber
27
+ hides the point, which is that the publisher has no arrows to them.
28
+
29
+ ```block
30
+ preset: event
31
+ groups:
32
+ - { id: subs, col: 3, row: 1, cols: 1, rows: 3, label: Subscribers }
33
+ nodes:
34
+ - { id: orders, col: 1, row: 2, kind: producer, name: Orders, tech: order.placed }
35
+ - { id: t, col: 2, row: 2, kind: topic, name: order-events, tech: Kafka }
36
+ - { id: mail, col: 3, row: 1, kind: consumer, name: Email }
37
+ - { id: search, col: 3, row: 2, kind: consumer, name: Search index }
38
+ - { id: audit, col: 3, row: 3, kind: consumer, name: Audit log }
39
+ edges:
40
+ - orders -> t: publish
41
+ - t -> mail
42
+ - t -> search
43
+ - t -> audit
44
+ ```
45
+
46
+ ## Competing consumers (one taker wins)
47
+
48
+ Question: how does work spread across N workers, and how many times is a
49
+ message handled? Stack: `block` (`preset: event`, a `queue` not a `topic`,
50
+ the workers in one group, dashed edges to the workers that did not take
51
+ the message) → `spec` for at-least-once and idempotency rules. Trap:
52
+ drawing it as pub/sub; a queue delivers each message once.
53
+
54
+ ## Partitioned log and consumer group (streams)
55
+
56
+ Question: how does the stream scale, and what keeps order? Stack: `block`
57
+ (partitions as `queue` nodes inside a `Topic` group, consumers in a
58
+ `Consumer group` group, the partition key on the producer edge) → prose on
59
+ what the key is and what happens when a consumer joins or leaves. Trap: a
60
+ `sequence`; the question is placement, not time.
61
+
62
+ ```block
63
+ preset: event
64
+ groups:
65
+ - { id: t, col: 2, row: 1, cols: 1, rows: 3, label: orders topic (3 partitions) }
66
+ - { id: cg, col: 3, row: 1, cols: 1, rows: 3, label: billing consumer group }
67
+ nodes:
68
+ - { id: prod, col: 1, row: 2, kind: producer, name: Orders API }
69
+ - { id: p0, col: 2, row: 1, kind: queue, name: partition 0 }
70
+ - { id: p1, col: 2, row: 2, kind: queue, name: partition 1 }
71
+ - { id: p2, col: 2, row: 3, kind: queue, name: partition 2 }
72
+ - { id: c0, col: 3, row: 1, kind: consumer, name: billing-1 }
73
+ - { id: c1, col: 3, row: 2, kind: consumer, name: billing-2 }
74
+ - { id: c2, col: 3, row: 3, kind: consumer, name: billing-3 }
75
+ edges:
76
+ - prod -> p0: "key = order_id"
77
+ - prod -> p1
78
+ - prod -> p2
79
+ - p0 -> c0
80
+ - p1 -> c1
81
+ - p2 -> c2
82
+ ```
83
+
84
+ ## Event-driven backbone (many producers, many consumers)
85
+
86
+ Question: what is the shape of the whole event system? Stack: `block` in
87
+ `layers` mode (Producers · Backbone · Consumers) with one `topic` node in
88
+ the middle band → `table` of topics × producer × consumers × retention.
89
+ Trap: drawing every topic as a node; past four topics the table carries
90
+ it and the diagram shows the bands.
91
+
92
+ ## Outbox (reliable publish after a commit)
93
+
94
+ Question: how do we never lose an event when the commit succeeds and the
95
+ publish fails? Stack: `sequence` (API → DB writes row and outbox in one
96
+ transaction; relay polls outbox → broker; `alt` for the broker being
97
+ down) → `state` for the outbox row (pending → published → failed) → `spec`
98
+ for the invariants (same transaction, at-least-once, consumer idempotent).
99
+ Trap: a `block` alone; the pattern is an ordering of writes, so it needs
100
+ time.
101
+
102
+ ## Dead-letter queue and retry (poison messages)
103
+
104
+ Question: what happens to a message that keeps failing, and who looks at
105
+ it? Stack: `flow` (consume → process → ok / retry with backoff / after N
106
+ to the DLQ, `kind: error` on the DLQ edge) → `block` (`queue` → consumer
107
+ → `DLQ` queue) → `table` of failure classes × action × owner. Trap: a
108
+ `sequence`; the loop and the threshold are decisions, not messages.
109
+
110
+ ## CQRS (separate read and write models)
111
+
112
+ Question: why are reads and writes different shapes, and how does a write
113
+ reach the read side? Stack: `block` (command side → write store → events
114
+ → projector → read store → query side, `dfd` also works) → `sequence` for
115
+ one write and the eventual read → prose on the consistency lag and what
116
+ the UI does about it. Trap: an `erd` of the read model; the reader asked
117
+ for the split, not the columns.
118
+
119
+ ## Event sourcing (append-only log)
120
+
121
+ Question: where is the truth, and how is current state rebuilt? Stack:
122
+ `block` (commands → aggregate → event store, `replay` dashed back,
123
+ projections subscribing) → `eventcontract` for one event → `spec` for
124
+ replay, snapshots, and schema evolution. Trap: a `state` machine of the
125
+ aggregate; the pattern is about storage, not lifecycle.
126
+
127
+ ## Saga (multi-service undo)
128
+
129
+ Question: what happens when step three of five fails after steps one and
130
+ two committed? Stack: `saga` (forward steps, compensation under each,
131
+ `failAt`) → `sequence` only if the message order between services is the
132
+ question → `table` of steps × compensation × idempotency key. Trap: a
133
+ `flow`; a saga's shape is steps with their undo, which `flow` cannot say.
134
+
135
+ ## Scatter-gather
136
+
137
+ Question: how does one request fan out to N workers and come back as one
138
+ answer? Stack: `block` (coordinator → workers group → aggregator) →
139
+ `sequence` with a `par` frame for the parallel calls and the timeout
140
+ branch → `spec` for the partial-result rule. Trap: `flow`; the parallelism
141
+ is the point and `par` draws it.
142
+
143
+ ## Backpressure, retry, and circuit breaker
144
+
145
+ Question: what does the system do when a downstream slows or fails?
146
+ Stack: `state` for the breaker (closed → open → half-open) or `flow` for
147
+ retry with backoff and the give-up exit → `spec` for the numbers
148
+ (timeout, attempts, backoff, jitter, trip threshold) → `sequence` only for
149
+ the one call that shows the breaker opening. Trap: prose only; the
150
+ numbers are the contract, and `spec` holds them.
151
+
152
+ ## Change data capture and webhooks (events out of a store or to a partner)
153
+
154
+ Question: how do changes leave the database, or reach a partner, in
155
+ order and exactly once as far as they can tell? Stack: `dfd` (table →
156
+ log → connector → topic → consumers) or `sequence` (producer → partner
157
+ endpoint, signed, retried, `alt` for 5xx) → `eventcontract` for the
158
+ payload → `spec` for signing, retry, and replay. Trap: an `endpoint`
159
+ block for a webhook; the partner's endpoint is not ours to document.
160
+
161
+ ## Idempotency
162
+
163
+ Question: what happens when the same message or request arrives twice?
164
+ Stack: `sequence` with the duplicate as a second message and an `alt`
165
+ frame (key seen → return stored result) → `spec` for the key, its scope,
166
+ and its TTL → `state` when the record itself moves (received → processed).
167
+ Trap: a `callout` only; the reader needs the exact key and window.
@@ -0,0 +1,153 @@
1
+ # Composition recipes
2
+
3
+ Part of the **chiltepin** skill (the hub is `SKILL.md`, one folder up).
4
+ These are worked examples of composition, not forms to fill in. Two different
5
+ systems must not produce structurally identical docs.
6
+
7
+ Start from the reader
8
+ questions, not from a recipe. Keep a block only if your system raises its
9
+ question, and drop it if not. Add a block these stacks never mention when your
10
+ system needs it. Fields: `chiltepin block <type>`; discriminators: the family files.
11
+
12
+ Each recipe: the reader questions → the block stack in document order → the
13
+ alternatives rejected, and why. The stack notes what each block carries and
14
+ what the prose around it carries. Prose carries why, tradeoff, and consequence — never a
15
+ description of the block beside it.
16
+
17
+ ## Backend architecture
18
+
19
+ Reader questions: What are the boundaries? · What calls what on the critical
20
+ path? · Who owns what?
21
+
22
+ 1. `meta` — the system's name and its one-line job.
23
+ 2. Prose — why the system exists; the one constraint that shaped the design.
24
+ 3. `c4` — ours vs external, one level only. Prose after: what the boundary
25
+ decision costs, not what the picture already shows.
26
+ 4. `cluster` or `block` (`preset: infra`) — the deployment topology. Prose
27
+ after: which parts fail independently.
28
+ 5. `sequence` — the one request path that pays the bills, with its failure
29
+ branch. Prose after: the consequence a client can rely on.
30
+ 6. `table` — service × responsibility × owner.
31
+ 7. `callout` — the invariant that must not break.
32
+
33
+ Rejected: `uml` (class detail is the code's job) · `graph` (no boundaries —
34
+ a backend doc is about what contains what).
35
+
36
+ ## AI / agent architecture
37
+
38
+ Reader questions: What does the loop do? · What can it call? · What fills the
39
+ window? · What does a real run look like?
40
+
41
+ 1. `meta` — the agent's name and the task it owns.
42
+ 2. Prose — the task delegated to the agent; where a human stays in the loop.
43
+ 3. `agentloop` — environment, tools, memory, stop condition.
44
+ 4. `context` — the window budget. Prose after: what gets evicted first, and
45
+ why that is safe.
46
+ 5. `prompt` — the contract the model is held to.
47
+ 6. `sequence` — one turn end-to-end, including a tool failure.
48
+ 7. `trace` — one real transcript, evidence the loop behaves as drawn.
49
+ 8. `callout` — the safety boundary the agent cannot cross.
50
+
51
+ Rejected: `flow` (the loop is the primitive here, not a branch chart).
52
+
53
+ ## Frontend architecture
54
+
55
+ Reader questions: What are the modules? · What states can the UI be in? ·
56
+ Where does data come from?
57
+
58
+ 1. `meta` — the app and its rendering model in one line.
59
+ 2. Prose — the rendering-model decision (SSR/SPA/islands) and its cost.
60
+ 3. `frontend` or `felogic` — the module graph. Prose after: the dependency
61
+ rule the graph must keep.
62
+ 4. `wireframe` — the one screen that matters.
63
+ 5. `state` — the UI states, error and empty included. Prose after: which
64
+ state users actually sit in most.
65
+ 6. `sequence` — the data-fetch path.
66
+ 7. `table` — the routes.
67
+
68
+ Rejected: `c4` (usually one container — a boundary diagram with one box says
69
+ nothing).
70
+
71
+ ## Data flow / pipeline
72
+
73
+ Reader questions: Where does data come from and go? · What shape is it at
74
+ rest? · How fresh is it?
75
+
76
+ 1. `meta` — the pipeline and what depends on its output.
77
+ 2. Prose — why batch or stream; the cost of staleness in user terms.
78
+ 3. `dfd` (processes and stores) or `sankey` (when volumes are the story).
79
+ Prose after: the stage that loses or transforms data.
80
+ 4. `erd` — the shape at rest.
81
+ 5. `steps` — the backfill / replay procedure an operator runs.
82
+ 6. `slo` — the freshness targets the team commits to.
83
+
84
+ Rejected: `sequence` (a pipeline has no request/response pairing to draw).
85
+
86
+ Zone patterns compose — they are not block types. A medallion view
87
+ (bronze → silver → gold) is `block` with `layers`: one layer per zone, one
88
+ node per dataset with `tech` for format and retention, edges for the
89
+ promotions. A deployment topology is `block` with `preset: infra` and
90
+ `groups` for the account and network boundaries.
91
+
92
+ ## State machine
93
+
94
+ Reader questions: What states exist? · What forces a transition? · What is
95
+ illegal?
96
+
97
+ 1. `meta` — the object whose lifecycle this is.
98
+ 2. Prose — why these states exist; the invariant the machine protects.
99
+ 3. `state` — states and transitions.
100
+ 4. `table` — transition × guard × side effect.
101
+ 5. `sequence` — one path that exercises the risky transition. Prose after:
102
+ what a caller observes while it runs.
103
+ 6. `callout` — the illegal states, and why they must stay illegal.
104
+
105
+ Rejected: `flow` (flows end; lifecycles loop back).
106
+
107
+ ## Incident writeup
108
+
109
+ Reader questions: What happened, when? · Why did it break? · What did it
110
+ cost? · What prevents recurrence?
111
+
112
+ 1. `meta` — incident id, date, severity.
113
+ 2. `timeline` — detection to resolution. Prose after: where the response was
114
+ slow, and why.
115
+ 3. `sequence` or `flow` — the failure mechanism, not the happy path.
116
+ 4. `stats` — the impact in numbers.
117
+ 5. `steps` — remediation, each step with an owner.
118
+ 6. `takeaways` — what the organization keeps from the incident.
119
+
120
+ Rejected: `scqa` (a postmortem argues with evidence, not narrative).
121
+
122
+ ## ADR
123
+
124
+ Reader questions: What forced a decision? · What were the options? · What did
125
+ we accept by choosing?
126
+
127
+ 1. `meta` — the decision's id and title.
128
+ 2. Prose (Context) — the forcing fact, with a number in it.
129
+ 3. `options` — candidates against the criteria, verdict per card.
130
+ 4. `callout` (title "Decision") — the decision in one sentence.
131
+ 5. `proscons` — the consequences of the winner, both directions. Prose after:
132
+ the tradeoff the team explicitly accepts.
133
+ 6. `statustable` — the follow-up work the decision creates.
134
+
135
+ Rejected: `harvey` (only when criteria resist numbers) · `scorecard`
136
+ (weights imply a precision most ADRs do not have).
137
+
138
+ ## API reference
139
+
140
+ Reader questions: What can I call? · What do errors look like? · How do calls
141
+ compose?
142
+
143
+ 1. `meta` — the API and its version.
144
+ 2. Prose — auth model, versioning, base URL: what endpoint cards cannot
145
+ carry.
146
+ 3. `endpoint` × N — one card per operation, examples included.
147
+ 4. `sequence` — a multi-call workflow. Prose after: the ordering rule the
148
+ workflow depends on.
149
+ 5. `table` — the error codes and what the client should do about each.
150
+ 6. `glossary` — the domain terms the paths use.
151
+
152
+ Rejected: `packet` (binary protocols only) · standalone `code` (snippets
153
+ live inside the endpoint cards).
@@ -0,0 +1,119 @@
1
+ # STE discipline — style rules for Chiltepin text
2
+
3
+ Aerospace maintenance manuals follow rules like these so that a technician who
4
+ reads English as a second language cannot read a step in two ways. Our failure
5
+ mode is the same: text that looks fluent but means several things. These rules
6
+ adapt ASD-STE100 Simplified Technical English to software documentation. They
7
+ trade style for one property: each sentence has exactly one reading.
8
+
9
+ ## Vocabulary and terms
10
+
11
+ - One word, one meaning. If `build` names a command, do not also use it for
12
+ the compiled output.
13
+ - One concept, one word. If the doc says `endpoint`, it never says `route`,
14
+ `path`, or `handler` for the same thing.
15
+ - Project terms live in a `glossary` block. That block is the approved term
16
+ list for the doc. For every term outside it, use ordinary English.
17
+ - Prefer the short common word: use, not utilize; before, not prior to; end,
18
+ not terminate; about, not approximately.
19
+
20
+ ## Sentences
21
+
22
+ - Length limits: instructions, 20 words at most; descriptive sentences, 25.
23
+ - Write one instruction per sentence.
24
+ - Instructions are always active voice: "Run `chiltepin check`", never "`chiltepin check`
25
+ should be run". Passive voice is allowed only in descriptive text, and only
26
+ when the actor is truly unknown or irrelevant.
27
+ - Use simple tenses only: past, present, future. No perfect or continuous
28
+ forms.
29
+ - Put the main action first and the condition after it: "Rerun the build if
30
+ the check fails."
31
+ - Keep articles and relative pronouns: "Run the check that validates the doc",
32
+ not "Run check validates doc". When you drop these small words, the sentence
33
+ becomes ambiguous.
34
+ - Keep noun clusters to 3 words at most. Write "the handler that refreshes
35
+ authentication tokens", not "authentication token refresh handler".
36
+ - Do not use an -ing word as a noun or modifier where a verb or clause works.
37
+ Write "when the parser fails", not "on parsing failure".
38
+
39
+ ## Paragraphs
40
+
41
+ - Descriptive paragraphs hold 6 sentences at most; procedural paragraphs, 3.
42
+ - Give each paragraph one topic. Announce the topic in the first sentence.
43
+ - Put warnings and prerequisites before the step they apply to, never after.
44
+
45
+ ## Where each level applies
46
+
47
+ **Full STE** — procedural and machine-adjacent text: `steps` blocks, CLI help,
48
+ `chiltepin check` diagnostics, error messages, MCP tool descriptions, and the skill's
49
+ own instructions. A reader parses this text under pressure, and the reader is
50
+ sometimes another model. Every rule above applies.
51
+
52
+ **STE-lite** — `prose`, `callout`, and `pullquote` content, and plain Markdown
53
+ paragraphs. Every rule applies except the restricted vocabulary. Prose carries
54
+ tradeoffs and consequences; a controlled word list flattens that. Keep the
55
+ sentence limits, active voice, and simple tenses, and keep one word per
56
+ concept.
57
+
58
+ **STE-lite, completeness first** — block text fields (`description`, `lede`,
59
+ `body`, `note`, `subtitle`, `summary`). The form rules apply, but never delete
60
+ a fact to satisfy a length rule. Split a long sentence into two sentences.
61
+ Keep every component, value, and condition the field states.
62
+
63
+ **Not applied** — marketing copy, changelog voice, code comments. Diagram data
64
+ (node names, messages, edge labels, states, values) is never edited for style:
65
+ the diagram is the data, and it must stay complete.
66
+
67
+ ## Worked pairs
68
+
69
+ **Pair 1 — a restated diagram (docs/showcase.md:512).**
70
+
71
+ ```
72
+ Before: A controller calls OrderService, which loads via an OrderRepository,
73
+ charges through a PaymentGateway interface (Stripe/Adyen adapters), and
74
+ egresses to Postgres, the event bus, and external gateways.
75
+
76
+ After: Payment providers sit behind one interface, so a Stripe outage is a
77
+ config change, not a code change.
78
+ ```
79
+
80
+ The before repeats what the diagram already shows. The after states the
81
+ consequence that the diagram cannot show.
82
+
83
+ **Pair 2 — a lede with three jobs (resources/orders-api.md:29).**
84
+
85
+ ```
86
+ Before: Time runs downward. Solid arrows are synchronous requests; dashed are
87
+ responses. The order row exists as PENDING only inside the transaction — it is
88
+ CONFIRMED before commit, or rolled back to CANCELLED on decline.
89
+
90
+ After: An order is never visible as PENDING outside the transaction: it
91
+ commits as CONFIRMED or rolls back to CANCELLED. Clients can treat every read
92
+ as final.
93
+ ```
94
+
95
+ The before teaches notation, describes arrows, and buries the invariant. The
96
+ after does one job: the guarantee, and what it lets clients do.
97
+
98
+ **Pair 3 — the wrapper opener (docs/showcase.md:9).**
99
+
100
+ ```
101
+ Before: The blocks below are rendered from typed YAML fences. Edit the source
102
+ .md file, rerun `chiltepin html`, and the HTML updates accordingly.
103
+
104
+ After: Edit a YAML block to change its diagram. Then run `chiltepin html`. The
105
+ .md file is the only source; there is no rendered state to fix by hand.
106
+ ```
107
+
108
+ The before is passive, restates the page, and stacks two instructions into one
109
+ sentence. The after gives one instruction per sentence, plus the fact that
110
+ makes the edit safe.
111
+
112
+ ## Constraints on how we use STE
113
+
114
+ - ASD-STE100 is free to obtain but not free to redistribute. Never copy the
115
+ specification text or its ~900-word approved dictionary into this repo. We
116
+ apply the rules and keep our own term list.
117
+ - Never claim Chiltepin output "is STE" or "is STE-compliant". Write
118
+ "STE-informed" or "follows STE writing discipline". Certified compliance
119
+ requires the real dictionary, and we do not ship it.
@@ -0,0 +1,161 @@
1
+ # Designing systems — the design method & the architecture blocks
2
+
3
+ Part of the **chiltepin** skill (the hub is `SKILL.md`, one folder up). Read
4
+ this for any architecture or design ask.
5
+
6
+ ## Designing a system — reason it, don't template it
7
+
8
+ "Design an X" asks (a notification system, a rate limiter, "how would you build Y
9
+ at scale") are where templating shows worst. Every real system's document
10
+ is shaped by *its* bottleneck. Do the design reasoning; each step emits the block
11
+ that carries it:
12
+
13
+ 1. **Requirements — ask, then pin them down.** Functional (what it does) and
14
+ non-functional (scale, latency, consistency, durability). If the user gave no
15
+ scale or constraints, **ask back** (move 1 of the method in `SKILL.md`; checklists in `intake.md`). Emit `drivers` — each driver a
16
+ real requirement with its consequence, never a platitude.
17
+ 2. **Envelope math.** Users × actions × fan-out → QPS, storage/day, peak factor.
18
+ Emit `stats` with the numbers that justify the architecture — skip when scale
19
+ genuinely isn't the story.
20
+ 3. **Contract.** The API surface (`endpoint` per route that matters) and the data
21
+ model (`erd`). These fix the names every later block reuses.
22
+ 4. **High level, shaped by the dominant motion.** Request/reply system → `c4`;
23
+ things flowing through stages → `block` (`preset: event`) or `dfd`;
24
+ deployment/regions/zones → `block` (`preset: infra`); a k8s estate →
25
+ `cluster`. One overview diagram of the whole system, using the real names
26
+ from step 3.
27
+ 5. **Deep-dive the bottleneck — this is where documents differ.** Work out what
28
+ actually breaks at the stated scale, and design *that* section:
29
+ - hot reads → caching + invalidation (a `sequence` of the miss path)
30
+ - write spikes → queue + backpressure (a `flow` with the shed path)
31
+ - fan-out → push vs pull (`options`, then the chosen `sequence`)
32
+ - cross-service consistency → outbox/saga (a `state` of the saga)
33
+ - geo-latency → replication + CDN (a `preset: infra` `block` per region)
34
+
35
+ One or two deep dives, chosen by the numbers from step 2 — never a fixed list.
36
+ 6. **Trade-offs on the record.** The genuine alternatives as `options` (with
37
+ `tone: chosen` on the winner), or `proscons` when only one option's tension
38
+ matters. A design doc with no rejected alternative wasn't a decision.
39
+ 7. **Failure & operations.** What breaks, the blast radius, how it degrades: a
40
+ `table` of failure modes → responses, `kind: error`/`forbidden` edges on the
41
+ diagrams, a `flow` of the degradation path.
42
+ 8. **Plan.** `timeline` for phasing, `statustable` for the open questions you
43
+ asked in step 1 but didn't get answered.
44
+
45
+ **Patterns are ingredients, not the meal.** When a named pattern is load-bearing
46
+ (pub-sub, saga, circuit breaker, CQRS, …), write it as a `pattern` card plus
47
+ one structure diagram that fits it (`block` for system patterns, `felogic` or
48
+ `uml` for code patterns, `flow`/`state`/`sequence` for agent patterns). Then
49
+ **name every node in the user's domain**: a card whose participants are still
50
+ "ServiceA" was pasted, not designed. Comparing patterns side by side → a
51
+ `gallery` with a nested `pattern`/diagram per cell.
52
+
53
+ The outline that falls out of steps 1-8 differs per system. A rate limiter's doc
54
+ is mostly steps 4-6 with algorithmic depth (`state`, `code`). A social feed's is
55
+ dominated by step 5 fan-out math, a payments integration by step 7 failure
56
+ semantics. **If two of your design docs share the same section list, you skipped
57
+ step 5.**
58
+
59
+
60
+ ## Architecture and topology (which one when?)
61
+
62
+ | If you want to show… | Use | Notes |
63
+ |---|---|---|
64
+ | Who uses the system + which external systems it depends on | `c4` (level: context) | One node per actor / system |
65
+ | Containers inside a system, with optional boundary box | `c4` (level: container) | Use `family` to colour-code (client / service / data / store) |
66
+ | Components inside one container | `c4` (level: component) | Same shape, finer granularity |
67
+ | Generic boxes-and-arrows architecture | `block` | Grid layout; add `groups` for dashed zones; add `layers` to switch to horizontal-band layout |
68
+ | Cloud deployment (CDN, gateway, compute, DB, …) | `block` (`preset: infra`) | Same engine; the preset frames it for cloud topology |
69
+ | Pub/sub event topology (producers → topics → consumers) | `block` (`preset: event`) | Same engine; framed for choreography |
70
+ | Bounded-context map for DDD | `block` (`preset: ddd`) | Same engine; framed for context maps |
71
+ | Security zones with trust boundaries | `block` (`preset: network`) | Same engine; supports `kind: forbidden` edges (red) |
72
+ | Kubernetes-style namespaces with services inside | `cluster` | Has its own nested-box engine; supports `replicas` count |
73
+
74
+ > Every `block` preset shares **one renderer** — presets differ only by the
75
+ > colored tag pill above the diagram (ARCH / INFRA / EVENT / DDD / ZONES) and
76
+ > the section eyebrow. Pick the preset that best signals intent to a reader;
77
+ > the YAML grammar is identical. (The old type names `infra` / `event` / `ddd`
78
+ > / `network` still work as permanent aliases.)
79
+
80
+ **Quick mode — no coordinates.** Every architecture diagram can be written as
81
+ just nodes + edges. Omit `col`/`row` on **all** nodes and the renderer computes a
82
+ clean left-to-right layered layout from the edges. This is the default way to
83
+ sketch a system fast.
84
+
85
+ Add explicit coordinates only when you want a deliberate
86
+ shape — and always when you use `groups`. Zones are anchored to grid cells, so
87
+ they need placed nodes. If *any* node has coordinates but others don't, the
88
+ auto-layout replaces all of them — place all or none.
89
+
90
+ **Edge labels — dense diagrams renumber themselves.** On every edge-bearing
91
+ diagram (`block` — any preset, `flow`, `dfd`, `graph`,
92
+ `swimlane`, `uml`, `cluster`, `felogic`), up to three labelled edges
93
+ render as text pills riding the arrows. At **four or more labelled edges** the
94
+ renderer switches to circled step numerals and moves the label
95
+ text to a numbered legend under the diagram. (`state` is the one exception —
96
+ its numerals point at the transition table's rows instead of a second legend.)
97
+ You don't opt in or lay anything out. Just keep edge labels short (a verb
98
+ phrase, a couple of words) so they read well as a pill or a legend entry.
99
+
100
+ **Node kinds** (block family; free strings — known ones get a colour + glyph):
101
+ `client` · `service`/`microservice`/`compute`/`container` · `worker`/`etl` ·
102
+ `db`/`store`/`database` · `bucket`/`blob` · `queue`/`mq`/`broker` · `stream` ·
103
+ `cache` · `gateway`/`lb`/`proxy` · `function`/`lambda` · `cdn` · `dns` ·
104
+ `waf`/`firewall`/`shield` · `auth`/`idp`/`iam`/`oauth`/`sso` ·
105
+ `secrets`/`vault`/`kms` · `monitor`/`metrics`/`logs`/`tracing` ·
106
+ `scheduler`/`cron`/`job` · `warehouse`/`lake` · `analytics`/`bi` ·
107
+ `search`/`index` · `ml`/`model`/`llm`/`agent` · `vm`/`server`/`host` ·
108
+ `user`/`person`/`browser`/`mobile` · `users`/`crowd` · `device`/`iot` ·
109
+ `notification`/`webhook` · `email`/`sms` · `ci`/`cicd`/`pipeline` · `git`/`repo`
110
+ · `registry` · `config` · `shard`/`sharded` · `replica`/`replicaset` ·
111
+ `region`/`geo`/`globe` · `producer`/`topic`/`consumer` · `context` · `external`.
112
+ **Vendor names work too**: `postgres`/`mysql`/`mongo`/`dynamo` → db, `s3` →
113
+ bucket, `sqs`/`rabbitmq` → queue, `kafka`/`kinesis` → stream,
114
+ `redis`/`memcached` → cache, `elasticsearch`/`opensearch` → search. Pick the
115
+ closest kind — an unknown kind renders as a neutral box.
116
+
117
+ **Kinds also pick the shape** (the canonical system-design silhouettes — you get
118
+ the right one automatically by choosing the right kind):
119
+
120
+ | Shape | Kinds |
121
+ |---|---|
122
+ | cylinder | `db` `database` `store` `postgres` `mysql` `mongo` `dynamo` |
123
+ | tiered cylinder | `warehouse` `lake` |
124
+ | pail (bucket) | `bucket` `blob` `object` `s3` |
125
+ | **sharded trio** (3 small cylinders) | `shard` `shards` `sharded` |
126
+ | **replica set** (stacked cylinders) | `replica` `replicas` `replicaset` |
127
+ | horizontal cylinder (pipe) | `queue` `topic` `stream` `mq` `broker` `sqs` `rabbitmq` `kafka` `kinesis` |
128
+ | cloud | `cdn` `external` |
129
+ | hexagon | `gateway` `proxy` |
130
+ | octagon | `lb` |
131
+ | instance stack (receding cards) | `cache` `redis` `memcached` `worker` `etl` |
132
+ | server rack (stacked slabs) | `vm` `server` `host` |
133
+ | shield | `waf` `firewall` `shield` |
134
+ | actor figure (boxless) | `user` `person` `actor` |
135
+ | crowd (overlapping figures) | `users` `crowd` |
136
+ | browser window | `browser` `web` |
137
+ | phone frame | `mobile` |
138
+ | circle with ƒ | `function` `lambda` |
139
+ | calendar with clock badge | `scheduler` `cron` `job` |
140
+ | padlock | `secrets` `vault` `kms` |
141
+ | globe (boxless) | `region` `geo` `globe` |
142
+ | clean rounded card + glyph | everything else |
143
+
144
+ The same silhouettes apply inside `felogic` (db/store → cylinder,
145
+ queue/bus/broker → pipe, cache → stack, external/backend/api → cloud), in `c4`
146
+ (`kind: store` → cylinder), and in `cluster` (db services → cylinder). A
147
+ database looks like a database in every diagram.
148
+
149
+ **C4 extras.** Edges take `tech:` — rendered as `label [tech]`, the C4
150
+ convention for the protocol. `boundaries[]` draws several named dashed boxes,
151
+ each fitted around an explicit `nodes: [ids]` list (optional `color`) — so one
152
+ diagram shows your platform and a partner's estate side by side. The single
153
+ auto-fit `boundary:` still works for one system.
154
+
155
+ **Mixing architecture views — one overview + one zoom.** Show the whole system
156
+ once (`c4` context, or a `block` landscape), then zoom into the one or
157
+ two places the doc is actually about. Zoom with `felogic` (or its `variant:
158
+ be`) for a module's internals, a `preset: infra` `block` or `cluster` for
159
+ deployment, and a `sequence` for the runtime of one path. Never redraw the same boxes in a
160
+ second engine — pick one block per level of zoom and stitch them with prose
161
+ ("inside the `api` container: …").