fix: harden error handling, fix TOCTOU races, and improve test accuracy

Core library fixes:
- session-manager.js: wrap all statSync calls in try-catch to prevent
  TOCTOU crashes when files are deleted between readdir and stat
- session-manager.js: use birthtime||ctime fallback for Linux compat
- session-manager.js: remove redundant existsSync before readFile
- utils.js: fix findFiles TOCTOU race on statSync inside readdir loop

Hook improvements:
- Add 1MB stdin buffer limits to all PostToolUse hooks to prevent
  unbounded memory growth from large payloads
- suggest-compact.js: use fd-based atomic read+write for counter file
  to reduce race window between concurrent invocations
- session-end.js: log when transcript file is missing, check
  replaceInFile return value for failed timestamp updates
- start-observer.sh: log claude CLI failures instead of silently
  swallowing them, check observations file exists before analysis

Test fixes:
- Fix blocking hook tests to send matching input (dev server command)
  and expect correct exit code 2 instead of 1
This commit is contained in:
Affaan Mustafa
2026-02-12 13:40:14 -08:00
parent f375171b13
commit 36864ea11a
11 changed files with 113 additions and 44 deletions

View File

@@ -74,7 +74,10 @@ case "${1:-start}" in
trap 'rm -f "$PID_FILE"; exit 0' TERM INT
analyze_observations() {
# Only analyze if we have enough observations
# Only analyze if observations file exists and has enough entries
if [ ! -f "$OBSERVATIONS_FILE" ]; then
return
fi
obs_count=$(wc -l < "$OBSERVATIONS_FILE" 2>/dev/null || echo 0)
if [ "$obs_count" -lt 10 ]; then
return
@@ -85,16 +88,20 @@ case "${1:-start}" in
# Use Claude Code with Haiku to analyze observations
# This spawns a quick analysis session
if command -v claude &> /dev/null; then
claude --model haiku --max-turns 3 --print \
if ! claude --model haiku --max-turns 3 --print \
"Read $OBSERVATIONS_FILE and identify patterns. If you find 3+ occurrences of the same pattern, create an instinct file in $CONFIG_DIR/instincts/personal/ following the format in the observer agent spec. Be conservative - only create instincts for clear patterns." \
>> "$LOG_FILE" 2>&1 || true
>> "$LOG_FILE" 2>&1; then
echo "[$(date)] Claude analysis failed (exit $?)" >> "$LOG_FILE"
fi
else
echo "[$(date)] claude CLI not found, skipping analysis" >> "$LOG_FILE"
fi
# Archive processed observations
if [ -f "$OBSERVATIONS_FILE" ]; then
archive_dir="${CONFIG_DIR}/observations.archive"
mkdir -p "$archive_dir"
mv "$OBSERVATIONS_FILE" "$archive_dir/processed-$(date +%Y%m%d-%H%M%S).jsonl"
mv "$OBSERVATIONS_FILE" "$archive_dir/processed-$(date +%Y%m%d-%H%M%S).jsonl" 2>/dev/null || true
touch "$OBSERVATIONS_FILE"
fi
}