sinapse-ai 1.7.0 → 1.8.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/CLAUDE.md +5 -11
- package/.claude/hooks/README.md +14 -1
- package/.claude/hooks/code-intel-pretool.cjs +115 -0
- package/.claude/hooks/enforce-delegation.cjs +31 -3
- package/.claude/hooks/enforce-framework-boundary.cjs +324 -0
- package/.claude/hooks/enforce-permission-mode.cjs +249 -0
- package/.claude/hooks/secret-scanning.cjs +34 -43
- package/.claude/hooks/synapse-engine.cjs +23 -23
- package/.claude/hooks/telemetry-post-tool.cjs +128 -0
- package/.claude/hooks/telemetry-stop.cjs +132 -0
- package/.claude/hooks/verify-packages.cjs +9 -2
- package/.claude/rules/hook-governance.md +2 -0
- package/.sinapse-ai/cli/commands/health/index.js +24 -0
- package/.sinapse-ai/core/README.md +11 -0
- package/.sinapse-ai/core/config/config-loader.js +19 -0
- package/.sinapse-ai/core/execution/build-orchestrator.js +4 -1
- package/.sinapse-ai/core/execution/parallel-executor.js +7 -1
- package/.sinapse-ai/core/execution/subagent-dispatcher.js +126 -28
- package/.sinapse-ai/core/execution/wave-executor.js +4 -1
- package/.sinapse-ai/core/grounding/README.md +71 -11
- package/.sinapse-ai/core/health-check/checks/project/framework-config.js +38 -2
- package/.sinapse-ai/core/health-check/checks/project/package-json.js +47 -3
- package/.sinapse-ai/core/health-check/checks/services/gemini-cli.js +117 -0
- package/.sinapse-ai/core/health-check/checks/services/index.js +2 -0
- package/.sinapse-ai/core/health-check/healers/index.js +40 -3
- package/.sinapse-ai/core/ideation/ideation-engine.js +170 -121
- package/.sinapse-ai/core/ids/gate-evaluator.js +318 -0
- package/.sinapse-ai/core/ids/gates/g5-semantic-handshake.js +190 -0
- package/.sinapse-ai/core/ids/gates/g6-ci-integrity.js +162 -0
- package/.sinapse-ai/core/ids/index.js +30 -0
- package/.sinapse-ai/core/memory/__tests__/active-modules.verify.js +11 -0
- package/.sinapse-ai/core/orchestration/agent-invoker.js +29 -6
- package/.sinapse-ai/core/orchestration/brownfield-handler.js +36 -3
- package/.sinapse-ai/core/orchestration/executors/epic-3-executor.js +76 -5
- package/.sinapse-ai/core/orchestration/executors/epic-4-executor.js +63 -17
- package/.sinapse-ai/core/orchestration/executors/epic-6-executor.js +153 -41
- package/.sinapse-ai/core/orchestration/executors/epic-executor.js +40 -0
- package/.sinapse-ai/core/orchestration/greenfield-handler.js +87 -3
- package/.sinapse-ai/core/orchestration/master-orchestrator.js +105 -7
- package/.sinapse-ai/core/orchestration/parallel-executor.js +6 -1
- package/.sinapse-ai/core/orchestration/workflow-executor.js +41 -0
- package/.sinapse-ai/core/registry/squad-agent-resolver.js +253 -0
- package/.sinapse-ai/core/telemetry/ids-sink.js +188 -0
- package/.sinapse-ai/core/utils/output-formatter.js +8 -290
- package/.sinapse-ai/core-config.yaml +49 -1
- package/.sinapse-ai/data/entity-registry.yaml +15081 -13735
- package/.sinapse-ai/data/registry-update-log.jsonl +86 -0
- package/.sinapse-ai/development/agents/developer.md +2 -0
- package/.sinapse-ai/development/agents/devops.md +9 -0
- package/.sinapse-ai/development/external-executors/README.md +18 -0
- package/.sinapse-ai/development/external-executors/codex.md +56 -0
- package/.sinapse-ai/development/scripts/populate-entity-registry.js +65 -9
- package/.sinapse-ai/development/scripts/squad/squad-downloader.js +54 -11
- package/.sinapse-ai/development/tasks/delegate-to-external-executor.md +152 -0
- package/.sinapse-ai/development/tasks/github-devops-pre-push-quality-gate.md +46 -29
- package/.sinapse-ai/development/tasks/update-sinapse.md +3 -3
- package/.sinapse-ai/hooks/sinapse-brand-grounding.cjs +4 -7
- package/.sinapse-ai/hooks/sinapse-ds-grounding.cjs +4 -7
- package/.sinapse-ai/hooks/sinapse-vault-grounding.cjs +4 -7
- package/.sinapse-ai/infrastructure/integrations/ai-providers/ai-provider-factory.js +4 -1
- package/.sinapse-ai/infrastructure/integrations/ai-providers/claude-provider.js +57 -55
- package/.sinapse-ai/infrastructure/scripts/ide-sync/gemini-commands.js +298 -0
- package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +127 -6
- package/.sinapse-ai/infrastructure/scripts/ide-sync/persona-renderer.js +97 -0
- package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/antigravity.js +121 -0
- package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/cursor.js +119 -0
- package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/github-copilot.js +191 -0
- package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/kimi.js +448 -0
- package/.sinapse-ai/install-manifest.yaml +158 -90
- package/.sinapse-ai/scripts/pm.sh +18 -6
- package/bin/cli.js +17 -0
- package/bin/commands/agents.js +96 -0
- package/bin/commands/doctor.js +15 -0
- package/bin/commands/ideate.js +129 -0
- package/bin/commands/uninstall.js +40 -0
- package/bin/postinstall.js +50 -4
- package/bin/sinapse.js +146 -2
- package/bin/utils/secret-scanner-core.js +253 -0
- package/bin/utils/staged-secret-scan.js +106 -40
- package/package.json +13 -3
- package/packages/installer/src/installer/git-hooks-installer.js +384 -0
- package/packages/installer/src/installer/sinapse-ai-installer.js +16 -0
- package/packages/installer/src/wizard/ide-config-generator.js +23 -0
- package/packages/installer/src/wizard/validators.js +38 -1
- package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +5 -1
- package/packages/installer/tests/unit/git-hooks-installer.test.js +262 -0
- package/scripts/eval-runner.js +422 -0
- package/scripts/generate-install-manifest.js +13 -9
- package/scripts/generate-synapse-runtime.js +51 -0
- package/scripts/validate-all.js +1 -0
- package/scripts/validate-evals.js +466 -0
- package/scripts/validate-schemas.js +539 -0
- package/scripts/validate-squad-orqx.js +9 -2
- package/.sinapse-ai/development/scripts/elicitation-engine.js +0 -385
- package/.sinapse-ai/development/scripts/elicitation-session-manager.js +0 -300
- package/.sinapse-ai/development/tasks/test-validation-task.md +0 -172
|
@@ -70,3 +70,89 @@
|
|
|
70
70
|
{"timestamp":"2026-06-02T05:33:13.938Z","action":"change","path":".sinapse-ai/product/templates/engine/renderer.js","trigger":"watcher"}
|
|
71
71
|
{"timestamp":"2026-06-02T13:29:02.813Z","action":"add","path":".sinapse-ai/core/ids/gates/g5-semantic-handshake.js","trigger":"watcher"}
|
|
72
72
|
{"timestamp":"2026-06-02T13:29:02.814Z","action":"change","path":".sinapse-ai/core/ids/index.js","trigger":"watcher"}
|
|
73
|
+
{"timestamp":"2026-06-03T00:54:57.904Z","action":"change","path":".sinapse-ai/core-config.yaml","trigger":"watcher"}
|
|
74
|
+
{"timestamp":"2026-06-03T00:54:57.906Z","action":"add","path":".sinapse-ai/core/ids/gate-evaluator.js","trigger":"watcher"}
|
|
75
|
+
{"timestamp":"2026-06-03T00:54:57.907Z","action":"change","path":".sinapse-ai/core/ids/index.js","trigger":"watcher"}
|
|
76
|
+
{"timestamp":"2026-06-03T00:54:57.908Z","action":"change","path":".sinapse-ai/core/orchestration/workflow-executor.js","trigger":"watcher"}
|
|
77
|
+
{"timestamp":"2026-06-03T01:35:03.557Z","action":"add","path":".sinapse-ai/development/tasks/delegate-to-external-executor.md","trigger":"watcher"}
|
|
78
|
+
{"timestamp":"2026-06-03T02:28:55.332Z","action":"change","path":".sinapse-ai/core/orchestration/greenfield-handler.js","trigger":"watcher"}
|
|
79
|
+
{"timestamp":"2026-06-03T02:58:23.890Z","action":"change","path":".sinapse-ai/core/ids/gate-evaluator.js","trigger":"watcher"}
|
|
80
|
+
{"timestamp":"2026-06-03T02:58:23.892Z","action":"add","path":".sinapse-ai/core/telemetry/ids-sink.js","trigger":"watcher"}
|
|
81
|
+
{"timestamp":"2026-06-03T04:08:44.518Z","action":"change","path":".sinapse-ai/core-config.yaml","trigger":"watcher"}
|
|
82
|
+
{"timestamp":"2026-06-03T04:08:44.520Z","action":"add","path":".sinapse-ai/core/health-check/checks/services/gemini-cli.js","trigger":"watcher"}
|
|
83
|
+
{"timestamp":"2026-06-03T04:08:44.520Z","action":"change","path":".sinapse-ai/core/health-check/checks/services/index.js","trigger":"watcher"}
|
|
84
|
+
{"timestamp":"2026-06-03T04:08:44.521Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/gemini-commands.js","trigger":"watcher"}
|
|
85
|
+
{"timestamp":"2026-06-03T04:08:44.522Z","action":"change","path":".sinapse-ai/infrastructure/scripts/ide-sync/index.js","trigger":"watcher"}
|
|
86
|
+
{"timestamp":"2026-06-03T04:08:44.523Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/antigravity.js","trigger":"watcher"}
|
|
87
|
+
{"timestamp":"2026-06-03T04:08:44.523Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/cursor.js","trigger":"watcher"}
|
|
88
|
+
{"timestamp":"2026-06-03T04:08:44.524Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/github-copilot.js","trigger":"watcher"}
|
|
89
|
+
{"timestamp":"2026-06-03T04:08:44.525Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/kimi.js","trigger":"watcher"}
|
|
90
|
+
{"timestamp":"2026-06-03T04:41:14.143Z","action":"change","path":".sinapse-ai/core/health-check/checks/project/framework-config.js","trigger":"watcher"}
|
|
91
|
+
{"timestamp":"2026-06-03T04:41:14.144Z","action":"change","path":".sinapse-ai/core/health-check/checks/project/package-json.js","trigger":"watcher"}
|
|
92
|
+
{"timestamp":"2026-06-03T04:41:14.145Z","action":"change","path":".sinapse-ai/core/health-check/healers/index.js","trigger":"watcher"}
|
|
93
|
+
{"timestamp":"2026-06-03T05:09:35.890Z","action":"change","path":".sinapse-ai/core/orchestration/greenfield-handler.js","trigger":"watcher"}
|
|
94
|
+
{"timestamp":"2026-06-03T05:09:40.836Z","action":"change","path":".sinapse-ai/core/ids/gate-evaluator.js","trigger":"watcher"}
|
|
95
|
+
{"timestamp":"2026-06-03T05:09:40.837Z","action":"add","path":".sinapse-ai/core/telemetry/ids-sink.js","trigger":"watcher"}
|
|
96
|
+
{"timestamp":"2026-06-03T05:09:47.410Z","action":"change","path":".sinapse-ai/core-config.yaml","trigger":"watcher"}
|
|
97
|
+
{"timestamp":"2026-06-03T05:09:47.411Z","action":"add","path":".sinapse-ai/core/health-check/checks/services/gemini-cli.js","trigger":"watcher"}
|
|
98
|
+
{"timestamp":"2026-06-03T05:09:47.412Z","action":"change","path":".sinapse-ai/core/health-check/checks/services/index.js","trigger":"watcher"}
|
|
99
|
+
{"timestamp":"2026-06-03T05:09:47.413Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/gemini-commands.js","trigger":"watcher"}
|
|
100
|
+
{"timestamp":"2026-06-03T05:09:47.413Z","action":"change","path":".sinapse-ai/infrastructure/scripts/ide-sync/index.js","trigger":"watcher"}
|
|
101
|
+
{"timestamp":"2026-06-03T05:09:47.414Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/antigravity.js","trigger":"watcher"}
|
|
102
|
+
{"timestamp":"2026-06-03T05:09:47.414Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/cursor.js","trigger":"watcher"}
|
|
103
|
+
{"timestamp":"2026-06-03T05:09:47.415Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/github-copilot.js","trigger":"watcher"}
|
|
104
|
+
{"timestamp":"2026-06-03T05:09:47.415Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/kimi.js","trigger":"watcher"}
|
|
105
|
+
{"timestamp":"2026-06-03T05:09:51.748Z","action":"change","path":".sinapse-ai/core/health-check/checks/project/framework-config.js","trigger":"watcher"}
|
|
106
|
+
{"timestamp":"2026-06-03T05:09:51.749Z","action":"change","path":".sinapse-ai/core/health-check/checks/project/package-json.js","trigger":"watcher"}
|
|
107
|
+
{"timestamp":"2026-06-03T05:09:51.750Z","action":"change","path":".sinapse-ai/core/health-check/healers/index.js","trigger":"watcher"}
|
|
108
|
+
{"timestamp":"2026-06-04T17:41:51.104Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-3-executor.js","trigger":"watcher"}
|
|
109
|
+
{"timestamp":"2026-06-04T17:41:51.105Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-4-executor.js","trigger":"watcher"}
|
|
110
|
+
{"timestamp":"2026-06-04T17:41:51.106Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-executor.js","trigger":"watcher"}
|
|
111
|
+
{"timestamp":"2026-06-04T17:41:51.107Z","action":"change","path":".sinapse-ai/core/orchestration/master-orchestrator.js","trigger":"watcher"}
|
|
112
|
+
{"timestamp":"2026-06-04T22:42:49.542Z","action":"change","path":".sinapse-ai/core/orchestration/agent-invoker.js","trigger":"watcher"}
|
|
113
|
+
{"timestamp":"2026-06-04T22:42:49.544Z","action":"change","path":".sinapse-ai/core/orchestration/master-orchestrator.js","trigger":"watcher"}
|
|
114
|
+
{"timestamp":"2026-06-08T21:43:49.050Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-3-executor.js","trigger":"watcher"}
|
|
115
|
+
{"timestamp":"2026-06-08T21:43:49.052Z","action":"change","path":".sinapse-ai/core/orchestration/master-orchestrator.js","trigger":"watcher"}
|
|
116
|
+
{"timestamp":"2026-06-09T12:07:18.916Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-4-executor.js","trigger":"watcher"}
|
|
117
|
+
{"timestamp":"2026-06-09T12:07:18.917Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-executor.js","trigger":"watcher"}
|
|
118
|
+
{"timestamp":"2026-06-10T21:22:08.944Z","action":"change","path":".sinapse-ai/core/execution/subagent-dispatcher.js","trigger":"watcher"}
|
|
119
|
+
{"timestamp":"2026-06-10T21:22:08.946Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-3-executor.js","trigger":"watcher"}
|
|
120
|
+
{"timestamp":"2026-06-11T04:23:35.214Z","action":"change","path":".sinapse-ai/core/execution/build-orchestrator.js","trigger":"watcher"}
|
|
121
|
+
{"timestamp":"2026-06-11T04:23:35.217Z","action":"change","path":".sinapse-ai/core/execution/subagent-dispatcher.js","trigger":"watcher"}
|
|
122
|
+
{"timestamp":"2026-06-11T04:23:35.218Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-6-executor.js","trigger":"watcher"}
|
|
123
|
+
{"timestamp":"2026-06-11T04:23:35.219Z","action":"add","path":".sinapse-ai/core/registry/squad-agent-resolver.js","trigger":"watcher"}
|
|
124
|
+
{"timestamp":"2026-06-11T05:03:25.244Z","action":"change","path":".sinapse-ai/core/orchestration/executors/epic-6-executor.js","trigger":"watcher"}
|
|
125
|
+
{"timestamp":"2026-06-11T06:24:04.878Z","action":"change","path":".sinapse-ai/core/ideation/ideation-engine.js","trigger":"watcher"}
|
|
126
|
+
{"timestamp":"2026-06-11T06:28:07.428Z","action":"change","path":".sinapse-ai/core/config/config-loader.js","trigger":"watcher"}
|
|
127
|
+
{"timestamp":"2026-06-11T12:50:54.736Z","action":"change","path":".sinapse-ai/core/execution/subagent-dispatcher.js","trigger":"watcher"}
|
|
128
|
+
{"timestamp":"2026-06-11T13:01:18.675Z","action":"add","path":".sinapse-ai/infrastructure/scripts/ide-sync/persona-renderer.js","trigger":"watcher"}
|
|
129
|
+
{"timestamp":"2026-06-11T13:01:18.677Z","action":"change","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/antigravity.js","trigger":"watcher"}
|
|
130
|
+
{"timestamp":"2026-06-11T13:01:18.677Z","action":"change","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/cursor.js","trigger":"watcher"}
|
|
131
|
+
{"timestamp":"2026-06-11T13:01:18.678Z","action":"change","path":".sinapse-ai/infrastructure/scripts/ide-sync/transformers/github-copilot.js","trigger":"watcher"}
|
|
132
|
+
{"timestamp":"2026-06-11T13:07:24.325Z","action":"change","path":".sinapse-ai/core/registry/squad-agent-resolver.js","trigger":"watcher"}
|
|
133
|
+
{"timestamp":"2026-06-11T13:13:02.297Z","action":"change","path":".sinapse-ai/core/execution/parallel-executor.js","trigger":"watcher"}
|
|
134
|
+
{"timestamp":"2026-06-11T13:13:02.298Z","action":"change","path":".sinapse-ai/core/orchestration/parallel-executor.js","trigger":"watcher"}
|
|
135
|
+
{"timestamp":"2026-06-11T13:23:23.014Z","action":"change","path":".sinapse-ai/development/scripts/squad/squad-downloader.js","trigger":"watcher"}
|
|
136
|
+
{"timestamp":"2026-06-11T13:28:29.589Z","action":"change","path":".sinapse-ai/core-config.yaml","trigger":"watcher"}
|
|
137
|
+
{"timestamp":"2026-06-13T17:22:58.704Z","action":"change","path":".sinapse-ai/core/execution/wave-executor.js","trigger":"watcher"}
|
|
138
|
+
{"timestamp":"2026-06-14T18:54:46.575Z","action":"change","path":".sinapse-ai/core/ids/gate-evaluator.js","trigger":"watcher"}
|
|
139
|
+
{"timestamp":"2026-06-14T18:54:46.577Z","action":"add","path":".sinapse-ai/core/ids/gates/g6-ci-integrity.js","trigger":"watcher"}
|
|
140
|
+
{"timestamp":"2026-06-14T18:54:46.577Z","action":"change","path":".sinapse-ai/core/ids/index.js","trigger":"watcher"}
|
|
141
|
+
{"timestamp":"2026-06-14T18:54:46.578Z","action":"change","path":".sinapse-ai/development/tasks/github-devops-pre-push-quality-gate.md","trigger":"watcher"}
|
|
142
|
+
{"timestamp":"2026-06-14T19:13:12.133Z","action":"unlink","path":".sinapse-ai/development/scripts/elicitation-engine.js","trigger":"watcher"}
|
|
143
|
+
{"timestamp":"2026-06-14T19:13:12.142Z","action":"unlink","path":".sinapse-ai/development/scripts/elicitation-session-manager.js","trigger":"watcher"}
|
|
144
|
+
{"timestamp":"2026-06-14T19:13:12.143Z","action":"unlink","path":".sinapse-ai/development/tasks/test-validation-task.md","trigger":"watcher"}
|
|
145
|
+
{"timestamp":"2026-06-15T00:41:14.369Z","action":"change","path":".sinapse-ai/development/scripts/populate-entity-registry.js","trigger":"watcher"}
|
|
146
|
+
{"timestamp":"2026-06-15T01:00:41.030Z","action":"change","path":".sinapse-ai/core/utils/output-formatter.js","trigger":"watcher"}
|
|
147
|
+
{"timestamp":"2026-06-15T01:09:04.926Z","action":"change","path":".sinapse-ai/development/agents/devops.md","trigger":"watcher"}
|
|
148
|
+
{"timestamp":"2026-06-15T01:41:48.134Z","action":"change","path":".sinapse-ai/development/scripts/populate-entity-registry.js","trigger":"watcher"}
|
|
149
|
+
{"timestamp":"2026-06-15T04:47:32.755Z","action":"change","path":"bin/sinapse.js","trigger":"watcher"}
|
|
150
|
+
{"timestamp":"2026-06-15T04:51:53.560Z","action":"change","path":".sinapse-ai/development/agents/developer.md","trigger":"watcher"}
|
|
151
|
+
{"timestamp":"2026-06-15T04:51:53.562Z","action":"change","path":".sinapse-ai/development/agents/devops.md","trigger":"watcher"}
|
|
152
|
+
{"timestamp":"2026-06-15T05:05:54.364Z","action":"change","path":".sinapse-ai/core/orchestration/agent-invoker.js","trigger":"watcher"}
|
|
153
|
+
{"timestamp":"2026-06-15T05:05:54.366Z","action":"change","path":".sinapse-ai/core/orchestration/master-orchestrator.js","trigger":"watcher"}
|
|
154
|
+
{"timestamp":"2026-06-15T05:21:11.730Z","action":"change","path":".sinapse-ai/core/memory/__tests__/active-modules.verify.js","trigger":"watcher"}
|
|
155
|
+
{"timestamp":"2026-06-15T05:21:11.732Z","action":"change","path":".sinapse-ai/development/tasks/update-sinapse.md","trigger":"watcher"}
|
|
156
|
+
{"timestamp":"2026-06-15T05:48:16.335Z","action":"change","path":"bin/sinapse.js","trigger":"watcher"}
|
|
157
|
+
{"timestamp":"2026-06-15T06:10:08.880Z","action":"change","path":".sinapse-ai/core/orchestration/brownfield-handler.js","trigger":"watcher"}
|
|
158
|
+
{"timestamp":"2026-06-15T06:10:08.884Z","action":"change","path":".sinapse-ai/core/orchestration/greenfield-handler.js","trigger":"watcher"}
|
|
@@ -272,6 +272,8 @@ dependencies:
|
|
|
272
272
|
- create-worktree.md
|
|
273
273
|
- list-worktrees.md
|
|
274
274
|
- remove-worktree.md
|
|
275
|
+
# Execution Mode (task→agent binding gap closed)
|
|
276
|
+
- yolo-toggle.md
|
|
275
277
|
scripts:
|
|
276
278
|
# Recovery System (Epic 5)
|
|
277
279
|
- recovery-tracker.js # Track implementation attempts
|
|
@@ -280,6 +280,15 @@ dependencies:
|
|
|
280
280
|
- merge-worktree.md
|
|
281
281
|
# Environment & Deployment (Infra Research 2026-04)
|
|
282
282
|
- environment-promotion-pipeline.md
|
|
283
|
+
# Release & Contributor Flow (task→agent binding gap closed)
|
|
284
|
+
- publish-npm.md
|
|
285
|
+
- review-contributor-pr.md
|
|
286
|
+
# IDS Governance & Registry (task→agent binding gap closed — devops owns CI/G6)
|
|
287
|
+
- ids-governor.md
|
|
288
|
+
- ids-health.md
|
|
289
|
+
- ids-query.md
|
|
290
|
+
- sync-registry-intel.md
|
|
291
|
+
- delegate-to-external-executor.md
|
|
283
292
|
knowledge_bases:
|
|
284
293
|
- environment-deployment-patterns.md
|
|
285
294
|
workflows:
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# External Executors
|
|
2
|
+
|
|
3
|
+
External executors let one SINAPSE runtime keep orchestration authority while another CLI runtime performs the implementation work in an isolated run directory.
|
|
4
|
+
|
|
5
|
+
This pattern is opt-in. The default development mode remains `native`, where the active SINAPSE agent plans, implements, validates, and updates story state in the same runtime.
|
|
6
|
+
|
|
7
|
+
## Contract
|
|
8
|
+
|
|
9
|
+
- The orchestrator owns story selection, acceptance criteria, scope, review, and story state updates.
|
|
10
|
+
- The external executor owns only the delegated implementation attempt.
|
|
11
|
+
- Run artifacts live under `.sinapse/external-runs/<timestamp>-<slug>/`.
|
|
12
|
+
- The orchestrator must read the executor output and inspect the diff before updating checkboxes, File List, or story status.
|
|
13
|
+
|
|
14
|
+
## Providers
|
|
15
|
+
|
|
16
|
+
- `codex.md`: reference provider for Codex CLI headless execution.
|
|
17
|
+
|
|
18
|
+
Future provider files can document `aider`, `cline`, `cursor-cli`, `gemini-cli`, or any other runtime that supports non-interactive execution.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Codex External Executor Adapter
|
|
2
|
+
|
|
3
|
+
## Provider ID
|
|
4
|
+
|
|
5
|
+
`codex`
|
|
6
|
+
|
|
7
|
+
## Invocation
|
|
8
|
+
|
|
9
|
+
The `sinapse-delegate` wrapper launches Codex in non-interactive exec mode and sends the prompt through stdin:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
codex -a never -s workspace-write exec -C <workdir> -o <run_dir>/output.md -
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For `--sandbox danger-full-access`, the wrapper uses the explicit Codex bypass flag:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
codex --dangerously-bypass-approvals-and-sandbox exec -C <workdir> -o <run_dir>/output.md -
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Sandbox Mapping
|
|
22
|
+
|
|
23
|
+
| SINAPSE sandbox | Codex behavior |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| `read-only` | `-a never -s read-only` |
|
|
26
|
+
| `workspace-write` | `-a never -s workspace-write` |
|
|
27
|
+
| `full-auto` | `-a never -s workspace-write` |
|
|
28
|
+
| `danger-full-access` | `--dangerously-bypass-approvals-and-sandbox` |
|
|
29
|
+
|
|
30
|
+
`full-auto` is retained as a SINAPSE abstraction for background executor runs. On current Codex CLI versions, it maps to `workspace-write` plus `approval=never` rather than bypassing the sandbox.
|
|
31
|
+
|
|
32
|
+
## Supported Options
|
|
33
|
+
|
|
34
|
+
- `--model <model>` maps to `codex -m <model>`.
|
|
35
|
+
- `--profile <name>` maps to `codex -p <name>`.
|
|
36
|
+
- `--image <path>` maps to `codex exec -i <path>`.
|
|
37
|
+
- `--workdir <path>` maps to `codex exec -C <path>`.
|
|
38
|
+
- `--prompt` and `--prompt-file` are sent via stdin.
|
|
39
|
+
- `--output-last-message` is managed by the wrapper through `-o <run_dir>/output.md`.
|
|
40
|
+
|
|
41
|
+
## Exit Code Semantics
|
|
42
|
+
|
|
43
|
+
- In background mode, `sinapse-delegate` returns after a process is spawned and prints the PID.
|
|
44
|
+
- In foreground mode, `sinapse-delegate` waits for Codex and returns Codex's exit code.
|
|
45
|
+
- Missing Codex binary is a pre-condition failure.
|
|
46
|
+
- Dirty git worktrees are blocked unless `--allow-dirty` is explicit.
|
|
47
|
+
|
|
48
|
+
## Run Artifacts
|
|
49
|
+
|
|
50
|
+
Each run directory contains:
|
|
51
|
+
|
|
52
|
+
- `prompt.md`: prompt sent to Codex
|
|
53
|
+
- `output.md`: last Codex message, written by Codex
|
|
54
|
+
- `codex.log`: stdout/stderr stream
|
|
55
|
+
- `command.txt`: exact command line
|
|
56
|
+
- `metadata.json`: provider, workdir, sandbox, PID, and artifact paths
|
|
@@ -12,6 +12,12 @@ const REPO_ROOT = path.resolve(__dirname, '../../..');
|
|
|
12
12
|
const REGISTRY_PATH = path.resolve(__dirname, '../../data/entity-registry.yaml');
|
|
13
13
|
|
|
14
14
|
const SCAN_CONFIG = [
|
|
15
|
+
// `bin` scanned FIRST on purpose: buildNameIndex is last-wins for the entity
|
|
16
|
+
// id key, so scanning bin before the other categories lets later categories
|
|
17
|
+
// win on the few generic id collisions (cli, constants) — preserving existing
|
|
18
|
+
// dependency resolution — while still indexing bin entry-points so their
|
|
19
|
+
// requires (e.g. bin/commands/ideate.js → ideation-engine) populate usedBy.
|
|
20
|
+
{ category: 'bin', basePath: 'bin', glob: '**/*.js', type: 'script' },
|
|
15
21
|
{ category: 'tasks', basePath: '.sinapse-ai/development/tasks', glob: '**/*.md', type: 'task' },
|
|
16
22
|
{ category: 'templates', basePath: '.sinapse-ai/product/templates', glob: '**/*.{yaml,yml,md}', type: 'template' },
|
|
17
23
|
{ category: 'scripts', basePath: '.sinapse-ai/development/scripts', glob: '**/*.{js,mjs}', type: 'script' },
|
|
@@ -32,6 +38,11 @@ const SCAN_CONFIG = [
|
|
|
32
38
|
{ category: 'product-data', basePath: '.sinapse-ai/product/data', glob: '**/*.{yaml,yml,md}', type: 'data' }
|
|
33
39
|
];
|
|
34
40
|
|
|
41
|
+
// Generated/self-referential artifacts excluded from scanning. The registry
|
|
42
|
+
// must not track ITSELF as an entity — its checksum would change every regen
|
|
43
|
+
// (each run rewrites the file), so it could never reach a stable fixed point.
|
|
44
|
+
const SCAN_IGNORE = ['**/entity-registry.yaml'];
|
|
45
|
+
|
|
35
46
|
const ADAPTABILITY_DEFAULTS = {
|
|
36
47
|
agent: 0.3,
|
|
37
48
|
module: 0.4,
|
|
@@ -322,7 +333,17 @@ function scanCategory(config, verbose = false) {
|
|
|
322
333
|
}
|
|
323
334
|
|
|
324
335
|
const globPattern = path.posix.join(absBase.replace(/\\/g, '/'), config.glob);
|
|
325
|
-
|
|
336
|
+
// Sort the glob result: fast-glob returns files in filesystem (readdir) order,
|
|
337
|
+
// which varies across machines/runs and reorders the entire registry on every
|
|
338
|
+
// regen (non-deterministic churn). A stable sort makes entity insertion order —
|
|
339
|
+
// and everything derived from it (usedBy push order, YAML key order) —
|
|
340
|
+
// deterministic.
|
|
341
|
+
// `ignore` drops self-referential / generated artifacts (the registry file
|
|
342
|
+
// itself) — tracking the registry as an entity makes its checksum oscillate
|
|
343
|
+
// every run (each regen rewrites the file), which can never stabilize.
|
|
344
|
+
const files = fg
|
|
345
|
+
.sync(globPattern, { onlyFiles: true, absolute: true, ignore: SCAN_IGNORE })
|
|
346
|
+
.sort();
|
|
326
347
|
|
|
327
348
|
const entities = {};
|
|
328
349
|
const seenIds = new Set();
|
|
@@ -474,6 +495,14 @@ function resolveUsedBy(allEntities) {
|
|
|
474
495
|
}
|
|
475
496
|
}
|
|
476
497
|
}
|
|
498
|
+
|
|
499
|
+
// Sort usedBy lists so the serialized order is deterministic regardless of the
|
|
500
|
+
// order entities were scanned in.
|
|
501
|
+
for (const entities of Object.values(allEntities)) {
|
|
502
|
+
for (const entity of Object.values(entities)) {
|
|
503
|
+
entity.usedBy.sort();
|
|
504
|
+
}
|
|
505
|
+
}
|
|
477
506
|
}
|
|
478
507
|
|
|
479
508
|
function classifyDependencies(allEntities, nameIndex) {
|
|
@@ -551,14 +580,23 @@ function populate(options = {}) {
|
|
|
551
580
|
for (const [category, entities] of Object.entries(existingRegistry.entities)) {
|
|
552
581
|
if (!allEntities[category]) continue;
|
|
553
582
|
for (const [entityId, entity] of Object.entries(entities)) {
|
|
554
|
-
|
|
583
|
+
const fresh = allEntities[category][entityId];
|
|
584
|
+
if (!fresh) continue;
|
|
585
|
+
if (entity.invocationExamples && Array.isArray(entity.invocationExamples)) {
|
|
555
586
|
// Enforce limits: max 3 examples, each max 200 chars
|
|
556
587
|
const examples = entity.invocationExamples.slice(0, 3).map((e) => String(e).slice(0, 200));
|
|
557
|
-
|
|
588
|
+
fresh.invocationExamples = examples;
|
|
589
|
+
}
|
|
590
|
+
// Preserve lastVerified when the file content (checksum) is unchanged.
|
|
591
|
+
// Re-stamping every entity on each regen — even untouched ones — was a
|
|
592
|
+
// primary source of registry churn; the timestamp only carries meaning
|
|
593
|
+
// when the entity was actually re-verified (i.e. its checksum changed).
|
|
594
|
+
if (entity.lastVerified && entity.checksum === fresh.checksum) {
|
|
595
|
+
fresh.lastVerified = entity.lastVerified;
|
|
558
596
|
}
|
|
559
597
|
}
|
|
560
598
|
}
|
|
561
|
-
console.log('[IDS] Preserved invocationExamples from existing registry');
|
|
599
|
+
console.log('[IDS] Preserved invocationExamples + lastVerified from existing registry');
|
|
562
600
|
}
|
|
563
601
|
} catch {
|
|
564
602
|
// No existing registry or parse error — skip preservation
|
|
@@ -599,11 +637,28 @@ function populate(options = {}) {
|
|
|
599
637
|
categories
|
|
600
638
|
};
|
|
601
639
|
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
640
|
+
const dumpOpts = { lineWidth: 120, noRefs: true, sortKeys: false };
|
|
641
|
+
|
|
642
|
+
// Idempotent timestamp: only bump `lastUpdated` when the substantive content
|
|
643
|
+
// (everything except the timestamp itself) actually changed. Without this,
|
|
644
|
+
// every regen rewrites the file solely because of a new timestamp, producing
|
|
645
|
+
// churn on each commit even when nothing meaningful changed.
|
|
646
|
+
try {
|
|
647
|
+
const existing = yaml.load(fs.readFileSync(REGISTRY_PATH, 'utf8'));
|
|
648
|
+
if (existing && existing.metadata && existing.metadata.lastUpdated) {
|
|
649
|
+
const stripStamp = (r) => yaml.dump(
|
|
650
|
+
{ ...r, metadata: { ...r.metadata, lastUpdated: null } },
|
|
651
|
+
dumpOpts,
|
|
652
|
+
);
|
|
653
|
+
if (stripStamp(existing) === stripStamp(registry)) {
|
|
654
|
+
registry.metadata.lastUpdated = existing.metadata.lastUpdated;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
} catch {
|
|
658
|
+
// No existing registry or parse error — keep the fresh timestamp.
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const yamlContent = yaml.dump(registry, dumpOpts);
|
|
607
662
|
|
|
608
663
|
try {
|
|
609
664
|
fs.writeFileSync(REGISTRY_PATH, yamlContent, 'utf8');
|
|
@@ -618,6 +673,7 @@ function populate(options = {}) {
|
|
|
618
673
|
|
|
619
674
|
function getCategoryDescription(category) {
|
|
620
675
|
const descriptions = {
|
|
676
|
+
bin: 'CLI entry points and command implementations',
|
|
621
677
|
tasks: 'Executable task workflows for agent operations',
|
|
622
678
|
templates: 'Document and code generation templates',
|
|
623
679
|
scripts: 'Utility and automation scripts',
|
|
@@ -52,6 +52,20 @@ const ALLOWED_REDIRECT_HOSTS = new Set([
|
|
|
52
52
|
*/
|
|
53
53
|
const MAX_REDIRECTS = 5;
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Per-request timeout (ms). Aborts a hung/slow remote so a compromised or
|
|
57
|
+
* unresponsive host can't stall the installer indefinitely (P3-001).
|
|
58
|
+
* @constant {number}
|
|
59
|
+
*/
|
|
60
|
+
const REQUEST_TIMEOUT_MS = 30000;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Maximum response size (bytes). Caps a single download so a malicious/
|
|
64
|
+
* misconfigured host can't exhaust memory (10 MB is ample for a squad).
|
|
65
|
+
* @constant {number}
|
|
66
|
+
*/
|
|
67
|
+
const MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
|
|
68
|
+
|
|
55
69
|
/**
|
|
56
70
|
* Error codes for SquadDownloaderError
|
|
57
71
|
* @enum {string}
|
|
@@ -483,8 +497,7 @@ class SquadDownloader {
|
|
|
483
497
|
}
|
|
484
498
|
}
|
|
485
499
|
|
|
486
|
-
https
|
|
487
|
-
.get(url, options, (res) => {
|
|
500
|
+
const req = https.get(url, options, (res) => {
|
|
488
501
|
// Check for rate limiting
|
|
489
502
|
if (res.statusCode === 403) {
|
|
490
503
|
const rateLimitRemaining = res.headers['x-ratelimit-remaining'];
|
|
@@ -565,25 +578,55 @@ class SquadDownloader {
|
|
|
565
578
|
return;
|
|
566
579
|
}
|
|
567
580
|
|
|
568
|
-
// Collect chunks as Buffer objects to support binary files
|
|
581
|
+
// Collect chunks as Buffer objects to support binary files, capping
|
|
582
|
+
// total size to prevent a malicious host from exhausting memory.
|
|
569
583
|
const chunks = [];
|
|
584
|
+
let total = 0;
|
|
570
585
|
res.on('data', (chunk) => {
|
|
586
|
+
total += chunk.length;
|
|
587
|
+
if (total > MAX_RESPONSE_BYTES) {
|
|
588
|
+
const err = new SquadDownloaderError(
|
|
589
|
+
DownloaderErrorCodes.NETWORK_ERROR,
|
|
590
|
+
`Response exceeded ${MAX_RESPONSE_BYTES} bytes — aborting`,
|
|
591
|
+
'The remote file is unexpectedly large; verify the source',
|
|
592
|
+
);
|
|
593
|
+
if (typeof req.destroy === 'function') req.destroy(err);
|
|
594
|
+
else reject(err);
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
571
597
|
chunks.push(chunk);
|
|
572
598
|
});
|
|
573
599
|
res.on('end', () => {
|
|
574
600
|
// Concatenate all chunks into a single Buffer
|
|
575
601
|
resolve(Buffer.concat(chunks));
|
|
576
602
|
});
|
|
577
|
-
})
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
// Abort hung requests (P3-001) — destroy() surfaces via the 'error' handler.
|
|
606
|
+
// Guarded: test doubles for https.get may not implement setTimeout/destroy.
|
|
607
|
+
if (typeof req.setTimeout === 'function') {
|
|
608
|
+
req.setTimeout(REQUEST_TIMEOUT_MS, () => {
|
|
609
|
+
const err = new SquadDownloaderError(
|
|
610
|
+
DownloaderErrorCodes.NETWORK_ERROR,
|
|
611
|
+
`Request timed out after ${REQUEST_TIMEOUT_MS}ms fetching ${url}`,
|
|
612
|
+
'Check internet connection or try again later',
|
|
585
613
|
);
|
|
614
|
+
if (typeof req.destroy === 'function') req.destroy(err);
|
|
615
|
+
else reject(err);
|
|
586
616
|
});
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
req.on('error', (error) => {
|
|
620
|
+
reject(
|
|
621
|
+
error instanceof SquadDownloaderError
|
|
622
|
+
? error
|
|
623
|
+
: new SquadDownloaderError(
|
|
624
|
+
DownloaderErrorCodes.NETWORK_ERROR,
|
|
625
|
+
`Network error: ${error.message}`,
|
|
626
|
+
'Check internet connection',
|
|
627
|
+
),
|
|
628
|
+
);
|
|
629
|
+
});
|
|
587
630
|
});
|
|
588
631
|
}
|
|
589
632
|
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# delegate-to-external-executor.md
|
|
2
|
+
|
|
3
|
+
**Task**: Delegate Implementation to External Executor
|
|
4
|
+
|
|
5
|
+
**Purpose**: Standardize the orchestrator/executor split for SINAPSE workflows. The active SINAPSE runtime keeps authority over story interpretation, acceptance criteria validation, constitutional gates, review, and story updates while a separate CLI runtime performs only the implementation attempt.
|
|
6
|
+
|
|
7
|
+
**When to use**: Use only for `@developer` implementation work where the story scope is clear enough to hand to another runtime. Do not use for @product-lead, @quality-gate, @sprint-lead, @devops, architecture approval, or release authority.
|
|
8
|
+
|
|
9
|
+
## Task Definition
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
task: delegateToExternalExecutor()
|
|
13
|
+
responsavel: Orchestrating agent
|
|
14
|
+
responsavel_type: Agente
|
|
15
|
+
atomic_layer: Organism
|
|
16
|
+
|
|
17
|
+
inputs:
|
|
18
|
+
- campo: prompt
|
|
19
|
+
tipo: string
|
|
20
|
+
obrigatorio: true
|
|
21
|
+
validacao: Must cite acceptance criteria, story path, file scope, and explicit non-goals
|
|
22
|
+
- campo: slug
|
|
23
|
+
tipo: string
|
|
24
|
+
obrigatorio: true
|
|
25
|
+
validacao: Stable filesystem-safe run slug
|
|
26
|
+
- campo: story_id
|
|
27
|
+
tipo: string
|
|
28
|
+
obrigatorio: false
|
|
29
|
+
- campo: story_path
|
|
30
|
+
tipo: string
|
|
31
|
+
obrigatorio: false
|
|
32
|
+
- campo: workdir
|
|
33
|
+
tipo: string
|
|
34
|
+
obrigatorio: false
|
|
35
|
+
default: Current project root
|
|
36
|
+
- campo: provider
|
|
37
|
+
tipo: string
|
|
38
|
+
obrigatorio: false
|
|
39
|
+
default: codex
|
|
40
|
+
|
|
41
|
+
outputs:
|
|
42
|
+
- campo: run_dir
|
|
43
|
+
tipo: string
|
|
44
|
+
destino: Orchestrator
|
|
45
|
+
- campo: output
|
|
46
|
+
tipo: file
|
|
47
|
+
destino: <run_dir>/output.md
|
|
48
|
+
- campo: log
|
|
49
|
+
tipo: file
|
|
50
|
+
destino: <run_dir>/<provider>.log
|
|
51
|
+
- campo: diff
|
|
52
|
+
tipo: git-diff
|
|
53
|
+
destino: Orchestrator review
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Configuration
|
|
57
|
+
|
|
58
|
+
Delegation is disabled by default.
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
dev:
|
|
62
|
+
execution_mode: native # native | delegate
|
|
63
|
+
delegate_to: codex
|
|
64
|
+
auto_review: true
|
|
65
|
+
|
|
66
|
+
external_executors:
|
|
67
|
+
enabled: false
|
|
68
|
+
default_sandbox: workspace-write # read-only | workspace-write | full-auto | danger-full-access
|
|
69
|
+
run_dir: .sinapse/external-runs
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Pre-Conditions
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
pre_conditions:
|
|
76
|
+
- [ ] External executor provider is installed and available on PATH.
|
|
77
|
+
- [ ] Working tree is clean, or existing intentional changes are already committed.
|
|
78
|
+
- [ ] Prompt cites the story path and acceptance criteria.
|
|
79
|
+
- [ ] Prompt lists allowed file scope and explicit non-goals.
|
|
80
|
+
- [ ] Delegated work is implementation work owned by @developer.
|
|
81
|
+
- [ ] Orchestrator has enough context to review the resulting diff.
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Execution
|
|
85
|
+
|
|
86
|
+
### 1. Build the Prompt
|
|
87
|
+
|
|
88
|
+
The orchestrator writes a prompt that contains:
|
|
89
|
+
|
|
90
|
+
- Story ID and story path
|
|
91
|
+
- Acceptance criteria copied or summarized from the story
|
|
92
|
+
- Allowed file paths or modules
|
|
93
|
+
- Testing expectations
|
|
94
|
+
- Constraints from Constitution and project rules
|
|
95
|
+
- Explicit instruction that the executor must not update story status, checkboxes, File List, PRs, or releases
|
|
96
|
+
|
|
97
|
+
### 2. Start the Delegate Run
|
|
98
|
+
|
|
99
|
+
Use the wrapper:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
sinapse-delegate codex -t <slug> -f <prompt_file> -d <workdir>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The wrapper prints:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
STATUS=started
|
|
109
|
+
RUN_DIR=.sinapse/external-runs/<timestamp>-<slug>
|
|
110
|
+
PID=<pid>
|
|
111
|
+
LOG=<run_dir>/codex.log
|
|
112
|
+
OUTPUT=<run_dir>/output.md
|
|
113
|
+
PROMPT=<run_dir>/prompt.md
|
|
114
|
+
COMMAND=<provider command>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 3. Monitor Completion
|
|
118
|
+
|
|
119
|
+
The orchestrator may tail the log or wait for the PID. Do not mark story progress while the external executor is still running.
|
|
120
|
+
|
|
121
|
+
### 4. Review Output and Diff
|
|
122
|
+
|
|
123
|
+
The orchestrator must read:
|
|
124
|
+
|
|
125
|
+
- `<run_dir>/output.md`
|
|
126
|
+
- `<run_dir>/<provider>.log`
|
|
127
|
+
- `git diff`
|
|
128
|
+
|
|
129
|
+
Then validate:
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
review_checklist:
|
|
133
|
+
- [ ] Every acceptance criterion is satisfied.
|
|
134
|
+
- [ ] Diff scope matches the story and prompt.
|
|
135
|
+
- [ ] Article IV No Invention: every change traces to a requirement.
|
|
136
|
+
- [ ] Tests were added or updated when behavior changed.
|
|
137
|
+
- [ ] Lint, typecheck, and relevant tests pass.
|
|
138
|
+
- [ ] No story state was mutated before review approval.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 5. Accept or Iterate
|
|
142
|
+
|
|
143
|
+
- **Approved**: orchestrator updates story checkboxes, File List, status, and final validation evidence.
|
|
144
|
+
- **Rejected**: orchestrator writes specific feedback and may start a new run with a new slug or iteration suffix.
|
|
145
|
+
|
|
146
|
+
## Anti-Patterns
|
|
147
|
+
|
|
148
|
+
- Marking a story done by trusting the executor summary without reading the diff.
|
|
149
|
+
- Delegating @product-lead, @quality-gate, @sprint-lead, or @devops authority to an external runtime.
|
|
150
|
+
- Letting the executor create PRs, push, release, or mutate story state.
|
|
151
|
+
- Delegating vague work without acceptance criteria and file scope.
|
|
152
|
+
- Running with `danger-full-access` unless the surrounding environment is externally sandboxed.
|