@sdotwinter/openclaw-deterministic 0.6.0 → 0.8.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/bin/doctor.js CHANGED
@@ -3,25 +3,19 @@
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
5
 
6
+ const pkg = require("../package.json");
7
+
6
8
  const HOME = process.env.HOME;
7
- const workspace = path.join(HOME, ".openclaw", "workspace");
9
+ const openclawRoot = path.join(HOME, ".openclaw");
10
+ const workspace = path.join(openclawRoot, "workspace");
8
11
 
9
- const paths = {
12
+ const files = {
10
13
  operating: path.join(workspace, "OPERATING_RULES.md"),
11
- soul: path.join(workspace, "SOUL.md"),
12
14
  detSoul: path.join(workspace, "SOUL.deterministic.md"),
15
+ soul: path.join(workspace, "SOUL.md"),
13
16
  compactor: path.join(workspace, "skills", "memory-compactor", "SKILL.md"),
14
- semantic: path.join(workspace, "memory", "semantic", "openclaw.md"),
15
17
  };
16
18
 
17
- const MARKER_OVERLAY = "## Deterministic Governance Overlay";
18
- const MARKER_OPERATING_CANON = "Deterministic Execution Contract — Hardened Overlay";
19
- const MARKER_DETSOUL_CANON = "Deterministic Governance Overlay — Canonical";
20
- const MARKER_COMPACTOR_CANON = "## Hybrid Trigger Model";
21
-
22
- const HARD_LIMIT = 1200;
23
- const RISK_THRESHOLD = 1020;
24
-
25
19
  function exists(p) {
26
20
  try {
27
21
  fs.accessSync(p);
@@ -35,68 +29,89 @@ function read(p) {
35
29
  return fs.readFileSync(p, "utf8");
36
30
  }
37
31
 
38
- // cheap, consistent estimate (good enough for thresholds)
39
- function tokenEstimate(text) {
40
- if (!text) return 0;
41
- const words = text.trim().split(/\s+/).filter(Boolean).length;
42
- return Math.ceil(words * 1.3);
32
+ function versionFromFile(content) {
33
+ const match = content.match(/Installed by openclaw-deterministic v([0-9.]+)/);
34
+ return match ? match[1] : null;
43
35
  }
44
36
 
45
- function ok(msg) { console.log(`✅ ${msg}`); }
46
- function warn(msg) { console.log(`⚠ ${msg}`); }
47
- function fail(msg) { console.log(`❌ ${msg}`); }
37
+ function checkVersion(filePath, label) {
38
+ if (!exists(filePath)) {
39
+ console.log(`❌ ${label} missing.`);
40
+ return;
41
+ }
48
42
 
49
- console.log("\nRunning deterministic doctor...\n");
43
+ const content = read(filePath);
44
+ const version = versionFromFile(content);
50
45
 
51
- // --- Presence checks
52
- exists(paths.operating) ? ok("OPERATING_RULES.md present.") : fail("OPERATING_RULES.md missing.");
53
- exists(paths.detSoul) ? ok("SOUL.deterministic.md present.") : fail("SOUL.deterministic.md missing.");
54
- exists(paths.compactor) ? ok("memory-compactor SKILL.md present.") : fail("memory-compactor SKILL.md missing.");
55
- exists(paths.soul) ? ok("SOUL.md present.") : fail("SOUL.md missing.");
46
+ if (!version) {
47
+ console.log(`⚠ ${label} version stamp missing.`);
48
+ return;
49
+ }
50
+
51
+ if (version === pkg.version) {
52
+ console.log(`✅ ${label} version matches CLI (${version})`);
53
+ } else {
54
+ console.log(`⚠ ${label} version mismatch (installed ${version}, CLI ${pkg.version})`);
55
+ }
56
+ }
56
57
 
57
- // If core files are missing, stop early (still exit cleanly)
58
- if (!exists(paths.operating) || !exists(paths.detSoul) || !exists(paths.compactor) || !exists(paths.soul)) {
59
- console.log("\nDoctor complete (incomplete install).\n");
60
- process.exit(0);
58
+ function overlayEnabled() {
59
+ if (!exists(files.soul)) return false;
60
+ const content = read(files.soul);
61
+ return content.includes("SOUL.deterministic.md");
61
62
  }
62
63
 
63
- // --- Activation checks
64
- const soul = read(paths.soul);
65
- if (soul.includes(MARKER_OVERLAY)) ok("Deterministic overlay ENABLED in SOUL.md.");
66
- else warn("Deterministic overlay installed but NOT enabled (run: oc-deterministic enable).");
64
+ function estimateSemanticTokens() {
65
+ const semanticPath = path.join(
66
+ openclawRoot,
67
+ "workspace",
68
+ "memory",
69
+ "semantic",
70
+ "openclaw.md"
71
+ );
67
72
 
68
- // --- Integrity checks (cross-file coherence)
69
- const operating = read(paths.operating);
70
- if (operating.includes(MARKER_OPERATING_CANON)) ok("OPERATING_RULES.md matches canonical marker.");
71
- else warn("OPERATING_RULES.md marker missing (file may be customized or outdated).");
73
+ if (!exists(semanticPath)) return 0;
72
74
 
73
- if (operating.includes("SOUL.deterministic.md")) ok("OPERATING_RULES.md references SOUL.deterministic.md.");
74
- else warn("OPERATING_RULES.md does not reference SOUL.deterministic.md (recommended).");
75
+ const content = read(semanticPath);
76
+ return Math.ceil(content.length / 4);
77
+ }
75
78
 
76
- const detSoul = read(paths.detSoul);
77
- if (detSoul.includes(MARKER_DETSOUL_CANON)) ok("SOUL.deterministic.md matches canonical marker.");
78
- else warn("SOUL.deterministic.md marker missing (file may be customized or outdated).");
79
+ console.log("\nRunning deterministic doctor...\n");
79
80
 
80
- const compactor = read(paths.compactor);
81
- if (compactor.includes(MARKER_COMPACTOR_CANON)) ok("memory-compactor includes Hybrid Trigger Model.");
82
- else warn("memory-compactor missing Hybrid Trigger Model marker (skill may be outdated).");
81
+ if (!exists(openclawRoot)) {
82
+ console.log(" OpenClaw directory not found.");
83
+ process.exit(1);
84
+ }
83
85
 
84
- // --- Semantic health
85
- if (exists(paths.semantic)) {
86
- const semantic = read(paths.semantic);
87
- const tokens = tokenEstimate(semantic);
86
+ if (!exists(workspace)) {
87
+ console.log("❌ Workspace missing.");
88
+ process.exit(1);
89
+ }
88
90
 
89
- console.log(`\nSemantic memory tokens (est): ${tokens}`);
91
+ checkVersion(files.operating, "OPERATING_RULES.md");
92
+ checkVersion(files.detSoul, "SOUL.deterministic.md");
93
+ checkVersion(files.compactor, "memory-compactor SKILL.md");
90
94
 
91
- if (tokens > HARD_LIMIT) {
92
- warn("ABOVE HARD LIMIT (Tier C enforced for semantic operations).");
93
- } else if (tokens > RISK_THRESHOLD) {
94
- warn("Near risk threshold (85%). Semantic appends should behave as Tier C per compactor rules.");
95
+ if (exists(files.soul)) {
96
+ console.log(" SOUL.md present.");
97
+ if (overlayEnabled()) {
98
+ console.log(" Deterministic overlay ENABLED in SOUL.md.");
95
99
  } else {
96
- ok("Semantic memory within safe bounds.");
100
+ console.log(" Deterministic overlay NOT enabled in SOUL.md.");
97
101
  }
98
102
  } else {
99
- console.log("\nℹ No semantic memory file detected (ok).");
103
+ console.log(" SOUL.md not found.");
104
+ }
105
+
106
+ const semanticTokens = estimateSemanticTokens();
107
+ console.log(`\nSemantic memory tokens (est): ${semanticTokens}`);
108
+
109
+ if (semanticTokens > 1200) {
110
+ console.log("❌ Semantic memory exceeds HARD_LIMIT (1200).");
111
+ } else if (semanticTokens > 1020) {
112
+ console.log("⚠ Semantic memory above risk threshold (1020).");
113
+ } else {
114
+ console.log("✅ Semantic memory within safe bounds.");
100
115
  }
101
116
 
102
117
  console.log("\nDoctor complete.\n");
package/bin/install.js CHANGED
@@ -3,11 +3,16 @@
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
5
 
6
+ const pkg = require("../package.json");
7
+
6
8
  const HOME = process.env.HOME;
7
9
  const openclawRoot = path.join(HOME, ".openclaw");
8
10
  const workspace = path.join(openclawRoot, "workspace");
9
11
  const backupsRoot = path.join(openclawRoot, "backups", "deterministic");
10
12
 
13
+ const args = process.argv.slice(2);
14
+ const DRY_RUN = args.includes("--dry-run");
15
+
11
16
  const tpl = (name) => path.join(__dirname, "..", "templates", name);
12
17
 
13
18
  const target = {
@@ -24,56 +29,72 @@ This system loads and adheres to SOUL.deterministic.md as a governing philosophi
24
29
  `;
25
30
 
26
31
  function exists(p) {
27
- try { fs.accessSync(p); return true; } catch { return false; }
32
+ try {
33
+ fs.accessSync(p);
34
+ return true;
35
+ } catch {
36
+ return false;
37
+ }
28
38
  }
29
39
 
30
40
  function ensureDir(p) {
31
- fs.mkdirSync(p, { recursive: true });
32
- }
33
-
34
- function read(p) {
35
- return fs.readFileSync(p, "utf8");
41
+ if (!DRY_RUN) {
42
+ fs.mkdirSync(p, { recursive: true });
43
+ }
36
44
  }
37
45
 
38
- function write(p, content) {
46
+ function writeFile(p, content) {
47
+ if (DRY_RUN) {
48
+ console.log(`[DRY-RUN] Would write: ${p}`);
49
+ return;
50
+ }
39
51
  ensureDir(path.dirname(p));
40
52
  fs.writeFileSync(p, content);
41
53
  }
42
54
 
43
- function copyFile(src, dst) {
44
- ensureDir(path.dirname(dst));
45
- fs.copyFileSync(src, dst);
55
+ function copyWithVersionStamp(templatePath, targetPath) {
56
+ const versionStamp = `<!-- Installed by openclaw-deterministic v${pkg.version} -->\n`;
57
+ const content = fs.readFileSync(templatePath, "utf8");
58
+ const stamped = versionStamp + content;
59
+
60
+ if (DRY_RUN) {
61
+ console.log(`[DRY-RUN] Would install: ${targetPath}`);
62
+ }
63
+
64
+ writeFile(targetPath, stamped);
46
65
  }
47
66
 
48
- function stamp() {
49
- return new Date().toISOString().replaceAll(":", "-");
67
+ function timestamp() {
68
+ return new Date().toISOString().replace(/:/g, "-");
50
69
  }
51
70
 
52
71
  function backupSnapshot(pathsToBackup) {
72
+ if (DRY_RUN) {
73
+ console.log("[DRY-RUN] Would create backup snapshot.");
74
+ return null;
75
+ }
76
+
53
77
  ensureDir(backupsRoot);
54
- const snap = path.join(backupsRoot, stamp());
78
+ const snap = path.join(backupsRoot, timestamp());
55
79
  ensureDir(snap);
56
80
 
57
81
  for (const p of pathsToBackup) {
58
82
  if (!exists(p)) continue;
59
- const rel = path.relative(openclawRoot, p); // keep structure
60
- const dst = path.join(snap, rel);
61
- ensureDir(path.dirname(dst));
62
- fs.copyFileSync(p, dst);
83
+
84
+ const relative = path.relative(openclawRoot, p);
85
+ const destination = path.join(snap, relative);
86
+
87
+ ensureDir(path.dirname(destination));
88
+ fs.copyFileSync(p, destination);
63
89
  }
64
90
 
65
91
  return snap;
66
92
  }
67
93
 
68
94
  function installTemplates() {
69
- copyFile(tpl("OPERATING_RULES.md"), target.operating);
70
- console.log("Installed: OPERATING_RULES.md");
71
-
72
- copyFile(tpl("SOUL.deterministic.md"), target.detSoul);
73
- console.log("Installed: SOUL.deterministic.md");
74
-
75
- copyFile(tpl("memory-compactor.SKILL.md"), target.compactor);
76
- console.log("Installed: skills/memory-compactor/SKILL.md");
95
+ copyWithVersionStamp(tpl("OPERATING_RULES.md"), target.operating);
96
+ copyWithVersionStamp(tpl("SOUL.deterministic.md"), target.detSoul);
97
+ copyWithVersionStamp(tpl("memory-compactor.SKILL.md"), target.compactor);
77
98
  }
78
99
 
79
100
  function bootstrapSoulIfMissing() {
@@ -83,28 +104,50 @@ function bootstrapSoulIfMissing() {
83
104
  }
84
105
 
85
106
  console.log("No SOUL.md detected — bootstrapping fresh SOUL.md with deterministic overlay.");
86
- write(target.soul, OVERLAY_BLOCK.trim() + "\n");
107
+
108
+ if (DRY_RUN) {
109
+ console.log("[DRY-RUN] Would create SOUL.md with deterministic overlay.");
110
+ return;
111
+ }
112
+
113
+ writeFile(target.soul, OVERLAY_BLOCK.trim() + "\n");
87
114
  console.log("Created: SOUL.md (deterministic overlay enabled by default)");
88
115
  }
89
116
 
90
117
  if (!exists(openclawRoot)) {
91
118
  console.error("OpenClaw not found at ~/.openclaw");
92
- console.error("Install OpenClaw first, then rerun oc-deterministic install.");
93
119
  process.exit(1);
94
120
  }
95
121
 
96
122
  if (!exists(workspace)) {
97
123
  console.error("OpenClaw workspace missing at ~/.openclaw/workspace");
98
- console.error("OpenClaw may not be fully initialized. Run `openclaw onboard` then retry.");
99
124
  process.exit(1);
100
125
  }
101
126
 
102
- console.log("Creating deterministic backup snapshot...");
103
- const snap = backupSnapshot([target.operating, target.detSoul, target.soul, target.compactor]);
104
- console.log(`Backup location: ${snap}`);
127
+ if (DRY_RUN) {
128
+ console.log("\nRunning deterministic install (dry-run mode)...\n");
129
+ } else {
130
+ console.log("Creating deterministic backup snapshot...");
131
+ }
132
+
133
+ const snap = backupSnapshot([
134
+ target.operating,
135
+ target.detSoul,
136
+ target.soul,
137
+ target.compactor,
138
+ ]);
139
+
140
+ if (snap) {
141
+ console.log(`Backup location: ${snap}`);
142
+ }
105
143
 
106
144
  installTemplates();
107
145
  bootstrapSoulIfMissing();
108
146
 
109
- console.log("\nDeterministic governance installed successfully.");
147
+ if (DRY_RUN) {
148
+ console.log("\nDry-run complete. No changes were written.\n");
149
+ } else {
150
+ console.log("\nDeterministic governance installed successfully.\n");
151
+ }
152
+
110
153
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdotwinter/openclaw-deterministic",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Deterministic governance and memory compaction layer for OpenClaw",
5
5
  "keywords": [
6
6
  "openclaw",