sinapse-ai 9.4.0 → 9.5.0

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 (266) hide show
  1. package/.claude/CLAUDE.md +10 -4
  2. package/.claude/hooks/enforce-architecture-first.py +197 -197
  3. package/.claude/hooks/enforce-git-push-authority.sh +25 -4
  4. package/.claude/hooks/mind-clone-governance.py +193 -193
  5. package/.claude/hooks/read-protection.py +152 -152
  6. package/.claude/hooks/sql-governance.py +183 -183
  7. package/.claude/hooks/verify-packages.cjs +83 -0
  8. package/.claude/hooks/write-path-validation.py +195 -195
  9. package/.claude/rules/hook-governance.md +1 -0
  10. package/.claude/rules/mandatory-delegation.md +24 -0
  11. package/.claude/rules/project-intelligence.md +63 -0
  12. package/.claude/rules/response-format.md +4 -0
  13. package/.claude/rules/safe-collaboration.md +4 -2
  14. package/.claude/rules/security-data-protection.md +18 -0
  15. package/.claude/rules/squad-awareness.md +93 -67
  16. package/.claude/rules/token-economy.md +148 -0
  17. package/.codex/agents/analyst.md +90 -0
  18. package/.codex/agents/architect.md +78 -0
  19. package/.codex/agents/data-engineer.md +38 -0
  20. package/.codex/agents/developer.md +97 -0
  21. package/.codex/agents/devops.md +121 -0
  22. package/.codex/agents/product-lead.md +27 -0
  23. package/.codex/agents/project-lead.md +28 -0
  24. package/.codex/agents/quality-gate.md +89 -0
  25. package/.codex/agents/sprint-lead.md +28 -0
  26. package/.codex/agents/squad-creator.md +58 -0
  27. package/.codex/agents/ux-design-expert.md +28 -0
  28. package/.sinapse-ai/core/code-intel/registry-syncer.js +56 -3
  29. package/.sinapse-ai/core/doctor/checks/agent-memory.js +5 -1
  30. package/.sinapse-ai/core/doctor/checks/claude-md.js +4 -1
  31. package/.sinapse-ai/core/doctor/checks/code-intel.js +5 -1
  32. package/.sinapse-ai/core/doctor/checks/commands-count.js +4 -1
  33. package/.sinapse-ai/core/doctor/checks/constitution-consistency.js +4 -1
  34. package/.sinapse-ai/core/doctor/checks/core-config.js +4 -1
  35. package/.sinapse-ai/core/doctor/checks/entity-registry.js +6 -1
  36. package/.sinapse-ai/core/doctor/checks/git-hooks.js +5 -1
  37. package/.sinapse-ai/core/doctor/checks/graph-dashboard.js +4 -1
  38. package/.sinapse-ai/core/doctor/checks/hooks-claude-count.js +5 -1
  39. package/.sinapse-ai/core/doctor/checks/ide-sync.js +4 -1
  40. package/.sinapse-ai/core/doctor/checks/node-version.js +4 -1
  41. package/.sinapse-ai/core/doctor/checks/npm-packages.js +4 -1
  42. package/.sinapse-ai/core/doctor/checks/rules-files.js +4 -1
  43. package/.sinapse-ai/core/doctor/checks/settings-json.js +4 -1
  44. package/.sinapse-ai/core/doctor/checks/skills-count.js +4 -1
  45. package/.sinapse-ai/core/doctor/index.js +157 -50
  46. package/.sinapse-ai/core/ids/registry-updater.js +6 -1
  47. package/.sinapse-ai/core/logger/index.js +319 -0
  48. package/.sinapse-ai/core/orchestration/terminal-spawner.js +2 -2
  49. package/.sinapse-ai/core/telemetry/index.js +247 -0
  50. package/.sinapse-ai/data/entity-registry.yaml +1384 -944
  51. package/.sinapse-ai/development/agents/architect.md +5 -0
  52. package/.sinapse-ai/development/agents/data-engineer.md +38 -0
  53. package/.sinapse-ai/development/agents/developer.md +28 -0
  54. package/.sinapse-ai/development/agents/devops.md +4 -0
  55. package/.sinapse-ai/development/agents/product-lead.md +27 -0
  56. package/.sinapse-ai/development/agents/project-lead.md +28 -0
  57. package/.sinapse-ai/development/agents/quality-gate.md +4 -0
  58. package/.sinapse-ai/development/agents/sprint-lead/MEMORY.md +8 -0
  59. package/.sinapse-ai/development/agents/sprint-lead.md +28 -0
  60. package/.sinapse-ai/development/agents/squad-creator.md +58 -0
  61. package/.sinapse-ai/development/agents/ux-design-expert.md +28 -0
  62. package/.sinapse-ai/development/knowledge-base/agent-communication-protocol.md +127 -0
  63. package/.sinapse-ai/development/knowledge-base/database-scaling-patterns.md +374 -0
  64. package/.sinapse-ai/development/knowledge-base/environment-deployment-patterns.md +353 -0
  65. package/.sinapse-ai/development/knowledge-base/gotchas-patterns.md +224 -0
  66. package/.sinapse-ai/development/knowledge-base/infrastructure-decision-framework.md +221 -0
  67. package/.sinapse-ai/development/knowledge-base/security-pre-deploy-checklist.md +410 -0
  68. package/.sinapse-ai/development/knowledge-base/software-architecture-patterns.md +299 -0
  69. package/.sinapse-ai/development/knowledge-base/token-economy-guide.md +198 -0
  70. package/.sinapse-ai/development/scripts/populate-entity-registry.js +5 -1
  71. package/.sinapse-ai/development/skills/captcha-handler.md +82 -0
  72. package/.sinapse-ai/development/skills/chrome-brain.md +81 -0
  73. package/.sinapse-ai/development/skills/deploy-readiness.md +93 -0
  74. package/.sinapse-ai/development/skills/model-router.md +92 -0
  75. package/.sinapse-ai/development/skills/sinapse-methodology.md +175 -0
  76. package/.sinapse-ai/development/skills/story-fast-track.md +71 -0
  77. package/.sinapse-ai/development/tasks/dev-develop-story.md +10 -0
  78. package/.sinapse-ai/development/tasks/environment-promotion-pipeline.md +582 -0
  79. package/.sinapse-ai/development/tasks/generate-agent-handoff.md +223 -0
  80. package/.sinapse-ai/development/tasks/infrastructure-assessment.md +432 -0
  81. package/.sinapse-ai/development/tasks/load-testing-setup.md +611 -0
  82. package/.sinapse-ai/development/tasks/observability-blueprint.md +562 -0
  83. package/.sinapse-ai/development/templates/legal/breach-notification-tmpl.md +113 -0
  84. package/.sinapse-ai/development/templates/legal/privacy-policy-tmpl.md +93 -0
  85. package/.sinapse-ai/development/templates/legal/terms-of-service-tmpl.md +85 -0
  86. package/.sinapse-ai/development/templates/service-template/README.md.hbs +159 -159
  87. package/.sinapse-ai/development/templates/service-template/__tests__/index.test.ts.hbs +238 -238
  88. package/.sinapse-ai/development/templates/service-template/client.ts.hbs +404 -404
  89. package/.sinapse-ai/development/templates/service-template/errors.ts.hbs +183 -183
  90. package/.sinapse-ai/development/templates/service-template/index.ts.hbs +121 -121
  91. package/.sinapse-ai/development/templates/service-template/package.json.hbs +88 -88
  92. package/.sinapse-ai/development/templates/service-template/types.ts.hbs +146 -146
  93. package/.sinapse-ai/development/templates/squad-template/LICENSE +22 -22
  94. package/.sinapse-ai/development/workflows/story-development-cycle.yaml +40 -1
  95. package/.sinapse-ai/hooks/ids-post-commit.js +22 -0
  96. package/.sinapse-ai/infrastructure/contracts/compatibility/README.md +42 -0
  97. package/.sinapse-ai/infrastructure/contracts/compatibility/sinapse-current.yaml +35 -0
  98. package/.sinapse-ai/infrastructure/scripts/llm-routing/templates/claude-free-tracked.cmd +127 -127
  99. package/.sinapse-ai/infrastructure/scripts/llm-routing/templates/deepseek-proxy.cmd +71 -71
  100. package/.sinapse-ai/infrastructure/scripts/llm-routing/templates/deepseek-usage.cmd +51 -51
  101. package/.sinapse-ai/infrastructure/scripts/pr-review-ai.js +16 -13
  102. package/.sinapse-ai/infrastructure/scripts/setup-project-infra.js +128 -0
  103. package/.sinapse-ai/infrastructure/scripts/test-discovery.js +8 -3
  104. package/.sinapse-ai/infrastructure/scripts/validate-manifest-parity.js +380 -0
  105. package/.sinapse-ai/infrastructure/scripts/validate-parity.js +76 -25
  106. package/.sinapse-ai/infrastructure/templates/coderabbit.yaml.template +280 -280
  107. package/.sinapse-ai/infrastructure/templates/config/env.example +16 -0
  108. package/.sinapse-ai/infrastructure/templates/config/gitignore-additions.tmpl +59 -0
  109. package/.sinapse-ai/infrastructure/templates/github/CODEOWNERS.template +12 -0
  110. package/.sinapse-ai/infrastructure/templates/github/PULL_REQUEST_TEMPLATE.md +29 -0
  111. package/.sinapse-ai/infrastructure/templates/github/ci-template.yml +77 -0
  112. package/.sinapse-ai/infrastructure/templates/github/issue-templates/bug_report.md +34 -0
  113. package/.sinapse-ai/infrastructure/templates/github/issue-templates/feature_request.md +19 -0
  114. package/.sinapse-ai/infrastructure/templates/github-workflows/ci.yml.template +170 -170
  115. package/.sinapse-ai/infrastructure/templates/github-workflows/pr-automation.yml.template +331 -331
  116. package/.sinapse-ai/infrastructure/templates/github-workflows/release.yml.template +197 -197
  117. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +19 -19
  118. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-node.tmpl +86 -86
  119. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-python.tmpl +146 -146
  120. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-sinapse-base.tmpl +64 -64
  121. package/.sinapse-ai/infrastructure/templates/sinapse-sync.yaml.template +183 -183
  122. package/.sinapse-ai/install-manifest.yaml +275 -140
  123. package/.sinapse-ai/local-config.yaml.template +65 -65
  124. package/.sinapse-ai/monitor/hooks/lib/__init__.py +2 -2
  125. package/.sinapse-ai/monitor/hooks/lib/enrich.py +59 -59
  126. package/.sinapse-ai/monitor/hooks/lib/send_event.py +48 -48
  127. package/.sinapse-ai/monitor/hooks/notification.py +30 -30
  128. package/.sinapse-ai/monitor/hooks/post_tool_use.py +46 -46
  129. package/.sinapse-ai/monitor/hooks/pre_compact.py +30 -30
  130. package/.sinapse-ai/monitor/hooks/pre_tool_use.py +41 -41
  131. package/.sinapse-ai/monitor/hooks/stop.py +30 -30
  132. package/.sinapse-ai/monitor/hooks/subagent_stop.py +30 -30
  133. package/.sinapse-ai/monitor/hooks/user_prompt_submit.py +39 -39
  134. package/.sinapse-ai/product/templates/adr.hbs +126 -126
  135. package/.sinapse-ai/product/templates/dbdr.hbs +242 -242
  136. package/.sinapse-ai/product/templates/epic.hbs +213 -213
  137. package/.sinapse-ai/product/templates/pmdr.hbs +187 -187
  138. package/.sinapse-ai/product/templates/prd-v2.0.hbs +217 -217
  139. package/.sinapse-ai/product/templates/prd.hbs +202 -202
  140. package/.sinapse-ai/product/templates/story-tmpl.yaml +59 -0
  141. package/.sinapse-ai/product/templates/story.hbs +264 -264
  142. package/.sinapse-ai/product/templates/task.hbs +171 -171
  143. package/.sinapse-ai/product/templates/tmpl-comment-on-examples.sql +159 -159
  144. package/.sinapse-ai/product/templates/tmpl-migration-script.sql +92 -92
  145. package/.sinapse-ai/product/templates/tmpl-rls-granular-policies.sql +105 -105
  146. package/.sinapse-ai/product/templates/tmpl-rls-kiss-policy.sql +11 -11
  147. package/.sinapse-ai/product/templates/tmpl-rls-roles.sql +136 -136
  148. package/.sinapse-ai/product/templates/tmpl-rls-simple.sql +78 -78
  149. package/.sinapse-ai/product/templates/tmpl-rls-tenant.sql +153 -153
  150. package/.sinapse-ai/product/templates/tmpl-rollback-script.sql +78 -78
  151. package/.sinapse-ai/product/templates/tmpl-seed-data.sql +141 -141
  152. package/.sinapse-ai/product/templates/tmpl-smoke-test.sql +17 -17
  153. package/.sinapse-ai/product/templates/tmpl-staging-copy-merge.sql +140 -140
  154. package/.sinapse-ai/product/templates/tmpl-stored-proc.sql +141 -141
  155. package/.sinapse-ai/product/templates/tmpl-trigger.sql +153 -153
  156. package/.sinapse-ai/product/templates/tmpl-view-materialized.sql +134 -134
  157. package/.sinapse-ai/product/templates/tmpl-view.sql +178 -178
  158. package/.sinapse-ai/scripts/diagnostics/health-dashboard/package-lock.json +427 -355
  159. package/LICENSE +34 -34
  160. package/README.en.md +167 -20
  161. package/README.md +190 -22
  162. package/bin/cli.js +510 -196
  163. package/bin/postinstall.js +564 -0
  164. package/bin/sinapse-cli +283 -283
  165. package/bin/sinapse-graph.js +9 -0
  166. package/bin/sinapse-init.js +36 -4
  167. package/bin/sinapse-minimal.js +20 -9
  168. package/bin/sinapse.js +202 -122
  169. package/bin/utils/deprecation-warning.js +46 -0
  170. package/bin/utils/pre-push-safety.js +14 -0
  171. package/docs/TELEMETRY.md +131 -0
  172. package/docs/chrome-brain-upgrade-plan.md +624 -0
  173. package/docs/framework/orqx-plan.md +1 -1
  174. package/docs/installation/chrome-brain.md +17 -7
  175. package/docs/mega-upgrade-orchestration-plan.md +71 -0
  176. package/docs/pt/contributing.md +20 -0
  177. package/docs/research-synthesis-for-upgrade.md +511 -0
  178. package/docs/security-audit-report.md +306 -0
  179. package/package.json +20 -8
  180. package/packages/installer/src/config/configure-environment.js +19 -44
  181. package/packages/installer/src/detection/detect-project-type.js +181 -63
  182. package/packages/installer/src/installer/manifest-signature.js +32 -17
  183. package/packages/installer/src/wizard/i18n.js +12 -0
  184. package/packages/installer/src/wizard/ide-config-generator.js +8 -39
  185. package/packages/installer/src/wizard/index.js +119 -14
  186. package/packages/installer/src/wizard/questions.js +2 -3
  187. package/packages/installer/tests/integration/environment-configuration.test.js +7 -5
  188. package/packages/installer/tests/unit/detection/detect-project-type.test.js +138 -1
  189. package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +3 -3
  190. package/packages/sinapse-install/bin/edmcp.js +0 -0
  191. package/packages/sinapse-install/bin/sinapse-install.js +0 -0
  192. package/packages/sinapse-pro-cli/bin/sinapse-pro.js +0 -0
  193. package/scripts/check-markdown-links.py +353 -353
  194. package/scripts/coverage-report-summary.js +169 -0
  195. package/scripts/generate-install-manifest.js +6 -2
  196. package/scripts/release-readiness.js +169 -0
  197. package/scripts/test-install-matrix-local.sh +153 -0
  198. package/scripts/validate-install-docs.js +394 -0
  199. package/scripts/validate-no-external-refs.js +376 -0
  200. package/scripts/validate-squad-orqx.js +302 -0
  201. package/scripts/validate-story-meta.js +263 -0
  202. package/squads/claude-code-mastery/CHANGELOG.md +1 -1
  203. package/squads/claude-code-mastery/README.md +2 -2
  204. package/squads/claude-code-mastery/squad.yaml +1 -1
  205. package/squads/squad-artdir/README.md +90 -0
  206. package/squads/squad-artdir/agents/accessibility-guardian.md +184 -0
  207. package/squads/squad-artdir/agents/artdir-orqx.md +145 -0
  208. package/squads/squad-artdir/agents/color-psychologist.md +166 -0
  209. package/squads/squad-artdir/agents/cro-persuasion.md +161 -0
  210. package/squads/squad-artdir/agents/design-system-architect.md +100 -0
  211. package/squads/squad-artdir/agents/ia-architect.md +169 -0
  212. package/squads/squad-artdir/agents/interaction-designer.md +162 -0
  213. package/squads/squad-artdir/agents/layout-engineer.md +163 -0
  214. package/squads/squad-artdir/agents/motion-architect.md +185 -0
  215. package/squads/squad-artdir/agents/platform-aesthetic-director.md +84 -0
  216. package/squads/squad-artdir/agents/premium-packaging-strategist.md +107 -0
  217. package/squads/squad-artdir/agents/product-surface-director.md +86 -0
  218. package/squads/squad-artdir/agents/type-systemist.md +138 -0
  219. package/squads/squad-artdir/agents/visual-strategist.md +127 -0
  220. package/squads/squad-artdir/checklists/seven-pillars-validation-checklist.md +172 -0
  221. package/squads/squad-artdir/knowledge-base/case-nyo-ia-reference.md +289 -0
  222. package/squads/squad-artdir/knowledge-base/deliverables-templates.md +457 -0
  223. package/squads/squad-artdir/knowledge-base/motion-technique-catalog.md +247 -0
  224. package/squads/squad-artdir/knowledge-base/premium-packaging-principles.md +133 -0
  225. package/squads/squad-artdir/knowledge-base/psychological-toolkit.md +229 -0
  226. package/squads/squad-artdir/knowledge-base/saas-art-direction-canon.md +242 -0
  227. package/squads/squad-artdir/knowledge-base/seven-pillars-framework.md +289 -0
  228. package/squads/squad-artdir/knowledge-base/ten-pillars-framework.md +221 -0
  229. package/squads/squad-artdir/package.json +20 -0
  230. package/squads/squad-artdir/squad.yaml +271 -0
  231. package/squads/squad-artdir/tasks/audit-conversion.md +97 -0
  232. package/squads/squad-artdir/tasks/audit-drift-multi-surface.md +55 -0
  233. package/squads/squad-artdir/tasks/consult-saas-canon.md +54 -0
  234. package/squads/squad-artdir/tasks/create-art-direction-brief.md +110 -0
  235. package/squads/squad-artdir/tasks/create-premium-packaging-brief.md +61 -0
  236. package/squads/squad-artdir/tasks/create-wireflow.md +84 -0
  237. package/squads/squad-artdir/tasks/design-color-system.md +81 -0
  238. package/squads/squad-artdir/tasks/design-product-surface.md +60 -0
  239. package/squads/squad-artdir/tasks/design-token-system.md +58 -0
  240. package/squads/squad-artdir/tasks/diagnose-visual-language.md +92 -0
  241. package/squads/squad-artdir/tasks/first-5-minutes-choreography.md +65 -0
  242. package/squads/squad-artdir/tasks/specify-motion-system.md +84 -0
  243. package/squads/squad-artdir/tasks/validate-against-pillars.md +143 -0
  244. package/squads/squad-artdir/templates/art-direction-brief-template.md +215 -0
  245. package/squads/squad-artdir/workflows/conversion-audit-cycle.yaml +78 -0
  246. package/squads/squad-artdir/workflows/full-art-direction-cycle.yaml +98 -0
  247. package/squads/squad-artdir/workflows/saas-platform-art-direction-cycle.yaml +174 -0
  248. package/squads/squad-brand/knowledge-base/ai-visual-generation-canon.md +234 -0
  249. package/squads/squad-brand/squad.yaml +20 -6
  250. package/squads/squad-claude/knowledge-base/context-window-optimization.md +1 -1
  251. package/squads/squad-claude/knowledge-base/swarm-orchestration-patterns.md +2 -2
  252. package/squads/squad-content/knowledge-base/ai-native-content-loop.md +220 -0
  253. package/squads/squad-content/knowledge-base/signal-intelligence-v2.md +234 -0
  254. package/squads/squad-content/knowledge-base/task-ownership-map.md +235 -0
  255. package/squads/squad-content/squad.yaml +187 -27
  256. package/squads/squad-copy/knowledge-base/ai-copy-human-loop-canon.md +235 -0
  257. package/squads/squad-copy/squad.yaml +19 -4
  258. package/squads/squad-design/knowledge-base/cross-surface-token-canon.md +209 -0
  259. package/squads/squad-design/squad.yaml +19 -4
  260. package/.sinapse-ai/core/registry/service-registry.json +0 -6346
  261. package/.sinapse-ai/data/registry-update-log.jsonl +0 -1323
  262. package/.sinapse-ai/manifests/agents.csv +0 -29
  263. package/.sinapse-ai/manifests/tasks.csv +0 -204
  264. package/.sinapse-ai/manifests/workers.csv +0 -196
  265. package/squads/squad-growth/tasks/calculate-sample-size.md +0 -121
  266. package/squads/squad-paidmedia/tasks/calculate-sample-size.md +0 -57
package/.claude/CLAUDE.md CHANGED
@@ -87,11 +87,17 @@ Use Grep (not grep), Read (not cat), Edit (not sed), Glob (not find). Prefer nat
87
87
  - Agent memory in `.sinapse-ai/development/agents/{id}/MEMORY.md`
88
88
  - **Memory as hints:** Memory entries are hints, NOT ground truth. Always verify against actual codebase before acting on remembered facts.
89
89
 
90
- ## Delegation Model
90
+ ## Token Economy & Response Format (NON-NEGOTIABLE)
91
91
 
92
- - **Persona switch:** For sequential agent work in same context (lightweight)
93
- - **Sub-agent (Agent tool):** Only for parallel/isolated work (min ~20K tokens overhead)
94
- - **Never** spawn sub-agents for simple sequential tasks — use persona switch instead
92
+ Auto-applied to all agents: `~/.claude/rules/token-economy.md` + `~/.claude/rules/response-format.md`. Compact at 60%, model route haiku/sonnet/opus, no preamble, no trailing summary.
93
+
94
+ ## Delegation & Anti-Hallucination
95
+
96
+ - Persona switch for sequential work, sub-agent only for parallel (20K+ tokens each)
97
+ - Model routing: `haiku` routine, `sonnet` standard, `opus` complex
98
+ - Sub-agents announce their model for visual verification via statusline
99
+ - `npm view {pkg}` before adding deps. Cite file:line for claims.
100
+ - Mark uncertain claims with [NEEDS VERIFICATION]. Compact at 60%.
95
101
 
96
102
  ---
97
103
  *SINAPSE v6.0 — CLI First | Observability Second | UI Third*
@@ -1,197 +1,197 @@
1
- #!/usr/bin/env python3
2
- """
3
- Hook: Enforce Architecture-First Development
4
-
5
- REGRA: Código só pode ser criado/editado se existir documentação prévia.
6
-
7
- Este hook intercepta Write/Edit em paths de código e verifica se existe
8
- documentação aprovada antes de permitir a operação.
9
-
10
- Exit Codes:
11
- - 0: Permitido (doc existe ou path não requer doc)
12
- - 2: Bloqueado (doc não existe para path protegido)
13
- """
14
-
15
- import json
16
- import sys
17
- import os
18
- from pathlib import Path
19
-
20
- # =============================================================================
21
- # CONFIGURAÇÃO: Paths que EXIGEM documentação prévia
22
- # =============================================================================
23
-
24
- PROTECTED_PATHS = [
25
- # Edge Functions - exigem docs/architecture/{function-name}.md
26
- {
27
- "pattern": "supabase/functions/",
28
- "doc_patterns": [
29
- "docs/architecture/{name}.md",
30
- "docs/architecture/{name}-architecture.md",
31
- "docs/approved-plans/{name}.md",
32
- ],
33
- "extract_name": lambda p: p.split("supabase/functions/")[1].split("/")[0] if "supabase/functions/" in p else None,
34
- },
35
- # Migrations - exigem documentação de schema changes
36
- {
37
- "pattern": "supabase/migrations/",
38
- "doc_patterns": [
39
- "docs/approved-plans/migration-{name}.md",
40
- "docs/architecture/database-changes.md",
41
- ],
42
- "extract_name": lambda p: Path(p).stem if "supabase/migrations/" in p else None,
43
- "allow_if_exists": True, # Permite editar migrations existentes
44
- },
45
- ]
46
-
47
- # Paths que são SEMPRE permitidos (não exigem doc)
48
- ALWAYS_ALLOWED = [
49
- ".claude/",
50
- "docs/",
51
- "outputs/",
52
- "squads/",
53
- ".sinapse-ai/",
54
- ".sinapse-custom/",
55
- "node_modules/",
56
- ".git/",
57
- "package.json",
58
- "package-lock.json",
59
- "tsconfig.json",
60
- ".env",
61
- "README.md",
62
- ]
63
-
64
- # =============================================================================
65
- # LÓGICA DO HOOK
66
- # =============================================================================
67
-
68
- def get_project_root():
69
- """Obtém o root do projeto via variável de ambiente ou cwd."""
70
- return os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
71
-
72
- def is_always_allowed(file_path: str) -> bool:
73
- """Verifica se o path está na lista de sempre permitidos."""
74
- for allowed in ALWAYS_ALLOWED:
75
- if allowed in file_path:
76
- return True
77
- return False
78
-
79
- def find_matching_protection(file_path: str) -> dict | None:
80
- """Encontra a regra de proteção que corresponde ao path."""
81
- for protection in PROTECTED_PATHS:
82
- if protection["pattern"] in file_path:
83
- return protection
84
- return None
85
-
86
- def check_documentation_exists(file_path: str, protection: dict, project_root: str) -> tuple[bool, str]:
87
- """
88
- Verifica se existe documentação para o path protegido.
89
-
90
- Returns:
91
- (exists: bool, doc_path: str | None)
92
- """
93
- extract_fn = protection.get("extract_name")
94
- if not extract_fn:
95
- return True, None
96
-
97
- name = extract_fn(file_path)
98
- if not name:
99
- return True, None
100
-
101
- # Verificar cada padrão de documentação
102
- for doc_pattern in protection["doc_patterns"]:
103
- doc_path = doc_pattern.format(name=name)
104
- full_doc_path = os.path.join(project_root, doc_path)
105
-
106
- if os.path.exists(full_doc_path):
107
- return True, doc_path
108
-
109
- # Se allow_if_exists e o arquivo já existe, permitir edição
110
- if protection.get("allow_if_exists"):
111
- full_file_path = os.path.join(project_root, file_path) if not file_path.startswith("/") else file_path
112
- if os.path.exists(full_file_path):
113
- return True, "(arquivo existente)"
114
-
115
- return False, None
116
-
117
- def format_required_docs(protection: dict, name: str) -> str:
118
- """Formata a lista de documentos aceitos."""
119
- docs = []
120
- for pattern in protection["doc_patterns"]:
121
- docs.append(f" - {pattern.format(name=name)}")
122
- return "\n".join(docs)
123
-
124
- def main():
125
- # Ler input do stdin
126
- try:
127
- input_data = json.load(sys.stdin)
128
- except json.JSONDecodeError:
129
- # Se não conseguir parsear, permitir (fail-open)
130
- sys.exit(0)
131
-
132
- tool_name = input_data.get("tool_name", "")
133
- tool_input = input_data.get("tool_input", {})
134
- file_path = tool_input.get("file_path", "")
135
-
136
- # Só processar Write e Edit
137
- if tool_name not in ["Write", "Edit"]:
138
- sys.exit(0)
139
-
140
- # Normalizar path (remover prefixo absoluto se presente)
141
- project_root = get_project_root()
142
- relative_path = file_path
143
- if file_path.startswith(project_root):
144
- relative_path = file_path[len(project_root):].lstrip("/")
145
-
146
- # Verificar se é sempre permitido
147
- if is_always_allowed(relative_path):
148
- sys.exit(0)
149
-
150
- # Verificar se path está protegido
151
- protection = find_matching_protection(relative_path)
152
- if not protection:
153
- # Path não protegido, permitir
154
- sys.exit(0)
155
-
156
- # Verificar se documentação existe
157
- doc_exists, doc_path = check_documentation_exists(relative_path, protection, project_root)
158
-
159
- if doc_exists:
160
- # Documentação existe, permitir
161
- sys.exit(0)
162
-
163
- # BLOQUEAR: Documentação não existe
164
- name = protection["extract_name"](relative_path) or "unknown"
165
- required_docs = format_required_docs(protection, name)
166
-
167
- error_message = f"""
168
- ╔══════════════════════════════════════════════════════════════════════════════╗
169
- ║ 🛑 ARCHITECTURE-FIRST: Documentação obrigatória antes de código ║
170
- ╠══════════════════════════════════════════════════════════════════════════════╣
171
- ║ ║
172
- ║ Arquivo bloqueado: {relative_path[:50]:<50} ║
173
- ║ ║
174
- ║ REGRA: Antes de criar/editar código em paths protegidos, você DEVE: ║
175
- ║ ║
176
- ║ 1. Documentar o plano de arquitetura ║
177
- ║ 2. Obter aprovação do usuário ║
178
- ║ 3. Criar o arquivo de documentação ║
179
- ║ ║
180
- ║ Documentos aceitos para '{name}': ║
181
- {required_docs}
182
- ║ ║
183
- ║ AÇÃO: Crie um dos documentos acima com o plano aprovado, depois tente ║
184
- ║ novamente a operação de código. ║
185
- ║ ║
186
- ║ DICA: Use `*create-doc architecture` para criar doc de arquitetura ║
187
- ║ Ou crie docs/approved-plans/{name}.md com o plano resumido ║
188
- ║ ║
189
- ╚══════════════════════════════════════════════════════════════════════════════╝
190
- """
191
-
192
- print(error_message, file=sys.stderr)
193
- sys.exit(2) # Exit code 2 = bloqueia o tool
194
-
195
- if __name__ == "__main__":
196
- main()
197
-
1
+ #!/usr/bin/env python3
2
+ """
3
+ Hook: Enforce Architecture-First Development
4
+
5
+ REGRA: Código só pode ser criado/editado se existir documentação prévia.
6
+
7
+ Este hook intercepta Write/Edit em paths de código e verifica se existe
8
+ documentação aprovada antes de permitir a operação.
9
+
10
+ Exit Codes:
11
+ - 0: Permitido (doc existe ou path não requer doc)
12
+ - 2: Bloqueado (doc não existe para path protegido)
13
+ """
14
+
15
+ import json
16
+ import sys
17
+ import os
18
+ from pathlib import Path
19
+
20
+ # =============================================================================
21
+ # CONFIGURAÇÃO: Paths que EXIGEM documentação prévia
22
+ # =============================================================================
23
+
24
+ PROTECTED_PATHS = [
25
+ # Edge Functions - exigem docs/architecture/{function-name}.md
26
+ {
27
+ "pattern": "supabase/functions/",
28
+ "doc_patterns": [
29
+ "docs/architecture/{name}.md",
30
+ "docs/architecture/{name}-architecture.md",
31
+ "docs/approved-plans/{name}.md",
32
+ ],
33
+ "extract_name": lambda p: p.split("supabase/functions/")[1].split("/")[0] if "supabase/functions/" in p else None,
34
+ },
35
+ # Migrations - exigem documentação de schema changes
36
+ {
37
+ "pattern": "supabase/migrations/",
38
+ "doc_patterns": [
39
+ "docs/approved-plans/migration-{name}.md",
40
+ "docs/architecture/database-changes.md",
41
+ ],
42
+ "extract_name": lambda p: Path(p).stem if "supabase/migrations/" in p else None,
43
+ "allow_if_exists": True, # Permite editar migrations existentes
44
+ },
45
+ ]
46
+
47
+ # Paths que são SEMPRE permitidos (não exigem doc)
48
+ ALWAYS_ALLOWED = [
49
+ ".claude/",
50
+ "docs/",
51
+ "outputs/",
52
+ "squads/",
53
+ ".sinapse-ai/",
54
+ ".sinapse-custom/",
55
+ "node_modules/",
56
+ ".git/",
57
+ "package.json",
58
+ "package-lock.json",
59
+ "tsconfig.json",
60
+ ".env",
61
+ "README.md",
62
+ ]
63
+
64
+ # =============================================================================
65
+ # LÓGICA DO HOOK
66
+ # =============================================================================
67
+
68
+ def get_project_root():
69
+ """Obtém o root do projeto via variável de ambiente ou cwd."""
70
+ return os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
71
+
72
+ def is_always_allowed(file_path: str) -> bool:
73
+ """Verifica se o path está na lista de sempre permitidos."""
74
+ for allowed in ALWAYS_ALLOWED:
75
+ if allowed in file_path:
76
+ return True
77
+ return False
78
+
79
+ def find_matching_protection(file_path: str) -> dict | None:
80
+ """Encontra a regra de proteção que corresponde ao path."""
81
+ for protection in PROTECTED_PATHS:
82
+ if protection["pattern"] in file_path:
83
+ return protection
84
+ return None
85
+
86
+ def check_documentation_exists(file_path: str, protection: dict, project_root: str) -> tuple[bool, str]:
87
+ """
88
+ Verifica se existe documentação para o path protegido.
89
+
90
+ Returns:
91
+ (exists: bool, doc_path: str | None)
92
+ """
93
+ extract_fn = protection.get("extract_name")
94
+ if not extract_fn:
95
+ return True, None
96
+
97
+ name = extract_fn(file_path)
98
+ if not name:
99
+ return True, None
100
+
101
+ # Verificar cada padrão de documentação
102
+ for doc_pattern in protection["doc_patterns"]:
103
+ doc_path = doc_pattern.format(name=name)
104
+ full_doc_path = os.path.join(project_root, doc_path)
105
+
106
+ if os.path.exists(full_doc_path):
107
+ return True, doc_path
108
+
109
+ # Se allow_if_exists e o arquivo já existe, permitir edição
110
+ if protection.get("allow_if_exists"):
111
+ full_file_path = os.path.join(project_root, file_path) if not file_path.startswith("/") else file_path
112
+ if os.path.exists(full_file_path):
113
+ return True, "(arquivo existente)"
114
+
115
+ return False, None
116
+
117
+ def format_required_docs(protection: dict, name: str) -> str:
118
+ """Formata a lista de documentos aceitos."""
119
+ docs = []
120
+ for pattern in protection["doc_patterns"]:
121
+ docs.append(f" - {pattern.format(name=name)}")
122
+ return "\n".join(docs)
123
+
124
+ def main():
125
+ # Ler input do stdin
126
+ try:
127
+ input_data = json.load(sys.stdin)
128
+ except json.JSONDecodeError:
129
+ # Se não conseguir parsear, permitir (fail-open)
130
+ sys.exit(0)
131
+
132
+ tool_name = input_data.get("tool_name", "")
133
+ tool_input = input_data.get("tool_input", {})
134
+ file_path = tool_input.get("file_path", "")
135
+
136
+ # Só processar Write e Edit
137
+ if tool_name not in ["Write", "Edit"]:
138
+ sys.exit(0)
139
+
140
+ # Normalizar path (remover prefixo absoluto se presente)
141
+ project_root = get_project_root()
142
+ relative_path = file_path
143
+ if file_path.startswith(project_root):
144
+ relative_path = file_path[len(project_root):].lstrip("/")
145
+
146
+ # Verificar se é sempre permitido
147
+ if is_always_allowed(relative_path):
148
+ sys.exit(0)
149
+
150
+ # Verificar se path está protegido
151
+ protection = find_matching_protection(relative_path)
152
+ if not protection:
153
+ # Path não protegido, permitir
154
+ sys.exit(0)
155
+
156
+ # Verificar se documentação existe
157
+ doc_exists, doc_path = check_documentation_exists(relative_path, protection, project_root)
158
+
159
+ if doc_exists:
160
+ # Documentação existe, permitir
161
+ sys.exit(0)
162
+
163
+ # BLOQUEAR: Documentação não existe
164
+ name = protection["extract_name"](relative_path) or "unknown"
165
+ required_docs = format_required_docs(protection, name)
166
+
167
+ error_message = f"""
168
+ ╔══════════════════════════════════════════════════════════════════════════════╗
169
+ ║ 🛑 ARCHITECTURE-FIRST: Documentação obrigatória antes de código ║
170
+ ╠══════════════════════════════════════════════════════════════════════════════╣
171
+ ║ ║
172
+ ║ Arquivo bloqueado: {relative_path[:50]:<50} ║
173
+ ║ ║
174
+ ║ REGRA: Antes de criar/editar código em paths protegidos, você DEVE: ║
175
+ ║ ║
176
+ ║ 1. Documentar o plano de arquitetura ║
177
+ ║ 2. Obter aprovação do usuário ║
178
+ ║ 3. Criar o arquivo de documentação ║
179
+ ║ ║
180
+ ║ Documentos aceitos para '{name}': ║
181
+ {required_docs}
182
+ ║ ║
183
+ ║ AÇÃO: Crie um dos documentos acima com o plano aprovado, depois tente ║
184
+ ║ novamente a operação de código. ║
185
+ ║ ║
186
+ ║ DICA: Use `*create-doc architecture` para criar doc de arquitetura ║
187
+ ║ Ou crie docs/approved-plans/{name}.md com o plano resumido ║
188
+ ║ ║
189
+ ╚══════════════════════════════════════════════════════════════════════════════╝
190
+ """
191
+
192
+ print(error_message, file=sys.stderr)
193
+ sys.exit(2) # Exit code 2 = bloqueia o tool
194
+
195
+ if __name__ == "__main__":
196
+ main()
197
+
@@ -1,13 +1,34 @@
1
1
  #!/bin/bash
2
2
  # enforce-git-push-authority.sh
3
- # PreToolUse hook: blocks "git push" commands in Bash tool
4
- # Only meant to run when agent is NOT @devops
3
+ # PreToolUse hook: blocks "git push" commands in Bash tool unless active agent is @devops
4
+ # Detects active agent via .sinapse/session-state.json (same pattern as enforce-delegation.cjs)
5
5
  # Uses node (not jq) for JSON parsing — works on Windows/Git Bash
6
- # FAIL-CLOSED: if parsing fails, blocks the command (exit 2)
7
- # Hardened v2: also detects indirect execution via script files and pipes
6
+ # FAIL-CLOSED: if parsing fails OR session-state is missing/unreadable, blocks the command
7
+ # Hardened v3: adds real agent detection (Story 10.15), retains indirect-execution checks
8
8
 
9
9
  INPUT=$(cat)
10
10
 
11
+ # Resolve project root consistently with other hooks
12
+ PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
13
+
14
+ # Detect active agent from session state (fail-closed: empty string on any error)
15
+ AGENT=$(node -e "
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ try {
19
+ const p = path.join(process.argv[1], '.sinapse', 'session-state.json');
20
+ const s = JSON.parse(fs.readFileSync(p, 'utf8'));
21
+ console.log(s.lastAgent || '');
22
+ } catch (e) {
23
+ console.log('');
24
+ }
25
+ " "$PROJECT_ROOT" 2>/dev/null)
26
+
27
+ # If active agent is @devops, allow the command immediately (AC 1)
28
+ if [ "$AGENT" = "devops" ]; then
29
+ exit 0
30
+ fi
31
+
11
32
  # Extract command from JSON using node (available on all SINAPSE systems)
12
33
  COMMAND=$(echo "$INPUT" | node -e "
13
34
  let d='';