@daniellins/power-claude 0.16.3

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.

Potentially problematic release.


This version of @daniellins/power-claude might be problematic. Click here for more details.

Files changed (467) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +121 -0
  3. package/bin/cli.js +124 -0
  4. package/installer/__tests__/doctor-ready-oracles.test.cjs +140 -0
  5. package/installer/__tests__/merge-settings.test.cjs +330 -0
  6. package/installer/adopt.js +161 -0
  7. package/installer/copy.js +203 -0
  8. package/installer/doctor.js +266 -0
  9. package/installer/install.js +155 -0
  10. package/installer/manifest.js +102 -0
  11. package/installer/motor-scripts.js +50 -0
  12. package/installer/motor-scripts.json +39 -0
  13. package/installer/uninstall.js +99 -0
  14. package/installer/update.js +376 -0
  15. package/installer/util.js +113 -0
  16. package/installer/wizard.js +64 -0
  17. package/package.json +26 -0
  18. package/scripts/__fixtures__/anti-path-demo/agents/ap-writer.md +13 -0
  19. package/scripts/__fixtures__/anti-path-demo/templates/write-tmpl.md +7 -0
  20. package/scripts/__fixtures__/anti-path-demo/workflows/wf-ap.smoke.json +10 -0
  21. package/scripts/__fixtures__/anti-path-demo/workflows/wf-ap.yaml +25 -0
  22. package/scripts/__fixtures__/assess-tier/retrofit-leve/pod/agents/content-chief.md +1 -0
  23. package/scripts/__fixtures__/assess-tier/retrofit-leve/pod/workflows/wf-criacao-redteam.yaml +3 -0
  24. package/scripts/__fixtures__/assess-tier/retrofit-leve/pod-spec.json +13 -0
  25. package/scripts/__fixtures__/fidelity/fake-green-average-in-band.yaml +21 -0
  26. package/scripts/__fixtures__/fidelity/fake-green-average.yaml +18 -0
  27. package/scripts/__fixtures__/fidelity/fake-green-denominator.yaml +19 -0
  28. package/scripts/__fixtures__/fidelity/fake-green-missing-evidence.yaml +18 -0
  29. package/scripts/__fixtures__/fidelity/fake-green-threshold.yaml +18 -0
  30. package/scripts/__fixtures__/fidelity/fake-green-weight.yaml +18 -0
  31. package/scripts/__fixtures__/fidelity/golden.yaml +31 -0
  32. package/scripts/__fixtures__/fidelity/trindade-incoherent.yaml +15 -0
  33. package/scripts/__fixtures__/forge-canonical/pod-spec-example.json +37 -0
  34. package/scripts/__fixtures__/migrate-squad/authored/agents/offer-engineer.md +17 -0
  35. package/scripts/__fixtures__/migrate-squad/authored/knowledge/no-source.md +7 -0
  36. package/scripts/__fixtures__/migrate-squad/authored/knowledge/value-stack-method.md +8 -0
  37. package/scripts/__fixtures__/migrate-squad/authored/specs/wf-sample.smoke.json +24 -0
  38. package/scripts/__fixtures__/migrate-squad/authored/specs/wf-sample.spec.json +45 -0
  39. package/scripts/__fixtures__/migrate-squad/legacy-squad/HEADLINE.md +3 -0
  40. package/scripts/__fixtures__/migrate-squad/legacy-squad/README.md +4 -0
  41. package/scripts/__fixtures__/migrate-squad/legacy-squad/agents/hormozi-offer.md +14 -0
  42. package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/dead-redundant.md +4 -0
  43. package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/method-guide.md +6 -0
  44. package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/veto-screen.md +4 -0
  45. package/scripts/__fixtures__/migrate-squad/legacy-squad/config/config.yaml +2 -0
  46. package/scripts/__fixtures__/migrate-squad/legacy-squad/data/case-library.md +3 -0
  47. package/scripts/__fixtures__/migrate-squad/legacy-squad/scripts/validate-mvn.py +16 -0
  48. package/scripts/__fixtures__/migrate-squad/legacy-squad/sops/sop-sample.md +3 -0
  49. package/scripts/__fixtures__/migrate-squad/legacy-squad/squad-io.yaml +14 -0
  50. package/scripts/__fixtures__/migrate-squad/legacy-squad/tasks/gather-context.md +7 -0
  51. package/scripts/__fixtures__/migrate-squad/legacy-squad/templates/output-tmpl.md +5 -0
  52. package/scripts/__fixtures__/migrate-squad/legacy-squad/workflows/wf-sample.yaml +24 -0
  53. package/scripts/__fixtures__/pipeline/pipelines/pipeline-checkpoint.yaml +21 -0
  54. package/scripts/__fixtures__/pipeline/pipelines/pipeline-demo.yaml +22 -0
  55. package/scripts/__fixtures__/pipeline/pods/pipe-a/agents/maker.md +13 -0
  56. package/scripts/__fixtures__/pipeline/pods/pipe-a/memory/learnings.consolidated.md +8 -0
  57. package/scripts/__fixtures__/pipeline/pods/pipe-a/memory/learnings.jsonl +83 -0
  58. package/scripts/__fixtures__/pipeline/pods/pipe-a/templates/make-tmpl.md +8 -0
  59. package/scripts/__fixtures__/pipeline/pods/pipe-a/workflows/wf-a.yaml +16 -0
  60. package/scripts/__fixtures__/pipeline/pods/pipe-b/agents/user.md +13 -0
  61. package/scripts/__fixtures__/pipeline/pods/pipe-b/memory/learnings.consolidated.md +8 -0
  62. package/scripts/__fixtures__/pipeline/pods/pipe-b/memory/learnings.jsonl +14 -0
  63. package/scripts/__fixtures__/pipeline/pods/pipe-b/templates/use-tmpl.md +6 -0
  64. package/scripts/__fixtures__/pipeline/pods/pipe-b/workflows/wf-b.yaml +16 -0
  65. package/scripts/__fixtures__/pod-run/agents/forge-chief.md +13 -0
  66. package/scripts/__fixtures__/pod-run/agents/pod-critic.md +13 -0
  67. package/scripts/__fixtures__/pod-run/templates/build-tmpl.md +8 -0
  68. package/scripts/__fixtures__/pod-run/templates/gate-tmpl.md +6 -0
  69. package/scripts/__fixtures__/pod-run/workflows/wf-min.yaml +43 -0
  70. package/scripts/__fixtures__/pod-run/workflows/wf-skip-modes.yaml +50 -0
  71. package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-all-skippable.yaml +30 -0
  72. package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-criteria-escalar-de-bloco.yaml +40 -0
  73. package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-skip-mode-desconhecido.yaml +30 -0
  74. package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-unknown-key.yaml +29 -0
  75. package/scripts/__fixtures__/pod-workflow/invalid-cycle.yaml +26 -0
  76. package/scripts/__fixtures__/pod-workflow/invalid-fix-loop-backedge.yaml +29 -0
  77. package/scripts/__fixtures__/pod-workflow/invalid-fix-loop-forward.yaml +29 -0
  78. package/scripts/__fixtures__/pod-workflow/invalid-handoff-open.yaml +27 -0
  79. package/scripts/__fixtures__/pod-workflow/invalid-knowledge-shape.yaml +18 -0
  80. package/scripts/__fixtures__/pod-workflow/invalid-missing-agent.yaml +15 -0
  81. package/scripts/__fixtures__/pod-workflow/invalid-missing-outputs.yaml +15 -0
  82. package/scripts/__fixtures__/pod-workflow/invalid-missing-template.yaml +15 -0
  83. package/scripts/__fixtures__/pod-workflow/invalid-missing-veto.yaml +13 -0
  84. package/scripts/__fixtures__/pod-workflow/invalid-template-not-on-disk.yaml +16 -0
  85. package/scripts/__fixtures__/pod-workflow/invalid-veto-prose.yaml +17 -0
  86. package/scripts/__fixtures__/pod-workflow/knowledge/a.md +4 -0
  87. package/scripts/__fixtures__/pod-workflow/knowledge/b.md +4 -0
  88. package/scripts/__fixtures__/pod-workflow/knowledge/c.md +4 -0
  89. package/scripts/__fixtures__/pod-workflow/templates/step-tmpl.md +7 -0
  90. package/scripts/__fixtures__/pod-workflow/valid-checkpoint-skip-modes.yaml +29 -0
  91. package/scripts/__fixtures__/pod-workflow/valid-fix-loop.yaml +30 -0
  92. package/scripts/__fixtures__/pod-workflow/valid-knowledge.yaml +30 -0
  93. package/scripts/__fixtures__/pod-workflow/valid-veto-always-true.yaml +20 -0
  94. package/scripts/__fixtures__/pod-workflow/valid.yaml +27 -0
  95. package/scripts/__fixtures__/smoke-canary/agents/canary-reporter.md +13 -0
  96. package/scripts/__fixtures__/smoke-canary/agents/canary-researcher.md +13 -0
  97. package/scripts/__fixtures__/smoke-canary/agents/canary-synth.md +13 -0
  98. package/scripts/__fixtures__/smoke-canary/memory/learnings.consolidated.md +10 -0
  99. package/scripts/__fixtures__/smoke-canary/memory/learnings.jsonl +448 -0
  100. package/scripts/__fixtures__/smoke-canary/templates/report-tmpl.md +9 -0
  101. package/scripts/__fixtures__/smoke-canary/templates/research-tmpl.md +7 -0
  102. package/scripts/__fixtures__/smoke-canary/templates/synth-tmpl.md +9 -0
  103. package/scripts/__fixtures__/smoke-canary/workflows/wf-canary.smoke.json +11 -0
  104. package/scripts/__fixtures__/smoke-canary/workflows/wf-canary.yaml +53 -0
  105. package/scripts/__fixtures__/source-audit/fake-green-bronze-unsignaled.yaml +10 -0
  106. package/scripts/__fixtures__/source-audit/fake-green-counts.yaml +9 -0
  107. package/scripts/__fixtures__/source-audit/fake-green-missing-evidence.yaml +9 -0
  108. package/scripts/__fixtures__/source-audit/fake-green-unclassified.yaml +10 -0
  109. package/scripts/__fixtures__/source-audit/fake-green-verdict.yaml +10 -0
  110. package/scripts/__fixtures__/source-audit/golden-blocked.yaml +10 -0
  111. package/scripts/__fixtures__/source-audit/golden.yaml +11 -0
  112. package/scripts/__fixtures__/sweep-forms/agents/forms-count.md +13 -0
  113. package/scripts/__fixtures__/sweep-forms/agents/forms-field.md +13 -0
  114. package/scripts/__fixtures__/sweep-forms/agents/forms-fileref.md +13 -0
  115. package/scripts/__fixtures__/sweep-forms/agents/forms-json.md +13 -0
  116. package/scripts/__fixtures__/sweep-forms/agents/forms-section.md +13 -0
  117. package/scripts/__fixtures__/sweep-forms/specs/wf-forms.spec.json +5 -0
  118. package/scripts/__fixtures__/sweep-forms/templates/t_count.md +5 -0
  119. package/scripts/__fixtures__/sweep-forms/templates/t_field.md +3 -0
  120. package/scripts/__fixtures__/sweep-forms/templates/t_fileref.md +3 -0
  121. package/scripts/__fixtures__/sweep-forms/templates/t_json.md +0 -0
  122. package/scripts/__fixtures__/sweep-forms/templates/t_section.md +3 -0
  123. package/scripts/__fixtures__/sweep-forms/workflows/wf-forms.smoke.json +13 -0
  124. package/scripts/__fixtures__/sweep-forms/workflows/wf-forms.yaml +67 -0
  125. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-1-noop-state-json.fixture.md +18 -0
  126. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-2-crash-buildworkflowyaml.fixture.md +26 -0
  127. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-3-nasce-verde-skip-modes.fixture.md +29 -0
  128. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-4-guarda-sem-irmao.fixture.md +17 -0
  129. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-5a-diff-stat-sem-guarda.fixture.md +17 -0
  130. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-5b-test-f-sobre-diretorio.fixture.md +20 -0
  131. package/scripts/__fixtures__/veto-checks/copy-clean.md +4 -0
  132. package/scripts/__fixtures__/veto-checks/copy-dashes.md +4 -0
  133. package/scripts/__fixtures__/veto-checks/n8n-bad.md +18 -0
  134. package/scripts/__fixtures__/veto-checks/n8n-ok.md +22 -0
  135. package/scripts/__fixtures__/veto-checks/page-bad.html +7 -0
  136. package/scripts/__fixtures__/veto-checks/phash/copy.png +0 -0
  137. package/scripts/__fixtures__/veto-checks/phash/distinct.png +0 -0
  138. package/scripts/__fixtures__/veto-checks/phash/distinct2.png +0 -0
  139. package/scripts/__fixtures__/veto-checks/phash/make-fixtures.cjs +203 -0
  140. package/scripts/__fixtures__/veto-checks/phash/ref.png +0 -0
  141. package/scripts/__fixtures__/veto-checks/slide-ok.html +15 -0
  142. package/scripts/__fixtures__/veto-checks/slide-overflow.html +14 -0
  143. package/scripts/__fixtures__/veto-checks/sweep-pod/agents/vc-checker.md +13 -0
  144. package/scripts/__fixtures__/veto-checks/sweep-pod/templates/check-tmpl.md +6 -0
  145. package/scripts/__fixtures__/veto-checks/sweep-pod/workflows/wf-vc.smoke.json +10 -0
  146. package/scripts/__fixtures__/veto-checks/sweep-pod/workflows/wf-vc.yaml +19 -0
  147. package/scripts/__fixtures__/voz-do-dono/README.md +23 -0
  148. package/scripts/__fixtures__/voz-do-dono/dono-escalar.yaml +9 -0
  149. package/scripts/__fixtures__/voz-do-dono/dono-guia.yaml +10 -0
  150. package/scripts/__fixtures__/voz-do-dono/peca-3a-pessoa.md +6 -0
  151. package/scripts/__fixtures__/voz-do-dono/peca-com-lexico-proibido.md +6 -0
  152. package/scripts/__fixtures__/voz-do-dono/peca-limpa-1a-pessoa.md +6 -0
  153. package/scripts/__tests__/derive-ready-transitions.test.cjs +269 -0
  154. package/scripts/__tests__/enforce-cycle-authority.test.cjs +869 -0
  155. package/scripts/__tests__/enforce-git-push-authority.test.cjs +701 -0
  156. package/scripts/__tests__/enforce-ready-oracles.test.cjs +745 -0
  157. package/scripts/__tests__/motor-scripts.test.cjs +339 -0
  158. package/scripts/__tests__/pc-run-pod-counter.test.cjs +58 -0
  159. package/scripts/__tests__/pc-run-pod.test.cjs +578 -0
  160. package/scripts/__tests__/validate-pod-workflow.test.cjs +90 -0
  161. package/scripts/__tests__/validate-story-acs.test.cjs +607 -0
  162. package/scripts/anti-path.test.cjs +163 -0
  163. package/scripts/arena.cjs +514 -0
  164. package/scripts/arena.test.cjs +213 -0
  165. package/scripts/brief-leitura-obrigatoria.test.cjs +364 -0
  166. package/scripts/consolidate-knowledge-runner.test.cjs +249 -0
  167. package/scripts/default-funcional.test.cjs +153 -0
  168. package/scripts/derive-ready-transitions.cjs +325 -0
  169. package/scripts/forge-additive.test.cjs +158 -0
  170. package/scripts/forge-assess-tier.cjs +205 -0
  171. package/scripts/forge-assess-tier.test.cjs +114 -0
  172. package/scripts/forge-canonical.test.cjs +624 -0
  173. package/scripts/forge-generate.cjs +1303 -0
  174. package/scripts/forge-harden-learning.cjs +921 -0
  175. package/scripts/forge-harden-learning.test.cjs +242 -0
  176. package/scripts/forge-ingest-memory.cjs +136 -0
  177. package/scripts/forge-upgrade-pod.cjs +368 -0
  178. package/scripts/forge.test.cjs +609 -0
  179. package/scripts/harden-knowledge.test.cjs +612 -0
  180. package/scripts/harness-g5-lite.cjs +243 -0
  181. package/scripts/harness-g5-lite.test.cjs +134 -0
  182. package/scripts/hn-carousel-contrato-entrada.test.cjs +96 -0
  183. package/scripts/migrate-squad-orchestration.test.cjs +146 -0
  184. package/scripts/migration-manifest-sf3.2.test.cjs +382 -0
  185. package/scripts/migration-manifest-sf3.3.test.cjs +170 -0
  186. package/scripts/migration-manifest-sf5.5.test.cjs +189 -0
  187. package/scripts/migration-manifest.cjs +1146 -0
  188. package/scripts/migration-manifest.test.cjs +186 -0
  189. package/scripts/npm-scope-invocation.test.cjs +194 -0
  190. package/scripts/owner-layer.cjs +442 -0
  191. package/scripts/owner-layer.test.cjs +358 -0
  192. package/scripts/pc-run-pipeline.cjs +289 -0
  193. package/scripts/pc-run-pipeline.test.cjs +256 -0
  194. package/scripts/pc-run-pod-countgte.test.cjs +66 -0
  195. package/scripts/pc-run-pod.cjs +1355 -0
  196. package/scripts/phash-gate.test.cjs +433 -0
  197. package/scripts/pod-export-compile.cjs +487 -0
  198. package/scripts/pod-export-compile.test.cjs +312 -0
  199. package/scripts/pod-export-executor.cjs +678 -0
  200. package/scripts/pod-export-executor.test.cjs +1341 -0
  201. package/scripts/pod-export-hardening.test.cjs +531 -0
  202. package/scripts/pod-export-postprocess.cjs +427 -0
  203. package/scripts/pod-export-postprocess.test.cjs +558 -0
  204. package/scripts/pod-export-queue-race.test.cjs +865 -0
  205. package/scripts/pod-export-release.cjs +473 -0
  206. package/scripts/pod-export-release.test.cjs +267 -0
  207. package/scripts/pod-export-service.cjs +1297 -0
  208. package/scripts/pod-export-service.test.cjs +489 -0
  209. package/scripts/pod-export-tools.cjs +470 -0
  210. package/scripts/pod-export-ui.cjs +805 -0
  211. package/scripts/pod-export-ui.test.cjs +301 -0
  212. package/scripts/pod-memory-budget.test.cjs +309 -0
  213. package/scripts/pod-memory-note.cjs +357 -0
  214. package/scripts/pod-memory-note.test.cjs +452 -0
  215. package/scripts/pod-memory.cjs +1252 -0
  216. package/scripts/pod-memory.test.cjs +951 -0
  217. package/scripts/render-png.test.cjs +307 -0
  218. package/scripts/smoke-isolation.test.cjs +100 -0
  219. package/scripts/smoke-pod-workflow.cjs +755 -0
  220. package/scripts/smoke-sweep.test.cjs +170 -0
  221. package/scripts/validate-adopt.js +235 -0
  222. package/scripts/validate-branding.js +84 -0
  223. package/scripts/validate-budgets.js +140 -0
  224. package/scripts/validate-fidelity-output.cjs +267 -0
  225. package/scripts/validate-fidelity-output.test.cjs +101 -0
  226. package/scripts/validate-install.js +230 -0
  227. package/scripts/validate-no-clone.cjs +220 -0
  228. package/scripts/validate-no-clone.test.cjs +77 -0
  229. package/scripts/validate-pipeline.cjs +145 -0
  230. package/scripts/validate-pod-workflow.cjs +878 -0
  231. package/scripts/validate-source-audit.cjs +170 -0
  232. package/scripts/validate-source-audit.test.cjs +90 -0
  233. package/scripts/validate-story-acs.cjs +862 -0
  234. package/scripts/validate-update-scope-motor.js +421 -0
  235. package/scripts/veto-checks/html-valid.cjs +92 -0
  236. package/scripts/veto-checks/lexical-check.cjs +62 -0
  237. package/scripts/veto-checks/phash-gate.cjs +589 -0
  238. package/scripts/veto-checks/render-gate.cjs +165 -0
  239. package/scripts/veto-checks/render-png.cjs +358 -0
  240. package/scripts/veto-checks.test.cjs +219 -0
  241. package/scripts/watcher-audit.cjs +178 -0
  242. package/template/.claude/CLAUDE.md +103 -0
  243. package/template/.claude/agents/pc-analyst.md +100 -0
  244. package/template/.claude/agents/pc-architect.md +32 -0
  245. package/template/.claude/agents/pc-dev.md +27 -0
  246. package/template/.claude/agents/pc-devops.md +45 -0
  247. package/template/.claude/agents/pc-planner.md +32 -0
  248. package/template/.claude/agents/pc-po.md +25 -0
  249. package/template/.claude/agents/pc-qa.md +25 -0
  250. package/template/.claude/commands/power/academy.md +9 -0
  251. package/template/.claude/commands/power/automation.md +9 -0
  252. package/template/.claude/commands/power/content-carousel.md +267 -0
  253. package/template/.claude/commands/power/content.md +9 -0
  254. package/template/.claude/commands/power/dev.md +9 -0
  255. package/template/.claude/commands/power/forge.md +224 -0
  256. package/template/.claude/commands/power/hormozi.md +221 -0
  257. package/template/.claude/commands/power/modo.md +57 -0
  258. package/template/.claude/hooks/README.md +114 -0
  259. package/template/.claude/hooks/context-budget.cjs +64 -0
  260. package/template/.claude/hooks/enforce-cycle-authority.cjs +457 -0
  261. package/template/.claude/hooks/enforce-git-push-authority.cjs +925 -0
  262. package/template/.claude/hooks/enforce-ready-oracles.cjs +502 -0
  263. package/template/.claude/rules/authority.md +76 -0
  264. package/template/.claude/rules/curadoria-de-conhecimento.md +30 -0
  265. package/template/.claude/rules/model-matrix.md +34 -0
  266. package/template/.claude/rules/orchestration.md +133 -0
  267. package/template/.claude/settings.json +50 -0
  268. package/template/.claude/skills/pc-apply-qa-fixes/SKILL.md +108 -0
  269. package/template/.claude/skills/pc-apply-qa-fixes/references/fix-loop.md +40 -0
  270. package/template/.claude/skills/pc-apply-qa-fixes/references/fix-request-template.md +70 -0
  271. package/template/.claude/skills/pc-arena/SKILL.md +96 -0
  272. package/template/.claude/skills/pc-close-story/SKILL.md +105 -0
  273. package/template/.claude/skills/pc-commit/SKILL.md +108 -0
  274. package/template/.claude/skills/pc-develop-story/SKILL.md +116 -0
  275. package/template/.claude/skills/pc-full-cycle/SKILL.md +150 -0
  276. package/template/.claude/skills/pc-pipeline/SKILL.md +63 -0
  277. package/template/.claude/skills/pc-pipeline/references/gate-templates.md +46 -0
  278. package/template/.claude/skills/pc-review-story/SKILL.md +129 -0
  279. package/template/.claude/skills/pc-review-story/references/false-positive-detection.md +50 -0
  280. package/template/.claude/skills/pc-review-story/references/nfr-assess.md +47 -0
  281. package/template/.claude/skills/pc-review-story/references/risk-profile.md +75 -0
  282. package/template/.claude/skills/pc-review-story/references/security-checklist.md +69 -0
  283. package/template/.claude/skills/pc-review-story/references/test-design.md +37 -0
  284. package/template/.claude/skills/pc-review-story/references/trace-requirements.md +46 -0
  285. package/template/.claude/skills/pc-run-pod/SKILL.md +123 -0
  286. package/template/.claude/skills/pc-validate-story/SKILL.md +114 -0
  287. package/template/.claude/skills/pc-wave/SKILL.md +133 -0
  288. package/template/.env.example +10 -0
  289. package/template/knowledge/analyst/brainstorming.md +40 -0
  290. package/template/knowledge/analyst/brief-skeleton.md +32 -0
  291. package/template/knowledge/analyst/competitor-skeleton.md +39 -0
  292. package/template/knowledge/analyst/elicitation-menu.md +49 -0
  293. package/template/knowledge/analyst/market-research-skeleton.md +36 -0
  294. package/template/knowledge/analyst/research-prompt-structure.md +48 -0
  295. package/template/knowledge/analyst/roi-skeleton.md +51 -0
  296. package/template/knowledge/voice-dna/README.md +99 -0
  297. package/template/knowledge/voice-dna/voice-dna.example.yaml +157 -0
  298. package/template/pods/README.md +64 -0
  299. package/template/pods/academy/README.md +37 -0
  300. package/template/pods/academy/agents/academy-chief.md +27 -0
  301. package/template/pods/academy/examples/palestra.example.md +142 -0
  302. package/template/pods/academy/pod-spec.json +44 -0
  303. package/template/pods/academy/templates/materiais-tmpl.md +17 -0
  304. package/template/pods/academy/templates/revisao-didatica-tmpl.md +20 -0
  305. package/template/pods/academy/workflows/wf-materiais-revisao.yaml +30 -0
  306. package/template/pods/authority-content/README.md +43 -0
  307. package/template/pods/authority-content/agents/content-chief.md +28 -0
  308. package/template/pods/authority-content/pod-spec.json +45 -0
  309. package/template/pods/authority-content/templates/criacao-na-voz-tmpl.md +17 -0
  310. package/template/pods/authority-content/templates/red-team-factual-tmpl.md +23 -0
  311. package/template/pods/authority-content/workflows/wf-criacao-redteam.yaml +30 -0
  312. package/template/pods/automation/README.md +37 -0
  313. package/template/pods/automation/agents/langgraph-architect.md +30 -0
  314. package/template/pods/automation/agents/n8n-architect.md +30 -0
  315. package/template/pods/automation/examples/README.md +46 -0
  316. package/template/pods/automation/examples/n8n-content-radar.example.json +380 -0
  317. package/template/pods/automation/knowledge/langgraph-patterns.md +126 -0
  318. package/template/pods/automation/knowledge/n8n-patterns.md +131 -0
  319. package/template/pods/automation/memory/README.md +16 -0
  320. package/template/pods/automation/memory/learnings.consolidated.md +8 -0
  321. package/template/pods/automation/memory/learnings.jsonl +0 -0
  322. package/template/pods/automation/pod-spec.json +109 -0
  323. package/template/pods/automation/specs/wf-langgraph-build.spec.json +107 -0
  324. package/template/pods/automation/squad-io.yaml +28 -0
  325. package/template/pods/automation/templates/lg-build-tmpl.md +17 -0
  326. package/template/pods/automation/templates/lg-design-tmpl.md +23 -0
  327. package/template/pods/automation/templates/lg-discover-tmpl.md +20 -0
  328. package/template/pods/automation/templates/lg-handoff-tmpl.md +20 -0
  329. package/template/pods/automation/templates/lg-test-tmpl.md +20 -0
  330. package/template/pods/automation/templates/n8n-build-tmpl.md +14 -0
  331. package/template/pods/automation/templates/n8n-design-tmpl.md +23 -0
  332. package/template/pods/automation/templates/n8n-discover-tmpl.md +20 -0
  333. package/template/pods/automation/templates/n8n-handoff-tmpl.md +20 -0
  334. package/template/pods/automation/templates/n8n-test-tmpl.md +20 -0
  335. package/template/pods/automation/workflows/wf-langgraph-build.smoke.json +11 -0
  336. package/template/pods/automation/workflows/wf-langgraph-build.yaml +64 -0
  337. package/template/pods/automation/workflows/wf-n8n-build.smoke.json +11 -0
  338. package/template/pods/automation/workflows/wf-n8n-build.yaml +65 -0
  339. package/template/pods/content-carousel/README.md +91 -0
  340. package/template/pods/content-carousel/agents/carousel-builder.md +28 -0
  341. package/template/pods/content-carousel/agents/carousel-visual.md +24 -0
  342. package/template/pods/content-carousel/agents/hn-curator.md +74 -0
  343. package/template/pods/content-carousel/config/heuristic-watcher-rubric.yaml +59 -0
  344. package/template/pods/content-carousel/knowledge/aquisicao-ancora.md +443 -0
  345. package/template/pods/content-carousel/knowledge/cta-brief.md +25 -0
  346. package/template/pods/content-carousel/knowledge/dono.example.yaml +45 -0
  347. package/template/pods/content-carousel/knowledge/identidade-visual-mascote.md +62 -0
  348. package/template/pods/content-carousel/knowledge/image-generation.md +62 -0
  349. package/template/pods/content-carousel/knowledge/selecao-de-ancora.md +60 -0
  350. package/template/pods/content-carousel/knowledge/slides-html.md +56 -0
  351. package/template/pods/content-carousel/memory/README.md +18 -0
  352. package/template/pods/content-carousel/memory/learnings.consolidated.md +6 -0
  353. package/template/pods/content-carousel/memory/learnings.jsonl +0 -0
  354. package/template/pods/content-carousel/pod-spec.json +100 -0
  355. package/template/pods/content-carousel/squad-io.yaml +10 -0
  356. package/template/pods/content-carousel/templates/assembly-tmpl.md +23 -0
  357. package/template/pods/content-carousel/templates/digest-tmpl.md +29 -0
  358. package/template/pods/content-carousel/templates/visuals-tmpl.md +20 -0
  359. package/template/pods/content-carousel/workflows/wf-content-carousel.smoke.json +23 -0
  360. package/template/pods/content-carousel/workflows/wf-content-carousel.yaml +80 -0
  361. package/template/pods/dev-ia/README.md +45 -0
  362. package/template/pods/dev-ia/agents/db-architect.md +33 -0
  363. package/template/pods/dev-ia/agents/ux-architect.md +29 -0
  364. package/template/pods/dev-ia/knowledge/db/migration-protocol.md +95 -0
  365. package/template/pods/dev-ia/knowledge/db/rls-patterns.md +101 -0
  366. package/template/pods/dev-ia/knowledge/db/schema-review-checklist.md +76 -0
  367. package/template/pods/dev-ia/memory/README.md +16 -0
  368. package/template/pods/dev-ia/memory/learnings.consolidated.md +8 -0
  369. package/template/pods/dev-ia/memory/learnings.jsonl +0 -0
  370. package/template/pods/dev-ia/pod-spec.json +34 -0
  371. package/template/pods/dev-ia/templates/schema-review-tmpl.md +23 -0
  372. package/template/pods/dev-ia/templates/ux-flow-review-tmpl.md +23 -0
  373. package/template/pods/dev-ia/tools/db-ops/backup-manager.sh +321 -0
  374. package/template/pods/dev-ia/tools/db-ops/best-practices-auditor.sh +534 -0
  375. package/template/pods/dev-ia/tools/db-ops/bootstrap-runner.sh +255 -0
  376. package/template/pods/dev-ia/tools/db-ops/data-loader.sh +616 -0
  377. package/template/pods/dev-ia/tools/db-ops/detect-database.sh +113 -0
  378. package/template/pods/dev-ia/tools/db-ops/explain-analyzer.sh +285 -0
  379. package/template/pods/dev-ia/tools/db-ops/health-checker.sh +323 -0
  380. package/template/pods/dev-ia/tools/db-ops/migration-runner.sh +308 -0
  381. package/template/pods/dev-ia/tools/db-ops/postgresql-schema-loader.sh +334 -0
  382. package/template/pods/dev-ia/tools/db-ops/query-runner.sh +171 -0
  383. package/template/pods/dev-ia/tools/db-ops/rls-policy-installer.sh +480 -0
  384. package/template/pods/dev-ia/tools/db-ops/rls-test-suite.sh +172 -0
  385. package/template/pods/dev-ia/tools/db-ops/schema-context-loader.sh +176 -0
  386. package/template/pods/hormozi-method/README.md +52 -0
  387. package/template/pods/hormozi-method/agents/acquisition-strategist.md +33 -0
  388. package/template/pods/hormozi-method/agents/conversion-copywriter.md +34 -0
  389. package/template/pods/hormozi-method/agents/monetization-architect.md +35 -0
  390. package/template/pods/hormozi-method/agents/offer-engineer.md +37 -0
  391. package/template/pods/hormozi-method/knowledge/core-four-leads.md +51 -0
  392. package/template/pods/hormozi-method/knowledge/grand-slam-offer.md +66 -0
  393. package/template/pods/hormozi-method/knowledge/growth-decision.md +38 -0
  394. package/template/pods/hormozi-method/knowledge/hooks-and-ads.md +56 -0
  395. package/template/pods/hormozi-method/knowledge/launch-email.md +31 -0
  396. package/template/pods/hormozi-method/knowledge/money-model.md +46 -0
  397. package/template/pods/hormozi-method/knowledge/opportunity-screening.md +44 -0
  398. package/template/pods/hormozi-method/knowledge/pages.md +25 -0
  399. package/template/pods/hormozi-method/knowledge/pos-lancamento-leads.md +56 -0
  400. package/template/pods/hormozi-method/knowledge/pricing.md +36 -0
  401. package/template/pods/hormozi-method/knowledge/retention-ltv.md +37 -0
  402. package/template/pods/hormozi-method/knowledge/scale-roadmap.md +35 -0
  403. package/template/pods/hormozi-method/knowledge/swipefiles-curados.md +44 -0
  404. package/template/pods/hormozi-method/knowledge/value-equation-diagnostic.md +77 -0
  405. package/template/pods/hormozi-method/memory/README.md +16 -0
  406. package/template/pods/hormozi-method/memory/learnings.consolidated.md +6 -0
  407. package/template/pods/hormozi-method/memory/learnings.jsonl +0 -0
  408. package/template/pods/hormozi-method/pod-spec.json +50 -0
  409. package/template/pods/hormozi-method/specs/wf-full-launch-sequence.spec.json +149 -0
  410. package/template/pods/hormozi-method/specs/wf-lead-magnet-pipeline.spec.json +125 -0
  411. package/template/pods/hormozi-method/specs/wf-money-model-design.spec.json +117 -0
  412. package/template/pods/hormozi-method/specs/wf-paid-ads-campaign.spec.json +132 -0
  413. package/template/pods/hormozi-method/specs/wf-scaling-diagnostic.spec.json +121 -0
  414. package/template/pods/hormozi-method/squad-io.yaml +43 -0
  415. package/template/pods/hormozi-method/templates/conversion-copywriter-tmpl.md +20 -0
  416. package/template/pods/hormozi-method/templates/launch-execucao-tmpl.md +17 -0
  417. package/template/pods/hormozi-method/templates/launch-fechamento-tmpl.md +17 -0
  418. package/template/pods/hormozi-method/templates/launch-pos-tmpl.md +17 -0
  419. package/template/pods/hormozi-method/templates/launch-preparacao-tmpl.md +17 -0
  420. package/template/pods/hormozi-method/templates/lm-copy-tmpl.md +17 -0
  421. package/template/pods/hormozi-method/templates/lm-distribuicao-tmpl.md +18 -0
  422. package/template/pods/hormozi-method/templates/lm-estrategia-tmpl.md +17 -0
  423. package/template/pods/hormozi-method/templates/mm-arquitetura-tmpl.md +18 -0
  424. package/template/pods/hormozi-method/templates/mm-copy-tmpl.md +17 -0
  425. package/template/pods/hormozi-method/templates/mm-diagnostico-tmpl.md +14 -0
  426. package/template/pods/hormozi-method/templates/monetization-architect-tmpl.md +17 -0
  427. package/template/pods/hormozi-method/templates/offer-engineer-tmpl.md +20 -0
  428. package/template/pods/hormozi-method/templates/paid-criativos-tmpl.md +19 -0
  429. package/template/pods/hormozi-method/templates/paid-fundacao-tmpl.md +17 -0
  430. package/template/pods/hormozi-method/templates/paid-teste-escala-tmpl.md +17 -0
  431. package/template/pods/hormozi-method/templates/scaling-diagnostico-tmpl.md +17 -0
  432. package/template/pods/hormozi-method/templates/scaling-priorizacao-tmpl.md +17 -0
  433. package/template/pods/hormozi-method/templates/scaling-roadmap-tmpl.md +17 -0
  434. package/template/pods/hormozi-method/workflows/wf-full-launch-sequence.smoke.json +12 -0
  435. package/template/pods/hormozi-method/workflows/wf-full-launch-sequence.yaml +56 -0
  436. package/template/pods/hormozi-method/workflows/wf-grand-slam-offer.smoke.json +11 -0
  437. package/template/pods/hormozi-method/workflows/wf-grand-slam-offer.yaml +45 -0
  438. package/template/pods/hormozi-method/workflows/wf-lead-magnet-pipeline.smoke.json +9 -0
  439. package/template/pods/hormozi-method/workflows/wf-lead-magnet-pipeline.yaml +45 -0
  440. package/template/pods/hormozi-method/workflows/wf-money-model-design.smoke.json +11 -0
  441. package/template/pods/hormozi-method/workflows/wf-money-model-design.yaml +45 -0
  442. package/template/pods/hormozi-method/workflows/wf-paid-ads-campaign.smoke.json +9 -0
  443. package/template/pods/hormozi-method/workflows/wf-paid-ads-campaign.yaml +46 -0
  444. package/template/pods/hormozi-method/workflows/wf-scaling-diagnostic.smoke.json +11 -0
  445. package/template/pods/hormozi-method/workflows/wf-scaling-diagnostic.yaml +44 -0
  446. package/template/pods/squad-forge/README.md +53 -0
  447. package/template/pods/squad-forge/agents/forge-chief.md +31 -0
  448. package/template/pods/squad-forge/agents/mind-extractor.md +29 -0
  449. package/template/pods/squad-forge/agents/pod-critic.md +26 -0
  450. package/template/pods/squad-forge/config/heuristic-watcher-rubric.yaml +74 -0
  451. package/template/pods/squad-forge/knowledge/fidelity-rubric.yaml +176 -0
  452. package/template/pods/squad-forge/knowledge/g6-memory-check.md +17 -0
  453. package/template/pods/squad-forge/knowledge/memory-ingest.md +16 -0
  454. package/template/pods/squad-forge/knowledge/source-audit-rubric.yaml +60 -0
  455. package/template/pods/squad-forge/memory/README.md +16 -0
  456. package/template/pods/squad-forge/memory/learnings.consolidated.md +8 -0
  457. package/template/pods/squad-forge/memory/learnings.jsonl +0 -0
  458. package/template/pods/squad-forge/pod-spec.json +166 -0
  459. package/template/pods/squad-forge/squad-io.yaml +13 -0
  460. package/template/pods/squad-forge/tasks/pipeline.md +158 -0
  461. package/template/pods/squad-forge/templates/discovery-tmpl.md +40 -0
  462. package/template/pods/squad-forge/templates/generation-tmpl.md +18 -0
  463. package/template/pods/squad-forge/templates/red-team-tmpl.md +17 -0
  464. package/template/pods/squad-forge/templates/register-tmpl.md +17 -0
  465. package/template/pods/squad-forge/templates/workflow-tmpl.yaml +101 -0
  466. package/template/pods/squad-forge/workflows/wf-forge.smoke.json +12 -0
  467. package/template/pods/squad-forge/workflows/wf-forge.yaml +60 -0
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /**
4
+ * make-fixtures.cjs — GERADOR determinístico dos PNGs de fixture do veto `phash-gate.cjs`
5
+ * (Story SF10.8). NÃO é script de produção (vive sob __fixtures__/, excluído do manifesto
6
+ * ADR-007): existe para que a calibração do limiar seja AUDITÁVEL e REPRODUZÍVEL — o QA
7
+ * regenera, altera a agressividade da "cópia" e re-mede a margem sem depender de binários
8
+ * opacos comitados no repo.
9
+ *
10
+ * ZERO-DEP: encoder PNG (RGB8, filtro 0) escrito à mão sobre `node:zlib` — nenhuma lib npm.
11
+ * PRNG determinístico (LCG com semente fixa) ⇒ os bytes gerados são idênticos a cada rodada.
12
+ *
13
+ * Uso: node scripts/__fixtures__/veto-checks/phash/make-fixtures.cjs [dir-de-saida]
14
+ *
15
+ * Saída (o "cenário" de calibração):
16
+ * ref.png — a REFERÊNCIA (papel da referência Pinterest do run)
17
+ * copy.png — CÓPIA ADVERSARIAL da referência: crop 4% + reescala + rotação de canal
18
+ * (recolor) + brilho + ruído. Um observador razoável diz "é a mesma imagem".
19
+ * DEVE ser VETADA.
20
+ * distinct.png — peça LEGÍTIMA de composição/paleta próprias. DEVE PASSAR.
21
+ * distinct2.png — 2ª peça legítima (o par capa+CTA do veredito POR-IMAGEM).
22
+ */
23
+
24
+ const fs = require('node:fs');
25
+ const path = require('node:path');
26
+ const zlib = require('node:zlib');
27
+
28
+ const W = 512;
29
+ const H = 640;
30
+
31
+ // --- PNG (RGB8, sem filtro) --------------------------------------------------
32
+ const CRC_TABLE = (() => {
33
+ const t = new Int32Array(256);
34
+ for (let n = 0; n < 256; n++) {
35
+ let c = n;
36
+ for (let k = 0; k < 8; k++) c = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);
37
+ t[n] = c;
38
+ }
39
+ return t;
40
+ })();
41
+ function crc32(buf) {
42
+ let c = 0xFFFFFFFF;
43
+ for (let i = 0; i < buf.length; i++) c = CRC_TABLE[(c ^ buf[i]) & 0xFF] ^ (c >>> 8);
44
+ return (c ^ 0xFFFFFFFF) >>> 0;
45
+ }
46
+ function chunk(type, data) {
47
+ const len = Buffer.alloc(4); len.writeUInt32BE(data.length, 0);
48
+ const td = Buffer.concat([Buffer.from(type, 'ascii'), data]);
49
+ const crc = Buffer.alloc(4); crc.writeUInt32BE(crc32(td), 0);
50
+ return Buffer.concat([len, td, crc]);
51
+ }
52
+ /** Codifica pixels RGB (Uint8Array de W*H*3) em PNG. */
53
+ function encodePng(px, w, h) {
54
+ const raw = Buffer.alloc(h * (1 + w * 3));
55
+ for (let y = 0; y < h; y++) {
56
+ raw[y * (1 + w * 3)] = 0; // filtro None
57
+ px.copy
58
+ ? px.copy(raw, y * (1 + w * 3) + 1, y * w * 3, (y + 1) * w * 3)
59
+ : Buffer.from(px.subarray(y * w * 3, (y + 1) * w * 3)).copy(raw, y * (1 + w * 3) + 1);
60
+ }
61
+ const ihdr = Buffer.alloc(13);
62
+ ihdr.writeUInt32BE(w, 0); ihdr.writeUInt32BE(h, 4);
63
+ ihdr[8] = 8; ihdr[9] = 2; ihdr[10] = 0; ihdr[11] = 0; ihdr[12] = 0; // 8bit, truecolor
64
+ return Buffer.concat([
65
+ Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
66
+ chunk('IHDR', ihdr),
67
+ chunk('IDAT', zlib.deflateSync(raw, { level: 9 })),
68
+ chunk('IEND', Buffer.alloc(0)),
69
+ ]);
70
+ }
71
+
72
+ // --- desenho ----------------------------------------------------------------
73
+ function canvas(w, h) { return Buffer.alloc(w * h * 3); }
74
+ const clamp = (v) => (v < 0 ? 0 : v > 255 ? 255 : v | 0);
75
+ function setPx(buf, w, x, y, r, g, b) {
76
+ const i = (y * w + x) * 3;
77
+ buf[i] = clamp(r); buf[i + 1] = clamp(g); buf[i + 2] = clamp(b);
78
+ }
79
+ function rect(buf, w, x0, y0, x1, y1, c) {
80
+ for (let y = Math.max(0, y0); y < Math.min(H, y1); y++) {
81
+ for (let x = Math.max(0, x0); x < Math.min(w, x1); x++) setPx(buf, w, x, y, c[0], c[1], c[2]);
82
+ }
83
+ }
84
+ function disc(buf, w, cx, cy, r, c) {
85
+ for (let y = Math.max(0, cy - r); y < Math.min(H, cy + r); y++) {
86
+ for (let x = Math.max(0, cx - r); x < Math.min(w, cx + r); x++) {
87
+ const dx = x - cx; const dy = y - cy;
88
+ if (dx * dx + dy * dy <= r * r) setPx(buf, w, x, y, c[0], c[1], c[2]);
89
+ }
90
+ }
91
+ }
92
+ function tri(buf, w, x0, y0, size, c) { // triângulo retângulo (cateto = size)
93
+ for (let y = 0; y < size; y++) {
94
+ for (let x = 0; x < size - y; x++) setPx(buf, w, x0 + x, y0 + y, c[0], c[1], c[2]);
95
+ }
96
+ }
97
+
98
+ /** PRNG determinístico (LCG) — fixtures byte-idênticas a cada geração. */
99
+ function lcg(seed) {
100
+ let s = seed >>> 0;
101
+ return () => { s = (Math.imul(s, 1664525) + 1013904223) >>> 0; return s / 4294967296; };
102
+ }
103
+
104
+ /** REFERÊNCIA: gradiente escuro + disco claro + barras + triângulo (composição forte). */
105
+ function drawRef() {
106
+ const buf = canvas(W, H);
107
+ for (let y = 0; y < H; y++) {
108
+ for (let x = 0; x < W; x++) {
109
+ const t = y / H;
110
+ setPx(buf, W, x, y, 20 + 60 * t + (x / W) * 30, 24 + 20 * t, 70 + 120 * (1 - t));
111
+ }
112
+ }
113
+ disc(buf, W, 150, 170, 105, [240, 214, 120]);
114
+ rect(buf, W, 40, 330, 470, 366, [250, 250, 250]);
115
+ rect(buf, W, 40, 392, 330, 424, [250, 250, 250]);
116
+ rect(buf, W, 40, 450, 400, 478, [180, 180, 190]);
117
+ tri(buf, W, 300, 500, 170, [230, 90, 60]);
118
+ return buf;
119
+ }
120
+
121
+ /** PEÇA LEGÍTIMA 1: fundo claro, composição e paleta próprias. */
122
+ function drawDistinct() {
123
+ const buf = canvas(W, H);
124
+ for (let y = 0; y < H; y++) {
125
+ for (let x = 0; x < W; x++) {
126
+ const t = x / W;
127
+ setPx(buf, W, x, y, 235 - 40 * t, 238 - 20 * (y / H), 228 - 60 * t);
128
+ }
129
+ }
130
+ rect(buf, W, 0, 0, W, 96, [18, 92, 76]);
131
+ disc(buf, W, 400, 520, 90, [24, 40, 120]);
132
+ rect(buf, W, 60, 180, 200, 470, [200, 60, 90]);
133
+ rect(buf, W, 230, 240, 300, 400, [40, 40, 40]);
134
+ return buf;
135
+ }
136
+
137
+ /** PEÇA LEGÍTIMA 2: outra composição (o par capa+CTA do veredito por-imagem). */
138
+ function drawDistinct2() {
139
+ const buf = canvas(W, H);
140
+ for (let y = 0; y < H; y++) {
141
+ for (let x = 0; x < W; x++) {
142
+ const d = Math.abs(x - W / 2) / (W / 2);
143
+ setPx(buf, W, x, y, 40 + 120 * d, 130 - 60 * d, 60 + 30 * (y / H));
144
+ }
145
+ }
146
+ rect(buf, W, 0, 240, W, 300, [255, 255, 255]);
147
+ rect(buf, W, 0, 340, W, 372, [255, 255, 255]);
148
+ disc(buf, W, 256, 560, 70, [10, 10, 10]);
149
+ return buf;
150
+ }
151
+
152
+ /**
153
+ * CÓPIA ADVERSARIAL da referência (o ataque que o veto TEM de pegar):
154
+ * crop de 4% em cada borda + reescala de volta (nearest) + rotação leve de canais (recolor)
155
+ * + ganho de brilho + ruído determinístico. Nenhum byte em comum; a MESMA imagem aos olhos.
156
+ */
157
+ function drawCopy(ref) {
158
+ const out = canvas(W, H);
159
+ const rnd = lcg(20260731);
160
+ const mx = Math.round(W * 0.04);
161
+ const my = Math.round(H * 0.04);
162
+ const cw = W - 2 * mx;
163
+ const ch = H - 2 * my;
164
+ // Ruído em BLOCOS 8×8 (artefato de compressão, não chuvisco por pixel): igualmente eficaz
165
+ // contra igualdade de bytes e MUITO mais compressível — o PNG de fixture fica leve.
166
+ const nb = new Float32Array(Math.ceil(W / 8) * Math.ceil(H / 8));
167
+ for (let i = 0; i < nb.length; i++) nb[i] = (rnd() - 0.5) * 10;
168
+ for (let y = 0; y < H; y++) {
169
+ const sy = my + Math.min(ch - 1, Math.floor((y / H) * ch));
170
+ for (let x = 0; x < W; x++) {
171
+ const sx = mx + Math.min(cw - 1, Math.floor((x / W) * cw));
172
+ const i = (sy * W + sx) * 3;
173
+ const n = nb[(y >> 3) * Math.ceil(W / 8) + (x >> 3)];
174
+ // recolor: mistura leve entre canais + brilho (preserva a estrutura luminante)
175
+ const r = ref[i] * 0.92 + ref[i + 2] * 0.08 + 10 + n;
176
+ const g = ref[i + 1] * 0.94 + ref[i] * 0.06 + 8 + n;
177
+ const b = ref[i + 2] * 0.90 + ref[i + 1] * 0.10 + 12 + n;
178
+ setPx(out, W, x, y, r, g, b);
179
+ }
180
+ }
181
+ return out;
182
+ }
183
+
184
+ function main() {
185
+ const outDir = process.argv[2] ? path.resolve(process.argv[2]) : __dirname;
186
+ fs.mkdirSync(outDir, { recursive: true });
187
+ const ref = drawRef();
188
+ const files = {
189
+ 'ref.png': ref,
190
+ 'copy.png': drawCopy(ref),
191
+ 'distinct.png': drawDistinct(),
192
+ 'distinct2.png': drawDistinct2(),
193
+ };
194
+ for (const [name, px] of Object.entries(files)) {
195
+ const p = path.join(outDir, name);
196
+ fs.writeFileSync(p, encodePng(px, W, H));
197
+ console.log(`escrito: ${p} (${fs.statSync(p).size}B)`);
198
+ }
199
+ }
200
+
201
+ if (require.main === module) main();
202
+
203
+ module.exports = { encodePng, drawRef, drawCopy, drawDistinct, drawDistinct2, W, H };
@@ -0,0 +1,15 @@
1
+ <!doctype html>
2
+ <html lang="pt-br"><head><meta charset="utf-8"><title>Slide 1</title>
3
+ <style>
4
+ *{margin:0;padding:0;box-sizing:border-box}
5
+ html,body{width:1080px;height:1350px;overflow:hidden;font-family:Arial,Helvetica,sans-serif}
6
+ .slide{width:1080px;height:1350px;padding:80px;background:#0b1e3a;color:#fff;display:flex;flex-direction:column;justify-content:center}
7
+ h1{font-size:88px;line-height:1.2;margin-bottom:40px}
8
+ p{font-size:44px;line-height:1.35;max-width:900px}
9
+ </style></head>
10
+ <body>
11
+ <div class="slide">
12
+ <h1>Notícia do dia</h1>
13
+ <p>Resumo que cabe folgado na moldura de 1080 por 1350, sem estourar nenhuma caixa.</p>
14
+ </div>
15
+ </body></html>
@@ -0,0 +1,14 @@
1
+ <!doctype html>
2
+ <html lang="pt-br"><head><meta charset="utf-8"><title>Slide quebrado</title>
3
+ <style>
4
+ *{margin:0;padding:0;box-sizing:border-box}
5
+ html,body{width:1080px;height:1350px;overflow:hidden;font-family:Arial,Helvetica,sans-serif}
6
+ .slide{width:1080px;height:1350px;padding:80px;background:#0b1e3a;color:#fff}
7
+ /* DEFEITO REAL da R5: título numa única linha sem quebra, 2400px de largura → corta na moldura de 1080. */
8
+ h1{font-size:120px;white-space:nowrap;width:2400px}
9
+ </style></head>
10
+ <body>
11
+ <div class="slide">
12
+ <h1>Manchete longa demais que não quebra de linha e estoura a largura</h1>
13
+ </div>
14
+ </body></html>
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: vc-checker
3
+ description: "Agente de FIXTURE da etapa \"check\" de sweep-pod. Existe para satisfazer a leitura obrigatória da etapa (SF11.2/ADR-021 DF-SF11.2-4): agente declarado no wf tem de existir em disco."
4
+ model: sonnet
5
+ budget_tokens: 200
6
+ ---
7
+
8
+ # vc-checker — agente de fixture (etapa "check")
9
+
10
+ Fixture de teste, não é agente de produção. O conteúdo é irrelevante para as provas
11
+ que usam este pod; o que importa é que o arquivo EXISTA, porque desde a Story SF11.2
12
+ o runner resolve e verifica `agents/<step.agent>.md` antes de despachar a etapa, e o
13
+ validador estático checa a mesma existência (paridade com `pod-export-compile.cjs:214`).
@@ -0,0 +1,6 @@
1
+ # Artefato da etapa `check`
2
+
3
+ ## Body
4
+
5
+ Conteúdo textual do artefato. A FORMA (este heading `## Body`) é verificada por
6
+ checkTemplateConformance; o veto `command_check` (lexical) roda sobre o texto.
@@ -0,0 +1,10 @@
1
+ {
2
+ "_comment": "Sidecar do wf-vc (SF7.2). 'artifacts' = conforme por etapa (passa template E veto). 'violations' = fixture de violação por etapa para o command_check (conforme ao template, mas o script blessed bloqueia). Sem 'violations[check]' o sweep é UNDERIVÁVEL fail-loud (ADR-011 Decisão 4).",
3
+ "target_step": "check",
4
+ "artifacts": {
5
+ "check": "## Body\n\nTexto limpo, sem travessao, passa no lexical-check.\n"
6
+ },
7
+ "violations": {
8
+ "check": "## Body\n\nTexto com travessao — aqui — que o lexical-check bloqueia.\n"
9
+ }
10
+ }
@@ -0,0 +1,19 @@
1
+ # wf-vc — workflow-fixture do SWEEP de command_check (Story SF7.2/ADR-011 Decisão 4).
2
+ # NÃO é pod de produção. Existe só para provar que o sweep bloqueia por uma fixture de
3
+ # violação DECLARADA no sidecar (scenario.violations), e que a ausência dessa fixture é
4
+ # UNDERIVÁVEL fail-loud. O veto é command_check lexical-check (blessed, Node puro).
5
+ state_machine:
6
+ states: [init, running, complete, failed]
7
+ initial: init
8
+ terminal: [complete, failed]
9
+ steps:
10
+ - id: check
11
+ agent: vc-checker
12
+ template: templates/check-tmpl.md
13
+ inputs: [pedido]
14
+ outputs: [artefato]
15
+ depends_on: []
16
+ checkpoint: null
17
+ veto:
18
+ assertions:
19
+ - { type: command_check, command: "lexical-check.cjs", args: ["--max", "0"] }
@@ -0,0 +1,23 @@
1
+ # Fixtures — guarda de voz do dono (SF7.9 / ADR-013)
2
+
3
+ Provas reproduzíveis da checagem híbrida (veto léxico de máquina + checkpoint de julgamento)
4
+ e da retrocompat do `dono.yaml`.
5
+
6
+ ## Arquivos
7
+
8
+ - `dono-guia.yaml` — bloco `voz:` ESTRUTURADO (forma nova, ADR-013 Decisão 2). O veto do
9
+ workflow deriva os args de `voz.lexico_proibido` em tempo de AUTORIA (args literais,
10
+ ADR-011).
11
+ - `dono-escalar.yaml` — forma ESCALAR antiga (`voz: "primeira pessoa"`), que permanece
12
+ VÁLIDA: nenhum script do motor parseia `dono.yaml` (dado de instância consumido pelo
13
+ AGENTE; a golden rule interpreta o escalar como `voz.pessoa: "primeira"` + defaults e
14
+ oferece upgrade). Retrocompat é por indiferença de máquina + prosa do agente.
15
+ - `peca-com-lexico-proibido.md` — peça VIOLANDO o léxico do guia (contém em-dash). O
16
+ blessed real bloqueia:
17
+ `node scripts/veto-checks/lexical-check.cjs scripts/__fixtures__/voz-do-dono/peca-com-lexico-proibido.md --max 0 --pattern "[—–]"` → exit 1.
18
+ - `peca-limpa-1a-pessoa.md` — peça conforme (1ª pessoa, sem tokens banidos) → exit 0.
19
+ - `peca-3a-pessoa.md` — o DEFEITO REAL da R2 do benchmark: cita o dono em 3ª pessoa como
20
+ fonte externa, SEM nenhum token do léxico proibido. O `lexical-check.cjs` dá exit 0
21
+ (a máquina NÃO pega — e não deve tentar por regex, ADR-013 Decisão 3/Risco 2): quem pega é
22
+ a cláusula de voz do CHECKPOINT (julgamento humano) em `wf-content-carousel.yaml`.
23
+ Este fixture é a prova de que a 3ª pessoa NÃO virou regex.
@@ -0,0 +1,9 @@
1
+ # Fixture — dono.yaml na forma ESCALAR antiga (pré-ADR-013). Continua VÁLIDO (retrocompat):
2
+ # o agente interpreta `voz` escalar como `voz.pessoa: "primeira"` com defaults e oferece o
3
+ # upgrade na ativação; nenhum script do motor parseia este arquivo. Dono FICTÍCIO.
4
+ dono:
5
+ nome: "Alexa Exemplo"
6
+ handle: "@alexa.exemplo"
7
+ autoridade: "Automação para pequenos negócios, testada em campo"
8
+ voz: "primeira pessoa"
9
+ acao_padrao_cta: "seguir"
@@ -0,0 +1,10 @@
1
+ # Fixture — dono.yaml com o bloco `voz:` estruturado (ADR-013 Decisão 2). Dono FICTÍCIO.
2
+ dono:
3
+ nome: "Alexa Exemplo"
4
+ handle: "@alexa.exemplo"
5
+ autoridade: "Automação para pequenos negócios, testada em campo"
6
+ acao_padrao_cta: "seguir"
7
+ voz:
8
+ pessoa: "primeira"
9
+ lexico_proibido: ["—", "–"]
10
+ tom: "direto, técnico sem jargão, sem hype"
@@ -0,0 +1,6 @@
1
+ # Slide de exemplo (fixture do DEFEITO R2: 3ª pessoa, SEM token proibido)
2
+
3
+ Como explica Alexa Exemplo, referência em automação para pequenos negócios, a ferramenta
4
+ resolve o problema quando bem configurada. Para Alexa, o segredo é começar pequeno.
5
+
6
+ confianca: alta
@@ -0,0 +1,6 @@
1
+ # Slide de exemplo (fixture de VIOLAÇÃO léxica)
2
+
3
+ Testei essa ferramenta na minha rotina — e o resultado me surpreendeu.
4
+ Ela resolve o problema — mas só se você configurar direito.
5
+
6
+ confianca: alta
@@ -0,0 +1,6 @@
1
+ # Slide de exemplo (fixture CONFORME)
2
+
3
+ Testei essa ferramenta na minha rotina e o resultado me surpreendeu: ela resolve o problema,
4
+ desde que você configure direito. Minha regra: comece pequeno e meça.
5
+
6
+ confianca: alta
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /**
4
+ * derive-ready-transitions.test.cjs — meta-prova do instrumento offline que
5
+ * deriva do git a contagem de `D-Dono-2` (i) (`ADR-035`, D7; story `SF13.8`).
6
+ *
7
+ * `ADR-035` D7 exige, no MÍNIMO, quatro elementos — e diz por quê: *"sem (b) e
8
+ * (d), o teste fica verde para um instrumento que conta zero"*. Um detector
9
+ * cuja classe alvo nunca é provada alcançável passa igual quebrado e correto
10
+ * (`calibrar-detector-exige-corpus-externo`). Os quatro estão aqui:
11
+ *
12
+ * (a) CORPUS REAL — a derivação roda sobre o histórico DESTE repositório,
13
+ * pinado num sha imutável (`force-push` é `deny` para todos os agentes,
14
+ * `authority.md`), e exige a âncora estável `6b948efa`/`sf13.1.story.md`
15
+ * com o veredito `ask` em `P8`.
16
+ * (b) CONTROLE POSITIVO — repositório git sintético e descartável, com uma
17
+ * transição `Draft`→`Ready` conhecida, num diretório de stories
18
+ * NÃO-padrão (o argumento `--stories-dir` é exercitado de verdade, não
19
+ * só declarado na assinatura).
20
+ * (c) CONTROLE NEGATIVO — commit que toca a story SEM mudar `## Status` não
21
+ * é contado. Sem ele, um instrumento que contasse "toda escrita" também
22
+ * ficaria verde em (b).
23
+ * (d) FALSO NEGATIVO ASSERTADO — story que NASCE `Ready` não é contada.
24
+ * É limitação conhecida e declarada (`ADR-035` M7/dívida 1), no mesmo
25
+ * padrão do `~~Ready~~` de `enforce-ready-oracles.test.cjs:595`:
26
+ * escrever a limitação em prosa não impede que ela vire outra coisa em
27
+ * silêncio — assertá-la trava o comportamento no valor que foi aceito.
28
+ *
29
+ * Mais três guardas que decorrem das decisões do ADR e não têm outro dono:
30
+ * D4 (`exit 0` sempre), D2 (fonte única — nenhum predicado reimplementado) e
31
+ * a Segurança (`git` por `execFileSync` com array, nunca shell).
32
+ */
33
+
34
+ const fs = require('node:fs');
35
+ const os = require('node:os');
36
+ const path = require('node:path');
37
+ const { execFileSync, spawnSync } = require('node:child_process');
38
+
39
+ const REPO_ROOT = path.resolve(__dirname, '..', '..');
40
+ const SCRIPT = path.join(REPO_ROOT, 'scripts', 'derive-ready-transitions.cjs');
41
+
42
+ // Sha pinado: o commit mais recente entre as 70 transições do corpus real.
43
+ // Pinar é o que impede o teste de ficar RED meses depois por trabalho legítimo
44
+ // do ciclo (a contagem só cresce a cada `Draft`→`Ready` novo).
45
+ const REV_PINADO = '6ef33f90';
46
+ const MARCO_V1 = 'd6ae744'; // commit em que a v1 do hook passou a existir em `template/`
47
+ const ANCORA_SHA = '6b948efa';
48
+ const ANCORA_ARQUIVO = 'sf13.1.story.md';
49
+
50
+ let failures = 0;
51
+ function assert(ok, msg) {
52
+ if (ok) {
53
+ console.log(`[OK ] ${msg}`);
54
+ } else {
55
+ console.error(`[FALHA] ${msg}`);
56
+ failures += 1;
57
+ }
58
+ }
59
+
60
+ function rodar(args) {
61
+ const r = spawnSync(process.execPath, [SCRIPT].concat(args), {
62
+ encoding: 'utf8',
63
+ cwd: REPO_ROOT,
64
+ maxBuffer: 64 * 1024 * 1024,
65
+ });
66
+ return { status: r.status, stdout: r.stdout || '', stderr: r.stderr || '' };
67
+ }
68
+
69
+ function campo(saida, nome) {
70
+ const linha = saida.split('\n').find((l) => l.includes(`${nome}=`));
71
+ if (!linha) return null;
72
+ const depois = linha.slice(linha.indexOf(`${nome}=`) + nome.length + 1);
73
+ const m = /^\d+/.test(depois) ? depois.match(/^\d+/) : null;
74
+ return m ? m[0] : null;
75
+ }
76
+
77
+ // Repositório git sintético e descartável. Criado por teste, nunca reusado:
78
+ // estado compartilhado entre controles faria um controle mascarar o outro.
79
+ function repoSintetico(prefixo) {
80
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefixo));
81
+ const git = (args) => execFileSync('git', args, { cwd: dir, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
82
+ git(['init', '-q']);
83
+ git(['config', 'user.email', 'teste@exemplo.invalid']);
84
+ git(['config', 'user.name', 'teste']);
85
+ fs.mkdirSync(path.join(dir, 'stories-sinteticas'));
86
+ return {
87
+ dir,
88
+ escrever(nome, conteudo, mensagem) {
89
+ fs.writeFileSync(path.join(dir, 'stories-sinteticas', nome), conteudo);
90
+ git(['add', '.']);
91
+ git(['commit', '-q', '-m', mensagem]);
92
+ },
93
+ };
94
+ }
95
+
96
+ // ---------------------------------------------------------------------------
97
+ // (a) Corpus real — o histórico deste repositório, pinado
98
+ // ---------------------------------------------------------------------------
99
+
100
+ function testCorpusReal() {
101
+ console.log('\n--- D7a: corpus real (histórico deste repositório, sha pinado) ---');
102
+
103
+ const r = rodar(['.', '--rev', REV_PINADO, '--since', MARCO_V1]);
104
+ assert(r.status === 0, `D7a: exit 0 sobre o corpus real (status=${r.status})`);
105
+
106
+ assert(campo(r.stdout, 'total') === '70', `D7a: total=70 transições draft→ready até ${REV_PINADO} (medido: ${campo(r.stdout, 'total')})`);
107
+
108
+ // `desde` é a leitura RESTRITA de `D-Dono-2` (i) — "com a v1". O número é 14,
109
+ // por ancestralidade `d6ae744..6ef33f90`. A tabela M3 do `ADR-035` publicou
110
+ // `17` na 1ª versão e foi CORRIGIDA para 14 (a causa era filtro por
111
+ // granularidade de DIA, que inclui 3 transições anteriores às 15:29:56 em que
112
+ // a v1 nasceu). Leitura superada, não repetir: quem vir 17 aqui está
113
+ // copiando a versão superada, não medindo.
114
+ assert(campo(r.stdout, 'desde') === '14', `D7a: desde=14 no recorte ${MARCO_V1}..${REV_PINADO} (medido: ${campo(r.stdout, 'desde')})`);
115
+
116
+ const listaTemAncora = r.stdout.split('\n').some((l) => l.includes(ANCORA_SHA) && l.includes(ANCORA_ARQUIVO));
117
+ assert(listaTemAncora, `D7a: a âncora ${ANCORA_SHA} (${ANCORA_ARQUIVO}) aparece na lista auditável — cada transição é conferível uma a uma, não é total agregado`);
118
+
119
+ // Replay do veredito da v1 (D2/D3): o hook é PURO, logo o veredito é função
120
+ // total do conteúdo resultante, e o conteúdo resultante é o que o git guarda.
121
+ assert(campo(r.stdout, 'ask') === '1' && campo(r.stdout, 'silencio') === '69', `D7a: replay da v1 sobre as 70 dá ask=1 silencio=69 (medido: ask=${campo(r.stdout, 'ask')} silencio=${campo(r.stdout, 'silencio')})`);
122
+
123
+ const linhaAsk = r.stdout.split('\n').find((l) => l.startsWith('ASK'));
124
+ assert(
125
+ !!linhaAsk && linhaAsk.includes(ANCORA_SHA) && linhaAsk.includes(ANCORA_ARQUIVO) && linhaAsk.includes('P8'),
126
+ `D7a: a única emissão é a já nomeada em ADR-032 (consequência 5): ${ANCORA_SHA}/${ANCORA_ARQUIVO}, predicado P8 (linha: ${linhaAsk || '<ausente>'})`,
127
+ );
128
+ }
129
+
130
+ // ---------------------------------------------------------------------------
131
+ // (b) Controle positivo — alcançabilidade da classe
132
+ // ---------------------------------------------------------------------------
133
+
134
+ function testControlePositivo() {
135
+ console.log('\n--- D7b: controle positivo (repo git sintético, --stories-dir não-padrão) ---');
136
+
137
+ const repo = repoSintetico('derive-positivo-');
138
+ repo.escrever('z.story.md', '## Status\n\nDraft\n', 'nasce Draft');
139
+ repo.escrever('z.story.md', '## Status\n\nReady\n', 'Draft -> Ready');
140
+
141
+ const r = rodar([repo.dir, '--stories-dir', 'stories-sinteticas']);
142
+ assert(r.status === 0, `D7b: exit 0 no repo sintético (status=${r.status})`);
143
+ assert(campo(r.stdout, 'total') === '1', `D7b/controle positivo: a transição conhecida É contada — total=1 (medido: ${campo(r.stdout, 'total')})`);
144
+ assert(
145
+ r.stdout.includes('stories-dir=stories-sinteticas') && r.stdout.includes('stories-sinteticas/z.story.md'),
146
+ 'D7b: `--stories-dir` é EXERCITADO de verdade (diretório não-padrão), não só declarado na assinatura',
147
+ );
148
+ }
149
+
150
+ // ---------------------------------------------------------------------------
151
+ // (c) Controle negativo — o instrumento não conta "toda escrita"
152
+ // ---------------------------------------------------------------------------
153
+
154
+ function testControleNegativo() {
155
+ console.log('\n--- D7c: controle negativo (commit toca a story sem mudar o status) ---');
156
+
157
+ const repo = repoSintetico('derive-negativo-');
158
+ repo.escrever('z.story.md', '## Status\n\nDraft\n', 'nasce Draft');
159
+ repo.escrever('z.story.md', '## Status\n\nReady\n\n## Acceptance Criteria\n', 'Draft -> Ready');
160
+ repo.escrever('z.story.md', '## Status\n\nReady\n\n## Acceptance Criteria\n\nAC-1 novo\n', 'toca a story sem mudar Status');
161
+
162
+ const r = rodar([repo.dir, '--stories-dir', 'stories-sinteticas']);
163
+ assert(r.status === 0, `D7c: exit 0 no repo sintético (status=${r.status})`);
164
+ assert(campo(r.stdout, 'total') === '1', `D7c/controle negativo: Ready→Ready NÃO conta — total continua 1, não sobe para 2 (medido: ${campo(r.stdout, 'total')})`);
165
+ }
166
+
167
+ // ---------------------------------------------------------------------------
168
+ // (d) Falso negativo DECLARADO — assertado, não só escrito em prosa
169
+ // ---------------------------------------------------------------------------
170
+
171
+ function testFalsoNegativoDeclarado() {
172
+ console.log('\n--- D7d: falso negativo <ausente>->ready, assertado ---');
173
+
174
+ const repo = repoSintetico('derive-falso-neg-');
175
+ repo.escrever('nasce-ready.story.md', '## Status\n\nReady\n', 'nasce em Ready, sem Draft anterior');
176
+
177
+ const r = rodar([repo.dir, '--stories-dir', 'stories-sinteticas']);
178
+ assert(r.status === 0, `D7d: exit 0 no repo sintético (status=${r.status})`);
179
+ assert(
180
+ campo(r.stdout, 'total') === '0',
181
+ `D7d: story que NASCE Ready não é contada — total=0. LIMITAÇÃO CONHECIDA e aceita (ADR-035 M7/dívida 1): a classe <ausente>->ready tem teto de 20 em 90 (22%) no framework, e a perda sempre SUBTRAI, nunca infla a contagem que autorizaria um deny. Se este número virar 1, alguém ampliou a detecção — o que pode ser bom, mas é decisão do dono, não efeito colateral (medido: ${campo(r.stdout, 'total')})`,
182
+ );
183
+ }
184
+
185
+ // ---------------------------------------------------------------------------
186
+ // D4 — o instrumento NUNCA é trava
187
+ // ---------------------------------------------------------------------------
188
+
189
+ function testNuncaTrava() {
190
+ console.log('\n--- D4: exit 0 sempre, com diagnóstico (nunca silêncio, nunca crash) ---');
191
+
192
+ const inexistente = path.join(os.tmpdir(), 'derive-alvo-que-nao-existe-4c1f9a');
193
+ const r = rodar([inexistente]);
194
+ assert(r.status === 0, `D4: repositório-alvo inexistente ⇒ exit 0 (status=${r.status})`);
195
+ assert(/DIAGNOSTICO/.test(r.stdout), 'D4: a falha é DECLARADA no stdout — nem silêncio (indistinguível de "zero transições") nem exceção não tratada');
196
+
197
+ const semGit = fs.mkdtempSync(path.join(os.tmpdir(), 'derive-sem-git-'));
198
+ const r2 = rodar([semGit]);
199
+ assert(r2.status === 0 && /DIAGNOSTICO/.test(r2.stdout), `D4: diretório que existe mas não é repo git ⇒ exit 0 + diagnóstico (status=${r2.status})`);
200
+
201
+ const r3 = rodar(['.', '--rev']);
202
+ assert(r3.status === 0 && /DIAGNOSTICO/.test(r3.stdout), `D4: opção sem valor ⇒ exit 0 + diagnóstico (status=${r3.status})`);
203
+
204
+ const r4 = rodar(['.', '--rev', 'ref-que-nao-existe-4c1f9a', '--stories-dir', 'docs/stories']);
205
+ assert(r4.status === 0 && /DIAGNOSTICO/.test(r4.stdout), `D4: rev irresolvível ⇒ exit 0 + diagnóstico (status=${r4.status})`);
206
+ }
207
+
208
+ // ---------------------------------------------------------------------------
209
+ // D2 / Segurança — fonte única e invocação sem shell
210
+ // ---------------------------------------------------------------------------
211
+
212
+ function testFonteUnicaESeguranca() {
213
+ console.log('\n--- D2 (fonte única) e Segurança (git por array, sem shell) ---');
214
+
215
+ const src = fs.readFileSync(SCRIPT, 'utf8');
216
+
217
+ assert(/enforce-cycle-authority/.test(src) && /enforce-ready-oracles/.test(src), 'D2: o instrumento REFERENCIA os dois hooks por path — isto é, os carrega em vez de copiá-los');
218
+ const redefine = /function\s+(extractStatusSection|statusToken|evaluateReadyOracles)\s*\(/.test(src);
219
+ assert(!redefine, 'D2: nenhum dos 3 predicados (extractStatusSection/statusToken/evaluateReadyOracles) é redefinido aqui — uma 2ª implementação poderia divergir do hook sobre o que É uma transição');
220
+
221
+ assert(/execFileSync\(\s*'git'\s*,\s*\[/.test(src), 'Segurança: `git` é invocado por execFileSync com argumentos em ARRAY');
222
+ assert(!/\bexecSync\(|\bexec\(|shell\s*:\s*true/.test(src), 'Segurança: nenhum `exec`/`execSync`/`shell: true` — o path do alvo nunca é concatenado em string de comando');
223
+
224
+ // O instrumento NÃO viaja para instalações (D5). Assertado, não só omitido:
225
+ // sem isto, a próxima passada "conserta" a ausência do manifesto.
226
+ const manifesto = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, 'installer', 'motor-scripts.json'), 'utf8'));
227
+ assert(
228
+ !manifesto.scripts.some((s) => s.path === 'scripts/derive-ready-transitions.cjs'),
229
+ 'D5: o instrumento NÃO está em scripts[] do manifesto — a decisão que ele serve acontece uma vez, no repositório do framework',
230
+ );
231
+ assert(
232
+ manifesto.exclude.includes('derive-ready-transitions.cjs'),
233
+ 'D5: o instrumento está no `exclude` do manifesto — a não-distribuição é DECIDIDA, não um esquecimento que o invariante 1 acusaria',
234
+ );
235
+ }
236
+
237
+ // ---------------------------------------------------------------------------
238
+ // Parser de log — puro, testável sem git
239
+ // ---------------------------------------------------------------------------
240
+
241
+ function testParseLog() {
242
+ console.log('\n--- parseLog: puro, sem git ---');
243
+
244
+ const { parseLog } = require(SCRIPT);
245
+ const SEP = '\u0001';
246
+ const texto = `${SEP}abc123|2026-08-09T02:34:21-04:00\ndocs/stories/a.story.md\ndocs/stories/README.md\n\n${SEP}def456|2026-08-08T10:00:00-04:00\ndocs/stories/b.story.md\n`;
247
+ const regs = parseLog(texto);
248
+ assert(regs.length === 2, `parseLog: 2 registros (medido: ${regs.length})`);
249
+ assert(regs[0].sha === 'abc123' && regs[0].iso === '2026-08-09T02:34:21-04:00', 'parseLog: sha e data do cabeçalho');
250
+ assert(regs[0].arquivos.length === 1 && regs[0].arquivos[0] === 'docs/stories/a.story.md', 'parseLog: só `*.story.md` entra (README.md do mesmo commit é descartado)');
251
+ assert(parseLog('').length === 0 && parseLog(null).length === 0, 'parseLog: entrada vazia/nula não vira registro fantasma');
252
+ }
253
+
254
+ // ---------------------------------------------------------------------------
255
+
256
+ console.log('=== derive-ready-transitions.test.cjs — ADR-035 D7 (SF13.8) ===');
257
+ testParseLog();
258
+ testControlePositivo();
259
+ testControleNegativo();
260
+ testFalsoNegativoDeclarado();
261
+ testNuncaTrava();
262
+ testFonteUnicaESeguranca();
263
+ testCorpusReal();
264
+
265
+ if (failures > 0) {
266
+ console.error(`\n${failures} falha(s).`);
267
+ process.exit(1);
268
+ }
269
+ console.log('\nTodos os testes passaram.');