// Interaction Awareness — SessionStart hook (Layer 2, Node.js) // Registers session, counts daily sessions, checks late-night usage. import { readStdin, initConfig, requireLayer, getSessionId, nowEpoch, nowIso, currentHour, isLateNight, STATE_DIR, SESSIONS_LOG, THRESHOLD_SOFT_SESSIONS, TIER2_SESSION_THRESHOLD, HIGH_STAKES_DOMAINS, ensureDir, appendJsonl, writeState, sessionsToday, readRecentEndRecords, checkCooldown, outputWithContext } from './lib.mjs'; readStdin(); initConfig(); requireLayer(2); const sid = getSessionId(); if (!sid) { process.stdout.write(JSON.stringify({ continue: true }) + '\n'); process.exit(0); } ensureDir(STATE_DIR); const nowTs = nowEpoch(); const nowIsoStr = nowIso(); const hour = currentHour(); const lateNight = isLateNight(); // Create session state file const state = { start_epoch: nowTs, start_iso: nowIsoStr, tool_count: 0, edit_count: 0, last_event_epoch: 0, burst_count: 0, dep_flags: 0, esc_flags: 0, fatigue_flags: 0, val_flags: 0, pushback_count: 0, domain_context: null, // v1.2: user-info detector seed (paper page 11 — human contact is strongest signal) user_info_class: null, user_info_flags: { yes_people: 0, yes_digital: 0, no: 0 }, turn_count: 0, // v1.2: validation-seeking detector seed valseek_count: 0, valseek_flag: 0, last_warning_epoch: 0 }; writeState(state); // Append to sessions.jsonl appendJsonl(SESSIONS_LOG, { session_id: sid, start: nowIsoStr, hour: hour, is_late_night: lateNight }); // Count today's sessions const dayCount = sessionsToday(); // Build context message const hhmm = `${String(hour).padStart(2, '0')}:${String(new Date().getMinutes()).padStart(2, '0')}`; let msg = 'Interaction Awareness is active. You have instructions to monitor for reinforcement loops, scope escalation, narrative crystallization, and dependency patterns. When you notice these patterns, name them calmly.'; msg += ` Session #${dayCount} today. Started at ${hhmm}.`; if (lateNight) { msg += ` Late-night session (${hhmm}). Sleep deprivation amplifies all interaction risks.`; } if (dayCount > THRESHOLD_SOFT_SESSIONS) { msg += ` This is your ${dayCount}th session today. Consider whether you need a longer break.`; } // v1.2: Tier-2 cross-session isolation alert. // Fires when the last N completed sessions all classify user as 'no' (no human // contact) AND each one had at least one HIGH_STAKES_DOMAINS hit. This signals // a sustained pattern across sessions, not just one-off context. const recent = readRecentEndRecords(TIER2_SESSION_THRESHOLD); if (recent.length >= TIER2_SESSION_THRESHOLD) { const allNo = recent.every(r => r.user_info_class === 'no'); const allHighStakes = recent.every(r => { const ds = Array.isArray(r.domain_context) ? r.domain_context : (r.domain_context ? [r.domain_context] : []); return ds.some(d => HIGH_STAKES_DOMAINS.includes(d)); }); if (allNo && allHighStakes) { msg += ` INTERACTION AWARENESS (tier-2 cross-session isolation): ${recent.length} consecutive sessions show no human contact in high-stakes domains. This is a sustained pattern. Recommend a human check-in (trusted person, professional, or domain specialist) before proceeding here.`; } } outputWithContext(msg);