build-edges.ps1 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. # Edge builder and validator for cockpit-real-data-wayfinding
  2. param(
  3. [string]$EffortDir = ""
  4. )
  5. if (-not $EffortDir) {
  6. $EffortDir = Split-Path $PSScriptRoot -Parent
  7. }
  8. $TicketsDir = Join-Path $EffortDir "issues"
  9. $MapPath = Join-Path $EffortDir "map.md"
  10. $ExpectedTickets = @{
  11. "01-backend-slice-ticket-boundary.md" = "None"
  12. "02-map-status-filter-and-unassociated-devices.md" = "01"
  13. "03-monitoring-created-at-contract.md" = "01"
  14. "04-real-lifecycle-contract.md" = "None"
  15. "05-integration-baseline-and-evidence.md" = "01, 04"
  16. "06-cross-mode-business-semantics.md" = "None"
  17. }
  18. $ExpectedCount = 6
  19. $Success = $true
  20. function Set-Edge {
  21. param([string]$TicketPath, [string]$ExpectedEdge)
  22. $Content = Get-Content $TicketPath -Raw
  23. $Line = "Blocked by: $ExpectedEdge"
  24. if ($Content -match "(?m)^Blocked by: .*$") {
  25. $Content = $Content -replace "(?m)^Blocked by: .*$", $Line
  26. } else {
  27. $Content = $Line + "`n`n" + $Content
  28. }
  29. Set-Content -Path $TicketPath -Value $Content -Encoding UTF8 -NoNewline
  30. }
  31. $TicketFiles = @(Get-ChildItem $TicketsDir -Filter "*.md")
  32. if ($TicketFiles.Count -ne $ExpectedCount) {
  33. Write-Host "Ticket count mismatch: expected $ExpectedCount, actual $($TicketFiles.Count)"
  34. $Success = $false
  35. }
  36. foreach ($Ticket in $TicketFiles) {
  37. if (-not $ExpectedTickets.ContainsKey($Ticket.Name)) {
  38. Write-Host "Unexpected ticket: $($Ticket.Name)"
  39. $Success = $false
  40. continue
  41. }
  42. Set-Edge $Ticket.FullName $ExpectedTickets[$Ticket.Name]
  43. }
  44. $MapContent = Get-Content $MapPath -Raw
  45. if ($MapContent -notmatch "(?m)^## Destination$") {
  46. Write-Host "Map is missing ## Destination"
  47. $Success = $false
  48. }
  49. $TaskLines = @([regex]::Matches($MapContent, '(?m)^- \[.\] \[\d{2}: .*?\]\(issues/.*?\.md\)$'))
  50. if ($TaskLines.Count -ne $ExpectedCount) {
  51. Write-Host "Map task count mismatch: expected $ExpectedCount, actual $($TaskLines.Count)"
  52. $Success = $false
  53. }
  54. foreach ($Ticket in @(Get-ChildItem $TicketsDir -Filter "*.md")) {
  55. $Content = Get-Content $Ticket.FullName -Raw
  56. if ($Content -notmatch "(?m)^Blocked by: (.*?)$") {
  57. Write-Host "Missing Blocked by in $($Ticket.Name)"
  58. $Success = $false
  59. continue
  60. }
  61. $Refs = $Matches[1] -split "," | ForEach-Object { $_.Trim() }
  62. foreach ($Ref in $Refs) {
  63. if ($Ref -ne "None" -and -not @(Get-ChildItem $TicketsDir -Filter "$Ref*.md")) {
  64. Write-Host "Invalid dependency in $($Ticket.Name): $Ref"
  65. $Success = $false
  66. }
  67. }
  68. }
  69. if (-not $Success) {
  70. Write-Host "Validation failed."
  71. exit 1
  72. }
  73. Write-Host "Edges and map validated: $ExpectedCount tickets, $($TaskLines.Count) map entries."