wal: pause
This commit is contained in:
460
scripts/artifact-integrity.ps1
Normal file
460
scripts/artifact-integrity.ps1
Normal file
@ -0,0 +1,460 @@
|
||||
# artifact-integrity.ps1 - MAY DIEM DANH VAT CHUNG (run-folder), do NGHIA khong chi do TON TAI
|
||||
#
|
||||
# San thi hanh: broadcasts/inbox/ai_infra/2026-08-04-Governance-upgrade-pack-phased-phu-luc-spec-pitfall.md
|
||||
# section GD-2 (san (i)-(v) + 4 bay + 6 o nghiem thu)
|
||||
# Thiet ke : runs/2026-08-07-S180-adap-upgrade-pack-phased/sub-n3-lane-b-gd2.md (13 khoan B-01..B-13, 4 vi tu V-1..V-4)
|
||||
# Ke hoach : runs/2026-08-07-S180-adap-upgrade-pack-phased/wave-plan-S180.md (W2)
|
||||
# Khuon may : scripts/naming-scan.ps1 (W1) - giu cung ky luat: pure-ASCII, INFORM-only, luon in mau so.
|
||||
#
|
||||
# HOP DONG CUA MAY NAY - doc truoc khi sua:
|
||||
#
|
||||
# (1) INFORM-only. LUON exit 0, ke ca khi co co. Lai ma thoat = wave W3b,
|
||||
# sau khi chu du an chot cau P1 (da chot PA-2). KHONG tu lai ma thoat o day.
|
||||
#
|
||||
# (2) VI SAO MAY NAY TON TAI - ca song, khong phai gia thuyet:
|
||||
# S180 co mot vai ha canh artifact 7.049 B voi 6/10 heading con nhan treo
|
||||
# sau 202K token. Chay `nhip-no-probe` len dung thu muc do => `run-chua-gom 0`,
|
||||
# exit 0, SACH. Control-duong (giau *-synthesis.md => 1, tra lai => 0) xac nhan
|
||||
# thuoc SONG => so 0 kia la MU THAT.
|
||||
# GOC: moi vi tu dang co deu do KICH THUOC; thu hong la TI LE KHUNG/RUOT.
|
||||
# Hai dai luong nay KHONG tuong quan - mot tep toan heading tang byte y het
|
||||
# mot tep day noi dung.
|
||||
#
|
||||
# (3) 4 VI TU cua hub -> 4 vi tu cai o day:
|
||||
# VANG -> V-3 (diem danh 2 nguon: ten neu trong run.md ma vang tren dia)
|
||||
# RONG -> V-1 nhanh 0-byte (KHONG duoc roi vao 'khong ap dung')
|
||||
# CUT -> V-2 (nhan treo neo HEADING) chinh + V-1 (ti le ruot/khung) phu
|
||||
# NEN-QUA-TAY -> V-4 (so ky tu voi ban truoc CUNG DON VI, lay tu git)
|
||||
#
|
||||
# (4) LUON IN MAU SO canh moi con so. Phien S180 da 8 ca bay don-vi.
|
||||
# Va luon in "dem CAI GI": tep / thu muc / muc / dong.
|
||||
#
|
||||
# (5) TAP VANG MAT != SACH (chong Goodhart). Neu thu muc goc vang, hoac mot
|
||||
# luot chay khong con vat nao, may in co THIEU-TAP RIENG canh so 0.
|
||||
# So 0 khong duoc phep doc thanh 'sach' khi chua co gi de dem.
|
||||
#
|
||||
# (6) Pure ASCII (gotcha #30). Nhan treo tieng Viet duoc dung bang MA DIEM
|
||||
# (xem $TAG_*) chu khong go thang - de tep nay giu 0 byte ngoai ASCII.
|
||||
#
|
||||
# (7) KHONG SUA GI. May chi doc va in. Che do -BuildIndex la ngoai le duy nhat:
|
||||
# no GHI DE mot tep duy nhat (.claude/workflows/runs/_index.md) va tep do
|
||||
# la DERIVE-VIEW sinh tu dia - cam sua tay, cam dung lam nguon.
|
||||
#
|
||||
# Fault-inject: chay voi -RepoRoot <cay-tam> de cay artifact hong / go ra. Khong dung kho that.
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$RepoRoot,
|
||||
[string]$RunId, # chi soi 1 thu muc luot chay. Vang => soi TAT CA.
|
||||
[switch]$V4All, # bat V-4 cho moi tep (moi tep ton ~1-2 lenh git). Mac dinh chi bat khi co -RunId.
|
||||
[switch]$BuildIndex, # sinh lai muc luc derive-view _index.md tu dia
|
||||
[double]$K = 3.00 # nguong V-1. Mac dinh = phan vi 5 cua ho sub-*, do 2026-08-07, mau so 446.
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not $RepoRoot -or $RepoRoot -eq '') { $RepoRoot = Split-Path -Parent $PSScriptRoot }
|
||||
$RepoRoot = (Resolve-Path -LiteralPath $RepoRoot).Path
|
||||
$RunsRel = '.claude/workflows/runs'
|
||||
$RunsRoot = Join-Path $RepoRoot $RunsRel
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Nhan treo dung bang MA DIEM de giu tep pure-ASCII (luat 6).
|
||||
# 0x0110 = D co gach ngang (chu HOA) -> dung trong "DANG DO"
|
||||
# 0x1EDC = O co sung + huyen (chu HOA) -> dung trong "CHO"
|
||||
# ---------------------------------------------------------------------------
|
||||
$chDbar = [string][char]0x0110
|
||||
$chOhg = [string][char]0x1EDC
|
||||
$TAG_DANGDO = $chDbar + 'ANG ' + $chDbar + 'O'
|
||||
$TAG_CHO = 'CH' + $chOhg
|
||||
$TAGSET = @($TAG_DANGDO, $TAG_CHO, 'TODO', 'PENDING') -join '|'
|
||||
|
||||
# Neo vao HEADING la chu y trung tam cua V-2: tach DUNG (nhan dang treo)
|
||||
# khoi NHAC DEN (cau van dinh nghia nhan). Dem tho cho duong-gia tren chinh
|
||||
# ban da xong - do 2026-08-07: tho=1, neo-heading=0. Lop citation-trap.
|
||||
$RX_PLACEHOLDER_HEAD = '^#{1,6} .*\[(' + $TAGSET + ')'
|
||||
$RX_PLACEHOLDER_RAW = '\[(' + $TAGSET + ')'
|
||||
|
||||
$RX_HEAD = '^#{1,6} '
|
||||
$RX_FENCE = '^\s*```'
|
||||
$RX_SUBFAM = '^(sub-.+|.+-return)\.md$' # cung ho voi governance-detectors.ps1:1102 / :1771
|
||||
$RX_SYNTH = '.+-synthesis\.md$'
|
||||
# Ten tep artifact duoc NHAC trong run.md. Mau ky tu CO Y khong chua '<' '>'
|
||||
# => khuon minh hoa dang `sub-<role>-<i>.md` KHONG bi bat (do 2026-08-07: 0 hit).
|
||||
$RX_NAMEREF = '(sub-[A-Za-z0-9._-]+\.md|[A-Za-z0-9._-]+-synthesis\.md)'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# So ke. Co (FLAG) va THIEU-TAP dem TACH NHAU - luat 5.
|
||||
# ---------------------------------------------------------------------------
|
||||
$script:Flags = @() # {Kind, Run, Name, Msg}
|
||||
$script:MissingSets = @() # {Run, Msg}
|
||||
$script:NFolder = 0; $script:NFile = 0; $script:NSkipV1 = 0
|
||||
$script:NV4Measured = 0; $script:NV4Unmeasurable = 0
|
||||
$script:NOutOfShape = @()
|
||||
$script:NKhongKhai = 0; $script:NTroCheo = 0
|
||||
# Tap ten MOI tep .md tren toan cay runs/ - de phan giai con tro CHEO giua cac
|
||||
# luot chay (xem V-3). Dung 1 lan, khong quet lai moi thu muc.
|
||||
$script:AllNamesInRuns = @{}
|
||||
|
||||
function Write-Head([string]$t) { Write-Host ''; Write-Host $t -ForegroundColor Cyan }
|
||||
function Add-Flag([string]$Kind, [string]$Run, [string]$Name, [string]$Msg) {
|
||||
$script:Flags += [pscustomobject]@{ Kind = $Kind; Run = $Run; Name = $Name; Msg = $Msg }
|
||||
}
|
||||
function Add-Missing([string]$Run, [string]$Msg) {
|
||||
$script:MissingSets += [pscustomobject]@{ Run = $Run; Msg = $Msg }
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Do 1 tep. Dinh nghia "dem CAI GI" - khai o day mot lan, dung suot:
|
||||
# head = dong khop '^#{1,6} ' VA KHONG nam trong khoi ma (``` toggle).
|
||||
# Khong loai khoi ma thi '# comment' trong bash bi dem la heading
|
||||
# => tep nhieu ma bi danh oan.
|
||||
# body = moi dong KHONG RONG con lai. Dong bang '|', dong trich '>', va dong
|
||||
# trong khoi ma DEU TINH LA RUOT. (Ban nhap lane B loai '^\|' khoi tu
|
||||
# so - do la sai, lane B tu sua o section 3.)
|
||||
# ---------------------------------------------------------------------------
|
||||
function Measure-Artifact {
|
||||
param([System.IO.FileInfo]$File)
|
||||
|
||||
$bytes = $File.Length
|
||||
if ($bytes -eq 0) {
|
||||
return [pscustomobject]@{ Bytes = 0; Head = 0; Body = 0; Ratio = -1; Ph = 0; PhRaw = 0; Chars = 0; Items = 0 }
|
||||
}
|
||||
$text = [System.IO.File]::ReadAllText($File.FullName, [System.Text.Encoding]::UTF8)
|
||||
$lines = $text -split "`r?`n"
|
||||
|
||||
$inFence = $false; $head = 0; $body = 0; $ph = 0; $phRaw = 0; $items = 0
|
||||
foreach ($ln in $lines) {
|
||||
if ($ln -match $RX_FENCE) { $inFence = -not $inFence; $body++; continue }
|
||||
if ($inFence) { if ($ln.Trim() -ne '') { $body++ }; continue }
|
||||
if ($ln -match $RX_HEAD) {
|
||||
$head++
|
||||
if ($ln -match $RX_PLACEHOLDER_HEAD) { $ph++ }
|
||||
if ($ln -match $RX_PLACEHOLDER_RAW) { $phRaw++ }
|
||||
continue
|
||||
}
|
||||
if ($ln -match $RX_PLACEHOLDER_RAW) { $phRaw++ }
|
||||
if ($ln -match '^\s*[-*] ' -or $ln -match '^\s*\|') { $items++ }
|
||||
if ($ln.Trim() -ne '') { $body++ }
|
||||
}
|
||||
$ratio = if ($head -gt 0) { [math]::Round($body / $head, 2) } else { -1 }
|
||||
return [pscustomobject]@{
|
||||
Bytes = $bytes; Head = $head; Body = $body; Ratio = $ratio
|
||||
Ph = $ph; PhRaw = $phRaw; Chars = $text.Length; Items = $items
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# V-4 - nen qua tay. So ky tu voi BAN TRUOC CUNG DON VI.
|
||||
# KHONG dung HEAD~1: hook `wal:` chen commit vao giua => HEAD~1 thuong KHONG
|
||||
# phai ban truoc CUA TEP NAY, va phep so se la 'so ban moi voi chinh no'
|
||||
# (giong het mot phep do hop le). Dung git log CUA CHINH TEP.
|
||||
# Khong du du lieu => KHONG DO DUOC (dung chu hub), khong doan.
|
||||
# ---------------------------------------------------------------------------
|
||||
function Test-Compression {
|
||||
param([string]$RelPath, [int]$NowChars, [int]$NowItems, [string]$FullPath)
|
||||
|
||||
$shas = & git -C $RepoRoot log --format=%H -2 -- $RelPath 2>$null
|
||||
if ($LASTEXITCODE -ne 0 -or -not $shas) {
|
||||
return [pscustomobject]@{ Ok = $false; Why = 'tep chua tracked / khong co lich su git' }
|
||||
}
|
||||
$shas = @($shas)
|
||||
if ($shas.Count -lt 2) {
|
||||
return [pscustomobject]@{ Ok = $false; Why = ('chi co {0} commit cham tep nay - chua co ban truoc CUNG DON VI de so' -f $shas.Count) }
|
||||
}
|
||||
$prev = & git -C $RepoRoot show ("{0}:{1}" -f $shas[1], $RelPath) 2>$null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
return [pscustomobject]@{ Ok = $false; Why = 'khong doc duoc ban truoc tu git' }
|
||||
}
|
||||
$prevText = ($prev -join "`n")
|
||||
$prevChars = $prevText.Length
|
||||
$prevItems = @($prevText -split "`n" | Where-Object { $_ -match '^\s*[-*] ' -or $_ -match '^\s*\|' }).Count
|
||||
if ($prevChars -eq 0) {
|
||||
return [pscustomobject]@{ Ok = $false; Why = 'ban truoc rong - ti le vo nghia' }
|
||||
}
|
||||
$r = [math]::Round($NowChars / [double]$prevChars, 3)
|
||||
return [pscustomobject]@{
|
||||
Ok = $true; Ratio = $r; PrevChars = $prevChars; PrevItems = $prevItems
|
||||
PrevSha = $shas[1].Substring(0, 7)
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Soi 1 thu muc luot chay.
|
||||
# ---------------------------------------------------------------------------
|
||||
function Scan-Run {
|
||||
param([System.IO.DirectoryInfo]$Dir, [switch]$DoV4)
|
||||
|
||||
$run = $Dir.Name
|
||||
$script:NFolder++
|
||||
|
||||
$allMd = @(Get-ChildItem -LiteralPath $Dir.FullName -Recurse -File -Filter '*.md' -ErrorAction SilentlyContinue)
|
||||
$flat = @($allMd | Where-Object { $_.Directory.FullName -eq $Dir.FullName })
|
||||
# C8 dual-accept: 5 thu muc cu giu 'sub-md/' + 'harvest/'. Khong tinh chung
|
||||
# la 'ngoai cau truc' - lam the la de 5 luot chay hop le keu oan ngay ngay dau.
|
||||
$c8 = @($allMd | Where-Object {
|
||||
$p = $_.Directory.Name
|
||||
($p -eq 'harvest' -or $p -eq 'sub-md') -and ($_.Directory.Parent.FullName -eq $Dir.FullName) })
|
||||
$arts = @($flat + $c8)
|
||||
$other = @($allMd | Where-Object { $arts -notcontains $_ })
|
||||
foreach ($o in $other) {
|
||||
$rel = $o.FullName.Substring($Dir.FullName.Length + 1) -replace '\\', '/'
|
||||
$script:NOutOfShape += ("{0}/{1}" -f $run, $rel)
|
||||
}
|
||||
|
||||
# --- THIEU-TAP (luat 5 / chieu A2 fault-inject) --------------------------
|
||||
if ($arts.Count -eq 0) {
|
||||
Add-Missing $run 'thu muc luot chay KHONG CO vat .md nao - phep do khong ton tai, khong phai "sach"'
|
||||
Write-Host (" [{0}] FLAG THIEU-TAP: 0 vat .md" -f $run) -ForegroundColor Red
|
||||
return
|
||||
}
|
||||
$runMd = $arts | Where-Object { $_.Name -eq 'run.md' } | Select-Object -First 1
|
||||
if (-not $runMd) {
|
||||
Add-Flag 'VANG' $run 'run.md' 'thu muc luot chay khong co run.md - mat NGUON-2 cua diem danh 2 nguon (V-3 khong do duoc o day)'
|
||||
}
|
||||
$synth = @($arts | Where-Object { $_.Name -match $RX_SYNTH -and $_.Length -gt 0 })
|
||||
if ($synth.Count -eq 0 -and $runMd) {
|
||||
Add-Flag 'VANG' $run '*-synthesis.md' 'khong co ban gom non-empty (dual-accept flat + harvest/) - cung tieu chi voi nhip-no-probe run-chua-gom'
|
||||
}
|
||||
|
||||
# --- V-1 / V-2 tren tung vat ---------------------------------------------
|
||||
$rows = @()
|
||||
foreach ($f in $arts) {
|
||||
$script:NFile++
|
||||
$m = Measure-Artifact -File $f
|
||||
$isSub = ($f.Name -match $RX_SUBFAM)
|
||||
|
||||
if ($m.Bytes -eq 0) {
|
||||
Add-Flag 'RONG' $run $f.Name 'tep 0 byte'
|
||||
$rows += [pscustomobject]@{ N = $f.Name; V = 'RONG'; D = '0 B' }
|
||||
continue
|
||||
}
|
||||
# V-2 - nhan treo neo HEADING (vi tu chinh cho CUT)
|
||||
if ($m.Ph -gt 0) {
|
||||
Add-Flag 'CUT' $run $f.Name ('V-2: {0}/{1} heading con nhan treo (mau so = so heading cua chinh tep nay)' -f $m.Ph, $m.Head)
|
||||
$rows += [pscustomobject]@{ N = $f.Name; V = 'CUT(V-2)'; D = ('{0}/{1} heading treo' -f $m.Ph, $m.Head) }
|
||||
}
|
||||
# V-1 - ti le ruot/khung (luoi PHU, chi ap ho sub-*/-return)
|
||||
if ($isSub) {
|
||||
if ($m.Head -eq 0) {
|
||||
$script:NSkipV1++
|
||||
$rows += [pscustomobject]@{ N = $f.Name; V = 'V1-KHONG-AP-DUNG'; D = ('0 heading, {0} B - khong chia duoc, KHONG doc thanh sach' -f $m.Bytes) }
|
||||
}
|
||||
elseif ($m.Ratio -lt $K) {
|
||||
Add-Flag 'CUT' $run $f.Name ('V-1: ruot/khung {0} < K={1} (body {2} dong / head {3} dong)' -f $m.Ratio, $K, $m.Body, $m.Head)
|
||||
if ($m.Ph -eq 0) { $rows += [pscustomobject]@{ N = $f.Name; V = 'CUT(V-1)'; D = ('ti le {0} < {1}' -f $m.Ratio, $K) } }
|
||||
}
|
||||
}
|
||||
# V-4 - nen qua tay
|
||||
if ($DoV4) {
|
||||
$rel = $f.FullName.Substring($RepoRoot.Length + 1) -replace '\\', '/'
|
||||
$c = Test-Compression -RelPath $rel -NowChars $m.Chars -NowItems $m.Items -FullPath $f.FullName
|
||||
if (-not $c.Ok) {
|
||||
$script:NV4Unmeasurable++
|
||||
} else {
|
||||
$script:NV4Measured++
|
||||
if ($c.Ratio -lt 0.70 -and $m.Items -lt $c.PrevItems) {
|
||||
$txt = [System.IO.File]::ReadAllText($f.FullName, [System.Text.Encoding]::UTF8)
|
||||
$mien = ($txt -match 'archive/' -or $txt -match 'con-tro' -or $txt -match 'moved-not-cut' -or $txt -match 'doi verbatim')
|
||||
if ($mien) {
|
||||
$rows += [pscustomobject]@{ N = $f.Name; V = 'NEN-MIEN'; D = ('{0}x so voi {1}, NHUNG co khai noi-di (mien tru HIEN HINH)' -f $c.Ratio, $c.PrevSha) }
|
||||
} else {
|
||||
Add-Flag 'NEN' $run $f.Name ('V-4: con {0}x so ky tu so voi {1} ({2} -> {3} ky tu) VA so muc giam {4} -> {5}, KHONG thay dong khai noi-di' -f $c.Ratio, $c.PrevSha, $c.PrevChars, $m.Chars, $c.PrevItems, $m.Items)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- V-3 - diem danh HAI NGUON (dia <-> run.md ghi TRUOC launch) -------
|
||||
$v3 = 'KHONG DO DUOC'
|
||||
if ($runMd) {
|
||||
$runTxt = [System.IO.File]::ReadAllText($runMd.FullName, [System.Text.Encoding]::UTF8)
|
||||
$named = @([regex]::Matches($runTxt, $RX_NAMEREF) | ForEach-Object { $_.Value } | Sort-Object -Unique)
|
||||
$onDisk = @($arts | ForEach-Object { $_.Name } | Sort-Object -Unique)
|
||||
if ($named.Count -eq 0) {
|
||||
$v3 = 'KHONG DO DUOC'
|
||||
Add-Missing $run 'V-3: run.md KHONG neu ten tep artifact nao => NGUON-2 rong. Day KHONG phai "chenh 0".'
|
||||
} else {
|
||||
$missOnDisk = @($named | Where-Object { $onDisk -notcontains $_ })
|
||||
$notDeclared= @($onDisk | Where-Object { $named -notcontains $_ -and $_ -ne 'run.md' })
|
||||
# Ten khong co trong thu muc NAY co the la con tro CHEO sang luot chay
|
||||
# TRUOC - runs/README.md:39 (C2 buoc 3) BAT run.md tro 'input spec:' sang
|
||||
# synthesis cua luot truoc. Tep co that, nam thu muc khac. So trong MOT thu
|
||||
# muc roi keu 'vang' la loi cua MAY, khong phai no cua kho.
|
||||
$crossRef = @(); $reallyMissing = @()
|
||||
foreach ($x in $missOnDisk) {
|
||||
if ($script:AllNamesInRuns.ContainsKey($x)) { $crossRef += $x } else { $reallyMissing += $x }
|
||||
}
|
||||
$v3 = ('nguon-2 neu {0} ten | thieu-tren-dia {1} | tro-cheo {2} | khong-khai {3}' -f $named.Count, $reallyMissing.Count, $crossRef.Count, $notDeclared.Count)
|
||||
foreach ($x in $reallyMissing) { Add-Flag 'VANG' $run $x 'V-3: run.md co neu ten nay, va KHONG TIM THAY o bat ky luot chay nao' }
|
||||
# KHONG-KHAI: dem RIENG, KHONG phai co. Chua he co luat nao bat run.md
|
||||
# neu ten tep => 245/720 co cho mot luat khong ton tai = duong-gia ngay dau.
|
||||
# Nhung con SO thi giu, vi no chung minh NGUON-2 mong den muc nao.
|
||||
$script:NKhongKhai += $notDeclared.Count
|
||||
$script:NTroCheo += $crossRef.Count
|
||||
}
|
||||
}
|
||||
|
||||
# --- in per-run ----------------------------------------------------------
|
||||
$bad = @($rows).Count
|
||||
$color = if ($bad -gt 0) { 'Yellow' } else { 'DarkGray' }
|
||||
Write-Host (" [{0}]" -f $run) -ForegroundColor $color
|
||||
Write-Host (" mau so: {0} vat .md (phang {1} + C8 harvest|sub-md {2}) | V-3: {3}" -f $arts.Count, $flat.Count, $c8.Count, $v3)
|
||||
foreach ($r in $rows) {
|
||||
$c = if ($r.V -like 'CUT*' -or $r.V -eq 'RONG') { 'Red' } else { 'DarkGray' }
|
||||
Write-Host (" [{0,-16}] {1} <- {2}" -f $r.V, $r.N, $r.D) -ForegroundColor $c
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# -BuildIndex : sinh muc luc DERIVE-VIEW tu dia.
|
||||
# Vi sao derive-view chu khong phai so chep tay: so chep tay se thanh NGUON-DOI
|
||||
# ngay khi ai do quen mot dong - va do dung cach `_ledger.md` da chet (15 dong,
|
||||
# toan 2026-06-18, trong khi dia da di toi 2026-08-07).
|
||||
# ---------------------------------------------------------------------------
|
||||
function Build-Index {
|
||||
if (-not (Test-Path -LiteralPath $RunsRoot)) {
|
||||
Write-Host ' FLAG THIEU-TAP: khong co thu muc runs/ - khong sinh duoc muc luc.' -ForegroundColor Red
|
||||
return
|
||||
}
|
||||
$dirs = @(Get-ChildItem -LiteralPath $RunsRoot -Directory | Sort-Object Name)
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
|
||||
$null = $sb.AppendLine('# `runs/_index.md` - MUC LUC SONG (DERIVE-VIEW, sinh tu dia)')
|
||||
$null = $sb.AppendLine('')
|
||||
$null = $sb.AppendLine('> **CAM SUA TAY. CAM DUNG LAM NGUON.** Tep nay duoc SINH LAI tron ven bang')
|
||||
$null = $sb.AppendLine('> `powershell -File scripts/artifact-integrity.ps1 -BuildIndex`. Moi dong deu doc thang tu dia.')
|
||||
$null = $sb.AppendLine('> Sua tay o day = de ra nguon-doi, dung benh da giet `_ledger.md` (so chep tay, RETIRED H18-B S100:')
|
||||
$null = $sb.AppendLine('> 15 dong, toan 2026-06-18, trong khi dia da di toi hom nay).')
|
||||
$null = $sb.AppendLine('>')
|
||||
$null = $sb.AppendLine('> **Tang-A (goi theo loai) = `README.md` canh ben** - chuc nang, ai ghi, ai doc, bo tep chuan.')
|
||||
$null = $sb.AppendLine('> **Tang-B (muc luc song) = tep nay.** Hai tang, khong tang nao chep tang kia.')
|
||||
$null = $sb.AppendLine('>')
|
||||
$null = $sb.AppendLine('> [!] **Tep nay KHONG duoc dung lam nguon-2 cua diem danh 2 nguon** - no doc thang dia,')
|
||||
$null = $sb.AppendLine('> tuc no CHINH LA nguon-1. Nguon-2 la anh chup taskList trong tung `run.md` (ghi TRUOC launch).')
|
||||
$null = $sb.AppendLine('')
|
||||
$null = $sb.AppendLine(('- **Sinh luc:** {0}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm')))
|
||||
$null = $sb.AppendLine(('- **Mau so:** {0} thu muc luot chay (dem THU MUC, khong dem entry - `ls` con thay ca tep README/_ledger/_index)' -f $dirs.Count))
|
||||
$null = $sb.AppendLine('')
|
||||
$null = $sb.AppendLine('| luot chay | run.md | vat .md | ban gom | co V-2 (nhan treo) | byte |')
|
||||
$null = $sb.AppendLine('|---|---|---|---|---|---|')
|
||||
|
||||
foreach ($d in $dirs) {
|
||||
$md = @(Get-ChildItem -LiteralPath $d.FullName -Recurse -File -Filter '*.md' -ErrorAction SilentlyContinue)
|
||||
$hasRun = if ($md | Where-Object { $_.Name -eq 'run.md' -and $_.Directory.FullName -eq $d.FullName }) { 'co' } else { '**VANG**' }
|
||||
$syn = @($md | Where-Object { $_.Name -match $RX_SYNTH -and $_.Length -gt 0 })
|
||||
$hasSyn = if ($syn.Count -gt 0) { 'co' } else { '**VANG**' }
|
||||
$ph = 0
|
||||
foreach ($f in $md) {
|
||||
if ($f.Length -eq 0) { continue }
|
||||
$t = [System.IO.File]::ReadAllText($f.FullName, [System.Text.Encoding]::UTF8)
|
||||
foreach ($ln in ($t -split "`r?`n")) { if ($ln -match $RX_PLACEHOLDER_HEAD) { $ph++ } }
|
||||
}
|
||||
$phTxt = if ($ph -gt 0) { ('**{0}**' -f $ph) } else { '0' }
|
||||
$bytes = ($md | Measure-Object -Property Length -Sum).Sum
|
||||
$null = $sb.AppendLine(('| `{0}` | {1} | {2} | {3} | {4} | {5} |' -f $d.Name, $hasRun, $md.Count, $hasSyn, $phTxt, $bytes))
|
||||
}
|
||||
|
||||
$out = Join-Path $RunsRoot '_index.md'
|
||||
[System.IO.File]::WriteAllText($out, $sb.ToString(), (New-Object System.Text.UTF8Encoding($false)))
|
||||
Write-Host (" Da sinh: {0}/_index.md ({1} thu muc luot chay)" -f $RunsRel, $dirs.Count) -ForegroundColor Green
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# MAIN
|
||||
# ===========================================================================
|
||||
Write-Host '=== artifact-integrity.ps1 - MAY DIEM DANH VAT CHUNG ===' -ForegroundColor White
|
||||
Write-Host ("RepoRoot : {0}" -f $RepoRoot)
|
||||
Write-Host "Che do : INFORM-only. LUON exit 0 ke ca khi co co (lai ma thoat = W3b, sau P1=PA-2)."
|
||||
Write-Host "Vi tu : V-1 ti le ruot/khung | V-2 nhan treo neo HEADING | V-3 diem danh 2 nguon | V-4 nen qua tay"
|
||||
Write-Host ("Nguong : K={0} (V-1) = phan vi 5 cua ho sub-*, do 2026-08-07, mau so 446 tep co heading." -f $K)
|
||||
Write-Host " Tai K nay, 20/446 tep lich su (4,5%) cung nam duoi nguong => co KHONG doc thanh 'hong'."
|
||||
|
||||
if ($BuildIndex) {
|
||||
Write-Head '--- SINH MUC LUC DERIVE-VIEW ---'
|
||||
Build-Index
|
||||
Write-Host ''
|
||||
Write-Host ' Ma thoat: 0 (INFORM-only theo hop dong muc 1).'
|
||||
exit 0
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $RunsRoot)) {
|
||||
Write-Head '--- DIEM DANH ---'
|
||||
Write-Host (" FLAG THIEU-TAP: khong tim thay '{0}'." -f $RunsRel) -ForegroundColor Red
|
||||
Write-Host " Day KHONG phai [skip]. Tap vang mat => phep do KHONG TON TAI, va so co 0 ben duoi VO NGHIA." -ForegroundColor Red
|
||||
Add-Missing '(goc)' 'thu muc runs/ vang mat'
|
||||
$dirs = @()
|
||||
} elseif ($RunId) {
|
||||
$one = Join-Path $RunsRoot $RunId
|
||||
if (-not (Test-Path -LiteralPath $one)) {
|
||||
Write-Head '--- DIEM DANH ---'
|
||||
Write-Host (" FLAG THIEU-TAP: khong co luot chay '{0}'." -f $RunId) -ForegroundColor Red
|
||||
Add-Missing $RunId 'thu muc luot chay duoc chi dinh nhung khong ton tai'
|
||||
$dirs = @()
|
||||
} else { $dirs = @(Get-Item -LiteralPath $one) }
|
||||
} else {
|
||||
$dirs = @(Get-ChildItem -LiteralPath $RunsRoot -Directory | Sort-Object Name)
|
||||
}
|
||||
|
||||
if (Test-Path -LiteralPath $RunsRoot) {
|
||||
foreach ($f in (Get-ChildItem -LiteralPath $RunsRoot -Recurse -File -Filter '*.md' -ErrorAction SilentlyContinue)) {
|
||||
$script:AllNamesInRuns[$f.Name] = $true
|
||||
}
|
||||
}
|
||||
|
||||
$doV4 = ($RunId -and -not $V4All) -or $V4All
|
||||
Write-Head ("--- DIEM DANH: {0} thu muc luot chay ---" -f $dirs.Count)
|
||||
if (-not $doV4) {
|
||||
Write-Host " V-4 (nen qua tay): KHONG DO DUOC o che do quet-toan-bo - moi tep ton 1-2 lenh git." -ForegroundColor DarkGray
|
||||
Write-Host " Bat bang -RunId <ten> (1 luot chay) hoac -V4All (chap nhan cham). KHONG phai 'da do va sach'." -ForegroundColor DarkGray
|
||||
}
|
||||
foreach ($d in $dirs) { Scan-Run -Dir $d -DoV4:$doV4 }
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
Write-Head '=== TONG ==='
|
||||
Write-Host (" mau so : {0} thu muc luot chay | {1} vat .md da do" -f $script:NFolder, $script:NFile)
|
||||
|
||||
$byKind = $script:Flags | Group-Object Kind | Sort-Object Name
|
||||
if ($script:Flags.Count -eq 0) {
|
||||
Write-Host (" CO : 0/{0} vat" -f $script:NFile) -ForegroundColor Green
|
||||
Write-Host " [!] 0 co CHI co nghia khi mau so tren khac 0 VA so THIEU-TAP ben duoi = 0." -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host (" CO : {0} (tren {1} vat)" -f $script:Flags.Count, $script:NFile) -ForegroundColor Red
|
||||
foreach ($g in $byKind) { Write-Host (" {0,-11} : {1}" -f $g.Name, $g.Count) -ForegroundColor Red }
|
||||
}
|
||||
|
||||
# THIEU-TAP in RIENG, canh so co - de so 0 mat quyen doc thanh 'sach' (luat 5).
|
||||
if ($script:MissingSets.Count -gt 0) {
|
||||
Write-Host (" THIEU-TAP : {0} <- dem TACH khoi so co tren. Moi tap vang lam mot phep do BIEN MAT." -f $script:MissingSets.Count) -ForegroundColor Red
|
||||
foreach ($m in $script:MissingSets) { Write-Host (" - [{0}] {1}" -f $m.Run, $m.Msg) -ForegroundColor Red }
|
||||
} else {
|
||||
Write-Host " THIEU-TAP : 0"
|
||||
}
|
||||
|
||||
Write-Host (" V-1 khong ap dung : {0}/{1} vat (0 heading => khong chia duoc; KHONG phai 'sach')" -f $script:NSkipV1, $script:NFile)
|
||||
# Hai hang muc DEM RIENG, KHONG phai co - va KHONG duoc giau di. Giau con so nay
|
||||
# la giau chinh bang chung "nguon-2 mong".
|
||||
Write-Host (" KHONG-KHAI : {0}/{1} vat co tren dia ma run.md khong neu ten." -f $script:NKhongKhai, $script:NFile)
|
||||
Write-Host " DEM RIENG, KHONG phai co: chua he co luat bat run.md neu ten tep."
|
||||
Write-Host " Day la thuoc do do MONG cua NGUON-2, khong phai danh sach vi pham."
|
||||
Write-Host (" TRO-CHEO : {0}/{1} ten run.md neu ma nam o luot chay KHAC" -f $script:NTroCheo, $script:NFile)
|
||||
Write-Host " (runs/README.md:39 C2 buoc 3 BAT tro 'input spec:' sang luot truoc) - HOP LE."
|
||||
if ($doV4) {
|
||||
Write-Host (" V-4 do duoc : {0} vat | KHONG DO DUOC {1} vat (chua tracked hoac chi 1 commit cham tep)" -f $script:NV4Measured, $script:NV4Unmeasurable)
|
||||
}
|
||||
if ($script:NOutOfShape.Count -gt 0) {
|
||||
Write-Host (" NGOAI CAU TRUC PHANG : {0} tep (C1 doi phang; C8 mien 'harvest/'+'sub-md/'). In ten, KHONG im lang:" -f $script:NOutOfShape.Count) -ForegroundColor Yellow
|
||||
foreach ($x in $script:NOutOfShape) { Write-Host (" - {0}" -f $x) -ForegroundColor Yellow }
|
||||
}
|
||||
|
||||
if ($script:Flags.Count -gt 0) {
|
||||
Write-Host ''
|
||||
Write-Host ' Danh sach CO (tung ten - cam nen thanh so tong):' -ForegroundColor Red
|
||||
foreach ($x in $script:Flags) { Write-Host (" - [{0,-11}] {1}/{2} <- {3}" -f $x.Kind, $x.Run, $x.Name, $x.Msg) }
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host ' Ma thoat: 0 (INFORM-only theo hop dong muc 1). Co o tren KHONG lai ma thoat.'
|
||||
Write-Host ' Lai ma thoat thuoc wave W3b, sau khi chu du an chot phan loai co theo PA-2.'
|
||||
exit 0
|
||||
@ -295,10 +295,19 @@ else {
|
||||
}
|
||||
else {
|
||||
$latest = $runDirs[0]
|
||||
$subMd = @(Get-ChildItem -Path $latest.FullName -Filter 'sub-*.md' -File -ErrorAction SilentlyContinue)
|
||||
# @S180 W1 FIX (naming-standard.md section 4): the filter used to be the literal glob
|
||||
# 'sub-*.md', so every '<role>-return.md' was INVISIBLE here - including the three trio
|
||||
# returns (harness-eval / harness-refine / harness-audit), i.e. the most expensive lanes.
|
||||
# governance-detectors.ps1:1101-1102 already fixed exactly this at S159 and measured it on
|
||||
# the S159 bookend: 9 spawns ran, the glob saw 6. That fix was never mirrored into THIS
|
||||
# file even though both scan the same directory - a diagnosed, named, patched bug still
|
||||
# alive one file over. Regex below is a byte-for-byte mirror of the detectors one; if you
|
||||
# change one, change both (naming-standard.md section 12 lists all 3 sites).
|
||||
$subMd = @(Get-ChildItem -Path $latest.FullName -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -match '^(sub-.+|.+-return)\.md$' })
|
||||
$synth = @(Get-ChildItem -Path $latest.FullName -Filter '*-synthesis.md' -File -ErrorAction SilentlyContinue)
|
||||
if ($subMd.Count -eq 0) {
|
||||
Write-Na 'eval:hcv' 'HCV' ("latest run {0} has no sub-*.md (return-delta-only mode) - proxy N/A" -f $latest.Name)
|
||||
Write-Na 'eval:hcv' 'HCV' ("latest run {0} has no sub-*.md / *-return.md (return-delta-only mode) - proxy N/A" -f $latest.Name)
|
||||
}
|
||||
elseif ($synth.Count -gt 0) {
|
||||
Write-Pass 'eval:hcv' 'HCV' ("latest run {0}: {1} sub-md + {2} synthesis present (harvest-complete proxy; ratio = calibration-interim)" -f $latest.Name, $subMd.Count, $synth.Count)
|
||||
|
||||
297
scripts/naming-scan.ps1
Normal file
297
scripts/naming-scan.ps1
Normal file
@ -0,0 +1,297 @@
|
||||
# naming-scan.ps1 - MAY SOI TEN, tang BO MAY (SOLUTION_ERP)
|
||||
#
|
||||
# Chuan thi hanh: docs/governance/naming-standard.md (ky S180 / 2026-08-07, wave W1).
|
||||
# Kiem ke may doc ten: runs/2026-08-07-S180-adap-upgrade-pack-phased/sub-w1a-mayd-octen.md
|
||||
#
|
||||
# HOP DONG CUA MAY NAY - doc truoc khi sua:
|
||||
#
|
||||
# (1) INFORM-only. LUON exit 0, ke ca khi co co. Lai ma thoat = wave W3b,
|
||||
# sau khi chu du an chot cau P1 (da chot PA-2). Ly do do duoc (lane F):
|
||||
# bat gate ma chua soak => 8-12 lop no ton keu cung luc, nguoi tuong may
|
||||
# hong roi tat may.
|
||||
#
|
||||
# (2) Quet 231 TEN VAT-BO-MAY, KHONG quet 1.545 tep .md.
|
||||
# Ly do: 5 vung dong bang = 1.131/1.545 = 73,2% kho, va 225/248 cho lech
|
||||
# (90,7%) nam TRONG vung mien tru => may quet .md se in "0 hit" ngay dau
|
||||
# va so 0 do VO NGHIA (bay-4 cua san GD-1).
|
||||
# Tap 231 co 0 mien tru vung, va 23 vat lech that van nam nguyen trong do.
|
||||
#
|
||||
# (3) LUON IN MAU SO canh moi con so. Phien S180 da 7 ca bay don-vi.
|
||||
#
|
||||
# (4) CAM 3 LOI CAM (R6 - lane a dat ten, ca 3 deu co that trong kho nay):
|
||||
# (a) liet-khong-co : governance-detectors.ps1:1109 do ten la roi chi liet
|
||||
# (b) -or nuot nhanh : governance-detectors.ps1:1660 chap ca _end lan closed.md
|
||||
# (c) [skip] im lang : governance-detectors.ps1:1622 / :1882 / mfe-eval.ps1:265
|
||||
# => O DAY: moi ten nhan DUNG MOT phan quyet va LUON duoc in ten khi khac OK.
|
||||
# Tap vang mat = FLAG "THIEU-TAP", KHONG PHAI skip.
|
||||
#
|
||||
# (5) Pure ASCII (gotcha #30) - do 3 script .ps1 nen: 0/0/0 byte ngoai ASCII,
|
||||
# control-duong tren 1 tep .md tieng Viet = 58. Giu nguyen ky luat nay.
|
||||
#
|
||||
# Fault-inject: chay voi -RepoRoot <cay-tam> de cay ten lech / go ra, khong dung kho that.
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$RepoRoot
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not $RepoRoot -or $RepoRoot -eq '') {
|
||||
$RepoRoot = Split-Path -Parent $PSScriptRoot
|
||||
}
|
||||
$RepoRoot = (Resolve-Path -LiteralPath $RepoRoot).Path
|
||||
|
||||
# ---------- hinh dang ----------
|
||||
$RX_KEBAB = '^[a-z0-9]+(-[a-z0-9]+)*$'
|
||||
$RX_SNAKE = '^[a-z0-9]+(_[a-z0-9]+)*$'
|
||||
$RX_ONEOFF = '^(s[0-9]+-|plan-)'
|
||||
$RX_SESSFAM = '^_(tiep|pause|snapshot|context-s|mind-s|end)'
|
||||
$RX_SESSDIR = '^session-[0-9]+$'
|
||||
|
||||
# ---------- so ke ----------
|
||||
$script:Total = 0
|
||||
$script:Ok = 0
|
||||
$script:Lech = 0
|
||||
$script:OneOff = 0
|
||||
$script:Mien = 0
|
||||
$script:Pep8 = 0
|
||||
$script:MissingSets = 0
|
||||
$script:LechList = @()
|
||||
|
||||
function Write-Head([string]$t) { Write-Host ''; Write-Host $t -ForegroundColor Cyan }
|
||||
|
||||
function Add-Verdict {
|
||||
param([string]$Group, [string]$Name, [string]$Verdict, [string]$Note)
|
||||
$script:Total++
|
||||
switch ($Verdict) {
|
||||
'OK' { $script:Ok++ }
|
||||
'PEP8' { $script:Ok++; $script:Pep8++ }
|
||||
'MOT-LAN' { $script:Ok++; $script:OneOff++ }
|
||||
'MIEN' { $script:Mien++ }
|
||||
'LECH' {
|
||||
$script:Lech++
|
||||
$script:LechList += [pscustomobject]@{ Group = $Group; Name = $Name; Note = $Note }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Quet 1 tap. Tap vang mat => FLAG, KHONG skip im lang (luat 4c).
|
||||
function Scan-Set {
|
||||
param(
|
||||
[string]$Label,
|
||||
[string]$RelPath,
|
||||
# 'Item' = ca tep LAN thu muc. Bat buoc cho scripts/ va docs/governance/ vi
|
||||
# tap 231 dem theo don vi "muc" o hai nhom do (bay don-vi: tep != muc).
|
||||
[ValidateSet('File', 'Dir', 'Item')][string]$Kind,
|
||||
[int]$Expect,
|
||||
[scriptblock]$Rule,
|
||||
[string]$Filter = '*',
|
||||
[switch]$Recurse
|
||||
)
|
||||
|
||||
$full = Join-Path $RepoRoot $RelPath
|
||||
Write-Head ("--- NHOM: {0} [{1}]" -f $Label, $RelPath)
|
||||
|
||||
if (-not (Test-Path -LiteralPath $full)) {
|
||||
$script:MissingSets++
|
||||
Write-Host (" FLAG THIEU-TAP: khong tim thay '{0}'." -f $RelPath) -ForegroundColor Red
|
||||
Write-Host (" Day KHONG phai [skip]. Tap vang mat => phep do khong ton tai, mau so = 0/{0} ky vong." -f $Expect) -ForegroundColor Red
|
||||
Write-Host " Nguyen nhan thuong gap: thu muc vua bi doi ten => moi may neo vao no cung mu theo."
|
||||
return
|
||||
}
|
||||
|
||||
$items = switch ($Kind) {
|
||||
'File' { @(Get-ChildItem -LiteralPath $full -File -Filter $Filter -Recurse:$Recurse -ErrorAction SilentlyContinue) }
|
||||
'Dir' { @(Get-ChildItem -LiteralPath $full -Directory -Recurse:$Recurse -ErrorAction SilentlyContinue) }
|
||||
'Item' { @(Get-ChildItem -LiteralPath $full -Recurse:$Recurse -ErrorAction SilentlyContinue) }
|
||||
}
|
||||
|
||||
$unit = switch ($Kind) { 'File' { 'tep' } 'Dir' { 'thu muc' } 'Item' { 'muc (tep + thu muc)' } }
|
||||
$n = $items.Count
|
||||
$lo = 0; $lk = 0; $lm = 0; $l1 = 0; $lp = 0
|
||||
$rows = @()
|
||||
|
||||
foreach ($it in $items) {
|
||||
$v = & $Rule $it
|
||||
$verdict = $v[0]; $note = $v[1]
|
||||
Add-Verdict -Group $Label -Name $it.Name -Verdict $verdict -Note $note
|
||||
switch ($verdict) {
|
||||
'OK' { $lo++ }
|
||||
'PEP8' { $lo++; $lp++ }
|
||||
'MOT-LAN' { $lo++; $l1++ }
|
||||
'MIEN' { $lm++ }
|
||||
'LECH' { $lk++ }
|
||||
}
|
||||
if ($verdict -ne 'OK') { $rows += [pscustomobject]@{ V = $verdict; N = $it.Name; Note = $note } }
|
||||
}
|
||||
|
||||
Write-Host (" mau so: {0} {1}" -f $n, $unit) -NoNewline
|
||||
if ($n -ne $Expect) {
|
||||
Write-Host (" [!] lech ky vong {0} - chuan hoac kho da doi, doc lai naming-standard.md" -f $Expect) -ForegroundColor Yellow
|
||||
} else { Write-Host '' }
|
||||
|
||||
Write-Host (" OK {0}/{1} | LECH {2}/{1} | MIEN-theo-luat {3}/{1}" -f $lo, $n, $lk, $lm)
|
||||
if ($lp -gt 0) { Write-Host (" trong OK: {0}/{1} theo PEP-8 (*.py snake_case - DUNG, khong phai troi)" -f $lp, $n) }
|
||||
if ($l1 -gt 0) { Write-Host (" trong OK: {0}/{1} MOT-LAN (tien to s<n>-/plan- = kich ban mot lan, HOP LE)" -f $l1, $n) }
|
||||
|
||||
foreach ($r in $rows) {
|
||||
$c = if ($r.V -eq 'LECH') { 'Red' } else { 'DarkGray' }
|
||||
Write-Host (" [{0,-7}] {1} <- {2}" -f $r.V, $r.N, $r.Note) -ForegroundColor $c
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host '=== naming-scan.ps1 - MAY SOI TEN (tang bo may) ===' -ForegroundColor White
|
||||
Write-Host ("RepoRoot : {0}" -f $RepoRoot)
|
||||
Write-Host "Che do : INFORM-only. LUON exit 0 ke ca khi co co (lai ma thoat = W3b, sau P1=PA-2)."
|
||||
Write-Host "Chuan : docs/governance/naming-standard.md"
|
||||
Write-Host "Tap do : 231 ten vat-bo-may, 0 mien tru VUNG (khong quet 1.545 tep .md - bay-4)."
|
||||
|
||||
# 1/7 - vai
|
||||
Scan-Set -Label 'vai' -RelPath '.claude/agents' -Kind File -Expect 27 -Filter '*.md' -Rule {
|
||||
param($f)
|
||||
if ($f.Name -eq 'README.md') { return @('MIEN', 'quy uoc pho quat (luat L4)') }
|
||||
if ($f.BaseName -cmatch $RX_KEBAB) { return @('OK', '') }
|
||||
return @('LECH', 'ten vai phai kebab thuan; xem naming-standard.md section 1')
|
||||
}
|
||||
|
||||
# 2/7 - thu muc nhat ky vai
|
||||
Scan-Set -Label 'nhat-ky-vai' -RelPath '.claude/agent-memory' -Kind Dir -Expect 26 -Rule {
|
||||
param($d)
|
||||
if ($d.Name -cmatch $RX_KEBAB) { return @('OK', '') }
|
||||
return @('LECH', 'thu muc nhat ky phai trung ten vai (kebab thuan)')
|
||||
}
|
||||
|
||||
# 3/7 - lenh
|
||||
Scan-Set -Label 'lenh' -RelPath '.claude/commands' -Kind File -Expect 19 -Rule {
|
||||
param($f)
|
||||
if ($f.Name -eq 'README.md') { return @('MIEN', 'quy uoc pho quat (luat L4)') }
|
||||
if ($f.BaseName -cmatch $RX_KEBAB) { return @('OK', '') }
|
||||
return @('LECH', 'ten lenh phai kebab; xem naming-standard.md section 7')
|
||||
}
|
||||
|
||||
# 4/7 - kich ban (2 quy uoc ngon ngu, luat L4). Don vi = MUC (co ca thu muc con).
|
||||
Scan-Set -Label 'kich-ban' -RelPath 'scripts' -Kind Item -Expect 55 -Rule {
|
||||
param($f)
|
||||
if ($f.Name -eq 'README.md') { return @('MIEN', 'quy uoc pho quat (luat L4)') }
|
||||
if ($f.Name -eq '__pycache__') { return @('MIEN', 'vat sinh tu dong (luat L4)') }
|
||||
if ($f.Extension -eq '.py') {
|
||||
if ($f.BaseName -cmatch $RX_SNAKE) { return @('PEP8', 'PEP-8: *.py snake_case la DUNG') }
|
||||
return @('LECH', '*.py phai snake_case theo PEP-8')
|
||||
}
|
||||
if ($f.BaseName -cnotmatch $RX_KEBAB) {
|
||||
return @('LECH', 'kich ban khong-phai-.py phai kebab; xem naming-standard.md section 8')
|
||||
}
|
||||
if ($f.BaseName -cmatch $RX_ONEOFF) {
|
||||
return @('MOT-LAN', 'kich ban mot lan thuoc phien/ke hoach - HOP LE, dem rieng')
|
||||
}
|
||||
return @('OK', '')
|
||||
}
|
||||
|
||||
# 5/7 - tep moc phien. BUOC -Recurse: tep nam trong session-<N>/, khong nam o goc.
|
||||
Scan-Set -Label 'moc-phien' -RelPath '.claude/sessions' -Kind File -Expect 90 -Recurse -Rule {
|
||||
param($f)
|
||||
if ($f.Name -cmatch $RX_SESSFAM) { return @('OK', '') }
|
||||
if ($f.Name -cmatch '^pause-') {
|
||||
return @('LECH', 'FORK ho cu: _pause-* la ho chuan. session_ctx.py:349-358 THA (doc ca 2 glob) => fork song mai neu khong ai goi ten')
|
||||
}
|
||||
if ($f.Name -eq 'closed.md') {
|
||||
return @('LECH', 'FORK dau-dong-phien: _end la ho chuan. detectors:1660 THA bang -or => doi sang ten thu BA thi phien da dong bi doc la DANG MO, co khong bao gio ban')
|
||||
}
|
||||
return @('LECH', 'tep moc phien moi BUOC BAT DAU bang _ ; xem naming-standard.md section 5')
|
||||
}
|
||||
|
||||
# 6/7 - so. Don vi = MUC (co ca thu muc con adap-reports/ adap-requests/).
|
||||
Scan-Set -Label 'so-governance' -RelPath 'docs/governance' -Kind Item -Expect 16 -Rule {
|
||||
param($f)
|
||||
if ($f.Name -eq 'README.md') { return @('MIEN', 'quy uoc pho quat (luat L4)') }
|
||||
if ($f.BaseName -cmatch $RX_KEBAB) { return @('OK', '') }
|
||||
return @('LECH', 'VAT LICH SU (thu da gui, mang ngay) - GIU NGUYEN theo luat L1, nhung phai duoc LIET TEN: no la chung nhan nhom nay co 2 ho')
|
||||
}
|
||||
|
||||
# 7/7 - hook
|
||||
Scan-Set -Label 'hook' -RelPath '.claude/hooks' -Kind File -Expect 1 -Rule {
|
||||
param($f)
|
||||
if ($f.BaseName -cmatch $RX_KEBAB) { return @('OK', '') }
|
||||
return @('LECH', 'hook phai kebab')
|
||||
}
|
||||
|
||||
# ---------- bat bien 2 chieu ----------
|
||||
Write-Head '--- BAT BIEN: .claude/agents/<role>.md == .claude/agent-memory/<role>/ ---'
|
||||
$agDir = Join-Path $RepoRoot '.claude/agents'
|
||||
$mmDir = Join-Path $RepoRoot '.claude/agent-memory'
|
||||
if ((Test-Path -LiteralPath $agDir) -and (Test-Path -LiteralPath $mmDir)) {
|
||||
$roles = @(Get-ChildItem -LiteralPath $agDir -File -Filter '*.md' |
|
||||
Where-Object { $_.Name -ne 'README.md' } | ForEach-Object { $_.BaseName })
|
||||
$dirs = @(Get-ChildItem -LiteralPath $mmDir -Directory | ForEach-Object { $_.Name })
|
||||
$noDiary = @($roles | Where-Object { $dirs -notcontains $_ })
|
||||
$noPersona = @($dirs | Where-Object { $roles -notcontains $_ })
|
||||
Write-Host (" mau so: {0} vai (tep persona, tru README) / {1} thu muc nhat ky" -f $roles.Count, $dirs.Count)
|
||||
Write-Host (" khop : {0}/{1}" -f ($roles.Count - $noDiary.Count), $roles.Count)
|
||||
if ($noDiary.Count -eq 0) { Write-Host ' vai THIEU thu muc nhat ky : (danh sach rong)' }
|
||||
else {
|
||||
$script:Lech += $noDiary.Count
|
||||
foreach ($r in $noDiary) {
|
||||
Write-Host (" FLAG vai THIEU nhat ky: {0} <- mfe-eval.ps1:264-267 se in 'N/A (no persistent diary)' va LOAI vai khoi phep do" -f $r) -ForegroundColor Red
|
||||
$script:LechList += [pscustomobject]@{ Group = 'bat-bien'; Name = $r; Note = 'thieu thu muc nhat ky' }
|
||||
}
|
||||
}
|
||||
if ($noPersona.Count -eq 0) { Write-Host ' nhat ky THUA (khong co persona): (danh sach rong)' }
|
||||
else {
|
||||
$script:Lech += $noPersona.Count
|
||||
foreach ($r in $noPersona) {
|
||||
Write-Host (" FLAG nhat ky THUA: {0} <- detectors:1109 se xep vao `$unmapped (LIET, KHONG CO)" -f $r) -ForegroundColor Red
|
||||
$script:LechList += [pscustomobject]@{ Group = 'bat-bien'; Name = $r; Note = 'thua thu muc nhat ky' }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$script:MissingSets++
|
||||
Write-Host ' FLAG THIEU-TAP: thieu .claude/agents hoac .claude/agent-memory => bat bien KHONG DO DUOC.' -ForegroundColor Red
|
||||
}
|
||||
|
||||
# ---------- khai tuong minh cai NGOAI tap ----------
|
||||
Write-Head '--- NGOAI TAP 231 (khai tuong minh - KHONG phai [skip]) ---'
|
||||
$sessRoot = Join-Path $RepoRoot '.claude/sessions'
|
||||
if (Test-Path -LiteralPath $sessRoot) {
|
||||
$sd = @(Get-ChildItem -LiteralPath $sessRoot -Directory)
|
||||
$sdOk = @($sd | Where-Object { $_.Name -cmatch $RX_SESSDIR })
|
||||
Write-Host (" thu muc phien: {0}/{1} dat hinh dang ^session-<so>$" -f $sdOk.Count, $sd.Count)
|
||||
Write-Host " CO CHU DICH nam ngoai tap 231: giu mau so 231 da thoa thuan, va nhom nay DA co may ep"
|
||||
Write-Host " (governance-detectors.ps1:1639 + session_ctx.py:133 + 2 ban session-scaffold)."
|
||||
$bad = @($sd | Where-Object { $_.Name -cnotmatch $RX_SESSDIR })
|
||||
foreach ($b in $bad) { Write-Host (" [LECH-ngoai-tap] {0}" -f $b.Name) -ForegroundColor Yellow }
|
||||
} else {
|
||||
Write-Host ' FLAG: .claude/sessions vang mat.' -ForegroundColor Red
|
||||
}
|
||||
|
||||
# ---------- tong ----------
|
||||
Write-Head '=== TONG ==='
|
||||
Write-Host (" mau so TONG : {0} ten vat-bo-may" -f $script:Total)
|
||||
Write-Host " goc 231 (do 2026-08-07 TRUOC wave W1) = 27 vai + 26 nhat ky + 19 lenh + 53 kich ban"
|
||||
Write-Host " + 90 moc phien + 15 so + 1 hook"
|
||||
Write-Host " +2 vat chinh W1 de ra: scripts/naming-scan.ps1 va docs/governance/naming-standard.md"
|
||||
Write-Host " => 233 sau W1. Khai ro de khong ai doc 233 thanh 'kho phinh ra' (bay-6: so do giua chung)."
|
||||
Write-Host (" OK : {0}/{1}" -f $script:Ok, $script:Total)
|
||||
Write-Host (" trong do PEP-8 : {0}/{1} (*.py snake - DUNG theo luat ngon ngu, khong phai troi)" -f $script:Pep8, $script:Total)
|
||||
Write-Host (" trong do MOT-LAN : {0}/{1} (kich ban mot lan - HOP LE, tin hieu ton kho chu khong phai vi pham)" -f $script:OneOff, $script:Total)
|
||||
Write-Host (" MIEN theo luat L4 : {0}/{1} (in ten o tung nhom - mien tru im lang va loi im lang trong giong het nhau)" -f $script:Mien, $script:Total)
|
||||
if ($script:Lech -gt 0) {
|
||||
Write-Host (" LECH : {0}/{1}" -f $script:Lech, $script:Total) -ForegroundColor Red
|
||||
} else {
|
||||
Write-Host (" LECH : 0/{0}" -f $script:Total) -ForegroundColor Green
|
||||
Write-Host " [!] 0 hit chi co nghia neu mau so tren KHAC 0 va tap do KHONG mien tru vung." -ForegroundColor Yellow
|
||||
}
|
||||
if ($script:MissingSets -gt 0) {
|
||||
Write-Host (" TAP VANG MAT : {0} <- moi tap vang lam phep do BIEN MAT, khong phai 'sach'" -f $script:MissingSets) -ForegroundColor Red
|
||||
}
|
||||
|
||||
if ($script:LechList.Count -gt 0) {
|
||||
Write-Host ''
|
||||
Write-Host ' Danh sach LECH (tung ten - cam nen thanh khoang):' -ForegroundColor Red
|
||||
foreach ($x in $script:LechList) { Write-Host (" - [{0}] {1}" -f $x.Group, $x.Name) }
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host ' Ma thoat: 0 (INFORM-only theo hop dong muc 1). Co o tren KHONG lai ma thoat.'
|
||||
Write-Host ' Lai ma thoat thuoc wave W3b, sau khi chu du an chot phan loai co theo PA-2.'
|
||||
exit 0
|
||||
122
scripts/tien-kiem-cua.ps1
Normal file
122
scripts/tien-kiem-cua.ps1
Normal file
@ -0,0 +1,122 @@
|
||||
# tien-kiem-cua.ps1 - GD-3 khoan (iv): tien kiem chi phi ~0 o DAU MOI CUA.
|
||||
#
|
||||
# Chi DOC. KHONG ghi. LUON exit 0 - day la lop INFORM, KHONG phai cong chan.
|
||||
# Cong chan bang ma loi = W3b (khoan C3-04 + thang 4 trang thai), dang cho owner (P1).
|
||||
# Ai sua file nay de tra ma != 0 la da doi lop, phai qua W3b truoc.
|
||||
#
|
||||
# Vi sao KHONG tin mtime cua he dieu hanh:
|
||||
# hook 'wal:' cham tep o bien moi luot, va 'git checkout' viet lai mtime hang loat.
|
||||
# mtime tra loi "tep bi cham luc nao", KHONG tra loi "cua dong luc nao".
|
||||
# => chon cua bang DAU THOI GIAN GHI TRONG TEP (hub: phu-luc GD-3 khoan (iv)).
|
||||
#
|
||||
# Guard vang tep = VI TU MAY (khoan (vii)): Test-Path roi bo qua VA KHAI.
|
||||
# CAM dung menh de "cai do chua lam" - menh de do sai ngay giay tep kia ha canh.
|
||||
#
|
||||
# A2 (mat ca tap): het nguon => in co THIEU-TAP RIENG, KHONG in "ok".
|
||||
# So 0 khong duoc phep doc thanh "sach".
|
||||
#
|
||||
# Dung: powershell -NoProfile -ExecutionPolicy Bypass -File scripts/tien-kiem-cua.ps1
|
||||
# -Cua adap-apply (ten cua dang mo - chi de in kem, khong doi hanh vi)
|
||||
# -RepoRoot <path> (fault-inject tren cay tam)
|
||||
|
||||
param(
|
||||
[string]$Cua = '',
|
||||
[string]$RepoRoot = ''
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Get-RepoRoot {
|
||||
param([string]$Explicit)
|
||||
if ($Explicit -and $Explicit.Trim().Length -gt 0) { return $Explicit }
|
||||
return (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
||||
}
|
||||
|
||||
# Rut dau thoi gian GHI TRONG TEP cua WAL (cua dung: /pause, /snapshot, hook wal:).
|
||||
# Khuon: "updated: YYYY-MM-DD | session: S<n> ..."
|
||||
function Read-WalStamp {
|
||||
param([string]$Root)
|
||||
$p = Join-Path $Root '.claude/WAL.md'
|
||||
if (-not (Test-Path -LiteralPath $p)) { return $null }
|
||||
# chi doc 10 dong dau - re, va moc luon nam o dau tep
|
||||
$head = Get-Content -LiteralPath $p -TotalCount 10 -ErrorAction Stop
|
||||
foreach ($line in $head) {
|
||||
$m = [regex]::Match($line, 'updated:\s*(\d{4}-\d{2}-\d{2})')
|
||||
if ($m.Success) {
|
||||
$s = [regex]::Match($line, 'session:\s*(S\d+)')
|
||||
return [pscustomobject]@{
|
||||
Nguon = 'WAL'
|
||||
Ngay = $m.Groups[1].Value
|
||||
Phien = $(if ($s.Success) { $s.Groups[1].Value } else { '?' })
|
||||
}
|
||||
}
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
# Rut dau thoi gian GHI TRONG TEP cua so dem phien (cua dung: /session-start, /session-end).
|
||||
function Read-CounterStamp {
|
||||
param([string]$Root)
|
||||
$p = Join-Path $Root '.claude/governance/.session-counter.json'
|
||||
if (-not (Test-Path -LiteralPath $p)) { return $null }
|
||||
$raw = Get-Content -LiteralPath $p -Raw -ErrorAction Stop
|
||||
$j = $raw | ConvertFrom-Json
|
||||
$ngay = $j.last_ticked_at
|
||||
if (-not $ngay) { return $null }
|
||||
if ($ngay -notmatch '^\d{4}-\d{2}-\d{2}$') { return $null }
|
||||
$phien = $j.last_ticked_session
|
||||
if (-not $phien) { $phien = '?' }
|
||||
return [pscustomobject]@{
|
||||
Nguon = 'counter'
|
||||
Ngay = $ngay
|
||||
Phien = "$phien"
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$root = Get-RepoRoot -Explicit $RepoRoot
|
||||
$nhan = ''
|
||||
if ($Cua -and $Cua.Trim().Length -gt 0) { $nhan = " cua=$Cua" }
|
||||
|
||||
$nguon = @()
|
||||
$hong = @()
|
||||
|
||||
foreach ($fn in @('Read-WalStamp', 'Read-CounterStamp')) {
|
||||
$r = $null
|
||||
try { $r = & $fn -Root $root } catch { $r = $null }
|
||||
if ($null -ne $r) { $nguon += $r } else { $hong += $fn }
|
||||
}
|
||||
|
||||
# A2 - mat CA TAP: khong con nguon nao doc duoc.
|
||||
# In co RIENG, tuyet doi khong in "ok". So 0 mat quyen doc thanh "sach".
|
||||
if ($nguon.Count -eq 0) {
|
||||
Write-Output "TIEN-KIEM:$nhan THIEU-TAP - 0/2 nguon moc doc duoc (WAL.md + .session-counter.json) | KHONG ket luan duoc gi | (khong chan)"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# chon cua dong GAN NHAT theo dau thoi gian TRONG TEP (khong phai mtime)
|
||||
$moi = $nguon | Sort-Object -Property Ngay -Descending | Select-Object -First 1
|
||||
|
||||
$co = @()
|
||||
if ($hong.Count -gt 0) {
|
||||
$ten = ($hong -join ',') -replace 'Read-|Stamp', ''
|
||||
$co += "NGUON-HONG:$ten"
|
||||
}
|
||||
|
||||
# lech phien giua 2 nguon = dau hieu mot dau cua khong dong
|
||||
if ($nguon.Count -ge 2) {
|
||||
$pset = @($nguon | ForEach-Object { $_.Phien } | Sort-Object -Unique)
|
||||
if ($pset.Count -gt 1) { $co += ("LECH-PHIEN:" + ($pset -join '/')) }
|
||||
}
|
||||
|
||||
$trangthai = $(if ($co.Count -eq 0) { 'ok' } else { ($co -join ' ') })
|
||||
|
||||
Write-Output ("TIEN-KIEM:$nhan cua-dong-gan-nhat={0} moc-trong-tep={1} phien={2} | nguon {3}/2 | {4}" -f `
|
||||
$moi.Nguon, $moi.Ngay, $moi.Phien, $nguon.Count, $trangthai)
|
||||
exit 0
|
||||
}
|
||||
catch {
|
||||
# fail-soft, y nguyen khuon nhip-no-probe: mot buoc MOI khong bao gio duoc lam hong nghi thuc dang chay tot
|
||||
Write-Output "tien-kiem loi (khong chan)"
|
||||
exit 0
|
||||
}
|
||||
Reference in New Issue
Block a user