import { createHash } from 'node:crypto'; import type { EnvironmentObservation } from '../../src/domain/environment-context'; import type { EnvironmentProfileContext } from '../../src/domain/gpo-snapshot-aggregation'; /** Observed platform inventory is evidence for candidate contexts, not GPO applicability. */ export function inferGpoEnvironmentContexts(observations: EnvironmentObservation[]): Array> { const contexts = new Map>(); for (const observation of observations) { if (observation.state !== 'observed' || observation.property !== 'operating_system.name') continue; const value = observation.normalizedValue ?? observation.originalValue; if (typeof value !== 'string') continue; const isDc = observation.subject.type === 'computer-information.domain-controllers'; const server = /^Windows(?: Server)? (2008(?: R2)?|2012(?: R2)?|2016|2019|2022|2025)(?:\b|$)/i.exec(value.trim()); // A generic server inventory row does not prove member-server role. if (!isDc || !server) continue; const productVersion = server[1].toUpperCase(); const key = `Windows Server:${productVersion}:Domain Controller`; const existing = contexts.get(key); if (existing) { existing.sourceObservationIds = [...new Set([...(existing.sourceObservationIds ?? []), observation.id])].sort(); continue; } contexts.set(key, { id: 'detected-context-' + createHash('sha256').update(key).digest('hex').slice(0, 24), kind: 'operating-system', productFamily: 'Windows Server', productVersion, role: 'Domain Controller', scope: 'computer', sourceObservationIds: [observation.id] }); } return [...contexts.values()].sort((a, b) => a.id.localeCompare(b.id)); }