@sdotwinter/openclaw-deterministic 0.9.0 → 0.11.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.
Files changed (2) hide show
  1. package/bin/doctor.js +83 -4
  2. package/package.json +1 -1
package/bin/doctor.js CHANGED
@@ -12,6 +12,17 @@ const HOME = process.env.HOME;
12
12
  const openclawRoot = path.join(HOME, ".openclaw");
13
13
  const workspace = path.join(openclawRoot, "workspace");
14
14
 
15
+ const DEFAULT_HARD_LIMIT = 1200;
16
+ const DEFAULT_RISK_THRESHOLD = 1020;
17
+
18
+ const episodicLogPath = path.join(
19
+ openclawRoot,
20
+ "workspace",
21
+ "memory",
22
+ "episodic",
23
+ "governance-log.md"
24
+ );
25
+
15
26
  const files = {
16
27
  operating: path.join(workspace, "OPERATING_RULES.md"),
17
28
  detSoul: path.join(workspace, "SOUL.deterministic.md"),
@@ -32,6 +43,18 @@ function read(p) {
32
43
  return fs.readFileSync(p, "utf8");
33
44
  }
34
45
 
46
+ function appendGovernanceEvent(event) {
47
+ try {
48
+ const timestamp = new Date().toISOString();
49
+ const entry = `\n---\nTime: ${timestamp}\nType: ${event.type}\nDetails: ${event.details}\n---\n`;
50
+
51
+ fs.mkdirSync(path.dirname(episodicLogPath), { recursive: true });
52
+ fs.appendFileSync(episodicLogPath, entry);
53
+ } catch {
54
+ // Logging must never crash doctor
55
+ }
56
+ }
57
+
35
58
  function versionFromFile(content) {
36
59
  const match = content.match(/Installed by openclaw-deterministic v([0-9.]+)/);
37
60
  return match ? match[1] : null;
@@ -77,6 +100,20 @@ function evaluateVersion(filePath) {
77
100
  return { status: "mismatch", version };
78
101
  }
79
102
 
103
+ function parseHardLimit() {
104
+ if (!exists(files.compactor)) return null;
105
+ const content = read(files.compactor);
106
+ const match = content.match(/HARD_LIMIT[^0-9]*([0-9]+)/);
107
+ return match ? parseInt(match[1], 10) : null;
108
+ }
109
+
110
+ function parseRiskThreshold() {
111
+ if (!exists(files.compactor)) return null;
112
+ const content = read(files.compactor);
113
+ const match = content.match(/RISK_THRESHOLD[^0-9]*([0-9]+)/);
114
+ return match ? parseInt(match[1], 10) : null;
115
+ }
116
+
80
117
  function evaluate() {
81
118
  const result = {
82
119
  cliVersion: pkg.version,
@@ -86,6 +123,13 @@ function evaluate() {
86
123
  overlayEnabled: false,
87
124
  semanticTokens: 0,
88
125
  semanticStatus: "safe",
126
+ limits: {
127
+ hardLimitConfigured: null,
128
+ riskThresholdConfigured: null,
129
+ hardLimitDefault: DEFAULT_HARD_LIMIT,
130
+ riskThresholdDefault: DEFAULT_RISK_THRESHOLD,
131
+ coherent: true,
132
+ },
89
133
  };
90
134
 
91
135
  if (!result.openclawDetected || !result.workspaceDetected) {
@@ -101,9 +145,26 @@ function evaluate() {
101
145
  const tokens = estimateSemanticTokens();
102
146
  result.semanticTokens = tokens;
103
147
 
104
- if (tokens > 1200) {
148
+ const hardLimit = parseHardLimit();
149
+ const riskThreshold = parseRiskThreshold();
150
+
151
+ result.limits.hardLimitConfigured = hardLimit;
152
+ result.limits.riskThresholdConfigured = riskThreshold;
153
+
154
+ if (hardLimit && hardLimit !== DEFAULT_HARD_LIMIT) {
155
+ result.limits.coherent = false;
156
+ }
157
+
158
+ if (riskThreshold && riskThreshold !== DEFAULT_RISK_THRESHOLD) {
159
+ result.limits.coherent = false;
160
+ }
161
+
162
+ const effectiveHardLimit = hardLimit || DEFAULT_HARD_LIMIT;
163
+ const effectiveRiskThreshold = riskThreshold || DEFAULT_RISK_THRESHOLD;
164
+
165
+ if (tokens > effectiveHardLimit) {
105
166
  result.semanticStatus = "hard-limit-exceeded";
106
- } else if (tokens > 1020) {
167
+ } else if (tokens > effectiveRiskThreshold) {
107
168
  result.semanticStatus = "risk-threshold";
108
169
  } else {
109
170
  result.semanticStatus = "safe";
@@ -135,12 +196,18 @@ function printHuman(result) {
135
196
 
136
197
  if (info.status === "missing") {
137
198
  console.log(`❌ ${label} missing.`);
199
+ appendGovernanceEvent({ type: "file-missing", details: label });
138
200
  } else if (info.status === "no-stamp") {
139
201
  console.log(`⚠ ${label} version stamp missing.`);
202
+ appendGovernanceEvent({ type: "no-version-stamp", details: label });
140
203
  } else if (info.status === "mismatch") {
141
204
  console.log(
142
205
  `⚠ ${label} version mismatch (installed ${info.version}, CLI ${pkg.version})`
143
206
  );
207
+ appendGovernanceEvent({
208
+ type: "version-mismatch",
209
+ details: `${label} installed ${info.version}, CLI ${pkg.version}`,
210
+ });
144
211
  } else {
145
212
  console.log(`✅ ${label} version matches CLI (${info.version})`);
146
213
  }
@@ -153,12 +220,24 @@ function printHuman(result) {
153
220
  : "⚠ Deterministic overlay NOT enabled in SOUL.md."
154
221
  );
155
222
 
223
+ if (!result.limits.coherent) {
224
+ console.log("⚠ Threshold configuration drift detected in SKILL.md.");
225
+ appendGovernanceEvent({
226
+ type: "threshold-drift",
227
+ details: `HARD_LIMIT=${result.limits.hardLimitConfigured}, RISK_THRESHOLD=${result.limits.riskThresholdConfigured}`,
228
+ });
229
+ }
230
+
156
231
  console.log(`\nSemantic memory tokens (est): ${result.semanticTokens}`);
157
232
 
158
233
  if (result.semanticStatus === "hard-limit-exceeded") {
159
- console.log("❌ Semantic memory exceeds HARD_LIMIT (1200).");
234
+ console.log("❌ Semantic memory exceeds HARD_LIMIT.");
235
+ appendGovernanceEvent({
236
+ type: "semantic-hard-limit-exceeded",
237
+ details: `Tokens=${result.semanticTokens}`,
238
+ });
160
239
  } else if (result.semanticStatus === "risk-threshold") {
161
- console.log("⚠ Semantic memory above risk threshold (1020).");
240
+ console.log("⚠ Semantic memory above risk threshold.");
162
241
  } else {
163
242
  console.log("✅ Semantic memory within safe bounds.");
164
243
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdotwinter/openclaw-deterministic",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Deterministic governance and memory compaction layer for OpenClaw",
5
5
  "keywords": [
6
6
  "openclaw",