Files
ruflo/plugins/ruflo-core/scripts/command-recording-switch.test.cjs
RuFlo 18ecd8ae7b fix(memory,hooks): keep the on-disk format on sql.js write-back (#4057); command-recording off switch, redaction and a cleanup that sees expired rows (#4056)
#4057: with encryption at rest on, `memory purge`'s sql.js fallback rewrote a
plaintext native SQLite store as an RFE1 blob and still printed [OK]; the
native bridge and every SQLite reader then rejected the file. Every whole-file
read-modify-write (purge, delete, get access-count, store, schema migration,
decay) now writes the image back in the format it read (plaintext -> plaintext,
RFE1 -> RFE1) via writeDbImagePreservingFormat. applyTemporalDecay also read
the raw bytes, so it failed on encrypted stores, and wrote plaintext: both
fixed.

#4056: `hooks post-command` stored every Bash command in full with no off
switch. Add CLAUDE_FLOW_HOOKS_RECORD_COMMANDS=0 / CLAUDE_FLOW_HOOKS_ENABLED=false /
hooks.recordCommands=false (nothing is stored when off), redact common secret
shapes and cap stored text at 2000 chars (bounded patterns, linear on hostile
input). `memory cleanup --expired-only` never saw expired rows because
listEntries hides them (TTL is a read-time rule): listEntries gains
includeExpired + expiresAt, and memory_cleanup uses it. ruflo-core 0.2.8: the
Bash shim stands down when recording is off.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-11 14:07:02 -04:00

32 lines
1.1 KiB
JavaScript

'use strict';
/**
* #4056: the PostToolUse Bash shim stands down when command recording is off.
* Pure-function test of the switch (RUFLO_HOOK_UNIT_TEST keeps main() from
* running on require).
*/
const test = require('node:test');
const assert = require('node:assert/strict');
process.env.RUFLO_HOOK_UNIT_TEST = '1';
const { commandRecordingOff } = require('./ruflo-hook.cjs');
test('recording is on by default', () => {
assert.equal(commandRecordingOff({}), false);
});
test('CLAUDE_FLOW_HOOKS_RECORD_COMMANDS 0/false/off/no turns it off', () => {
for (const v of ['0', 'false', 'off', 'no', 'FALSE', ' Off ']) {
assert.equal(commandRecordingOff({ CLAUDE_FLOW_HOOKS_RECORD_COMMANDS: v }), true, v);
}
});
test('CLAUDE_FLOW_HOOKS_ENABLED=false turns it off', () => {
assert.equal(commandRecordingOff({ CLAUDE_FLOW_HOOKS_ENABLED: 'false' }), true);
assert.equal(commandRecordingOff({ CLAUDE_FLOW_HOOKS_ENABLED: 'true' }), false);
});
test('other values leave it on', () => {
for (const v of ['1', 'true', 'on', '']) {
assert.equal(commandRecordingOff({ CLAUDE_FLOW_HOOKS_RECORD_COMMANDS: v }), false, v);
}
});