@aperant/framework 0.6.3 → 0.6.5

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 (244) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +64 -10
  3. package/agents/apt-improver.md +99 -0
  4. package/agents/apt-planner.md +115 -10
  5. package/dist/__test-helpers/run-cmd.d.mts +4 -2
  6. package/dist/__test-helpers/run-cmd.d.mts.map +1 -1
  7. package/dist/__test-helpers/run-cmd.mjs +56 -15
  8. package/dist/__test-helpers/run-cmd.mjs.map +1 -1
  9. package/dist/cli/artifacts/classification.d.mts.map +1 -1
  10. package/dist/cli/artifacts/classification.mjs +10 -0
  11. package/dist/cli/artifacts/classification.mjs.map +1 -1
  12. package/dist/cli/ci-watch/lock.d.mts +53 -0
  13. package/dist/cli/ci-watch/lock.d.mts.map +1 -0
  14. package/dist/cli/ci-watch/lock.mjs +172 -0
  15. package/dist/cli/ci-watch/lock.mjs.map +1 -0
  16. package/dist/cli/ci-watch/state.d.mts +36 -0
  17. package/dist/cli/ci-watch/state.d.mts.map +1 -0
  18. package/dist/cli/ci-watch/state.mjs +103 -0
  19. package/dist/cli/ci-watch/state.mjs.map +1 -0
  20. package/dist/cli/ci-watch/stop-matrix.d.mts +58 -0
  21. package/dist/cli/ci-watch/stop-matrix.d.mts.map +1 -0
  22. package/dist/cli/ci-watch/stop-matrix.mjs +164 -0
  23. package/dist/cli/ci-watch/stop-matrix.mjs.map +1 -0
  24. package/dist/cli/cli-wrappers/ci-watch.d.mts +2 -0
  25. package/dist/cli/cli-wrappers/ci-watch.d.mts.map +1 -0
  26. package/dist/cli/cli-wrappers/ci-watch.mjs +9 -0
  27. package/dist/cli/cli-wrappers/ci-watch.mjs.map +1 -0
  28. package/dist/cli/commands/adr.d.mts +5 -0
  29. package/dist/cli/commands/adr.d.mts.map +1 -0
  30. package/dist/cli/commands/adr.mjs +228 -0
  31. package/dist/cli/commands/adr.mjs.map +1 -0
  32. package/dist/cli/commands/ci-watch.d.mts +7 -0
  33. package/dist/cli/commands/ci-watch.d.mts.map +1 -0
  34. package/dist/cli/commands/ci-watch.mjs +465 -0
  35. package/dist/cli/commands/ci-watch.mjs.map +1 -0
  36. package/dist/cli/commands/context.d.mts +7 -0
  37. package/dist/cli/commands/context.d.mts.map +1 -0
  38. package/dist/cli/commands/context.mjs +224 -0
  39. package/dist/cli/commands/context.mjs.map +1 -0
  40. package/dist/cli/commands/event.d.mts.map +1 -1
  41. package/dist/cli/commands/event.mjs +59 -24
  42. package/dist/cli/commands/event.mjs.map +1 -1
  43. package/dist/cli/commands/host-detect.d.mts +1 -1
  44. package/dist/cli/commands/host-detect.d.mts.map +1 -1
  45. package/dist/cli/commands/host-detect.mjs +30 -3
  46. package/dist/cli/commands/host-detect.mjs.map +1 -1
  47. package/dist/cli/commands/init.d.mts.map +1 -1
  48. package/dist/cli/commands/init.mjs +73 -5
  49. package/dist/cli/commands/init.mjs.map +1 -1
  50. package/dist/cli/commands/modes.d.mts +13 -0
  51. package/dist/cli/commands/modes.d.mts.map +1 -0
  52. package/dist/cli/commands/modes.mjs +220 -0
  53. package/dist/cli/commands/modes.mjs.map +1 -0
  54. package/dist/cli/commands/pr-review-audit-fixer.d.mts +41 -2
  55. package/dist/cli/commands/pr-review-audit-fixer.d.mts.map +1 -1
  56. package/dist/cli/commands/pr-review-audit-fixer.mjs +91 -14
  57. package/dist/cli/commands/pr-review-audit-fixer.mjs.map +1 -1
  58. package/dist/cli/commands/route.d.mts.map +1 -1
  59. package/dist/cli/commands/route.mjs +11 -2
  60. package/dist/cli/commands/route.mjs.map +1 -1
  61. package/dist/cli/commands/task.d.mts.map +1 -1
  62. package/dist/cli/commands/task.mjs +136 -6
  63. package/dist/cli/commands/task.mjs.map +1 -1
  64. package/dist/cli/commands/tokens.d.mts.map +1 -1
  65. package/dist/cli/commands/tokens.mjs +150 -6
  66. package/dist/cli/commands/tokens.mjs.map +1 -1
  67. package/dist/cli/commands/triage.d.mts +8 -0
  68. package/dist/cli/commands/triage.d.mts.map +1 -0
  69. package/dist/cli/commands/triage.mjs +259 -0
  70. package/dist/cli/commands/triage.mjs.map +1 -0
  71. package/dist/cli/config/post-merge-sweep.d.mts +18 -0
  72. package/dist/cli/config/post-merge-sweep.d.mts.map +1 -1
  73. package/dist/cli/config/post-merge-sweep.mjs +48 -3
  74. package/dist/cli/config/post-merge-sweep.mjs.map +1 -1
  75. package/dist/cli/consistency/registry.d.mts +11 -0
  76. package/dist/cli/consistency/registry.d.mts.map +1 -1
  77. package/dist/cli/consistency/registry.mjs +13 -0
  78. package/dist/cli/consistency/registry.mjs.map +1 -1
  79. package/dist/cli/coordination/agent-identity.d.mts +9 -0
  80. package/dist/cli/coordination/agent-identity.d.mts.map +1 -1
  81. package/dist/cli/coordination/agent-identity.mjs +11 -0
  82. package/dist/cli/coordination/agent-identity.mjs.map +1 -1
  83. package/dist/cli/coordination/event-log.d.mts +27 -0
  84. package/dist/cli/coordination/event-log.d.mts.map +1 -1
  85. package/dist/cli/coordination/event-log.mjs +72 -2
  86. package/dist/cli/coordination/event-log.mjs.map +1 -1
  87. package/dist/cli/design/frontmatter-schema.d.mts +3 -3
  88. package/dist/cli/design/frontmatter-schema.d.mts.map +1 -1
  89. package/dist/cli/design/frontmatter-schema.mjs +3 -1
  90. package/dist/cli/design/frontmatter-schema.mjs.map +1 -1
  91. package/dist/cli/dispatch.d.mts.map +1 -1
  92. package/dist/cli/dispatch.mjs +14 -1
  93. package/dist/cli/dispatch.mjs.map +1 -1
  94. package/dist/cli/gate/registry.d.mts +11 -0
  95. package/dist/cli/gate/registry.d.mts.map +1 -1
  96. package/dist/cli/gate/registry.mjs +13 -0
  97. package/dist/cli/gate/registry.mjs.map +1 -1
  98. package/dist/cli/help.d.mts.map +1 -1
  99. package/dist/cli/help.mjs +1 -0
  100. package/dist/cli/help.mjs.map +1 -1
  101. package/dist/cli/host/detect.d.mts +1 -0
  102. package/dist/cli/host/detect.d.mts.map +1 -1
  103. package/dist/cli/host/detect.mjs +5 -0
  104. package/dist/cli/host/detect.mjs.map +1 -1
  105. package/dist/cli/route/envelope.d.mts +68 -4
  106. package/dist/cli/route/envelope.d.mts.map +1 -1
  107. package/dist/cli/route/envelope.mjs +140 -103
  108. package/dist/cli/route/envelope.mjs.map +1 -1
  109. package/dist/cli/route/skill-discover.d.mts +11 -0
  110. package/dist/cli/route/skill-discover.d.mts.map +1 -1
  111. package/dist/cli/route/skill-discover.mjs +46 -1
  112. package/dist/cli/route/skill-discover.mjs.map +1 -1
  113. package/dist/cli/skill-author/contract.d.mts +20 -0
  114. package/dist/cli/skill-author/contract.d.mts.map +1 -1
  115. package/dist/cli/skill-author/contract.mjs +27 -0
  116. package/dist/cli/skill-author/contract.mjs.map +1 -1
  117. package/dist/cli/skill-author/skill-template.d.mts.map +1 -1
  118. package/dist/cli/skill-author/skill-template.mjs +4 -3
  119. package/dist/cli/skill-author/skill-template.mjs.map +1 -1
  120. package/dist/cli/task/worktree-cleanup.d.mts +9 -1
  121. package/dist/cli/task/worktree-cleanup.d.mts.map +1 -1
  122. package/dist/cli/task/worktree-cleanup.mjs +190 -9
  123. package/dist/cli/task/worktree-cleanup.mjs.map +1 -1
  124. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  125. package/dist/plugin/agents/apt-planner.md +1 -1
  126. package/dist/plugin/skills/apt/SKILL.md +111 -5
  127. package/dist/plugin/skills/apt-author-skill/SKILL.md +11 -0
  128. package/dist/plugin/skills/apt-bootstrap/SKILL.md +1 -0
  129. package/dist/plugin/skills/apt-classify/SKILL.md +1 -0
  130. package/dist/plugin/skills/apt-close-task/SKILL.md +1 -0
  131. package/dist/plugin/skills/apt-create-docs/SKILL.md +1 -0
  132. package/dist/plugin/skills/apt-debug/SKILL.md +2 -0
  133. package/dist/plugin/skills/apt-design/SKILL.md +2 -0
  134. package/dist/plugin/skills/apt-discuss/SKILL.md +2 -0
  135. package/dist/plugin/skills/apt-docs/SKILL.md +2 -0
  136. package/dist/plugin/skills/apt-execute/SKILL.md +1 -0
  137. package/dist/plugin/skills/apt-mockup/SKILL.md +2 -0
  138. package/dist/plugin/skills/apt-pause/SKILL.md +1 -0
  139. package/dist/plugin/skills/apt-personas/SKILL.md +1 -0
  140. package/dist/plugin/skills/apt-plan/SKILL.md +2 -0
  141. package/dist/plugin/skills/apt-pr-review/SKILL.md +1 -0
  142. package/dist/plugin/skills/apt-quick/SKILL.md +2 -0
  143. package/dist/plugin/skills/apt-resume/SKILL.md +1 -0
  144. package/dist/plugin/skills/apt-review/SKILL.md +1 -0
  145. package/dist/plugin/skills/apt-roadmap/SKILL.md +1 -0
  146. package/dist/plugin/skills/apt-roundtable/SKILL.md +2 -0
  147. package/dist/plugin/skills/apt-run/SKILL.md +1 -0
  148. package/dist/plugin/skills/apt-scan/SKILL.md +1 -0
  149. package/dist/plugin/skills/apt-setup/SKILL.md +1 -0
  150. package/dist/plugin/skills/apt-ship/SKILL.md +6 -5
  151. package/dist/plugin/skills/apt-stress-test/SKILL.md +1 -0
  152. package/dist/plugin/skills/apt-terminal/SKILL.md +1 -0
  153. package/dist/plugin/skills/apt-update/SKILL.md +5 -0
  154. package/dist/plugin/skills/apt-verify/SKILL.md +1 -0
  155. package/dist/plugin/skills/apt-verify-proof/SKILL.md +1 -0
  156. package/dist/types/config.d.ts +85 -0
  157. package/dist/types/config.d.ts.map +1 -1
  158. package/package.json +125 -122
  159. package/prompts/coder.md +2 -0
  160. package/prompts/planner.md +12 -0
  161. package/prompts/spec_writer.md +9 -0
  162. package/skills/apt/SKILL.md +112 -5
  163. package/skills/apt-author-skill/SKILL.md +11 -0
  164. package/skills/apt-bootstrap/SKILL.md +1 -0
  165. package/skills/apt-classify/SKILL.md +1 -0
  166. package/skills/apt-close-task/SKILL.md +33 -1
  167. package/skills/apt-create-docs/SKILL.md +1 -0
  168. package/skills/apt-debug/SKILL.md +41 -6
  169. package/skills/apt-debug/appendices/diagnose-discipline.md +119 -0
  170. package/skills/apt-design/SKILL.md +2 -0
  171. package/skills/apt-diagram/SKILL.md +342 -0
  172. package/skills/apt-diagram/appendices/design-discipline.md +97 -0
  173. package/skills/apt-discuss/SKILL.md +27 -0
  174. package/skills/apt-discuss/appendices/grill-discipline.md +104 -0
  175. package/skills/apt-discuss/appendices/zoom-out-helper.md +79 -0
  176. package/skills/apt-docs/SKILL.md +2 -0
  177. package/skills/apt-execute/SKILL.md +49 -5
  178. package/skills/apt-execute/appendices/tdd-mode.md +107 -0
  179. package/skills/apt-improve/DEEPENING.md +84 -0
  180. package/skills/apt-improve/INTERFACE-DESIGN.md +97 -0
  181. package/skills/apt-improve/LANGUAGE.md +104 -0
  182. package/skills/apt-improve/SKILL.md +141 -0
  183. package/skills/apt-mockup/SKILL.md +2 -0
  184. package/skills/apt-pause/SKILL.md +1 -0
  185. package/skills/apt-personas/SKILL.md +1 -0
  186. package/skills/apt-plan/SKILL.md +149 -4
  187. package/skills/apt-planner.md +42 -1
  188. package/skills/apt-pr-review/SKILL.md +47 -16
  189. package/skills/apt-prototype/LOGIC.md +109 -0
  190. package/skills/apt-prototype/SKILL.md +143 -0
  191. package/skills/apt-prototype/UI.md +90 -0
  192. package/skills/apt-quick/SKILL.md +32 -0
  193. package/skills/apt-resume/SKILL.md +1 -0
  194. package/skills/apt-review/SKILL.md +3 -0
  195. package/skills/apt-roadmap/SKILL.md +1 -0
  196. package/skills/apt-roundtable/SKILL.md +2 -0
  197. package/skills/apt-run/SKILL.md +33 -4
  198. package/skills/apt-scan/SKILL.md +1 -0
  199. package/skills/apt-setup/SKILL.md +129 -2
  200. package/skills/apt-ship/SKILL.md +52 -4
  201. package/skills/apt-stress-test/SKILL.md +1 -0
  202. package/skills/apt-terminal/SKILL.md +1 -0
  203. package/skills/apt-triage/AGENT-BRIEF.md +84 -0
  204. package/skills/apt-triage/OUT-OF-SCOPE.md +75 -0
  205. package/skills/apt-triage/SKILL.md +169 -0
  206. package/skills/apt-update/SKILL.md +3 -0
  207. package/skills/apt-verify/SKILL.md +4 -0
  208. package/skills/apt-verify-proof/SKILL.md +4 -0
  209. package/skills/apt-watch-ci/SKILL.md +163 -0
  210. package/skills/apt-zoom-out/SKILL.md +130 -0
  211. package/src/cli/artifacts/classification.mjs +10 -0
  212. package/src/cli/ci-watch/lock.mjs +178 -0
  213. package/src/cli/ci-watch/state.mjs +103 -0
  214. package/src/cli/ci-watch/stop-matrix.mjs +181 -0
  215. package/src/cli/cli-wrappers/ci-watch.mjs +9 -0
  216. package/src/cli/commands/adr.mjs +243 -0
  217. package/src/cli/commands/ci-watch.mjs +503 -0
  218. package/src/cli/commands/context.mjs +244 -0
  219. package/src/cli/commands/event.mjs +63 -24
  220. package/src/cli/commands/host-detect.mjs +33 -7
  221. package/src/cli/commands/init.mjs +83 -5
  222. package/src/cli/commands/modes.mjs +215 -0
  223. package/src/cli/commands/pr-review-audit-fixer.mjs +95 -16
  224. package/src/cli/commands/route.mjs +11 -2
  225. package/src/cli/commands/task.mjs +152 -18
  226. package/src/cli/commands/tokens.mjs +157 -6
  227. package/src/cli/commands/triage.mjs +277 -0
  228. package/src/cli/config/post-merge-sweep.mjs +49 -3
  229. package/src/cli/consistency/registry.mjs +14 -0
  230. package/src/cli/coordination/agent-identity.mjs +12 -0
  231. package/src/cli/coordination/event-log.mjs +73 -2
  232. package/src/cli/design/frontmatter-schema.mjs +3 -1
  233. package/src/cli/dispatch.mjs +15 -1
  234. package/src/cli/gate/registry.mjs +14 -0
  235. package/src/cli/help.mjs +1 -0
  236. package/src/cli/host/detect.mjs +5 -0
  237. package/src/cli/route/envelope.mjs +140 -106
  238. package/src/cli/route/skill-discover.mjs +46 -1
  239. package/src/cli/skill-author/contract.mjs +29 -0
  240. package/src/cli/skill-author/skill-template.mjs +4 -3
  241. package/src/cli/task/worktree-cleanup.mjs +191 -9
  242. package/templates/adr-format.md +56 -0
  243. package/templates/config.json +4 -0
  244. package/templates/context-format.md +34 -0
@@ -0,0 +1,342 @@
1
+ ---
2
+ name: apt:diagram
3
+ description: "Generate .excalidraw or MCP-canvas diagrams"
4
+ apt-skill-version: {{APT_VERSION}}
5
+ stage: design
6
+ intent: design
7
+ when_to_use: "The user wants to generate a diagram from a prompt — system architecture sketch, flowchart, data-flow picture. Produces either a local .excalidraw file (default) or a live Excalidraw MCP canvas."
8
+ user_invocable: true
9
+ internal: false
10
+ spawns_agent: false
11
+ agent_name: null
12
+ task_context: self-managed
13
+ # default_track omitted — self-managed skill, router does not consult this field
14
+ default_execution_mode: auto
15
+ execution_modes:
16
+ - auto
17
+ - step
18
+ allowed-tools: "Read, Write, Edit, Bash, Grep, Glob"
19
+ argument-hint: "apt:diagram [prompt] [--mode=file|--mode=mcp] [--depth=default|comprehensive]"
20
+ gates: []
21
+ ---
22
+
23
+ <objective>
24
+ Turn a natural-language prompt into a diagram. The skill splits the
25
+ work into two phases: (1) the agent itself produces a `DiagramScene`
26
+ JSON (a minimal graph of labelled `nodes` and directed `edges`) from
27
+ the user prompt, and (2) a deterministic renderer turns that scene
28
+ into Excalidraw geometry — either a local `.excalidraw` file under
29
+ `docs/diagrams/<slug>.excalidraw` or a live canvas via the Excalidraw
30
+ MCP server.
31
+
32
+ There are exactly two render modes — `file` (offline, default) and
33
+ `mcp` (live canvas). There is no `auto` mode and no automatic
34
+ degradation between them: if the chosen renderer fails, the skill
35
+ hard-errors with a message telling the user to re-run with the other
36
+ mode. This is intentional in v1 — diagnostics over magic.
37
+ </objective>
38
+
39
+ <process>
40
+
41
+ ## 1. Parse arguments
42
+
43
+ `$ARGUMENTS` may contain free-text prompt material plus at most one
44
+ `--mode=<value>` flag and at most one `--depth=<value>` flag. Extract the
45
+ prompt by removing any flags (if present) and trimming. Extract each
46
+ flag value if any.
47
+
48
+ - If a `--mode=...` flag is present and its value is anything other
49
+ than `"file"` or `"mcp"`, emit a hard error of the exact shape:
50
+ `Unknown --mode value: <value>. Expected file or mcp.` and exit.
51
+ - Empty prompt → emit `apt:diagram requires a prompt describing what to draw.` and exit.
52
+ - If a `--depth=...` flag is present and its value is anything other
53
+ than `"default"` or `"comprehensive"`, emit a hard error of the exact
54
+ shape: `Unknown --depth value: <value>. Expected default or comprehensive.`
55
+ and exit. The default value when absent is `default`. When the value
56
+ is `comprehensive`, before generating the scene in Step 3 load
57
+ `appendices/design-discipline.md` into reasoning context (mirrors
58
+ apt:discuss's `appendices/grill-discipline.md` load pattern). The flag
59
+ is per-call only — it is NOT persisted to `.aperant/config.json`.
60
+
61
+ ## 2. Resolve mode
62
+
63
+ Resolution order: --mode flag > .aperant/config.json#diagram.mode > "file" default
64
+
65
+ Read `.aperant/config.json` and look for `diagram.mode`. The lookup
66
+ runs through the same in-skill Node one-liner pattern apt:quick uses
67
+ for `preferences.quick_task_post_verify` (see apt-quick/SKILL.md
68
+ Step 8):
69
+
70
+ ```bash
71
+ node -e '
72
+ const fs = require("fs");
73
+ const path = require("path");
74
+ const cfgPath = path.join(process.cwd(), ".aperant/config.json");
75
+ let mode = "file"; // default
76
+ try {
77
+ const cfg = JSON.parse(fs.readFileSync(cfgPath, "utf-8"));
78
+ if (cfg && cfg.diagram && (cfg.diagram.mode === "file" || cfg.diagram.mode === "mcp")) {
79
+ mode = cfg.diagram.mode;
80
+ }
81
+ } catch {}
82
+ // The flag override (if present) is layered on top in the agent step,
83
+ // not in this snippet — this only reads the persisted default.
84
+ process.stdout.write(mode);
85
+ '
86
+ ```
87
+
88
+ If the user passed `--mode=file` or `--mode=mcp`, that wins
89
+ unconditionally over whatever the file says — the flag is a one-call
90
+ override and is not persisted to config.
91
+
92
+ ## 3. Generate a `DiagramScene`
93
+
94
+ The agent itself produces a JSON object of shape:
95
+
96
+ ```json
97
+ {
98
+ "nodes": [{ "id": "<stable-id>", "label": "<short-label>", "x": <number>, "y": <number> }, ...],
99
+ "edges": [{ "from": "<id>", "to": "<id>", "label": "<optional>" }, ...]
100
+ }
101
+ ```
102
+
103
+ Constraints the agent MUST honour while producing the scene:
104
+
105
+ - **Stable string ids.** Every node has a short, stable `id` (lowercase
106
+ kebab works well — `auth-service`, `db`, `cdn`). Edges reference
107
+ these ids in `from`/`to`. NEVER use positional ids like `n0`/`n1`.
108
+ - **Endpoint validity.** Every `edge.from` and `edge.to` MUST appear in
109
+ the `nodes` array. The renderer hard-errors on a missing endpoint
110
+ with `DiagramScene edge references unknown node id: <id>` — that is
111
+ a failure of scene generation, not a renderer bug, so the agent
112
+ MUST validate this before dispatching to the renderer.
113
+ - **Coordinates.** Use a rough grid to avoid overlap — e.g. 200px
114
+ horizontal spacing between sibling nodes, 150px vertical between
115
+ layers. Nodes default to ~180x70 px in the renderer; keep ≥200px
116
+ centre-to-centre.
117
+ - **Scope.** v1 has no groups, containers, or layout constraints.
118
+ Don't invent extra fields — the renderer ignores them at best,
119
+ rejects the scene at worst.
120
+
121
+ ## 4. File mode — dispatch to `renderToFile`
122
+
123
+ When the resolved mode is `file`:
124
+
125
+ 1. Derive a slug from the prompt by calling `deriveSlug(prompt)` from
126
+ `@aperant/core/workflows/diagram`. The slug becomes the filename
127
+ under `docs/diagrams/<slug>.excalidraw`.
128
+ 2. Invoke `renderToFile({ scene, slug, projectDir })` via a small Node
129
+ invocation — same precedent as apt:design Step 3 ("invoke the
130
+ library entry point via a small Node invocation"). The agent
131
+ serialises the scene into the command via a temp file or
132
+ `JSON.stringify`-ed env var:
133
+
134
+ ```bash
135
+ node -e '
136
+ import("@aperant/core/workflows/diagram").then(async (m) => {
137
+ const scene = JSON.parse(process.env.APT_DIAGRAM_SCENE);
138
+ const slug = m.deriveSlug(process.env.APT_DIAGRAM_PROMPT || "diagram");
139
+ const result = await m.renderToFile({
140
+ scene,
141
+ slug,
142
+ projectDir: process.cwd(),
143
+ });
144
+ process.stdout.write(result.absolutePath);
145
+ }).catch((err) => {
146
+ process.stderr.write("renderToFile failed: " + err.message + "\n");
147
+ process.exit(1);
148
+ });
149
+ '
150
+ ```
151
+
152
+ Pass the scene as `APT_DIAGRAM_SCENE` env (JSON-encoded) and the raw
153
+ prompt as `APT_DIAGRAM_PROMPT`. The wrapper prints the absolute path
154
+ to stdout on success.
155
+
156
+ 3. On success, print to the user:
157
+
158
+ ```
159
+ Diagram written to <absolutePath>. Open it in Excalidraw (drag-drop the file into excalidraw.com or open via Aperant's Excalidraw integration).
160
+ ```
161
+
162
+ Relative path under the project: `docs/diagrams/<slug>.excalidraw`.
163
+
164
+ 4. On failure (any `Error` thrown from `renderToFile`, including the
165
+ `unknown node id` validation case), surface the message to the user
166
+ verbatim with no retry and no fallback. Keep the generated scene
167
+ JSON visible in the chat so the user can inspect what was
168
+ produced — that is the diagnostic.
169
+
170
+ ## 5. MCP mode — consent gate + renderer dispatch
171
+
172
+ When the resolved mode is `mcp`, the skill runs three sub-steps in
173
+ order: (a) consent gate, (b) renderer dispatch, (c) failure handling.
174
+
175
+ ### 5a. Consent gate
176
+
177
+ Read `.aperant/config.json` and look at `diagram.mcpConsent`. The
178
+ shape is:
179
+
180
+ ```json
181
+ { "host": "<host string>", "decision": "granted" | "denied", "grantedAt": "<ISO 8601 timestamp>" }
182
+ ```
183
+
184
+ or `null` if no decision has ever been recorded.
185
+
186
+ Determine the "configured MCP host" from the connected Excalidraw MCP
187
+ server. The skill does NOT manage MCP server installation — it reads
188
+ the host name from whatever `mcp__excalidraw__*` namespace is already
189
+ present on the agent's tool surface. (For most setups the host is
190
+ something like `mcp.excalidraw.com` or a self-hosted URL — use
191
+ whatever the surface reports.)
192
+
193
+ Decide whether to prompt:
194
+
195
+ - If `diagram.mcpConsent` is `null` → prompt.
196
+ - If `diagram.mcpConsent.host !== <configured MCP host>` → prompt.
197
+ - If `diagram.mcpConsent.host === <configured MCP host>` AND `diagram.mcpConsent.decision === "denied"` → hard-error immediately with the exact denied text (no re-prompt):
198
+ ```
199
+ diagram MCP consent denied; re-run with `--mode=file` or change diagram.mcpConsent in .aperant/config.json
200
+ ```
201
+ - Otherwise (host matches AND decision is `"granted"`) → the existing consent applies; proceed to 5b.
202
+
203
+ When prompting, print a single line naming the host and ask `granted / denied`:
204
+
205
+ ```
206
+ apt:diagram is about to send diagram data to the Excalidraw MCP server at <host>. Type `granted` to allow, `denied` to refuse.
207
+ ```
208
+
209
+ Read one line of input. Persist the decision back to
210
+ `.aperant/config.json` with a read-mutate-write JSON pattern:
211
+
212
+ ```bash
213
+ node -e '
214
+ const fs = require("fs");
215
+ const path = require("path");
216
+ const cfgPath = path.join(process.cwd(), ".aperant/config.json");
217
+ const decision = process.env.APT_DIAGRAM_DECISION; // "granted" | "denied"
218
+ if (decision !== "granted" && decision !== "denied") {
219
+ process.stderr.write("invalid decision\n");
220
+ process.exit(1);
221
+ }
222
+ const host = process.env.APT_DIAGRAM_HOST;
223
+ let cfg = { diagram: { mode: "mcp", mcpConsent: null } };
224
+ try { cfg = JSON.parse(fs.readFileSync(cfgPath, "utf-8")); } catch {}
225
+ cfg.diagram = cfg.diagram || { mode: "mcp", mcpConsent: null };
226
+ cfg.diagram.mcpConsent = {
227
+ host,
228
+ decision,
229
+ grantedAt: new Date().toISOString(),
230
+ };
231
+ fs.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
232
+ '
233
+ ```
234
+
235
+ If the decision is `"denied"`, exit with EXACTLY this text (verbatim,
236
+ no rewording, no extra punctuation):
237
+
238
+ ```
239
+ diagram MCP consent denied; re-run with `--mode=file` or change diagram.mcpConsent in .aperant/config.json
240
+ ```
241
+
242
+ If the decision is `"granted"`, proceed to 5b.
243
+
244
+ ### 5b. Renderer dispatch
245
+
246
+ The skill IS the MCP renderer — there is no shared TS module here. The
247
+ agent dispatches MCP tool calls directly:
248
+
249
+ 1. Iterate `scene.nodes` FIRST. For each node, call the Excalidraw MCP
250
+ `create_element` tool (expected name `mcp__excalidraw__create_element`;
251
+ if the connected server exposes a different equivalent, use that
252
+ discovered name) with rectangle parameters: position from
253
+ `node.x`/`node.y`, default size 180x70, and the `node.label` as
254
+ text content. Record the element id the MCP server returns.
255
+ 2. Then iterate `scene.edges`. For each edge, call the same tool with
256
+ arrow parameters, setting `startBinding.elementId` to the rectangle
257
+ id created for `edge.from` and `endBinding.elementId` to the
258
+ rectangle id created for `edge.to`. If `edge.label` is set, pass it
259
+ as the arrow's label.
260
+
261
+ Nodes MUST be created before edges so the edge bindings have valid
262
+ element ids on both ends.
263
+
264
+ On success, surface whatever stable identifier the MCP server returned
265
+ (session id, canvas URL, or scene id) so the user can open the live
266
+ canvas — e.g. `Live canvas: <url>`.
267
+
268
+ ### 5c. Failure handling
269
+
270
+ If ANY `mcp__excalidraw__*` tool call fails — tool error, transport
271
+ error, or the expected tool is missing from the surface — emit EXACTLY
272
+ this message (verbatim) and exit:
273
+
274
+ ```
275
+ Excalidraw MCP renderer failed: <reason>. Re-run with `--mode=file` to generate an offline .excalidraw file.
276
+ ```
277
+
278
+ No retries. No automatic switch to file mode. No partial cleanup of
279
+ already-created MCP elements (v1 leaves them as a debugging artifact;
280
+ v2 may add cleanup).
281
+
282
+ ## 7. Quality pass loop (file mode only)
283
+
284
+ (Step 6 is intentionally reserved for future MCP-side quality work; v2
285
+ ships Step 7 for file mode only.)
286
+
287
+ After Step 4 (file written), if Playwright is installed, run a visual
288
+ quality-pass loop. The loop is capped at **3 iterations**. If
289
+ `validateScene(scene).score >= 70` AND the vision review reports no
290
+ critical issues, exit early.
291
+
292
+ ### 7a. Detect Playwright
293
+
294
+ Probe with:
295
+
296
+ ```bash
297
+ node -e 'import("playwright").then(() => process.stdout.write("yes"), () => process.stdout.write("no"))'
298
+ ```
299
+
300
+ If the result is `no`, skip Step 7 silently and append the following
301
+ one-line tip to the success message printed in Step 4:
302
+
303
+ ```
304
+ Tip: install playwright to enable visual quality-pass on future runs (pnpm add -D playwright && npx playwright install chromium).
305
+ ```
306
+
307
+ ### 7b. Loop body (max 3 iterations)
308
+
309
+ For each iteration `i` in `0..2`:
310
+
311
+ 1. Call `renderToPng({ excalidrawPath })` from `@aperant/core/workflows/diagram`
312
+ via the same Node-invocation pattern Step 4 uses. Capture the
313
+ absolute PNG path.
314
+ 2. Call `validateScene(scene)` from the same module. Capture
315
+ `{warnings, score}`.
316
+ 3. Read the PNG via the `Read` tool (multimodal vision review).
317
+ 4. Decide:
318
+ - If `score >= 70` AND the vision review reports no critical issues
319
+ (overlaps, off-canvas elements, illegible text), exit the loop
320
+ and return success.
321
+ - Else: emit IR patches as a JSON delta. Mutable fields are
322
+ exactly `DiagramNode.x`, `DiagramNode.y`, and `DiagramNode.label`.
323
+ Apply the patches to `scene`, re-call `renderToFile` (re-using
324
+ the slug from Step 4), and continue to the next iteration.
325
+ 5. After 3 iterations: return final state. If unresolved warnings
326
+ remain, print exactly:
327
+
328
+ ```
329
+ Quality pass: <N> warning(s) remain after 3 iterations. See <png-path> to inspect.
330
+ ```
331
+
332
+ ### 7c. Hard rules
333
+
334
+ - Iteration cap is exactly **3** (hard-coded, not configurable in v2).
335
+ - Score threshold is exactly **70** (hard-coded, not configurable in v2).
336
+ - Patch grammar is `{x, y, label}` — no other `DiagramNode`/
337
+ `DiagramEdge` fields are mutable.
338
+ - If `renderToPng` throws `DiagramMissingDep`, treat the same as Step
339
+ 7a's `no` branch (silent skip + tip). Any OTHER `renderToPng` error
340
+ fails the loop and surfaces verbatim to the user.
341
+
342
+ </process>
@@ -0,0 +1,97 @@
1
+ # apt:diagram — design-discipline appendix
2
+
3
+ Loaded into `apt:diagram`'s reasoning context when the skill is invoked
4
+ with `--depth=comprehensive`. Aperant-authored — not a verbatim port. The
5
+ goal: emit a diagram that earns its space on the page, not a free-floating
6
+ box graph that "looks like a diagram."
7
+
8
+ This appendix is a posture loader. It does not change the IR. It changes
9
+ what the agent decides to put *in* the IR.
10
+
11
+ ## Visual pattern library
12
+
13
+ Excalidraw exposes rectangles, ellipses, diamonds, arrows, text, and
14
+ free-form shapes. When you have a choice, the shape should encode
15
+ information the label can't:
16
+
17
+ - **Rectangle** — a unit of work, a service, a process, a system
18
+ component. Default for "this is a thing that exists." The boring,
19
+ honest shape.
20
+ - **Ellipse** — a state, a phase, a "moment in time." Use when the noun
21
+ is more like a place a flow visits than a thing that owns state.
22
+ - **Diamond** — a decision point, a branching condition. If the
23
+ outgoing arrows have different semantics ("yes" / "no" / "retry"),
24
+ the source should be a diamond.
25
+
26
+ v2 only emits rectangles. The IR has no `shape` field on `DiagramNode`,
27
+ and `renderToFile` hard-codes rectangle elements. The choice above is
28
+ informational — it tells you *what richer shapes would mean* so you can
29
+ note the missing semantics in the diagram's accompanying prose if a
30
+ node really wants to be a diamond. Richer shapes are scheduled for v3.
31
+
32
+ ## Isomorphism test
33
+
34
+ The diagram should be *the same shape* as the thing it depicts.
35
+
36
+ If the system has three layers (edge / app / data), the diagram has
37
+ three visually-distinct horizontal zones. If the system has a single
38
+ hub that talks to four leaves, the diagram has a single central node
39
+ with four spokes — not five nodes in a line.
40
+
41
+ Concretely:
42
+
43
+ - Count the "structural axes" in the thing being depicted. Layers?
44
+ Phases? Owners? Each axis should map to a visual axis (vertical /
45
+ horizontal / radial) in the diagram.
46
+ - If you cannot draw the structural axis, the diagram is lying. Either
47
+ add the missing axis or admit you're depicting a different thing.
48
+ - Symmetry in the system should appear as symmetry in the layout.
49
+ Asymmetry is a flag — either it's load-bearing (good — show it) or
50
+ it's noise (bad — fix it).
51
+
52
+ The `validateStructure` validator codifies one slice of this: it checks
53
+ that nodes occupy the top / middle / bottom thirds of the canvas in
54
+ roughly the expected counts. That's a weak proxy — the real check is in
55
+ your eyes.
56
+
57
+ ## Depth assessment
58
+
59
+ Every diagram answers one of two questions: **what** or **what + how**.
60
+
61
+ - A **what** diagram shows the inventory of things and the connections
62
+ between them. "These are the services. They talk to each other."
63
+ v2 targets this depth.
64
+ - A **what + how** diagram additionally encodes the protocol on each
65
+ connection — request shape, retry policy, idempotency key, transport.
66
+ This often requires labels on every edge, sub-groups around clusters
67
+ of services, and sometimes a second pass at a different zoom level.
68
+ v2 does not target this. The IR has no edge-protocol field.
69
+
70
+ Before generating the scene, decide which question the diagram answers.
71
+ If the user prompt implies "what + how" and you can only render "what,"
72
+ say so in the chat so the user knows they're getting the shallower
73
+ picture.
74
+
75
+ ## Multi-zoom architecture
76
+
77
+ A real system has multiple zoom levels:
78
+
79
+ - **Far zoom** — one diagram showing the 4-7 top-level components and
80
+ their primary connections. Fits on a slide.
81
+ - **Mid zoom** — one diagram per top-level component, showing its
82
+ internal modules. 4-7 boxes each, again.
83
+ - **Near zoom** — one diagram per critical interface, showing the
84
+ protocol/sequence.
85
+
86
+ v2 generates one diagram per `apt:diagram` invocation. If a user prompt
87
+ implies a multi-zoom set ("system architecture for the auth flow,"
88
+ where "the auth flow" is itself worth a deeper drawing), the agent
89
+ should:
90
+
91
+ 1. Generate the far-zoom diagram for v2.
92
+ 2. State in the chat that a mid-zoom diagram for the named subsystem
93
+ would be a natural follow-up.
94
+ 3. NOT chain a second `renderToFile` call automatically.
95
+
96
+ The default is one diagram per prompt. Multi-zoom orchestration is a
97
+ v3 problem.
@@ -9,6 +9,8 @@ user_invocable: true
9
9
  internal: false
10
10
  spawns_agent: false
11
11
  agent_name: null
12
+ task_context: create-new
13
+ default_track: STANDARD
12
14
  default_execution_mode: step
13
15
  execution_modes:
14
16
  - auto
@@ -44,6 +46,31 @@ never by asking:
44
46
  These are two postures of the same skill, not two different skills. The
45
47
  intent-detection step below decides which one to enter — same file, same
46
48
  artifact layout, different section populated.
49
+
50
+ **Decision-lock posture loader (Pocock adoption ID-02 + ID-04 — AC11).**
51
+ When entering decision-lock posture, you MUST load
52
+ `appendices/grill-discipline.md` into reasoning context. It carries the
53
+ validated 100-token reframe sentence ("Your job is not to emit a plan;
54
+ your job is to resolve the design tree until planning is mechanical.")
55
+ and the autonomy-aware degradation table (Autonomy 1 grills everything;
56
+ Autonomy 2 batches recommendations; Autonomy 3 auto-locks with three
57
+ escalation triggers — conflict with prior locked decision, critical-path
58
+ file touched, or no defensible default). This appendix is the canonical
59
+ source for the autonomy-aware rule; downstream skills (`apt:improve`,
60
+ `apt:triage`) reference it rather than re-stating the policy. Brainstorm
61
+ posture does NOT load this appendix.
62
+
63
+ **Brainstorm posture zoom-out helper (Pocock adoption AC6 + AC11).**
64
+ When in brainstorm posture and the user's turn contains a zoom-out
65
+ trigger phrase ("give me a broader picture", "I'm lost in this area",
66
+ "explain how this fits", "what's the surrounding architecture", "zoom
67
+ out from X"), load `appendices/zoom-out-helper.md` and follow its
68
+ 3-6-line compressed orientation pattern. The brainstorm posture stays
69
+ active — this is an augmentation, not a pivot. The full router-invocable
70
+ `/apt:zoom-out` skill is the right answer when the user invokes it
71
+ explicitly; this helper is the right answer when the request surfaces
72
+ inside an active brainstorm discussion. Decision-lock posture does NOT
73
+ load this helper (orientation is descriptive, not normative).
47
74
  </objective>
48
75
 
49
76
  <your_environment>
@@ -0,0 +1,104 @@
1
+ <!--
2
+ Adapted from Matt Pocock's MIT-licensed skill suite:
3
+ https://github.com/mattpocock/skills/blob/main/skills/engineering/grill-with-docs
4
+ Licensed under MIT. Modifications: ported as an apt:discuss posture loader,
5
+ extended with the validated 100-token reframe sentence and the
6
+ autonomy-aware degradation table from the Pocock adoption brainstorm
7
+ (Architectural principles to lock §2).
8
+ -->
9
+
10
+ # Grill Discipline — apt:discuss posture loader
11
+
12
+ This appendix loads into `apt:discuss`'s reasoning context whenever the
13
+ skill is invoked in decision-lock posture (or as a sub-step inside
14
+ `apt:improve` / `apt:triage`'s grill loop). It carries two load-bearing
15
+ artifacts:
16
+
17
+ 1. The 100-token **reframe sentence** validated by the V2 grill-comparison
18
+ experiment (43/44 vs 38/44 blind-judge score against Pocock's verbatim
19
+ `grill-with-docs`).
20
+ 2. The **autonomy-aware degradation table** that prevents full-auto runs
21
+ from grinding to a halt grilling every gray area.
22
+
23
+ ## The reframe sentence (validated, 43/44 vs 38/44)
24
+
25
+ > **Your job is not to emit a plan; your job is to resolve the design
26
+ > tree until planning is mechanical.**
27
+
28
+ This sentence is the *first thing* you load into your reasoning context
29
+ when entering decision-lock posture. It does two things at once:
30
+
31
+ - It refuses the "I'll just emit a plan and let the executor figure
32
+ out the gaps" anti-pattern. Plans with unresolved gray areas push the
33
+ cost into execution where rollbacks are 10× more expensive.
34
+ - It frames the goal as *resolving a design tree*, not *answering a
35
+ questionnaire*. The interview-style "ask the user 47 clarifying
36
+ questions" is the failure mode this reframe blocks.
37
+
38
+ The empirical V1 + V2 evidence is in
39
+ `.aperant/experiments/grill-comparison-20260513/SUMMARY-FOR-AGENT-REVIEW.md`.
40
+
41
+ ## Autonomy-aware degradation table (load-bearing)
42
+
43
+ The grill discipline runs at every autonomy level — the *interaction
44
+ shape* degrades, not the discipline itself. This is the canonical
45
+ source for this rule; new skills (apt:improve, apt:triage) reference
46
+ THIS table rather than re-stating the policy.
47
+
48
+ | Autonomy | Mode | Behavior |
49
+ |---|---|---|
50
+ | **1 (Supervised)** | Grill everything | Ask the user for every load-bearing decision. The user reviews each Q&A turn before the next one fires. |
51
+ | **2 (Balanced / Semi)** | Batch-recommend | Auto-recommend per decision; collect all recommendations into a single batch the user reviews at the end. This is the existing `--review-auto` pattern. |
52
+ | **3 (Full auto / YOLO)** | Auto-lock with escalation triggers | Auto-recommend and lock decisions silently. Escalate to the user only when one of THREE triggers fires (below). |
53
+
54
+ ## The three escalation triggers (Autonomy 3 only)
55
+
56
+ At Autonomy 3, the agent locks recommendations silently — **EXCEPT** when:
57
+
58
+ 1. **Conflict with a prior locked decision.** The new recommendation
59
+ contradicts a decision already written to
60
+ `.aperant/context/notes/{task-id}.md` (or any other notes file under
61
+ `.aperant/context/notes/`). Re-litigating a locked decision needs
62
+ human sign-off.
63
+ 2. **Critical-path file touched.** The decision's downstream effect
64
+ modifies a file matching a glob in
65
+ `.aperant/config.json.risk_map.critical_paths` (e.g., auth, billing,
66
+ migration paths). Critical-path changes always escalate at every
67
+ autonomy level — this trigger is the autonomy-3 surface for the same
68
+ policy.
69
+ 3. **No defensible default exists.** Neither AGENTS.md nor an existing
70
+ codebase pattern provides a defensible answer. "Just pick one" is
71
+ not a defensible default; the agent must say "I see two viable
72
+ paths and no precedent — which do you want?"
73
+
74
+ These three triggers cover the cases where a silent auto-lock would
75
+ cause real harm. Everything else gets locked, logged, and surfaced in
76
+ the final report only — not as a blocking prompt.
77
+
78
+ ## Practical consequence for new skills
79
+
80
+ When `apt:improve`'s deepening loop, `apt:triage`'s priority resolution,
81
+ or any other agent reaches a gray area:
82
+
83
+ - It loads THIS appendix into reasoning context.
84
+ - It reads the current autonomy from `.aperant/config.json` (or the
85
+ per-task autonomy from `apt-tools task get`).
86
+ - It enters the matching row of the degradation table.
87
+ - At Autonomy 3, it walks the three triggers before deciding to lock or
88
+ escalate.
89
+
90
+ The "ask first vs lock first" decision is NOT a per-skill policy.
91
+ Reasoning lives here; every grill-loop-bearing skill references it.
92
+
93
+ ## When NOT to load this appendix
94
+
95
+ This appendix is for **decision-lock** posture (convergent discussion
96
+ where the user has a concrete task with implicit gray areas). The
97
+ **brainstorm** posture (divergent — user has a rough vision, exploring
98
+ options) does NOT load this appendix; brainstorm has its own posture
99
+ encoded in apt:discuss's `<objective>` block.
100
+
101
+ `apt:zoom-out` (a sibling skill, also Pocock-adopted) does NOT load
102
+ this appendix. Zoom-out is descriptive ("show me the broader picture"),
103
+ not normative ("lock this decision"). Loading grill-discipline there
104
+ would mis-fire the reframe sentence on a read-only operation.
@@ -0,0 +1,79 @@
1
+ <!--
2
+ Adapted from Matt Pocock's MIT-licensed skill suite:
3
+ https://github.com/mattpocock/skills/blob/main/skills/engineering/zoom-out
4
+ Licensed under MIT. Modifications: ported as a loaded-helper for apt:discuss
5
+ brainstorm mode so the discipline activates without spawning the full
6
+ apt:zoom-out skill (the latter is a router-invocable verb on its own).
7
+ -->
8
+
9
+ # Zoom-Out Helper — apt:discuss brainstorm mode loaded helper
10
+
11
+ This appendix loads into `apt:discuss` brainstorm mode when the user's
12
+ turn contains a zoom-out trigger phrase. The full
13
+ `/apt:zoom-out` skill (router-invocable) is the right answer when the
14
+ user invokes it explicitly; this helper is the right answer when the
15
+ zoom-out request surfaces *inside* a brainstorm discussion.
16
+
17
+ ## When to load this appendix
18
+
19
+ Inside an active `apt:discuss --brainstorm` session, if the user's turn
20
+ contains any of these phrases (or their natural-language variants):
21
+
22
+ - "give me a broader picture"
23
+ - "I'm lost in this area"
24
+ - "explain how this fits"
25
+ - "what's the surrounding architecture"
26
+ - "zoom out from {topic}"
27
+
28
+ …load this appendix into reasoning context and follow the helper
29
+ process below. The brainstorm posture stays active — you don't pivot
30
+ out of `apt:discuss`; you augment its reasoning with the orientation
31
+ discipline.
32
+
33
+ ## Process (helper mode, not full skill)
34
+
35
+ 1. **Identify the area.** Pull the noun phrase from the user's message
36
+ (e.g., "the sparring engine"). If ambiguous, ask a single targeted
37
+ clarifying question — do NOT enter a 20-question interview.
38
+
39
+ 2. **Load CONTEXT.md term-blocks if matching.** Same as the full
40
+ `apt:zoom-out` skill: if the area name matches a term or alias in
41
+ `CONTEXT.md`, pre-load that term-block's definition + flagged
42
+ ambiguities into the orientation.
43
+
44
+ 3. **Emit a compressed orientation INLINE in the discussion.** Format:
45
+
46
+ > **Purpose:** {one sentence}
47
+ > **Entry points:** `{file1}`, `{file2}`
48
+ > **State owners:** `{file3}` ({what state})
49
+ > **External boundaries:** `{file4}` ({what external})
50
+ > **Watch out for:** {one-line fragile area}
51
+
52
+ Three to six lines. The full one-page `apt:zoom-out` report is
53
+ overkill when the user is mid-discussion — they want enough context
54
+ to keep brainstorming, not a separate artifact.
55
+
56
+ 4. **Resume brainstorm posture.** After the orientation block, ask:
57
+ "Want me to keep zooming, lock a decision, or stay in brainstorm?"
58
+ so the user explicitly drives whether to deepen.
59
+
60
+ ## When NOT to load this appendix
61
+
62
+ - In decision-lock posture (the user wants to *resolve* a decision, not
63
+ *orient* themselves) — load `grill-discipline.md` instead.
64
+ - When the user explicitly types `/apt:zoom-out` — they invoked the
65
+ full skill; let that skill run unmodified.
66
+ - In `apt:plan` — the planner's Phase-0 codebase investigation already
67
+ covers orientation. Loading this helper there would duplicate work.
68
+
69
+ ## Relationship to the full apt:zoom-out skill
70
+
71
+ | | `apt:discuss + zoom-out-helper` | `/apt:zoom-out` (full skill) |
72
+ |---|---|---|
73
+ | Invocation | Detected mid-brainstorm | User-explicit verb |
74
+ | Output | 3-6 line inline orientation | One-page report |
75
+ | Side effects | None | None (read-only) |
76
+ | Posture after | Brainstorm continues | Skill exits — no continuation |
77
+
78
+ Same underlying discipline; different surface shapes for different
79
+ work contexts.
@@ -9,6 +9,8 @@ user_invocable: true
9
9
  internal: false
10
10
  spawns_agent: false
11
11
  agent_name: null
12
+ task_context: create-new
13
+ default_track: STANDARD
12
14
  default_execution_mode: auto
13
15
  execution_modes:
14
16
  - auto