kairos-chain 2.8.0 → 2.9.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/lib/kairos_mcp/version.rb +1 -1
- data/templates/knowledge/multi_agent_design_workflow/multi_agent_design_workflow.md +124 -0
- data/templates/knowledge/multi_agent_design_workflow_jp/multi_agent_design_workflow_jp.md +123 -0
- data/templates/skillsets/autoexec/config/autoexec.yml +75 -0
- data/templates/skillsets/autoexec/knowledge/autoexec_guide/autoexec_guide.md +63 -0
- data/templates/skillsets/autoexec/lib/autoexec/plan_store.rb +173 -0
- data/templates/skillsets/autoexec/lib/autoexec/risk_classifier.rb +95 -0
- data/templates/skillsets/autoexec/lib/autoexec/task_dsl.rb +272 -0
- data/templates/skillsets/autoexec/lib/autoexec.rb +79 -0
- data/templates/skillsets/autoexec/skillset.json +20 -0
- data/templates/skillsets/autoexec/test/test_autoexec.rb +340 -0
- data/templates/skillsets/autoexec/tools/autoexec_plan.rb +150 -0
- data/templates/skillsets/autoexec/tools/autoexec_run.rb +315 -0
- metadata +14 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f00cda5bb11b581435b296790b3cac3b49a1919f7280897b545b23ed2ead72a9
|
|
4
|
+
data.tar.gz: cb213562d6fa26ee5cec11ee68f2242bff54ae72e23d51457a9beee11ece5fbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b53f2bde852c3a0476509819b31cea297904c9515cddf438b0922d1efcf8c7f4eaa2a9b1762d39ba2e8b2f9057287354e946bca8bc9654459b92ef0389a8323
|
|
7
|
+
data.tar.gz: 832dcf7703ce7cbfcf035684841e7922370430725e412044b4427e87353459e87984b122717966b3c1aca1e5b874b2cf1fffc2b391844b3e9636ff6a0267e7c8
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,31 @@ All notable changes to the `kairos-chain` gem will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
This project follows [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [2.9.0] - 2026-03-14
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **AutoExec SkillSet** (`autoexec` v0.1.1): New opt-in SkillSet for semi-autonomous task planning and execution with constitutive chain recording.
|
|
12
|
+
- `autoexec_plan`: Generate structured task plans from natural language descriptions. Outputs `.kdsl` DSL files with SHA-256 hash-locked integrity. Supports DSL and JSON input formats.
|
|
13
|
+
- `autoexec_run`: Execute planned tasks with graduated approval (`dry_run` default, `execute`, `status` modes). Two-phase commit records intent before and outcome after execution. Checkpoint resume for halted tasks.
|
|
14
|
+
- **Regex DSL parser**: No `eval`, no `BasicObject` sandbox — 18 forbidden patterns checked before parsing. Roundtrip-safe (`parse` → `to_source` → `parse`).
|
|
15
|
+
- **Risk classifier**: Static rule-based risk classification (low/medium/high) with L0 deny-list (read from L0 governance skill, self-referential design), protected file detection, and L0 firewall.
|
|
16
|
+
- **Plan store**: File-based plan storage with atomic execution lock (`File::CREAT|EXCL|WRONLY`), PID liveness checks, stale lock timeout, and checkpoint management.
|
|
17
|
+
- **`requires_human_cognition`**: Step-level halt for human cognitive participation (constitutive, not cautionary — Proposition 9). Saves checkpoint and resumes on re-run.
|
|
18
|
+
- **TOCTOU prevention**: Single load + in-memory hash verification (no separate verify then load).
|
|
19
|
+
- **Chain recording**: Two-phase commit with intent block before execution and outcome block after (validity-conditional recording, Proposition 5). Chain failures surfaced in response, never silently swallowed.
|
|
20
|
+
- **Path traversal prevention**: `task_id` validated with `\A\w+\z` in both DSL and JSON input paths.
|
|
21
|
+
- Bundled L1 knowledge: `autoexec_guide` (usage guide with examples)
|
|
22
|
+
- 75 unit tests across TaskDsl, RiskClassifier, and PlanStore
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **TaskDsl colon false-positive**: Unknown key scanner no longer matches colons inside quoted action strings (e.g., `"run command: echo hello"`)
|
|
27
|
+
- **TaskDsl missing requires**: Added `require 'digest'` and `require 'json'` for module independence
|
|
28
|
+
- **AutoexecRun lock release**: Moved `acquire_lock` inside `begin/ensure` block with `lock_acquired` flag to guarantee lock release on any exception
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
7
32
|
## [2.8.0] - 2026-03-08
|
|
8
33
|
|
|
9
34
|
### Added
|
|
@@ -371,6 +396,7 @@ This project follows [Semantic Versioning](https://semver.org/).
|
|
|
371
396
|
- Skill promotion with Persona Assembly
|
|
372
397
|
- Tool guide and metadata system
|
|
373
398
|
|
|
399
|
+
[2.9.0]: https://github.com/masaomi/KairosChain_2026/compare/v2.8.0...v2.9.0
|
|
374
400
|
[2.8.0]: https://github.com/masaomi/KairosChain_2026/compare/v2.7.0...v2.8.0
|
|
375
401
|
[2.7.0]: https://github.com/masaomi/KairosChain_2026/compare/v2.6.0...v2.7.0
|
|
376
402
|
[2.6.0]: https://github.com/masaomi/KairosChain_2026/compare/v2.5.0...v2.6.0
|
data/lib/kairos_mcp/version.rb
CHANGED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: multi_agent_design_workflow
|
|
3
|
+
description: "Multi-agent deliberation workflow for design, implementation, and iterative review"
|
|
4
|
+
version: "1.0"
|
|
5
|
+
layer: L1
|
|
6
|
+
tags: [workflow, multi-agent, design, review, persona-assembly, multi-llm]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Multi-Agent Design Workflow
|
|
10
|
+
|
|
11
|
+
Implementation decisions are made through structured multi-agent deliberation,
|
|
12
|
+
not by a single agent acting alone. This workflow applies to both initial design
|
|
13
|
+
and post-implementation review, forming an iterative loop.
|
|
14
|
+
|
|
15
|
+
## Workflow Overview
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────┐
|
|
19
|
+
│ 1. Rough Idea (Human) │
|
|
20
|
+
│ - Present rough thoughts, goals, constraints │
|
|
21
|
+
│ │
|
|
22
|
+
│ 2. Agent Team Analysis │
|
|
23
|
+
│ - Multiple agents analyze from different angles │
|
|
24
|
+
│ - Surface trade-offs, risks, alternatives │
|
|
25
|
+
│ │
|
|
26
|
+
│ 3. Persona Assembly │
|
|
27
|
+
│ - Project-philosophy-aware discussion │
|
|
28
|
+
│ - e.g., KairosChain: consider 9 propositions │
|
|
29
|
+
│ - Filter proposals through project identity │
|
|
30
|
+
│ │
|
|
31
|
+
│ 4. Final Proposal Selection │
|
|
32
|
+
│ - Design: select design plan │
|
|
33
|
+
│ - Review: identify critical blockers │
|
|
34
|
+
│ - Human makes the final call │
|
|
35
|
+
│ │
|
|
36
|
+
│ 5. (Optional) Multi-LLM Integration │
|
|
37
|
+
│ - Run Gemini, GPT, etc. in separate terminals │
|
|
38
|
+
│ - Integrate diverse LLM perspectives │
|
|
39
|
+
│ - Synthesize before proceeding │
|
|
40
|
+
│ │
|
|
41
|
+
│ 6. Implementation / Revision │
|
|
42
|
+
│ - Execute the agreed plan │
|
|
43
|
+
│ - On first pass: implement │
|
|
44
|
+
│ - On subsequent passes: apply fixes │
|
|
45
|
+
│ │
|
|
46
|
+
│ ┌─── Review Loop (steps 2-6) ───────────────┐ │
|
|
47
|
+
│ │ After implementation, loop back to step 2 │ │
|
|
48
|
+
│ │ for review. Continue until exit condition. │ │
|
|
49
|
+
│ └────────────────────────────────────────────┘ │
|
|
50
|
+
└─────────────────────────────────────────────────────┘
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Review Loop and Termination
|
|
54
|
+
|
|
55
|
+
After the initial implementation (step 6), the workflow loops back to step 2
|
|
56
|
+
for review. Each review iteration may produce further fixes, which are then
|
|
57
|
+
reviewed again.
|
|
58
|
+
|
|
59
|
+
### Exit Conditions (whichever comes first)
|
|
60
|
+
|
|
61
|
+
| Condition | Description |
|
|
62
|
+
|-----------|-------------|
|
|
63
|
+
| **No critical defects** | No blockers or fatal flaws remain after review |
|
|
64
|
+
| **Max loop count reached** | Default: **3 iterations**. Adjustable per task. |
|
|
65
|
+
|
|
66
|
+
### Loop Behavior
|
|
67
|
+
|
|
68
|
+
- **Iteration 1**: Full review — architectural, logical, edge cases
|
|
69
|
+
- **Iteration 2**: Focused review — only issues from iteration 1 fixes
|
|
70
|
+
- **Iteration 3+**: Regression check — confirm no new issues introduced
|
|
71
|
+
|
|
72
|
+
If the max loop count is reached but blockers remain, the workflow pauses
|
|
73
|
+
and escalates to the human for a decision (continue, defer, or accept as-is).
|
|
74
|
+
|
|
75
|
+
## Output Artifacts
|
|
76
|
+
|
|
77
|
+
Each workflow execution produces two distinct artifacts, saved to both
|
|
78
|
+
L2 context and the `log/` directory.
|
|
79
|
+
|
|
80
|
+
### Pre-Implementation Plan
|
|
81
|
+
|
|
82
|
+
Saved **before** step 6 (first implementation):
|
|
83
|
+
|
|
84
|
+
- **L2 context**: `context_save()` with tag `plan`
|
|
85
|
+
- **log/ file**: `log/{date}_{feature}_plan.md`
|
|
86
|
+
- **Contents**: design decision, rationale, rejected alternatives, risks
|
|
87
|
+
|
|
88
|
+
### Post-Implementation Review Log
|
|
89
|
+
|
|
90
|
+
Saved **after** each review loop iteration:
|
|
91
|
+
|
|
92
|
+
- **L2 context**: `context_save()` with tag `review`
|
|
93
|
+
- **log/ file**: `log/{date}_{feature}_review_N.md` (N = iteration number)
|
|
94
|
+
- **Contents**: findings, severity, fixes applied, remaining issues
|
|
95
|
+
|
|
96
|
+
### Naming Convention
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
log/20260313_auth_refactor_plan.md
|
|
100
|
+
log/20260313_auth_refactor_review_1.md
|
|
101
|
+
log/20260313_auth_refactor_review_2.md
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## When to Use This Workflow
|
|
105
|
+
|
|
106
|
+
- New feature design with significant architectural impact
|
|
107
|
+
- Refactoring that touches multiple components
|
|
108
|
+
- Any change where "just implement it" risks cascading problems
|
|
109
|
+
- Bug fixes that require root cause analysis before patching
|
|
110
|
+
|
|
111
|
+
## When NOT to Use
|
|
112
|
+
|
|
113
|
+
- Trivial fixes (typos, single-line changes)
|
|
114
|
+
- Well-understood, isolated changes with no design ambiguity
|
|
115
|
+
- Exploratory prototyping where speed matters more than correctness
|
|
116
|
+
|
|
117
|
+
## Relation to Existing Tools
|
|
118
|
+
|
|
119
|
+
| Step | KairosChain Tool |
|
|
120
|
+
|------|-----------------|
|
|
121
|
+
| Agent Team Analysis | Agent tool with multiple subagents |
|
|
122
|
+
| Persona Assembly | `skills_audit(command: "check")` or manual persona invocation |
|
|
123
|
+
| Multi-LLM Integration | External (separate terminal sessions) |
|
|
124
|
+
| Plan/Review output | `context_save()` + file write to `log/` |
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: multi_agent_design_workflow_jp
|
|
3
|
+
description: "マルチエージェント審議ワークフロー:設計・実装・反復レビュー"
|
|
4
|
+
version: "1.0"
|
|
5
|
+
layer: L1
|
|
6
|
+
tags: [workflow, multi-agent, design, review, persona-assembly, multi-llm]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# マルチエージェント設計ワークフロー
|
|
10
|
+
|
|
11
|
+
実装の意思決定は、単一エージェントではなく、構造化されたマルチエージェント審議を
|
|
12
|
+
通じて行う。このワークフローは初期設計と実装後レビューの両方に適用され、
|
|
13
|
+
反復ループを形成する。
|
|
14
|
+
|
|
15
|
+
## ワークフロー概要
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────┐
|
|
19
|
+
│ 1. ラフなアイデア提示(人間) │
|
|
20
|
+
│ - 大まかな考え、目標、制約を伝える │
|
|
21
|
+
│ │
|
|
22
|
+
│ 2. エージェントチーム多角的分析 │
|
|
23
|
+
│ - 複数エージェントが異なる角度から分析 │
|
|
24
|
+
│ - トレードオフ、リスク、代替案を洗い出す │
|
|
25
|
+
│ │
|
|
26
|
+
│ 3. Persona Assembly │
|
|
27
|
+
│ - プロジェクトの哲学を考慮した議論 │
|
|
28
|
+
│ - 例:KairosChainなら9命題を考慮 │
|
|
29
|
+
│ - プロジェクトのアイデンティティで提案をフィルタ │
|
|
30
|
+
│ │
|
|
31
|
+
│ 4. 最終案選定 │
|
|
32
|
+
│ - 設計:設計案を選定 │
|
|
33
|
+
│ - レビュー:致命的ブロッカーを特定 │
|
|
34
|
+
│ - 最終判断は人間が行う │
|
|
35
|
+
│ │
|
|
36
|
+
│ 5.(任意)マルチLLM統合 │
|
|
37
|
+
│ - Gemini、GPT等を別ターミナルで起動 │
|
|
38
|
+
│ - 異なるLLMの視点を統合 │
|
|
39
|
+
│ - 統合結果をもとに次のステップへ │
|
|
40
|
+
│ │
|
|
41
|
+
│ 6. 実装 / 修正 │
|
|
42
|
+
│ - 合意された計画を実行 │
|
|
43
|
+
│ - 初回:実装 │
|
|
44
|
+
│ - 2回目以降:修正適用 │
|
|
45
|
+
│ │
|
|
46
|
+
│ ┌─── レビューループ(ステップ2-6)──────────┐ │
|
|
47
|
+
│ │ 実装後、ステップ2に戻りレビュー。 │ │
|
|
48
|
+
│ │ 終了条件を満たすまで繰り返す。 │ │
|
|
49
|
+
│ └──────────────────────────────────────────┘ │
|
|
50
|
+
└─────────────────────────────────────────────────────┘
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## レビューループと終了条件
|
|
54
|
+
|
|
55
|
+
初回実装(ステップ6)の後、ステップ2に戻りレビューを行う。
|
|
56
|
+
各レビューで追加修正が発生した場合、再度レビューを繰り返す。
|
|
57
|
+
|
|
58
|
+
### 終了条件(いずれか先に満たされた方)
|
|
59
|
+
|
|
60
|
+
| 条件 | 説明 |
|
|
61
|
+
|------|------|
|
|
62
|
+
| **致命的欠陥なし** | ブロッカーや致命的欠陥がレビューで検出されない |
|
|
63
|
+
| **最大ループ回数到達** | デフォルト:**3回**。タスクごとに調整可能。 |
|
|
64
|
+
|
|
65
|
+
### ループごとの挙動
|
|
66
|
+
|
|
67
|
+
- **1回目**:フルレビュー — アーキテクチャ、ロジック、エッジケース
|
|
68
|
+
- **2回目**:焦点レビュー — 1回目の修正に起因する問題のみ
|
|
69
|
+
- **3回目以降**:リグレッションチェック — 新たな問題の混入がないか確認
|
|
70
|
+
|
|
71
|
+
最大ループ回数に到達してもブロッカーが残っている場合、ワークフローを一時停止し
|
|
72
|
+
人間に判断をエスカレーションする(継続、延期、現状受け入れ)。
|
|
73
|
+
|
|
74
|
+
## 出力成果物
|
|
75
|
+
|
|
76
|
+
ワークフロー実行ごとに2種類の成果物を生成し、L2コンテキストと
|
|
77
|
+
`log/` ディレクトリの両方に保存する。
|
|
78
|
+
|
|
79
|
+
### 実装前プラン
|
|
80
|
+
|
|
81
|
+
ステップ6(初回実装)の**前**に保存:
|
|
82
|
+
|
|
83
|
+
- **L2コンテキスト**: `context_save()` タグ `plan`
|
|
84
|
+
- **log/ ファイル**: `log/{日付}_{機能名}_plan.md`
|
|
85
|
+
- **内容**: 設計判断、理由、却下された代替案、リスク
|
|
86
|
+
|
|
87
|
+
### 実装後レビューログ
|
|
88
|
+
|
|
89
|
+
各レビューループ反復の**後**に保存:
|
|
90
|
+
|
|
91
|
+
- **L2コンテキスト**: `context_save()` タグ `review`
|
|
92
|
+
- **log/ ファイル**: `log/{日付}_{機能名}_review_N.md`(N = 反復回数)
|
|
93
|
+
- **内容**: 発見事項、重大度、適用した修正、残存課題
|
|
94
|
+
|
|
95
|
+
### 命名規則
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
log/20260313_auth_refactor_plan.md
|
|
99
|
+
log/20260313_auth_refactor_review_1.md
|
|
100
|
+
log/20260313_auth_refactor_review_2.md
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## 使用すべき場面
|
|
104
|
+
|
|
105
|
+
- アーキテクチャに大きな影響を与える新機能の設計
|
|
106
|
+
- 複数コンポーネントにまたがるリファクタリング
|
|
107
|
+
- 「とりあえず実装」では連鎖的な問題を引き起こすリスクがある変更
|
|
108
|
+
- パッチ適用前に根本原因分析が必要なバグ修正
|
|
109
|
+
|
|
110
|
+
## 使用しない場面
|
|
111
|
+
|
|
112
|
+
- 些細な修正(タイポ、1行の変更)
|
|
113
|
+
- 設計に曖昧さのない、よく理解された独立した変更
|
|
114
|
+
- 正確さよりもスピードが重要な探索的プロトタイピング
|
|
115
|
+
|
|
116
|
+
## 既存ツールとの対応
|
|
117
|
+
|
|
118
|
+
| ステップ | KairosChainツール |
|
|
119
|
+
|----------|------------------|
|
|
120
|
+
| エージェントチーム分析 | Agent tool(複数サブエージェント) |
|
|
121
|
+
| Persona Assembly | `skills_audit(command: "check")` またはペルソナ手動起動 |
|
|
122
|
+
| マルチLLM統合 | 外部(別ターミナルセッション) |
|
|
123
|
+
| プラン/レビュー出力 | `context_save()` + `log/` へのファイル書き出し |
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# AutoExec SkillSet Configuration
|
|
2
|
+
# Semi-autonomous task planning and execution
|
|
3
|
+
|
|
4
|
+
# Default execution mode: dry_run or execute
|
|
5
|
+
default_mode: dry_run
|
|
6
|
+
|
|
7
|
+
# Maximum steps per task plan
|
|
8
|
+
max_steps: 20
|
|
9
|
+
|
|
10
|
+
# Maximum concurrent tasks (enforced by execution mutex)
|
|
11
|
+
max_concurrent: 1
|
|
12
|
+
|
|
13
|
+
# Stale lock timeout in seconds (3600 = 1 hour)
|
|
14
|
+
stale_lock_timeout: 3600
|
|
15
|
+
|
|
16
|
+
# Loop detection thresholds
|
|
17
|
+
loop_detection:
|
|
18
|
+
generic_repeat:
|
|
19
|
+
warn: 5
|
|
20
|
+
halt: 10
|
|
21
|
+
poll_no_progress:
|
|
22
|
+
warn: 3
|
|
23
|
+
halt: 5
|
|
24
|
+
ping_pong:
|
|
25
|
+
warn: 4
|
|
26
|
+
halt: 8
|
|
27
|
+
replan_cycle:
|
|
28
|
+
warn: 2
|
|
29
|
+
halt: 3
|
|
30
|
+
|
|
31
|
+
# Risk classification defaults
|
|
32
|
+
risk_defaults:
|
|
33
|
+
read: low
|
|
34
|
+
search: low
|
|
35
|
+
analyze: low
|
|
36
|
+
edit: medium
|
|
37
|
+
create: medium
|
|
38
|
+
test: medium
|
|
39
|
+
delete: high
|
|
40
|
+
push: high
|
|
41
|
+
deploy: high
|
|
42
|
+
|
|
43
|
+
# L0 deny-list (hardcoded, cannot be overridden)
|
|
44
|
+
# These operations are NEVER allowed regardless of risk classification
|
|
45
|
+
# l0_deny_list:
|
|
46
|
+
# - l0_evolution
|
|
47
|
+
# - chain_modification
|
|
48
|
+
# - skill_deletion
|
|
49
|
+
|
|
50
|
+
# Content firewall
|
|
51
|
+
content_firewall:
|
|
52
|
+
enabled: true
|
|
53
|
+
block_on_detection: true # false = warn only (NOT recommended)
|
|
54
|
+
|
|
55
|
+
# Runtime boundary
|
|
56
|
+
runtime_boundary:
|
|
57
|
+
enabled: true
|
|
58
|
+
network_allowlist_mode: true # only declared URLs allowed
|
|
59
|
+
forbidden_read_paths:
|
|
60
|
+
- "~/.ssh"
|
|
61
|
+
- "~/.aws"
|
|
62
|
+
- "~/.gnupg"
|
|
63
|
+
- "~/.config/gcloud"
|
|
64
|
+
- "/etc/shadow"
|
|
65
|
+
forbidden_write_paths:
|
|
66
|
+
- "/dev/"
|
|
67
|
+
- "/proc/"
|
|
68
|
+
- "/sys/"
|
|
69
|
+
- "/boot/"
|
|
70
|
+
|
|
71
|
+
# Storage paths (relative to .kairos/)
|
|
72
|
+
storage:
|
|
73
|
+
plans_dir: "autoexec/plans"
|
|
74
|
+
state_dir: "autoexec/state"
|
|
75
|
+
violations_dir: "autoexec/violations"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: AutoExec SkillSet Guide
|
|
3
|
+
tags: [autoexec, task-planning, semi-autonomous, execution]
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# AutoExec SkillSet Guide
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
AutoExec enables semi-autonomous task planning and execution with constitutive
|
|
12
|
+
chain recording. It decomposes tasks into structured DSL plans, classifies risk,
|
|
13
|
+
and executes with graduated approval.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### 1. Create a Plan
|
|
18
|
+
|
|
19
|
+
Provide a JSON task decomposition to `autoexec_plan`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"task_id": "add_mcp_tool",
|
|
24
|
+
"meta": { "description": "Add token_balance MCP tool", "risk_default": "medium" },
|
|
25
|
+
"steps": [
|
|
26
|
+
{ "step_id": "analyze", "action": "read existing tool patterns", "risk": "low" },
|
|
27
|
+
{ "step_id": "implement", "action": "create tool file", "risk": "medium", "depends_on": ["analyze"] },
|
|
28
|
+
{ "step_id": "test", "action": "write and run tests", "risk": "medium", "depends_on": ["implement"] }
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Review and Dry Run
|
|
34
|
+
|
|
35
|
+
Use the returned `plan_hash` to dry-run:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
autoexec_run(task_id: "add_mcp_tool", mode: "dry_run", approved_hash: "<hash>")
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 3. Execute
|
|
42
|
+
|
|
43
|
+
After reviewing the dry run, switch to execute mode:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
autoexec_run(task_id: "add_mcp_tool", mode: "execute", approved_hash: "<hash>")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Safety Model
|
|
50
|
+
|
|
51
|
+
- **Dry-run default**: All plans start in dry_run mode
|
|
52
|
+
- **Hash-locked plans**: Plans are SHA-256 hashed at creation; execution verifies the hash
|
|
53
|
+
- **L0 deny-list**: Operations like L0 evolution and chain modification are always blocked
|
|
54
|
+
- **Protected files**: Writes to config files force :high risk classification
|
|
55
|
+
- **Human cognition markers**: Steps with `requires_human_cognition: true` halt execution
|
|
56
|
+
|
|
57
|
+
## Risk Classification
|
|
58
|
+
|
|
59
|
+
| Level | Auto-execute | Examples |
|
|
60
|
+
|-------|-------------|---------|
|
|
61
|
+
| Low | Yes | read, search, analyze, list |
|
|
62
|
+
| Medium | With approval | edit, create, test, build |
|
|
63
|
+
| High | Individual approval | delete, push, deploy |
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Autoexec
|
|
4
|
+
# Stores task plans, manages hash verification, execution locks, and checkpoints.
|
|
5
|
+
# Plans stored as .kdsl (non-executable DSL text) with .json metadata sidecar.
|
|
6
|
+
class PlanStore
|
|
7
|
+
LOCK_FILE = 'autoexec.lock'
|
|
8
|
+
|
|
9
|
+
# --- Plan Storage ---
|
|
10
|
+
|
|
11
|
+
def self.save(task_id, plan, source)
|
|
12
|
+
raise ArgumentError, "Invalid task_id: must contain only word characters" unless task_id.to_s.match?(/\A\w+\z/)
|
|
13
|
+
|
|
14
|
+
plans_dir = Autoexec.storage_path('plans')
|
|
15
|
+
plan_path = File.join(plans_dir, "#{task_id}.kdsl")
|
|
16
|
+
meta_path = File.join(plans_dir, "#{task_id}.json")
|
|
17
|
+
plan_hash = TaskDsl.compute_hash(source)
|
|
18
|
+
|
|
19
|
+
File.write(plan_path, source)
|
|
20
|
+
File.write(meta_path, JSON.pretty_generate({
|
|
21
|
+
task_id: task_id.to_s,
|
|
22
|
+
plan_hash: plan_hash,
|
|
23
|
+
step_count: plan.steps.size,
|
|
24
|
+
risk_summary: RiskClassifier.risk_summary(plan.steps),
|
|
25
|
+
created_at: Time.now.iso8601,
|
|
26
|
+
status: 'planned'
|
|
27
|
+
}))
|
|
28
|
+
|
|
29
|
+
plan_hash
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.load(task_id)
|
|
33
|
+
plans_dir = Autoexec.storage_path('plans')
|
|
34
|
+
plan_path = File.join(plans_dir, "#{task_id}.kdsl")
|
|
35
|
+
meta_path = File.join(plans_dir, "#{task_id}.json")
|
|
36
|
+
|
|
37
|
+
return nil unless File.exist?(plan_path) && File.exist?(meta_path)
|
|
38
|
+
|
|
39
|
+
source = File.read(plan_path)
|
|
40
|
+
metadata = JSON.parse(File.read(meta_path), symbolize_names: true)
|
|
41
|
+
plan = TaskDsl.parse(source)
|
|
42
|
+
computed_hash = TaskDsl.compute_hash(source)
|
|
43
|
+
|
|
44
|
+
{
|
|
45
|
+
plan: plan,
|
|
46
|
+
source: source,
|
|
47
|
+
hash: computed_hash,
|
|
48
|
+
metadata: metadata
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.verify_hash(task_id, expected_hash)
|
|
53
|
+
stored = load(task_id)
|
|
54
|
+
return false unless stored
|
|
55
|
+
|
|
56
|
+
stored[:hash] == expected_hash
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.list
|
|
60
|
+
plans_dir = Autoexec.storage_path('plans')
|
|
61
|
+
Dir.glob(File.join(plans_dir, '*.json')).map do |meta_path|
|
|
62
|
+
JSON.parse(File.read(meta_path), symbolize_names: true)
|
|
63
|
+
rescue JSON::ParserError => e
|
|
64
|
+
warn "[autoexec] Corrupted metadata file: #{meta_path} (#{e.message})"
|
|
65
|
+
nil
|
|
66
|
+
end.compact
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.update_status(task_id, status)
|
|
70
|
+
plans_dir = Autoexec.storage_path('plans')
|
|
71
|
+
meta_path = File.join(plans_dir, "#{task_id}.json")
|
|
72
|
+
return unless File.exist?(meta_path)
|
|
73
|
+
|
|
74
|
+
metadata = JSON.parse(File.read(meta_path))
|
|
75
|
+
metadata['status'] = status
|
|
76
|
+
metadata['updated_at'] = Time.now.iso8601
|
|
77
|
+
File.write(meta_path, JSON.pretty_generate(metadata))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# --- Execution Lock (OpenClaw session-write-lock pattern, simplified) ---
|
|
81
|
+
|
|
82
|
+
def self.acquire_lock(task_id)
|
|
83
|
+
state_dir = Autoexec.storage_path('state')
|
|
84
|
+
lock_path = File.join(state_dir, LOCK_FILE)
|
|
85
|
+
|
|
86
|
+
# Check for existing lock and handle stale/dead locks
|
|
87
|
+
if File.exist?(lock_path)
|
|
88
|
+
lock_data = JSON.parse(File.read(lock_path)) rescue {}
|
|
89
|
+
pid = lock_data['pid']
|
|
90
|
+
|
|
91
|
+
pid_alive = begin
|
|
92
|
+
Process.kill(0, pid)
|
|
93
|
+
true
|
|
94
|
+
rescue Errno::ESRCH, Errno::EPERM
|
|
95
|
+
false
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
if pid_alive
|
|
99
|
+
stale_timeout = Autoexec.config.dig('stale_lock_timeout') || 3600
|
|
100
|
+
lock_age = Time.now - Time.parse(lock_data['started_at'])
|
|
101
|
+
if lock_age < stale_timeout
|
|
102
|
+
raise "Execution locked by task '#{lock_data['task_id']}' (PID #{pid}, " \
|
|
103
|
+
"started #{lock_data['started_at']}). Use autoexec_run to check status."
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
# PID dead or stale — remove before atomic create
|
|
107
|
+
File.delete(lock_path) rescue nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Atomic lock creation using CREAT|EXCL (prevents race condition)
|
|
111
|
+
lock_data = JSON.pretty_generate({
|
|
112
|
+
task_id: task_id.to_s,
|
|
113
|
+
pid: Process.pid,
|
|
114
|
+
started_at: Time.now.iso8601
|
|
115
|
+
})
|
|
116
|
+
begin
|
|
117
|
+
fd = File.open(lock_path, File::CREAT | File::EXCL | File::WRONLY)
|
|
118
|
+
fd.write(lock_data)
|
|
119
|
+
fd.close
|
|
120
|
+
rescue Errno::EEXIST
|
|
121
|
+
# Another process acquired the lock between our check and create
|
|
122
|
+
raise "Execution locked by another process (race condition). Retry shortly."
|
|
123
|
+
end
|
|
124
|
+
true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def self.release_lock
|
|
128
|
+
state_dir = Autoexec.storage_path('state')
|
|
129
|
+
lock_path = File.join(state_dir, LOCK_FILE)
|
|
130
|
+
File.delete(lock_path) if File.exist?(lock_path)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def self.locked?
|
|
134
|
+
state_dir = Autoexec.storage_path('state')
|
|
135
|
+
lock_path = File.join(state_dir, LOCK_FILE)
|
|
136
|
+
return false unless File.exist?(lock_path)
|
|
137
|
+
|
|
138
|
+
lock_data = JSON.parse(File.read(lock_path))
|
|
139
|
+
pid_alive = begin
|
|
140
|
+
Process.kill(0, lock_data['pid'])
|
|
141
|
+
true
|
|
142
|
+
rescue Errno::ESRCH, Errno::EPERM
|
|
143
|
+
false
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
pid_alive
|
|
147
|
+
rescue StandardError
|
|
148
|
+
false
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# --- Checkpoints ---
|
|
152
|
+
|
|
153
|
+
def self.save_checkpoint(task_id, state)
|
|
154
|
+
state_dir = Autoexec.storage_path('state')
|
|
155
|
+
path = File.join(state_dir, "#{task_id}.checkpoint.json")
|
|
156
|
+
File.write(path, JSON.pretty_generate(state))
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def self.load_checkpoint(task_id)
|
|
160
|
+
state_dir = Autoexec.storage_path('state')
|
|
161
|
+
path = File.join(state_dir, "#{task_id}.checkpoint.json")
|
|
162
|
+
return nil unless File.exist?(path)
|
|
163
|
+
|
|
164
|
+
JSON.parse(File.read(path), symbolize_names: true)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def self.clear_checkpoint(task_id)
|
|
168
|
+
state_dir = Autoexec.storage_path('state')
|
|
169
|
+
path = File.join(state_dir, "#{task_id}.checkpoint.json")
|
|
170
|
+
File.delete(path) if File.exist?(path)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|