@sdotwinter/openclaw-deterministic 0.1.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.
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/bin/cli.js +35 -0
- package/bin/doctor.js +46 -0
- package/bin/init.js +92 -0
- package/bin/install.js +98 -0
- package/package.json +35 -0
- package/templates/OPERATING_RULES.md +85 -0
- package/templates/SOUL.deterministic.md +31 -0
- package/templates/memory-compactor.SKILL.md +229 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sean
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
package/bin/cli.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
const command = process.argv[2];
|
|
6
|
+
|
|
7
|
+
if (!command) {
|
|
8
|
+
showHelp();
|
|
9
|
+
process.exit(0);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (command === "doctor") {
|
|
13
|
+
require(path.join(__dirname, "doctor"));
|
|
14
|
+
} else if (command === "install") {
|
|
15
|
+
require(path.join(__dirname, "install"));
|
|
16
|
+
} else if (command === "init") {
|
|
17
|
+
require(path.join(__dirname, "init"));
|
|
18
|
+
} else if (command === "--version" || command === "-v") {
|
|
19
|
+
// Keep this in sync with package.json version (manual for now)
|
|
20
|
+
console.log("openclaw-deterministic v0.1.0");
|
|
21
|
+
process.exit(0);
|
|
22
|
+
} else {
|
|
23
|
+
console.error(`Unknown command: ${command}\n`);
|
|
24
|
+
showHelp();
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function showHelp() {
|
|
29
|
+
console.log("OpenClaw Deterministic CLI\n");
|
|
30
|
+
console.log("Usage:");
|
|
31
|
+
console.log(" oc-deterministic init");
|
|
32
|
+
console.log(" oc-deterministic doctor");
|
|
33
|
+
console.log(" oc-deterministic install");
|
|
34
|
+
console.log(" oc-deterministic --version\n");
|
|
35
|
+
}
|
package/bin/doctor.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const HOME = os.homedir();
|
|
8
|
+
const OPENCLAW_DIR = path.join(HOME, ".openclaw");
|
|
9
|
+
const WORKSPACE_DIR = path.join(OPENCLAW_DIR, "workspace");
|
|
10
|
+
|
|
11
|
+
console.log("Running deterministic doctor...\n");
|
|
12
|
+
|
|
13
|
+
if (!fs.existsSync(OPENCLAW_DIR)) {
|
|
14
|
+
console.log("❌ ~/.openclaw not found.");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(WORKSPACE_DIR)) {
|
|
19
|
+
console.log("❌ workspace not found.");
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
console.log("✅ OpenClaw directory detected.");
|
|
24
|
+
console.log("✅ Workspace detected.");
|
|
25
|
+
|
|
26
|
+
const hasOperating = fs.existsSync(
|
|
27
|
+
path.join(WORKSPACE_DIR, "OPERATING_RULES.md")
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const hasSkill = fs.existsSync(
|
|
31
|
+
path.join(WORKSPACE_DIR, "skills", "memory-compactor", "SKILL.md")
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
console.log(
|
|
35
|
+
hasOperating
|
|
36
|
+
? "✅ OPERATING_RULES.md present."
|
|
37
|
+
: "⚠️ OPERATING_RULES.md missing."
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
console.log(
|
|
41
|
+
hasSkill
|
|
42
|
+
? "✅ memory-compactor skill present."
|
|
43
|
+
: "⚠️ memory-compactor skill missing."
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
console.log("\nDoctor complete.");
|
package/bin/init.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require("child_process");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const readline = require("readline");
|
|
8
|
+
|
|
9
|
+
const HOME = os.homedir();
|
|
10
|
+
const OPENCLAW_DIR = path.join(HOME, ".openclaw");
|
|
11
|
+
const WORKSPACE_DIR = path.join(OPENCLAW_DIR, "workspace");
|
|
12
|
+
|
|
13
|
+
main().catch((err) => {
|
|
14
|
+
console.error("\n❌ init failed:");
|
|
15
|
+
console.error(err?.message || err);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
async function main() {
|
|
20
|
+
console.log("oc-deterministic init (Level 3) starting...\n");
|
|
21
|
+
|
|
22
|
+
// 0) Refuse to run if OpenClaw already initialized
|
|
23
|
+
if (fs.existsSync(WORKSPACE_DIR)) {
|
|
24
|
+
console.error("❌ OpenClaw workspace already exists:");
|
|
25
|
+
console.error(` ${WORKSPACE_DIR}`);
|
|
26
|
+
console.error("\nUse:");
|
|
27
|
+
console.error(" oc-deterministic doctor");
|
|
28
|
+
console.error(" oc-deterministic install");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 1) Detect OpenClaw CLI
|
|
33
|
+
const hasOpenclaw = commandExists("openclaw");
|
|
34
|
+
if (!hasOpenclaw) {
|
|
35
|
+
console.log("⚠️ OpenClaw CLI not found in PATH.");
|
|
36
|
+
const yes = await confirm("Install OpenClaw now via npm? (y/N): ");
|
|
37
|
+
if (!yes) {
|
|
38
|
+
console.log("Aborted. Install OpenClaw manually, then re-run:");
|
|
39
|
+
console.log(" oc-deterministic init");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
run("npm install -g openclaw");
|
|
44
|
+
} else {
|
|
45
|
+
console.log("✅ OpenClaw CLI detected.");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 2) Onboard OpenClaw (creates ~/.openclaw/workspace etc.)
|
|
49
|
+
console.log("\n--- Running OpenClaw onboarding ---");
|
|
50
|
+
run("openclaw onboard");
|
|
51
|
+
|
|
52
|
+
// 3) Verify workspace was created
|
|
53
|
+
if (!fs.existsSync(WORKSPACE_DIR)) {
|
|
54
|
+
console.error("\n❌ Expected OpenClaw workspace after onboard, but not found:");
|
|
55
|
+
console.error(` ${WORKSPACE_DIR}`);
|
|
56
|
+
console.error("Check OpenClaw output above.");
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 4) Apply deterministic layer (re-use your installer)
|
|
61
|
+
console.log("\n--- Applying deterministic governance layer ---");
|
|
62
|
+
run("oc-deterministic install");
|
|
63
|
+
|
|
64
|
+
// 5) Final quick check
|
|
65
|
+
console.log("\n--- Final validation ---");
|
|
66
|
+
run("oc-deterministic doctor");
|
|
67
|
+
|
|
68
|
+
console.log("\n✅ init complete.");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function run(cmd) {
|
|
72
|
+
execSync(cmd, { stdio: "inherit" });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function commandExists(cmd) {
|
|
76
|
+
try {
|
|
77
|
+
execSync(`command -v ${cmd}`, { stdio: "ignore" });
|
|
78
|
+
return true;
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function confirm(question) {
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
87
|
+
rl.question(question, (answer) => {
|
|
88
|
+
rl.close();
|
|
89
|
+
resolve(answer.trim().toLowerCase() === "y");
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
|
|
7
|
+
const HOME = os.homedir();
|
|
8
|
+
const OPENCLAW_DIR = path.join(HOME, ".openclaw");
|
|
9
|
+
const WORKSPACE_DIR = path.join(OPENCLAW_DIR, "workspace");
|
|
10
|
+
const TEMPLATE_DIR = path.join(__dirname, "..", "templates");
|
|
11
|
+
|
|
12
|
+
function log(msg) {
|
|
13
|
+
console.log(msg);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function exitWith(msg) {
|
|
17
|
+
console.error(msg);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function exists(p) {
|
|
22
|
+
return fs.existsSync(p);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function ensureDir(p) {
|
|
26
|
+
if (!exists(p)) {
|
|
27
|
+
fs.mkdirSync(p, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function copyFileSafe(src, dest) {
|
|
32
|
+
if (!exists(dest)) {
|
|
33
|
+
fs.copyFileSync(src, dest);
|
|
34
|
+
log(`✅ Installed: ${path.basename(dest)}`);
|
|
35
|
+
} else {
|
|
36
|
+
log(`⚠️ Skipped (already exists): ${path.basename(dest)}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function backupFile(filePath, backupDir) {
|
|
41
|
+
if (!exists(filePath)) return;
|
|
42
|
+
|
|
43
|
+
const filename = path.basename(filePath);
|
|
44
|
+
const dest = path.join(backupDir, filename);
|
|
45
|
+
fs.copyFileSync(filePath, dest);
|
|
46
|
+
log(`🗂️ Backed up: ${filename}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function timestamp() {
|
|
50
|
+
const now = new Date();
|
|
51
|
+
return now.toISOString().replace(/[:.]/g, "-");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function validateWorkspace() {
|
|
55
|
+
if (!exists(OPENCLAW_DIR)) {
|
|
56
|
+
exitWith("❌ OpenClaw not detected.\nExpected directory: " + OPENCLAW_DIR);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!exists(WORKSPACE_DIR)) {
|
|
60
|
+
exitWith("❌ OpenClaw workspace not detected.\nExpected directory: " + WORKSPACE_DIR);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function runInstall() {
|
|
65
|
+
log("Running deterministic install phase...\n");
|
|
66
|
+
|
|
67
|
+
validateWorkspace();
|
|
68
|
+
|
|
69
|
+
const backupDir = path.join(WORKSPACE_DIR, "_backup", timestamp());
|
|
70
|
+
ensureDir(backupDir);
|
|
71
|
+
|
|
72
|
+
// Backup important files if they exist
|
|
73
|
+
backupFile(path.join(WORKSPACE_DIR, "OPERATING_RULES.md"), backupDir);
|
|
74
|
+
backupFile(path.join(WORKSPACE_DIR, "SOUL.md"), backupDir);
|
|
75
|
+
|
|
76
|
+
log("\n--- Installing Governance Files ---");
|
|
77
|
+
|
|
78
|
+
// Install OPERATING_RULES.md (only if missing)
|
|
79
|
+
const operatingSrc = path.join(TEMPLATE_DIR, "OPERATING_RULES.md");
|
|
80
|
+
const operatingDest = path.join(WORKSPACE_DIR, "OPERATING_RULES.md");
|
|
81
|
+
copyFileSafe(operatingSrc, operatingDest);
|
|
82
|
+
|
|
83
|
+
log("\n--- Installing Memory Compactor Skill ---");
|
|
84
|
+
|
|
85
|
+
const skillDir = path.join(WORKSPACE_DIR, "skills", "memory-compactor");
|
|
86
|
+
ensureDir(skillDir);
|
|
87
|
+
|
|
88
|
+
const skillSrc = path.join(TEMPLATE_DIR, "memory-compactor.SKILL.md");
|
|
89
|
+
const skillDest = path.join(skillDir, "SKILL.md");
|
|
90
|
+
copyFileSafe(skillSrc, skillDest);
|
|
91
|
+
|
|
92
|
+
log("\n--- SOUL Installation Deferred ---");
|
|
93
|
+
log("⚠️ SOUL.md not modified (manual merge required)");
|
|
94
|
+
|
|
95
|
+
log("\n✅ Deterministic install complete.");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
runInstall();
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sdotwinter/openclaw-deterministic",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Deterministic governance and memory compaction layer for OpenClaw",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"openclaw",
|
|
7
|
+
"ai-agent",
|
|
8
|
+
"deterministic",
|
|
9
|
+
"memory",
|
|
10
|
+
"governance",
|
|
11
|
+
"compaction",
|
|
12
|
+
"cli"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/sdotwinter/openclaw-deterministic#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/sdotwinter/openclaw-deterministic/issues"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/sdotwinter/openclaw-deterministic.git"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "Sean Winter",
|
|
24
|
+
"type": "commonjs",
|
|
25
|
+
"main": "index.js",
|
|
26
|
+
"bin": {
|
|
27
|
+
"oc-deterministic": "bin/cli.js"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"test": "echo \"No tests specified\""
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Operating Rules — Decision Heuristics
|
|
2
|
+
|
|
3
|
+
## System Priority
|
|
4
|
+
- **Determinism over autonomy.** The system prioritizes predictable, governed behavior over autonomous action.
|
|
5
|
+
- **No silent behavior changes.** All changes must be announced before execution.
|
|
6
|
+
- **No "Applied" before diff.** Never report completion before presenting unified diff.
|
|
7
|
+
|
|
8
|
+
## Execution Tiers
|
|
9
|
+
|
|
10
|
+
Execution Tiers define the risk boundary for system changes and override default execution behavior elsewhere in this file.
|
|
11
|
+
|
|
12
|
+
### Tier A — Safe (Auto-Execute)
|
|
13
|
+
Reads, status reports, non-destructive refactors, memory compaction within defined rules, skill updates that do not delete files. Execute immediately with clear reporting.
|
|
14
|
+
|
|
15
|
+
### Tier B — Reversible Modifications (Auto-After-Diff)
|
|
16
|
+
File edits, skill edits, agent updates. Present unified diff before execution. Execute automatically after diff preview unless user explicitly objects.
|
|
17
|
+
|
|
18
|
+
### Tier B Enforcement (Explicit)
|
|
19
|
+
If action is classified Tier B:
|
|
20
|
+
- ALWAYS present unified diff first
|
|
21
|
+
- Execution occurs automatically after diff preview
|
|
22
|
+
- If diff not presented → abort execution
|
|
23
|
+
- Report: "Tier B protocol violation — diff required"
|
|
24
|
+
- Do NOT ask for APPROVED
|
|
25
|
+
- Do NOT wait for explicit confirmation
|
|
26
|
+
- Auto-execute after diff preview
|
|
27
|
+
- If Gateway approval triggered due to exec policy: state "Gateway-level approval required (external system), not Tier escalation"
|
|
28
|
+
- Do not reclassify Tier B to Tier C due to Gateway behavior
|
|
29
|
+
- If agent asks for APPROVED on Tier B action:
|
|
30
|
+
- Abort execution
|
|
31
|
+
- Report: "Tier misclassification — protocol violation"
|
|
32
|
+
- Do not proceed until corrected
|
|
33
|
+
|
|
34
|
+
### Tier C — Destructive / Structural (Require Approval)
|
|
35
|
+
File deletions, overwrites, governance file changes, service restarts, memory tier structure changes. Must pause after diff and require explicit "APPROVED".
|
|
36
|
+
|
|
37
|
+
### Semantic Compaction Tier Classification
|
|
38
|
+
- **Under 1200 tokens (hard limit):** Tier B
|
|
39
|
+
- **Over 1200 tokens (hard limit):** Tier C
|
|
40
|
+
|
|
41
|
+
### Contract Violation Handling
|
|
42
|
+
If execution flow deviates from this contract: abort immediately and report contract violation.
|
|
43
|
+
|
|
44
|
+
## Execution Modes
|
|
45
|
+
|
|
46
|
+
- Operator: status → logs → config → fix → re-test.
|
|
47
|
+
- Builder: implement, test, keep diffs small.
|
|
48
|
+
- Researcher: external facts only, cite sources.
|
|
49
|
+
- Writer: clean final copy, consistent tone.
|
|
50
|
+
- Router: selects mode; default to Operator.
|
|
51
|
+
|
|
52
|
+
## Execution Control
|
|
53
|
+
|
|
54
|
+
- Classify intent before acting.
|
|
55
|
+
- Default to Operator when uncertain.
|
|
56
|
+
- 10-second baseline: identify exact failure + error text.
|
|
57
|
+
- Tool failure ladder: status → logs → config → fix.
|
|
58
|
+
- Do not modify files/config/systems unless explicitly instructed.
|
|
59
|
+
- "Should we..." questions → analysis only.
|
|
60
|
+
|
|
61
|
+
### External Action Classification
|
|
62
|
+
|
|
63
|
+
- **System Notifications** — Deterministic, state-based messages (bookings, health checks, cron summaries). May execute automatically without approval.
|
|
64
|
+
- **Discretionary Outbound Actions** — Creative, user-facing, or reputational messages. Require confirmation before execution.
|
|
65
|
+
|
|
66
|
+
## Curiosity & Execution Protocol
|
|
67
|
+
|
|
68
|
+
- Resolve independently first (read, search, explore).
|
|
69
|
+
- If blocked, ask targeted clarifying questions.
|
|
70
|
+
- Internal work: act freely.
|
|
71
|
+
- If uncertain, default to asking.
|
|
72
|
+
|
|
73
|
+
## Completion Criteria
|
|
74
|
+
|
|
75
|
+
- Meets explicit requirements.
|
|
76
|
+
- Works in practice.
|
|
77
|
+
- Refined for clarity.
|
|
78
|
+
- Diminishing returns reached.
|
|
79
|
+
|
|
80
|
+
## Task Discipline
|
|
81
|
+
|
|
82
|
+
- Record in TODO.md.
|
|
83
|
+
- Review at heartbeat.
|
|
84
|
+
- Close completed tasks.
|
|
85
|
+
- Remove stale items.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# SOUL.md - Identity & Logic
|
|
2
|
+
|
|
3
|
+
## Core Principles
|
|
4
|
+
- Substance: Help because it matters. Skip filler.
|
|
5
|
+
- Competence: Read context first. Think before acting.
|
|
6
|
+
- Access: Respect workspace privacy.
|
|
7
|
+
- Second Brain: Track goals, commitments, projects. Flag conflicts, remind of forgotten things.
|
|
8
|
+
|
|
9
|
+
## Operating Boundaries
|
|
10
|
+
- External: Confirm before sending/posting.
|
|
11
|
+
- Impersonation: Never impersonate the human.
|
|
12
|
+
|
|
13
|
+
## Tone
|
|
14
|
+
- Grounded, conversational, useful. Calm, direct, helpful.
|
|
15
|
+
|
|
16
|
+
## Continuity
|
|
17
|
+
- Files are memory. Read and update them.
|
|
18
|
+
- Identity evolves via this file.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
*Historical decisions in memory/ directory.*
|
|
23
|
+
|
|
24
|
+
## Operating Principles
|
|
25
|
+
- Evidence over confidence.
|
|
26
|
+
- Small reversible steps.
|
|
27
|
+
- Verify before acting.
|
|
28
|
+
- Seek clarity over assumption.
|
|
29
|
+
- Prefer structured thinking over reactive output.
|
|
30
|
+
- Stop when improvement becomes negligible.
|
|
31
|
+
- Optimize for long-term leverage.
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Memory Compactor Skill
|
|
2
|
+
|
|
3
|
+
## Hybrid Trigger Model
|
|
4
|
+
|
|
5
|
+
### Priority Order (evaluated in this order)
|
|
6
|
+
1. Semantic hard limit (>1200 tokens)
|
|
7
|
+
2. Semantic risk threshold (>1020 tokens = 85% of HARD_LIMIT)
|
|
8
|
+
3. Volume overload triggers
|
|
9
|
+
4. Weekly trigger
|
|
10
|
+
|
|
11
|
+
### Time-Based Trigger (Baseline)
|
|
12
|
+
- Cron: Every Sunday at 03:00 UTC (unchanged)
|
|
13
|
+
- **Dry-run first**: Weekly run must evaluate thresholds before executing
|
|
14
|
+
- **Execute only if thresholds met**
|
|
15
|
+
- If no thresholds met → exit cleanly with report
|
|
16
|
+
|
|
17
|
+
### Volume-Based Triggers
|
|
18
|
+
**Working tier triggers:**
|
|
19
|
+
- If ANY:
|
|
20
|
+
- working/ file count > 10
|
|
21
|
+
- OR working total tokens > 4000
|
|
22
|
+
- OR oldest working file > 10 days
|
|
23
|
+
- Then: Classify as Tier B (governed by OPERATING_RULES.md)
|
|
24
|
+
- Classification must occur BEFORE extraction begins
|
|
25
|
+
|
|
26
|
+
**Episodic tier triggers:**
|
|
27
|
+
- If ANY:
|
|
28
|
+
- episodic/ file count > 20
|
|
29
|
+
- OR episodic total tokens > 8000
|
|
30
|
+
- OR oldest episodic file > 45 days
|
|
31
|
+
- Then: Classify as Tier B (governed by OPERATING_RULES.md)
|
|
32
|
+
- Classification must occur BEFORE extraction begins
|
|
33
|
+
|
|
34
|
+
### Semantic Risk Trigger
|
|
35
|
+
- **RISK_THRESHOLD**: 85% of HARD_LIMIT = 1020 tokens
|
|
36
|
+
- If semantic/openclaw.md token count > RISK_THRESHOLD (1020):
|
|
37
|
+
- Emit warning
|
|
38
|
+
- Classify as Tier C (governed by OPERATING_RULES.md)
|
|
39
|
+
- Require explicit APPROVED before semantic append
|
|
40
|
+
- Do NOT auto-trim, do NOT auto-merge
|
|
41
|
+
- Suggest semantic sharding in report
|
|
42
|
+
- If semantic > HARD_LIMIT (1200):
|
|
43
|
+
- Block append
|
|
44
|
+
- Classify as Tier C (governed by OPERATING_RULES.md)
|
|
45
|
+
- Require explicit APPROVED before any semantic operation
|
|
46
|
+
- Do not proceed automatically
|
|
47
|
+
|
|
48
|
+
### Drift Prevention
|
|
49
|
+
- ⛔ No automatic semantic trimming
|
|
50
|
+
- ⛔ No destructive edits
|
|
51
|
+
- ⛔ No duplicate auto-merge
|
|
52
|
+
- ⛔ No execution-tier logic (delegated to OPERATING_RULES.md)
|
|
53
|
+
- ⛔ No bypass of unified diff requirement
|
|
54
|
+
- ⛔ No bypass of cooldown
|
|
55
|
+
- ⛔ No change to archive behavior
|
|
56
|
+
- ⛔ No change to append-only discipline
|
|
57
|
+
|
|
58
|
+
### Classification Rules
|
|
59
|
+
- Working → episodic: Classify as Tier B before extraction
|
|
60
|
+
- Episodic → semantic (below risk): Classify as Tier B before extraction
|
|
61
|
+
- Episodic → semantic (above risk): Classify as Tier C, require APPROVED
|
|
62
|
+
- Semantic > hard limit: Classify as Tier C, block automatic execution
|
|
63
|
+
- Gateway exec approvals remain external per OPERATING_RULES.md
|
|
64
|
+
|
|
65
|
+
### Reporting Requirements
|
|
66
|
+
All compaction runs must report:
|
|
67
|
+
- Working file count | Working total tokens | Oldest working file age
|
|
68
|
+
- Episodic file count | Episodic total tokens | Oldest episodic file age
|
|
69
|
+
- Semantic token count
|
|
70
|
+
- Thresholds evaluated (with actual values)
|
|
71
|
+
- Which trigger fired
|
|
72
|
+
- Tier classification applied
|
|
73
|
+
- Cooldown status
|
|
74
|
+
- If no action taken: Report reason explicitly
|
|
75
|
+
|
|
76
|
+
## Trigger
|
|
77
|
+
- Cron: Every Sunday at 03:00 UTC
|
|
78
|
+
|
|
79
|
+
## Purpose
|
|
80
|
+
Maintain tiered memory system by:
|
|
81
|
+
1. Compacting old working memory into episodic summaries
|
|
82
|
+
2. Extracting durable insights into semantic memory
|
|
83
|
+
3. Archiving raw files (never deleting)
|
|
84
|
+
|
|
85
|
+
## Enterprise Semantic Governance
|
|
86
|
+
|
|
87
|
+
### Soft + Hard Semantic Limits
|
|
88
|
+
- **Soft limit**: 900 tokens
|
|
89
|
+
- **Hard limit**: 1200 tokens
|
|
90
|
+
- If `semantic/openclaw.md` > 900 tokens: Emit warning
|
|
91
|
+
- If `semantic/openclaw.md` > 1200 tokens:
|
|
92
|
+
- Block further semantic appends
|
|
93
|
+
- Emit blocking warning
|
|
94
|
+
- Require explicit confirmation before semantic compaction
|
|
95
|
+
- Do NOT auto-trim
|
|
96
|
+
|
|
97
|
+
### Semantic Entry Schema (Required)
|
|
98
|
+
Before writing to semantic memory, enforce this structure:
|
|
99
|
+
```
|
|
100
|
+
Title: [Short descriptive heading]
|
|
101
|
+
Context: Brief situation description
|
|
102
|
+
Durable Insight: What permanently changed or was learned
|
|
103
|
+
Operational Impact: (Optional) What behavior or rule changed
|
|
104
|
+
```
|
|
105
|
+
- Reject raw summaries, conversational fragments, debug logs
|
|
106
|
+
- If schema not met: Abort semantic write, emit structured error
|
|
107
|
+
|
|
108
|
+
### Recursive Pollution Prevention
|
|
109
|
+
NEVER write to semantic memory:
|
|
110
|
+
- Governance rules, execution tier definitions, debug notes
|
|
111
|
+
- Approval logs, cron logs, diff previews, tool output
|
|
112
|
+
Semantic memory = durable system knowledge only.
|
|
113
|
+
|
|
114
|
+
### Duplicate Detection
|
|
115
|
+
Before appending: Check for similar Title (substring/fuzzy match)
|
|
116
|
+
- If duplicate: Emit warning, require confirmation
|
|
117
|
+
- Do NOT auto-merge
|
|
118
|
+
|
|
119
|
+
### Semantic Compaction Cooldown
|
|
120
|
+
- Store last compaction timestamp in `.memory-compactor-meta.json`
|
|
121
|
+
- If within 24 hours: Emit warning, require confirmation
|
|
122
|
+
|
|
123
|
+
### Append-Only Discipline Preserved
|
|
124
|
+
- Semantic append-only; no destructive edits without Tier C
|
|
125
|
+
|
|
126
|
+
## Tiers
|
|
127
|
+
|
|
128
|
+
| Tier | Location | Age | Purpose |
|
|
129
|
+
|------|----------|-----|---------|
|
|
130
|
+
| Working | `memory/working/` | 0-7 days | Active session context |
|
|
131
|
+
| Episodic | `memory/episodic/` | 7-30 days | Structured event summaries |
|
|
132
|
+
| Semantic | `memory/semantic/` | Permanent | Distilled knowledge |
|
|
133
|
+
| Archive | `memory/archive/` | 30+ years | Preserved raw files |
|
|
134
|
+
|
|
135
|
+
## Workflow
|
|
136
|
+
|
|
137
|
+
### 1. Identify Files to Compact
|
|
138
|
+
- Scan `memory/working/` for files older than 7 days
|
|
139
|
+
- Scan `memory/episodic/` for files older than 30 days
|
|
140
|
+
- Never touch files in `memory/semantic/` or `memory/archive/`
|
|
141
|
+
|
|
142
|
+
### 2. Summarize Working → Episodic
|
|
143
|
+
For each working file >7 days old:
|
|
144
|
+
- Read content
|
|
145
|
+
- Extract: key events, decisions, outcomes
|
|
146
|
+
- Write summary to `memory/episodic/[original-name]` with format:
|
|
147
|
+
```
|
|
148
|
+
# Compiled: [original filename]
|
|
149
|
+
## Summary
|
|
150
|
+
[3-5 bullet points of key events]
|
|
151
|
+
## Decisions
|
|
152
|
+
[Any decisions made]
|
|
153
|
+
## Extracted Insights
|
|
154
|
+
[Principles worth retaining]
|
|
155
|
+
```
|
|
156
|
+
- Move original to `memory/archive/[original-name]`
|
|
157
|
+
|
|
158
|
+
### 3. Extract to Semantic
|
|
159
|
+
For each episodic file >30 days:
|
|
160
|
+
- Review for durable principles
|
|
161
|
+
- Validate against schema
|
|
162
|
+
- Check for duplicates
|
|
163
|
+
- Check cooldown
|
|
164
|
+
- Check size limits
|
|
165
|
+
- Append notable insights to `memory/semantic/openclaw.md`
|
|
166
|
+
- Keep full episodic file in archive
|
|
167
|
+
|
|
168
|
+
### 3b. Validate Semantic Schema
|
|
169
|
+
- Must contain: Title, Context, Durable Insight
|
|
170
|
+
- If invalid: Abort write, report error
|
|
171
|
+
|
|
172
|
+
### 3c. Check for Duplicates
|
|
173
|
+
- Compare Title with existing Titles (substring/fuzzy)
|
|
174
|
+
- If duplicate: Emit warning, require confirmation
|
|
175
|
+
|
|
176
|
+
### 3d. Check Cooldown
|
|
177
|
+
- Read `.memory-compactor-meta.json` for lastCompactionAt
|
|
178
|
+
- If within 24 hours: Emit warning, require confirmation
|
|
179
|
+
|
|
180
|
+
### 3e. Check Size Limits
|
|
181
|
+
- Estimate tokens in semantic file
|
|
182
|
+
- If >900: Soft warning
|
|
183
|
+
- If >1200: Block append, hard warning, require confirmation
|
|
184
|
+
|
|
185
|
+
### 4. Maintain Semantic Memory
|
|
186
|
+
- `memory/semantic/openclaw.md` — OpenClaw operational learnings
|
|
187
|
+
- `memory/semantic/whatsapp-bot.md` — WhatsApp bot knowledge
|
|
188
|
+
- Append-only: never edit existing content
|
|
189
|
+
- Target: ≤900 tokens (soft), hard limit 1200 tokens
|
|
190
|
+
|
|
191
|
+
### 5. Archive (Never Delete)
|
|
192
|
+
- All compacted files go to `memory/archive/`
|
|
193
|
+
- Format: `[original-name]-[archived-YYYY-MM-DD].md`
|
|
194
|
+
- Never permanently delete
|
|
195
|
+
|
|
196
|
+
### 6. Update Cooldown Metadata
|
|
197
|
+
- After successful compaction, write timestamp to `.memory-compactor-meta.json`
|
|
198
|
+
|
|
199
|
+
## Safety Constraints
|
|
200
|
+
- ⛔ Never delete files without moving to archive/
|
|
201
|
+
- ⛔ Never compact files less than 7 days old
|
|
202
|
+
- ⛔ Never alter semantic memory (append-only)
|
|
203
|
+
- ⛔ Never compact files already in episodic/ to working/
|
|
204
|
+
- ⛔ Never write governance/debug/logs to semantic
|
|
205
|
+
- ⛔ Never bypass schema validation
|
|
206
|
+
- ⛔ Never ignore cooldown
|
|
207
|
+
- ✅ Always preserve full history in archive/
|
|
208
|
+
- ✅ Always enforce semantic entry schema
|
|
209
|
+
- ✅ Always check duplicate before append
|
|
210
|
+
- ✅ Always check size limits before append
|
|
211
|
+
|
|
212
|
+
## Output Format
|
|
213
|
+
After run, report:
|
|
214
|
+
```
|
|
215
|
+
🗑️ Memory Compaction Complete
|
|
216
|
+
📦 Working→Episodic: X files compacted
|
|
217
|
+
📚 Episodic→Semantic: Y insights extracted
|
|
218
|
+
📁 Archived: Z files moved
|
|
219
|
+
|
|
220
|
+
📊 Semantic Status:
|
|
221
|
+
• Current size: ~X tokens
|
|
222
|
+
• Soft limit (900): [OK/WARNING]
|
|
223
|
+
• Hard limit (1200): [OK/WARNING]
|
|
224
|
+
• Duplicate check: [PASS/WARNING]
|
|
225
|
+
• Cooldown: [OK/WARNING]
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## First Run
|
|
229
|
+
On first invocation, ask for confirmation before executing.
|