@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.
- package/LICENSE +21 -0
- package/README.md +121 -0
- package/bin/cli.js +124 -0
- package/installer/__tests__/doctor-ready-oracles.test.cjs +140 -0
- package/installer/__tests__/merge-settings.test.cjs +330 -0
- package/installer/adopt.js +161 -0
- package/installer/copy.js +203 -0
- package/installer/doctor.js +266 -0
- package/installer/install.js +155 -0
- package/installer/manifest.js +102 -0
- package/installer/motor-scripts.js +50 -0
- package/installer/motor-scripts.json +39 -0
- package/installer/uninstall.js +99 -0
- package/installer/update.js +376 -0
- package/installer/util.js +113 -0
- package/installer/wizard.js +64 -0
- package/package.json +26 -0
- package/scripts/__fixtures__/anti-path-demo/agents/ap-writer.md +13 -0
- package/scripts/__fixtures__/anti-path-demo/templates/write-tmpl.md +7 -0
- package/scripts/__fixtures__/anti-path-demo/workflows/wf-ap.smoke.json +10 -0
- package/scripts/__fixtures__/anti-path-demo/workflows/wf-ap.yaml +25 -0
- package/scripts/__fixtures__/assess-tier/retrofit-leve/pod/agents/content-chief.md +1 -0
- package/scripts/__fixtures__/assess-tier/retrofit-leve/pod/workflows/wf-criacao-redteam.yaml +3 -0
- package/scripts/__fixtures__/assess-tier/retrofit-leve/pod-spec.json +13 -0
- package/scripts/__fixtures__/fidelity/fake-green-average-in-band.yaml +21 -0
- package/scripts/__fixtures__/fidelity/fake-green-average.yaml +18 -0
- package/scripts/__fixtures__/fidelity/fake-green-denominator.yaml +19 -0
- package/scripts/__fixtures__/fidelity/fake-green-missing-evidence.yaml +18 -0
- package/scripts/__fixtures__/fidelity/fake-green-threshold.yaml +18 -0
- package/scripts/__fixtures__/fidelity/fake-green-weight.yaml +18 -0
- package/scripts/__fixtures__/fidelity/golden.yaml +31 -0
- package/scripts/__fixtures__/fidelity/trindade-incoherent.yaml +15 -0
- package/scripts/__fixtures__/forge-canonical/pod-spec-example.json +37 -0
- package/scripts/__fixtures__/migrate-squad/authored/agents/offer-engineer.md +17 -0
- package/scripts/__fixtures__/migrate-squad/authored/knowledge/no-source.md +7 -0
- package/scripts/__fixtures__/migrate-squad/authored/knowledge/value-stack-method.md +8 -0
- package/scripts/__fixtures__/migrate-squad/authored/specs/wf-sample.smoke.json +24 -0
- package/scripts/__fixtures__/migrate-squad/authored/specs/wf-sample.spec.json +45 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/HEADLINE.md +3 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/README.md +4 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/agents/hormozi-offer.md +14 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/dead-redundant.md +4 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/method-guide.md +6 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/veto-screen.md +4 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/config/config.yaml +2 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/data/case-library.md +3 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/scripts/validate-mvn.py +16 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/sops/sop-sample.md +3 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/squad-io.yaml +14 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/tasks/gather-context.md +7 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/templates/output-tmpl.md +5 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/workflows/wf-sample.yaml +24 -0
- package/scripts/__fixtures__/pipeline/pipelines/pipeline-checkpoint.yaml +21 -0
- package/scripts/__fixtures__/pipeline/pipelines/pipeline-demo.yaml +22 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/agents/maker.md +13 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/memory/learnings.consolidated.md +8 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/memory/learnings.jsonl +83 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/templates/make-tmpl.md +8 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/workflows/wf-a.yaml +16 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/agents/user.md +13 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/memory/learnings.consolidated.md +8 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/memory/learnings.jsonl +14 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/templates/use-tmpl.md +6 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/workflows/wf-b.yaml +16 -0
- package/scripts/__fixtures__/pod-run/agents/forge-chief.md +13 -0
- package/scripts/__fixtures__/pod-run/agents/pod-critic.md +13 -0
- package/scripts/__fixtures__/pod-run/templates/build-tmpl.md +8 -0
- package/scripts/__fixtures__/pod-run/templates/gate-tmpl.md +6 -0
- package/scripts/__fixtures__/pod-run/workflows/wf-min.yaml +43 -0
- package/scripts/__fixtures__/pod-run/workflows/wf-skip-modes.yaml +50 -0
- package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-all-skippable.yaml +30 -0
- package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-criteria-escalar-de-bloco.yaml +40 -0
- package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-skip-mode-desconhecido.yaml +30 -0
- package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-unknown-key.yaml +29 -0
- package/scripts/__fixtures__/pod-workflow/invalid-cycle.yaml +26 -0
- package/scripts/__fixtures__/pod-workflow/invalid-fix-loop-backedge.yaml +29 -0
- package/scripts/__fixtures__/pod-workflow/invalid-fix-loop-forward.yaml +29 -0
- package/scripts/__fixtures__/pod-workflow/invalid-handoff-open.yaml +27 -0
- package/scripts/__fixtures__/pod-workflow/invalid-knowledge-shape.yaml +18 -0
- package/scripts/__fixtures__/pod-workflow/invalid-missing-agent.yaml +15 -0
- package/scripts/__fixtures__/pod-workflow/invalid-missing-outputs.yaml +15 -0
- package/scripts/__fixtures__/pod-workflow/invalid-missing-template.yaml +15 -0
- package/scripts/__fixtures__/pod-workflow/invalid-missing-veto.yaml +13 -0
- package/scripts/__fixtures__/pod-workflow/invalid-template-not-on-disk.yaml +16 -0
- package/scripts/__fixtures__/pod-workflow/invalid-veto-prose.yaml +17 -0
- package/scripts/__fixtures__/pod-workflow/knowledge/a.md +4 -0
- package/scripts/__fixtures__/pod-workflow/knowledge/b.md +4 -0
- package/scripts/__fixtures__/pod-workflow/knowledge/c.md +4 -0
- package/scripts/__fixtures__/pod-workflow/templates/step-tmpl.md +7 -0
- package/scripts/__fixtures__/pod-workflow/valid-checkpoint-skip-modes.yaml +29 -0
- package/scripts/__fixtures__/pod-workflow/valid-fix-loop.yaml +30 -0
- package/scripts/__fixtures__/pod-workflow/valid-knowledge.yaml +30 -0
- package/scripts/__fixtures__/pod-workflow/valid-veto-always-true.yaml +20 -0
- package/scripts/__fixtures__/pod-workflow/valid.yaml +27 -0
- package/scripts/__fixtures__/smoke-canary/agents/canary-reporter.md +13 -0
- package/scripts/__fixtures__/smoke-canary/agents/canary-researcher.md +13 -0
- package/scripts/__fixtures__/smoke-canary/agents/canary-synth.md +13 -0
- package/scripts/__fixtures__/smoke-canary/memory/learnings.consolidated.md +10 -0
- package/scripts/__fixtures__/smoke-canary/memory/learnings.jsonl +448 -0
- package/scripts/__fixtures__/smoke-canary/templates/report-tmpl.md +9 -0
- package/scripts/__fixtures__/smoke-canary/templates/research-tmpl.md +7 -0
- package/scripts/__fixtures__/smoke-canary/templates/synth-tmpl.md +9 -0
- package/scripts/__fixtures__/smoke-canary/workflows/wf-canary.smoke.json +11 -0
- package/scripts/__fixtures__/smoke-canary/workflows/wf-canary.yaml +53 -0
- package/scripts/__fixtures__/source-audit/fake-green-bronze-unsignaled.yaml +10 -0
- package/scripts/__fixtures__/source-audit/fake-green-counts.yaml +9 -0
- package/scripts/__fixtures__/source-audit/fake-green-missing-evidence.yaml +9 -0
- package/scripts/__fixtures__/source-audit/fake-green-unclassified.yaml +10 -0
- package/scripts/__fixtures__/source-audit/fake-green-verdict.yaml +10 -0
- package/scripts/__fixtures__/source-audit/golden-blocked.yaml +10 -0
- package/scripts/__fixtures__/source-audit/golden.yaml +11 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-count.md +13 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-field.md +13 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-fileref.md +13 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-json.md +13 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-section.md +13 -0
- package/scripts/__fixtures__/sweep-forms/specs/wf-forms.spec.json +5 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_count.md +5 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_field.md +3 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_fileref.md +3 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_json.md +0 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_section.md +3 -0
- package/scripts/__fixtures__/sweep-forms/workflows/wf-forms.smoke.json +13 -0
- package/scripts/__fixtures__/sweep-forms/workflows/wf-forms.yaml +67 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-1-noop-state-json.fixture.md +18 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-2-crash-buildworkflowyaml.fixture.md +26 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-3-nasce-verde-skip-modes.fixture.md +29 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-4-guarda-sem-irmao.fixture.md +17 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-5a-diff-stat-sem-guarda.fixture.md +17 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-5b-test-f-sobre-diretorio.fixture.md +20 -0
- package/scripts/__fixtures__/veto-checks/copy-clean.md +4 -0
- package/scripts/__fixtures__/veto-checks/copy-dashes.md +4 -0
- package/scripts/__fixtures__/veto-checks/n8n-bad.md +18 -0
- package/scripts/__fixtures__/veto-checks/n8n-ok.md +22 -0
- package/scripts/__fixtures__/veto-checks/page-bad.html +7 -0
- package/scripts/__fixtures__/veto-checks/phash/copy.png +0 -0
- package/scripts/__fixtures__/veto-checks/phash/distinct.png +0 -0
- package/scripts/__fixtures__/veto-checks/phash/distinct2.png +0 -0
- package/scripts/__fixtures__/veto-checks/phash/make-fixtures.cjs +203 -0
- package/scripts/__fixtures__/veto-checks/phash/ref.png +0 -0
- package/scripts/__fixtures__/veto-checks/slide-ok.html +15 -0
- package/scripts/__fixtures__/veto-checks/slide-overflow.html +14 -0
- package/scripts/__fixtures__/veto-checks/sweep-pod/agents/vc-checker.md +13 -0
- package/scripts/__fixtures__/veto-checks/sweep-pod/templates/check-tmpl.md +6 -0
- package/scripts/__fixtures__/veto-checks/sweep-pod/workflows/wf-vc.smoke.json +10 -0
- package/scripts/__fixtures__/veto-checks/sweep-pod/workflows/wf-vc.yaml +19 -0
- package/scripts/__fixtures__/voz-do-dono/README.md +23 -0
- package/scripts/__fixtures__/voz-do-dono/dono-escalar.yaml +9 -0
- package/scripts/__fixtures__/voz-do-dono/dono-guia.yaml +10 -0
- package/scripts/__fixtures__/voz-do-dono/peca-3a-pessoa.md +6 -0
- package/scripts/__fixtures__/voz-do-dono/peca-com-lexico-proibido.md +6 -0
- package/scripts/__fixtures__/voz-do-dono/peca-limpa-1a-pessoa.md +6 -0
- package/scripts/__tests__/derive-ready-transitions.test.cjs +269 -0
- package/scripts/__tests__/enforce-cycle-authority.test.cjs +869 -0
- package/scripts/__tests__/enforce-git-push-authority.test.cjs +701 -0
- package/scripts/__tests__/enforce-ready-oracles.test.cjs +745 -0
- package/scripts/__tests__/motor-scripts.test.cjs +339 -0
- package/scripts/__tests__/pc-run-pod-counter.test.cjs +58 -0
- package/scripts/__tests__/pc-run-pod.test.cjs +578 -0
- package/scripts/__tests__/validate-pod-workflow.test.cjs +90 -0
- package/scripts/__tests__/validate-story-acs.test.cjs +607 -0
- package/scripts/anti-path.test.cjs +163 -0
- package/scripts/arena.cjs +514 -0
- package/scripts/arena.test.cjs +213 -0
- package/scripts/brief-leitura-obrigatoria.test.cjs +364 -0
- package/scripts/consolidate-knowledge-runner.test.cjs +249 -0
- package/scripts/default-funcional.test.cjs +153 -0
- package/scripts/derive-ready-transitions.cjs +325 -0
- package/scripts/forge-additive.test.cjs +158 -0
- package/scripts/forge-assess-tier.cjs +205 -0
- package/scripts/forge-assess-tier.test.cjs +114 -0
- package/scripts/forge-canonical.test.cjs +624 -0
- package/scripts/forge-generate.cjs +1303 -0
- package/scripts/forge-harden-learning.cjs +921 -0
- package/scripts/forge-harden-learning.test.cjs +242 -0
- package/scripts/forge-ingest-memory.cjs +136 -0
- package/scripts/forge-upgrade-pod.cjs +368 -0
- package/scripts/forge.test.cjs +609 -0
- package/scripts/harden-knowledge.test.cjs +612 -0
- package/scripts/harness-g5-lite.cjs +243 -0
- package/scripts/harness-g5-lite.test.cjs +134 -0
- package/scripts/hn-carousel-contrato-entrada.test.cjs +96 -0
- package/scripts/migrate-squad-orchestration.test.cjs +146 -0
- package/scripts/migration-manifest-sf3.2.test.cjs +382 -0
- package/scripts/migration-manifest-sf3.3.test.cjs +170 -0
- package/scripts/migration-manifest-sf5.5.test.cjs +189 -0
- package/scripts/migration-manifest.cjs +1146 -0
- package/scripts/migration-manifest.test.cjs +186 -0
- package/scripts/npm-scope-invocation.test.cjs +194 -0
- package/scripts/owner-layer.cjs +442 -0
- package/scripts/owner-layer.test.cjs +358 -0
- package/scripts/pc-run-pipeline.cjs +289 -0
- package/scripts/pc-run-pipeline.test.cjs +256 -0
- package/scripts/pc-run-pod-countgte.test.cjs +66 -0
- package/scripts/pc-run-pod.cjs +1355 -0
- package/scripts/phash-gate.test.cjs +433 -0
- package/scripts/pod-export-compile.cjs +487 -0
- package/scripts/pod-export-compile.test.cjs +312 -0
- package/scripts/pod-export-executor.cjs +678 -0
- package/scripts/pod-export-executor.test.cjs +1341 -0
- package/scripts/pod-export-hardening.test.cjs +531 -0
- package/scripts/pod-export-postprocess.cjs +427 -0
- package/scripts/pod-export-postprocess.test.cjs +558 -0
- package/scripts/pod-export-queue-race.test.cjs +865 -0
- package/scripts/pod-export-release.cjs +473 -0
- package/scripts/pod-export-release.test.cjs +267 -0
- package/scripts/pod-export-service.cjs +1297 -0
- package/scripts/pod-export-service.test.cjs +489 -0
- package/scripts/pod-export-tools.cjs +470 -0
- package/scripts/pod-export-ui.cjs +805 -0
- package/scripts/pod-export-ui.test.cjs +301 -0
- package/scripts/pod-memory-budget.test.cjs +309 -0
- package/scripts/pod-memory-note.cjs +357 -0
- package/scripts/pod-memory-note.test.cjs +452 -0
- package/scripts/pod-memory.cjs +1252 -0
- package/scripts/pod-memory.test.cjs +951 -0
- package/scripts/render-png.test.cjs +307 -0
- package/scripts/smoke-isolation.test.cjs +100 -0
- package/scripts/smoke-pod-workflow.cjs +755 -0
- package/scripts/smoke-sweep.test.cjs +170 -0
- package/scripts/validate-adopt.js +235 -0
- package/scripts/validate-branding.js +84 -0
- package/scripts/validate-budgets.js +140 -0
- package/scripts/validate-fidelity-output.cjs +267 -0
- package/scripts/validate-fidelity-output.test.cjs +101 -0
- package/scripts/validate-install.js +230 -0
- package/scripts/validate-no-clone.cjs +220 -0
- package/scripts/validate-no-clone.test.cjs +77 -0
- package/scripts/validate-pipeline.cjs +145 -0
- package/scripts/validate-pod-workflow.cjs +878 -0
- package/scripts/validate-source-audit.cjs +170 -0
- package/scripts/validate-source-audit.test.cjs +90 -0
- package/scripts/validate-story-acs.cjs +862 -0
- package/scripts/validate-update-scope-motor.js +421 -0
- package/scripts/veto-checks/html-valid.cjs +92 -0
- package/scripts/veto-checks/lexical-check.cjs +62 -0
- package/scripts/veto-checks/phash-gate.cjs +589 -0
- package/scripts/veto-checks/render-gate.cjs +165 -0
- package/scripts/veto-checks/render-png.cjs +358 -0
- package/scripts/veto-checks.test.cjs +219 -0
- package/scripts/watcher-audit.cjs +178 -0
- package/template/.claude/CLAUDE.md +103 -0
- package/template/.claude/agents/pc-analyst.md +100 -0
- package/template/.claude/agents/pc-architect.md +32 -0
- package/template/.claude/agents/pc-dev.md +27 -0
- package/template/.claude/agents/pc-devops.md +45 -0
- package/template/.claude/agents/pc-planner.md +32 -0
- package/template/.claude/agents/pc-po.md +25 -0
- package/template/.claude/agents/pc-qa.md +25 -0
- package/template/.claude/commands/power/academy.md +9 -0
- package/template/.claude/commands/power/automation.md +9 -0
- package/template/.claude/commands/power/content-carousel.md +267 -0
- package/template/.claude/commands/power/content.md +9 -0
- package/template/.claude/commands/power/dev.md +9 -0
- package/template/.claude/commands/power/forge.md +224 -0
- package/template/.claude/commands/power/hormozi.md +221 -0
- package/template/.claude/commands/power/modo.md +57 -0
- package/template/.claude/hooks/README.md +114 -0
- package/template/.claude/hooks/context-budget.cjs +64 -0
- package/template/.claude/hooks/enforce-cycle-authority.cjs +457 -0
- package/template/.claude/hooks/enforce-git-push-authority.cjs +925 -0
- package/template/.claude/hooks/enforce-ready-oracles.cjs +502 -0
- package/template/.claude/rules/authority.md +76 -0
- package/template/.claude/rules/curadoria-de-conhecimento.md +30 -0
- package/template/.claude/rules/model-matrix.md +34 -0
- package/template/.claude/rules/orchestration.md +133 -0
- package/template/.claude/settings.json +50 -0
- package/template/.claude/skills/pc-apply-qa-fixes/SKILL.md +108 -0
- package/template/.claude/skills/pc-apply-qa-fixes/references/fix-loop.md +40 -0
- package/template/.claude/skills/pc-apply-qa-fixes/references/fix-request-template.md +70 -0
- package/template/.claude/skills/pc-arena/SKILL.md +96 -0
- package/template/.claude/skills/pc-close-story/SKILL.md +105 -0
- package/template/.claude/skills/pc-commit/SKILL.md +108 -0
- package/template/.claude/skills/pc-develop-story/SKILL.md +116 -0
- package/template/.claude/skills/pc-full-cycle/SKILL.md +150 -0
- package/template/.claude/skills/pc-pipeline/SKILL.md +63 -0
- package/template/.claude/skills/pc-pipeline/references/gate-templates.md +46 -0
- package/template/.claude/skills/pc-review-story/SKILL.md +129 -0
- package/template/.claude/skills/pc-review-story/references/false-positive-detection.md +50 -0
- package/template/.claude/skills/pc-review-story/references/nfr-assess.md +47 -0
- package/template/.claude/skills/pc-review-story/references/risk-profile.md +75 -0
- package/template/.claude/skills/pc-review-story/references/security-checklist.md +69 -0
- package/template/.claude/skills/pc-review-story/references/test-design.md +37 -0
- package/template/.claude/skills/pc-review-story/references/trace-requirements.md +46 -0
- package/template/.claude/skills/pc-run-pod/SKILL.md +123 -0
- package/template/.claude/skills/pc-validate-story/SKILL.md +114 -0
- package/template/.claude/skills/pc-wave/SKILL.md +133 -0
- package/template/.env.example +10 -0
- package/template/knowledge/analyst/brainstorming.md +40 -0
- package/template/knowledge/analyst/brief-skeleton.md +32 -0
- package/template/knowledge/analyst/competitor-skeleton.md +39 -0
- package/template/knowledge/analyst/elicitation-menu.md +49 -0
- package/template/knowledge/analyst/market-research-skeleton.md +36 -0
- package/template/knowledge/analyst/research-prompt-structure.md +48 -0
- package/template/knowledge/analyst/roi-skeleton.md +51 -0
- package/template/knowledge/voice-dna/README.md +99 -0
- package/template/knowledge/voice-dna/voice-dna.example.yaml +157 -0
- package/template/pods/README.md +64 -0
- package/template/pods/academy/README.md +37 -0
- package/template/pods/academy/agents/academy-chief.md +27 -0
- package/template/pods/academy/examples/palestra.example.md +142 -0
- package/template/pods/academy/pod-spec.json +44 -0
- package/template/pods/academy/templates/materiais-tmpl.md +17 -0
- package/template/pods/academy/templates/revisao-didatica-tmpl.md +20 -0
- package/template/pods/academy/workflows/wf-materiais-revisao.yaml +30 -0
- package/template/pods/authority-content/README.md +43 -0
- package/template/pods/authority-content/agents/content-chief.md +28 -0
- package/template/pods/authority-content/pod-spec.json +45 -0
- package/template/pods/authority-content/templates/criacao-na-voz-tmpl.md +17 -0
- package/template/pods/authority-content/templates/red-team-factual-tmpl.md +23 -0
- package/template/pods/authority-content/workflows/wf-criacao-redteam.yaml +30 -0
- package/template/pods/automation/README.md +37 -0
- package/template/pods/automation/agents/langgraph-architect.md +30 -0
- package/template/pods/automation/agents/n8n-architect.md +30 -0
- package/template/pods/automation/examples/README.md +46 -0
- package/template/pods/automation/examples/n8n-content-radar.example.json +380 -0
- package/template/pods/automation/knowledge/langgraph-patterns.md +126 -0
- package/template/pods/automation/knowledge/n8n-patterns.md +131 -0
- package/template/pods/automation/memory/README.md +16 -0
- package/template/pods/automation/memory/learnings.consolidated.md +8 -0
- package/template/pods/automation/memory/learnings.jsonl +0 -0
- package/template/pods/automation/pod-spec.json +109 -0
- package/template/pods/automation/specs/wf-langgraph-build.spec.json +107 -0
- package/template/pods/automation/squad-io.yaml +28 -0
- package/template/pods/automation/templates/lg-build-tmpl.md +17 -0
- package/template/pods/automation/templates/lg-design-tmpl.md +23 -0
- package/template/pods/automation/templates/lg-discover-tmpl.md +20 -0
- package/template/pods/automation/templates/lg-handoff-tmpl.md +20 -0
- package/template/pods/automation/templates/lg-test-tmpl.md +20 -0
- package/template/pods/automation/templates/n8n-build-tmpl.md +14 -0
- package/template/pods/automation/templates/n8n-design-tmpl.md +23 -0
- package/template/pods/automation/templates/n8n-discover-tmpl.md +20 -0
- package/template/pods/automation/templates/n8n-handoff-tmpl.md +20 -0
- package/template/pods/automation/templates/n8n-test-tmpl.md +20 -0
- package/template/pods/automation/workflows/wf-langgraph-build.smoke.json +11 -0
- package/template/pods/automation/workflows/wf-langgraph-build.yaml +64 -0
- package/template/pods/automation/workflows/wf-n8n-build.smoke.json +11 -0
- package/template/pods/automation/workflows/wf-n8n-build.yaml +65 -0
- package/template/pods/content-carousel/README.md +91 -0
- package/template/pods/content-carousel/agents/carousel-builder.md +28 -0
- package/template/pods/content-carousel/agents/carousel-visual.md +24 -0
- package/template/pods/content-carousel/agents/hn-curator.md +74 -0
- package/template/pods/content-carousel/config/heuristic-watcher-rubric.yaml +59 -0
- package/template/pods/content-carousel/knowledge/aquisicao-ancora.md +443 -0
- package/template/pods/content-carousel/knowledge/cta-brief.md +25 -0
- package/template/pods/content-carousel/knowledge/dono.example.yaml +45 -0
- package/template/pods/content-carousel/knowledge/identidade-visual-mascote.md +62 -0
- package/template/pods/content-carousel/knowledge/image-generation.md +62 -0
- package/template/pods/content-carousel/knowledge/selecao-de-ancora.md +60 -0
- package/template/pods/content-carousel/knowledge/slides-html.md +56 -0
- package/template/pods/content-carousel/memory/README.md +18 -0
- package/template/pods/content-carousel/memory/learnings.consolidated.md +6 -0
- package/template/pods/content-carousel/memory/learnings.jsonl +0 -0
- package/template/pods/content-carousel/pod-spec.json +100 -0
- package/template/pods/content-carousel/squad-io.yaml +10 -0
- package/template/pods/content-carousel/templates/assembly-tmpl.md +23 -0
- package/template/pods/content-carousel/templates/digest-tmpl.md +29 -0
- package/template/pods/content-carousel/templates/visuals-tmpl.md +20 -0
- package/template/pods/content-carousel/workflows/wf-content-carousel.smoke.json +23 -0
- package/template/pods/content-carousel/workflows/wf-content-carousel.yaml +80 -0
- package/template/pods/dev-ia/README.md +45 -0
- package/template/pods/dev-ia/agents/db-architect.md +33 -0
- package/template/pods/dev-ia/agents/ux-architect.md +29 -0
- package/template/pods/dev-ia/knowledge/db/migration-protocol.md +95 -0
- package/template/pods/dev-ia/knowledge/db/rls-patterns.md +101 -0
- package/template/pods/dev-ia/knowledge/db/schema-review-checklist.md +76 -0
- package/template/pods/dev-ia/memory/README.md +16 -0
- package/template/pods/dev-ia/memory/learnings.consolidated.md +8 -0
- package/template/pods/dev-ia/memory/learnings.jsonl +0 -0
- package/template/pods/dev-ia/pod-spec.json +34 -0
- package/template/pods/dev-ia/templates/schema-review-tmpl.md +23 -0
- package/template/pods/dev-ia/templates/ux-flow-review-tmpl.md +23 -0
- package/template/pods/dev-ia/tools/db-ops/backup-manager.sh +321 -0
- package/template/pods/dev-ia/tools/db-ops/best-practices-auditor.sh +534 -0
- package/template/pods/dev-ia/tools/db-ops/bootstrap-runner.sh +255 -0
- package/template/pods/dev-ia/tools/db-ops/data-loader.sh +616 -0
- package/template/pods/dev-ia/tools/db-ops/detect-database.sh +113 -0
- package/template/pods/dev-ia/tools/db-ops/explain-analyzer.sh +285 -0
- package/template/pods/dev-ia/tools/db-ops/health-checker.sh +323 -0
- package/template/pods/dev-ia/tools/db-ops/migration-runner.sh +308 -0
- package/template/pods/dev-ia/tools/db-ops/postgresql-schema-loader.sh +334 -0
- package/template/pods/dev-ia/tools/db-ops/query-runner.sh +171 -0
- package/template/pods/dev-ia/tools/db-ops/rls-policy-installer.sh +480 -0
- package/template/pods/dev-ia/tools/db-ops/rls-test-suite.sh +172 -0
- package/template/pods/dev-ia/tools/db-ops/schema-context-loader.sh +176 -0
- package/template/pods/hormozi-method/README.md +52 -0
- package/template/pods/hormozi-method/agents/acquisition-strategist.md +33 -0
- package/template/pods/hormozi-method/agents/conversion-copywriter.md +34 -0
- package/template/pods/hormozi-method/agents/monetization-architect.md +35 -0
- package/template/pods/hormozi-method/agents/offer-engineer.md +37 -0
- package/template/pods/hormozi-method/knowledge/core-four-leads.md +51 -0
- package/template/pods/hormozi-method/knowledge/grand-slam-offer.md +66 -0
- package/template/pods/hormozi-method/knowledge/growth-decision.md +38 -0
- package/template/pods/hormozi-method/knowledge/hooks-and-ads.md +56 -0
- package/template/pods/hormozi-method/knowledge/launch-email.md +31 -0
- package/template/pods/hormozi-method/knowledge/money-model.md +46 -0
- package/template/pods/hormozi-method/knowledge/opportunity-screening.md +44 -0
- package/template/pods/hormozi-method/knowledge/pages.md +25 -0
- package/template/pods/hormozi-method/knowledge/pos-lancamento-leads.md +56 -0
- package/template/pods/hormozi-method/knowledge/pricing.md +36 -0
- package/template/pods/hormozi-method/knowledge/retention-ltv.md +37 -0
- package/template/pods/hormozi-method/knowledge/scale-roadmap.md +35 -0
- package/template/pods/hormozi-method/knowledge/swipefiles-curados.md +44 -0
- package/template/pods/hormozi-method/knowledge/value-equation-diagnostic.md +77 -0
- package/template/pods/hormozi-method/memory/README.md +16 -0
- package/template/pods/hormozi-method/memory/learnings.consolidated.md +6 -0
- package/template/pods/hormozi-method/memory/learnings.jsonl +0 -0
- package/template/pods/hormozi-method/pod-spec.json +50 -0
- package/template/pods/hormozi-method/specs/wf-full-launch-sequence.spec.json +149 -0
- package/template/pods/hormozi-method/specs/wf-lead-magnet-pipeline.spec.json +125 -0
- package/template/pods/hormozi-method/specs/wf-money-model-design.spec.json +117 -0
- package/template/pods/hormozi-method/specs/wf-paid-ads-campaign.spec.json +132 -0
- package/template/pods/hormozi-method/specs/wf-scaling-diagnostic.spec.json +121 -0
- package/template/pods/hormozi-method/squad-io.yaml +43 -0
- package/template/pods/hormozi-method/templates/conversion-copywriter-tmpl.md +20 -0
- package/template/pods/hormozi-method/templates/launch-execucao-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/launch-fechamento-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/launch-pos-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/launch-preparacao-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/lm-copy-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/lm-distribuicao-tmpl.md +18 -0
- package/template/pods/hormozi-method/templates/lm-estrategia-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/mm-arquitetura-tmpl.md +18 -0
- package/template/pods/hormozi-method/templates/mm-copy-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/mm-diagnostico-tmpl.md +14 -0
- package/template/pods/hormozi-method/templates/monetization-architect-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/offer-engineer-tmpl.md +20 -0
- package/template/pods/hormozi-method/templates/paid-criativos-tmpl.md +19 -0
- package/template/pods/hormozi-method/templates/paid-fundacao-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/paid-teste-escala-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/scaling-diagnostico-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/scaling-priorizacao-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/scaling-roadmap-tmpl.md +17 -0
- package/template/pods/hormozi-method/workflows/wf-full-launch-sequence.smoke.json +12 -0
- package/template/pods/hormozi-method/workflows/wf-full-launch-sequence.yaml +56 -0
- package/template/pods/hormozi-method/workflows/wf-grand-slam-offer.smoke.json +11 -0
- package/template/pods/hormozi-method/workflows/wf-grand-slam-offer.yaml +45 -0
- package/template/pods/hormozi-method/workflows/wf-lead-magnet-pipeline.smoke.json +9 -0
- package/template/pods/hormozi-method/workflows/wf-lead-magnet-pipeline.yaml +45 -0
- package/template/pods/hormozi-method/workflows/wf-money-model-design.smoke.json +11 -0
- package/template/pods/hormozi-method/workflows/wf-money-model-design.yaml +45 -0
- package/template/pods/hormozi-method/workflows/wf-paid-ads-campaign.smoke.json +9 -0
- package/template/pods/hormozi-method/workflows/wf-paid-ads-campaign.yaml +46 -0
- package/template/pods/hormozi-method/workflows/wf-scaling-diagnostic.smoke.json +11 -0
- package/template/pods/hormozi-method/workflows/wf-scaling-diagnostic.yaml +44 -0
- package/template/pods/squad-forge/README.md +53 -0
- package/template/pods/squad-forge/agents/forge-chief.md +31 -0
- package/template/pods/squad-forge/agents/mind-extractor.md +29 -0
- package/template/pods/squad-forge/agents/pod-critic.md +26 -0
- package/template/pods/squad-forge/config/heuristic-watcher-rubric.yaml +74 -0
- package/template/pods/squad-forge/knowledge/fidelity-rubric.yaml +176 -0
- package/template/pods/squad-forge/knowledge/g6-memory-check.md +17 -0
- package/template/pods/squad-forge/knowledge/memory-ingest.md +16 -0
- package/template/pods/squad-forge/knowledge/source-audit-rubric.yaml +60 -0
- package/template/pods/squad-forge/memory/README.md +16 -0
- package/template/pods/squad-forge/memory/learnings.consolidated.md +8 -0
- package/template/pods/squad-forge/memory/learnings.jsonl +0 -0
- package/template/pods/squad-forge/pod-spec.json +166 -0
- package/template/pods/squad-forge/squad-io.yaml +13 -0
- package/template/pods/squad-forge/tasks/pipeline.md +158 -0
- package/template/pods/squad-forge/templates/discovery-tmpl.md +40 -0
- package/template/pods/squad-forge/templates/generation-tmpl.md +18 -0
- package/template/pods/squad-forge/templates/red-team-tmpl.md +17 -0
- package/template/pods/squad-forge/templates/register-tmpl.md +17 -0
- package/template/pods/squad-forge/templates/workflow-tmpl.yaml +101 -0
- package/template/pods/squad-forge/workflows/wf-forge.smoke.json +12 -0
- 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 };
|