@lifeaitools/rdc-skills 0.24.38 → 0.24.41

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 (196) hide show
  1. package/.claude/settings.json +15 -15
  2. package/.claude-plugin/marketplace.json +21 -21
  3. package/.claude-plugin/plugin.json +1371 -1371
  4. package/.github/workflows/publish.yml +34 -34
  5. package/.github/workflows/self-test.yml +58 -58
  6. package/CHANGELOG.md +310 -310
  7. package/LICENSE +21 -21
  8. package/MANIFEST.md +221 -221
  9. package/README.md +376 -375
  10. package/README.sandbox.md +3 -3
  11. package/RELEASE.md +42 -0
  12. package/assets/watcher/viewer.html +164 -164
  13. package/bin/rdc-skills-mcp.mjs +316 -316
  14. package/commands/build.md +183 -183
  15. package/commands/collab.md +180 -180
  16. package/commands/deploy.md +152 -152
  17. package/commands/design.md +31 -31
  18. package/commands/edit.md +28 -28
  19. package/commands/fixit.md +124 -124
  20. package/commands/handoff.md +173 -173
  21. package/commands/help.md +95 -95
  22. package/commands/overnight.md +220 -220
  23. package/commands/plan.md +158 -158
  24. package/commands/preplan.md +131 -131
  25. package/commands/prototype.md +145 -145
  26. package/commands/release.md +49 -49
  27. package/commands/report.md +99 -99
  28. package/commands/review.md +120 -120
  29. package/commands/self-test.md +113 -113
  30. package/commands/status.md +86 -86
  31. package/commands/watch.md +98 -98
  32. package/commands/workitems.md +137 -137
  33. package/git-sha.json +1 -1
  34. package/guides/agent-bootstrap.md +295 -295
  35. package/guides/agents/backend.md +104 -104
  36. package/guides/agents/content.md +94 -94
  37. package/guides/agents/cs2.md +56 -56
  38. package/guides/agents/data.md +87 -87
  39. package/guides/agents/design.md +77 -77
  40. package/guides/agents/frontend.md +92 -92
  41. package/guides/agents/infrastructure.md +81 -81
  42. package/guides/agents/setup.md +281 -281
  43. package/guides/agents/verify.md +151 -151
  44. package/guides/agents/viz.md +106 -106
  45. package/guides/backend.md +146 -146
  46. package/guides/content.md +147 -147
  47. package/guides/cs2.md +190 -190
  48. package/guides/data.md +123 -123
  49. package/guides/design.md +116 -116
  50. package/guides/engineering-behavior.md +43 -43
  51. package/guides/escalation-protocol.md +125 -125
  52. package/guides/frontend.md +151 -151
  53. package/guides/history-md-spec.md +297 -297
  54. package/guides/infrastructure.md +179 -179
  55. package/guides/lessons-learned-spec.md +151 -145
  56. package/guides/output-contract.md +108 -108
  57. package/guides/publish-md-spec.md +289 -289
  58. package/guides/rdc-skills-startup.md +30 -30
  59. package/guides/verify.md +11 -11
  60. package/hooks/check-cwd.js +31 -31
  61. package/hooks/check-rdc-environment.js +164 -164
  62. package/hooks/check-services.js +6 -6
  63. package/hooks/check-stale-work-items.js +19 -19
  64. package/hooks/foreground-process-gate.js +128 -128
  65. package/hooks/gate-watchdog-selfcheck.js +257 -257
  66. package/hooks/hook-logger.js +25 -25
  67. package/hooks/lib/run-evidence-gate.mjs +241 -241
  68. package/hooks/no-stop-open-epics.js +127 -127
  69. package/hooks/post-tool-batch-gate.js +203 -203
  70. package/hooks/post-work-check.js +21 -21
  71. package/hooks/postcompact-log.js +13 -13
  72. package/hooks/precompact-log.js +13 -13
  73. package/hooks/rate-limit-retry.js +46 -46
  74. package/hooks/rdc-invocation-marker.js +157 -157
  75. package/hooks/rdc-output-contract-gate.js +94 -94
  76. package/hooks/require-work-item-on-commit.js +294 -294
  77. package/hooks/restart-brief.js +19 -19
  78. package/hooks/run-hidden-hook.ps1 +47 -47
  79. package/hooks/task-completed-gate.js +274 -274
  80. package/hooks/work-item-exit-gate.js +944 -944
  81. package/lib/catalog.mjs +236 -236
  82. package/lib/cloud-rewrite.mjs +155 -155
  83. package/package.json +57 -56
  84. package/rules/work-items-rpc.md +520 -520
  85. package/scaffold/templates/HISTORY.md.template +39 -39
  86. package/scaffold/templates/PUBLISH.md.template +21 -21
  87. package/scaffold/templates/brochure-studio-default.html +70 -70
  88. package/scripts/acceptance.mjs +502 -502
  89. package/scripts/fixtures/guides/bad-guide.md +15 -15
  90. package/scripts/fixtures/guides-clean/good-guide.md +16 -16
  91. package/scripts/install-rdc-skills.js +1289 -1289
  92. package/scripts/install.ps1 +202 -202
  93. package/scripts/install.sh +132 -132
  94. package/scripts/lib/assertions.mjs +287 -287
  95. package/scripts/lib/manifest-schema.mjs +754 -754
  96. package/scripts/lib/runner.mjs +465 -465
  97. package/scripts/lib/sandbox.mjs +435 -435
  98. package/scripts/prepack.mjs +32 -32
  99. package/scripts/rdc-brochure.mjs +482 -464
  100. package/scripts/rdc-design-cli.mjs +134 -134
  101. package/scripts/rebuild-mcp.mjs +107 -107
  102. package/scripts/self-test.mjs +1460 -1460
  103. package/scripts/stamp-git-sha.mjs +29 -29
  104. package/scripts/test-guide-validator.mjs +196 -196
  105. package/scripts/test-rdc-hooks.mjs +145 -145
  106. package/scripts/uninstall.ps1 +77 -77
  107. package/scripts/uninstall.sh +69 -69
  108. package/scripts/update.ps1 +43 -43
  109. package/scripts/update.sh +43 -43
  110. package/scripts/validate-place-histories.js +461 -461
  111. package/scripts/validate-publish-manifests.js +424 -424
  112. package/scripts/watch-init.mjs +100 -100
  113. package/skills/brochure/SKILL.md +107 -107
  114. package/skills/build/SKILL.md +563 -563
  115. package/skills/channel-formatter/SKILL.md +533 -533
  116. package/skills/co-develop/SKILL.md +196 -196
  117. package/skills/collab/SKILL.md +239 -239
  118. package/skills/convert/SKILL.md +140 -140
  119. package/skills/deploy/SKILL.md +541 -541
  120. package/skills/design/SKILL.md +211 -211
  121. package/skills/design/reference/ownership.md +16 -16
  122. package/skills/design/reference/rampa.md +92 -92
  123. package/skills/design/reference/studio-model.md +153 -153
  124. package/skills/edit/SKILL.md +98 -98
  125. package/skills/fixit/SKILL.md +165 -165
  126. package/skills/fs-mcp/SKILL.md +148 -148
  127. package/skills/handoff/SKILL.md +236 -200
  128. package/skills/help/SKILL.md +143 -143
  129. package/skills/housekeeping/SKILL.md +219 -160
  130. package/skills/lifeai-brochure-author/SKILL.md +340 -340
  131. package/skills/overnight/SKILL.md +251 -251
  132. package/skills/plan/SKILL.md +345 -345
  133. package/skills/preplan/SKILL.md +90 -90
  134. package/skills/prototype/SKILL.md +150 -150
  135. package/skills/rdc-brochurify/SKILL.md +245 -245
  136. package/skills/rdc-extract-verifier-rules/SKILL.md +191 -191
  137. package/skills/release/SKILL.md +140 -140
  138. package/skills/report/SKILL.md +100 -100
  139. package/skills/review/SKILL.md +152 -152
  140. package/skills/rpms-filemap/SKILL.cloud.md +111 -111
  141. package/skills/rpms-filemap/SKILL.md +111 -111
  142. package/skills/self-test/SKILL.md +132 -132
  143. package/skills/status/SKILL.md +99 -99
  144. package/skills/terminal-config/SKILL.md +62 -62
  145. package/skills/tests/MATRIX.md +54 -54
  146. package/skills/tests/README.md +47 -47
  147. package/skills/tests/rdc-brochure.test.json +34 -34
  148. package/skills/tests/rdc-build.test.json +36 -36
  149. package/skills/tests/rdc-channel-formatter.test.json +45 -45
  150. package/skills/tests/rdc-co-develop.test.json +29 -29
  151. package/skills/tests/rdc-collab.test.json +29 -29
  152. package/skills/tests/rdc-convert.test.json +35 -35
  153. package/skills/tests/rdc-deploy.test.json +30 -30
  154. package/skills/tests/rdc-design.test.json +27 -27
  155. package/skills/tests/rdc-edit.test.json +29 -29
  156. package/skills/tests/rdc-fixit.test.json +36 -36
  157. package/skills/tests/rdc-fs-mcp.test.json +36 -36
  158. package/skills/tests/rdc-handoff.test.json +28 -28
  159. package/skills/tests/rdc-help.test.json +29 -29
  160. package/skills/tests/rdc-housekeeping.test.json +32 -28
  161. package/skills/tests/rdc-lifeai-brochure-author.test.json +35 -35
  162. package/skills/tests/rdc-overnight.test.json +37 -37
  163. package/skills/tests/rdc-plan.test.json +27 -27
  164. package/skills/tests/rdc-preplan.test.json +31 -31
  165. package/skills/tests/rdc-prototype.test.json +28 -28
  166. package/skills/tests/rdc-rdc-brochurify.test.json +23 -23
  167. package/skills/tests/rdc-rdc-extract-verifier-rules.test.json +34 -34
  168. package/skills/tests/rdc-release.test.json +29 -29
  169. package/skills/tests/rdc-report.test.json +28 -28
  170. package/skills/tests/rdc-review.test.json +29 -29
  171. package/skills/tests/rdc-rpms-filemap.test.json +28 -28
  172. package/skills/tests/rdc-self-test.test.json +24 -24
  173. package/skills/tests/rdc-status.test.json +29 -29
  174. package/skills/tests/rdc-terminal-config.test.json +29 -29
  175. package/skills/tests/rdc-watch.test.json +24 -24
  176. package/skills/tests/rdc-workitems.test.json +27 -27
  177. package/skills/watch/SKILL.md +97 -97
  178. package/skills/workitems/SKILL.md +151 -151
  179. package/tests/acceptance.test.mjs +59 -59
  180. package/tests/channel-formatter.contract.test.mjs +251 -251
  181. package/tests/curl-surface.test.mjs +289 -289
  182. package/tests/harness-gates.test.mjs +325 -325
  183. package/tests/help-surface.test.mjs +61 -61
  184. package/tests/housekeeping-lessons-triage.test.mjs +49 -0
  185. package/tests/install-rdc-skills.test.mjs +49 -49
  186. package/tests/lessons-pipeline-contract.test.mjs +26 -0
  187. package/tests/manifest-contract-fields.test.mjs +78 -78
  188. package/tests/mcp.test.mjs +271 -271
  189. package/tests/rdc-brochure.test.mjs +125 -0
  190. package/tests/release-contract.test.mjs +16 -0
  191. package/tests/require-work-item-on-commit.test.mjs +162 -162
  192. package/tests/run-evidence-gate.test.mjs +82 -82
  193. package/tests/skill-test-matrix.test.mjs +66 -66
  194. package/tests/validate-skills.js +27 -27
  195. package/tests/work-item-exit-gate-l2.test.mjs +368 -368
  196. package/tests/work-item-exit-gate-l3.test.mjs +197 -197
@@ -1,245 +1,245 @@
1
- ---
2
- name: rdc-brochurify
3
- version: 0.1.0
4
- description: |
5
- Orchestrate a Brochurify job from source ingest through delivered PDF, using six parallel-dispatched typed sub-agents and the convergence loop. Use this skill EVERY TIME the user invokes Brochurify directly via "brochurify this", "make a brochure from", "convert this to a brochure PDF", or "rdc:brochurify". Also runs automatically when a job arrives from the broker via monkey_dispatch. The skill enforces D-001 through D-016 from the brochurify DECISIONS-LOG.
6
- triggers:
7
- - "rdc:brochurify"
8
- - "brochurify this"
9
- - "make a brochure from"
10
- - "convert to brochure PDF"
11
- - "generate brochure from"
12
- - monkey_dispatch payload with skill="brochurify"
13
- ---
14
-
15
- # rdc:brochurify Orchestrator
16
- > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
17
- > Report brochure job state, artifacts, and blockers directly; do not dump raw tool logs.
18
-
19
- > **Sandbox contract:** When `RDC_TEST=1`, do not install dependencies, open browsers,
20
- > upload to R2/Supabase, ask follow-up questions, or fabricate a PDF/grade/URL. Inspect
21
- > the fixture, report Wave 1 feasibility, and state that render/grade/deliver are
22
- > gated when the Brochurify runtime is absent.
23
-
24
- The orchestrator dispatches six waves of typed sub-agents in sequence. Each wave has a clear input contract, an output contract, and a parallelism profile.
25
-
26
- ## Inputs
27
-
28
- The orchestrator accepts a job payload:
29
-
30
- ```json
31
- {
32
- "job_id": "uuid",
33
- "source": {
34
- "kind": "url" | "html" | "docx" | "md" | "jsx" | "corpus",
35
- "ref": "https://..." | "file:///path/..." | "<html>..." | { corpus_query }
36
- },
37
- "mode": "read-only" | "cosmetic" | "editorial" | "creative",
38
- "theme": "prt" | "place-fund" | "zoen" | "evergreen" | "editorial-neutral",
39
- "page_size": "letter" | "a4" | "legal" | "digest" | "tabloid",
40
- "brief": "optional natural-language brief for editorial/creative modes",
41
- "org_id": "uuid",
42
- "user_id": "uuid"
43
- }
44
- ```
45
-
46
- ## Outputs
47
-
48
- - A PDF in R2 (`brochurify-output` bucket) with a signed URL
49
- - A completion record in Supabase `brochure_jobs` with:
50
- - `pdf_r2_key`, `pdf_url`
51
- - `final_grade`, `page_scores` (jsonb array)
52
- - `iter` (iteration count reached)
53
- - `trace` (jsonb log of all 6 waves × iterations)
54
-
55
- ## The Six Waves
56
-
57
- ### Wave 1 — Ingest
58
-
59
- **Goal:** Normalize any source into kit-compliant JSX.
60
-
61
- **Sub-agent:** `ingest-author` (typed agent with the `lifeai-brochure-author` skill loaded)
62
-
63
- **Inputs:** raw source from job payload
64
- **Outputs:** `working/draft.jsx` (kit-compliant JSX) + `working/assets/` (extracted images)
65
-
66
- **Per-source handling:**
67
- - `url` — fetch via Playwright (whitelist) or structural-summary mode (open web)
68
- - `html` — direct ingest, strip scripts/iframes/ads
69
- - `docx` — pandoc to HTML, then ingest
70
- - `md` — render to HTML, then ingest
71
- - `jsx` — pre-built input; skip to validate
72
- - `corpus` — Creative mode only; corpus reader + Author-Mode-* sub-agent
73
-
74
- **Failure mode:** if ingest cannot map content to kit primitives, raise a structured error with the unmappable content range and ask the user to clarify.
75
-
76
- ### Wave 2 — Validate
77
-
78
- **Goal:** Confirm the JSX passes static and structural validation before render.
79
-
80
- **Sub-agent:** none — runs `pnpm bk-lint working/draft.jsx` directly
81
-
82
- **Behavior:**
83
- - If pass → Wave 3
84
- - If fail → return errors to Wave 1 agent, retry once
85
- - If fail twice → escalate to orchestrator: try a different ingest strategy, page-size change, or surface to user
86
-
87
- **Every failure here writes to `enhancement-log.jsonl`** with:
88
- - `src: "ingest-author"`
89
- - `fail_layer: "static"` or `fail_layer: "structural"`
90
- - The specific rule violated
91
-
92
- ### Wave 3 — Render
93
-
94
- **Goal:** Produce a first-iteration PDF and per-page screenshots.
95
-
96
- **Sub-agent:** none — runs Paged.js via Playwright headless
97
-
98
- **Process:**
99
- 1. Build the kit + theme bundle into `working/bundle.html`
100
- 2. Open with Paged.js polyfill
101
- 3. Wait for `pagedjs:rendered` event
102
- 4. Snapshot DOM after pagination → `working/paged.html`
103
- 5. Per-page screenshot at 150 DPI → `working/pages/page-{N}.png`
104
- 6. Render to PDF → `working/iter-{i}.pdf`
105
-
106
- **Failure mode:** if Paged.js fails to converge (rare; usually a kit bug), fall back to print-to-PDF without paged-media polyfill, flag as low-quality iteration, continue.
107
-
108
- ### Wave 4 — Grade (Vision, Parallel)
109
-
110
- **Goal:** Score each page against the 7-dimension rubric.
111
-
112
- **Sub-agent:** `vision-grader` — dispatched **once per page in parallel**.
113
-
114
- **Per-page inputs:**
115
- - The page screenshot
116
- - The source JSX for that page (extracted by walking the paginated DOM)
117
- - The rubric (R1-R7 with weights and target ranges)
118
-
119
- **Per-page outputs (structured):**
120
- ```json
121
- {
122
- "page": 3,
123
- "grade": 82,
124
- "dimensions": {
125
- "R1_margin_integrity": 95,
126
- "R2_bottom_slack": 70,
127
- "R3_heading_breathing": 85,
128
- "R4_widows_orphans": 100,
129
- "R5_image_placement": 80,
130
- "R6_table_integrity": 100,
131
- "R7_text_density": 75
132
- },
133
- "issues": [
134
- {"dim": "R2", "desc": "tail gap 1.1in below last paragraph", "fix_hint": "compress paragraph or push next-page content"}
135
- ]
136
- }
137
- ```
138
-
139
- **Document grade:** `min(page_grades)` per D-013.
140
-
141
- **Convergence:**
142
- - Grade ≥ 75 → Wave 6 (Deliver)
143
- - Grade < 75 AND iter < 10 → Wave 5 (Patch)
144
- - iter = 10 → Wave 6 with `partial=true` flag
145
-
146
- ### Wave 5 — Patch (Parallel)
147
-
148
- **Goal:** Produce a corrected JSX that addresses the issues from Wave 4.
149
-
150
- **Sub-agent:** `patch-author` — dispatched **once per low-graded page in parallel**.
151
-
152
- **Mode restrictions:**
153
- - `read-only` — only break, sizing, spacing patches allowed
154
- - `cosmetic` — read-only patches + image resize, caption compression, paragraph splits at sentence boundaries
155
- - `editorial` — cosmetic + paragraph rewrites within 15% character or 25% word reduction
156
- - `creative` — editorial + free composition (the authoring sub-agent fully active)
157
-
158
- **Patch types:**
159
- - `force-break-before` — insert page break before an element
160
- - `adjust-spacing` — change Stack/Cluster gap variant
161
- - `resize-figure` — change Figure width/height variant
162
- - `compress-paragraph` — drop or merge a sentence (cosmetic+ only)
163
- - `rewrite-paragraph` — full rewrite (editorial+ only)
164
- - `rebalance-cluster` — split a Cluster onto two pages
165
- - `change-affinity` — adjust an affinity prop
166
-
167
- Each patch is applied to `working/draft.jsx`, the validator re-runs, then Wave 3 renders again.
168
-
169
- **Edit tracking (editorial mode):** every paragraph rewrite is logged with before/after to `working/edits.jsonl`. The completion record includes this log.
170
-
171
- ### Wave 6 — Deliver
172
-
173
- **Goal:** Final PDF, signed URL, completion record.
174
-
175
- **Process:**
176
- 1. Upload final PDF to R2 with key `brochurify-output/{org_id}/{job_id}.pdf`
177
- 2. Generate 7-day signed URL
178
- 3. Update `brochure_jobs` row:
179
- ```sql
180
- UPDATE brochure_jobs SET
181
- status = 'completed',
182
- iter = $iter,
183
- current_grade = $grade,
184
- page_scores = $pageScoresJson,
185
- pdf_r2_key = $r2Key,
186
- pdf_url = $signedUrl,
187
- completed_at = now()
188
- WHERE id = $jobId;
189
- ```
190
- 4. Send SSE event `{type:"complete", url, grade, iter}` to broker
191
- 5. Append enhancement log entries from this run to `enhancement-log.jsonl`
192
-
193
- ## Trace Logging
194
-
195
- Every wave appends to `working/trace.jsonl`:
196
-
197
- ```jsonl
198
- {"ts":"...","wave":1,"agent":"ingest-author","iter":1,"status":"start"}
199
- {"ts":"...","wave":1,"agent":"ingest-author","iter":1,"status":"complete","blocks":127}
200
- {"ts":"...","wave":2,"iter":1,"status":"complete","errors":0}
201
- {"ts":"...","wave":3,"iter":1,"status":"complete","pages":8,"render_ms":2340}
202
- {"ts":"...","wave":4,"iter":1,"page":1,"grade":85,"status":"complete"}
203
- {"ts":"...","wave":4,"iter":1,"page":2,"grade":68,"status":"complete","issues":2}
204
- ...
205
- ```
206
-
207
- This trace is stored in `brochure_jobs.payload.trace` for forensic review.
208
-
209
- ## Cost Profile
210
-
211
- - **Wave 1:** 1 sub-agent call (one model invocation)
212
- - **Wave 2:** 0 model calls (deterministic validator)
213
- - **Wave 3:** 0 model calls (deterministic render)
214
- - **Wave 4:** N parallel model calls (N = page count)
215
- - **Wave 5:** M parallel model calls (M = pages needing patch; usually 0-3)
216
- - **Wave 6:** 0 model calls
217
-
218
- Typical 8-page brochure, 2 iterations: ~1 + 16 + 4 = ~21 model calls total. All on Max plan. Zero per-job API cost.
219
-
220
- ## Hard Caps
221
-
222
- - **Max iterations:** 10 (per D-006)
223
- - **Max wall-clock:** 15 minutes per job
224
- - **Max page count:** 50 (anything larger is split into multiple jobs)
225
- - **Max source size:** 5MB raw HTML, 25MB docx, 50MB total assets
226
-
227
- Exceeding any cap → job fails with structured error; no partial billing.
228
-
229
- ## Failure Recovery
230
-
231
- | Failure | Recovery |
232
- |---|---|
233
- | Validator fails repeatedly | Try page-size change (Letter → Legal → Digest) before failing job |
234
- | Vision agent disagrees with itself | Lock grade after 3 iterations of same page; mark "best-effort" |
235
- | Convergence not reached at iter=10 | Ship best version, flag low-graded pages, log to enhancement |
236
- | Paged.js render fails | Fall back to direct PDF; flag low-quality iteration |
237
- | R2 upload fails | Retry 3x then fall back to Supabase storage URL |
238
-
239
- ## When to invoke
240
-
241
- Direct user invocation: `rdc:brochurify <source-url-or-path> [--mode] [--theme] [--page-size]`
242
-
243
- Programmatic invocation: a `monkey_dispatch` job arriving with `skill="brochurify"` and the job payload as `args`.
244
-
245
- Either path executes the same 6-wave loop. Direct user invocation also returns the trace and the PDF URL to the calling session.
1
+ ---
2
+ name: rdc-brochurify
3
+ version: 0.1.0
4
+ description: |
5
+ Orchestrate a Brochurify job from source ingest through delivered PDF, using six parallel-dispatched typed sub-agents and the convergence loop. Use this skill EVERY TIME the user invokes Brochurify directly via "brochurify this", "make a brochure from", "convert this to a brochure PDF", or "rdc:brochurify". Also runs automatically when a job arrives from the broker via monkey_dispatch. The skill enforces D-001 through D-016 from the brochurify DECISIONS-LOG.
6
+ triggers:
7
+ - "rdc:brochurify"
8
+ - "brochurify this"
9
+ - "make a brochure from"
10
+ - "convert to brochure PDF"
11
+ - "generate brochure from"
12
+ - monkey_dispatch payload with skill="brochurify"
13
+ ---
14
+
15
+ # rdc:brochurify Orchestrator
16
+ > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
17
+ > Report brochure job state, artifacts, and blockers directly; do not dump raw tool logs.
18
+
19
+ > **Sandbox contract:** When `RDC_TEST=1`, do not install dependencies, open browsers,
20
+ > upload to R2/Supabase, ask follow-up questions, or fabricate a PDF/grade/URL. Inspect
21
+ > the fixture, report Wave 1 feasibility, and state that render/grade/deliver are
22
+ > gated when the Brochurify runtime is absent.
23
+
24
+ The orchestrator dispatches six waves of typed sub-agents in sequence. Each wave has a clear input contract, an output contract, and a parallelism profile.
25
+
26
+ ## Inputs
27
+
28
+ The orchestrator accepts a job payload:
29
+
30
+ ```json
31
+ {
32
+ "job_id": "uuid",
33
+ "source": {
34
+ "kind": "url" | "html" | "docx" | "md" | "jsx" | "corpus",
35
+ "ref": "https://..." | "file:///path/..." | "<html>..." | { corpus_query }
36
+ },
37
+ "mode": "read-only" | "cosmetic" | "editorial" | "creative",
38
+ "theme": "prt" | "place-fund" | "zoen" | "evergreen" | "editorial-neutral",
39
+ "page_size": "letter" | "a4" | "legal" | "digest" | "tabloid",
40
+ "brief": "optional natural-language brief for editorial/creative modes",
41
+ "org_id": "uuid",
42
+ "user_id": "uuid"
43
+ }
44
+ ```
45
+
46
+ ## Outputs
47
+
48
+ - A PDF in R2 (`brochurify-output` bucket) with a signed URL
49
+ - A completion record in Supabase `brochure_jobs` with:
50
+ - `pdf_r2_key`, `pdf_url`
51
+ - `final_grade`, `page_scores` (jsonb array)
52
+ - `iter` (iteration count reached)
53
+ - `trace` (jsonb log of all 6 waves × iterations)
54
+
55
+ ## The Six Waves
56
+
57
+ ### Wave 1 — Ingest
58
+
59
+ **Goal:** Normalize any source into kit-compliant JSX.
60
+
61
+ **Sub-agent:** `ingest-author` (typed agent with the `lifeai-brochure-author` skill loaded)
62
+
63
+ **Inputs:** raw source from job payload
64
+ **Outputs:** `working/draft.jsx` (kit-compliant JSX) + `working/assets/` (extracted images)
65
+
66
+ **Per-source handling:**
67
+ - `url` — fetch via Playwright (whitelist) or structural-summary mode (open web)
68
+ - `html` — direct ingest, strip scripts/iframes/ads
69
+ - `docx` — pandoc to HTML, then ingest
70
+ - `md` — render to HTML, then ingest
71
+ - `jsx` — pre-built input; skip to validate
72
+ - `corpus` — Creative mode only; corpus reader + Author-Mode-* sub-agent
73
+
74
+ **Failure mode:** if ingest cannot map content to kit primitives, raise a structured error with the unmappable content range and ask the user to clarify.
75
+
76
+ ### Wave 2 — Validate
77
+
78
+ **Goal:** Confirm the JSX passes static and structural validation before render.
79
+
80
+ **Sub-agent:** none — runs `pnpm bk-lint working/draft.jsx` directly
81
+
82
+ **Behavior:**
83
+ - If pass → Wave 3
84
+ - If fail → return errors to Wave 1 agent, retry once
85
+ - If fail twice → escalate to orchestrator: try a different ingest strategy, page-size change, or surface to user
86
+
87
+ **Every failure here writes to `enhancement-log.jsonl`** with:
88
+ - `src: "ingest-author"`
89
+ - `fail_layer: "static"` or `fail_layer: "structural"`
90
+ - The specific rule violated
91
+
92
+ ### Wave 3 — Render
93
+
94
+ **Goal:** Produce a first-iteration PDF and per-page screenshots.
95
+
96
+ **Sub-agent:** none — runs Paged.js via Playwright headless
97
+
98
+ **Process:**
99
+ 1. Build the kit + theme bundle into `working/bundle.html`
100
+ 2. Open with Paged.js polyfill
101
+ 3. Wait for `pagedjs:rendered` event
102
+ 4. Snapshot DOM after pagination → `working/paged.html`
103
+ 5. Per-page screenshot at 150 DPI → `working/pages/page-{N}.png`
104
+ 6. Render to PDF → `working/iter-{i}.pdf`
105
+
106
+ **Failure mode:** if Paged.js fails to converge (rare; usually a kit bug), fall back to print-to-PDF without paged-media polyfill, flag as low-quality iteration, continue.
107
+
108
+ ### Wave 4 — Grade (Vision, Parallel)
109
+
110
+ **Goal:** Score each page against the 7-dimension rubric.
111
+
112
+ **Sub-agent:** `vision-grader` — dispatched **once per page in parallel**.
113
+
114
+ **Per-page inputs:**
115
+ - The page screenshot
116
+ - The source JSX for that page (extracted by walking the paginated DOM)
117
+ - The rubric (R1-R7 with weights and target ranges)
118
+
119
+ **Per-page outputs (structured):**
120
+ ```json
121
+ {
122
+ "page": 3,
123
+ "grade": 82,
124
+ "dimensions": {
125
+ "R1_margin_integrity": 95,
126
+ "R2_bottom_slack": 70,
127
+ "R3_heading_breathing": 85,
128
+ "R4_widows_orphans": 100,
129
+ "R5_image_placement": 80,
130
+ "R6_table_integrity": 100,
131
+ "R7_text_density": 75
132
+ },
133
+ "issues": [
134
+ {"dim": "R2", "desc": "tail gap 1.1in below last paragraph", "fix_hint": "compress paragraph or push next-page content"}
135
+ ]
136
+ }
137
+ ```
138
+
139
+ **Document grade:** `min(page_grades)` per D-013.
140
+
141
+ **Convergence:**
142
+ - Grade ≥ 75 → Wave 6 (Deliver)
143
+ - Grade < 75 AND iter < 10 → Wave 5 (Patch)
144
+ - iter = 10 → Wave 6 with `partial=true` flag
145
+
146
+ ### Wave 5 — Patch (Parallel)
147
+
148
+ **Goal:** Produce a corrected JSX that addresses the issues from Wave 4.
149
+
150
+ **Sub-agent:** `patch-author` — dispatched **once per low-graded page in parallel**.
151
+
152
+ **Mode restrictions:**
153
+ - `read-only` — only break, sizing, spacing patches allowed
154
+ - `cosmetic` — read-only patches + image resize, caption compression, paragraph splits at sentence boundaries
155
+ - `editorial` — cosmetic + paragraph rewrites within 15% character or 25% word reduction
156
+ - `creative` — editorial + free composition (the authoring sub-agent fully active)
157
+
158
+ **Patch types:**
159
+ - `force-break-before` — insert page break before an element
160
+ - `adjust-spacing` — change Stack/Cluster gap variant
161
+ - `resize-figure` — change Figure width/height variant
162
+ - `compress-paragraph` — drop or merge a sentence (cosmetic+ only)
163
+ - `rewrite-paragraph` — full rewrite (editorial+ only)
164
+ - `rebalance-cluster` — split a Cluster onto two pages
165
+ - `change-affinity` — adjust an affinity prop
166
+
167
+ Each patch is applied to `working/draft.jsx`, the validator re-runs, then Wave 3 renders again.
168
+
169
+ **Edit tracking (editorial mode):** every paragraph rewrite is logged with before/after to `working/edits.jsonl`. The completion record includes this log.
170
+
171
+ ### Wave 6 — Deliver
172
+
173
+ **Goal:** Final PDF, signed URL, completion record.
174
+
175
+ **Process:**
176
+ 1. Upload final PDF to R2 with key `brochurify-output/{org_id}/{job_id}.pdf`
177
+ 2. Generate 7-day signed URL
178
+ 3. Update `brochure_jobs` row:
179
+ ```sql
180
+ UPDATE brochure_jobs SET
181
+ status = 'completed',
182
+ iter = $iter,
183
+ current_grade = $grade,
184
+ page_scores = $pageScoresJson,
185
+ pdf_r2_key = $r2Key,
186
+ pdf_url = $signedUrl,
187
+ completed_at = now()
188
+ WHERE id = $jobId;
189
+ ```
190
+ 4. Send SSE event `{type:"complete", url, grade, iter}` to broker
191
+ 5. Append enhancement log entries from this run to `enhancement-log.jsonl`
192
+
193
+ ## Trace Logging
194
+
195
+ Every wave appends to `working/trace.jsonl`:
196
+
197
+ ```jsonl
198
+ {"ts":"...","wave":1,"agent":"ingest-author","iter":1,"status":"start"}
199
+ {"ts":"...","wave":1,"agent":"ingest-author","iter":1,"status":"complete","blocks":127}
200
+ {"ts":"...","wave":2,"iter":1,"status":"complete","errors":0}
201
+ {"ts":"...","wave":3,"iter":1,"status":"complete","pages":8,"render_ms":2340}
202
+ {"ts":"...","wave":4,"iter":1,"page":1,"grade":85,"status":"complete"}
203
+ {"ts":"...","wave":4,"iter":1,"page":2,"grade":68,"status":"complete","issues":2}
204
+ ...
205
+ ```
206
+
207
+ This trace is stored in `brochure_jobs.payload.trace` for forensic review.
208
+
209
+ ## Cost Profile
210
+
211
+ - **Wave 1:** 1 sub-agent call (one model invocation)
212
+ - **Wave 2:** 0 model calls (deterministic validator)
213
+ - **Wave 3:** 0 model calls (deterministic render)
214
+ - **Wave 4:** N parallel model calls (N = page count)
215
+ - **Wave 5:** M parallel model calls (M = pages needing patch; usually 0-3)
216
+ - **Wave 6:** 0 model calls
217
+
218
+ Typical 8-page brochure, 2 iterations: ~1 + 16 + 4 = ~21 model calls total. All on Max plan. Zero per-job API cost.
219
+
220
+ ## Hard Caps
221
+
222
+ - **Max iterations:** 10 (per D-006)
223
+ - **Max wall-clock:** 15 minutes per job
224
+ - **Max page count:** 50 (anything larger is split into multiple jobs)
225
+ - **Max source size:** 5MB raw HTML, 25MB docx, 50MB total assets
226
+
227
+ Exceeding any cap → job fails with structured error; no partial billing.
228
+
229
+ ## Failure Recovery
230
+
231
+ | Failure | Recovery |
232
+ |---|---|
233
+ | Validator fails repeatedly | Try page-size change (Letter → Legal → Digest) before failing job |
234
+ | Vision agent disagrees with itself | Lock grade after 3 iterations of same page; mark "best-effort" |
235
+ | Convergence not reached at iter=10 | Ship best version, flag low-graded pages, log to enhancement |
236
+ | Paged.js render fails | Fall back to direct PDF; flag low-quality iteration |
237
+ | R2 upload fails | Retry 3x then fall back to Supabase storage URL |
238
+
239
+ ## When to invoke
240
+
241
+ Direct user invocation: `rdc:brochurify <source-url-or-path> [--mode] [--theme] [--page-size]`
242
+
243
+ Programmatic invocation: a `monkey_dispatch` job arriving with `skill="brochurify"` and the job payload as `args`.
244
+
245
+ Either path executes the same 6-wave loop. Direct user invocation also returns the trace and the PDF URL to the calling session.