sinapse-ai 1.16.0 → 1.19.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.
- package/.claude/hooks/doc-first-gate.cjs +156 -0
- package/.claude/hooks/enforce-story-gate.cjs +6 -2
- package/.claude/rules/documentation-first.md +6 -0
- package/.claude/rules/hook-governance.md +1 -0
- package/.sinapse-ai/constitution.md +3 -3
- package/.sinapse-ai/core/atlas/atlas-data.js +278 -0
- package/.sinapse-ai/core/atlas/flows-pt.js +253 -0
- package/.sinapse-ai/core/atlas/flows.js +266 -0
- package/.sinapse-ai/core/atlas/index.js +62 -0
- package/.sinapse-ai/core/atlas/render-html.js +216 -0
- package/.sinapse-ai/core/atlas/render-markdown.js +313 -0
- package/.sinapse-ai/core/atlas/render-research-card.js +164 -0
- package/.sinapse-ai/core/code-intel/registry-syncer.js +5 -3
- package/.sinapse-ai/core/doctor/checks/agent-memory.js +7 -5
- package/.sinapse-ai/core/doctor/checks/claude-md.js +13 -0
- package/.sinapse-ai/core/doctor/checks/constitution-consistency.js +1 -0
- package/.sinapse-ai/core/doctor/checks/hooks-claude-count.js +11 -0
- package/.sinapse-ai/core/doctor/checks/settings-json.js +16 -2
- package/.sinapse-ai/core/doctor/index.js +27 -0
- package/.sinapse-ai/core/execution/build-orchestrator.js +192 -8
- package/.sinapse-ai/core/external-executors/delegate-cli.js +6 -2
- package/.sinapse-ai/core/health-check/checks/project/constitution-consistency.js +2 -1
- package/.sinapse-ai/core/ideation/ideation-engine.js +10 -8
- package/.sinapse-ai/core/mcp/config-migrator.js +8 -5
- package/.sinapse-ai/core/mcp/global-config-manager.js +4 -1
- package/.sinapse-ai/core/mcp/symlink-manager.js +6 -3
- package/.sinapse-ai/core/orchestration/brownfield-handler.js +5 -4
- package/.sinapse-ai/core/orchestration/build-command.js +136 -0
- package/.sinapse-ai/core/orchestration/doc-first-resolver.js +322 -0
- package/.sinapse-ai/core/orchestration/executors/epic-4-executor.js +3 -0
- package/.sinapse-ai/core/orchestration/gate-evaluator.js +58 -9
- package/.sinapse-ai/core/orchestration/route-command.js +97 -0
- package/.sinapse-ai/core/orchestration/session-state.js +19 -2
- package/.sinapse-ai/core/orchestration/terminal-spawner.js +24 -1
- package/.sinapse-ai/core/orchestration/workflow-executor.js +102 -3
- package/.sinapse-ai/core/quality-gates/focus-area-recommender.js +15 -11
- package/.sinapse-ai/core/registry/build-registry.js +3 -2
- package/.sinapse-ai/core/synapse/scripts/generate-constitution.js +1 -0
- package/.sinapse-ai/core/synapse/utils/atomic-write.js +34 -9
- package/.sinapse-ai/core-config.yaml +5 -1
- package/.sinapse-ai/data/capability-detection.js +3 -3
- package/.sinapse-ai/data/entity-registry.yaml +288 -90
- package/.sinapse-ai/data/mcp-discipline.js +1 -1
- package/.sinapse-ai/data/mcp-tool-examples.yaml +8 -8
- package/.sinapse-ai/data/tok2-validation.js +1 -1
- package/.sinapse-ai/data/tool-registry.yaml +4 -3
- package/.sinapse-ai/development/agents/snps-orqx.md +14 -5
- package/.sinapse-ai/development/scripts/migrate-task-to-v2.js +1 -1
- package/.sinapse-ai/development/scripts/validate-task-v2.js +67 -4
- package/.sinapse-ai/development/tasks/advanced-elicitation.md +3 -3
- package/.sinapse-ai/development/tasks/analyst-facilitate-brainstorming.md +3 -3
- package/.sinapse-ai/development/tasks/analyze-framework.md +1 -8
- package/.sinapse-ai/development/tasks/analyze-performance.md +1 -8
- package/.sinapse-ai/development/tasks/apply-qa-fixes.md +3 -3
- package/.sinapse-ai/development/tasks/architect-analyze-impact.md +3 -3
- package/.sinapse-ai/development/tasks/audit-codebase.md +1 -8
- package/.sinapse-ai/development/tasks/audit-tailwind-config.md +1 -4
- package/.sinapse-ai/development/tasks/audit-utilities.md +1 -8
- package/.sinapse-ai/development/tasks/bootstrap-shadcn-library.md +3 -3
- package/.sinapse-ai/development/tasks/brownfield-create-epic.md +3 -3
- package/.sinapse-ai/development/tasks/brownfield-create-story.md +3 -3
- package/.sinapse-ai/development/tasks/build-component.md +2 -5
- package/.sinapse-ai/development/tasks/calculate-roi.md +3 -3
- package/.sinapse-ai/development/tasks/ci-cd-configuration.md +1 -1
- package/.sinapse-ai/development/tasks/cleanup-utilities.md +3 -3
- package/.sinapse-ai/development/tasks/collaborative-edit.md +3 -3
- package/.sinapse-ai/development/tasks/compose-molecule.md +2 -5
- package/.sinapse-ai/development/tasks/consolidate-patterns.md +3 -3
- package/.sinapse-ai/development/tasks/correct-course.md +3 -3
- package/.sinapse-ai/development/tasks/create-brownfield-story.md +2 -5
- package/.sinapse-ai/development/tasks/create-deep-research-prompt.md +2 -5
- package/.sinapse-ai/development/tasks/create-doc.md +3 -6
- package/.sinapse-ai/development/tasks/create-next-story.md +4 -8
- package/.sinapse-ai/development/tasks/create-suite.md +2 -5
- package/.sinapse-ai/development/tasks/create-task.md +2 -5
- package/.sinapse-ai/development/tasks/create-workflow.md +2 -5
- package/.sinapse-ai/development/tasks/db-analyze-hotpaths.md +1 -8
- package/.sinapse-ai/development/tasks/db-apply-migration.md +1 -8
- package/.sinapse-ai/development/tasks/db-bootstrap.md +1 -8
- package/.sinapse-ai/development/tasks/db-domain-modeling.md +1 -8
- package/.sinapse-ai/development/tasks/db-dry-run.md +1 -8
- package/.sinapse-ai/development/tasks/db-env-check.md +1 -8
- package/.sinapse-ai/development/tasks/db-explain.md +1 -8
- package/.sinapse-ai/development/tasks/db-impersonate.md +1 -8
- package/.sinapse-ai/development/tasks/db-load-csv.md +1 -8
- package/.sinapse-ai/development/tasks/db-policy-apply.md +1 -8
- package/.sinapse-ai/development/tasks/db-rls-audit.md +1 -8
- package/.sinapse-ai/development/tasks/db-rollback.md +1 -8
- package/.sinapse-ai/development/tasks/db-run-sql.md +1 -8
- package/.sinapse-ai/development/tasks/db-schema-audit.md +1 -8
- package/.sinapse-ai/development/tasks/db-seed.md +1 -8
- package/.sinapse-ai/development/tasks/db-smoke-test.md +1 -8
- package/.sinapse-ai/development/tasks/db-snapshot.md +1 -8
- package/.sinapse-ai/development/tasks/db-squad-integration.md +1 -8
- package/.sinapse-ai/development/tasks/db-supabase-setup.md +1 -8
- package/.sinapse-ai/development/tasks/db-verify-order.md +1 -8
- package/.sinapse-ai/development/tasks/deprecate-component.md +3 -3
- package/.sinapse-ai/development/tasks/dev-apply-qa-fixes.md +3 -3
- package/.sinapse-ai/development/tasks/dev-backlog-debt.md +3 -3
- package/.sinapse-ai/development/tasks/dev-develop-story.md +1 -1
- package/.sinapse-ai/development/tasks/dev-improve-code-quality.md +3 -3
- package/.sinapse-ai/development/tasks/dev-optimize-performance.md +3 -3
- package/.sinapse-ai/development/tasks/dev-suggest-refactoring.md +3 -3
- package/.sinapse-ai/development/tasks/dev-validate-next-story.md +3 -3
- package/.sinapse-ai/development/tasks/document-project.md +3 -3
- package/.sinapse-ai/development/tasks/environment-bootstrap.md +0 -4
- package/.sinapse-ai/development/tasks/execute-checklist.md +3 -3
- package/.sinapse-ai/development/tasks/export-design-tokens-dtcg.md +3 -3
- package/.sinapse-ai/development/tasks/extend-pattern.md +1 -8
- package/.sinapse-ai/development/tasks/extract-tokens.md +3 -3
- package/.sinapse-ai/development/tasks/facilitate-brainstorming-session.md +1 -1
- package/.sinapse-ai/development/tasks/generate-ai-frontend-prompt.md +2 -5
- package/.sinapse-ai/development/tasks/generate-documentation.md +2 -5
- package/.sinapse-ai/development/tasks/generate-migration-strategy.md +2 -5
- package/.sinapse-ai/development/tasks/generate-shock-report.md +2 -5
- package/.sinapse-ai/development/tasks/github-devops-github-pr-automation.md +3 -3
- package/.sinapse-ai/development/tasks/github-devops-repository-cleanup.md +3 -3
- package/.sinapse-ai/development/tasks/github-devops-version-management.md +3 -3
- package/.sinapse-ai/development/tasks/improve-self.md +1 -16
- package/.sinapse-ai/development/tasks/index-docs.md +1 -4
- package/.sinapse-ai/development/tasks/init-project-status.md +1 -7
- package/.sinapse-ai/development/tasks/integrate-squad.md +3 -3
- package/.sinapse-ai/development/tasks/kb-mode-interaction.md +3 -3
- package/.sinapse-ai/development/tasks/learn-patterns.md +3 -3
- package/.sinapse-ai/development/tasks/modify-agent.md +1 -8
- package/.sinapse-ai/development/tasks/modify-task.md +1 -8
- package/.sinapse-ai/development/tasks/modify-workflow.md +1 -8
- package/.sinapse-ai/development/tasks/po-backlog-add.md +3 -3
- package/.sinapse-ai/development/tasks/po-manage-story-backlog.md +3 -3
- package/.sinapse-ai/development/tasks/po-pull-story-from-clickup.md +3 -3
- package/.sinapse-ai/development/tasks/po-pull-story.md +3 -3
- package/.sinapse-ai/development/tasks/po-stories-index.md +3 -3
- package/.sinapse-ai/development/tasks/po-sync-story-to-clickup.md +3 -3
- package/.sinapse-ai/development/tasks/po-sync-story.md +3 -3
- package/.sinapse-ai/development/tasks/pr-automation.md +1 -1
- package/.sinapse-ai/development/tasks/propose-modification.md +3 -3
- package/.sinapse-ai/development/tasks/qa-backlog-add-followup.md +1 -8
- package/.sinapse-ai/development/tasks/qa-create-fix-request.md +1 -4
- package/.sinapse-ai/development/tasks/qa-gate.md +1 -8
- package/.sinapse-ai/development/tasks/qa-generate-tests.md +1 -8
- package/.sinapse-ai/development/tasks/qa-nfr-assess.md +1 -8
- package/.sinapse-ai/development/tasks/qa-review-proposal.md +1 -8
- package/.sinapse-ai/development/tasks/qa-review-story.md +1 -8
- package/.sinapse-ai/development/tasks/qa-risk-profile.md +1 -8
- package/.sinapse-ai/development/tasks/qa-run-tests.md +1 -8
- package/.sinapse-ai/development/tasks/qa-test-design.md +1 -8
- package/.sinapse-ai/development/tasks/qa-trace-requirements.md +1 -8
- package/.sinapse-ai/development/tasks/release-management.md +1 -1
- package/.sinapse-ai/development/tasks/security-audit.md +1 -4
- package/.sinapse-ai/development/tasks/security-scan.md +1 -4
- package/.sinapse-ai/development/tasks/setup-database.md +2 -11
- package/.sinapse-ai/development/tasks/setup-design-system.md +2 -11
- package/.sinapse-ai/development/tasks/shard-doc.md +3 -3
- package/.sinapse-ai/development/tasks/sm-create-next-story.md +3 -3
- package/.sinapse-ai/development/tasks/spec-gather-requirements.md +11 -0
- package/.sinapse-ai/development/tasks/sync-documentation.md +1 -6
- package/.sinapse-ai/development/tasks/tailwind-upgrade.md +3 -3
- package/.sinapse-ai/development/tasks/test-as-user.md +3 -3
- package/.sinapse-ai/development/tasks/undo-last.md +2 -5
- package/.sinapse-ai/development/tasks/update-manifest.md +1 -8
- package/.sinapse-ai/development/tasks/ux-create-wireframe.md +1 -1
- package/.sinapse-ai/development/tasks/ux-ds-scan-artifact.md +3 -3
- package/.sinapse-ai/development/tasks/ux-user-research.md +3 -3
- package/.sinapse-ai/development/tasks/validate-next-story.md +1 -8
- package/.sinapse-ai/development/templates/approval-table.md +106 -0
- package/.sinapse-ai/development/templates/chrome-brain/scripts/chrome-ensure.cjs +1 -1
- package/.sinapse-ai/development/workflows/spec-pipeline.yaml +1 -0
- package/.sinapse-ai/git-hooks/post-commit +0 -0
- package/.sinapse-ai/git-hooks/pre-commit +0 -0
- package/.sinapse-ai/git-hooks/pre-push +0 -0
- package/.sinapse-ai/infrastructure/scripts/changelog-generator.js +5 -1
- package/.sinapse-ai/infrastructure/scripts/pattern-extractor.js +11 -2
- package/.sinapse-ai/infrastructure/scripts/test-utilities.js +34 -13
- package/.sinapse-ai/infrastructure/scripts/usage-analytics.js +9 -5
- package/.sinapse-ai/infrastructure/scripts/validate-claude-integration.js +10 -2
- package/.sinapse-ai/install-manifest.yaml +364 -320
- package/.sinapse-ai/lib/build.json +1 -0
- package/.sinapse-ai/product/templates/personalized-task-template-v2.md +4 -2
- package/.sinapse-ai/product/templates/prd-tmpl.yaml +6 -2
- package/.sinapse-ai/product/templates/statusline/statusline-script.js +7 -3
- package/CHANGELOG.md +85 -7
- package/README.en.md +5 -5
- package/README.md +5 -5
- package/bin/cli.js +1 -1
- package/bin/commands/install.js +288 -114
- package/bin/commands/local.js +11 -0
- package/bin/lib/command-generator.js +31 -2
- package/bin/sinapse.js +121 -0
- package/docs/README.md +1 -1
- package/docs/agent-reference-guide.md +1 -1
- package/docs/community/README-community-snippet-core.md +1 -1
- package/docs/community/README-community-snippet-mcp.md +1 -1
- package/docs/community/README-community-snippet-squads.md +1 -1
- package/docs/examples/quickstart-recording.md +1 -1
- package/docs/framework/README.md +1 -1
- package/docs/framework/architecture-overview.md +1 -0
- package/docs/framework/atlas/OPERATING-ATLAS.md +537 -0
- package/docs/framework/atlas/README.md +34 -0
- package/docs/framework/atlas/atlas-data.json +2810 -0
- package/docs/framework/atlas/atlas.html +392 -0
- package/docs/framework/coding-standards.md +1 -1
- package/docs/framework/core-architecture.md +1 -1
- package/docs/framework/guiding-principles.md +1 -1
- package/docs/framework/source-tree.md +1 -1
- package/docs/framework/tech-stack.md +1 -1
- package/docs/framework/versioning-and-releases.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/guides/agent-reference.md +1 -1
- package/docs/guides/agent-selection-guide.md +1 -1
- package/docs/guides/api-reference.md +1 -1
- package/docs/guides/contextual-greeting-system-guide.md +1 -1
- package/docs/guides/contributing-squads.md +1 -1
- package/docs/guides/development-setup.md +1 -1
- package/docs/guides/git-workflow-guide.md +1 -1
- package/docs/guides/installation-troubleshooting.md +1 -1
- package/docs/guides/llm-routing.md +1 -1
- package/docs/guides/mcp-global-setup.md +1 -1
- package/docs/guides/meta-agent-commands.md +1 -1
- package/docs/guides/project-status-feature.md +1 -1
- package/docs/guides/quality-dashboard.md +1 -1
- package/docs/guides/quality-gates.md +1 -1
- package/docs/guides/security-hardening.md +1 -1
- package/docs/guides/service-discovery.md +19 -22
- package/docs/guides/squad-examples/README.md +1 -1
- package/docs/guides/squad-migration.md +1 -1
- package/docs/guides/squads-guide.md +1 -1
- package/docs/guides/squads-overview.md +10 -13
- package/docs/guides/template-engine-v2.md +1 -1
- package/docs/guides/testing-guide.md +1 -1
- package/docs/guides/user-guide.md +30 -26
- package/docs/installation/README.md +3 -3
- package/docs/installation/faq.md +1 -1
- package/docs/installation/linux.md +2 -2
- package/docs/installation/macos.md +1 -1
- package/docs/installation/npx-install.md +1 -1
- package/docs/installation/troubleshooting.md +1 -1
- package/docs/installation/uninstallation.md +1 -1
- package/docs/installation/v4-quick-start.md +1 -1
- package/docs/installation/windows.md +2 -2
- package/docs/pt/CHANGELOG.md +1 -1
- package/docs/pt/DOCUMENTATION-ROADMAP.md +1 -1
- package/docs/pt/ENVIRONMENT.md +1 -1
- package/docs/pt/FEATURE_PROCESS.md +2 -2
- package/docs/pt/GUIDING-PRINCIPLES.md +2 -2
- package/docs/pt/agent-reference-guide.md +3 -3
- package/docs/pt/architecture/ARCHITECTURE-INDEX.md +2 -2
- package/docs/pt/architecture/ade-architecture.md +1 -1
- package/docs/pt/architecture/agent-config-audit.md +1 -1
- package/docs/pt/architecture/agent-responsibility-matrix.md +1 -1
- package/docs/pt/architecture/agent-tool-integration-guide.md +1 -1
- package/docs/pt/architecture/ci-cd.md +1 -1
- package/docs/pt/architecture/coding-standards.md +1 -1
- package/docs/pt/architecture/contribution-workflow-research.md +1 -1
- package/docs/pt/architecture/dashboard-architecture.md +1 -1
- package/docs/pt/architecture/dashboard-realtime.md +1 -1
- package/docs/pt/architecture/hcs-check-specifications.md +1 -1
- package/docs/pt/architecture/hcs-execution-modes.md +1 -1
- package/docs/pt/architecture/hcs-self-healing-spec.md +1 -1
- package/docs/pt/architecture/high-level-architecture.md +1 -1
- package/docs/pt/architecture/introduction.md +1 -1
- package/docs/pt/architecture/mcp-api-keys-management.md +3 -3
- package/docs/pt/architecture/mcp-system-diagrams.md +1 -1
- package/docs/pt/architecture/module-system.md +4 -4
- package/docs/pt/architecture/multi-repo-strategy.md +2 -2
- package/docs/pt/architecture/source-tree.md +1 -1
- package/docs/pt/architecture/squad-improvement-analysis.md +1 -1
- package/docs/pt/architecture/squad-improvement-recommended-approach.md +1 -1
- package/docs/pt/architecture/tech-stack.md +1 -1
- package/docs/pt/architecture/utility-integration-guide.md +1 -1
- package/docs/pt/code-of-conduct.md +1 -1
- package/docs/pt/community/README-community-snippet-core.md +1 -1
- package/docs/pt/community/README-community-snippet-mcp.md +2 -2
- package/docs/pt/contributing.md +7 -7
- package/docs/pt/core-architecture.md +1 -1
- package/docs/pt/docker-mcp-setup.md +1 -1
- package/docs/pt/framework/README.md +1 -1
- package/docs/pt/framework/coding-standards.md +1 -1
- package/docs/pt/framework/source-tree.md +1 -1
- package/docs/pt/framework/tech-stack.md +1 -1
- package/docs/pt/getting-started.md +1 -1
- package/docs/pt/git-workflow-guide.md +1 -1
- package/docs/pt/guides/README.md +3 -3
- package/docs/pt/guides/agent-selection-guide.md +2 -2
- package/docs/pt/guides/api-reference.md +1 -1
- package/docs/pt/guides/contextual-greeting-system-guide.md +1 -1
- package/docs/pt/guides/contributing-squads.md +1 -1
- package/docs/pt/guides/development-setup.md +1 -1
- package/docs/pt/guides/installation-troubleshooting.md +1 -1
- package/docs/pt/guides/llm-routing.md +1 -1
- package/docs/pt/guides/mcp/desktop-commander.md +1 -1
- package/docs/pt/guides/mcp/docker-gateway-tutorial.md +1 -1
- package/docs/pt/guides/mcp-global-setup.md +1 -1
- package/docs/pt/guides/project-status-feature.md +1 -1
- package/docs/pt/guides/quality-dashboard.md +1 -1
- package/docs/pt/guides/quality-gates.md +1 -1
- package/docs/pt/guides/security-hardening.md +2 -2
- package/docs/pt/guides/service-discovery.md +19 -22
- package/docs/pt/guides/squad-examples/README.md +1 -1
- package/docs/pt/guides/squad-migration.md +1 -1
- package/docs/pt/guides/squads-guide.md +1 -1
- package/docs/pt/guides/squads-overview.md +11 -13
- package/docs/pt/guides/template-engine-v2.md +1 -1
- package/docs/pt/guides/testing-guide.md +3 -3
- package/docs/pt/guides/user-guide.md +30 -26
- package/docs/pt/guides/workflows-guide.md +1 -1
- package/docs/pt/how-to-contribute-with-pull-requests.md +1 -1
- package/docs/pt/ide-integration.md +2 -2
- package/docs/pt/installation/README.md +1 -1
- package/docs/pt/installation/faq.md +1 -1
- package/docs/pt/installation/linux.md +1 -1
- package/docs/pt/installation/macos.md +1 -1
- package/docs/pt/installation/troubleshooting.md +1 -1
- package/docs/pt/installation/v4-quick-start.md +1 -1
- package/docs/pt/installation/windows.md +1 -1
- package/docs/pt/meta-agent-commands.md +1 -1
- package/docs/pt/migration-guide.md +1 -1
- package/docs/pt/npx-install.md +1 -1
- package/docs/pt/performance-tuning-guide.md +1 -1
- package/docs/pt/platforms/claude-code.md +2 -2
- package/docs/pt/roadmap.md +2 -2
- package/docs/pt/security-best-practices.md +2 -2
- package/docs/pt/security.md +1 -1
- package/docs/pt/sinapse-nomenclature-specification.md +1 -1
- package/docs/pt/troubleshooting.md +1 -1
- package/docs/pt/uninstallation.md +1 -1
- package/docs/pt/versioning-and-releases.md +1 -1
- package/docs/security/overview.md +1 -1
- package/docs/security/security-best-practices.md +2 -2
- package/docs/sinapse-workflows/README.md +1 -1
- package/package.json +2 -1
- package/packages/installer/package.json +1 -0
- package/packages/installer/src/wizard/feedback.js +18 -2
- package/packages/installer/src/wizard/i18n.js +78 -0
- package/packages/installer/src/wizard/ide-config-generator.js +14 -9
- package/packages/installer/src/wizard/index.js +16 -16
- package/packages/installer/src/wizard/validation/report-generator.js +22 -21
- package/packages/installer/src/wizard/validation/troubleshooting-system.js +19 -13
- package/scripts/gen-agent-badges.js +1 -1
- package/scripts/install-chrome-brain.sh +2 -2
- package/scripts/package-synapse.js +14 -5
- package/scripts/prepare-hooks.js +19 -0
- package/scripts/validate-agent-codenames.js +174 -0
- package/scripts/validate-all.js +1 -0
- package/scripts/validate-no-personal-leaks.js +24 -9
- package/sinapse/agents/sinapse-orqx.md +5 -5
- package/sinapse/agents/snps-orqx.md +5 -5
- package/squads/squad-brand/agents/brand-creative-engineer.md +5 -5
- package/squads/squad-brand/squad.yaml +6 -6
- package/squads/squad-content/agents/content-engineer.md +7 -7
- package/squads/squad-content/squad.yaml +5 -5
- package/squads/squad-copy/knowledge-base/consequence-headline-patterns.md +2 -2
- package/squads/squad-courses/agents/production-director.md +5 -5
- package/squads/squad-courses/squad.yaml +1 -1
- package/docs/guides/hooks-two-layers.md +0 -66
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render — SINAPSE research card (PT-BR).
|
|
3
|
+
*
|
|
4
|
+
* Emits the SINAPSE framework as a case-study card in the same template as the
|
|
5
|
+
* engineering-software research corpus (domain cards + LOOPS-*-diagramas.md),
|
|
6
|
+
* fully in Portuguese. One source (the live atlas `data` + flows-pt translations)
|
|
7
|
+
* → two markdown files, so the card never drifts from how the framework actually
|
|
8
|
+
* works. Regenerated by `sinapse atlas --research-card`.
|
|
9
|
+
*
|
|
10
|
+
* Pure string builder: no fs, no Date — caller passes data.generatedAt and writes.
|
|
11
|
+
*
|
|
12
|
+
* @module core/atlas/render-research-card
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const { FRAMEWORK_FLOWS_PT } = require('./flows-pt');
|
|
18
|
+
|
|
19
|
+
/** Roman-numeral severity → short PT label is not needed; severity is kept verbatim. */
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Build the SINAPSE case-study card markdown (PT-BR).
|
|
23
|
+
* @param {object} data - atlas data (buildAtlasData output)
|
|
24
|
+
* @param {Record<string,object>} pt - flow id → PT translation
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
function buildCard(data, pt) {
|
|
28
|
+
const c = data.counts;
|
|
29
|
+
const date = (data.generatedAt || '').slice(0, 10);
|
|
30
|
+
const flows = data.flows || [];
|
|
31
|
+
|
|
32
|
+
const flowList = flows
|
|
33
|
+
.map((f) => {
|
|
34
|
+
const t = pt[f.id] || { titulo: f.title, proposito: f.purpose };
|
|
35
|
+
return `- **${t.titulo}** — ${t.proposito}`;
|
|
36
|
+
})
|
|
37
|
+
.join('\n');
|
|
38
|
+
|
|
39
|
+
const articleRows = (data.articles || [])
|
|
40
|
+
.map((a) => `| ${a.number} | ${a.title} | ${a.severity} |`)
|
|
41
|
+
.join('\n');
|
|
42
|
+
|
|
43
|
+
return `---
|
|
44
|
+
titulo: "SINAPSE — Framework de Engenharia Orientada por IA (estudo de caso)"
|
|
45
|
+
tipo: estudo-de-caso
|
|
46
|
+
dominio: sinapse-framework
|
|
47
|
+
status: instancia-viva
|
|
48
|
+
prioridade: alta
|
|
49
|
+
created: ${date}
|
|
50
|
+
gerado_por: "sinapse atlas --research-card (auto-regenerável a partir do disco)"
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
# SINAPSE — Framework de Engenharia Orientada por IA
|
|
54
|
+
|
|
55
|
+
> O SINAPSE é a instância viva dos domínios desta pesquisa: um meta-framework que impõe processo (spec antes de código, gates inegociáveis, delegação a especialistas) e orquestra ${c.agentsTotal} agentes em ${c.squads} squads para construir software com rigor.
|
|
56
|
+
> Este card é gerado do próprio framework (\`sinapse atlas\`), então descreve o que ele **realmente** faz hoje — não uma intenção desatualizada.
|
|
57
|
+
|
|
58
|
+
## Por que este estudo de caso importa
|
|
59
|
+
|
|
60
|
+
Os ${60} domínios desta pesquisa descrevem **como** construir software de qualidade com IA. O SINAPSE é uma resposta concreta a "como operacionalizar tudo isso de forma reproduzível": transforma princípios (Building Effective Agents, spec-driven development, context engineering, evals como gate) em **enforcement automático** — hooks que bloqueiam, gates que barram, orquestradores que delegam. Ler este card lado a lado com os domínios mostra a ponte entre teoria de engenharia aumentada por IA e um sistema sociotécnico em produção.
|
|
61
|
+
|
|
62
|
+
## O que é o SINAPSE (números exatos, do disco)
|
|
63
|
+
|
|
64
|
+
| Dimensão | Quantidade |
|
|
65
|
+
|---|---:|
|
|
66
|
+
| Squads | ${c.squads} |
|
|
67
|
+
| Agentes (total) | ${c.agentsTotal} |
|
|
68
|
+
| — de framework | ${c.frameworkAgents} |
|
|
69
|
+
| — de squad | ${c.squadAgents} |
|
|
70
|
+
| Orquestradores (-orqx) | ${c.orqx} |
|
|
71
|
+
| Workflows | ${c.workflowsTotal} |
|
|
72
|
+
| Artigos da constituição | ${c.articles} |
|
|
73
|
+
| Regras ativas | ${c.rules} |
|
|
74
|
+
|
|
75
|
+
## Como funciona — a cada pedido, prompt, execução e orquestração
|
|
76
|
+
|
|
77
|
+
O SINAPSE é descrito por ${flows.length} meta-fluxos. Cada um é um mecanismo real do framework (não há invenção — todos rastreiam para uma regra/hook). Os diagramas em PT-BR estão em \`LOOPS-sinapse-diagramas.md\`.
|
|
78
|
+
|
|
79
|
+
${flowList}
|
|
80
|
+
|
|
81
|
+
## Princípios constitucionais (gates inegociáveis)
|
|
82
|
+
|
|
83
|
+
A constituição tem ${c.articles} artigos. Gates automáticos bloqueiam violações.
|
|
84
|
+
|
|
85
|
+
| Art. | Princípio | Severidade |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
${articleRows}
|
|
88
|
+
|
|
89
|
+
## Catálogo de workflows
|
|
90
|
+
|
|
91
|
+
${c.workflowsTotal} workflows no total — ${c.frameworkWorkflows} de framework (orquestração, doc-first, greenfield/brownfield, QA) e ${c.squadWorkflows} de squad (expertise de domínio). O catálogo completo (com arquivo-fonte) vive no Atlas em \`docs/framework/atlas/OPERATING-ATLAS.md\`.
|
|
92
|
+
|
|
93
|
+
## Os meta-fluxos visuais
|
|
94
|
+
|
|
95
|
+
Todos os ${flows.length} diagramas Mermaid, em PT-BR, em **\`LOOPS-sinapse-diagramas.md\`** — no mesmo formato dos arquivos \`LOOPS-*-diagramas.md\` desta pesquisa.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
*Card gerado por \`sinapse atlas --research-card\` em ${date}. Fonte única → não editar à mão (re-rode o gerador).*
|
|
100
|
+
`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Build the LOOPS-sinapse-diagramas markdown (PT-BR): every flow as a Mermaid block.
|
|
105
|
+
* @param {object} data - atlas data
|
|
106
|
+
* @param {Record<string,object>} pt - flow id → PT translation
|
|
107
|
+
* @returns {string}
|
|
108
|
+
*/
|
|
109
|
+
function buildLoops(data, pt) {
|
|
110
|
+
const date = (data.generatedAt || '').slice(0, 10);
|
|
111
|
+
const flows = data.flows || [];
|
|
112
|
+
|
|
113
|
+
const blocks = flows
|
|
114
|
+
.map((f, i) => {
|
|
115
|
+
const t = pt[f.id] || { titulo: f.title, proposito: f.purpose, mermaid: f.mermaid };
|
|
116
|
+
const mermaid = t.mermaid || f.mermaid;
|
|
117
|
+
return `## MF${i + 1} — ${t.titulo}
|
|
118
|
+
|
|
119
|
+
> ${t.proposito}
|
|
120
|
+
|
|
121
|
+
\`\`\`mermaid
|
|
122
|
+
${mermaid}
|
|
123
|
+
\`\`\`
|
|
124
|
+
`;
|
|
125
|
+
})
|
|
126
|
+
.join('\n');
|
|
127
|
+
|
|
128
|
+
return `---
|
|
129
|
+
titulo: "LOOPS — Meta-fluxos do SINAPSE (estudo de caso)"
|
|
130
|
+
tipo: loops-diagramas
|
|
131
|
+
dominio: sinapse-framework
|
|
132
|
+
status: instancia-viva
|
|
133
|
+
created: ${date}
|
|
134
|
+
total_diagramas: ${flows.length}
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
# LOOPS — Meta-fluxos do SINAPSE
|
|
138
|
+
|
|
139
|
+
> Os ${flows.length} fluxos operacionais do framework SINAPSE em Mermaid — como ele funciona a cada pedido, prompt, execução e orquestração. Renderizam direto no GitHub.
|
|
140
|
+
> Gerado por \`sinapse atlas --research-card\`; fonte única no próprio framework.
|
|
141
|
+
|
|
142
|
+
${blocks}
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
*Gerado em ${date}. Re-rode \`sinapse atlas --research-card\` para atualizar.*
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Render both PT-BR research artifacts from atlas data.
|
|
151
|
+
* @param {object} data - atlas data (buildAtlasData output)
|
|
152
|
+
* @param {object} [opts]
|
|
153
|
+
* @param {Record<string,object>} [opts.pt] - flow translations (defaults to FRAMEWORK_FLOWS_PT)
|
|
154
|
+
* @returns {{ card: string, loops: string }}
|
|
155
|
+
*/
|
|
156
|
+
function renderResearchCard(data, opts = {}) {
|
|
157
|
+
const pt = opts.pt || FRAMEWORK_FLOWS_PT;
|
|
158
|
+
return {
|
|
159
|
+
card: buildCard(data, pt),
|
|
160
|
+
loops: buildLoops(data, pt),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = { renderResearchCard };
|
|
@@ -6,6 +6,7 @@ const crypto = require('crypto');
|
|
|
6
6
|
const yaml = require('js-yaml');
|
|
7
7
|
const { getClient, isCodeIntelAvailable } = require('../code-intel');
|
|
8
8
|
const { RegistryLoader, DEFAULT_REGISTRY_PATH } = require('../ids/registry-loader');
|
|
9
|
+
const { atomicWriteSync } = require('../synapse/utils/atomic-write');
|
|
9
10
|
|
|
10
11
|
// Role inference from entity path (order matters: more specific patterns first)
|
|
11
12
|
const ROLE_MAP = [
|
|
@@ -366,10 +367,11 @@ class RegistrySyncer {
|
|
|
366
367
|
* @private
|
|
367
368
|
*/
|
|
368
369
|
_atomicWrite(registryPath, registry) {
|
|
369
|
-
const tmpPath = registryPath + '.tmp';
|
|
370
370
|
const content = yaml.dump(registry, { lineWidth: 120, noRefs: true });
|
|
371
|
-
|
|
372
|
-
|
|
371
|
+
// Delegate to the canonical helper: it does unlink-first on Windows and
|
|
372
|
+
// retries the rename on transient EPERM/EBUSY locks (AV / Search indexer /
|
|
373
|
+
// concurrent readers) that POSIX never hits.
|
|
374
|
+
atomicWriteSync(registryPath, content, 'utf8');
|
|
373
375
|
}
|
|
374
376
|
|
|
375
377
|
/**
|
|
@@ -12,13 +12,15 @@ const fs = require('fs');
|
|
|
12
12
|
|
|
13
13
|
const name = 'agent-memory';
|
|
14
14
|
|
|
15
|
+
// Canonical SINAPSE agent ids (current naming, since v6.0.0).
|
|
16
|
+
// These match the directory names under .sinapse-ai/development/agents/.
|
|
15
17
|
const EXPECTED_AGENTS = [
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
+
'developer',
|
|
19
|
+
'quality-gate',
|
|
18
20
|
'architect',
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
21
|
+
'project-lead',
|
|
22
|
+
'product-lead',
|
|
23
|
+
'sprint-lead',
|
|
22
24
|
'analyst',
|
|
23
25
|
'data-engineer',
|
|
24
26
|
'ux',
|
|
@@ -45,6 +45,19 @@ async function run(context) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
// In the framework's own source repo, .claude/CLAUDE.md is the contributor
|
|
49
|
+
// variant (headings like "Framework Boundary", "Agents") rather than the
|
|
50
|
+
// install template (PT section titles). The content exists under different
|
|
51
|
+
// headings, so this is expected — surface as INFO, not WARN.
|
|
52
|
+
if (context.isFrameworkRepo) {
|
|
53
|
+
return {
|
|
54
|
+
check: name,
|
|
55
|
+
status: 'INFO',
|
|
56
|
+
message: `Dev CLAUDE.md variant — install-template sections not required in the source repo (${missingSections.join(', ')})`,
|
|
57
|
+
fixCommand: null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
48
61
|
return {
|
|
49
62
|
check: name,
|
|
50
63
|
status: 'WARN',
|
|
@@ -99,6 +99,17 @@ async function run(context) {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
if (hookCount >= 2 && !registered) {
|
|
102
|
+
// In the framework's own source repo, settings.local.json is gitignored
|
|
103
|
+
// (per-machine) and hook registration is an install-time step. Hook files
|
|
104
|
+
// shipping unregistered is expected here — surface as INFO, not WARN.
|
|
105
|
+
if (context.isFrameworkRepo) {
|
|
106
|
+
return {
|
|
107
|
+
check: name,
|
|
108
|
+
status: 'INFO',
|
|
109
|
+
message: `${hookCount} hook files present — registration is install-time (settings.local.json is gitignored in the source repo)`,
|
|
110
|
+
fixCommand: null,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
102
113
|
return {
|
|
103
114
|
check: name,
|
|
104
115
|
status: 'WARN',
|
|
@@ -28,8 +28,11 @@ function checkBoundaryAlignment(context, denyRules) {
|
|
|
28
28
|
return [];
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
// Extract boundary.protected paths from YAML (simple line parsing)
|
|
32
|
-
|
|
31
|
+
// Extract boundary.protected paths from YAML (simple line parsing).
|
|
32
|
+
// Split on /\r?\n/ so a CRLF-saved core-config.yaml (Windows editors,
|
|
33
|
+
// core.autocrlf) does not leave a trailing \r that breaks the path regex
|
|
34
|
+
// below and silently empties protectedPaths (false-negative boundary check).
|
|
35
|
+
const lines = content.split(/\r?\n/);
|
|
33
36
|
const protectedPaths = [];
|
|
34
37
|
let inProtected = false;
|
|
35
38
|
|
|
@@ -91,6 +94,17 @@ async function run(context) {
|
|
|
91
94
|
const allowCount = allowRules.length;
|
|
92
95
|
|
|
93
96
|
if (denyCount < 40) {
|
|
97
|
+
// In the framework's own source repo, boundary protection is OFF by design
|
|
98
|
+
// (core-config boundary.frameworkProtection:false) so contributors can edit
|
|
99
|
+
// core files — 0 deny rules is the expected, correct state here.
|
|
100
|
+
if (context.isFrameworkRepo) {
|
|
101
|
+
return {
|
|
102
|
+
check: name,
|
|
103
|
+
status: 'INFO',
|
|
104
|
+
message: `Deny rules off (${denyCount}) — expected in the framework source repo (frameworkProtection:false)`,
|
|
105
|
+
fixCommand: null,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
94
108
|
return {
|
|
95
109
|
check: name,
|
|
96
110
|
status: 'WARN',
|
|
@@ -69,6 +69,27 @@ function detectInstallState(context) {
|
|
|
69
69
|
return { installed: false };
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Detect whether doctor is running inside the framework's OWN source repo,
|
|
74
|
+
* as opposed to a user project that installed SINAPSE. In the source repo the
|
|
75
|
+
* root package.json name is exactly 'sinapse-ai'. User projects have their own
|
|
76
|
+
* name (with sinapse-ai under node_modules), so this never false-positives for
|
|
77
|
+
* them.
|
|
78
|
+
*
|
|
79
|
+
* @param {string} projectRoot
|
|
80
|
+
* @returns {boolean}
|
|
81
|
+
*/
|
|
82
|
+
function detectFrameworkRepo(projectRoot) {
|
|
83
|
+
try {
|
|
84
|
+
const pkg = JSON.parse(
|
|
85
|
+
fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'),
|
|
86
|
+
);
|
|
87
|
+
return Boolean(pkg) && pkg.name === 'sinapse-ai';
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
72
93
|
const VALID_ON_ERROR = new Set(['fail', 'warn', 'skip']);
|
|
73
94
|
|
|
74
95
|
/**
|
|
@@ -134,6 +155,12 @@ async function runDoctorChecks(options = {}) {
|
|
|
134
155
|
const context = {
|
|
135
156
|
projectRoot,
|
|
136
157
|
frameworkRoot: path.resolve(__dirname, '..', '..', '..'),
|
|
158
|
+
// True when doctor runs inside the framework's OWN source repo (vs a user
|
|
159
|
+
// install). In the source repo some install-time artifacts are absent BY
|
|
160
|
+
// DESIGN — deny rules are off for contributors (frameworkProtection:false),
|
|
161
|
+
// hooks live in gitignored settings.local.json, and CLAUDE.md is the dev
|
|
162
|
+
// variant. Context checks degrade WARN→INFO here to avoid false alarms.
|
|
163
|
+
isFrameworkRepo: detectFrameworkRepo(projectRoot),
|
|
137
164
|
options: { fix, json, dryRun, quiet, deep, homeDir },
|
|
138
165
|
};
|
|
139
166
|
|
|
@@ -227,6 +227,10 @@ class BuildOrchestrator extends EventEmitter {
|
|
|
227
227
|
duration,
|
|
228
228
|
phases: ctx.phases,
|
|
229
229
|
reportPath: ctx.reportPath,
|
|
230
|
+
// F5 (epic: orchestration-consolidation): surface the real plan object so the
|
|
231
|
+
// quality gate can inspect its honesty (degraded/stub/subtasks). Without this
|
|
232
|
+
// the epic4_to_epic6 gate has nothing real to bite on.
|
|
233
|
+
plan: ctx.plan,
|
|
230
234
|
};
|
|
231
235
|
} catch (error) {
|
|
232
236
|
ctx.errors.push(error);
|
|
@@ -850,18 +854,120 @@ The subtask is complete only when verification passes.
|
|
|
850
854
|
}
|
|
851
855
|
|
|
852
856
|
/**
|
|
853
|
-
*
|
|
857
|
+
* Whether real planning-via-agent (spawning `claude`) is allowed.
|
|
858
|
+
*
|
|
859
|
+
* Mirrors {@link EpicExecutor#_realExecutionAllowed}: returns false inside the
|
|
860
|
+
* jest runner unless `SINAPSE_REAL_DISPATCH=1`. This guard is CRITICAL — the
|
|
861
|
+
* `claude` CLI IS on the PATH in this repo, so without it a `generatePlan()`
|
|
862
|
+
* call under unit tests would spawn the real CLI, burn the user's tokens and be
|
|
863
|
+
* non-deterministic.
|
|
864
|
+
*
|
|
865
|
+
* Honesty invariant (epic: orchestration-consolidation, F4): no path returns a
|
|
866
|
+
* "real" plan without doing real work. When this returns false, the caller
|
|
867
|
+
* falls back to a deterministic plan explicitly marked degraded/stub — never a
|
|
868
|
+
* fabricated plan passed off as agent-generated.
|
|
869
|
+
*
|
|
870
|
+
* @returns {boolean}
|
|
871
|
+
* @private
|
|
854
872
|
*/
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
873
|
+
_planningViaAgentAllowed() {
|
|
874
|
+
return (
|
|
875
|
+
process.env.JEST_WORKER_ID === undefined || process.env.SINAPSE_REAL_DISPATCH === '1'
|
|
876
|
+
);
|
|
877
|
+
}
|
|
859
878
|
|
|
860
|
-
|
|
879
|
+
/**
|
|
880
|
+
* Build the planning prompt sent to the `claude` CLI.
|
|
881
|
+
* Feeds the FULL story (prose + ACs) and asks for a structured JSON plan.
|
|
882
|
+
*
|
|
883
|
+
* @param {string} storyId
|
|
884
|
+
* @param {string} storyContent - Full raw story file content
|
|
885
|
+
* @returns {string}
|
|
886
|
+
*/
|
|
887
|
+
buildPlanPrompt(storyId, storyContent) {
|
|
888
|
+
return `You are a senior engineer producing an implementation plan for a development story.
|
|
861
889
|
|
|
862
|
-
|
|
863
|
-
|
|
890
|
+
## Story (${storyId})
|
|
891
|
+
${storyContent}
|
|
892
|
+
|
|
893
|
+
## Task
|
|
894
|
+
Analyze the FULL story above (prose AND acceptance criteria) and produce a structured implementation plan.
|
|
895
|
+
|
|
896
|
+
Respond with ONLY a JSON object (optionally inside a \`\`\`json fenced block), no prose before or after, in EXACTLY this shape:
|
|
897
|
+
|
|
898
|
+
{
|
|
899
|
+
"phases": [
|
|
900
|
+
{
|
|
901
|
+
"id": "phase-id",
|
|
902
|
+
"name": "Human-readable phase name",
|
|
903
|
+
"subtasks": [
|
|
904
|
+
{
|
|
905
|
+
"id": "1.1",
|
|
906
|
+
"description": "What to implement",
|
|
907
|
+
"files": ["path/to/file.js"],
|
|
908
|
+
"verification": "command or check that confirms this subtask is done"
|
|
909
|
+
}
|
|
910
|
+
]
|
|
911
|
+
}
|
|
912
|
+
]
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
Rules:
|
|
916
|
+
- Break the work into logical phases, each with concrete subtasks.
|
|
917
|
+
- Every subtask MUST have a stable id ("phase.subtask", e.g. "1.1"), a clear description, the files it will touch, and a verification step.
|
|
918
|
+
- Ground every subtask in the story's acceptance criteria — do not invent scope.`;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Robustly parse a plan JSON object out of a raw `claude` response.
|
|
923
|
+
* Tolerates ```json fenced blocks and surrounding prose; returns null when no
|
|
924
|
+
* valid plan object can be extracted (caller then degrades honestly).
|
|
925
|
+
*
|
|
926
|
+
* @param {string} raw - Raw CLI stdout
|
|
927
|
+
* @returns {{phases: Array}|null}
|
|
928
|
+
*/
|
|
929
|
+
parsePlanResponse(raw) {
|
|
930
|
+
if (!raw || typeof raw !== 'string') {
|
|
931
|
+
return null;
|
|
932
|
+
}
|
|
933
|
+
let text = raw.trim();
|
|
934
|
+
|
|
935
|
+
// Prefer a fenced ```json ... ``` block when present.
|
|
936
|
+
const fenceMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
937
|
+
if (fenceMatch) {
|
|
938
|
+
text = fenceMatch[1].trim();
|
|
939
|
+
} else {
|
|
940
|
+
// Otherwise slice from the first `{` to the last `}` (drops surrounding prose).
|
|
941
|
+
const first = text.indexOf('{');
|
|
942
|
+
const last = text.lastIndexOf('}');
|
|
943
|
+
if (first !== -1 && last > first) {
|
|
944
|
+
text = text.slice(first, last + 1);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
864
947
|
|
|
948
|
+
try {
|
|
949
|
+
const obj = JSON.parse(text);
|
|
950
|
+
if (!obj || typeof obj !== 'object' || !Array.isArray(obj.phases)) {
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
return obj;
|
|
954
|
+
} catch {
|
|
955
|
+
return null;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* Build a deterministic, HONESTLY-DEGRADED plan from the story's ACs via regex.
|
|
961
|
+
* Always marked `degraded: true` / `stub: true` with a `reason` so the engine
|
|
962
|
+
* never passes a fallback off as a real agent-generated plan (F4 invariant).
|
|
963
|
+
*
|
|
964
|
+
* @param {Object} ctx
|
|
965
|
+
* @param {string[]} acMatches - Pre-extracted `- [ ] ACn:` lines
|
|
966
|
+
* @param {string} reason - Why we degraded (for honest reporting)
|
|
967
|
+
* @returns {Object}
|
|
968
|
+
* @private
|
|
969
|
+
*/
|
|
970
|
+
_degradedPlan(ctx, acMatches, reason) {
|
|
865
971
|
const subtasks = acMatches.map((ac, i) => ({
|
|
866
972
|
id: `1.${i + 1}`, // Format: phase.subtask (e.g., "1.1", "1.2")
|
|
867
973
|
description: ac.replace(/- \[ \] AC\d+:\s*/, ''),
|
|
@@ -872,6 +978,9 @@ The subtask is complete only when verification passes.
|
|
|
872
978
|
return {
|
|
873
979
|
storyId: ctx.storyId,
|
|
874
980
|
generatedAt: new Date().toISOString(),
|
|
981
|
+
degraded: true,
|
|
982
|
+
stub: true,
|
|
983
|
+
reason,
|
|
875
984
|
phases: [
|
|
876
985
|
{
|
|
877
986
|
id: 'implementation',
|
|
@@ -882,6 +991,81 @@ The subtask is complete only when verification passes.
|
|
|
882
991
|
};
|
|
883
992
|
}
|
|
884
993
|
|
|
994
|
+
/**
|
|
995
|
+
* Generate an implementation plan from a story.
|
|
996
|
+
*
|
|
997
|
+
* Honesty invariant (epic: orchestration-consolidation, F4):
|
|
998
|
+
* - AC1: when real execution is allowed → invoke `claude` over the FULL story
|
|
999
|
+
* and return a rich plan WITHOUT any stub/degraded mark.
|
|
1000
|
+
* - AC2: when real execution is NOT allowed (jest w/o SINAPSE_REAL_DISPATCH),
|
|
1001
|
+
* claude is unavailable/fails, or the response can't be parsed → fall back to
|
|
1002
|
+
* the deterministic regex plan, marked `degraded:true`/`stub:true` + `reason`.
|
|
1003
|
+
* Never throws here; the pipeline proceeds with a degraded plan.
|
|
1004
|
+
* - AC3: missing / empty / non-actionable story → throw explicitly.
|
|
1005
|
+
*
|
|
1006
|
+
* @param {Object} ctx - { storyId, storyPath, config, worktree? }
|
|
1007
|
+
* @returns {Promise<Object>} Plan ({ phases, ... }); degraded plans are marked.
|
|
1008
|
+
*/
|
|
1009
|
+
async generatePlan(ctx) {
|
|
1010
|
+
// AC3: explicit failure when there is no usable story file.
|
|
1011
|
+
if (!ctx || !ctx.storyPath || !fs.existsSync(ctx.storyPath)) {
|
|
1012
|
+
throw new Error(
|
|
1013
|
+
`generatePlan: story file not found (storyId=${ctx && ctx.storyId}, path=${ctx && ctx.storyPath})`,
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
const storyContent = fs.readFileSync(ctx.storyPath, 'utf-8');
|
|
1018
|
+
const trimmed = storyContent.trim();
|
|
1019
|
+
|
|
1020
|
+
// Deterministic AC extraction — shared by both the real and fallback paths.
|
|
1021
|
+
const acMatches = storyContent.match(/- \[ \] AC\d+:.*$/gm) || [];
|
|
1022
|
+
|
|
1023
|
+
// "Actionable" = has ACs OR meaningful prose (more than a bare heading).
|
|
1024
|
+
const proseWithoutHeadings = trimmed
|
|
1025
|
+
.split('\n')
|
|
1026
|
+
.filter((line) => !line.trim().startsWith('#'))
|
|
1027
|
+
.join('\n')
|
|
1028
|
+
.trim();
|
|
1029
|
+
const hasActionableContent = acMatches.length > 0 || proseWithoutHeadings.length >= 20;
|
|
1030
|
+
|
|
1031
|
+
// AC3: empty or non-actionable story → explicit error, never a silent empty plan.
|
|
1032
|
+
if (trimmed.length === 0 || !hasActionableContent) {
|
|
1033
|
+
throw new Error(
|
|
1034
|
+
`generatePlan: story has no actionable content (storyId=${ctx.storyId}, path=${ctx.storyPath})`,
|
|
1035
|
+
);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// AC1: real planning path — guarded against burning tokens under jest.
|
|
1039
|
+
if (this._planningViaAgentAllowed()) {
|
|
1040
|
+
try {
|
|
1041
|
+
const prompt = this.buildPlanPrompt(ctx.storyId, storyContent);
|
|
1042
|
+
const workDir = (ctx.worktree && ctx.worktree.path) || this.rootPath;
|
|
1043
|
+
const cliResult = await this.runClaudeCLI(prompt, workDir, ctx.config || this.config);
|
|
1044
|
+
const stdout =
|
|
1045
|
+
typeof cliResult === 'string' ? cliResult : (cliResult && cliResult.stdout) || '';
|
|
1046
|
+
const parsed = this.parsePlanResponse(stdout);
|
|
1047
|
+
|
|
1048
|
+
if (parsed && Array.isArray(parsed.phases) && parsed.phases.length > 0) {
|
|
1049
|
+
// AC1: real plan — no stub/degraded mark.
|
|
1050
|
+
return {
|
|
1051
|
+
storyId: ctx.storyId,
|
|
1052
|
+
generatedAt: new Date().toISOString(),
|
|
1053
|
+
phases: parsed.phases,
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
// AC2: unparseable / empty agent response → honest degraded fallback.
|
|
1058
|
+
return this._degradedPlan(ctx, acMatches, 'agent-response-unparseable');
|
|
1059
|
+
} catch (err) {
|
|
1060
|
+
// AC2: claude unavailable / spawn error / timeout → honest degraded fallback (no throw).
|
|
1061
|
+
return this._degradedPlan(ctx, acMatches, `agent-invocation-failed: ${err.message}`);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
// AC2: real planning disabled (jest without SINAPSE_REAL_DISPATCH) → honest degraded fallback.
|
|
1066
|
+
return this._degradedPlan(ctx, acMatches, 'real-planning-disabled');
|
|
1067
|
+
}
|
|
1068
|
+
|
|
885
1069
|
/**
|
|
886
1070
|
* Format duration
|
|
887
1071
|
*/
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const {
|
|
3
|
+
const { spawnSync } = require('child_process');
|
|
4
|
+
// cross-spawn resolves Windows .cmd/.bat/.ps1 shims (e.g. an npm-global `codex.cmd`)
|
|
5
|
+
// that native child_process.spawn cannot launch without a shell — it throws ENOENT.
|
|
6
|
+
// It preserves detached + stdio + env semantics, so background spawning is unchanged.
|
|
7
|
+
const crossSpawn = require('cross-spawn');
|
|
4
8
|
|
|
5
9
|
const DEFAULT_RUN_DIR = '.sinapse/external-runs';
|
|
6
10
|
const SUPPORTED_SANDBOXES = new Set([
|
|
@@ -449,7 +453,7 @@ async function spawnExecutor(plan) {
|
|
|
449
453
|
};
|
|
450
454
|
|
|
451
455
|
try {
|
|
452
|
-
child =
|
|
456
|
+
child = crossSpawn(plan.command, plan.args, {
|
|
453
457
|
cwd: plan.options.workdir,
|
|
454
458
|
detached: !plan.options.foreground,
|
|
455
459
|
stdio: ['pipe', logFd, logFd],
|
|
@@ -15,7 +15,7 @@ const path = require('path');
|
|
|
15
15
|
const { BaseCheck, CheckSeverity, CheckDomain } = require('../../base-check');
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Expected articles in Constitution v2.
|
|
18
|
+
* Expected articles in Constitution v2.2.0
|
|
19
19
|
* Source of truth: .sinapse-ai/constitution.md
|
|
20
20
|
*/
|
|
21
21
|
const EXPECTED_ARTICLES = [
|
|
@@ -29,6 +29,7 @@ const EXPECTED_ARTICLES = [
|
|
|
29
29
|
{ number: 'VIII', title: 'Mandatory Delegation', severity: 'NON-NEGOTIABLE' },
|
|
30
30
|
{ number: 'IX', title: 'Safe Collaboration', severity: 'NON-NEGOTIABLE' },
|
|
31
31
|
{ number: 'X', title: 'Security & Data Protection', severity: 'NON-NEGOTIABLE' },
|
|
32
|
+
{ number: 'XI', title: 'Conservative Default', severity: 'MUST' },
|
|
32
33
|
];
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
const fs = require('fs');
|
|
10
10
|
const path = require('path');
|
|
11
|
-
|
|
11
|
+
// cross-spawn.sync resolves npm/npx to their Windows .cmd shims WITHOUT a shell.
|
|
12
|
+
// Native spawnSync('npm.cmd', ...) without shell:true returns EINVAL on modern Node
|
|
13
|
+
// (post CVE-2024-27980), silently no-op'ing the audit/madge checks on Windows.
|
|
14
|
+
const crossSpawn = require('cross-spawn');
|
|
12
15
|
|
|
13
16
|
// Import dependencies with fallbacks
|
|
14
17
|
const GOTCHAS_MEMORY_MODULE = '../memory/gotchas-memory';
|
|
@@ -622,10 +625,9 @@ class SecurityAnalyzer {
|
|
|
622
625
|
const findings = [];
|
|
623
626
|
|
|
624
627
|
try {
|
|
625
|
-
//
|
|
626
|
-
// exist but still prints the JSON report to stdout
|
|
627
|
-
const
|
|
628
|
-
const audit = spawnSync(npmCmd, ['audit', '--json'], {
|
|
628
|
+
// cross-spawn.sync resolves npm's Windows shim without a shell; npm exits
|
|
629
|
+
// non-zero when vulns exist but still prints the JSON report to stdout.
|
|
630
|
+
const audit = crossSpawn.sync('npm', ['audit', '--json'], {
|
|
629
631
|
cwd: this.rootPath,
|
|
630
632
|
encoding: 'utf8',
|
|
631
633
|
maxBuffer: 10 * 1024 * 1024,
|
|
@@ -866,9 +868,9 @@ class ArchitectureAnalyzer {
|
|
|
866
868
|
const findings = [];
|
|
867
869
|
|
|
868
870
|
try {
|
|
869
|
-
//
|
|
870
|
-
|
|
871
|
-
const proc =
|
|
871
|
+
// cross-spawn.sync resolves npx's Windows shim without a shell (native
|
|
872
|
+
// spawnSync of npx.cmd without shell:true returns EINVAL on modern Node).
|
|
873
|
+
const proc = crossSpawn.sync('npx', ['madge', '--circular', '--warning', path.join(this.rootPath, 'src')], {
|
|
872
874
|
encoding: 'utf8',
|
|
873
875
|
timeout: 30000,
|
|
874
876
|
windowsHide: true,
|