acstack 0.0.0-stage → 0.47.1

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 (143) hide show
  1. package/.claude-plugin/plugin.json +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +389 -2
  4. package/THIRD_PARTY_NOTICES +14 -0
  5. package/TROUBLESHOOTING.md +225 -0
  6. package/agents/codex/frontend-verifier.toml +352 -0
  7. package/agents/codex/task-checker.toml +345 -0
  8. package/agents/codex/task-executor.toml +157 -0
  9. package/agents/codex/test-writer.toml +149 -0
  10. package/agents/frontend-verifier.md +351 -0
  11. package/agents/task-checker.md +344 -0
  12. package/agents/task-executor.md +156 -0
  13. package/agents/test-writer.md +148 -0
  14. package/assets/playwriter-bridge/build-launcher.ps1 +32 -0
  15. package/assets/playwriter-bridge/doctor.ps1 +450 -0
  16. package/assets/playwriter-bridge/launcher-src.cs +131 -0
  17. package/assets/playwriter-bridge/opener.js +330 -0
  18. package/assets/playwriter-bridge/opener.ps1 +63 -0
  19. package/assets/playwriter-bridge/register-tasks.ps1 +328 -0
  20. package/assets/playwriter-bridge/relay.ps1 +50 -0
  21. package/assets/playwriter-bridge/stop.ps1 +125 -0
  22. package/assets/playwriter-bridge/sync.ps1 +271 -0
  23. package/assets/playwriter-bridge/tunnel.ps1 +325 -0
  24. package/assets/playwriter-bridge/vm-free-port.sh +166 -0
  25. package/assets/terminal-workspace/client-keybindings.md +87 -0
  26. package/assets/terminal-workspace/config.example.yaml +334 -0
  27. package/assets/terminal-workspace/setup.sh +4404 -0
  28. package/cli/README.md +47 -0
  29. package/cli/bin/acstack.js +3 -0
  30. package/cli/dist/index.js +25984 -0
  31. package/cli/dist/index.js.map +7 -0
  32. package/cli/package.json +59 -0
  33. package/docs/adr/0001-ste-writing-standard.md +16 -0
  34. package/docs/adr/0002-version-gate-not-auto-bump.md +35 -0
  35. package/docs/adr/0003-handoff-ack-command.md +19 -0
  36. package/docs/adr/0004-dev-setup-per-host.md +13 -0
  37. package/docs/adr/0005-two-orchestrators-per-host.md +25 -0
  38. package/docs/adr/0006-document-opener-service.md +89 -0
  39. package/docs/adr/0007-lead-check-reads-the-transcript.md +87 -0
  40. package/docs/adr/0008-cli-audits-skill-interviews.md +37 -0
  41. package/docs/adr/0009-verify-the-write-not-the-writer.md +51 -0
  42. package/docs/adr/0010-promote-dev-to-main-by-fast-forward.md +115 -0
  43. package/docs/adr/0011-node-header-is-the-edge-encoding.md +20 -0
  44. package/docs/adr/0012-node-kind-is-a-closed-set-of-five.md +31 -0
  45. package/docs/adr/0013-the-diagram-renderer-is-pure.md +23 -0
  46. package/docs/adr/0014-reading-a-node-hides-its-generated-diagram.md +29 -0
  47. package/docs/adr/0015-a-node-id-links-to-its-issue-through-an-anchor.md +37 -0
  48. package/docs/adr/0016-the-map-root-carries-no-status-of-its-own.md +21 -0
  49. package/docs/adr/0017-call-impeccable-copy-only-its-questions.md +13 -0
  50. package/docs/adr/index.md +17 -0
  51. package/docs/config-reference.md +572 -0
  52. package/docs/dev-setups.md +164 -0
  53. package/docs/migrate-0.8.md +28 -0
  54. package/docs/playwriter-bridge-windows.md +15 -0
  55. package/docs/terminal-workspace-keys.md +137 -0
  56. package/docs/terminal-workspace.md +1780 -0
  57. package/docs/workflows.md +309 -0
  58. package/hooks/ac-writing-style-reminder.sh +86 -0
  59. package/hooks/context-pressure.sh +583 -0
  60. package/hooks/hooks.json +50 -0
  61. package/hooks/session-start-handoff.sh +165 -0
  62. package/hooks/session-start.sh +214 -0
  63. package/orchestrator/AGENTS.md +532 -0
  64. package/output-styles/ac-writing-style.md +286 -0
  65. package/package.json +50 -4
  66. package/pi/agents/frontend-verifier.md +357 -0
  67. package/pi/agents/task-checker.md +348 -0
  68. package/pi/agents/task-executor.md +160 -0
  69. package/pi/agents/test-writer.md +154 -0
  70. package/pi/extension.ts +723 -0
  71. package/profiles/fullstack-python.yaml +29 -0
  72. package/profiles/node-typescript.yaml +23 -0
  73. package/profiles/python.yaml +24 -0
  74. package/skills/archive/SKILL.md +160 -0
  75. package/skills/bootstrap/SKILL.md +109 -0
  76. package/skills/bridge/HANDOFF.md +93 -0
  77. package/skills/bridge/SKILL-VM.md +292 -0
  78. package/skills/bridge/SKILL-WINDOWS.md +526 -0
  79. package/skills/bridge/SKILL.md +121 -0
  80. package/skills/browser-verify/SKILL.md +229 -0
  81. package/skills/code-review/SKILL.md +44 -0
  82. package/skills/commit/SKILL.md +106 -0
  83. package/skills/compact-and-continue/SKILL.md +241 -0
  84. package/skills/explore/SKILL.md +149 -0
  85. package/skills/grilling/SKILL.md +134 -0
  86. package/skills/handoff/SKILL.md +250 -0
  87. package/skills/handoff/launch-herdr.md +197 -0
  88. package/skills/handoff/launch-without-herdr.md +30 -0
  89. package/skills/handoff/lead-check.md +59 -0
  90. package/skills/handoff/outcomes.md +162 -0
  91. package/skills/handoff/running-agent.md +50 -0
  92. package/skills/handoff/watch.md +115 -0
  93. package/skills/host/SKILL.md +247 -0
  94. package/skills/host/detect-host.sh +297 -0
  95. package/skills/host/herdr.md +79 -0
  96. package/skills/host/install-herdr-block.sh +467 -0
  97. package/skills/host/install-orca.sh +512 -0
  98. package/skills/host/notes.md +97 -0
  99. package/skills/host/orca.md +160 -0
  100. package/skills/host/questions.md +163 -0
  101. package/skills/host/report.md +42 -0
  102. package/skills/implement/SKILL.md +230 -0
  103. package/skills/implement/decision-log.md +62 -0
  104. package/skills/implement/design-pass.md +32 -0
  105. package/skills/implement/relaxed-tdd.md +28 -0
  106. package/skills/map/SKILL.md +250 -0
  107. package/skills/map/frontend.md +227 -0
  108. package/skills/map/trackers/files.md +74 -0
  109. package/skills/map/trackers/github.md +180 -0
  110. package/skills/map/visuals.md +387 -0
  111. package/skills/new-worktree/SKILL.md +155 -0
  112. package/skills/new-worktree/detect-orchestrator.sh +328 -0
  113. package/skills/new-worktree/detect-orchestrator.test.sh +894 -0
  114. package/skills/new-worktree/herdr.md +84 -0
  115. package/skills/new-worktree/orca.md +101 -0
  116. package/skills/pre-commit-review/SKILL.md +242 -0
  117. package/skills/pre-commit-review/auto-fix.md +19 -0
  118. package/skills/pre-commit-review/interactive.md +35 -0
  119. package/skills/quick-fix/SKILL.md +125 -0
  120. package/skills/record-context/SKILL.md +106 -0
  121. package/skills/setup/SKILL.md +250 -0
  122. package/skills/setup/browser.md +123 -0
  123. package/skills/setup/design-review.md +97 -0
  124. package/skills/setup/first-run.md +114 -0
  125. package/skills/setup/report.md +68 -0
  126. package/skills/setup/row-fixes.md +196 -0
  127. package/skills/setup/terminal-workspace.md +153 -0
  128. package/skills/sync/SKILL.md +171 -0
  129. package/skills/teardown-worktree/SKILL.md +245 -0
  130. package/skills/teardown-worktree/detector.md +39 -0
  131. package/skills/teardown-worktree/herdr.md +113 -0
  132. package/skills/teardown-worktree/orca.md +61 -0
  133. package/skills/terminal-workspace/SKILL.md +249 -0
  134. package/skills/terminal-workspace/components.md +36 -0
  135. package/skills/terminal-workspace/config-choices.md +69 -0
  136. package/skills/terminal-workspace/emulator-keys.md +48 -0
  137. package/skills/terminal-workspace/headless-clipboard.md +175 -0
  138. package/skills/terminal-workspace/turn-off-and-update.md +104 -0
  139. package/skills/test-conventions/SKILL.md +59 -0
  140. package/skills/visual-docs/SKILL.md +246 -0
  141. package/skills/writing/SKILL.md +231 -0
  142. package/skills/writing/examples.md +153 -0
  143. package/skills/writing/vocabulary.md +96 -0
@@ -0,0 +1,104 @@
1
+ # Turn off and update
2
+
3
+ `SKILL.md` decides when to read this file: when the user asks to turn a component off or uninstall, or `outdated` reports something.
4
+
5
+ ## 8. Turning one component off, or all of them
6
+
7
+ *`disable` undoes one component. `uninstall` undoes the managed config. harlequin is the one binary either of them removes.*
8
+
9
+ ```bash
10
+ bash "$SETUP" disable herdr # or delta, diffnav, gh_dash, harlequin, lazygit, neovim, pi, tuicr
11
+ ```
12
+
13
+ `disable` takes those nine components and no others. For `diffnav`, `gh_dash`,
14
+ `harlequin`, `lazygit` and `tuicr` it writes `<component>.enabled: false` into
15
+ the config itself, then rebuilds the herdr keymap so the rest of it survives.
16
+
17
+ For `herdr`, `delta`, `neovim` and `pi` it does not. Set `<component>.enabled: false`
18
+ yourself after those four, or the next `apply` restores them.
19
+
20
+ `neovim` is the one whose undo is a deletion. The component writes a whole file
21
+ of ACStack's own, so `disable` removes `~/.config/nvim/lua/plugins/acstack.lua`
22
+ and leaves the rest of the user's neovim config alone. Neither `disable` nor
23
+ `uninstall` touches a `acstack.lua` the user wrote by hand.
24
+
25
+ `pi` undoes only what `apply` added, because pi's config is the user's:
26
+
27
+ - It removes the pi packages `apply` installed, and keeps any the user installed first
28
+ - It releases the four settings and `toolActivation`, unless the user has changed one since
29
+ - A value `apply` replaced goes back to what the user had, and a key `apply` added goes
30
+ - It puts back an ACStack pin `apply` moved forward, unless the user has moved it since
31
+ - It removes the delegation block from pi's context file, and the user's text stays byte for byte
32
+ - It removes agentic-retro's extension only when `apply` was the one to write it
33
+ - It keeps the pi binary, its logins and its sessions
34
+ - It touches nothing in a `settings.json` that does not parse, and says so
35
+ - It records what it added in `~/.config/acstack/terminal-workspace.pi.json`
36
+
37
+ `yazi`, `markdown` and `remote` have no `disable` path. `disable` refuses for
38
+ those three and names the edit that turns one off. Set the component's
39
+ `enabled` key to `false` in the config, then run `apply` again.
40
+
41
+ ```bash
42
+ bash "$SETUP" uninstall
43
+ ```
44
+
45
+ `uninstall` removes everything `apply` wrote. It strips the managed blocks from
46
+ the herdr, tuicr and yazi configs. It unsets delta as the git pager.
47
+
48
+ It deletes the helper scripts, the `xclip` stand-in, the neovim plugin file, and
49
+ the keybindings it wrote into gh-dash. It runs `disable pi`. The user's own
50
+ settings around them survive, and every binary stays except harlequin, which uv
51
+ owns whole rather than as one file in `$BIN`.
52
+
53
+ pi stays too. It holds the user's logins and sessions, and the user may run it
54
+ without ACStack. `uninstall` prints the npm command that removes it.
55
+
56
+ ## 9. Keeping it current
57
+
58
+ *`outdated` reports what has moved on. `upgrade` fetches it.*
59
+
60
+ ```bash
61
+ bash "$SETUP" outdated
62
+ ```
63
+
64
+ It prints one finding per line, tab-separated as kind, name and detail, and
65
+ answers in its exit code:
66
+
67
+ | Exit | Meaning | What to do |
68
+ |---|---|---|
69
+ | 0 | Nothing to do | Say nothing |
70
+ | 1 | Something is missing, new or stale | Show the findings and offer `upgrade` |
71
+ | 2 | It cannot tell | Name the reason once and move on |
72
+
73
+ Four kinds of finding:
74
+
75
+ - `missing` – this machine has never applied the workspace, so run section 4 of `SKILL.md` rather than `upgrade`
76
+ - `new` – a component this plugin version ships that the user's last `apply` never saw
77
+ - `stale` – an installed tool behind its published release
78
+ - `unknown` – the script cannot compare, so there is nothing to act on
79
+
80
+ ```bash
81
+ bash "$SETUP" upgrade # everything reported stale
82
+ bash "$SETUP" upgrade yazi delta # only these
83
+ ```
84
+
85
+ pi adds four rows of its own:
86
+
87
+ - `pi`, `pi-subagents` and `pi-compact-tools` compare against npm, and `upgrade` runs `pi update` for each
88
+ - A package the user pinned, such as `npm:pi-subagents@1.0.0`, reports `unknown`, because `pi update` never moves it
89
+ - `pi-acstack` compares ACStack's pin in pi against this plugin's version, with no network at all
90
+ - `upgrade pi-acstack` moves the pin forward, and so does `apply`
91
+ - Neither moves a pin newer than this plugin, because the user chose it
92
+ - Neither installs ACStack where it is absent or unpinned
93
+
94
+ `upgrade` reinstalls each stale binary and appends any new component's config
95
+ block to the user's file, comments intact. The three tools that update
96
+ themselves go through `herdr update`, `gh extension upgrade dlvhdr/gh-dash`,
97
+ and `uv tool upgrade harlequin`. Run `apply` afterwards to install what the new
98
+ block turned on.
99
+
100
+ Naming a tool skips the version comparison, which is the only way to refresh
101
+ `mermaid-ascii`. It has no version flag, so nothing can read the installed version.
102
+
103
+ `outdated` reads herdr's stable release manifest, so a user on the preview
104
+ channel sees a `stale` row for herdr that is not one.
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: test-conventions
3
+ description: Test placement rules and framework conventions. Invoke before writing ANY test. Provides file location decision tree, naming conventions, and layer guidance (unit, integration, E2E). Triggers on writing new tests, creating test files, or test-writer agent starting work.
4
+ ---
5
+
6
+ # Test Conventions
7
+
8
+ ## Decision Tree: Where Does My Test Go?
9
+
10
+ Read `acstack/project.yaml` for `directories.source`, `directories.tests`, and `frontend` config.
11
+
12
+ ```
13
+ Backend code? → <tests-dir>/<mirror-source-path>/test_<module>.py
14
+ Frontend component/hook? → <frontend-dir>/src/<path>/__tests__/<Name>.test.tsx
15
+ Browser-based user flow? → <frontend-dir>/tests/<feature>.spec.ts
16
+ Visual regression? → <frontend-dir>/tests/visual-regression.spec.ts
17
+ ```
18
+
19
+ ## Layer 1: Backend Unit Tests
20
+
21
+ Mirror the source directory structure. Example: `src/auth/sessions.py` → `tests/auth/test_sessions.py`.
22
+
23
+ - Create `__init__.py` in new subdirectories (Python)
24
+ - Cross-cutting integration tests → `<tests-dir>/integration/`
25
+ - Shared fixtures → `<tests-dir>/conftest.py` (Python) or shared setup files
26
+ - Use markers for slow/integration tests (configured in `test_markers.exclude`)
27
+ - Run with the `commands.test` command from project.yaml
28
+ - Baseline: `.test-baseline` – count must never drop
29
+
30
+ ## Layer 2: Frontend Unit Tests
31
+
32
+ Colocated with source. Example: `src/hooks/useAuth.ts` → `src/hooks/__tests__/useAuth.test.ts`.
33
+
34
+ - Components: `.test.tsx`, pure functions: `.test.ts`
35
+ - Run with `frontend.commands.test` from project.yaml
36
+
37
+ ## Layer 3: E2E Tests (Browser)
38
+
39
+ One file per feature or user flow. Example: `tests/login-flow.spec.ts`.
40
+
41
+ - Auth setup: save auth state to a storage file, reuse across tests
42
+ - Credentials: use environment variables (gitignored `.env.test`)
43
+ - Agent/async tests: use generous timeouts, take screenshots at key steps
44
+ - Run with `agent-browser` CLI or the project's configured E2E test command
45
+
46
+ ## Naming Conventions
47
+
48
+ | Type | Pattern | Example |
49
+ |------|---------|---------|
50
+ | Python test file | `test_<module>.py` | `test_sessions.py` |
51
+ | Python test function | `test_<behavior>` | `test_expired_token_returns_401` |
52
+ | JS/TS test file | `<Name>.test.ts(x)` | `useAuth.test.ts` |
53
+ | E2E spec | `<feature>.spec.ts` | `login-flow.spec.ts` |
54
+
55
+ ## Gitignored Artifacts (never commit)
56
+
57
+ - Browser test artifacts, test results, reports
58
+ - Coverage output
59
+ - Test environment files (`.env.test`)
@@ -0,0 +1,246 @@
1
+ ---
2
+ name: visual-docs
3
+ description: "Write or restructure documentation that leads with a diagram and derives its structure from it. Use whenever the user asks for docs, a README, an architecture or workflow write-up, an explainer, or says existing docs are hard to follow, confusing, or a wall of text – and whenever you are about to write more than two paragraphs explaining how something works. Applies the Minto pyramid: answer first, then support."
4
+ ---
5
+
6
+ # visual-docs
7
+
8
+ *A reader should see the system's shape from one diagram. They then find every detail in a section that maps to a part of it.*
9
+
10
+ This skill makes a doc lead with a diagram, then derive its sections from that diagram.
11
+
12
+ - **Most technical docs explain in reading order rather than importance order**
13
+ - The reader builds the picture themselves and learns what mattered last
14
+ - **One diagram carries the whole shape**
15
+ - **Every section maps to a part of that diagram**
16
+ - **The prose rules live in the `writing` skill**
17
+ - This skill owns shape alone
18
+
19
+ This skill owns document shape. Prose follows the `writing` skill.
20
+
21
+ ```mermaid
22
+ flowchart TD
23
+ A["Establish the shape<br/>(read code, not existing docs)"] --> B["Draw the lead diagram<br/>(section 4)"]
24
+ B --> C["Derive sections from nodes<br/>(section 1)"]
25
+ C --> D["Write the opening<br/>(section 2.1)"]
26
+ D --> E["Fill sections in bullets<br/>(sections 2.2 and 3)"]
27
+ E --> F{"Siblings MECE?<br/>(section 2.3)"}
28
+ F -->|no| C
29
+ F -->|yes| G["Check every node has a section<br/>(section 6)"]
30
+ G --> H["Verify the diagram renders"]
31
+ ```
32
+
33
+ | Step in the diagram | Detail |
34
+ | ------------------------ | --------------- |
35
+ | Derive sections | section 1 |
36
+ | Opening, vertical, MECE | section 2 |
37
+ | Bullets carry the body | section 3 |
38
+ | Draw and label | section 4 |
39
+ | Headings and duplication | section 5 |
40
+ | Full order of operations | section 6 |
41
+ | What to avoid | section 7 |
42
+
43
+ ## 1. The rule that makes this work
44
+
45
+ *The diagram is the table of contents. If a section has no home in the diagram, one of the two is wrong.*
46
+
47
+ Every numbered section maps to an element of the lead diagram, and a section heading reuses the diagram's node label verbatim. This is mechanical, not stylistic:
48
+
49
+ - A box showing something **happening**, with no section, means the doc is incomplete
50
+ - A section covering no part of the diagram either belongs in another doc, or the
51
+ diagram is missing something
52
+
53
+ - Renaming a box renames its section, and the reverse
54
+
55
+ Three exemptions, and only these three.
56
+
57
+ - **Start and end boxes** – a box for what comes in, or what remains after, is not a step and needs no section
58
+ - In a workflow diagram, the incoming request and the final stored output are both this
59
+ - **Two boxes, one command** – two boxes are sometimes worth drawing separately because they are two ideas, though one command does both
60
+ - Give them one section and name both in the heading
61
+ - The reader can tell it covers both
62
+ - **Sections about the document** – a section on what this doc leaves out, or what is about to change, is housekeeping for the reader
63
+ - It describes the document rather than the system
64
+ - No box should exist for it
65
+
66
+ **Start and end boxes.** A box for what comes in, or what remains after, is not
67
+ a step and needs no section. In a workflow diagram, the
68
+ incoming request and the final stored output are both this.
69
+
70
+ **Two boxes, one command.** Sometimes two boxes are worth drawing separately
71
+ because they are two ideas, but one command does both. Give them one section and
72
+ name both in the heading, so the reader can tell it covers both.
73
+
74
+ **Sections about the document.** A section on what this doc leaves out, or what is
75
+ about to change, is housekeeping for the reader. It describes the document, not the
76
+ system, so no box should exist for it.
77
+
78
+ - Anything else without a match is a defect in one of the two
79
+ - Do not add a section to justify a node, or a node to justify a section
80
+ - End the lead diagram with a mapping table when the doc has more than four sections
81
+ - The table lets the reader jump from a box to its detail
82
+
83
+ End the lead diagram with a mapping table when the doc has more than four sections. It lets the reader jump from a box to its detail.
84
+
85
+ ## 2. Minto pyramid
86
+
87
+ *Answer first. Every level summarises the level below it. Siblings are the same kind of thing, and they are complete.*
88
+
89
+ ### 2.1. Open with one sentence, then bullets
90
+
91
+ *Say what the thing is and who it is for in one sentence. Put everything else in bullets under it.*
92
+
93
+ The opening is never a paragraph. A reader meeting the doc for the first time scans it. A four-sentence block of setup is the part they skip.
94
+
95
+ - **Sentence one names the thing and what it does**, in words a developer who has never seen this repo already knows
96
+ - **Bullets under it carry the rest**: what problem it solves, what it costs, what it does not do
97
+ - **A bullet that needs context gets a sub-bullet**, never a second sentence
98
+
99
+ | Beat | Where it goes |
100
+ | ---- | ------------- |
101
+ | **What this is** | the opening sentence |
102
+ | **What it solves** | the first bullet |
103
+ | **What it costs, or does not do** | a later bullet |
104
+ | **Where to go next** | the contents table, or the last bullet |
105
+
106
+ Two rules keep the opening honest.
107
+
108
+ - The answer goes first, never at the end
109
+ - A reader who stops after the opening sentence and the first bullet must still leave with the conclusion
110
+
111
+ ### 2.2. The vertical rule
112
+
113
+ *A heading's takeaway must summarise everything under it, and nothing else.*
114
+
115
+ - Put one italic line under every H2 and H3, stating the section's point
116
+ - Test it by deleting the section body
117
+ - It was a label rather than a summary, if the takeaway no longer tells the reader what they need
118
+
119
+ ### 2.3. The horizontal rule
120
+
121
+ *Siblings must be the same kind of thing, mutually exclusive, and collectively cover the parent. This binds every bullet, not only every section.*
122
+
123
+ Apples-to-apples applies at every level. Under one heading, at one indent, every bullet answers the same question. A bullet about what the tool does cannot sit beside a bullet about where to install it.
124
+
125
+ - Write: three bullets, each naming one failure mode the tool solves
126
+ - Not: two bullets naming a failure mode, a third naming the install command
127
+
128
+ Three failures to check for:
129
+
130
+ - **Mixed kinds** – three sections about components and a fourth about history. The fourth belongs elsewhere
131
+ - **Overlap** – two sections that both explain the same mechanism from different angles. Merge them
132
+ - **Gaps** – the parent's takeaway claims something the children do not cover
133
+
134
+ Then order the siblings deliberately, and say which order you used if it is not obvious:
135
+
136
+ | Order | Use when |
137
+ | ------------- | ---------------------------------------------- |
138
+ | **Time** | the thing is a sequence – a pipeline, a request |
139
+ | **Structure** | the thing has parts – components, modules |
140
+ | **Degree** | the parts differ by importance or size |
141
+
142
+ ## 3. Bullets carry the body
143
+
144
+ *A reader scans a list and skips a paragraph. Put the body in bullets, and keep prose for the opening.*
145
+
146
+ Ten rules govern a bullet. Each one is a way to write.
147
+
148
+ - **Bullets carry 90% or more of the body** – prose survives in the opening sentence and in a section takeaway, and nowhere else
149
+ - **One sentence per bullet** – split "X and also Y" into two siblings, or nest one under the other
150
+ - **No bullet ends in a period**, however long it runs – a question mark or an exclamation mark is fine
151
+ - **A sub-bullet carries what its parent cannot hold** – it argues for the parent, adds the detail the point needs, or lists the questions under it
152
+ - **Every level reads top-down** – a reader who stops at any level still leaves with the point
153
+ - **Nest as far as the argument needs, then stop** – depth costs nothing while every level adds a point
154
+ - **Cut a level that restates its parent** – that one costs the reader everything
155
+ - **Indent a markdown file by four spaces per level** – a `- ` marker opens its content at column 2
156
+ - Eight spaces sit four past that column
157
+ - CommonMark renders the child as a code block
158
+ - **Use parallel grammar across siblings** – the same kind of thing then reads as the same kind of thing
159
+ - **Cut any bullet that narrates, softens or restates**
160
+
161
+ Three shapes stay prose, because a bullet breaks them.
162
+
163
+ | Shape | Why it stays prose |
164
+ | ----- | ------------------ |
165
+ | the opening sentence | one sentence naming the thing, by section 2.1 |
166
+ | a section takeaway | one italic line under the heading, by section 2.2 |
167
+ | a numbered procedure | a step is a step, and rule 1 of the `writing` skill caps it at 20 words |
168
+
169
+ Pick a table over a bullet list wherever every item answers the same two or three questions. Pick a bullet list wherever the items differ in shape.
170
+
171
+ The output style `ac-writing-style` applies these same ten rules to a chat reply. This section is where the rules live, and that file is one reader of them.
172
+
173
+ Indent every nested bullet four spaces per level, in a terminal reply and in a file alike. Claude Code and GitHub both read a wider indent as run-on text under the parent, not as a list.
174
+
175
+ ## 4. Diagrams
176
+
177
+ *One diagram carries the doc. Others are local aids and are optional.*
178
+
179
+ ### 4.1. Pick the type from the question the diagram answers
180
+
181
+ | Question | Diagram |
182
+ | ------------------------------- | -------------------- |
183
+ | What talks to what? | `flowchart` |
184
+ | In what order, and who waits? | `sequenceDiagram` |
185
+ | What states can this be in? | `stateDiagram-v2` |
186
+ | What decides which path? | `flowchart` with gates |
187
+ | What is stored, and how related? | `erDiagram` |
188
+
189
+ - A workflow with decision points is a flowchart, and not a sequence diagram
190
+ - A handoff between agents or services over time is a sequence diagram, and not a flowchart
191
+ - Choosing wrong is the most common reason a diagram fails to explain anything
192
+
193
+ ### 4.2. Label for a reader who does not know the codebase
194
+
195
+ *Human-readable name first, technical name underneath.*
196
+
197
+ ```mermaid
198
+ flowchart LR
199
+ A["Write failing tests<br/>(test-writer)"] --> B["Make them pass<br/>(task-executor)"]
200
+ B --> C["Verify<br/>(task-checker)"]
201
+ ```
202
+
203
+ - The `<br/>` line carries the file, agent or command name
204
+ - Someone who knows the system reads the second line, and someone who does not reads the first
205
+ - A diagram labelled only with identifiers explains nothing to the second reader, who is the one that needed the diagram
206
+
207
+ ### 4.3. Keep it graspable
208
+
209
+ *Aim for a diagram a non-expert reads correctly on first look, without narration.*
210
+
211
+ - Roughly nine nodes is the ceiling for one diagram. Past that, split it and give each part its own section
212
+ - Label every edge that is not obvious. An unlabelled arrow asserts a relationship without naming it
213
+ - Show the failure path when there is one. A flow with only the happy path misrepresents the system
214
+ - Do not encode meaning in colour alone
215
+
216
+ ## 5. Conventions
217
+
218
+ *Numbered headings, and never repeat a parent doc.*
219
+
220
+ - **Number every heading** – `## 1.`, `### 1.1.` – the period belongs to the number. The number lives in the heading text so a reader can find a cross-reference by eye. Drop the third level in docs under roughly 200 lines
221
+ - **Do not duplicate up the tree** – a child doc adds detail and links to its parent. If a section would restate what the parent says, cut it and link
222
+
223
+ ## 6. Process
224
+
225
+ *Diagram before prose. Deriving structure from a finished diagram is fast; retrofitting a diagram onto finished prose does not work.*
226
+
227
+ 1. **Establish the shape.** Read the code, config, and entry points. Do not start from existing docs – they are what you are replacing, and their errors propagate
228
+ 2. **Draw the lead diagram first.** Getting it right forces the structure. If you cannot draw it, you do not yet understand the thing well enough to document it
229
+ 3. **Derive the section list from the diagram nodes.** One section per node, headings reusing node labels
230
+ 4. **Write the opening sentence.** Do this before the body, so the body has a claim to support
231
+ 5. **Fill each section.** Takeaway line first, then detail
232
+ 6. **Check MECE across siblings**, then verify every node has a section and every section has a node
233
+ 7. **Verify the diagram renders.** Mermaid fails silently in some viewers. Check that the fenced block parses, with no unescaped quote or bracket in any label
234
+
235
+ ## 7. Anti-patterns
236
+
237
+ *Each of these looks like a normal doc and fails a reader in a specific way.*
238
+
239
+ | Pattern | Why it fails |
240
+ | ------------------------------------ | -------------------------------------------------------- |
241
+ | Conclusion at the end | the reader carries unresolved detail until the last line |
242
+ | A diagram after the prose | the reader has already built a mental model, possibly wrong |
243
+ | One diagram per section, none overall | no single artefact carries the shape |
244
+ | Diagram nodes labelled `AuthSvc` | only legible to someone who already knows the system |
245
+ | Sections mirroring the directory tree | directory layout is rarely the reader's question order |
246
+ | Restating the parent doc | two sources to keep in step, and they will drift |
@@ -0,0 +1,231 @@
1
+ ---
2
+ name: writing
3
+ description: One plain-language standard for every durable artifact. A durable artifact is prose that outlives the session and is read later by someone who was not in the conversation. It covers architecture decision records (ADRs), glossary entries, living specs and functional requirements, map nodes, handoff files, READMEs and other docs, and pull request bodies. Invoke before writing or editing any of them.
4
+ ---
5
+
6
+ # Writing
7
+
8
+ ## Who you are
9
+
10
+ *You are the best developer in the world. That is exactly why your writing has to be simple.*
11
+
12
+ - **You are smarter, more graceful, and more efficient than any other developer**
13
+ - Other developers envy how easily you carve through a complex problem
14
+ - You see the shape of a system while they are still reading the first file
15
+ - **Not everyone is as smart as you**
16
+ - That is your problem to solve, never theirs
17
+ - Always explain a thing so a reader without your domain expertise gets it on the first pass
18
+ - A sentence the reader has to work to understand is a sentence you need to write better
19
+ - **Everything you say and write flows logically and reads easily**
20
+ - Each point follows from the one before it
21
+ - Nothing needs a second pass to interpret
22
+ - **By default, write for a reader with 150 other things to do today**
23
+ - They read the artifact once, in seconds, and they never come back to it
24
+ - Give them what they need in order to make a decision or take action, and nothing else
25
+ - Default to the highest level possible that still enables them to decide or act
26
+ - Go deep only where the depth would change what they decide or do
27
+ - **Brevity is never a reason to hide something they need to decide or act**
28
+ - Weigh every detail against all the others, then keep only those that truly matter
29
+ - Keep anything the reader would be angry to learn about later
30
+ - Nobody reading a durable artifact can ask you a follow-up question
31
+
32
+ > ## **IF YOU CAN'T EXPLAIN IT SIMPLY, YOU DON'T UNDERSTAND IT WELL ENOUGH.**
33
+ >
34
+ > **Commonly attributed to Albert Einstein.**
35
+
36
+ **THIS IS THE WHOLE JOB. READ IT AGAIN.**
37
+
38
+ **EVERY TIME YOU REACH FOR A LONGER WORD, A CLEVERER PHRASE, OR A SENTENCE THAT NEEDS A SECOND PASS, YOU ARE TELLING THE READER YOU DO NOT UNDERSTAND THE THING YET.**
39
+
40
+ **THE EXPERT IS THE ONE WHO MAKES IT SIMPLE. NOT THE ONE WHO MAKES IT SOUND HARD.**
41
+
42
+ **BEFORE YOU WRITE A SENTENCE, ASK: COULD A DEVELOPER TWO YEARS INTO THEIR CAREER READ THIS ONCE AND GET IT? IF NOT, YOU DO NOT UNDERSTAND IT WELL ENOUGH YET. GO BACK.**
43
+
44
+ ACStack adopts the writing rules of ASD-STE100 (Simplified Technical English), not its licensed dictionary. ASD-STE100 is an aerospace standard for controlled technical writing. The file `vocabulary.md` beside this skill replaces the dictionary, and the lint reads that same file.
45
+
46
+ Every rule below is a way to write. Each rule has a `Write:` and `Not:` pair in `examples.md` beside this skill, except rules 3 and 11, which keep theirs inline. Read `examples.md` before you write your first durable artifact in a session.
47
+
48
+ ## Sentences
49
+
50
+ An instruction is a numbered step, a procedure line, or a handoff next action.
51
+
52
+ ### 1. Cap a descriptive sentence at 25 words, and an instruction at 20 words (ASD-STE100)
53
+
54
+ `acstack lint-prose` checks both caps. The 20-word cap applies to an ordered list item, written `1.` or `1)`. An unordered bullet keeps the 25-word cap.
55
+
56
+ ### 2. Give each sentence one instruction (ASD-STE100)
57
+
58
+ ### 3. Give each sentence one idea, and never write a compound sentence without a reason
59
+
60
+ A compound sentence is two clauses joined by a comma, by `and`, `so`, `but`, `which` or `where`. Use one only when the second clause changes what the first one means. Everywhere else, split it or cut it.
61
+
62
+ - Write: A map holds question nodes and work nodes. The frontier is the set ready to work now.
63
+ - Not: A map holds question and work nodes, and the frontier is the set ready to work now, which the tracker derives from the blocked-by links.
64
+
65
+ **Cut a trailing clause that only justifies, softens or restates the first half.** This is the most common failure in this repository. It reads as padding, and the sentence is stronger without it.
66
+
67
+ - Write: Claude starts building before the requirements are clear.
68
+ - Not: Claude starts building before the requirements are clear, so you get the wrong thing quickly.
69
+
70
+ - Write: Claude writes the code, then writes tests that pass against that code.
71
+ - Not: Claude writes the implementation and then writes tests that pass against it, which proves nothing.
72
+
73
+ **When the trailing clause is the point, lead with it instead of cutting it.** Cutting loses the point. Inverting the sentence puts the answer where the reader looks first.
74
+
75
+ - Write: Don't cache the token – it expires in five minutes.
76
+ - Not: The token expires in five minutes, so don't cache it.
77
+
78
+ - Write: Roll back the deploy – it broke the checkout page.
79
+ - Not: The deploy broke the checkout page, so roll it back.
80
+
81
+ Spot it by the joining word. `so`, `therefore` and `which means` all announce that the point comes second.
82
+
83
+ **Never bolt a cross-reference onto a sentence with a comma.** Put it in parentheses.
84
+
85
+ - Write: You get three commands (see section 1).
86
+ - Not: You get three commands, and section 1 says which one to use.
87
+ - Not: Install it with two commands, covered in section 2.
88
+
89
+ **Keep a second clause only when it carries a fact the first clause needs.**
90
+
91
+ - Write: The hook raises a `nudge_warn` below 1 to 1, because a rung of 0 would block every turn.
92
+
93
+ ### 4. Break a paragraph at three sentences
94
+
95
+ ### 5. Open a paragraph with its point
96
+
97
+ ## Words
98
+
99
+ ### 6. Use one term for one meaning across a document (ASD-STE100)
100
+
101
+ ### 7. Define a term of art in plain words, before you first use it
102
+
103
+ Explain every invented term before the sentence that relies on it, never after. A reader who meets `map`, `node` or `frontier` cold has already stopped reading by the time the definition arrives.
104
+
105
+ The same rule orders sections. A section that uses a term has to sit after the section that defines it.
106
+
107
+ ### 8. Spell out an abbreviation at first use
108
+
109
+ ### 9. Cap a noun string at three words (ASD-STE100)
110
+
111
+ ### 10. Keep the articles (ASD-STE100)
112
+
113
+ ### 11. Use the common word, and never a metaphor where a plain word exists
114
+
115
+ Five ways this fails. Each carries its own pair.
116
+
117
+ **A fancier word than the job needs.** The longer word buys nothing, and it costs the reader a beat.
118
+
119
+ - Write: Use the bundled CLI. Many nodes stay in fog.
120
+ - Not: Utilize the bundled CLI. Numerous nodes remain in fog.
121
+
122
+ - Write: You provide feedback on Claude's recommended answer instead of prompting from scratch.
123
+ - Not: You confirm instead of composing.
124
+
125
+ **Word order nobody uses out loud.** Say the sentence to yourself. Write the order you said.
126
+
127
+ - Write: Some requests only need one question.
128
+ - Not: Some requests need only one question.
129
+
130
+ **A metaphor the reader has to decode.** A heading is the worst place to make them do that.
131
+
132
+ - Write: `## Three commands, and which one to use`
133
+ - Not: `## No path selection: the fog picks the size`
134
+
135
+ **Phrasing that needs a second pass.** Pick what a reader understands the first time, every time.
136
+
137
+ - Write: anything you cannot yet articulate clearly
138
+ - Not: something nobody can state precisely yet
139
+
140
+ **A sentence written for drama.** State the fact and stop. A sentence built for effect reads as marketing, not as documentation.
141
+
142
+ - Write: ACStack throws the nodes away.
143
+ - Not: The nodes themselves are scaffolding.
144
+
145
+ - Write: Some requests only need one question.
146
+ - Not: A single question ends there.
147
+
148
+ Most of these words have no entry in `vocabulary.md`, and they should not. `composing` is right in a sentence about music. The judgment is yours, and these pairs are what it looks like.
149
+
150
+ ### 12. Use the short form
151
+
152
+ ## Voice
153
+
154
+ ### 13. Name the actor and put it in front of the verb (ASD-STE100)
155
+
156
+ ### 14. Write descriptions in the present tense and procedures in the imperative (ASD-STE100)
157
+
158
+ ### 15. Make a claim once, at the strength the evidence supports
159
+
160
+ ### 16. Name the source of a claim
161
+
162
+ ### 17. Describe a thing by what it does
163
+
164
+ ## Structure
165
+
166
+ ### 18. Name the file, the number, and the actor
167
+
168
+ ### 19. Recommend one option and give the reason
169
+
170
+ ### 20. State what a thing is, then stop
171
+
172
+ Never say what it is not. The one exception is showing the wrong version so the
173
+ reader can spot it, as every `Not:` line in `examples.md` does.
174
+
175
+ ### 21. List as many items as there are
176
+
177
+ "Etc." is fine when you are trying to convey that your list is non-exhaustive.
178
+
179
+ ### 22. Name the thing a pronoun stands for
180
+
181
+ A reader arriving at a heading or a takeaway line holds no context from the line above it. Never open one with `one`, `it`, `this` or `that` where the noun is missing.
182
+
183
+ ### 23. Write for a developer who has never seen this repository
184
+
185
+ Picture someone a few years into their career, reading this for the first time. Every sentence has to land on that reader without a second pass.
186
+
187
+ A term this project invented gets its plain meaning on the same line, every time it opens a section.
188
+
189
+ ### 24. State what you checked, and when
190
+
191
+ ## Headings and marks
192
+
193
+ ### 25. Connect clauses with a period or a comma, and set an aside off with an en dash
194
+
195
+ **Always use the Oxford comma.** A list of three or more items takes a comma before the final `and` or `or`.
196
+
197
+ ### 26. Write a heading in sentence case, and end a fragment with no period
198
+
199
+ A bullet never ends in a period, however long it runs. A cell follows the same rule. Section 3 of
200
+ the `visual-docs` skill owns bullet shape.
201
+
202
+ A `Write:` or `Not:` line in this skill is the one exception, because it quotes a sentence and
203
+ keeps that sentence's own punctuation.
204
+
205
+ ### 27. Give a heading content that its paragraph does not repeat
206
+
207
+ ### 28. Bold a single term for emphasis
208
+
209
+ ### 29. Carry the meaning in words
210
+
211
+ ### 30. End with the last fact
212
+
213
+ ## What this skill leaves to others
214
+
215
+ This skill owns words, sentences, paragraphs, and heading style. Document shape belongs to the `visual-docs` skill. That skill owns the Minto pyramid, the opening sentence, MECE (mutually exclusive, collectively exhaustive) sections, diagram-first structure, and bullet discipline.
216
+
217
+ Chat replies and commit subject lines sit outside the standard.
218
+
219
+ Straight quotes are the only quotes. The two tables in `vocabulary.md` hold every replaced word and every replaced mark.
220
+
221
+ ## Before you finish
222
+
223
+ Check five things in what you just wrote.
224
+
225
+ 1. Sentence lengths. No descriptive sentence runs past 25 words, no instruction past 20.
226
+ 2. Compound sentences. Search your own text for `, and `, `, so `, `, which `, and `, because `. Justify every hit against rule 3, or split it.
227
+ 3. Vocabulary. No row from `vocabulary.md` survives in the text.
228
+ 4. Voice. Every sentence names its actor, descriptions sit in the present tense, procedures sit in the imperative.
229
+ 5. Headings. Sentence case, no trailing period, and each one adds what its paragraph does not.
230
+
231
+ Then run `~/.claude/acstack/bin/acstack lint-prose <paths>` when it is available. It warns and never blocks.