@bastani/atomic 0.9.39 → 0.9.40-alpha.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 (261) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +14 -0
  3. package/dist/builtin/intercom/broker/broker.ts +523 -72
  4. package/dist/builtin/intercom/broker/client.ts +136 -5
  5. package/dist/builtin/intercom/broker/database-wake-up-bus.ts +274 -0
  6. package/dist/builtin/intercom/broker/group-membership.ts +2 -2
  7. package/dist/builtin/intercom/broker/multinode-router.ts +1500 -0
  8. package/dist/builtin/intercom/broker/multinode-state-store.ts +569 -0
  9. package/dist/builtin/intercom/broker/open-broker-state.ts +160 -0
  10. package/dist/builtin/intercom/broker/paths.ts +6 -0
  11. package/dist/builtin/intercom/broker/pending-send-registry.ts +14 -0
  12. package/dist/builtin/intercom/broker/recipient-receipts.ts +93 -0
  13. package/dist/builtin/intercom/broker/restoring-recipients.ts +263 -0
  14. package/dist/builtin/intercom/broker/send-handler.ts +241 -25
  15. package/dist/builtin/intercom/broker/session-id-reclaim.ts +41 -0
  16. package/dist/builtin/intercom/broker/socket-writes.ts +47 -0
  17. package/dist/builtin/intercom/broker/spawn.ts +10 -2
  18. package/dist/builtin/intercom/broker/sql-held-send-store.ts +96 -0
  19. package/dist/builtin/intercom/broker/sql-known-session-store.ts +129 -0
  20. package/dist/builtin/intercom/broker/sql-lease-store.ts +194 -0
  21. package/dist/builtin/intercom/broker/sql-outbox-store.ts +249 -0
  22. package/dist/builtin/intercom/broker/sql-pending-ask-store.ts +105 -0
  23. package/dist/builtin/intercom/broker/sql-restoring-reservation-store.ts +295 -0
  24. package/dist/builtin/intercom/broker/sql-sent-message-authority.ts +126 -0
  25. package/dist/builtin/intercom/broker/supervisor-channel.ts +10 -0
  26. package/dist/builtin/intercom/broker/wake-up-bus.ts +60 -0
  27. package/dist/builtin/intercom/index.bundle.mjs +793 -91
  28. package/dist/builtin/intercom/package.json +1 -1
  29. package/dist/builtin/intercom/retry-policy.ts +4 -0
  30. package/dist/builtin/intercom/session-target.ts +24 -0
  31. package/dist/builtin/intercom/types.ts +57 -3
  32. package/dist/builtin/mcp/package.json +1 -1
  33. package/dist/builtin/subagents/CHANGELOG.md +31 -0
  34. package/dist/builtin/subagents/README.md +18 -12
  35. package/dist/builtin/subagents/package.json +1 -1
  36. package/dist/builtin/subagents/skills/agent-browser/SKILL.md +1 -1
  37. package/dist/builtin/subagents/skills/cua-driver/BROWSER.md +55 -8
  38. package/dist/builtin/subagents/skills/cua-driver/EMBEDDING.md +7 -2
  39. package/dist/builtin/subagents/skills/cua-driver/LINUX.md +7 -1
  40. package/dist/builtin/subagents/skills/cua-driver/MACOS.md +151 -27
  41. package/dist/builtin/subagents/skills/cua-driver/RUNTIME.md +1 -1
  42. package/dist/builtin/subagents/skills/cua-driver/SKILL.md +33 -17
  43. package/dist/builtin/subagents/skills/cua-driver/WINDOWS.md +5 -0
  44. package/dist/builtin/subagents/skills/cua-driver/WORKFLOW.md +46 -8
  45. package/dist/builtin/subagents/skills/subagent/SKILL.md +18 -20
  46. package/dist/builtin/subagents/src/extension/index.bundle.mjs +8032 -6034
  47. package/dist/builtin/web-access/package.json +1 -1
  48. package/dist/builtin/workflows/CHANGELOG.md +18 -0
  49. package/dist/builtin/workflows/README.md +1 -1
  50. package/dist/builtin/workflows/package.json +1 -1
  51. package/dist/builtin/workflows/skills/impeccable/SKILL.md +8 -8
  52. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +3 -3
  53. package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +1 -1
  54. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +4 -2
  55. package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +2 -2
  56. package/dist/builtin/workflows/skills/impeccable/reference/craft-floor.md +1 -1
  57. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +22 -9
  58. package/dist/builtin/workflows/skills/impeccable/reference/degraded/finish-reviewer.md +2 -2
  59. package/dist/builtin/workflows/skills/impeccable/reference/distill.md +3 -3
  60. package/dist/builtin/workflows/skills/impeccable/reference/extract.md +3 -3
  61. package/dist/builtin/workflows/skills/impeccable/reference/harden.md +2 -4
  62. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +4 -4
  63. package/dist/builtin/workflows/skills/impeccable/reference/live.md +1 -1
  64. package/dist/builtin/workflows/skills/impeccable/reference/new-work.md +6 -6
  65. package/dist/builtin/workflows/skills/impeccable/reference/onboard.md +3 -3
  66. package/dist/builtin/workflows/skills/impeccable/reference/optimize.md +3 -3
  67. package/dist/builtin/workflows/skills/impeccable/reference/overdrive.md +3 -3
  68. package/dist/builtin/workflows/skills/impeccable/reference/quieter.md +3 -3
  69. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +10 -0
  70. package/dist/builtin/workflows/skills/impeccable/reference/visualize.md +1 -1
  71. package/dist/builtin/workflows/skills/impeccable/scripts/VERSION +1 -1
  72. package/dist/builtin/workflows/skills/impeccable/scripts/impeccable +6 -0
  73. package/dist/builtin/workflows/skills/impeccable/scripts/impeccable.cmd +47 -22
  74. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser-dom.js +34 -1
  75. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser-session.js +25 -1
  76. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +33 -8
  77. package/dist/builtin/workflows/src/durable/journal/resolution.d.ts +7 -7
  78. package/dist/builtin/workflows/src/extension/index.bundle.mjs +22855 -22308
  79. package/dist/builtin/workflows/src/index.js +106 -35
  80. package/dist/cli/args.d.ts +2 -0
  81. package/dist/cli/args.d.ts.map +1 -1
  82. package/dist/cli/args.js +16 -0
  83. package/dist/cli/args.js.map +1 -1
  84. package/dist/core/agent-session-extension-bindings.d.ts +2 -0
  85. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  86. package/dist/core/agent-session-extension-bindings.js +6 -6
  87. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  88. package/dist/core/agent-session-methods.d.ts +6 -3
  89. package/dist/core/agent-session-methods.d.ts.map +1 -1
  90. package/dist/core/agent-session-methods.js.map +1 -1
  91. package/dist/core/agent-session-persistent-custom-messages.d.ts +7 -2
  92. package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
  93. package/dist/core/agent-session-persistent-custom-messages.js +29 -12
  94. package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
  95. package/dist/core/agent-session-recovery.d.ts +14 -0
  96. package/dist/core/agent-session-recovery.d.ts.map +1 -0
  97. package/dist/core/agent-session-recovery.js +83 -0
  98. package/dist/core/agent-session-recovery.js.map +1 -0
  99. package/dist/core/agent-session-tasks.d.ts.map +1 -1
  100. package/dist/core/agent-session-tasks.js +4 -6
  101. package/dist/core/agent-session-tasks.js.map +1 -1
  102. package/dist/core/agent-session-types.d.ts +13 -0
  103. package/dist/core/agent-session-types.d.ts.map +1 -1
  104. package/dist/core/agent-session-types.js.map +1 -1
  105. package/dist/core/agent-session.d.ts +2 -1
  106. package/dist/core/agent-session.d.ts.map +1 -1
  107. package/dist/core/agent-session.js +4 -1
  108. package/dist/core/agent-session.js.map +1 -1
  109. package/dist/core/extensions/api-types.d.ts +6 -2
  110. package/dist/core/extensions/api-types.d.ts.map +1 -1
  111. package/dist/core/extensions/api-types.js.map +1 -1
  112. package/dist/core/extensions/event-results.d.ts +21 -0
  113. package/dist/core/extensions/event-results.d.ts.map +1 -1
  114. package/dist/core/extensions/event-results.js.map +1 -1
  115. package/dist/core/extensions/index.d.ts +1 -1
  116. package/dist/core/extensions/index.d.ts.map +1 -1
  117. package/dist/core/extensions/index.js.map +1 -1
  118. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  119. package/dist/core/extensions/loader-api.js +4 -0
  120. package/dist/core/extensions/loader-api.js.map +1 -1
  121. package/dist/core/extensions/runner-events.d.ts +9 -2
  122. package/dist/core/extensions/runner-events.d.ts.map +1 -1
  123. package/dist/core/extensions/runner-events.js +29 -0
  124. package/dist/core/extensions/runner-events.js.map +1 -1
  125. package/dist/core/extensions/runner.d.ts +5 -3
  126. package/dist/core/extensions/runner.d.ts.map +1 -1
  127. package/dist/core/extensions/runner.js +7 -2
  128. package/dist/core/extensions/runner.js.map +1 -1
  129. package/dist/core/extensions/runtime-types.d.ts +1 -0
  130. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  131. package/dist/core/extensions/runtime-types.js.map +1 -1
  132. package/dist/core/extensions/session-events.d.ts +30 -2
  133. package/dist/core/extensions/session-events.d.ts.map +1 -1
  134. package/dist/core/extensions/session-events.js.map +1 -1
  135. package/dist/core/sdk-types.d.ts +3 -2
  136. package/dist/core/sdk-types.d.ts.map +1 -1
  137. package/dist/core/sdk-types.js.map +1 -1
  138. package/dist/core/sdk.d.ts.map +1 -1
  139. package/dist/core/sdk.js +3 -0
  140. package/dist/core/sdk.js.map +1 -1
  141. package/dist/core/session-storage.d.ts.map +1 -1
  142. package/dist/core/session-storage.js +15 -9
  143. package/dist/core/session-storage.js.map +1 -1
  144. package/dist/core/storage/process-selection.d.ts +39 -0
  145. package/dist/core/storage/process-selection.d.ts.map +1 -0
  146. package/dist/core/storage/process-selection.js +154 -0
  147. package/dist/core/storage/process-selection.js.map +1 -0
  148. package/dist/core/storage/provider.d.ts +6 -1
  149. package/dist/core/storage/provider.d.ts.map +1 -1
  150. package/dist/core/storage/provider.js +3 -2
  151. package/dist/core/storage/provider.js.map +1 -1
  152. package/dist/core/storage/selection.d.ts +1 -1
  153. package/dist/core/storage/selection.d.ts.map +1 -1
  154. package/dist/core/storage/selection.js.map +1 -1
  155. package/dist/core/storage/session/jsonl-session-store.d.ts +2 -0
  156. package/dist/core/storage/session/jsonl-session-store.d.ts.map +1 -1
  157. package/dist/core/storage/session/jsonl-session-store.js +38 -2
  158. package/dist/core/storage/session/jsonl-session-store.js.map +1 -1
  159. package/dist/core/tasks/completion.d.ts +11 -2
  160. package/dist/core/tasks/completion.d.ts.map +1 -1
  161. package/dist/core/tasks/completion.js +40 -16
  162. package/dist/core/tasks/completion.js.map +1 -1
  163. package/dist/core/tasks/pause.d.ts +4 -1
  164. package/dist/core/tasks/pause.d.ts.map +1 -1
  165. package/dist/core/tasks/pause.js +8 -5
  166. package/dist/core/tasks/pause.js.map +1 -1
  167. package/dist/index-extensions.d.ts +1 -1
  168. package/dist/index-extensions.d.ts.map +1 -1
  169. package/dist/index-extensions.js.map +1 -1
  170. package/dist/index.d.ts +2 -1
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +2 -0
  173. package/dist/index.js.map +1 -1
  174. package/dist/main.d.ts.map +1 -1
  175. package/dist/main.js +7 -1
  176. package/dist/main.js.map +1 -1
  177. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  178. package/dist/modes/interactive/components/chat-session-host-rendering.js +11 -1
  179. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  180. package/dist/modes/interactive/components/chat-session-host-state.d.ts +2 -0
  181. package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
  182. package/dist/modes/interactive/components/chat-session-host-state.js +2 -0
  183. package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
  184. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  185. package/dist/modes/interactive/interactive-deferred-startup.js +4 -0
  186. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  187. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -1
  188. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  189. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  190. package/dist/modes/interactive/interactive-render-chat.js +3 -0
  191. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  192. package/dist/modes/interactive/interactive-session-routing.js +2 -0
  193. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  194. package/dist/modes/interactive/interactive-session-runtime.d.ts +2 -1
  195. package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
  196. package/dist/modes/interactive/interactive-session-runtime.js +29 -0
  197. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  198. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  199. package/dist/modes/interactive/interactive-startup.js +4 -1
  200. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  201. package/dist/modes/interactive-engine/engine-args.d.ts.map +1 -1
  202. package/dist/modes/interactive-engine/engine-args.js +4 -0
  203. package/dist/modes/interactive-engine/engine-args.js.map +1 -1
  204. package/dist/modes/interactive-engine/engine-render-service.d.ts.map +1 -1
  205. package/dist/modes/interactive-engine/engine-render-service.js +4 -4
  206. package/dist/modes/interactive-engine/engine-render-service.js.map +1 -1
  207. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  208. package/dist/modes/interactive-engine/isolated-runtime.js +4 -0
  209. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  210. package/dist/modes/interactive-engine/remote-renderer.js +1 -1
  211. package/dist/modes/interactive-engine/remote-renderer.js.map +1 -1
  212. package/dist/modes/rpc/rpc-client-api.d.ts +4 -1
  213. package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -1
  214. package/dist/modes/rpc/rpc-client-api.js +4 -0
  215. package/dist/modes/rpc/rpc-client-api.js.map +1 -1
  216. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  217. package/dist/modes/rpc/rpc-command-handler.js +3 -0
  218. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  219. package/dist/modes/rpc/rpc-command-timeouts.d.ts.map +1 -1
  220. package/dist/modes/rpc/rpc-command-timeouts.js +1 -0
  221. package/dist/modes/rpc/rpc-command-timeouts.js.map +1 -1
  222. package/dist/modes/rpc/rpc-input-scheduler.d.ts.map +1 -1
  223. package/dist/modes/rpc/rpc-input-scheduler.js +6 -1
  224. package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -1
  225. package/dist/modes/rpc/rpc-types.d.ts +12 -1
  226. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  227. package/dist/modes/rpc/rpc-types.js.map +1 -1
  228. package/dist/utils/shell.d.ts.map +1 -1
  229. package/dist/utils/shell.js +44 -11
  230. package/dist/utils/shell.js.map +1 -1
  231. package/dist/utils/tools-manager.js +1 -1
  232. package/dist/utils/tools-manager.js.map +1 -1
  233. package/docs/background-tasks.md +5 -3
  234. package/docs/computer-use.md +2 -2
  235. package/docs/environment-variables.md +4 -1
  236. package/docs/extensions/events.md +29 -2
  237. package/docs/getting-started/first-session.md +1 -1
  238. package/docs/guides/intercom.md +1 -1
  239. package/docs/intercom/operations.md +103 -1
  240. package/docs/intercom/reference.md +10 -3
  241. package/docs/intercom.md +8 -6
  242. package/docs/keybindings.md +1 -1
  243. package/docs/models.md +1 -1
  244. package/docs/providers.md +4 -2
  245. package/docs/reference/cli.md +5 -0
  246. package/docs/rpc/protocol.md +19 -0
  247. package/docs/rpc.md +3 -0
  248. package/docs/sdk/web-server.md +1 -1
  249. package/docs/sdk.md +5 -2
  250. package/docs/sessions.md +17 -1
  251. package/docs/settings.md +5 -3
  252. package/docs/skills.md +1 -1
  253. package/docs/storage.md +54 -3
  254. package/docs/subagents.md +49 -9
  255. package/docs/usage.md +1 -1
  256. package/docs/windows.md +14 -4
  257. package/docs/workflows/api-reference.md +1 -1
  258. package/docs/workflows/authoring.md +1 -1
  259. package/docs/workflows/operations.md +10 -6
  260. package/npm-shrinkwrap.json +37 -37
  261. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/web-access",
3
- "version": "0.9.39",
3
+ "version": "0.9.40-alpha.1",
4
4
  "private": true,
5
5
  "description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
6
6
  "contributors": [
@@ -6,6 +6,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.9.40-alpha.1] - 2026-10-20
10
+
11
+ ### Added
12
+
13
+ - The workflow journal can be selected for one process with `ATOMIC_WORKFLOWS_JOURNAL`, `ATOMIC_STORAGE`, or Atomic's `--storage` and `--storage-file` flags, using the same JSON as the `workflows.journal` and `storage` settings. Setting `ATOMIC_WORKFLOWS_JOURNAL` together with `ATOMIC_WORKFLOW_JOURNAL_PATH` is rejected as a conflict ([#3783](https://github.com/bastani-inc/atomic/issues/3783)).
14
+
15
+ ### Changed
16
+
17
+ - Updated the bundled Impeccable skill to 4.7.0 with engine 0.1.16. Critique and audit can scan a running Electron, NW.js, CEF, or WebView2 app window through its debugging port (`impeccable detect --cdp 9222`), and critique runs its design review on iOS, Android, and adaptive projects instead of reporting an empty web scan as clean. New `straggler` and `unbalanced-heading` typography checks flag a paragraph ending on one word and a heading whose last line is a stub, and the detector raises fewer false alarms on hidden, screen-reader-only, and layered content. Decision and review pages follow the OS dark mode, `context` offers only workspaces that render a UI as targets, and the Claude Code design hook can be installed in your user settings instead of the project's. Live Mode now starts on LAN and Tailscale addresses over plain HTTP, copying works there when the clipboard API is unavailable, and an interrupted engine download cleans up after itself. Atomic's launcher still turns off the engine's choice reports and update check by default.
18
+
19
+ ### Fixed
20
+
21
+ - Resuming a workflow restores the background subagents its stages launched and delivers the stages' interrupted messages before the stage continues. Both happen visibly in the stage, and stages stay addressable at the same `workflow:<rootRunId>/...` targets ([#3760](https://github.com/bastani-inc/atomic/issues/3760)).
22
+ - An interrupted workflow run stays addressable after the session that launched it restarts, before you run `/workflow resume`. Sends to `workflow:<rootRunId>/<stage>` and `workflow:<rootRunId>/**` are queued in the run's own journal instead of failing with `Session not found`, and `intercom list` shows the run's stages as pending. Each queued message is delivered exactly once when its stage is live again, including messages sent while resume is starting. A queued message no longer makes a resume that started at the same time fail as stale. The background subagents that the run's stages launched stay addressable in the same interval: sends to them wait and are delivered once after the resumed stage restores them. If another Atomic session resumes the run instead, that session takes over the run's Intercom targets and the sends still waiting for the subagents get an error saying so ([#3760](https://github.com/bastani-inc/atomic/issues/3760)).
23
+ - A session created with its own `agentDir` now keeps its workflow runs in the same storage as its sessions. Relative paths, `{ file }` secrets, and storage adapters in a shared `storage` selection, from settings or from `ATOMIC_STORAGE`/`--storage`, previously resolved against the default Atomic home for workflow runs, and the default journal ignored the custom `agentDir` ([#3783](https://github.com/bastani-inc/atomic/issues/3783)).
24
+ - On Windows, removing a workflow's temporary worktree now deletes the worktree directory and leaves the main checkout's `node_modules` alone. Atomic unlinks the worktree's `node_modules` junction, and any other directory it linked, before asking Git to remove the worktree. Current Git for Windows left these worktrees behind, and older releases could delete the main checkout's `node_modules` through the junction. If Atomic cannot inspect or unlink one of these links, it leaves the worktree and its branch in place rather than risk Git following the link.
25
+ - Killing a workflow run while it waits, after Atomic restarts, for `/workflow resume` now ends the background subagents its stages launched. Their launch cards no longer show them as resumable, and reopening a stage's session no longer restores them ([#3784](https://github.com/bastani-inc/atomic/pull/3784)).
26
+
9
27
  ## [0.9.39] - 2026-10-19
10
28
 
11
29
  ### Added
@@ -846,7 +846,7 @@ The live session is unbounded: accepted variants and steered edits are written i
846
846
 
847
847
  The session starts at `user-feedback-N-start`; durable `live-poll-N-M` and `live-reply-N-M` tool nodes own polling and acknowledgements, while `live-generate-*`, `live-steer-*`, `live-manual_edit_apply-*`, and `live-variant_mount_failed-*` mint model stages. Replies pass the event id before the status. Successful `variant_mounted` events are journal-only; `accept`, `discard`, and `prefetch` mint no model stage, and `timeout` is absorbed in the poll node. Nonzero helper exits fail the run rather than looking like timeouts. No `<artifact_dir>/feedback/` directory or per-session record is written.
848
848
 
849
- The poll and reply nodes run the bundled Impeccable 4.5.2 launcher (`skills/impeccable/scripts/impeccable`, or `impeccable.cmd` on Windows) with the `live-poll` verb; the launcher runs the engine binary beside it or downloads and checksum-verifies the pinned engine release on first use, so a machine without network access needs `IMPECCABLE_BIN` pointed at a preinstalled engine. Live sessions persist the selected app root for every helper and support SvelteKit, Nuxt, TanStack Start, Astro, Next.js, Vite, and static HTML injection.
849
+ The poll and reply nodes run the bundled Impeccable 4.7.0 launcher (`skills/impeccable/scripts/impeccable`, or `impeccable.cmd` on Windows) with the `live-poll` verb; the launcher runs the engine binary beside it or downloads and checksum-verifies the pinned engine release on first use, so a machine without network access needs `IMPECCABLE_BIN` pointed at a preinstalled engine. Live sessions persist the selected app root for every helper and support SvelteKit, Nuxt, TanStack Start, Astro, Next.js, Vite, and static HTML injection.
850
850
 
851
851
  Research context moves between stages as artifact files, not inline prompt payloads: the project design context is written to `<artifact_dir>/design-context.md` and the curated references brief to `<artifact_dir>/references.md`; `reference-discovery`, `generate-1`, and `exporter` read the required files via `reads`.
852
852
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/workflows",
3
- "version": "0.9.39",
3
+ "version": "0.9.40-alpha.1",
4
4
  "private": true,
5
5
  "description": "Atomic extension for multi-stage workflow authoring and execution.",
6
6
  "contributors": [
@@ -1,24 +1,24 @@
1
1
  ---
2
2
  name: impeccable
3
- description: Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks.
4
- version: 4.5.2
3
+ description: "Use when the user wants to design, redesign, shape, critique, audit, polish, simplify, harden, animate, or otherwise improve a frontend interface: websites, landing pages, dashboards, product UI, components, forms, settings, onboarding, empty states, and native iOS or Android screens. Handles UX review, hierarchy, layout, typography, color, motion, UX copy, accessibility, responsive behavior, edge cases, and capturing or documenting design systems (DESIGN.md, tokens). Also for making bland UI bolder, loud UI quieter, or ambitious visual effects. Not for backend-only or non-UI tasks."
4
+ version: 4.7.0
5
5
  license: Apache 2.0
6
6
  metadata:
7
7
  github-repo: https://github.com/pbakaus/impeccable
8
8
  github-path: .pi/skills/impeccable
9
- github-ref: refs/tags/skill-v4.5.2
10
- github-tree-sha: b8337bb1f0256bf3ed6231552d4e2cb5e8eb0223
9
+ github-ref: refs/tags/skill-v4.7.0
10
+ github-tree-sha: f90e37ea2e9987475f4bdc263cf9d60499dba0ec
11
11
  allowed-tools:
12
12
  - Bash(npx impeccable *)
13
13
  - Bash(.pi/skills/impeccable/scripts/impeccable *)
14
14
  ---
15
15
 
16
- This skill gives you the tools and permission to create design that earns to be called out-of-distribution craft: Whereas before, your design work would have been safe, timid and measured, you now approach every design task as an award-winning design director with impeccable understanding for what makes exceptional design work: production-grade code, peak creativity, a clear POV, deep understanding of the needs of the client and users, and exceptional craft.
16
+ This skill gives you the tools and permission to make design that earns the name out-of-distribution craft. Work as an award-winning design director would: production-grade code, a clear POV, a deep grasp of what the client and its users need, and exceptional craft.
17
17
 
18
18
  Core principles:
19
- - Go all out. No hedging, no shortcuts. The deliverable must be complete (except assets the user must provide).
20
- - Dream big and bold. Distinct, beautiful, outstanding and highly inspiring work.
21
- - Verify in bounded passes, not a loop, and the ceiling covers the whole cycle: screenshots, defect scans, micro-edits, and rebuilds alike. Build fully, inspect once with a batched round (desktop and mobile together on the web; the shipped device classes on a native platform), fix everything it shows in one batch, confirm with at most one more round, and stop polishing. Open-ended self-QA burns the user's money doing worse what the finish handoffs do better.
19
+ - Finish the job. No hedging, no shortcuts: the deliverable is complete, except assets the user must provide.
20
+ - Scale ambition to the surface's mode (see Modes). Persuade and Experience get full commitment: bold, distinct work with a point of view. On Operate and Read, ambition shows as precision and restraint, and patterns the visitor already knows earn their place.
21
+ - Verify by looking at the rendered result at the sizes it ships at, and batch the checks: fix what one look shows before looking again, rather than screenshotting after every tweak.
22
22
 
23
23
  ## Setup
24
24
 
@@ -28,7 +28,7 @@ Understand what needs adaptation and why:
28
28
  - What won't work? (Hover states on touch, tiny touch targets)
29
29
  - What's inappropriate? (Desktop patterns on mobile, mobile patterns on desktop)
30
30
 
31
- **CRITICAL**: Adaptation is rethinking the experience for the new context, not scaling pixels.
31
+ Adaptation is rethinking the experience for the new context, not scaling pixels.
32
32
 
33
33
  ## Plan Adaptation Strategy
34
34
 
@@ -165,9 +165,9 @@ Choose appropriate breakpoints:
165
165
  - Persistent side navigation on desktop
166
166
  - Breadcrumbs on smaller screens for context
167
167
 
168
- **IMPORTANT**: Test on real devices. Device emulation in DevTools is helpful but not perfect.
168
+ Test on real devices. DevTools emulation is a useful first pass but misses real touch, performance, and browser chrome.
169
169
 
170
- **NEVER**:
170
+ **Avoid**:
171
171
  - Hide core functionality on mobile (if it matters, make it work)
172
172
  - Assume desktop = powerful device (consider accessibility, older machines)
173
173
  - Use different information architecture across contexts (confusing)
@@ -50,7 +50,7 @@ Reconform, don't reflow. Replace web navigation with the platform's model, HTML-
50
50
 
51
51
  When the adaptation feels native to each context, hand off to `/impeccable polish` for the final pass.
52
52
 
53
- **NEVER**:
53
+ **Avoid**:
54
54
  - Ship a stretched phone layout on a tablet
55
55
  - Port one platform's controls or navigation onto the other
56
56
  - Hide core functionality on smaller devices (if it matters, make it work)
@@ -59,6 +59,8 @@ Run comprehensive checks across 5 dimensions. Score each dimension 0-4 using the
59
59
 
60
60
  Run the bundled detector and verify each finding in context. Look for repeated implementation shortcuts, design-system drift, misleading or decorative content, and structure that is interchangeable with an unrelated product. Keep deterministic findings separate from visual judgment and call out false positives.
61
61
 
62
+ **Desktop apps** (Electron, NW.js, CEF, WebView2): launch the app with a local DevTools port (`--remote-debugging-port=9222`, or `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=9222` for WebView2; keep it on 127.0.0.1, never exposed), seed the state to audit, keep the window on screen (a hidden one skips the pixel contrast reads), then run `.pi/skills/impeccable/scripts/impeccable detect --cdp 9222 --target <part of the page URL or title> --json`. It returns the same JSON as a URL scan and leaves the window as found. Take screenshots through the harness's CDP tooling, and leave the window as you found it too. Tauri on macOS (WKWebView) and on Linux (WebKitGTK) expose no CDP: scan the source and say the rendered check did not run.
63
+
62
64
  **Score 0-4**: 0=systemic drift, 1=major repeated failures, 2=several verified issues, 3=minor isolated issues, 4=coherent and intentional
63
65
 
64
66
  ## Generate Report
@@ -127,9 +129,9 @@ After presenting the summary, tell the user:
127
129
  >
128
130
  > Re-run `/impeccable audit` after fixes to see your score improve.
129
131
 
130
- **IMPORTANT**: Be thorough but actionable. Too many P3 issues creates noise. Focus on what actually matters.
132
+ Keep P3s few: a long tail of minor issues buries the ones that matter.
131
133
 
132
- **NEVER**:
134
+ **Avoid**:
133
135
  - Report issues without explaining impact (why does this matter?)
134
136
  - Provide generic recommendations (be specific and actionable)
135
137
  - Skip positive findings (celebrate what works)
@@ -129,9 +129,9 @@ After presenting the summary, tell the user:
129
129
  >
130
130
  > Re-run `/impeccable audit` after fixes to see your score improve.
131
131
 
132
- **IMPORTANT**: Be thorough but actionable. Too many P3 issues creates noise. Focus on what actually matters.
132
+ Keep P3s few: a long tail of minor issues buries the ones that matter.
133
133
 
134
- **NEVER**:
134
+ **Avoid**:
135
135
  - Report issues without explaining impact (why does this matter?)
136
136
  - Provide generic recommendations (be specific and actionable)
137
137
  - Skip positive findings (celebrate what works)
@@ -4,7 +4,7 @@ Load this after the direction is settled, and build without announcing the check
4
4
 
5
5
  ## Verify
6
6
 
7
- Each of these is a check on the built result, not an intention. Run them together in the batched inspection rounds, not as separate screenshot trips; the checks share one render.
7
+ Each of these is a check on the built result, not an intention. Run them together in each batched look at the render, not as separate screenshot trips; the checks share one render.
8
8
 
9
9
  - **Contrast:** body and placeholder text ≥4.5:1, large text ≥3:1. On colored surfaces tint secondary text from that hue or the foreground; never gray.
10
10
  - **Depth:** shadows carry an offset and a soft blur. A zero-offset colored halo is decoration.
@@ -4,11 +4,11 @@ Resolve one stable target, run two independent assessments, synthesize a design
4
4
 
5
5
  ### Hard Invariants
6
6
 
7
- - Assessment A (design review) and Assessment B (detector/browser evidence) are both required.
8
- - Assessment A and B MUST run as two isolated sub-agents whenever a sub-agent/Task tool is exposed. Running them inline in this context is "possible" but is NOT permitted; it is a degraded run. Inline is allowed ONLY when no sub-agent tool exists (or the user declined, on harnesses that ask).
7
+ - Assessment A (design review) and Assessment B (detector/browser evidence) are both required, except on a native platform (see Assessment Orchestration).
8
+ - Assessment A and B MUST run as two isolated sub-agents whenever a sub-agent/Task tool is exposed. Running them inline in this context is "possible" but is NOT permitted; it is a degraded run. Inline is allowed ONLY when no sub-agent tool exists (or the user declined, on harnesses that ask). Native platforms run A alone (see Assessment Orchestration).
9
9
  - If you degrade for any reason, the report's first line MUST be a banner: `⚠️ DEGRADED: single-context (<reason>)`. A silent degraded critique is a failed critique.
10
10
  - Assessment A must finish before detector findings enter the parent synthesis context. Detector output is deterministic, but it still anchors judgment.
11
- - A skipped detector is a failed critique run unless `impeccable detect` is missing or crashes after a real attempt.
11
+ - A skipped detector is a failed critique run unless `impeccable detect` is missing or crashes after a real attempt, or the platform is native (see Assessment Orchestration).
12
12
  - Viewable targets require browser inspection when available.
13
13
  - Any local server started only for critique visualization must run in the background, have a recorded stop method, and be stopped before final reporting unless the user asks to keep it.
14
14
  - Do not claim a user-visible overlay exists unless script injection succeeded and the detector ran in the page.
@@ -30,15 +30,18 @@ Resolve one stable target, run two independent assessments, synthesize a design
30
30
 
31
31
  ### Assessment Orchestration
32
32
 
33
+ **Native platforms** (`ios` / `android` / `adaptive`): Assessment B does not apply, because `impeccable detect` and the browser overlay read only web markup. Run Assessment A alone in this context and skip both sub-agent gates below, the Codex permission question included: with no B there is nothing to isolate A from, so this is the complete native method and carries no degraded banner. Do not run `impeccable detect` on native source; its empty result reads as clean.
34
+
33
35
  Delegate Assessment A and Assessment B to separate sub-agents. They must not see each other's output. Do not show findings to the user until synthesis.
34
36
 
35
37
  Sub-agent gate (all harnesses):
36
38
  - Unless a harness-specific gate below overrides this, spawn A and B as two isolated, parallel sub-agents whenever a sub-agent/Task tool is exposed. This is the default and is mandatory; do not run them inline because it is faster.
39
+ - Desktop apps (see **Desktop apps** under Assessment B) are the one exception to parallel: both sub-agents would drive the app's single window at once. Seed the window, spawn A, wait until it has finished and put the window back, then spawn B. They are still two isolated sub-agents, so this is not the degraded path.
37
40
  - "Unavailable" means exactly one thing: no sub-agent/Task tool is exposed in this session (or, on harnesses that ask, the user declined). It does not mean inconvenient.
38
41
  - If and only if sub-agents are unavailable, fall back sequentially: finish and record Assessment A, then run Assessment B, then synthesize, and emit the degraded banner.
39
42
  - Whichever path you take, declare it in the report header (see Report header provenance). Skipping sub-agents without the banner is the most common failure of this command.
40
43
 
41
- If browser automation is available, each assessment creates its own new tab. Never reuse an existing tab, even if it is already at the right URL.
44
+ If browser automation is available, each assessment creates its own new tab. Never reuse an existing tab, even if it is already at the right URL. Desktop apps are the exception (see **Desktop apps** under Assessment B).
42
45
 
43
46
  ### Assessment A: Design Review
44
47
 
@@ -55,7 +58,7 @@ Return: design-specificity verdict, heuristic scores, cognitive load, emotional
55
58
 
56
59
  ### Assessment B: Detector + Browser Evidence
57
60
 
58
- Run the bundled detector and browser visualization evidence. Assessment B is mandatory and must remain isolated from Assessment A until both are complete.
61
+ Run the bundled detector and browser visualization evidence. On web, Assessment B is mandatory and must remain isolated from Assessment A until both are complete.
59
62
 
60
63
  CLI scan:
61
64
  ```bash
@@ -73,16 +76,25 @@ Browser visualization is required for a viewable target when browser automation
73
76
  1. Create a fresh tab and navigate. Prefer the harness's native/browser-canvas screenshot path before hand-rolling a Playwright/Puppeteer script; only fall back to a custom script when no native browser tool is exposed.
74
77
  2. Preflight mutable injection by setting `document.title` and appending a `<script>` tag. Read-only evaluate APIs do not count.
75
78
  3. If mutation is unavailable, skip live server, browser presentation, and injection; report fallback signal.
76
- 4. If mutation is available, start `.pi/skills/impeccable/scripts/impeccable live-server --background`, present the browser if supported, label `[Human]`, scroll top, inject `http://localhost:PORT/detect.js`, wait 2-3 seconds, read `impeccable` console messages, then stop the live server.
79
+ 4. If mutation is available, start `.pi/skills/impeccable/scripts/impeccable live-server --background`, present the browser if supported, label `[Human]`, scroll top, inject `http://localhost:PORT/detect.js`, wait 2-3 seconds, read `impeccable` console messages, then run `.pi/skills/impeccable/scripts/impeccable live-server stop --keep-inject`. The overlay went in through the browser, so the project's HTML has no script tag to strip; a bare `stop` also runs `live-inject --remove` against the project's entry file, an edit a read-only critique should not make.
77
80
  5. For multi-view targets, inject on 3-5 representative pages.
78
81
 
82
+ **Desktop apps** (Electron, NW.js, CEF, WebView2): there is no URL to open, so Assessment B attaches to the running app instead.
83
+
84
+ 1. Launch the app with a local DevTools port: `--remote-debugging-port=9222` (Electron, NW.js, CEF), or `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=9222` for WebView2. Keep the port on 127.0.0.1 and never expose it beyond this machine; prefer a test profile and test data.
85
+ 2. Seed the state under review (route, open panel, theme, data). The scan reads the window as it stands. Keep the window on screen: a minimized or hidden window scans without the pixel contrast reads.
86
+ 3. Run `.pi/skills/impeccable/scripts/impeccable detect --cdp 9222 --target <part of the page URL or title> --json`. It returns the same JSON as a URL scan and leaves the page as found. With several pages open it fails and lists them; rerun with a `--target` that names one.
87
+ 4. Take screenshots through the harness's CDP tooling (`Page.captureScreenshot` on the same target). Skip the live-server overlay: there is no `[Human]` tab.
88
+
89
+ The app has one window, so the assessments take turns in it instead of opening tabs (A, then B; see the sub-agent gate), and each must leave it as found: put back any route, scroll, theme, or panel it changed. Tauri on macOS (WKWebView) and on Linux (WebKitGTK) expose no CDP: run Assessment A and the source scan only, and say so in Run Notes.
90
+
79
91
  Return: CLI findings JSON/counts, browser console findings if applicable, false positives, and skipped/failed browser steps with concrete reasons.
80
92
 
81
93
  After Assessment B returns usable CLI findings, reuse them. Do not rerun `impeccable detect` in the parent unless Assessment B failed, was truncated, or omitted count, rule names, or file locations.
82
94
 
83
95
  ### Generate Combined Critique Report
84
96
 
85
- Synthesize both assessments into a single report. Do NOT simply concatenate. Weave the findings together, noting where the LLM review and detector agree, where the detector caught issues the LLM missed, and where detector findings are false positives.
97
+ Synthesize both assessments into a single report. Do not simply concatenate. Weave the findings together, noting where the LLM review and detector agree, where the detector caught issues the LLM missed, and where detector findings are false positives.
86
98
 
87
99
  The chat response is the primary user-facing deliverable. Present the full structured critique below in chat; do not replace it with a summary and a link. The persisted snapshot is an archive of that run.
88
100
 
@@ -93,6 +105,7 @@ Structure your feedback as a design director would:
93
105
  The report's first line MUST declare how the assessments were run, so a degraded run is never silent:
94
106
  - Dual-agent: `Method: dual-agent (A: <agent-id> · B: <agent-id>)`
95
107
  - Degraded: `⚠️ DEGRADED: single-context (<reason, e.g. no sub-agent tool exposed>)`
108
+ - Native: `Method: design review only (detector not applicable, native platform)`
96
109
 
97
110
  #### Design Health Score
98
111
  > *Consult the [Heuristics Scoring Guide](#heuristics-scoring-guide) section below.*
@@ -125,7 +138,7 @@ Be honest with scores. A 4 means genuinely excellent. Most real interfaces score
125
138
 
126
139
  **LLM assessment**: Your unanchored evaluation of design specificity. Cover overall coherence, structural sameness, category-interchangeable choices, and missed opportunities for product character.
127
140
 
128
- **Deterministic scan**: Summarize what the automated detector found, with counts and file locations. Note any additional issues the detector caught that you missed, and flag any false positives.
141
+ **Deterministic scan**: Summarize what the automated detector found, with counts and file locations. Note any additional issues the detector caught that you missed, and flag any false positives. On a native platform, write `not applicable (native platform)` instead.
129
142
 
130
143
  **Visual overlays** (if injection succeeded): Tell the user that overlays are now visible in the **[Human]** tab in their browser, highlighting the detected issues. Summarize what the console output reported. If browser visualization was attempted but injection failed, say that no reliable user-visible overlay is available and report the fallback signal instead.
131
144
 
@@ -226,7 +239,7 @@ This is fire-and-forget. Do not show the user the helper's JSON output; only the
226
239
 
227
240
  Ask in the same message that carries the report, with the report written out first and the question last. Do not split the two across turns: a turn that ends on the report is a turn that ends, and the questions never arrive. Order within the message is what matters, because prose emitted after a structured question is withheld until the user answers.
228
241
 
229
- Ask questions along these lines (adapt to the specific findings; do NOT ask generic questions):
242
+ Ask questions along these lines (adapt to the specific findings; do not ask generic questions):
230
243
 
231
244
  1. **Priority direction**: Based on the issues found, ask which category matters most to the user right now. For example: "I found problems with visual hierarchy, color usage, and information overload. Which area should we tackle first?" Offer the top 2-3 issue categories as options.
232
245
 
@@ -19,9 +19,9 @@ Expect: the original request; the confirmed user answers; the artifact path(s);
19
19
  1. **Persistence.** PRODUCT.md exists. On a comp-led build, `.impeccable/build/state.json` exists and every phase before `review` is `closed` or explicitly `skipped`; an open or failed phase is a material finding. A comp-led config with no state file, or a state whose `comps` phase is neither `closed` nor `skipped`, means the comp round was skipped and the build ran from a world description alone, a material finding that outranks craft; a phase closed with a `forced` record is disclosed as a material finding unless the user downgraded the comp in words the packet quotes; a state file whose `hero.gate.score` sits under 0.72, or a missing state file, means the reproduction ran unproven, a material finding, and `.impeccable/review/hero-repro.png` must exist either way. When DESIGN.md predates this build (an extension or redesign), it matches the built world; on a new world it is written after this review by the documenter, so its absence here is not a finding. When comp-round comps exist under `.impeccable/mocks/`, an approval record exists too: the surface brief naming the approved comp, or an `approved` flag in its sidecar. Comp-round comps with no recorded pick mean the approval point was skipped, a material finding. Files under `.impeccable/mocks/decision/` are exempt: they are the direction round's dealt hand, produced before any comp round, and imply no approval whatever the build path; a code-led build has no comp round at all.
20
20
  2. **Fidelity.** Start from the measurement, then judge what it cannot: read `.impeccable/review/diff/final/report.json` (and hero) first; every region scored `missing` or `contradicted` is a matrix row in that state unless the paired crop under `regions/` shows the score is wrong, and you say why; a region scored `match` still gets your eye for lettering character and material, which the numbers do not measure. Then, against your own element inventory of the approved comp, never against the contract's summary of it: topology, reading order, focal scale, overlaps and z-order, density, signature geometry, the primary action's treatment (a CTA the comp physically works, dissolves, or stamps is a signature element; its plain-rectangle rendition is contradicted), navigation items and icons, headline levels and scale relationships. Classify every salient element: match, acceptable adaptation, missing, contradicted, or added without approval. Three rows are mandatory in every matrix. TYPE: the display lettering's character, compression, width, weight, contrast, terminals, against the comp's; a face of a different character is contradicted however the layout matches. MATERIAL: an element rendered as flat CSS or clean vector where the comp shows painted, textured, dimensional, or photographic material is contradicted regardless of placement; medium is part of the promise. GROUND: the page field's value and temperature against the comp's, sampled from pixels on both sides when tooling allows rather than judged from memory, and read as the net on-screen result where a texture or tile paints over the base color; a ground warmer or cooler than the comp's is contradicted however faithfully the layout matches, and drift toward the rendition prior (warm cream on light grounds, blue-black slate on dark) is the direction to hunt. With no approved comp, TYPE and MATERIAL do not lapse: judge them against the contract's OWN-WORLD and the world's real materials, and treat faked physicality (CSS bevels, embossing, stamped-metal or chalk effects imitating a material the page never renders) as contradicted on its face; imitation material is the single most reliable mark of machine-made design. GROUND narrows rather than lapses: with no comp to sample, a color OWN-WORLD names is the target and the same warmer-or-cooler judgment applies; when OWN-WORLD names none, there is no GROUND authority, and the review says so in place of a verdict, because a target the reviewer invents turns the check into taste. A critique-reference comp on such a build is provocation, not spec: no element matrix, no adaptation citations, no asset obligations; its one contribution is what the image dared that the build did not, and dares worth adopting enter material_fixes as ordinary ordered fixes. An adaptation counts as intentional only when it cites the user answer, surface brief, accessibility need, or product truth that forced it; an uncited deviation is a defect. A missing signature element, a changed topology, or content added without approval fails fidelity and outranks every craft point in material_fixes. When MATERIAL is contradicted on the focal element, or contradiction is the page rather than the exception, stop ordering repairs: make the first material fix a rebuild directive naming the comp regions to re-derive and the assets to produce; a list of patches against a rejected page launders the rejection into an approval. A fix that requires producing an asset says so explicitly ("produce: <region> as a raster asset"), never phrased as a style adjustment the parent will answer with CSS. The comp is the spec for composition, topology, element inventory, density, lettering character, and material; it is not a pixel spec for semantics, accessibility, or responsive reflow, and that allowance covers translation, never replacement.
21
21
  3. **Ceiling.** Against the QUALITY BAR card: name the world's native devices the build left unused, frame, depth, lettering treatment, ornament density, motion. The card governs commitment and finish, never composition.
22
- 4. **Contract, promise by promise.** First verify FORM carries the seed key the concept roll printed; a contract with no seed key, or one the parent cannot corroborate, means the roll was skipped, a material fix ahead of any craft point. Then, for each of the five blocks: does the render keep the promise? Apply the memory test to the first viewport.
22
+ 4. **Contract, promise by promise.** First verify FORM carries the seed reference the concept roll printed (`seed:` and 16 hex), corroborated against the roll output the parent saw or with `impeccable concept-seed --check-seed <reference>` (exit 0 means this machine rolled it). A raw seed key in FORM is itself a material fix: the brief is committed, and the key must not be. `seed: none (unavailable)` stands only when the roll printed SEED REFERENCE unavailable, which `--check-seed none` confirms with exit 0. Any other contract with no reference, or one neither source corroborates, means the roll was skipped, a material fix ahead of any craft point. Then, for each of the five blocks: does the render keep the promise? Apply the memory test to the first viewport.
23
23
  5. **Truth.** Demonstration data authored and labeled synthetic; no invented commercial claims; unanswered claims present as marked placeholders, not omissions. Every raster region of the spec shipped as its plate (the spec names the file; the page references it; the region's diff row is not `missing`), not a gradient, an inline SVG, or a many-vertex `clip-path` standing in for it, and every produced asset visibly present in the screenshots; an asset applied at near-zero opacity or buried behind a wash is a compliance token, not a shipped material, and the detector's `buried-raster` and `organic-clip-path` findings in the packet are material fixes.
24
- 6. **Floor.** Read the craft floor's Refuse list and hold the screenshots against it: kickers and eyebrows, hard offset shadows outside a neobrutalist world, glyph icons, system display faces, gradient text, side stripes, and the rest. A banned element is a material fix even when it matches nothing in the comp: the builder loaded the same ban before writing it, and fidelity to a comp cannot authorize what the floor refuses. The parent's hook findings cover this mechanically where hooks run; this check exists because hookless harnesses reach you with none, and the last two live sessions shipped five kickers past a reviewer that never looked.
24
+ 6. **Floor.** Read the craft floor's Refuse list and hold the screenshots against it: kickers and eyebrows, hard offset shadows outside a neobrutalist world, glyph icons, system display faces, gradient text, side stripes, and the rest. A banned element is a material fix even when it matches nothing in the comp: the builder loaded the same ban before writing it, and fidelity to a comp cannot authorize what the floor refuses. The parent's hook findings cover this mechanically where hooks run; this check exists because hookless harnesses reach you with none, and on those harnesses a banned element you miss ships.
25
25
 
26
26
  Do not run a second detector pass; mechanical findings belong to the parent's hooks.
27
27
 
@@ -23,7 +23,7 @@ Analyze what makes the design feel complex or cluttered:
23
23
 
24
24
  If any of these are unclear from the codebase, do not guess. Ask the user directly to clarify what you cannot infer.
25
25
 
26
- **CRITICAL**: Simplicity is not about removing features. It's about removing obstacles between users and their goals. Every element should justify its existence.
26
+ Simplicity is not about removing features. It's about removing obstacles between users and their goals. Every element should justify its existence.
27
27
 
28
28
  ## Plan Simplification
29
29
 
@@ -34,7 +34,7 @@ Create a ruthless editing strategy:
34
34
  - **Progressive disclosure**: What can be hidden until needed?
35
35
  - **Consolidation opportunities**: What can be combined or integrated?
36
36
 
37
- **IMPORTANT**: Simplification is hard. It requires saying no to good ideas to make room for great execution. Be ruthless.
37
+ Expect to say no to good ideas to make room for great execution.
38
38
 
39
39
  ## Simplify the Design
40
40
 
@@ -83,7 +83,7 @@ Systematically remove complexity across these dimensions:
83
83
  - **Consolidate styles**: Merge similar styles, use utilities consistently
84
84
  - **Reduce variants**: Does that component need 12 variations, or can 3 cover 90% of cases?
85
85
 
86
- **NEVER**:
86
+ **Avoid**:
87
87
  - Remove necessary functionality (simplicity ≠ feature-less)
88
88
  - Sacrifice accessibility for simplicity (clear labels and ARIA still required)
89
89
  - Make things so simple they're unclear (mystery ≠ minimalism)
@@ -6,7 +6,7 @@ Identify reusable patterns, components, and design tokens, then extract and cons
6
6
 
7
7
  Find the design system, component library, or shared UI directory. Understand its structure: component organization, naming conventions, design token structure, import/export conventions.
8
8
 
9
- **CRITICAL**: If no design system exists, do not create one yet. Ask the user directly to clarify what you cannot infer. Understand the preferred location and structure first.
9
+ If no design system exists, do not create one yet. Ask the user directly to clarify what you cannot infer. Understand the preferred location and structure first.
10
10
 
11
11
  ## Step 2: Identify Patterns
12
12
 
@@ -31,7 +31,7 @@ Create a systematic plan:
31
31
  - **Naming conventions**: Component names, token names, prop names that match existing patterns
32
32
  - **Migration path**: How to refactor existing uses to consume the new shared versions
33
33
 
34
- **IMPORTANT**: Design systems grow incrementally. Extract what is clearly reusable now, not everything that might someday be reusable.
34
+ Design systems grow incrementally. Extract what is clearly reusable now, not everything that might someday be reusable.
35
35
 
36
36
  ## Step 4: Extract & Enrich
37
37
 
@@ -59,7 +59,7 @@ Update design system documentation:
59
59
  - Add examples and guidelines
60
60
  - Update any Storybook or component catalog
61
61
 
62
- **NEVER**:
62
+ **Avoid**:
63
63
  - Extract one-off, context-specific implementations without generalization
64
64
  - Create components so generic they are useless
65
65
  - Extract without considering existing design system conventions
@@ -28,7 +28,7 @@ Identify weaknesses and edge cases:
28
28
  - Number formats (1,000 vs 1.000)
29
29
  - Currency symbols
30
30
 
31
- **CRITICAL**: Designs that only work with perfect data aren't production-ready. Harden against reality.
31
+ Designs that only work with perfect data aren't production-ready.
32
32
 
33
33
  ## Hardening Dimensions
34
34
 
@@ -313,9 +313,7 @@ const throttledScroll = throttle(handleScroll, 100);
313
313
  - Visual regression tests
314
314
  - Accessibility tests (axe, WAVE)
315
315
 
316
- **IMPORTANT**: Hardening is about expecting the unexpected. Real users will do things you never imagined.
317
-
318
- **NEVER**:
316
+ **Avoid**:
319
317
  - Assume perfect input (validate everything)
320
318
  - Ignore internationalization (design for global)
321
319
  - Leave error messages generic ("Error occurred")
@@ -12,9 +12,9 @@ This command toggles the hook **per project** by editing `.impeccable/config.jso
12
12
 
13
13
  Declare server-side template extensions under **`detector.extensions`** when the project uses Blade, Twig, ERB, or Handlebars files; the hook skips them otherwise because they sit outside the built-in extension list. One entry per extension, `{ "ext": ".blade.php", "engine": "html" }`. `engine` picks the analyzer (`html` for markup templates, `text` for JS/TS/CSS-like files) and defaults to `html`. Match against the end of the filename, so double extensions like `.blade.php` and `.html.erb` work. Config only adds extensions; the built-in list always applies.
14
14
 
15
- Manual `npx impeccable detect` scans use the same project filter config by default: `detector.ignoreRules`, `detector.ignoreFiles`, `detector.ignoreValues`, and `detector.designSystem.enabled`. `hook.enabled` only controls automatic hook execution, not manual CLI scans. Use `npx impeccable detect --no-config ...` for a raw detector run that ignores project config/context. Use `npx impeccable ignores ...` for direct CLI CRUD on the same detector ignores.
15
+ Manual `.pi/skills/impeccable/scripts/impeccable detect` scans use the same project filter config by default: `detector.ignoreRules`, `detector.ignoreFiles`, `detector.ignoreValues`, and `detector.designSystem.enabled`. `hook.enabled` only controls automatic hook execution, not manual CLI scans. Use `.pi/skills/impeccable/scripts/impeccable detect --no-config ...` for a raw detector run that ignores project config/context. Use `.pi/skills/impeccable/scripts/impeccable ignores ...` for direct CLI CRUD on the same detector ignores.
16
16
 
17
- Supported harnesses: Claude Code (`.claude/settings.local.json` in the project, which is gitignored so the hook stays machine-local; a hook you move into the shared `settings.json` is honored in place too), Codex (`.codex/hooks.json` in the project), Grok Build (`.grok/hooks/impeccable.json` in the project; requires `/hooks-trust` or `--trust`), and GitHub Copilot (`.github/hooks/impeccable.json` in the project, a team-shared committed file that both the Copilot CLI and the cloud agent read). For the Copilot CLI, repo-level hooks fire once `.github/hooks/impeccable.json` is committed to the repository's default branch.
17
+ Supported harnesses: Claude Code (`.claude/settings.local.json` for a project-scope install; `~/.claude/settings.json` for a user-scope install; a project hook moved into shared `.claude/settings.json` is honored in place too), Codex (`.codex/hooks.json` in the project), Grok Build (`.grok/hooks/impeccable.json` in the project; requires `/hooks-trust` or `--trust`), and GitHub Copilot (`.github/hooks/impeccable.json` in the project, a team-shared committed file that both the Copilot CLI and the cloud agent read). For the Copilot CLI, repo-level hooks fire once `.github/hooks/impeccable.json` is committed to the repository's default branch.
18
18
 
19
19
  Gemini installs session and completion hooks in `.gemini/settings.json`, merged into the settings already there (comments are tolerated; a commented file is backed up to `settings.json.bak` before the rewrite, and a file that is not valid JSON is left alone). It does not install a per-edit detector hook. The `BeforeTool` hook only rewrites shell commands that run `build-phase`, and only on macOS and Linux; on Windows (where Gemini runs hooks through PowerShell) no session id reaches the shell, so a comp build is not tied to the session and the completion reminder stays silent.
20
20
 
@@ -62,7 +62,7 @@ Prefer the narrowest exception:
62
62
 
63
63
  - If the finding line shows an `ignore-value <rule> <value>` pair, pass it to `impeccable hooks ignore-value` with your `--reason`. This writes shared `.impeccable/config.json` by default.
64
64
  - For value-specific findings such as `overused-font` and `bounce-easing`, use `ignore-value` for the specific value. Do not use `ignore-rule overused-font` for a specific font.
65
- - If the finding has no value-specific command, such as `side-tab`, scope that one rule to the file: `ignore-value <id> "*" --file <path>`. Run `npx impeccable detect <path>` first to see what actually fires there.
65
+ - If the finding has no value-specific command, such as `side-tab`, scope that one rule to the file: `ignore-value <id> "*" --file <path>`. Run `.pi/skills/impeccable/scripts/impeccable detect <path>` first to see what actually fires there.
66
66
  - Reach for `ignore-file <path>` only when the whole file is out of scope for design review: a fixture, a generated artifact, a deliberate slop demo. It silences every rule for that file permanently, including rules that have not been written yet. A real UI surface with one noisy rule wants the file-scoped value ignore above.
67
67
  - Use `ignore-rule <id>` only when the user asks to suppress that whole rule across the project. For broad overused-font suppression, use `ignore-rule overused-font --all-values` only when the user asks to ignore overused fonts generally.
68
68
  - Prefer config ignores (the commands above) by default; they keep suppressions in one reviewable place. Reach for an inline comment only when the waiver must travel with a single file that leaves the repo (a generated/exported standalone document, an emailed HTML file). The supported marker is `impeccable-disable <rule>` (whole file) or `impeccable-disable-line` / `impeccable-disable-next-line` (one line), in any comment syntax, with an optional reason after `:` or `--`. The detector honors it by default; `--no-inline-ignores` or `--no-config` bypasses it.
@@ -103,7 +103,7 @@ Example whole-file exception, for a file that is out of scope entirely:
103
103
  - Never modify `.impeccable/config.json` or `.impeccable/config.local.json` by hand from this command. Always go through `impeccable hooks` so writes stay validated and the file shape stays consistent. One exception: `detector.extensions` has no admin action, so when the user asks to cover a template stack, edit that one field in `.impeccable/config.json` directly and leave the rest of the file untouched.
104
104
  - Do not edit the launcher or the binary behind `impeccable hook` from this flow. Those are skill plumbing.
105
105
  - Claude Code, Codex, and GitHub Copilot do not block the edit; they emit a post-edit reminder instead. Disabling stops those reminders.
106
- - The hook is bundled with the Impeccable skill and installed through project-local manifests: `.claude/settings.local.json`, `.codex/hooks.json`, `.github/hooks/impeccable.json`, and `.gemini/settings.json`. On Codex, the user must approve the hook via `/hooks` the first time. On GitHub Copilot, the CLI loads `.github/hooks/impeccable.json` once it is committed to the repository's default branch, and the cloud agent reads it from the repo directly.
106
+ - The hook is bundled with the Impeccable skill. Project installs use `.claude/settings.local.json`, `.codex/hooks.json`, `.github/hooks/impeccable.json`, and `.gemini/settings.json`; a user-scope Claude install uses `~/.claude/settings.json`. On Codex, the user must approve the hook via `/hooks` the first time. On GitHub Copilot, the CLI loads `.github/hooks/impeccable.json` once it is committed to the repository's default branch, and the cloud agent reads it from the repo directly.
107
107
 
108
108
  ## Failure modes
109
109
 
@@ -255,7 +255,7 @@ If wrap or generation fails after the browser flipped to GENERATING, tell the **
255
255
  When wrap returns `fallback: "agent-driven"`, you pick the source file yourself; the goal is unchanged: three preview variants now, and the accepted one persisted where the next build cannot wipe it.
256
256
 
257
257
  1. **Find where the element really lives** from the error payload: `element_not_in_source` + `generatedMatch` means the served HTML is generated, so find the generator's template or partial; `element_not_found` means runtime-injected, so find the rendering component or data source; `file_is_generated` resolves the same way. A purely visual change may belong in a shared stylesheet rather than a template.
258
- 2. **Preview in the served file**: manually write the same wrapper scaffold `impeccable live-wrap` produces (`<!-- impeccable-variants-start ID --><div data-impeccable-variants="ID" data-impeccable-variant-count="3" style="display: contents">…</div><!-- end -->`) into the file the browser actually loaded, insert your variant divs, `--reply EVENT_ID done --file <served file>`. This edit is temporary; a regen wiping it is fine.
258
+ 2. **Preview in the served file**: manually write the same wrapper scaffold `impeccable live-wrap` produces into the file the browser actually loaded, moving the element itself into the original slot: `<!-- impeccable-variants-start ID --><div data-impeccable-variants="ID" data-impeccable-variant-count="3" style="display: contents"><div data-impeccable-variant="original">THE ELEMENT, UNCHANGED</div><!-- Variants: insert below this line --></div><!-- impeccable-variants-end ID -->`. Insert your variant divs after the marker, then `--reply EVENT_ID done --file <served file>`. Never drop the original slot: discard restores the element from it and refuses a wrapper without one. This edit is temporary; a regen wiping it is fine.
259
259
  3. **On accept, write to true source** (accept refuses generated files, so `_acceptResult.handled` is usually `false` here): structural change → template/component source; visual-only → the right stylesheet; content rendered from data → the data source or render logic. Then remove the temporary wrapper from the served file.
260
260
  4. **On discard**, just remove the temporary wrapper.
261
261
 
@@ -38,7 +38,7 @@ Keep the visual system fixed. Derive five to seven materially different structur
38
38
 
39
39
  `.pi/skills/impeccable/scripts/impeccable concept-seed --scope surface --mode <mode>`
40
40
 
41
- The script deals three of your structures; the dice pick which three reach the user, breaking the ranking rut while the user keeps a real choice. Present them on the decision page as full cards of equal salience, the dealt lead under kicker THE ROLL, with steer and re-roll; the user locks one. No canon card and no pick card at surface scope: the world is settled, so every card visualizes composition, not identity. With image generation and a comp-led build path (the path the PRESENTATION block printed for this surface; the build-path paragraph below), each card declares a `comp` under `.impeccable/mocks/decision/`, generated after serving, in reading order, under [visualize.md](visualize.md)'s comp discipline and the MODE RULES block concept-seed printed for this surface. Anchor each comp on the established identity: pass a screenshot of a representative existing page as a reference image (the harness image tool's input image, or `impeccable generate-image --ref`) with a short prompt in visualize.md's shape; prose paraphrases of a design system drift, pixel references do not. Without image generation, or on a code-led round, each card carries an HTML sketch of the first viewport, declared as its `html`, which the page draws as a skeleton; the PRESENTATION block names its shape, and a card without one falls back to a `wireframe` schematic (`impeccable serve-question --schema`). Locking a card is the approval and sets the build path: a locked comp builds comp-led with that comp as the approved comp, discharging [visualize.md](visualize.md)'s three-option round with no second approval point; a locked sketch or wireframe builds code-led, its ambition carried by the direction contract, and a locked sketch is the composition the build matches. Never run the script for a local extension or a precisely specified narrow request; shape those directly.
41
+ The script deals three of your structures; the dice pick which three reach the user, breaking the ranking rut while the user keeps a real choice. Present them on the decision page as full cards of equal salience, the dealt lead under kicker THE ROLL, with steer and re-roll; the user locks one. Each card declares `kind`: `assigned` on the dealt lead, `dealt` on the other dealt structures, and `challenger` with its `catalogId` (the SOURCE ID) on a challenger that won its place. No canon card and no pick card at surface scope: the world is settled, so every card visualizes composition, not identity. With image generation and a comp-led build path (the path the PRESENTATION block printed for this surface; the build-path paragraph below), each card declares a `comp` under `.impeccable/mocks/decision/`, generated after serving, in reading order, under [visualize.md](visualize.md)'s comp discipline and the MODE RULES block concept-seed printed for this surface. Anchor each comp on the established identity: pass a screenshot of a representative existing page as a reference image (the harness image tool's input image, or `impeccable generate-image --ref`) with a short prompt in visualize.md's shape; prose paraphrases of a design system drift, pixel references do not. Without image generation, or on a code-led round, each card carries an HTML sketch of the first viewport, declared as its `html`, which the page draws as a skeleton; the PRESENTATION block names its shape, and a card without one falls back to a `wireframe` schematic (`impeccable serve-question --schema`). Locking a card is the approval and sets the build path: a locked comp builds comp-led with that comp as the approved comp, discharging [visualize.md](visualize.md)'s three-option round with no second approval point; a locked sketch or wireframe builds code-led, its ambition carried by the direction contract, and a locked sketch is the composition the build matches. Never run the script for a local extension or a precisely specified narrow request; shape those directly.
42
42
 
43
43
  ### Create or replace the visual world
44
44
 
@@ -48,7 +48,7 @@ The script deals three of your structures; the dice pick which three reach the u
48
48
  4. Run `.pi/skills/impeccable/scripts/impeccable concept-seed --scope direction --mode <mode>` and follow what it prints. No substitute, no skip: on a new or replacement world, writing artifact code before this script has run and its assignment is acknowledged is a contract violation, whatever the harness, the model, or the time pressure; the roll is what keeps every run from converging on the category default. The script assigns the direction to build and deals catalog challengers. Fuse each challenger before judging it: the challenger supplies the form and its system grammar, the product supplies every fact, clarity wins conflicts. Weigh fused challengers against the assigned direction on exactly two axes, audience identification and product clarity. Losing to strong grounded material is a valid outcome; beating a thin or tool-monoculture list is the point. Close with a verdict per challenger, decided before any borrowing: wins (beats the assigned direction on both axes; becomes the build candidate), competitive (holds one axis; stays a full alternate), or declined (loses both). A declined challenger is not spent: name the one discipline of its system the assigned direction lacks, and raise the assigned direction to match before presenting it. A donation transfers ambition and system discipline (a palette's total commitment, a grid's density courage, a form's structural honesty), never the challenger's clothes. A component treatment, such as a button's shadow or a display face, is clothes, not discipline; a lifted motif is a costume note, not a raise, and one world owns the page. Write each raise into the presented direction as its own line, named for its donor; a raise nobody can read did not happen.
49
49
  5. Present one direction, fully committed and already raised by the hand it beat, raises visible as named lines: world, first viewport, visitor path, signature interaction, cross-surface reach, honest risk. Route each challenger by verdict: winning and competitive challengers are full alternates with their QUALITY BAR cards and one-line case; declined challengers render demoted, compact and quiet, each carrying its verdict and what the direction kept from it, never full-size, never silently dropped, still adoptable on request. The verdict informs the user's choice, never pre-empts it; the demoted row is the hand's proof of judgment. A hand holds at most three full-card challengers: when the roll deals more, the three strongest join and the rest wait in the re-roll pool, noted in one line; dropping a challenger from the hand itself takes a named product-truth failure, disclosed. Add one card for your own top-ranked grounded candidate when it is not the assigned direction, kicker IMPECCABLE’S PICK, same anatomy as every card, with an honest risk line naming its familiarity when true: the strongest grounded direction is often where most runs in this category land, and the user deciding that trade is the point of showing it. Familiar and effective is a legitimate destination, not a failure of nerve; the pick card and the standing exit serve it at two depths. One pick card, never two, never a ranked list: a lineup of your candidates hands selection back to a taste function and invites the safest card. The pick never takes the lead position; when the dice assign your top candidate there is no pick card, and the assigned card notes it topped your list. Add re-roll with an optional one-line steer, in three registers: plain (a fresh hand, same spread), safer (your remaining conventional grounded candidates plus the canon against named competitors), bolder (foreign forms only, at full commitment). The register is the user's steering on the familiar-to-bold axis, never yours to pre-select; when the answer carries one, re-run the seed with `--register <value>` and the next `--reroll` round, and follow what it prints. A user saying "bolder" or "safer" while a direction round is open means these registers, never the bolder or harden commands. The two channels share this structure and differ only in richness: cards and boards on the decision page, names and one-liners through the structured tool, whose option list carries the assigned direction, the pick, the winning and competitive challengers, and the standing exit last; declined challengers fold into the assigned option's description as their kept lines, so the raise survives the text channel.
50
50
 
51
- The standing exit: every direction round offers one quiet, permanent alternative, the category standard, played straight. It is the user's door, never yours: never recommend it, never weigh it against the roll, never let it soften the dealt directions; the counterweights bind the unchosen default, not the chosen one. When the user takes it (the canon action, a safer-steer, or plain words asking for the familiar or competitor-like path), convention becomes the commitment: ask once for two or three products this should sit alongside, make their craft level the bar, and execute the canon at full fidelity, without irony or smuggled quirk. Record a standing preference as a brand commitment in PRODUCT.md. Re-roll eliminates every direction already shown, grounded and challenger alike; after two consecutive re-rolls, ask what quality is missing. Re-roll on your own only on named factual grounds, when the assigned direction cannot carry the product's truth or task; taste is never grounds. The user may re-roll freely, and a user- or brief-pinned direction beats the roll, always. Resolve collisions field by field: preserve every user- or brief-pinned constraint. In dimensions the brief leaves open, the assignment still binds through its topology, controls, state vocabulary, and ritual; when only its materials conflict with a pinned visual direction or PRODUCT.md brand commitment, translate that material expression and name the translation in the presented direction. A look mismatch is not grounds to re-roll. Present the decision visually: write an options payload with the assigned direction leading, its raised lines included; the pick card when one exists; the dealt challengers as alternates with their QUALITY BAR cards, verdicts, and kept lines; re-roll with its safer and bolder registers; steer; canon enabled; and `buildPath` carrying the recorded default with `toggle: true` whenever image generation exists (details in the build-path paragraph below). A degraded roll with no challengers still uses the page, as a single text-only card with re-roll. Give every card the same anatomy: thesis, palette, materials, first viewport, honest risk, and the challengers' case lines (`--schema` prints the exact shape); the page renders identity from these fields, demotes declined challengers to their row on its own, and a challenger's catalog image rides as labeled inspiration, never the promise of the build. Author `canonCard` too: the category standard as one honest card, same anatomy; the page keeps it subordinate, and the counterweights still bind you. Run `.pi/skills/impeccable/scripts/impeccable serve-question --start --payload <file>` (`--schema` first for the payload shape). It daemonizes, prints the page URL and a key, and exits; open that URL for the user, in-app browser first, then the system opener, then showing the URL. Collect the choice with `--wait --key <key>`, repeating while it exits 3; the ANSWER prints as JSON. An ANSWER of `{"optionId":"reroll"}` keeps the server alive and the page open on a loading hand: rerun concept-seed with the same `--scope` and `--mode` plus `--from <seed-key> --reroll <n>` (1 on the first re-roll, counting up), build the next payload, deliver it with `--update --key <same key> --payload <file>`, then return to `--wait` on that key. Never `--start` a second server or fall back to chat here: either strands the open tab on a hand that never arrives. Exit 4 means the page closed unanswered: re-present once through the structured question tool, and with no answer there either, proceed unattended with the assigned direction and state the assumptions. A harness that can leave a shell blocked in the background may run the script without `--start` and let it auto-open and block. A harness that cannot hold a blocking `--wait` (it detaches long-running commands without ever returning their output, or reaps a backgrounded child) takes the structured tool without starting the page and discloses the substitution in the first reply, so the tab is never left unanswered. A shell that hands back a still-running command as a session you can poll holds the wait: poll that session until it exits, and rerun `--wait` only after it exits without an answer. Never predict any other fallback: run the script, and only exit code 2 from starting it, or that wait check before starting, routes the decision to the structured tool; those are the fallback, never an error to retry. concept-seed closes every roll with this procedure, condensed, as a PRESENTATION block that names the recorded build path.
51
+ The standing exit: every direction round offers one quiet, permanent alternative, the category standard, played straight. It is the user's door, never yours: never recommend it, never weigh it against the roll, never let it soften the dealt directions; the counterweights bind the unchosen default, not the chosen one. When the user takes it (the canon action, a safer-steer, or plain words asking for the familiar or competitor-like path), convention becomes the commitment: ask once for two or three products this should sit alongside, make their craft level the bar, and execute the canon at full fidelity, without irony or smuggled quirk. Record a standing preference as a brand commitment in PRODUCT.md. Re-roll eliminates every direction already shown, grounded and challenger alike; after two consecutive re-rolls, ask what quality is missing. Re-roll on your own only on named factual grounds, when the assigned direction cannot carry the product's truth or task; taste is never grounds. The user may re-roll freely, and a user- or brief-pinned direction beats the roll, always. Resolve collisions field by field: preserve every user- or brief-pinned constraint. In dimensions the brief leaves open, the assignment still binds through its topology, controls, state vocabulary, and ritual; when only its materials conflict with a pinned visual direction or PRODUCT.md brand commitment, translate that material expression and name the translation in the presented direction. A look mismatch is not grounds to re-roll. Present the decision visually: write an options payload with the assigned direction leading, its raised lines included; the pick card when one exists; the dealt challengers as alternates with their QUALITY BAR cards, verdicts, and kept lines; re-roll with its safer and bolder registers; steer; canon enabled; and `buildPath` carrying the recorded default with `toggle: true` whenever image generation exists (details in the build-path paragraph below). A degraded roll with no challengers still uses the page, as a single text-only card with re-roll. Every option declares its identity: `kind` is `assigned`, `pick`, `challenger`, or `grounded` (another of your own grounded directions, such as each card of a safer hand's lineup, any number of them), and each challenger carries `catalogId`, the SOURCE ID concept-seed printed for its world, never the card's own id; `--start` and `--update` refuse a direction or surface payload without them, and the page reports the choice from them. Give every card the same anatomy: thesis, palette, materials, first viewport, honest risk, and the challengers' case lines (`--schema` prints the exact shape); the page renders identity from these fields, demotes declined challengers to their row on its own, and a challenger's catalog image rides as labeled inspiration, never the promise of the build. Author `canonCard` too: the category standard as one honest card, same anatomy; the page keeps it subordinate, and the counterweights still bind you. Run `.pi/skills/impeccable/scripts/impeccable serve-question --start --payload <file>` (`--schema` first for the payload shape). It daemonizes, prints the page URL and a key, and exits; open that URL for the user, in-app browser first, then the system opener, then showing the URL. Collect the choice with `--wait --key <key>`, repeating while it exits 3; the ANSWER prints as JSON. An ANSWER of `{"optionId":"reroll"}` keeps the server alive and the page open on a loading hand: rerun concept-seed with the same `--scope` and `--mode` plus `--from <seed-key> --reroll <n>` (1 on the first re-roll, counting up), build the next payload, deliver it with `--update --key <same key> --payload <file>`, then return to `--wait` on that key. Never `--start` a second server or fall back to chat here: either strands the open tab on a hand that never arrives. Exit 4 means the page closed unanswered: re-present once through the structured question tool, and with no answer there either, proceed unattended with the assigned direction and state the assumptions. A harness that can leave a shell blocked in the background may run the script without `--start` and let it auto-open and block. A harness that cannot hold a blocking `--wait` (it detaches long-running commands without ever returning their output, or reaps a backgrounded child) takes the structured tool without starting the page and discloses the substitution in the first reply, so the tab is never left unanswered. A shell that hands back a still-running command as a session you can poll holds the wait: poll that session until it exits, and rerun `--wait` only after it exits without an answer. Never predict any other fallback: run the script, and only exit code 2 from starting it, or that wait check before starting, routes the decision to the structured tool; those are the fallback, never an error to retry. concept-seed closes every roll with this procedure, condensed, as a PRESENTATION block that names the recorded build path.
52
52
 
53
53
  When image generation exists, every card also declares a `comp` path under `.impeccable/mocks/decision/`, the canon card included. Where the harness sandboxes its shell, start the page through the least-sandboxed command path it offers: a sandboxed shell cannot bind the board's port, and the first-attempt failure costs a retry every session. Serve the page first, then produce the comps; the page shimmer-waits per slot and the user may answer before they land. Load [visualize.md](visualize.md) before writing the first decision comp prompt, not at the comp round: each card's image is that direction's north-star comp at full fidelity under its comp discipline and the MODE RULES block concept-seed printed, and a prompt written before reading them misses every rule there: the requested surface as the real page, its first viewport and the start of the section below it, held like every comp to visualize.md's rule that a template skeleton stays the template whatever world paints it (your own pick included: a safe layout under a world skin is the template), a short prompt in visualize.md's shape, real product name and real content, no invented commercial claims, in that card's own palette, type character, and material world, committed all the way. Once a round declares comps it has not generated yet, `impeccable serve-question --start` (and `--update`, and a flip to comp) prints a `NEXT read <path>/visualize.md` line; read that file then, before the first prompt. `--wait` prints `COMP SIDECAR MISSING` for any landed decision comp with no prompt sidecar (the image's full file name plus `.json`: `a.png` gets `a.png.json`); write the missing sidecar before you continue. `COMP STALE` names a file an earlier round left at one of this hand's slots; regenerate it there. Generation takes the same time at any fidelity, so an unfinished draft pays comp cost for draft quality; fairness between cards is equal fidelity in each card's own grammar, one surface, one aspect, never shared unfinishedness. The frame's aspect is the surface's own: portrait at device viewport for a native app or mobile-first surface, landscape for desktop web; the decision page adapts to either, and a phone screen comped landscape is a broken frame, not a neutral default. Produce in reading order, the assigned card, then the pick, then the full-card hand, then canon, each file written with its prompt sidecar the moment it is done, so a re-roll's spend front-loads onto the cards read first; declined challengers get no comp, their catalog thumb is their face. With parallel subagents, fan out one agent per card: each spawn is the shipped asset producer with a single-comp packet, that card's fields, its world's card images when the NEXT line names them, PRODUCT.md, the shared frame, the path to visualize.md for its comp discipline, the COMPS section of the MODE RULES block copied verbatim (the subagent never sees the roll's output), and the card's declared path, up to four in flight. Regenerate inline any slot still empty when its agent returns; drop without ceremony any slot still empty when the user answers. No other supervision is owed. Without parallel subagents, generate in the main thread after serving, same order, and let the harness's own generation display carry the progress; the wait for the answer follows the last file. The chosen card's comp is not spent by the choice: comp-led, it enters the comp round as compositional option one; code-led, it returns at the finish review as the critique reference, what the image dared that the build did not. Unchosen comps stay in `.impeccable/mocks/decision/` as the round's spent hand; they carry no approval and imply none. With no image generation, cards carry their identity in palette chips and facts, and that page is complete, not a lesser version; the page then also demotes every challenger's catalog art to a labeled thumbnail on its own, because salience must encode the verdict, never the accident of which cards have images.
54
54
 
@@ -70,7 +70,7 @@ Calibration: AI-generated interfaces cluster around a few looks regardless of su
70
70
 
71
71
  ## 5. Record the decision
72
72
 
73
- Before code, record the chosen direction as a development-only contract under `## Direction contract` in the relevant surface brief. A direction contract is durable route or artifact strategy, so create or update the brief even when no other surface strategy needs persistence. Use six short blocks, roughly 150 words; do not spend tool calls counting words. THESIS: the one idea this surface owns and the category-default arrangement it refuses. OWN-WORLD: the palette and component language, specific enough to be recognizable with all content removed. STORY: what the visitor understands, believes, and does. FIRST VIEWPORT: the exact composition, what is where and at what scale, and where the primary action sits. FORM: the chosen form, its position on your ordered list, and the seed key the script printed. Close with one more line, FINISH: the run's exit condition, verbatim "unreviewed and undocumented is unfinished; this build ends with the finish review, the verdict, DESIGN.md, and every shipping raster carrying its provenance". The surface brief is the reminder later agents reload across edits and sessions: a page that looks complete with the FINISH line undischarged is not done, it is abandoned at the finish line. If a block reads like a mood, the direction is not decided yet; the finishing review audits the render against this contract.
73
+ Before code, record the chosen direction as a development-only contract under `## Direction contract` in the relevant surface brief. A direction contract is durable route or artifact strategy, so create or update the brief even when no other surface strategy needs persistence. Use six short blocks, roughly 150 words; do not spend tool calls counting words. THESIS: the one idea this surface owns and the category-default arrangement it refuses. OWN-WORLD: the palette and component language, specific enough to be recognizable with all content removed. STORY: what the visitor understands, believes, and does. FIRST VIEWPORT: the exact composition, what is where and at what scale, and where the primary action sits. FORM: the chosen form, its position on your ordered list, and the SEED REFERENCE concept-seed printed (`seed:` and 16 hex), never the raw seed key: the brief is committed, and on this machine the reference stands in for the key wherever a command takes one. When the roll printed SEED REFERENCE unavailable, write `seed: none (unavailable)` instead, and nothing else. Close with one more line, FINISH: the run's exit condition, verbatim "unreviewed and undocumented is unfinished; this build ends with the finish review, the verdict, DESIGN.md, and every shipping raster carrying its provenance". The surface brief is the reminder later agents reload across edits and sessions: a page that looks complete with the FINISH line undischarged is not done, it is abandoned at the finish line. If a block reads like a mood, the direction is not decided yet; the finishing review audits the render against this contract.
74
74
 
75
75
  Never copy the direction contract into implementation source or any browser-delivered artifact. This includes HTML or framework comments, hidden DOM, `<template>` elements, `data-*` attributes, rendered JSX or TSX output, serialized props or state, React Server Component payloads, client bundles, metadata or JSON-LD, accessibility-only text, and files served beside the artifact. A compiler or optimizer removing development metadata is not a safety boundary. Reviewers and documenters receive the contract from the surface brief.
76
76
 
@@ -82,7 +82,7 @@ Read the existing surface brief before updating it:
82
82
 
83
83
  `.pi/skills/impeccable/scripts/impeccable surface-brief write <primary-target> <body-file> [related-target ...]`
84
84
 
85
- After writing, read the brief once more and verify that all six contract blocks and the seed key are present before building.
85
+ After writing, read the brief once more and verify that all six contract blocks and the seed reference (or `seed: none (unavailable)` when the roll printed that) are present before building.
86
86
 
87
87
  Keep the brief small: scope and visitor mode; audience, job, action/task, proof/content, and constraints; chosen direction and memorable moment; unresolved decisions. Do not copy global product truth or DESIGN.md tokens into it.
88
88
 
@@ -98,7 +98,7 @@ Build the assigned direction, not a safer interpretation of it. The form supplie
98
98
 
99
99
  When an approved comp exists, it is a spatial contract, not a mood board: only the user can downgrade its authority, in explicit words. Models systematically believe their HTML, CSS, and SVG recreation of an image succeeded when it did not, so the build runs as a state machine on disk whose gates measure the screen against the comp instead of asking you to remember it. Start it once, and let it tell you what is next:
100
100
 
101
- `.pi/skills/impeccable/scripts/impeccable build-phase start --direction <seed key> --artifact <entry file>` right after the direction choice, adding `--decision-comp <path>` when the chosen card has a decision comp (the path CHOSEN COMP names) so the comps gate counts it as option one, or `start --comp <approved comp> --artifact <entry file>` when a surface round already locked one. Start is not the choice ping: that is the `concept-seed --kind` rerun the roll's TELEMETRY line names, sent once when the roll printed one.
101
+ `.pi/skills/impeccable/scripts/impeccable build-phase start --direction <seed reference, or none when it was unavailable> --artifact <entry file>` right after the direction choice, adding `--decision-comp <path>` when the chosen card has a decision comp (the path CHOSEN COMP names) so the comps gate counts it as option one, or `start --comp <approved comp> --artifact <entry file>` when a surface round already locked one. Start is not the choice ping: that is the `concept-seed --kind` rerun the roll's TELEMETRY line names, sent once when the roll printed one.
102
102
 
103
103
  Then, in order, each closed by `.pi/skills/impeccable/scripts/impeccable build-phase advance` (every verb below runs as `.pi/skills/impeccable/scripts/impeccable <verb>`; exit 2 means the gate failed and printed why; fix that and advance again; write nothing for a later phase while an earlier gate is open):
104
104
 
@@ -133,7 +133,7 @@ Preserve semantics, accessibility, performance, responsiveness, project conventi
133
133
 
134
134
  ## 7. Inspect and finish
135
135
 
136
- Inspect the surface's target sizes in one batched screenshot round: desktop and mobile on the web; on a native platform (`ios` / `android` / `adaptive`), the shipped device classes per OS, captured from the simulator or emulator the way the platform reference's Verifying the build section describes. When the harness reports the user's actual viewport (an in-app browser's size, a named resolution), add that width to the set: the width that breaks is the one the user sees first. Critique the render against the user's request and the direction contract, fix material gaps, and confirm with one final round; two rounds is the ceiling, and fixes batch between them rather than earning per-tweak screenshots. The ceiling bounds inspection and never closes an open build-phase gate: a gate stays open until it passes or the route it names is taken. On a comp-led build, run `.pi/skills/impeccable/scripts/impeccable comp-diff --comp <approved comp> --build .impeccable/review/desktop.png --spec .impeccable/build/spec.json --out-dir .impeccable/review/diff/final` and read its region rows and paired crops as the critique: the side-by-side is the view the build thread never has on its own, and a region it scores missing or contradicted is a fix whatever the page looks like from memory. Never judge fidelity from one full-page thumbnail; it hides exactly the failures that matter. On a Persuade surface, verify the mode did its job: a first-time visitor should know what this is, why it matters, and what to do within seconds, in the form's own vocabulary.
136
+ Inspect the surface's target sizes in one batched screenshot round: desktop and mobile on the web; on a native platform (`ios` / `android` / `adaptive`), the shipped device classes per OS, captured from the simulator or emulator the way the platform reference's Verifying the build section describes. When the harness reports the user's actual viewport (an in-app browser's size, a named resolution), add that width to the set: the width that breaks is the one the user sees first. On anything interactive, the round drives every interaction and reachable state (open, closed, hover, focus, error, empty, overlong content) and checks each for overlap and clipping, not only the resting screen. Critique the render against the user's request and the direction contract, fix material gaps, and confirm with one final round; two rounds is the ceiling, and fixes batch between them rather than earning per-tweak screenshots. The ceiling bounds inspection and never closes an open build-phase gate: a gate stays open until it passes or the route it names is taken. On a comp-led build, run `.pi/skills/impeccable/scripts/impeccable comp-diff --comp <approved comp> --build .impeccable/review/desktop.png --spec .impeccable/build/spec.json --out-dir .impeccable/review/diff/final` and read its region rows and paired crops as the critique: the side-by-side is the view the build thread never has on its own, and a region it scores missing or contradicted is a fix whatever the page looks like from memory. Never judge fidelity from one full-page thumbnail; it hides exactly the failures that matter. On a Persuade surface, verify the mode did its job: a first-time visitor should know what this is, why it matters, and what to do within seconds, in the form's own vocabulary.
137
137
 
138
138
  A capture is evidence only when it is valid, and you validate before you send. Settle or disable entrance motion first: an element hidden by animation timing reads as a missing element and gets fixed into a regression. Capture full-page shots from the document top. Capture the comp comparison at the comp's own pixel dimensions. Then open every file once and confirm it shows what its name claims: no black or blank regions, no wrong section behind a right filename, no half-loaded state. A malformed capture sent onward costs the whole round; the reviewer answers it with `disposition: recapture` and nothing it reviewed binds.
139
139
 
@@ -23,7 +23,7 @@ Understand what users need to learn and why:
23
23
  - What's the key action we want them to take? (First project? First invite?)
24
24
  - How do we know onboarding worked? (Completion rate? Time to value?)
25
25
 
26
- **CRITICAL**: Onboarding should get users to value as quickly as possible, not teach everything possible.
26
+ Onboarding should get users to value as quickly as possible, not teach everything possible.
27
27
 
28
28
  ## Onboarding Principles
29
29
 
@@ -208,9 +208,9 @@ localStorage.setItem('onboarding-completed', 'true');
208
208
  localStorage.setItem('feature-tooltip-seen-reports', 'true');
209
209
  ```
210
210
 
211
- **IMPORTANT**: Don't show same onboarding twice (annoying). Track completion and respect dismissals.
211
+ Show onboarding once: track completion and respect dismissals.
212
212
 
213
- **NEVER**:
213
+ **Avoid**:
214
214
  - Force users through long onboarding before they can use product
215
215
  - Patronize users with obvious explanations
216
216
  - Show same tooltip repeatedly (respect dismissals)