mishkan-harness 0.1.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 (186) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +205 -0
  3. package/bin/mishkan.js +221 -0
  4. package/docs/design/MISHKAN_agent_aliases.md +140 -0
  5. package/docs/design/MISHKAN_decisions.md +172 -0
  6. package/docs/design/MISHKAN_harness_design.md +820 -0
  7. package/docs/design/MISHKAN_ontology.md +87 -0
  8. package/docs/design/MISHKAN_token_optimisation.md +181 -0
  9. package/docs/engineer/README.md +37 -0
  10. package/docs/engineer/profile.example.md +79 -0
  11. package/docs/usage/01-installation.md +178 -0
  12. package/docs/usage/02-project-init.md +151 -0
  13. package/docs/usage/03-orchestration.md +218 -0
  14. package/docs/usage/04-memory-layer.md +201 -0
  15. package/docs/usage/05-selective-ingest.md +177 -0
  16. package/docs/usage/06-llm-providers.md +195 -0
  17. package/docs/usage/07-troubleshooting.md +316 -0
  18. package/docs/usage/08-glossary.md +154 -0
  19. package/docs/usage/09-workflows.md +123 -0
  20. package/docs/usage/README.md +77 -0
  21. package/package.json +43 -0
  22. package/payload/install/settings.hooks.json +47 -0
  23. package/payload/mishkan/AGENT_SPEC.md +154 -0
  24. package/payload/mishkan/agents/ahikam.md +58 -0
  25. package/payload/mishkan/agents/aholiab.md +68 -0
  26. package/payload/mishkan/agents/asaph.md +73 -0
  27. package/payload/mishkan/agents/baruch.md +88 -0
  28. package/payload/mishkan/agents/benaiah.md +76 -0
  29. package/payload/mishkan/agents/bezalel.md +83 -0
  30. package/payload/mishkan/agents/caleb.md +74 -0
  31. package/payload/mishkan/agents/deborah.md +63 -0
  32. package/payload/mishkan/agents/elasah.md +58 -0
  33. package/payload/mishkan/agents/eliashib.md +68 -0
  34. package/payload/mishkan/agents/ezra.md +69 -0
  35. package/payload/mishkan/agents/hanun.md +64 -0
  36. package/payload/mishkan/agents/hiram.md +68 -0
  37. package/payload/mishkan/agents/hizkiah.md +76 -0
  38. package/payload/mishkan/agents/huldah.md +59 -0
  39. package/payload/mishkan/agents/huram.md +66 -0
  40. package/payload/mishkan/agents/hushai.md +59 -0
  41. package/payload/mishkan/agents/igal.md +58 -0
  42. package/payload/mishkan/agents/ira.md +86 -0
  43. package/payload/mishkan/agents/jahaziel.md +71 -0
  44. package/payload/mishkan/agents/jakin.md +66 -0
  45. package/payload/mishkan/agents/jehonathan.md +62 -0
  46. package/payload/mishkan/agents/jehoshaphat.md +68 -0
  47. package/payload/mishkan/agents/joab.md +71 -0
  48. package/payload/mishkan/agents/joah.md +62 -0
  49. package/payload/mishkan/agents/maaseiah.md +61 -0
  50. package/payload/mishkan/agents/meremoth.md +65 -0
  51. package/payload/mishkan/agents/meshullam.md +67 -0
  52. package/payload/mishkan/agents/nathan.md +70 -0
  53. package/payload/mishkan/agents/nehemiah.md +93 -0
  54. package/payload/mishkan/agents/obed.md +60 -0
  55. package/payload/mishkan/agents/oholiab.md +67 -0
  56. package/payload/mishkan/agents/palal.md +63 -0
  57. package/payload/mishkan/agents/phinehas.md +73 -0
  58. package/payload/mishkan/agents/rehum.md +60 -0
  59. package/payload/mishkan/agents/salma.md +69 -0
  60. package/payload/mishkan/agents/seraiah.md +73 -0
  61. package/payload/mishkan/agents/shallum.md +66 -0
  62. package/payload/mishkan/agents/shaphan.md +64 -0
  63. package/payload/mishkan/agents/shemaiah.md +67 -0
  64. package/payload/mishkan/agents/shevna.md +58 -0
  65. package/payload/mishkan/agents/uriah.md +70 -0
  66. package/payload/mishkan/agents/zaccur.md +58 -0
  67. package/payload/mishkan/agents/zadok.md +67 -0
  68. package/payload/mishkan/agents/zerubbabel.md +69 -0
  69. package/payload/mishkan/cognee/.env.curated.example +61 -0
  70. package/payload/mishkan/cognee/.env.example +165 -0
  71. package/payload/mishkan/cognee/Dockerfile +50 -0
  72. package/payload/mishkan/cognee/README.md +129 -0
  73. package/payload/mishkan/cognee/docker-compose.curated-ui.yml +61 -0
  74. package/payload/mishkan/cognee/docker-compose.curated.yml +85 -0
  75. package/payload/mishkan/cognee/docker-compose.hardening.yml +16 -0
  76. package/payload/mishkan/cognee/docker-compose.selfhosted.yml +114 -0
  77. package/payload/mishkan/cognee/docker-compose.ui.yml +70 -0
  78. package/payload/mishkan/cognee/docker-compose.yml +71 -0
  79. package/payload/mishkan/cognee/ingest-curated.py +92 -0
  80. package/payload/mishkan/commands/dep-audit.md +24 -0
  81. package/payload/mishkan/commands/mishkan-init.md +25 -0
  82. package/payload/mishkan/commands/mishkan-resume.md +21 -0
  83. package/payload/mishkan/commands/promote.md +19 -0
  84. package/payload/mishkan/commands/sefer-pull.md +19 -0
  85. package/payload/mishkan/commands/sprint-close.md +21 -0
  86. package/payload/mishkan/config/curated-library.yaml +113 -0
  87. package/payload/mishkan/config/improvement-queries.md +29 -0
  88. package/payload/mishkan/config/model-routing.yaml +87 -0
  89. package/payload/mishkan/config/projects.yaml +38 -0
  90. package/payload/mishkan/evals/baruch/README.md +93 -0
  91. package/payload/mishkan/evals/baruch/fixtures/invalid/bad-outcome-enum.json +15 -0
  92. package/payload/mishkan/evals/baruch/fixtures/invalid/bad-sprint-pattern.json +15 -0
  93. package/payload/mishkan/evals/baruch/fixtures/invalid/bad-trigger-enum.json +15 -0
  94. package/payload/mishkan/evals/baruch/fixtures/invalid/malformed-json.json +7 -0
  95. package/payload/mishkan/evals/baruch/fixtures/invalid/missing-required-field.json +14 -0
  96. package/payload/mishkan/evals/baruch/fixtures/valid/blocked-vendor.json +15 -0
  97. package/payload/mishkan/evals/baruch/fixtures/valid/curated-shortcircuit.json +15 -0
  98. package/payload/mishkan/evals/baruch/fixtures/valid/partial-no-write.json +14 -0
  99. package/payload/mishkan/evals/baruch/fixtures/valid/resolved-cross-harness.json +15 -0
  100. package/payload/mishkan/evals/baruch/golden_case/expected.yaml +35 -0
  101. package/payload/mishkan/evals/baruch/golden_case/input.yaml +47 -0
  102. package/payload/mishkan/evals/baruch/golden_case/produced.json +15 -0
  103. package/payload/mishkan/evals/baruch/run.sh +129 -0
  104. package/payload/mishkan/hooks/model-route.py +96 -0
  105. package/payload/mishkan/hooks/post-tool-observe.sh +45 -0
  106. package/payload/mishkan/hooks/pre-tool-security.sh +150 -0
  107. package/payload/mishkan/hooks/session-start.sh +20 -0
  108. package/payload/mishkan/hooks/stop-reporter.sh +29 -0
  109. package/payload/mishkan/ontology.md +87 -0
  110. package/payload/mishkan/rules/backend/yasad.md +23 -0
  111. package/payload/mishkan/rules/common/dependencies.md +53 -0
  112. package/payload/mishkan/rules/common/quality.md +16 -0
  113. package/payload/mishkan/rules/common/security.md +20 -0
  114. package/payload/mishkan/rules/documentation/sefer.md +19 -0
  115. package/payload/mishkan/rules/frontend/panim.md +21 -0
  116. package/payload/mishkan/rules/infrastructure/migdal.md +22 -0
  117. package/payload/mishkan/scripts/dependency-audit.sh +171 -0
  118. package/payload/mishkan/scripts/ensure-curated-box.sh +66 -0
  119. package/payload/mishkan/scripts/mishkan-ingest.sh +92 -0
  120. package/payload/mishkan/scripts/observability-aggregate.sh +57 -0
  121. package/payload/mishkan/scripts/seed-curated-library.sh +62 -0
  122. package/payload/mishkan/scripts/sync-profile.sh +65 -0
  123. package/payload/mishkan/scripts/validate-research-log.sh +108 -0
  124. package/payload/mishkan/skills/asaph-a11y-seo-craft/SKILL.md +289 -0
  125. package/payload/mishkan/skills/baruch-research-reporting-craft/SKILL.md +460 -0
  126. package/payload/mishkan/skills/benaiah-devsecops-craft/SKILL.md +329 -0
  127. package/payload/mishkan/skills/bezalel-cto-craft/SKILL.md +391 -0
  128. package/payload/mishkan/skills/caleb-web-research-craft/SKILL.md +306 -0
  129. package/payload/mishkan/skills/cognee-promote/SKILL.md +40 -0
  130. package/payload/mishkan/skills/cognee-quickstart/SKILL.md +66 -0
  131. package/payload/mishkan/skills/context-compress/SKILL.md +36 -0
  132. package/payload/mishkan/skills/deborah-ux-craft/SKILL.md +295 -0
  133. package/payload/mishkan/skills/dependency-audit/SKILL.md +59 -0
  134. package/payload/mishkan/skills/dependency-vetting/SKILL.md +59 -0
  135. package/payload/mishkan/skills/documentation-craft/SKILL.md +468 -0
  136. package/payload/mishkan/skills/ezra-research-formulation-craft/SKILL.md +319 -0
  137. package/payload/mishkan/skills/hanun-observability-craft/SKILL.md +312 -0
  138. package/payload/mishkan/skills/hiram-ui-craft/SKILL.md +334 -0
  139. package/payload/mishkan/skills/hizkiah-implementation-craft/SKILL.md +701 -0
  140. package/payload/mishkan/skills/hushai-security-advisor-craft/SKILL.md +282 -0
  141. package/payload/mishkan/skills/ira-code-security-craft/SKILL.md +553 -0
  142. package/payload/mishkan/skills/jakin-intent-clarification-craft/SKILL.md +299 -0
  143. package/payload/mishkan/skills/jehonathan-publication-craft/SKILL.md +262 -0
  144. package/payload/mishkan/skills/joab-app-security-craft/SKILL.md +266 -0
  145. package/payload/mishkan/skills/meremoth-devops-craft/SKILL.md +298 -0
  146. package/payload/mishkan/skills/meshullam-infra-design-craft/SKILL.md +302 -0
  147. package/payload/mishkan/skills/mishkan-ingest/SKILL.md +65 -0
  148. package/payload/mishkan/skills/mishkan-init/SKILL.md +65 -0
  149. package/payload/mishkan/skills/nathan-architecture-craft/SKILL.md +547 -0
  150. package/payload/mishkan/skills/nehemiah-pm-craft/SKILL.md +484 -0
  151. package/payload/mishkan/skills/obed-asset-pipeline-craft/SKILL.md +286 -0
  152. package/payload/mishkan/skills/oholiab-design-system-craft/SKILL.md +334 -0
  153. package/payload/mishkan/skills/palal-systems-craft/SKILL.md +281 -0
  154. package/payload/mishkan/skills/qa-evaluation-craft/SKILL.md +406 -0
  155. package/payload/mishkan/skills/rehum-sre-advisor-craft/SKILL.md +228 -0
  156. package/payload/mishkan/skills/reporter-discipline-craft/SKILL.md +351 -0
  157. package/payload/mishkan/skills/research-pipeline/SKILL.md +55 -0
  158. package/payload/mishkan/skills/salma-frontend-implementation-craft/SKILL.md +369 -0
  159. package/payload/mishkan/skills/sefer-pull/SKILL.md +37 -0
  160. package/payload/mishkan/skills/shallum-database-craft/SKILL.md +347 -0
  161. package/payload/mishkan/skills/shaphan-summarisation-craft/SKILL.md +271 -0
  162. package/payload/mishkan/skills/shemaiah-evaluation-craft/SKILL.md +342 -0
  163. package/payload/mishkan/skills/sprint-report/SKILL.md +28 -0
  164. package/payload/mishkan/skills/team-lead-craft/SKILL.md +457 -0
  165. package/payload/mishkan/skills/zadok-contract-craft/SKILL.md +520 -0
  166. package/payload/mishkan/templates/case-node.schema.json +22 -0
  167. package/payload/mishkan/templates/mcp.json +22 -0
  168. package/payload/mishkan/templates/observability-log.schema.json +24 -0
  169. package/payload/mishkan/templates/project-CLAUDE.md +47 -0
  170. package/payload/mishkan/templates/research-log.schema.json +40 -0
  171. package/payload/mishkan/templates/settings.json +12 -0
  172. package/payload/mishkan/templates/settings.local.json +6 -0
  173. package/payload/mishkan/templates/sprint-state.schema.json +47 -0
  174. package/payload/mishkan/templates/team-report.schema.json +50 -0
  175. package/payload/mishkan/templates/user-CLAUDE.md +62 -0
  176. package/payload/mishkan/workflows/README.md +88 -0
  177. package/payload/mishkan/workflows/mishkan-architecture-panel.js +156 -0
  178. package/payload/mishkan/workflows/mishkan-codebase-audit.js +188 -0
  179. package/payload/mishkan/workflows/mishkan-deep-research.js +251 -0
  180. package/payload/mishkan/workflows/mishkan-init.js +156 -0
  181. package/payload/mishkan/workflows/mishkan-migration-wave.js +180 -0
  182. package/payload/mishkan/workflows/mishkan-release-readiness.js +163 -0
  183. package/payload/mishkan/workflows/mishkan-sprint-close.js +112 -0
  184. package/payload/user/CLAUDE.md +62 -0
  185. package/payload/user/rules/engineer-standards.md +66 -0
  186. package/payload/user/rules/y4nn-standards.md +167 -0
@@ -0,0 +1,251 @@
1
+ // mishkan-deep-research — pipelined research with adversarial verification.
2
+ //
3
+ // Same shape as Anthropic's bundled /deep-research but using MISHKAN's
4
+ // six research-pipeline stages (Jakin, Ezra, Caleb, Shaphan, Shemaiah,
5
+ // Baruch). The Anthropic version fans web searches across angles and
6
+ // cross-checks; this one threads them through MISHKAN's roles so the
7
+ // research-log.json contract is honoured at the end.
8
+ //
9
+ // Patterns: pipeline (Ezra brief → per-sub-question fan-out) +
10
+ // adversarial verification (3-vote refute per finding) + barrier
11
+ // (Shemaiah needs all summarised findings to evaluate coverage).
12
+ //
13
+ // Args: { intent: "raw research query", agent: "calling agent alias",
14
+ // team: "calling agent team", sprint: "S2",
15
+ // applied_to_task: "T-12" | "exploration" }
16
+
17
+ export const meta = {
18
+ name: 'mishkan-deep-research',
19
+ description: 'Run the MISHKAN research pipeline as a workflow: Jakin clarifies, Ezra formulates, Caleb fans out across sub-questions, 3-vote adversarial verify per finding, Shaphan compresses, Shemaiah evaluates, Baruch reports.',
20
+ whenToUse: 'Any unknown that needs the web and where false-confident answers are costly. Cheaper alternative for routine lookups: the sequential research-pipeline skill via Task delegation.',
21
+ phases: [
22
+ { title: 'Clarify', detail: 'Jakin sharpens intent' },
23
+ { title: 'Formulate', detail: 'Ezra writes brief, checks curated library' },
24
+ { title: 'Research', detail: 'Caleb fans out per sub-question; 3-vote verify per claim' },
25
+ { title: 'Compress', detail: 'Shaphan summarises surviving findings' },
26
+ { title: 'Evaluate', detail: 'Shemaiah judges; curated cross-reference' },
27
+ { title: 'Report', detail: 'Baruch emits research-log.json' },
28
+ ],
29
+ }
30
+
31
+ if (!args?.intent || !args?.agent || !args?.team || !args?.sprint) {
32
+ throw new Error('mishkan-deep-research requires args: { intent, agent, team, sprint, applied_to_task? }')
33
+ }
34
+
35
+ const INTENT_SCHEMA = {
36
+ type: 'object',
37
+ required: ['clarified_intent', 'open_questions', 'ready_for_formulation'],
38
+ properties: {
39
+ clarified_intent: { type: ['string', 'null'] },
40
+ open_questions: { type: 'array', items: { type: 'string' } },
41
+ ready_for_formulation: { type: 'boolean' },
42
+ },
43
+ }
44
+
45
+ const BRIEF_SCHEMA = {
46
+ type: 'object',
47
+ required: ['research_brief', 'curated_library_match'],
48
+ properties: {
49
+ research_brief: {
50
+ type: 'object',
51
+ required: ['sub_questions', 'priority_sources', 'acceptance_criteria'],
52
+ properties: {
53
+ sub_questions: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: 7 },
54
+ priority_sources: { type: 'array', items: { type: 'string' } },
55
+ acceptance_criteria: { type: 'string' },
56
+ },
57
+ },
58
+ curated_library_match: { type: 'boolean' },
59
+ curated_library_extract: { type: ['string', 'null'] },
60
+ },
61
+ }
62
+
63
+ const FINDINGS_SCHEMA = {
64
+ type: 'object',
65
+ required: ['findings', 'coverage'],
66
+ properties: {
67
+ findings: {
68
+ type: 'array',
69
+ items: {
70
+ type: 'object',
71
+ required: ['claim', 'source', 'confidence'],
72
+ properties: {
73
+ claim: { type: 'string' },
74
+ source: { type: 'string' },
75
+ confidence: { enum: ['high', 'medium', 'low', 'unverified'] },
76
+ },
77
+ },
78
+ },
79
+ coverage: {
80
+ type: 'object',
81
+ required: ['answered', 'unanswered'],
82
+ properties: {
83
+ answered: { type: 'array' },
84
+ unanswered: { type: 'array' },
85
+ unanswered_reason: { type: 'string' },
86
+ },
87
+ },
88
+ },
89
+ }
90
+
91
+ const VERDICT_SCHEMA = {
92
+ type: 'object',
93
+ required: ['refuted', 'reason'],
94
+ properties: {
95
+ refuted: { type: 'boolean' },
96
+ reason: { type: 'string' },
97
+ },
98
+ }
99
+
100
+ const EVAL_SCHEMA = {
101
+ type: 'object',
102
+ required: ['verdict', 'confidence', 'gaps', 'curated_library_agreement', 'notes'],
103
+ properties: {
104
+ verdict: { enum: ['resolved', 'partial', 'blocked'] },
105
+ confidence: { enum: ['high', 'medium', 'low'] },
106
+ gaps: { type: 'array', items: { type: 'string' } },
107
+ curated_library_agreement: { enum: ['agrees', 'conflicts', 'not_covered'] },
108
+ notes: { type: 'string' },
109
+ },
110
+ }
111
+
112
+ // --- Stage 1: Jakin clarifies ------------------------------------------
113
+ phase('Clarify')
114
+ const intent = await agent(
115
+ `Act as Jakin. Apply jakin-intent-clarification-craft. The raw query: ${JSON.stringify(args.intent)}. ` +
116
+ `Return clarified intent + open questions. No fabricated readiness.`,
117
+ { label: 'jakin:clarify', phase: 'Clarify', agentType: 'jakin', schema: INTENT_SCHEMA }
118
+ )
119
+
120
+ if (!intent.ready_for_formulation) {
121
+ log(`Jakin returned ready_for_formulation=false; ${intent.open_questions.length} open questions.`)
122
+ return {
123
+ outcome: 'blocked',
124
+ stage_blocked: 'jakin',
125
+ open_questions: intent.open_questions,
126
+ research_log: null,
127
+ }
128
+ }
129
+
130
+ // --- Stage 2: Ezra formulates ------------------------------------------
131
+ phase('Formulate')
132
+ const brief = await agent(
133
+ `Act as Ezra. Apply ezra-research-formulation-craft. Clarified intent: ${JSON.stringify(intent.clarified_intent)}. ` +
134
+ `Check curated library first via mcp__cognee-curated__search. If match, set curated_library_match=true and include curated_library_extract.`,
135
+ { label: 'ezra:formulate', phase: 'Formulate', agentType: 'ezra', schema: BRIEF_SCHEMA }
136
+ )
137
+
138
+ // Curated short-circuit: skip Caleb/Shaphan, go straight to Shemaiah evaluating the curated extract.
139
+ if (brief.curated_library_match) {
140
+ log('Ezra short-circuit — curated library match. Skipping web research.')
141
+
142
+ phase('Evaluate')
143
+ const verdict = await agent(
144
+ `Act as Shemaiah. Apply shemaiah-evaluation-craft. Evaluate the curated extract against the original ` +
145
+ `sub-questions. The brief: ${JSON.stringify(brief)}. The extract is the only source.`,
146
+ { label: 'shemaiah:evaluate-curated', phase: 'Evaluate', agentType: 'shemaiah', schema: EVAL_SCHEMA }
147
+ )
148
+
149
+ phase('Report')
150
+ const log_short = {
151
+ agent: args.agent, team: args.team, sprint: args.sprint,
152
+ trigger: 'faced_problem',
153
+ query_intent: intent.clarified_intent,
154
+ tools_invoked: ['jakin', 'ezra', 'shemaiah', 'baruch'],
155
+ research_output_summary: brief.curated_library_extract,
156
+ applied_to_task: args.applied_to_task || 'exploration',
157
+ outcome: verdict.verdict,
158
+ knowledge_graph_write: false,
159
+ curated_library_match: true,
160
+ cognee_node_id: null,
161
+ }
162
+ return { outcome: verdict.verdict, research_log: log_short, source: 'curated' }
163
+ }
164
+
165
+ // --- Stage 3: Caleb pipelines across sub-questions ---------------------
166
+ // Pipeline: each sub-question runs through (research → 3-vote adversarial verify)
167
+ // independently. Faster wall-clock than barrier(research) → barrier(verify).
168
+ phase('Research')
169
+ const verified = await pipeline(
170
+ brief.research_brief.sub_questions,
171
+
172
+ // Stage A: Caleb researches one sub-question.
173
+ (q, _, i) => agent(
174
+ `Act as Caleb. Apply caleb-web-research-craft. Sub-question: ${JSON.stringify(q)}. ` +
175
+ `Priority sources: ${JSON.stringify(brief.research_brief.priority_sources)}. ` +
176
+ `Acceptance: ${brief.research_brief.acceptance_criteria}. Return findings + coverage.`,
177
+ { label: `caleb:Q${i + 1}`, phase: 'Research', agentType: 'caleb', schema: FINDINGS_SCHEMA }
178
+ ),
179
+
180
+ // Stage B: for each finding from stage A, 3-vote adversarial verify.
181
+ // 2/3 refute → drop the finding.
182
+ async (researchResult, q, i) => {
183
+ if (!researchResult?.findings?.length) return { sub_question: q, findings: [], coverage: researchResult?.coverage }
184
+ const survived = await parallel(researchResult.findings.map((f) => async () => {
185
+ const votes = await parallel([0, 1, 2].map((v) => () => agent(
186
+ `Adversarial verifier ${v + 1}/3. Try to REFUTE this finding. Default to refuted=true if uncertain. ` +
187
+ `Finding: ${JSON.stringify(f)}. Source: ${f.source}.`,
188
+ { label: `verify:Q${i + 1}:f${f.claim.slice(0, 24)}:v${v + 1}`, phase: 'Research',
189
+ agentType: 'shemaiah', schema: VERDICT_SCHEMA }
190
+ )))
191
+ const refuted = votes.filter(Boolean).filter(v => v.refuted).length
192
+ return refuted >= 2 ? null : f
193
+ }))
194
+ return {
195
+ sub_question: q,
196
+ findings: survived.filter(Boolean),
197
+ coverage: researchResult.coverage,
198
+ killed_by_verify: researchResult.findings.length - survived.filter(Boolean).length,
199
+ }
200
+ }
201
+ )
202
+
203
+ const allFindings = verified.filter(Boolean).flatMap(v => v.findings)
204
+ const totalKilled = verified.filter(Boolean).reduce((n, v) => n + (v.killed_by_verify || 0), 0)
205
+ log(`Research+verify done: ${allFindings.length} findings survived; ${totalKilled} refuted by adversarial vote.`)
206
+
207
+ // --- Stage 4: Shaphan compresses ---------------------------------------
208
+ phase('Compress')
209
+ const summary = await agent(
210
+ `Act as Shaphan. Apply shaphan-summarisation-craft. Findings from ${verified.length} sub-questions: ` +
211
+ `${JSON.stringify(allFindings)}. Coverage per sub-question: ` +
212
+ `${JSON.stringify(verified.filter(Boolean).map(v => ({ q: v.sub_question, coverage: v.coverage })))}. ` +
213
+ `Preserve every source and confidence. Surface contradictions explicitly.`,
214
+ { label: 'shaphan:compress', phase: 'Compress', agentType: 'shaphan' }
215
+ )
216
+
217
+ // --- Stage 5: Shemaiah evaluates ---------------------------------------
218
+ phase('Evaluate')
219
+ const verdict = await agent(
220
+ `Act as Shemaiah. Apply shemaiah-evaluation-craft. Brief: ${JSON.stringify(brief.research_brief)}. ` +
221
+ `Summary: ${JSON.stringify(summary)}. Cross-reference the curated library via mcp__cognee-curated__search. ` +
222
+ `Return verdict + confidence + gaps + curated_library_agreement.`,
223
+ { label: 'shemaiah:evaluate', phase: 'Evaluate', agentType: 'shemaiah', schema: EVAL_SCHEMA }
224
+ )
225
+
226
+ // --- Stage 6: Baruch reports -------------------------------------------
227
+ phase('Report')
228
+ const research_log = {
229
+ agent: args.agent, team: args.team, sprint: args.sprint,
230
+ trigger: 'faced_problem',
231
+ query_intent: intent.clarified_intent,
232
+ tools_invoked: ['jakin', 'ezra', 'caleb', 'shaphan', 'shemaiah', 'baruch'],
233
+ research_output_summary: typeof summary === 'string' ? summary : JSON.stringify(summary),
234
+ applied_to_task: args.applied_to_task || 'exploration',
235
+ outcome: verdict.verdict,
236
+ knowledge_graph_write: false, // Baruch sets to true if writing a node downstream
237
+ curated_library_match: false,
238
+ cognee_node_id: null,
239
+ }
240
+
241
+ return {
242
+ outcome: verdict.verdict,
243
+ confidence: verdict.confidence,
244
+ gaps: verdict.gaps,
245
+ research_log,
246
+ stats: {
247
+ sub_questions: brief.research_brief.sub_questions.length,
248
+ findings_surviving: allFindings.length,
249
+ findings_refuted: totalKilled,
250
+ },
251
+ }
@@ -0,0 +1,156 @@
1
+ // mishkan-init — pipelined project bootstrap.
2
+ //
3
+ // The sequence-before-implementation chain (PRD → SRS → CONTRACT →
4
+ // ARCHITECTURE → THREAT_MODEL → C4) currently runs as a sequential skill.
5
+ // As a workflow with overlapping stages, downstream agents start as soon
6
+ // as their upstream dependency lands — cutting init from hours to
7
+ // minutes without violating the sequence rule (each artefact still has
8
+ // its prerequisite, just no idle gap between them).
9
+ //
10
+ // Patterns: pipeline with explicit dependencies (PRD → SRS, SRS → both
11
+ // CONTRACT and ARCHITECTURE in parallel, ARCHITECTURE → C4, ARCHITECTURE
12
+ // → THREAT_MODEL) + fan-out where dependencies allow.
13
+ //
14
+ // Args: {
15
+ // project_name: "aiobi-forms",
16
+ // project_root: "/path/to/project",
17
+ // raw_intent: "<paragraph: what is being built, for whom, with what constraints>",
18
+ // stack_hint: "Laravel 11 + Nuxt 3" | "FastAPI + React" | ...
19
+ // }
20
+
21
+ export const meta = {
22
+ name: 'mishkan-init',
23
+ description: 'Pipelined PRD → SRS → CONTRACT → ARCHITECTURE → THREAT_MODEL → C4. Downstream stages start as soon as their upstream dependency lands; sequence rule preserved.',
24
+ whenToUse: 'Once per project at /mishkan-init. Brownfield mode uses the same shape with read-existing instead of write-new at each stage.',
25
+ phases: [
26
+ { title: 'PRD', detail: 'Nehemiah writes the product requirement document' },
27
+ { title: 'SRS', detail: 'Nathan turns PRD into a testable system requirement spec' },
28
+ { title: 'CONTRACT+ARCH',detail: 'Zadok writes CONTRACT; Nathan writes ARCHITECTURE — in parallel' },
29
+ { title: 'THREAT+C4', detail: 'Benaiah writes THREAT_MODEL; Meshullam writes C4 diagrams — in parallel' },
30
+ { title: 'Settle', detail: 'Bezalel signs off on the artefact set; Jehoshaphat scaffolds docs/' },
31
+ ],
32
+ }
33
+
34
+ if (!args?.project_name || !args?.project_root || !args?.raw_intent) {
35
+ throw new Error('mishkan-init requires: { project_name, project_root, raw_intent, stack_hint? }')
36
+ }
37
+
38
+ const ARTEFACT_SCHEMA = {
39
+ type: 'object',
40
+ required: ['artefact', 'path', 'summary'],
41
+ properties: {
42
+ artefact: { type: 'string' },
43
+ path: { type: 'string', description: 'relative path under project_root' },
44
+ summary: { type: 'string' },
45
+ open_questions: { type: 'array', items: { type: 'string' } },
46
+ },
47
+ }
48
+
49
+ const STACK = args.stack_hint || 'undetermined'
50
+
51
+ // --- Stage 1: PRD ------------------------------------------------------
52
+ phase('PRD')
53
+ const prd = await agent(
54
+ `Act as Nehemiah. Apply nehemiah-pm-craft. Write PRD.md for ${args.project_name} from the raw intent: ` +
55
+ `${args.raw_intent}. Stack hint (informational only): ${STACK}. ` +
56
+ `Write to ${args.project_root}/docs/PRD.md. Include: problem, who-for, success criteria (numeric where possible), ` +
57
+ `explicitly-out-of-scope (three items minimum), constraints.`,
58
+ { label: 'nehemiah:prd', phase: 'PRD', agentType: 'nehemiah', schema: ARTEFACT_SCHEMA }
59
+ )
60
+
61
+ // --- Stage 2: SRS depends on PRD --------------------------------------
62
+ phase('SRS')
63
+ const srs = await agent(
64
+ `Act as Nathan. Apply nathan-architecture-craft. Write SRS.md for ${args.project_name}. ` +
65
+ `Read the PRD at ${prd.path}. Produce testable requirements: every F-N requirement has an acceptance test ` +
66
+ `shape; every NF-N requirement is numeric; constraints called out explicitly; assumptions named. ` +
67
+ `Write to ${args.project_root}/docs/SRS.md.`,
68
+ { label: 'nathan:srs', phase: 'SRS', agentType: 'nathan', schema: ARTEFACT_SCHEMA }
69
+ )
70
+
71
+ // --- Stage 3: CONTRACT + ARCHITECTURE in parallel ---------------------
72
+ // Both depend on SRS only; they can run concurrently.
73
+ phase('CONTRACT+ARCH')
74
+ const [contract, architecture] = await parallel([
75
+ () => agent(
76
+ `Act as Zadok. Apply zadok-contract-craft. Write CONTRACT.md for ${args.project_name}. ` +
77
+ `Read the SRS at ${srs.path}. Author invariants + guarantees: error envelope (code/message/request_id), ` +
78
+ `pagination shape (cursor only), naming conventions, idempotency clauses where applicable, versioning ` +
79
+ `policy. Three things explicitly out of scope. Write to ${args.project_root}/docs/CONTRACT.md.`,
80
+ { label: 'zadok:contract', phase: 'CONTRACT+ARCH', agentType: 'zadok', schema: ARTEFACT_SCHEMA }
81
+ ),
82
+ () => agent(
83
+ `Act as Nathan. Apply nathan-architecture-craft. Write ARCHITECTURE.md for ${args.project_name}. ` +
84
+ `Read the SRS at ${srs.path}. Produce: system-in-one-diagram (C4 L1 to be drawn by Meshullam), ` +
85
+ `system-in-one-paragraph, bounded contexts named with ownership rules, data flow on the golden path, ` +
86
+ `consistency map per data store, failure modes with fallbacks, links to ADRs (none yet, structure ready). ` +
87
+ `Write to ${args.project_root}/docs/ARCHITECTURE.md.`,
88
+ { label: 'nathan:architecture', phase: 'CONTRACT+ARCH', agentType: 'nathan', schema: ARTEFACT_SCHEMA }
89
+ ),
90
+ ])
91
+
92
+ // --- Stage 4: THREAT_MODEL + C4 in parallel ---------------------------
93
+ // THREAT_MODEL needs ARCHITECTURE (trust boundaries derived from it).
94
+ // C4 needs ARCHITECTURE (containers drawn from the named bounded contexts).
95
+ // Neither needs CONTRACT, so the parallelism is real.
96
+ phase('THREAT+C4')
97
+ const [threat, c4] = await parallel([
98
+ () => agent(
99
+ `Act as Benaiah. Apply benaiah-devsecops-craft. Write THREAT_MODEL.md for ${args.project_name}. ` +
100
+ `Read ARCHITECTURE.md at ${architecture.path}. Walk STRIDE per asset and trust boundary. Mitigations are ` +
101
+ `concrete (not "use TLS" but "mTLS at Traefik with cert rotation every 90 days via cert-manager"). ` +
102
+ `Open items routed to specialists named. Write to ${args.project_root}/docs/THREAT_MODEL.md.`,
103
+ { label: 'benaiah:threat-model', phase: 'THREAT+C4', agentType: 'benaiah', schema: ARTEFACT_SCHEMA }
104
+ ),
105
+ () => agent(
106
+ `Act as Meshullam. Apply meshullam-infra-design-craft. Produce C4 diagrams for ${args.project_name}. ` +
107
+ `Read ARCHITECTURE.md at ${architecture.path}. Generate at least L1 (Context) and L2 (Containers). ` +
108
+ `Source format Mermaid or PlantUML committed alongside rendered output. Write to ` +
109
+ `${args.project_root}/docs/diagrams/C4/.`,
110
+ { label: 'meshullam:c4', phase: 'THREAT+C4', agentType: 'meshullam', schema: ARTEFACT_SCHEMA }
111
+ ),
112
+ ])
113
+
114
+ // --- Stage 5: Settle — Bezalel signs off, Jehoshaphat scaffolds docs --
115
+ phase('Settle')
116
+ const [signoff, docsScaffold] = await parallel([
117
+ () => agent(
118
+ `Act as Bezalel. Apply bezalel-cto-craft. Review the six artefacts produced for ${args.project_name}: ` +
119
+ `${JSON.stringify({ prd, srs, contract, architecture, threat, c4 })}. ` +
120
+ `Apply the quality bar: every artefact dated; every requirement testable; every contract clause sourceable; ` +
121
+ `every threat anchored. Return a sign-off { status: 'accepted' | 'changes_requested', notes }.`,
122
+ {
123
+ label: 'bezalel:signoff',
124
+ phase: 'Settle',
125
+ agentType: 'bezalel',
126
+ schema: {
127
+ type: 'object',
128
+ required: ['status', 'notes'],
129
+ properties: {
130
+ status: { enum: ['accepted', 'changes_requested'] },
131
+ notes: { type: 'string' },
132
+ changes_requested: { type: 'array', items: { type: 'string' } },
133
+ },
134
+ },
135
+ }
136
+ ),
137
+ () => agent(
138
+ `Act as Jehoshaphat. Apply documentation-craft. Scaffold the docs/ tree for ${args.project_name} ` +
139
+ `at ${args.project_root}/docs/: ADR index, runbooks/, changelog stub, README, Diátaxis quadrant ` +
140
+ `placeholders. Do not author content; create the scaffold and the index.`,
141
+ { label: 'jehoshaphat:scaffold', phase: 'Settle', agentType: 'jehoshaphat', schema: ARTEFACT_SCHEMA }
142
+ ),
143
+ ])
144
+
145
+ return {
146
+ project_name: args.project_name,
147
+ project_root: args.project_root,
148
+ artefacts: {
149
+ prd, srs, contract, architecture, threat, c4,
150
+ docs_scaffold: docsScaffold,
151
+ },
152
+ bezalel_signoff: signoff,
153
+ next: signoff?.status === 'accepted'
154
+ ? `Init complete. Begin Sprint S0; Nehemiah leads. Hand the directory state to Y4NN for git init + first commit.`
155
+ : `Init blocked on changes_requested. Address Bezalel's notes; re-run mishkan-init or run targeted skill invocations.`,
156
+ }
@@ -0,0 +1,180 @@
1
+ // mishkan-migration-wave — pipeline + worktree-isolated transformation
2
+ // across many files.
3
+ //
4
+ // The MISHKAN-shaped equivalent of the canonical migration workflow
5
+ // (Bun Zig→Rust port: hundreds of files in parallel, two reviewers each,
6
+ // fix-loop until tests green). Adapted to MISHKAN's roles: the transformer
7
+ // is the team's implementer (Hizkiah for backend, Salma for frontend, etc.)
8
+ // and the reviewers are QA + the relevant Lead's specialist.
9
+ //
10
+ // Patterns: pipeline (find → transform → review → verify, each file
11
+ // independent) + worktree isolation per agent (parallel writes don't
12
+ // conflict) + judge panel on review (2 independent reviewers must agree).
13
+ //
14
+ // Args: {
15
+ // project_root: "/path/to/project",
16
+ // target_glob: "src/**/*.tsx",
17
+ // transformation: "<one-paragraph description of what to do to each file>",
18
+ // transformer_agent: "salma" | "hizkiah" | "oholiab" | ...
19
+ // reviewers: ["jahaziel", "asaph"] // 2+ specialists who verify
20
+ // verify_command: "pnpm test --filter=changed" // optional; runs after each file
21
+ // max_files: 200
22
+ // }
23
+
24
+ export const meta = {
25
+ name: 'mishkan-migration-wave',
26
+ description: 'Apply a defined transformation to N files in parallel with 2 reviewers each, optional per-file verify. The MISHKAN shape of the canonical large-migration workflow.',
27
+ whenToUse: 'Refactors, framework swaps, contract renames, API deprecations, language ports. Anywhere the transformation is per-file and the test suite (or a typecheck/build) can verify each.',
28
+ phases: [
29
+ { title: 'Discover', detail: 'enumerate target files' },
30
+ { title: 'Transform', detail: 'per-file transformer in an isolated worktree' },
31
+ { title: 'Review', detail: 'two reviewers per file (judge panel; both must accept)' },
32
+ { title: 'Verify', detail: 'optional per-file test/typecheck/build' },
33
+ { title: 'Report', detail: 'per-file status; the wave summary' },
34
+ ],
35
+ }
36
+
37
+ if (!args?.project_root || !args?.target_glob || !args?.transformation || !args?.transformer_agent) {
38
+ throw new Error('mishkan-migration-wave requires: { project_root, target_glob, transformation, transformer_agent, reviewers?, verify_command?, max_files? }')
39
+ }
40
+
41
+ const REVIEWERS = (args.reviewers && args.reviewers.length >= 2)
42
+ ? args.reviewers.slice(0, 4)
43
+ : ['uriah', 'jahaziel'] // sensible default; QA-style
44
+ const MAX_FILES = args.max_files || 200
45
+
46
+ const TRANSFORM_RESULT_SCHEMA = {
47
+ type: 'object',
48
+ required: ['file', 'changed', 'rationale'],
49
+ properties: {
50
+ file: { type: 'string' },
51
+ changed: { type: 'boolean' },
52
+ rationale: { type: 'string' },
53
+ notes: { type: 'string' },
54
+ },
55
+ }
56
+
57
+ const REVIEW_SCHEMA = {
58
+ type: 'object',
59
+ required: ['accept', 'reason'],
60
+ properties: {
61
+ accept: { type: 'boolean' },
62
+ reason: { type: 'string' },
63
+ blockers: { type: 'array', items: { type: 'string' } },
64
+ },
65
+ }
66
+
67
+ const VERIFY_SCHEMA = {
68
+ type: 'object',
69
+ required: ['passed', 'detail'],
70
+ properties: {
71
+ passed: { type: 'boolean' },
72
+ detail: { type: 'string' },
73
+ },
74
+ }
75
+
76
+ // --- Stage 1: Discover -------------------------------------------------
77
+ phase('Discover')
78
+ const discovery = await agent(
79
+ `List files under ${args.project_root} matching glob ${JSON.stringify(args.target_glob)}. ` +
80
+ `Cap at ${MAX_FILES}. Return JSON object { files: [...] }.`,
81
+ {
82
+ label: 'discover:targets',
83
+ phase: 'Discover',
84
+ agentType: 'Explore',
85
+ schema: { type: 'object', required: ['files'], properties: { files: { type: 'array', items: { type: 'string' } } } },
86
+ }
87
+ )
88
+ const files = (discovery?.files || []).slice(0, MAX_FILES)
89
+ log(`${files.length} files match for migration; ${REVIEWERS.length} reviewers per file`)
90
+
91
+ if (files.length === 0) {
92
+ return { wave_status: 'no-op', files_changed: [], files_rejected: [], files_failed_verify: [] }
93
+ }
94
+
95
+ // --- Stage 2-4: per-file pipeline -------------------------------------
96
+ // Each file runs through (transform → review → verify) independently.
97
+ // Transformer runs in an isolated worktree so parallel writes don't
98
+ // conflict; if both reviewers accept and verify passes, we keep it.
99
+ const wave = await pipeline(
100
+ files,
101
+
102
+ // Stage 2: Transform in an isolated worktree.
103
+ (file, _, i) => agent(
104
+ `Act as ${args.transformer_agent}. Apply the transformation to ${args.project_root}/${file}. ` +
105
+ `Transformation: ${args.transformation}. ` +
106
+ `Read the file first, then Edit it in-place. Do not refactor surrounding code. ` +
107
+ `Return { file: "${file}", changed: true|false, rationale, notes? }.`,
108
+ {
109
+ label: `transform:${file.slice(-40)}`,
110
+ phase: 'Transform',
111
+ agentType: args.transformer_agent,
112
+ isolation: 'worktree',
113
+ schema: TRANSFORM_RESULT_SCHEMA,
114
+ }
115
+ ),
116
+
117
+ // Stage 3: Two reviewers in parallel; both must accept.
118
+ async (transformResult, file) => {
119
+ if (!transformResult || !transformResult.changed) {
120
+ return { file, transform: transformResult, review: { accept: false, reason: 'no change emitted' }, verify: null }
121
+ }
122
+ const reviews = await parallel(REVIEWERS.map((reviewer) => () => agent(
123
+ `Act as ${reviewer}. Review the transformed ${args.project_root}/${file}. ` +
124
+ `The transformation was: ${args.transformation}. The transformer's rationale: ` +
125
+ `${transformResult.rationale}. Accept only if (a) the transformation is correctly applied at every site ` +
126
+ `in the file, (b) no unrelated changes were introduced, and (c) the file still type-checks at the local ` +
127
+ `level. Block on any finding.`,
128
+ { label: `review:${reviewer}:${file.slice(-32)}`, phase: 'Review',
129
+ agentType: reviewer, schema: REVIEW_SCHEMA }
130
+ )))
131
+ const accepts = reviews.filter(Boolean).filter(r => r.accept).length
132
+ const allAccept = accepts === REVIEWERS.length
133
+ return {
134
+ file,
135
+ transform: transformResult,
136
+ review: { accept: allAccept, reviews: reviews.filter(Boolean), accepts, required: REVIEWERS.length },
137
+ verify: null,
138
+ }
139
+ },
140
+
141
+ // Stage 4: Optional verify (run the test/typecheck on the changed file scope).
142
+ async (stage3) => {
143
+ if (!stage3 || !stage3.review.accept) return { ...stage3, verify: { passed: false, detail: 'skipped — review did not accept' } }
144
+ if (!args.verify_command) return { ...stage3, verify: { passed: true, detail: 'no verify_command configured; accepted on review alone' } }
145
+ const v = await agent(
146
+ `Run the verify command for the changes to ${stage3.file}: ${args.verify_command}. ` +
147
+ `Cd to ${args.project_root} before running. Return { passed, detail }.`,
148
+ { label: `verify:${stage3.file.slice(-40)}`, phase: 'Verify',
149
+ agentType: 'uriah', schema: VERIFY_SCHEMA }
150
+ )
151
+ return { ...stage3, verify: v || { passed: false, detail: 'verifier returned null' } }
152
+ }
153
+ )
154
+
155
+ // --- Stage 5: Report --------------------------------------------------
156
+ phase('Report')
157
+ const safe = wave.filter(Boolean)
158
+ const changed = safe.filter(w => w.transform?.changed)
159
+ const accepted_by_review = changed.filter(w => w.review.accept)
160
+ const verify_pass = accepted_by_review.filter(w => w.verify?.passed)
161
+ const verify_fail = accepted_by_review.filter(w => w.verify?.passed === false)
162
+ const rejected_by_review = changed.filter(w => !w.review.accept)
163
+
164
+ log(`Migration wave: ${changed.length} transformed, ${accepted_by_review.length} review-accepted, ` +
165
+ `${verify_pass.length} verify-passed, ${verify_fail.length} verify-failed, ${rejected_by_review.length} rejected.`)
166
+
167
+ return {
168
+ wave_status: verify_fail.length === 0 && rejected_by_review.length === 0 ? 'clean' : 'partial',
169
+ files_changed_verified: verify_pass.map(w => w.file),
170
+ files_changed_review_rejected: rejected_by_review.map(w => ({ file: w.file, reasons: w.review.reviews.filter(r => !r.accept).map(r => r.reason) })),
171
+ files_changed_verify_failed: verify_fail.map(w => ({ file: w.file, detail: w.verify.detail })),
172
+ files_no_change: safe.filter(w => !w.transform?.changed).map(w => w.file),
173
+ totals: {
174
+ files_in_scope: files.length,
175
+ transformed: changed.length,
176
+ review_accepted: accepted_by_review.length,
177
+ verify_passed: verify_pass.length,
178
+ final_clean: verify_pass.length,
179
+ },
180
+ }