@cleocode/cleo 2026.4.131 → 2026.4.132

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/dist/cli/index.js CHANGED
@@ -5148,6 +5148,43 @@ var init_registry = __esm({
5148
5148
  }
5149
5149
  ]
5150
5150
  },
5151
+ // T1147 W7 — BRAIN noise sweep (shadow-write envelope, self-healing gate)
5152
+ {
5153
+ gateway: "query",
5154
+ domain: "memory",
5155
+ operation: "sweep",
5156
+ description: "memory.sweep (query/mutate) \u2014 T1147 W7 BRAIN noise sweep. dry-run: detect noise candidates and write sample JSON to agent-outputs. approve <runId>: apply sweep to live brain tables (sets killSwitch during tx). status: list all noise-sweep-2440 runs. rollback <runId>: discard a staged run without applying changes.",
5157
+ tier: 0,
5158
+ idempotent: false,
5159
+ sessionRequired: false,
5160
+ requiredParams: [],
5161
+ params: [
5162
+ {
5163
+ name: "dry-run",
5164
+ type: "boolean",
5165
+ required: false,
5166
+ description: "Detect noise candidates without staging DB writes."
5167
+ },
5168
+ {
5169
+ name: "approve",
5170
+ type: "string",
5171
+ required: false,
5172
+ description: "Run ID to approve and apply to live tables."
5173
+ },
5174
+ {
5175
+ name: "status",
5176
+ type: "boolean",
5177
+ required: false,
5178
+ description: "List recent noise-sweep-2440 runs."
5179
+ },
5180
+ {
5181
+ name: "rollback",
5182
+ type: "string",
5183
+ required: false,
5184
+ description: "Run ID to roll back without applying changes."
5185
+ }
5186
+ ]
5187
+ },
5151
5188
  // T791 — LLM extraction backend status
5152
5189
  {
5153
5190
  gateway: "query",
@@ -19015,19 +19052,141 @@ var init_memory2 = __esm({
19015
19052
  const { scanBrainNoise } = await import("@cleocode/core/memory/brain-doctor.js");
19016
19053
  const result = await scanBrainNoise(projectRoot);
19017
19054
  const assertClean = params?.["assert-clean"];
19018
- if (assertClean && !result.isClean) {
19019
- return errorResult(
19055
+ if (assertClean) {
19056
+ let pendingCandidates = 0;
19057
+ try {
19058
+ const { getBrainNativeDb: _getDoctorNativeDb } = await import("@cleocode/core/store/memory-sqlite.js");
19059
+ const doctorNativeDb = _getDoctorNativeDb();
19060
+ if (doctorNativeDb) {
19061
+ const tableExists = doctorNativeDb.prepare(
19062
+ `SELECT name FROM sqlite_master WHERE type='table' AND name='brain_v2_candidate'`
19063
+ ).get();
19064
+ if (tableExists) {
19065
+ const countRow = doctorNativeDb.prepare(
19066
+ `SELECT COUNT(*) AS cnt FROM brain_v2_candidate WHERE validation_status = 'pending'`
19067
+ ).get();
19068
+ pendingCandidates = countRow?.cnt ?? 0;
19069
+ }
19070
+ }
19071
+ } catch {
19072
+ }
19073
+ if (!result.isClean) {
19074
+ return errorResult(
19075
+ "query",
19076
+ "memory",
19077
+ operation,
19078
+ "E_BRAIN_NOISE_DETECTED",
19079
+ `Brain noise detected: ${result.findings.length} pattern(s) across ${result.totalScanned} entries. ` + result.findings.map((f) => `${f.pattern}(${f.count})`).join(", ") + ". Run `cleo memory doctor` for details. Fix noise before enabling Sentient v1 (M7 gate).",
19080
+ startTime
19081
+ );
19082
+ }
19083
+ if (pendingCandidates > 0) {
19084
+ return errorResult(
19085
+ "query",
19086
+ "memory",
19087
+ operation,
19088
+ "E_SWEEP_PENDING",
19089
+ `Staged sweep has ${pendingCandidates} pending brain_v2_candidate rows. Run \`cleo memory sweep --status\` to review, then \`cleo memory sweep --approve <runId>\` to apply.`,
19090
+ startTime
19091
+ );
19092
+ }
19093
+ } else if (!result.isClean) {
19094
+ }
19095
+ return wrapResult(
19096
+ { success: true, data: { ...result, pendingCandidates: 0 } },
19097
+ "query",
19098
+ "memory",
19099
+ operation,
19100
+ startTime
19101
+ );
19102
+ }
19103
+ // T1147 W7 — BRAIN noise sweep (shadow-write envelope, self-healing gate)
19104
+ case "sweep": {
19105
+ const dryRun = params?.["dry-run"] === true || params?.dryRun === true;
19106
+ const approveRunId = params?.approve;
19107
+ const statusQuery = params?.status === true;
19108
+ const rollbackRunId = params?.rollback;
19109
+ if (statusQuery) {
19110
+ const { getBrainDb: _getBrainDb2, getBrainNativeDb: _getNativeDb2 } = await import("@cleocode/core/store/memory-sqlite.js");
19111
+ const sweepDb = await _getBrainDb2(projectRoot);
19112
+ const nativeDb2 = _getNativeDb2();
19113
+ if (!nativeDb2) {
19114
+ return errorResult(
19115
+ "query",
19116
+ "memory",
19117
+ operation,
19118
+ "E_DB_UNAVAILABLE",
19119
+ "brain.db not available",
19120
+ startTime
19121
+ );
19122
+ }
19123
+ const rows = nativeDb2.prepare(
19124
+ `SELECT id, status, rows_affected, created_at, approved_at, approved_by
19125
+ FROM brain_backfill_runs
19126
+ WHERE kind = 'noise-sweep-2440'
19127
+ ORDER BY created_at DESC
19128
+ LIMIT 20`
19129
+ ).all();
19130
+ void sweepDb;
19131
+ return wrapResult(
19132
+ { success: true, data: { runs: rows } },
19020
19133
  "query",
19021
19134
  "memory",
19022
19135
  operation,
19023
- "E_BRAIN_NOISE_DETECTED",
19024
- `Brain noise detected: ${result.findings.length} pattern(s) across ${result.totalScanned} entries. ` + result.findings.map((f) => `${f.pattern}(${f.count})`).join(", ") + ". Run `cleo memory doctor` for details. Fix noise before enabling Sentient v1 (M7 gate).",
19025
19136
  startTime
19026
19137
  );
19027
19138
  }
19139
+ if (approveRunId) {
19140
+ const { executeSweep } = await import("@cleocode/core/memory/brain-sweep-executor.js");
19141
+ const result = await executeSweep({
19142
+ projectRoot,
19143
+ runId: approveRunId,
19144
+ approvedBy: "cleo-cli"
19145
+ });
19146
+ if (!result.success) {
19147
+ return errorResult(
19148
+ "mutate",
19149
+ "memory",
19150
+ operation,
19151
+ "E_SWEEP_FAILED",
19152
+ result.errorMessage ?? "Sweep failed",
19153
+ startTime
19154
+ );
19155
+ }
19156
+ return wrapResult(
19157
+ { success: true, data: result },
19158
+ "mutate",
19159
+ "memory",
19160
+ operation,
19161
+ startTime
19162
+ );
19163
+ }
19164
+ if (rollbackRunId) {
19165
+ const { rollbackSweep } = await import("@cleocode/core/memory/brain-sweep-executor.js");
19166
+ const rolled = await rollbackSweep(projectRoot, rollbackRunId);
19167
+ if (!rolled) {
19168
+ return errorResult(
19169
+ "mutate",
19170
+ "memory",
19171
+ operation,
19172
+ "E_SWEEP_ROLLBACK_FAILED",
19173
+ `Run '${rollbackRunId}' not found or not in staged status`,
19174
+ startTime
19175
+ );
19176
+ }
19177
+ return wrapResult(
19178
+ { success: true, data: { rolledBack: rollbackRunId } },
19179
+ "mutate",
19180
+ "memory",
19181
+ operation,
19182
+ startTime
19183
+ );
19184
+ }
19185
+ const { detectNoiseCandidates } = await import("@cleocode/core/memory/brain-noise-detector.js");
19186
+ const detectResult = await detectNoiseCandidates(projectRoot, { dryRun });
19028
19187
  return wrapResult(
19029
- { success: true, data: result },
19030
- "query",
19188
+ { success: true, data: detectResult },
19189
+ dryRun ? "query" : "mutate",
19031
19190
  "memory",
19032
19191
  operation,
19033
19192
  startTime
@@ -20131,8 +20290,10 @@ var init_memory2 = __esm({
20131
20290
  "code.links",
20132
20291
  "code.memories-for-code",
20133
20292
  "code.for-memory",
20134
- // T1262 — brain noise detector (E1-parallel, read-only)
20293
+ // T1262 — brain noise detector (E1-parallel, read-only) + assert-clean gate
20135
20294
  "doctor",
20295
+ // T1147 W7 — sweep status query (dry-run mode)
20296
+ "sweep",
20136
20297
  // T791 — LLM extraction backend status
20137
20298
  "llm-status",
20138
20299
  // T792 — pending verification queue