Private/Test-IsPovTaxonomyData.ps1
|
# Copyright (c) 2026 Jeffrey Snover. All rights reserved. # Licensed under the MIT License. See LICENSE file in the project root. function Test-IsPovTaxonomyData { <# .SYNOPSIS Returns $true when a parsed JSON object has the shape of a POV/taxonomy node file — a 'nodes' array whose entries carry an 'id' property. .DESCRIPTION Gates $script:TaxonomyData registration (both the module-import loader in AITriad.psm1 and the Assert-TaxonomyCacheFresh reload loop) against sidecar/log files that also live in taxonomy/Origin and happen to expose a top-level 'nodes[]' of a DIFFERENT shape. The motivating case is entity_extraction_log.json (t/1806): its nodes are keyed by 'node_id', not 'id'. A presence-of-'nodes' check alone passes it through, it gets registered as a fake POV, and Get-Tax then crashes when ConvertTo-TaxonomyNode reads $Node.id under Set-StrictMode (t/1834). A blanket '*.json' glob plus an ever-growing skip-list is fragile — new sidecars keep landing in the dir. Shape-gating on the taxonomy-node contract (nodes[].id) is self-maintaining: any file whose 'nodes' entries don't look like taxonomy nodes is skipped without touching a blocklist. Empty 'nodes' arrays are treated as valid POV data to preserve the prior registration behavior (an empty POV file is unusual but harmless — there is nothing to iterate, so no crash). .PARAMETER Json The deserialized JSON object (from ConvertFrom-Json), or $null. .OUTPUTS [bool] #> [OutputType([bool])] param( [AllowNull()] $Json ) if (-not ($Json -and $Json.PSObject.Properties['nodes'])) { return $false } $Nodes = @($Json.nodes) # An empty POV file is unusual but valid — nothing to misread. Preserve the # pre-t/1834 behavior of registering it. if ($Nodes.Count -eq 0) { return $true } # Real POV/taxonomy nodes carry an 'id'; sidecar logs (entity_extraction_log) # use 'node_id' / other shapes and are rejected here. return [bool]$Nodes[0].PSObject.Properties['id'] } |