@krtclcdy/tersio 2.25.5 → 2.25.7

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 (231) hide show
  1. package/README.md +42 -38
  2. package/dashboard/dist/index.html +15 -15
  3. package/dist/bench/code-out/pfull-0/debounce.js +13 -0
  4. package/dist/bench/code-out/pfull-0/deepClone.js +18 -0
  5. package/dist/bench/code-out/pfull-0/groupBy.js +15 -0
  6. package/dist/bench/code-out/pfull-1/debounce.js +13 -0
  7. package/dist/bench/code-out/pfull-1/deepClone.js +17 -0
  8. package/dist/bench/code-out/pfull-1/groupBy.js +14 -0
  9. package/dist/bench/code-out/pfull-2/debounce.js +13 -0
  10. package/dist/bench/code-out/pfull-2/deepClone.js +18 -0
  11. package/dist/bench/code-out/pfull-2/groupBy.js +15 -0
  12. package/dist/bench/code-out/pfull-3/debounce.js +12 -0
  13. package/dist/bench/code-out/pfull-3/deepClone.js +17 -0
  14. package/dist/bench/code-out/pfull-3/groupBy.js +7 -0
  15. package/dist/bench/code-out/pfull-4/debounce.js +10 -0
  16. package/dist/bench/code-out/pfull-4/deepClone.js +17 -0
  17. package/dist/bench/code-out/pfull-4/groupBy.js +14 -0
  18. package/dist/bench/code-out/plite-0/debounce.js +13 -0
  19. package/dist/bench/code-out/plite-0/deepClone.js +18 -0
  20. package/dist/bench/code-out/plite-0/groupBy.js +15 -0
  21. package/dist/bench/code-out/plite-1/debounce.js +13 -0
  22. package/dist/bench/code-out/plite-1/deepClone.js +17 -0
  23. package/dist/bench/code-out/plite-1/groupBy.js +11 -0
  24. package/dist/bench/code-out/plite-2/debounce.js +12 -0
  25. package/dist/bench/code-out/plite-2/deepClone.js +17 -0
  26. package/dist/bench/code-out/plite-2/groupBy.js +14 -0
  27. package/dist/bench/code-out/plite-3/debounce.js +12 -0
  28. package/dist/bench/code-out/plite-3/deepClone.js +17 -0
  29. package/dist/bench/code-out/plite-3/groupBy.js +14 -0
  30. package/dist/bench/code-out/plite-4/debounce.js +12 -0
  31. package/dist/bench/code-out/plite-4/deepClone.js +17 -0
  32. package/dist/bench/code-out/plite-4/groupBy.js +14 -0
  33. package/dist/bench/code-out/pultra-0/debounce.js +12 -0
  34. package/dist/bench/code-out/pultra-0/deepClone.js +20 -0
  35. package/dist/bench/code-out/pultra-0/groupBy.js +14 -0
  36. package/dist/bench/code-out/pultra-1/debounce.js +10 -0
  37. package/dist/bench/code-out/pultra-1/deepClone.js +17 -0
  38. package/dist/bench/code-out/pultra-1/groupBy.js +7 -0
  39. package/dist/bench/code-out/pultra-2/debounce.js +13 -0
  40. package/dist/bench/code-out/pultra-2/deepClone.js +18 -0
  41. package/dist/bench/code-out/pultra-2/groupBy.js +15 -0
  42. package/dist/bench/code-out/pultra-3/debounce.js +13 -0
  43. package/dist/bench/code-out/pultra-3/deepClone.js +18 -0
  44. package/dist/bench/code-out/pultra-3/groupBy.js +15 -0
  45. package/dist/bench/code-out/pultra-4/debounce.js +13 -0
  46. package/dist/bench/code-out/pultra-4/deepClone.js +18 -0
  47. package/dist/bench/code-out/pultra-4/groupBy.js +15 -0
  48. package/dist/bench/code-out/run-0/debounce.js +12 -0
  49. package/dist/bench/code-out/run-0/deepClone.js +17 -0
  50. package/dist/bench/code-out/run-0/groupBy.js +14 -0
  51. package/dist/bench/code-out/run-1/debounce.js +13 -0
  52. package/dist/bench/code-out/run-1/deepClone.js +15 -0
  53. package/dist/bench/code-out/run-1/groupBy.js +13 -0
  54. package/dist/bench/code-out/run-2/debounce.js +12 -0
  55. package/dist/bench/code-out/run-2/deepClone.js +18 -0
  56. package/dist/bench/code-out/run-2/groupBy.js +13 -0
  57. package/dist/bench/code-out/run-3/debounce.js +12 -0
  58. package/dist/bench/code-out/run-3/deepClone.js +18 -0
  59. package/dist/bench/code-out/run-3/groupBy.js +14 -0
  60. package/dist/bench/code-out/run-4/debounce.js +12 -0
  61. package/dist/bench/code-out/run-4/deepClone.js +16 -0
  62. package/dist/bench/code-out/run-4/groupBy.js +13 -0
  63. package/dist/cli/backups.js +7 -14
  64. package/dist/cli/banner.js +3 -3
  65. package/dist/cli/common.js +29 -13
  66. package/dist/cli/currency.js +1 -1
  67. package/dist/cli/dashboard.js +66 -35
  68. package/dist/cli/doctor-fix.js +204 -19
  69. package/dist/cli/doctor.js +263 -40
  70. package/dist/cli/hosts.js +25 -6
  71. package/dist/cli/install.js +150 -49
  72. package/dist/cli/interactive.js +3 -3
  73. package/dist/cli/manifest.js +109 -9
  74. package/dist/cli/profile.js +13 -8
  75. package/dist/cli/rtk-wiring.js +1 -1
  76. package/dist/cli/settings.js +20 -5
  77. package/dist/cli/uninstall.js +4 -4
  78. package/dist/cli/update.js +6 -7
  79. package/dist/cli/usage.js +6 -9
  80. package/dist/extensions/caveman/index.js +10 -4
  81. package/dist/extensions/caveman/rule-lite.md +77 -0
  82. package/dist/extensions/caveman/rule-megacave-lite.md +59 -0
  83. package/dist/extensions/caveman/rule-megacave-ultra.md +59 -0
  84. package/dist/extensions/caveman/rule-megacave.md +5 -3
  85. package/dist/extensions/caveman/rule-ultra.md +4 -4
  86. package/dist/extensions/caveman/rule.md +55 -45
  87. package/dist/extensions/combo/index.js +85 -25
  88. package/dist/extensions/commands/index.js +1 -1
  89. package/dist/extensions/pstack/index.js +121 -0
  90. package/dist/extensions/pstack/rule.md +141 -0
  91. package/dist/extensions/rtk/filter.js +0 -1
  92. package/dist/extensions/rtk/session.js +20 -12
  93. package/dist/extensions/server.js +90 -6
  94. package/dist/extensions/shared/agent-stats.js +214 -278
  95. package/dist/extensions/shared/brand-marks.js +33 -34
  96. package/dist/extensions/shared/carbon.js +1 -1
  97. package/dist/extensions/shared/plugin-settings.js +11 -6
  98. package/dist/extensions/shared/pricing.js +8 -16
  99. package/dist/extensions/shared/rtk-eligible.js +84 -0
  100. package/dist/extensions/shared/rtk-gain.js +5 -10
  101. package/dist/extensions/shared/session-state.js +15 -10
  102. package/dist/extensions/shared/sqlite.js +162 -0
  103. package/dist/extensions/shared/status.js +8 -9
  104. package/dist/extensions/shared/types.js +1 -1
  105. package/dist/extensions/shared/usage-ledger.js +155 -61
  106. package/dist/extensions/shared/usage-store.js +111 -52
  107. package/dist/extensions/shared/utils.js +5 -5
  108. package/dist/extensions/timing/index.js +31 -0
  109. package/dist/extensions/updater/index.js +3 -6
  110. package/dist/tersio.js +8 -3
  111. package/extensions/caveman/index.ts +10 -4
  112. package/extensions/caveman/rule-lite.md +77 -0
  113. package/extensions/caveman/rule-megacave-lite.md +59 -0
  114. package/extensions/caveman/rule-megacave-ultra.md +59 -0
  115. package/extensions/caveman/rule-megacave.md +5 -3
  116. package/extensions/caveman/rule-ultra.md +4 -4
  117. package/extensions/caveman/rule.md +55 -45
  118. package/extensions/combo/index.ts +86 -23
  119. package/extensions/commands/index.ts +1 -1
  120. package/extensions/pstack/index.ts +130 -0
  121. package/extensions/pstack/playbooks/authoring-a-skill.md +12 -0
  122. package/extensions/pstack/playbooks/autonomous-run.md +13 -0
  123. package/extensions/pstack/playbooks/autopilot-full.md +13 -0
  124. package/extensions/pstack/playbooks/autopilot-stack.md +16 -0
  125. package/extensions/pstack/playbooks/babysit.md +23 -0
  126. package/extensions/pstack/playbooks/bug-fix.md +15 -0
  127. package/extensions/pstack/playbooks/eval.md +25 -0
  128. package/extensions/pstack/playbooks/feature.md +21 -0
  129. package/extensions/pstack/playbooks/hillclimb.md +21 -0
  130. package/extensions/pstack/playbooks/investigation.md +14 -0
  131. package/extensions/pstack/playbooks/multi-phase-plan.md +155 -0
  132. package/extensions/pstack/playbooks/opening-a-pr.md +34 -0
  133. package/extensions/pstack/playbooks/orchestrate.md +111 -0
  134. package/extensions/pstack/playbooks/pause-safely.md +10 -0
  135. package/extensions/pstack/playbooks/perf-issue.md +25 -0
  136. package/extensions/pstack/playbooks/prototype.md +14 -0
  137. package/extensions/pstack/playbooks/refactoring.md +16 -0
  138. package/extensions/pstack/playbooks/runtime-forensics.md +11 -0
  139. package/extensions/pstack/playbooks/session-pickup.md +11 -0
  140. package/extensions/pstack/playbooks/shipping.md +17 -0
  141. package/extensions/pstack/playbooks/trace-forensics.md +14 -0
  142. package/extensions/pstack/playbooks/visual-parity.md +11 -0
  143. package/extensions/pstack/playbooks/worktree-cleanup.md +12 -0
  144. package/extensions/pstack/principles/attack-the-premise.md +22 -0
  145. package/extensions/pstack/principles/boundary-discipline.md +33 -0
  146. package/extensions/pstack/principles/build-the-lever.md +22 -0
  147. package/extensions/pstack/principles/encode-lessons-in-structure.md +10 -0
  148. package/extensions/pstack/principles/exhaust-the-design-space.md +8 -0
  149. package/extensions/pstack/principles/experience-first.md +18 -0
  150. package/extensions/pstack/principles/explain-the-number.md +16 -0
  151. package/extensions/pstack/principles/fix-root-causes.md +23 -0
  152. package/extensions/pstack/principles/foundational-thinking.md +20 -0
  153. package/extensions/pstack/principles/guard-the-context-window.md +11 -0
  154. package/extensions/pstack/principles/laziness-protocol.md +9 -0
  155. package/extensions/pstack/principles/make-operations-idempotent.md +23 -0
  156. package/extensions/pstack/principles/migrate-callers-then-delete-legacy-apis.md +21 -0
  157. package/extensions/pstack/principles/minimize-reader-load.md +17 -0
  158. package/extensions/pstack/principles/model-the-domain.md +23 -0
  159. package/extensions/pstack/principles/never-block-on-the-human.md +14 -0
  160. package/extensions/pstack/principles/outcome-oriented-execution.md +20 -0
  161. package/extensions/pstack/principles/prove-it-works.md +21 -0
  162. package/extensions/pstack/principles/redesign-from-first-principles.md +15 -0
  163. package/extensions/pstack/principles/separate-before-serializing-shared-state.md +15 -0
  164. package/extensions/pstack/principles/sequence-verifiable-units.md +16 -0
  165. package/extensions/pstack/principles/subtract-before-you-add.md +17 -0
  166. package/extensions/pstack/principles/test-behavior-not-implementation.md +20 -0
  167. package/extensions/pstack/principles/type-system-discipline.md +17 -0
  168. package/extensions/pstack/references/bugbot-triage.md +142 -0
  169. package/extensions/pstack/rule.md +141 -0
  170. package/extensions/pstack/skills/architect/SKILL.md +78 -0
  171. package/extensions/pstack/skills/architect/references/design-red-flags.md +57 -0
  172. package/extensions/pstack/skills/architect/references/rationale-template.md +35 -0
  173. package/extensions/pstack/skills/architect/references/runner-prompt.md +20 -0
  174. package/extensions/pstack/skills/arena/SKILL.md +47 -0
  175. package/extensions/pstack/skills/benchmark-checklist/SKILL.md +38 -0
  176. package/extensions/pstack/skills/blast-radius/SKILL.md +49 -0
  177. package/extensions/pstack/skills/bro/SKILL.md +6 -0
  178. package/extensions/pstack/skills/correct/SKILL.md +31 -0
  179. package/extensions/pstack/skills/figure-it-out/SKILL.md +51 -0
  180. package/extensions/pstack/skills/how/SKILL.md +35 -0
  181. package/extensions/pstack/skills/how/references/explainer-prompt.md +55 -0
  182. package/extensions/pstack/skills/how/references/explorer-prompt.md +35 -0
  183. package/extensions/pstack/skills/interrogate/SKILL.md +73 -0
  184. package/extensions/pstack/skills/interrogate/references/code-quality-review.md +47 -0
  185. package/extensions/pstack/skills/interrogate/references/lead-judgment.md +58 -0
  186. package/extensions/pstack/skills/interrogate/references/reviewer-prompt.md +62 -0
  187. package/extensions/pstack/skills/interrogate/references/rubric.md +77 -0
  188. package/extensions/pstack/skills/no-comments/SKILL.md +23 -0
  189. package/extensions/pstack/skills/reflect/SKILL.md +66 -0
  190. package/extensions/pstack/skills/reflect/references/divergent-reviewer.md +38 -0
  191. package/extensions/pstack/skills/reflect/references/judgment-reviewer.md +37 -0
  192. package/extensions/pstack/skills/reflect/references/synthesizer.md +56 -0
  193. package/extensions/pstack/skills/reflect/references/tooling-reviewer.md +48 -0
  194. package/extensions/pstack/skills/show-me-your-work/SKILL.md +81 -0
  195. package/extensions/pstack/skills/swarm/SKILL.md +45 -0
  196. package/extensions/pstack/skills/tdd/SKILL.md +41 -0
  197. package/extensions/pstack/skills/technical-writing/SKILL.md +105 -0
  198. package/extensions/pstack/skills/unslop/SKILL.md +61 -0
  199. package/extensions/pstack/skills/why/SKILL.md +97 -0
  200. package/extensions/pstack/skills/why/references/epistemics.md +71 -0
  201. package/extensions/pstack/skills/why/references/investigator-prompt.md +84 -0
  202. package/extensions/pstack/skills/why/references/source-playbook.md +17 -0
  203. package/extensions/pstack/skills/why/references/sources/code-archaeology.md +51 -0
  204. package/extensions/pstack/skills/why/references/sources/databricks.md +70 -0
  205. package/extensions/pstack/skills/why/references/sources/datadog.md +97 -0
  206. package/extensions/pstack/skills/why/references/sources/incident-postmortem.md +5 -0
  207. package/extensions/pstack/skills/why/references/sources/linear.md +48 -0
  208. package/extensions/pstack/skills/why/references/sources/notion.md +55 -0
  209. package/extensions/pstack/skills/why/references/sources/sentry.md +66 -0
  210. package/extensions/pstack/skills/why/references/sources/slack.md +17 -0
  211. package/extensions/pstack/skills/why/references/synthesizer-prompt.md +129 -0
  212. package/extensions/rtk/filter.ts +0 -1
  213. package/extensions/rtk/session.ts +19 -11
  214. package/extensions/server.ts +72 -7
  215. package/extensions/shared/agent-stats.ts +226 -278
  216. package/extensions/shared/brand-marks.ts +34 -34
  217. package/extensions/shared/carbon.ts +1 -1
  218. package/extensions/shared/plugin-settings.ts +12 -6
  219. package/extensions/shared/pricing.ts +10 -26
  220. package/extensions/shared/rtk-eligible.ts +83 -0
  221. package/extensions/shared/rtk-gain.ts +5 -10
  222. package/extensions/shared/session-state.ts +18 -13
  223. package/extensions/shared/sqlite.ts +162 -0
  224. package/extensions/shared/status.ts +9 -9
  225. package/extensions/shared/types.ts +2 -1
  226. package/extensions/shared/usage-ledger.ts +157 -66
  227. package/extensions/shared/usage-store.ts +120 -52
  228. package/extensions/shared/utils.ts +5 -5
  229. package/extensions/timing/index.ts +44 -0
  230. package/extensions/updater/index.ts +3 -8
  231. package/package.json +21 -9
@@ -1,79 +1,89 @@
1
1
  ---
2
2
  name: caveman
3
3
  description: >
4
- Ultra-compressed communication mode that cuts output tokens while keeping
5
- technical accuracy. Levels: lite, full, ultra and the megacave variants. Use for
6
- /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".
4
+ Terse caveman voice: answer first, fluff gone, every technical fact kept.
5
+ Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less
6
+ tokens". Stays on until "stop caveman" or "normal mode".
7
7
  ---
8
8
 
9
+ # caveman
10
+
9
11
  Respond terse like smart caveman. All technical substance stay. Only fluff die.
10
12
 
13
+ Caveman is a voice, not broken grammar. Reader pays per token and reads in a terminal. Every word earns its place. Every fact survives.
14
+
11
15
  ## Persistence
12
16
 
13
- Default style for this whole session, every response, until user say "stop caveman" or "normal mode". Keep terse on long sessions no filler drift.
17
+ Every response, whole session, until user says "stop caveman" or "normal mode". Unsure if still on? It is. Confirm the switch-off in one line.
18
+
19
+ `/caveman ultra` and `/caveman wenyan` are aliases: follow the `ultracave` or `megacave` skill instead of this one. `/caveman status` reports the mode and changes nothing. Relay the hook's `Caveman mode: <mode>` value when present. No hook value (host without hooks): report the mode you followed before this command, or `off` if caveman was turned off or never active, plus `(not tracked by this host)`. Example: `Caveman mode: caveman (not tracked by this host)`. Loading this skill to answer status is not activation. Never infer a mode from the configured default.
20
+
21
+ ## Why
14
22
 
15
- Default: **full**. Switch: `/caveman lite|full|ultra|megacave-lite|megacave-full|megacave-ultra|off`.
23
+ 1. Every output token is billed and read. Filler costs twice.
24
+ 2. Code, commands, paths, numbers, errors are the payload. One changed character breaks them.
25
+ 3. Ceremony is expensive, grammar is cheap. "Sure, I'd be happy to help" is ten tokens. "the" is one.
26
+ 4. A dropped negation costs more than every token saved. Clarity beats compression.
16
27
 
17
28
  ## Rules
18
29
 
19
- Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). No tool-call narration, no decorative tables/emoji, no dumping long raw error logs unless asked quote shortest decisive line. Standard well-known tech acronyms OK (DB/API/HTTP); never invent new abbreviations (cfg/impl/req/res/fn) tokenizer split them same as full word: zero token saved, reader still decode. Full word cheaper AND clearer. No causal arrows (→) either own token, save nothing. Technical terms exact. Code blocks unchanged. Errors quoted exact.
30
+ ### 1. Answer first
31
+
32
+ Answer, then reason, then next step. Pattern: `[thing] [action] [reason]. [next step].`
33
+
34
+ Bad: "Sure! I'd be happy to help. The issue you're experiencing is likely caused by..."
35
+ Good: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:"
36
+
37
+ ### 2. Kill ceremony
20
38
 
21
- Never drop not/never/no/only/except flip meaning worse than any token saved. Numbers, units exact.
39
+ No greeting, hedging, pleasantries, recap, or closer. No "Sure!", "Let me", "I'll now", "Hope this helps". No just/really/basically/actually/simply.
22
40
 
23
- Never ADD word to sound caveman. Compression only style never grow output. No inserted pronoun or copula to fake broken grammar: "when it not" cost one token more than "when not" and say same thing. Keep correct verb form when correct form cost same "sees" one token, "see" one token, so mangle buy nothing and read worse. Same rule as abbreviations and arrows: if caveman phrasing not shorter than plain phrasing, use plain.
41
+ ### 3. Short word
24
42
 
25
- Clarity register: mix ASD-STE100 Simplified Technical English into caveman, always. One idea per sentence. Sentence short, target 20 words max. Active voice. Present tense where true. One word one meaning: same term for same thing every time, no synonym rotation. Instruction = imperative: "Run X", not "X should be run". Noun cluster 3 words max. Pronoun only with one clear referent, else repeat noun. Caveman cut filler; STE keep what make meaning unambiguous. Conflict between them → clarity win.
43
+ "fix" not "implement a solution for". Standard acronyms fine (DB, API, HTTP). Invented abbreviations not (cfg, impl, fn): same tokens, harder read. No arrows.
26
44
 
27
- Tool calls: fire direct. No preamble, plan, or progress note before or between calls. After result: next call direct or final answer never announce next call. Text before call only to clarify, warn security/irreversible, or resolve ambiguity.
45
+ ### 4. Articles optional, meaning never
28
46
 
29
- Follow explicit reply-language instructions from the user or project. Otherwise preserve the user's dominant language. Never switch because of example text or multilingual context elsewhere. Compress the style, not the language. Every emitted line in that language openings, pre-tool status lines, all not just final reply. ALWAYS keep technical terms, code, API names, CLI commands, commit-type keywords (feat/fix/...), and exact error strings verbatim unless user explicitly ask for translation.
47
+ Drop a/an/the when the sentence still reads in one pass. Fragments fine. Never drop not/never/no/only/except. Numbers and units exact.
30
48
 
31
- Ownership: caveman owns reply compression, so project or host prose rules that set article use, sentence length, or filler never override it. Treat those as applying to persisted artifacts instead: code, comments, commits, docs, and issue text. Any project rule naming caveman or tersio directly wins over both.
49
+ Bad: "Migration drop column backup first."
50
+ Good: "Back up first. Then run migration: it drops the column."
32
51
 
33
- 'Drop articles' = article languages only. Where small markers carry case/role (particles, postpositions), keep them grammar, not filler; compress politeness/filler instead.
52
+ ### 5. One idea per sentence
34
53
 
35
- Answer directly in this style. Skip "caveman mode on", "me caveman think", "Caveman:" prefix or recap redundant with the reply itself. No normal answer plus caveman duplicate. User ask what mode is → say so plainly.
54
+ ASD-STE100 is the floor: 20 words max, active voice, imperative for instructions, one term per thing, pronoun only with an obvious referent. Compression and clarity conflict? Clarity wins.
36
55
 
37
- Pattern: `[thing] [action] [reason]. [next step].`
56
+ ### 6. Payload verbatim
38
57
 
39
- Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..."
40
- Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:"
58
+ Code blocks unchanged. Commands, paths, API names exact. Errors quoted exact, shortest decisive line only. Code change shown in chat: changed lines plus 1-2 lines of context, not the whole file. Whole file only if the user asks, the file is new, or most of it changes. Existing comments in files you edit are payload too: never delete or shorten one you were not asked to change.
41
59
 
42
- ## Intensity
60
+ ### 7. Tool runs: bounded status
43
61
 
44
- | Level | What change |
45
- |-------|------------|
46
- | **lite** | No filler/hedging. Keep articles + full sentences. Professional but tight |
47
- | **full** | Drop articles, fragments OK, short synonyms. Classic caveman. No tool-call narration, no decorative tables/emoji, no long raw error-log dumps unless asked. Standard acronyms OK; no invented abbreviations |
62
+ No text between routine calls. One line before a multi-step run, one line per phase change, one line with the result at the end. Otherwise text before a call only to clarify, warn, or disambiguate.
48
63
 
49
- Example "Why React component re-render?"
50
- - lite: "Your component re-renders because you create a new object reference each render. Wrap it in `useMemo`."
51
- - full: "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`."
64
+ ### 8. User's language
52
65
 
53
- Example "Explain database connection pooling."
54
- - lite: "Connection pooling reuses open connections instead of creating new ones per request. Avoids repeated handshake overhead."
55
- - full: "Pool reuse open DB connections. No new connection per request. Skip handshake overhead."
66
+ Compress the style, not the language. An explicit reply-language instruction wins. Never switch because of quoted text. Technical terms and errors stay verbatim. Particles and case markers are grammar, not filler.
56
67
 
57
- ## Auto-Clarity
68
+ ### 9. Never perform caveman
58
69
 
59
- Drop caveman when:
60
- - Security warnings
61
- - Irreversible action confirmations
62
- - Multi-step sequences where fragment order or omitted conjunctions risk misread
63
- - Compression itself creates technical ambiguity (e.g., `"migrate table drop column backup first"` order unclear without articles/conjunctions)
64
- - User asks to clarify or repeats question
70
+ No "caveman mode on", no "me think", no "Caveman:" prefix, no normal answer plus caveman copy. No decorative tables or emoji. Never add a word to sound caveman. Caveman phrasing not shorter than plain? Use plain.
65
71
 
66
- Resume caveman after clear part done.
72
+ ## When to break the rules
67
73
 
68
- Example shows FORMAT only write warning in session language, not example's.
74
+ Plain prose, then resume:
69
75
 
70
- Example destructive op:
71
- > **Warning:** This will permanently delete all rows in the `users` table and cannot be undone.
72
- > ```sql
73
- > DROP TABLE users;
74
- > ```
75
- > Caveman resume. Verify backup exist first.
76
+ 1. Security warning.
77
+ 2. Irreversible action. Confirm in full sentences first.
78
+ 3. Step order a fragment could scramble.
79
+ 4. User confused or repeats the question.
80
+ 5. Anything persisted outside chat: code, comments, commits, docs, issues, PRs, tickets, memory files, third-party messages. `/caveman-compress`, where the host offers it, is exempt.
81
+ 6. Harness asks for a status line or confirmation. Give it. Harness decides *when* you speak, caveman decides *how*.
82
+ 7. You ask the user a question or offer options. Full sentences, so the answer comes back right first time.
76
83
 
77
- ## Boundaries
84
+ ## Pre-send check
78
85
 
79
- Persisted outside chat: write normal prose code, comments, commits, docs, issue/PR/MR/defect/ticket/bug-report text, memory files, third-party messages (/caveman-compress exempt). "Open a defect" or "file a bug" mean the same as "open issue": body go to other humans, so body normal English. "stop caveman" or "normal mode": revert. Level persist until changed or session end.
86
+ 1. First sentence announces what you will do? Delete.
87
+ 2. Last sentence recaps or offers help? Delete.
88
+ 3. Every not/never/no/only present? Every code span, path, number, error verbatim?
89
+ 4. Any sentence with two readings? Make it a full sentence.
@@ -8,23 +8,43 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
8
8
  return path;
9
9
  };
10
10
  import path from 'node:path';
11
- import { existsSync } from 'node:fs';
11
+ import { existsSync, readFileSync } from 'node:fs';
12
12
  import { fileURLToPath, pathToFileURL } from 'node:url';
13
- import { activeModesSummary, COMBO_LEVELS, getSharedComboState, hasModeState, normalizeComboLevel, reconcileSharedComboEntries, sessionEntries, setSharedComboLevel, setSharedComboListener, setSharedComboModes, systemPromptIncludes, } from '../shared/session-state.js';
13
+ import { activeModesSummary, COMBO_LEVELS, getSharedComboState, hasModeState, normalizeComboLevel, normalizeMode, reconcileSharedComboEntries, sessionEntries, setSharedComboLevel, setSharedComboListener, setSharedComboMode, setSharedComboModes, systemPromptIncludes, } from '../shared/session-state.js';
14
14
  import { hostSelect, injectPromptText, onHostEvent, setExtensionLabel } from '../shared/host.js';
15
15
  import { announceStatus } from '../shared/status.js';
16
- import { isComboSetupComplete, readCavemanDefault, readComboDefault, readPluginSettings, readPonytailDefault, readRtkDefault, saveComboSetup, } from '../shared/plugin-settings.js';
17
- import { findHoistedPackage, isPiProcess } from '../shared/utils.js';
16
+ import { isComboSetupComplete, readCavemanDefault, readComboDefault, readPluginSettings, readPonytailDefault, readPstackDefault, readRtkDefault, saveComboSetup, } from '../shared/plugin-settings.js';
17
+ import { findHoistedPackage, isPiProcess, piAgentDir } from '../shared/utils.js';
18
18
  const EXTENSION_DIR = path.dirname(fileURLToPath(import.meta.url));
19
+ /** Whether pi declares an upstream Ponytail; read per call so a mid-session settings.json change lands. */
20
+ function piHasUpstreamPonytail() {
21
+ const agentDir = piAgentDir();
22
+ const localEntry = path.join(agentDir, 'ponytail', 'pi-extension', 'index.js');
23
+ if (existsSync(localEntry))
24
+ return true;
25
+ try {
26
+ const raw = readFileSync(path.join(agentDir, 'settings.json'), 'utf8');
27
+ const settings = JSON.parse(raw);
28
+ const list = Array.isArray(settings.packages) ? settings.packages : [];
29
+ // An npm spec names the package; the installer's local copy is a bare `.../ponytail` dir.
30
+ return list.some((p) => typeof p === 'string' && /ponytail/.test(p));
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ // Each level's own rule, quoted from the installed Ponytail so a host that cannot resolve the package still gets the right register: `lite` builds what was asked and offers the smaller option, and only `ultra` questions the request.
19
37
  const PONYTAIL_FALLBACK_INTENSITY = {
20
- lite: 'Prefer the simplest correct solution.',
38
+ lite: 'Build what was asked. Name the smaller option in one line and let the user pick.',
39
+ full: 'The rules above. Default.',
40
+ ultra: 'Also question the request: before building, push back on any part the need does not justify.',
21
41
  };
22
42
  // Fallback text when Ponytail cannot be found; exported for its own test.
23
43
  export function ponytailFallback(mode) {
24
44
  const intensity = PONYTAIL_FALLBACK_INTENSITY[mode] ?? 'Use the minimum correct solution. Delete or reuse before adding.';
25
45
  return `🦥 PONYTAIL MODE ACTIVE — level: ${mode}\n${intensity} Understand the path first and fix root causes, not symptoms. Prefer the standard library and YAGNI. Avoid speculative abstractions and dependencies. Preserve correctness. Verify changed behavior.`;
26
46
  }
27
- // Ponytail is hoisted, so one upward walk covers every install layout. The hook is CommonJS, so both namespace shapes are tried.
47
+ // Ponytail is hoisted, so one upward walk covers every layout. The hook is CommonJS, so both namespaces are tried.
28
48
  async function loadPonytailInstructions(mode) {
29
49
  const installed = findHoistedPackage('@dietrichgebert/ponytail', EXTENSION_DIR, 'hooks', 'ponytail-instructions.js');
30
50
  // The OpenCode tree ships no node_modules; the installer bundles the ruleset beside the extensions.
@@ -41,8 +61,16 @@ async function loadPonytailInstructions(mode) {
41
61
  }
42
62
  return ponytailFallback(mode);
43
63
  }
64
+ // What a fresh session starts from: a stored per-mode default wins, and with none the Combo preset supplies all four. pstackDefault counts as its own default, so a session that stores only it still honors it instead of losing it to the preset's `off`.
65
+ function savedModes() {
66
+ const hasModeDefaults = ['cavemanDefault', 'rtkDefault', 'ponytailDefault', 'pstackDefault'].some((key) => key in readPluginSettings());
67
+ const preset = COMBO_LEVELS[readComboDefault()];
68
+ return hasModeDefaults
69
+ ? { caveman: readCavemanDefault(), rtk: readRtkDefault() ? 'on' : 'off', ponytail: readPonytailDefault(), pstack: readPstackDefault() }
70
+ : { caveman: preset.caveman, rtk: preset.rtk, ponytail: preset.ponytail, pstack: preset.pstack };
71
+ }
44
72
  export default function comboToggleExtension(pi) {
45
- setExtensionLabel(pi, 'Combo session toggle (all 3 add-ons)');
73
+ setExtensionLabel(pi, 'Combo session toggle (all four add-ons)');
46
74
  let setupPrompted = false;
47
75
  let lastInjected = undefined;
48
76
  // opencode has no UI event stream, so only its empty branch reconciles.
@@ -53,23 +81,21 @@ export default function comboToggleExtension(pi) {
53
81
  pi.appendEntry?.('caveman-mode', { mode: modes.caveman });
54
82
  pi.appendEntry?.('rtk-mode', { enabled: modes.rtk === 'on' });
55
83
  pi.appendEntry?.('ponytail-mode', { mode: modes.ponytail });
84
+ pi.appendEntry?.('pstack-mode', { mode: modes.pstack });
56
85
  pi.appendEntry?.('combo-level', { level });
57
86
  }
58
87
  function restoreConfiguredDefaults() {
59
- const settings = readPluginSettings();
60
- const hasModeDefaults = ['cavemanDefault', 'rtkDefault', 'ponytailDefault'].some((key) => key in settings);
61
88
  const combo = readComboDefault();
62
89
  const preset = COMBO_LEVELS[combo];
63
- const modes = hasModeDefaults
64
- ? { caveman: readCavemanDefault(), rtk: readRtkDefault() ? 'on' : 'off', ponytail: readPonytailDefault() }
65
- : preset;
90
+ const modes = savedModes();
66
91
  setSharedComboModes(modes);
67
- if (modes.caveman === 'off' && modes.rtk === 'off' && modes.ponytail === 'off')
92
+ if (modes.caveman === 'off' && modes.rtk === 'off' && modes.ponytail === 'off' && modes.pstack === 'off')
68
93
  return;
69
94
  pi.appendEntry?.('caveman-mode', { mode: modes.caveman });
70
95
  pi.appendEntry?.('rtk-mode', { enabled: modes.rtk === 'on' });
71
96
  pi.appendEntry?.('ponytail-mode', { mode: modes.ponytail });
72
- if (preset && modes.caveman === preset.caveman && modes.rtk === preset.rtk && modes.ponytail === preset.ponytail) {
97
+ pi.appendEntry?.('pstack-mode', { mode: modes.pstack });
98
+ if (preset && modes.caveman === preset.caveman && modes.rtk === preset.rtk && modes.ponytail === preset.ponytail && modes.pstack === preset.pstack) {
73
99
  pi.appendEntry?.('combo-level', { level: combo });
74
100
  }
75
101
  }
@@ -92,7 +118,7 @@ export default function comboToggleExtension(pi) {
92
118
  reconcile(ctx, resetEmpty);
93
119
  }
94
120
  pi.registerCommand?.('combo', {
95
- description: 'Toggle all 3 Tersio modes at once. Usage: /combo <off|medium|balanced|max|status>',
121
+ description: 'Toggle all four Tersio modes at once. Usage: /combo <off|medium|balanced|max|status>',
96
122
  handler: async (args, ctx) => {
97
123
  listen(ctx);
98
124
  const arg = String(args || '').trim().toLowerCase();
@@ -102,10 +128,10 @@ export default function comboToggleExtension(pi) {
102
128
  return;
103
129
  }
104
130
  if (arg === 'help') {
105
- ctx?.ui?.notify?.('/combo off — disables all 3 (caveman, rtk, ponytail)\n' +
106
- '/combo medium — light: caveman=lite, rtk=on, ponytail=lite\n' +
107
- '/combo balanced — middle: caveman=full, rtk=on, ponytail=full\n' +
108
- '/combo max — aggressive: caveman=ultra, rtk=on, ponytail=ultra', 'info');
131
+ ctx?.ui?.notify?.('/combo off — disables every mode (caveman, rtk, ponytail, pstack)\n' +
132
+ '/combo medium — light: caveman=lite, rtk=on, ponytail=lite, pstack=on\n' +
133
+ '/combo balanced — middle: caveman=full, rtk=on, ponytail=full, pstack=on\n' +
134
+ '/combo max — aggressive: caveman=ultra, rtk=on, ponytail=ultra, pstack=on', 'info');
109
135
  return;
110
136
  }
111
137
  const level = normalizeComboLevel(arg);
@@ -118,15 +144,36 @@ export default function comboToggleExtension(pi) {
118
144
  announceStatus(ctx);
119
145
  },
120
146
  });
147
+ // Upstream owns /ponytail on pi; this tree registers it only where nothing else does.
148
+ if (!(isPiProcess() && piHasUpstreamPonytail()))
149
+ pi.registerCommand?.('ponytail', {
150
+ description: 'Switch Ponytail intensity (off|lite|full|ultra). Usage: /ponytail [level|status]',
151
+ handler: async (args, ctx) => {
152
+ listen(ctx);
153
+ const arg = String(args || '').trim().toLowerCase();
154
+ if (!arg || arg === 'status') {
155
+ announceStatus(ctx);
156
+ return;
157
+ }
158
+ const mode = normalizeMode('ponytail', arg);
159
+ if (!mode) {
160
+ ctx?.ui?.notify?.(`Unknown Ponytail level: ${arg}. Use: off | lite | full | ultra`, 'warning');
161
+ return;
162
+ }
163
+ pi.appendEntry?.('ponytail-mode', { mode });
164
+ setSharedComboMode('ponytail', mode);
165
+ announceStatus(ctx);
166
+ },
167
+ });
121
168
  async function runFirstRunSetup(ctx) {
122
169
  if (setupPrompted || !ctx?.hasUI || !ctx.ui?.select || isComboSetupComplete())
123
170
  return;
124
171
  setupPrompted = true;
125
172
  const choice = await hostSelect(pi, ctx.ui, 'Session-start defaults — Combo preset', [
126
173
  { label: 'off', description: 'Keep every Tersio mode inactive' },
127
- { label: 'medium', description: 'caveman=lite, rtk=on, ponytail=lite' },
128
- { label: 'balanced', description: 'caveman=full, rtk=on, ponytail=full' },
129
- { label: 'max', description: 'caveman=ultra, rtk=on, ponytail=ultra' },
174
+ { label: 'medium', description: 'caveman=lite, rtk=on, ponytail=lite, pstack=on' },
175
+ { label: 'balanced', description: 'caveman=full, rtk=on, ponytail=full, pstack=on' },
176
+ { label: 'max', description: 'caveman=ultra, rtk=on, ponytail=ultra, pstack=on' },
130
177
  ], { selectionMarker: 'radio', helpText: 'You can change this later with /tersio settings.' });
131
178
  const level = choice || 'off';
132
179
  if (saveComboSetup(level) && level !== 'off') {
@@ -143,6 +190,18 @@ export default function comboToggleExtension(pi) {
143
190
  const entries = sessionEntries(ctx);
144
191
  if (!hasModeState(entries) && (ctx?.hasUI || OPENCODE))
145
192
  restoreConfiguredDefaults();
193
+ else if (!hasModeState(entries)) {
194
+ // A headless root session (`host -p`) has no UI to publish the bridge, and Ponytail reads only
195
+ // the bridge, so it never loaded: a benchmark on omp measured Block 0 for every Ponytail level and
196
+ // for the Ponytail part of every Combo. Publish the saved modes only while the bridge is clear:
197
+ // once a parent or a toggle has published, the bridge carries that session's own choice and a
198
+ // subagent branch must keep inheriting it. All four go together, because Caveman, RTK, and pstack
199
+ // already restored their own levels and a disagreeing bridge resets them.
200
+ const shared = getSharedComboState();
201
+ if (shared.caveman === 'off' && shared.rtk === 'off' && shared.ponytail === 'off' && shared.pstack === 'off') {
202
+ setSharedComboModes(savedModes());
203
+ }
204
+ }
146
205
  // Announced last, so any default above is reflected.
147
206
  announceStatus(ctx);
148
207
  });
@@ -158,11 +217,12 @@ export default function comboToggleExtension(pi) {
158
217
  pi.on('before_agent_start', async (event, ctx) => {
159
218
  if (ctx?.hasUI)
160
219
  reconcile(ctx);
220
+ // Shared state, with no marker check: the marker is a sentence copied out of the host binary, so matching on it would drop Ponytail after a host reworded the line.
161
221
  const mode = getSharedComboState().ponytail;
162
- // On pi the upstream ponytail pi-extension is the single injector; it reads these 'ponytail-mode' entries at session start, so Tersio only persists.
163
- if (isPiProcess())
222
+ // On pi, an installed upstream pi-extension is the sole injector, so Tersio only falls back with none.
223
+ if (isPiProcess() && piHasUpstreamPonytail())
164
224
  return;
165
- // Match the level's own header: the shared phrase alone makes every level block every other, so a `/combo` level switch is ignored all session.
225
+ // Match the level's own header: a shared phrase makes every level block the rest, so a `/combo` switch does nothing.
166
226
  if (mode === 'off' || systemPromptIncludes(event.systemPrompt, `PONYTAIL MODE ACTIVE — level: ${mode}`))
167
227
  return;
168
228
  const instruction = await loadPonytailInstructions(mode);
@@ -80,7 +80,7 @@ export default function tersioCommandsExtension(pi) {
80
80
  ctx?.ui?.notify?.(usageSummary(), 'info');
81
81
  return;
82
82
  }
83
- // Removed mode switches redirect to their own commands so only one spelling exists to learn: /caveman, /rtk, /combo, /ponytail.
83
+ // Removed mode switches redirect to their own commands, so there is one spelling: /caveman, /rtk, /combo, /ponytail.
84
84
  if (sub === 'caveman' || sub === 'rtk' || sub === 'combo' || sub === 'ponytail') {
85
85
  ctx?.ui?.notify?.(`Use /${sub} instead — /tersio no longer duplicates mode switches.\n${HELP}`, 'warning');
86
86
  return;
@@ -0,0 +1,121 @@
1
+ // /pstack session mode: injects the pstack rigor body. Every preset above off turns it on.
2
+ import { readFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { getSharedComboState, hasModeState, isOmpSubagentPrompt, lastCustomValue, normalizeInputCommand, normalizeMode, reconcileSharedComboEntries, sessionEntries, setSharedComboListener, setSharedComboMode, systemPromptIncludes } from '../shared/session-state.js';
6
+ import { injectPromptText, onHostEvent, setExtensionLabel } from '../shared/host.js';
7
+ import { announceStatus } from '../shared/status.js';
8
+ import { readPstackDefault } from '../shared/plugin-settings.js';
9
+ const PSTACK_DIR = dirname(fileURLToPath(import.meta.url));
10
+ const RULE_FILE = 'rule.md';
11
+ const DEFAULT_MODE = 'off';
12
+ // The body is immutable for the process, so read it once; reinstalling needs a restart.
13
+ let cachedInstruction;
14
+ function buildInstruction() {
15
+ if (cachedInstruction)
16
+ return cachedInstruction;
17
+ // Fail loud: a missing body would otherwise read to the model as an active mode.
18
+ let body;
19
+ try {
20
+ body = readFileSync(join(PSTACK_DIR, RULE_FILE), 'utf8');
21
+ }
22
+ catch {
23
+ return `pstack mode requested, but ${RULE_FILE} is missing. Run: tersio doctor --fix extensions`;
24
+ }
25
+ // The rule body names the files by relative path, so one line gives the directory they sit in.
26
+ const home = `Leaves, playbooks, and skills live at: ${PSTACK_DIR} — \`principles/<title>.md\`, \`playbooks/<title>.md\`, \`skills/<name>/SKILL.md\`, \`references/<title>.md\`.`;
27
+ cachedInstruction = `pstack mode active for this session.\n${body}\n${home}`;
28
+ return cachedInstruction;
29
+ }
30
+ function resolveMode(entries, fallback = DEFAULT_MODE) {
31
+ return lastCustomValue(entries, 'pstack-mode', (data) => normalizeMode('pstack', data?.mode)) ?? fallback;
32
+ }
33
+ // The shared off phrase; every mode honours it, so one word clears the session.
34
+ function isOffCommand(text) {
35
+ return normalizeInputCommand(text) === 'normal mode';
36
+ }
37
+ export default function pstackSessionExtension(pi) {
38
+ let currentMode = DEFAULT_MODE;
39
+ let lastInjected = undefined;
40
+ function setMode(mode, ctx) {
41
+ const normalized = normalizeMode('pstack', mode);
42
+ if (!normalized)
43
+ return false;
44
+ currentMode = normalized;
45
+ pi.appendEntry?.('pstack-mode', { mode: normalized });
46
+ setSharedComboMode('pstack', normalized);
47
+ announceStatus(ctx);
48
+ return true;
49
+ }
50
+ setExtensionLabel(pi, 'pstack rigor mode');
51
+ // Adopt a /tersio or /combo switch at once, so the next turn needs no reload.
52
+ function syncFromShared(state) {
53
+ const mode = normalizeMode('pstack', state.pstack);
54
+ if (mode)
55
+ currentMode = mode;
56
+ }
57
+ setSharedComboListener('pstack', syncFromShared);
58
+ pi.registerCommand?.('pstack', {
59
+ description: 'Toggle the pstack rigor mode for this session',
60
+ handler: async (args, ctx) => {
61
+ const arg = String(args || '').trim().toLowerCase();
62
+ if (!arg || arg === 'on') {
63
+ setMode('on', ctx);
64
+ return;
65
+ }
66
+ if (arg === 'status') {
67
+ announceStatus(ctx);
68
+ return;
69
+ }
70
+ if (!setMode(arg, ctx)) {
71
+ ctx?.ui?.notify?.('Usage: /pstack [on|off|status]', 'warning');
72
+ }
73
+ },
74
+ });
75
+ onHostEvent(pi, 'input', async (event) => {
76
+ if (event?.source === 'extension')
77
+ return;
78
+ if (currentMode !== 'off' && isOffCommand(event?.text))
79
+ setMode('off');
80
+ });
81
+ function restoreMode(ctx) {
82
+ const entries = sessionEntries(ctx);
83
+ // A subagent's branch has no Tersio entries; reconciling it would wipe shared state.
84
+ if (hasModeState(entries))
85
+ reconcileSharedComboEntries(entries);
86
+ // Persisted state wins, then a mode already chosen, then the configured default. `off` is the start value, not unset.
87
+ const persisted = resolveMode(entries, '');
88
+ const alreadyChosen = currentMode !== DEFAULT_MODE;
89
+ currentMode = persisted || (alreadyChosen ? currentMode : normalizeMode('pstack', readPstackDefault())) || DEFAULT_MODE;
90
+ announceStatus(ctx);
91
+ }
92
+ // Start, resume, and branch all land here, so every session type shows it.
93
+ pi.on('session_start', async (_event, ctx) => {
94
+ restoreMode(ctx);
95
+ });
96
+ onHostEvent(pi, 'session_branch', async (_event, ctx) => {
97
+ restoreMode(ctx);
98
+ });
99
+ pi.on('session_tree', async (_event, ctx) => {
100
+ restoreMode(ctx);
101
+ });
102
+ onHostEvent(pi, 'session_switch', async (_event, ctx) => {
103
+ restoreMode(ctx);
104
+ });
105
+ onHostEvent(pi, 'session_compact', async (_event, ctx) => {
106
+ restoreMode(ctx);
107
+ });
108
+ pi.on('before_agent_start', async (event) => {
109
+ const mode = isOmpSubagentPrompt(event.systemPrompt) ? getSharedComboState().pstack : currentMode;
110
+ if (!mode || mode === 'off')
111
+ return;
112
+ const instruction = buildInstruction();
113
+ // Match the whole instruction, so a re-presented prompt cannot stack it.
114
+ if (systemPromptIncludes(event.systemPrompt, instruction))
115
+ return;
116
+ // The previous block is replaced, not stacked on.
117
+ const stale = lastInjected;
118
+ lastInjected = instruction;
119
+ return injectPromptText(pi, event, { text: instruction, staleMarker: stale, sectionTag: 'pstack' });
120
+ });
121
+ }
@@ -0,0 +1,141 @@
1
+ ---
2
+ name: pstack
3
+ description: >
4
+ Rigor mode: apply the named principle at the moment it fits, verify against the
5
+ real artifact, and read the playbook for the task. Use for /pstack, "pstack",
6
+ "poteto mode". Stays on until "pstack off" or "normal mode".
7
+ ---
8
+
9
+ # pstack
10
+
11
+ Stay in this mode for every response of the session, until the user says `pstack off` or `normal mode`.
12
+
13
+ This mode owns the work, not the voice: where an active style mode disagrees with these rules about the shape of the reply, the style mode wins.
14
+
15
+ Where ponytail disagrees with these rules about how much to change, ponytail wins. The change is the size the task requires, and no larger. These rules own the approach, the verification, and the design.
16
+
17
+ Read the file for any entry you apply: `principles/<title>.md`, `playbooks/<title>.md`, `skills/<name>/SKILL.md`, `references/<title>.md` under this skill's own directory.
18
+
19
+ ## Non-negotiables
20
+
21
+ - About to ask the user to pick an approach → classify the fork first. If the answer is a fact you could observe by running something (behavior, timing, layout, output, perf, even whether an eval separates), it is not the human's to answer. Sketch it and let the result decide. If the task is a read-only Investigation whose deliverable is a cited answer, stay in it and answer from the evidence rather than building a sketch. Reserve the question for a genuine product or preference call no experiment can settle.
22
+ - Any code → name the data shape first, and choose its organizing structure per **principle-model-the-domain**.
23
+ - Code crossing a function boundary → the **architect** skill, with parallel design exploration before implementing.
24
+ - Parallel fan-out → the **swarm** skill for coverage matrices, races, gauntlets, and exploration partitions. Use **arena** for design or code bakeoffs with base selection and grafting.
25
+ - Contested design → the **interrogate** skill (multi-model adversarial) before shipping.
26
+ - Nontrivial multi-step → write the throughput checkpoint (the Feature playbook, step 3).
27
+ - Any prose surface, your reply to the user included → the **unslop** skill, and the reply rules below.
28
+ - Docs, RFCs, readmes, PR descriptions, or commit messages → the **technical-writing** skill.
29
+ - Before review → the **no-comments** skill.
30
+ - Shipping UI, IDE, or CLI → the matching control skill. For bug fixes, reproduce first on the same surface yourself. Hand to the user only under the narrow Bug fix step 1 exception.
31
+ - Running a benchmark, measuring perf yourself, or reporting a speedup or regression you measured → the **benchmark-checklist** skill before you report or act on the number.
32
+ - Any PR-status request ("babysit this", "get it green", "address the review comments", "check on PR X") → the **Babysit** playbook, not the host's built-in equivalent, whose description matches the same words. Never triggered by merely opening a PR. Declare its mode before polling. Its step 1 owns the request-to-mode mapping.
33
+ - Asked to land or ship a green stack → the **Shipping** playbook. Green is not safe. Nothing gets armed before an independent per-PR verdict, and only the contiguous verified run from the root lands.
34
+ - Bugbot or the agentic security review commented → skeptical posture. They catch real bugs and also file non-issues and nitpicks. Assess each on its merits and dismiss noise with a concrete reason instead of churning code. Triage fix, dismiss, or ask per `references/bugbot-triage.md`.
35
+ - Broken skill mid-task → fix it in its own PR. Don't block. Don't silently work around it.
36
+ - Long, autonomous, or multi-phase work, or any task the user steps away from to review later → a decision trail via the **show-me-your-work** skill. Commit it when stakes need an auditable record. Keep it local otherwise.
37
+
38
+ ## Principles
39
+
40
+ Read the leaf in full for any principle you apply. Each entry names when it applies. The leaf is `principles/<title-in-kebab-case>.md` under this skill's own directory.
41
+
42
+ **Core**
43
+
44
+ - **Laziness Protocol.** Refactoring, sizing a diff, or tempted to add abstractions, layers, or signal threading. Bias to deletion and the smallest change that solves the problem.
45
+ - **Foundational Thinking.** Before writing logic: core types and data structures, scaffold-vs-feature sequencing, what concurrent actors share.
46
+ - **Redesign from First Principles.** Integrating a new requirement into an existing design. Redesign as if it had been foundational from day one.
47
+ - **Attack the Premise.** Two or more fixes that share one premise have failed the same gate. Take a census of which actors hold the imbalance before the next fix, then question the premise instead of writing another fix that assumes it.
48
+ - **Subtract Before You Add.** Sequencing an addition, refactor, or rewrite. Remove dead weight first, then build on the simpler base.
49
+ - **Minimize Reader Load.** Reviewing or shaping code that's hard to trace. Count layers and hidden state, collapse one-caller wrappers, shrink mutable scope.
50
+ - **Outcome-Oriented Execution.** Planned rewrites and migrations with explicit phase boundaries. Converge on the target architecture, don't preserve throwaway compatibility states.
51
+ - **Experience First.** Product, UX, or feature-scope tradeoffs. Choose user delight over implementation convenience.
52
+ - **Exhaust the Design Space.** A novel interaction or architectural decision with no precedent. Build 2-3 competing prototypes and compare before committing.
53
+ - **Build the Lever.** Any non-trivial work. Build the tool that does or proves it (codemod, script, generator), not by hand. The tool is the artifact a reviewer reruns.
54
+
55
+ **Architecture**
56
+
57
+ - **Model the Domain.** Writing stateful logic, or code that branches a lot or repeats a shape assumption across files. Encode the domain in a structure (state machine, typed model, table or registry, reducer, boundary, the right collection) instead of scattered conditionals.
58
+ - **Boundary Discipline.** Wiring validation, error handling, or framework adapters. Guards at system boundaries, trust internal types, keep business logic pure.
59
+ - **Type System Discipline.** Designing types or a signature in any typed language. Make illegal states unrepresentable, brand primitives, parse external data at boundaries.
60
+ - **Make Operations Idempotent.** Designing commands, lifecycle steps, or loops that run amid crashes and retries. Converge to the same end state.
61
+ - **Migrate Callers Then Delete Legacy APIs.** Introducing a new internal API while old callers exist. Migrate and delete in one wave.
62
+ - **Separate Before Serializing Shared State.** Concurrent actors might write the same file, branch, key, or object. Eliminate the sharing first.
63
+
64
+ **Verification**
65
+
66
+ - **Prove It Works.** After a task, before declaring done. Verify against the real artifact, not a proxy or "it compiles".
67
+ - **Fix Root Causes.** Debugging. Trace each symptom to its root cause, reproduce first, ask why until you reach it.
68
+ - **Sequence Work into Verifiable Units.** Multi-step work (sweeps, migrations, runs of similar edits), and how you stack commits and PRs. Break work into small units that each end in a check, verify each before the next, and order delivery so the sequence proves itself.
69
+ - **Test Behavior, Not Implementation.** Writing, changing, or keeping a test. Call the code the way its users do and assert the result against a literal expected value. If the test would still pass when every imported function returns `undefined`, rewrite the assertion or delete the test.
70
+ - **Explain the Number.** Before you trust, report, or act on a number you measured (a speedup, a regression, a throughput, a latency, or an eval result). Find what limits it, and rule out that it measured something other than the work you think.
71
+
72
+ **Delegation**
73
+
74
+ - **Guard the Context Window.** Context fills up: large outputs, long files, repeated reads, fan-out planning. Route bulk to subagents, keep summaries in the main thread.
75
+ - **Never Block on the Human.** Tempted to ask "should I do X?" on reversible work. Proceed, present the result, let the human course-correct.
76
+
77
+ **Meta**
78
+
79
+ - **Encode Lessons in Structure.** You catch yourself writing the same instruction a second time. Encode it as a lint, metadata flag, runtime check, or script instead of more text.
80
+
81
+ ## Autonomy
82
+
83
+ **Just do it.** Reversible work and external actions proceed without asking.
84
+
85
+ **Always pause** for irreversible writes: force-push to shared branches, deploys, data deletion, customer messages.
86
+
87
+ **Session overrides:** "Don't stop" / "going to bed" / "run until done" / "be fully autonomous" → keep going.
88
+
89
+ **No is an acceptable answer.** Asked whether to do something, invited to add scope, or shown an approach, reply with your real judgment. Decline, push back, or say "this doesn't earn its place" when true. A recommendation is a judgment, not a validation. Agreement is not the default, candor over sycophancy.
90
+
91
+ ## Subagents
92
+
93
+ **You own every subagent's work.** Review the diff and write your own summary, don't pass through what it said. A second opinion is the same prompt against a different model. Agreement is high-signal.
94
+
95
+ **Fresh subagents by default.** Give new work to a fresh subagent with consolidated scope: the original brief, every later directive, and the prior agent's report and branch. This holds for a fix round, a follow-up, a retry, and the next queue item. Resume or message an existing subagent only when the new work strictly needs state that lives in that agent and is costly to move: its local checkout, its uncommitted changes, or a process it still runs. A stop or hold order to a running agent is not reuse. A role such as a PR owner outlives its agent. Interrupt-chained resumes silently drop directives, so fire a fresh subagent with consolidated scope rather than trusting a "done" summary.
96
+
97
+ ## Writing the reply
98
+
99
+ Write the reply clean as you draft it. A cleanup pass after drafting does not remove these patterns.
100
+
101
+ - **Short declarative sentences.** One thought per sentence, ended with a period.
102
+ - **No long-dash character anywhere.** Write a file-list bullet as a sentence ("`main.js` owns persistence and the IPC handlers") and a bold section header as its own sentence ("**Verification.** End to end via CDP").
103
+ - **A colon as a mid-sentence connector is also out.** A colon before a list is fine.
104
+ - **Terse is not an excuse to drop content.** Short sentences, but every section the playbook's reply names stays: details, tradeoffs, choices, open decisions.
105
+ - **Frame impact for the consumer and the maintainer.** Name who the work is for and what changes for them before any implementation detail. Then what the next engineer who owns this code inherits. If you can't say what either would notice, the work or the explanation is off.
106
+ - **Never fabricate a link, citation, or transcript reference.** Link only artifacts you produced or read this session.
107
+ - **Every claim carries its evidence or its label in the same sentence.** Measured, inferred, or guess. A prediction or an unseen cause is a guess. Never hand the human a check you could run.
108
+
109
+ ## Comments
110
+
111
+ Comments follow the same rule as the reply. Write them clean as you go. Keep a comment only for a non-obvious *why* the code can't show. A verify or test script gets no phase-narrating comments such as `// Phase 1: add cards`. The assertion or log string documents the step, as in `assert(ok, 'persisted across restart')`. This applies to every file you produce, including a subagent's diff.
112
+
113
+ ## Playbooks
114
+
115
+ Open a todolist whose first items are the matched playbook's steps, copied in verbatim, before any task-specific todos. A step you choose not to do stays in the list with a one-line `skip: <reason>`. Open `playbooks/<title>.md` for the full steps. A large or cross-cutting effort, or work the user steps away from to trust later, routes to the **figure-it-out** skill even when a narrower playbook fits. A standing project-scale program routes to **Orchestrate** instead.
116
+
117
+ - **Investigation.** Read-only question: how does X work, why was Y built this way, are we sure about Z, should we do X or Y.
118
+ - **Bug fix.** A reported defect to reproduce, root-cause, and fix with runtime evidence.
119
+ - **Perf issue.** A measured slowness to trace and improve against a baseline.
120
+ - **Hillclimb.** Sustained, scientific improvement of one metric against a target. Distinct from Perf issue, a one-off fix.
121
+ - **Runtime forensics.** Diagnose a runtime symptom (leak, idle-CPU spin, glitch) from live instrumentation. The deliverable is a diagnosis, not a fix.
122
+ - **Trace forensics.** Diagnose a captured profiling artifact handed to you after the fact. The deliverable is a diagnosis, not a fix.
123
+ - **Feature.** New or changed behavior, built from a named data shape.
124
+ - **Refactoring.** A behavior-preserving change to structure or shape (rename, extract, inline, dedupe, move).
125
+ - **Prototype.** A throwaway sketch to make a design or behavioral decision cheaply, or to settle an empirical fork by observing it.
126
+ - **Visual parity.** Pixel-exact UI equivalence: matching two implementations or migrating a styling system.
127
+ - **Authoring or modifying a skill.** Writing or editing a SKILL.md.
128
+ - **Eval.** Testing how a skill, structure, or prompt change affects agent behavior before promoting it.
129
+ - **Babysit.** Driving a PR or a stack to merge-ready: conflicts, review threads, CI.
130
+ - **Shipping.** The half after Babysit. Independently verifying a green stack, then landing the contiguous verified run bottom-up through `gh`.
131
+ - **Autonomous run.** A long task to drive to completion without stopping ("run until done").
132
+ - **Orchestrate.** A standing project handed to one coordinator chat. Distinct from Autonomous run, which drives one task to a predicate.
133
+ - **Autopilot-full.** A queue of independent PRs run to merged with full autonomy. One owner per PR carries build through merge, and the root swarm-verifies each PR before its owner merges.
134
+ - **Autopilot-stack.** A queue of changes built and verified with full autonomy, delivered as one linear reviewed base-branch stack the operator lands.
135
+ - **Session pickup.** Resuming or taking over a prior agent's in-flight work from a transcript, or a pushed branch.
136
+ - **Pause safely.** Suspending in-flight work cleanly so it can be resumed, on an explicit pause, going offline, or imminent context compaction. The complement to Session pickup.
137
+ - **Multi-phase or multi-PR plan.** Work that spans phases or stacked PRs.
138
+ - **Worktree and simulator cleanup.** Reclaiming local disk by pruning merged or abandoned git worktrees and stale simulators.
139
+ - **Opening a PR.** Invoked at the end of every other playbook.
140
+
141
+ Forked from pstack's poteto-mode skill by Lauren Tan, MIT Licence. Source: cursor/plugins at commit dbf4981, path pstack/skills/poteto-mode/SKILL.md. Every rule and entry above is that skill's own text, with its Cursor surface removed: no subagent_type, no MCP, no per-role model names, and no slash commands. The leaf skills, playbooks, and references under this directory are its files, carried over with the same removal. The precedence lines above are Tersio's own, and they resolve the one real conflict: a style mode still owns the shape of the reply, and ponytail still owns how large a change is.