stealthos-cli 0.1.0-alpha.2 → 0.1.0-alpha.4

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.
Files changed (178) hide show
  1. package/ai/CONTRACT.md +110 -0
  2. package/ai/INDEX.md +203 -0
  3. package/ai/README.md +434 -0
  4. package/ai/ROUTER.md +288 -0
  5. package/ai/agents/README.md +103 -0
  6. package/ai/agents/architect.md +59 -0
  7. package/ai/agents/backend-engineer.md +62 -0
  8. package/ai/agents/founder.md +45 -0
  9. package/ai/agents/frontend-engineer.md +61 -0
  10. package/ai/agents/product-manager.md +56 -0
  11. package/ai/agents/qa-engineer.md +53 -0
  12. package/ai/agents/researcher.md +74 -0
  13. package/ai/agents/reviewer.md +73 -0
  14. package/ai/agents/security-engineer.md +59 -0
  15. package/ai/agents/sre-engineer.md +70 -0
  16. package/ai/agents/tech-lead.md +70 -0
  17. package/ai/architecture/README.md +35 -0
  18. package/ai/architecture/components.md +24 -0
  19. package/ai/architecture/containers.md +30 -0
  20. package/ai/architecture/event-flows.md +36 -0
  21. package/ai/architecture/sequence-diagrams.md +38 -0
  22. package/ai/architecture/system-context.md +46 -0
  23. package/ai/architecture/threat-modeling.md +40 -0
  24. package/ai/blueprints/README.md +67 -0
  25. package/ai/blueprints/_schema.json +40 -0
  26. package/ai/blueprints/ai-platform.json +28 -0
  27. package/ai/blueprints/crm.json +22 -0
  28. package/ai/blueprints/game.json +25 -0
  29. package/ai/blueprints/mobile.json +24 -0
  30. package/ai/blueprints/realtime.json +22 -0
  31. package/ai/blueprints/saas.json +25 -0
  32. package/ai/blueprints/telemetry.json +30 -0
  33. package/ai/blueprints/web.json +23 -0
  34. package/ai/bootstrap/discovery-questions.md +117 -0
  35. package/ai/bootstrap/dispatcher.md +85 -0
  36. package/ai/bootstrap/existing-project.md +191 -0
  37. package/ai/bootstrap/new-project.md +127 -0
  38. package/ai/bootstrap/tech-mapping.md +164 -0
  39. package/ai/clients/README.md +114 -0
  40. package/ai/clients/antigravity.md +125 -0
  41. package/ai/clients/claude-code.md +65 -0
  42. package/ai/clients/cline.md +69 -0
  43. package/ai/clients/codex-aider-cli.md +82 -0
  44. package/ai/clients/continue.md +67 -0
  45. package/ai/clients/copilot.md +49 -0
  46. package/ai/clients/cursor.md +81 -0
  47. package/ai/clients/snippets/mcp-absolute-paths.json +9 -0
  48. package/ai/clients/snippets/mcp-http.json +7 -0
  49. package/ai/clients/snippets/mcp-stdio.json +9 -0
  50. package/ai/clients/trae.md +69 -0
  51. package/ai/clients/windsurf.md +71 -0
  52. package/ai/core/pipeline/execution-engine.md +157 -0
  53. package/ai/engineering/README.md +32 -0
  54. package/ai/engineering/observability/incident-response.md +82 -0
  55. package/ai/evals/protocol-tests.md +150 -0
  56. package/ai/evolution/agent-evolution.md +161 -0
  57. package/ai/evolution/improvements.md +91 -0
  58. package/ai/evolution/learnings.md +49 -0
  59. package/ai/evolution/patterns-discovered.md +48 -0
  60. package/ai/execution/README.md +33 -0
  61. package/ai/execution/backlog.md +27 -0
  62. package/ai/execution/milestones.md +26 -0
  63. package/ai/execution/roadmap.md +30 -0
  64. package/ai/execution/sprint.md +42 -0
  65. package/ai/governance/README.md +34 -0
  66. package/ai/governance/architecture-principles.md +99 -0
  67. package/ai/governance/definition-of-done.md +88 -0
  68. package/ai/governance/definition-of-ready.md +69 -0
  69. package/ai/governance/engineering-principles.md +70 -0
  70. package/ai/governance/quality-gates.md +85 -0
  71. package/ai/governance/security-policies.md +84 -0
  72. package/ai/hooks/enforce-audit.ps1 +41 -0
  73. package/ai/hooks/enforce-audit.sh +39 -0
  74. package/ai/hooks/guard-edit.ps1 +182 -0
  75. package/ai/hooks/guard-edit.sh +161 -0
  76. package/ai/hooks/inject-os-reminder.ps1 +40 -0
  77. package/ai/hooks/inject-os-reminder.sh +16 -0
  78. package/ai/manifest.json +238 -0
  79. package/ai/memory/_detected-stack.json +33 -0
  80. package/ai/memory/_summary.md +49 -0
  81. package/ai/memory/archive/.gitkeep +3 -0
  82. package/ai/memory/completed-tasks.md +156 -0
  83. package/ai/memory/decisions.md +257 -0
  84. package/ai/memory/errors-and-solutions.md +41 -0
  85. package/ai/memory/known-issues.md +40 -0
  86. package/ai/memory/pending-tasks.md +37 -0
  87. package/ai/memory/project-context.md +67 -0
  88. package/ai/operating-system/architecture.md +54 -0
  89. package/ai/operating-system/coding-standards.md +84 -0
  90. package/ai/operating-system/folder-structure.md +126 -0
  91. package/ai/operating-system/performance-rules.md +86 -0
  92. package/ai/operating-system/quality-control.md +81 -0
  93. package/ai/operating-system/security-rules.md +91 -0
  94. package/ai/operating-system/workflow.md +86 -0
  95. package/ai/product/README.md +24 -0
  96. package/ai/product/business-rules.md +26 -0
  97. package/ai/product/personas.md +29 -0
  98. package/ai/product/user-journeys.md +30 -0
  99. package/ai/product/vision.md +35 -0
  100. package/ai/rules/behavior.md +45 -0
  101. package/ai/rules/do.md +47 -0
  102. package/ai/rules/dont.md +46 -0
  103. package/ai/rules/execution-flow.md +125 -0
  104. package/ai/rules/structural-constraints.md +59 -0
  105. package/ai/rules/structure-canon.md +116 -0
  106. package/ai/runtime.md +179 -0
  107. package/ai/scripts/detect-stack.ps1 +166 -0
  108. package/ai/scripts/detect-stack.sh +172 -0
  109. package/ai/scripts/init-ai-os.ps1 +170 -0
  110. package/ai/scripts/init-ai-os.sh +99 -0
  111. package/ai/scripts/lint-os.ps1 +99 -0
  112. package/ai/scripts/lint-os.sh +85 -0
  113. package/ai/scripts/start-os.ps1 +151 -0
  114. package/ai/scripts/start-os.sh +141 -0
  115. package/ai/server/README.md +105 -0
  116. package/ai/server/aios-server.mjs +2134 -0
  117. package/ai/server/package-lock.json +802 -0
  118. package/ai/server/package.json +31 -0
  119. package/ai/server/src/analyzer/graph-builder.ts +92 -0
  120. package/ai/server/src/analyzer/index.ts +191 -0
  121. package/ai/server/src/analyzer/module-mapper.ts +171 -0
  122. package/ai/server/src/analyzer/smell-detector.ts +54 -0
  123. package/ai/server/src/analyzer/stack-detector.ts +70 -0
  124. package/ai/server/src/index.ts +16 -0
  125. package/ai/server/src/packager/context-builder.ts +217 -0
  126. package/ai/server/src/packager/index.ts +3 -0
  127. package/ai/server/src/packager/memory-injector.ts +128 -0
  128. package/ai/server/src/packager/module-summarizer.ts +60 -0
  129. package/ai/server/src/packager/token-estimator.ts +26 -0
  130. package/ai/server/src/snapshot/index.ts +3 -0
  131. package/ai/server/src/snapshot/snapshot-creator.ts +206 -0
  132. package/ai/server/src/snapshot/snapshot-diff.ts +86 -0
  133. package/ai/server/src/snapshot/snapshot-restore.ts +14 -0
  134. package/ai/server/src/types.ts +94 -0
  135. package/ai/server/tsconfig.json +26 -0
  136. package/ai/skills/architecture-design.md +82 -0
  137. package/ai/skills/backend-engineering.md +57 -0
  138. package/ai/skills/database-design.md +76 -0
  139. package/ai/skills/frontend-engineering.md +63 -0
  140. package/ai/skills/performance.md +73 -0
  141. package/ai/skills/scalability.md +84 -0
  142. package/ai/skills/security.md +71 -0
  143. package/ai/skills/testing.md +77 -0
  144. package/ai/specs/ADR/ADR-0002-typescript-runtime.md +103 -0
  145. package/ai/specs/ADR/ADR-0004-runtime-orchestrator.md +94 -0
  146. package/ai/specs/ADR/ADR-0005-workflow-engine.md +105 -0
  147. package/ai/specs/ADR/ADR-0006-runtime-state.md +104 -0
  148. package/ai/specs/ADR/ADR-0007-state-compiler-drift-context-layers-artifact-index.md +82 -0
  149. package/ai/specs/ADR/ADR-0008-intent-runtime-discovery-branching.md +93 -0
  150. package/ai/specs/ADR/ADR-0009-confidence-system-maturity-tracking.md +113 -0
  151. package/ai/specs/ADR/ADR-0010-structural-architecture-standards.md +121 -0
  152. package/ai/specs/ADR/ADR-0011-mcp-prompts.md +86 -0
  153. package/ai/specs/ADR/ADR-0012-stealthos-hybrid-architecture.md +174 -0
  154. package/ai/specs/ADR/_TEMPLATE.md +60 -0
  155. package/ai/specs/BRD/_TEMPLATE.md +50 -0
  156. package/ai/specs/PRD/_TEMPLATE.md +72 -0
  157. package/ai/specs/README.md +43 -0
  158. package/ai/specs/RFC/RFC-0001-runtime-orchestrator.md +149 -0
  159. package/ai/specs/RFC/RFC-0002-runtime-orchestrator-extended.md +134 -0
  160. package/ai/specs/RFC/_TEMPLATE.md +61 -0
  161. package/ai/specs/RUNBOOKS/_TEMPLATE.md +68 -0
  162. package/ai/specs/SDD/_TEMPLATE.md +104 -0
  163. package/ai/specs/TASKS/_TEMPLATE.md +52 -0
  164. package/ai/tools/debugging.md +64 -0
  165. package/ai/tools/dependency-analysis.md +46 -0
  166. package/ai/tools/internet-research.md +42 -0
  167. package/ai/tools/mcp-discovery.md +44 -0
  168. package/ai/workflows/_schema.json +81 -0
  169. package/ai/workflows/init.json +148 -0
  170. package/ai/workflows/sync.json +71 -0
  171. package/ai/workflows/work.json +91 -0
  172. package/bin.cjs +7 -0
  173. package/package.json +9 -3
  174. package/scripts/bundle-ai.mjs +58 -0
  175. package/src/cli.mjs +1 -1
  176. package/src/commands/install.mjs +35 -11
  177. package/src/lib/resolve-source.mjs +27 -10
  178. package/stealthos +0 -2
@@ -0,0 +1,70 @@
1
+ ---
2
+ version: 1.0.0
3
+ updated: 2026-05-15
4
+ tier: conditional
5
+ tokens: ~700
6
+ load: architecture, design, refactor, review
7
+ triggers: princípio, principle, fundamentos, governança
8
+ ---
9
+
10
+ # Engineering Principles
11
+
12
+ > Princípios que governam toda decisão técnica neste OS. Quando houver dúvida, voltar aqui.
13
+
14
+ ---
15
+
16
+ ## P1 — Simplicidade vence sofisticação
17
+
18
+ Se há duas soluções, escolha a mais simples que funciona. Sofisticação só é justificada quando há requisito claro (escala, segurança, regulação). Anti-padrão: prematuramente introduzir microsserviços, ORM customizado, framework próprio.
19
+
20
+ ## P2 — Causa raiz, não sintoma
21
+
22
+ Bug nunca é fechado com workaround silencioso. Identifique a causa, corrija, documente em `memory/errors-and-solutions.md`. Se urgência exige workaround, registre como `known-issue` com data de validade.
23
+
24
+ ## P3 — Menor mudança que resolve
25
+
26
+ Refator oportunista é proibido em PR de feature/bug. Cada mudança tem 1 objetivo declarado.
27
+
28
+ ## P4 — Reversibilidade
29
+
30
+ Toda decisão deve responder: "como desfazer se errado?". Migrações têm script de rollback; deploys têm canário/blue-green; ADRs têm seção "consequências negativas".
31
+
32
+ ## P5 — Spec antes de código
33
+
34
+ Não escrever código sem PRD + SDD (para features) ou RFC (para mudanças cross-cutting). Bug-fix pequeno é exceção, mas deve atualizar o doc associado se a regra mudou.
35
+
36
+ ## P6 — Memória explícita
37
+
38
+ Decisão tomada, registrar. Erro encontrado, registrar. Padrão emergente, registrar. O cérebro está no disco, não no chat.
39
+
40
+ ## P7 — Custo é restrição
41
+
42
+ Toda escolha que adiciona custo (financeiro, complexidade, manutenção) é justificada em ADR. Default é não adicionar.
43
+
44
+ ## P8 — Defesa em camadas
45
+
46
+ Validação no front + no back + no DB. Segurança no perímetro + na camada de aplicação + nos dados. Resiliência via timeouts + retries + circuit breakers + fallbacks.
47
+
48
+ ## P9 — Observabilidade desde o dia 1
49
+
50
+ Sem logs estruturados + metrics + traces, qualquer sistema cresce no escuro. Logs com prefixo `[MODULE]`, métricas com nome em `snake_case`, traces propagados via `x-trace-id`.
51
+
52
+ ## P10 — Não inventar
53
+
54
+ `rules/dont.md` regra 1. Se não tem certeza, leia o código, rode comando, ou pergunte. APIs/flags/versões nunca são chutadas.
55
+
56
+ ---
57
+
58
+ ## Princípios derivados (operacionais)
59
+
60
+ - **YAGNI** (You Aren't Gonna Need It) — derivado de P1.
61
+ - **Boy Scout** — derivado de P3 invertido: deixe **igual ou melhor**, mas dentro do escopo da PR.
62
+ - **Trunk-based** — branches curtas; ramos longos viram conflito e divergência.
63
+ - **Test first, when it pays** — TDD para regras críticas; smoke depois para UI.
64
+ - **Documentation as code** — markdown versionado >> wiki externo.
65
+
66
+ ---
67
+
68
+ ## Quando questionar um princípio
69
+
70
+ Quando 3+ casos reais mostrarem que o princípio prejudica mais que ajuda. Abrir entrada em `evolution/improvements.md`, validar, escalar para ADR de mudança.
@@ -0,0 +1,85 @@
1
+ ---
2
+ version: 1.0.0
3
+ updated: 2026-05-15
4
+ tier: conditional
5
+ tokens: ~600
6
+ load: pipeline, gate, review, deploy
7
+ triggers: gate, qualidade, quality, checkpoint
8
+ ---
9
+
10
+ # Quality Gates
11
+
12
+ > Pontos obrigatórios de validação no pipeline. O fluxo IDEIA → DEPLOY só avança quando o gate atual passa. Cada gate tem **owner** (humano OU agente) e **artefato de saída**.
13
+
14
+ ---
15
+
16
+ ## Pipeline canônico (referência: `core/pipeline/execution-engine.md`)
17
+
18
+ ```
19
+ G1 G2 G3 G4 G5 G6 G7 G8 G9 G10
20
+ IDEIA→PRD→ARCH→SDD→TASKS→IMPL→TEST→REVIEW→DEPLOY→OBSERVE→LEARN
21
+ ```
22
+
23
+ | Gate | Nome | Owner | Artefato | Critério |
24
+ |---|---|---|---|---|
25
+ | **G1** | Discovery aprovado | `product-manager` agent + Founder | PRD draft | Problema, objetivo, KPIs, personas, escopo claros |
26
+ | **G2** | PRD aprovado | Founder | PRD final | Requisitos funcionais + não-funcionais + critérios de aceite |
27
+ | **G3** | Arquitetura aprovada | `architect` agent + Founder | SDD + ADRs | Decisões justificadas, alternativas listadas, riscos |
28
+ | **G4** | Tasks definidas | `tech-lead` agent | Backlog | Cada task atende DoR (`governance/definition-of-ready.md`) |
29
+ | **G5** | Implementação | `backend/frontend-engineer` | Código + testes unit | Build verde, types OK, testes unit passam |
30
+ | **G6** | QA aprovado | `qa-engineer` agent | Testes E2E + edge cases | Cobertura subiu ou manteve, edge cases cobertos |
31
+ | **G7** | Review aprovado | `reviewer` agent + humano | PR aprovada | Diff revisado, conformidade com `governance/*` |
32
+ | **G8** | Deploy autorizado | `sre-engineer` agent | Plano de deploy + rollback | Pré-deploy checklist OK, janela respeitada |
33
+ | **G9** | Observabilidade ativa | `sre-engineer` agent | Dashboards + alertas | Métrica de sucesso instrumentada, alertas no canal |
34
+ | **G10** | Aprendizado registrado | qualquer agent | Entrada em `evolution/` | Lessons learned, patterns ou anti-patterns |
35
+
36
+ ---
37
+
38
+ ## Como o agente sinaliza um gate
39
+
40
+ ```
41
+ [GATE G3 — Arquitetura]
42
+ Status: ✅ aprovado | ⏸ aguardando aprovação humana | ❌ bloqueado
43
+
44
+ Artefato: .ai/specs/SDD/SDD-007-events-heatmap.md
45
+ Decisão pendente: ADR-0042 — Cassandra vs PostgreSQL para hot path
46
+
47
+ Próximo gate: G4 — Task Breakdown (owner: tech-lead)
48
+ ```
49
+
50
+ ## Gates parciais (não-todos os projetos precisam de todos)
51
+
52
+ | Cenário | Gates obrigatórios | Gates opcionais |
53
+ |---|---|---|
54
+ | Bug fix P0 | G5, G6, G7, G8, G9 | G1-G4 (skip) |
55
+ | Feature nova | G1-G10 (todos) | — |
56
+ | Refator interno | G3 (mini), G5, G6, G7 | G1, G2, G4, G8, G9 |
57
+ | Spike / pesquisa | G1, G10 | resto skip |
58
+ | Mudança de config | G7, G8, G9 | resto skip |
59
+
60
+ Skip de gate deve aparecer no Audit: `Gates skipped: G2, G4 (motivo: bug fix P0, escopo cirúrgico)`.
61
+
62
+ ---
63
+
64
+ ## Falha de gate
65
+
66
+ Quando um gate falha, o agente:
67
+ 1. Para o pipeline.
68
+ 2. Registra em `memory/known-issues.md` se for problema sistêmico.
69
+ 3. Devolve para o gate anterior com diagnóstico:
70
+ ```
71
+ [GATE G5] FALHOU
72
+ Causa: build vermelho em tsc server (1 erro em foo.ts:42)
73
+ Ação: voltar para G5 com fix; manter PR open.
74
+ ```
75
+
76
+ Repetir falha do mesmo gate em 3+ tasks → revisar o gate (talvez está mal calibrado) em `improvements.md`.
77
+
78
+ ---
79
+
80
+ ## Anti-padrões
81
+
82
+ - Pular G3 (arquitetura) em feature complex → deriva inevitável.
83
+ - Pular G6 (QA) em bug crítico → bug volta.
84
+ - "Aprovar" gate sem artefato escrito — só vale com doc no `.ai/`.
85
+ - Founder fazer manual override em todos os gates → use override moderado, registre em `decisions.md`.
@@ -0,0 +1,84 @@
1
+ ---
2
+ version: 1.0.0
3
+ updated: 2026-05-15
4
+ tier: conditional
5
+ tokens: ~500
6
+ load: security, auth, secret, vulnerability
7
+ triggers: segurança, security, auth, autenticação, senha, password, token, vuln, lgpd, gdpr
8
+ ---
9
+
10
+ # Security Policies
11
+
12
+ > Políticas mínimas que se aplicam a todos os projetos sob este OS. Específicas por projeto vivem em `operating-system/security-rules.md`.
13
+
14
+ ---
15
+
16
+ ## P-SEC-1 — Segredos fora do código
17
+
18
+ - **Nunca** commitar `.env`, chaves, tokens, dumps de credencial.
19
+ - `.env` SEMPRE no `.gitignore` e adicionado em template `*.example`.
20
+ - Secret manager (1Password, Vault, AWS SSM, Doppler) para produção.
21
+ - Rotação obrigatória após exposição acidental + log do incidente em `memory/errors-and-solutions.md`.
22
+
23
+ ## P-SEC-2 — Autenticação e autorização
24
+
25
+ - Senhas hash com `bcrypt`/`argon2` (custo ≥10).
26
+ - JWT com expiração curta (≤1h) + refresh token rotativo.
27
+ - Default-deny: rota pública é a exceção, declarada.
28
+ - Princípio do menor privilégio em DB users, cloud roles, MCPs.
29
+
30
+ ## P-SEC-3 — Validação de input
31
+
32
+ - **Validar no perímetro** (request body, query string, headers).
33
+ - Usar lib de schema (`zod`, `joi`, `valibot`) — não validar manualmente.
34
+ - Rejeitar antes de tocar lógica de negócio.
35
+ - Sanitizar antes de renderizar (XSS) e antes de SQL (SQL injection).
36
+
37
+ ## P-SEC-4 — Logging seguro
38
+
39
+ - **Nunca** logar valores de variáveis sensíveis (senha, token, cartão, CPF parcial).
40
+ - Logs estruturados com filtro de PII no transporte.
41
+ - `[MODULE]` prefix obrigatório (ver `governance/engineering-principles.md` P9).
42
+
43
+ ## P-SEC-5 — Dependências
44
+
45
+ - Lockfile commitado (`package-lock.json`, `pnpm-lock.yaml`, etc.).
46
+ - Audit semanal: `npm audit --production`, `pip-audit`, `cargo audit`.
47
+ - Dep major (semver-breaking) upgrade exige ADR.
48
+
49
+ ## P-SEC-6 — Threat modeling
50
+
51
+ Para qualquer feature que toca dados sensíveis, criar entrada em `architecture/threat-modeling.md`:
52
+ - O que está sendo protegido?
53
+ - De quem (atores)?
54
+ - Como (vetores)?
55
+ - Mitigações?
56
+
57
+ Usar STRIDE mínimo (Spoofing, Tampering, Repudiation, Info Disclosure, DoS, Elevation of Privilege).
58
+
59
+ ## P-SEC-7 — Compliance (quando aplicável)
60
+
61
+ - **LGPD/GDPR**: registrar bases legais, ter `/privacy` endpoint, suportar export/delete.
62
+ - **PCI-DSS**: nunca armazenar PAN não-criptografado; usar tokenização do provedor.
63
+ - **HIPAA**: BAA + criptografia at-rest e in-transit + auditoria de acesso.
64
+
65
+ Cada um desses requisitos vira ADR no projeto + entrada em `operating-system/security-rules.md`.
66
+
67
+ ---
68
+
69
+ ## Em PR de feature/bug
70
+
71
+ Reviewer (humano ou `security-engineer` agent) DEVE confirmar:
72
+ - [ ] Sem segredo no diff
73
+ - [ ] Inputs validados
74
+ - [ ] Outputs não vazam PII em logs
75
+ - [ ] Sem `eval`, `Function()`, `child_process.exec(unescaped)`
76
+ - [ ] Sem `dangerouslySetInnerHTML` sem sanitize
77
+ - [ ] Sem `cors({ origin: '*' })` em prod
78
+
79
+ ## Em incidente
80
+
81
+ 1. **Conter** — desabilitar feature flag, revogar token, isolar host.
82
+ 2. **Comunicar** — registrar timestamp + impact em `memory/known-issues.md`.
83
+ 3. **Investigar** — causa-raiz, em `memory/errors-and-solutions.md`.
84
+ 4. **Aprender** — entrada em `evolution/learnings.md` se padrão emergir.
@@ -0,0 +1,41 @@
1
+ # Stop hook
2
+ # Roda quando o agente termina seu turno.
3
+ # Verifica se transcript do turno contem [OS Audit] para tarefas nao-triviais.
4
+
5
+ $projectDir = $env:CLAUDE_PROJECT_DIR
6
+ if (-not $projectDir) { $projectDir = (Get-Location).Path }
7
+
8
+ $raw = [Console]::In.ReadToEnd()
9
+ try {
10
+ $payload = $raw | ConvertFrom-Json
11
+ } catch {
12
+ exit 0
13
+ }
14
+
15
+ $transcriptPath = $payload.transcript_path
16
+ if (-not $transcriptPath -or -not (Test-Path $transcriptPath)) {
17
+ exit 0
18
+ }
19
+
20
+ # Le ultimas linhas da transcript
21
+ $lines = Get-Content $transcriptPath -Tail 100 -ErrorAction SilentlyContinue
22
+ if (-not $lines) { exit 0 }
23
+
24
+ $transcriptText = $lines -join "`n"
25
+
26
+ # Heuristica: se houve tool calls de Edit/Write neste turno e nao ha [OS Audit] na resposta final
27
+ $hasEdits = $transcriptText -match '"tool_name"\s*:\s*"(Edit|Write|NotebookEdit)"'
28
+ $hasAudit = $transcriptText -match '\[OS Audit\]'
29
+ $hasTrivialMark = $transcriptText -match '\[OS Audit\] skipped: trivial'
30
+
31
+ if ($hasEdits -and -not $hasAudit -and -not $hasTrivialMark) {
32
+ # Pede ao agente para completar o audit antes de parar
33
+ $response = @{
34
+ decision = "block"
35
+ reason = "Protocolo nao cumprido: tarefa fez edicoes mas nao emitiu [OS Audit]. Adicione o bloco de audit no formato definido em .ai/CONTRACT.md antes de encerrar:`n[OS Audit]`n- Files touched: ...`n- Memory updated: ...`n- Validations: ...`n- Decisions: ...`n- Open items: ..."
36
+ } | ConvertTo-Json -Depth 5 -Compress
37
+ Write-Output $response
38
+ exit 0
39
+ }
40
+
41
+ exit 0
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ # Stop hook (Unix)
3
+ # Verifica se transcript contem [OS Audit] para tarefas com edicoes.
4
+ set -euo pipefail
5
+
6
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
7
+ PAYLOAD=$(cat)
8
+
9
+ TRANSCRIPT_PATH=""
10
+ if command -v python3 &>/dev/null; then
11
+ TRANSCRIPT_PATH=$(echo "$PAYLOAD" | python3 -c 'import sys,json
12
+ try:
13
+ d=json.load(sys.stdin); print(d.get("transcript_path",""))
14
+ except: pass' 2>/dev/null || echo "")
15
+ elif command -v node &>/dev/null; then
16
+ TRANSCRIPT_PATH=$(echo "$PAYLOAD" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{try{console.log(JSON.parse(s).transcript_path||"")}catch{}})' 2>/dev/null || echo "")
17
+ fi
18
+
19
+ [[ -z "$TRANSCRIPT_PATH" || ! -f "$TRANSCRIPT_PATH" ]] && exit 0
20
+
21
+ # Pega as ultimas 100 linhas
22
+ TAIL_TEXT=$(tail -n 100 "$TRANSCRIPT_PATH" 2>/dev/null || echo "")
23
+ [[ -z "$TAIL_TEXT" ]] && exit 0
24
+
25
+ HAS_EDITS=0
26
+ HAS_AUDIT=0
27
+ HAS_TRIVIAL=0
28
+
29
+ echo "$TAIL_TEXT" | grep -Eq '"tool_name"[[:space:]]*:[[:space:]]*"(Edit|Write|NotebookEdit)"' && HAS_EDITS=1
30
+ echo "$TAIL_TEXT" | grep -Fq '[OS Audit]' && HAS_AUDIT=1
31
+ echo "$TAIL_TEXT" | grep -Fq '[OS Audit] skipped: trivial' && HAS_TRIVIAL=1
32
+
33
+ if [[ $HAS_EDITS -eq 1 && $HAS_AUDIT -eq 0 && $HAS_TRIVIAL -eq 0 ]]; then
34
+ REASON='Protocolo nao cumprido: tarefa fez edicoes mas nao emitiu [OS Audit]. Adicione o bloco de audit conforme .ai/CONTRACT.md antes de encerrar:\n[OS Audit]\n- Files touched: ...\n- Memory updated: ...\n- Validations: ...\n- Decisions: ...\n- Open items: ...'
35
+ printf '{"decision":"block","reason":"%s"}\n' "$REASON"
36
+ exit 0
37
+ fi
38
+
39
+ exit 0
@@ -0,0 +1,182 @@
1
+ # PreToolUse hook (Windows / PowerShell) — matcher: Edit|Write|NotebookEdit|Bash
2
+ # Bloqueia mudancas em arquivos protegidos do AI OS sem confirmacao explicita.
3
+ # Para Bash, faz split em SUBCOMANDOS por separadores (&&, ||, ;, |, newline) e
4
+ # bloqueia apenas o subcomando que contem write verb + path protegido juntos.
5
+ # Override autorizado: criar .claude\.unlock (mera existencia = bypass total).
6
+
7
+ $projectDir = $env:CLAUDE_PROJECT_DIR
8
+ if (-not $projectDir) { $projectDir = (Get-Location).Path }
9
+
10
+ # Bypass via sentinela
11
+ $unlockPath = Join-Path $projectDir '.claude\.unlock'
12
+ if (Test-Path $unlockPath) { exit 0 }
13
+
14
+ # Ler payload do hook
15
+ $raw = [Console]::In.ReadToEnd()
16
+ try {
17
+ $payload = $raw | ConvertFrom-Json
18
+ } catch {
19
+ exit 0
20
+ }
21
+
22
+ $toolName = $payload.tool_name
23
+
24
+ # Paths PROTEGIDOS (substring match, normalizado para / lower-case)
25
+ $protectedSubstrings = @(
26
+ '.ai/rules/dont.md',
27
+ '.ai/contract.md',
28
+ '.ai/router.md',
29
+ '.ai/manifest.json',
30
+ '.ai/hooks/inject-os-reminder.ps1',
31
+ '.ai/hooks/inject-os-reminder.sh',
32
+ '.ai/hooks/guard-edit.ps1',
33
+ '.ai/hooks/guard-edit.sh',
34
+ '.ai/hooks/enforce-audit.ps1',
35
+ '.ai/hooks/enforce-audit.sh',
36
+ '.claude/settings.json'
37
+ )
38
+
39
+ # Verbos de escrita (regex); se houver match no subcomando + path protegido no mesmo, bloqueia.
40
+ $writeVerbPatterns = @(
41
+ 'Set-Content', 'Out-File', 'Add-Content', 'Clear-Content',
42
+ 'Tee-Object', 'New-Item', 'Remove-Item', 'Move-Item', 'Copy-Item',
43
+ 'fs\.writeFile', 'fs\.appendFile', 'fs\.unlink', 'fs\.rm',
44
+ 'fs\.rmdir', '\brm\s', '\bmv\s', '\bcp\s', '\btee\s',
45
+ 'sed\s+-i', '\bawk\b.*>', '>\s*[^\s|&]', '>>\s*[^\s|&]'
46
+ )
47
+
48
+ function Test-ProtectedPath([string]$path) {
49
+ if (-not $path) { return $false }
50
+ $norm = ($path -replace '\\', '/').ToLower()
51
+ foreach ($p in $protectedSubstrings) {
52
+ if ($norm.Contains($p.ToLower())) { return $true }
53
+ }
54
+ return $false
55
+ }
56
+
57
+ function Split-Subcommands([string]$cmd) {
58
+ # Divide o comando em subcomandos por separadores: && || ; | newline
59
+ # Nao quebra dentro de strings (heuristica simples — suficiente para uso geral).
60
+ $parts = [System.Collections.ArrayList]::new()
61
+ $buf = ''
62
+ $inSingle = $false
63
+ $inDouble = $false
64
+ $i = 0
65
+ while ($i -lt $cmd.Length) {
66
+ $c = $cmd[$i]
67
+ $next = if ($i + 1 -lt $cmd.Length) { $cmd[$i + 1] } else { $null }
68
+ if ($c -eq "'" -and -not $inDouble) { $inSingle = -not $inSingle; $buf += $c; $i++; continue }
69
+ if ($c -eq '"' -and -not $inSingle) { $inDouble = -not $inDouble; $buf += $c; $i++; continue }
70
+ if (-not $inSingle -and -not $inDouble) {
71
+ if (($c -eq '&' -and $next -eq '&') -or ($c -eq '|' -and $next -eq '|')) {
72
+ $null = $parts.Add($buf); $buf = ''; $i += 2; continue
73
+ }
74
+ if ($c -eq ';' -or $c -eq '|' -or $c -eq "`n") {
75
+ $null = $parts.Add($buf); $buf = ''; $i++; continue
76
+ }
77
+ }
78
+ $buf += $c
79
+ $i++
80
+ }
81
+ if ($buf.Length -gt 0) { $null = $parts.Add($buf) }
82
+ return ,$parts
83
+ }
84
+
85
+ function Find-WriteToProtected([string]$subcmd) {
86
+ # Retorna o path protegido se este subcomando contem write verb + path; senao $null.
87
+ # Allowlist: subcomandos comecando com leitura (grep/cat/etc) NUNCA bloqueiam,
88
+ # mesmo que tenham strings como 'Set-Content' como argumento.
89
+ $trimmed = $subcmd.TrimStart()
90
+ $readOnlyPrefixes = @(
91
+ 'grep', 'egrep', 'fgrep', 'rg', 'ag', 'cat', 'head', 'tail',
92
+ 'less', 'more', 'ls', 'find', 'wc', 'stat', 'file', 'which',
93
+ 'type', 'echo', 'printf',
94
+ 'Get-Content', 'Get-ChildItem', 'Select-String', 'Test-Path',
95
+ 'Resolve-Path', 'Get-Item', 'gci', 'gc', 'sls'
96
+ )
97
+ # Allowlist so vale se NAO houver redirect de escrita (> ou >>) no subcomando.
98
+ $hasRedirect = ($subcmd -match '>\s*[^\s|&]')
99
+ if (-not $hasRedirect) {
100
+ foreach ($pfx in $readOnlyPrefixes) {
101
+ if ($trimmed -match "^$([regex]::Escape($pfx))(\s|$)") { return $null }
102
+ }
103
+ }
104
+
105
+ $hasWriteVerb = $false
106
+ foreach ($v in $writeVerbPatterns) {
107
+ if ($subcmd -match $v) { $hasWriteVerb = $true; break }
108
+ }
109
+ if (-not $hasWriteVerb) { return $null }
110
+ $norm = ($subcmd -replace '\\', '/').ToLower()
111
+ foreach ($p in $protectedSubstrings) {
112
+ if ($norm.Contains($p.ToLower())) { return $p }
113
+ }
114
+ return $null
115
+ }
116
+
117
+ function Deny-Edit([string]$target, [string]$source) {
118
+ $reason = @"
119
+ [OS GUARD] Arquivo protegido bloqueado: $target (via $source)
120
+
121
+ Este arquivo faz parte do nucleo do AI Operating System.
122
+
123
+ Para prosseguir, escolha UMA das opcoes:
124
+ 1. Criar ADR em .ai/memory/decisions.md justificando a mudanca + pedir confirmacao explicita do usuario no formato 'Confirmo alteracao em <path> - motivo: <razao>'.
125
+ 2. Bypass autorizado: o usuario cria o arquivo .claude/.unlock (basta existir). O guard fica inativo enquanto o arquivo existir.
126
+
127
+ Apos a mudanca, recomenda-se remover .claude/.unlock para restaurar a protecao.
128
+ "@
129
+ $response = @{
130
+ hookSpecificOutput = @{
131
+ hookEventName = 'PreToolUse'
132
+ permissionDecision = 'deny'
133
+ permissionDecisionReason = $reason
134
+ }
135
+ } | ConvertTo-Json -Depth 5 -Compress
136
+ Write-Output $response
137
+ exit 0
138
+ }
139
+
140
+ # Branch 1: Edit / Write / NotebookEdit — payload.tool_input.file_path
141
+ if ($toolName -in @('Edit', 'Write', 'NotebookEdit')) {
142
+ $filePath = $payload.tool_input.file_path
143
+ if ($filePath -and (Test-ProtectedPath $filePath)) {
144
+ Deny-Edit -target $filePath -source $toolName
145
+ }
146
+ }
147
+
148
+ # Branch 2: Bash — split em subcomandos, bloqueia apenas se write verb + path protegido coexistirem no MESMO subcomando.
149
+ if ($toolName -eq 'Bash') {
150
+ $cmd = $payload.tool_input.command
151
+ if ($cmd) {
152
+ $subs = Split-Subcommands $cmd
153
+ foreach ($s in $subs) {
154
+ $hit = Find-WriteToProtected $s
155
+ if ($hit) {
156
+ Deny-Edit -target $hit -source 'Bash'
157
+ }
158
+ }
159
+ }
160
+ }
161
+
162
+ # Aviso leve: editar codigo de producao sem ter consultado project-context.md
163
+ if ($toolName -in @('Edit', 'Write', 'NotebookEdit')) {
164
+ $filePath = $payload.tool_input.file_path
165
+ if ($filePath) {
166
+ $markerPath = Join-Path $projectDir '.claude\.os-context-loaded'
167
+ $contextPath = Join-Path $projectDir '.ai\memory\project-context.md'
168
+ $isProductionEdit = ($filePath -notmatch '\.ai[\\/]') -and ($filePath -notmatch '(?i)(test|spec|\.md)$')
169
+ if ($isProductionEdit -and (Test-Path $contextPath) -and (-not (Test-Path $markerPath))) {
170
+ $warning = @{
171
+ hookSpecificOutput = @{
172
+ hookEventName = 'PreToolUse'
173
+ additionalContext = '[OS WARNING] Voce esta editando codigo de producao mas project-context.md ainda nao foi consultado nesta sessao. Considere ler antes de prosseguir.'
174
+ }
175
+ } | ConvertTo-Json -Depth 5 -Compress
176
+ Write-Output $warning
177
+ exit 0
178
+ }
179
+ }
180
+ }
181
+
182
+ exit 0
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env bash
2
+ # PreToolUse hook (Unix) — matcher: Edit|Write|NotebookEdit|Bash
3
+ # Bloqueia mudancas em arquivos protegidos do AI OS sem confirmacao explicita.
4
+ # Para Bash, faz split em SUBCOMANDOS (&&, ||, ;, |, newline) e bloqueia
5
+ # apenas o subcomando que contem write verb + path protegido juntos.
6
+ # Override autorizado: criar .claude/.unlock (basta existir).
7
+ set -euo pipefail
8
+
9
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
10
+
11
+ # Bypass via sentinela
12
+ if [[ -f "$PROJECT_DIR/.claude/.unlock" ]]; then
13
+ exit 0
14
+ fi
15
+
16
+ PAYLOAD=$(cat)
17
+
18
+ # Extractor JSON: node primeiro (mais robusto), depois python3 real (nao stub MS Store), depois grep.
19
+ extract_field() {
20
+ local field="$1"
21
+ if command -v node &>/dev/null; then
22
+ echo "$PAYLOAD" | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{try{const o=JSON.parse(s);const f='$field';console.log(f==='tool_name'?o.tool_name||'':o.tool_input?.[f]||'')}catch{}})" 2>/dev/null && return 0
23
+ fi
24
+ if command -v python3 &>/dev/null && python3 -c "print('ok')" 2>/dev/null | grep -q '^ok$'; then
25
+ echo "$PAYLOAD" | python3 -c "import sys,json
26
+ try:
27
+ d=json.load(sys.stdin)
28
+ f='$field'
29
+ print(d.get('tool_name','') if f=='tool_name' else d.get('tool_input',{}).get(f,''))
30
+ except: pass" 2>/dev/null && return 0
31
+ fi
32
+ echo "$PAYLOAD" | grep -oE "\"$field\"[[:space:]]*:[[:space:]]*\"([^\"\\\\]|\\\\.)*\"" | sed 's/^"[^"]*"[[:space:]]*:[[:space:]]*"//; s/"$//' | head -1
33
+ }
34
+
35
+ TOOL_NAME=$(extract_field tool_name)
36
+
37
+ PROTECTED=(
38
+ '.ai/rules/dont.md'
39
+ '.ai/contract.md'
40
+ '.ai/router.md'
41
+ '.ai/manifest.json'
42
+ '.ai/hooks/inject-os-reminder.ps1'
43
+ '.ai/hooks/inject-os-reminder.sh'
44
+ '.ai/hooks/guard-edit.ps1'
45
+ '.ai/hooks/guard-edit.sh'
46
+ '.ai/hooks/enforce-audit.ps1'
47
+ '.ai/hooks/enforce-audit.sh'
48
+ '.claude/settings.json'
49
+ )
50
+
51
+ WRITE_VERBS='(Set-Content|Out-File|Add-Content|Clear-Content|Tee-Object|New-Item|Remove-Item|Move-Item|Copy-Item|fs\.writeFile|fs\.appendFile|fs\.unlink|fs\.rm|fs\.rmdir|\brm[[:space:]]|\bmv[[:space:]]|\bcp[[:space:]]|\btee[[:space:]]|sed[[:space:]]+-i|>[[:space:]]*[^[:space:]|&]|>>[[:space:]]*[^[:space:]|&])'
52
+
53
+ is_protected_path() {
54
+ local norm="${1//\\//}"
55
+ norm="$(echo "$norm" | tr '[:upper:]' '[:lower:]')"
56
+ for p in "${PROTECTED[@]}"; do
57
+ if [[ "$norm" == *"$p"* ]]; then
58
+ return 0
59
+ fi
60
+ done
61
+ return 1
62
+ }
63
+
64
+ # Retorna 0 (true) e ecoa o path se o subcomando tem write verb + path protegido.
65
+ # Allowlist: subcomandos comecando com leitura (grep/cat/etc) NUNCA bloqueiam.
66
+ READ_ONLY_PREFIXES='^[[:space:]]*(grep|egrep|fgrep|rg|ag|cat|head|tail|less|more|ls|find|wc|stat|file|which|type|echo|printf|Get-Content|Get-ChildItem|Select-String|Test-Path|Resolve-Path|Get-Item|gci|gc|sls)([[:space:]]|$)'
67
+
68
+ find_write_to_protected() {
69
+ local sub="$1"
70
+ # Se o subcomando NAO contem redirect de escrita E comeca com prefixo read-only, nao bloqueia.
71
+ if ! echo "$sub" | grep -Eq '>[[:space:]]*[^[:space:]|&]'; then
72
+ if echo "$sub" | grep -Eq "$READ_ONLY_PREFIXES"; then
73
+ return 1
74
+ fi
75
+ fi
76
+ if ! echo "$sub" | grep -Eq "$WRITE_VERBS"; then
77
+ return 1
78
+ fi
79
+ local norm
80
+ norm=$(echo "${sub//\\//}" | tr '[:upper:]' '[:lower:]')
81
+ for p in "${PROTECTED[@]}"; do
82
+ if [[ "$norm" == *"$p"* ]]; then
83
+ echo "$p"
84
+ return 0
85
+ fi
86
+ done
87
+ return 1
88
+ }
89
+
90
+ # Split em subcomandos: usa awk com FS multi-char.
91
+ # Separadores: && || ; | \n (heuristica: nao quebra dentro de aspas — suficiente para uso geral)
92
+ split_subcommands() {
93
+ local cmd="$1"
94
+ # Substitui separadores por \0 e divide.
95
+ echo "$cmd" | awk '
96
+ BEGIN { in_single=0; in_double=0; buf="" }
97
+ {
98
+ s = $0
99
+ for (i = 1; i <= length(s); i++) {
100
+ c = substr(s, i, 1)
101
+ n = (i < length(s)) ? substr(s, i+1, 1) : ""
102
+ if (c == "\047" && !in_double) { in_single = !in_single; buf = buf c; continue }
103
+ if (c == "\"" && !in_single) { in_double = !in_double; buf = buf c; continue }
104
+ if (!in_single && !in_double) {
105
+ if ((c == "&" && n == "&") || (c == "|" && n == "|")) {
106
+ print buf; buf = ""; i++; continue
107
+ }
108
+ if (c == ";" || c == "|") {
109
+ print buf; buf = ""; continue
110
+ }
111
+ }
112
+ buf = buf c
113
+ }
114
+ if (length(buf) > 0) { print buf; buf = "" }
115
+ }'
116
+ }
117
+
118
+ deny() {
119
+ local target="$1"
120
+ local source="$2"
121
+ local REASON="[OS GUARD] Arquivo protegido bloqueado: $target (via $source). Este arquivo faz parte do nucleo do AI Operating System. Para prosseguir: 1) Criar ADR em .ai/memory/decisions.md + confirmacao explicita do usuario no formato 'Confirmo alteracao em <path> - motivo: <razao>'. OU 2) Bypass autorizado: usuario cria .claude/.unlock (basta existir; remover apos a mudanca para restaurar protecao)."
122
+ printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"%s"}}\n' "$REASON"
123
+ exit 0
124
+ }
125
+
126
+ case "$TOOL_NAME" in
127
+ Edit|Write|NotebookEdit)
128
+ FILE_PATH=$(extract_field file_path)
129
+ if [[ -n "$FILE_PATH" ]] && is_protected_path "$FILE_PATH"; then
130
+ deny "$FILE_PATH" "$TOOL_NAME"
131
+ fi
132
+ ;;
133
+ Bash)
134
+ CMD=$(extract_field command)
135
+ if [[ -n "$CMD" ]]; then
136
+ while IFS= read -r sub; do
137
+ [[ -z "$sub" ]] && continue
138
+ hit=$(find_write_to_protected "$sub" || true)
139
+ if [[ -n "$hit" ]]; then
140
+ deny "$hit" "Bash"
141
+ fi
142
+ done < <(split_subcommands "$CMD")
143
+ fi
144
+ ;;
145
+ esac
146
+
147
+ # Aviso leve para edicao de producao sem ter consultado project-context.md
148
+ if [[ "$TOOL_NAME" == "Edit" || "$TOOL_NAME" == "Write" || "$TOOL_NAME" == "NotebookEdit" ]]; then
149
+ FILE_PATH=$(extract_field file_path)
150
+ MARKER="$PROJECT_DIR/.claude/.os-context-loaded"
151
+ CONTEXT="$PROJECT_DIR/.ai/memory/project-context.md"
152
+ if [[ -n "$FILE_PATH" && -f "$CONTEXT" && ! -f "$MARKER" ]] && \
153
+ echo "$FILE_PATH" | grep -vqE '\.ai[\\/]' && \
154
+ echo "$FILE_PATH" | grep -vqiE '(test|spec|\.md)$'; then
155
+ WARN='[OS WARNING] Voce esta editando codigo de producao mas project-context.md ainda nao foi consultado nesta sessao. Considere ler antes de prosseguir.'
156
+ printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"%s"}}\n' "$WARN"
157
+ exit 0
158
+ fi
159
+ fi
160
+
161
+ exit 0