principles-disciple 1.209.4 → 1.209.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.
Files changed (132) hide show
  1. package/README.md +73 -0
  2. package/dist/bundle.js +13 -11
  3. package/dist/constants/tools.d.ts +1 -1
  4. package/dist/hooks/prompt-helpers.d.ts +5 -5
  5. package/dist/openclaw.plugin.json +1 -1
  6. package/dist/templates/langs/en/core/AGENTS.md +40 -180
  7. package/dist/templates/langs/en/core/BOOT.md +19 -47
  8. package/dist/templates/langs/en/core/HEARTBEAT.md +26 -58
  9. package/dist/templates/langs/en/core/IDENTITY.md +15 -8
  10. package/dist/templates/langs/en/core/PRINCIPLES.md +6 -7
  11. package/dist/templates/langs/en/core/SOUL.md +10 -41
  12. package/dist/templates/langs/en/core/TOOLS.md +18 -10
  13. package/dist/templates/langs/en/core/USER.md +13 -8
  14. package/dist/templates/langs/en/skills/pd-auditor/SKILL.md +1 -1
  15. package/dist/templates/langs/en/skills/pd-explorer/SKILL.md +1 -1
  16. package/dist/templates/langs/en/skills/pd-implementer/SKILL.md +1 -1
  17. package/dist/templates/langs/en/skills/pd-mentor/SKILL.md +6 -30
  18. package/dist/templates/langs/en/skills/pd-planner/SKILL.md +1 -1
  19. package/dist/templates/langs/zh/core/AGENTS.md +38 -173
  20. package/dist/templates/langs/zh/core/BOOT.md +14 -46
  21. package/dist/templates/langs/zh/core/HEARTBEAT.md +20 -82
  22. package/dist/templates/langs/zh/core/IDENTITY.md +15 -8
  23. package/dist/templates/langs/zh/core/PRINCIPLES.md +7 -7
  24. package/dist/templates/langs/zh/core/SOUL.md +9 -41
  25. package/dist/templates/langs/zh/core/TOOLS.md +14 -10
  26. package/dist/templates/langs/zh/core/USER.md +12 -8
  27. package/dist/templates/langs/zh/skills/pd-auditor/SKILL.md +1 -1
  28. package/dist/templates/langs/zh/skills/pd-explorer/SKILL.md +1 -1
  29. package/dist/templates/langs/zh/skills/pd-implementer/SKILL.md +1 -1
  30. package/dist/templates/langs/zh/skills/pd-mentor/SKILL.md +6 -30
  31. package/dist/templates/langs/zh/skills/pd-planner/SKILL.md +1 -1
  32. package/dist/templates/pain_settings.json +1 -2
  33. package/openclaw.plugin.json +1 -1
  34. package/package.json +1 -2
  35. package/templates/langs/en/core/AGENTS.md +40 -180
  36. package/templates/langs/en/core/BOOT.md +19 -47
  37. package/templates/langs/en/core/HEARTBEAT.md +26 -58
  38. package/templates/langs/en/core/IDENTITY.md +15 -8
  39. package/templates/langs/en/core/PRINCIPLES.md +6 -7
  40. package/templates/langs/en/core/SOUL.md +10 -41
  41. package/templates/langs/en/core/TOOLS.md +18 -10
  42. package/templates/langs/en/core/USER.md +13 -8
  43. package/templates/langs/en/skills/pd-auditor/SKILL.md +1 -1
  44. package/templates/langs/en/skills/pd-explorer/SKILL.md +1 -1
  45. package/templates/langs/en/skills/pd-implementer/SKILL.md +1 -1
  46. package/templates/langs/en/skills/pd-mentor/SKILL.md +6 -30
  47. package/templates/langs/en/skills/pd-planner/SKILL.md +1 -1
  48. package/templates/langs/zh/core/AGENTS.md +38 -173
  49. package/templates/langs/zh/core/BOOT.md +14 -46
  50. package/templates/langs/zh/core/HEARTBEAT.md +20 -82
  51. package/templates/langs/zh/core/IDENTITY.md +15 -8
  52. package/templates/langs/zh/core/PRINCIPLES.md +7 -7
  53. package/templates/langs/zh/core/SOUL.md +9 -41
  54. package/templates/langs/zh/core/TOOLS.md +14 -10
  55. package/templates/langs/zh/core/USER.md +12 -8
  56. package/templates/langs/zh/skills/pd-auditor/SKILL.md +1 -1
  57. package/templates/langs/zh/skills/pd-explorer/SKILL.md +1 -1
  58. package/templates/langs/zh/skills/pd-implementer/SKILL.md +1 -1
  59. package/templates/langs/zh/skills/pd-mentor/SKILL.md +6 -30
  60. package/templates/langs/zh/skills/pd-planner/SKILL.md +1 -1
  61. package/templates/pain_settings.json +1 -2
  62. package/dist/templates/langs/en/core/BOOTSTRAP.md +0 -259
  63. package/dist/templates/langs/en/skills/admin/SKILL.md +0 -39
  64. package/dist/templates/langs/en/skills/bootstrap-tools/SKILL.md +0 -53
  65. package/dist/templates/langs/en/skills/deductive-audit/SKILL.md +0 -36
  66. package/dist/templates/langs/en/skills/evolution-framework-update/SKILL.md +0 -31
  67. package/dist/templates/langs/en/skills/evolve-task/SKILL.md +0 -83
  68. package/dist/templates/langs/en/skills/feedback/SKILL.md +0 -51
  69. package/dist/templates/langs/en/skills/init-strategy/SKILL.md +0 -54
  70. package/dist/templates/langs/en/skills/inject-rule/SKILL.md +0 -19
  71. package/dist/templates/langs/en/skills/profile/SKILL.md +0 -24
  72. package/dist/templates/langs/en/skills/reflection/SKILL.md +0 -40
  73. package/dist/templates/langs/en/skills/reflection-log/SKILL.md +0 -37
  74. package/dist/templates/langs/en/skills/report/SKILL.md +0 -13
  75. package/dist/templates/langs/en/skills/root-cause/SKILL.md +0 -33
  76. package/dist/templates/langs/en/skills/triage/SKILL.md +0 -29
  77. package/dist/templates/langs/en/skills/watch-evolution/SKILL.md +0 -33
  78. package/dist/templates/langs/zh/core/BOOTSTRAP.md +0 -260
  79. package/dist/templates/langs/zh/skills/admin/SKILL.md +0 -41
  80. package/dist/templates/langs/zh/skills/bootstrap-tools/SKILL.md +0 -52
  81. package/dist/templates/langs/zh/skills/deductive-audit/SKILL.md +0 -36
  82. package/dist/templates/langs/zh/skills/evolution-framework-update/SKILL.md +0 -31
  83. package/dist/templates/langs/zh/skills/evolve-task/SKILL.md +0 -83
  84. package/dist/templates/langs/zh/skills/feedback/SKILL.md +0 -53
  85. package/dist/templates/langs/zh/skills/init-strategy/SKILL.md +0 -54
  86. package/dist/templates/langs/zh/skills/inject-rule/SKILL.md +0 -19
  87. package/dist/templates/langs/zh/skills/profile/SKILL.md +0 -24
  88. package/dist/templates/langs/zh/skills/reflection/SKILL.md +0 -40
  89. package/dist/templates/langs/zh/skills/reflection-log/SKILL.md +0 -37
  90. package/dist/templates/langs/zh/skills/report/SKILL.md +0 -13
  91. package/dist/templates/langs/zh/skills/root-cause/SKILL.md +0 -33
  92. package/dist/templates/langs/zh/skills/triage/SKILL.md +0 -29
  93. package/dist/templates/langs/zh/skills/watch-evolution/SKILL.md +0 -33
  94. package/scripts/acceptance-test.mjs +0 -257
  95. package/scripts/bootstrap-rules.mjs +0 -70
  96. package/scripts/compile-principles.mjs +0 -104
  97. package/scripts/install-dependencies.cjs +0 -47
  98. package/scripts/postinstall.cjs +0 -177
  99. package/scripts/sync-plugin.mjs +0 -1442
  100. package/scripts/verify-build.mjs +0 -120
  101. package/templates/langs/en/core/BOOTSTRAP.md +0 -259
  102. package/templates/langs/en/skills/admin/SKILL.md +0 -39
  103. package/templates/langs/en/skills/bootstrap-tools/SKILL.md +0 -53
  104. package/templates/langs/en/skills/deductive-audit/SKILL.md +0 -36
  105. package/templates/langs/en/skills/evolution-framework-update/SKILL.md +0 -31
  106. package/templates/langs/en/skills/evolve-task/SKILL.md +0 -83
  107. package/templates/langs/en/skills/feedback/SKILL.md +0 -51
  108. package/templates/langs/en/skills/init-strategy/SKILL.md +0 -54
  109. package/templates/langs/en/skills/inject-rule/SKILL.md +0 -19
  110. package/templates/langs/en/skills/profile/SKILL.md +0 -24
  111. package/templates/langs/en/skills/reflection/SKILL.md +0 -40
  112. package/templates/langs/en/skills/reflection-log/SKILL.md +0 -37
  113. package/templates/langs/en/skills/report/SKILL.md +0 -13
  114. package/templates/langs/en/skills/root-cause/SKILL.md +0 -33
  115. package/templates/langs/en/skills/triage/SKILL.md +0 -29
  116. package/templates/langs/en/skills/watch-evolution/SKILL.md +0 -33
  117. package/templates/langs/zh/core/BOOTSTRAP.md +0 -260
  118. package/templates/langs/zh/skills/admin/SKILL.md +0 -41
  119. package/templates/langs/zh/skills/bootstrap-tools/SKILL.md +0 -52
  120. package/templates/langs/zh/skills/deductive-audit/SKILL.md +0 -36
  121. package/templates/langs/zh/skills/evolution-framework-update/SKILL.md +0 -31
  122. package/templates/langs/zh/skills/evolve-task/SKILL.md +0 -83
  123. package/templates/langs/zh/skills/feedback/SKILL.md +0 -53
  124. package/templates/langs/zh/skills/init-strategy/SKILL.md +0 -54
  125. package/templates/langs/zh/skills/inject-rule/SKILL.md +0 -19
  126. package/templates/langs/zh/skills/profile/SKILL.md +0 -24
  127. package/templates/langs/zh/skills/reflection/SKILL.md +0 -40
  128. package/templates/langs/zh/skills/reflection-log/SKILL.md +0 -37
  129. package/templates/langs/zh/skills/report/SKILL.md +0 -13
  130. package/templates/langs/zh/skills/root-cause/SKILL.md +0 -33
  131. package/templates/langs/zh/skills/triage/SKILL.md +0 -29
  132. package/templates/langs/zh/skills/watch-evolution/SKILL.md +0 -33
@@ -1,40 +0,0 @@
1
- ---
2
- name: reflection
3
- description: Perform a deep metacognitive reflection on the current task status, user sentiment, and systemic issues. Use this before context compaction or when stuck.
4
- disable-model-invocation: false
5
- ---
6
-
7
- # 痛定思痛 (Metacognitive Reflection)
8
-
9
- **触发场景**: 上下文即将压缩 (Memory Loss Imminent) 或 任务长期停滞。
10
- **目标**: 在遗忘详细过程之前,提取“痛苦教训”并固化为原则。
11
-
12
- 请执行以下反思步骤:
13
-
14
- ## 1. 现状扫描 (Status Scan)
15
- - **Goal**: 我们最初的目标是什么?(检查早期对话上下文)
16
- - **Status**: 现在完成了多少?卡在哪里?
17
- - **Cost**: 我们消耗了大量 Token,产出是否匹配?
18
-
19
- ## 2. 痛苦感知 (Pain Detection)
20
- 请诚实回答以下问题(Yes/No):
21
- - [ ] **任务停滞**: 是否连续 3 轮以上没有实质性代码进展?
22
- - [ ] **重复犯错**: 是否有 Bug 被修复后又重现,或同样的错误报了两次?
23
- - [ ] **用户挫败**: 用户是否使用了“不对”、“不是”、“停下”等否定词,或语气变得急躁?
24
- - [ ] **盲目行动**: 是否在没有 PLAN 或 AUDIT 的情况下直接修改了代码?
25
- - [ ] **架构劣化**: 现在的代码是否比开始时更乱了?
26
-
27
- ## 3. 根因分析 (If Pain Detected)
28
- 如果上述任一为 Yes,必须进行深层归因:
29
- - **Direct Cause**: 我们做了什么(或没做什么)导致了现在的局面?
30
- - **Root Cause**: 思维模型哪里出了问题?(是太急于求成?还是忽视了已有文件?还是轻视了测试?)
31
-
32
- ## 4. 进化落盘 (Evolution)
33
- 如果检测到痛苦,必须执行:
34
- 1. **记录**: 将分析结果写入 `memory/ISSUE_LOG.md`。
35
- 2. **提炼**: 如果这是第二次发生,提炼一条 **禁止性原则 (Must NOT)**。
36
- 3. **加固**: 建议一个具体的 Hook 或 Test 来防止未来重犯。
37
-
38
- ## 5. 恢复计划 (Recovery)
39
- - 既然要压缩上下文,我们下一步该如何以“最干净”的状态继续?
40
- - 更新 `memory/.scratchpad.md`,标记当前进度,确保压缩后能无缝衔接。
@@ -1,37 +0,0 @@
1
- ---
2
- name: reflection-log
3
- description: Final task reflection and evolution logging. Use to capture pain signals, update profiles, and propose new principles.
4
- disable-model-invocation: true
5
- ---
6
-
7
- # Reflection & Evolution (反思与落盘)
8
-
9
- **目标**: 将单次任务的经验转化为系统的永久记忆。
10
-
11
- 请执行以下结项操作:
12
-
13
- ## 1. Pain Summary (痛苦摘要)
14
- - 简述本次任务中最折磨、最耗时或导致失败的点。
15
-
16
- ## 2. Issue Logging
17
- - **Action**: 将详细的 Pain Signal 和诊断结果追加到 `memory/ISSUE_LOG.md`。
18
-
19
- ## 3. Evolution Candidates
20
- - **Principle**: 提议一条新原则(P-XX)。
21
- - **Guardrail**: 建议一个具体的 Hook、Rule 或 Test。
22
- - **路径拦截**: 建议将敏感目录加入 `.principles/PROFILE.json` 的 `risk_paths`。
23
- - **行为拦截**: 建议在 `.principles/PROFILE.json` 的 `custom_guards` 中添加正则,以拦截特定工具的危险调用(如 `Edit.*SYSTEM`)。
24
-
25
- ## 4. Positive Reinforcement (正向强化)
26
- - **检查卓越信号**:
27
- 1. 用户明确的赞赏 (Quote user).
28
- 2. 性能/质量指标的客观跃迁 (Cite data).
29
- 3. Reviewer 的高度评价 (Excellent/Elegant).
30
- - **提取模式**: 如果存在上述信号,在 `.state/.user_verdict.json` 中额外记录 `achievement` 字段,描述本次成功的行为模式。
31
-
32
- ## 5. Attribution (画像更新)
33
- - **Agent Scorecard**: 评估本次使用的子智能体表现,写入 `.state/.verdict.json`。格式遵循 `@.principles/schemas/agent_verdict_schema.json`。
34
- - **User Profile**: 评估用户指令质量与偏好,写入 `.state/.user_verdict.json`。格式遵循 `@.principles/schemas/user_verdict_schema.json`。
35
-
36
- ## 6. Cleanup
37
- - 清理所有中间标记文件(如 `.pain_flag`, `.verdict.json` 等)。
@@ -1,13 +0,0 @@
1
- ---
2
- name: report
3
- description: Manually request a formal status report from the Reporter agent.
4
- disable-model-invocation: true
5
- ---
6
-
7
- # /report: 获取工作汇报
8
-
9
- 用户(老板)要求立即汇报工作。
10
-
11
- ## 执行动作
12
- 1. 立即委派 ``pd_spawn_agent(reporter)``。
13
- 2. 任务描述:“老板想知道当前的情况。请分析当前的对话上下文和最近的 `memory/ISSUE_LOG.md`,为老板写一份优雅的汇报。请记住先看他的画像!”
@@ -1,33 +0,0 @@
1
- ---
2
- name: root-cause
3
- description: Deep dive analysis into why a problem occurred. Uses the 5 Whys method and classifies the cause.
4
- disable-model-invocation: true
5
- ---
6
-
7
- # Root Cause Analysis (根因分析)
8
-
9
- **目标**: 穿透现象看本质,防止重复犯错。
10
-
11
- 请按以下格式执行诊断:
12
-
13
- ## 1. Proximal Cause (直接原因)
14
- - **动词驱动**: 描述了什么具体操作或缺失导致了即时失败。
15
-
16
- ## 2. 5 Whys (深度追问)
17
- 1. 为什么直接原因会发生?
18
- 2. ...
19
- 3. ...
20
- 4. ...
21
- 5. 追问到系统性或认知性根源。
22
-
23
- ## 3. Root Cause (根本原因)
24
- - **形容词/设计驱动**: 描述系统架构、流程缺陷或错误的假设。
25
- - **Guardrail Failure Analysis**: 为什么现有的门禁 (Hooks) 或 规则 (Rules) 没能拦截这个错误?是规则缺失、匹配不严还是逻辑漏洞?
26
-
27
- ## 4. Category (分类)
28
- - [ ] **People**: 能力盲区、习惯问题。
29
- - [ ] **Design**: 流程/工具缺陷、门禁不足、架构漏洞。
30
- - [ ] **Assumption**: 对环境、版本或依赖的错误前提假设。
31
-
32
- ## 5. Principle Candidate (原则提炼)
33
- - 如果我们修复了这个问题,应该增加什么原则防止它再次发生?
@@ -1,29 +0,0 @@
1
- ---
2
- name: triage
3
- description: Initial problem definition and risk assessment. Use to collect environment info, reproduction steps, and logs.
4
- disable-model-invocation: true
5
- ---
6
-
7
- # Triage (问题分诊)
8
-
9
- **目标**: 收集足够的证据来定义问题,并评估变更风险。
10
-
11
- 请按以下结构输出:
12
-
13
- ## 1. Goal (目标)
14
- - 一句话描述本次任务的最终成功标准。
15
-
16
- ## 2. Problem (问题描述)
17
- - 当前发生了什么?预期的行为是什么?
18
- - **Evidence**: 列出相关的日志片段、错误代码或观察到的异常现象。
19
-
20
- ## 3. Reproduction (复现步骤)
21
- - 提供明确的复现命令或操作序列。
22
- - 标注当前环境的关键变量。
23
-
24
- ## 4. Scope (范围)
25
- - 涉及的文件或模块预览。
26
- - **Risk Level**: Low / Medium / High (基于 `.principles/PROFILE.json` 定义)。
27
-
28
- ## 5. Next Step
29
- - 建议委派哪个子智能体 (通常是 Explorer) 进一步收集证据。
@@ -1,33 +0,0 @@
1
- ---
2
- name: watch-evolution
3
- description: Start the background evolution daemon to process queued tasks from EVOLUTION_QUEUE.json.
4
- ---
5
-
6
- # /watch-evolution: 后台进化守护者
7
-
8
- **目标**: 启动一个持续运行的进程,自动分析并修复积压的代码问题。
9
-
10
- ## 1. 运行环境准备
11
- - 确保已配置 `.principles/PROFILE.json` 中的 `evolution_mode: "async"`。
12
- - 确保 `.state/evolution_queue.json` 存在。
13
-
14
- ## 2. 启动指令
15
- 请运行以下命令启动守护进程:
16
-
17
- ```bash
18
- python scripts/evolution_daemon.py
19
- ```
20
-
21
- ## 3. 工作流程
22
- 1. **自动扫描**: 每隔 30 秒扫描一次 `.state/evolution_queue.json`。
23
- 2. **调度策略**:
24
- - 按 `priority` 从高到低处理任务(高优先级先执行)。
25
- - `status: retrying` 的任务仅在 `next_retry_at` 到期后才会再次执行。
26
- - 失败任务进入指数退避重试,超过最大尝试次数后标记为 `failed`。
27
- 3. **诊断 (Diagnosis)**: 加载 `root-cause` 技能,通过 Headless 模式定位错误根因。
28
- 4. **修复 (Fix)**: 加载修复技能,自动修改代码并运行测试。
29
- 5. **落盘 (Log)**: 调用 `reflection-log` 将经验存入 `PRINCIPLES.md` 和 `ISSUE_LOG.md`。
30
- 6. **看板**: 实时更新 `memory/EVOLUTION_PRD.md` 展示进度。
31
-
32
- ## 4. 退出
33
- - 按 `Ctrl+C` 停止后台任务。任务的状态将被保留在 JSON 中,下次启动可继续执行。
@@ -1,257 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * PD Pipeline — End-to-End Acceptance Test
5
- *
6
- * Verifies that all components of the PD reflection pipeline
7
- * work correctly in a real environment (not unit tests).
8
- *
9
- * Usage:
10
- * node scripts/acceptance-test.mjs --workspace /path/to/workspace
11
- *
12
- * Output: Pass/Fail for each checkpoint with detailed diagnostics.
13
- */
14
-
15
- import { existsSync, readFileSync, writeFileSync, rmSync, mkdirSync, readdirSync } from 'fs';
16
- import { join, dirname } from 'path';
17
- import { fileURLToPath } from 'url';
18
- import { execFileSync } from 'child_process';
19
-
20
- const __filename = fileURLToPath(import.meta.url);
21
- const __dirname = dirname(__filename);
22
-
23
- // ─── Helpers ───
24
- let passCount = 0;
25
- let failCount = 0;
26
- let warnCount = 0;
27
-
28
- function assert(condition, testName, detail = '') {
29
- if (condition) {
30
- console.log(` ✅ ${testName}`);
31
- passCount++;
32
- } else {
33
- console.log(` ❌ ${testName}${detail ? ` — ${detail}` : ''}`);
34
- failCount++;
35
- }
36
- }
37
-
38
- function warn(testName, detail = '') {
39
- console.log(` ⚠️ ${testName}${detail ? ` — ${detail}` : ''}`);
40
- warnCount++;
41
- }
42
-
43
- function runSql(dbPath, sql) {
44
- return execFileSync('sqlite3', [dbPath, sql], {
45
- encoding: 'utf-8',
46
- timeout: 5000,
47
- }).trim();
48
- }
49
-
50
- // ─── Parse workspace ───
51
- function parseArgs() {
52
- const argv = process.argv.slice(2);
53
- for (let i = 0; i < argv.length; i++) {
54
- if (argv[i] === '--workspace' && argv[i + 1]) return argv[++i];
55
- }
56
- try {
57
- return execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf-8' }).trim();
58
- } catch {
59
- return process.cwd();
60
- }
61
- }
62
-
63
- // ─── Main ───
64
- function main() {
65
- const workspaceDir = parseArgs();
66
- const stateDir = join(workspaceDir, '.state');
67
- const dbPath = join(stateDir, 'trajectory.db');
68
-
69
- if (!existsSync(dbPath)) {
70
- console.error('❌ trajectory.db not found. Run seed script first.');
71
- process.exit(1);
72
- }
73
-
74
- console.log('\n🧪 PD Pipeline Acceptance Test');
75
- console.log('═'.repeat(55));
76
- console.log(`Workspace: ${workspaceDir}`);
77
- console.log(`Database: ${dbPath}\n`);
78
-
79
- // ═══════════════════════════════════════════════
80
- // SECTION 1: Seed Scenario Data Integrity
81
- // ═══════════════════════════════════════════════
82
- console.log('── 1. Seed Scenario Data Integrity ──');
83
-
84
- // 1.1 Count seed sessions
85
- const sessionCount = parseInt(runSql(dbPath, "SELECT COUNT(*) FROM sessions WHERE session_id LIKE 'seed-%';"));
86
- assert(sessionCount === 10, '10 seed sessions exist', `found ${sessionCount}`);
87
-
88
- // 1.2 Count seed pain events
89
- const painCount = parseInt(runSql(dbPath, "SELECT COUNT(*) FROM pain_events WHERE session_id LIKE 'seed-%';"));
90
- assert(painCount >= 10, 'Pain events exist for seed sessions', `found ${painCount}`);
91
-
92
- // 1.3 Verify signal diversity
93
- const sources = runSql(dbPath, "SELECT DISTINCT source FROM pain_events WHERE session_id LIKE 'seed-%';").split('\n');
94
- assert(sources.includes('tool_failure'), 'tool_failure signal present');
95
- assert(sources.includes('user_empathy'), 'user_empathy signal present');
96
-
97
- // 1.4 Verify pain event scores are in valid range
98
- const invalidScores = runSql(dbPath, "SELECT COUNT(*) FROM pain_events WHERE session_id LIKE 'seed-%' AND (score < 0 OR score > 100);");
99
- assert(parseInt(invalidScores) === 0, 'All pain scores in 0-100 range', `${invalidScores} invalid`);
100
-
101
- // 1.5 Verify correction cues exist
102
- const correctionCount = parseInt(runSql(dbPath, "SELECT COUNT(*) FROM user_turns WHERE session_id LIKE 'seed-%' AND correction_detected = 1;"));
103
- assert(correctionCount >= 5, 'Multiple correction cues present', `found ${correctionCount}`);
104
-
105
- // 1.6 Verify tool calls (both success and failure)
106
- const failureCalls = parseInt(runSql(dbPath, "SELECT COUNT(*) FROM tool_calls WHERE session_id LIKE 'seed-%' AND outcome = 'failure';"));
107
- const successCalls = parseInt(runSql(dbPath, "SELECT COUNT(*) FROM tool_calls WHERE session_id LIKE 'seed-%' AND outcome = 'success';"));
108
- assert(failureCalls > 0, 'Failed tool calls in seed data', `found ${failureCalls}`);
109
- assert(successCalls > 0, 'Successful tool calls in seed data', `found ${successCalls}`);
110
-
111
- // 1.7 Verify scenario descriptions are unique and meaningful
112
- const reasons = runSql(dbPath, "SELECT DISTINCT reason FROM pain_events WHERE session_id LIKE 'seed-%' ORDER BY reason;").split('\n');
113
- const uniqueReasons = new Set(reasons);
114
- assert(uniqueReasons.size === reasons.length, 'All pain reasons are unique', `${uniqueReasons.size}/${reasons.length} unique`);
115
-
116
- // ═══════════════════════════════════════════════
117
- // SECTION 2: PainSignalBridge + Runtime v2
118
- // ═══════════════════════════════════════════════
119
- console.log('\n── 2. PainSignalBridge + Runtime v2 ──');
120
-
121
- // 2.1 Verify PainSignalBridge is imported from runtime-v2 in pain.ts
122
- const painHookSource = join(__dirname, '..', 'src', 'hooks', 'pain.ts');
123
- if (existsSync(painHookSource)) {
124
- const painContent = readFileSync(painHookSource, 'utf-8');
125
- assert(painContent.includes('PainToPrincipleService'), 'pain.ts uses PainToPrincipleService from runtime-v2');
126
- assert(!painContent.includes('createPainSignalBridge'), 'pain.ts no longer imports createPainSignalBridge');
127
- }
128
-
129
- // 2.2 Verify write_pain_flag tool is NOT registered in index.ts
130
- const indexSource2 = join(__dirname, '..', 'src', 'index.ts');
131
- if (existsSync(indexSource2)) {
132
- const indexContent = readFileSync(indexSource2, 'utf-8');
133
- assert(!indexContent.includes('createWritePainFlagTool'), 'write_pain_flag NOT registered in index.ts');
134
- }
135
-
136
- // ═══════════════════════════════════════════════
137
- // SECTION 3: Dedup Logic
138
- // ═══════════════════════════════════════════════
139
- console.log('\n── 3. Dedup Logic (Phase 3c) ──');
140
-
141
- const workerSource = join(__dirname, '..', 'src', 'service', 'evolution-worker.ts');
142
- if (existsSync(workerSource)) {
143
- const workerContent = readFileSync(workerSource, 'utf-8');
144
-
145
- // 3.1 Helper functions exist
146
- assert(workerContent.includes('hasRecentSimilarReflection'), 'hasRecentSimilarReflection helper extracted');
147
- assert(workerContent.includes('buildPainSourceKey'), 'buildPainSourceKey helper extracted');
148
- assert(workerContent.includes('shouldSkipForDedup'), 'shouldSkipForDedup helper extracted');
149
-
150
- // 3.2 Dedup window is configured
151
- assert(workerContent.includes('4 * 60 * 60 * 1000') || workerContent.includes('DEDUP_WINDOW_MS'), '4-hour dedup window configured');
152
-
153
- // 3.3 No-pain-context bypass
154
- const bypassCheck = workerContent.includes('!painSourceKey') || workerContent.includes('painSourceKey === null') ||
155
- workerContent.includes('painSourceKey) return false') || workerContent.includes('if (!painSourceKey) return false');
156
- assert(bypassCheck, 'no_pain_context bypasses dedup', 'bypass pattern not found');
157
-
158
- // 3.4 Only completed tasks are checked (not failed)
159
- assert(workerContent.includes("status !== 'completed'") || workerContent.includes("status === 'completed'"), 'Only completed tasks matched for dedup');
160
- } else {
161
- fail('Dedup logic check', 'evolution-worker.ts not found');
162
- }
163
-
164
- // ═══════════════════════════════════════════════
165
- // SECTION 4: Correction Rejected Pain Event
166
- // ═══════════════════════════════════════════════
167
- console.log('\n── 4. Correction Rejected Pain Signal ──');
168
-
169
- const trajectorySource = join(__dirname, '..', 'src', 'core', 'trajectory.ts');
170
- if (existsSync(trajectorySource)) {
171
- const trajContent = readFileSync(trajectorySource, 'utf-8');
172
-
173
- // 4.1 Method exists
174
- assert(trajContent.includes('recordCorrectionRejectedPain'), 'recordCorrectionRejectedPain method exists');
175
-
176
- // 4.2 Called on rejected status
177
- assert(trajContent.includes("status === 'rejected'"), 'Pain event created on rejected status');
178
-
179
- // 4.3 Uses correct source
180
- assert(trajContent.includes("'correction_rejected'"), 'Uses correction_rejected source');
181
-
182
- // 4.4 Score is clamped
183
- assert(trajContent.includes('Math.max(0') && trajContent.includes('Math.min(100'), 'Score clamped 0-100');
184
- } else {
185
- fail('Correction rejected check', 'trajectory.ts not found');
186
- }
187
-
188
- // ═══════════════════════════════════════════════
189
- // SECTION 5: Shell Injection Safety
190
- // ═══════════════════════════════════════════════
191
- console.log('\n── 5. Shell Injection Safety ──');
192
- // (Nocturnal scripts removed in PRI-231 — section retained for future script checks)
193
-
194
- // ═══════════════════════════════════════════════
195
- // SECTION 6: Pending Review Warning Fix
196
- // ═══════════════════════════════════════════════
197
- console.log('\n── 6. Pending Review Warning Fix ──');
198
- // (Nocturnal scripts removed in PRI-231 — section retained for future checks)
199
-
200
- // ═══════════════════════════════════════════════
201
- // SECTION 7: Path Resolver Fallback
202
- // ═══════════════════════════════════════════════
203
- console.log('\n── 7. Path Resolver Fallback ──');
204
-
205
- const pathResolverSource = join(__dirname, '..', 'src', 'core', 'path-resolver.ts');
206
- if (existsSync(pathResolverSource)) {
207
- const prContent = readFileSync(pathResolverSource, 'utf-8');
208
- // 7.1 resolveWorkspaceDirFromApi checks config.workspaceDir
209
- assert(prContent.includes('config.workspaceDir') || prContent.includes('cfgWorkspaceDir'),
210
- 'resolveWorkspaceDirFromApi checks config.workspaceDir');
211
- }
212
-
213
- // ═══════════════════════════════════════════════
214
- // SECTION 8: Seed Scenario Quality (Manual Review)
215
- // ═══════════════════════════════════════════════
216
- console.log('\n── 8. Seed Scenario Quality ──');
217
-
218
- // 8.1 Verify pain score distribution
219
- const avgScore = parseFloat(runSql(dbPath, "SELECT ROUND(AVG(score), 1) FROM pain_events WHERE session_id LIKE 'seed-%';"));
220
- assert(avgScore > 50 && avgScore < 100, 'Average pain score reasonable (50-100)', `avg=${avgScore}`);
221
-
222
- // 8.2 Verify severity levels are set
223
- const nullSeverity = parseInt(runSql(dbPath, "SELECT COUNT(*) FROM pain_events WHERE session_id LIKE 'seed-%' AND severity IS NULL;"));
224
- assert(nullSeverity === 0, 'All seed pain events have severity', `${nullSeverity} null`);
225
-
226
- // 8.3 Verify origin is set
227
- const nullOrigin = parseInt(runSql(dbPath, "SELECT COUNT(*) FROM pain_events WHERE session_id LIKE 'seed-%' AND origin IS NULL;"));
228
- assert(nullOrigin === 0, 'All seed pain events have origin', `${nullOrigin} null`);
229
-
230
- // 8.4 Verify all 10 scenario IDs follow naming convention
231
- const seedSessions = runSql(dbPath, "SELECT session_id FROM sessions WHERE session_id LIKE 'seed-%' ORDER BY session_id;").split('\n');
232
- const validPattern = /^seed-[a-z-]+-\d{3}$/;
233
- const allValid = seedSessions.every(s => validPattern.test(s));
234
- assert(allValid, 'All session IDs follow naming convention', `${seedSessions.filter(s => !validPattern.test(s)).length} invalid`);
235
-
236
- // ═══════════════════════════════════════════════
237
- // SUMMARY
238
- // ═══════════════════════════════════════════════
239
- console.log('\n' + '═'.repeat(55));
240
- console.log(` Acceptance Test Summary`);
241
- console.log('═'.repeat(55));
242
- console.log(` ✅ Passed: ${passCount}`);
243
- console.log(` ❌ Failed: ${failCount}`);
244
- console.log(` ⚠️ Warnings: ${warnCount}`);
245
- console.log(` Total: ${passCount + failCount + warnCount}`);
246
- console.log('═'.repeat(55));
247
-
248
- if (failCount === 0) {
249
- console.log('\n🎉 All acceptance tests passed!');
250
- process.exit(0);
251
- } else {
252
- console.log(`\n❌ ${failCount} test(s) failed. Review details above.`);
253
- process.exit(1);
254
- }
255
- }
256
-
257
- main();
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Minimal Rule Bootstrap CLI (Phase 17)
5
- *
6
- * Seeds 1-3 stub Rule entities for high-value deterministic principles.
7
- * Idempotent: re-running skips already-existing rules.
8
- *
9
- * Usage:
10
- * npm run bootstrap-rules # default (3 principles)
11
- * BOOTSTRAP_LIMIT=2 npm run bootstrap-rules # limit to 2 principles
12
- * STATE_DIR=/path/to/state npm run bootstrap-rules # custom state dir
13
- */
14
-
15
- import { join, dirname } from 'path';
16
- import { fileURLToPath } from 'url';
17
-
18
- const __filename = fileURLToPath(import.meta.url);
19
- const __dirname = dirname(__filename);
20
-
21
- const PROJECT_ROOT = join(__dirname, '..');
22
- const STATE_DIR = process.env.STATE_DIR || join(PROJECT_ROOT, '..', '.state');
23
- const LIMIT = parseInt(process.env.BOOTSTRAP_LIMIT || '3', 10);
24
-
25
- async function run() {
26
- let BootstrapModule;
27
- try {
28
- BootstrapModule = await import('../dist/core/bootstrap-rules.js');
29
- } catch {
30
- console.error('Bootstrap module not found in dist/. Build first: node esbuild.config.js');
31
- process.exit(1);
32
- }
33
-
34
- const { bootstrapRules, validateBootstrap, selectPrinciplesForBootstrap } = BootstrapModule;
35
-
36
- console.log('Selecting principles for bootstrap...');
37
- console.log(` State dir: ${STATE_DIR}`);
38
- console.log(` Limit: ${LIMIT}`);
39
-
40
- try {
41
- const selectedIds = selectPrinciplesForBootstrap(STATE_DIR, LIMIT);
42
- console.log(` Selected ${selectedIds.length} principle(s): ${selectedIds.join(', ')}`);
43
-
44
- console.log('\nRunning bootstrap...');
45
- const results = bootstrapRules(STATE_DIR, LIMIT);
46
-
47
- for (const r of results) {
48
- console.log(` ${r.status === 'created' ? '+' : '='} ${r.principleId} -> ${r.ruleId} (${r.status})`);
49
- }
50
-
51
- const created = results.filter((r) => r.status === 'created');
52
- const skipped = results.filter((r) => r.status === 'skipped');
53
- console.log(`\nDone: ${created.length} created, ${skipped.length} skipped.`);
54
-
55
- if (created.length > 0) {
56
- console.log('\nValidating...');
57
- const valid = validateBootstrap(STATE_DIR, selectedIds);
58
- console.log(` Validation: ${valid ? 'PASS' : 'FAIL'}`);
59
- }
60
- } catch (err) {
61
- if (err && typeof err === 'object' && 'code' in err && err.code === 'NO_DETERMINISTIC_PRINCIPLES') {
62
- console.log('\nNothing to bootstrap yet; the workspace has no deterministic principles.');
63
- return;
64
- }
65
- console.error(`\nBootstrap failed: ${err instanceof Error ? err.message : String(err)}`);
66
- process.exit(1);
67
- }
68
- }
69
-
70
- run();
@@ -1,104 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Principle Compiler CLI
5
- *
6
- * Compiles eligible principles (those derived from pain events) into
7
- * auto-generated rules via the PrincipleCompiler pipeline.
8
- *
9
- * Usage:
10
- * npm run compile-principles
11
- * WORKSPACE_DIR=/path/to/workspace npm run compile-principles
12
- * node scripts/compile-principles.mjs /path/to/workspace
13
- */
14
-
15
- import { join, dirname } from 'path';
16
- import { fileURLToPath } from 'url';
17
-
18
- const __filename = fileURLToPath(import.meta.url);
19
- const __dirname = dirname(__filename);
20
-
21
- /**
22
- * Cross-platform home directory (Linux: HOME, Windows: USERPROFILE/HOMEDRIVE+HOMEPATH)
23
- */
24
- function getHomeDir() {
25
- return process.env.HOME
26
- || process.env.USERPROFILE
27
- || (process.env.HOMEDRIVE && process.env.HOMEPATH ? process.env.HOMEDRIVE + process.env.HOMEPATH : null)
28
- || '.';
29
- }
30
-
31
- // Resolve workspace directory: CLI arg > env var > default
32
- const WORKSPACE_DIR = process.argv[2]
33
- || process.env.WORKSPACE_DIR
34
- || join(getHomeDir(), '.openclaw', 'workspace');
35
-
36
- const STATE_DIR = join(WORKSPACE_DIR, '.state');
37
-
38
- async function run() {
39
- console.log('Principle Compiler CLI');
40
- console.log(` Workspace: ${WORKSPACE_DIR}`);
41
- console.log(` State dir: ${STATE_DIR}`);
42
-
43
- let compilerModule, trajectoryModule;
44
-
45
- try {
46
- compilerModule = await import('../dist/core/principle-compiler/index.js');
47
- } catch {
48
- console.error('PrincipleCompiler module not found in dist/. Build first: node esbuild.config.js');
49
- process.exit(1);
50
- }
51
-
52
- try {
53
- trajectoryModule = await import('../dist/core/trajectory/index.js');
54
- } catch {
55
- console.error('TrajectoryDatabase module not found in dist/. Build first: node esbuild.config.js');
56
- process.exit(1);
57
- }
58
-
59
- const { PrincipleCompiler } = compilerModule;
60
- const { TrajectoryDatabase } = trajectoryModule;
61
-
62
- let trajectory;
63
- try {
64
- trajectory = new TrajectoryDatabase({ workspaceDir: WORKSPACE_DIR });
65
- } catch (err) {
66
- console.error(`Failed to open trajectory database: ${err.message}`);
67
- process.exit(1);
68
- }
69
-
70
- try {
71
- const compiler = new PrincipleCompiler(STATE_DIR, trajectory);
72
-
73
- console.log('\nCompiling eligible principles...');
74
- const results = compiler.compileAll();
75
-
76
- const succeeded = results.filter(r => r.success);
77
- const failed = results.filter(r => !r.success);
78
-
79
- console.log(`\nResults: ${succeeded.length} succeeded, ${failed.length} failed`);
80
-
81
- for (const r of succeeded) {
82
- console.log(` + ${r.principleId} -> rule ${r.ruleId} (impl: ${r.implementationId})`);
83
- }
84
-
85
- for (const r of failed) {
86
- console.log(` x ${r.principleId}: ${r.reason}`);
87
- }
88
-
89
- if (results.length === 0) {
90
- console.log(' No eligible principles found for compilation.');
91
- }
92
-
93
- if (failed.length > 0) {
94
- process.exitCode = 1;
95
- }
96
- } finally {
97
- trajectory.dispose();
98
- }
99
- }
100
-
101
- run().catch((err) => {
102
- console.error(`Fatal: ${err.message}`);
103
- process.exit(1);
104
- });
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const { execFileSync } = require('child_process');
4
- const { existsSync, readFileSync } = require('fs');
5
- const { join } = require('path');
6
-
7
- const PLUGIN_DIR = join(__dirname, '..');
8
-
9
- console.log('Setting up Principles Disciple plugin dependencies...');
10
-
11
- const packageJsonPath = join(PLUGIN_DIR, 'package.json');
12
- if (!existsSync(packageJsonPath)) {
13
- console.log('Not in plugin directory, skipping dependency setup');
14
- process.exit(0);
15
- }
16
-
17
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
18
- const dependencyNames = ['micromatch', '@sinclair/typebox', 'better-sqlite3'];
19
- const DEPENDENCIES = dependencyNames.map((name) => {
20
- const version = packageJson.dependencies?.[name] || packageJson.devDependencies?.[name];
21
- if (!version) {
22
- throw new Error(`Missing dependency version in package.json for ${name}`);
23
- }
24
- return `${name}@${version}`;
25
- });
26
-
27
- const nodeModulesDir = join(PLUGIN_DIR, 'node_modules');
28
- const betterSqliteDir = join(nodeModulesDir, 'better-sqlite3');
29
- if (existsSync(nodeModulesDir) && existsSync(betterSqliteDir)) {
30
- console.log('Dependencies already installed');
31
- process.exit(0);
32
- }
33
-
34
- console.log('Installing plugin dependencies...');
35
- try {
36
- execFileSync('npm', ['install', ...DEPENDENCIES], {
37
- cwd: PLUGIN_DIR,
38
- stdio: 'inherit',
39
- });
40
- console.log('Plugin dependencies installed successfully');
41
- } catch (error) {
42
- console.error('Failed to install plugin dependencies:', error.message);
43
- console.log('\nManual fix:');
44
- console.log(' cd', PLUGIN_DIR);
45
- console.log(' npm install', DEPENDENCIES.join(' '));
46
- process.exit(1);
47
- }