kenaz 0.3.22 → 0.3.23

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 (465) hide show
  1. package/core/.claude/hooks/_user-scope.js +1 -1
  2. package/core/.claude/hooks/core-resolve.js +1 -1
  3. package/core/.claude/hooks/worktree-create.js +6 -6
  4. package/core/.claude/hooks/worktree-remove.js +4 -4
  5. package/core/.collaboration/core/reconcile.js +16 -1
  6. package/core/.collaboration/core/task-2467-lifecycle.test.js +63 -0
  7. package/core/.collaboration/core/task-api.js +37 -7
  8. package/core/.formation/bifrost/launch.js +1 -1
  9. package/core/.formation/tools/kenaz-stats.js +1 -1
  10. package/core/.formation/tools/post-complete/git-merge.js +1 -1
  11. package/core/.formation/tools/prompt.js +1 -1
  12. package/core/.kenaz/specialist/ansuz_rules.yaml +7 -51
  13. package/core/.kenaz/specialist/ansuz_session_handoff.schema.json +2 -6
  14. package/core/.rule/general/project-self-containment.yaml +2 -2
  15. package/core/.specialist/Amelia/README.md +1 -1
  16. package/core/.specialist/Amelia/rule.yaml +1 -1
  17. package/core/.specialist/Ansuz/RULES.md +1 -1
  18. package/core/.specialist/Ansuz/concepts/commitment_layer.yaml +1 -1
  19. package/core/.specialist/Ansuz/concepts/evolvable_guardrails.yaml +1 -1
  20. package/core/.specialist/Ansuz/knowledge.yaml +1 -3
  21. package/core/.specialist/tools/__tests__/task-2409-lessons.test.js +10 -0
  22. package/core/.specialist/tools/__tests__/task-2427-harvest.test.js +25 -0
  23. package/core/.specialist/tools/ansuz-boot-fast.js +1 -1
  24. package/core/.specialist/tools/failure-detector.js +4 -4
  25. package/core/.specialist/tools/handoff-doc.js +1 -1
  26. package/core/.specialist/tools/lessons.js +2 -2
  27. package/core/CLAUDE.md +5 -5
  28. package/core/KENAZ_CORE_VERSION +1 -1
  29. package/core/dashboard/scripts/install-kenaz-cli.js +21 -6
  30. package/core/dev/scripts/check-file-size.js +1 -1
  31. package/core/dev/scripts/ci-feedback.js +1 -1
  32. package/core/dev/scripts/gc-agent-worktrees.js +11 -11
  33. package/core/dev/scripts/kenaz-session.js +3 -3
  34. package/core/dev/scripts/peer-identity-e2e.js +3 -3
  35. package/core/dev/scripts/run-rust-tests.js +2 -2
  36. package/core/dev/scripts/skill-routing-replay.js +3 -3
  37. package/core/dev/scripts/task1961/selftest.js +2 -2
  38. package/core/dev/scripts/windows-hide-guard.test.js +97 -0
  39. package/core/plugins/kenaz/guidance.md +1 -0
  40. package/core/plugins/kenaz/hooks/core-resolve.js +1 -1
  41. package/core/plugins/kenaz/hooks/kenaz-hook.js +52 -4
  42. package/core/plugins/kenaz/scripts/kenaz.test.js +72 -5
  43. package/lib/cli.js +9 -5
  44. package/package.json +6 -6
  45. package/vendor/install-kenaz-cli.js +21 -6
  46. package/core/.kenaz/designs/METAPLASTICITY_CONFIDENCE_DESIGN.md +0 -537
  47. package/core/.kenaz/designs/REFLEX_INITIATOR_DESIGN.md +0 -501
  48. package/core/.kenaz/designs/TASK_1385_handoff_mcp_design.md +0 -426
  49. package/core/.kenaz/designs/TASK_932_hippocampus_consolidation.md +0 -103
  50. package/core/.kenaz/designs/TASK_934_efe_signal_engine.md +0 -97
  51. package/core/.kenaz/designs/TASK_935_self_evolution_framework.md +0 -154
  52. package/core/.kenaz/designs/VISION_cognitive_architecture_roadmap.md +0 -159
  53. package/core/.kenaz/designs/metaplasticity_simulation_results.json +0 -696
  54. package/core/.kenaz/main-memory/README.md +0 -230
  55. package/core/.kenaz/main-memory/kenaz/cortex/001_cortex_overview.md +0 -168
  56. package/core/.kenaz/main-memory/kenaz/cortex/001_rag_engine_overview.md +0 -30
  57. package/core/.kenaz/main-memory/kenaz/memory-system/001_three_tier_architecture.md +0 -361
  58. package/core/.kenaz/main-memory/kenaz/pipeline/001_task_execution_flow.md +0 -117
  59. package/core/.kenaz/main-memory/kenaz/pipeline/001_task_granularity.md +0 -154
  60. package/core/.kenaz/main-memory/kenaz/pipeline/002_team_priority.md +0 -51
  61. package/core/.kenaz/main-memory/kenaz/pipeline/003_feature_id_system.md +0 -46
  62. package/core/.kenaz/main-memory/kenaz/rules/001_gen_007_self_containment.md +0 -108
  63. package/core/.kenaz/main-memory/kenaz/rules/001_rule_priority_system.md +0 -121
  64. package/core/.kenaz/main-memory/kenaz/rules/002_agt_006_pre_check.md +0 -0
  65. package/core/.kenaz/main-memory/kenaz/rules/003_ppl_002_task_archival.md +0 -48
  66. package/core/.kenaz/main-memory/kenaz/system/001_dual_track_task_system.md +0 -197
  67. package/core/.kenaz/main-memory/knowledge/patterns/001_json_bom_issue.md +0 -78
  68. package/core/.kenaz/main-memory/knowledge/patterns/001_leader_worker_pattern.md +0 -0
  69. package/core/.kenaz/main-memory/knowledge/patterns/002_scope_path_conflict.md +0 -115
  70. package/core/.kenaz/main-memory/knowledge/patterns/002_task_dependency_resolution.md +0 -223
  71. package/core/.kenaz/main-memory/knowledge/patterns/003_question_protocol.md +0 -242
  72. package/core/.kenaz/main-memory/knowledge/patterns/004_user_insight_value.md +0 -111
  73. package/core/.kenaz/main-memory/knowledge/patterns/005_file_lock_pattern.md +0 -274
  74. package/core/.kenaz/main-memory/knowledge/references/001_ppl_rules.md +0 -28
  75. package/core/.kenaz/main-memory/knowledge/solutions/001_json_bom_issue.md +0 -137
  76. package/core/.kenaz/main-memory/knowledge/solutions/001_team_invocation.md +0 -0
  77. package/core/.kenaz/main-memory/knowledge/solutions/002_passive_monitoring.md +0 -0
  78. package/core/.kenaz/main-memory/knowledge/solutions/003_windows_file_race_condition.md +0 -239
  79. package/core/.kenaz/main-memory/registry.json +0 -326
  80. package/core/.kenaz/main-memory/version.yaml +0 -58
  81. package/core/.kenaz/specialist/memory_guard_fired.json +0 -1
  82. package/core/.kenaz/specialist/memory_guard_trigger_cache.json +0 -1
  83. package/core/.kenaz/specialist/memory_source_priority.yaml +0 -260
  84. package/core/.kenaz/specialist/prompt_1775.txt +0 -317
  85. package/core/.kenaz/specialist/prompt_1776.txt +0 -326
  86. package/core/.kenaz/specialist/prompt_1791.txt +0 -320
  87. package/core/.kenaz/specialist/prompt_1792.txt +0 -320
  88. package/core/.kenaz/specialist/prompt_1795.txt +0 -281
  89. package/core/.kenaz/specialist/prompt_1813.txt +0 -332
  90. package/core/.kenaz/specialist/prompt_1814.txt +0 -401
  91. package/core/.kenaz/specialist/prompt_1815.txt +0 -394
  92. package/core/.kenaz/specialist/prompt_1816.txt +0 -437
  93. package/core/.kenaz/specialist/prompt_1818.txt +0 -361
  94. package/core/.kenaz/specialist/prompt_1819.txt +0 -421
  95. package/core/.kenaz/specialist/prompt_1821.txt +0 -345
  96. package/core/.kenaz/specialist/prompt_1822.txt +0 -313
  97. package/core/.kenaz/specialist/prompt_1824.txt +0 -348
  98. package/core/.kenaz/specialist/prompt_1826.txt +0 -388
  99. package/core/.kenaz/specialist/rune_efe_salience_gap.md +0 -21
  100. package/core/.kenaz/specialist/task1825_update.json +0 -43
  101. package/core/.kenaz/specialist/taskgen/consolidation_i.json +0 -38
  102. package/core/.kenaz/specialist/taskgen/csharp_a.json +0 -44
  103. package/core/.kenaz/specialist/taskgen/csharp_b.json +0 -40
  104. package/core/.kenaz/specialist/taskgen/embedding_e.json +0 -34
  105. package/core/.kenaz/specialist/taskgen/hygiene_fg.json +0 -39
  106. package/core/.kenaz/specialist/taskgen/pathology_h.json +0 -36
  107. package/core/.kenaz/specialist/taskgen/unity_noise_d.json +0 -38
  108. package/core/.kenaz/specialist/taskgen/visibility_c.json +0 -38
  109. package/core/.specialist/Ansuz/decisions/ADR-requirement-graph-layer.md +0 -390
  110. package/core/.specialist/Ansuz/self_model_seed.backup.json +0 -100
  111. package/core/.specialist/ansuz_session_handoff.json +0 -96
  112. package/core/dev/ALAYA_FIELD_FEEDBACK_DESIGN.md +0 -126
  113. package/core/dev/ANSUZ_SCAFFOLD_DIET_2026-09-20.md +0 -231
  114. package/core/dev/ANSUZ_STARTUP_INJECTION_REVIEW.md +0 -355
  115. package/core/dev/ANSUZ_WORKFLOW_MODERNIZATION.md +0 -143
  116. package/core/dev/CORTEX_META_GRAPH_ASSESSMENT.md +0 -99
  117. package/core/dev/FREYA_DOWNSTREAM_BUGS_2026-09-19.md +0 -44
  118. package/core/dev/GLOBAL_MEMORY_IDENTITY_CONSOLIDATION.md +0 -263
  119. package/core/dev/GUARD_EFFECTIVENESS_DESIGN.md +0 -180
  120. package/core/dev/HEALTH_GATE_VARIANCE_ASSESSMENT.md +0 -271
  121. package/core/dev/HOOK_DIET_2026-09-21.md +0 -126
  122. package/core/dev/JEV_INTEGRATION_PLAN.md +0 -189
  123. package/core/dev/KENAZ_AGENT_CONNECT_v1_SPEC.md +0 -139
  124. package/core/dev/MOBILE_DESIGN_SPEC.md +0 -569
  125. package/core/dev/MULTI_ANSUZ_SPEC.md +0 -136
  126. package/core/dev/MUNINN_RETIREMENT.md +0 -115
  127. package/core/dev/PHASE3_ATTRIBUTION_POPULATION_DIAGNOSIS.md +0 -211
  128. package/core/dev/PHASE3_P3-2B_TASKLEVEL_PROBE.md +0 -83
  129. package/core/dev/PHASE3_P3-2_POPULATION_DISJOINTNESS.md +0 -83
  130. package/core/dev/PHASE3_P3-2_REMEASURE_REPORT.md +0 -231
  131. package/core/dev/PREDICTION_GROUNDING_DESIGN.md +0 -376
  132. package/core/dev/PRODUCT_SPEC.md +0 -317
  133. package/core/dev/PROJECT_REGISTRY_DUPLICATE_ASSESSMENT.md +0 -86
  134. package/core/dev/STARTUP_TIMELINE_TASK_1995.md +0 -181
  135. package/core/dev/SYNAPSE_WORKER_PER_PROJECT.md +0 -881
  136. package/core/dev/TASK_1680_P3-3_DISPATCH_SPEC.md +0 -96
  137. package/core/dev/TASK_1684_CALIBRATION_IMPACT_ANALYSIS.md +0 -170
  138. package/core/dev/TASK_1684_FORK_A_GOODHART_DESIGN.md +0 -171
  139. package/core/dev/TASK_1684_P3_2_REMEASURE_VALIDATION.md +0 -262
  140. package/core/dev/TASK_1903_SIGNAL_AUC_MEASUREMENT.md +0 -207
  141. package/core/dev/TASK_1904_BRANCH_INTEGRITY_AUDIT.md +0 -146
  142. package/core/dev/ansuz-eval/README.md +0 -38
  143. package/core/dev/ansuz-eval/build-fixtures.js +0 -87
  144. package/core/dev/ansuz-eval/grade.js +0 -96
  145. package/core/dev/ansuz-eval/grader.test.js +0 -117
  146. package/core/dev/ansuz-eval/tasks.md +0 -32
  147. package/core/dev/archive/ansuz/BOOT_FULL.md +0 -141
  148. package/core/dev/archive/ansuz/agents/ansuz-boot.md +0 -176
  149. package/core/dev/archive/ansuz/designs/alaya-passive-surfacing.md +0 -84
  150. package/core/dev/archive/ansuz/designs/cc_memory_indexing.md +0 -307
  151. package/core/dev/archive/ansuz/designs/check_guard.md +0 -322
  152. package/core/dev/archive/ansuz/designs/consequence_loop.md +0 -227
  153. package/core/dev/archive/ansuz/designs/mcp_kuzudb_lock_architecture.md +0 -312
  154. package/core/dev/archive/ansuz/designs/phase0_git_enrichment.md +0 -278
  155. package/core/dev/archive/ansuz/designs/refactor_mcp_tools_synapse.md +0 -490
  156. package/core/dev/archive/ansuz/designs/semantic_markdown_extraction.md +0 -167
  157. package/core/dev/archive/ansuz/designs/task_1372_prompt_injects_into.md +0 -193
  158. package/core/dev/archive/ansuz/designs/thought_stack.md +0 -286
  159. package/core/dev/archive/ansuz/investigations/reachability_unified_api_2026-04-11.md +0 -330
  160. package/core/dev/archive/ansuz/investigations/synapse_orphans_indexing_bug_2026-04-11.md +0 -352
  161. package/core/dev/archive/ansuz/investigations/synapse_orphans_reindex_verification_2026-04-11.md +0 -48
  162. package/core/dev/archive/ansuz/investigations/synapse_orphans_verification_2026-04-11.md +0 -170
  163. package/core/dev/archive/ansuz/legacy/kernel.yaml +0 -399
  164. package/core/dev/archive/ansuz/legacy/phases/phase_0.yaml +0 -418
  165. package/core/dev/archive/ansuz/legacy/phases/phase_1.yaml +0 -376
  166. package/core/dev/archive/ansuz/legacy/phases/phase_10.yaml +0 -35
  167. package/core/dev/archive/ansuz/legacy/phases/phase_11.yaml +0 -582
  168. package/core/dev/archive/ansuz/legacy/phases/phase_2.yaml +0 -94
  169. package/core/dev/archive/ansuz/legacy/phases/phase_3.yaml +0 -274
  170. package/core/dev/archive/ansuz/legacy/phases/phase_4.yaml +0 -67
  171. package/core/dev/archive/ansuz/legacy/phases/phase_5.yaml +0 -32
  172. package/core/dev/archive/ansuz/legacy/phases/phase_6.yaml +0 -91
  173. package/core/dev/archive/ansuz/legacy/phases/phase_7.yaml +0 -58
  174. package/core/dev/archive/ansuz/legacy/phases/phase_8.yaml +0 -146
  175. package/core/dev/archive/ansuz/legacy/phases/phase_9.yaml +0 -424
  176. package/core/dev/archive/ansuz/specs/INDEX_bifrost_hook_parity.yaml +0 -92
  177. package/core/dev/archive/ansuz/specs/active-inference-formation.yaml +0 -453
  178. package/core/dev/archive/ansuz/specs/brief_TASK_1228_userpromptsubmit.yaml +0 -191
  179. package/core/dev/archive/ansuz/specs/brief_TASK_1229_pretooluse_posttooluse.yaml +0 -250
  180. package/core/dev/archive/ansuz/specs/brief_TASK_1230_sessionstart_stop.yaml +0 -301
  181. package/core/dev/archive/ansuz/specs/brief_TASK_1231_verification.yaml +0 -272
  182. package/core/dev/archive/skills/feature_agent/SKILL.md +0 -289
  183. package/core/dev/design/PHASE4_DESIGN.md +0 -559
  184. package/core/dev/design/dashboard_docs_integration_PLAN.md +0 -388
  185. package/core/dev/design/matrix_format_ABBREVIATIONS.md +0 -655
  186. package/core/dev/design/matrix_format_DESIGN_SPEC.md +0 -601
  187. package/core/dev/design/matrix_format_DISCUSSION_SUMMARY.md +0 -484
  188. package/core/dev/design/matrix_format_EXAMPLE_memory.matrix +0 -13
  189. package/core/dev/design/matrix_format_EXAMPLE_project_status.matrix +0 -9
  190. package/core/dev/design/matrix_format_EXAMPLE_tasks.matrix +0 -14
  191. package/core/dev/design/matrix_format_SYNTAX_BNF.md +0 -754
  192. package/core/dev/design/matrix_format_TOKEN_COMPARISON.md +0 -484
  193. package/core/dev/design/matrix_v2_COGNITIVE_DESIGN.md +0 -503
  194. package/core/dev/design/matrix_v2_DISCUSSION_SUMMARY.md +0 -414
  195. package/core/dev/design/matrix_v2_EXAMPLE.matrix +0 -67
  196. package/core/dev/designs/EXPANDABLE_CARD_DESIGN_SPEC.md +0 -509
  197. package/core/dev/jev-eval/ACTIVE_CORRECTION.md +0 -52
  198. package/core/dev/jev-eval/ANNOTATION_GUIDE.md +0 -68
  199. package/core/dev/jev-eval/BASELINE_COMPARISON.md +0 -45
  200. package/core/dev/jev-eval/CONTEXT_REVIEW.md +0 -31
  201. package/core/dev/jev-eval/EVALUATION_STATUS.md +0 -39
  202. package/core/dev/jev-eval/HISTORICAL_CORPUS.md +0 -33
  203. package/core/dev/jev-eval/PACKAGING_VERIFICATION.md +0 -42
  204. package/core/dev/jev-eval/README.md +0 -101
  205. package/core/dev/jev-eval/THALAMUS_RANKING.md +0 -58
  206. package/core/dev/jev-eval/VALIDATION_PROGRESS.md +0 -54
  207. package/core/dev/jev-eval/cli.mjs +0 -50
  208. package/core/dev/jev-eval/context.mjs +0 -183
  209. package/core/dev/jev-eval/corpus.mjs +0 -186
  210. package/core/dev/jev-eval/fixtures/conversation-review.seed.jsonl +0 -6
  211. package/core/dev/jev-eval/fixtures/synthetic.jsonl +0 -11
  212. package/core/dev/jev-eval/metrics.mjs +0 -67
  213. package/core/dev/jev-eval/muninn-baseline.mjs +0 -119
  214. package/core/dev/jev-eval/providers.mjs +0 -95
  215. package/core/dev/jev-eval/reports/annotation-pilot-2026-09-20.json +0 -32
  216. package/core/dev/jev-eval/reports/context-review-2026-09-20.json +0 -48
  217. package/core/dev/jev-eval/reports/conversation-review.pending.json +0 -151
  218. package/core/dev/jev-eval/reports/history-corpus-2026-09-20.json +0 -52
  219. package/core/dev/jev-eval/reports/length-probe-2026-09-20.json +0 -133
  220. package/core/dev/jev-eval/reports/live-smoke-2026-09-20.json +0 -616
  221. package/core/dev/jev-eval/reports/muninn-baseline-2026-09-20.json +0 -52
  222. package/core/dev/jev-eval/reports/resilience-2026-09-20.json +0 -520
  223. package/core/dev/jev-eval/reports/rules-baseline.json +0 -197
  224. package/core/dev/jev-eval/reports/synthetic-review.pending.json +0 -357
  225. package/core/dev/jev-eval/resilience.mjs +0 -71
  226. package/core/dev/jev-eval/review.mjs +0 -78
  227. package/core/dev/jev-eval/schema.mjs +0 -87
  228. package/core/dev/jev-eval/test/context.test.mjs +0 -95
  229. package/core/dev/jev-eval/test/corpus.test.mjs +0 -102
  230. package/core/dev/jev-eval/test/eval.test.mjs +0 -146
  231. package/core/dev/jev-eval/test/muninn-baseline.test.mjs +0 -71
  232. package/core/dev/jev-eval/test/resilience.test.mjs +0 -72
  233. package/core/dev/jev-eval/test/review.test.mjs +0 -61
  234. package/core/dev/pipeline/PHASE3_PLANNING_SUMMARY.md +0 -338
  235. package/core/dev/pipeline/PROGRESS.md +0 -113
  236. package/core/dev/pipeline/PROGRESS_template.md +0 -860
  237. package/core/dev/pipeline/QA_REPORT_F008.md +0 -431
  238. package/core/dev/pipeline/QA_REPORT_LOCAL_CLAUDE_DIAGNOSIS.md +0 -583
  239. package/core/dev/pipeline/README.md +0 -210
  240. package/core/dev/pipeline/WORKFLOW_GUIDE.md +0 -824
  241. package/core/dev/pipeline/archived/TASK_015_tauri_init.yaml +0 -53
  242. package/core/dev/pipeline/archived/TASK_016_tauri_commands.yaml +0 -54
  243. package/core/dev/pipeline/archived/TASK_017_rust_pty.yaml +0 -54
  244. package/core/dev/pipeline/archived/TASK_018_tauri_bundle.yaml +0 -53
  245. package/core/dev/pipeline/archived/TASK_019_release_workflow.yaml +0 -56
  246. package/core/dev/pipeline/archived/TASK_020_update_ui.yaml +0 -54
  247. package/core/dev/pipeline/archived/TASK_021_update_notification_ui.yaml +0 -55
  248. package/core/dev/pipeline/archived/TASK_022_remove_node_pty.yaml +0 -65
  249. package/core/dev/pipeline/archived/TASK_023_api_routes_migration.yaml +0 -86
  250. package/core/dev/pipeline/archived/TASK_024_feature_id_system.yaml +0 -51
  251. package/core/dev/pipeline/archived/TASK_025_executable_acceptance.yaml +0 -66
  252. package/core/dev/pipeline/archived/TASK_026_spec_versioning.yaml +0 -56
  253. package/core/dev/pipeline/archived/TASK_027_drift_detection.yaml +0 -60
  254. package/core/dev/pipeline/archived/TASK_028_tauri_pty_manager.yaml +0 -60
  255. package/core/dev/pipeline/archived/TASK_029_tauri_pty_commands.yaml +0 -62
  256. package/core/dev/pipeline/archived/TASK_030_frontend_session_adapter.yaml +0 -54
  257. package/core/dev/pipeline/archived/TASK_031_terminal_tauri_events.yaml +0 -56
  258. package/core/dev/pipeline/archived/TASK_041_scheduler_data_models.yaml +0 -54
  259. package/core/dev/pipeline/archived/TASK_042_path_lock_manager.yaml +0 -53
  260. package/core/dev/pipeline/archived/TASK_043_process_manager.yaml +0 -57
  261. package/core/dev/pipeline/archived/TASK_044_git_integration.yaml +0 -85
  262. package/core/dev/pipeline/archived/TASK_045_task_queue_manager.yaml +0 -54
  263. package/core/dev/pipeline/archived/TASK_046_scheduler_dispatcher.yaml +0 -60
  264. package/core/dev/pipeline/archived/TASK_047_tauri_scheduler_commands.yaml +0 -55
  265. package/core/dev/pipeline/archived/TASK_048_realtime_status_push.yaml +0 -92
  266. package/core/dev/pipeline/archived/TASK_049_frontend_scheduler_integration.yaml +0 -58
  267. package/core/dev/pipeline/archived/TASK_050_error_recovery.yaml +0 -56
  268. package/core/dev/pipeline/archived/TASK_051_optimization_proposals_backend.yaml +0 -53
  269. package/core/dev/pipeline/archived/TASK_052_optimization_proposals_ui.yaml +0 -58
  270. package/core/dev/pipeline/archived/TASK_053_optimization_proposals_diff_view.yaml +0 -54
  271. package/core/dev/pipeline/archived/TASK_054_multi_project_scheduler_state.yaml +0 -76
  272. package/core/dev/pipeline/archived/TASK_055_scheduler_api_project_scope.yaml +0 -64
  273. package/core/dev/pipeline/archived/TASK_056_frontend_scheduler_project_scope.yaml +0 -62
  274. package/core/dev/pipeline/archived/TASK_057_scheduler_module_structure.yaml +0 -54
  275. package/core/dev/pipeline/archived/TASK_058_scheduler_models_extract.yaml +0 -51
  276. package/core/dev/pipeline/archived/TASK_059_scheduler_core_extract.yaml +0 -51
  277. package/core/dev/pipeline/archived/TASK_060_scheduler_commands_extract.yaml +0 -51
  278. package/core/dev/pipeline/archived/TASK_061_scheduler_specialized_commands.yaml +0 -53
  279. package/core/dev/pipeline/archived/TASK_062_process_manager_module_structure.yaml +0 -56
  280. package/core/dev/pipeline/archived/TASK_063_process_manager_core_extract.yaml +0 -56
  281. package/core/dev/pipeline/archived/TASK_064_recovery_module_structure.yaml +0 -57
  282. package/core/dev/pipeline/archived/TASK_065_recovery_core_extract.yaml +0 -56
  283. package/core/dev/pipeline/archived/TASK_066_self_enhancement_scheduler_models.yaml +0 -60
  284. package/core/dev/pipeline/archived/TASK_067_agents_section_quick_actions.yaml +0 -53
  285. package/core/dev/pipeline/archived/TASK_067_self_enhancement_scheduler_core.yaml +0 -65
  286. package/core/dev/pipeline/archived/TASK_068_agent_workflow_rule_enhancement.yaml +0 -46
  287. package/core/dev/pipeline/archived/TASK_068_self_enhancement_tauri_commands.yaml +0 -61
  288. package/core/dev/pipeline/archived/TASK_069_agent_wizard_responsive.yaml +0 -46
  289. package/core/dev/pipeline/archived/TASK_069_self_enhancement_ui.yaml +0 -62
  290. package/core/dev/pipeline/archived/TASK_070_preview_panel_redesign.yaml +0 -62
  291. package/core/dev/pipeline/archived/TASK_070_self_enhancement_integration.yaml +0 -57
  292. package/core/dev/pipeline/archived/TASK_071_preview_panel_qa.yaml +0 -98
  293. package/core/dev/pipeline/archived/TASK_071_single_agent_config.yaml +0 -57
  294. package/core/dev/pipeline/archived/TASK_072_preview_modal_esc_fix.yaml +0 -71
  295. package/core/dev/pipeline/archived/TASK_072_product_review_module.yaml +0 -57
  296. package/core/dev/pipeline/archived/TASK_073_agents_page_component_refactor.yaml +0 -68
  297. package/core/dev/pipeline/archived/TASK_073_rename_single_agent.yaml +0 -64
  298. package/core/dev/pipeline/archived/TASK_074_preview_mode_ui_diagnosis.yaml +0 -71
  299. package/core/dev/pipeline/archived/TASK_074_single_agent_ui_toggle.yaml +0 -56
  300. package/core/dev/pipeline/archived/TASK_075_agents_page_component_refactor.yaml +0 -69
  301. package/core/dev/pipeline/archived/TASK_075_single_agent_integration_test.yaml +0 -75
  302. package/core/dev/pipeline/archived/TASK_076_preview_mode_ui_diagnosis.yaml +0 -70
  303. package/core/dev/pipeline/archived/TASK_076_single_agent_continuous_mode.yaml +0 -65
  304. package/core/dev/pipeline/archived/TASK_077_failure_directory_structure.yaml +0 -51
  305. package/core/dev/pipeline/archived/TASK_077_single_agent_typescript_types.yaml +0 -59
  306. package/core/dev/pipeline/archived/TASK_078_fail_001_agent_no_output.yaml +0 -53
  307. package/core/dev/pipeline/archived/TASK_078_single_agent_ui_simplify.yaml +0 -74
  308. package/core/dev/pipeline/archived/TASK_079_dashboard_rwd_responsive.yaml +0 -63
  309. package/core/dev/pipeline/archived/TASK_079_fail_002_json_bom.yaml +0 -56
  310. package/core/dev/pipeline/archived/TASK_080_fail_003_queue_pollution.yaml +0 -56
  311. package/core/dev/pipeline/archived/TASK_080_http_server_module.yaml +0 -55
  312. package/core/dev/pipeline/archived/TASK_081_failure_logging_tools.yaml +0 -57
  313. package/core/dev/pipeline/archived/TASK_081_http_api_routes.yaml +0 -62
  314. package/core/dev/pipeline/archived/TASK_082_frontend_api_adapter.yaml +0 -51
  315. package/core/dev/pipeline/archived/TASK_082_integrate_failure_to_workflow.yaml +0 -60
  316. package/core/dev/pipeline/archived/TASK_083_cleanup_nextjs_api.yaml +0 -48
  317. package/core/dev/pipeline/archived/TASK_083_task_queue_cleanup.yaml +0 -67
  318. package/core/dev/pipeline/archived/TASK_084_rust_dead_code_cleanup.yaml +0 -66
  319. package/core/dev/pipeline/archived/TASK_084_scheduler_sync_logic_fix.yaml +0 -68
  320. package/core/dev/pipeline/archived/TASK_085_http_api_web_mode_fixes.yaml +0 -46
  321. package/core/dev/pipeline/archived/TASK_085_memory_consolidation_0204_0205.yaml +0 -98
  322. package/core/dev/pipeline/archived/TASK_086_collapsible_preview_panel.yaml +0 -161
  323. package/core/dev/pipeline/archived/TASK_086_web_mode_feature_parity.yaml +0 -62
  324. package/core/dev/pipeline/archived/TASK_087_manual_memory_archival.yaml +0 -163
  325. package/core/dev/pipeline/archived/TASK_087_mobile_http_control.yaml +0 -68
  326. package/core/dev/pipeline/archived/TASK_088_fail_003_to_ppl_002_rule.yaml +0 -63
  327. package/core/dev/pipeline/archived/TASK_088_mobile_http_qa.yaml +0 -121
  328. package/core/dev/pipeline/archived/TASK_089_agent_collaboration_topic.yaml +0 -60
  329. package/core/dev/pipeline/archived/TASK_089_web_mode_monitor_fix.yaml +0 -58
  330. package/core/dev/pipeline/archived/TASK_090_cli_detection_fix.yaml +0 -61
  331. package/core/dev/pipeline/archived/TASK_090_ui_ux_lessons_topic.yaml +0 -63
  332. package/core/dev/pipeline/archived/TASK_091_expandable_card_design.yaml +0 -56
  333. package/core/dev/pipeline/archived/TASK_091_move_agent_section_components.yaml +0 -65
  334. package/core/dev/pipeline/archived/TASK_092_expandable_card_component.yaml +0 -60
  335. package/core/dev/pipeline/archived/TASK_092_refactor_agent_create_wizard.yaml +0 -84
  336. package/core/dev/pipeline/archived/TASK_093_taskcard_detail_integration.yaml +0 -57
  337. package/core/dev/pipeline/archived/TASK_093_update_barrel_exports_test.yaml +0 -84
  338. package/core/dev/pipeline/archived/TASK_094_ai_agent_generation_enhancement.yaml +0 -115
  339. package/core/dev/pipeline/archived/TASK_094_proposalcard_detail_integration.yaml +0 -55
  340. package/core/dev/pipeline/archived/TASK_095_preview_fixes.yaml +0 -129
  341. package/core/dev/pipeline/archived/TASK_095_single_agent_task_selector.yaml +0 -60
  342. package/core/dev/pipeline/archived/TASK_096_agents_page_ux_improvements.yaml +0 -163
  343. package/core/dev/pipeline/archived/TASK_096_single_agent_status_sync.yaml +0 -60
  344. package/core/dev/pipeline/archived/TASK_097_local_claude_error_logging.yaml +0 -59
  345. package/core/dev/pipeline/archived/TASK_097_single_agent_monitor_events.yaml +0 -59
  346. package/core/dev/pipeline/archived/TASK_098_product_manager_team_phase2.yaml +0 -60
  347. package/core/dev/pipeline/archived/TASK_098_single_agent_refactor_test.yaml +0 -58
  348. package/core/dev/pipeline/archived/TASK_099_backend_team_creation.yaml +0 -258
  349. package/core/dev/pipeline/archived/TASK_100_frontend_team_creation.yaml +0 -61
  350. package/core/dev/pipeline/archived/TASK_101_orchestrator_system.yaml +0 -403
  351. package/core/dev/pipeline/archived/TASK_102_designer_sre_teams.yaml +0 -90
  352. package/core/dev/pipeline/archived/TASK_103_integration_testing.yaml +0 -86
  353. package/core/dev/pipeline/archived/TASK_128_integration_testing.yaml +0 -83
  354. package/core/dev/pipeline/archived/TASK_134_cortex_v2_phase3_file_watcher.yaml +0 -65
  355. package/core/dev/pipeline/archived/TASK_134_team_http_api.yaml +0 -96
  356. package/core/dev/pipeline/archived/TASK_135_cortex_v2_phase3_git_monitor.yaml +0 -63
  357. package/core/dev/pipeline/archived/TASK_136_cortex_v2_phase3_change_analyzer.yaml +0 -69
  358. package/core/dev/pipeline/archived/TASK_137_cortex_v2_phase3_cache_invalidator.yaml +0 -67
  359. package/core/dev/pipeline/archived/TASK_137_team_orchestrator_integration.yaml +0 -93
  360. package/core/dev/pipeline/archived/TASK_138_cortex_v2_phase3_distributed_cache.yaml +0 -68
  361. package/core/dev/pipeline/archived/TASK_138_matrix_folder_structure.yaml +0 -61
  362. package/core/dev/pipeline/archived/TASK_139_cortex_v2_phase3_cache_prewarming.yaml +0 -65
  363. package/core/dev/pipeline/archived/TASK_146_unified_documentation.yaml +0 -141
  364. package/core/dev/pipeline/archived/TASK_147_pipeline_execution_rules.yaml +0 -76
  365. package/core/dev/pipeline/archived/TASK_148_update_claude_md.yaml +0 -77
  366. package/core/dev/pipeline/archived/TASK_149_fix_nextjs_mdx_serialization.yaml +0 -63
  367. package/core/dev/pipeline/archived/TASK_149_update_team_docs.yaml +0 -77
  368. package/core/dev/pipeline/archived/TASK_150_pipeline_workflow_guide.yaml +0 -82
  369. package/core/dev/pipeline/archived/TASK_164_fix_smart_context_switch.yaml +0 -49
  370. package/core/dev/pipeline/archived/TASK_165_ctags_symbol_index.yaml +0 -53
  371. package/core/dev/pipeline/archived/TASK_166_symbol_search_mcp_tool.yaml +0 -48
  372. package/core/dev/pipeline/archived/TASK_167_llm_module_summary.yaml +0 -55
  373. package/core/dev/pipeline/archived/TASK_168_map_reduce_context.yaml +0 -51
  374. package/core/dev/pipeline/archived/TASK_169_v2_integration_testing.yaml +0 -52
  375. package/core/dev/pipeline/backups/archive_2026-02-04T22-07-22/TASK_QUEUE_backup.json +0 -95
  376. package/core/dev/pipeline/docs/multi-agent-coordination.md +0 -446
  377. package/core/dev/pipeline/docs/overview.md +0 -406
  378. package/core/dev/pipeline/docs/task-management.md +0 -412
  379. package/core/dev/pipeline/docs/workflows.md +0 -32
  380. package/core/dev/pipeline/orchestrator/schemas/task_queue_schema.json +0 -58
  381. package/core/dev/pipeline/orchestrator/schemas/task_schema.json +0 -139
  382. package/core/dev/pipeline/plans/PLAN_task_cli_refactor.md +0 -281
  383. package/core/dev/pipeline/test_results/TASK_TEST_PARALLEL_002_result.txt +0 -27
  384. package/core/dev/plans/ANSUZ_SLIM_PLAN.md +0 -68
  385. package/core/dev/plans/CLI_FIRST_INSTALL_FLOW.md +0 -120
  386. package/core/dev/plans/FORMATION_RETIREMENT_PLAN.md +0 -313
  387. package/core/dev/plans/KUZU_REPLACEMENT_PLAN.md +0 -126
  388. package/core/dev/scripts/CRASH_DIAGNOSIS.md +0 -47
  389. package/core/dev/scripts/README.md +0 -142
  390. package/core/dev/scripts/RUN_ONCE.bat +0 -40
  391. package/core/dev/scripts/START_DEV_AGENT.bat +0 -63
  392. package/core/dev/scripts/START_MULTI_AGENT.bat +0 -80
  393. package/core/dev/scripts/dev_agent_scheduler.ps1 +0 -536
  394. package/core/dev/scripts/init_git.ps1 +0 -396
  395. package/core/dev/scripts/init_git.sh +0 -337
  396. package/core/dev/scripts/init_project.ps1 +0 -851
  397. package/core/dev/scripts/init_project.sh +0 -477
  398. package/core/dev/scripts/multi_agent_scheduler.ps1 +0 -2021
  399. package/core/dev/scripts/multi_agent_scheduler.sh +0 -1344
  400. package/core/dev/scripts/run_once.sh +0 -47
  401. package/core/dev/scripts/setup_rag.ps1 +0 -304
  402. package/core/dev/scripts/setup_rag.sh +0 -230
  403. package/core/dev/scripts/start_dev_agent.sh +0 -137
  404. package/core/dev/scripts/start_multi_agent.sh +0 -41
  405. package/core/dev/scripts/sync_task_queue.ps1 +0 -505
  406. package/core/dev/scripts/sync_task_queue.sh +0 -392
  407. package/core/dev/specs/agent-connect/PROTOCOL.md +0 -177
  408. package/core/dev/specs/agent-connect/SDK_GUIDE.md +0 -915
  409. package/core/dev/specs/agent-connect/examples/minimal-site/README.md +0 -137
  410. package/core/dev/specs/agent-connect/examples/minimal-site/package.json +0 -12
  411. package/core/dev/specs/agent-connect/examples/minimal-site/public/index.html +0 -116
  412. package/core/dev/specs/agent-connect/examples/minimal-site/public/install-redirect.js +0 -73
  413. package/core/dev/specs/agent-connect/examples/minimal-site/server.js +0 -516
  414. package/core/dev/specs/agent-connect/examples/minimal-site/test/smoke.test.mjs +0 -263
  415. package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-empty-prompt-no-first-turn.md +0 -77
  416. package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-prompt-mojibake.md +0 -90
  417. package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-07.md +0 -61
  418. package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-08_relay-v1-conformance.md +0 -76
  419. package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-09_v0.4-session-channel.md +0 -87
  420. package/core/dev/specs/agent-connect/history/FLOWPIX_REPLY_agent-hub_2026-09-08_relay-v1-answers.md +0 -68
  421. package/core/dev/specs/agent-connect/history/FLOWPIX_bridge_CONTRACT.md +0 -642
  422. package/core/dev/specs/agent-connect/history/FLOWPIX_spikes_relay_spike_relay.mjs +0 -244
  423. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-07.md +0 -77
  424. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_direction-change-v0.3.md +0 -44
  425. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-answers-ack.md +0 -37
  426. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-conformance.md +0 -56
  427. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_annotations-install-coldstart.md +0 -44
  428. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_empty-prompt-first-turn.md +0 -56
  429. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_prompt-mojibake-fixed.md +0 -48
  430. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_session-channel.md +0 -57
  431. package/core/dev/specs/agent-connect/history/PROTOCOL_v0.3_snapshot.md +0 -379
  432. package/core/dev/specs/agent-connect/history/README.md +0 -47
  433. package/core/dev/specs/peer/CODEX_INTERACTIVE_PUSH.md +0 -65
  434. package/core/dev/specs/peer/CODEX_MANAGED_DAEMON.md +0 -54
  435. package/core/dev/specs/peer/CODEX_PEER_PULL_SPIKE.md +0 -54
  436. package/core/dev/specs/peer/MODS_SPIKE.md +0 -133
  437. package/core/dev/specs/peer/PER_PROJECT_ADDRESSING.md +0 -143
  438. package/core/dev/specs/peer/SWARM_PROTOCOLS.md +0 -256
  439. package/core/dev/specs/peer/codex-hook-shim-peer.test.js +0 -113
  440. package/core/dev/specs/peer/codex-push-launcher.test.js +0 -142
  441. package/core/dev/specs/peer/setup-codex-hooks.test.js +0 -60
  442. package/core/dev/specs/peer-ansuz/DELIVERY_SPIKE.md +0 -397
  443. package/core/dev/specs/peer-ansuz/DESIGN.md +0 -109
  444. package/core/dev/specs/peer-ansuz/spike/claude_poke.js +0 -129
  445. package/core/dev/specs/peer-ansuz/spike/claude_session_start_hook.js +0 -37
  446. package/core/dev/specs/peer-ansuz/spike/claude_settings_hook.json +0 -14
  447. package/core/dev/specs/peer-ansuz/spike/codex_appserver_client.js +0 -105
  448. package/core/dev/specs/peer-ansuz/spike/codex_appserver_query.js +0 -29
  449. package/core/dev/specs/peer-ansuz/spike/extract_timeline.js +0 -26
  450. package/core/dev/specs/synapse/SYMBOL_IDENTITY.md +0 -305
  451. package/core/dev/spikes/A4-cypher-varlen.md +0 -176
  452. package/core/dev/spikes/bloat-rounds.sh +0 -25
  453. package/core/dev/spikes/mods/clean-claude.js +0 -9
  454. package/core/dev/spikes/mods/drive-probe.js +0 -29
  455. package/core/dev/spikes/mods/e2e-peer.js +0 -71
  456. package/core/dev/spikes/mods/evidence/e2e-peer-control.json +0 -17
  457. package/core/dev/spikes/mods/evidence/e2e-peer-mod.json +0 -17
  458. package/core/dev/spikes/mods/evidence/probe-006a6e65-d807-4bc1-b648-fd7d1edfe0b4.jsonl +0 -4
  459. package/core/dev/spikes/mods/evidence/probe-cebdf1f7-f9c4-47a8-83cd-7c0786177404.jsonl +0 -12
  460. package/core/dev/spikes/mods/evidence/probe-eb21147d-10ce-4c32-93ed-37ca37d88d5a.jsonl +0 -11
  461. package/core/dev/spikes/mods/evidence/stream-cebdf1f7.jsonl +0 -18
  462. package/core/dev/spikes/mods/kenaz-mod-probe/.claude-plugin/plugin.json +0 -1
  463. package/core/dev/spikes/mods/kenaz-mod-probe/hooks/hooks.json +0 -1
  464. package/core/dev/spikes/mods/kenaz-mod-probe/hooks/register.ts +0 -65
  465. package/core/dev/spikes/mods/kenaz-mod-probe/tsconfig.json +0 -3
@@ -328,7 +328,7 @@ function captureGitCommitSnapshot(taskId) {
328
328
  try {
329
329
  const logOutput = execFileSync(
330
330
  'git', ['log', branch, '--not', 'main', '--oneline'],
331
- { cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
331
+ { windowsHide: true, cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
332
332
  ).toString().trim();
333
333
  snapshot.logOk = true;
334
334
  snapshot.commitLines = logOutput ? logOutput.split('\n').filter(Boolean) : [];
@@ -339,7 +339,7 @@ function captureGitCommitSnapshot(taskId) {
339
339
  try {
340
340
  snapshot.numstatOutput = execFileSync(
341
341
  'git', ['log', branch, '--not', 'main', '--numstat', '--format='],
342
- { cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
342
+ { windowsHide: true, cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
343
343
  ).toString().trim();
344
344
  } catch {
345
345
  // No numstat — non-fatal, mirrors original tolerance for this failure
@@ -446,7 +446,7 @@ function detectGitCommitPattern(taskId, guard, taskData, postCompleteResult) {
446
446
  try {
447
447
  logOutput = execFileSync(
448
448
  'git', ['log', branch, '--not', 'main', '--oneline'],
449
- { cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
449
+ { windowsHide: true, cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
450
450
  ).toString().trim();
451
451
  } catch {
452
452
  return { result: null, reason: 'git_log_failed' };
@@ -463,7 +463,7 @@ function detectGitCommitPattern(taskId, guard, taskData, postCompleteResult) {
463
463
  try {
464
464
  numstatOutput = execFileSync(
465
465
  'git', ['log', branch, '--not', 'main', '--numstat', '--format='],
466
- { cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
466
+ { windowsHide: true, cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
467
467
  ).toString().trim();
468
468
  } catch {
469
469
  // No numstat — still evaluate revert/signature above
@@ -24,7 +24,7 @@ function stamp(d) {
24
24
  }
25
25
 
26
26
  function git(projectPath, args) {
27
- try { return execFileSync('git', args, { cwd: projectPath, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim(); } catch { return ''; }
27
+ try { return execFileSync('git', args, { windowsHide: true, cwd: projectPath, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim(); } catch { return ''; }
28
28
  }
29
29
 
30
30
  function template({ topic, session, projectPath, now }) {
@@ -258,13 +258,13 @@ function rm(id, o = {}) {
258
258
  return l;
259
259
  }
260
260
 
261
- /** Project lessons for the dispatch prompt: facts (paths overlap scope_paths) and checks; bounded, most-fired first. */
261
+ /** Project lessons for the dispatch prompt: facts and checks whose paths overlap scope_paths (no paths = every card); bounded, most-fired first. */
262
262
  function dispatchLessons(projectPath, scopePaths = [], { home, now } = {}) {
263
263
  const norm = (s) => String(s).replace(/\\/g, '/').toLowerCase();
264
264
  const scope = scopePaths.map(norm);
265
265
  const overlaps = (l) => !l.paths.length || l.paths.some((p) => scope.some((s) => s.includes(norm(p)) || norm(p).includes(s)));
266
266
  const pick = listLayer('project', { projectPath, home, now })
267
- .filter((l) => !l.triggers.length && ((l.type === 'fact' && overlaps(l)) || l.type === 'check'));
267
+ .filter((l) => !l.triggers.length && (l.type === 'fact' || l.type === 'check') && overlaps(l));
268
268
  const out = { facts: [], checks: [] };
269
269
  let bytes = 0, lines = 0;
270
270
  for (const l of pick) {
package/core/CLAUDE.md CHANGED
@@ -61,7 +61,7 @@ harness 預設「每條記憶都在 MEMORY.md 加一行」;本專案改為三
61
61
  KenazAI 是一個 Claude Code 多 Agent 協作系統,包含:
62
62
  - **kenaz-server**:Rust 後端(`dashboard/src-tauri/`,npm `@kenazai/server-*`);Dashboard 桌面版已於 2026-10-11 退役(TASK_2396)
63
63
  - **Specialist 系統**:AI Agent 調度引擎(`.specialist/`)
64
- - **Formation 系統**:多 Agent 協作調度,支援 unit/solo/squad/legion 陣型(`.formation/`)
64
+ - **Formation 工具**:subagent worktree 派工與合併工具(`.formation/tools/`);unit/solo/squad/legion 與 `kenaz_dispatch` 已退役,只剩 subagent 派工
65
65
 
66
66
  技術棧:Rust(kenaz-server)、Node.js(kenaz CLI、hooks、工具)、SQLite
67
67
 
@@ -72,7 +72,7 @@ KenazAI 是一個 Claude Code 多 Agent 協作系統,包含:
72
72
  | Specialist | 定位 | 指令 |
73
73
  |-----------|------|------|
74
74
  | **Ansuz** ᚨ | 產品全生命週期引擎(需求→架構→任務→執行) | `/Ansuz` |
75
- | **Amelia** | Agent Center 調度者(多 Agent 協作) | `/Amelia` |
75
+ | **Amelia** | 多 Agent 協作調度者 | `/Amelia` |
76
76
 
77
77
  文檔:`.specialist/Ansuz/SYSTEM_DOC.md`、`.specialist/Amelia/README.md`
78
78
 
@@ -128,7 +128,7 @@ node .collaboration/core/task-api.js move TASK_XXX active # 移動狀態
128
128
  | 規則庫 | `.rule/` | 最高優先級規則,見 `INDEX.yaml` |
129
129
  | 失敗學習 | `.failure/` | 已知失敗模式,Agent 執行前應檢查 |
130
130
  | Rust 測試 | `npm run test:rust -- <filter>` | 主目錄直接可跑;用共用短路徑 target,不和其他建置搶 `target/` 鎖。勿直接 `cargo test` |
131
- | Formation | `.formation/` | 多 Agent 調度,見 `README.md` |
131
+ | Formation | `.formation/` | subagent 派工與合併工具,見 `README.md` |
132
132
  | Skills | `.claude/skills/` | Agent 行為定義(40+ skills) |
133
133
  | 外部 Skills | `.agents/skills/` | `vercel-react-best-practices`、`supabase-postgres-best-practices` |
134
134
 
@@ -137,7 +137,7 @@ node .collaboration/core/task-api.js move TASK_XXX active # 移動狀態
137
137
  KenazAI 支援管理子專案。Core 擁有系統檔,子專案只存 `.kenaz/`(tasks + logs + project.yaml)。
138
138
 
139
139
  子專案工作時:讀取 `.kenaz/project.yaml` 的 `core_path` 確定系統檔來源。
140
- task-api 和 Formation dispatch 都支援 `--project-path` 參數。
140
+ task-api 和 `.formation/tools/dispatch.js` 都支援 `--project-path` 參數。
141
141
 
142
142
  文檔:`.system/collaboration/README.md`
143
143
 
@@ -155,7 +155,7 @@ DB: postgresql://postgres:postgres@127.0.0.1:54322/postgres
155
155
  .rule/ # 規則庫(最高優先級)
156
156
  .specialist/ # Specialist 系統(Ansuz、Amelia)
157
157
  .collaboration/ # 任務系統
158
- .formation/ # Formation 調度
158
+ .formation/ # subagent 派工與合併工具
159
159
  .failure/ # 失敗學習系統
160
160
  .memory/ # (歷史)舊記憶資料,記憶系統已移除
161
161
  .claude/ # Skills、Commands、Hooks
@@ -1 +1 @@
1
- 0.3.22
1
+ 0.3.23
@@ -22,6 +22,8 @@ const MIN_CLI = [2, 1, 287];
22
22
  const SEP = process.platform === 'win32' ? ';' : ':';
23
23
  const TASK_NAME = 'KenazServer';
24
24
  const LABEL = 'ai.kenaz.server';
25
+ const BATTERY_PS = '$s = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit ([TimeSpan]::Zero); Set-ScheduledTask -TaskName ' + TASK_NAME + ' -Settings $s';
26
+ const linuxUser = () => { try { return os.userInfo().username; } catch (_) { return process.env.USER || ''; } };
25
27
 
26
28
  const norm = (e) => {
27
29
  const s = String(e).trim().replace(/\\/g, '/').replace(/\/+$/, '');
@@ -136,8 +138,8 @@ function retireDashboardHooks(file, dry) {
136
138
 
137
139
  function claudeVersion() {
138
140
  const r = process.platform === 'win32' // one string with shell (.cmd shim): args + shell:true is deprecated (DEP0190)
139
- ? spawnSync('claude --version', { encoding: 'utf8', shell: true, timeout: 15000 })
140
- : spawnSync('claude', ['--version'], { encoding: 'utf8', timeout: 15000 });
141
+ ? spawnSync('claude --version', { windowsHide: true, encoding: 'utf8', shell: true, timeout: 15000 })
142
+ : spawnSync('claude', ['--version'], { windowsHide: true, encoding: 'utf8', timeout: 15000 });
141
143
  return r.status === 0 ? parseVersion(r.stdout) : null;
142
144
  }
143
145
 
@@ -208,7 +210,7 @@ function servicePlan(home, bin, core, platform = process.platform, caps = { syst
208
210
  const p = path.join(home, '.config', 'systemd', 'user', 'kenaz-server.service');
209
211
  return { kind: 'systemd', files: [[p, systemdUnit(bin, core)]], unit: p };
210
212
  }
211
- const sh = (cmd, args, opts) => spawnSync(cmd, args, { encoding: 'utf8', ...(opts || {}) });
213
+ const sh = (cmd, args, opts) => spawnSync(cmd, args, { windowsHide: true, encoding: 'utf8', ...(opts || {}) });
212
214
 
213
215
  // crontab -l: null = no crontab binary; '' = binary present, no crontab yet. All through the injected `run`.
214
216
  function readCron(run) {
@@ -303,8 +305,13 @@ function serviceInstall(plan, dry, log, run = sh, uid) {
303
305
  log('schtasks /Create /TN ' + TASK_NAME + ' /SC ONLOGON /TR ' + tr + ' /F (fallback: ' + plan.fallbackFile + ')');
304
306
  if (dry) return;
305
307
  const r = sh('schtasks', ['/Create', '/TN', TASK_NAME, '/SC', 'ONLOGON', '/TR', tr, '/F']);
306
- if (r.status === 0) sh('schtasks', ['/Run', '/TN', TASK_NAME]);
307
- else { // ONLOGON tasks can need elevation: a Startup-folder launcher is the per-user equivalent
308
+ if (r.status === 0) {
309
+ // Task Scheduler defaults refuse to start on battery and stop the task when going on battery:
310
+ // a laptop unplugged at logon never got the server (TASK_2468). Re-running install fixes an old task.
311
+ const b = sh('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', BATTERY_PS]);
312
+ if (b.status !== 0) log('WARNING: could not set the task to run on battery (exit ' + b.status + '); on a laptop the server may not start unplugged. Run in PowerShell: ' + BATTERY_PS);
313
+ sh('schtasks', ['/Run', '/TN', TASK_NAME]);
314
+ } else { // ONLOGON tasks can need elevation: a Startup-folder launcher is the per-user equivalent
308
315
  fs.mkdirSync(path.dirname(plan.fallbackFile), { recursive: true });
309
316
  fs.copyFileSync(plan.files[0][0], plan.fallbackFile);
310
317
  sh('wscript.exe', [plan.files[0][0]]);
@@ -326,6 +333,10 @@ function serviceInstall(plan, dry, log, run = sh, uid) {
326
333
  } else {
327
334
  log('systemctl --user enable --now kenaz-server');
328
335
  if (!dry) { sh('systemctl', ['--user', 'daemon-reload']); sh('systemctl', ['--user', 'enable', '--now', 'kenaz-server']); }
336
+ // Without linger the user service starts only at login (headless boxes: never). Best effort.
337
+ const u = linuxUser();
338
+ log('loginctl enable-linger ' + u);
339
+ if (!dry && sh('loginctl', ['enable-linger', u]).status !== 0) log('WARNING: could not enable linger; the server starts at boot only after you log in. Run: loginctl enable-linger ' + u + ' (may need sudo)');
329
340
  serviceRestart(plan, dry, log, sh, uid);
330
341
  }
331
342
  }
@@ -365,7 +376,11 @@ function detectServiceMode(home, core, run = sh, platform = process.platform) {
365
376
  return fs.existsSync(p) ? { mode: 'launchd', detail: p } : { mode: 'manual', detail: 'no launchd agent; run `kenaz install`' };
366
377
  }
367
378
  const unit = servicePlan(home, '', core, 'linux').unit;
368
- if (fs.existsSync(unit) && probeLinux(run).systemd) return { mode: 'systemd', detail: unit };
379
+ if (fs.existsSync(unit) && probeLinux(run).systemd) {
380
+ const u = linuxUser();
381
+ const off = /Linger=no/.test(run('loginctl', ['show-user', u, '-p', 'Linger']).stdout || '');
382
+ return off ? { mode: 'systemd', detail: unit + '; linger is off, the server starts only after login: run loginctl enable-linger ' + u, warn: true } : { mode: 'systemd', detail: unit };
383
+ }
369
384
  const c = readCron(run);
370
385
  if (c && c.includes(CRON_MARK)) return { mode: 'cron', detail: '@reboot crontab entry (no systemd user session)' };
371
386
  return { mode: 'manual', detail: 'no systemd unit or cron entry; run `kenaz install`' };
@@ -103,7 +103,7 @@ function countLines(text) {
103
103
  }
104
104
 
105
105
  function git(args, cwd) {
106
- const result = spawnSync('git', args, { cwd, encoding: 'utf8' });
106
+ const result = spawnSync('git', args, { windowsHide: true, cwd, encoding: 'utf8' });
107
107
  return result;
108
108
  }
109
109
 
@@ -40,7 +40,7 @@ const TASK_API = path.join(ROOT, '.collaboration', 'core', 'task-api.js');
40
40
  // ─────────────────────────────────────────
41
41
 
42
42
  function runTaskApi(...args) {
43
- const result = spawnSync('node', [TASK_API, ...args], {
43
+ const result = spawnSync('node', [TASK_API, ...args], { windowsHide: true,
44
44
  encoding: 'utf8',
45
45
  timeout: 15000,
46
46
  cwd: ROOT,
@@ -72,11 +72,11 @@ const DRY_RUN = !process.argv.includes('--apply');
72
72
  // ─── Git helpers (GEN-008: dynamic root, never hardcoded) ────────────────────
73
73
 
74
74
  function gitRoot() {
75
- return execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
75
+ return execSync('git rev-parse --show-toplevel', { windowsHide: true, encoding: 'utf8' }).trim();
76
76
  }
77
77
 
78
78
  function currentBranch() {
79
- return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
79
+ return execSync('git rev-parse --abbrev-ref HEAD', { windowsHide: true, encoding: 'utf8' }).trim();
80
80
  }
81
81
 
82
82
  /**
@@ -84,7 +84,7 @@ function currentBranch() {
84
84
  * Uses exit code of `git merge-base --is-ancestor <commit> HEAD`.
85
85
  */
86
86
  function isAncestorOfHead(tipCommit) {
87
- const result = spawnSync('git', ['merge-base', '--is-ancestor', tipCommit, 'HEAD'], {
87
+ const result = spawnSync('git', ['merge-base', '--is-ancestor', tipCommit, 'HEAD'], { windowsHide: true,
88
88
  encoding: 'utf8',
89
89
  });
90
90
  return result.status === 0;
@@ -95,7 +95,7 @@ function isAncestorOfHead(tipCommit) {
95
95
  * Each entry: { path, head, branch, locked, lockReason }
96
96
  */
97
97
  function listWorktrees() {
98
- const raw = execSync('git worktree list --porcelain', { encoding: 'utf8' });
98
+ const raw = execSync('git worktree list --porcelain', { windowsHide: true, encoding: 'utf8' });
99
99
  const entries = [];
100
100
  let current = null;
101
101
 
@@ -199,7 +199,7 @@ function listUntrackedAgentDirs(root, trackedPaths) {
199
199
  function listDanglingAgentBranches(trackedBranches) {
200
200
  let raw = '';
201
201
  try {
202
- raw = execSync('git branch --list "worktree-agent-*" --format="%(refname:short)"', { encoding: 'utf8' });
202
+ raw = execSync('git branch --list "worktree-agent-*" --format="%(refname:short)"', { windowsHide: true, encoding: 'utf8' });
203
203
  } catch {
204
204
  return [];
205
205
  }
@@ -209,7 +209,7 @@ function listDanglingAgentBranches(trackedBranches) {
209
209
  const b = line.trim();
210
210
  if (!b || trackedSet.has(b)) continue;
211
211
  let tip = '';
212
- try { tip = execSync(`git rev-parse "${b}"`, { encoding: 'utf8' }).trim(); } catch { /* ignore */ }
212
+ try { tip = execSync(`git rev-parse "${b}"`, { windowsHide: true, encoding: 'utf8' }).trim(); } catch { /* ignore */ }
213
213
  out.push({ branch: b, tip, integrated: tip ? isAncestorOfHead(tip) : false });
214
214
  }
215
215
  return out;
@@ -354,7 +354,7 @@ function main() {
354
354
  // Unlock if locked (harness may have left lock even after pid is gone)
355
355
  if (wt.locked) {
356
356
  try {
357
- execSync(`git worktree unlock "${wt.path}"`, { encoding: 'utf8' });
357
+ execSync(`git worktree unlock "${wt.path}"`, { windowsHide: true, encoding: 'utf8' });
358
358
  } catch {
359
359
  // unlock may fail if git disagrees — proceed, remove --force handles it
360
360
  }
@@ -374,7 +374,7 @@ function main() {
374
374
 
375
375
  // Remove worktree (--force bypasses remaining lock metadata)
376
376
  try {
377
- execSync(`git worktree remove --force "${wt.path}"`, { encoding: 'utf8' });
377
+ execSync(`git worktree remove --force "${wt.path}"`, { windowsHide: true, encoding: 'utf8' });
378
378
  } catch (err) {
379
379
  console.log(` FAILED (worktree remove): ${err.message.trim()}`);
380
380
  failedCount++;
@@ -384,7 +384,7 @@ function main() {
384
384
  // Delete the branch (best-effort; branch may already be deleted or missing)
385
385
  if (wt.branch) {
386
386
  try {
387
- execSync(`git branch -D "${wt.branch}"`, { encoding: 'utf8' });
387
+ execSync(`git branch -D "${wt.branch}"`, { windowsHide: true, encoding: 'utf8' });
388
388
  } catch {
389
389
  // Branch may already be deleted — not an error
390
390
  }
@@ -396,7 +396,7 @@ function main() {
396
396
 
397
397
  // Prune stale worktree admin dirs (idempotent, always safe)
398
398
  try {
399
- execSync('git worktree prune', { encoding: 'utf8' });
399
+ execSync('git worktree prune', { windowsHide: true, encoding: 'utf8' });
400
400
  console.log('\n git worktree prune done');
401
401
  } catch (err) {
402
402
  console.log(`\n git worktree prune FAILED (non-fatal): ${err.message.trim()}`);
@@ -419,7 +419,7 @@ function main() {
419
419
  for (const b of danglingBranches) {
420
420
  if (!b.integrated) continue; // keep not-in-HEAD branches for salvage
421
421
  try {
422
- execSync(`git branch -D "${b.branch}"`, { encoding: 'utf8' });
422
+ execSync(`git branch -D "${b.branch}"`, { windowsHide: true, encoding: 'utf8' });
423
423
  danglingDeleted++;
424
424
  } catch { /* already gone — not an error */ }
425
425
  }
@@ -218,7 +218,7 @@ function parseCliArgs(argv) {
218
218
  function resolveExecutableWindows(whereFn) {
219
219
  whereFn = whereFn || function runWhere() {
220
220
  try {
221
- return cp.execSync('where claude', { encoding: 'utf8' });
221
+ return cp.execSync('where claude', { windowsHide: true, encoding: 'utf8' });
222
222
  } catch (e) {
223
223
  return '';
224
224
  }
@@ -263,13 +263,13 @@ function escapeCmdExe(exe) {
263
263
 
264
264
  function launch(exec, cwd, argv) {
265
265
  if (exec.useShell) {
266
- return cp.spawn(escapeCmdExe(exec.command), argv.map(escapeCmdArg), {
266
+ return cp.spawn(escapeCmdExe(exec.command), argv.map(escapeCmdArg), { windowsHide: true,
267
267
  cwd,
268
268
  stdio: 'inherit',
269
269
  shell: true,
270
270
  });
271
271
  }
272
- return cp.spawn(exec.command, argv, { cwd, stdio: 'inherit', shell: false });
272
+ return cp.spawn(exec.command, argv, { windowsHide: true, cwd, stdio: 'inherit', shell: false });
273
273
  }
274
274
 
275
275
  // ---- main ----
@@ -59,12 +59,12 @@ function start(name, exe, args, env, cwd) {
59
59
  }
60
60
  async function stop(p) {
61
61
  if (!p || p.exited) return;
62
- if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(p.pid), '/T', '/F'], { stdio: 'ignore' }); // our PID only
62
+ if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(p.pid), '/T', '/F'], { windowsHide: true, stdio: 'ignore' }); // our PID only
63
63
  else p.child.kill('SIGKILL');
64
64
  await until(`${p.name} exit`, () => p.exited, 15000, 100).catch(() => {});
65
65
  }
66
66
  function sh(cmd, args, env) {
67
- const r = spawnSync(cmd, args, { env: { ...process.env, ...env }, encoding: 'utf8' });
67
+ const r = spawnSync(cmd, args, { windowsHide: true, env: { ...process.env, ...env }, encoding: 'utf8' });
68
68
  return { code: r.status, out: `${r.stdout || ''}${r.stderr || ''}`.trim() };
69
69
  }
70
70
  function sqlite(file, readOnly = true) {
@@ -398,5 +398,5 @@ async function main() {
398
398
  return bad ? 1 : 0;
399
399
  }
400
400
 
401
- process.on('SIGINT', () => { for (const p of procs) if (!p.exited) { if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(p.pid), '/T', '/F'], { stdio: 'ignore' }); else p.child.kill('SIGKILL'); } process.exit(130); });
401
+ process.on('SIGINT', () => { for (const p of procs) if (!p.exited) { if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(p.pid), '/T', '/F'], { windowsHide: true, stdio: 'ignore' }); else p.child.kill('SIGKILL'); } process.exit(130); });
402
402
  main().then((c) => process.exit(c), (e) => { console.error(e); process.exit(1); });
@@ -142,7 +142,7 @@ function main() {
142
142
  const build = spawnSync(
143
143
  'cargo',
144
144
  ['test', '--lib', '--no-run', '--message-format=json'],
145
- { cwd: crateDir, encoding: 'utf8', shell: false, maxBuffer: 256 * 1024 * 1024, env }
145
+ { windowsHide: true, cwd: crateDir, encoding: 'utf8', shell: false, maxBuffer: 256 * 1024 * 1024, env }
146
146
  );
147
147
  if (build.status !== 0) {
148
148
  const compilerErrors = renderCompilerErrors(build.stdout);
@@ -180,7 +180,7 @@ function main() {
180
180
  }
181
181
 
182
182
  // 3. Run the artifact directly.
183
- const run = spawnSync(testExe, exeArgs, { stdio: 'inherit' });
183
+ const run = spawnSync(testExe, exeArgs, { windowsHide: true, stdio: 'inherit' });
184
184
  process.exit(run.status ?? 1);
185
185
  }
186
186
 
@@ -36,7 +36,7 @@ function evaluate(streamText, expected) {
36
36
  }
37
37
 
38
38
  function copyRepo(dest) {
39
- const files = execFileSync('git', ['ls-files', '-z'], { cwd: REPO, encoding: 'utf8', maxBuffer: 1 << 28 }).split('\0').filter(Boolean);
39
+ const files = execFileSync('git', ['ls-files', '-z'], { windowsHide: true, cwd: REPO, encoding: 'utf8', maxBuffer: 1 << 28 }).split('\0').filter(Boolean);
40
40
  for (const f of files) {
41
41
  const from = path.join(REPO, f);
42
42
  if (!fs.existsSync(from)) continue;
@@ -49,11 +49,11 @@ function runScenario(sc, opts) {
49
49
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'skill-replay-'));
50
50
  try {
51
51
  copyRepo(dir);
52
- execFileSync('git', ['init', '-q'], { cwd: dir });
52
+ execFileSync('git', ['init', '-q'], { windowsHide: true, cwd: dir });
53
53
  const prompt = (sc.prefix === undefined ? '/Ansuz ' : sc.prefix) + sc.message;
54
54
  // Prompt goes on stdin: with shell:true (needed on Windows) argv is concatenated unquoted, which split the message.
55
55
  const r = spawnSync('claude', ['-p', '--output-format', 'stream-json', '--verbose', '--max-turns', String(opts.maxTurns)],
56
- { cwd: dir, input: prompt, encoding: 'utf8', maxBuffer: 1 << 28, timeout: opts.timeoutMs, shell: process.platform === 'win32' });
56
+ { windowsHide: true, cwd: dir, input: prompt, encoding: 'utf8', maxBuffer: 1 << 28, timeout: opts.timeoutMs, shell: process.platform === 'win32' });
57
57
  const ev = evaluate(r.stdout || '', sc.expected);
58
58
  return { id: sc.id, expected: sc.expected, hit: ev.hit, calls: ev.calls, exit: r.status, error: r.error && r.error.message };
59
59
  } finally {
@@ -120,7 +120,7 @@ async function testSlowServe() {
120
120
  KENAZ_FIXTURE_SLOW_PHASE_MS: '4000',
121
121
  });
122
122
  const spawnedAt = Date.now();
123
- const child = spawn(process.execPath, [SLOW_SERVE], { env, stdio: ['ignore', 'pipe', 'pipe'] });
123
+ const child = spawn(process.execPath, [SLOW_SERVE], { windowsHide: true, env, stdio: ['ignore', 'pipe', 'pipe'] });
124
124
  spawnedPids.push(child.pid);
125
125
  let out = '';
126
126
  child.stdout.on('data', (d) => (out += d.toString()));
@@ -166,7 +166,7 @@ async function testSlowServe() {
166
166
 
167
167
  async function testNeverListens() {
168
168
  console.log('\n[selftest] never-listens.server.js');
169
- const child = spawn(process.execPath, [NEVER_LISTENS], { stdio: ['ignore', 'pipe', 'pipe'] });
169
+ const child = spawn(process.execPath, [NEVER_LISTENS], { windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'] });
170
170
  spawnedPids.push(child.pid);
171
171
  let exited = false;
172
172
  child.on('exit', () => {
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+ // TASK_2474 guard: every child process Kenaz starts must be hidden on Windows.
3
+ // - Node: spawn/exec* calls in shipped JS must pass windowsHide (inline in the call, or on an options
4
+ // object defined in the same file). JS_ALLOW = intentionally visible terminals, with reasons.
5
+ // - Rust: Command::new in non-test Rust files outside common/process.rs must be hidden_command.
6
+ const test = require('node:test');
7
+ const assert = require('node:assert');
8
+ const fs = require('node:fs');
9
+ const path = require('node:path');
10
+
11
+ const ROOT = path.resolve(__dirname, '..', '..');
12
+ const JS_DIRS = ['.specialist/tools', '.formation', '.claude/hooks', 'plugins/kenaz/hooks', 'plugins/kenaz/scripts',
13
+ '.collaboration/core', 'packages/kenaz/lib', 'packages/kenaz/bin', 'dashboard/scripts', 'dev/scripts'];
14
+ const RS_DIR = 'dashboard/src-tauri/src';
15
+
16
+ // "relative/path.js:line" -> reason. Intentionally visible terminals only.
17
+ const JS_ALLOW = {
18
+ 'dev/scripts/task1961/selftest.js:132': 'false positive: "spawn (took ..." inside a template-string message, not a call',
19
+ };
20
+ // "relative/path.rs" -> reason (whole file may use raw Command::new outside #[cfg(test)]).
21
+ const RS_ALLOW = {
22
+ 'dashboard/src-tauri/src/common/process.rs': 'the hidden_command constructors themselves',
23
+ };
24
+
25
+ function walk(dir, exts, out = []) {
26
+ const abs = path.join(ROOT, dir);
27
+ if (!fs.existsSync(abs)) return out;
28
+ for (const e of fs.readdirSync(abs, { withFileTypes: true })) {
29
+ if (['node_modules', '.git', 'target', 'dist', 'fixtures'].includes(e.name)) continue;
30
+ const rel = dir + '/' + e.name;
31
+ if (e.isDirectory()) walk(rel, exts, out);
32
+ else if (exts.some((x) => e.name.endsWith(x)) && !/\.test\.[cm]?js$/.test(e.name)) out.push(rel);
33
+ }
34
+ return out;
35
+ }
36
+
37
+ // plugins/kenaz/hooks/core-resolve.js is generated (gitignored) from .claude/hooks/core-resolve.js
38
+ const isGenerated = (rel) => rel === 'plugins/kenaz/hooks/core-resolve.js';
39
+
40
+ function matchParen(src, open) {
41
+ let depth = 0, q = null;
42
+ for (let i = open; i < src.length; i++) {
43
+ const c = src[i];
44
+ if (q) { if (c === '\\') i++; else if (c === q) q = null; continue; }
45
+ if (c === '"' || c === "'" || c === '`') { q = c; continue; }
46
+ if (c === '(') depth++;
47
+ else if (c === ')' && --depth === 0) return i;
48
+ }
49
+ return src.length;
50
+ }
51
+
52
+ function scanJs(rel, src) {
53
+ if (!/child_process/.test(src)) return [];
54
+ const bad = [];
55
+ // blank block comments and whole-line // comments (offsets and line numbers preserved)
56
+ src = src.replace(/\/\*[\s\S]*?\*\//g, (c) => c.replace(/[^\n]/g, ' ')).replace(/^[ \t]*\/\/.*$/gm, (c) => ' '.repeat(c.length));
57
+ const re = /(?<![\w$.])(?:(?:cp|child_process|childProcess|proc)\.)?(spawn|spawnSync|exec|execSync|execFile|execFileSync)\s*\(/g;
58
+ let m;
59
+ while ((m = re.exec(src))) {
60
+ const open = m.index + m[0].length - 1;
61
+ const args = src.slice(open, matchParen(src, open) + 1);
62
+ if (/windowsHide/.test(args)) continue;
63
+ // options passed as a bare identifier: accept when that identifier is defined with windowsHide in the file
64
+ const last = args.slice(1, -1).split(',').pop().trim();
65
+ if (/^[A-Za-z_$][\w$]*$/.test(last) && new RegExp(`${last}\\s*=\\s*\\{[^;]*windowsHide`).test(src)) continue;
66
+ const line = src.slice(0, m.index).split('\n').length;
67
+ if (JS_ALLOW[`${rel}:${line}`]) continue;
68
+ bad.push(`${rel}:${line} ${m[1]}`);
69
+ }
70
+ return bad;
71
+ }
72
+
73
+ function scanRs(rel, src) {
74
+ if (RS_ALLOW[rel]) return [];
75
+ const cut = src.search(/#\[cfg\(test\)\]/);
76
+ const body = cut >= 0 ? src.slice(0, cut) : src;
77
+ const bad = [];
78
+ body.split('\n').forEach((ln, i) => {
79
+ if (/^\s*\/\//.test(ln)) return;
80
+ if (/Command::new\s*\(/.test(ln) && !/hidden_/.test(ln)) bad.push(`${rel}:${i + 1}`);
81
+ });
82
+ return bad;
83
+ }
84
+
85
+ test('Node: every child_process call passes windowsHide', () => {
86
+ const files = JS_DIRS.flatMap((d) => walk(d, ['.js', '.cjs', '.mjs'])).filter((f) => !isGenerated(f));
87
+ const bad = files.flatMap((f) => scanJs(f, fs.readFileSync(path.join(ROOT, f), 'utf8')));
88
+ console.log(`node violations: ${bad.length}`);
89
+ assert.deepStrictEqual(bad, []);
90
+ });
91
+
92
+ test('Rust: no raw Command::new in production code outside common/process.rs', () => {
93
+ const files = walk(RS_DIR, ['.rs']).filter((f) => !/(^|\/)tests?\.rs$|_tests?\.rs$|\/tests\//.test(f));
94
+ const bad = files.flatMap((f) => scanRs(f, fs.readFileSync(path.join(ROOT, f), 'utf8')));
95
+ console.log(`rust violations: ${bad.length}`);
96
+ assert.deepStrictEqual(bad, []);
97
+ });
@@ -2,5 +2,6 @@
2
2
  - Code navigation: kenaz_lsp_callers / kenaz_lsp_references / kenaz_lsp_definition / kenaz_lsp_symbols (always pass projectPath). Text search: Grep/Glob.
3
3
  - Collaboration: kenaz_peer_send / kenaz_peer_threads (other sessions, other machines, Codex), /kenaz ygg status|join.
4
4
  - Rooms: when the user pastes a room key or asks to join/create a room, run `kenaz ygg join <key>` / `kenaz ygg create` yourself (never ask them to type it), then relay the status block and any "restart Claude Code" note.
5
+ - Reporting a Kenaz problem or idea: call kenaz_wish_create (scope kenaz) yourself; it uploads to the Kenaz mother (Alaya) automatically, no user step. Claude Code's SendFeedback tool and /feedback go to Anthropic, never to Kenaz.
5
6
  - Reply in the user's language. Commands: /Ansuz, /Amelia, /review, /security, /incident, /spec.
6
7
  - Switch: /kenaz off | assist | full (or env KENAZ_MODE). off disables every Kenaz hook.
@@ -221,7 +221,7 @@ if (require.main === module) {
221
221
  if (!result) process.exit(0); // silent -- non-blocking hook
222
222
 
223
223
  try {
224
- execFileSync("node", [result.resolved, ...result.args], { stdio: "inherit" });
224
+ execFileSync("node", [result.resolved, ...result.args], { stdio: "inherit", windowsHide: true });
225
225
  } catch {
226
226
  // Hook errors should not block
227
227
  }
@@ -13,7 +13,8 @@ const fs = require('fs');
13
13
  const path = require('path');
14
14
  const net = require('net');
15
15
  const http = require('http');
16
- const { spawnSync } = require('child_process');
16
+ const os = require('os');
17
+ const { spawn, spawnSync } = require('child_process');
17
18
  const { resolveMode, allows, projectDir } = require('./mode');
18
19
  const { isSdkSession } = require('./sdk-gate');
19
20
 
@@ -49,6 +50,42 @@ function backendUp(cb) {
49
50
  s.on('error', () => done(false));
50
51
  }
51
52
 
53
+ // TASK_2468: after a reboot nothing has started kenaz-server yet (the plugin MCP is a static http URL).
54
+ // Start the installed binary detached, the way the installer does; never by process name, and only
55
+ // called after the port probe failed (a second server is never started over an answering one).
56
+ function startServer(dir) {
57
+ try {
58
+ const home = os.homedir();
59
+ const meta = JSON.parse(fs.readFileSync(path.join(home, '.kenaz', 'install.json'), 'utf8'));
60
+ const bin = meta && meta.serverBin;
61
+ if (!bin || !fs.existsSync(bin)) return false;
62
+ const vbs = path.join(home, '.kenaz', 'kenaz-server.vbs');
63
+ const core = coreDir(dir);
64
+ const env = Object.assign({}, process.env, core ? { KENAZ_SOURCE_DIR: core } : {});
65
+ const opts = { env, detached: true, stdio: 'ignore', windowsHide: true };
66
+ const viaNode = /\.js$/.test(bin); // a script (tests) runs under node; the real server is a binary
67
+ let child;
68
+ if (process.platform === 'win32') {
69
+ child = fs.existsSync(vbs) ? spawn('wscript.exe', [vbs], opts) : viaNode ? spawn(process.execPath, [bin], opts) : spawn(bin, [], opts);
70
+ } else {
71
+ const log = path.join(home, '.kenaz', 'kenaz-server.log');
72
+ const sq = (v) => "'" + String(v).replace(/'/g, "'\\''") + "'";
73
+ const cmd = 'if command -v setsid >/dev/null 2>&1; then S=setsid; else S=; fi; $S nohup ' +
74
+ (viaNode ? sq(process.execPath) + ' ' : '') + sq(bin) + ' >> ' + sq(log) + ' 2>&1 < /dev/null &';
75
+ child = spawn('sh', ['-c', cmd], opts);
76
+ }
77
+ child.on('error', () => {});
78
+ child.unref();
79
+ return true;
80
+ } catch (_) { return false; }
81
+ }
82
+
83
+ function waitForBackend(ms, cb) {
84
+ const end = Date.now() + ms;
85
+ const tick = () => backendUp((ok) => { if (ok || Date.now() >= end) return cb(ok); setTimeout(tick, 150); });
86
+ tick();
87
+ }
88
+
52
89
  function post(body, cb) {
53
90
  const r = http.request({ hostname: HOST, port: PORT, path: '/api/rust/agent-flow/hook', method: 'POST',
54
91
  headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }, timeout: 3000 },
@@ -75,7 +112,7 @@ function run(spec, stdin, dir) {
75
112
  const stdio = ['pipe', 'inherit', 'ignore'];
76
113
  if (spec.kind === 'core-script') {
77
114
  const target = path.join(core, spec.rel);
78
- if (fs.existsSync(target)) spawnSync(process.execPath, [target, ...(spec.args || [])], { cwd: dir, env, input: stdin, stdio, timeout: 10000 });
115
+ if (fs.existsSync(target)) spawnSync(process.execPath, [target, ...(spec.args || [])], { cwd: dir, env, input: stdin, stdio, timeout: 10000, windowsHide: true });
79
116
  return;
80
117
  }
81
118
  const file = path.join(core, '.claude', 'hooks', spec.file);
@@ -83,7 +120,7 @@ function run(spec, stdin, dir) {
83
120
  // Same shape as the core's own `node -e "chdir; require(hook)"` wrappers (require.main stays undefined).
84
121
  const code = 'process.chdir(process.env.CLAUDE_PROJECT_DIR);const m=require(process.argv[1]);' +
85
122
  (spec.call ? 'm[process.argv[2]]();' : '');
86
- spawnSync(process.execPath, ['-e', code, file, spec.call || ''], { cwd: dir, env, input: stdin, stdio, timeout: 10000 });
123
+ spawnSync(process.execPath, ['-e', code, file, spec.call || ''], { cwd: dir, env, input: stdin, stdio, timeout: 10000, windowsHide: true });
87
124
  }
88
125
 
89
126
  function main() {
@@ -105,7 +142,18 @@ function main() {
105
142
  }
106
143
  run(spec, stdin, dir);
107
144
  };
108
- if (spec.backend) backendUp((ok) => { if (ok) go(); }); else go();
145
+ if (!spec.backend) return go();
146
+ backendUp((ok) => {
147
+ if (ok) return go();
148
+ if (spec.kind !== 'session-start') return;
149
+ const finish = (up) => {
150
+ if (up) go();
151
+ process.stdout.write(up
152
+ ? 'kenaz-server was not running; the Kenaz hook started it on ' + HOST + ':' + PORT + '. If the kenaz MCP tools (kenaz-dashboard) show as failed, ask the user to run /mcp to reconnect them (they connected before the server was up).\n'
153
+ : 'kenaz-server is not running on ' + HOST + ':' + PORT + ', so the kenaz MCP tools are unavailable. Ask the user to run `! npx kenaz install` (registers the boot service and starts it), then /mcp to reconnect kenaz-dashboard.\n');
154
+ };
155
+ if (startServer(dir)) waitForBackend(3000, finish); else finish(false);
156
+ });
109
157
  }
110
158
 
111
159
  process.on('uncaughtException', () => process.exit(0));