@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,220 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
/**
|
|
4
|
+
* validate-no-clone.cjs — lint DETERMINÍSTICO da regra 3 (clonagem), classe
|
|
5
|
+
* TOKEN-DETECTÁVEL (Decisão E.1 do design *migrate-squad; SF3.3 P0.5).
|
|
6
|
+
*
|
|
7
|
+
* A regra 3 do ledger: métodos de figuras públicas migram COM fonte citada;
|
|
8
|
+
* clones/marcas do ecossistema anterior NÃO migram. Este lint cobre a classe que
|
|
9
|
+
* um token detecta — o RESIDUAL (persona parafraseada SEM token: tom/1ª pessoa/
|
|
10
|
+
* bordões copiados com o nome removido) é dívida DECLARADA e fica com o gate
|
|
11
|
+
* adversarial do pod-critic (dimensão anti-persona do G6, E.2). O lint NÃO
|
|
12
|
+
* pretende "resolver a regra 3 por máquina" — esse foi o overclaim da v1.
|
|
13
|
+
*
|
|
14
|
+
* Denylist (E.1.1) SEM lista mágica — derivada do squad-fonte quando dado:
|
|
15
|
+
* - `source_mind` do squad-io.yaml legado (+ sobrenome/token ≥5 chars);
|
|
16
|
+
* - nome do squad;
|
|
17
|
+
* - prefixos dos agentes legados (agents/<prefixo>-*.md);
|
|
18
|
+
* - + FORBIDDEN_TERMS de validate-branding.js (fonte única, importada).
|
|
19
|
+
*
|
|
20
|
+
* Regras de FAIL:
|
|
21
|
+
* 1. IDENTIDADE (E.1.2) — token na denylist em filename, `name:`/`description:`
|
|
22
|
+
* de frontmatter, ou nome de step/agent (spec/wf). Nunca excusável por citação.
|
|
23
|
+
* 2. PERSONA com token (E.1.3) — `você é <mind>`, `encarne <mind>`,
|
|
24
|
+
* `persona de <mind>`, `atue como <mind>`, assinatura em 1ª pessoa (`— <mind>`).
|
|
25
|
+
* Assunção de persona é FAIL mesmo com citação (citar ≠ encarnar).
|
|
26
|
+
* 3. TOKEN em prosa SEM citação — token da denylist numa linha sem marcador de
|
|
27
|
+
* fonte (`> Fonte:`, `[SOURCE:`, `Fonte:`). Citação é PERMITIDA e OBRIGATÓRIA.
|
|
28
|
+
* 4. KNOWLEDGE sem `Fonte:` (E.1.4) — todo arquivo passado via --knowledge deve
|
|
29
|
+
* ter ≥1 linha de fonte citada; sem ela → FAIL.
|
|
30
|
+
*
|
|
31
|
+
* CLI:
|
|
32
|
+
* node scripts/validate-no-clone.cjs <path...> [--squad-source <legacyDir>] [--knowledge <dir>]...
|
|
33
|
+
* Exit 0 = limpo; exit 1 = listando arquivo:linha de cada violação.
|
|
34
|
+
*
|
|
35
|
+
* Integrado ao gate junto com validate-budgets.js/validate-branding.js
|
|
36
|
+
* (npm run validate). Node >= 18, sem dependências externas.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const fs = require('node:fs');
|
|
40
|
+
const path = require('node:path');
|
|
41
|
+
const { FORBIDDEN_TERMS } = require('./validate-branding.js');
|
|
42
|
+
|
|
43
|
+
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
44
|
+
const CITATION_MARKERS = [/>\s*Fonte:/i, /\[SOURCE:/i, /\bFonte:/i];
|
|
45
|
+
const PERSONA_VERBS = ['você é', 'voce e', 'encarne', 'persona de', 'atue como', 'incorpore o mind', 'assuma a persona'];
|
|
46
|
+
|
|
47
|
+
function isProbablyBinary(buf) {
|
|
48
|
+
return buf.subarray(0, 8000).includes(0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function collectFiles(target) {
|
|
52
|
+
const full = path.isAbsolute(target) ? target : path.join(REPO_ROOT, target);
|
|
53
|
+
if (!fs.existsSync(full)) return [];
|
|
54
|
+
if (fs.statSync(full).isFile()) return [full];
|
|
55
|
+
const out = [];
|
|
56
|
+
const stack = [full];
|
|
57
|
+
while (stack.length) {
|
|
58
|
+
const dir = stack.pop();
|
|
59
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
60
|
+
const p = path.join(dir, entry.name);
|
|
61
|
+
if (entry.isDirectory()) stack.push(p);
|
|
62
|
+
else if (entry.isFile()) out.push(p);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return out.sort();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Deriva a denylist do squad-fonte (E.1.1) — sem lista mágica. */
|
|
69
|
+
function deriveDenylist(squadSource) {
|
|
70
|
+
const terms = new Set(FORBIDDEN_TERMS.map((t) => t.toLowerCase()));
|
|
71
|
+
if (!squadSource) return terms;
|
|
72
|
+
const abs = path.isAbsolute(squadSource) ? squadSource : path.join(REPO_ROOT, squadSource);
|
|
73
|
+
// source_mind + squad name do squad-io.yaml.
|
|
74
|
+
const ioPath = path.join(abs, 'squad-io.yaml');
|
|
75
|
+
if (fs.existsSync(ioPath)) {
|
|
76
|
+
const io = fs.readFileSync(ioPath, 'utf8');
|
|
77
|
+
const mind = io.match(/^\s*source_mind:\s*["']?([^"'\n]+)["']?/m);
|
|
78
|
+
if (mind) {
|
|
79
|
+
const phrase = mind[1].trim().toLowerCase();
|
|
80
|
+
terms.add(phrase);
|
|
81
|
+
for (const w of phrase.split(/\s+/)) if (w.length >= 5) terms.add(w);
|
|
82
|
+
}
|
|
83
|
+
const sq = io.match(/^\s*squad:\s*["']?([^"'\n]+)["']?/m);
|
|
84
|
+
if (sq) terms.add(sq[1].trim().toLowerCase());
|
|
85
|
+
}
|
|
86
|
+
// prefixos dos agentes legados: agents/<prefixo>-*.md.
|
|
87
|
+
const agentsDir = path.join(abs, 'agents');
|
|
88
|
+
if (fs.existsSync(agentsDir)) {
|
|
89
|
+
for (const f of fs.readdirSync(agentsDir)) {
|
|
90
|
+
if (!f.endsWith('.md')) continue;
|
|
91
|
+
const base = f.replace(/\.md$/, '');
|
|
92
|
+
const prefix = base.includes('-') ? base.slice(0, base.indexOf('-')) : base;
|
|
93
|
+
if (prefix.length >= 4) terms.add(prefix.toLowerCase());
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// nome do diretório do squad como fallback de nome.
|
|
97
|
+
terms.add(path.basename(abs).toLowerCase());
|
|
98
|
+
return terms;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function hasCitation(line) {
|
|
102
|
+
return CITATION_MARKERS.some((re) => re.test(line));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function tokenIn(text, terms) {
|
|
106
|
+
const lower = text.toLowerCase();
|
|
107
|
+
for (const t of terms) if (t && lower.includes(t)) return t;
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function frontmatter(content) {
|
|
112
|
+
const m = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
113
|
+
return m ? m[1] : '';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Varre UM arquivo pelas regras 1-3. Retorna [{ line, rule, term, text }]. */
|
|
117
|
+
function scanClone(filePath, terms) {
|
|
118
|
+
const buf = fs.readFileSync(filePath);
|
|
119
|
+
if (isProbablyBinary(buf)) return [];
|
|
120
|
+
const content = buf.toString('utf8');
|
|
121
|
+
const violations = [];
|
|
122
|
+
const base = path.basename(filePath);
|
|
123
|
+
|
|
124
|
+
// Regra 1 — IDENTIDADE: filename.
|
|
125
|
+
const fnTerm = tokenIn(base, terms);
|
|
126
|
+
if (fnTerm) violations.push({ line: 0, rule: 'identidade/filename', term: fnTerm, text: base });
|
|
127
|
+
|
|
128
|
+
// Regra 1 — IDENTIDADE: name:/description: do frontmatter.
|
|
129
|
+
const fm = frontmatter(content);
|
|
130
|
+
for (const key of ['name', 'description']) {
|
|
131
|
+
const kv = fm.match(new RegExp(`^\\s*${key}:\\s*(.+)$`, 'm'));
|
|
132
|
+
if (kv) {
|
|
133
|
+
const t = tokenIn(kv[1], terms);
|
|
134
|
+
if (t) violations.push({ line: 0, rule: `identidade/${key}`, term: t, text: kv[1].trim().slice(0, 80) });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const lines = content.split(/\r?\n/);
|
|
139
|
+
lines.forEach((line, idx) => {
|
|
140
|
+
const lower = line.toLowerCase();
|
|
141
|
+
const term = tokenIn(line, terms);
|
|
142
|
+
// Regra 2 — PERSONA com token (FAIL mesmo com citação).
|
|
143
|
+
const verb = PERSONA_VERBS.find((v) => lower.includes(v));
|
|
144
|
+
if (verb && term) {
|
|
145
|
+
violations.push({ line: idx + 1, rule: 'persona', term, text: line.trim().slice(0, 80) });
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
// assinatura em 1ª pessoa: linha `— <mind>` / `- <mind>` no fim.
|
|
149
|
+
if (term && /^\s*[—-]\s*/.test(line) && lower.trim().replace(/^[—-]\s*/, '').startsWith(term)) {
|
|
150
|
+
violations.push({ line: idx + 1, rule: 'persona/assinatura', term, text: line.trim().slice(0, 80) });
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
// Regra 3 — token em prosa SEM citação.
|
|
154
|
+
if (term && !hasCitation(line)) {
|
|
155
|
+
violations.push({ line: idx + 1, rule: 'token-sem-fonte', term, text: line.trim().slice(0, 80) });
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return violations;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Regra 4 — KNOWLEDGE sem `Fonte:`. */
|
|
162
|
+
function scanKnowledge(filePath) {
|
|
163
|
+
const buf = fs.readFileSync(filePath);
|
|
164
|
+
if (isProbablyBinary(buf)) return [];
|
|
165
|
+
const content = buf.toString('utf8');
|
|
166
|
+
if (!/^\s*(>?\s*)?\[?(SOURCE|Fonte):/im.test(content)) {
|
|
167
|
+
return [{ line: 0, rule: 'knowledge-sem-fonte', term: '(fonte)', text: path.basename(filePath) }];
|
|
168
|
+
}
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function parseArgs(argv) {
|
|
173
|
+
const targets = [];
|
|
174
|
+
const knowledge = [];
|
|
175
|
+
let squadSource = null;
|
|
176
|
+
for (let i = 0; i < argv.length; i++) {
|
|
177
|
+
const a = argv[i];
|
|
178
|
+
if (a === '--squad-source') squadSource = argv[++i];
|
|
179
|
+
else if (a === '--knowledge') knowledge.push(argv[++i]);
|
|
180
|
+
else targets.push(a);
|
|
181
|
+
}
|
|
182
|
+
return { targets, knowledge, squadSource };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function run(argv) {
|
|
186
|
+
const { targets, knowledge, squadSource } = parseArgs(argv);
|
|
187
|
+
const terms = deriveDenylist(squadSource);
|
|
188
|
+
const violations = [];
|
|
189
|
+
for (const target of targets) {
|
|
190
|
+
for (const file of collectFiles(target)) {
|
|
191
|
+
for (const v of scanClone(file, terms)) violations.push({ file, ...v });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
for (const kdir of knowledge) {
|
|
195
|
+
for (const file of collectFiles(kdir)) {
|
|
196
|
+
if (!file.endsWith('.md')) continue;
|
|
197
|
+
for (const v of scanKnowledge(file)) violations.push({ file, ...v });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return { violations, denylistSize: terms.size };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function main() {
|
|
204
|
+
const { violations } = run(process.argv.slice(2));
|
|
205
|
+
if (violations.length) {
|
|
206
|
+
for (const v of violations) {
|
|
207
|
+
const rel = path.relative(REPO_ROOT, v.file);
|
|
208
|
+
const loc = v.line ? `${rel}:${v.line}` : rel;
|
|
209
|
+
console.error(`${loc}: [${v.rule}] token "${v.term}" — ${v.text}`);
|
|
210
|
+
}
|
|
211
|
+
console.error(`\n${violations.length} violação(ões) da regra 3 (classe token-detectável). Gate vermelho.`);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
console.log('Regra 3 (token-detectável): limpo.');
|
|
215
|
+
process.exit(0);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
module.exports = { run, deriveDenylist, scanClone, scanKnowledge, hasCitation };
|
|
219
|
+
|
|
220
|
+
if (require.main === module) main();
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
/**
|
|
4
|
+
* validate-no-clone.test.cjs — suíte PRÓPRIA do lint da regra 3 (Story SF3.3, AC5).
|
|
5
|
+
* Prova a classe TOKEN-DETECTÁVEL (E.1) com fixture positiva E negativa; o residual
|
|
6
|
+
* (persona parafraseada sem token) NÃO é testado aqui — é dívida declarada do G6.
|
|
7
|
+
* Cobre:
|
|
8
|
+
* - denylist derivada do squad-fonte (source_mind + prefixo de agente + squad name).
|
|
9
|
+
* - FAIL identidade (filename + name:) no estilo hormozi-*.
|
|
10
|
+
* - FAIL persona com token ("você é Alex Hormozi", "encarne").
|
|
11
|
+
* - PASS agente capability-based com `> Fonte:`.
|
|
12
|
+
* - FAIL/PASS knowledge (sem/com `Fonte:`).
|
|
13
|
+
* - gate default (só FORBIDDEN_TERMS) sobre template/ → limpo.
|
|
14
|
+
*
|
|
15
|
+
* Node >= 18. Exit 0/1.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const path = require('node:path');
|
|
19
|
+
const v = require('./validate-no-clone.cjs');
|
|
20
|
+
|
|
21
|
+
const FIX = path.join(__dirname, '__fixtures__', 'migrate-squad');
|
|
22
|
+
const LEGACY = path.join(FIX, 'legacy-squad');
|
|
23
|
+
const AUTH = path.join(FIX, 'authored');
|
|
24
|
+
|
|
25
|
+
let passed = 0;
|
|
26
|
+
const failures = [];
|
|
27
|
+
function ok(cond, label) {
|
|
28
|
+
if (cond) { passed++; console.log(`[OK ] ${label}`); }
|
|
29
|
+
else { failures.push(label); console.log(`[FALHA] ${label}`); }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// denylist derivada do squad-fonte.
|
|
33
|
+
{
|
|
34
|
+
const terms = v.deriveDenylist(LEGACY);
|
|
35
|
+
ok(terms.has('alex hormozi') && terms.has('hormozi'), 'denylist deriva source_mind (frase + sobrenome ≥5) do squad-io.yaml');
|
|
36
|
+
ok(terms.has('aiox'), 'denylist inclui FORBIDDEN_TERMS de validate-branding (fonte única)');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// FAIL — agente legado hormozi-offer.md: identidade + persona com token.
|
|
40
|
+
{
|
|
41
|
+
const { violations } = v.run([path.join(LEGACY, 'agents', 'hormozi-offer.md'), '--squad-source', LEGACY]);
|
|
42
|
+
const rules = new Set(violations.map((x) => x.rule));
|
|
43
|
+
ok(rules.has('identidade/filename'), 'FAIL identidade: filename hormozi-*.md (nome de marca)');
|
|
44
|
+
ok(rules.has('identidade/name'), 'FAIL identidade: name: hormozi-* no frontmatter');
|
|
45
|
+
ok([...rules].some((r) => r.startsWith('persona')), 'FAIL persona: "você é Alex Hormozi"/"encarne" com token');
|
|
46
|
+
ok(violations.length >= 3, 'FAIL agente legado acumula ≥3 violações');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// PASS — agente capability-based com citação obrigatória (> Fonte:).
|
|
50
|
+
{
|
|
51
|
+
const { violations } = v.run([path.join(AUTH, 'agents', 'offer-engineer.md'), '--squad-source', LEGACY]);
|
|
52
|
+
ok(violations.length === 0, 'PASS offer-engineer.md (metodologia com `> Fonte: $100M Offers`, sem persona)');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Knowledge — regra 4.
|
|
56
|
+
{
|
|
57
|
+
const bad = v.run(['--knowledge', path.join(AUTH, 'knowledge', 'no-source.md')]);
|
|
58
|
+
ok(bad.violations.length === 1 && bad.violations[0].rule === 'knowledge-sem-fonte', 'FAIL knowledge sem `Fonte:`');
|
|
59
|
+
const good = v.run(['--knowledge', path.join(AUTH, 'knowledge', 'value-stack-method.md')]);
|
|
60
|
+
ok(good.violations.length === 0, 'PASS knowledge COM `Fonte:` citada');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Citação PERMITE mencionar o mind em prosa; persona ainda REPROVA mesmo citando.
|
|
64
|
+
{
|
|
65
|
+
ok(v.hasCitation('> Fonte: método público de Alex Hormozi'), 'citação `> Fonte:` reconhecida como marcador válido');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Gate default (sem --squad-source): só FORBIDDEN_TERMS; template/ limpo.
|
|
69
|
+
{
|
|
70
|
+
const { violations, denylistSize } = v.run([path.join(__dirname, '..', 'template')]);
|
|
71
|
+
ok(denylistSize >= 5, 'gate default usa denylist = FORBIDDEN_TERMS (sem lista mágica extra)');
|
|
72
|
+
ok(violations.length === 0, 'gate default sobre template/ → limpo (integração npm run validate)');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log(`\n${passed} verificações OK, ${failures.length} falha(s).`);
|
|
76
|
+
if (failures.length) { for (const f of failures) console.error(` - ${f}`); process.exit(1); }
|
|
77
|
+
process.exit(0);
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
/**
|
|
4
|
+
* validate-pipeline.cjs — validador ESTÁTICO do contrato cross-pod `pipeline-<id>.yaml`
|
|
5
|
+
* (Story SF9.1/ADR-017 Decisão 1). Script NOVO, distinto de validate-pod-workflow.cjs (o
|
|
6
|
+
* validador intra-pod é consumido pelos 7 pods; misturar lógica cross-pod ali os arriscaria).
|
|
7
|
+
*
|
|
8
|
+
* Prova, SEM EXECUTAR NADA, que um pipeline está BEM-FORMADO:
|
|
9
|
+
* 1. Schema — topo {id, deliverable, phases[]}; fase {id, pod, workflow, outputs≥1};
|
|
10
|
+
* inputs?/gate? opcionais; ids de fase únicos.
|
|
11
|
+
* 2. Referências — cada pod/workflow existe em disco (<pods-root>/<pod>/workflows/<wf>.yaml).
|
|
12
|
+
* 3. Sequencial — inputs de uma fase referenciam SÓ outputs de uma fase ANTERIOR de fato
|
|
13
|
+
* declarada (nunca fase futura/self/ inexistente) — sem ciclo por construção.
|
|
14
|
+
* 4. Portão — gate.veto[] reduz às formas de VETO_TYPES (reusa o vocabulário intra-pod,
|
|
15
|
+
* incl. command_check blessed); gate.checkpoint{criteria} bem-formado.
|
|
16
|
+
*
|
|
17
|
+
* Uso: node scripts/validate-pipeline.cjs <pipeline.yaml> [...] [--pods-root <dir>]
|
|
18
|
+
* Exit 0 = contrato bem-formado; exit != 0 = primeira violação nomeada. Node >= 18, zero-dep.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const fs = require('node:fs');
|
|
22
|
+
const path = require('node:path');
|
|
23
|
+
const {
|
|
24
|
+
parseYaml, VETO_TYPES, checkCommandCheckSafety, checkJsonSchemaExtract, Fail,
|
|
25
|
+
} = require('./validate-pod-workflow.cjs');
|
|
26
|
+
|
|
27
|
+
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
28
|
+
function fail(msg) { throw new Fail(msg); }
|
|
29
|
+
function isMap(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }
|
|
30
|
+
|
|
31
|
+
/** Valida a forma de UMA asserção de veto do portão (reusa o vocabulário intra-pod). */
|
|
32
|
+
function checkGateAssertion(a, where) {
|
|
33
|
+
if (!isMap(a)) fail(`${where}: asserção de portão é prosa/valor livre, não asserção estruturada (formas: ${Object.keys(VETO_TYPES).join(', ')})`);
|
|
34
|
+
if (typeof a.type !== 'string' || !(a.type in VETO_TYPES)) {
|
|
35
|
+
fail(`${where}: type de portão inválido ("${a.type}") — não redutível a asserção de máquina (formas: ${Object.keys(VETO_TYPES).join(', ')})`);
|
|
36
|
+
}
|
|
37
|
+
for (const req of VETO_TYPES[a.type]) {
|
|
38
|
+
if (!(req in a) || a[req] === null || a[req] === '') fail(`${where}: asserção (type=${a.type}) sem campo obrigatório "${req}"`);
|
|
39
|
+
}
|
|
40
|
+
if (a.type === 'field_matches') {
|
|
41
|
+
try { new RegExp(String(a.pattern)); } catch (e) { fail(`${where}: field_matches com regex inválida: ${e.message}`); }
|
|
42
|
+
}
|
|
43
|
+
if (a.type === 'command_check') { try { checkCommandCheckSafety(a); } catch (e) { fail(`${where}: ${e.message}`); } }
|
|
44
|
+
if (a.type === 'json_schema_valid') { try { checkJsonSchemaExtract(a); } catch (e) { fail(`${where}: ${e.message}`); } }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function podsRootFor(override) {
|
|
48
|
+
if (override) return path.resolve(override);
|
|
49
|
+
return path.join(REPO_ROOT, 'pods');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function validatePipeline(pipelinePath, podsRootOverride) {
|
|
53
|
+
let doc;
|
|
54
|
+
try { doc = parseYaml(fs.readFileSync(pipelinePath, 'utf8')); }
|
|
55
|
+
catch (e) { fail(`YAML malformado: ${e.message}`); }
|
|
56
|
+
|
|
57
|
+
// 1. Schema de topo.
|
|
58
|
+
if (!isMap(doc)) fail('raiz do pipeline não é um mapa YAML');
|
|
59
|
+
if (typeof doc.id !== 'string' || doc.id.trim() === '') fail('campo obrigatório ausente/vazio: id');
|
|
60
|
+
if (typeof doc.deliverable !== 'string' || doc.deliverable.trim() === '') fail('campo obrigatório ausente/vazio: deliverable');
|
|
61
|
+
if (!Array.isArray(doc.phases) || doc.phases.length === 0) fail('campo obrigatório ausente/vazio: phases[] (lista não-vazia)');
|
|
62
|
+
|
|
63
|
+
const podsRoot = podsRootFor(podsRootOverride);
|
|
64
|
+
const seenPhaseIds = new Set();
|
|
65
|
+
const outputsByPhase = new Map(); // phaseId -> Set(outputName), na ORDEM (só as anteriores contam)
|
|
66
|
+
|
|
67
|
+
doc.phases.forEach((ph, i) => {
|
|
68
|
+
const at = `phases[${i}]`;
|
|
69
|
+
if (!isMap(ph)) fail(`${at} não é um mapa`);
|
|
70
|
+
for (const req of ['id', 'pod', 'workflow']) {
|
|
71
|
+
if (typeof ph[req] !== 'string' || ph[req].trim() === '') fail(`${at}: campo obrigatório ausente/vazio: ${req}`);
|
|
72
|
+
}
|
|
73
|
+
if (seenPhaseIds.has(ph.id)) fail(`${at}: id de fase duplicado "${ph.id}"`);
|
|
74
|
+
// outputs: mapa não-vazio, paths RELATIVOS ao runDir (sem absoluto/traversal).
|
|
75
|
+
if (!isMap(ph.outputs) || Object.keys(ph.outputs).length === 0) fail(`fase "${ph.id}": outputs ausente ou vazio (mapa nome→path relativo ao runDir, ≥1)`);
|
|
76
|
+
for (const [name, rel] of Object.entries(ph.outputs)) {
|
|
77
|
+
if (typeof rel !== 'string' || rel.trim() === '') fail(`fase "${ph.id}": output "${name}" com path vazio`);
|
|
78
|
+
if (path.isAbsolute(rel) || rel.split(/[\\/]/).includes('..')) fail(`fase "${ph.id}": output "${name}" deve ser path RELATIVO ao runDir, sem traversal ("${rel}")`);
|
|
79
|
+
}
|
|
80
|
+
// 2. pod/workflow existem em disco.
|
|
81
|
+
const wfPath = path.join(podsRoot, ph.pod, 'workflows', `${ph.workflow}.yaml`);
|
|
82
|
+
if (!fs.existsSync(wfPath)) fail(`fase "${ph.id}": pod/workflow inexistente em disco — ${path.relative(REPO_ROOT, wfPath)}`);
|
|
83
|
+
// 3. inputs referenciam SÓ output de fase ANTERIOR declarada.
|
|
84
|
+
if ('inputs' in ph && ph.inputs != null) {
|
|
85
|
+
if (!isMap(ph.inputs)) fail(`fase "${ph.id}": inputs deve ser um mapa {local: "<- fase.output"}`);
|
|
86
|
+
for (const [local, refRaw] of Object.entries(ph.inputs)) {
|
|
87
|
+
if (typeof refRaw !== 'string') fail(`fase "${ph.id}": input "${local}" deve ser string "<- fase.output"`);
|
|
88
|
+
const ref = refRaw.replace(/^\s*<-\s*/, '').trim();
|
|
89
|
+
const dot = ref.indexOf('.');
|
|
90
|
+
if (dot <= 0) fail(`fase "${ph.id}": input "${local}" mal-formado ("${refRaw}") — esperado "<- <fase-anterior>.<output>"`);
|
|
91
|
+
const srcPhase = ref.slice(0, dot);
|
|
92
|
+
const srcOut = ref.slice(dot + 1);
|
|
93
|
+
if (srcPhase === ph.id) fail(`fase "${ph.id}": input "${local}" referencia a PRÓPRIA fase (ciclo)`);
|
|
94
|
+
if (!outputsByPhase.has(srcPhase)) fail(`fase "${ph.id}": input "${local}" referencia fase "${srcPhase}" não declarada ANTES desta (fase futura/inexistente — pipeline é sequencial puro)`);
|
|
95
|
+
if (!outputsByPhase.get(srcPhase).has(srcOut)) fail(`fase "${ph.id}": input "${local}" referencia output "${srcOut}" inexistente na fase "${srcPhase}"`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// 4. gate opcional.
|
|
99
|
+
if ('gate' in ph && ph.gate != null) {
|
|
100
|
+
const g = ph.gate;
|
|
101
|
+
if (!isMap(g)) fail(`fase "${ph.id}": gate deve ser um mapa {veto?, checkpoint?}`);
|
|
102
|
+
const hasVeto = Array.isArray(g.veto) && g.veto.length > 0;
|
|
103
|
+
const hasCp = g.checkpoint != null;
|
|
104
|
+
if (!hasVeto && !hasCp) fail(`fase "${ph.id}": gate presente mas vazio (declare veto[] e/ou checkpoint)`);
|
|
105
|
+
if ('veto' in g && g.veto != null) {
|
|
106
|
+
if (!Array.isArray(g.veto)) fail(`fase "${ph.id}": gate.veto deve ser um array de asserções`);
|
|
107
|
+
g.veto.forEach((a, ai) => checkGateAssertion(a, `fase "${ph.id}" gate.veto[${ai}]`));
|
|
108
|
+
}
|
|
109
|
+
if (hasCp) {
|
|
110
|
+
if (!isMap(g.checkpoint) || typeof g.checkpoint.criteria !== 'string' || g.checkpoint.criteria.trim() === '') {
|
|
111
|
+
fail(`fase "${ph.id}": gate.checkpoint deve ser {criteria: "<texto>"} não-vazio`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
seenPhaseIds.add(ph.id);
|
|
116
|
+
outputsByPhase.set(ph.id, new Set(Object.keys(ph.outputs)));
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function main() {
|
|
121
|
+
const args = process.argv.slice(2);
|
|
122
|
+
let podsRoot = null;
|
|
123
|
+
const targets = [];
|
|
124
|
+
for (let i = 0; i < args.length; i++) {
|
|
125
|
+
if (args[i] === '--pods-root') podsRoot = args[++i];
|
|
126
|
+
else targets.push(args[i]);
|
|
127
|
+
}
|
|
128
|
+
if (targets.length === 0) {
|
|
129
|
+
console.error('Uso: node scripts/validate-pipeline.cjs <pipeline.yaml> [...] [--pods-root <dir>]');
|
|
130
|
+
process.exit(2);
|
|
131
|
+
}
|
|
132
|
+
let ok = 0;
|
|
133
|
+
for (const t of targets) {
|
|
134
|
+
const rel = path.relative(REPO_ROOT, path.resolve(t));
|
|
135
|
+
if (!fs.existsSync(t)) { console.error(`[FALHA] ${rel}: arquivo não encontrado`); process.exit(1); }
|
|
136
|
+
try { validatePipeline(t, podsRoot); console.log(`[OK ] ${rel}`); ok++; }
|
|
137
|
+
catch (e) { if (e instanceof Fail) { console.error(`[FALHA] ${rel}: ${e.message}`); process.exit(1); } throw e; }
|
|
138
|
+
}
|
|
139
|
+
console.log(`\n${ok} pipeline(s) validado(s). Contrato bem-formado.`);
|
|
140
|
+
process.exit(0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (require.main === module) main();
|
|
144
|
+
|
|
145
|
+
module.exports = { validatePipeline, checkGateAssertion, Fail };
|