@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,242 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /**
4
+ * forge-harden-learning.test.cjs — fixture PONTA-A-PONTA do caso motivador (SF7.6/AC6):
5
+ * a heurística "evitar travessões" de um pod-canário, consolidada na memória, é promovida
6
+ * a veto físico `command_check` (lexical-check.cjs, SF7.2) — e o teste PROVA:
7
+ *
8
+ * POSITIVA: antes do hardening, um artefato COM travessão passa o workflow inteiro
9
+ * (smoke happy-path verde) — a heurística em prosa NÃO impede (o caso R5).
10
+ * NEGATIVA: depois do hardening, o MESMO artefato bloqueia na etapa-alvo (smoke falha).
11
+ *
12
+ * Mais: aprovação obrigatória (--approved-by, exit 2 sem ela), spec/wf com diff confinado
13
+ * à etapa-alvo, marcação append-only type:"hardening" (log intacto), 🔒 no consolidado e
14
+ * demoção do top-N ativo, idempotência (re-promover recusa).
15
+ */
16
+
17
+ const assert = require('node:assert');
18
+ const fs = require('node:fs');
19
+ const os = require('node:os');
20
+ const path = require('node:path');
21
+ const { spawnSync } = require('node:child_process');
22
+
23
+ const podMemory = require('./pod-memory.cjs');
24
+ const { generatePod } = require('./forge-generate.cjs');
25
+ const { splitWfBlocks } = require('./forge-harden-learning.cjs');
26
+
27
+ const REPO = path.resolve(__dirname, '..');
28
+ const HARDEN = path.join(REPO, 'scripts', 'forge-harden-learning.cjs');
29
+ const SMOKE = path.join(REPO, 'scripts', 'smoke-pod-workflow.cjs');
30
+ const VALIDATE = path.join(REPO, 'scripts', 'validate-pod-workflow.cjs');
31
+
32
+ let passed = 0;
33
+ function ok(label, cond) {
34
+ if (!cond) {
35
+ console.error(`[FALHOU] ${label}`);
36
+ process.exit(1);
37
+ }
38
+ passed += 1;
39
+ console.log(`[OK ] ${label}`);
40
+ }
41
+
42
+ function sh(args) {
43
+ return spawnSync(process.execPath, args, { encoding: 'utf8', cwd: REPO });
44
+ }
45
+
46
+ // ── setup: pod-canário gerado pela fábrica real ───────────────────────────────
47
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'harden-fixture-'));
48
+ const podDir = path.join(tmp, 'canario-hard');
49
+ const spec = {
50
+ pod: 'canario-hard',
51
+ workflowId: 'canario-hard',
52
+ handoffs: 1,
53
+ memoryOpt: true,
54
+ agents: [
55
+ { name: 'redator', step: 'redacao', output: 'texto', sections: ['## Texto'] },
56
+ { name: 'revisor', step: 'revisao', output: 'parecer', sections: ['## Parecer'] },
57
+ ],
58
+ };
59
+ fs.mkdirSync(podDir, { recursive: true });
60
+ fs.writeFileSync(path.join(podDir, 'pod-spec.json'), `${JSON.stringify(spec, null, 2)}\n`);
61
+ // SF12.4a/ADR-030 Bloco O — bootstrap do fixture (pod pré-existente antes do hardening);
62
+ // 'derived' também preserva o comportamento pré-SF12.4a de NÃO emitir agents/*.md aqui
63
+ // (o teste os autora logo abaixo, simulando o forge-chief).
64
+ generatePod(spec, podDir, { withMemory: true, specOrigin: 'derived' });
65
+
66
+ const wfPath = path.join(podDir, 'workflows', 'wf-canario-hard.yaml');
67
+ ok('setup: wf gerado pela fábrica', fs.existsSync(wfPath));
68
+
69
+ // [SF11.2/DF-SF11.2-4] `forge-generate.cjs` escreve workflows/templates/squad-io/memory, mas
70
+ // NÃO escreve `agents/*.md` (autorados depois, pela skill do forge). Desde a SF11.2 o runner
71
+ // resolve e VERIFICA `agents/<step.agent>.md` antes de despachar — pod sem o agente em disco
72
+ // é `blocked: leitura_obrigatoria_ausente` e o smoke não roda. O mesmo já valia para o export
73
+ // (`pod-export-compile.cjs:214` falha pela mesma causa). Aqui o fixture completa o pod.
74
+ fs.mkdirSync(path.join(podDir, 'agents'), { recursive: true });
75
+ for (const a of ['redator', 'revisor']) {
76
+ fs.writeFileSync(path.join(podDir, 'agents', `${a}.md`),
77
+ `---\nname: ${a}\ndescription: "Agente de fixture do pod-canário desta suíte."\nmodel: sonnet\nbudget_tokens: 200\n---\n\n# ${a}\n\nFixture de teste.\n`);
78
+ }
79
+
80
+ // sidecar canônico (baseline LIMPO — sem travessão) usado pelo próprio harden
81
+ const cleanScenario = {
82
+ target_step: 'redacao',
83
+ artifacts: {
84
+ redacao: '## Texto\nTexto limpo, com virgulas e dois-pontos no lugar do tell de IA.\n\nconfianca: alta\n',
85
+ revisao: '## Parecer\nParecer conforme sobre o texto.\n\nconfianca: alta\n',
86
+ },
87
+ template_violation: 'confianca: alta\n',
88
+ veto_violation: '## Texto\nTexto presente mas campo de maquina fora do dominio.\n\nconfianca: incerta\n',
89
+ };
90
+ const cleanPath = wfPath.replace(/\.yaml$/, '.smoke.json');
91
+ fs.writeFileSync(cleanPath, JSON.stringify(cleanScenario, null, 2));
92
+
93
+ // cenário do CASO MOTIVADOR: artefato da etapa-alvo COM travessão (em-dash U+2014)
94
+ const dashScenario = {
95
+ ...cleanScenario,
96
+ artifacts: {
97
+ ...cleanScenario.artifacts,
98
+ redacao: '## Texto\nTexto que regride — com travessão de IA — apesar da heurística.\n\nconfianca: alta\n',
99
+ },
100
+ };
101
+ const dashPath = path.join(podDir, 'workflows', 'dash.smoke.json');
102
+ fs.writeFileSync(dashPath, JSON.stringify(dashScenario, null, 2));
103
+
104
+ // ── memória: a heurística do caso real, consolidada no top-N ─────────────────
105
+ const e1 = podMemory.append('canario-hard', {
106
+ trigger: 'travessoes no texto final',
107
+ recommendation: 'nunca usar travessao (em/en-dash); prefira virgula ou dois-pontos',
108
+ source_run_id: 'r1',
109
+ }, { podDir });
110
+ podMemory.append('canario-hard', {
111
+ trigger: 'travessoes no texto final',
112
+ recommendation: 'nunca usar travessao (em/en-dash); prefira virgula ou dois-pontos',
113
+ source_run_id: 'r4',
114
+ }, { podDir });
115
+ podMemory.consolidate('canario-hard', { podDir });
116
+ const memPaths = podMemory.memoryPaths('canario-hard', { podDir });
117
+ const consolidatedBefore = fs.readFileSync(memPaths.consolidated, 'utf8');
118
+ ok('memória: heurística no top-N do consolidado',
119
+ consolidatedBefore.includes('**[travessoes no texto final]**') && !consolidatedBefore.includes('🔒'));
120
+
121
+ // ── PROVA POSITIVA (pré-hardening): artefato com travessão PASSA ─────────────
122
+ const smokeDashBefore = sh([SMOKE, wfPath, '--scenario', dashPath]);
123
+ ok('caso R5 reproduzido: smoke 4/4 verde COM travessão no artefato (heurística em prosa não bloqueia)',
124
+ smokeDashBefore.status === 0);
125
+
126
+ // ── aprovação obrigatória: sem --approved-by ⇒ exit 2, nada aplicado ─────────
127
+ const specBytes = fs.readFileSync(path.join(podDir, 'pod-spec.json'), 'utf8');
128
+ const wfBytes = fs.readFileSync(wfPath, 'utf8');
129
+ const assertionJson = JSON.stringify({ type: 'command_check', command: 'lexical-check.cjs', args: ['--max', '0'] });
130
+ const noApproval = sh([HARDEN, podDir, '--learning', e1.entry.id, '--step', 'redacao', '--assertion', assertionJson]);
131
+ ok('sem --approved-by: recusa exit 2', noApproval.status === 2);
132
+ ok('sem --approved-by: spec e wf INTOCADOS',
133
+ fs.readFileSync(path.join(podDir, 'pod-spec.json'), 'utf8') === specBytes &&
134
+ fs.readFileSync(wfPath, 'utf8') === wfBytes);
135
+
136
+ // ── QA CONCERNS-2: ROLLBACK automático pós-regen (fixture dedicada) ──────────
137
+ // Asserção de FORMA válida (passa checkAssertionShape e o estático) que o artefato
138
+ // conforme NÃO satisfaz ⇒ o smoke PÓS-regen reprova (prova 2 bloqueia) ⇒ o motor
139
+ // restaura spec/wf/templates BYTE-IDÊNTICOS, sai exit 2 e NÃO marca a memória.
140
+ // Kill-test coberto: sabotar a restauração (ou o pós-gate) torna isto VERMELHO.
141
+ const tmplPaths = ['redacao', 'revisao'].map((s) => path.join(podDir, 'templates', `${s}-tmpl.md`));
142
+ const tmplBytesBefore = tmplPaths.map((p) => fs.readFileSync(p, 'utf8'));
143
+ const rawBytesBeforeRollback = fs.readFileSync(memPaths.raw, 'utf8');
144
+ const badAssertion = JSON.stringify({ type: 'field_matches', field: 'campo_inexistente', pattern: '^presente$' });
145
+ const rb = sh([HARDEN, podDir, '--learning', e1.entry.id, '--step', 'revisao',
146
+ '--assertion', badAssertion, '--approved-by', 'daniel']);
147
+ ok('rollback: pós-smoke vermelho ⇒ comando sai ≠0 (exit 2)', rb.status === 2);
148
+ ok('rollback: recusa nomeia pós-gate vermelho + ROLLBACK aplicado',
149
+ /pós-gate vermelho/.test(rb.stderr) && /ROLLBACK aplicado/.test(rb.stderr));
150
+ ok('rollback: pod-spec.json BYTE-IDÊNTICO ao baseline',
151
+ fs.readFileSync(path.join(podDir, 'pod-spec.json'), 'utf8') === specBytes);
152
+ ok('rollback: wf BYTE-IDÊNTICO ao baseline', fs.readFileSync(wfPath, 'utf8') === wfBytes);
153
+ ok('rollback: templates BYTE-IDÊNTICOS ao baseline',
154
+ tmplPaths.every((p, i) => fs.readFileSync(p, 'utf8') === tmplBytesBefore[i]));
155
+ ok('rollback: memória INTOCADA (log cru byte-idêntico, sem registro hardening, sem 🔒)',
156
+ fs.readFileSync(memPaths.raw, 'utf8') === rawBytesBeforeRollback &&
157
+ !fs.readFileSync(memPaths.raw, 'utf8').includes('"type":"hardening"') &&
158
+ !fs.readFileSync(memPaths.consolidated, 'utf8').includes('🔒'));
159
+
160
+ // ── promoção aprovada ────────────────────────────────────────────────────────
161
+ const rawLinesBefore = fs.readFileSync(memPaths.raw, 'utf8').split('\n').filter(Boolean);
162
+ const promote = sh([HARDEN, podDir, '--learning', e1.entry.id, '--step', 'redacao',
163
+ '--assertion', assertionJson, '--approved-by', 'daniel']);
164
+ ok(`promoção aprovada: exit 0 (${promote.status})${promote.status !== 0 ? `\n${promote.stdout}${promote.stderr}` : ''}`,
165
+ promote.status === 0);
166
+
167
+ // spec: asserção aplicada SÓ na etapa-alvo, com rastreabilidade
168
+ const specAfter = JSON.parse(fs.readFileSync(path.join(podDir, 'pod-spec.json'), 'utf8'));
169
+ const vetoRedacao = specAfter.agents[0].veto || [];
170
+ ok('spec: command_check aplicado à etapa-alvo com _sources de hardening',
171
+ vetoRedacao.some((a) => a.type === 'command_check' && a.command === 'lexical-check.cjs' &&
172
+ String(a._sources || '').includes('promovido a enforcement por daniel')) &&
173
+ !(specAfter.agents[1].veto || []).some((a) => a.type === 'command_check'));
174
+
175
+ // wf: diff confinado à etapa-alvo
176
+ const wfAfter = fs.readFileSync(wfPath, 'utf8');
177
+ const b = splitWfBlocks(wfBytes);
178
+ const a = splitWfBlocks(wfAfter);
179
+ ok('wf: etapa-alvo ganhou o command_check',
180
+ a.blocks.get('redacao').join('\n').includes('command_check') &&
181
+ a.blocks.get('redacao').join('\n').includes('lexical-check.cjs'));
182
+ ok('wf: etapa NÃO-alvo byte-idêntica (preservação)',
183
+ b.blocks.get('revisao').join('\n') === a.blocks.get('revisao').join('\n') &&
184
+ b.header === a.header);
185
+
186
+ // estático continua verde sobre o wf regenerado
187
+ ok('validate-pod-workflow exit 0 no wf regenerado', sh([VALIDATE, wfPath]).status === 0);
188
+
189
+ // smoke 4/4 continua verde no cenário LIMPO (preservação funcional)
190
+ ok('smoke 4/4 verde pós-hardening no cenário limpo', sh([SMOKE, wfPath, '--scenario', cleanPath]).status === 0);
191
+
192
+ // ── PROVA NEGATIVA (pós-hardening): o MESMO artefato com travessão BLOQUEIA ──
193
+ const smokeDashAfter = sh([SMOKE, wfPath, '--scenario', dashPath]);
194
+ ok('enforcement real: smoke com travessão agora FALHA (bloqueio físico na etapa-alvo)',
195
+ smokeDashAfter.status !== 0);
196
+
197
+ // ── memória: append-only + 🔒 + demoção do top-N ─────────────────────────────
198
+ const rawLinesAfter = fs.readFileSync(memPaths.raw, 'utf8').split('\n').filter(Boolean);
199
+ ok('log cru: linhas originais INTACTAS + 1 registro hardening apendado',
200
+ rawLinesAfter.length === rawLinesBefore.length + 1 &&
201
+ rawLinesAfter.slice(0, rawLinesBefore.length).join('\n') === rawLinesBefore.join('\n'));
202
+ const hardRecord = JSON.parse(rawLinesAfter[rawLinesAfter.length - 1]);
203
+ ok('registro hardening no formato ADR-012 (type/ref/target/approved_by/timestamp)',
204
+ hardRecord.type === 'hardening' &&
205
+ hardRecord.ref === podMemory.dedupKey(e1.entry) &&
206
+ hardRecord.target.workflowId === 'canario-hard' &&
207
+ hardRecord.target.step === 'redacao' &&
208
+ hardRecord.target.assertion.type === 'command_check' &&
209
+ hardRecord.approved_by === 'daniel' &&
210
+ typeof hardRecord.timestamp === 'string');
211
+
212
+ const consolidatedAfter = fs.readFileSync(memPaths.consolidated, 'utf8');
213
+ // SF11.4/ADR-022 (DF-SF11.4-1): o consolidado (artefato INJETADO) traz a referência
214
+ // AGREGADA; o detalhe íntegro — asserção, aprovador, momento — vive na trilha auditável
215
+ // `memory/learnings.hardened.md`, append-only e fora do caminho de injeção.
216
+ const hardenedDetailAfter = fs.readFileSync(memPaths.hardenedDetail, 'utf8');
217
+ ok('consolidado: referência AGREGADA 🔒 → veto command_check em redacao (1)',
218
+ consolidatedAfter.includes('## Endurecidas (🔒 → enforcement)') &&
219
+ consolidatedAfter.includes('veto command_check em redacao (1)') &&
220
+ consolidatedAfter.includes(podMemory.HARDENED_DETAIL_REL));
221
+ ok('trilha auditável: detalhe íntegro da endurecida (asserção, aprovador, momento)',
222
+ hardenedDetailAfter.includes('🔒 **[travessoes no texto final]**') &&
223
+ hardenedDetailAfter.includes('endurecida → veto command_check em redacao') &&
224
+ hardenedDetailAfter.includes('(por daniel,'), hardenedDetailAfter);
225
+ const topNSection = consolidatedAfter.split('## Endurecidas')[0];
226
+ ok('consolidado: heurística DEMOVIDA do top-N ativo (não compete por injeção)',
227
+ !topNSection.includes('**[travessoes no texto final]**'));
228
+
229
+ // consolidate idempotente mantém a marcação
230
+ const again = podMemory.consolidate('canario-hard', { podDir });
231
+ ok('consolidate idempotente: hardenedCount=1, referência 🔒 preservada e trilha byte-idêntica',
232
+ again.hardenedCount === 1 &&
233
+ fs.readFileSync(memPaths.consolidated, 'utf8').includes('veto command_check em redacao (1)') &&
234
+ fs.readFileSync(memPaths.hardenedDetail, 'utf8') === hardenedDetailAfter);
235
+
236
+ // ── idempotência da promoção: repetir recusa (exit 2) ────────────────────────
237
+ const repeat = sh([HARDEN, podDir, '--learning', e1.entry.id, '--step', 'redacao',
238
+ '--assertion', assertionJson, '--approved-by', 'daniel']);
239
+ ok('re-promover a mesma heurística: recusa exit 2 (já endurecida)', repeat.status === 2);
240
+
241
+ fs.rmSync(tmp, { recursive: true, force: true });
242
+ console.log(`\n${passed}/${passed} verificações passaram.`);
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /**
4
+ * forge-ingest-memory.cjs — ingest EXTERNO OPT-IN de conhecimento para a memória de um
5
+ * pod, com dedup M1 (Story SF2.3, SPEC §M1).
6
+ *
7
+ * RESTRIÇÃO DO DANIEL (reafirmada, Risco 4): a memória v1 é aprendizado-DO-USO; ingest
8
+ * de fonte EXTERNA é SEMPRE OPT-IN MANUAL — só existe como invocação explícita do
9
+ * comando `*ingest-memory` do forge-chief. Este script NUNCA é chamado por outro fluxo
10
+ * automático (em particular, NÃO é importado por pc-run-pod.cjs). Verificável por grep.
11
+ *
12
+ * DEDUP M1: chave = `sha256(conteúdo normalizado) :: fonte normalizada`. Se a chave já
13
+ * existe no log cru → MERGE (incrementa a ocorrência via evidence.count) EM VEZ DE
14
+ * DUPLICAR a linha. Fonte diferente com o MESMO conteúdo = chave diferente = entrada
15
+ * distinta (a proveniência importa). O merge reescreve UMA linha do log cru — é operação
16
+ * SEPARADA do append-only (como rotate()), não uma quebra do contrato do motor.
17
+ *
18
+ * Uso:
19
+ * node scripts/forge-ingest-memory.cjs <podDir> --source "<fonte citada>" \
20
+ * --trigger "<gatilho>" --recommendation "<recomendação>" [--content-file <arq>]
21
+ * (--content-file: hash do conteúdo do arquivo; senão hash da recomendação)
22
+ *
23
+ * Node >= 18, sem dependências externas.
24
+ */
25
+
26
+ const fs = require('node:fs');
27
+ const path = require('node:path');
28
+ const crypto = require('node:crypto');
29
+ const podMemory = require('./pod-memory.cjs');
30
+
31
+ function normalizeContent(s) {
32
+ return String(s == null ? '' : s)
33
+ .toLowerCase()
34
+ .normalize('NFD')
35
+ .replace(/[̀-ͯ]/g, '')
36
+ .replace(/\s+/g, ' ')
37
+ .trim();
38
+ }
39
+
40
+ /** Chave de dedup M1: hash do conteúdo normalizado + fonte normalizada. */
41
+ function ingestKey(content, source) {
42
+ const hash = crypto.createHash('sha256').update(normalizeContent(content)).digest('hex').slice(0, 16);
43
+ return `${hash}::${normalizeContent(source)}`;
44
+ }
45
+
46
+ // A chave M1 viaja em `source_run_id` (campo que pod-memory.append PRESERVA — ele
47
+ // descarta campos desconhecidos, então não usamos um campo próprio). Prefixo estável.
48
+ const KEY_PREFIX = 'ingest::';
49
+
50
+ /**
51
+ * Ingesta uma lição externa na memória do pod com dedup M1.
52
+ * @param podDir diretório do pod (contém memory/)
53
+ * @param entry { trigger, recommendation, source, content? } — content hashado (senão a recomendação)
54
+ * @returns { action: 'appended'|'merged', key, occurrences }
55
+ */
56
+ function ingestExternal(podDir, entry, opts = {}) {
57
+ if (!entry || !entry.trigger || !entry.recommendation || !entry.source) {
58
+ throw new Error('ingest-memory: exige { trigger, recommendation, source } (fonte citada é obrigatória — M1)');
59
+ }
60
+ const content = entry.content != null ? entry.content : entry.recommendation;
61
+ const key = ingestKey(content, entry.source);
62
+ const runIdKey = KEY_PREFIX + key;
63
+ const paths = podMemory.memoryPaths('_', { podDir });
64
+ fs.mkdirSync(paths.dir, { recursive: true });
65
+
66
+ // lê o log cru e procura a chave M1 já ingerida (carregada em source_run_id)
67
+ const lines = fs.existsSync(paths.raw)
68
+ ? fs.readFileSync(paths.raw, 'utf8').split('\n').filter((l) => l.trim())
69
+ : [];
70
+ const records = lines.map((l) => { try { return JSON.parse(l); } catch { return null; } });
71
+
72
+ let hitIdx = -1;
73
+ for (let i = 0; i < records.length; i++) {
74
+ if (records[i] && records[i].source_run_id === runIdKey) { hitIdx = i; break; }
75
+ }
76
+
77
+ if (hitIdx >= 0) {
78
+ // MERGE — incrementa ocorrência, NÃO duplica a linha (M1).
79
+ const rec = records[hitIdx];
80
+ const prev = (rec.evidence && typeof rec.evidence.count === 'number') ? rec.evidence.count : 1;
81
+ rec.evidence = { count: prev + 1 };
82
+ rec.ts = Date.now();
83
+ lines[hitIdx] = JSON.stringify(rec);
84
+ fs.writeFileSync(paths.raw, lines.join('\n') + '\n');
85
+ return { action: 'merged', key, occurrences: rec.evidence.count };
86
+ }
87
+
88
+ // NOVA entrada — via o motor (append-only, tier normal; ingest externo NUNCA é
89
+ // critical: attributed_by de critical exige human/deterministic_rule upstream). A
90
+ // chave M1 viaja em source_run_id (campo que o motor PRESERVA).
91
+ const record = {
92
+ trigger: entry.trigger,
93
+ recommendation: entry.recommendation,
94
+ evidence: { count: 1 },
95
+ tier: 'normal',
96
+ source_run_id: runIdKey,
97
+ };
98
+ podMemory.append('_', record, { podDir });
99
+ return { action: 'appended', key, occurrences: 1 };
100
+ }
101
+
102
+ function main() {
103
+ const args = process.argv.slice(2);
104
+ let podDir = null;
105
+ const o = {};
106
+ for (let i = 0; i < args.length; i++) {
107
+ if (args[i] === '--source') o.source = args[++i];
108
+ else if (args[i] === '--trigger') o.trigger = args[++i];
109
+ else if (args[i] === '--recommendation') o.recommendation = args[++i];
110
+ else if (args[i] === '--content-file') o.contentFile = args[++i];
111
+ else podDir = args[i];
112
+ }
113
+ if (!podDir || !o.source || !o.trigger || !o.recommendation) {
114
+ console.error('Uso: node scripts/forge-ingest-memory.cjs <podDir> --source "<fonte>" --trigger "<gatilho>" --recommendation "<rec>" [--content-file <arq>]');
115
+ process.exit(2);
116
+ }
117
+ const content = o.contentFile ? fs.readFileSync(path.resolve(o.contentFile), 'utf8') : o.recommendation;
118
+ const r = ingestExternal(path.resolve(podDir), { trigger: o.trigger, recommendation: o.recommendation, source: o.source, content });
119
+ console.log(`${r.action}: chave M1 ${r.key} (ocorrências: ${r.occurrences})`);
120
+ // consolida para refletir a ingestão no artefato lido pelo agente.
121
+ // SF11.4b/ADR-023 (DF-SF11.4b-1, DEBT-SF11.4b-B autorizado pelo dono): o retorno
122
+ // PARA DE SER DESCARTADO — era o último dos 4 chamadores cegos ao que a consolidação
123
+ // deixou de fora (QA-4 do gate da SF11.4). Ingerir conhecimento externo é justamente
124
+ // o ato que empurra a cauda para fora: ingerir e não ver o que saiu é o sub-relato de
125
+ // C2 num quarto lugar. Mesmo padrão dos outros 3 emissores: ledger do motor, total
126
+ // primeiro, quebra por causa depois. Aviso não derruba a ingestão (já gravada).
127
+ const resolvedPodDir = path.resolve(podDir);
128
+ const res = podMemory.consolidate('_', { podDir: resolvedPodDir });
129
+ const ledger = podMemory.formatEvictionLedger(path.basename(resolvedPodDir), res);
130
+ if (ledger) console.error(ledger);
131
+ process.exit(0);
132
+ }
133
+
134
+ if (require.main === module) main();
135
+
136
+ module.exports = { ingestExternal, ingestKey, normalizeContent };