kenaz 0.3.22 → 0.3.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/.claude/hooks/_user-scope.js +1 -1
- package/core/.claude/hooks/core-resolve.js +1 -1
- package/core/.claude/hooks/worktree-create.js +11 -29
- package/core/.claude/hooks/worktree-remove.js +12 -38
- package/core/.collaboration/core/reconcile.js +16 -1
- package/core/.collaboration/core/task-2467-lifecycle.test.js +63 -0
- package/core/.collaboration/core/task-api.js +37 -7
- package/core/.formation/bifrost/launch.js +1 -1
- package/core/.formation/tools/dispatch-detail/worktree-subagent-mode.md +6 -1
- package/core/.formation/tools/kenaz-stats.js +1 -1
- package/core/.formation/tools/post-complete/git-merge.js +1 -1
- package/core/.formation/tools/prompt.js +1 -1
- package/core/.formation/tools/utils.js +5 -5
- package/core/.formation/tools/worktree-reclaim.js +73 -2
- package/core/.formation/tools/worktree-reclaim.test.js +113 -0
- package/core/.kenaz/specialist/ansuz_rules.yaml +7 -51
- package/core/.kenaz/specialist/ansuz_session_handoff.schema.json +2 -6
- package/core/.rule/general/project-self-containment.yaml +2 -2
- package/core/.specialist/Amelia/README.md +1 -1
- package/core/.specialist/Amelia/rule.yaml +1 -1
- package/core/.specialist/Ansuz/RULES.md +6 -2
- package/core/.specialist/Ansuz/concepts/commitment_layer.yaml +1 -1
- package/core/.specialist/Ansuz/concepts/evolvable_guardrails.yaml +1 -1
- package/core/.specialist/Ansuz/knowledge.yaml +1 -3
- package/core/.specialist/tools/__tests__/task-2409-lessons.test.js +10 -0
- package/core/.specialist/tools/__tests__/task-2427-harvest.test.js +25 -0
- package/core/.specialist/tools/ansuz-boot-fast.js +1 -1
- package/core/.specialist/tools/failure-detector.js +4 -4
- package/core/.specialist/tools/handoff-doc.js +1 -1
- package/core/.specialist/tools/lessons.js +2 -2
- package/core/CLAUDE.md +5 -5
- package/core/KENAZ_CORE_VERSION +1 -1
- package/core/dashboard/scripts/install-kenaz-cli.js +56 -30
- package/core/dev/scripts/check-file-size.js +1 -1
- package/core/dev/scripts/ci-feedback.js +1 -1
- package/core/dev/scripts/gc-agent-worktrees.js +13 -12
- package/core/dev/scripts/kenaz-session.js +3 -3
- package/core/dev/scripts/peer-identity-e2e.js +6 -4
- package/core/dev/scripts/run-rust-tests.js +2 -2
- package/core/dev/scripts/skill-routing-replay.js +3 -3
- package/core/dev/scripts/task1961/selftest.js +2 -2
- package/core/dev/scripts/windows-hide-guard.test.js +112 -0
- package/core/plugins/kenaz/guidance.md +1 -0
- package/core/plugins/kenaz/hooks/core-resolve.js +1 -1
- package/core/plugins/kenaz/hooks/hooks.json +9 -0
- package/core/plugins/kenaz/hooks/kenaz-hook.js +58 -4
- package/core/plugins/kenaz/hooks/worktree-guard.js +121 -0
- package/core/plugins/kenaz/hooks/worktree-guard.test.js +75 -0
- package/core/plugins/kenaz/scripts/kenaz.test.js +72 -5
- package/core/plugins/kenaz-peer/hooks/register.test.ts +14 -2
- package/core/plugins/kenaz-peer/hooks/register.ts +6 -1
- package/lib/cli.js +9 -5
- package/package.json +6 -6
- package/vendor/install-kenaz-cli.js +56 -30
- package/core/.kenaz/designs/METAPLASTICITY_CONFIDENCE_DESIGN.md +0 -537
- package/core/.kenaz/designs/REFLEX_INITIATOR_DESIGN.md +0 -501
- package/core/.kenaz/designs/TASK_1385_handoff_mcp_design.md +0 -426
- package/core/.kenaz/designs/TASK_932_hippocampus_consolidation.md +0 -103
- package/core/.kenaz/designs/TASK_934_efe_signal_engine.md +0 -97
- package/core/.kenaz/designs/TASK_935_self_evolution_framework.md +0 -154
- package/core/.kenaz/designs/VISION_cognitive_architecture_roadmap.md +0 -159
- package/core/.kenaz/designs/metaplasticity_simulation_results.json +0 -696
- package/core/.kenaz/main-memory/README.md +0 -230
- package/core/.kenaz/main-memory/kenaz/cortex/001_cortex_overview.md +0 -168
- package/core/.kenaz/main-memory/kenaz/cortex/001_rag_engine_overview.md +0 -30
- package/core/.kenaz/main-memory/kenaz/memory-system/001_three_tier_architecture.md +0 -361
- package/core/.kenaz/main-memory/kenaz/pipeline/001_task_execution_flow.md +0 -117
- package/core/.kenaz/main-memory/kenaz/pipeline/001_task_granularity.md +0 -154
- package/core/.kenaz/main-memory/kenaz/pipeline/002_team_priority.md +0 -51
- package/core/.kenaz/main-memory/kenaz/pipeline/003_feature_id_system.md +0 -46
- package/core/.kenaz/main-memory/kenaz/rules/001_gen_007_self_containment.md +0 -108
- package/core/.kenaz/main-memory/kenaz/rules/001_rule_priority_system.md +0 -121
- package/core/.kenaz/main-memory/kenaz/rules/002_agt_006_pre_check.md +0 -0
- package/core/.kenaz/main-memory/kenaz/rules/003_ppl_002_task_archival.md +0 -48
- package/core/.kenaz/main-memory/kenaz/system/001_dual_track_task_system.md +0 -197
- package/core/.kenaz/main-memory/knowledge/patterns/001_json_bom_issue.md +0 -78
- package/core/.kenaz/main-memory/knowledge/patterns/001_leader_worker_pattern.md +0 -0
- package/core/.kenaz/main-memory/knowledge/patterns/002_scope_path_conflict.md +0 -115
- package/core/.kenaz/main-memory/knowledge/patterns/002_task_dependency_resolution.md +0 -223
- package/core/.kenaz/main-memory/knowledge/patterns/003_question_protocol.md +0 -242
- package/core/.kenaz/main-memory/knowledge/patterns/004_user_insight_value.md +0 -111
- package/core/.kenaz/main-memory/knowledge/patterns/005_file_lock_pattern.md +0 -274
- package/core/.kenaz/main-memory/knowledge/references/001_ppl_rules.md +0 -28
- package/core/.kenaz/main-memory/knowledge/solutions/001_json_bom_issue.md +0 -137
- package/core/.kenaz/main-memory/knowledge/solutions/001_team_invocation.md +0 -0
- package/core/.kenaz/main-memory/knowledge/solutions/002_passive_monitoring.md +0 -0
- package/core/.kenaz/main-memory/knowledge/solutions/003_windows_file_race_condition.md +0 -239
- package/core/.kenaz/main-memory/registry.json +0 -326
- package/core/.kenaz/main-memory/version.yaml +0 -58
- package/core/.kenaz/specialist/memory_guard_fired.json +0 -1
- package/core/.kenaz/specialist/memory_guard_trigger_cache.json +0 -1
- package/core/.kenaz/specialist/memory_source_priority.yaml +0 -260
- package/core/.kenaz/specialist/prompt_1775.txt +0 -317
- package/core/.kenaz/specialist/prompt_1776.txt +0 -326
- package/core/.kenaz/specialist/prompt_1791.txt +0 -320
- package/core/.kenaz/specialist/prompt_1792.txt +0 -320
- package/core/.kenaz/specialist/prompt_1795.txt +0 -281
- package/core/.kenaz/specialist/prompt_1813.txt +0 -332
- package/core/.kenaz/specialist/prompt_1814.txt +0 -401
- package/core/.kenaz/specialist/prompt_1815.txt +0 -394
- package/core/.kenaz/specialist/prompt_1816.txt +0 -437
- package/core/.kenaz/specialist/prompt_1818.txt +0 -361
- package/core/.kenaz/specialist/prompt_1819.txt +0 -421
- package/core/.kenaz/specialist/prompt_1821.txt +0 -345
- package/core/.kenaz/specialist/prompt_1822.txt +0 -313
- package/core/.kenaz/specialist/prompt_1824.txt +0 -348
- package/core/.kenaz/specialist/prompt_1826.txt +0 -388
- package/core/.kenaz/specialist/rune_efe_salience_gap.md +0 -21
- package/core/.kenaz/specialist/task1825_update.json +0 -43
- package/core/.kenaz/specialist/taskgen/consolidation_i.json +0 -38
- package/core/.kenaz/specialist/taskgen/csharp_a.json +0 -44
- package/core/.kenaz/specialist/taskgen/csharp_b.json +0 -40
- package/core/.kenaz/specialist/taskgen/embedding_e.json +0 -34
- package/core/.kenaz/specialist/taskgen/hygiene_fg.json +0 -39
- package/core/.kenaz/specialist/taskgen/pathology_h.json +0 -36
- package/core/.kenaz/specialist/taskgen/unity_noise_d.json +0 -38
- package/core/.kenaz/specialist/taskgen/visibility_c.json +0 -38
- package/core/.specialist/Ansuz/decisions/ADR-requirement-graph-layer.md +0 -390
- package/core/.specialist/Ansuz/self_model_seed.backup.json +0 -100
- package/core/.specialist/ansuz_session_handoff.json +0 -96
- package/core/dev/ALAYA_FIELD_FEEDBACK_DESIGN.md +0 -126
- package/core/dev/ANSUZ_SCAFFOLD_DIET_2026-09-20.md +0 -231
- package/core/dev/ANSUZ_STARTUP_INJECTION_REVIEW.md +0 -355
- package/core/dev/ANSUZ_WORKFLOW_MODERNIZATION.md +0 -143
- package/core/dev/CORTEX_META_GRAPH_ASSESSMENT.md +0 -99
- package/core/dev/FREYA_DOWNSTREAM_BUGS_2026-09-19.md +0 -44
- package/core/dev/GLOBAL_MEMORY_IDENTITY_CONSOLIDATION.md +0 -263
- package/core/dev/GUARD_EFFECTIVENESS_DESIGN.md +0 -180
- package/core/dev/HEALTH_GATE_VARIANCE_ASSESSMENT.md +0 -271
- package/core/dev/HOOK_DIET_2026-09-21.md +0 -126
- package/core/dev/JEV_INTEGRATION_PLAN.md +0 -189
- package/core/dev/KENAZ_AGENT_CONNECT_v1_SPEC.md +0 -139
- package/core/dev/MOBILE_DESIGN_SPEC.md +0 -569
- package/core/dev/MULTI_ANSUZ_SPEC.md +0 -136
- package/core/dev/MUNINN_RETIREMENT.md +0 -115
- package/core/dev/PHASE3_ATTRIBUTION_POPULATION_DIAGNOSIS.md +0 -211
- package/core/dev/PHASE3_P3-2B_TASKLEVEL_PROBE.md +0 -83
- package/core/dev/PHASE3_P3-2_POPULATION_DISJOINTNESS.md +0 -83
- package/core/dev/PHASE3_P3-2_REMEASURE_REPORT.md +0 -231
- package/core/dev/PREDICTION_GROUNDING_DESIGN.md +0 -376
- package/core/dev/PRODUCT_SPEC.md +0 -317
- package/core/dev/PROJECT_REGISTRY_DUPLICATE_ASSESSMENT.md +0 -86
- package/core/dev/STARTUP_TIMELINE_TASK_1995.md +0 -181
- package/core/dev/SYNAPSE_WORKER_PER_PROJECT.md +0 -881
- package/core/dev/TASK_1680_P3-3_DISPATCH_SPEC.md +0 -96
- package/core/dev/TASK_1684_CALIBRATION_IMPACT_ANALYSIS.md +0 -170
- package/core/dev/TASK_1684_FORK_A_GOODHART_DESIGN.md +0 -171
- package/core/dev/TASK_1684_P3_2_REMEASURE_VALIDATION.md +0 -262
- package/core/dev/TASK_1903_SIGNAL_AUC_MEASUREMENT.md +0 -207
- package/core/dev/TASK_1904_BRANCH_INTEGRITY_AUDIT.md +0 -146
- package/core/dev/ansuz-eval/README.md +0 -38
- package/core/dev/ansuz-eval/build-fixtures.js +0 -87
- package/core/dev/ansuz-eval/grade.js +0 -96
- package/core/dev/ansuz-eval/grader.test.js +0 -117
- package/core/dev/ansuz-eval/tasks.md +0 -32
- package/core/dev/archive/ansuz/BOOT_FULL.md +0 -141
- package/core/dev/archive/ansuz/agents/ansuz-boot.md +0 -176
- package/core/dev/archive/ansuz/designs/alaya-passive-surfacing.md +0 -84
- package/core/dev/archive/ansuz/designs/cc_memory_indexing.md +0 -307
- package/core/dev/archive/ansuz/designs/check_guard.md +0 -322
- package/core/dev/archive/ansuz/designs/consequence_loop.md +0 -227
- package/core/dev/archive/ansuz/designs/mcp_kuzudb_lock_architecture.md +0 -312
- package/core/dev/archive/ansuz/designs/phase0_git_enrichment.md +0 -278
- package/core/dev/archive/ansuz/designs/refactor_mcp_tools_synapse.md +0 -490
- package/core/dev/archive/ansuz/designs/semantic_markdown_extraction.md +0 -167
- package/core/dev/archive/ansuz/designs/task_1372_prompt_injects_into.md +0 -193
- package/core/dev/archive/ansuz/designs/thought_stack.md +0 -286
- package/core/dev/archive/ansuz/investigations/reachability_unified_api_2026-04-11.md +0 -330
- package/core/dev/archive/ansuz/investigations/synapse_orphans_indexing_bug_2026-04-11.md +0 -352
- package/core/dev/archive/ansuz/investigations/synapse_orphans_reindex_verification_2026-04-11.md +0 -48
- package/core/dev/archive/ansuz/investigations/synapse_orphans_verification_2026-04-11.md +0 -170
- package/core/dev/archive/ansuz/legacy/kernel.yaml +0 -399
- package/core/dev/archive/ansuz/legacy/phases/phase_0.yaml +0 -418
- package/core/dev/archive/ansuz/legacy/phases/phase_1.yaml +0 -376
- package/core/dev/archive/ansuz/legacy/phases/phase_10.yaml +0 -35
- package/core/dev/archive/ansuz/legacy/phases/phase_11.yaml +0 -582
- package/core/dev/archive/ansuz/legacy/phases/phase_2.yaml +0 -94
- package/core/dev/archive/ansuz/legacy/phases/phase_3.yaml +0 -274
- package/core/dev/archive/ansuz/legacy/phases/phase_4.yaml +0 -67
- package/core/dev/archive/ansuz/legacy/phases/phase_5.yaml +0 -32
- package/core/dev/archive/ansuz/legacy/phases/phase_6.yaml +0 -91
- package/core/dev/archive/ansuz/legacy/phases/phase_7.yaml +0 -58
- package/core/dev/archive/ansuz/legacy/phases/phase_8.yaml +0 -146
- package/core/dev/archive/ansuz/legacy/phases/phase_9.yaml +0 -424
- package/core/dev/archive/ansuz/specs/INDEX_bifrost_hook_parity.yaml +0 -92
- package/core/dev/archive/ansuz/specs/active-inference-formation.yaml +0 -453
- package/core/dev/archive/ansuz/specs/brief_TASK_1228_userpromptsubmit.yaml +0 -191
- package/core/dev/archive/ansuz/specs/brief_TASK_1229_pretooluse_posttooluse.yaml +0 -250
- package/core/dev/archive/ansuz/specs/brief_TASK_1230_sessionstart_stop.yaml +0 -301
- package/core/dev/archive/ansuz/specs/brief_TASK_1231_verification.yaml +0 -272
- package/core/dev/archive/skills/feature_agent/SKILL.md +0 -289
- package/core/dev/design/PHASE4_DESIGN.md +0 -559
- package/core/dev/design/dashboard_docs_integration_PLAN.md +0 -388
- package/core/dev/design/matrix_format_ABBREVIATIONS.md +0 -655
- package/core/dev/design/matrix_format_DESIGN_SPEC.md +0 -601
- package/core/dev/design/matrix_format_DISCUSSION_SUMMARY.md +0 -484
- package/core/dev/design/matrix_format_EXAMPLE_memory.matrix +0 -13
- package/core/dev/design/matrix_format_EXAMPLE_project_status.matrix +0 -9
- package/core/dev/design/matrix_format_EXAMPLE_tasks.matrix +0 -14
- package/core/dev/design/matrix_format_SYNTAX_BNF.md +0 -754
- package/core/dev/design/matrix_format_TOKEN_COMPARISON.md +0 -484
- package/core/dev/design/matrix_v2_COGNITIVE_DESIGN.md +0 -503
- package/core/dev/design/matrix_v2_DISCUSSION_SUMMARY.md +0 -414
- package/core/dev/design/matrix_v2_EXAMPLE.matrix +0 -67
- package/core/dev/designs/EXPANDABLE_CARD_DESIGN_SPEC.md +0 -509
- package/core/dev/jev-eval/ACTIVE_CORRECTION.md +0 -52
- package/core/dev/jev-eval/ANNOTATION_GUIDE.md +0 -68
- package/core/dev/jev-eval/BASELINE_COMPARISON.md +0 -45
- package/core/dev/jev-eval/CONTEXT_REVIEW.md +0 -31
- package/core/dev/jev-eval/EVALUATION_STATUS.md +0 -39
- package/core/dev/jev-eval/HISTORICAL_CORPUS.md +0 -33
- package/core/dev/jev-eval/PACKAGING_VERIFICATION.md +0 -42
- package/core/dev/jev-eval/README.md +0 -101
- package/core/dev/jev-eval/THALAMUS_RANKING.md +0 -58
- package/core/dev/jev-eval/VALIDATION_PROGRESS.md +0 -54
- package/core/dev/jev-eval/cli.mjs +0 -50
- package/core/dev/jev-eval/context.mjs +0 -183
- package/core/dev/jev-eval/corpus.mjs +0 -186
- package/core/dev/jev-eval/fixtures/conversation-review.seed.jsonl +0 -6
- package/core/dev/jev-eval/fixtures/synthetic.jsonl +0 -11
- package/core/dev/jev-eval/metrics.mjs +0 -67
- package/core/dev/jev-eval/muninn-baseline.mjs +0 -119
- package/core/dev/jev-eval/providers.mjs +0 -95
- package/core/dev/jev-eval/reports/annotation-pilot-2026-09-20.json +0 -32
- package/core/dev/jev-eval/reports/context-review-2026-09-20.json +0 -48
- package/core/dev/jev-eval/reports/conversation-review.pending.json +0 -151
- package/core/dev/jev-eval/reports/history-corpus-2026-09-20.json +0 -52
- package/core/dev/jev-eval/reports/length-probe-2026-09-20.json +0 -133
- package/core/dev/jev-eval/reports/live-smoke-2026-09-20.json +0 -616
- package/core/dev/jev-eval/reports/muninn-baseline-2026-09-20.json +0 -52
- package/core/dev/jev-eval/reports/resilience-2026-09-20.json +0 -520
- package/core/dev/jev-eval/reports/rules-baseline.json +0 -197
- package/core/dev/jev-eval/reports/synthetic-review.pending.json +0 -357
- package/core/dev/jev-eval/resilience.mjs +0 -71
- package/core/dev/jev-eval/review.mjs +0 -78
- package/core/dev/jev-eval/schema.mjs +0 -87
- package/core/dev/jev-eval/test/context.test.mjs +0 -95
- package/core/dev/jev-eval/test/corpus.test.mjs +0 -102
- package/core/dev/jev-eval/test/eval.test.mjs +0 -146
- package/core/dev/jev-eval/test/muninn-baseline.test.mjs +0 -71
- package/core/dev/jev-eval/test/resilience.test.mjs +0 -72
- package/core/dev/jev-eval/test/review.test.mjs +0 -61
- package/core/dev/pipeline/PHASE3_PLANNING_SUMMARY.md +0 -338
- package/core/dev/pipeline/PROGRESS.md +0 -113
- package/core/dev/pipeline/PROGRESS_template.md +0 -860
- package/core/dev/pipeline/QA_REPORT_F008.md +0 -431
- package/core/dev/pipeline/QA_REPORT_LOCAL_CLAUDE_DIAGNOSIS.md +0 -583
- package/core/dev/pipeline/README.md +0 -210
- package/core/dev/pipeline/WORKFLOW_GUIDE.md +0 -824
- package/core/dev/pipeline/archived/TASK_015_tauri_init.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_016_tauri_commands.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_017_rust_pty.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_018_tauri_bundle.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_019_release_workflow.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_020_update_ui.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_021_update_notification_ui.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_022_remove_node_pty.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_023_api_routes_migration.yaml +0 -86
- package/core/dev/pipeline/archived/TASK_024_feature_id_system.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_025_executable_acceptance.yaml +0 -66
- package/core/dev/pipeline/archived/TASK_026_spec_versioning.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_027_drift_detection.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_028_tauri_pty_manager.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_029_tauri_pty_commands.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_030_frontend_session_adapter.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_031_terminal_tauri_events.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_041_scheduler_data_models.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_042_path_lock_manager.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_043_process_manager.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_044_git_integration.yaml +0 -85
- package/core/dev/pipeline/archived/TASK_045_task_queue_manager.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_046_scheduler_dispatcher.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_047_tauri_scheduler_commands.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_048_realtime_status_push.yaml +0 -92
- package/core/dev/pipeline/archived/TASK_049_frontend_scheduler_integration.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_050_error_recovery.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_051_optimization_proposals_backend.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_052_optimization_proposals_ui.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_053_optimization_proposals_diff_view.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_054_multi_project_scheduler_state.yaml +0 -76
- package/core/dev/pipeline/archived/TASK_055_scheduler_api_project_scope.yaml +0 -64
- package/core/dev/pipeline/archived/TASK_056_frontend_scheduler_project_scope.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_057_scheduler_module_structure.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_058_scheduler_models_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_059_scheduler_core_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_060_scheduler_commands_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_061_scheduler_specialized_commands.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_062_process_manager_module_structure.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_063_process_manager_core_extract.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_064_recovery_module_structure.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_065_recovery_core_extract.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_066_self_enhancement_scheduler_models.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_067_agents_section_quick_actions.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_067_self_enhancement_scheduler_core.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_068_agent_workflow_rule_enhancement.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_068_self_enhancement_tauri_commands.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_069_agent_wizard_responsive.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_069_self_enhancement_ui.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_070_preview_panel_redesign.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_070_self_enhancement_integration.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_071_preview_panel_qa.yaml +0 -98
- package/core/dev/pipeline/archived/TASK_071_single_agent_config.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_072_preview_modal_esc_fix.yaml +0 -71
- package/core/dev/pipeline/archived/TASK_072_product_review_module.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_073_agents_page_component_refactor.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_073_rename_single_agent.yaml +0 -64
- package/core/dev/pipeline/archived/TASK_074_preview_mode_ui_diagnosis.yaml +0 -71
- package/core/dev/pipeline/archived/TASK_074_single_agent_ui_toggle.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_075_agents_page_component_refactor.yaml +0 -69
- package/core/dev/pipeline/archived/TASK_075_single_agent_integration_test.yaml +0 -75
- package/core/dev/pipeline/archived/TASK_076_preview_mode_ui_diagnosis.yaml +0 -70
- package/core/dev/pipeline/archived/TASK_076_single_agent_continuous_mode.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_077_failure_directory_structure.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_077_single_agent_typescript_types.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_078_fail_001_agent_no_output.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_078_single_agent_ui_simplify.yaml +0 -74
- package/core/dev/pipeline/archived/TASK_079_dashboard_rwd_responsive.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_079_fail_002_json_bom.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_080_fail_003_queue_pollution.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_080_http_server_module.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_081_failure_logging_tools.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_081_http_api_routes.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_082_frontend_api_adapter.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_082_integrate_failure_to_workflow.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_083_cleanup_nextjs_api.yaml +0 -48
- package/core/dev/pipeline/archived/TASK_083_task_queue_cleanup.yaml +0 -67
- package/core/dev/pipeline/archived/TASK_084_rust_dead_code_cleanup.yaml +0 -66
- package/core/dev/pipeline/archived/TASK_084_scheduler_sync_logic_fix.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_085_http_api_web_mode_fixes.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_085_memory_consolidation_0204_0205.yaml +0 -98
- package/core/dev/pipeline/archived/TASK_086_collapsible_preview_panel.yaml +0 -161
- package/core/dev/pipeline/archived/TASK_086_web_mode_feature_parity.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_087_manual_memory_archival.yaml +0 -163
- package/core/dev/pipeline/archived/TASK_087_mobile_http_control.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_088_fail_003_to_ppl_002_rule.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_088_mobile_http_qa.yaml +0 -121
- package/core/dev/pipeline/archived/TASK_089_agent_collaboration_topic.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_089_web_mode_monitor_fix.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_090_cli_detection_fix.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_090_ui_ux_lessons_topic.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_091_expandable_card_design.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_091_move_agent_section_components.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_092_expandable_card_component.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_092_refactor_agent_create_wizard.yaml +0 -84
- package/core/dev/pipeline/archived/TASK_093_taskcard_detail_integration.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_093_update_barrel_exports_test.yaml +0 -84
- package/core/dev/pipeline/archived/TASK_094_ai_agent_generation_enhancement.yaml +0 -115
- package/core/dev/pipeline/archived/TASK_094_proposalcard_detail_integration.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_095_preview_fixes.yaml +0 -129
- package/core/dev/pipeline/archived/TASK_095_single_agent_task_selector.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_096_agents_page_ux_improvements.yaml +0 -163
- package/core/dev/pipeline/archived/TASK_096_single_agent_status_sync.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_097_local_claude_error_logging.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_097_single_agent_monitor_events.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_098_product_manager_team_phase2.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_098_single_agent_refactor_test.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_099_backend_team_creation.yaml +0 -258
- package/core/dev/pipeline/archived/TASK_100_frontend_team_creation.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_101_orchestrator_system.yaml +0 -403
- package/core/dev/pipeline/archived/TASK_102_designer_sre_teams.yaml +0 -90
- package/core/dev/pipeline/archived/TASK_103_integration_testing.yaml +0 -86
- package/core/dev/pipeline/archived/TASK_128_integration_testing.yaml +0 -83
- package/core/dev/pipeline/archived/TASK_134_cortex_v2_phase3_file_watcher.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_134_team_http_api.yaml +0 -96
- package/core/dev/pipeline/archived/TASK_135_cortex_v2_phase3_git_monitor.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_136_cortex_v2_phase3_change_analyzer.yaml +0 -69
- package/core/dev/pipeline/archived/TASK_137_cortex_v2_phase3_cache_invalidator.yaml +0 -67
- package/core/dev/pipeline/archived/TASK_137_team_orchestrator_integration.yaml +0 -93
- package/core/dev/pipeline/archived/TASK_138_cortex_v2_phase3_distributed_cache.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_138_matrix_folder_structure.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_139_cortex_v2_phase3_cache_prewarming.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_146_unified_documentation.yaml +0 -141
- package/core/dev/pipeline/archived/TASK_147_pipeline_execution_rules.yaml +0 -76
- package/core/dev/pipeline/archived/TASK_148_update_claude_md.yaml +0 -77
- package/core/dev/pipeline/archived/TASK_149_fix_nextjs_mdx_serialization.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_149_update_team_docs.yaml +0 -77
- package/core/dev/pipeline/archived/TASK_150_pipeline_workflow_guide.yaml +0 -82
- package/core/dev/pipeline/archived/TASK_164_fix_smart_context_switch.yaml +0 -49
- package/core/dev/pipeline/archived/TASK_165_ctags_symbol_index.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_166_symbol_search_mcp_tool.yaml +0 -48
- package/core/dev/pipeline/archived/TASK_167_llm_module_summary.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_168_map_reduce_context.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_169_v2_integration_testing.yaml +0 -52
- package/core/dev/pipeline/backups/archive_2026-02-04T22-07-22/TASK_QUEUE_backup.json +0 -95
- package/core/dev/pipeline/docs/multi-agent-coordination.md +0 -446
- package/core/dev/pipeline/docs/overview.md +0 -406
- package/core/dev/pipeline/docs/task-management.md +0 -412
- package/core/dev/pipeline/docs/workflows.md +0 -32
- package/core/dev/pipeline/orchestrator/schemas/task_queue_schema.json +0 -58
- package/core/dev/pipeline/orchestrator/schemas/task_schema.json +0 -139
- package/core/dev/pipeline/plans/PLAN_task_cli_refactor.md +0 -281
- package/core/dev/pipeline/test_results/TASK_TEST_PARALLEL_002_result.txt +0 -27
- package/core/dev/plans/ANSUZ_SLIM_PLAN.md +0 -68
- package/core/dev/plans/CLI_FIRST_INSTALL_FLOW.md +0 -120
- package/core/dev/plans/FORMATION_RETIREMENT_PLAN.md +0 -313
- package/core/dev/plans/KUZU_REPLACEMENT_PLAN.md +0 -126
- package/core/dev/scripts/CRASH_DIAGNOSIS.md +0 -47
- package/core/dev/scripts/README.md +0 -142
- package/core/dev/scripts/RUN_ONCE.bat +0 -40
- package/core/dev/scripts/START_DEV_AGENT.bat +0 -63
- package/core/dev/scripts/START_MULTI_AGENT.bat +0 -80
- package/core/dev/scripts/dev_agent_scheduler.ps1 +0 -536
- package/core/dev/scripts/init_git.ps1 +0 -396
- package/core/dev/scripts/init_git.sh +0 -337
- package/core/dev/scripts/init_project.ps1 +0 -851
- package/core/dev/scripts/init_project.sh +0 -477
- package/core/dev/scripts/multi_agent_scheduler.ps1 +0 -2021
- package/core/dev/scripts/multi_agent_scheduler.sh +0 -1344
- package/core/dev/scripts/run_once.sh +0 -47
- package/core/dev/scripts/setup_rag.ps1 +0 -304
- package/core/dev/scripts/setup_rag.sh +0 -230
- package/core/dev/scripts/start_dev_agent.sh +0 -137
- package/core/dev/scripts/start_multi_agent.sh +0 -41
- package/core/dev/scripts/sync_task_queue.ps1 +0 -505
- package/core/dev/scripts/sync_task_queue.sh +0 -392
- package/core/dev/specs/agent-connect/PROTOCOL.md +0 -177
- package/core/dev/specs/agent-connect/SDK_GUIDE.md +0 -915
- package/core/dev/specs/agent-connect/examples/minimal-site/README.md +0 -137
- package/core/dev/specs/agent-connect/examples/minimal-site/package.json +0 -12
- package/core/dev/specs/agent-connect/examples/minimal-site/public/index.html +0 -116
- package/core/dev/specs/agent-connect/examples/minimal-site/public/install-redirect.js +0 -73
- package/core/dev/specs/agent-connect/examples/minimal-site/server.js +0 -516
- package/core/dev/specs/agent-connect/examples/minimal-site/test/smoke.test.mjs +0 -263
- 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
- package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-prompt-mojibake.md +0 -90
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-07.md +0 -61
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-08_relay-v1-conformance.md +0 -76
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-09_v0.4-session-channel.md +0 -87
- package/core/dev/specs/agent-connect/history/FLOWPIX_REPLY_agent-hub_2026-09-08_relay-v1-answers.md +0 -68
- package/core/dev/specs/agent-connect/history/FLOWPIX_bridge_CONTRACT.md +0 -642
- package/core/dev/specs/agent-connect/history/FLOWPIX_spikes_relay_spike_relay.mjs +0 -244
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-07.md +0 -77
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_direction-change-v0.3.md +0 -44
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-answers-ack.md +0 -37
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-conformance.md +0 -56
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_annotations-install-coldstart.md +0 -44
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_empty-prompt-first-turn.md +0 -56
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_prompt-mojibake-fixed.md +0 -48
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_session-channel.md +0 -57
- package/core/dev/specs/agent-connect/history/PROTOCOL_v0.3_snapshot.md +0 -379
- package/core/dev/specs/agent-connect/history/README.md +0 -47
- package/core/dev/specs/peer/CODEX_INTERACTIVE_PUSH.md +0 -65
- package/core/dev/specs/peer/CODEX_MANAGED_DAEMON.md +0 -54
- package/core/dev/specs/peer/CODEX_PEER_PULL_SPIKE.md +0 -54
- package/core/dev/specs/peer/MODS_SPIKE.md +0 -133
- package/core/dev/specs/peer/PER_PROJECT_ADDRESSING.md +0 -143
- package/core/dev/specs/peer/SWARM_PROTOCOLS.md +0 -256
- package/core/dev/specs/peer/codex-hook-shim-peer.test.js +0 -113
- package/core/dev/specs/peer/codex-push-launcher.test.js +0 -142
- package/core/dev/specs/peer/setup-codex-hooks.test.js +0 -60
- package/core/dev/specs/peer-ansuz/DELIVERY_SPIKE.md +0 -397
- package/core/dev/specs/peer-ansuz/DESIGN.md +0 -109
- package/core/dev/specs/peer-ansuz/spike/claude_poke.js +0 -129
- package/core/dev/specs/peer-ansuz/spike/claude_session_start_hook.js +0 -37
- package/core/dev/specs/peer-ansuz/spike/claude_settings_hook.json +0 -14
- package/core/dev/specs/peer-ansuz/spike/codex_appserver_client.js +0 -105
- package/core/dev/specs/peer-ansuz/spike/codex_appserver_query.js +0 -29
- package/core/dev/specs/peer-ansuz/spike/extract_timeline.js +0 -26
- package/core/dev/specs/synapse/SYMBOL_IDENTITY.md +0 -305
- package/core/dev/spikes/A4-cypher-varlen.md +0 -176
- package/core/dev/spikes/bloat-rounds.sh +0 -25
- package/core/dev/spikes/mods/clean-claude.js +0 -9
- package/core/dev/spikes/mods/drive-probe.js +0 -29
- package/core/dev/spikes/mods/e2e-peer.js +0 -71
- package/core/dev/spikes/mods/evidence/e2e-peer-control.json +0 -17
- package/core/dev/spikes/mods/evidence/e2e-peer-mod.json +0 -17
- package/core/dev/spikes/mods/evidence/probe-006a6e65-d807-4bc1-b648-fd7d1edfe0b4.jsonl +0 -4
- package/core/dev/spikes/mods/evidence/probe-cebdf1f7-f9c4-47a8-83cd-7c0786177404.jsonl +0 -12
- package/core/dev/spikes/mods/evidence/probe-eb21147d-10ce-4c32-93ed-37ca37d88d5a.jsonl +0 -11
- package/core/dev/spikes/mods/evidence/stream-cebdf1f7.jsonl +0 -18
- package/core/dev/spikes/mods/kenaz-mod-probe/.claude-plugin/plugin.json +0 -1
- package/core/dev/spikes/mods/kenaz-mod-probe/hooks/hooks.json +0 -1
- package/core/dev/spikes/mods/kenaz-mod-probe/hooks/register.ts +0 -65
- package/core/dev/spikes/mods/kenaz-mod-probe/tsconfig.json +0 -3
package/core/dev/PRODUCT_SPEC.md
DELETED
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
spec_version: "1.0.0"
|
|
3
|
-
last_modified: "2026-02-20"
|
|
4
|
-
changelog:
|
|
5
|
-
- version: "1.1.0"
|
|
6
|
-
date: "2026-02-20"
|
|
7
|
-
changes:
|
|
8
|
-
- "F-007 duplicate fix → 錯誤學習系統 renamed to F-008"
|
|
9
|
-
- "F-005, F-015 marked deprecated"
|
|
10
|
-
- "F-009 completed (evolved to Formation system)"
|
|
11
|
-
- "F-018, F-019 marked completed"
|
|
12
|
-
- "MVP Scope Phase 2 updated (F-004 → F-019)"
|
|
13
|
-
- version: "1.0.0"
|
|
14
|
-
date: "2026-02-02"
|
|
15
|
-
changes:
|
|
16
|
-
- "Initial versioned specification"
|
|
17
|
-
- "Added Feature ID system (F-001 ~ F-006)"
|
|
18
|
-
- "Desktop App (F-006) marked as in_progress"
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
# Product Specification: Kenaz Dashboard
|
|
22
|
-
|
|
23
|
-
## Overview
|
|
24
|
-
|
|
25
|
-
Kenaz Dashboard 是一個 **多 Agent 協作視覺化看板**,讓開發者能即時監控 AI Agent 的工作狀態、管理任務流程、審核優化提案,並追蹤資源消耗。
|
|
26
|
-
|
|
27
|
-
**核心價值**:將隱藏在終端機 Log 和 JSON 檔案中的開發狀態,轉化為直觀的視覺化介面,解決多 Agent 協作的「黑盒效應」。
|
|
28
|
-
|
|
29
|
-
## Target Users
|
|
30
|
-
|
|
31
|
-
- 使用 Kenaz AI 多 Agent 系統的開發者
|
|
32
|
-
- 需要監控 AI 開發進度的專案管理者
|
|
33
|
-
- 想要控制 Token 消耗預算的用戶
|
|
34
|
-
|
|
35
|
-
## Feature ID Index
|
|
36
|
-
|
|
37
|
-
| Feature ID | Title | Priority | Status |
|
|
38
|
-
|------------|-------|----------|--------|
|
|
39
|
-
| F-001 | 任務狀態牆 (Task Board) | P0 | completed |
|
|
40
|
-
| F-002 | Agent 監控器 (Agent Monitor) | P0 | completed |
|
|
41
|
-
| F-003 | 優化提案區 (Optimization Proposals) | P1 | completed |
|
|
42
|
-
| F-004 | ~~RAG 狀態面板 (RAG Status)~~ | P2 | deprecated |
|
|
43
|
-
| F-005 | ~~Token 消耗追蹤 (Token Tracker)~~ | P2 | deprecated |
|
|
44
|
-
| F-006 | 桌面應用程式 (Desktop App) | P1 | completed |
|
|
45
|
-
| F-007 | 統一後端架構 (Unified Backend) | P1 | completed |
|
|
46
|
-
| F-008 | 錯誤學習系統 (.failure) | P1 | completed |
|
|
47
|
-
| F-009 | 多角色團隊協作系統 (Formation) | P0 | completed |
|
|
48
|
-
| F-015 | ~~.matrix Token 優化系統~~ | P0 | deprecated |
|
|
49
|
-
| F-018 | 結構化 RAG 精準度優化 (Structured RAG) | P1 | completed |
|
|
50
|
-
| F-019 | Kenaz Cortex Panel 優化 | P1 | completed |
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## Core Features
|
|
55
|
-
|
|
56
|
-
### F-001: 任務狀態牆 (Task Board)
|
|
57
|
-
- **ID**: F-001
|
|
58
|
-
- **Description**: Kanban 風格的任務看板,分為 Backlog / Active / Done 三欄
|
|
59
|
-
- **Priority**: P0
|
|
60
|
-
- **Status**: completed
|
|
61
|
-
- **Details**:
|
|
62
|
-
- 顯示任務卡片(標題、優先級、負責 Agent)
|
|
63
|
-
- Active 欄位顯示檔案路徑鎖定標籤
|
|
64
|
-
- 卡片閃爍效果表示 Agent 正在操作
|
|
65
|
-
- 依賴關係可視化(被阻塞的任務顯示為灰色)
|
|
66
|
-
|
|
67
|
-
### F-002: Agent 監控器 (Agent Monitor)
|
|
68
|
-
- **ID**: F-002
|
|
69
|
-
- **Description**: 左側欄顯示所有 Agent 的即時狀態
|
|
70
|
-
- **Priority**: P0
|
|
71
|
-
- **Status**: completed
|
|
72
|
-
- **Details**:
|
|
73
|
-
- 狀態指示:思考中 / 檢索 RAG / 寫入中 / 閒置
|
|
74
|
-
- 當前操作描述(例:「正在檢索 auth.ts...」)
|
|
75
|
-
- Agent 頭像與名稱標識
|
|
76
|
-
|
|
77
|
-
### F-003: 優化提案區 (Optimization Proposals)
|
|
78
|
-
- **ID**: F-003
|
|
79
|
-
- **Description**: 右側區域顯示 AI 自我增強建議
|
|
80
|
-
- **Priority**: P1
|
|
81
|
-
- **Status**: completed
|
|
82
|
-
- **Details**:
|
|
83
|
-
- 燈泡圖示提示新提案
|
|
84
|
-
- 展開查看優化理由與代碼對比(Diff View)
|
|
85
|
-
- [Accept] / [Ignore] 按鈕一鍵操作
|
|
86
|
-
- Accept 後自動轉入任務佇列
|
|
87
|
-
|
|
88
|
-
### F-004: ~~RAG 狀態面板 (RAG Status)~~ [DEPRECATED]
|
|
89
|
-
- **ID**: F-004
|
|
90
|
-
- **Description**: ~~顯示 RAG 索引狀態與手動同步功能~~
|
|
91
|
-
- **Priority**: P2
|
|
92
|
-
- **Status**: deprecated
|
|
93
|
-
- **Deprecated Reason**: 已被 F-019 Kenaz Cortex Panel 取代,RAG 功能整合進 Cortex Control Panel
|
|
94
|
-
|
|
95
|
-
### F-019: Kenaz Cortex Panel 優化
|
|
96
|
-
- **ID**: F-019
|
|
97
|
-
- **Description**: Cortex Control Panel 修復與優化,整合雙層記憶管理
|
|
98
|
-
- **Priority**: P1
|
|
99
|
-
- **Status**: completed
|
|
100
|
-
- **Replaces**: F-004
|
|
101
|
-
- **Details**:
|
|
102
|
-
- 移除舊 RAG Status Panel,統一使用 Kenaz Cortex Panel
|
|
103
|
-
- 修復所有 Cortex API 端點 404 問題
|
|
104
|
-
- Conscious Memory(專案記憶):切換專案時自動聯動
|
|
105
|
-
- Subconscious Memory(全局記憶):鎖定開發者指定的 ChromaDB,用戶不可更換
|
|
106
|
-
- Export/Import GPU Embedding 工作流程
|
|
107
|
-
- Agent 使用監控
|
|
108
|
-
- 手動檔案索引
|
|
109
|
-
|
|
110
|
-
### F-005: ~~Token 消耗追蹤 (Token Tracker)~~ [DEPRECATED]
|
|
111
|
-
- **ID**: F-005
|
|
112
|
-
- **Description**: ~~即時統計 Token 使用量與預估費用~~
|
|
113
|
-
- **Priority**: P2
|
|
114
|
-
- **Status**: deprecated
|
|
115
|
-
- **Deprecated Reason**: 已棄用
|
|
116
|
-
|
|
117
|
-
## Technical Requirements
|
|
118
|
-
|
|
119
|
-
### Frontend
|
|
120
|
-
- **Framework**: Next.js 14+ (App Router)
|
|
121
|
-
- **UI Library**: shadcn/ui + Tailwind CSS
|
|
122
|
-
- **State Management**: React Query (TanStack Query)
|
|
123
|
-
- **Real-time**: Polling (1-2 秒) 或 WebSocket
|
|
124
|
-
|
|
125
|
-
### Backend
|
|
126
|
-
- **API Routes**: Next.js API Routes
|
|
127
|
-
- **External API**: Python FastAPI (Orchestrator)
|
|
128
|
-
- **File Watching**: chokidar 或 fs.watch
|
|
129
|
-
|
|
130
|
-
### Data Sources
|
|
131
|
-
| 檔案路徑 | 用途 |
|
|
132
|
-
|---------|------|
|
|
133
|
-
| `dev/pipeline/tasks/*.md` | 任務定義 |
|
|
134
|
-
| `dev/pipeline/PROGRESS.md` | 進度追蹤 |
|
|
135
|
-
| `dev/pipeline/TASK_QUEUE.json` | 任務佇列 |
|
|
136
|
-
| `dev/pipeline/LOCK_STATE.json` | 路徑鎖定狀態 |
|
|
137
|
-
| `dev/pipeline/AGENT_STATE.json` | Agent 狀態 |
|
|
138
|
-
| `dev/pipeline/SELF_ENHANCEMENT_STATUS.json` | 自我增強狀態 |
|
|
139
|
-
| `dev/pipeline/logs/*.log` | Agent 操作日誌 |
|
|
140
|
-
| `.claude/METRICS.json` (新增) | Token 消耗統計 |
|
|
141
|
-
|
|
142
|
-
### API Endpoints (Python Orchestrator)
|
|
143
|
-
| Method | Endpoint | Description |
|
|
144
|
-
|--------|----------|-------------|
|
|
145
|
-
| GET | `/api/tasks` | 獲取所有任務 |
|
|
146
|
-
| GET | `/api/agents` | 獲取 Agent 狀態 |
|
|
147
|
-
| GET | `/api/metrics` | 獲取 Token 統計 |
|
|
148
|
-
| POST | `/api/proposals/:id/accept` | 核准優化提案 |
|
|
149
|
-
| POST | `/api/proposals/:id/ignore` | 忽略優化提案 |
|
|
150
|
-
| POST | `/api/rag/sync` | 觸發 RAG 同步 |
|
|
151
|
-
|
|
152
|
-
## Page Layout
|
|
153
|
-
|
|
154
|
-
```
|
|
155
|
-
+------------------+------------------------+------------------+
|
|
156
|
-
| | | |
|
|
157
|
-
| Agent Monitor | Task Board | Optimization |
|
|
158
|
-
| (Left Sidebar) | (Kanban) | Proposals |
|
|
159
|
-
| | | (Right Panel) |
|
|
160
|
-
| - Agent 1: Idle | Backlog | Active | Done |
|
|
161
|
-
| - Agent 2: 寫入 | [Card] [Card] [Card] | [Lightbulb] |
|
|
162
|
-
| - Agent 3: RAG | [Card] [Card] [Card] | [Accept] |
|
|
163
|
-
| | | [Ignore] |
|
|
164
|
-
+------------------+------------------------+------------------+
|
|
165
|
-
| Status Bar / Token Tracker |
|
|
166
|
-
+--------------------------------------------------------------+
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## Success Metrics
|
|
170
|
-
|
|
171
|
-
- 開發者能在 3 秒內了解當前專案狀態
|
|
172
|
-
- 優化提案審核時間從閱讀 Markdown 的 5 分鐘縮短至 30 秒
|
|
173
|
-
- 減少 50% 的終端機與 IDE 之間的 Context 切換
|
|
174
|
-
|
|
175
|
-
## MVP Scope
|
|
176
|
-
|
|
177
|
-
**Phase 1 (MVP)**:
|
|
178
|
-
1. 任務狀態牆(基本 Kanban)
|
|
179
|
-
2. Agent 監控器(狀態顯示)
|
|
180
|
-
3. 基礎 API 串接
|
|
181
|
-
|
|
182
|
-
**Phase 2**:
|
|
183
|
-
4. 優化提案區 + 一鍵審核
|
|
184
|
-
5. ~~RAG 狀態面板~~ → 已被 F-019 Kenaz Cortex Panel 取代
|
|
185
|
-
|
|
186
|
-
**Phase 3**:
|
|
187
|
-
6. Token 消耗追蹤
|
|
188
|
-
7. 依賴關係圖
|
|
189
|
-
8. Diff View 代碼對比
|
|
190
|
-
|
|
191
|
-
**Phase 4 (Desktop App)**:
|
|
192
|
-
9. Tauri 桌面應用打包
|
|
193
|
-
10. Rust PTY 終端機整合
|
|
194
|
-
11. 自動更新機制
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
### F-006: 桌面應用程式 (Desktop App)
|
|
199
|
-
- **ID**: F-006
|
|
200
|
-
- **Description**: 將 Dashboard 打包成可本地執行的輕量級桌面應用程式
|
|
201
|
-
- **Priority**: P1
|
|
202
|
-
- **Status**: completed
|
|
203
|
-
- **Details**:
|
|
204
|
-
- 使用 Tauri 框架整合 Next.js(更輕量、效能更好)
|
|
205
|
-
- 使用 Rust portable-pty 替代 node-pty(原生終端機)
|
|
206
|
-
- 支援 Windows 平台(優先),後續擴展 macOS/Linux
|
|
207
|
-
- 連接 GitHub Releases 檢查更新
|
|
208
|
-
- 自動下載並安裝新版本
|
|
209
|
-
- 更新進度 UI 顯示與用戶通知
|
|
210
|
-
|
|
211
|
-
### F-008: 錯誤學習系統 (.failure)
|
|
212
|
-
- **ID**: F-008
|
|
213
|
-
- **Description**: 建立失敗經驗記錄系統,讓 AI Agent 能從錯誤中學習並避免重複失敗
|
|
214
|
-
- **Priority**: P1
|
|
215
|
-
- **Status**: completed
|
|
216
|
-
- **Completed**: 2026-02-05
|
|
217
|
-
- **Details**:
|
|
218
|
-
- 失敗記錄分類系統(Agent 執行、代碼品質、架構、Pipeline、數據完整性)
|
|
219
|
-
- 失敗嚴重程度定義(Critical/High/Medium/Low)
|
|
220
|
-
- 標準化失敗記錄模板(根因分析、解決方案、預防措施)
|
|
221
|
-
- Agent 工作流程整合(執行前檢查、失敗時學習)
|
|
222
|
-
- 自動化工具(記錄失敗腳本、檢查失敗模式腳本)
|
|
223
|
-
- 失敗經驗轉化為規則的機制(`.failure/` → `.rule/`)
|
|
224
|
-
|
|
225
|
-
### Technical Requirements (Desktop)
|
|
226
|
-
- **Framework**: Tauri 2.x + Rust
|
|
227
|
-
- **PTY Library**: portable-pty (Rust)
|
|
228
|
-
- **Auto Update**: tauri-plugin-updater
|
|
229
|
-
- **Update Server**: GitHub Releases
|
|
230
|
-
- **Build Tool**: tauri-cli + tauri-action
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
### F-009: 多角色團隊協作系統 (Formation)
|
|
235
|
-
- **ID**: F-009
|
|
236
|
-
- **Description**: 多角色協作模式,已演進為 Formation 系統(unit/solo/squad/legion 四種陣型)
|
|
237
|
-
- **Priority**: P0
|
|
238
|
-
- **Status**: completed
|
|
239
|
-
- **Completed**: 2026-02-06(MVP)→ 已演進為 Formation 系統
|
|
240
|
-
- **Details**:
|
|
241
|
-
- 團隊結構定義系統(TEAM.yaml)
|
|
242
|
-
- 成員角色定義(members/*.yaml)
|
|
243
|
-
- 權限矩陣與衝突防止(permissions/scope_matrix.yaml)
|
|
244
|
-
- 工作流程引擎(workflows/*.yaml)
|
|
245
|
-
- 團隊調度器(orchestrator/team_scheduler.py)
|
|
246
|
-
- 訊息佇列與共享上下文(communication/)
|
|
247
|
-
- 路徑鎖定機制(防止多成員同時寫入同一文件)
|
|
248
|
-
- 審批流程(關鍵操作需多人同意)
|
|
249
|
-
|
|
250
|
-
**團隊範例**:
|
|
251
|
-
- **Product Manager Team**(已實作):PM Lead, Doc Specialist, Assessment Analyst, Research Specialist, QA Validator, Code Reviewer
|
|
252
|
-
- **Backend Team**(規劃中):Backend Lead, API Developer, Database Specialist, Doc Specialist, QA Engineer, Security Specialist, Performance Engineer
|
|
253
|
-
- **Frontend Team**(規劃中):Frontend Lead, UI Developer, UX Specialist, Doc Specialist, QA Engineer, Accessibility Expert
|
|
254
|
-
|
|
255
|
-
**核心機制**:
|
|
256
|
-
1. **權限管理**:每個成員只能訪問特定路徑(R/W/E/X 權限)
|
|
257
|
-
2. **並行執行**:多個成員同時工作(如 Doc + Assessment + Research 並行分析)
|
|
258
|
-
3. **衝突防止**:排他性路徑鎖定(如 TASK_QUEUE.json 同時只能一人寫入)
|
|
259
|
-
4. **工作流程**:標準化流程(8 階段任務建立流程)
|
|
260
|
-
5. **團隊通訊**:訊息佇列與共享上下文
|
|
261
|
-
|
|
262
|
-
### Technical Requirements (.team)
|
|
263
|
-
- **Language**: Python 3.9+ (orchestrator)
|
|
264
|
-
- **Configuration**: YAML (團隊、成員、權限、工作流程)
|
|
265
|
-
- **Orchestration**: asyncio (並行執行)
|
|
266
|
-
- **Communication**: JSON (訊息佇列、共享上下文)
|
|
267
|
-
- **Lock Management**: 文件鎖定機制(first-come-first-served)
|
|
268
|
-
|
|
269
|
-
---
|
|
270
|
-
|
|
271
|
-
## Feature ID Reference Guide
|
|
272
|
-
|
|
273
|
-
**Feature ID 格式**: `F-XXX`(三位數字,支援 001 ~ 999)
|
|
274
|
-
|
|
275
|
-
**任務追溯**:當建立新任務時,`source` 欄位應引用對應的 Feature ID,例如:
|
|
276
|
-
- `source: "F-001"` → 追溯到任務狀態牆功能
|
|
277
|
-
- `source: "F-006"` → 追溯到桌面應用程式功能
|
|
278
|
-
|
|
279
|
-
**子功能 ID**:若需要細分功能,可使用 `F-XXX.Y` 格式:
|
|
280
|
-
- `F-006.1` → Desktop App - Tauri 初始化
|
|
281
|
-
- `F-006.2` → Desktop App - Rust PTY 整合
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
### F-007: 統一後端架構 (Unified Backend)
|
|
286
|
-
- **ID**: F-007
|
|
287
|
-
- **Description**: 統一 Tauri IPC 和 HTTP API,減少維護成本,讓瀏覽器/手機能訪問完整功能
|
|
288
|
-
- **Priority**: P1
|
|
289
|
-
- **Status**: completed
|
|
290
|
-
- **Details**:
|
|
291
|
-
- 在 Rust 後端新增 HTTP Server(使用 axum)
|
|
292
|
-
- HTTP routes 調用現有的 core 邏輯(scheduler/core.rs 等)
|
|
293
|
-
- 前端 api.ts 在 Web 模式改調 Rust HTTP API
|
|
294
|
-
- 移除冗餘的 Next.js API Routes
|
|
295
|
-
- 支援區域網路訪問(手機預覽 UI)
|
|
296
|
-
|
|
297
|
-
### Technical Requirements (Unified Backend)
|
|
298
|
-
- **HTTP Framework**: axum (Rust)
|
|
299
|
-
- **Port**: 8080 (可配置)
|
|
300
|
-
- **啟動時機**: Tauri 應用啟動時自動啟動 HTTP server
|
|
301
|
-
- **API 路徑**: `/api/*` (與現有 Next.js routes 相容)
|
|
302
|
-
|
|
303
|
-
---
|
|
304
|
-
|
|
305
|
-
### F-015: ~~.matrix Token 優化系統~~ [DEPRECATED]
|
|
306
|
-
- **ID**: F-015
|
|
307
|
-
- **Description**: ~~建立極簡 DSL 格式的規則存儲系統,達成 5-10:1 Token 壓縮比~~
|
|
308
|
-
- **Priority**: P0
|
|
309
|
-
- **Status**: deprecated
|
|
310
|
-
- **Deprecated Reason**: 已棄用,方向已改變
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
314
|
-
*Generated by Product Manager Agent | 2026-01-29*
|
|
315
|
-
*Updated with Feature ID System | 2026-02-02*
|
|
316
|
-
*Updated with F-007 Unified Backend | 2026-02-05*
|
|
317
|
-
*Updated with F-015 .matrix System | 2026-02-07*
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# Assessment: KenazAI repo registered twice in `~/.kenaz/projects.json`
|
|
2
|
-
|
|
3
|
-
TASK_2055 · assessment only · 2026-09-26
|
|
4
|
-
|
|
5
|
-
## 0. The fact on disk
|
|
6
|
-
|
|
7
|
-
`~/.kenaz/projects.json` (read directly, this session):
|
|
8
|
-
|
|
9
|
-
```json
|
|
10
|
-
{
|
|
11
|
-
"currentProjectId": "proj_1776613204237_0p34i5y",
|
|
12
|
-
"projects": [
|
|
13
|
-
{ "id": "default", "name": "Kenaz", "path": "__kenaz_core__",
|
|
14
|
-
"is_core": true, "core_path": "__kenaz_core__" },
|
|
15
|
-
...,
|
|
16
|
-
{ "id": "proj_1776613204237_0p34i5y", "name": "KenazAI", "path": "__kenaz_core__",
|
|
17
|
-
"is_core": false, "core_path": "__kenaz_core__",
|
|
18
|
-
"createdAt": "2026-04-19T15:40:04.237Z" },
|
|
19
|
-
...
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Both entries resolve `__kenaz_core__` to the same real path (`common::virtual_path::resolve`), i.e. one repo, two ids. `currentProjectId` currently points at the **non-core** `proj_1776613204237_0p34i5y` entry, not at `default`.
|
|
25
|
-
|
|
26
|
-
## 1. Root cause — confirmed from the actual seed code
|
|
27
|
-
|
|
28
|
-
**`default` is minted by two independent, well-behaved seeders**, both hard-coding `id: "default"` and `is_core: true`, never colliding with each other:
|
|
29
|
-
- `dashboard/src-tauri/src/lib.rs:309-383` `auto_seed_project_config()` — runs on every Tauri startup (`lib.rs:1562`), strips any existing `is_core:true` entry and re-inserts a fresh `{"id":"default", ..., "is_core":true}` at index 0. **This alone would re-seed `default` if it were ever deleted** — it runs unconditionally on every launch, not just first-run.
|
|
30
|
-
- `dashboard/src-tauri/src/infrastructure/http_server/routes/projects.rs:110-203` `seed_from_config_json()` — HTTP-route fallback, only fires when `projects.json` doesn't exist at all; also mints `id: "default"`.
|
|
31
|
-
|
|
32
|
-
**`proj_1776613204237_0p34i5y` was NOT auto-seeded.** It was created by the user (or a click automated on the user's behalf) through the "Add Project" UI flow:
|
|
33
|
-
- `dashboard/src/contexts/ProjectContext.tsx:57-58` `generateId()` → `` `proj_${Date.now()}_${random}` `` — `1776613204237` is literally `Date.now()` at the moment of creation, which decodes to `2026-04-19T15:40:04.237Z`, matching the entry's own `createdAt` field exactly.
|
|
34
|
-
- `dashboard/src/contexts/ProjectContext.tsx:743-756` `addProject()` — called by the two UI call sites below — assigns a fresh `generateId()` id and pushes the entry **unconditionally**. There is no check anywhere in `addProject()` against `path`/`core_path` already matching an existing (especially `is_core`) entry.
|
|
35
|
-
- Call sites, both from the "Add Project" dialog, both hard-coding `is_core: false`:
|
|
36
|
-
- `dashboard/src/components/project-selector/NewProjectDialog.tsx:217-223` — `addProject({ name: projectName, path: trimmedPath, ..., is_core: false, core_path: resolvedCorePath || null })`
|
|
37
|
-
- `dashboard/src/app/page.tsx:1229` — `addProject({ name, path: dir.replace(/\\/g,'/'), pipelinePath: 'dev/pipeline' })`
|
|
38
|
-
|
|
39
|
-
So the mechanism is: at some point the user pointed the "Add Project" folder picker at the KenazAI core repo itself (or a symlink/junction to it) and confirmed. `addProject()` had no idea that path was already the registered core, minted a second id, and wrote it in as a normal (`is_core:false`) sub-project named "KenazAI".
|
|
40
|
-
|
|
41
|
-
**Would deleting `proj_1776613204237_0p34i5y` be re-seeded?** No, not automatically, by the same mechanism that created it — no seed/auto-register code path ever mints a `proj_*` id; that only happens through the interactive `addProject()` UI flow. But the *effects* of the duplicate come back the moment a user (or an automated UI-driving agent) repeats the same manual mistake — nothing in `addProject()`/`NewProjectDialog.tsx` was fixed to reject "path already registered." `auto_seed_project_config()` and `seed_from_config_json()` only touch/recreate the `is_core:true` (`default`) entry; they never touch or recreate `proj_*` entries, and deleting `proj_1776613204237_0p34i5y` would leave `default` untouched.
|
|
42
|
-
|
|
43
|
-
## 2. Consumer table
|
|
44
|
-
|
|
45
|
-
Legend: **id-first** = looks up `currentProjectId` by exact `id` match, falling back to `is_core:true` only if no id match (so today, with `currentProjectId = proj_1776613204237_0p34i5y`, these resolve to the **non-core** entry, name `"KenazAI"`, `is_core:false`). **is_core-first** = ignores `currentProjectId`, always finds the `is_core:true` entry directly (immune to which id is "current").
|
|
46
|
-
|
|
47
|
-
| Consumer | File:line | Id used | Resolution style | Impact if the `proj_` entry disappears / today's impact |
|
|
48
|
-
|---|---|---|---|---|
|
|
49
|
-
| Core dir resolution (Ansuz daemon init) | `dashboard/src-tauri/src/lib.rs:2559-2569` | `currentProjectId` → path | id-first, `virtual_path::resolve()`'d | Path resolves correctly either way (both ids → same real path). No breakage on deletion. |
|
|
50
|
-
| Ansuz daemon watcher poll loop | `dashboard/src-tauri/src/features/ansuz_daemon/mod.rs:158-183` | `currentProjectId` → path | id-first, resolved | Same — path-equivalent, safe either way. |
|
|
51
|
-
| Session lease "active project" filter | `dashboard/src-tauri/src/features/session/active_projects.rs:190-203` | `currentProjectId` → path | id-first, **NOT** `virtual_path::resolve()`'d | Returns literal `"__kenaz_core__"` string (unresolved token) regardless of which entry wins — pre-existing bug, not created by the duplicate, but the duplicate is what's live today. Breaks lease-path comparison against real session paths. |
|
|
52
|
-
| Prefrontal background project-root resolver | `dashboard/src-tauri/src/features/prefrontal/background.rs:105-128` | `currentProjectId`, falls back to `is_core:true` | id-first (id match wins over is_core fallback), resolved | Path-equivalent — safe. If `proj_` entry removed, falls through to `default`/is_core, still correct. |
|
|
53
|
-
| Proposal manager active-root resolver | `dashboard/src-tauri/src/features/proposal/manager.rs:264-289` | same pattern | id-first, resolved | Same — safe either way. |
|
|
54
|
-
| MCP `kenaz_project_current` / project list | `dashboard/src-tauri/src/infrastructure/http_server/routes/mcp.rs:150-171` | same pattern | id-first | Returns `(projects, current_id)` — a caller matching by name (`"KenazAI"` vs `"Kenaz"`) would see the sub-project's name, not the core's. |
|
|
55
|
-
| Synapse route resolvers (2 fns) | `dashboard/src-tauri/src/infrastructure/http_server/routes/synapse.rs:249-289` and `:307-344` | same pattern | id-first, resolved via `core_path` first | Path-equivalent — safe. |
|
|
56
|
-
| Cortex registry — canonical id chooser | `dashboard/src-tauri/src/features/cortex/registry.rs:205-227` `choose_canonical_id()` | both ids as candidates | **Explicitly prefers `default`** over any `proj_*` id (TASK_2053, tested at `registry.rs:266-274`) | Already the fix point: this is the one place in the codebase that was rewritten specifically *because of* this duplicate (see `identity_consolidation` / `sync.rs` — TASK_2050/2053 commits in this branch's history). Deleting `proj_` entry: harmless, `default` still wins by rule 1. |
|
|
57
|
-
| Cortex cross-project self-echo filter | `dashboard/src-tauri/src/features/cortex/hints.rs:229-280` `query_cross_project_runes()` / `is_same_repo` | `current_project_id` param (whatever the caller passed) + path-based fallback via `registry::find_project_path_by_id` | Path/identity-aware, already hardened (TASK_2049) | Self-correcting regardless of which id is "current" — already treats both ids as the same repo. |
|
|
58
|
-
| **Frontend: Project switcher dropdown (visible symptom)** | `dashboard/src/components/project-selector/ProjectSelector.tsx:120` `userProjects = projects.filter(p => !p.is_core)` | filters by `is_core`, not id | — | **The `proj_1776613204237_0p34i5y` "KenazAI" entry shows up as a selectable sub-project in the UI**, indistinguishable from a real sub-project like `deardearly_management`. This is how a user can (re-)select it and re-trigger the bug below. |
|
|
59
|
-
| **Frontend: current-project resolution + "is this a sub-project" gate** | `dashboard/src/contexts/ProjectContext.tsx:698-741` (`currentProject`, `corePath`) and `:805-822` (auto-ensure `.kenaz/` structure effect) | `currentProjectId` (id-first, no is_core fallback in `currentProject`) | — | **Confirmed live defect.** Because `currentProjectId` = the `is_core:false` `proj_` entry, `ProjectContext.tsx:809` (`if (currentProject.is_core \|\| !currentProject.path) return;`) does **not** short-circuit, so the effect calls `tauriCommands.initProject(currentProject.path, ...)` treating the **core repo itself as a sub-project**. Evidence: `.kenaz/project.yaml` in this very repo (both this worktree and the main checkout `C:\Users\user\Documents\GitHub\KenazAI\.kenaz\project.yaml`) contains `# Kenaz AI Sub-Project Configuration` / `project_name: "KenazAI"` / `core_path: "__kenaz_core__"` — the core repo self-registered as its own sub-project. (File's `created_at: 2026-03-13`, *before* `proj_1776613204237_0p34i5y`'s `createdAt: 2026-04-19` — so this specific file predates today's duplicate and may be residue of an earlier, already-repaired instance of the same failure mode; it corroborates the mechanism rather than being proof of this exact incident.) |
|
|
60
|
-
| **Frontend: "Add Project" duplicate-creation path** | `dashboard/src/contexts/ProjectContext.tsx:743-756` `addProject()`, `NewProjectDialog.tsx:217-223`, `page.tsx:1229` | mints new `proj_*` id unconditionally | — | Root cause (§1) and the only path by which a *third* duplicate could be created tomorrow — no path-collision guard exists here today. |
|
|
61
|
-
| Global-memory sync writer | `dashboard/src-tauri/src/features/cortex/sync.rs` (`find_project_by_path` → `registry::find_project_by_canonical_path`) | resolves by canonical path, delegates to `choose_canonical_id` | already hardened (TASK_2050/2053, this branch) | Already fixed — was the actual live-incident source (repo background: "caused three rounds of global_memory duplication"). |
|
|
62
|
-
| `.claude/hooks/worktree-create.js:106-115` `resolveTargetRepo()` | raw `fs.readFileSync` + `JSON.parse`, **no virtual-token resolve** | id-first via `pj.currentProjectId` | JS, unresolved | `proj.path` for either core-identified entry is the **literal string `"__kenaz_core__"`**, not a real path → `isGitRepo("__kenaz_core__")` is false → `resolveTargetRepo()` returns `null` regardless of which id is current. Pre-existing gap, not created by the duplicate (same failure for `default`), but currently masked because `worktree-create.js:723` only calls this as one fallback among several (grep: `resolveTargetRepo` at lines 106, 723). |
|
|
63
|
-
| `.specialist/tools/ansuz-boot-fast.js:293-303` `readProjectsJsonSync()` | raw `fs.readFileSync` + `JSON.parse`, no virtual-token resolve, id-first | same as above | Returns literal `"__kenaz_core__"` for `currentProjectPath` when current entry is either core id; `getDashboardCurrentProject()` (`:327-329`) tries this **before** falling back to the (correctly-resolving) HTTP endpoint `fetchCurrentProjectHttp()` (`:305-325`), so a non-null-but-wrong sync answer can win over a correct HTTP one. Same failure for `default` — orthogonal to which id is picked, but live today because `currentProjectId` is currently a core-identified id. |
|
|
64
|
-
| `.claude/hooks/core-resolve.js:100-107, :158-163` | `.find(p => p.is_core)` | is_core-first, ignores `currentProjectId` entirely | Immune — always finds `default` directly by flag, never looks at the duplicate. |
|
|
65
|
-
| `.collaboration/core/task-api.js` `resolveTasksDir` | — | none (grep: 0 matches for `currentProjectId`/`projects.json` in this file) | Not a consumer — resolves task dirs from cwd/`--project-path`, never reads the registry. |
|
|
66
|
-
| `.formation/*`, `.collaboration/hooks/*` other than above | — | none found (grep across `.formation`, `.specialist`, `.collaboration`, `.claude/hooks` for `currentProjectId`/`projects.json`/`project_id` returned only the files listed above) | Not consumers. |
|
|
67
|
-
|
|
68
|
-
Search method for completeness: `grep -rln "currentProjectId\|current_project_id" dashboard/src-tauri/src dashboard/src dev/scripts .collaboration .formation` (27 Rust hits / 9 files, 25 TS hits / 3 files — counts above), plus `grep -rln "currentProjectId\|projects\.json\|project_id\b" .formation .specialist .collaboration .claude/hooks` (10 files, all covered in the table or confirmed non-consumers).
|
|
69
|
-
|
|
70
|
-
## 3. Options
|
|
71
|
-
|
|
72
|
-
**Option A — remove the `proj_` entry, repoint `currentProjectId` to `default`.**
|
|
73
|
-
Steps: (1) stop the Dashboard, (2) edit `~/.kenaz/projects.json`: delete the `proj_1776613204237_0p34i5y` object, set `"currentProjectId": "default"`, (3) restart Dashboard, verify `auto_seed_project_config()` doesn't reintroduce a second core entry (it won't — it only ever writes `id:"default"`), (4) verify `ProjectSelector.tsx` dropdown no longer shows a "KenazAI" sub-project, (5) verify `.kenaz/project.yaml`'s self-sub-project registration doesn't get recreated (the `is_core` short-circuit at `ProjectContext.tsx:809` now correctly fires since `currentProject.is_core` will be `true`).
|
|
74
|
-
Risk: low. Every id-first Rust consumer in the table already resolves the same real path for both ids (`virtual_path::resolve` is symmetric), so no path regression. The one behavior *change* is desired: `currentProject.is_core` becomes `true` again, which is the correct state. `choose_canonical_id` already prefers `default` unconditionally, so cortex/global_memory identity is unaffected. Must also fix `addProject()` (§1) with a path-collision guard, or a future "Add Project" click recreates the exact same problem.
|
|
75
|
-
|
|
76
|
-
**Option B — keep both entries, mark the `proj_` one as an alias in the registry schema.**
|
|
77
|
-
Would require: a new `aliasOf`/`canonicalId` field in the `Project` type (`ProjectContext.tsx:16-26`, `routes/projects.rs:20-34`), every id-first consumer in the table updated to resolve through the alias, `ProjectSelector.tsx:120`'s `userProjects` filter updated to also exclude aliases, and `choose_canonical_id`/`is_same_repo` updated to treat "alias" as authoritative rather than inferring canonicalness from timestamp/`is_core`. This touches ~9 Rust files, 3+ TS files, and duplicates the exact per-consumer knowledge that TASK_2053's `choose_canonical_id` already centralizes — net new surface area to keep in sync, for a state (two live ids for one repo) that has no legitimate use case here (unlike, say, a real rename-with-history feature). Not worth building for a single already-known-bad row.
|
|
78
|
-
|
|
79
|
-
**Option C — leave as is.**
|
|
80
|
-
The immediate global_memory duplication is patched (`choose_canonical_id`, TASK_2053, this branch, tests passing per commit history). But: (a) the entry still shows in the UI as a selectable sub-project (`ProjectSelector.tsx:120`), inviting a user to click it and re-trigger the self-sub-project `initProject()` bug (§2, `ProjectContext.tsx:805-822`); (b) `currentProjectId` staying on a non-`default`/non-`is_core` id is exactly the state that made `ProjectContext.tsx:809`'s short-circuit fail; (c) it remains a trap for the next engineer who writes a *new* id-first-without-is_core-fallback consumer (as CLAUDE.md's task background states was the original motivation).
|
|
81
|
-
|
|
82
|
-
## Recommendation
|
|
83
|
-
|
|
84
|
-
**Option A.** It is a five-minute, low-risk data fix (`choose_canonical_id` already guarantees `default` wins identity resolution regardless, so nothing downstream regresses), it removes the visible UI trap (`ProjectSelector.tsx:120`) and the confirmed live self-sub-project defect (`ProjectContext.tsx:809`/`.kenaz/project.yaml`), and it costs far less than Option B's schema/consumer-update surface for a case with no legitimate use for two live ids. Pair it with a one-line guard in `addProject()` (`ProjectContext.tsx:743`) / `NewProjectDialog.tsx` rejecting a `path`/`core_path` that already resolves to an existing entry's `path`/`core_path`, so the same manual mistake can't recreate the duplicate.
|
|
85
|
-
|
|
86
|
-
**Addendum (TASK_2062, 2026-09-27):** step (4) above was wrong — after removing the `proj_` entry, the core project didn't just stop appearing as a duplicate "KenazAI" sub-project, it disappeared from the dropdown entirely and became unselectable: `ProjectSelector.tsx:120`'s `userProjects` filter excluded *every* `is_core` entry (there was no other one left to filter out), and `ProjectContext.tsx`'s `currentProject` resolver silently redirected any core selection to the first sub-project. The duplicate had been the user's only way to select the core repo. Fixed by listing the core project first in `ProjectSelector.tsx` (selectable, badged, no delete control) and removing the redirect in `ProjectContext.tsx`'s `currentProject` — see TASK_2062.
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
# TASK_1995 R1 — Startup timeline instrumentation + blocking-in-async audit
|
|
2
|
-
|
|
3
|
-
Scope: R1 only (instrument, no behavior change). R2 (moving the blocking
|
|
4
|
-
work off the runtime) is a separate, unscoped task. This document is the
|
|
5
|
-
R1 deliverable: a table of every task/thread spawned inside `lib.rs`'s
|
|
6
|
-
`.setup()` closure, whether its closure calls a blocking API directly on
|
|
7
|
-
the tokio runtime (i.e. without `spawn_blocking` or a dedicated
|
|
8
|
-
`std::thread`), and the evidence line numbers.
|
|
9
|
-
|
|
10
|
-
## Evidence
|
|
11
|
-
|
|
12
|
-
- rune_386048f8 (2026-08-21): the 30 x 500ms TCP ready-wait
|
|
13
|
-
(`infrastructure::nextjs_sidecar::probe_frontend_ready`,
|
|
14
|
-
`ProbeBudget::initial()`) measured at 76.6s wall-clock twice — nominal
|
|
15
|
-
15s, ~5x factor.
|
|
16
|
-
- TASK_1995 never-listens fixture (`dev/scripts/task1961/run-fixture.js
|
|
17
|
-
--arm=never-listens`) reproduced 75983ms / 75799ms on the release build,
|
|
18
|
-
0.2.235 and 0.2.237 — the 5x factor is stable across releases, ruling
|
|
19
|
-
out a one-off regression.
|
|
20
|
-
- Hypothesis (unconfirmed by this task — R1 only *exposes* the evidence,
|
|
21
|
-
it does not prove causation): the shared tokio multi-thread runtime's
|
|
22
|
-
worker pool is starved by blocking calls made directly inside async
|
|
23
|
-
tasks spawned from `.setup()`, so `tokio::time::sleep(500ms)` inside the
|
|
24
|
-
ready-wait loop cannot be polled and resumed promptly even after its
|
|
25
|
-
timer fires.
|
|
26
|
-
|
|
27
|
-
## What R1 added (instrumentation only)
|
|
28
|
-
|
|
29
|
-
- `dashboard/src-tauri/src/infrastructure/startup_timeline.rs` — new
|
|
30
|
-
module. `mark(label)` records `(label, t_ms since first mark, calling
|
|
31
|
-
thread name)` into a bounded (`MAX_ENTRIES = 512`) `Vec` behind a
|
|
32
|
-
`Mutex`, and logs one `tracing::info!(target: "startup_timeline", ...)`
|
|
33
|
-
line per call. `entries()` reads the timeline back.
|
|
34
|
-
- `~25` `mark()` call sites added across `lib.rs`'s `run()`/`.setup()` —
|
|
35
|
-
see the table below (column "Timeline marks added") for exactly which
|
|
36
|
-
ones bracket which spawn site.
|
|
37
|
-
- `infrastructure::nextjs_sidecar::probe_frontend_ready`: per-TCP-attempt
|
|
38
|
-
timing (`nominal_ms` vs `actual_ms`, `max_gap_ms` = worst single
|
|
39
|
-
attempt's overrun) logged once at the end of the TCP phase, and one
|
|
40
|
-
`startup_timeline` line per HTTP hop (`hop`, `budget_ms`, `actual_ms`,
|
|
41
|
-
`status`). No change to attempt counts, intervals, or break conditions.
|
|
42
|
-
- `GET /api/health` now additionally returns `startup_timeline: [{label,
|
|
43
|
-
t_ms, thread}]` (additive field; existing fields unchanged).
|
|
44
|
-
|
|
45
|
-
None of the above changes probe budgets, port handling, ordering, or any
|
|
46
|
-
sleep duration — purely read-only measurement (R4 compliance).
|
|
47
|
-
|
|
48
|
-
## Audit table — spawn sites inside `.setup()`
|
|
49
|
-
|
|
50
|
-
`.setup(|app| { ... Ok(()) })` spans `lib.rs:1332-3506` (post-instrumentation
|
|
51
|
-
line numbers; pre-instrumentation the closure was `1329-3463`). All 34
|
|
52
|
-
concurrency primitives below are inside it. "Blocking in async?" = a
|
|
53
|
-
blocking API (std::fs, rusqlite/KuzuDB open, ONNX load, std::process
|
|
54
|
-
spawn/wait, std::thread::sleep, blocking HTTP) called directly inside an
|
|
55
|
-
`async` closure/fn body, NOT wrapped in `spawn_blocking` and NOT run on a
|
|
56
|
-
dedicated `std::thread`.
|
|
57
|
-
|
|
58
|
-
| # | Site (lib.rs line, post-instrumentation) | Mechanism | Blocking in async? | Evidence (line, call) |
|
|
59
|
-
|---|---|---|---|---|
|
|
60
|
-
| 1 | ~1376 MCP server startup | `tauri::async_runtime::spawn` | Not verified deeply this pass (bounded effort) — `start_mcp_servers` (`features/plugins/mod.rs:155`) loops `list_plugins()` + awaits `mcp_host.start_plugin_server(...).await`, which itself spawns child MCP server processes. Flagged **possible** — child process spawn may share the same `cmd.spawn()`-is-synchronous issue as #16 below. | `features/plugins/mod.rs:155-175` |
|
|
61
|
-
| 2 | ~1420 Yggdrasil remote-ref poller | `tauri::async_runtime::spawn` | **No** direct blocking seen in `remote_poll::start`'s hot path — gated off by default (`remote_poll_enabled=false`); `load_config().await` and `poll_once` are `.await`ed. Not a startup-window contributor while disabled. | `features/remote_poll/mod.rs:93-131` |
|
|
62
|
-
| 3 | ~1613 ONNX warmup thread | `std::thread::Builder::spawn` (own OS thread) | **Isolated — safe.** `eager_init_engine()` (blocking: ONNX model load) runs on a dedicated named thread (`"onnx-warmup"`), not a tokio worker. | `lib.rs` ONNX block; `features/synapse/embedding.rs::eager_init_engine` |
|
|
63
|
-
| 4 | ~1633 ΔGraph gap recovery thread | `std::thread::Builder::spawn` (own OS thread) | **Isolated — safe**, same pattern as #3. `MemoryDb::open()` (rusqlite `Connection::open_with_flags`, blocking) + `delta_graph::recover_gap` + `heat::init_for_project` all run on the dedicated `"delta-gap-recovery"` thread, not a tokio worker. | `lib.rs:1636-1680`; `features/synapse/memory/mod.rs:276-288` (the actual blocking open call, safely isolated here) |
|
|
64
|
-
| 5 | ~1786 startup hook backfill | `tauri::async_runtime::spawn(async {...})`, 5s initial `sleep` | `backfill_all_registered_projects(...).await` — not deep-audited this pass; async signature suggests non-blocking, but its internals were out of the bounded-effort budget. | `lib.rs` hook backfill block |
|
|
65
|
-
| 6 | ~1805 hippocampus consolidation daemon | `tauri::async_runtime::spawn(async {...})`, 60s initial `sleep`, then every 6h | **Yes.** `MemoryDb::open(&db_path)` (rusqlite, blocking disk I/O — journal mode pragma, busy_timeout) called directly inside the async task body, no `spawn_blocking`. | `lib.rs` consolidation block: `features::synapse::memory::MemoryDb::open(&db_path)`; sink fn at `features/synapse/memory/mod.rs:276` |
|
|
66
|
-
| 7 | ~1858 Alaya bija sync daemon | `tauri::async_runtime::spawn(async {...})`, 30s initial `sleep`, then hourly | **Yes.** `GlobalMemoryDb::open()` (rusqlite, blocking) called directly inside the async task, no `spawn_blocking`. The bija-linker step correctly uses `spawn_blocking` (good precedent already in this file). | `lib.rs` alaya block: `GlobalMemoryDb::open()`; sink fn at `features/cortex/global_memory.rs:151` |
|
|
67
|
-
| 8 | ~1929 MCP+HTTP+sidecar mega-task | `tauri::async_runtime::spawn(async move {...})` (never returns — ends in `std::future::pending().await`) | **Yes, several sub-blocks** — see rows 8a-8d below. This is the SAME task that later runs the ready-wait loop (#17), so anything blocking earlier in this task's own body delays reaching the ready-wait, and anything blocking on OTHER tokio workers concurrently can starve the ready-wait's own `sleep()` resumption. | `lib.rs:1929` |
|
|
68
|
-
| 8a | ~1934-1961 port cleanup | `std::thread::spawn` x2 (own OS threads) for `kill_process_on_port` | **Isolated — safe.** Blocking netstat/taskkill work is on dedicated OS threads; only the `done_rx.recv_timeout` wait (bounded 3s) blocks the task's own progress, by design. | `lib.rs` port-cleanup block |
|
|
69
|
-
| 8b | ~2149 EMBER daemon auto-start check | `tokio::task::spawn_blocking` | **Correctly isolated** — good precedent: `std::fs::read_to_string(&models_path)` + child process spawn (`cmd.spawn()`, `common::process::hidden_command`) all inside `spawn_blocking`. | `lib.rs` EMBER block |
|
|
70
|
-
| 8c | ~2247-2260 Ansuz wake-up gate + watchdog | inline in the mega-task (not wrapped) | **Yes.** `std::fs::read_to_string(&models_path)` (line ~2211, `ansuz_wakeup_enabled` check) runs directly in the mega-task body — small file, but still a synchronous disk read on a shared worker thread, on every app launch, unconditionally. | `lib.rs` ansuz wakeup gate |
|
|
71
|
-
| 8d | ~2283-2295 Ansuz wake-up task itself | `tokio::spawn(async move {...})`, 3s initial sleep | **Yes.** `pid_file.exists()` + `std::fs::read_to_string(&pid_file)` + `std::fs::remove_file(&pid_file)` all called directly (not `tokio::fs`, not `spawn_blocking`) inside the async task. | `lib.rs` ansuz wake-up task, `pid_file` handling |
|
|
72
|
-
| 8e | ~2360-2367 Ansuz daemon watcher: "selected project" resolution | inline in the mega-task (not wrapped) | **Yes, explicitly acknowledged in-code.** `std::fs::read_to_string(&projects_file)` inside a sync closure, called directly in the mega-task body. The existing comment reads *"Read projects.json directly (avoid block_in_place in async context)"* — the author knew this blocks and chose it over `block_in_place` anyway. | `lib.rs` "Auto-start Ansuz daemon watcher" block, `let selected_project_path: Option<String> = (|| { ... std::fs::read_to_string(&projects_file) ... })();` |
|
|
73
|
-
| 9 | ~2360 `ansuz_daemon::start(...)` | `tokio::spawn(run_daemon(...))` inside `features::ansuz_daemon::mod.rs:133` | **Yes — the strongest single suspect found this pass.** `run_daemon`'s loop sleeps only **500ms** between iterations (`ansuz_daemon/mod.rs:290`) — the SAME nominal interval as the ready-wait TCP loop. Every iteration unconditionally does `std::fs::read_to_string(&projects_file)` (`ansuz_daemon/mod.rs:152`, direct `std::fs`, not `tokio::fs`), and when a runner PID is tracked, ALSO `std::fs::read_to_string(&models_path)` (`ansuz_daemon/mod.rs:229`, same pattern) every iteration. This loop is started (via `ansuz_daemon::start(...)`, `lib.rs` ~2360) BEFORE the Next.js sidecar is spawned in the same overall startup sequence, so it is running concurrently with the ready-wait loop for its entire duration, contending for worker threads on the identical 500ms cadence. On a cold/AV-scanned disk (the exact condition TASK_1907 measured `GET /` taking 60s+ under) `std::fs::read_to_string` can itself block far longer than the nominal interval. | `features/ansuz_daemon/mod.rs:152, 229, 290` |
|
|
74
|
-
| 10 | ~2404-2429 session watcher spawn | `tokio::spawn(async move {...})`, 4s initial sleep, then `session_watcher::start(...)` | **No** — `run_watcher_with_dir` uses `tokio::fs::read_to_string` (async), not a raw blocking read. Good precedent. | `features/session_watcher/mod.rs:188` |
|
|
75
|
-
| 11 | ~2446 (`#[cfg(not(debug_assertions))]`) Next.js port-availability check | inline, `std::net::TcpListener::bind` | **Technically blocking**, but `bind()`/`drop()` are near-instant syscalls, not a real contributor. Noted for completeness only. | `lib.rs` port_available block |
|
|
76
|
-
| 12 | ~2517 Next.js sidecar `cmd.spawn()` | inline in the mega-task (not wrapped) | **Yes — second strongest suspect.** `tokio::process::Command::spawn()` is a SYNCHRONOUS method (not `.await`ed) — process creation (`CreateProcessW` on Windows) runs directly on whichever tokio worker thread is polling this task. On a cold/AV-scanned install this can be arbitrarily slow (same AV-scan mechanism TASK_1907 measured making `GET /` take 60s+). Now bracketed by `startup_timeline::mark("nextjs_sidecar_spawn_start"/"_done")` so a live repro can show its actual cost. | `lib.rs:2517-2524` (`match cmd.spawn() {`) |
|
|
77
|
-
| 13 | ~2560 stream loggers | `tokio::spawn` x2 inside `spawn_nextjs_stream_loggers` | **No** — uses `tokio::io::AsyncBufReadExt` / async `BufReader`; `append_sidecar_log`'s `std::fs` calls run per log line, inside the async task but each is small/append-only; not flagged as a primary suspect (lower call frequency, not on the ready-wait's own critical path). | `infrastructure/nextjs_sidecar.rs:431-447` |
|
|
78
|
-
| 14 | ~2578 splash status ticker | `tokio::spawn(async move {...})` | **No** — only `tokio::time::sleep` + a webview `eval()` call (IPC, not disk/DB). | `lib.rs` splash_ticker block |
|
|
79
|
-
| 15 | ~2599 (in-line, same mega-task) `probe_frontend_ready(...).await` — **the ready-wait itself** | awaited call, not spawned | N/A — this is the loop being measured, not a spawn site. Its own body is now instrumented (per-attempt/per-hop timing, this task's R1 scope). | `infrastructure/nextjs_sidecar.rs:135-284` |
|
|
80
|
-
| 16 | ~2698 health monitor | `tokio::spawn(async move {...})`, 20s grace, then every 15s | **Partially.** The hot path uses `tokio::time::timeout` + `tokio::net::TcpStream::connect` (non-blocking) and `tokio::task::...` is NOT used, but the respawn branch calls `new_cmd.spawn()` (same synchronous-spawn issue as #12) and `c.kill().await` / `c.wait().await` (these ARE async on `tokio::process::Child`, fine). Respawn's `cmd.spawn()` synchronous cost is the same class of issue as #12, just on the restart path instead of first boot. | `lib.rs` respawn block, `new_cmd.spawn()` |
|
|
81
|
-
| 17 | ~2884 dev-mode route warmer (`#[cfg(debug_assertions)]`) | inline in the mega-task | **No** — uses `reqwest` async client + `tokio::time::sleep`; debug builds only, not relevant to the release-build fixture this task measures against. | `lib.rs` dev warm_routes block |
|
|
82
|
-
| 18 | ~2939 PTY server start | `pty_launcher.start().await` | Not deep-audited this pass (bounded effort); `PtyServerLauncher::start` at `infrastructure/pty_server_launcher/launcher.rs:206` is `async fn`, awaited — likely fine, flagged for a future pass if R2 needs it. | `lib.rs:2939` |
|
|
83
|
-
| 19 | ~2960-3010 heat/pulse/reaper periodic-save tasks | `tauri::async_runtime::spawn` x3, first tick after 300s/interval | **Reaper is correctly isolated** (`tokio::task::spawn_blocking(reap_idle_once)`, `lib.rs` reaper block — good precedent, explicit comment cites TASK_1924 convention). Heat/pulse saves (`heat::save_all_caches()`, `pulse::save_all_caches()`) are called directly — not deep-audited, but their first tick fires after 300s, well outside the 0-76s ready-wait window, so not flagged as a contributor to THIS measurement. | `lib.rs` periodic-save blocks |
|
|
84
|
-
| 20 | ~3206 Synapse auto-index watcher | `tauri::async_runtime::spawn(async {...})`, loop every 30s | **Correctly isolated for the heavy calls** — `git2::Repository::open` and `features::synapse::index::run_index` are both wrapped in `tokio::task::spawn_blocking` (good precedent, explicit TASK_1927/1983 comments). Lighter calls (`get_index_state`, `watcher_decision`) not audited but are pure/JSON-state reads, not flagged. | `lib.rs:3236, 3336` (`tokio::task::spawn_blocking`) |
|
|
85
|
-
| 21 | ~3441 (`#[cfg(not(debug_assertions))]`) updater startup check | `tauri::async_runtime::spawn`, 15s delay | Not deep-audited (bounded effort); release-only. | `lib.rs` updater block |
|
|
86
|
-
|
|
87
|
-
## Top suspects (ranked)
|
|
88
|
-
|
|
89
|
-
1. **`ansuz_daemon::run_daemon` loop — `features/ansuz_daemon/mod.rs:152,
|
|
90
|
-
229, 290`.** Runs on the SAME 500ms cadence as the ready-wait's own
|
|
91
|
-
`tokio::time::sleep`, started before the sidecar spawn, does a direct
|
|
92
|
-
(non-`tokio::fs`, non-`spawn_blocking`) `std::fs::read_to_string` EVERY
|
|
93
|
-
iteration, unconditionally. The single clearest "runs concurrently, on
|
|
94
|
-
the same tokio worker pool, on the same nominal interval, doing
|
|
95
|
-
synchronous disk I/O every cycle" candidate found this pass.
|
|
96
|
-
2. **Next.js sidecar `cmd.spawn()` — `lib.rs:2517-2524`** (and the
|
|
97
|
-
structurally identical respawn call in the health monitor, `lib.rs`
|
|
98
|
-
~row 16). `tokio::process::Command::spawn()` is synchronous; on a
|
|
99
|
-
cold/AV-scanned install this is exactly the class of delay TASK_1907
|
|
100
|
-
measured (`GET /` up to 60836ms) — but here it would block a tokio
|
|
101
|
-
*worker thread*, not just this task's own progress, degrading every
|
|
102
|
-
other task sharing that runtime, including the ready-wait loop that
|
|
103
|
-
runs moments later in the SAME task.
|
|
104
|
-
3. **Hippocampus consolidation (`MemoryDb::open`, `lib.rs` ~1805-1858+
|
|
105
|
-
`features/synapse/memory/mod.rs:276`) and Alaya sync
|
|
106
|
-
(`GlobalMemoryDb::open`, `features/cortex/global_memory.rs:151`)
|
|
107
|
-
daemons.** Both open a rusqlite connection directly inside an async
|
|
108
|
-
task, no `spawn_blocking`. Their 60s/30s initial delays put them near
|
|
109
|
-
the tail of the 76s measured window, not the start — lower-confidence
|
|
110
|
-
contributor to the FIRST ~20s of the loop, more plausible for the
|
|
111
|
-
later attempts within the same 76s run.
|
|
112
|
-
4. **`lib.rs` "Auto-start Ansuz daemon watcher" project-path resolution**
|
|
113
|
-
(`std::fs::read_to_string(&projects_file)`, explicitly commented as an
|
|
114
|
-
intentional block-avoiding-`block_in_place` choice) — a single call at
|
|
115
|
-
startup, not a loop, so lower severity than #1, but confirms the
|
|
116
|
-
pattern is a known, deliberate tradeoff elsewhere in this file too.
|
|
117
|
-
|
|
118
|
-
## Root cause (measured) — R2b
|
|
119
|
-
|
|
120
|
-
R1's top suspects above (`ansuz_daemon::run_daemon`'s 500ms `std::fs`
|
|
121
|
-
loop, the synchronous `cmd.spawn()` calls, the rusqlite `MemoryDb::open`
|
|
122
|
-
daemons) were a *hypothesis* — "the shared tokio runtime is starved by
|
|
123
|
-
blocking calls" — built on a node-based control (rune_386048f8) that
|
|
124
|
-
connected to the never-listens fixture's port in ~1ms and was read as
|
|
125
|
-
proof the runtime, not the connect itself, was slow. That control was
|
|
126
|
-
misleading: it measured Node/libuv's connect path, not the Winsock path
|
|
127
|
-
`tokio::net::TcpStream::connect` actually uses on Windows.
|
|
128
|
-
|
|
129
|
-
Direct measurement on this Windows machine, connecting to an UNBOUND
|
|
130
|
-
loopback port:
|
|
131
|
-
|
|
132
|
-
- curl: ECONNREFUSED after ~2.07s
|
|
133
|
-
- .NET `TcpClient`: ECONNREFUSED after 2118ms
|
|
134
|
-
- Node/libuv `net.connect`: refused after ~1ms (the misleading control)
|
|
135
|
-
|
|
136
|
-
`probe_frontend_ready`'s TCP ready-wait loop (`ProbeBudget::initial()`,
|
|
137
|
-
30 attempts, 500ms nominal interval) had **no timeout wrapped around the
|
|
138
|
-
`TcpStream::connect` call itself**. Measured tonight on the release exe
|
|
139
|
-
(0.2.238, after R2) with the never-listens fixture, the ready-wait still
|
|
140
|
-
took **76190ms**; R1's own per-attempt timing line reported:
|
|
141
|
-
|
|
142
|
-
```
|
|
143
|
-
ready-wait TCP phase timing attempts=30 nominal_ms=14500 actual_ms=76182 max_gap_ms=2071
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Every attempt costs a uniform ~2.5s (~2.07-2.12s refused-connect +
|
|
147
|
-
~0.5s sleep) — not a handful of unusually slow outliers, which is what
|
|
148
|
-
runtime starvation (occasional worker-thread contention) would look
|
|
149
|
-
like. A uniform per-attempt cost close to the measured Winsock
|
|
150
|
-
refused-connect latency is the signature of a missing per-attempt
|
|
151
|
-
bound, not starvation: **30 x (~2.07-2.12s refused-connect + 0.5s
|
|
152
|
-
sleep) ≈ 77s**, matching the measured 76190ms almost exactly.
|
|
153
|
-
|
|
154
|
-
**Corrected conclusion:** the never-listens ready-wait's ~5x-nominal
|
|
155
|
-
wall-clock cost is explained by Winsock's refused-connect latency on
|
|
156
|
-
this Windows machine (~2s/attempt, unbounded) times 30 attempts — not
|
|
157
|
-
by tokio runtime starvation from the R1 audit's blocking-in-async call
|
|
158
|
-
sites. The fix (this task, R2b) wraps each TCP attempt in
|
|
159
|
-
`tokio::time::timeout(budget.tcp_connect_timeout, TcpStream::connect(..))`
|
|
160
|
-
with a 200ms budget (a listening localhost port completes the handshake
|
|
161
|
-
in <5ms), treating a timeout exactly like a refused connect.
|
|
162
|
-
|
|
163
|
-
The R1 audit table's "Blocking in async?" findings (`ansuz_daemon`'s
|
|
164
|
-
500ms `std::fs::read_to_string` loop, synchronous `cmd.spawn()` calls,
|
|
165
|
-
`MemoryDb::open`/`GlobalMemoryDb::open` inside async tasks, etc.) are
|
|
166
|
-
real code-hygiene issues worth fixing on their own merits — direct
|
|
167
|
-
blocking I/O on a shared tokio worker thread is bad practice regardless
|
|
168
|
-
of whether it caused this particular symptom — but they are **not** the
|
|
169
|
-
cause of the measured 76190ms never-listens ready-wait. That gap is
|
|
170
|
-
fully accounted for by the unbounded per-attempt connect latency above.
|
|
171
|
-
|
|
172
|
-
## Explicitly NOT done in R1
|
|
173
|
-
|
|
174
|
-
- No blocking call was moved to `spawn_blocking` or a dedicated thread.
|
|
175
|
-
- No timing/interval/ordering was changed anywhere (`nextjs_sidecar.rs`
|
|
176
|
-
probe logic, `ansuz_daemon` loop interval, spawn ordering in `.setup()`).
|
|
177
|
-
- Rows marked "not deep-audited this pass" (MCP host child-process
|
|
178
|
-
startup, hook backfill, PTY server start, updater check, heat/pulse
|
|
179
|
-
periodic saves) were scoped out to keep this pass bounded — R2 (or a
|
|
180
|
-
follow-up audit) should re-visit those before claiming the full
|
|
181
|
-
blocking-call inventory is exhaustive.
|