102 lines
3.4 KiB
PowerShell
102 lines
3.4 KiB
PowerShell
param(
|
|
[string]$Root = (Split-Path -Parent $PSScriptRoot)
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$failures = [System.Collections.Generic.List[string]]::new()
|
|
|
|
$requiredFiles = @(
|
|
'AGENTS.md',
|
|
'docs\README.md',
|
|
'docs\DOCUMENTATION_STANDARD.md',
|
|
'docs\modules\README.md',
|
|
'docs\modules\TEMPLATE.md',
|
|
'targets\DEVELOPMENT_ROADMAP.md'
|
|
)
|
|
|
|
foreach ($relative in $requiredFiles) {
|
|
if (-not (Test-Path -LiteralPath (Join-Path $Root $relative))) {
|
|
$failures.Add("Missing required documentation file: $relative")
|
|
}
|
|
}
|
|
|
|
$agentGuide = Join-Path $Root 'AGENTS.md'
|
|
if (Test-Path -LiteralPath $agentGuide) {
|
|
$agentContent = Get-Content -Raw -Encoding UTF8 -LiteralPath $agentGuide
|
|
if ($agentContent -notmatch 'DOCUMENTATION_STANDARD\.md') {
|
|
$failures.Add('AGENTS.md does not reference docs/DOCUMENTATION_STANDARD.md')
|
|
}
|
|
}
|
|
|
|
$requiredHeadings = @(
|
|
'## Metadata',
|
|
'## Purpose',
|
|
'## Non-goals',
|
|
'## Context and boundaries',
|
|
'## Public API',
|
|
'## Inputs and outputs',
|
|
'## Data flow',
|
|
'## Ownership, threading and resources',
|
|
'## Errors, cancellation and recovery',
|
|
'## Verification',
|
|
'## Known gaps and risks',
|
|
'## Source map'
|
|
)
|
|
|
|
$modulesDir = Join-Path $Root 'docs\modules'
|
|
$moduleCount = 0
|
|
if (Test-Path -LiteralPath $modulesDir) {
|
|
$moduleFiles = Get-ChildItem -LiteralPath $modulesDir -Filter '*.md' -File |
|
|
Where-Object { $_.Name -notin @('README.md', 'TEMPLATE.md') }
|
|
foreach ($file in $moduleFiles) {
|
|
++$moduleCount
|
|
$content = Get-Content -Raw -Encoding UTF8 -LiteralPath $file.FullName
|
|
foreach ($heading in $requiredHeadings) {
|
|
if (-not $content.Contains($heading)) {
|
|
$failures.Add("docs/modules/$($file.Name): missing heading '$heading'")
|
|
}
|
|
}
|
|
if ($content -notmatch '(?s)```mermaid\s+flowchart') {
|
|
$failures.Add("docs/modules/$($file.Name): missing Mermaid data-flow diagram")
|
|
}
|
|
if ($content -notmatch '\| Status \|') {
|
|
$failures.Add("docs/modules/$($file.Name): missing Status metadata")
|
|
}
|
|
if ($content -notmatch '\| Last verified \|') {
|
|
$failures.Add("docs/modules/$($file.Name): missing Last verified metadata")
|
|
}
|
|
}
|
|
}
|
|
|
|
$documentationRoots = @('docs', 'targets', 'coordination')
|
|
foreach ($relativeRoot in $documentationRoots) {
|
|
$path = Join-Path $Root $relativeRoot
|
|
if (-not (Test-Path -LiteralPath $path)) {
|
|
continue
|
|
}
|
|
foreach ($file in Get-ChildItem -LiteralPath $path -Recurse -Filter '*.md' -File) {
|
|
$content = Get-Content -Raw -Encoding UTF8 -LiteralPath $file.FullName
|
|
foreach ($match in [regex]::Matches($content, '\[[^\]]+\]\(([^)#]+)(?:#[^)]+)?\)')) {
|
|
$target = $match.Groups[1].Value
|
|
if ($target -match '^(https?:|mailto:)') {
|
|
continue
|
|
}
|
|
$resolved = Join-Path $file.DirectoryName $target
|
|
if (-not (Test-Path -LiteralPath $resolved)) {
|
|
$relativeFile = Resolve-Path -LiteralPath $file.FullName -Relative
|
|
$failures.Add("$relativeFile`: broken relative link '$target'")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($failures.Count -gt 0) {
|
|
foreach ($failure in $failures) {
|
|
Write-Error $failure
|
|
}
|
|
exit 1
|
|
}
|
|
|
|
Write-Output "Documentation check passed: module_specs=$moduleCount required_files=$($requiredFiles.Count)"
|
|
exit 0
|