Files
16gagent/scripts/guard-dreaming-phase.mjs
2026-06-06 10:40:48 +08:00

107 lines
3.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Guard 6: Dreaming Phase Guard
* Prevents dreaming phase proliferation beyond 3 phases.
*
* → Architecture Freeze v2 (PR-1): docs/architecture-freeze-v2.md
* → Current: light, deep, rem | Legacy: rem → to be replaced by promote
*
* Currently allowed phases: light, deep, rem
* After PR-5: will be reduced to collect, promote
*
* FAIL: new dreaming phase appears (count > 3)
* PASS: phase count <= 3
*/
import { readdirSync, readFileSync, existsSync } from "node:fs";
import { join } from "node:path";
const OPENCLAW_HOME = process.env.OPENCLAW_HOME || "/opt/homebrew/lib/node_modules/openclaw";
const EXTENSIONS_DIR = join(OPENCLAW_HOME, "dist", "extensions");
const PHASE_LIMIT = 3; // Current baseline
const POST_PR5_LIMIT = 2; // After PR-5: collect + promote
function guardDreamingPhases() {
const issues = [];
let foundPhases = [];
let source = "none";
// Check memory-core plugin config schema
const memoryCorePath = join(EXTENSIONS_DIR, "memory-core", "openclaw.plugin.json");
if (existsSync(memoryCorePath)) {
try {
const plugin = JSON.parse(readFileSync(memoryCorePath, "utf8"));
const dreaming = plugin.configSchema?.properties?.dreaming;
if (dreaming) {
const phases = dreaming.properties?.phases?.properties;
if (phases) {
foundPhases = Object.keys(phases);
source = "memory-core/openclaw.plugin.json → configSchema.properties.dreaming.properties.phases";
}
}
} catch (e) {
issues.push({ level: "ERROR", msg: `Could not parse memory-core plugin.json: ${e.message}` });
}
}
// Also check active-memory for dreaming references
const activeMemoryPath = join(EXTENSIONS_DIR, "active-memory", "openclaw.plugin.json");
if (existsSync(activeMemoryPath)) {
try {
const plugin = JSON.parse(readFileSync(activeMemoryPath, "utf8"));
// Check if active-memory references phases
const configKeys = Object.keys(plugin.configSchema?.properties || {});
if (configKeys.includes("dreaming")) {
// Active memory has dreaming config too
}
} catch {}
}
console.log("");
console.log("═══════════════════════════════════════");
console.log(" Guard 6: Dreaming Phase Guard");
console.log("═══════════════════════════════════════");
console.log("");
if (foundPhases.length === 0) {
console.log(" No dreaming phases found in plugin config schemas.");
console.log(" (This may indicate a config schema location change.)");
issues.push({ level: "WARN", msg: "Could not locate dreaming phases in config schema" });
} else {
console.log(` Source: ${source}`);
console.log(` Dreaming phases: ${foundPhases.join(", ")}`);
console.log(` Phase count: ${foundPhases.length}`);
console.log(` Current limit: ${PHASE_LIMIT} (light, deep, rem)`);
console.log(` Post-PR5 limit: ${POST_PR5_LIMIT} (collect, promote)`);
if (foundPhases.length > PHASE_LIMIT) {
issues.push({
level: "FAIL",
msg: `Dreaming phase count ${foundPhases.length} exceeds limit ${PHASE_LIMIT}`
});
} else {
console.log(`\n Phase details:`);
for (const phase of foundPhases) {
console.log(`${phase}`);
}
}
}
console.log("");
for (const issue of issues) {
console.log(` [${issue.level}] ${issue.msg}`);
}
if (issues.filter(i => i.level === "FAIL").length === 0) {
console.log(" ✓ PASS: dreaming phase count within allowed limit");
console.log(` (After PR-5, limit will be reduced from ${PHASE_LIMIT}${POST_PR5_LIMIT})`);
process.exit(0);
} else {
console.log(" ✗ FAIL: dreaming phase count exceeded");
process.exit(1);
}
}
guardDreamingPhases();