@sitar_fiercer4c/skills 0.1.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 (50) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +75 -0
  3. package/bin/install.js +45 -0
  4. package/package.json +29 -0
  5. package/skills/architecture-walkthrough/SKILL.md +223 -0
  6. package/skills/architecture-walkthrough/references/sections.md +29 -0
  7. package/skills/architecture-walkthrough/scripts/check_structure.py +200 -0
  8. package/skills/autotest-webapp-ui/SKILL.md +58 -0
  9. package/skills/backend-code-review/SKILL.md +386 -0
  10. package/skills/backend-code-review/references/report-format.md +333 -0
  11. package/skills/backend-code-review/scripts/list_routes.py +269 -0
  12. package/skills/backend-code-review/scripts/sweep.py +550 -0
  13. package/skills/backend-code-review/scripts/verify_citations.py +201 -0
  14. package/skills/be-brief/SKILL.md +18 -0
  15. package/skills/clarke-list-excel/SKILL.md +51 -0
  16. package/skills/clarke-list-excel/references/output-schema.md +125 -0
  17. package/skills/clarke-list-excel/scripts/clarke_common.py +251 -0
  18. package/skills/clarke-list-excel/scripts/clarke_extract.py +487 -0
  19. package/skills/clarke-list-excel/scripts/load_clarke.py +322 -0
  20. package/skills/clarke-list-excel/scripts/run_all.py +63 -0
  21. package/skills/datalab-api/SKILL.md +163 -0
  22. package/skills/datalab-api/references/parameters-and-payload.md +121 -0
  23. package/skills/datalab-api/references/table-selection.md +35 -0
  24. package/skills/datalab-api/scripts/datalab_tables.py +365 -0
  25. package/skills/find-test-seam/SKILL.md +41 -0
  26. package/skills/frontend-code-review/SKILL.md +247 -0
  27. package/skills/frontend-code-review-2/SKILL.md +192 -0
  28. package/skills/frontend-code-review-2/scripts/fetch_pr_comments.py +65 -0
  29. package/skills/frontend-code-review-2/scripts/render_report.py +139 -0
  30. package/skills/murtaza-breif/SKILL.md +143 -0
  31. package/skills/murtaza-breif/scripts/save_brief.py +128 -0
  32. package/skills/pdf-to-json/SKILL.md +42 -0
  33. package/skills/pdf-to-json/references/output-schema.md +168 -0
  34. package/skills/pdf-to-json/scripts/extract_figures.py +319 -0
  35. package/skills/pdf-to-json/scripts/load_mongo.py +287 -0
  36. package/skills/pdf-to-json/scripts/pdf_extract.py +1313 -0
  37. package/skills/record-api-traffic/SKILL.md +434 -0
  38. package/skills/record-api-traffic/references/reading-recordings.md +224 -0
  39. package/skills/record-api-traffic/scripts/check-schema.mjs +184 -0
  40. package/skills/record-api-traffic/scripts/dump-quotation.mjs +67 -0
  41. package/skills/record-api-traffic/scripts/dump-source-excel.mjs +75 -0
  42. package/skills/record-api-traffic/scripts/lib/repo.mjs +109 -0
  43. package/skills/record-api-traffic/scripts/preflight.py +528 -0
  44. package/skills/record-api-traffic/scripts/record-api-traffic.py +720 -0
  45. package/skills/refac-wrt-business-goal/SKILL.md +305 -0
  46. package/skills/refac-wrt-business-goal/references/critic.md +170 -0
  47. package/skills/system-resource-triage/SKILL.md +180 -0
  48. package/skills/system-resource-triage/scripts/reap.sh +116 -0
  49. package/skills/system-resource-triage/scripts/triage.sh +111 -0
  50. package/skills/using-git-worktrees/SKILL.md +167 -0
@@ -0,0 +1,305 @@
1
+ ---
2
+ name: refac-wrt-business-goal
3
+ description: Converge on a business model of a codebase — an under-50-word business goal, a node table, an edge list, an ASCII graph, and the input and output test seams a characterization test can be pinned to — from the repo, the user's account of the happy path, and an API recording of it. Use this whenever someone wants a flow modelled before a refactor, or asks where to pin a test for that flow.
4
+ ---
5
+
6
+ # Refactor with respect to the business goal
7
+
8
+ ## Inputs
9
+
10
+ Three things, all required. Ask for any that is missing and wait — starting without one costs more
11
+ than the wait does.
12
+
13
+ 1. **The repo, and which flow in it.** One flow, named by what the user does, not by a file.
14
+ 2. **The user's account of the happy path.** What they do, step by step, and where the business
15
+ considers the job done. The finish line especially: it is almost never where the code stops.
16
+ 3. **An API recording of that happy path** — the `backend-inbound.log` and `.jsonl` pair
17
+ produced by the `record-api-traffic` skill, landing in that skill's own workspace at
18
+ `skills/record-api-traffic-workspace/recordings/<repo-slug>/run-<stamp>/`. That run folder
19
+ also holds the frontend's two legs and the backend's outbound calls, if you need them.
20
+
21
+ The recording is not a nice-to-have. Without it you are guessing which code runs, and a graph built
22
+ from code that never executes is the expensive failure here — you model a path the business
23
+ abandoned two years ago and hand it back as a blueprint. If the user has no recording, point them at
24
+ `record-api-traffic` to capture one, and wait. Its `references/reading-recordings.md` has the field
25
+ meanings and jq recipes.
26
+
27
+ ## Output
28
+
29
+ Exactly one file, at
30
+ `skills/refac-wrt-business-goal-workspace/<target-name>-business-model.md`, with six sections:
31
+
32
+ ```
33
+ # Business model: <target>
34
+
35
+ ## Business goal (under 50 words)
36
+ ## Nodes (the workflow's steps: the table, plus external inputs and rule footnotes)
37
+ ## Edges (what moves between steps, explicit list)
38
+ ## Graph (the workflow drawn, ASCII)
39
+ ## Input seam (where a test drives this workflow, in code that exists today)
40
+ ## Output seam (where every outcome becomes durable, and which field carries each node)
41
+ ```
42
+
43
+ There are three things here, not six. The **goal** is what the business is for. The **workflow** is
44
+ how it gets there — the ordered decisions that carry an external input to an outcome — and the
45
+ nodes, edges and graph are that one workflow written three ways: its steps, its transitions, its
46
+ picture. The **seams** are where that workflow touches the code as it stands today.
47
+
48
+ The first two give the chain the whole exercise is built on: **every business goal is achieved by a
49
+ workflow, and the graph represents that workflow.** They are done when an independent critic says
50
+ both links hold — that the workflow achieves the goal, and that the graph is a faithful drawing of
51
+ the workflow.
52
+
53
+ The seams exist because a model that stops at the graph is a claim nobody can check. The refactor it
54
+ is written to guide will move every file it describes, and without two fixed points where the
55
+ current behaviour can be held still, nothing afterwards can show the workflow survived. Naming the
56
+ seams is what turns the model from a description into something falsifiable.
57
+
58
+ **Not an output: any change to the repo. Not one line, not a rename, not a comment.** The artifact is
59
+ the whole deliverable. If the user asks for the refactor too, produce the artifact first and let them
60
+ start the refactor as a separate request. A model written by someone already mid-edit drifts toward
61
+ describing the edits instead of the business.
62
+
63
+ Naming a seam invites writing the test at it. Don't: this skill names seams, it does not write tests,
64
+ and it does not export a helper to make one reachable.
65
+
66
+ ## 1. Read the code, against the recording
67
+
68
+ Follow one flow, from the entry point to the business finish line. The recording tells you where
69
+ that flow really goes: every call it made, in order, with bodies. Read it first, then open the code
70
+ the calls land in.
71
+
72
+ Before opening anything, list the files and their sizes and work out which sit past the finish line
73
+ — those you skim only far enough to confirm they are downstream, and then don't model. A quarter of
74
+ a services directory is often export and delivery code that runs after the business considers the
75
+ job done.
76
+
77
+ Read in batches: issue the reads for every file in the current layer in one go, rather than opening
78
+ one, thinking, and opening the next. You are following a flow, not auditing a directory, and the
79
+ thinking that matters happens once you have the layer in front of you.
80
+
81
+ Four things will lie to you, all in the same direction — they describe an older system. The
82
+ recording is what you check each of them against, because it is the only account of the system that
83
+ cannot be out of date:
84
+
85
+ - **the repo's own docs** (architecture notes, code reviews, plans)
86
+ - **comments and names** — a step labelled `fallback` may be the success path
87
+ - **a subagent's narrative** — subagents find files well and summarise flows badly, because they
88
+ read excerpts
89
+ - **your first read** — go back and check what each step *writes*, including mutation of arguments
90
+
91
+ Find what is dead at runtime as well as what runs. Dead code tells you which business rules were
92
+ tried and abandoned, which is exactly the kind of thing the user has stopped noticing. The recording
93
+ makes this cheap: code with no call behind it is a candidate, and grepping the exported names on
94
+ your flow for callers settles the rest.
95
+
96
+ ## 2. Say what you think this is for, and wait to be told you're right
97
+
98
+ You have read the code and watched the calls. Now commit to a reading of the business and have the
99
+ user check it — before you write the goal, a node, or an edge.
100
+
101
+ Put three things in front of them with `AskUserQuestion`:
102
+
103
+ - **A short paragraph in plain language.** Who this serves, what they get out of it, where the
104
+ business considers it finished, what it refuses to do. No vocabulary from the repo — if a
105
+ sentence needs a filename to make sense, you are describing the code.
106
+ - **The steps of the workflow you expect, in order. Names only, no descriptions.** Names are cheap
107
+ to throw away; a filled-in node table takes long enough to write that you would defend it rather
108
+ than drop it. The point here is a cheap check on the *shape* of the workflow, while changing it is
109
+ still free.
110
+ - **3–4 questions.** Each one a thing that would change the paragraph or the node list if answered
111
+ the other way. The test of a good question: it is about what the business wants, and a person who
112
+ has never read the code could answer it.
113
+
114
+ Good: *"Is the photo on the customer's inquiry decoration, or part of the requirement?"*
115
+ Bad: *"Should `injectImages` run before or after filtering?"*
116
+
117
+ **Then stop.** No goal sentence, no node table, no graph until the answers land. The finish line, and
118
+ which rules are invariants rather than conveniences somebody added, are not recoverable from code —
119
+ a model built without them is a picture of the code, which is the thing the user is complaining
120
+ about. And a goal drafted before the answers arrive is a goal you will then defend: what comes back
121
+ gets filed as a correction to it, rather than as the thing it should have been built on.
122
+
123
+ If the answers change your understanding, rewrite it and put it back. **Loop until the user confirms
124
+ it, with no cap.** This is the only unbounded loop in the skill, and deliberately so — a human ends
125
+ it. The critic loop later is capped precisely because nothing human is there to stop it.
126
+
127
+ ## 3. Write the goal in under 50 words
128
+
129
+ The budget is the mechanism. It has no room for what the system does, only what it is *for*, so it
130
+ forces you to rank the business's concerns. Write it as one sentence about the customer's outcome.
131
+
132
+ If a rule you believe is important won't fit, that is information: either it isn't core, or your
133
+ goal sentence is aimed at the wrong thing.
134
+
135
+ The sentence says what the business is for. It does not say how the business gets there — that is
136
+ the workflow, and it is next.
137
+
138
+ ## 4. Write the workflow: nodes, edges and graph
139
+
140
+ A goal is achieved by a workflow: an ordered run of decisions that carries something arriving from
141
+ outside all the way to an outcome the business recognises. Model that, and the three artifacts fall
142
+ out of it — the **nodes** are its steps, the **edges** are what moves between them, the **graph** is
143
+ it drawn.
144
+
145
+ Keeping the workflow in mind is what stops this becoming a taxonomy. A decomposition of a system
146
+ into parts is easy to write and passes a casual read; it has no start, no order, and nothing that
147
+ would let you say a step ran too late. If a node isn't a step on the way from an input to an
148
+ outcome, it is not part of the workflow, however true it may be about the system.
149
+
150
+ Node names are verb phrases in the language of the business, named for the decision the step makes.
151
+ Not for the function that makes it — a workflow rebuilt from the call chain is a picture of the code
152
+ you already have, which is the thing the user is complaining about.
153
+
154
+ List the **external inputs** — the things arriving from outside the workflow — above the table, so
155
+ the first step's `handed` column has somewhere to come from.
156
+
157
+ Then one table, five columns:
158
+
159
+ | node | handed | decides | refuses when | emits |
160
+ |---|---|---|---|---|
161
+ | `carry-quantities-into-the-draft` | the quotable line rows, and which column holds quantity | fills in the quantity the customer asked for, and nothing else (R1, R2) | never — see R2 | draft rows in the customer's order, each naming its inquiry row |
162
+ | `pin-photos-to-their-inquiry-rows` | every photo with the row it sits on | which inquiry line each photo illustrates (R3) | never — strays are discarded | for each row that has one, the photo belonging to it |
163
+
164
+ **Keep cells to a clause each.** A rule that needs a paragraph becomes a numbered footnote under the
165
+ table — `R1`, `R2` — referenced from the cell:
166
+
167
+ > R1. Every other field is left blank for the salesperson deliberately; this is the rule, not an
168
+ > unfinished mapping.
169
+ > R2. A quantity that cannot be read as a number is left empty rather than guessed at, and the line
170
+ > is still created.
171
+ > R3. One photo to a row, first wins a contested row; photos anchored outside the item table are
172
+ > discarded rather than attached to an arbitrary line.
173
+
174
+ The table earns its shape by putting `handed` and `emits` on the same row, so a node whose output
175
+ nothing consumes, or whose input no edge produces, shows up by scanning one column. That is exactly
176
+ what the critic checks under graph integrity. The thing to guard against is not columns but **cells
177
+ that swell into paragraphs** — once they do, the row stops being scannable and the defect hides
178
+ again. That is what the footnotes are for: let the rule run as long as it genuinely needs down
179
+ there, where nothing depends on it staying short.
180
+
181
+ Write the **edge list** out explicitly and separately: `E<n>. <source> -> <target> — <what travels>`.
182
+ The drawing is where mistakes hide; the edge list is what you check it against.
183
+
184
+ Then draw the graph in this shape, every time:
185
+
186
+ ```
187
+ (A) external input
188
+ (B) external input
189
+ |
190
+ | E1,E2
191
+ v
192
+ first-node ........................ E4 -> [R]
193
+ | E3
194
+ v
195
+ second-node ....................... E8 -> [R]
196
+ | E5
197
+ v
198
+ third-node ........................ E13 -> [R]
199
+ | E9 E10 -> a-later-node
200
+ v E11 -> another-node
201
+ fourth-node ....................... E16 -> [R]
202
+
203
+ [R] refuse-node -> OUTCOME 2: <what the user is told, and can act on>
204
+ commit-node --------------------> OUTCOME 1: <what they get>
205
+ ```
206
+
207
+ External inputs at the top, the spine down the left one step per line in the order the workflow runs
208
+ them, forward and cross edges as labelled jumps on the right, a single refusal sink `[R]` at the
209
+ bottom, and every path ending in a named outcome. The layout is doing more than looking tidy: read
210
+ top to bottom it is the workflow in sequence, so a step drawn out of order, or one with nothing
211
+ above it and nothing below, is visible without checking anything. One fixed shape also means the
212
+ drawing is comparable run to run and diffable, and that you spend your effort on the model rather
213
+ than on inventing notation.
214
+
215
+ ## 5. Loop a critic until it agrees
216
+
217
+ The loop tests the chain: **the workflow achieves the 50-word goal, and the graph represents the
218
+ workflow.** Everything below serves those two links.
219
+
220
+ **Methodology.** Spawn a fresh critic each round — a continuation anchors to its own last verdict.
221
+ Round 1 is three critics in a single message so they run concurrently, each led onto a different part
222
+ of the checklist; round 2 onward is one. Merge by defect, not by critic. Where two critics
223
+ *contradict* each other, don't split the difference — go to the code and the goal and settle it.
224
+ Brief them from `references/critic.md`, which holds the checklist, the emphasis split and the
225
+ response format.
226
+
227
+ **Constraints.** TRUE means every clause of the goal is achieved by a step, every step earns its
228
+ place from the goal, and the drawing is the workflow — not that the model is beyond improvement. Two
229
+ rounds is normal, four is the hard ceiling. Defects still standing at four are reported as open
230
+ questions, not fixed.
231
+
232
+ **Gotchas.** A lone first-round TRUE is an agreeable critic, not a correct graph. Critics may read
233
+ the repo to settle a factual dispute, but the model is what is under review — a critic that starts
234
+ listing what it would change about the code has drifted. Re-submitting a converged model always
235
+ returns a fresh remark — that is oscillation, not a reopened defect.
236
+
237
+ ## 6. Find the seams the model can be pinned to
238
+
239
+ Only now, once the critic has converged. A seam mapped against a graph that is still moving gets
240
+ re-mapped every round, and mapping is the expensive part of this step.
241
+
242
+ **Find a seam, don't create one.** A seam you have to export into existence is a change to the repo,
243
+ and this skill makes none. Search only `services/` and `utils/`: a seam above that layer drags HTTP,
244
+ auth and Express into the fixture without adding a single business input.
245
+
246
+ Read the recording again first, filtered to the state-changing 2xx calls — OPTIONS, 304s and polling
247
+ GETs carried nothing. A `202` is worth stopping on: it means the work is fire-and-forget, so the
248
+ response body is not the outcome and the seam does not await it. Name the signal a test polls for
249
+ completion instead, or the test asserts on a workflow that hasn't run yet.
250
+
251
+ - **Input seam** — the narrowest already-exported function with every external input on its input
252
+ side. Count what it fetches, reads and imports, not just its parameters: an env var, a module-level
253
+ client and a database read are all things the test has to control, and they don't appear in a
254
+ signature.
255
+ - **Output seam** — where every outcome becomes durable, refusals included. Read the `catch` block;
256
+ that is usually where the refusal is written, and a seam that only sees OUTCOME 1 can never assert
257
+ OUTCOME 2.
258
+ - **Reject any seam the refactor would dissolve.** Pure helpers die under a refactor — that is what
259
+ the refactor is for. The orchestrator entry and the terminal write survive it, which is exactly
260
+ what makes them seams and a well-named private helper not one.
261
+ - **Grep every call site of the output seam** and say what distinguishes the in-graph ones. A durable
262
+ write is usually shared with unrelated code, and a test asserting that a save happened has proved
263
+ nothing about this workflow.
264
+ - **Read the seam's body before committing to it.** Retry loops and pruning ladders mutate the
265
+ payload between attempts, and they will silently void the assertions you are about to plan.
266
+
267
+ **Then map every node onto the output seam.** Take each node's `emits` and name the field on the
268
+ seam's payload that carries it. This mapping is the check — it is why no critic round is spent here.
269
+ A node that will not map means one of two things, and which one matters: either the seam is in the
270
+ wrong place, or nobody implemented that node. Say which. An unimplemented node is the most valuable
271
+ thing this step turns up, and the graph is the only reason anyone noticed it.
272
+
273
+ Write the two sections tight — the node table is where length is earned, not here. Each seam is
274
+ `name(signature)` with `file:line`, one sentence on why this one and not the runner-up you rejected,
275
+ then bullets: for the input seam one per external input, saying what it is, how it arrives and which
276
+ node it feeds; for the output seam one per node, naming the field that carries its `emits`. Cite
277
+ `file:line` for every claim — a seam named without a line number is a guess, and whoever writes the
278
+ test finds that out the expensive way.
279
+
280
+ ## 7. Write the artifact and stop
281
+
282
+ Write the six-section file described under **Output**. Then say in chat — not in the file — how many
283
+ rounds the critic loop ran and anything the last round still noted.
284
+
285
+ Then stop. Don't start the refactor, don't sketch a file layout, don't rename anything, and don't
286
+ write the test.
287
+
288
+ ## Anti-patterns
289
+
290
+ - Starting without the recording, and modelling a path that no longer runs.
291
+ - Drafting the goal or the nodes before the user has confirmed your understanding.
292
+ - Building the graph from function names or the call chain.
293
+ - A decomposition rather than a workflow — parts of the system with no order, no start and no
294
+ outcome, so nothing in it could ever be said to happen too late.
295
+ - A node that only moves data from one place to another.
296
+ - Table cells grown into paragraphs, so the row stops being scannable and the rules stop being
297
+ findable.
298
+ - Treating a convenience (dropping noisy rows to save typing) as an invariant.
299
+ - A refusal path that stops without a stated outcome the user can act on.
300
+ - Declaring convergence yourself instead of letting the critic do it.
301
+ - Running a fifth round because the fourth critic had one more thought. Past the ceiling, remaining
302
+ defects get reported, not fixed.
303
+ - Creating a seam — exporting a private helper — rather than finding one that already exists.
304
+ - An output seam that only sees the success path, leaving the refusal outcome unassertable.
305
+ - Hunting for seams before the critic has converged, pinning them to a graph still in motion.
@@ -0,0 +1,170 @@
1
+ # Briefing and running the critic
2
+
3
+ Read this when you reach step 5. It covers what to hand a critic, how many to run, what to ask them
4
+ for, and why the loop is capped.
5
+
6
+ ## What the loop is for
7
+
8
+ **Every business goal is achieved by a workflow, and the graph represents that workflow.** The
9
+ critic certifies both links:
10
+
11
+ - **goal → workflow.** Every clause of the 50-word sentence is achieved by a step; every step earns
12
+ its place from that sentence. Checklist item 1.
13
+ - **workflow → graph.** The drawing and the edge list are a faithful, ordered picture of that
14
+ workflow, with a start, a run and an outcome. Checklist item 5.
15
+
16
+ The nodes, edges and graph are not three things — they are one workflow written three ways. The
17
+ remaining checks exist because a workflow that is mis-scoped, at the wrong granularity, or made of
18
+ mechanism cannot be judged against a business goal in the first place.
19
+
20
+ Say this to the critic in as many words. A critic that is not told what it is deciding falls back on
21
+ generic code-review instincts and returns a list of things it would have written differently.
22
+
23
+ ## What the critic gets
24
+
25
+ Give it:
26
+
27
+ - the business goal
28
+ - the node table, **including the rule footnotes** (`R1`, `R2`…)
29
+ - the edge list
30
+ - the graph
31
+ - one paragraph of domain background, so it can make judgment calls about the business
32
+ - the repo, to check a claim against
33
+
34
+ The critic may read the code. It should not review it. The distinction is the whole job: it is
35
+ deciding whether this model represents the business, and a claim it cannot check is a claim it can
36
+ only test for internal tidiness. A critic that starts listing what it would change about the code has
37
+ drifted — the model is the subject, the code is the evidence.
38
+
39
+ Be aware that the paragraph of background is written by you, the author of the model under review, so
40
+ it can smuggle in the assumption being tested. That is a second reason the critic needs the repo.
41
+
42
+ Spawn a **fresh** critic each round. Continuing the previous one anchors it to its own last verdict;
43
+ a new one re-reads with clean eyes and finds different defects.
44
+
45
+ ## Where the rules live
46
+
47
+ Node cells carry a clause; the rule itself lives in the footnote the cell points at. So a cell
48
+ reading "fills in the quantity the customer asked for, and nothing else (R1, R2)" is judged by R1 and
49
+ R2, not by the cell alone. Footnotes are in scope for every checklist item, and a critic names one by
50
+ its id when the defect is there.
51
+
52
+ ## Round 1: three critics, concurrently
53
+
54
+ Different critics find different defects. This used to cost five rounds; buy the variety all at once
55
+ instead. **Spawn three critics in a single message containing three tool calls, so they run
56
+ concurrently.**
57
+
58
+ Give each the whole checklist, but tell each to lead with a different part:
59
+
60
+ | critic | leads with | checklist items |
61
+ |---|---|---|
62
+ | A | coverage and scope | 1, 6 |
63
+ | B | self-contradiction and mechanism leaks | 2, 3 |
64
+ | C | granularity, graph integrity, hidden assumptions | 4, 5, 7 |
65
+
66
+ Splitting the emphasis is what stops all three sharing a blind spot, which three identically-prompted
67
+ critics would.
68
+
69
+ Merge their findings **by defect, not by critic**: two critics naming the same node is one entry, not
70
+ two. The one-line defect format below is what makes this a deduplication rather than a second act of
71
+ synthesis.
72
+
73
+ **When two critics contradict each other** — one says a node is a mechanism leak, another says it
74
+ carries a real business rule — that is not a merge, and it is not yours to average. Go to the code
75
+ and to the goal sentence and settle which is true. A contradiction between two readers of the same
76
+ model is the loop working: it has found a place where the model is ambiguous enough to support both
77
+ readings, and the resolution belongs in the text so the next reader cannot make the same mistake.
78
+
79
+ **Check you actually have concurrency.** If you have no subagent tool and are emulating critics with
80
+ separate shell invocations, they will run one after another — and three critics back to back cost
81
+ what three rounds cost while telling you less. In that case spawn **one critic per round**, not
82
+ three.
83
+
84
+ Round 2 onward is a single critic with no seeded emphasis, judging the whole checklist against your
85
+ revision.
86
+
87
+ ## The checklist
88
+
89
+ Have the critic work through all seven, whatever it was told to lead with:
90
+
91
+ 1. **Coverage, both ways — does the workflow achieve the goal?** Every clause of the goal is *done*
92
+ by a step — and no step asserts a rule the goal gives no support for. Check the clause against the
93
+ step's `decides` and `refuses when` cells and the footnotes they point at, **never against its
94
+ name**. A step named for a goal clause whose decision does something else passes a name check and
95
+ fails the business; that is the defect this item exists to catch.
96
+ 2. **Self-contradiction.** Does any node's stated invariant survive the inputs it is actually handed?
97
+ This catches the most valuable class of defect: a commitment step that promises "every line, with
98
+ its photo" when an upstream filter already removed some.
99
+ 3. **Mechanism leaks.** Any node that is really storage, transport, authorization, a vendor, or a
100
+ file format wearing a business hat.
101
+ 4. **Granularity.** One node bundling three rules while another splits one rule across two.
102
+ 5. **Graph integrity — is the drawing the workflow?** Every declared input produced by an incoming
103
+ edge; every step reachable from an external input; every path ending in a stated outcome; the
104
+ drawing matching the edge list exactly. And is this a workflow at all, or a decomposition wearing
105
+ arrows — steps with no order between them, or a set of parts of the system rather than a run from
106
+ input to outcome?
107
+ 6. **Scope.** Nothing straying past the stated finish line, nothing stopping short of it.
108
+ 7. **Hidden assumptions** a reader would need told.
109
+
110
+ ## What the verdict means
111
+
112
+ Tell the critic this, or it will never give you one. The bar for TRUE is that **every clause of the
113
+ goal is achieved by a step, every step earns its place from the goal, and the drawing is that
114
+ workflow** — *not* that the model is beyond improvement. Every model is beyond improvement; a critic holding out for that answers FALSE
115
+ forever, and you find yourself on round nine of a loop that was right at round three.
116
+
117
+ So: if the remaining remarks are things the critic would mention in review but merge anyway, that is
118
+ `VERDICT: TRUE` with the remarks listed under it.
119
+
120
+ ## Response format
121
+
122
+ Ask for exactly this, and nothing else:
123
+
124
+ ```
125
+ HOLDS: <checklist numbers that pass, and the nodes already right — names only, no explanation>
126
+
127
+ <checklist#> <subject> — <the defect>
128
+ <checklist#> <subject> — <the defect>
129
+ ...
130
+
131
+ VERDICT: TRUE
132
+ ```
133
+
134
+ `<subject>` is a node name, an edge id (`E4`), a rule footnote id (`R2`), or **`GOAL`** for a defect
135
+ in the goal sentence itself — a clause with no home in any node, a clause the graph contradicts, or a
136
+ rule the graph enforces that the sentence never licenses. Given what this loop is for, `GOAL` defects
137
+ are the most important ones available, and without a subject to file them under they get quietly
138
+ rewritten as complaints about whichever node happened to be nearest.
139
+
140
+ No preamble, no summary, no restating your model back to you. You wrote it; you don't need it read
141
+ aloud. The verdict is a bare final line.
142
+
143
+ Two instructions matter as much as the checklist itself:
144
+
145
+ - **Don't manufacture defects to appear rigorous.**
146
+ - **Name what already passes**, so the next revision doesn't break it. Without the `HOLDS:` line,
147
+ revisions oscillate and you fix defect 3 while reintroducing defect 1.
148
+
149
+ ## Why the loop is capped
150
+
151
+ A competent critic can always find *something* to say about a ten-node graph, so "loop until a round
152
+ comes back clean" is a loop with no reliable exit. Runs left open-ended have gone ten rounds and
153
+ taken an hour to land where round three already was.
154
+
155
+ Two rounds is the normal case; four is the hard ceiling. Don't stop at one — a lone TRUE is as likely
156
+ to mean an agreeable critic as a correct graph, and that holds even when all three round-1 critics
157
+ return TRUE: run round 2 against the merged revision anyway, then take the verdict.
158
+
159
+ If defects remain when round four ends, that is a genuine finding: report them to the user as open
160
+ questions. It is not an instruction to keep going. Three honestly-recorded open questions are worth
161
+ far more than an hour of polish.
162
+
163
+ Between the floor and the ceiling, stop as soon as a round raises no defect that would change a node,
164
+ an edge, or a clause of the goal. Wording preferences and "you could also mention" notes are not
165
+ defects.
166
+
167
+ On FALSE, revise the goal, node and edge text. Most of what a critic finds are internal-consistency
168
+ defects your own notes already answer, and those never need the repo. When it disputes a specific
169
+ factual claim you can't settle from memory, go back — to that one function, not to the codebase.
170
+ Re-reading everything once per round is the most expensive habit available here and it buys nothing.
@@ -0,0 +1,180 @@
1
+ ---
2
+ name: system-resource-triage
3
+ description: Diagnose why a Linux box is slow, out of memory, or showing high load, explain the cause in two or three lines, propose a fix, offer to apply it, and report a before/after table. Use this whenever the user asks about CPU or memory utilisation, says the machine or dev box feels slow, sluggish or laggy, asks what is eating their RAM or CPU, mentions high load average, full swap, OOM kills, runaway or leaked processes, too many open processes, or zombies — and also when they simply paste top/htop/free/ps output and ask what is going on. It exists because the obvious readings mislead — ps %CPU is a lifetime average rather than current usage, load average is not the same as CPU busy, and per-process views hide problems that only show up in aggregate.
4
+ ---
5
+
6
+ # System resource triage
7
+
8
+ ## What this is for
9
+
10
+ Someone says "my machine is slow" or "check my CPU and memory". The naive answer is to run `top`,
11
+ read off the first row, and name whatever sits at the top. That answer is usually wrong, and
12
+ confidently wrong, because the default readings on a long-uptime box are averages over the life of
13
+ the process rather than a description of now.
14
+
15
+ This skill produces a short honest diagnosis, a proposed fix, and — if the user accepts — a
16
+ measured before/after. The value is mostly in not being fooled during the measurement, and in not
17
+ destroying something the user still needs during the fix.
18
+
19
+ ## Shape of the interaction
20
+
21
+ Five beats, in order. Don't merge them and don't skip the pause.
22
+
23
+ 1. **Measure** — one pass, cheap, read-only.
24
+ 2. **Explain** — two or three lines. Not a report.
25
+ 3. **Suggest** — the specific fix, and what it will reclaim.
26
+ 4. **Offer** — stop and wait for a yes before touching anything.
27
+ 5. **Before/after** — a table, from numbers you captured *before* you acted.
28
+
29
+ The pause at step 4 is the point. Freeing memory means killing processes, and the user is the only
30
+ one who knows whether the thing you're about to kill matters.
31
+
32
+ ## Step 1: Measure
33
+
34
+ Run `scripts/triage.sh`. It's read-only and takes a few seconds. It gathers everything below in one
35
+ pass, which matters for a reason explained in the next section.
36
+
37
+ ```bash
38
+ bash scripts/triage.sh # group memory by process name
39
+ bash scripts/triage.sh claude node # or group by patterns matched against full command line
40
+ ```
41
+
42
+ Pass patterns when process names are uninformative — VS Code's server processes are all called
43
+ `MainThread`, so grouping by name tells you nothing and grouping by `vscode-server` tells you
44
+ everything.
45
+
46
+ ## Reading the numbers without being fooled
47
+
48
+ These are the traps. Each has bitten a real diagnosis.
49
+
50
+ **`ps %CPU` is a lifetime average, not current usage.** It is total CPU consumed divided by process
51
+ age. On a box up 64 days, long-lived daemons like `containerd` and `dockerd` routinely show 60-80%
52
+ while using nothing at all right now. If you name them as the culprit you will be wrong. Take
53
+ instantaneous CPU from the *second* sample of `top -bn2`.
54
+
55
+ **The first row of `vmstat` is also a since-boot average.** Discard it. Always read row two onward.
56
+
57
+ **Load average is not "CPU busy".** It counts runnable *and* uninterruptible processes. High load
58
+ with high idle means the load is coming from somewhere other than CPU work. Decompose it before
59
+ concluding anything:
60
+
61
+ - `wa` high, processes in `D` state → I/O or swap thrashing.
62
+ - `r` persistently above core count → genuine CPU contention.
63
+ - both low, `cs` very high → scheduler churn, often just many idle pollers. Frequently harmless.
64
+ - Load average is a decaying 1/5/15-minute mean, so it lags a fix by minutes. Don't judge a fix by
65
+ it immediately; `free` and `r` respond right away.
66
+
67
+ **Aggregate before you conclude.** This is the single highest-value move. Forty-five processes at
68
+ 340 MB each never appear in `top`'s top ten, but they are 15 GB. Problems that live in the count
69
+ rather than the size are invisible per-process and obvious in aggregate. The script does this
70
+ grouping for you.
71
+
72
+ **Read swap per process, not just in total.** `free` says swap is full; `/proc/PID/status`'s
73
+ `VmSwap` says who put it there. A process swapped fully out shows near-zero RSS and looks innocent.
74
+
75
+ **Your own measuring can create the symptom.** A loop that spawns a subprocess per PID across 1500
76
+ PIDs generates tens of thousands of context switches and inflates the run queue — you then read
77
+ that back and diagnose it as the problem. Prefer one `awk` pass over `/proc/*/status` to a shell
78
+ loop, and if you see a run queue spike only while your own diagnostic runs, that's you. Re-measure
79
+ with nothing else running before you believe a churn number.
80
+
81
+ **Check zombies.** They cost no RAM or CPU, so they never surface in a memory hunt, but a large
82
+ count means a parent isn't reaping and PID slots are leaking. The classic cause is a container
83
+ whose PID 1 is `sleep infinity`, which never calls `wait()`. Group zombies by PPID to find the
84
+ offender; the fix is giving that container a real init (`init: true`), not killing anything.
85
+
86
+ ## Step 2: Explain, in two or three lines
87
+
88
+ Lead with which resource is actually constrained, name the cause, and give the number that proves
89
+ it. If CPU is fine, say so first — it stops the user chasing it.
90
+
91
+ > CPU is fine — 63% idle, no iowait. The problem is memory: 26 of 30 GB used and swap completely
92
+ > full. 45 abandoned `claude` sessions, 2-21 days old with no terminal attached, account for
93
+ > 15.5 GB of it.
94
+
95
+ Resist expanding this. The evidence goes in the table later; anything you cut here the user can ask
96
+ for. If you found something real but off-topic — leaked zombies, a container misconfiguration —
97
+ hold it until after the main fix rather than diluting the headline.
98
+
99
+ ## Step 3: Suggest
100
+
101
+ Name the specific action and what it reclaims. Prefer the smallest action with the largest return,
102
+ and say what you are deliberately *not* touching, so the user can object.
103
+
104
+ > Suggest SIGTERM on those 28 detached sessions — should return ~12 GB and drain most of swap. I'd
105
+ > leave the VS Code servers alone since those are likely your live editor windows.
106
+
107
+ If there are stages, order them most-reclaim-for-least-risk and plan to stop as soon as enough is
108
+ free. Running stage 3 when stage 1 sufficed is how a routine cleanup becomes an outage.
109
+
110
+ ## Step 4: Offer, then act safely
111
+
112
+ Ask, and wait. Once the user agrees:
113
+
114
+ **Capture the "before" numbers first.** You cannot reconstruct them afterwards and the table is
115
+ part of the deliverable. `scripts/triage.sh --snapshot /tmp/before.txt` saves them.
116
+
117
+ **Dry run and show the list.** `scripts/reap.sh --name <pattern>` prints candidates and totals;
118
+ nothing dies without `--confirm`. Let the user see actual PIDs and ages first.
119
+
120
+ It only ever selects processes that are detached, older than `--min-age-days` (default 2), and
121
+ owned by the current user. Kernel threads, init, other users' daemons, and zombies are excluded —
122
+ a candidate list containing `dockerd` or `systemd` is a bug, and zombies are worth excluding
123
+ because they hold no memory, so counting them inflates the reclaim estimate for no gain.
124
+
125
+ **Kill the list you showed, verbatim.** Recomputing the candidate set at kill time reintroduces
126
+ everything the review was meant to catch. Paste the reviewed PIDs.
127
+
128
+ **Never kill your own session.** Walk `/proc/PID/status`'s `PPid` up from `$$` and exclude every
129
+ ancestor. `reap.sh` does this and refuses to run if a protected PID appears in the list. Processes
130
+ with a controlling terminal are attached to something a human is using — exclude those too.
131
+
132
+ **SIGTERM, wait, then reconsider.** TERM lets sessions flush state to disk. Wait ~10 seconds and
133
+ re-check. `kill -9` only for genuine stragglers, and it's worth asking again first.
134
+
135
+ **In zsh, `kill $PIDS` fails.** zsh doesn't word-split unquoted variables, so a space-separated PID
136
+ list is passed as one argument and the whole kill is rejected — easy to misread as success if you
137
+ echo a count afterwards. Loop over the list, or use `${=PIDS}`. The scripts here use `bash`
138
+ explicitly to sidestep this.
139
+
140
+ **Reclaim swap last, and only with headroom.** Swap usually drains on its own as processes exit.
141
+ If stale pages remain, `swapoff -a && swapon -a` forces them back to RAM — which OOMs the box if
142
+ RAM isn't free yet. Verify free RAM exceeds used swap before running it, and skip it entirely if
143
+ swap is already comfortable.
144
+
145
+ ## Step 5: Before/after table
146
+
147
+ Re-measure and report. Keep it to the metrics that moved.
148
+
149
+ ```markdown
150
+ | | Before | After |
151
+ |---|---|---|
152
+ | RAM used | 26 Gi / 30 Gi | 14 Gi / 30 Gi |
153
+ | Available | 4.6 Gi | 15 Gi |
154
+ | Swap | 4.0 Gi (100%) | 815 Mi (20%) |
155
+ | Load (1m) | 8.30 | 5.91 |
156
+ ```
157
+
158
+ Add one line on what you skipped and why ("swap drained on its own, so I didn't need `swapoff`"),
159
+ and surface any secondary finding you held back.
160
+
161
+ ## Say so when a prediction misses
162
+
163
+ If you predicted a number would move and it didn't, lead with that rather than letting the table
164
+ quietly omit it. Concretely: context switches staying at 60-80k/s after removing 28 processes
165
+ falsifies "idle pollers cause the churn", and the honest follow-up is a quick check of
166
+ `/proc/interrupts` — high `CAL` and `TLB` on a KVM guest is normal hypervisor overhead, not
167
+ something to chase.
168
+
169
+ A fix that worked for a reason you got wrong is worth flagging, because the user will otherwise
170
+ apply the wrong lesson next time. It also stops you from proposing the same wrong fix again.
171
+
172
+ ## Scope
173
+
174
+ This covers diagnosis and reclaiming resources on a machine the user controls. Application-level
175
+ memory profiling (heap dumps, leak hunting inside one process) is a different job — say so and
176
+ stop rather than stretching this to fit.
177
+
178
+ Two things are worth naming as out of scope even when they'd help, because they change the
179
+ machine's configuration rather than its current state: restarting containers and editing service
180
+ definitions. Report them as findings with the specific fix, and let the user decide.