@caddis/cli 0.4.1 → 0.4.2

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.
@@ -0,0 +1,237 @@
1
+ # Diagram vocabulary for explainers
2
+
3
+ Four Mermaid patterns cover almost every explainer. Reusing a small set is deliberate: the reader
4
+ learns the visual grammar once, in §3, and reads every later diagram faster because of it. A document
5
+ where each diagram is a different Mermaid type makes the reader re-learn the notation five times.
6
+
7
+ ## Contents
8
+
9
+ - [Rule zero: does this diagram earn its place?](#rule-zero-does-this-diagram-earn-its-place)
10
+ - [Pattern 1 — the pipeline (`flowchart LR`)](#pattern-1--the-pipeline-flowchart-lr)
11
+ - [Pattern 2 — the layer stack (`flowchart TB` + subgraphs)](#pattern-2--the-layer-stack-flowchart-tb--subgraphs)
12
+ - [Pattern 3 — the ranked-effect diagram (the important one)](#pattern-3--the-ranked-effect-diagram-the-important-one)
13
+ - [Pattern 4 — the check loop](#pattern-4--the-check-loop)
14
+ - [Pattern 5 — proportion (`pie showData`)](#pattern-5--proportion-pie-showdata)
15
+ - [Pattern 6 — the next-steps chain](#pattern-6--the-next-steps-chain)
16
+ - [Syntax notes that bite](#syntax-notes-that-bite)
17
+
18
+ ## Rule zero: does this diagram earn its place?
19
+
20
+ Delete the diagram if a table says it better. Diagrams carry **shape and relationship**; tables carry
21
+ **detail and comparison**. A diagram listing five options with three attributes each is a table drawn
22
+ badly.
23
+
24
+ Four to six diagrams across a long document is right. Every one should answer a different question.
25
+
26
+ ## Pattern 1 — the pipeline (`flowchart LR`)
27
+
28
+ For §3, "what we are building". Left to right, one path, database shapes for stores. Put the size of
29
+ the data on the arrows or in the nodes — the reader's first question about a pipeline is "how big".
30
+
31
+ ````markdown
32
+ ```mermaid
33
+ flowchart LR
34
+ DB[("Customer<br/>database")] --> P["Build the prompt<br/>about 16,400 tokens"]
35
+ P --> S["LLM server<br/>on the H100 GPU"]
36
+ S --> J["JSON summary<br/>about 2,400 tokens"]
37
+ J --> O[("Stored<br/>summary")]
38
+ ```
39
+ ````
40
+
41
+ Keep it to five or six nodes. A pipeline diagram with fifteen boxes is an architecture diagram, and
42
+ the reader stops tracing it.
43
+
44
+ ## Pattern 2 — the layer stack (`flowchart TB` + subgraphs)
45
+
46
+ For §5, "what sits on what". One subgraph per layer, numbered and named. Peers go side by side inside
47
+ their layer with `direction LR`. Mark what you do **not** have — the absence is often the reader's
48
+ actual question.
49
+
50
+ ````markdown
51
+ ```mermaid
52
+ flowchart TB
53
+ subgraph programs["LAYER 1 — Programs (the wrapper you install)"]
54
+ direction LR
55
+ A["<b>Ollama</b><br/>installed and used"]
56
+ B["<b>llama-server</b><br/>installed and used"]
57
+ C["<b>LM Studio</b><br/>NOT installed"]
58
+ end
59
+
60
+ subgraph engine["LAYER 2 — Engine (this does the real work)"]
61
+ D["<b>llama.cpp / ggml</b><br/>CUDA calculation code"]
62
+ end
63
+
64
+ subgraph driver["LAYER 3 — Driver"]
65
+ E["NVIDIA driver, TCC mode"]
66
+ end
67
+
68
+ subgraph hardware["LAYER 4 — Hardware"]
69
+ F["H100 NVL GPU<br/>94 GB memory"]
70
+ end
71
+
72
+ A --> D
73
+ B --> D
74
+ C -.->|"would use the<br/>same engine"| D
75
+ D --> E
76
+ E --> F
77
+ ```
78
+ ````
79
+
80
+ Two techniques here do real work:
81
+
82
+ - **The dotted arrow with a label** (`C -.->|"would use the same engine"| D`) shows a hypothetical
83
+ without asserting it exists. This is how you answer "what if we used X?" inside the diagram.
84
+ - **The parenthetical in each subgraph title** ("the wrapper you install", "this does the real work")
85
+ tells the reader what the layer *is for*, which is what they actually lack.
86
+
87
+ Follow the diagram with the one-line consequence: *"Layer 1 is easy to change. Layer 2 decides the
88
+ speed."*
89
+
90
+ ## Pattern 3 — the ranked-effect diagram (the important one)
91
+
92
+ For §8, "what limits the result". This is the diagram the document exists to deliver. It is the layer
93
+ stack again, but **ordered by size of effect and labelled with the magnitude**.
94
+
95
+ ````markdown
96
+ ```mermaid
97
+ flowchart TB
98
+ subgraph L1["LAYER 1 — The model — LARGEST EFFECT — about 3x"]
99
+ M["<b>gpt-oss:120b writes 6,000 to 9,000 tokens.</b><br/>gpt-4o writes 2,373 tokens for the same job.<br/>The local model does about 3 times more work."]
100
+ end
101
+ subgraph L2["LAYER 2 — The engine — MEDIUM EFFECT — tens of percent"]
102
+ E["<b>llama.cpp has no Hopper-specific code.</b><br/>It cannot use the H100 FP8 units.<br/>Faster engines (vLLM, TensorRT-LLM) do not run on Windows."]
103
+ end
104
+ subgraph L3["LAYER 3 — The program — SMALL EFFECT — under 5%"]
105
+ W["<b>Ollama or llama-server or LM Studio.</b><br/>All contain the same engine.<br/>Measured difference is small."]
106
+ end
107
+ subgraph L4["LAYER 4 — The operating system — NO EFFECT"]
108
+ O["<b>Windows against Linux.</b><br/>For work held fully in GPU memory,<br/>measured difference is about zero."]
109
+ end
110
+ L1 --> L2 --> L3 --> L4
111
+ ```
112
+ ````
113
+
114
+ Construction rules:
115
+
116
+ - **Title format:** `LAYER n — <the thing> — <EFFECT SIZE IN CAPS> — <the number>`. The caps and the
117
+ number are what the reader takes away; the layer number just keeps the ordering legible.
118
+ - **Node body:** bold first line = the claim. Following lines = the evidence and the comparison. Three
119
+ lines per node is the ceiling.
120
+ - **The arrows mean rank, not flow.** `L1 --> L2 --> L3 --> L4` reads as descending importance. Say so
121
+ in the sentence above the diagram so nobody reads it as a data path.
122
+ - **Include the reader's preferred fix even when it ranks last.** Omitting it looks like evasion;
123
+ ranking it with a measured number is the argument.
124
+ - **A layer you did not measure says so** — "NOT MEASURED" is an honest rank. An invented one is the
125
+ fastest way to lose the reader who happens to know that layer.
126
+
127
+ Always follow it with the reading instruction:
128
+
129
+ > **Read the diagram this way.** If we change the program (Layer 3), we gain a few percent. If we
130
+ > change the model (Layer 1), we can gain about 3 times. Layer 1 is where the work must go.
131
+
132
+ ### The same move outside the "stack" case
133
+
134
+ Nothing here depends on the causes forming a real stack. When they do not, call them causes and rank
135
+ them by measured share — the diagram does exactly the same job:
136
+
137
+ ````markdown
138
+ ```mermaid
139
+ flowchart TB
140
+ subgraph L1["CAUSE 1 — The Salesforce rate limit — LARGEST EFFECT — 192 of 300 minutes, 64.0%"]
141
+ A["<b>19,000 accounts at 100 requests per minute needs 190 minutes.</b><br/>The extract took 192 minutes.<br/>It already runs at 99% of the permitted rate."]
142
+ end
143
+ subgraph L2["CAUSE 2 — The dbt tests — SECOND EFFECT — 45 of 300 minutes, 15.0%"]
144
+ B["<b>780 tests run after every load.</b><br/>Not yet split by severity."]
145
+ end
146
+ subgraph L3["CAUSE 3 — The load into Snowflake — SMALLEST EFFECT — 22 of 300 minutes, 7.3%"]
147
+ C["<b>This is the step people call 'copying the data'.</b><br/>It is 7.3% of the run."]
148
+ end
149
+ L1 --> L2 --> L3
150
+ ```
151
+ ````
152
+
153
+ Note the third node: the reader's own mental model ("it's just copying data") is named and ranked
154
+ rather than dismissed. That is the move, in one box.
155
+
156
+ ## Pattern 4 — the check loop
157
+
158
+ For §6, "why the work took so long" — the procedure that catches bad results. A decision diamond with
159
+ a failure branch that loops back.
160
+
161
+ ````markdown
162
+ ```mermaid
163
+ flowchart LR
164
+ A["Change one thing"] --> B["Measure it"]
165
+ B --> C{"Does the number agree<br/>with a second,<br/>independent number?"}
166
+ C -->|"No"| D["The instrument is wrong.<br/>Repair the test."]
167
+ D --> B
168
+ C -->|"Yes"| E["Record the result"]
169
+ ```
170
+ ````
171
+
172
+ The loop-back arrow is the content. It shows that the failure path is normal and expected, which is
173
+ what makes the withdrawn-results list read as rigour instead of incompetence.
174
+
175
+ ## Pattern 5 — proportion (`pie showData`)
176
+
177
+ For §7, "where the time goes". Use it when the reader is about to optimise the small slice.
178
+
179
+ ````markdown
180
+ ```mermaid
181
+ pie showData
182
+ title Time in one call
183
+ "Decode — write the answer" : 91.6
184
+ "Prefill — read the prompt" : 8.4
185
+ ```
186
+ ````
187
+
188
+ - `showData` prints the values — always use it; an unlabelled pie is a decoration.
189
+ - Up to five slices. Above five, use a table — the labels stop fitting and the small slices become
190
+ indistinguishable. If the natural breakdown is four or five stages, the pie is still the right
191
+ visual; do not split it artificially.
192
+ - **Say what the numbers are drawn from**, in the sentence above: a sample count where you have one
193
+ (*"We measured 223 samples of each stage"*), otherwise the single run and its date (*"From the run
194
+ of 2026-08-06"*). A one-run pie is honest as long as it says it is one run — a pie with no stated
195
+ basis is the single easiest thing in the document to misquote.
196
+ - Follow with the consequence: *"Earlier work tried to make prompt reading faster. That work can only
197
+ improve 8.4% of the time."*
198
+
199
+ ## Pattern 6 — the next-steps chain
200
+
201
+ For §11. Numbered steps, top to bottom, each with its method and its acceptance in the node.
202
+
203
+ ````markdown
204
+ ```mermaid
205
+ flowchart TB
206
+ A["<b>Step 1 — Test other models</b><br/>Find a model that writes shorter answers.<br/>Measure tokens per call, not tokens per second."] --> B
207
+ B["<b>Step 2 — Quality gate</b><br/>Check that the local model writes<br/>summaries that are good enough.<br/>15 test cases."] --> C
208
+ C["<b>Step 3 — Make it a service</b><br/>Run the server with NSSM.<br/>Confirm the GPU works from a service."]
209
+ ```
210
+ ````
211
+
212
+ Name the step that matters most immediately below, with the reason: *"Step 1 is the most important
213
+ step. The model decides about 3 times the work. No change to the server software can equal that."*
214
+
215
+ ## Syntax notes that bite
216
+
217
+ | Need | Write | Note |
218
+ | ----------------------- | -------------------------------------------- | -------------------------------------------------------------------- |
219
+ | Line break in a node | `<br/>` | Not `\n`. Renderers differ on `<br>` without the slash. |
220
+ | Bold inside a node | `["<b>Claim.</b><br/>Evidence."]` | Markdown `**` does not render inside Mermaid nodes. |
221
+ | Any label with punctuation | Wrap in double quotes: `A["a, b: c"]` | Unquoted `(`, `,`, `:`, `-` break the parser. |
222
+ | Database / store shape | `DB[("Customer<br/>database")]` | |
223
+ | Decision | `C{"Does it agree?"}` | |
224
+ | Hypothetical / optional | `C -.->|"would use"| D` | Dotted = does not exist today. |
225
+ | Peers side by side | `direction LR` inside the `subgraph` | Without it, subgraph children stack vertically. |
226
+ | Subgraph with a title | `subgraph id["The title text"]` | The bare form `subgraph The title` mangles punctuation. |
227
+
228
+ Check every diagram renders before shipping — a broken Mermaid block shows the reader raw source and
229
+ costs more credibility than the diagram was worth. In order of preference:
230
+
231
+ 1. **Paste into `mermaid.live`** — authoritative, and it points at the failing line.
232
+ 2. **VS Code / GitHub / GitLab preview** — all render every pattern above.
233
+ 3. **If you are offline**, read each block against the table above. Nearly every failure is one of
234
+ four things: an unquoted label containing `(`, `,`, `:` or `-`; a `<br>` without the slash;
235
+ markdown `**bold**` inside a node; or a `subgraph` title that is not bracketed and quoted.
236
+
237
+ Do not ship a diagram you have not checked by one of these three.
@@ -0,0 +1,141 @@
1
+ # Simplified Technical English for explainers
2
+
3
+ Read this during the STE rewrite pass (process step 6), not while drafting. Drafting in STE from the
4
+ first word produces stilted, thin prose — write the ideas out normally, then compress them here.
5
+
6
+ ## Contents
7
+
8
+ - [Why STE, and what it is not](#why-ste-and-what-it-is-not)
9
+ - [The rules](#the-rules)
10
+ - [The rewrite table](#the-rewrite-table)
11
+ - [Building the vocabulary table (§2)](#building-the-vocabulary-table-2)
12
+ - [Numbers](#numbers)
13
+ - [Words to delete on sight](#words-to-delete-on-sight)
14
+ - [The mechanical pass](#the-mechanical-pass)
15
+
16
+ ## Why STE, and what it is not
17
+
18
+ Simplified Technical English comes from aerospace maintenance manuals, where a misread sentence
19
+ grounds an aircraft. It constrains grammar and vocabulary so that a sentence has exactly one reading.
20
+
21
+ It is **not** writing for a beginner. Your reader may be more senior than you. They are expert in a
22
+ *different* area, and they are reading fast. STE removes the work of guessing which of two readings
23
+ you meant, so their attention goes to your argument instead of your syntax.
24
+
25
+ A side effect worth knowing: STE makes weak claims obvious. "Performance was somewhat impacted by
26
+ the configuration" survives normal prose. Rewritten as "the configuration made X slower by Y" it
27
+ either gets a number or gets deleted. **The rewrite pass is also a truth pass.**
28
+
29
+ ## The rules
30
+
31
+ 1. **One idea per sentence.** Target under 20 words. Split on `and`, `but`, `which`, `;`, and any
32
+ comma joining two independent clauses.
33
+ 2. **One word, one meaning.** Fix each term in §2 and use only that term. Synonym variation is good
34
+ literary style and bad technical style — the reader cannot tell whether "engine", "runtime", and
35
+ "backend" are three things or one.
36
+ 3. **One meaning, one word.** The converse: never use a defined term for anything else. If "program"
37
+ means the installable wrapper, do not also call a Python script a "program".
38
+ 4. **Active voice, actor named.** "We withdrew the result" > "the result was withdrawn". Passive
39
+ hides who did it, and in an investigation write-up that is exactly the information at stake.
40
+ 5. **Present tense for what is true, past tense for what was measured.** "Decode is 91.6% of the
41
+ time" (a property). "We measured 223 samples" (an event).
42
+ 6. **No idiom, no metaphor, no humour, no rhetorical questions.** These are the constructs that
43
+ translate worst and skim worst.
44
+ 7. **No hedging without a size.** Not "it seems likely" — instead name the uncertainty: "we measured
45
+ this once, with a test prompt, not a real prompt".
46
+ 8. **Never open a paragraph with a bare pronoun** referring to the previous paragraph. Readers land
47
+ mid-page. Name the subject again.
48
+ 9. **Front-load the sentence.** Subject and verb in the first six words. Put conditions after the
49
+ main clause: "Use TCC mode if the server runs as a Windows service" — not "If the server runs as
50
+ a Windows service, then in that case TCC mode should be used."
51
+ 10. **Lists for lists.** If a sentence contains three or more parallel items, make it a bulleted list
52
+ or a table. Prose is for judgement, not enumeration.
53
+ 11. **Bold the answer, not the emphasis.** Bold carries the sentence a skimming reader must not miss.
54
+ If half a paragraph is bold, none of it is.
55
+ 12. **Define on first use, inline, and again in §2.** The reader will not follow a link mid-document.
56
+
57
+ ## The rewrite table
58
+
59
+ | Instead of | Write |
60
+ | --------------------------------------------------------- | --------------------------------------------------------- |
61
+ | utilize, leverage | use |
62
+ | initiate, commence | start |
63
+ | terminate | stop |
64
+ | in order to | to |
65
+ | due to the fact that | because |
66
+ | at this point in time | now |
67
+ | a number of, several | the number (or "about 12") |
68
+ | significantly faster | 1.9 times faster |
69
+ | performance degradation was observed | it became slower — by X |
70
+ | there is a possibility that | X may happen if Y |
71
+ | it should be noted that | *(delete; state the thing)* |
72
+ | we were unable to determine | we did not measure this. To measure it: \<method\> |
73
+ | the aforementioned approach | *(name it)* |
74
+ | this is non-trivial | this takes \<time\> and needs \<thing\> |
75
+ | best-in-class, industry-standard, robust | *(delete; give the number or the source)* |
76
+ | optimize, improve | make faster / make smaller / reduce cost — say which |
77
+ | The result was withdrawn. | We withdrew the result. |
78
+
79
+ ## Building the vocabulary table (§2)
80
+
81
+ Include a term when **any** of these is true:
82
+
83
+ - It is an acronym (`TCC`, `MoE`, `GGUF`, `SLA`).
84
+ - Two readers in the thread have used it to mean different things. These are the highest-value rows.
85
+ - It has a common meaning and a narrow meaning here ("program", "engine", "wrapper", "load").
86
+ - Your argument turns on the distinction between it and a neighbouring term.
87
+
88
+ Format — one meaning, in plain words, using only terms already defined:
89
+
90
+ ```markdown
91
+ | Word | Meaning |
92
+ | --------------- | ----------------------------------------------------------------------------- |
93
+ | **Token** | A piece of a word. About 4 characters of English. A model reads and writes tokens. |
94
+ | **Engine** | The software that does the mathematics on the GPU. |
95
+ | **Wrapper** | A program that contains an engine, but does not replace it. |
96
+ ```
97
+
98
+ Eight to twelve rows is typical. Above about fifteen, the table stops being read — move the rare
99
+ terms to inline definitions at first use.
100
+
101
+ Open the section with the instruction, not just the table: *"Use these words with one meaning only."*
102
+
103
+ ## Numbers
104
+
105
+ Every number in the document carries three things, either inline or in the table it sits in:
106
+
107
+ - **The unit.** "659 tokens per second", not "659".
108
+ - **The basis.** Measured or calculated? From what sample? On what date? "measured from `gpt-4o`",
109
+ "223 samples", "measured 2026-08-07".
110
+ - **Its precision.** Write "about 125" when the run-to-run spread is ±10. False precision ("125.4")
111
+ invites a challenge you cannot defend, and burns the credibility of the numbers that *are* exact.
112
+
113
+ Ratios beat percentages when the gap is large: "about 5 times too slow" lands harder and is
114
+ remembered better than "80% below target". Percentages are right for small differences: "0.3%
115
+ slower".
116
+
117
+ State the direction: "10.3% slower" not "10.3% difference".
118
+
119
+ ## Words to delete on sight
120
+
121
+ `basically`, `essentially`, `simply`, `just`, `obviously`, `of course`, `clearly`, `actually`,
122
+ `very`, `quite`, `fairly`, `really`, `arguably`, `interestingly`, `unfortunately`, `it turns out
123
+ that`, `as we all know`.
124
+
125
+ Each one either adds nothing or, worse, tells the reader their question was stupid. "Simply run the
126
+ benchmark" is a sentence that makes a reader who then fails feel foolish, and they will not tell you.
127
+
128
+ ## The mechanical pass
129
+
130
+ Work through the draft once per rule. Batching is faster and catches more than reading for "style".
131
+
132
+ 1. **Sentence length.** Find every sentence over 25 words. Split or cut it.
133
+ 2. **Passive voice.** Search `was `, `were `, `been `, `is being`. Rewrite with the actor named,
134
+ or confirm the actor genuinely does not matter.
135
+ 3. **Synonyms for defined terms.** For each row of §2, search the document for its synonyms and
136
+ replace them.
137
+ 4. **Bare numbers.** Search for digits. Every hit needs a unit and a basis.
138
+ 5. **Filler.** Search the delete-on-sight list.
139
+ 6. **Paragraph openings.** Scan the first three words of each paragraph for `This`, `It`, `They`,
140
+ `That`.
141
+ 7. **Read the five-line summary cold**, as though you had read nothing else.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "caddis-extras",
3
- "version": "1.3.27",
3
+ "version": "1.3.28",
4
4
  "description": "caddis-extras — the long-tail skills for the Antigravity (agy) caddis plugin; install alongside caddis for the full set."
5
5
  }
@@ -174,13 +174,3 @@ This:
174
174
  service-a OK declared=24 missing=0 <- every declared dep imported
175
175
  service-b OK declared=19 missing=0
176
176
  ```
177
-
178
- ## Reference implementation
179
-
180
- The estate this skill came from keeps working tools at `.caddis/tools/`:
181
-
182
- - `venv-audit.py` - imports every dependency each `pyproject.toml` declares
183
- - `rebuild-venv.ps1` - renames aside, rebuilds, restarts services, refuses on links or live processes
184
- - `README-venv-safety.md` - the incident record
185
-
186
- Adapt rather than copy: the rules matter more than the scripts.
@@ -174,13 +174,3 @@ This:
174
174
  service-a OK declared=24 missing=0 <- every declared dep imported
175
175
  service-b OK declared=19 missing=0
176
176
  ```
177
-
178
- ## Reference implementation
179
-
180
- The estate this skill came from keeps working tools at `.caddis/tools/`:
181
-
182
- - `venv-audit.py` - imports every dependency each `pyproject.toml` declares
183
- - `rebuild-venv.ps1` - renames aside, rebuilds, restarts services, refuses on links or live processes
184
- - `README-venv-safety.md` - the incident record
185
-
186
- Adapt rather than copy: the rules matter more than the scripts.