#!/usr/bin/env node /** * Pure adapter: docs/registry/nodes.yaml → {classificationMap, dormancy}. * * Replaces tools/observer-classification-map.json (single point of edit * для маппинга «task_classification → recommended node ids») and * tools/extract-node-dormancy.mjs (Tooling §4.X scraping for status). * * Pure / read-only. No exec, no fs (caller passes loaded registry). * Source of truth for missed-activation detection (Pravila §16.4 v1.36). * * Security Guidance #40: pure parsing — no exec/execSync. */ /** * Group active-status nodes by their `classification:` trigger value. * Returns `{ [classification]: [nodeId, ...] }`. Nodes without classification * triggers, or non-active (dormant/deferred/historic), are excluded. */ export function buildClassificationMap(registry) { const out = {}; for (const node of registry.nodes || []) { if (node.status !== 'active') continue; for (const t of node.triggers || []) { if (!t.classification) continue; const c = t.classification; if (!out[c]) out[c] = []; if (!out[c].includes(node.id)) out[c].push(node.id); } } return out; } /** * Build dormancy map for missed-activations consumer: id → true iff node is * effectively unavailable (status ∈ {dormant, deferred, historic}). * Active nodes: false. Unknown nodes: absent. */ export function buildDormancyMap(registry) { const out = {}; for (const node of registry.nodes || []) { out[node.id] = node.status !== 'active'; } return out; }