// detection-schedule.mjs — Spor C / C1: opt-in session-anchored detection. // // The DETECTION layer (poll → report → discover → detect-skill-lifecycle) is // pure node: it polls Microsoft Learn sitemaps and writes JSON reports, and // NEVER contacts Anthropic/Claude. It is therefore OUTSIDE the ToS surface — // Consumer Terms §3.7 restricts automated access to "our Services" (Anthropic), // not running local scripts. The APPLY layer (which invokes Claude) stays // manual, in-session, and gated. This module is the pure decision core for the // SessionStart hook + the run-detection.mjs executor. // // parseScheduleConfig is pure (text in, config out). loadScheduleConfig resolves // paths via lib/user-data.mjs (which itself depends only on node:os/path), so // the user-owned config dir is the single source of truth shared with the hook. import { readFileSync, existsSync } from 'node:fs'; import { join } from 'node:path'; import { homedir } from 'node:os'; import { resolveConfigPath, CONFIG_FILENAME } from './user-data.mjs'; // Opt-in: detection is OFF until the user sets enabled:true. "Frivillig å sette // opp — men gjøres det, skal det virke." (operator 2026-06-20) export const DEFAULT_SCHEDULE_CONFIG = Object.freeze({ enabled: false, interval_days: 7, include_skill_lifecycle: true, // C3.4: opt-in inside opt-in. Course detection (Learn Platform API) needs Entra // Keychain creds almost nobody has, so default false — a default-true would // give every user a red/"skipped" step. (spec §5, §8 d) include_course_detection: false, // Tier 2 (launchd) cadence. 'daily' = poll on every (daily) fire; 'interval' // = throttle to interval_days via the same staleness gate Tier 1 uses. Read // ONLY by the Tier-2 entrypoint (scheduler.mjs run); the Tier-1 hook ignores // it, so existing behavior is unchanged. Operator default: daily. os_scheduler_cadence: 'daily', }); // The ordered, Claude-FREE detection pipeline. Every step is a local node // script that produces a JSON report; none invoke Claude. run-detection.mjs // resolves each as `node /scripts//