kenaz 0.3.17 → 0.3.19
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/commands/agent-worker.md +1 -1
- package/core/.claude/commands/architect.md +1 -2
- package/core/.claude/commands/spec.md +1 -1
- package/core/.claude/commands//347/224/242/345/223/201.md +1 -1
- package/core/.claude/hooks/__tests__/task-1977-dedupe-guard.test.js +8 -8
- package/core/.claude/hooks/synapse-first-investigation.js +15 -0
- package/core/.claude/skills/architect_agent/SKILL.md +11 -92
- package/core/.claude/skills/assessment_agent/SKILL.md +0 -1
- package/core/.claude/skills/backend_engineer/SKILL.md +3 -6
- package/core/.claude/skills/code_reviewer/SKILL.md +1 -1
- package/core/.claude/skills/code_reviewer/patterns.yaml +1 -1
- package/core/.claude/skills/designer/SKILL.md +3 -6
- package/core/.claude/skills/dev_agent/SKILL.md +30 -491
- package/core/.claude/skills/developer/SKILL.md +3 -6
- package/core/.claude/skills/feature_agent/SKILL.md +3 -17
- package/core/.claude/skills/product_manager/SKILL.md +29 -1064
- package/core/.claude/skills/qa_engineer/SKILL.md +12 -17
- package/core/.claude/skills/spec_optimizer/SKILL.md +25 -275
- package/core/.claude/skills/sre_agent/SKILL.md +3 -6
- package/core/.collaboration/README.md +2 -3
- package/core/.collaboration/core/task-api.js +5 -138
- package/core/.collaboration/docs/CLI.md +0 -2
- package/core/.failure/INDEX.yaml +6 -40
- package/core/.failure/agent-execution/FAIL-013-search-cwd-drift-and-case-mismatch.yaml +1 -1
- package/core/.failure/tools/README.md +9 -227
- package/core/.formation/bifrost/exec.js +29 -4
- package/core/.formation/bifrost/launch.js +1 -6
- package/core/.formation/bifrost/launch.test.js +1 -1
- package/core/.formation/bifrost/provider-launch.js +18 -11
- package/core/.formation/bifrost/provider-launch.test.js +26 -2
- package/core/.formation/bifrost/shared/ansuz-boot-policy.js +3 -3
- package/core/.formation/bifrost/shared/ansuz-boot-policy.test.js +1 -2
- package/core/.formation/tools/__tests__/dispatch-cwd-project.test.js +42 -0
- package/core/.formation/tools/__tests__/m1-hmap-convid.test.js +1 -124
- package/core/.formation/tools/__tests__/subagent-executor.test.js +3 -2
- package/core/.formation/tools/dispatch.js +15 -2
- package/core/.formation/tools/loader.js +17 -140
- package/core/.formation/tools/post-complete.js +0 -31
- package/core/.rule/INDEX.yaml +0 -18
- package/core/.rule/general/agent-workflow.yaml +14 -164
- package/core/.rule/general/project-self-containment.yaml +8 -19
- package/core/.rule/general/rust-verify-target.yaml +6 -5
- package/core/.rule/general/synapse-code-intelligence.yaml +3 -3
- package/core/.specialist/Amelia/capability.yaml +12 -12
- package/core/.specialist/Amelia/workflow.yaml +2 -2
- package/core/.specialist/Ansuz/SYSTEM_DOC.md +20 -578
- package/core/.specialist/Ansuz/cognitive_principles.yaml +2 -3
- package/core/.specialist/Ansuz/concepts/boot_rules_summary.yaml +0 -1
- package/core/.specialist/Ansuz/concepts/deep_knowledge_pointers.yaml +1 -2
- package/core/.specialist/Ansuz/core.yaml +6 -108
- package/core/.specialist/Ansuz/guards/lesson_guards.yaml +0 -3
- package/core/.specialist/Ansuz/identity_contract.yaml +0 -1
- package/core/.specialist/Ansuz/knowledge.yaml +0 -4
- package/core/.specialist/Ansuz/rule.yaml +0 -1
- package/core/.specialist/Ansuz/tools/handoff-session-identity.test.js +6 -150
- package/core/.specialist/tests/runtime-discovery/README.md +1 -1
- package/core/.specialist/tools/__tests__/task-2374-usage-counter.test.js +1 -12
- package/core/.specialist/tools/prompt-files.test.js +1 -0
- package/core/.specialist/tools/task-bridge.js +1 -66
- package/core/.system/README.md +11 -552
- package/core/.system/collaboration/README.md +10 -174
- package/core/CLAUDE.md +1 -6
- package/core/KENAZ_CORE_VERSION +1 -1
- package/core/dev/scripts/js-yaml-resolution.test.js +1 -1
- package/core/dev/scripts/run-rust-tests.js +30 -46
- package/core/dev/scripts/run-rust-tests.test.js +17 -0
- package/core/dev/scripts/rust-verify-worktree.js +4 -4
- package/core/dev/scripts/verify-target-dir.js +6 -6
- package/core/plugins/kenaz/INVENTORY.md +8 -8
- package/core/plugins/kenaz/commands/architect.md +1 -2
- package/core/plugins/kenaz/commands/spec.md +1 -1
- package/core/plugins/kenaz/commands//347/224/242/345/223/201.md +1 -1
- package/core/plugins/kenaz/guidance.md +1 -1
- package/core/plugins/kenaz/scripts/sync.js +1 -1
- package/core/plugins/kenaz/scripts/ygg.js +6 -0
- package/core/plugins/kenaz/skills/architect_agent/SKILL.md +11 -92
- package/core/plugins/kenaz/skills/assessment_agent/SKILL.md +0 -1
- package/core/plugins/kenaz/skills/backend_engineer/SKILL.md +3 -6
- package/core/plugins/kenaz/skills/code_reviewer/SKILL.md +1 -1
- package/core/plugins/kenaz/skills/code_reviewer/patterns.yaml +1 -1
- package/core/plugins/kenaz/skills/designer/SKILL.md +3 -6
- package/core/plugins/kenaz/skills/dev_agent/SKILL.md +30 -491
- package/core/plugins/kenaz/skills/developer/SKILL.md +3 -6
- package/core/plugins/kenaz/skills/feature_agent/SKILL.md +3 -17
- package/core/plugins/kenaz/skills/product_manager/SKILL.md +29 -1064
- package/core/plugins/kenaz/skills/qa_engineer/SKILL.md +12 -17
- package/core/plugins/kenaz/skills/spec_optimizer/SKILL.md +25 -275
- package/core/plugins/kenaz/skills/sre_agent/SKILL.md +3 -6
- package/package.json +6 -6
- package/core/.claude/commands/archive.md +0 -24
- package/core/.claude/commands/init.md +0 -112
- package/core/.claude/commands/legacy_dev.md +0 -18
- package/core/.claude/commands/product-review.md +0 -131
- package/core/.claude/commands/strategy.md +0 -141
- package/core/.claude/commands/sunny.md +0 -1
- package/core/.claude/commands//347/224/242/345/223/201/346/252/242/350/246/226.md +0 -129
- package/core/.claude/commands//351/200/262/345/272/246.md +0 -15
- package/core/.claude/hooks/__tests__/substrate.test.js +0 -122
- package/core/.claude/hooks/_substrate-paths.js +0 -95
- package/core/.claude/hooks/context-check.js +0 -51
- package/core/.claude/hooks/fatigue-check.js +0 -52
- package/core/.claude/hooks/handoff-snapshot-on-commit.js +0 -154
- package/core/.claude/hooks/handoff-snapshot-on-question.js +0 -158
- package/core/.claude/hooks/handoff-staleness.js +0 -197
- package/core/.claude/hooks/jev-thalamus-context.js +0 -17
- package/core/.claude/hooks/jev-thalamus-context.test.js +0 -41
- package/core/.claude/hooks/lease-release.js +0 -119
- package/core/.claude/hooks/lease-touch.js +0 -96
- package/core/.claude/hooks/reflex-feedback.js +0 -5
- package/core/.claude/hooks/session-init.ps1 +0 -49
- package/core/.claude/hooks/sound-event.js +0 -70
- package/core/.claude/hooks/sound-event.sh +0 -37
- package/core/.claude/hooks/stream-delta.js +0 -169
- package/core/.claude/no-hooks.settings.json +0 -3
- package/core/.claude/skills/legacy_dev/SKILL.md +0 -202
- package/core/.claude/skills/sunny/SKILL.md +0 -74
- package/core/.collaboration/cli/commands/assign.js +0 -39
- package/core/.collaboration/cli/commands/claim.js +0 -33
- package/core/.collaboration/cli/commands/complete.js +0 -44
- package/core/.collaboration/cli/commands/create.js +0 -110
- package/core/.collaboration/cli/commands/get.js +0 -83
- package/core/.collaboration/cli/commands/index.js +0 -52
- package/core/.collaboration/cli/commands/list.js +0 -51
- package/core/.collaboration/cli/commands/lock.js +0 -45
- package/core/.collaboration/cli/commands/rebuild.js +0 -39
- package/core/.collaboration/cli/commands/search.js +0 -61
- package/core/.collaboration/cli/commands/stats.js +0 -61
- package/core/.collaboration/cli/commands/transfer.js +0 -41
- package/core/.collaboration/cli/commands/unlock.js +0 -48
- package/core/.collaboration/cli/formatters/help-formatter.js +0 -70
- package/core/.collaboration/cli/formatters/index.js +0 -7
- package/core/.collaboration/cli/task-cli.js +0 -46
- package/core/.collaboration/cli/utils/arg-parser.js +0 -74
- package/core/.collaboration/cli/utils/git-user.js +0 -25
- package/core/.collaboration/cli/utils/index.js +0 -9
- package/core/.collaboration/cli/utils/output.js +0 -10
- package/core/.collaboration/config/default.yaml +0 -189
- package/core/.collaboration/core/conflict-resolver.js +0 -461
- package/core/.collaboration/core/conflict-resolver.test.js +0 -389
- package/core/.collaboration/core/migrate-legacy.js +0 -260
- package/core/.collaboration/docs/API.md +0 -787
- package/core/.collaboration/docs/ARCHITECTURE.md +0 -596
- package/core/.collaboration/docs/FAQ.md +0 -695
- package/core/.collaboration/docs/MIGRATION.md +0 -804
- package/core/.collaboration/docs/examples/README.md +0 -320
- package/core/.collaboration/docs/examples/advanced-queries.js +0 -261
- package/core/.collaboration/docs/examples/basic-usage.js +0 -184
- package/core/.collaboration/docs/examples/team-workflow.js +0 -352
- package/core/.failure/agent-execution/FAIL-001-agent-no-output.yaml +0 -391
- package/core/.failure/agent-execution/FAIL-007-pm-lead-wrong-team-invocation.yaml +0 -0
- package/core/.failure/agent-execution/FAIL-010-phase0-poem-format-skipped.yaml +0 -28
- package/core/.failure/agent-execution/FAIL-010-skipping-cognitive-checkpoint-after-verification.yaml +0 -59
- package/core/.failure/agent-execution/FAIL-012-grep-shortcut-during-investigation.yaml +0 -85
- package/core/.failure/architecture/FAIL-006-python-version-compatibility.yaml +0 -445
- package/core/.failure/pipeline/FAIL-003-queue-pollution.yaml +0 -335
- package/core/.failure/pipeline/README.md +0 -95
- package/core/.failure/retired/FAIL-009-skipping-synapse-pulse-before-code-change.yaml +0 -49
- package/core/.failure/tools/USAGE_GUIDE.md +0 -323
- package/core/.failure/tools/check_failures.ps1 +0 -387
- package/core/.failure/tools/log_failure.ps1 +0 -474
- package/core/.formation/.episode-input.json +0 -10
- package/core/.formation/.merge-lock +0 -1
- package/core/.formation/lead.yaml +0 -118
- package/core/.formation/legacy.bak/designer.yaml +0 -57
- package/core/.formation/legacy.bak/pm.yaml +0 -57
- package/core/.formation/legacy.bak/qa.yaml +0 -57
- package/core/.formation/legacy.bak/review.yaml +0 -62
- package/core/.formation/legacy.bak/scheduler.yaml +0 -129
- package/core/.formation/legacy.bak/sre.yaml +0 -57
- package/core/.formation/role-map.yaml +0 -274
- package/core/.formation/roles/_shared/modules/code_review.yaml +0 -98
- package/core/.formation/roles/_shared/modules/security.yaml +0 -103
- package/core/.formation/roles/_shared/modules/testing.yaml +0 -14
- package/core/.formation/roles/backend/role.yaml +0 -93
- package/core/.formation/roles/code_reviewer/role.yaml +0 -102
- package/core/.formation/roles/database_optimizer/role.yaml +0 -107
- package/core/.formation/roles/designer/role.yaml +0 -66
- package/core/.formation/roles/developer/role.yaml +0 -75
- package/core/.formation/roles/frontend/role.yaml +0 -134
- package/core/.formation/roles/incident_response/role.yaml +0 -89
- package/core/.formation/roles/qa/role.yaml +0 -89
- package/core/.formation/roles/security/role.yaml +0 -87
- package/core/.formation/roles/sre/role.yaml +0 -66
- package/core/.formation/skills/coordinator.yaml +0 -52
- package/core/.formation/solo/diagnosis.yaml +0 -78
- package/core/.formation/solo/strategy.yaml +0 -121
- package/core/.formation/tests/hello.txt +0 -2
- package/core/.formation/tools/coordinator.js +0 -350
- package/core/.formation/tools/jev-correction.js +0 -214
- package/core/.formation/tools/jev-correction.test.js +0 -178
- package/core/.formation/tools/log-reader.js +0 -232
- package/core/.formation/tools/revert-daemon-state.js +0 -162
- package/core/.formation/tools/test-drift.js +0 -148
- package/core/.formation/unit/heimdall.yaml +0 -96
- package/core/.formation/unit/plan.yaml +0 -67
- package/core/.formation/unit/think.yaml +0 -58
- package/core/.kenaz/MUNINN_SNAPSHOT9_EPISODE.json +0 -32
- package/core/.kenaz/MUNINN_SNAPSHOT9_RUNE.json +0 -23
- package/core/.kenaz/MUNINN_SNAPSHOT9_SUMMARY.md +0 -89
- package/core/.kenaz/ash_TASK_1428-20260507.json +0 -14
- package/core/.kenaz/muninn_episode_write.ps1 +0 -17
- package/core/.kenaz/muninn_snapshot11_rune_candidates.md +0 -63
- package/core/.kenaz/muninn_snapshot1_rune_candidates.md +0 -49
- package/core/.kenaz/runes_TASK_1428.json +0 -57
- package/core/.kenaz/tmp_heimdall_proposal_8d3e392.json +0 -13
- package/core/.kenaz/tmp_props.json +0 -1
- package/core/.kenaz/tmp_sounddrop_t1_prompt.txt +0 -371
- package/core/.rule/MECHANIZED.md +0 -61
- package/core/.rule/general/cortex-memory-recall.yaml +0 -446
- package/core/.rule/general/pipeline.yaml +0 -246
- package/core/.rule/general/sunny-access-control.yaml +0 -60
- package/core/.rule/general/system-invariants.yaml +0 -231
- package/core/.rule/pipeline/PPL-002-completed-task-archival.yaml +0 -528
- package/core/.rule/pipeline/auto-update.yaml +0 -282
- package/core/.rule/pipeline/task-execution.yaml +0 -365
- package/core/.specialist/Ansuz/concepts/phase_protocol.yaml +0 -65
- package/core/.specialist/Ansuz/experiments/boot_ablation_replay.js +0 -197
- package/core/.specialist/Ansuz/tools/bootstrap-anchors.js +0 -289
- package/core/.specialist/Ansuz/workflow.yaml +0 -1225
- package/core/.specialist/experiments/rg_benchmark.js +0 -523
- package/core/.specialist/experiments/rg_benchmark_results.json +0 -27
- package/core/.specialist/tools/jev-optional-context.js +0 -107
- package/core/.specialist/tools/jev-optional-context.test.js +0 -152
- package/core/.specialist/tools/memory-action-log.js +0 -839
- package/core/.specialist/tools/phase-gate.js +0 -3534
- package/core/.specialist/tools/phase-gate.test.js +0 -85
- package/core/.specialist/tools/precompute-runner.js +0 -444
- package/core/.specialist/tools/rule-engine.js +0 -621
- package/core/.specialist/tools/task-bridge-jev.test.js +0 -170
- package/core/.synapse/memory-shared.json.sync +0 -1
- package/core/.system/agent-skills/README.md +0 -724
- package/core/.system/cli-tools/README.md +0 -724
- package/core/.system/cortex/MODULES.md +0 -1046
- package/core/.system/dashboard/FRONTEND.md +0 -812
- package/core/.system/dashboard/README.md +0 -737
- package/core/.system/failure/README.md +0 -723
- package/core/.system/formation/LEGACY_SKILLS.md +0 -974
- package/core/.system/formation/POST_COMPLETE.md +0 -602
- package/core/.system/formation/README.md +0 -1094
- package/core/.system/formation/TOOLS_REFERENCE.md +0 -1145
- package/core/.system/kenaz/README.md +0 -787
- package/core/.system/memory/README.md +0 -719
- package/core/.system/pipeline/README.md +0 -712
- package/core/.system/rule/README.md +0 -794
- package/core/.system/sunny/README.md +0 -476
- package/core/.system/sunny/RULES.json +0 -89
- package/core/.system/sunny/knowledge/INDEX.md +0 -37
- package/core/.system/sunny/knowledge/agent-teams-api.md +0 -0
- package/core/.system/sunny/knowledge/ansuz-specialist.md +0 -500
- package/core/.system/sunny/knowledge/claude-cli-spawn.md +0 -177
- package/core/.system/sunny/knowledge/collaboration-api.md +0 -925
- package/core/.system/sunny/teammates/README.md +0 -107
- package/core/.system/sunny/teammates/how_to_use.yaml +0 -101
- package/core/.system/sunny/teammates/tools/headless/launcher.js +0 -318
- package/core/.system/sunny/teammates/tools/powershell/launcher.js +0 -241
- package/core/.system/sunny/teammates/tools/powershell/start.bat +0 -50
- package/core/.system/sunny/teammates/tools/utils/env.js +0 -96
- package/core/.system/sunny/teammates/tools/utils/format-output.js +0 -329
- package/core/.system/sunny/tools.json +0 -101
- package/core/dev/scripts/cleanup-queue.js +0 -184
- package/core/dev/scripts/cleanup_queue.js +0 -86
- package/core/dev/scripts/legacy/README.md +0 -39
- package/core/dev/scripts/legacy/dev_agent_scheduler.ps1.bak +0 -536
- package/core/dev/scripts/legacy/multi_agent_scheduler.ps1.bak +0 -1978
- package/core/dev/scripts/matrix/CLI_README.md +0 -214
- package/core/dev/scripts/matrix/README.md +0 -310
- package/core/dev/scripts/matrix/package-lock.json +0 -4266
- package/core/dev/scripts/matrix/package.json +0 -55
- package/core/dev/scripts/matrix/src/abbreviations.ts +0 -295
- package/core/dev/scripts/matrix/src/cli/commands/convert.ts +0 -211
- package/core/dev/scripts/matrix/src/cli/commands/create.ts +0 -95
- package/core/dev/scripts/matrix/src/cli/commands/delete.ts +0 -102
- package/core/dev/scripts/matrix/src/cli/commands/list-tags.ts.wip +0 -140
- package/core/dev/scripts/matrix/src/cli/commands/manage-tags.ts.wip +0 -173
- package/core/dev/scripts/matrix/src/cli/commands/query.ts +0 -261
- package/core/dev/scripts/matrix/src/cli/commands/read.ts +0 -77
- package/core/dev/scripts/matrix/src/cli/commands/stats.ts.wip +0 -168
- package/core/dev/scripts/matrix/src/cli/commands/tokens.ts.wip +0 -126
- package/core/dev/scripts/matrix/src/cli/commands/update.ts +0 -147
- package/core/dev/scripts/matrix/src/cli/commands/validate.ts +0 -275
- package/core/dev/scripts/matrix/src/cli/index.ts +0 -350
- package/core/dev/scripts/matrix/src/cli/utils/file-handler.ts +0 -72
- package/core/dev/scripts/matrix/src/cli/utils/logger.ts +0 -65
- package/core/dev/scripts/matrix/src/index.ts +0 -62
- package/core/dev/scripts/matrix/src/indexer/tag-indexer.ts +0 -165
- package/core/dev/scripts/matrix/src/parser.ts +0 -281
- package/core/dev/scripts/matrix/src/serializer.ts +0 -151
- package/core/dev/scripts/matrix/src/validator.ts +0 -301
- package/core/dev/scripts/matrix/tests/abbreviations.test.ts +0 -122
- package/core/dev/scripts/matrix/tests/cli.test.ts +0 -177
- package/core/dev/scripts/matrix/tests/convert.test.ts +0 -143
- package/core/dev/scripts/matrix/tests/parser.test.ts +0 -203
- package/core/dev/scripts/matrix/tests/query.test.ts +0 -85
- package/core/dev/scripts/matrix/tests/serializer.test.ts +0 -197
- package/core/dev/scripts/matrix/tests/validate.test.ts +0 -141
- package/core/dev/scripts/matrix/tests/validator.test.ts +0 -167
- package/core/dev/scripts/matrix/tsconfig.json +0 -20
- package/core/dev/scripts/matrix/types/index.d.ts +0 -111
- package/core/dev/scripts/matrix/types/index.d.ts.map +0 -1
- package/core/dev/scripts/matrix/types/index.js +0 -8
- package/core/dev/scripts/matrix/types/index.js.map +0 -1
- package/core/dev/scripts/matrix/types/index.ts +0 -124
- package/core/dev/scripts/memory-usage-report.js +0 -152
- package/core/dev/scripts/probe/ansuz-scaffold-ablation.js +0 -579
- package/core/dev/scripts/probe/ansuz-scaffold-ablation.test.js +0 -244
- package/core/dev/scripts/probe/hook-latency-probe.js +0 -315
- package/core/dev/scripts/probe/hook-latency-probe.test.js +0 -105
- package/core/dev/scripts/probe/prediction-signal-auc.js +0 -483
- package/core/dev/scripts/probe/prediction-signal-auc.test.js +0 -200
- package/core/dev/scripts/test-pty-ws-tunnel.js +0 -229
- package/core/dev/scripts/validate_pipeline.js +0 -197
- package/core/dev/spikes/task2145-evidence-20261004/backend-log-excerpt.txt +0 -56
- package/core/dev/spikes/task2145-evidence-20261004/graph.shadow +0 -0
- package/core/dev/spikes/task2145-evidence-20261004/graph.wal +0 -0
- package/core/dev/spikes/task2145-evidence-20261004/graph_corrupt_suspect.marker +0 -1
- package/core/plugins/kenaz/commands/strategy.md +0 -141
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// TASK_1764 AMEND + TASK_1766 validation: scratch_<convId>.json as bind source.
|
|
2
|
-
// Tests REG-0
|
|
2
|
+
// Tests REG-0, T11 (resolveOwnBinding), T15 (dispatch scope gate). The lease-touch/lease-release hook cases were removed with those hooks.
|
|
3
3
|
// Usage: node .formation/tools/__tests__/m1-hmap-convid.test.js
|
|
4
4
|
// Exit 0 = all pass, non-zero = failure.
|
|
5
5
|
'use strict';
|
|
@@ -17,8 +17,6 @@ function resolveRoot() {
|
|
|
17
17
|
throw new Error('Cannot resolve root from ' + __dirname);
|
|
18
18
|
}
|
|
19
19
|
const WT = resolveRoot();
|
|
20
|
-
const LEASE_TOUCH = path.join(WT, '.claude/hooks/lease-touch.js');
|
|
21
|
-
const LEASE_RELEASE = path.join(WT, '.claude/hooks/lease-release.js');
|
|
22
20
|
const STREAM_LEASE = path.join(WT, '.specialist/tools/stream-lease.js');
|
|
23
21
|
const SESSION_IDENT = path.join(WT, '.claude/hooks/_session-identity.js');
|
|
24
22
|
const SB = path.join(os.tmpdir(), 'hmap_convid_' + process.pid);
|
|
@@ -34,7 +32,6 @@ function check(name, cond, detail) {
|
|
|
34
32
|
cond ? pass++ : fail++;
|
|
35
33
|
}
|
|
36
34
|
const baseEnv = { ...process.env, CLAUDE_PROJECT_DIR: SB, KENAZ_SOURCE_DIR: SB };
|
|
37
|
-
function runHook(hp, sj) { return cp.spawnSync(process.execPath, [hp], { input: JSON.stringify(sj), encoding: 'utf8', env: baseEnv, timeout: 5000 }); }
|
|
38
35
|
function sbSL(a) { return cp.spawnSync(process.execPath, [path.join(SB, '.specialist/tools/stream-lease.js'), ...a], { encoding: 'utf8', env: baseEnv, timeout: 5000 }); }
|
|
39
36
|
function readHmap(id) { try { return JSON.parse(fs.readFileSync(path.join(SB, '.kenaz/specialist/sessions/hmap_' + id + '.json'), 'utf8')); } catch { return null; } }
|
|
40
37
|
function hmapExists(id) { return fs.existsSync(path.join(SB, '.kenaz/specialist/sessions/hmap_' + id + '.json')); }
|
|
@@ -52,96 +49,6 @@ console.log('\n--- REG-0: register writes scratch ---');
|
|
|
52
49
|
check('REG-0b: scratch.session_id', sc&&sc.session_id===s, JSON.stringify(sc));
|
|
53
50
|
check('REG-0c: scratch.conversation_id', sc&&sc.conversation_id===c, JSON.stringify(sc));
|
|
54
51
|
try{sbSL(['release','--session-id='+s]);}catch(_){} }
|
|
55
|
-
// --- REG-1: hmap bind source is scratch (TASK_1766) ---
|
|
56
|
-
console.log('\n--- REG-1: hmap bind source is scratch ---');
|
|
57
|
-
{ const cA='conv-aaa-111', sA='sid-aaa-001'; reg(sA,cA);
|
|
58
|
-
runHook(LEASE_TOUCH, { session_id: 'harness-abc', transcript_path: '/fake/'+cA+'.jsonl' });
|
|
59
|
-
const h=readHmap(cA);
|
|
60
|
-
check('REG-1a: hmap created after first touch', !!h, 'file not found');
|
|
61
|
-
check('REG-1b: hmap.conversation_id', h&&h.conversation_id===cA, JSON.stringify(h));
|
|
62
|
-
check('REG-1c: hmap.boot_sid=sA', h&&h.boot_sid===sA, JSON.stringify(h));
|
|
63
|
-
check('REG-1d: no hmap_harness-abc', !fs.existsSync(path.join(SB,'.kenaz/specialist/sessions/hmap_harness-abc.json')),'');
|
|
64
|
-
runHook(LEASE_TOUCH, { session_id: 'harness-xyz', transcript_path: '/fake/'+cA+'.jsonl' });
|
|
65
|
-
const h2=readHmap(cA);
|
|
66
|
-
check('REG-2a: hmap still present after rotated session_id', !!h2,'');
|
|
67
|
-
check('REG-2b: boot_sid unchanged', h2&&h2.boot_sid===sA, JSON.stringify(h2));
|
|
68
|
-
try{sbSL(['release','--session-id='+sA]);}catch(_){} }
|
|
69
|
-
// --- T1: transcript conv has no scratch -> no bind ---
|
|
70
|
-
console.log('\n--- T1: transcript conv has no scratch -> no bind ---');
|
|
71
|
-
{ const cA='conv-aaa-bind-guard', cB='conv-bbb-different', sA='sid-t1-aaa'; reg(sA,cA);
|
|
72
|
-
runHook(LEASE_TOUCH, { transcript_path: '/fake/'+cB+'.jsonl' });
|
|
73
|
-
check('T1: no hmap for convBBB (no scratch)', !hmapExists(cB), 'hmap_'+cB+' created');
|
|
74
|
-
try{sbSL(['release','--session-id='+sA]);}catch(_){} }
|
|
75
|
-
// --- T2: lease-release resolves hmap by convId ---
|
|
76
|
-
console.log('\n--- T2: lease-release resolves hmap by convId ---');
|
|
77
|
-
{ const cC='conv-ccc-release', sC='sid-ccc-003'; reg(sC,cC); writeHmap(cC,sC);
|
|
78
|
-
check('T2-pre: sC lease exists', leaseExists(sC), '');
|
|
79
|
-
runHook(LEASE_RELEASE, { hook_event_name:'SessionEnd', source:'logout', transcript_path:'/fake/'+cC+'.jsonl' });
|
|
80
|
-
check('T2: lease removed', !leaseExists(sC), 'still present');
|
|
81
|
-
check('T2: hmap cleaned', !hmapExists(cC), ''); }
|
|
82
|
-
// --- T3: SessionEnd source=resume -> no release ---
|
|
83
|
-
console.log('\n--- T3: SessionEnd source=resume -> no release ---');
|
|
84
|
-
{ const cD='conv-ddd-resume', sD='sid-ddd-004'; reg(sD,cD); writeHmap(cD,sD);
|
|
85
|
-
check('T3-pre: sD lease exists', leaseExists(sD), '');
|
|
86
|
-
runHook(LEASE_RELEASE, { hook_event_name:'SessionEnd', source:'resume', transcript_path:'/fake/'+cD+'.jsonl' });
|
|
87
|
-
check('T3: lease NOT released on source=resume', leaseExists(sD), 'deleted');
|
|
88
|
-
check('T3: hmap NOT cleaned', hmapExists(cD), '');
|
|
89
|
-
try{sbSL(['release','--session-id='+sD]);}catch(_){} }
|
|
90
|
-
// --- T4: no transcript_path -> headless no-op (BUG-10) ---
|
|
91
|
-
console.log('\n--- T4: no transcript_path -> headless no-op ---');
|
|
92
|
-
{ const sH='sid-headless-005'; reg(sH,null); writeStream(sH,null);
|
|
93
|
-
const t4=runHook(LEASE_TOUCH, { tool_name:'UserPromptSubmit' });
|
|
94
|
-
check('T4: hook exits cleanly', t4.status===0||t4.signal===null, 'status='+t4.status);
|
|
95
|
-
try{sbSL(['release','--session-id='+sH]);}catch(_){} }
|
|
96
|
-
// --- T5: SessionEnd no transcript_path -> no-op ---
|
|
97
|
-
console.log('\n--- T5: SessionEnd no transcript_path -> no-op ---');
|
|
98
|
-
{ const cE='conv-eee-noop', sE='sid-eee-006'; reg(sE,cE); writeStream(sE,cE);
|
|
99
|
-
check('T5-pre: sE lease exists', leaseExists(sE), '');
|
|
100
|
-
runHook(LEASE_RELEASE, { hook_event_name:'SessionEnd', source:'logout' });
|
|
101
|
-
check('T5: lease present (no transcript_path -> no-op)', leaseExists(sE), 'deleted');
|
|
102
|
-
try{sbSL(['release','--session-id='+sE]);}catch(_){} }
|
|
103
|
-
// --- T8: compact rotation - session_id rotates, hmap key stays convId ---
|
|
104
|
-
console.log('\n--- T8: compact rotation ---');
|
|
105
|
-
{ const cF='conv-fff-compact', sF1='sid-fff-pre-compact', sF2='sid-fff-post-compact';
|
|
106
|
-
reg(sF1,cF);
|
|
107
|
-
runHook(LEASE_TOUCH, { session_id:sF1, transcript_path:'/fake/'+cF+'.jsonl' });
|
|
108
|
-
const hPre=readHmap(cF);
|
|
109
|
-
check('T8-pre: hmap written with sF1', hPre&&hPre.boot_sid===sF1, JSON.stringify(hPre));
|
|
110
|
-
reg(sF2,cF);
|
|
111
|
-
runHook(LEASE_TOUCH, { session_id:sF2, transcript_path:'/fake/'+cF+'.jsonl' });
|
|
112
|
-
const hPost=readHmap(cF);
|
|
113
|
-
check('T8-post: hmap still exists', !!hPost, 'missing');
|
|
114
|
-
check('T8-post: boot_sid unchanged (sF1)', hPost&&hPost.boot_sid===sF1, JSON.stringify(hPost));
|
|
115
|
-
check('T8-post: no orphan hmap for sF2', !fs.existsSync(path.join(SB,'.kenaz/specialist/sessions/hmap_'+sF2+'.json')), '');
|
|
116
|
-
check('T8-pre-release: sF1 lease exists', leaseExists(sF1), '');
|
|
117
|
-
runHook(LEASE_RELEASE, { hook_event_name:'SessionEnd', source:'logout', transcript_path:'/fake/'+cF+'.jsonl' });
|
|
118
|
-
check('T8: sF1 lease removed', !leaseExists(sF1), 'sF1.json still exists');
|
|
119
|
-
check('T8: hmap cleaned', !hmapExists(cF), '');
|
|
120
|
-
try{sbSL(['release','--session-id='+sF2]);}catch(_){} }
|
|
121
|
-
// --- T9 (BUG-8): dual register A-first -> both bind independently ---
|
|
122
|
-
console.log('\n--- T9 (BUG-8): dual register A-first -> both bind ---');
|
|
123
|
-
{ const cG1='conv-g1-dual-a', sG1='sid-g1-stream-a', cG2='conv-g2-dual-b', sG2='sid-g2-stream-b';
|
|
124
|
-
reg(sG1,cG1); reg(sG2,cG2);
|
|
125
|
-
runHook(LEASE_TOUCH, { transcript_path:'/fake/'+cG1+'.jsonl' });
|
|
126
|
-
runHook(LEASE_TOUCH, { transcript_path:'/fake/'+cG2+'.jsonl' });
|
|
127
|
-
const hG1=readHmap(cG1), hG2=readHmap(cG2);
|
|
128
|
-
check('T9a: stream-A hmap created (not starved)', !!hG1, 'hmap missing for cG1');
|
|
129
|
-
check('T9b: stream-A boot_sid=sG1', hG1&&hG1.boot_sid===sG1, JSON.stringify(hG1));
|
|
130
|
-
check('T9c: stream-B hmap created independently', !!hG2, 'hmap missing for cG2');
|
|
131
|
-
check('T9d: stream-B boot_sid=sG2', hG2&&hG2.boot_sid===sG2, JSON.stringify(hG2));
|
|
132
|
-
try{sbSL(['release','--session-id='+sG1]);}catch(_){} try{sbSL(['release','--session-id='+sG2]);}catch(_){} }
|
|
133
|
-
// --- T10 (BUG-8 reverse): register B first then A -> both bind ---
|
|
134
|
-
console.log('\n--- T10 (BUG-8 reverse): register B first then A -> both bind ---');
|
|
135
|
-
{ const cH1='conv-h1-rev-a', sH1='sid-h1-stream-a', cH2='conv-h2-rev-b', sH2='sid-h2-stream-b';
|
|
136
|
-
reg(sH2,cH2); reg(sH1,cH1);
|
|
137
|
-
runHook(LEASE_TOUCH, { transcript_path:'/fake/'+cH1+'.jsonl' });
|
|
138
|
-
runHook(LEASE_TOUCH, { transcript_path:'/fake/'+cH2+'.jsonl' });
|
|
139
|
-
const hH1=readHmap(cH1), hH2=readHmap(cH2);
|
|
140
|
-
check('T10a: stream-A hmap exists', !!hH1, 'missing');
|
|
141
|
-
check('T10b: stream-A boot_sid', hH1&&hH1.boot_sid===sH1, JSON.stringify(hH1));
|
|
142
|
-
check('T10c: stream-B hmap exists', !!hH2, 'missing');
|
|
143
|
-
check('T10d: stream-B boot_sid', hH2&&hH2.boot_sid===sH2, JSON.stringify(hH2));
|
|
144
|
-
try{sbSL(['release','--session-id='+sH1]);}catch(_){} try{sbSL(['release','--session-id='+sH2]);}catch(_){} }
|
|
145
52
|
// --- T11 (BUG-9): resolveOwnBinding ignores current_stream singleton ---
|
|
146
53
|
console.log('\n--- T11 (BUG-9): resolveOwnBinding ignores current_stream ---');
|
|
147
54
|
{ const cI1='conv-i1-a', sI1='sid-i1-a', cI2='conv-i2-b', sI2='sid-i2-b', cI3='conv-i3-c', sI3='sid-i3-c';
|
|
@@ -158,36 +65,6 @@ console.log('\n--- T11 (BUG-9): resolveOwnBinding ignores current_stream ---');
|
|
|
158
65
|
check('T11d: resolveOwnBinding via scratch (no hmap)', bI3.bootSid===sI3, JSON.stringify(bI3));
|
|
159
66
|
check('T11e: source=scratch', bI3.source==='scratch', JSON.stringify(bI3));
|
|
160
67
|
try{sbSL(['release','--session-id='+sI1]);}catch(_){} try{sbSL(['release','--session-id='+sI2]);}catch(_){} try{sbSL(['release','--session-id='+sI3]);}catch(_){} }
|
|
161
|
-
// --- T12 (BUG-10): foreign convId -> lease-touch no-op ---
|
|
162
|
-
console.log('\n--- T12 (BUG-10): foreign convId -> no-op ---');
|
|
163
|
-
{ const cJ='conv-j1-main', sJ='sid-j1-main', cJC='conv-jchild';
|
|
164
|
-
reg(sJ,cJ); writeHmap(cJ,sJ);
|
|
165
|
-
const lb=leaseExists(sJ);
|
|
166
|
-
runHook(LEASE_TOUCH, { transcript_path:'/fake/'+cJC+'.jsonl' });
|
|
167
|
-
check('T12a: main lease untouched after child hook', leaseExists(sJ)===lb, 'missing');
|
|
168
|
-
check('T12b: no hmap for child convId', !hmapExists(cJC), 'created unexpectedly');
|
|
169
|
-
try{sbSL(['release','--session-id='+sJ]);}catch(_){} }
|
|
170
|
-
// --- T13 (open-question repro + FIXED): stream bind blocked by current_stream overwrite ---
|
|
171
|
-
console.log('\n--- T13 (open-question): bind blocked by current_stream -> FIXED ---');
|
|
172
|
-
{ const cK1='conv-k1-a', sK1='sid-k1-a', cK2='conv-k2-b', sK2='sid-k2-b';
|
|
173
|
-
reg(sK1,cK1); reg(sK2,cK2);
|
|
174
|
-
runHook(LEASE_TOUCH, { transcript_path:'/fake/'+cK1+'.jsonl' });
|
|
175
|
-
const hK1=readHmap(cK1);
|
|
176
|
-
check('T13a: stream-A hmap created despite stream-B overwriting current_stream (BUG-8 FIXED)', !!hK1, 'hmap missing');
|
|
177
|
-
check('T13b: stream-A boot_sid=sK1', hK1&&hK1.boot_sid===sK1, JSON.stringify(hK1));
|
|
178
|
-
runHook(LEASE_TOUCH, { transcript_path:'/fake/'+cK2+'.jsonl' });
|
|
179
|
-
const hK2=readHmap(cK2);
|
|
180
|
-
check('T13c: stream-B hmap created', !!hK2, 'missing');
|
|
181
|
-
check('T13d: stream-B boot_sid=sK2', hK2&&hK2.boot_sid===sK2, JSON.stringify(hK2));
|
|
182
|
-
try{sbSL(['release','--session-id='+sK1]);}catch(_){} try{sbSL(['release','--session-id='+sK2]);}catch(_){} }
|
|
183
|
-
// --- T14: lease-release cleans up scratch ---
|
|
184
|
-
console.log('\n--- T14: lease-release cleans scratch ---');
|
|
185
|
-
{ const cL='conv-l1-cleanup', sL='sid-l1-cleanup'; reg(sL,cL); writeHmap(cL,sL);
|
|
186
|
-
check('T14-pre: scratch exists', scratchExists(cL), 'not found');
|
|
187
|
-
runHook(LEASE_RELEASE, { hook_event_name:'SessionEnd', source:'logout', transcript_path:'/fake/'+cL+'.jsonl' });
|
|
188
|
-
check('T14a: lease removed', !leaseExists(sL), 'still present');
|
|
189
|
-
check('T14b: hmap cleaned', !hmapExists(cL), '');
|
|
190
|
-
check('T14c: scratch cleaned', !scratchExists(cL), 'scratch still present'); }
|
|
191
68
|
// --- dispatch.js env name ---
|
|
192
69
|
// --- T15 (TASK_1767): empty scope_paths must not bypass same-task-id guard ---
|
|
193
70
|
console.log('\n--- T15: empty-scope same-task gate (TASK_1767) ---');
|
|
@@ -139,8 +139,9 @@ test('subagent set: unknown codex id and unknown prefix are refused with the val
|
|
|
139
139
|
const p = tmp(t, 'dm-');
|
|
140
140
|
const a = dmRun(['set', 'codex:nope'], p);
|
|
141
141
|
assert.equal(a.code, 1); assert.match(a.out, /unknown codex model 'nope'.*codex:gpt-5\.6-sol/);
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
// any well-formed deepseek id is accepted (a new vendor model needs no Kenaz release); a malformed one is refused
|
|
143
|
+
const b = dmRun(['set', 'deepseek:bad id'], p);
|
|
144
|
+
assert.equal(b.code, 1); assert.match(b.out, /invalid deepseek model id/);
|
|
144
145
|
const c = dmRun(['set', 'gemini:pro'], p);
|
|
145
146
|
assert.equal(c.code, 1); assert.match(c.out, /unknown executor prefix 'gemini:'.*codex:<id>, deepseek:<model>/);
|
|
146
147
|
assert.equal(fs.existsSync(path.join(p, '.kenaz', 'dashboard-models.json')), false);
|
|
@@ -487,6 +487,15 @@ function samePath(a, b) {
|
|
|
487
487
|
* @param {boolean|null} [opts.useWorktreeOverride] - dispatch-time toggle (CLI --use-worktree)
|
|
488
488
|
* @returns {{ isCrossProject: boolean, mode: string, useWorktree: boolean, source: string, verifyOffline: string|null }}
|
|
489
489
|
*/
|
|
490
|
+
/** The Kenaz project around the cwd (CLAUDE_PROJECT_DIR first), or null when it is the core itself / none. */
|
|
491
|
+
function cwdProject(start = process.env.CLAUDE_PROJECT_DIR || process.cwd()) {
|
|
492
|
+
let root = null;
|
|
493
|
+
try { root = require('../../.claude/hooks/_project-guard').findProjectRoot(start); } catch { return null; }
|
|
494
|
+
if (!root) return null;
|
|
495
|
+
const norm = (p) => path.resolve(p).replace(/\\/g, '/').toLowerCase();
|
|
496
|
+
return norm(root) === norm(ROOT) ? null : root;
|
|
497
|
+
}
|
|
498
|
+
|
|
490
499
|
function resolveDispatchIsolation({ projectPath = null, useWorktreeOverride = null } = {}) {
|
|
491
500
|
// TASK_1710 semantics: samePath, not raw string compare (separator/case).
|
|
492
501
|
const isCrossProject = !!(projectPath && !samePath(projectPath, ROOT));
|
|
@@ -804,7 +813,7 @@ Options:
|
|
|
804
813
|
(with --release-lock: release a lock this session
|
|
805
814
|
cannot prove it owns)
|
|
806
815
|
|
|
807
|
-
Skills: unit: do
|
|
816
|
+
Skills: unit: do.
|
|
808
817
|
|
|
809
818
|
Sub-agent dispatch (Ansuz billing-aware path):
|
|
810
819
|
node .formation/tools/dispatch.js --skill=do --task=TASK_172 --dispatch-mode=subagent
|
|
@@ -829,7 +838,11 @@ Sub-agent dispatch (Ansuz billing-aware path):
|
|
|
829
838
|
const formation = getArg('--formation') || 'unit';
|
|
830
839
|
const skill = getArg('--skill');
|
|
831
840
|
const task = getArg('--task');
|
|
832
|
-
|
|
841
|
+
// No --project-path: the Kenaz project around the cwd, when that is not the core itself. Plugin users run
|
|
842
|
+
// dispatch.js from their own project through core-resolve, so ROOT is the core: before this, the card was looked
|
|
843
|
+
// up in the core ("任務不存在") and the worktree was created in the core repo, leaving Ansuz waiting on a
|
|
844
|
+
// subagent with no card in the wrong repo (repro 2026-10-12).
|
|
845
|
+
const projectPath = getArg('--project-path') || cwdProject();
|
|
833
846
|
const dryRun = args.includes('--dry-run');
|
|
834
847
|
const dispatchModeCli = getArg('--dispatch-mode');
|
|
835
848
|
// TASK_1998 R3: subagent-path model override — wins over dashboard
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Formation Loader
|
|
3
|
-
* YAML
|
|
4
|
-
*
|
|
5
|
-
* 任務系統:
|
|
6
|
-
* 新系統 (.collaboration/tasks/) — TASK_151+ 目錄即狀態,YAML 格式
|
|
7
|
-
* 舊系統 (dev/pipeline/) — TASK_134~187 JSON 索引 + YAML 檔
|
|
8
|
-
* 查詢順序:新系統 → 舊系統 YAML → 舊系統 TASK_QUEUE.json
|
|
3
|
+
* YAML skill definitions + task loading (via task-api.js, which resolves
|
|
4
|
+
* .kenaz/tasks/ first and .collaboration/tasks/ as the legacy fallback).
|
|
9
5
|
*/
|
|
10
6
|
|
|
11
7
|
const { execSync } = require('child_process');
|
|
@@ -14,14 +10,10 @@ const fs = require('fs');
|
|
|
14
10
|
const yaml = (() => { try { return require('js-yaml'); } catch { return require('../../.vendor/js-yaml.cjs'); } })();
|
|
15
11
|
const { FORMATION_DIR, COLLABORATION_API, ROOT } = require('./utils');
|
|
16
12
|
|
|
17
|
-
// 舊系統路徑
|
|
18
|
-
const LEGACY_PIPELINE_DIR = path.join(ROOT, 'dev', 'pipeline');
|
|
19
|
-
const LEGACY_TASK_QUEUE = path.join(LEGACY_PIPELINE_DIR, 'TASK_QUEUE.json');
|
|
20
|
-
|
|
21
13
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @param {string} formation -
|
|
24
|
-
* @param {string} skill -
|
|
14
|
+
* Load a skill YAML definition (.formation/<formation>/<skill>.yaml).
|
|
15
|
+
* @param {string} formation - formation name (unit)
|
|
16
|
+
* @param {string} skill - skill name
|
|
25
17
|
* @returns {object} parsed YAML
|
|
26
18
|
*/
|
|
27
19
|
function loadSkill(formation, skill) {
|
|
@@ -34,48 +26,33 @@ function loadSkill(formation, skill) {
|
|
|
34
26
|
}
|
|
35
27
|
|
|
36
28
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* 查詢順序:
|
|
40
|
-
* 1. .collaboration/tasks/ 或 .kenaz/tasks/ (新系統 — task-api.js get)
|
|
41
|
-
* 2. dev/pipeline/completed/ + tasks/ (舊系統 YAML 檔)
|
|
42
|
-
* 3. dev/pipeline/TASK_QUEUE.json (舊系統 JSON 索引)
|
|
29
|
+
* Load task data through task-api.js.
|
|
43
30
|
*
|
|
44
|
-
* @param {string} taskId - TASK_XXX
|
|
45
|
-
* @param {object} [options]
|
|
46
|
-
* @param {string} [options.projectPath] -
|
|
47
|
-
* @returns {string|null}
|
|
31
|
+
* @param {string} taskId - TASK_XXX
|
|
32
|
+
* @param {object} [options]
|
|
33
|
+
* @param {string} [options.projectPath] - sub-project path (looked up first)
|
|
34
|
+
* @returns {string|null} task YAML text, or null
|
|
48
35
|
*/
|
|
49
36
|
function loadTask(taskId, options) {
|
|
50
37
|
if (!taskId || !taskId.startsWith('TASK_')) return null;
|
|
51
38
|
|
|
52
39
|
const projectRoot = options?.projectPath || ROOT;
|
|
53
40
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (fromCollab) return fromCollab;
|
|
57
|
-
|
|
58
|
-
// 2. 舊系統 YAML 檔 (dev/pipeline/completed/ + tasks/)
|
|
59
|
-
const fromYaml = loadTaskFromLegacyYaml(taskId, projectRoot);
|
|
60
|
-
if (fromYaml) return fromYaml;
|
|
61
|
-
|
|
62
|
-
// 3. 舊系統 JSON 索引 (TASK_QUEUE.json)
|
|
63
|
-
const fromQueue = loadTaskFromLegacyQueue(taskId, projectRoot);
|
|
64
|
-
if (fromQueue) return fromQueue;
|
|
41
|
+
const fromApi = loadTaskFromApi(taskId, projectRoot);
|
|
42
|
+
if (fromApi) return fromApi;
|
|
65
43
|
|
|
66
|
-
console.warn(`⚠️ Task ${taskId} not found
|
|
44
|
+
console.warn(`⚠️ Task ${taskId} not found (root: ${projectRoot})`);
|
|
67
45
|
return null;
|
|
68
46
|
}
|
|
69
47
|
|
|
70
48
|
/**
|
|
71
|
-
* 從新系統 .collaboration 載入
|
|
72
49
|
* @param {string} taskId
|
|
73
|
-
* @param {string} projectRoot
|
|
50
|
+
* @param {string} projectRoot
|
|
74
51
|
*/
|
|
75
|
-
function
|
|
52
|
+
function loadTaskFromApi(taskId, projectRoot) {
|
|
76
53
|
if (!fs.existsSync(COLLABORATION_API)) return null;
|
|
77
54
|
try {
|
|
78
|
-
//
|
|
55
|
+
// When projectRoot differs from the core ROOT, pass --project-path
|
|
79
56
|
const projectArg = projectRoot !== ROOT ? ` --project-path "${projectRoot}"` : '';
|
|
80
57
|
const result = execSync(
|
|
81
58
|
`node "${COLLABORATION_API}"${projectArg} get ${taskId}`,
|
|
@@ -87,104 +64,4 @@ function loadTaskFromCollaboration(taskId, projectRoot) {
|
|
|
87
64
|
return null;
|
|
88
65
|
}
|
|
89
66
|
|
|
90
|
-
|
|
91
|
-
* 從舊系統 YAML 檔載入 (dev/pipeline/completed/ + tasks/)
|
|
92
|
-
* @param {string} taskId
|
|
93
|
-
* @param {string} projectRoot - 專案根目錄
|
|
94
|
-
*/
|
|
95
|
-
function loadTaskFromLegacyYaml(taskId, projectRoot) {
|
|
96
|
-
const pipelineDir = path.join(projectRoot, 'dev', 'pipeline');
|
|
97
|
-
const dirs = ['completed', 'tasks'];
|
|
98
|
-
for (const dir of dirs) {
|
|
99
|
-
const dirPath = path.join(pipelineDir, dir);
|
|
100
|
-
if (!fs.existsSync(dirPath)) continue;
|
|
101
|
-
try {
|
|
102
|
-
const files = fs.readdirSync(dirPath);
|
|
103
|
-
const match = files.find(f => f.startsWith(taskId) && f.endsWith('.yaml'));
|
|
104
|
-
if (match) {
|
|
105
|
-
return fs.readFileSync(path.join(dirPath, match), 'utf8').trim();
|
|
106
|
-
}
|
|
107
|
-
} catch (e) {}
|
|
108
|
-
}
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* 從舊系統 TASK_QUEUE.json 載入
|
|
114
|
-
* @param {string} taskId
|
|
115
|
-
* @param {string} projectRoot - 專案根目錄
|
|
116
|
-
*/
|
|
117
|
-
function loadTaskFromLegacyQueue(taskId, projectRoot) {
|
|
118
|
-
const queuePath = path.join(projectRoot, 'dev', 'pipeline', 'TASK_QUEUE.json');
|
|
119
|
-
if (!fs.existsSync(queuePath)) return null;
|
|
120
|
-
try {
|
|
121
|
-
const queue = JSON.parse(fs.readFileSync(queuePath, 'utf8'));
|
|
122
|
-
const task = (queue.tasks || []).find(t => t.id === taskId);
|
|
123
|
-
if (task) {
|
|
124
|
-
return yaml.dump(task, { lineWidth: -1 });
|
|
125
|
-
}
|
|
126
|
-
} catch (e) {}
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* 列出某個 formation 下所有可用的 skill
|
|
132
|
-
* @param {string} formation - 陣型名稱
|
|
133
|
-
* @returns {string[]} skill 名稱列表
|
|
134
|
-
*/
|
|
135
|
-
function listSkills(formation) {
|
|
136
|
-
const dir = path.join(FORMATION_DIR, formation);
|
|
137
|
-
if (!fs.existsSync(dir)) return [];
|
|
138
|
-
return fs.readdirSync(dir)
|
|
139
|
-
.filter(f => f.endsWith('.yaml'))
|
|
140
|
-
.map(f => f.replace('.yaml', ''));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* 載入 specialist 定義(5 個 YAML 檔案)
|
|
145
|
-
* @param {string} name - specialist 名稱 (e.g., "Ansuz", "Amelia")
|
|
146
|
-
* @returns {object} { principles, workflow, knowledge, rule, capability }
|
|
147
|
-
*/
|
|
148
|
-
function loadSpecialist(name) {
|
|
149
|
-
const specialistDir = path.join(ROOT, '.specialist', name);
|
|
150
|
-
if (!fs.existsSync(specialistDir)) {
|
|
151
|
-
console.error(`❌ Specialist not found: ${specialistDir}`);
|
|
152
|
-
process.exit(1);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const files = ['principles', 'workflow', 'knowledge', 'rule', 'capability'];
|
|
156
|
-
const specialist = { name };
|
|
157
|
-
|
|
158
|
-
for (const file of files) {
|
|
159
|
-
const filePath = path.join(specialistDir, `${file}.yaml`);
|
|
160
|
-
if (!fs.existsSync(filePath)) {
|
|
161
|
-
console.warn(`⚠️ Missing ${file}.yaml for specialist ${name}`);
|
|
162
|
-
specialist[file] = null;
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
try {
|
|
166
|
-
specialist[file] = yaml.load(fs.readFileSync(filePath, 'utf8'));
|
|
167
|
-
} catch (e) {
|
|
168
|
-
console.error(`❌ Failed to parse ${filePath}: ${e.message}`);
|
|
169
|
-
process.exit(1);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return specialist;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* 列出所有可用的 specialist
|
|
178
|
-
* @returns {string[]} specialist 名稱列表
|
|
179
|
-
*/
|
|
180
|
-
function listSpecialists() {
|
|
181
|
-
const specialistDir = path.join(ROOT, '.specialist');
|
|
182
|
-
if (!fs.existsSync(specialistDir)) return [];
|
|
183
|
-
return fs.readdirSync(specialistDir)
|
|
184
|
-
.filter(f => {
|
|
185
|
-
const stat = fs.statSync(path.join(specialistDir, f));
|
|
186
|
-
return stat.isDirectory();
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
module.exports = { loadSkill, loadTask, listSkills, loadSpecialist, listSpecialists };
|
|
67
|
+
module.exports = { loadSkill, loadTask };
|
|
@@ -54,7 +54,6 @@
|
|
|
54
54
|
* | 2.5d | Safety net: force-move to done | merge succeeded but complete() failed | spawnSync | task stays in active |
|
|
55
55
|
* | 2.6b | Ansuz inbox signal | result.taskCompleted && !dryRun | catch (silent) | Ansuz not notified |
|
|
56
56
|
* | 2.6c | Relay task_completed event (TASK_1409) | result.taskCompleted && !dryRun && relay | catch (silent) | PM inbox not notified cross-node |
|
|
57
|
-
* | 3 | Memory agent onTaskCompleted/onError | memoryAgent && taskId | catch (log warning) | memory event not queued |
|
|
58
57
|
*
|
|
59
58
|
* A.2 gitBranchAndMerge() — serial mode (L2344)
|
|
60
59
|
*
|
|
@@ -301,12 +300,6 @@ const { verify: verifyAcceptance } = require('./verify-acceptance');
|
|
|
301
300
|
// LLM-based acceptance verification (./verify-acceptance.js) remains and is the
|
|
302
301
|
// one whose result (result.git.acceptance) is actually read.
|
|
303
302
|
|
|
304
|
-
// Memory Agent(記憶系統整合)
|
|
305
|
-
let memoryAgent = null;
|
|
306
|
-
try {
|
|
307
|
-
memoryAgent = require('../../.memory/tools/memory-agent');
|
|
308
|
-
} catch { /* memory-agent not available — graceful degradation */ }
|
|
309
|
-
|
|
310
303
|
// Design Reasoning Attribution (TASK_1074)
|
|
311
304
|
let designReasoning = null;
|
|
312
305
|
try {
|
|
@@ -587,7 +580,6 @@ function listDaemonManagedPaths(projectRoot) {
|
|
|
587
580
|
|
|
588
581
|
scanDir('.synapse');
|
|
589
582
|
scanDir('.prefrontal');
|
|
590
|
-
scanDir('.memory');
|
|
591
583
|
if (fs.existsSync(path.join(projectRoot, '.tmp'))) discovered.add('.tmp/');
|
|
592
584
|
|
|
593
585
|
return Array.from(discovered);
|
|
@@ -3003,29 +2995,6 @@ function postComplete(opts = {}) {
|
|
|
3003
2995
|
} catch { /* fire-and-forget — never blocks post-complete */ }
|
|
3004
2996
|
}
|
|
3005
2997
|
|
|
3006
|
-
// Step 3: Memory Agent(記憶系統整合)
|
|
3007
|
-
if (memoryAgent && taskId) {
|
|
3008
|
-
try {
|
|
3009
|
-
const testsFailed = result.git?.regression && !result.git.regression.passed && !result.git.regression.skipped;
|
|
3010
|
-
if (testsFailed) {
|
|
3011
|
-
// 回歸測試失敗 → onError(fire-and-forget)
|
|
3012
|
-
memoryAgent.onError({
|
|
3013
|
-
event: 'regression_test_failure',
|
|
3014
|
-
taskId,
|
|
3015
|
-
error: `Regression tests failed after ${taskId} completion`,
|
|
3016
|
-
summary: result.git.regression.output?.slice(-500),
|
|
3017
|
-
}).catch(() => {});
|
|
3018
|
-
console.log(' 🧠 Memory: error event queued (regression failure)');
|
|
3019
|
-
} else {
|
|
3020
|
-
// 任務成功完成 → onTaskCompleted(fire-and-forget)
|
|
3021
|
-
memoryAgent.onTaskCompleted(taskId).catch(() => {});
|
|
3022
|
-
console.log(' 🧠 Memory: task completion event queued');
|
|
3023
|
-
}
|
|
3024
|
-
} catch (e) {
|
|
3025
|
-
console.log(` ⚠️ Memory agent skipped: ${e.message}`);
|
|
3026
|
-
}
|
|
3027
|
-
}
|
|
3028
|
-
|
|
3029
2998
|
// Step 4.6: Guard Failure Detector (TASK_1653)
|
|
3030
2999
|
// Runs shadow-mode failure detectors for active lesson guards that carry failure_signature.
|
|
3031
3000
|
// Reads guard snapshots directly from lesson_guards.yaml (not the task chart) because
|
package/core/.rule/INDEX.yaml
CHANGED
|
@@ -24,8 +24,6 @@ load_order:
|
|
|
24
24
|
description: "GEN-009: 跨平台相容原則 - Windows/macOS/Linux 三平台相容性要求"
|
|
25
25
|
- path: "general/agent-workflow.yaml"
|
|
26
26
|
description: "Agent 工作流程 - 記憶點優先 + 邊界意識 + Context Integrity Canary(AGT-001 至 AGT-009)"
|
|
27
|
-
- path: "general/sunny-access-control.yaml"
|
|
28
|
-
description: "SEC-010: Sunny 系統存取控制 - 禁止其他 Agent 存取 .system/sunny/"
|
|
29
27
|
- path: "general/synapse-code-intelligence.yaml"
|
|
30
28
|
description: "SYN-001~007: 代碼導航 — kenaz_lsp_* 代碼導航、Grep/Glob 文字與概念搜尋。記憶層 synapse_* 工具已於 2026-10-11 移除(TASK_2411)"
|
|
31
29
|
# 2026-10-11 (TASK_2411): synapse-cognitive-fusion.yaml, cortex-tools.yaml, memory-source-priority.yaml, memory-language.yaml deleted - memory system removed.
|
|
@@ -41,14 +39,6 @@ load_order:
|
|
|
41
39
|
description: "VERIFY-TGT-001~002: Rust 驗證正典 CARGO_TARGET_DIR — 單一共用目錄(dev/scripts/verify-target-dir.js),禁止自創目錄;並行驗證被 cargo 檔案鎖串行化屬正常等待"
|
|
42
40
|
- path: "general/task-pool-routing.yaml"
|
|
43
41
|
description: "POOL-001~003: 本地任務 vs 任務池 路由規則 — 詞彙驅動路由、術語一致性、Pool 操作安全(publish/claim 破壞性語義)"
|
|
44
|
-
- path: "general/pipeline.yaml"
|
|
45
|
-
description: "Pipeline 系統規則 - 任務管理規範"
|
|
46
|
-
- path: "pipeline/PPL-002-completed-task-archival.yaml"
|
|
47
|
-
description: "已完成任務封存規則 - 防止佇列污染"
|
|
48
|
-
- path: "pipeline/auto-update.yaml"
|
|
49
|
-
description: "PPL-003 - 任務完成後必須更新 Pipeline 系統(Critical)"
|
|
50
|
-
- path: "pipeline/task-execution.yaml"
|
|
51
|
-
description: "PPL-101 至 PPL-113 - Pipeline 任務執行規範(拆分、依賴、並行、回歸保護等)"
|
|
52
42
|
|
|
53
43
|
# Code 規則組 - 從核心原則到具體實踐
|
|
54
44
|
- path: "code/principles.yaml"
|
|
@@ -70,14 +60,6 @@ load_order:
|
|
|
70
60
|
|
|
71
61
|
- path: "design/ui.yaml"
|
|
72
62
|
description: "UI 設計規範"
|
|
73
|
-
- path: "design/ux.yaml"
|
|
74
|
-
description: "UX 設計原則"
|
|
75
|
-
- path: "design/colors.yaml"
|
|
76
|
-
description: "色彩系統"
|
|
77
|
-
- path: "architecture/decisions.yaml"
|
|
78
|
-
description: "架構決策記錄"
|
|
79
|
-
- path: "business/constraints.yaml"
|
|
80
|
-
description: "業務邏輯約束"
|
|
81
63
|
|
|
82
64
|
# 嚴重程度定義
|
|
83
65
|
severity_levels:
|