@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,502 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* POWER CLAUDE — PreToolUse hook: a trava de `Ready` (story SF13.2, `ADR-032`).
|
|
6
|
+
*
|
|
7
|
+
* O que ele faz: interrompe a transição `Draft`→`Ready` de uma story sempre
|
|
8
|
+
* que o conteúdo resultante da escrita contiver um dos 5 defeitos de forma
|
|
9
|
+
* DECIDÍVEIS SEM EXECUTAR NADA — e fica em silêncio absoluto em qualquer
|
|
10
|
+
* outro caso.
|
|
11
|
+
*
|
|
12
|
+
* A propriedade central (`ADR-032`, `DF-SF13.2-1`): **este hook é PURO**.
|
|
13
|
+
* Zero subprocesso, zero execução de oráculo — ele só consulta as funções
|
|
14
|
+
* puras já expostas por `scripts/validate-story-acs.cjs`. Executar os 47
|
|
15
|
+
* oráculos de uma story custa 1,23 s no caminho quente de TODA escrita de
|
|
16
|
+
* arquivo e herdaria a superfície de execução de texto de terceiro (a ameaça
|
|
17
|
+
* T2 do `ADR-011`); o passe puro custa 49 ms para as 85 stories do repo.
|
|
18
|
+
* Por isso nenhuma linha aqui spawna processo: a pureza não é performance,
|
|
19
|
+
* é fronteira de segurança.
|
|
20
|
+
*
|
|
21
|
+
* Limiar (`DF-SF13.2-3`, `D-Dono-1`): a única decisão que este hook emite é
|
|
22
|
+
* `ask`. Ele NUNCA nega — nenhuma classe hoje é "positivamente conhecida e
|
|
23
|
+
* positivamente errada" (medido: 7 falsos positivos em 7 da família
|
|
24
|
+
* `[Guarda]` contra a própria `sf13.1.story.md`). A negativa é estrutural,
|
|
25
|
+
* não disciplinar: o literal da decisão negativa não existe neste arquivo.
|
|
26
|
+
*
|
|
27
|
+
* Os 8 predicados (zero falso positivo medido sobre as stories reais):
|
|
28
|
+
* P1 — fence órfã: nº de blocos `oraculo` na seção `## Acceptance Criteria`
|
|
29
|
+
* MAIOR que o nº de ACs a que o parser os atribuiu (o parser está cego).
|
|
30
|
+
* P2 — `[Guarda] (...)` que não casa nenhuma das 3 formas reconhecidas.
|
|
31
|
+
* P3 — `[Guarda] (prova: AC-N)` apontando para um AC que não existe.
|
|
32
|
+
* P4 — `# espera:` presente e não reconhecido.
|
|
33
|
+
* P5 — fence `oraculo` declarada e vazia.
|
|
34
|
+
* P6 — oráculo que o validador recusaria (cabeçalho fora da allow-list,
|
|
35
|
+
* metacaractere de shell, subcomando `git` fora da sub-allow-list).
|
|
36
|
+
* P7 — `[Guarda] (sem irmão)` sem asserção de AUSÊNCIA no oráculo.
|
|
37
|
+
* P8 — contagem ingênua (`grep -c` sem `-w`/`-x`/âncora) sob `exit0`.
|
|
38
|
+
*
|
|
39
|
+
* A leitura *"a família `[Guarda]` (P2/P3/P7) fica FORA por falso positivo
|
|
40
|
+
* medido (7 em 7 contra `sf13.1.story.md`)"* está SUPERADA — não repetir. A
|
|
41
|
+
* causa-raiz daqueles 7 era `parseGuarda` não distinguir CITAÇÃO de USO, e foi
|
|
42
|
+
* consertada na SF13.7; a SF13.9 remediu o corpus real ANTES de ligar os 3
|
|
43
|
+
* (zero disparo), com controle positivo de alcançabilidade. O que NÃO mudou:
|
|
44
|
+
* os 3 entram na mesma escada de 2 degraus, `ask`-only — promover qualquer um
|
|
45
|
+
* a `deny` continua exigindo `D-Dono-2` completo, que não está pago.
|
|
46
|
+
*
|
|
47
|
+
* Fonte única, sem cópia (`ADR-031` Emenda 10 através de uma fronteira de
|
|
48
|
+
* arquivo): NENHUM predicado é reimplementado aqui. A simulação da edição
|
|
49
|
+
* vem do hook irmão `enforce-cycle-authority.cjs`; a análise dos ACs vem de
|
|
50
|
+
* `scripts/validate-story-acs.cjs`. Duas implementações paralelas divergem.
|
|
51
|
+
*
|
|
52
|
+
* Raiz do repositório: ancorada em `path.resolve(__dirname, '..', '..')`
|
|
53
|
+
* (Emenda 1 do `ADR-032`). NUNCA `input.cwd`/`process.cwd()` — `resolveGitDir`
|
|
54
|
+
* do hook irmão NÃO sobe diretórios (ele testa só `<cwd>/.git`), e derivar o
|
|
55
|
+
* path de um `require` de dado de ENTRADA abriria exatamente a superfície que
|
|
56
|
+
* este desenho fecha por não abrir.
|
|
57
|
+
*
|
|
58
|
+
* Loaders PREGUIÇOSOS e GUARDADOS (Emenda 2 do `ADR-032`, item 4): nenhum
|
|
59
|
+
* `require` de irmão/validador no topo do módulo. Um `require` top-level de
|
|
60
|
+
* arquivo ausente lançaria ANTES de `runWithFailSafe` existir — o processo
|
|
61
|
+
* morreria mudo e a ferramenta passaria. Zero decisão emitida é o pior
|
|
62
|
+
* desfecho possível deste desenho (fail-open silencioso).
|
|
63
|
+
*
|
|
64
|
+
* Ordem normativa em `main()`/`runMain()` (Emenda 2, item 3):
|
|
65
|
+
* silêncio cedo (`tool_name`, `file_path`) → `loadCycleAuthority()` →
|
|
66
|
+
* transição `Draft`→`Ready` → `loadValidator()` → predicados → orçamento →
|
|
67
|
+
* emissão. O loader do irmão vem ANTES do detector de transição: se a
|
|
68
|
+
* falha do loader virasse `false` dentro do detector, o resultado seria
|
|
69
|
+
* silêncio — indistinguível de "não é a transição". O caminho de
|
|
70
|
+
* degradação não pode se parecer com o caminho feliz.
|
|
71
|
+
*
|
|
72
|
+
* As 5 rotas de degradação (`DF-SF13.2-4` + Emenda 2, item 1) — todas FALAM,
|
|
73
|
+
* nenhuma lança, nenhuma nega: exceção em qualquer ponto; irmão ausente;
|
|
74
|
+
* validador ausente; orçamento interno (2000 ms) estourado; JSON de entrada
|
|
75
|
+
* ilegível (fail-closed proporcional: `ask` só se o texto bruto aparentar
|
|
76
|
+
* `Status`/`Ready`, senão silêncio).
|
|
77
|
+
*
|
|
78
|
+
* Alcance declarado: `Edit`/`Write` sobre `*.story.md`. A cobertura real é
|
|
79
|
+
* função da adoção da convenção ` ```oraculo ` pelo PRODUTOR de stories —
|
|
80
|
+
* hoje ~2,4% (2 de 85). Quem quiser cobertura maior mexe no produtor, não
|
|
81
|
+
* aqui (`DF-SF13.2-6`).
|
|
82
|
+
*
|
|
83
|
+
* Circuito de destravamento: docs/mecanismos/hooks-de-autoridade-do-ciclo.md
|
|
84
|
+
* §Destravamento.
|
|
85
|
+
*
|
|
86
|
+
* Sem dependências externas (roda em qualquer instalação limpa).
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
const fs = require('fs');
|
|
90
|
+
const path = require('path');
|
|
91
|
+
|
|
92
|
+
const BUDGET_MS = 2000;
|
|
93
|
+
const MECANISMO_DOC = 'docs/mecanismos/hooks-de-autoridade-do-ciclo.md';
|
|
94
|
+
const DESTRAVAMENTO = `Se isto é um falso positivo, veja ${MECANISMO_DOC} §Destravamento.`;
|
|
95
|
+
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// I/O do protocolo de hook.
|
|
98
|
+
//
|
|
99
|
+
// `readStdin`/`parseHookInput` são locais de propósito, e isso NÃO contradiz
|
|
100
|
+
// a regra de fonte única: a leitura do payload acontece ANTES de qualquer
|
|
101
|
+
// loader (é o que decide se há sequer um `input` para trabalhar), então não
|
|
102
|
+
// pode depender do hook irmão — que pode estar ausente (5ª rota).
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
function readStdin() {
|
|
106
|
+
try {
|
|
107
|
+
return fs.readFileSync(0, 'utf8');
|
|
108
|
+
} catch {
|
|
109
|
+
return '';
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function parseHookInput(rawInput) {
|
|
114
|
+
try {
|
|
115
|
+
const parsed = JSON.parse(rawInput || '{}');
|
|
116
|
+
return parsed && typeof parsed === 'object' ? parsed : null;
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function emitDecision(permissionDecision, permissionDecisionReason) {
|
|
123
|
+
process.stdout.write(JSON.stringify({
|
|
124
|
+
hookSpecificOutput: {
|
|
125
|
+
hookEventName: 'PreToolUse',
|
|
126
|
+
permissionDecision,
|
|
127
|
+
permissionDecisionReason,
|
|
128
|
+
},
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Raiz e loaders guardados.
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
// O hook vive sempre em `<raiz>/.claude/hooks/` numa instalação. Aritmética
|
|
137
|
+
// de path pura: não consulta disco, não consulta `input` — logo não tem modo
|
|
138
|
+
// de falha (Emenda 2, item 2: a rota "raiz não resolvível" é INALCANÇÁVEL).
|
|
139
|
+
function resolveRepoRoot() {
|
|
140
|
+
return path.resolve(__dirname, '..', '..');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Superfície de export do irmão de que ESTE hook depende. Checada na carga,
|
|
144
|
+
// não presumida: uma instalação em SKEW (`ADR-019` — template atualizado num
|
|
145
|
+
// lado só) carrega o módulo sem erro e devolve `undefined` no ponto de uso,
|
|
146
|
+
// e um `undefined(...)` no meio do detector viraria exceção genérica ou, pior,
|
|
147
|
+
// `false` — indistinguível de "não é a transição". O caminho de degradação não
|
|
148
|
+
// pode se parecer com o caminho feliz (`ADR-032` Emenda 2, item 3).
|
|
149
|
+
const REQUIRED_SIBLING_EXPORTS = ['simulateResult', 'extractStatusSection', 'statusToken'];
|
|
150
|
+
|
|
151
|
+
function loadCycleAuthority() {
|
|
152
|
+
const p = path.join(__dirname, 'enforce-cycle-authority.cjs');
|
|
153
|
+
let mod;
|
|
154
|
+
try {
|
|
155
|
+
mod = require(p);
|
|
156
|
+
} catch (err) {
|
|
157
|
+
return { ok: false, error: err, path: p };
|
|
158
|
+
}
|
|
159
|
+
const faltando = REQUIRED_SIBLING_EXPORTS.filter((nome) => !mod || typeof mod[nome] !== 'function');
|
|
160
|
+
if (faltando.length > 0) {
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
skew: true,
|
|
164
|
+
faltando,
|
|
165
|
+
error: new Error(`superfície de export incompleta — faltam: ${faltando.join(', ')}`),
|
|
166
|
+
path: p,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return { ok: true, mod, path: p };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function loadValidator(repoRoot) {
|
|
173
|
+
const p = path.join(repoRoot, 'scripts', 'validate-story-acs.cjs');
|
|
174
|
+
try {
|
|
175
|
+
return { ok: true, mod: require(p), path: p };
|
|
176
|
+
} catch (err) {
|
|
177
|
+
return { ok: false, error: err, path: p };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// Detecção da transição, por SIMULAÇÃO (nunca por leitura do texto do diff).
|
|
183
|
+
//
|
|
184
|
+
// `cycleAuthorityMod` é o módulo JÁ carregado por `runMain()` e passado como
|
|
185
|
+
// argumento — a função é pura em relação ao loader e testável sem ele.
|
|
186
|
+
//
|
|
187
|
+
// Comparação por TOKEN nos DOIS lados (`ADR-032` Emenda 3, `FINDING-8` do gate
|
|
188
|
+
// da SF13.7). A IGUALDADE ESTRITA pós-normalização que estava aqui está
|
|
189
|
+
// SUPERADA — não repetir: ela deixava a trava MUDA sempre que um papel
|
|
190
|
+
// anotava o status (`Ready (validado pelo PO, 10/10)`, `Ready — aguardando
|
|
191
|
+
// dev`), coisa que já aconteceu 4× em `docs/stories/`, por 2 papéis
|
|
192
|
+
// diferentes, no mesmo dia em que a trava nasceu. O silêncio era total: nem
|
|
193
|
+
// `ask`, nem log.
|
|
194
|
+
//
|
|
195
|
+
// Exigir os dois lados continua sendo o que impede a interrupção a cada
|
|
196
|
+
// escrita: `depois === 'ready'` sozinho daria verdadeiro para qualquer edição
|
|
197
|
+
// numa story já `Ready` que nem toca o `## Status`.
|
|
198
|
+
//
|
|
199
|
+
// Escada de 2 DEGRAUS (token ⇒ `ask`; resto ⇒ silêncio), deliberadamente
|
|
200
|
+
// diferente da escada de 3 do P1 do irmão (`ADR-032` E3.10): este sítio só
|
|
201
|
+
// emite `ask`, e com uma severidade só não há para onde descer — um degrau de
|
|
202
|
+
// "menção" faria interromper toda NEGAÇÃO (`Not Ready`, `ainda não está
|
|
203
|
+
// Ready`). Quem "uniformizar" as duas escadas está revertendo essa decisão.
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
|
|
206
|
+
function detectDraftToReady(input, cycleAuthorityMod) {
|
|
207
|
+
if (!cycleAuthorityMod || !cycleAuthorityMod.simulateResult || !cycleAuthorityMod.statusToken) return false;
|
|
208
|
+
const sim = cycleAuthorityMod.simulateResult(input);
|
|
209
|
+
if (!sim) return false;
|
|
210
|
+
const antes = cycleAuthorityMod.statusToken(cycleAuthorityMod.extractStatusSection(sim.before));
|
|
211
|
+
const depois = cycleAuthorityMod.statusToken(cycleAuthorityMod.extractStatusSection(sim.after));
|
|
212
|
+
return antes === 'draft' && depois === 'ready';
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
// Os 5 predicados puros. Toda a análise é delegada ao validador
|
|
217
|
+
// (`extractAcSection`, `parseAcs`, `parseEspera` — via `parseAcs` —,
|
|
218
|
+
// `wouldBeRefused`, `looksLikeNaiveCounting`).
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
// Abertura de fence `oraculo` REAL (CommonMark): início de linha, nada além
|
|
222
|
+
// de espaço/tab até o fim da linha. Distingue de menção inline em prosa.
|
|
223
|
+
const ORACLE_FENCE_OPEN_RE = /^```oraculo[ \t]*\r?$/gm;
|
|
224
|
+
|
|
225
|
+
function countOracleFences(section) {
|
|
226
|
+
const re = new RegExp(ORACLE_FENCE_OPEN_RE.source, ORACLE_FENCE_OPEN_RE.flags);
|
|
227
|
+
let n = 0;
|
|
228
|
+
while (re.exec(section)) n += 1;
|
|
229
|
+
return n;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// P1 — fence órfã. Comparação de contagem ESTRUTURAL, não heurística de
|
|
233
|
+
// texto: se a seção declara N blocos e o parser atribuiu M < N a ACs, o
|
|
234
|
+
// parser está cego. `fences === 0` é silêncio declarado, fora do alcance
|
|
235
|
+
// (83 de 85 stories, `DF-SF13.2-6`) — não é aprovação, é ausência de matéria.
|
|
236
|
+
function evaluateFenceOrfa(content, validatorMod) {
|
|
237
|
+
const section = validatorMod.extractAcSection(content);
|
|
238
|
+
if (!section) return null;
|
|
239
|
+
const fences = countOracleFences(section);
|
|
240
|
+
if (fences === 0) return null;
|
|
241
|
+
const atribuidas = validatorMod.parseAcs(content).filter((ac) => ac.hasOraculo).length;
|
|
242
|
+
if (fences <= atribuidas) return null;
|
|
243
|
+
return {
|
|
244
|
+
predicate: 'P1',
|
|
245
|
+
id: null,
|
|
246
|
+
detail: `a seção "## Acceptance Criteria" declara ${fences} bloco(s) \`oraculo\` e o parser atribuiu apenas ${atribuidas} a um AC — o parser está cego para ao menos um. Causas conhecidas: cabeçalho fora da convenção \`**AC-N.**\`, heading de seção divergente, ou AC dentro de lista numerada.`,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// P2/P3/P7 (família `[Guarda]`) + P4/P5/P6/P8 — por AC.
|
|
251
|
+
//
|
|
252
|
+
// A família `[Guarda]` ficou FORA da v1 por falso positivo MEDIDO (7 em 7
|
|
253
|
+
// contra `sf13.1.story.md`), cuja causa-raiz era `parseGuarda` não distinguir
|
|
254
|
+
// CITAÇÃO de USO. A causa foi consertada na SF13.7, e o pré-requisito para
|
|
255
|
+
// ligar os 3 aqui foi medido ANTES do wiring (SF13.9, AC-15): zero disparo de
|
|
256
|
+
// P2/P3/P7 sobre as stories reais de `docs/stories/`, com controle positivo de
|
|
257
|
+
// que as 3 formas de fato disparam quando aplicadas de verdade.
|
|
258
|
+
//
|
|
259
|
+
// Nenhuma lógica de `parseGuarda` é reimplementada aqui — só a LEITURA de
|
|
260
|
+
// `ac.guarda.forma`/`ac.guarda.provaId`, já produzidos por `parseAcs`, no
|
|
261
|
+
// mesmo padrão em que P4/P5/P6/P8 leem `ac.espera`/`ac.oracleCmd`.
|
|
262
|
+
//
|
|
263
|
+
// Os 3 entram na MESMA escada de 2 degraus dos outros 5 — sempre `ask`, nunca
|
|
264
|
+
// `deny` (`DF-SF13.2-3`). Promover qualquer um exige `D-Dono-2` COMPLETO (10
|
|
265
|
+
// transições reais registradas E o conserto de `parseGuarda`); só a segunda
|
|
266
|
+
// condição foi paga.
|
|
267
|
+
function evaluatePerAcPredicates(content, validatorMod) {
|
|
268
|
+
const acs = validatorMod.parseAcs(content);
|
|
269
|
+
const acIds = new Set(acs.map((ac) => ac.id));
|
|
270
|
+
const hits = [];
|
|
271
|
+
for (const ac of acs) {
|
|
272
|
+
// ANTES do `continue` de `!hasOraculo`, de propósito: um AC pode ter
|
|
273
|
+
// `[Guarda]` malformado E não ter oráculo nenhum, e é justamente esse o
|
|
274
|
+
// caso mais grave (nada prova nada). Se este bloco viesse depois do
|
|
275
|
+
// `continue`, P2/P3 ficariam cegos para ele em silêncio.
|
|
276
|
+
if (ac.guarda) {
|
|
277
|
+
if (ac.guarda.forma === 'desconhecida') {
|
|
278
|
+
hits.push({
|
|
279
|
+
predicate: 'P2',
|
|
280
|
+
id: ac.id,
|
|
281
|
+
detail: `a etiqueta \`[Guarda] (${ac.guarda.raw})\` não casa nenhuma das 3 formas reconhecidas — o guarda não classifica, logo não vale como declaração. Formas válidas: \`(prova: AC-N)\`, \`(sem irmão — ...)\`, \`(citação de fato pré-existente, ...)\`.`,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
if (ac.guarda.forma === 'prova' && !acIds.has(ac.guarda.provaId)) {
|
|
285
|
+
hits.push({
|
|
286
|
+
predicate: 'P3',
|
|
287
|
+
id: ac.id,
|
|
288
|
+
detail: `o guarda aponta para \`${ac.guarda.provaId}\` como o AC que prova a mudança, e esse AC NÃO existe nesta story — o par declarado não fecha, e o controle fica sem prova pareada.`,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
if (ac.guarda.forma === 'sem-irmao') {
|
|
292
|
+
const tipo = ac.espera && ac.espera.type;
|
|
293
|
+
const isAusencia = tipo === 'stdout-vazio' || (tipo === 'stdout==' && String(ac.espera.value).trim() === '0');
|
|
294
|
+
if (!isAusencia) {
|
|
295
|
+
hits.push({
|
|
296
|
+
predicate: 'P7',
|
|
297
|
+
id: ac.id,
|
|
298
|
+
detail: `o guarda declara "sem irmão" (ausência), mas a asserção do oráculo (\`${tipo || 'exit0'}\`) não é de AUSÊNCIA — só \`stdout-vazio\` ou \`stdout == 0\` sustentam "não existe"; um \`exit0\` qualquer passa sem provar a ausência que o guarda promete.`,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (!ac.hasOraculo) continue;
|
|
305
|
+
|
|
306
|
+
if (ac.oracleEmpty) {
|
|
307
|
+
hits.push({
|
|
308
|
+
predicate: 'P5',
|
|
309
|
+
id: ac.id,
|
|
310
|
+
detail: 'fence `oraculo` declarada e VAZIA — nenhum comando dentro do bloco, logo o AC não tem oráculo nenhum apesar de aparentar ter.',
|
|
311
|
+
});
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (ac.espera && ac.espera.type === 'desconhecida') {
|
|
316
|
+
hits.push({
|
|
317
|
+
predicate: 'P4',
|
|
318
|
+
id: ac.id,
|
|
319
|
+
detail: `"# espera: ${ac.espera.raw}" não é uma forma reconhecida — o validador cairia no default \`exit0\` e o AC não provaria o que o texto promete. Formas válidas: exit0, exit!=0, stdout-vazio, stdout-nao-vazio, stdout== <valor>.`,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const recusa = validatorMod.wouldBeRefused(ac.oracleCmd);
|
|
324
|
+
if (recusa && recusa.refused) {
|
|
325
|
+
hits.push({
|
|
326
|
+
predicate: 'P6',
|
|
327
|
+
id: ac.id,
|
|
328
|
+
detail: `o oráculo seria RECUSADO pelo validador (${recusa.reason}) — um AC recusado nunca vira prova.`,
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const sobExit0 = !ac.espera || ac.espera.type === 'exit0';
|
|
333
|
+
if (sobExit0 && validatorMod.looksLikeNaiveCounting(ac.oracleCmd)) {
|
|
334
|
+
hits.push({
|
|
335
|
+
predicate: 'P8',
|
|
336
|
+
id: ac.id,
|
|
337
|
+
detail: '`grep -c` sem `-w`/`-x`/âncora sob `# espera: exit0` imprime `0` e sai com código 0 mesmo quando não acha nada — pode ser no-op. (Hedge do instrumento reproduzido literalmente: ele diz "pode ser", e este hook não afirma mais que ele.)',
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return hits;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function evaluateReadyOracles(content, validatorMod) {
|
|
345
|
+
const hits = [];
|
|
346
|
+
const orfa = evaluateFenceOrfa(content, validatorMod);
|
|
347
|
+
if (orfa) hits.push(orfa);
|
|
348
|
+
for (const hit of evaluatePerAcPredicates(content, validatorMod)) hits.push(hit);
|
|
349
|
+
return hits;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ---------------------------------------------------------------------------
|
|
353
|
+
// Orçamento e fail-safe.
|
|
354
|
+
// ---------------------------------------------------------------------------
|
|
355
|
+
|
|
356
|
+
// Pura: recebe os dois instantes, nunca espera nem consulta relógio.
|
|
357
|
+
function budgetExceeded(startedAtMs, nowMs) {
|
|
358
|
+
return Number(nowMs) - Number(startedAtMs) > BUDGET_MS;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function runWithFailSafe(fn) {
|
|
362
|
+
try {
|
|
363
|
+
return fn();
|
|
364
|
+
} catch (err) {
|
|
365
|
+
emitDecision('ask', `O hook lançou uma exceção (${err && err.message}) — aprovação humana necessária, nunca falha silenciosa. ${DESTRAVAMENTO}`);
|
|
366
|
+
return undefined;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// ---------------------------------------------------------------------------
|
|
371
|
+
// Mensagem de interrupção.
|
|
372
|
+
// ---------------------------------------------------------------------------
|
|
373
|
+
|
|
374
|
+
function buildHitsMessage(filePath, hits) {
|
|
375
|
+
const linhas = hits.map((h) => ` - ${h.predicate}${h.id ? ` (${h.id})` : ''}: ${h.detail}`).join('\n');
|
|
376
|
+
return [
|
|
377
|
+
`A trava de Ready encontrou ${hits.length} defeito(s) de forma nos oráculos de "${filePath}", decidíveis sem executar nada:`,
|
|
378
|
+
linhas,
|
|
379
|
+
'A transição Draft→Ready foi INTERROMPIDA para você responder — nada foi bloqueado: aprove se o achado for falso positivo, ou corrija a story antes.',
|
|
380
|
+
`Detalhe completo: node scripts/validate-story-acs.cjs "${filePath}". ${DESTRAVAMENTO}`,
|
|
381
|
+
].join('\n');
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// ---------------------------------------------------------------------------
|
|
385
|
+
// Núcleo testável. `opts.now` e `opts.evaluateReadyOracles` são injeção de
|
|
386
|
+
// dependência com default REAL (`Date.now`, `evaluateReadyOracles`) — existem
|
|
387
|
+
// para permitir teste determinístico sem espera real, não são backdoor: em
|
|
388
|
+
// produção `main()` chama `runMain(input)` sem `opts`.
|
|
389
|
+
//
|
|
390
|
+
// `runMain` NÃO tem try/catch próprio, de propósito: quem protege é o
|
|
391
|
+
// `runWithFailSafe` de `main()`. Se ele tivesse a sua própria rede, a rede
|
|
392
|
+
// externa nunca seria exercitada e a rota de exceção viraria letra morta.
|
|
393
|
+
// ---------------------------------------------------------------------------
|
|
394
|
+
|
|
395
|
+
function runMain(input, opts) {
|
|
396
|
+
const options = opts || {};
|
|
397
|
+
const now = options.now || Date.now;
|
|
398
|
+
const startedAtMs = now();
|
|
399
|
+
|
|
400
|
+
// 1. Silêncio o mais cedo possível — o caminho quente é TODA escrita.
|
|
401
|
+
if (!input || (input.tool_name !== 'Edit' && input.tool_name !== 'Write')) return;
|
|
402
|
+
const filePath = input.tool_input && input.tool_input.file_path;
|
|
403
|
+
if (typeof filePath !== 'string' || !/\.story\.md$/i.test(filePath)) return;
|
|
404
|
+
|
|
405
|
+
// 2. Irmão ANTES da transição (Emenda 2, item 3): ignorância sobre a
|
|
406
|
+
// própria dependência é ignorância sobre a story — fala, nunca cala.
|
|
407
|
+
const cycleAuthority = loadCycleAuthority();
|
|
408
|
+
if (!cycleAuthority.ok) {
|
|
409
|
+
const motivo = cycleAuthority.skew
|
|
410
|
+
? `carregou o hook irmão "${cycleAuthority.path}", mas a superfície de export dele está em SKEW — faltam as funções: ${cycleAuthority.faltando.join(', ')} (instalação com os dois hooks em versões diferentes; rode a atualização do motor a partir do framework)`
|
|
411
|
+
: `não conseguiu carregar o hook irmão "${cycleAuthority.path}" (${cycleAuthority.error && cycleAuthority.error.message})`;
|
|
412
|
+
emitDecision(
|
|
413
|
+
'ask',
|
|
414
|
+
`A trava de Ready ${motivo} — sem ele nem dá para decidir se esta escrita é a transição Draft→Ready. Aprovação humana necessária: silêncio aqui seria indistinguível de "não é a transição". ${DESTRAVAMENTO}`,
|
|
415
|
+
);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// 3. Gate por TRANSIÇÃO antes do gate por CONTEÚDO: fora de Draft→Ready o
|
|
420
|
+
// hook não avalia predicado nenhum, nem que a story tenha defeito.
|
|
421
|
+
if (!detectDraftToReady(input, cycleAuthority.mod)) return;
|
|
422
|
+
|
|
423
|
+
// 4. Validador — resolvido a partir do `__dirname` do próprio hook.
|
|
424
|
+
const validator = loadValidator(resolveRepoRoot());
|
|
425
|
+
if (!validator.ok) {
|
|
426
|
+
emitDecision(
|
|
427
|
+
'ask',
|
|
428
|
+
`Transição Draft→Ready detectada em "${filePath}", mas scripts/validate-story-acs.cjs ausente ou não carregável em "${validator.path}" (${validator.error && validator.error.message}) — nada se sabe sobre os oráculos desta story. Conserto: rode a atualização do motor ("adopt" + "update --scope motor") a partir do framework. Aprovação humana necessária. ${DESTRAVAMENTO}`,
|
|
429
|
+
);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// 5. Predicados sobre o conteúdo RESULTANTE da escrita (simulado, sem tocar
|
|
434
|
+
// o disco) — nunca sobre o conteúdo atual do arquivo.
|
|
435
|
+
const simulado = cycleAuthority.mod.simulateResult(input);
|
|
436
|
+
const conteudo = simulado ? simulado.after : '';
|
|
437
|
+
const avaliar = options.evaluateReadyOracles || evaluateReadyOracles;
|
|
438
|
+
const hits = avaliar(conteudo, validator.mod);
|
|
439
|
+
|
|
440
|
+
// 6. Orçamento — checado SEMPRE, mesmo com zero achado, e vence a decisão
|
|
441
|
+
// de silêncio: nunca travar para sempre, nunca liberar em silêncio.
|
|
442
|
+
if (budgetExceeded(startedAtMs, now())) {
|
|
443
|
+
emitDecision(
|
|
444
|
+
'ask',
|
|
445
|
+
`A trava de Ready estourou o orçamento interno de 2000 ms avaliando "${filePath}" — o passe pode ter ficado incompleto, então o veredito de silêncio não é confiável. Aprovação humana necessária. ${DESTRAVAMENTO}`,
|
|
446
|
+
);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// 7. Emissão. Sem achado: silêncio absoluto.
|
|
451
|
+
if (!hits || hits.length === 0) return;
|
|
452
|
+
emitDecision('ask', buildHitsMessage(filePath, hits));
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
function main() {
|
|
456
|
+
runWithFailSafe(() => {
|
|
457
|
+
const rawInput = readStdin();
|
|
458
|
+
const input = parseHookInput(rawInput);
|
|
459
|
+
|
|
460
|
+
if (!input) {
|
|
461
|
+
// Fail-closed proporcional, precedente literal de
|
|
462
|
+
// `enforce-cycle-authority.cjs:261-274`: sem JSON não há story
|
|
463
|
+
// resolvível, mas se o texto bruto aparenta a transição que esta trava
|
|
464
|
+
// guarda, perguntar custa uma tecla e calar custa a garantia.
|
|
465
|
+
const aparentaTransicao = /status/i.test(rawInput) && /ready/i.test(rawInput);
|
|
466
|
+
if (aparentaTransicao) {
|
|
467
|
+
emitDecision(
|
|
468
|
+
'ask',
|
|
469
|
+
`O hook não conseguiu interpretar o input do PreToolUse e o texto bruto aparenta tocar Status/Ready. Aprovação humana necessária. ${DESTRAVAMENTO}`,
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
runMain(input);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (require.main === module) {
|
|
480
|
+
main();
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
module.exports = {
|
|
484
|
+
BUDGET_MS,
|
|
485
|
+
REQUIRED_SIBLING_EXPORTS,
|
|
486
|
+
readStdin,
|
|
487
|
+
parseHookInput,
|
|
488
|
+
emitDecision,
|
|
489
|
+
resolveRepoRoot,
|
|
490
|
+
loadCycleAuthority,
|
|
491
|
+
loadValidator,
|
|
492
|
+
detectDraftToReady,
|
|
493
|
+
countOracleFences,
|
|
494
|
+
evaluateFenceOrfa,
|
|
495
|
+
evaluatePerAcPredicates,
|
|
496
|
+
evaluateReadyOracles,
|
|
497
|
+
budgetExceeded,
|
|
498
|
+
runWithFailSafe,
|
|
499
|
+
buildHitsMessage,
|
|
500
|
+
runMain,
|
|
501
|
+
main,
|
|
502
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Matriz de Autoridade — Ciclo de Desenvolvimento
|
|
2
|
+
|
|
3
|
+
Regra global do ambiente POWER CLAUDE. Separação de papéis é o mecanismo central de qualidade: cada transição de estado de uma story tem um dono exclusivo, e ninguém revisa o próprio trabalho.
|
|
4
|
+
|
|
5
|
+
## Matriz de papéis
|
|
6
|
+
|
|
7
|
+
| Papel | Autoridade exclusiva | Proibido |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| **PO** (valida) | Veredito GO/NO-GO da story (Draft → Ready); correções mecânicas do draft | Implementar; mudar escopo/ACs materialmente; aprovar implementação |
|
|
10
|
+
| **Dev** (implementa) | Código, testes, commits locais; Status Ready → InProgress → InReview | `git push`; setar Done; validar a própria story; editar QA Results |
|
|
11
|
+
| **QA** (aprova) | Veredito do gate (PASS/CONCERNS/FAIL/WAIVED); **único que seta Done**; seção QA Results | Implementar correções; revisar código que ele mesmo escreveu |
|
|
12
|
+
| **DevOps** (publica) | **Único que faz `git push` / `gh pr create` / `gh pr merge`** | Force-push (proibido para TODOS, inclusive devops — bloqueado por hook) |
|
|
13
|
+
| **Planner** (planeja) | SPEC, epics e drafts de story (fase Plan) | Validar o próprio draft (→ PO); implementar; mudar story Done |
|
|
14
|
+
| **Analyst** (explora) | Brief, research, benchmark, brainstorming (fase Explore) | Escrever SPEC/PRD (→ Planner); decidir arquitetura (→ Architect) |
|
|
15
|
+
| **Architect** (decide) | Classificação de complexidade; decisões de stack/arquitetura com ADR; revisão de arquitetura pré-dev | Implementar; aprovar a própria arquitetura no QA gate |
|
|
16
|
+
|
|
17
|
+
Enforcement determinístico: `.claude/hooks/enforce-git-push-authority.cjs` nega force-push para qualquer agente e exige aprovação humana para push/PR de quem não é devops; `.claude/hooks/enforce-cycle-authority.cjs` mecaniza as 2 garantias de autoridade do ciclo que não podem depender só de disciplina — **só QA marca `Status: Done`** e **só QA escreve `docs/qa/gates/*.yaml`** (predicados 1/2), e **Dev não edita código enquanto a story associada está `Draft`** (predicado 3). Ver `docs/mecanismos/hooks-de-autoridade-do-ciclo.md`.
|
|
18
|
+
|
|
19
|
+
**Fronteira real de `enforce-git-push-authority.cjs` (D6/D7, story SF12.3, fix rounds F3/F5):** este hook é **guard-rail contra erro, não barreira contra evasão deliberada**. Ele pega a forma direta de `git`/`gh` em qualquer sintaxe (flags combinadas, opções globais, comandos encadeados) e **alias em AMBOS os branches** — alias de `git` (`git config alias.<nome>`, inclusive já configurado no repositório, resolvido por consulta a `git config`) e alias NATIVO de `gh` (`gh alias set`, inclusive já configurado, resolvido por consulta a `gh alias list`) — os 2 mecanismos foram simetrizados no fix round F5, depois de o F3 ter coberto só o `git`. Ele **não pega** indireção por `sh -c`/`bash -c`/`eval`/`npm run`/`node -e`/scripts externos (ex.: `./deploy.sh`) que por sua vez rodem git/gh — qualquer uma dessas contorna o hook por desenho, decisão do dono: perseguir essas variantes não converge e não é o problema que este guard-rail resolve.
|
|
20
|
+
|
|
21
|
+
## Roster de status da story — este arquivo é a FONTE DA VERDADE
|
|
22
|
+
|
|
23
|
+
O conjunto de status do ciclo é **fechado** e mora aqui. Quem muda o processo edita **este arquivo primeiro**; toda outra ocorrência (comentário de código, AC de story, asserção de teste) é **cópia** e deve derivar daqui, nunca ser a autoridade.
|
|
24
|
+
|
|
25
|
+
<!-- roster:status -->
|
|
26
|
+
`Draft` · `Ready` · `InProgress` · `InReview` · `Done`
|
|
27
|
+
|
|
28
|
+
| Status | Quem transiciona para ele | Quando |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `Draft` | Planner | Story recém-escrita, ainda não validada |
|
|
31
|
+
| `Ready` | **PO** (exclusivo) | Veredito GO da validação do draft |
|
|
32
|
+
| `InProgress` | Dev | Dev começa a implementar — **e a cada `FAIL` do gate**, quando a story volta para o loop de fix (duas rotas de entrada) |
|
|
33
|
+
| `InReview` | Dev | Implementação concluída, entregue ao gate |
|
|
34
|
+
| `Done` | **QA** (exclusivo) | Veredito do gate não-FAIL, com gate file em `docs/qa/gates/` |
|
|
35
|
+
|
|
36
|
+
**Negação explícita — leitura SUPERADA, não repetir:** a enumeração `{draft, ready, inreview, done, blocked}`, publicada em `ADR-032` (`E3.2`/`E3.12`) e copiada daí para o comentário do hook e para um AC de story, está **errada nos dois sentidos**: omite `InProgress`, que é **mandatório** no ciclo, e inclui `Blocked`, que nenhum documento do framework define como status de story (`ADR-032` Emenda 5, `E5.1`/`E5.3`). O `blocked` do motor de pod/pipeline e o `blocked` do `state.json` de `pc-wave` são **outro namespace** — fase de execução, não lifecycle de story; nunca unificar por semelhança de nome.
|
|
37
|
+
|
|
38
|
+
**Como incluir um status novo:** ele entra **primeiro** nesta seção, com dono de transição definido na tabela acima, e só então as cópias o seguem. Um status que existe só no roster de um teste ou de um ADR é um status sem dono — e um controle que aceita valor que ninguém definiu deixa de detectar o evento que existe para detectar (um status entrar no ciclo sem ninguém decidir).
|
|
39
|
+
|
|
40
|
+
**Mecanismo, não disciplina:** `scripts/__tests__/enforce-cycle-authority.test.cjs` **deriva** o roster da âncora `<!-- roster:status -->` acima e o compara com um literal escrito à mão no próprio teste. Divergência **nos dois sentidos** fica vermelha — inclusive a remoção da âncora. Derivar sem comparar contra literal independente ficaria verde para qualquer documento, inclusive um errado: **derivar sozinho não é tripwire** (`ADR-032` Emenda 5, `E5.5`).
|
|
41
|
+
|
|
42
|
+
**Este teste não viaja para a instalação — qualificação que faltava (`F-3`, gate `SF13.10`, fechada por `SF13.11`).** `scripts/__tests__/` está na lista de exclusão de `installer/motor-scripts.json` (`exclude`), por desenho: o tripwire protege quem EDITA este arquivo (autor do template, dentro deste repositório, via `npm test`), não quem o RECEBE — nada numa instalação altera o roster deste arquivo depois de instalado. **Negação explícita, não repetir:** a leitura anterior ("mecanismo, não disciplina", sem qualificação) deixava a impressão de que a instalação também é guardada; não é — numa instalação de terceiro, este parágrafo descreve um mecanismo que só existe no repositório do framework. **Por que não fazer o teste viajar:** fazê-lo seria recriar uma NOVA cópia hardcoded do roster dentro de `installer/doctor.js` (comparando contra um literal ali) para o `doctor` poder checá-lo — o mesmo anti-padrão (roster copiado 3×, uma errada) que originou a `SF13.9`/`SF13.10`; a correção certa não recria o defeito que veio corrigir. Se uma instalação real precisar desta garantia, a resposta é outra: nada no ciclo de uma instalação edita o roster deste arquivo depois de copiado — só quem publica uma versão nova do framework o faz, e é lá, no repositório do framework, que o tripwire já roda.
|
|
43
|
+
|
|
44
|
+
## Regra anti-self-review
|
|
45
|
+
|
|
46
|
+
1. Quem implementou uma story **não pode** executar o QA gate dela na mesma sessão/contexto.
|
|
47
|
+
2. O revisor **re-executa** os gates (lint, typecheck, test) — nunca aceita o relato do implementador como evidência.
|
|
48
|
+
3. Quem aplica fixes de QA devolve para **re-review**; nunca fecha o próprio fix.
|
|
49
|
+
4. Se só existe um operador humano, a separação vale entre agentes: subagente Dev implementa, subagente QA revisa com contexto limpo.
|
|
50
|
+
|
|
51
|
+
## Fluxo canônico
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
PO valida (GO) → Dev implementa → QA gate → [FAIL? Dev corrige → re-review] → QA seta Done → DevOps publica
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Escalação
|
|
58
|
+
|
|
59
|
+
| Situação | Ação |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Gate FAIL | Dev entra no loop de fix (`pc-apply-qa-fixes`) e devolve para re-review |
|
|
62
|
+
| 3 iterações de fix sem PASS | **PARA. Escala ao humano** com o histórico dos vereditos — nunca afrouxar o gate para fechar |
|
|
63
|
+
| Veredito WAIVED | Só com justificativa registrada no gate file e ciência humana |
|
|
64
|
+
| Conflito de autoridade entre papéis | Escala ao humano; nenhum agente arbitra o próprio limite |
|
|
65
|
+
|
|
66
|
+
## Aplicação a subagentes
|
|
67
|
+
|
|
68
|
+
- Os papéis são encarnados pelos subagentes `pc-analyst`, `pc-planner`, `pc-architect`, `pc-po`, `pc-dev`, `pc-qa` e `pc-devops` (`.claude/agents/`); especialistas de pod (`db-architect`, `ux-architect`) entram por gatilho registrado na story. Spawnar o subagente correto é a forma prática de garantir contexto limpo entre implementação e revisão.
|
|
69
|
+
- A identidade devops é lida pelo hook exclusivamente de `input.agent_type` (payload do `PreToolUse`, o `subagent_type` literal do despacho) — SEM fallback a variáveis de ambiente (`PC_ACTIVE_AGENT`/`CLAUDE_AGENT_NAME`/`CLAUDE_CODE_AGENT` não existem no produto, medido; mantê-las como fonte reabriria a autoproclamação via `.claude/settings.json`). Prefixo inline no comando e env var no processo não conferem autoridade (Bloco M da SF12.3, D1/M-1). Calibração de 3 níveis (D4): `git push`/`gh pr create` liberados para `pc-devops`, sem `ask`; `gh pr merge` continua `ask` para TODO agente, sem exceção; force-push continua `deny` para TODO agente.
|
|
70
|
+
- Sessão principal sem papel declarado opera como generalista: pode orquestrar, mas herda as proibições de todos os papéis (sem Done, sem push, sem self-review).
|
|
71
|
+
|
|
72
|
+
## Invariantes
|
|
73
|
+
|
|
74
|
+
- Nenhuma story chega a Done sem gate file em `docs/qa/gates/{story}.yaml` com veredito não-FAIL.
|
|
75
|
+
- Push é sempre fast-forward, sempre com aprovação humana ou papel devops ativo.
|
|
76
|
+
- Toda decisão autônoma de um papel fica registrada no artefato da story como `[AUTO-DECISION]`.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Curadoria de Conhecimento — Destino de Artefatos ao Fechar Trabalho
|
|
2
|
+
|
|
3
|
+
Regra global do ambiente POWER CLAUDE. Aplica-se sempre que o fechamento de um ciclo, story, épico ou sessão deixa para trás um artefato cujo destino precisa ser decidido — doc de mecanismo, ADR, nota de backlog, fixture, run de evidência, arquivo de scratch. **Palavras do dono, formuladas ao fechar o backlog parqueado do épico `pod-export`:** *"Conhecimento importante deve ser organizado e eternizado, ou mantido no backlog para uso e depois descarte (pós-mecanismo pronto). Conhecimento temporário já utilizado pode virar documentação se for regra ou comportamento importante. Se for apenas lembrete do processo de desenvolvimento, pode ser excluído se já foi resolvido. Lixo deve ser descartado, conhecimento válido deve ser documentado."*
|
|
4
|
+
|
|
5
|
+
## Os 4 destinos
|
|
6
|
+
|
|
7
|
+
| Classe do artefato | Destino | Gatilho de saída do destino |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| Conhecimento importante e duradouro | **Documentar/eternizar** (doc de mecanismo, ADR, story) | Nenhum — é permanente por natureza |
|
|
10
|
+
| Conhecimento importante mas transitório (ainda serve de insumo a um mecanismo em construção) | **Backlog**, mantido para uso | O mecanismo fica pronto **e** a regra/comportamento vira documentação — só então o artefato bruto vira descartável |
|
|
11
|
+
| Conhecimento temporário já utilizado, que registra regra ou comportamento importante | **Vira documentação** (o comportamento sobrevive; o rastro bruto não precisa) | — |
|
|
12
|
+
| Conhecimento temporário já utilizado, que é só lembrete de processo já resolvido | **Excluído** | Já disparou — o processo foi resolvido |
|
|
13
|
+
| Lixo (não é nenhuma das classes acima) | **Descartado** | Já disparou |
|
|
14
|
+
|
|
15
|
+
## Regra central
|
|
16
|
+
|
|
17
|
+
Ao decidir o que fazer com um artefato ao fechar trabalho, pergunte nesta ordem:
|
|
18
|
+
|
|
19
|
+
1. **É regra ou comportamento que vai continuar valendo?** → documente/eternize (destino 1). Não fica pendurado em backlog nem em disco solto — vira página de mecanismo, ADR ou seção de story.
|
|
20
|
+
2. **É válido mas só serve de insumo enquanto um mecanismo específico ainda está em construção?** → backlog (destino 2), com o gatilho de saída **nomeado e datável** (não "algum dia"): o mecanismo ficar pronto E as regras que ele revela virarem documentação. O descarte é **consequência de a documentação existir**, não do tempo passar.
|
|
21
|
+
3. **Já foi consumido e a única coisa que resta é rastro de processo** (uma prova que já foi transcrita para onde interessa, um comentário de sessão, um arquivo de trabalho intermediário)? → se o processo que ele documentava já foi resolvido, **exclua** (destino 3b). Se o rastro em si é a regra/comportamento (não só a prova de que algo aconteceu), documente primeiro (destino 3a), então exclua o bruto.
|
|
22
|
+
4. **Nenhuma das anteriores?** → é lixo. Descarte (destino 4).
|
|
23
|
+
|
|
24
|
+
**Quem decide:** o papel `pc-planner`, ao curar backlog/SPEC/epic, e a sessão coordenadora, ao fechar o trabalho de um subagente — nunca por omissão silenciosa. Um artefato sem destino decidido não é "resolvido depois", é órfão.
|
|
25
|
+
|
|
26
|
+
## Não confundir com a triagem de ITEM
|
|
27
|
+
|
|
28
|
+
Esta regra decide o destino do **artefato** (o que fica gravado em disco/documentação sobre um achado). É complementar, não sobreposta, à disciplina de **decidir imediatamente o destino de um item de trabalho** (entra no ciclo agora / fica parqueado com gatilho concreto de retorno / nunca) que já existe na prática deste framework — um item entra, é parqueado ou nunca acontece; **isto aqui** responde, para o conhecimento que qualquer um dos três desfechos produziu, se ele é digno de virar documentação permanente, backlog transitório, ou lixo. As duas disciplinas juntas fecham o ciclo completo: nada fica pendurado por esquecimento, nem no nível do item, nem no nível do que ele deixou para trás.
|
|
29
|
+
|
|
30
|
+
Um backlog de itens parqueados com gatilho de retorno nomeado — cada item registrando o quê, a evidência, por que ficou fora e o gatilho que o traz de volta — é a materialização em disco do **destino 2** desta régua: conhecimento importante mas transitório, mantido para uso até o mecanismo que o resolve estar pronto.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Matriz de Modelos por Papel — Modo Desempenho (padrão)
|
|
2
|
+
|
|
3
|
+
Régua de decisão: **profundidade de julgamento por chamada × custo do erro × frequência**. A coordenadora aplica a matriz via override `model:` (e `effort`) nas chamadas do Agent tool.
|
|
4
|
+
|
|
5
|
+
## Matriz padrão
|
|
6
|
+
|
|
7
|
+
| Papel | Modelo |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Coordenadora (sessão principal) | Modelo de topo disponível |
|
|
10
|
+
| architect | Modelo de topo disponível (chamadas raras, alavancagem máxima) |
|
|
11
|
+
| qa (gate adversarial) | opus |
|
|
12
|
+
| dev | opus |
|
|
13
|
+
| devops / planner / analyst / po | sonnet |
|
|
14
|
+
| Etapas mecânicas (transições de status, commits de docs) | haiku + `effort: low` |
|
|
15
|
+
|
|
16
|
+
## Gatilhos de escalada (um degrau acima)
|
|
17
|
+
|
|
18
|
+
A coordenadora escala o papel envolvido **um degrau** (sonnet → opus; opus → modelo de topo), sem pedir, quando a story toca:
|
|
19
|
+
|
|
20
|
+
- Segurança / autenticação / autorização
|
|
21
|
+
- Migration de dados
|
|
22
|
+
- Dinheiro / cobrança / preço
|
|
23
|
+
- Compliance / dados pessoais
|
|
24
|
+
- Desempate fundamentado entre especialistas divergentes
|
|
25
|
+
|
|
26
|
+
Nunca escalar por padrão — escalada é por gatilho, não por hábito.
|
|
27
|
+
|
|
28
|
+
## Âncora inviolável
|
|
29
|
+
|
|
30
|
+
**O gate adversarial do QA nunca desce de opus** — em nenhum modo, sob nenhuma economia. O funil de detecção permanece na potência integral.
|
|
31
|
+
|
|
32
|
+
## Modo econômico
|
|
33
|
+
|
|
34
|
+
`/power:modo economico` escreve `.claude/rules/economy-mode.md`, que suspende parcialmente esta matriz enquanto existir (`/power:modo desempenho` remove). Esta matriz padrão nunca é editada pelo toggle.
|