kenaz 0.3.3 → 0.3.6
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/.agents/skills/typesafe-ai/LICENSE +21 -21
- package/core/.agents/skills/typesafe-ai/SKILL.md +149 -149
- package/core/.claude/commands/Ansuz.md +15 -2
- package/core/.claude/hooks/__tests__/task-2395-project-registration.test.js +84 -0
- package/core/.claude/hooks/handoff-staleness.js +2 -2
- package/core/.claude/hooks/session-init.ps1 +49 -49
- package/core/.claude/hooks/turn-context.js +50 -2
- package/core/.claude/skills/ui-ux-pro-max/data/charts.csv +26 -26
- package/core/.claude/skills/ui-ux-pro-max/data/colors.csv +97 -97
- package/core/.claude/skills/ui-ux-pro-max/data/icons.csv +101 -101
- package/core/.claude/skills/ui-ux-pro-max/data/landing.csv +31 -31
- package/core/.claude/skills/ui-ux-pro-max/data/products.csv +96 -96
- package/core/.claude/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/core/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/core/.claude/skills/ui-ux-pro-max/data/styles.csv +68 -68
- package/core/.claude/skills/ui-ux-pro-max/data/typography.csv +57 -57
- package/core/.claude/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
- package/core/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
- package/core/.claude/skills/ui-ux-pro-max/data/web-interface.csv +31 -31
- package/core/.claude/skills/ui-ux-pro-max/scripts/core.py +253 -253
- package/core/.claude/skills/ui-ux-pro-max/scripts/design_system.py +1067 -1067
- package/core/.claude/skills/ui-ux-pro-max/scripts/search.py +106 -106
- package/core/.collaboration/core/task-api.js +1 -4
- package/core/.formation/README.md +21 -146
- package/core/.formation/bifrost/codex-doctor.js +37 -2
- package/core/.formation/bifrost/codex-doctor.test.js +18 -0
- package/core/.formation/bifrost/launch.js +1 -1
- package/core/.formation/bifrost/openai/codex-hook-shim.js +6 -0
- package/core/.formation/bifrost/openai/codex-hook-shim.test.js +11 -1
- package/core/.formation/bifrost/setup-codex.js +3 -0
- package/core/.formation/native/claude/README.md +1 -1
- package/core/.formation/role-map.yaml +3 -3
- package/core/.formation/spec/task_operations.parity.test.js +0 -1
- package/core/.formation/spec/task_operations.yaml +3 -3
- package/core/.formation/tests/hello.txt +2 -2
- package/core/.formation/tools/__tests__/subagent-bifrost-guard.test.js +4 -4
- package/core/.formation/tools/dashboard-models-chain.test.js +0 -6
- package/core/.formation/tools/dispatch-detail/cross-project-worktree.md +1 -9
- package/core/.formation/tools/dispatch-detail/worktree-subagent-mode.md +2 -2
- package/core/.formation/tools/dispatch.js +33 -554
- package/core/.formation/tools/mcp-allowlist.test.js +0 -1
- package/core/.formation/tools/post-complete/task2345.test.js +0 -5
- package/core/.formation/tools/pre-dispatch-snapshot.test.js +0 -100
- package/core/.formation/tools/prompt.js +33 -1623
- package/core/.formation/tools/prompt.test.js +26 -594
- package/core/.formation/unit/do.yaml +2 -4
- package/core/.kenaz/knowledge/ladybug_2c51da1e_shadow_file_frame_group.patch +163 -163
- package/core/.kenaz/knowledge/ladybug_30cf85690e_shadow_page_read_during_checkpoint.patch +393 -393
- package/core/.kenaz/knowledge/ladybug_7a17858d3a_node_group_delete_lock.patch +102 -102
- package/core/.kenaz/knowledge/ladybug_926a0ba1_column_checkpoint.patch +412 -412
- package/core/.kenaz/knowledge/ladybug_a346c4c4b6_pk_index_header_pages.patch +144 -144
- package/core/.kenaz/knowledge/ladybug_ba5f38815b_csr_node_group.patch +86 -86
- package/core/.kenaz/muninn_episode_write.ps1 +17 -17
- package/core/.kenaz/specialist/field_report_watermark.json +1 -1
- package/core/.kenaz/specialist/memory_guard_fired.json +1 -1
- package/core/.kenaz/specialist/memory_guard_trigger_cache.json +1 -1
- package/core/.kenaz/specialist/t1777_probe.txt +1 -1
- package/core/.matrix/index.matrix +5 -5
- package/core/.rule/general/agent-workflow.yaml +4 -4
- package/core/.rule/general/file-size-threshold.yaml +16 -4
- package/core/.rule/general/rust-verify-target.yaml +0 -1
- package/core/.rule/general/system-invariants.yaml +8 -25
- package/core/.specialist/Ansuz/SYSTEM_DOC.md +17 -42
- package/core/.specialist/Ansuz/capability.yaml +7 -14
- package/core/.specialist/Ansuz/concepts/formation_quick_ref.yaml +4 -11
- package/core/.specialist/Ansuz/elixir.yaml +3 -4
- package/core/.specialist/Ansuz/identity_contract.yaml +1 -1
- package/core/.specialist/Ansuz/knowledge.yaml +7 -10
- package/core/.specialist/Ansuz/rule.yaml +2 -2
- package/core/.specialist/Ansuz/tools/verify-and-land.js +22 -0
- package/core/.specialist/Ansuz/tools/verify-and-land.test.js +59 -5
- package/core/.specialist/Ansuz/workflow.yaml +7 -11
- package/core/.specialist/Forseti/core.yaml +1 -1
- package/core/.specialist/Heimdall/SKILL.md +1 -1
- package/core/.specialist/Heimdall/core.yaml +2 -2
- package/core/.specialist/Huginn/rule.yaml +1 -1
- package/core/.specialist/tools/README.md +2 -2
- package/core/.specialist/tools/__tests__/freya-cli-contract.test.js +0 -1
- package/core/.system/collaboration/README.md +1 -1
- package/core/.system/formation/LEGACY_SKILLS.md +2 -0
- package/core/.system/formation/POST_COMPLETE.md +2 -0
- package/core/.system/formation/README.md +2 -0
- package/core/KENAZ_CORE_VERSION +1 -1
- package/core/dev/ANSUZ_STARTUP_INJECTION_REVIEW.md +355 -355
- package/core/dev/JEV_INTEGRATION_PLAN.md +189 -189
- package/core/dev/design/matrix_format_EXAMPLE_memory.matrix +13 -13
- package/core/dev/design/matrix_format_EXAMPLE_project_status.matrix +9 -9
- package/core/dev/design/matrix_format_EXAMPLE_tasks.matrix +14 -14
- package/core/dev/design/matrix_v2_EXAMPLE.matrix +67 -67
- package/core/dev/jev-eval/ACTIVE_CORRECTION.md +52 -52
- package/core/dev/jev-eval/CONTEXT_REVIEW.md +31 -31
- package/core/dev/jev-eval/EVALUATION_STATUS.md +39 -39
- package/core/dev/jev-eval/HISTORICAL_CORPUS.md +33 -33
- package/core/dev/jev-eval/README.md +99 -99
- package/core/dev/jev-eval/THALAMUS_RANKING.md +58 -58
- package/core/dev/jev-eval/reports/annotation-pilot-2026-09-20.json +32 -32
- package/core/dev/jev-eval/reports/context-review-2026-09-20.json +48 -48
- package/core/dev/jev-eval/reports/history-corpus-2026-09-20.json +52 -52
- package/core/dev/pipeline/SELF_ENHANCEMENT_STATUS.json.bak +47 -47
- package/core/dev/pipeline/tasks/.gitkeep +1 -1
- package/core/dev/pipeline/test_results/TASK_TEST_PARALLEL_002_result.txt +27 -27
- package/core/dev/scripts/check-file-size.js +44 -17
- package/core/dev/scripts/init_git.sh +0 -0
- package/core/dev/scripts/init_project.sh +0 -0
- package/core/dev/scripts/legacy/dev_agent_scheduler.ps1.bak +536 -536
- package/core/dev/scripts/legacy/multi_agent_scheduler.ps1.bak +1978 -1978
- package/core/dev/scripts/matrix/src/cli/commands/list-tags.ts.wip +140 -140
- package/core/dev/scripts/matrix/src/cli/commands/manage-tags.ts.wip +173 -173
- package/core/dev/scripts/matrix/src/cli/commands/stats.ts.wip +168 -168
- package/core/dev/scripts/matrix/src/cli/commands/tokens.ts.wip +126 -126
- package/core/dev/scripts/multi_agent_scheduler.sh +0 -0
- package/core/dev/scripts/run_once.sh +0 -0
- package/core/dev/scripts/setup_mcp.sh +0 -0
- package/core/dev/scripts/setup_rag.sh +0 -0
- package/core/dev/scripts/start_dev_agent.sh +0 -0
- package/core/dev/scripts/start_multi_agent.sh +0 -0
- package/core/dev/scripts/sync_task_queue.sh +0 -0
- package/core/k-cli/README.md +1 -94
- package/core/k-cli/test/TEST_SPEC.md +5 -22
- package/core/k-cli/test/run.sh +1 -67
- package/core/plugins/kenaz/commands/Amelia.md +1 -1
- package/core/plugins/kenaz/commands/Ansuz.md +16 -3
- package/core/plugins/kenaz/scripts/kenaz-mode.js +11 -1
- package/core/plugins/kenaz/scripts/sync.js +6 -2
- package/core/plugins/kenaz/scripts/ygg.js +13 -1
- package/core/plugins/kenaz/skills/product_manager/SKILL.md +12 -12
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/charts.csv +26 -26
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/colors.csv +97 -97
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/icons.csv +101 -101
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/landing.csv +31 -31
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/products.csv +96 -96
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/styles.csv +68 -68
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/typography.csv +57 -57
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
- package/core/plugins/kenaz/skills/ui-ux-pro-max/data/web-interface.csv +31 -31
- package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/core.py +253 -253
- package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/design_system.py +1067 -1067
- package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/search.py +106 -106
- package/lib/cli.js +11 -4
- package/package.json +11 -7
- package/vendor/install-kenaz-cli.js +18 -7
- package/core/.formation/legion/forge.yaml +0 -299
- package/core/.formation/legion/hive.yaml +0 -238
- package/core/.formation/squad/blitz.yaml +0 -192
- package/core/.formation/squad/strategy-tribunal.yaml +0 -354
- package/core/.formation/squad/strategy.yaml +0 -349
- package/core/.formation/squad/sweep.yaml +0 -208
- package/core/.formation/tools/broadcast.js +0 -103
- package/core/.formation/tools/dispatch-dryrun.test.js +0 -54
- package/core/.formation/tools/dispatch-notifier.js +0 -84
- package/core/.formation/tools/formations.js +0 -1203
- package/core/.formation/tools/headless-branch-recovery.test.js +0 -64
- package/core/.formation/tools/headless-dryrun.test.js +0 -79
- package/core/.formation/tools/headless-v2.js +0 -659
- package/core/.formation/tools/headless.js +0 -1071
- package/core/.formation/tools/legacy-scheduler.js +0 -1994
- package/core/.formation/tools/logger.js +0 -273
- package/core/.formation/tools/memory-loader.js +0 -422
- package/core/.formation/tools/process-state.js +0 -33
- package/core/.formation/tools/remote-conflict.js +0 -98
- package/core/.formation/tools/runner.js +0 -1332
- package/core/.formation/tools/task-utils.js +0 -344
- package/core/.formation/tools/task2028-headless-worktree.test.js +0 -112
- package/core/.formation/tools/tests/headless-mcp-args-plumbing.test.js +0 -123
- package/core/.formation/tools/worktree-leak.test.js +0 -162
- package/core/k-cli/dist/alaya/run.js +0 -91
- package/core/k-cli/dist/core/output.js +0 -24
- package/core/k-cli/dist/core/process.js +0 -38
- package/core/k-cli/dist/core/project.js +0 -80
- package/core/k-cli/dist/core/spawn.js +0 -268
- package/core/k-cli/dist/core/types.js +0 -2
- package/core/k-cli/dist/dashboard/update.js +0 -53
- package/core/k-cli/dist/dashboard/version.js +0 -20
- package/core/k-cli/dist/dispatch/run.js +0 -241
- package/core/k-cli/dist/dispatch/status.js +0 -103
- package/core/k-cli/dist/index.js +0 -283
- package/core/k-cli/dist/project/initialize.js +0 -301
- package/core/k-cli/dist/project/install.js +0 -89
- package/core/k-cli/dist/project/status.js +0 -138
- package/core/k-cli/dist/specialist/list.js +0 -100
- package/core/k-cli/dist/specialist/run.js +0 -93
- package/core/k-cli/dist/task/create.js +0 -194
- package/core/k-cli/dist/task/delete.js +0 -98
- package/core/k-cli/dist/task/get.js +0 -55
- package/core/k-cli/dist/task/list.js +0 -58
- package/core/k-cli/dist/task/submit.js +0 -156
- package/core/k-cli/dist/ygg/run.js +0 -51
- package/core/k-cli/node_modules/.bin/yaml +0 -16
- package/core/k-cli/node_modules/.bin/yaml.cmd +0 -17
- package/core/k-cli/node_modules/.bin/yaml.ps1 +0 -28
- package/core/k-cli/node_modules/.package-lock.json +0 -23
- package/core/k-cli/node_modules/yaml/LICENSE +0 -13
- package/core/k-cli/node_modules/yaml/README.md +0 -172
- package/core/k-cli/node_modules/yaml/bin.mjs +0 -11
- package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-collection.js +0 -88
- package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-doc.js +0 -43
- package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-node.js +0 -109
- package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-scalar.js +0 -86
- package/core/k-cli/node_modules/yaml/browser/dist/compose/composer.js +0 -217
- package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-map.js +0 -115
- package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +0 -198
- package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +0 -49
- package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-end.js +0 -37
- package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +0 -207
- package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +0 -223
- package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-props.js +0 -146
- package/core/k-cli/node_modules/yaml/browser/dist/compose/util-contains-newline.js +0 -34
- package/core/k-cli/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +0 -26
- package/core/k-cli/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +0 -15
- package/core/k-cli/node_modules/yaml/browser/dist/compose/util-map-includes.js +0 -13
- package/core/k-cli/node_modules/yaml/browser/dist/doc/Document.js +0 -335
- package/core/k-cli/node_modules/yaml/browser/dist/doc/anchors.js +0 -71
- package/core/k-cli/node_modules/yaml/browser/dist/doc/applyReviver.js +0 -55
- package/core/k-cli/node_modules/yaml/browser/dist/doc/createNode.js +0 -88
- package/core/k-cli/node_modules/yaml/browser/dist/doc/directives.js +0 -176
- package/core/k-cli/node_modules/yaml/browser/dist/errors.js +0 -57
- package/core/k-cli/node_modules/yaml/browser/dist/index.js +0 -17
- package/core/k-cli/node_modules/yaml/browser/dist/log.js +0 -11
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/Alias.js +0 -114
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/Collection.js +0 -147
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/Node.js +0 -38
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/Pair.js +0 -36
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/Scalar.js +0 -24
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/YAMLMap.js +0 -144
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +0 -113
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +0 -63
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/identity.js +0 -36
- package/core/k-cli/node_modules/yaml/browser/dist/nodes/toJS.js +0 -37
- package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-scalar.js +0 -214
- package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-stringify.js +0 -61
- package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-visit.js +0 -97
- package/core/k-cli/node_modules/yaml/browser/dist/parse/cst.js +0 -98
- package/core/k-cli/node_modules/yaml/browser/dist/parse/lexer.js +0 -717
- package/core/k-cli/node_modules/yaml/browser/dist/parse/line-counter.js +0 -39
- package/core/k-cli/node_modules/yaml/browser/dist/parse/parser.js +0 -967
- package/core/k-cli/node_modules/yaml/browser/dist/public-api.js +0 -102
- package/core/k-cli/node_modules/yaml/browser/dist/schema/Schema.js +0 -37
- package/core/k-cli/node_modules/yaml/browser/dist/schema/common/map.js +0 -17
- package/core/k-cli/node_modules/yaml/browser/dist/schema/common/null.js +0 -15
- package/core/k-cli/node_modules/yaml/browser/dist/schema/common/seq.js +0 -17
- package/core/k-cli/node_modules/yaml/browser/dist/schema/common/string.js +0 -14
- package/core/k-cli/node_modules/yaml/browser/dist/schema/core/bool.js +0 -19
- package/core/k-cli/node_modules/yaml/browser/dist/schema/core/float.js +0 -43
- package/core/k-cli/node_modules/yaml/browser/dist/schema/core/int.js +0 -38
- package/core/k-cli/node_modules/yaml/browser/dist/schema/core/schema.js +0 -23
- package/core/k-cli/node_modules/yaml/browser/dist/schema/json/schema.js +0 -62
- package/core/k-cli/node_modules/yaml/browser/dist/schema/tags.js +0 -96
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +0 -58
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +0 -26
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +0 -46
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +0 -71
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +0 -64
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +0 -74
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +0 -78
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +0 -39
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +0 -93
- package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +0 -101
- package/core/k-cli/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +0 -146
- package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringify.js +0 -129
- package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +0 -153
- package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyComment.js +0 -20
- package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +0 -85
- package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +0 -24
- package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyPair.js +0 -150
- package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyString.js +0 -336
- package/core/k-cli/node_modules/yaml/browser/dist/util.js +0 -11
- package/core/k-cli/node_modules/yaml/browser/dist/visit.js +0 -233
- package/core/k-cli/node_modules/yaml/browser/index.js +0 -5
- package/core/k-cli/node_modules/yaml/browser/package.json +0 -3
- package/core/k-cli/node_modules/yaml/dist/cli.d.ts +0 -8
- package/core/k-cli/node_modules/yaml/dist/cli.mjs +0 -201
- package/core/k-cli/node_modules/yaml/dist/compose/compose-collection.d.ts +0 -11
- package/core/k-cli/node_modules/yaml/dist/compose/compose-collection.js +0 -90
- package/core/k-cli/node_modules/yaml/dist/compose/compose-doc.d.ts +0 -7
- package/core/k-cli/node_modules/yaml/dist/compose/compose-doc.js +0 -45
- package/core/k-cli/node_modules/yaml/dist/compose/compose-node.d.ts +0 -29
- package/core/k-cli/node_modules/yaml/dist/compose/compose-node.js +0 -112
- package/core/k-cli/node_modules/yaml/dist/compose/compose-scalar.d.ts +0 -5
- package/core/k-cli/node_modules/yaml/dist/compose/compose-scalar.js +0 -88
- package/core/k-cli/node_modules/yaml/dist/compose/composer.d.ts +0 -63
- package/core/k-cli/node_modules/yaml/dist/compose/composer.js +0 -222
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-map.d.ts +0 -6
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-map.js +0 -117
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +0 -11
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-scalar.js +0 -200
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +0 -6
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-seq.js +0 -51
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-end.d.ts +0 -6
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-end.js +0 -39
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +0 -7
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-collection.js +0 -209
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +0 -10
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-scalar.js +0 -225
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-props.d.ts +0 -23
- package/core/k-cli/node_modules/yaml/dist/compose/resolve-props.js +0 -148
- package/core/k-cli/node_modules/yaml/dist/compose/util-contains-newline.d.ts +0 -2
- package/core/k-cli/node_modules/yaml/dist/compose/util-contains-newline.js +0 -36
- package/core/k-cli/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +0 -2
- package/core/k-cli/node_modules/yaml/dist/compose/util-empty-scalar-position.js +0 -28
- package/core/k-cli/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +0 -3
- package/core/k-cli/node_modules/yaml/dist/compose/util-flow-indent-check.js +0 -17
- package/core/k-cli/node_modules/yaml/dist/compose/util-map-includes.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/compose/util-map-includes.js +0 -15
- package/core/k-cli/node_modules/yaml/dist/doc/Document.d.ts +0 -141
- package/core/k-cli/node_modules/yaml/dist/doc/Document.js +0 -337
- package/core/k-cli/node_modules/yaml/dist/doc/anchors.d.ts +0 -24
- package/core/k-cli/node_modules/yaml/dist/doc/anchors.js +0 -76
- package/core/k-cli/node_modules/yaml/dist/doc/applyReviver.d.ts +0 -9
- package/core/k-cli/node_modules/yaml/dist/doc/applyReviver.js +0 -57
- package/core/k-cli/node_modules/yaml/dist/doc/createNode.d.ts +0 -17
- package/core/k-cli/node_modules/yaml/dist/doc/createNode.js +0 -90
- package/core/k-cli/node_modules/yaml/dist/doc/directives.d.ts +0 -49
- package/core/k-cli/node_modules/yaml/dist/doc/directives.js +0 -178
- package/core/k-cli/node_modules/yaml/dist/errors.d.ts +0 -21
- package/core/k-cli/node_modules/yaml/dist/errors.js +0 -62
- package/core/k-cli/node_modules/yaml/dist/index.d.ts +0 -25
- package/core/k-cli/node_modules/yaml/dist/index.js +0 -50
- package/core/k-cli/node_modules/yaml/dist/log.d.ts +0 -3
- package/core/k-cli/node_modules/yaml/dist/log.js +0 -19
- package/core/k-cli/node_modules/yaml/dist/nodes/Alias.d.ts +0 -29
- package/core/k-cli/node_modules/yaml/dist/nodes/Alias.js +0 -116
- package/core/k-cli/node_modules/yaml/dist/nodes/Collection.d.ts +0 -73
- package/core/k-cli/node_modules/yaml/dist/nodes/Collection.js +0 -151
- package/core/k-cli/node_modules/yaml/dist/nodes/Node.d.ts +0 -53
- package/core/k-cli/node_modules/yaml/dist/nodes/Node.js +0 -40
- package/core/k-cli/node_modules/yaml/dist/nodes/Pair.d.ts +0 -22
- package/core/k-cli/node_modules/yaml/dist/nodes/Pair.js +0 -39
- package/core/k-cli/node_modules/yaml/dist/nodes/Scalar.d.ts +0 -43
- package/core/k-cli/node_modules/yaml/dist/nodes/Scalar.js +0 -27
- package/core/k-cli/node_modules/yaml/dist/nodes/YAMLMap.d.ts +0 -53
- package/core/k-cli/node_modules/yaml/dist/nodes/YAMLMap.js +0 -147
- package/core/k-cli/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +0 -60
- package/core/k-cli/node_modules/yaml/dist/nodes/YAMLSeq.js +0 -115
- package/core/k-cli/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/nodes/addPairToJSMap.js +0 -65
- package/core/k-cli/node_modules/yaml/dist/nodes/identity.d.ts +0 -23
- package/core/k-cli/node_modules/yaml/dist/nodes/identity.js +0 -53
- package/core/k-cli/node_modules/yaml/dist/nodes/toJS.d.ts +0 -29
- package/core/k-cli/node_modules/yaml/dist/nodes/toJS.js +0 -39
- package/core/k-cli/node_modules/yaml/dist/options.d.ts +0 -350
- package/core/k-cli/node_modules/yaml/dist/parse/cst-scalar.d.ts +0 -64
- package/core/k-cli/node_modules/yaml/dist/parse/cst-scalar.js +0 -218
- package/core/k-cli/node_modules/yaml/dist/parse/cst-stringify.d.ts +0 -8
- package/core/k-cli/node_modules/yaml/dist/parse/cst-stringify.js +0 -63
- package/core/k-cli/node_modules/yaml/dist/parse/cst-visit.d.ts +0 -39
- package/core/k-cli/node_modules/yaml/dist/parse/cst-visit.js +0 -99
- package/core/k-cli/node_modules/yaml/dist/parse/cst.d.ts +0 -109
- package/core/k-cli/node_modules/yaml/dist/parse/cst.js +0 -112
- package/core/k-cli/node_modules/yaml/dist/parse/lexer.d.ts +0 -87
- package/core/k-cli/node_modules/yaml/dist/parse/lexer.js +0 -719
- package/core/k-cli/node_modules/yaml/dist/parse/line-counter.d.ts +0 -22
- package/core/k-cli/node_modules/yaml/dist/parse/line-counter.js +0 -41
- package/core/k-cli/node_modules/yaml/dist/parse/parser.d.ts +0 -84
- package/core/k-cli/node_modules/yaml/dist/parse/parser.js +0 -972
- package/core/k-cli/node_modules/yaml/dist/public-api.d.ts +0 -44
- package/core/k-cli/node_modules/yaml/dist/public-api.js +0 -107
- package/core/k-cli/node_modules/yaml/dist/schema/Schema.d.ts +0 -17
- package/core/k-cli/node_modules/yaml/dist/schema/Schema.js +0 -39
- package/core/k-cli/node_modules/yaml/dist/schema/common/map.d.ts +0 -2
- package/core/k-cli/node_modules/yaml/dist/schema/common/map.js +0 -19
- package/core/k-cli/node_modules/yaml/dist/schema/common/null.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/schema/common/null.js +0 -17
- package/core/k-cli/node_modules/yaml/dist/schema/common/seq.d.ts +0 -2
- package/core/k-cli/node_modules/yaml/dist/schema/common/seq.js +0 -19
- package/core/k-cli/node_modules/yaml/dist/schema/common/string.d.ts +0 -2
- package/core/k-cli/node_modules/yaml/dist/schema/common/string.js +0 -16
- package/core/k-cli/node_modules/yaml/dist/schema/core/bool.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/schema/core/bool.js +0 -21
- package/core/k-cli/node_modules/yaml/dist/schema/core/float.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/schema/core/float.js +0 -47
- package/core/k-cli/node_modules/yaml/dist/schema/core/int.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/schema/core/int.js +0 -42
- package/core/k-cli/node_modules/yaml/dist/schema/core/schema.d.ts +0 -1
- package/core/k-cli/node_modules/yaml/dist/schema/core/schema.js +0 -25
- package/core/k-cli/node_modules/yaml/dist/schema/json/schema.d.ts +0 -2
- package/core/k-cli/node_modules/yaml/dist/schema/json/schema.js +0 -64
- package/core/k-cli/node_modules/yaml/dist/schema/json-schema.d.ts +0 -69
- package/core/k-cli/node_modules/yaml/dist/schema/tags.d.ts +0 -48
- package/core/k-cli/node_modules/yaml/dist/schema/tags.js +0 -99
- package/core/k-cli/node_modules/yaml/dist/schema/types.d.ts +0 -92
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +0 -2
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/binary.js +0 -70
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +0 -7
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/bool.js +0 -29
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/float.js +0 -50
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +0 -5
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/int.js +0 -76
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +0 -9
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/merge.js +0 -68
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +0 -22
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/omap.js +0 -77
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +0 -10
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +0 -82
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +0 -1
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/schema.js +0 -41
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +0 -28
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/set.js +0 -96
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +0 -6
- package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +0 -105
- package/core/k-cli/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +0 -34
- package/core/k-cli/node_modules/yaml/dist/stringify/foldFlowLines.js +0 -151
- package/core/k-cli/node_modules/yaml/dist/stringify/stringify.d.ts +0 -21
- package/core/k-cli/node_modules/yaml/dist/stringify/stringify.js +0 -132
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +0 -17
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyCollection.js +0 -155
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyComment.d.ts +0 -10
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyComment.js +0 -24
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyDocument.js +0 -87
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +0 -2
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyNumber.js +0 -26
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyPair.d.ts +0 -3
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyPair.js +0 -152
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyString.d.ts +0 -9
- package/core/k-cli/node_modules/yaml/dist/stringify/stringifyString.js +0 -338
- package/core/k-cli/node_modules/yaml/dist/test-events.d.ts +0 -4
- package/core/k-cli/node_modules/yaml/dist/test-events.js +0 -134
- package/core/k-cli/node_modules/yaml/dist/util.d.ts +0 -16
- package/core/k-cli/node_modules/yaml/dist/util.js +0 -28
- package/core/k-cli/node_modules/yaml/dist/visit.d.ts +0 -102
- package/core/k-cli/node_modules/yaml/dist/visit.js +0 -236
- package/core/k-cli/node_modules/yaml/package.json +0 -97
- package/core/k-cli/node_modules/yaml/util.js +0 -2
|
@@ -90,19 +90,6 @@ invariants:
|
|
|
90
90
|
# Parallel execution caps, locks, isolation boundaries
|
|
91
91
|
# ============================================================================
|
|
92
92
|
|
|
93
|
-
- name: max_parallel_dispatches
|
|
94
|
-
category: concurrency
|
|
95
|
-
formula: "concurrent_worktree_dispatches ≤ MAX_PARALLEL"
|
|
96
|
-
bound: "MAX_PARALLEL = 5"
|
|
97
|
-
enforcement: |
|
|
98
|
-
Semaphore in formations.js dispatch loop — when count reaches
|
|
99
|
-
MAX_PARALLEL, new dispatches wait. Logs "Max parallel dispatches
|
|
100
|
-
reached (N/5), waiting...".
|
|
101
|
-
violation_detection: |
|
|
102
|
-
Count live worktree dispatches (.formation/worktrees/task_*/ with
|
|
103
|
-
active child processes); if > 5, semaphore leaked.
|
|
104
|
-
source: ".formation/tools/formations.js#L773-L810 (MAX_PARALLEL semaphore)"
|
|
105
|
-
|
|
106
93
|
- name: worktree_isolation_boundary
|
|
107
94
|
category: concurrency
|
|
108
95
|
formula: |
|
|
@@ -111,17 +98,13 @@ invariants:
|
|
|
111
98
|
repo paths)
|
|
112
99
|
bound: "one worktree per active dispatch; no cross-worktree writes"
|
|
113
100
|
enforcement: |
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
worktreeDir is set. Agent-tool dispatch additionally carries
|
|
118
|
-
SUBAGENT_PREFIX rule 11 (WORKTREE FILE PATH RULE) in prompt.js.
|
|
119
|
-
(TASK_1819: the former do.yaml worktree_path_rule field was a dead
|
|
120
|
-
field — never rendered by prompt.js — and has been removed.)
|
|
101
|
+
Agent-tool dispatch carries SUBAGENT_PREFIX rule 11 (WORKTREE FILE
|
|
102
|
+
PATH RULE) in prompt.js. (The former runner.js spawn-time "[WORKTREE]"
|
|
103
|
+
injection was removed with the headless path, TASK_2401.)
|
|
121
104
|
violation_detection: |
|
|
122
105
|
Agent Edits a path under main repo root while cwd is a worktree →
|
|
123
106
|
`git add -A` in worktree finds no changes. See FAIL-013.
|
|
124
|
-
source: ".formation/tools/
|
|
107
|
+
source: ".formation/tools/prompt.js SUBAGENT_PREFIX rule 11"
|
|
125
108
|
failure_witness: ".failure/agent-execution/FAIL-013-search-cwd-drift-and-case-mismatch.yaml"
|
|
126
109
|
|
|
127
110
|
- name: per_project_dispatch_lock
|
|
@@ -129,13 +112,13 @@ invariants:
|
|
|
129
112
|
formula: "per-project dispatch-lock serializes non-worktree dispatches"
|
|
130
113
|
bound: "1 in-flight serial dispatch per project at a time"
|
|
131
114
|
enforcement: |
|
|
132
|
-
Dispatch-lock fallback in
|
|
133
|
-
|
|
134
|
-
per-project serial lock.
|
|
115
|
+
Dispatch-lock fallback in dispatch.js (tryAcquireDispatchLock) — when a
|
|
116
|
+
worktree is unavailable or the task is unsuitable for one, fall back
|
|
117
|
+
to the per-project serial lock.
|
|
135
118
|
violation_detection: |
|
|
136
119
|
Two concurrent non-worktree dispatches writing the same project
|
|
137
120
|
state (e.g., task-api moves). Lock contention visible in logs.
|
|
138
|
-
source: ".formation/tools/
|
|
121
|
+
source: ".formation/tools/dispatch.js (tryAcquireDispatchLock) + .formation/tools/utils.js (dispatchLockPath)"
|
|
139
122
|
|
|
140
123
|
# ============================================================================
|
|
141
124
|
# CATEGORY: cognitive
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
身份: "Ansuz = 產品全生命週期引擎(PM + Lead 合一)"
|
|
37
37
|
行為規則:
|
|
38
38
|
❌ 不 invoke 其他 Skill — 不切換身份
|
|
39
|
-
✅ 需要執行時 →
|
|
39
|
+
✅ 需要執行時 → Agent tool subagent dispatch(dispatch.js --dispatch-mode=subagent)
|
|
40
40
|
✅ 本體負責:需求理解、任務設計、陣型判斷、調度、追蹤、回報
|
|
41
41
|
❌ 不親自寫程式碼 — 只做決策和調度
|
|
42
42
|
```
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
**工作模式**:
|
|
45
45
|
- **Ansuz = 指揮官 + 調度者**,不是執行者
|
|
46
46
|
- 所有實作交給 Formation 系統的 agent(developer, backend, designer...)
|
|
47
|
-
- 通過 `.formation/tools/
|
|
47
|
+
- 通過 `.formation/tools/dispatch.js` 組裝 prompt,再由 Agent tool subagent 執行任務
|
|
48
48
|
|
|
49
49
|
### 2. 事件驅動生命週期(7 Phases)
|
|
50
50
|
|
|
@@ -146,7 +146,7 @@ fi
|
|
|
146
146
|
|
|
147
147
|
# 子專案範例
|
|
148
148
|
node {CORE}/.collaboration/core/task-api.js --project-path {PROJECT_PATH} list
|
|
149
|
-
node {CORE}/.formation/tools/
|
|
149
|
+
node {CORE}/.formation/tools/dispatch.js --project-path {PROJECT_PATH} --skill=do --task=TASK_XXX --dispatch-mode=subagent
|
|
150
150
|
node {CORE}/.formation/tools/post-complete.js --task=TASK_XXX --project-path={PROJECT_PATH}
|
|
151
151
|
```
|
|
152
152
|
|
|
@@ -154,48 +154,26 @@ node {CORE}/.formation/tools/post-complete.js --task=TASK_XXX --project-path={PR
|
|
|
154
154
|
|
|
155
155
|
### 2. Dispatch 執行機制
|
|
156
156
|
|
|
157
|
-
**工具**: `.formation/tools/
|
|
158
|
-
**方法**: Bash tool → `node
|
|
157
|
+
**工具**: `.formation/tools/dispatch.js`
|
|
158
|
+
**方法**: Bash tool → `node dispatch.js --dispatch-mode=subagent` → 取回 `promptText` + `agentParams` → Agent tool 開 subagent
|
|
159
|
+
(headless CLI 進程、squad/legion 陣型已退役;只剩 unit/solo skill。)
|
|
159
160
|
|
|
160
161
|
**CLI 命令格式**:
|
|
161
162
|
|
|
162
163
|
```bash
|
|
163
164
|
# Unit 陣型
|
|
164
|
-
node .formation/tools/
|
|
165
|
+
node .formation/tools/dispatch.js --skill=do --task=TASK_XXX --dispatch-mode=subagent
|
|
165
166
|
|
|
166
167
|
# Solo 陣型
|
|
167
|
-
node .formation/tools/
|
|
168
|
-
|
|
169
|
-
# Squad 陣型
|
|
170
|
-
node .formation/tools/headless.js --formation=squad --skill=blitz --task=TASK_XXX
|
|
171
|
-
|
|
172
|
-
# Legion 陣型
|
|
173
|
-
node .formation/tools/headless.js --formation=legion --skill=forge --task=TASK_XXX
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
**並行模式**:
|
|
177
|
-
|
|
178
|
-
```javascript
|
|
179
|
-
// 單任務(單一 Bash)
|
|
180
|
-
Bash(run_in_background: true): node headless.js --task=TASK_148
|
|
181
|
-
|
|
182
|
-
// 並行多任務(多個 Bash 同時啟動)
|
|
183
|
-
Bash(run_in_background: true): node headless.js --task=TASK_148
|
|
184
|
-
Bash(run_in_background: true): node headless.js --task=TASK_149
|
|
185
|
-
Bash(run_in_background: true): node headless.js --task=TASK_150
|
|
186
|
-
|
|
187
|
-
// 有依賴(順序執行)
|
|
188
|
-
Bash: node headless.js --task=TASK_147
|
|
189
|
-
// 等待完成後
|
|
190
|
-
Bash: node headless.js --task=TASK_148
|
|
168
|
+
node .formation/tools/dispatch.js --formation=solo --skill=strategy --task=TASK_XXX --dispatch-mode=subagent
|
|
191
169
|
```
|
|
192
170
|
|
|
193
171
|
**關鍵規則**:
|
|
194
172
|
- ✅ 所有調度必須經過 `.collaboration` 任務系統
|
|
195
|
-
- ✅ 流程:create →
|
|
196
|
-
- ✅
|
|
173
|
+
- ✅ 流程:create → dispatch.js(subagent) → Agent tool → complete
|
|
174
|
+
- ✅ 有依賴 → 前一個完成再 dispatch 下一個;同一 project 序列化
|
|
197
175
|
- ❌ 不跳過任務系統直接 dispatch
|
|
198
|
-
- ❌
|
|
176
|
+
- ❌ 不手寫 subagent prompt — 用 dispatch.js 組裝(prompt 組裝、principles 注入)
|
|
199
177
|
|
|
200
178
|
### 3. Scope 安全保證
|
|
201
179
|
|
|
@@ -254,7 +232,7 @@ rigor: "medium" # low | medium | high
|
|
|
254
232
|
dependencies: ["TASK_147"] # 真依賴(B 的輸入 = A 的輸出)
|
|
255
233
|
scope_paths: # 修改的檔案/目錄(用於衝突檢測)
|
|
256
234
|
- "CLAUDE.md"
|
|
257
|
-
- ".formation/tools/
|
|
235
|
+
- ".formation/tools/dispatch.js"
|
|
258
236
|
requirements:
|
|
259
237
|
- "新增 Lead Agent 開發流程章節"
|
|
260
238
|
- "引用 .rule/pipeline/task-execution.yaml"
|
|
@@ -402,9 +380,8 @@ Step 2: 展示 Banner
|
|
|
402
380
|
└── Ansuz.md # 斜線指令觸發點
|
|
403
381
|
|
|
404
382
|
.formation/tools/
|
|
405
|
-
├──
|
|
383
|
+
├── dispatch.js # Formation 調度核心(subagent)
|
|
406
384
|
├── prompt.js # Prompt 組裝 + principles 注入
|
|
407
|
-
├── runner.js # 執行引擎
|
|
408
385
|
├── post-complete.js # 任務完成後自動化
|
|
409
386
|
└── logger.js # 日誌系統
|
|
410
387
|
|
|
@@ -439,11 +416,9 @@ Phase 3: 建立任務
|
|
|
439
416
|
- node task-api.js create ... (x3 任務)
|
|
440
417
|
|
|
441
418
|
Phase 4: 陣型判斷 + Dispatch
|
|
442
|
-
- 判斷:3
|
|
419
|
+
- 判斷:3 個任務 → 各自 unit/do,序列化 dispatch
|
|
443
420
|
- Dispatch:
|
|
444
|
-
|
|
445
|
-
Bash(bg): node headless.js --formation=squad --skill=blitz --task=TASK_152
|
|
446
|
-
Bash(bg): node headless.js --formation=squad --skill=blitz --task=TASK_153
|
|
421
|
+
node dispatch.js --skill=do --task=TASK_151 --dispatch-mode=subagent(完成後再下一個)
|
|
447
422
|
|
|
448
423
|
Phase 5: 結果處理
|
|
449
424
|
- 驗證:檔案變更 + Git commit + 驗收標準
|
|
@@ -531,7 +506,7 @@ Phase 7: 回報
|
|
|
531
506
|
```yaml
|
|
532
507
|
無衝突(可並行):
|
|
533
508
|
TASK_A: scope_paths: ["CLAUDE.md"]
|
|
534
|
-
TASK_B: scope_paths: [".formation/tools/
|
|
509
|
+
TASK_B: scope_paths: [".formation/tools/dispatch.js"]
|
|
535
510
|
|
|
536
511
|
有衝突(必須順序執行):
|
|
537
512
|
TASK_A: scope_paths: [".rule/pipeline/"]
|
|
@@ -601,7 +576,7 @@ Phase 7: 回報
|
|
|
601
576
|
| 能力定義 | `.specialist/Ansuz/capability.yaml` | 需求分析、任務設計、陣型判斷等能力 |
|
|
602
577
|
| 執行模式 | `.specialist/Ansuz/workflow.yaml` | 事件驅動 7 phases 工作流程 |
|
|
603
578
|
| 共享詞彙 | `.specialist/Ansuz/knowledge.yaml` | Formation、任務系統、Agent 類型 |
|
|
604
|
-
| Formation 系統 | `.formation/tools/` |
|
|
579
|
+
| Formation 系統 | `.formation/tools/` | dispatch.js, prompt.js, post-complete.js... |
|
|
605
580
|
| 任務系統 | `.collaboration/core/task-api.js` | 任務 API |
|
|
606
581
|
| CLAUDE.md | `CLAUDE.md` | 專案級指令與工作流程 |
|
|
607
582
|
|
|
@@ -91,24 +91,17 @@ capabilities:
|
|
|
91
91
|
# ─── 調度執行 ───
|
|
92
92
|
# §dispatch
|
|
93
93
|
dispatch:
|
|
94
|
-
description: "使用 Formation
|
|
95
|
-
tool: ".formation/tools/
|
|
96
|
-
method: "Bash tool → node
|
|
94
|
+
description: "使用 Formation prompt 組裝 + Agent tool subagent 執行任務(headless CLI 進程已退役)"
|
|
95
|
+
tool: ".formation/tools/dispatch.js"
|
|
96
|
+
method: "Bash tool → node dispatch.js --dispatch-mode=subagent → 取回 assembled prompt → Agent tool 開 subagent"
|
|
97
97
|
rules:
|
|
98
98
|
- "✅ 所有調度必須經過 .collaboration 任務系統"
|
|
99
|
-
- "✅ create →
|
|
100
|
-
- "
|
|
101
|
-
- "⚠️
|
|
102
|
-
- "⚠️ 原因:多個 agent 共用同一 git working directory,並行會 git 衝突 + agent stall"
|
|
103
|
-
- "⚠️ 有依賴鏈時:按依賴順序逐一 dispatch,等 TaskOutput/poll 確認前一個完成"
|
|
99
|
+
- "✅ create → dispatch.js(subagent) → Agent tool → complete"
|
|
100
|
+
- "⚠️ 同一 project 的 dispatch 必須序列化 — 多個 agent 共用同一 git working directory,並行會衝突"
|
|
101
|
+
- "⚠️ 有依賴鏈時:按依賴順序逐一 dispatch,確認前一個完成"
|
|
104
102
|
- "❌ 不跳過任務系統直接 dispatch"
|
|
105
|
-
- "❌ 不用 Task tool 開 subagent 繞過 Formation — Formation 有 prompt 組裝、log、principles 注入"
|
|
106
|
-
- "❌ 禁止同時 dispatch 多個 task 到同一 project(即使它們沒有依賴關係)"
|
|
107
103
|
commands:
|
|
108
|
-
unit: "node .formation/tools/
|
|
109
|
-
solo: "node .formation/tools/headless.js --formation=solo --skill=strategy --task=TASK_XXX"
|
|
110
|
-
squad: "node .formation/tools/headless.js --formation=squad --skill=blitz --task=TASK_XXX"
|
|
111
|
-
legion: "node .formation/tools/headless.js --formation=legion --skill=forge --task=TASK_XXX"
|
|
104
|
+
unit: "node .formation/tools/dispatch.js --skill=do --task=TASK_XXX --dispatch-mode=subagent"
|
|
112
105
|
|
|
113
106
|
# ─── 結果追蹤 ───
|
|
114
107
|
# §result_tracking
|
|
@@ -9,20 +9,13 @@ size_kb: 0.98
|
|
|
9
9
|
evolution_status: reference
|
|
10
10
|
---
|
|
11
11
|
formation_quick_ref:
|
|
12
|
-
principle: "
|
|
12
|
+
principle: "Only unit/solo skills are dispatchable (squad/legion retired); dispatch = Agent-tool subagent"
|
|
13
13
|
unit:
|
|
14
14
|
when: "Clear goal, single scope, direct execution"
|
|
15
|
-
command: "node .formation/tools/
|
|
15
|
+
command: "node .formation/tools/dispatch.js --skill=do --task=TASK_XXX --dispatch-mode=subagent"
|
|
16
16
|
solo:
|
|
17
17
|
when: "Multi-perspective analysis needed"
|
|
18
|
-
command: "node .formation/tools/
|
|
19
|
-
squad:
|
|
20
|
-
when: "Independent parallel subtasks possible"
|
|
21
|
-
command: "node .formation/tools/headless.js --formation=squad --skill=blitz --task=TASK_XXX"
|
|
22
|
-
legion:
|
|
23
|
-
when: "Sequential dependencies or real-time coordination required"
|
|
24
|
-
command: "node .formation/tools/headless.js --formation=legion --skill=forge --task=TASK_XXX"
|
|
18
|
+
command: "node .formation/tools/dispatch.js --formation=solo --skill=strategy --task=TASK_XXX --dispatch-mode=subagent"
|
|
25
19
|
dispatch_rules:
|
|
26
|
-
- "✅ Always background=true for parallel dispatch (Bash run_in_background=true)"
|
|
27
20
|
- "⚠️ Same project: serialize dispatches — wait for each to complete (git conflicts)"
|
|
28
|
-
- "✅ create →
|
|
21
|
+
- "✅ create → dispatch.js(subagent) → Agent tool → complete lifecycle"
|
|
@@ -54,13 +54,12 @@ mandates:
|
|
|
54
54
|
- "Project pinning: when boot banner shows a `[pin:...]` line or session was started with --project-path, EVERY MCP call to synapse_*/hippocampus_*/cortex_* that accepts a projectPath param MUST pass projectPath=<pin>; every specialist tool CLI call (task-api, phase-gate, dispatch) MUST pass --project-path <pin>. Missing projectPath leaks memory into the wrong project graph."
|
|
55
55
|
- "Verification policy (PARTIAL/UNVERIFIED/FIX-keeps-original/verified_uncommitted vs committed_unmerged vs merged): .specialist/Ansuz/VERIFY.md, loaded on demand at Phase 9."
|
|
56
56
|
- "Landing mechanics for a verified card (branch check -> Rust/node suites -> optional negative control -> merge -> task-api complete -> mark-landed -> optional backend-restart wait): run .specialist/Ansuz/tools/verify-and-land.js instead of doing the same 10-20 tool calls by hand; it only executes, judgement (what to verify, scope) stays with you."
|
|
57
|
-
- "WISHING WELL (every incarnation, TASK_1997/TASK_2040): file a wish with kenaz_wish_create — BEFORE working around the problem — whenever the Kenaz app itself blocks or degrades the work: a Kenaz tool/route fails or returns wrong data, a capability you needed is missing, a UX confusion cost you a turn, or a task ends failed/blocked because of the app. wish_type=bug|feature|question, one-line repro + what you expected, task_id when there is one. SCOPE (required on every wish): scope 'kenaz' — the Kenaz app/tools/dispatch itself blocked or degraded the work; scope 'project' — an idea or problem specific to the project being worked on (still sent; the mother may adopt it globally when it benefits Kenaz overall). FEATURE PROPOSALS: when the work reveals a capability Kenaz itself lacks that would help beyond this one task (not only blockers), you may file kenaz_wish_create with wish_type=feature, scope=kenaz. Content, in this order, within ~3000 chars: need (what you were trying to do), why current Kenaz falls short (evidence), proposed shape, who else benefits. Propose only - do not build Kenaz-core changes from a branch instance; the mother decides whether and how. MOTHER-SIDE TRIAGE: on the mother machine, field-report cards tagged needs-triage (blockers, project-scope wishes, and feature proposals alike) are judged at boot — adopt (rewrite as a global card stating the Kenaz-wide benefit, cancel the original with a pointer) or decline (cancel with a one-line reason); a feature proposal may be reshaped rather than built as proposed; never implement a project-specific ask verbatim in core. EXAMPLES — blocker: scope=kenaz, wish_type=bug, '
|
|
57
|
+
- "WISHING WELL (every incarnation, TASK_1997/TASK_2040): file a wish with kenaz_wish_create — BEFORE working around the problem — whenever the Kenaz app itself blocks or degrades the work: a Kenaz tool/route fails or returns wrong data, a capability you needed is missing, a UX confusion cost you a turn, or a task ends failed/blocked because of the app. wish_type=bug|feature|question, one-line repro + what you expected, task_id when there is one. SCOPE (required on every wish): scope 'kenaz' — the Kenaz app/tools/dispatch itself blocked or degraded the work; scope 'project' — an idea or problem specific to the project being worked on (still sent; the mother may adopt it globally when it benefits Kenaz overall). FEATURE PROPOSALS: when the work reveals a capability Kenaz itself lacks that would help beyond this one task (not only blockers), you may file kenaz_wish_create with wish_type=feature, scope=kenaz. Content, in this order, within ~3000 chars: need (what you were trying to do), why current Kenaz falls short (evidence), proposed shape, who else benefits. Propose only - do not build Kenaz-core changes from a branch instance; the mother decides whether and how. MOTHER-SIDE TRIAGE: on the mother machine, field-report cards tagged needs-triage (blockers, project-scope wishes, and feature proposals alike) are judged at boot — adopt (rewrite as a global card stating the Kenaz-wide benefit, cancel the original with a pointer) or decline (cancel with a one-line reason); a feature proposal may be reshaped rather than built as proposed; never implement a project-specific ask verbatim in core. EXAMPLES — blocker: scope=kenaz, wish_type=bug, 'dispatch.js timed out on a cross-project worktree with no partial log, TASK_2011'. feature proposal: scope=kenaz, wish_type=feature, 'need: retry one failed sub-task without rerunning the whole formation; current Kenaz only retries the full formation; shape: dispatch.js --retry-task <id>; benefits every multi-task formation'. project-specific: scope=project, wish_type=feature, 'this project needs a CSV importer for onboarding — project-specific, flagging in case it generalizes'. At session close, anything unfinished BECAUSE of the app also becomes a wish. This is the channel that feeds the mother from every branch (TASK_1994); a session that hit an app problem and filed no wish has skipped a mandate, not saved time. Boot banner shows the open-wish count (and needs-triage count when >0) so you can see the channel is live."
|
|
58
58
|
dispatch_routing:
|
|
59
59
|
paths:
|
|
60
60
|
subagent: "Agent tool within interactive session — stays on subscription billing, results return directly, no log polling. Use: short/medium tasks (rigor:low/medium, same-project or trivial scope)."
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
mandate: "ALWAYS evaluate both paths before dispatching. Check .kenaz/dashboard-models.json dispatchMode for the user override (set from the Dashboard Model Selection panel > Dispatch Routing, persisted by dashboard_settings.rs since TASK_1814): 'formation' or 'subagent' = hard override, route ALL dispatches through that path; 'auto' = no forced route, apply the heuristic (subagent when within interactive session unless task requires cross-project cwd or is rigor:high, else formation); key missing = dispatch.js falls back to 'formation' (TASK_1813 contract) — treat missing the same as no override and apply the heuristic at the Ansuz level."
|
|
61
|
+
how: "Run `node .formation/tools/dispatch.js --skill=do --task=TASK_XXX --dispatch-mode=subagent` (include the project pin when present). Read the assembled prompt from top-level promptText and pass it as the Agent tool prompt alongside agentParams. Top-level isolation is orchestration metadata, NOT an Agent tool argument: cross-project worktreePath specifies the target cwd; serialLock specifies required serialization and release. agentParams.isolation is present only for the native same-project worktree route. agentParams.model is ALREADY translated to the Agent tool enum (sonnet|opus|haiku|fable, TASK_1815) — pass it verbatim to a compatible Agent tool, do NOT re-translate or improvise. LIMIT: the Agent tool expresses family names ONLY, so dashboard version/speed picks (claude-opus-5[1m] vs claude-opus-4-8[1m], [1m] modifiers) all degrade to the family name; the payload's modelTranslation {requested, agentToolModel, granularityLoss} shows exactly what was lost. Unmappable dispatchModel values make dispatch.js exit 1 loudly; never substitute a model silently."
|
|
62
|
+
mandate: "Subagent is the only dispatch path (Formation headless/kenaz_dispatch retired, TASK_2359/2401/2402). dispatchMode in .kenaz/dashboard-models.json no longer selects a route."
|
|
64
63
|
exo_cortex:
|
|
65
64
|
opening_move: synapse_recall + kenaz_lsp_callers
|
|
66
65
|
anti_pattern: "Bash grep/rg/find for source archaeology — prefer Grep/Glob (and kenaz_lsp_symbols for symbols); the hook nudge is downstream of you knowing the tool exists"
|
|
@@ -339,7 +339,7 @@ cross_model:
|
|
|
339
339
|
- "ME-001 governance (immutable rules cannot be deleted) must hold"
|
|
340
340
|
- "AskUserQuestion tool must be available and used for all user-response questions"
|
|
341
341
|
- "Phase sequence 0-11 must be respected; phase-gate.js must be callable"
|
|
342
|
-
- "
|
|
342
|
+
- "Subagent dispatch must work (.formation/tools/dispatch.js --dispatch-mode=subagent must be callable)"
|
|
343
343
|
- "Task-api.js must be callable for task lifecycle management"
|
|
344
344
|
|
|
345
345
|
acceptable_substrate_drift:
|
|
@@ -34,9 +34,8 @@ formation:
|
|
|
34
34
|
- "Squad ≠ 開會。Squad = 多個獨立 subagent 並行,零溝通"
|
|
35
35
|
- "Legion ≠ 大號 Squad。Legion = 持久化團隊,成員間即時通訊"
|
|
36
36
|
key_files:
|
|
37
|
-
|
|
37
|
+
dispatch: ".formation/tools/dispatch.js"
|
|
38
38
|
prompt: ".formation/tools/prompt.js"
|
|
39
|
-
runner: ".formation/tools/runner.js"
|
|
40
39
|
logs: ".formation/logs/{formation}/"
|
|
41
40
|
post_complete: ".formation/tools/post-complete.js"
|
|
42
41
|
research_notes:
|
|
@@ -49,12 +48,10 @@ formation:
|
|
|
49
48
|
- "Better mapping: represent agent-role reliability and coordination cost as factorised hidden states, then evaluate a whole formation against task context."
|
|
50
49
|
- "Keep a collective dispatch objective separate from per-agent or per-symbol EFE because ensemble-level EFE is not guaranteed to be aggregate-optimal."
|
|
51
50
|
dispatch_mechanism:
|
|
52
|
-
how: "Bash tool → node
|
|
53
|
-
why: "
|
|
54
|
-
anti_pattern: "❌
|
|
55
|
-
|
|
56
|
-
max_parallel: 5 # 同時最多 5 個 headless 進程,超過排隊等空位
|
|
57
|
-
monitoring: "讀 .formation/logs/{formation}/ 下的 log 確認結果"
|
|
51
|
+
how: "Bash tool → node dispatch.js --dispatch-mode=subagent → Agent tool subagent"
|
|
52
|
+
why: "dispatch.js 統一處理 prompt 組裝(prompt.js)、principles 注入"
|
|
53
|
+
anti_pattern: "❌ 不手寫 subagent prompt — 用 dispatch.js 組裝"
|
|
54
|
+
monitoring: "Agent tool 結果直接返回"
|
|
58
55
|
|
|
59
56
|
# ═══════════════════════════════════════
|
|
60
57
|
# 任務系統
|
|
@@ -89,10 +86,10 @@ task_system:
|
|
|
89
86
|
project_yaml: ".kenaz/project.yaml"
|
|
90
87
|
rule: |
|
|
91
88
|
子專案的任務存在 .kenaz/tasks/,不是 .collaboration/tasks/。
|
|
92
|
-
所有 task-api.js、
|
|
89
|
+
所有 task-api.js、dispatch.js、post-complete.js 呼叫都必須加 --project-path。
|
|
93
90
|
cli_pattern:
|
|
94
91
|
task_api: "node {CORE}/.collaboration/core/task-api.js --project-path {PROJECT_PATH} <command>"
|
|
95
|
-
|
|
92
|
+
dispatch: "node {CORE}/.formation/tools/dispatch.js --project-path {PROJECT_PATH} --skill=do --task=TASK_XXX --dispatch-mode=subagent"
|
|
96
93
|
post_complete: "node {CORE}/.formation/tools/post-complete.js --task=TASK_XXX --project-path={PROJECT_PATH}"
|
|
97
94
|
|
|
98
95
|
# ═══════════════════════════════════════
|
|
@@ -35,7 +35,7 @@ allow:
|
|
|
35
35
|
- "讀取專案內所有原始碼"
|
|
36
36
|
- "讀寫 specialist/Ansuz/ 下所有檔案"
|
|
37
37
|
- "使用 .collaboration/core/task-api.js 管理任務"
|
|
38
|
-
- "使用 .formation/tools/
|
|
38
|
+
- "使用 .formation/tools/dispatch.js --dispatch-mode=subagent 調度執行"
|
|
39
39
|
- "使用 .formation/tools/post-complete.js 完成後自動化"
|
|
40
40
|
- "執行 git 操作(建立分支、commit、merge 到用戶分支)"
|
|
41
41
|
|
|
@@ -51,7 +51,7 @@ identity:
|
|
|
51
51
|
symbol: "ᚨ — 神諭符文:理解意圖,傳遞給執行層"
|
|
52
52
|
rules:
|
|
53
53
|
- "❌ 不 invoke 其他 Skill — 不切換身份"
|
|
54
|
-
- "✅ 需要執行時 → 用
|
|
54
|
+
- "✅ 需要執行時 → 用 Agent tool subagent dispatch(dispatch.js --dispatch-mode=subagent)"
|
|
55
55
|
- "✅ Ansuz 本體負責:需求理解、任務設計、陣型判斷、調度、追蹤、回報"
|
|
56
56
|
- "❌ 不親自寫程式碼 — 只做決策和調度"
|
|
57
57
|
- "✅ Task-First — 預設先建立任務卡再 dispatch,除非是極簡單的單檔修改(< 20 行)"
|
|
@@ -147,6 +147,8 @@ function buildPlan(config) {
|
|
|
147
147
|
plan.push({ name: 'negative-control', kind: 'neg' });
|
|
148
148
|
}
|
|
149
149
|
if (!config.noMerge) {
|
|
150
|
+
// TASK_2400: ARCH-001 file-size gate, cheap and deterministic, so before the heavy checks.
|
|
151
|
+
plan.push({ name: 'file-size', kind: 'file-size' });
|
|
150
152
|
// TASK_2176: the authoritative, serialized heavyweight check runs right
|
|
151
153
|
// before merge, on the main tree (config.repo) -- gates the merge that
|
|
152
154
|
// follows it, same as the worktree-side negative control gates it above.
|
|
@@ -759,6 +761,24 @@ function coreToolPath(config, rel) {
|
|
|
759
761
|
return path.join(__dirname, '..', '..', '..', rel);
|
|
760
762
|
}
|
|
761
763
|
|
|
764
|
+
/**
|
|
765
|
+
* TASK_2400: ARCH-001 gate. Runs the core's check-file-size.js on branch vs merge-base
|
|
766
|
+
* (--repo = the project, so a user project uses its own .rule yaml or the built-in
|
|
767
|
+
* defaults). BLOCK -> step fails, merge never runs; WARN lines go into the step summary.
|
|
768
|
+
*/
|
|
769
|
+
function stepFileSize(config, deps, ctx) {
|
|
770
|
+
const script = coreToolPath(config, path.join('dev', 'scripts', 'check-file-size.js'));
|
|
771
|
+
if (!fs.existsSync(script)) return { ok: true, summary: 'check-file-size.js not found in core, skipped', log: '' };
|
|
772
|
+
const base = git(deps, config.repo, ['merge-base', 'HEAD', ctx.branch]);
|
|
773
|
+
const res = deps.spawnSync('node', [script, '--base', base, '--head', ctx.branch, '--repo', config.repo], { encoding: 'utf8' });
|
|
774
|
+
const output = (res.stdout || '') + (res.stderr || '');
|
|
775
|
+
const found = output.split('\n').filter((l) => /ARCH-001 (BLOCK|WARN)/.test(l)).map((l) => l.trim());
|
|
776
|
+
if (res.status === 0) {
|
|
777
|
+
return { ok: true, summary: found.length ? `${found.length} warning(s): ${found.join(' | ')}`.slice(0, 600) : 'within thresholds', log: output };
|
|
778
|
+
}
|
|
779
|
+
return { ok: false, summary: `ARCH-001 blocked (exit ${res.status}): ${found.join(' | ') || output.trim()}`.slice(0, 800), log: output };
|
|
780
|
+
}
|
|
781
|
+
|
|
762
782
|
function writeLandingInfo(config, deps, ctx) {
|
|
763
783
|
if (!ctx || !ctx.postMergeHead) return; // no merge landed (--no-merge etc.) -- nothing to record
|
|
764
784
|
const shortSha = ctx.postMergeHead.slice(0, 8);
|
|
@@ -845,6 +865,7 @@ async function executeStep(stepDef, config, deps, ctx) {
|
|
|
845
865
|
case 'rust': return stepRust(config, deps, ctx, stepDef.filter);
|
|
846
866
|
case 'node': return stepNode(config, deps, ctx, stepDef.file);
|
|
847
867
|
case 'neg': return stepNegativeControl(config, deps, ctx);
|
|
868
|
+
case 'file-size': return stepFileSize(config, deps, ctx);
|
|
848
869
|
case 'verify-offline': return stepVerifyOffline(config, deps);
|
|
849
870
|
case 'merge': return stepMerge(config, deps, ctx);
|
|
850
871
|
case 'task-complete': return stepTaskComplete(config, deps, ctx);
|
|
@@ -1000,6 +1021,7 @@ module.exports = {
|
|
|
1000
1021
|
latestStartedAtAfter,
|
|
1001
1022
|
resolveRepoFromWorktree,
|
|
1002
1023
|
coreToolPath,
|
|
1024
|
+
stepFileSize,
|
|
1003
1025
|
assertRepoOwnsWorktree,
|
|
1004
1026
|
resolveRepo,
|
|
1005
1027
|
UsageError,
|
|
@@ -33,6 +33,7 @@ const {
|
|
|
33
33
|
DEFAULT_RUST_MAX_S,
|
|
34
34
|
resolveVerifyOfflineCmd,
|
|
35
35
|
stepVerifyOffline,
|
|
36
|
+
stepFileSize,
|
|
36
37
|
} = require('./verify-and-land.js');
|
|
37
38
|
|
|
38
39
|
// Same shared list verify-and-land.js reads (TASK_2069) — tests assert
|
|
@@ -273,6 +274,7 @@ test('buildPlan: fixed step order for a full config (default warm route — no c
|
|
|
273
274
|
'rust:foo',
|
|
274
275
|
'node:t.js',
|
|
275
276
|
'negative-control',
|
|
277
|
+
'file-size',
|
|
276
278
|
'merge',
|
|
277
279
|
'task-complete',
|
|
278
280
|
'mark-landed',
|
|
@@ -362,6 +364,8 @@ test('success path: runs steps in order (rust via the warm rust-verify-worktree.
|
|
|
362
364
|
return ok('test result: ok. 5 passed; 0 failed\n');
|
|
363
365
|
}
|
|
364
366
|
if (cmd === 'node' && args[0] === '--test') return ok('ℹ pass 2\nℹ fail 0\n');
|
|
367
|
+
if (cmd === 'git' && args[2] === 'merge-base' && args[3] === 'HEAD') return ok('basesha\n');
|
|
368
|
+
if (cmd === 'node' && args[0].includes('check-file-size.js')) return ok('');
|
|
365
369
|
if (cmd === 'git' && args[2] === 'merge' && args.includes('--no-ff')) {
|
|
366
370
|
mergeCount++;
|
|
367
371
|
return ok('Merge made by the recursive strategy.\n');
|
|
@@ -386,7 +390,7 @@ test('success path: runs steps in order (rust via the warm rust-verify-worktree.
|
|
|
386
390
|
// copies its own resources into the fixed verify worktree.
|
|
387
391
|
assert.deepEqual(
|
|
388
392
|
result.steps.map(s => s.name),
|
|
389
|
-
['preflight', 'rust:foo', 'node:test/a.test.js', 'merge', 'task-complete', 'mark-landed']
|
|
393
|
+
['preflight', 'rust:foo', 'node:test/a.test.js', 'file-size', 'merge', 'task-complete', 'mark-landed']
|
|
390
394
|
);
|
|
391
395
|
assert.ok(result.steps.every(s => s.ok === true));
|
|
392
396
|
assert.equal(mergeCount, 1, 'merge must run exactly once');
|
|
@@ -416,6 +420,8 @@ test('TASK_2142 R2: task-complete bakes landed commit sha + verification summary
|
|
|
416
420
|
if (cmd === 'git' && args[2] === 'status') return ok('');
|
|
417
421
|
if (cmd === 'git' && args[2] === 'rev-list') return ok('1\n');
|
|
418
422
|
if (cmd === 'node' && args[0].includes('rust-verify-worktree.js') && args[1] === 'run') return ok('test result: ok. 3 passed; 0 failed\n');
|
|
423
|
+
if (cmd === 'git' && args[2] === 'merge-base' && args[3] === 'HEAD') return ok('basesha\n');
|
|
424
|
+
if (cmd === 'node' && args[0].includes('check-file-size.js')) return ok('');
|
|
419
425
|
if (cmd === 'git' && args[2] === 'merge' && args.includes('--no-ff')) return ok('Merge made by the recursive strategy.\n');
|
|
420
426
|
if (cmd === 'git' && args[2] === 'rev-parse' && args[3] === 'HEAD') {
|
|
421
427
|
headCount++;
|
|
@@ -772,7 +778,7 @@ test('dry-run: resolves/validates --repo via read-only git (same guard as a real
|
|
|
772
778
|
assert.equal(result.repo, config.repo, 'dry-run output includes the resolved repo path');
|
|
773
779
|
assert.deepEqual(
|
|
774
780
|
result.steps.map(s => s.name),
|
|
775
|
-
['preflight', 'rust:foo', 'node:t.js', 'negative-control', 'merge', 'task-complete', 'mark-landed', 'wait-backend', 'live']
|
|
781
|
+
['preflight', 'rust:foo', 'node:t.js', 'negative-control', 'file-size', 'merge', 'task-complete', 'mark-landed', 'wait-backend', 'live']
|
|
776
782
|
);
|
|
777
783
|
assert.ok(result.steps.every(s => s.planned === true));
|
|
778
784
|
});
|
|
@@ -923,6 +929,8 @@ test('merge verification: "Already up to date" (unchanged HEAD) fails the merge
|
|
|
923
929
|
if (cmd === 'git' && args[2] === 'status') return ok('');
|
|
924
930
|
if (cmd === 'git' && args[2] === 'rev-list') return ok('1\n');
|
|
925
931
|
if (cmd === 'node' && args[0].includes('rust-verify-worktree.js') && args[1] === 'run') return ok('test result: ok. 1 passed; 0 failed\n');
|
|
932
|
+
if (cmd === 'git' && args[2] === 'merge-base' && args[3] === 'HEAD') return ok('basesha\n');
|
|
933
|
+
if (cmd === 'node' && args[0].includes('check-file-size.js')) return ok('');
|
|
926
934
|
if (cmd === 'git' && args[2] === 'merge' && args.includes('--no-ff')) return ok('Already up to date.\n');
|
|
927
935
|
// HEAD is the SAME before and after — this is the exact bug that shipped.
|
|
928
936
|
if (cmd === 'git' && args[2] === 'rev-parse' && args[3] === 'HEAD') return ok('deadbeef\n');
|
|
@@ -934,7 +942,7 @@ test('merge verification: "Already up to date" (unchanged HEAD) fails the merge
|
|
|
934
942
|
const result = await runVerifyAndLand(config, deps);
|
|
935
943
|
assert.equal(result.ok, false);
|
|
936
944
|
assert.equal(result.failed_step, 'merge');
|
|
937
|
-
assert.deepEqual(result.steps.map(s => s.name), ['preflight', 'rust:foo', 'merge']);
|
|
945
|
+
assert.deepEqual(result.steps.map(s => s.name), ['preflight', 'rust:foo', 'file-size', 'merge']);
|
|
938
946
|
assert.match(result.steps[result.steps.length - 1].summary, /unchanged|did not land/);
|
|
939
947
|
assert.equal(taskCompleteCalled, false, 'task-api complete must never run after a merge that did not actually land');
|
|
940
948
|
});
|
|
@@ -958,7 +966,7 @@ test('resolveVerifyOfflineCmd: project.yaml without the key -> null', () => {
|
|
|
958
966
|
|
|
959
967
|
test('buildPlan: verify-offline step is included only when verifyOfflineCmd is set, placed right before merge', () => {
|
|
960
968
|
const withCmd = buildPlan(baseConfig({ verifyOfflineCmd: 'node fake-unity.js' }));
|
|
961
|
-
assert.deepEqual(withCmd.map(s => s.name), ['preflight', 'verify-offline', 'merge', 'task-complete', 'mark-landed']);
|
|
969
|
+
assert.deepEqual(withCmd.map(s => s.name), ['preflight', 'file-size', 'verify-offline', 'merge', 'task-complete', 'mark-landed']);
|
|
962
970
|
const withoutCmd = buildPlan(baseConfig({ verifyOfflineCmd: null }));
|
|
963
971
|
assert.ok(!withoutCmd.some(s => s.kind === 'verify-offline'), 'no key in project.yaml -> no step, unaffected');
|
|
964
972
|
});
|
|
@@ -1028,6 +1036,8 @@ test('runVerifyAndLand: verify_offline failure blocks landing (full pipeline, re
|
|
|
1028
1036
|
if (cmd === 'git' && args[2] === 'status') return ok('');
|
|
1029
1037
|
if (cmd === 'git' && args[2] === 'rev-list') return ok('1\n');
|
|
1030
1038
|
if (cmd === 'node fake-unity.js --break') return bad(1, '', 'compile error'); // shell:true -- cmd is the whole command string, args is []
|
|
1039
|
+
if (cmd === 'git' && args[2] === 'merge-base' && args[3] === 'HEAD') return ok('basesha\n');
|
|
1040
|
+
if (cmd === 'node' && args[0].includes('check-file-size.js')) return ok('');
|
|
1031
1041
|
if (cmd === 'git' && args[2] === 'merge') { mergeCalled = true; return ok('merged\n'); }
|
|
1032
1042
|
throw new Error('unexpected spawnSync in verify_offline-blocks-landing test: ' + JSON.stringify({ cmd, args }));
|
|
1033
1043
|
},
|
|
@@ -1035,7 +1045,7 @@ test('runVerifyAndLand: verify_offline failure blocks landing (full pipeline, re
|
|
|
1035
1045
|
const result = await runVerifyAndLand(config, deps);
|
|
1036
1046
|
assert.equal(result.ok, false);
|
|
1037
1047
|
assert.equal(result.failed_step, 'verify-offline');
|
|
1038
|
-
assert.deepEqual(result.steps.map(s => s.name), ['preflight', 'verify-offline']);
|
|
1048
|
+
assert.deepEqual(result.steps.map(s => s.name), ['preflight', 'file-size', 'verify-offline']);
|
|
1039
1049
|
assert.equal(mergeCalled, false, 'verify_offline failure must block the merge that follows it');
|
|
1040
1050
|
});
|
|
1041
1051
|
|
|
@@ -1097,3 +1107,47 @@ test('coreToolPath: a sub-project repo (only .kenaz/) resolves core tools via pr
|
|
|
1097
1107
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
1098
1108
|
}
|
|
1099
1109
|
});
|
|
1110
|
+
|
|
1111
|
+
// ── TASK_2400: ARCH-001 file-size gate (real temp repo, real check-file-size.js) ──
|
|
1112
|
+
|
|
1113
|
+
function makeSizeFixture(extraFiles) {
|
|
1114
|
+
const fsr = require('node:fs');
|
|
1115
|
+
const os = require('node:os');
|
|
1116
|
+
const repo = fsr.mkdtempSync(path.join(os.tmpdir(), 'size-gate-'));
|
|
1117
|
+
const run = (...a) => { const r = realSpawnSync('git', ['-C', repo, ...a], { encoding: 'utf8' }); assert.equal(r.status, 0, r.stderr); return r.stdout; };
|
|
1118
|
+
const body = n => Array.from({ length: n }, (_, i) => `const v${i} = ${i};`).join('\n') + '\n';
|
|
1119
|
+
run('init', '-q', '-b', 'main');
|
|
1120
|
+
run('config', 'user.email', 't@t'); run('config', 'user.name', 't');
|
|
1121
|
+
fsr.writeFileSync(path.join(repo, 'big.js'), body(2100)); // over the 2000 hard limit: grandfathered debt
|
|
1122
|
+
run('add', '-A'); run('commit', '-q', '-m', 'base');
|
|
1123
|
+
run('checkout', '-q', '-b', 'task');
|
|
1124
|
+
fsr.writeFileSync(path.join(repo, 'big.js'), body(2200)); // +100 lines
|
|
1125
|
+
for (const [name, n] of Object.entries(extraFiles || {})) fsr.writeFileSync(path.join(repo, name), body(n));
|
|
1126
|
+
run('add', '-A'); run('commit', '-q', '-m', 'grow');
|
|
1127
|
+
run('checkout', '-q', 'main');
|
|
1128
|
+
return { repo, cleanup: () => fsr.rmSync(repo, { recursive: true, force: true }) };
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
test('stepFileSize: growing an over-limit file without an extraction is refused (BLOCK)', () => {
|
|
1132
|
+
const fx = makeSizeFixture();
|
|
1133
|
+
try {
|
|
1134
|
+
const res = stepFileSize({ repo: fx.repo }, { spawnSync: realSpawnSync }, { branch: 'task' });
|
|
1135
|
+
assert.equal(res.ok, false);
|
|
1136
|
+
assert.match(res.summary, /ARCH-001 blocked/);
|
|
1137
|
+
assert.match(res.summary, /big\.js/);
|
|
1138
|
+
} finally { fx.cleanup(); }
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
test('stepFileSize: same growth paired with a new extracted module passes', () => {
|
|
1142
|
+
const fx = makeSizeFixture({ 'extracted.js': 60 });
|
|
1143
|
+
try {
|
|
1144
|
+
const res = stepFileSize({ repo: fx.repo }, { spawnSync: realSpawnSync }, { branch: 'task' });
|
|
1145
|
+
assert.equal(res.ok, true, res.summary);
|
|
1146
|
+
} finally { fx.cleanup(); }
|
|
1147
|
+
});
|
|
1148
|
+
|
|
1149
|
+
test('buildPlan: file-size runs before merge, and not at all with --no-merge', () => {
|
|
1150
|
+
const names = buildPlan(baseConfig({})).map(s => s.name);
|
|
1151
|
+
assert.deepEqual(names, ['preflight', 'file-size', 'merge', 'task-complete', 'mark-landed']);
|
|
1152
|
+
assert.ok(!buildPlan(baseConfig({ noMerge: true })).some(s => s.name === 'file-size'));
|
|
1153
|
+
});
|
|
@@ -94,7 +94,7 @@ phase_0_initialization:
|
|
|
94
94
|
1. 檢查當前工作目錄(cwd)是否有 .kenaz/project.yaml
|
|
95
95
|
2. 如果有 → 子專案模式:設定 PROJECT_PATH = cwd, CORE = project.yaml 的 core_path
|
|
96
96
|
3. 如果沒有 → Core 模式:PROJECT_PATH 為空,不需要 --project-path
|
|
97
|
-
4. 後續所有 task-api.js /
|
|
97
|
+
4. 後續所有 task-api.js / dispatch.js / post-complete.js 呼叫都根據此結果決定是否加 --project-path
|
|
98
98
|
check: |
|
|
99
99
|
# 子專案偵測(在 cwd 執行)
|
|
100
100
|
if [ -f .kenaz/project.yaml ]; then
|
|
@@ -753,19 +753,15 @@ phase_8_dispatch:
|
|
|
753
753
|
|
|
754
754
|
# ─── Dispatch 執行 ───
|
|
755
755
|
execution:
|
|
756
|
-
tool: ".formation/tools/
|
|
757
|
-
method: "Bash tool → node
|
|
758
|
-
max_parallel: 5
|
|
756
|
+
tool: ".formation/tools/dispatch.js"
|
|
757
|
+
method: "Bash tool → node dispatch.js --dispatch-mode=subagent → 取回 promptText + agentParams → Agent tool 開 subagent"
|
|
759
758
|
patterns:
|
|
760
|
-
single: "一個任務 →
|
|
761
|
-
parallel: "多個無依賴 → 多個 Bash(background) 同時啟動(上限 5,超過排隊)"
|
|
759
|
+
single: "一個任務 → node dispatch.js --task=TASK_XXX --dispatch-mode=subagent [--project-path ...] → Agent tool"
|
|
762
760
|
sequential: "有依賴 → 前一個完成再 dispatch 下一個"
|
|
763
761
|
cli:
|
|
764
|
-
unit: "node {CORE}/.formation/tools/
|
|
765
|
-
solo: "node {CORE}/.formation/tools/
|
|
766
|
-
|
|
767
|
-
legion: "node {CORE}/.formation/tools/headless.js --formation=legion --skill=forge --task=TASK_XXX [--project-path {PROJECT_PATH}]"
|
|
768
|
-
anti_pattern: "❌ 禁止用 Task tool 直接開 subagent — 繞過 Formation 會失去 prompt 組裝、principles 注入和 log"
|
|
762
|
+
unit: "node {CORE}/.formation/tools/dispatch.js --skill=do --task=TASK_XXX --dispatch-mode=subagent [--project-path {PROJECT_PATH}]"
|
|
763
|
+
solo: "node {CORE}/.formation/tools/dispatch.js --formation=solo --skill=strategy --task=TASK_XXX --dispatch-mode=subagent [--project-path {PROJECT_PATH}]"
|
|
764
|
+
anti_pattern: "❌ 不手寫 subagent prompt — 用 dispatch.js 組裝(prompt 組裝、principles 注入)"
|
|
769
765
|
|
|
770
766
|
# ─── Scope 安全 ───
|
|
771
767
|
scope:
|
|
@@ -162,7 +162,7 @@ degradation:
|
|
|
162
162
|
# ═══════════════════════════════════════
|
|
163
163
|
invocation:
|
|
164
164
|
via_formation:
|
|
165
|
-
command: "node .formation/tools/
|
|
165
|
+
command: "node .formation/tools/dispatch.js --skill=do --task={FORSETI_TASK_ID} --project-path={path} --dispatch-mode=subagent"
|
|
166
166
|
context_required:
|
|
167
167
|
- "task_id: 被驗證的 Dev Task ID(必填)"
|
|
168
168
|
- "project_path: /absolute/path/to/project(必填)"
|
|
@@ -49,7 +49,7 @@ post_complete_verdict: RECORDED | delta: {N.NN|n/a} | reason: {text}
|
|
|
49
49
|
| 項目 | 說明 |
|
|
50
50
|
|------|------|
|
|
51
51
|
| 路徑 | `.kenaz/health_snapshots/{taskId}_before.json` / `_after.json` |
|
|
52
|
-
| 寫入者 |
|
|
52
|
+
| 寫入者 | 首次運行時由 post-complete.js 寫入 |
|
|
53
53
|
| 格式 | `{ "score": 82, "grade": "B", "timestamp": "..." }` |
|
|
54
54
|
| 無快照時 | 保存當前分數為基線 |
|
|
55
55
|
|