[CLAUDE] Docs: bookend @close S185 ONE-SHOT (YC-018) — trio+H24deep+ring1/2+ctx 9-vai mot-mach, harvest 698KB->11 so, 16-FLAG patched, Tests canonical 668
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@ -347,10 +347,55 @@ if (Test-Path $gotchasPath) {
|
||||
ForEach-Object { $gotchaAnchors[[int]$_.Matches[0].Groups[1].Value] = $true }
|
||||
}
|
||||
|
||||
# --- L7-BOLT (C-2 @S185, medicine of broadcast 2026-08-05 "Lop 7 - neo vao hinh dang
|
||||
# chu do nguoi go", Ro C) ---------------------------------------------------------
|
||||
# '### N.' is a HUMAN-TYPED heading glyph. Let the writer file the two newest gotchas as
|
||||
# "### 87 -" or "#### 87." and they drop OUT of $gotchaAnchors in silence -- after which
|
||||
# this detector keeps emitting CONFIDENT per-ref lines ("'gotcha #87' has no anchor")
|
||||
# that are pure artefacts of a dead parse, not findings. That is the exact failure the
|
||||
# broadcast reports: the machine slid past the newest lines, re-anchored on an older
|
||||
# block and printed 13 overdue items to the session when the true number was 0.
|
||||
#
|
||||
# The medicine has TWO layers and layer 2 is the load-bearing one:
|
||||
# (1) do not anchor on the glyph -> not fixable here without owning gotchas.md's
|
||||
# heading convention (= owner ground), so it is NOT attempted; declared instead.
|
||||
# (2) add a live/dead BOLT read from an INDEPENDENT source: the newest anchor parsed
|
||||
# must not sit more than ONE step behind canonical. Canonical here is the
|
||||
# docs/STATUS.md Gotchas row -- a different FILE reached by a different parse
|
||||
# (Get-StatusValue table-row regex), so a heading-shape change cannot move both.
|
||||
# Off by more than one step => print "chua do duoc" and emit NO anchor-derived
|
||||
# number. Without the bolt a "0" and a "13" are equally meaningless.
|
||||
# Tolerance is ONE step by construction (a gotcha counted in STATUS whose section is
|
||||
# written a beat later is normal drift, not a dead parse) - that is the broadcast's own
|
||||
# wording ("khong cu hon moc moi nhat qua mot bac"), not a threshold invented here.
|
||||
# SCOPE of the suppression: only the ANCHOR-EXISTENCE verdict is withheld. The
|
||||
# range check (cites #N > canonical max) does NOT read $gotchaAnchors at all, so it
|
||||
# keeps firing -- withholding it would hide a real witness behind a parse problem.
|
||||
$anchorMaxGotcha = 0
|
||||
foreach ($ak in $gotchaAnchors.Keys) { if ($ak -gt $anchorMaxGotcha) { $anchorMaxGotcha = $ak } }
|
||||
$gotchaAnchorLive = $true
|
||||
$gotchaAnchorGap = 0
|
||||
if ($null -ne $maxGotcha -and $gotchaAnchors.Count -gt 0) {
|
||||
$gotchaAnchorGap = $maxGotcha - $anchorMaxGotcha
|
||||
if ($gotchaAnchorGap -gt 1) { $gotchaAnchorLive = $false }
|
||||
}
|
||||
$gotchaAnchorSuppressed = 0
|
||||
|
||||
if ($null -eq $maxGotcha -or $gotchaAnchors.Count -eq 0) {
|
||||
Write-Host ' [skip] no canonical max-gotcha or no anchors parsed - cannot validate gotcha refs' -ForegroundColor DarkGray
|
||||
}
|
||||
else {
|
||||
if (-not $gotchaAnchorLive) {
|
||||
Write-Host (" CHUA DO DUOC (L7-bolt): newest '### N.' anchor parsed = {0} but canonical (docs/STATUS.md Gotchas) = {1} -> the heading anchor is {2} steps behind, i.e. the parse is DEAD, not the docs. Anchor-existence verdict WITHHELD - no number is emitted from a dead anchor." -f `
|
||||
$anchorMaxGotcha, $maxGotcha, $gotchaAnchorGap) -ForegroundColor Yellow
|
||||
Write-InformFlag ("docs/gotchas.md") `
|
||||
("L7-bolt: gotcha anchor parse is DEAD (newest '### N.' anchor = {0}, canonical = {1}, gap {2} > 1) - anchor-existence checking measured NOTHING this run (chua do duoc, NOT clean)" -f $anchorMaxGotcha, $maxGotcha, $gotchaAnchorGap) `
|
||||
"re-file the newest gotcha section(s) as '### <N>. <title>' so the anchor parse reaches canonical, OR re-ground the docs/STATUS.md Gotchas row if IT is the stale side"
|
||||
}
|
||||
else {
|
||||
Write-Host (" [ok] L7-bolt: newest anchor {0} vs canonical {1} (gap {2} <= 1) - anchor parse is LIVE, numbers below are measured" -f `
|
||||
$anchorMaxGotcha, $maxGotcha, $gotchaAnchorGap) -ForegroundColor DarkGray
|
||||
}
|
||||
# Match "gotcha #N", "gotcha N", and bare "#N" tokens.
|
||||
# S151 fix (FP #111, H1 F-6 + ring1 confirm): the word-branch used to swallow
|
||||
# "gotchas 111.616B" (a BYTE-SIZE, thousands-separator) and flag a phantom #111.
|
||||
@ -382,6 +427,10 @@ else {
|
||||
'fix the number or add the gotcha to docs/gotchas.md'
|
||||
}
|
||||
elseif ($isGotchaWord -and -not $gotchaAnchors.ContainsKey($num)) {
|
||||
# L7-bolt (C-2): a dead anchor parse makes EVERY ref look anchorless.
|
||||
# Count what is withheld and print the count, so the drop in emitted
|
||||
# lines is told by its COMPONENTS and can never read as "got cleaner".
|
||||
if (-not $gotchaAnchorLive) { $gotchaAnchorSuppressed++; continue }
|
||||
Write-Flag 'LOW' ("{0}:{1}" -f (Rel $f.FullName), ($i + 1)) `
|
||||
("broken-gotcha-ref: 'gotcha #{0}' has no '### {0}.' anchor in gotchas.md" -f $num) `
|
||||
'fix ref or create the missing gotcha anchor'
|
||||
@ -389,6 +438,9 @@ else {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (-not $gotchaAnchorLive) {
|
||||
Write-Host (" L7-bolt withheld {0} anchor-existence line(s) this run (they would all be artefacts of the dead parse, not findings)" -f $gotchaAnchorSuppressed) -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -908,18 +960,70 @@ else {
|
||||
# that flags the sentence DEFINING its own pattern is the self-reference trap.
|
||||
$carryRx = '\[carry:([a-z0-9][a-z0-9._-]*)\]'
|
||||
$carryLines = @()
|
||||
foreach ($s in $segs) {
|
||||
$carrySegIdx = @() # L7-bolt: which segment each carry-line came from
|
||||
for ($si = 0; $si -lt $segs.Count; $si++) {
|
||||
$ks = @()
|
||||
foreach ($cm in [regex]::Matches($s, $carryRx)) { $ks += $cm.Groups[1].Value }
|
||||
if ($ks.Count -gt 0) { $carryLines += , (@($ks | Select-Object -Unique)) }
|
||||
foreach ($cm in [regex]::Matches($segs[$si], $carryRx)) { $ks += $cm.Groups[1].Value }
|
||||
if ($ks.Count -gt 0) { $carryLines += , (@($ks | Select-Object -Unique)); $carrySegIdx += $si }
|
||||
}
|
||||
Write-Host (" HANDOFF logic-segments (pre-marker + NEXT anh/em) = {0} ; of those, carry-lines = {1}" -f `
|
||||
$segs.Count, $carryLines.Count)
|
||||
|
||||
# --- L7-BOLT (C-2 @S185, medicine of broadcast 2026-08-05 "Lop 7", Ro C) ---------
|
||||
# This net anchors on TWO human-typed shapes: the '**NEXT anh/em' segment header and
|
||||
# the '[carry:slug]' stamp. Only the NEWEST carry-bearing segment can hold a live
|
||||
# streak, so if the newest block is typed differently (bold dropped, stamp cased
|
||||
# '[Carry:'), the anchor SLIDES DOWN to an older block and every streak is then
|
||||
# measured against history the repo already replaced -- while the output keeps its
|
||||
# confident per-key shape ("streak=3 < M=6"). That is the broadcast's ca verbatim:
|
||||
# the machine slid past the newest lines and reported precise, wrong numbers.
|
||||
#
|
||||
# BOLT, read from an INDEPENDENT source: the session milestone of the anchored
|
||||
# segment vs the newest milestone in the SAME document parsed WITHOUT any of the two
|
||||
# glyphs (plain S<N> scan over the raw text). Both readings come off the same file
|
||||
# but through disjoint parse paths, so no single glyph change can move both. Off by
|
||||
# more than ONE step => print "chua do duoc" and emit NO streak number.
|
||||
# WHY the doc's own newest S and not the session counter: the question this net asks
|
||||
# is "is my anchor at the FRONT of this document", which is a property of the
|
||||
# document. The counter would answer a different question (is the document current),
|
||||
# and picking a tolerance for THAT is an owner number -- not invented here.
|
||||
$SMilestoneRx = '(?<![A-Za-z0-9])S(\d+)(?![\d])'
|
||||
$docMaxS = 0
|
||||
foreach ($sm in [regex]::Matches($raw, $SMilestoneRx)) {
|
||||
$sn = [int]$sm.Groups[1].Value; if ($sn -gt $docMaxS) { $docMaxS = $sn }
|
||||
}
|
||||
$anchorMaxS = 0
|
||||
if ($carrySegIdx.Count -gt 0) {
|
||||
foreach ($sm in [regex]::Matches($segs[$carrySegIdx[0]], $SMilestoneRx)) {
|
||||
$sn = [int]$sm.Groups[1].Value; if ($sn -gt $anchorMaxS) { $anchorMaxS = $sn }
|
||||
}
|
||||
}
|
||||
$carryAnchorLive = $true
|
||||
$carryAnchorGap = 0
|
||||
if ($carryLines.Count -gt 0 -and $docMaxS -gt 0 -and $anchorMaxS -gt 0) {
|
||||
$carryAnchorGap = $docMaxS - $anchorMaxS
|
||||
if ($carryAnchorGap -gt 1) { $carryAnchorLive = $false }
|
||||
}
|
||||
|
||||
if ($carryLines.Count -eq 0) {
|
||||
Write-Host ' (0 carry-line - no [carry:<slug>] stamped yet, nothing to age)' -ForegroundColor DarkGray
|
||||
}
|
||||
elseif ($docMaxS -eq 0 -or $anchorMaxS -eq 0) {
|
||||
Write-Host (" CHUA DO DUOC (L7-bolt): no S<N> milestone readable ({0} in doc / {1} in anchored segment) - cannot tell whether the anchor is at the front of the file, so NO streak number is emitted" -f $docMaxS, $anchorMaxS) -ForegroundColor Yellow
|
||||
Write-InformFlag 'docs/HANDOFF.md' `
|
||||
'L7-bolt: carry-age anchor liveness UNMEASURABLE (no S<N> milestone in the doc and/or in the anchored segment) - carry-age measured NOTHING this run (chua do duoc, NOT clean)' `
|
||||
'keep an S<N> session milestone in the newest carry block so the anchor can be proven to sit at the front of the file'
|
||||
}
|
||||
elseif (-not $carryAnchorLive) {
|
||||
Write-Host (" CHUA DO DUOC (L7-bolt): carry anchor sits at S{0} while the document's newest milestone is S{1} ({2} steps behind) -> the '**NEXT' / '[carry:' shape anchor has SLID off the newest block. Streak numbers WITHHELD ({3} key(s) would have been scored against replaced history)." -f `
|
||||
$anchorMaxS, $docMaxS, $carryAnchorGap, $carryLines[0].Count) -ForegroundColor Yellow
|
||||
Write-InformFlag 'docs/HANDOFF.md' `
|
||||
("L7-bolt: carry-age anchor DEAD - anchored segment is S{0}, doc newest is S{1} (gap {2} > 1); {3} key(s) NOT scored, carry-age measured NOTHING this run (chua do duoc, NOT clean)" -f $anchorMaxS, $docMaxS, $carryAnchorGap, $carryLines[0].Count) `
|
||||
"restore the newest block's '**NEXT anh/em' header and lower-case '[carry:<slug>]' stamps so the newest segment is the anchored one again"
|
||||
}
|
||||
else {
|
||||
Write-Host (" [ok] L7-bolt: carry anchor S{0} vs doc newest S{1} (gap {2} <= 1) - anchor is at the front of the file, streaks below are measured" -f `
|
||||
$anchorMaxS, $docMaxS, $carryAnchorGap) -ForegroundColor DarkGray
|
||||
foreach ($k in $carryLines[0]) {
|
||||
$n = 0
|
||||
for ($i = 0; $i -lt $carryLines.Count; $i++) {
|
||||
@ -971,6 +1075,12 @@ else {
|
||||
# ---------------------------------------------------------------------------
|
||||
Write-Section 'H25-closeout-ritual (GAP-2)'
|
||||
|
||||
# C13 hook (carve-out liveness, C-8 @S185): counts close-groups this section ACTUALLY
|
||||
# scored. 0 = the grid ran but measured nothing (skip branch) = "chet lang". Read by
|
||||
# the C13 section far below; kept here so the number is produced by the grid itself and
|
||||
# not re-derived (a second derivation would be a second definition).
|
||||
$script:H25Scored = 0
|
||||
|
||||
# Subject shape of a session-close commit. Held in a variable (used by -match on git
|
||||
# SUBJECTS, never on any scanned file) so no prose copy exists to self-trip a matcher.
|
||||
$CloseoutSubjectRx = '^\[CLAUDE\] Docs: S\d+.*(?:closeout|session-end)'
|
||||
@ -1041,6 +1151,7 @@ else {
|
||||
continue
|
||||
}
|
||||
$prev = $closeGroups[$i + 1].Tip
|
||||
$script:H25Scored++ # C13 hook: this group IS scored (not skipped)
|
||||
$range = ("{0}..{1}" -f $prev.Hash, $cur.Hash)
|
||||
|
||||
$union = @()
|
||||
@ -1942,6 +2053,325 @@ else {
|
||||
$c12Note = if ($c12Measured) { '' } else { ' -- MEASURED NOTHING (no session log at/after the land date); a 0 outside the window is not a green' }
|
||||
Write-Host (" C12 raw-engine-bypass flags = {0} [INFORM-only, LOW, NOT folded into TOTAL baseline]{1}" -f $c12Flags, $c12Note) -ForegroundColor DarkGray
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# C13 - carve-out liveness (INFORM-only, NEW @S185; count SEPARATE, NOT in TOTAL)
|
||||
# ---------------------------------------------------------------------------
|
||||
# NAMING: this is the script's OWN C-numbering (C1..C12 already exist above). It is a
|
||||
# DIFFERENT namespace from the S185 run-checklist codes; this detector implements
|
||||
# checklist item C-8. Do not read "C13" as "checklist C-13".
|
||||
#
|
||||
# WHY: docs/governance/error-ledger.md "Carve-out o3 - dieu-kien SONG" pins the
|
||||
# force-fire carve-out at rank `PASS-voi-carve-out`, VALID **only while BOTH grids are
|
||||
# alive at the same time** (error-ledger:52-54, verbatim targets):
|
||||
# (a) the read-only debt line still PRINTS at every stop point - scripts/nhip-no-probe.ps1
|
||||
# (b) the "closeout-missing-ritual" probe is still WIRED - section H25-closeout-ritual
|
||||
# (GAP-2) in THIS script
|
||||
# One grid dead => the carve-out loses its self-transparency layer => RE-EVAL the rank,
|
||||
# and fall back to unconditional running until the grid is alive again (error-ledger:58).
|
||||
#
|
||||
# THE GAP THIS CLOSES - self-declared, not hypothetical. The SE adap-report for the
|
||||
# 2026-07-17 hub reply says, in its own honest-caveat (section 5):
|
||||
# "Carve-out dang duoc canh bang NGUOI, khong bang MAY ... khong co detector nao canh
|
||||
# chinh dieu-kien do. Neu mot luoi chet lang, nac PASS-voi-carve-out se TIEP TUC duoc
|
||||
# khai ma khong ai biet"
|
||||
# and section 4 files the liveness detector as "follow-up, chua build". This section is that
|
||||
# follow-up. Until now the condition holds by DISCIPLINE, which is exactly the
|
||||
# `cam-bang-tri-nho` class the ledger forbids.
|
||||
#
|
||||
# HOW EACH GRID IS MEASURED (existence is NOT liveness):
|
||||
# (a) is measured in TWO parts, because a guard can fail in two independent ways:
|
||||
# (a1) EMITS - the probe is RUN and must print a line starting `NHIP-NO:`.
|
||||
# Existence alone proves nothing: nhip-no-probe.ps1 exits 0 ALWAYS and
|
||||
# degrades to `probe-loi (khong chan)` on any exception, i.e. its failure
|
||||
# mode is precisely "alive-looking and silent". Only running it separates
|
||||
# the two. Cost measured before wiring: ~512 ms, and this script is an
|
||||
# audit tool, not a stop point (the stop-point cheapness predicate C7 is
|
||||
# about /pause and /tiep, not about the detector suite).
|
||||
# (a2) IS CALLED - at least one stop-point command file must carry a real
|
||||
# INVOCATION. use vs mention matters here as a measured fact, not a theory:
|
||||
# a prior count of "6 call sites" included .claude/commands/check-email.md,
|
||||
# where both hits are the script's NAME in prose and neither is a call; the
|
||||
# true set is 5. The predicate therefore requires `-File <...>nhip-no-probe.ps1`
|
||||
# on the line, which prose mentions do not carry. A machine that emits
|
||||
# perfectly but that nothing calls is dead in the only sense that matters.
|
||||
# (b) is measured by whether the H25 section SCORED anything this run
|
||||
# ($script:H25Scored), not by whether its code is present. A section that runs and
|
||||
# takes the [skip] branch prints reassuring output while measuring nothing.
|
||||
#
|
||||
# SEVERITY: INFORM. A dead grid is a governance fact of some weight, but folding a
|
||||
# brand-new net into the audited TOTAL (and raising its severity) is a post-triage,
|
||||
# owner-gated decision per the sink contract at the top of this file - never the net
|
||||
# author's call. The line shape is identical to Write-Flag, so `comm before/after`
|
||||
# isolates it and a fault-inject greps it exactly like any other flag.
|
||||
Write-Section 'C13 - carve-out liveness (INFORM-only)'
|
||||
$c13Flags = 0
|
||||
$c13Measured = $false
|
||||
$c13LedgerPath = Join-Path $RepoRoot 'docs\governance\error-ledger.md'
|
||||
$c13Resolve = 'restore the dead grid, OR re-eval the carve-out rank in docs/governance/error-ledger.md (Carve-out o3) and fall back to unconditional running until it is alive again'
|
||||
|
||||
if (-not (Test-Path $c13LedgerPath)) {
|
||||
Write-Host ' [skip] docs/governance/error-ledger.md not found - no carve-out rank is being claimed here, nothing to guard' -ForegroundColor DarkGray
|
||||
}
|
||||
else {
|
||||
$c13Measured = $true
|
||||
|
||||
# ---- grid (a1): the probe RUNS and EMITS ----
|
||||
$probePath = Join-Path $RepoRoot 'scripts\nhip-no-probe.ps1'
|
||||
$aEmits = $false
|
||||
$aWhy = ''
|
||||
if (-not (Test-Path $probePath)) {
|
||||
$aWhy = 'scripts/nhip-no-probe.ps1 is GONE from disk'
|
||||
}
|
||||
else {
|
||||
$pOut = ''
|
||||
try { $pOut = (& powershell.exe -ExecutionPolicy Bypass -File $probePath -RepoRoot $RepoRoot 2>&1 | Out-String) }
|
||||
catch { $pOut = '' }
|
||||
if ($pOut -match '(?m)^NHIP-NO:') { $aEmits = $true }
|
||||
else {
|
||||
$first = (($pOut -split "`r?`n") | Where-Object { $_.Trim().Length -gt 0 } | Select-Object -First 1)
|
||||
if ($null -eq $first) { $first = '(no output at all)' }
|
||||
$aWhy = ("the probe ran but printed no 'NHIP-NO:' line (first line: {0})" -f $first.Trim())
|
||||
}
|
||||
}
|
||||
|
||||
# ---- grid (a2): at least one stop point CALLS it ----
|
||||
$callRx = '-File\s+\S*nhip-no-probe\.ps1'
|
||||
$callSites = @()
|
||||
$cmdDir = Join-Path $RepoRoot '.claude\commands'
|
||||
if (Test-Path $cmdDir) {
|
||||
foreach ($cf in (Get-ChildItem -Path $cmdDir -Filter *.md -File -ErrorAction SilentlyContinue)) {
|
||||
$cl = Get-Content -Path $cf.FullName -Encoding UTF8 -ErrorAction SilentlyContinue
|
||||
for ($i = 0; $i -lt $cl.Count; $i++) {
|
||||
if ($cl[$i] -match $callRx) { $callSites += ("{0}:{1}" -f $cf.Name, ($i + 1)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---- verdicts ----
|
||||
if (-not $aEmits) {
|
||||
Write-InformFlag 'scripts/nhip-no-probe.ps1' `
|
||||
("carve-out grid (a) DEAD - the debt line no longer prints: {0}. error-ledger 'Carve-out o3' requires BOTH grids alive; rank PASS-voi-carve-out is NOT valid while this is dead" -f $aWhy) `
|
||||
$c13Resolve
|
||||
$c13Flags++
|
||||
}
|
||||
elseif ($callSites.Count -eq 0) {
|
||||
Write-InformFlag 'scripts/nhip-no-probe.ps1' `
|
||||
("carve-out grid (a) DEAD-BY-DISCONNECT - the probe emits, but NO stop-point command actually calls it (0 lines matching '-File ...nhip-no-probe.ps1' under .claude/commands). A debt line nobody triggers is not printed 'at every stop point'") `
|
||||
$c13Resolve
|
||||
$c13Flags++
|
||||
}
|
||||
else {
|
||||
Write-Host (" [ok] grid (a) ALIVE: nhip-no-probe emits NHIP-NO: and is CALLED from {0} stop point(s) - {1}" -f `
|
||||
$callSites.Count, ($callSites -join ', ')) -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
if ($script:H25Scored -le 0) {
|
||||
Write-InformFlag 'scripts/governance-detectors.ps1 (H25-closeout-ritual)' `
|
||||
'carve-out grid (b) DEAD - the closeout-ritual probe took its [skip] branch and scored 0 close-group this run, i.e. it is wired but measuring NOTHING. error-ledger Carve-out o3 requires BOTH grids alive' `
|
||||
$c13Resolve
|
||||
$c13Flags++
|
||||
}
|
||||
else {
|
||||
Write-Host (" [ok] grid (b) ALIVE: H25-closeout-ritual scored {0} close-group(s) this run" -f $script:H25Scored) -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
$c13Note = if ($c13Measured) { '' } else { ' -- MEASURED NOTHING (skipped above); a 0 after a skip is not a green' }
|
||||
Write-Host (" C13 carve-out-liveness flags = {0} [INFORM-only, LOW, NOT folded into TOTAL baseline]{1}" -f $c13Flags, $c13Note) -ForegroundColor DarkGray
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# C14 - stamp_verify mirror-drift (INFORM-only, NEW @S185; count SEPARATE, NOT in TOTAL)
|
||||
# ---------------------------------------------------------------------------
|
||||
# NAMING: script-local C-numbering (see C13 note). This implements S185 checklist C-19.
|
||||
#
|
||||
# WHY: scripts/stamp_verify.py is a MIRROR, not a source. Its own header says so:
|
||||
# "mirror-of AI_INFRA/scripts/stamp_verify.py (ported S141 ...) - re-pull khi hub doi
|
||||
# section-N canon. KHONG sua logic local."
|
||||
# The SE adap-report for 2026-07-17-Governance-chuan-hoa-stamp-decode says it plainly
|
||||
# (section 5 honest-caveat): "hub doi section-N canon ma SE quen re-pull thi 2 ben lech IM LANG - hien
|
||||
# KHONG CO MAY NAO canh drift giua 2 ban, chi co header-note nhac NGUOI." Measured @S185:
|
||||
# a note is the only guard, and a note guards nothing once nobody re-reads it. Two copies
|
||||
# of one canon = the drift class B1 exists to prevent (same shape as C9 above).
|
||||
#
|
||||
# WHAT IS COMPARED - and why not the raw bytes. Measured today: the two files differ by
|
||||
# exactly ONE line, the local mirror-of note itself (`diff` = 1 added line, 2378 B vs
|
||||
# 2247 B). A raw-hash watcher would therefore INFORM on EVERY run forever - a permanently
|
||||
# red lamp is read as noise within a week and is just a dead grid pointing the other way.
|
||||
# So the drift verdict is taken on the LOGIC hash: the declared local-only note line is
|
||||
# excluded (it is the file's own statement that only the note may differ), CRLF is
|
||||
# normalized to LF (a checkout EOL setting is not a canon change), and the RAW hashes are
|
||||
# printed alongside anyway so nothing is hidden by the normalization.
|
||||
#
|
||||
# HUB PATH IS DERIVED, NEVER HARDCODED: repo-root -> up 2 -> AI_INFRA. An absolute path
|
||||
# with a machine-specific prefix silently degrades to the else-branch on any other
|
||||
# machine, and a silent degrade reads exactly like "clean" - the S122 W5 lesson already
|
||||
# paid for once in this file. Hub unreachable => "CHUA DO DUOC", never [ok], never silence.
|
||||
Write-Section 'C14 - stamp_verify mirror-drift (INFORM-only)'
|
||||
$c14Flags = 0
|
||||
$c14Measured = $false
|
||||
|
||||
function Get-MirrorHashes {
|
||||
param([string]$Path)
|
||||
$txt = [System.IO.File]::ReadAllText($Path)
|
||||
$raw = $txt -replace "`r`n", "`n"
|
||||
$logic = (($raw -split "`n") | Where-Object { $_ -notmatch '^\s*#.*mirror-of' }) -join "`n"
|
||||
$sha = [System.Security.Cryptography.SHA256]::Create()
|
||||
$enc = New-Object System.Text.UTF8Encoding($false)
|
||||
$h1 = ($sha.ComputeHash($enc.GetBytes($raw)) | ForEach-Object { $_.ToString('x2') }) -join ''
|
||||
$h2 = ($sha.ComputeHash($enc.GetBytes($logic)) | ForEach-Object { $_.ToString('x2') }) -join ''
|
||||
return [pscustomobject]@{ Raw = $h1; Logic = $h2; Lines = (($raw -split "`n").Count) }
|
||||
}
|
||||
|
||||
$mirLocal = Join-Path $RepoRoot 'scripts\stamp_verify.py'
|
||||
$hubRoot = $null
|
||||
$p1 = Split-Path $RepoRoot -Parent
|
||||
if ($null -ne $p1) { $p2 = Split-Path $p1 -Parent; if ($null -ne $p2) { $hubRoot = Join-Path $p2 'AI_INFRA' } }
|
||||
$mirHub = if ($null -eq $hubRoot) { $null } else { Join-Path $hubRoot 'scripts\stamp_verify.py' }
|
||||
|
||||
if (-not (Test-Path $mirLocal)) {
|
||||
Write-InformFlag 'scripts/stamp_verify.py' `
|
||||
'stamp mirror MISSING locally - the ported verifier is gone, so /check-email and /send-email fall back to the regex-pin path with nothing checking the canon' `
|
||||
're-pull scripts/stamp_verify.py from AI_INFRA, or declare the regex-pin path canonical and retire the mirror in the SAME change'
|
||||
$c14Flags++; $c14Measured = $true
|
||||
}
|
||||
elseif ($null -eq $mirHub -or -not (Test-Path $mirHub)) {
|
||||
$shown = if ($null -eq $mirHub) { '(hub root underivable)' } else { $mirHub }
|
||||
Write-Host (" CHUA DO DUOC: hub copy not reachable at {0} - drift is UNMEASURED on this machine (this is NOT a green; the mirror may be stale and nothing here can tell)" -f $shown) -ForegroundColor Yellow
|
||||
}
|
||||
else {
|
||||
$c14Measured = $true
|
||||
$hl = Get-MirrorHashes $mirLocal
|
||||
$hh = Get-MirrorHashes $mirHub
|
||||
if ($hl.Logic -ne $hh.Logic) {
|
||||
Write-InformFlag 'scripts/stamp_verify.py' `
|
||||
("stamp mirror DRIFT: local logic-sha {0} != hub logic-sha {1} (local {2} lines / hub {3} lines; raw-sha local {4} hub {5}) - the mirror no longer carries the hub canon, so a stamp verified here can pass while the hub would fail it" -f `
|
||||
$hl.Logic.Substring(0, 12), $hh.Logic.Substring(0, 12), $hl.Lines, $hh.Lines, $hl.Raw.Substring(0, 8), $hh.Raw.Substring(0, 8)) `
|
||||
'BLOCKING NOTHING (INFORM): re-pull the hub copy over scripts/stamp_verify.py keeping ONLY the mirror-of header note, then re-run this detector'
|
||||
$c14Flags++
|
||||
}
|
||||
else {
|
||||
$rawNote = if ($hl.Raw -eq $hh.Raw) { 'raw identical too' } else { ('raw differs only by the declared mirror-of note: local {0} / hub {1}' -f $hl.Raw.Substring(0, 8), $hh.Raw.Substring(0, 8)) }
|
||||
Write-Host (" [ok] stamp mirror in sync: logic-sha {0} on both sides ({1})" -f $hl.Logic.Substring(0, 12), $rawNote) -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
$c14Note = if ($c14Measured) { '' } else { ' -- MEASURED NOTHING (hub unreachable); a 0 here is "chua do duoc", not a green' }
|
||||
Write-Host (" C14 stamp-mirror-drift flags = {0} [INFORM-only, LOW, NOT folded into TOTAL baseline]{1}" -f $c14Flags, $c14Note) -ForegroundColor DarkGray
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# C15 - V-5 encoding predicate (INFORM-only, NEW @S185; count SEPARATE, NOT in TOTAL)
|
||||
# ---------------------------------------------------------------------------
|
||||
# NAMING: script-local C-numbering (see C13 note). This implements S185 checklist C-11.
|
||||
#
|
||||
# WHY: the artifact roll-call machine (scripts/artifact-integrity.ps1) carries FOUR
|
||||
# predicates - absent / empty / truncated / over-compressed - and is BLIND at the
|
||||
# encoding level; the sub-w3 case proved it. The debt is on the books as "V-5 vi-tu
|
||||
# ma-hoa CHUA CAM" in docs/governance/adap-reports/upgrade-pack-phased-bao-cao-cuoi.md:79
|
||||
# (section 9, "No co moc"), where the V5 line is FILLED BY HAND with no machine behind
|
||||
# it. The spec already existed - one grep line, TWO ranks - and was only waiting for a
|
||||
# home. This section is that home, i.e. the hand-filled line becomes a measured count.
|
||||
#
|
||||
# TWO RANKS, kept apart on purpose (they need different actions):
|
||||
# rank-1 DATA LOSS - raw U+FFFD present (UTF-8 bytes EF BF BD). The original bytes
|
||||
# are GONE; re-decoding cannot bring them back, only the source
|
||||
# artifact can. Detected on BYTES, so it is decode-independent.
|
||||
# rank-2 MOJIBAKE-ONLY - no U+FFFD, but double-encoding signatures present. Nothing is
|
||||
# lost; a correct re-decode repairs it.
|
||||
# rank-1 dominates when a file shows both: "lost" is the actionable fact.
|
||||
#
|
||||
# USE vs MENTION is enforced at the BYTE level and that is not a detail: a previous
|
||||
# baseline counted a file that writes the ASCII token "<FFFD>" seven times as if it held
|
||||
# seven damaged characters, then a later reader saw the count "drop" and went hunting a
|
||||
# phantom file. Matching raw EF BF BD only cannot make that mistake - a doc that TALKS
|
||||
# about U+FFFD in ASCII is invisible to it (proved by the boundary case in the harness).
|
||||
#
|
||||
# CORPUS: $GovMd PLUS .claude/workflows/runs/**/*.md. The run folders are excluded from
|
||||
# $GovMd by the C4 self-line rule (they describe patterns), but that rule is about
|
||||
# CONTENT patterns and this predicate reads BYTES, so the exclusion buys nothing here and
|
||||
# costs everything: measured @S185, 7 of the 12 damaged files live exactly there. An
|
||||
# auditor that skipped runs/ has already reported a false 0-hit once.
|
||||
#
|
||||
# The mojibake markers are built from CODE POINTS (same U helper as the VN tokens) so this
|
||||
# .ps1 stays pure-ASCII on disk (gotcha #30) and so the detector never carries a literal
|
||||
# specimen of the thing it hunts.
|
||||
Write-Section 'C15 - V-5 encoding predicate (INFORM-only)'
|
||||
$c15Flags = 0
|
||||
$c15Measured = $false
|
||||
|
||||
# Double-encoding signatures. Chosen for precision over recall: each is a Latin-1 lead
|
||||
# byte followed by a continuation-range char, a pair that legitimate Vietnamese/English
|
||||
# prose does not produce. Recall is deliberately partial - this is a lowering net.
|
||||
# NOTE ON THE PARENTHESES, which are load-bearing: each element must be wrapped so the
|
||||
# '+' concatenation cannot run ACROSS the commas. Written without them, PowerShell folds
|
||||
# the three patterns into ONE string and the array silently becomes Count=1 - a net that
|
||||
# then matches nothing and reports a confident 0. That is not hypothetical: the first
|
||||
# measurement taken while building this section was exactly that shape and returned
|
||||
# "mojibake: 0 files" on a corpus that really holds 13. Verified by printing
|
||||
# ($MojiRx.Count = 3) and each element's code points before trusting any number.
|
||||
$MojiRx = @(
|
||||
((U @(0x00C3)) + '[' + (U @(0x00A0)) + '-' + (U @(0x00BF)) + ']'),
|
||||
((U @(0x00E2, 0x20AC))),
|
||||
((U @(0x00C4, 0x0091)))
|
||||
)
|
||||
# U+FFFD as its three UTF-8 bytes, seen through the Latin-1 view (EF BF BD).
|
||||
$FFFD_BYTES = U @(0x00EF, 0x00BF, 0x00BD)
|
||||
|
||||
$v5Files = @($GovMd)
|
||||
$runsDirV5 = Join-Path $RepoRoot '.claude\workflows\runs'
|
||||
if (Test-Path $runsDirV5) {
|
||||
$v5Files += @(Get-ChildItem -Path $runsDirV5 -Recurse -Filter *.md -File -ErrorAction SilentlyContinue)
|
||||
}
|
||||
$v5Files = $v5Files | Where-Object { $_.FullName -notmatch '[\\/](bin|obj|node_modules)[\\/]' }
|
||||
|
||||
if ($v5Files.Count -eq 0) {
|
||||
Write-Host ' [skip] no .md in scope - encoding predicate measured NOTHING (not a green)' -ForegroundColor DarkGray
|
||||
}
|
||||
else {
|
||||
$c15Measured = $true
|
||||
$lossFiles = @(); $lossHits = 0
|
||||
$mojiFiles = @(); $mojiHits = 0
|
||||
foreach ($vf in $v5Files) {
|
||||
$bytes = $null
|
||||
try { $bytes = [System.IO.File]::ReadAllBytes($vf.FullName) } catch { $bytes = $null }
|
||||
if ($null -eq $bytes) { continue }
|
||||
# rank-1 counted on RAW BYTES via a Latin-1 view (codepage 28591 maps byte n ->
|
||||
# char U+00n, 1:1 and lossless), so the needle EF BF BD is matched exactly as
|
||||
# bytes while still using the fast .NET regex engine. A per-byte PowerShell loop
|
||||
# measured the same thing but took ~18 s longer over this corpus.
|
||||
$lat = [System.Text.Encoding]::GetEncoding(28591).GetString($bytes)
|
||||
$n = ([regex]::Matches($lat, $FFFD_BYTES)).Count
|
||||
if ($n -gt 0) {
|
||||
$lossFiles += ("{0} x{1}" -f (Rel $vf.FullName), $n); $lossHits += $n
|
||||
continue # rank-1 dominates: a lost-byte file is not re-classified as merely mojibake
|
||||
}
|
||||
$txt = [System.Text.Encoding]::UTF8.GetString($bytes)
|
||||
$mm = 0
|
||||
foreach ($rx in $MojiRx) { $mm += ([regex]::Matches($txt, $rx)).Count }
|
||||
if ($mm -gt 0) { $mojiFiles += ("{0} x{1}" -f (Rel $vf.FullName), $mm); $mojiHits += $mm }
|
||||
}
|
||||
|
||||
Write-Host (" V-5 measured over {0} .md (docs + .claude + workflows/runs) ; rank-1 data-loss: {1} file(s) / {2} hit(s) ; rank-2 mojibake-only: {3} file(s) / {4} hit(s)" -f `
|
||||
$v5Files.Count, $lossFiles.Count, $lossHits, $mojiFiles.Count, $mojiHits)
|
||||
|
||||
if ($lossFiles.Count -gt 0) {
|
||||
Write-InformFlag 'V-5 rank-1' `
|
||||
("encoding DATA LOSS: {0} file(s) / {1} raw U+FFFD - the original bytes are gone and no re-decode recovers them; only the source artifact can" -f $lossFiles.Count, $lossHits) `
|
||||
're-fetch each file from its source artifact (a re-save will NOT restore the lost characters); if a file is a frozen record, note the loss in it explicitly so it is not read as content'
|
||||
$c15Flags++
|
||||
foreach ($lf in $lossFiles) { Write-Host (" [rank-1] {0}" -f $lf) -ForegroundColor DarkGray }
|
||||
}
|
||||
if ($mojiFiles.Count -gt 0) {
|
||||
Write-InformFlag 'V-5 rank-2' `
|
||||
("encoding MOJIBAKE-ONLY: {0} file(s) / {1} double-encoding signature(s) - nothing is lost, a correct re-decode repairs it" -f $mojiFiles.Count, $mojiHits) `
|
||||
're-decode the file as UTF-8 and re-save; verify by re-running this detector (rank-2 must go to 0 without rank-1 rising)'
|
||||
$c15Flags++
|
||||
foreach ($mf in $mojiFiles) { Write-Host (" [rank-2] {0}" -f $mf) -ForegroundColor DarkGray }
|
||||
}
|
||||
if ($lossFiles.Count -eq 0 -and $mojiFiles.Count -eq 0) {
|
||||
Write-Host ' [ok] no encoding damage found in scope' -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
$c15Note = if ($c15Measured) { '' } else { ' -- MEASURED NOTHING (skipped above); a 0 after a skip is not a green' }
|
||||
Write-Host (" C15 V-5 encoding flags = {0} [INFORM-only, LOW, NOT folded into TOTAL baseline]{1}" -f $c15Flags, $c15Note) -ForegroundColor DarkGray
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Summary + C4 self-exclusion audit (RUNTIME proof)
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -1965,7 +2395,7 @@ if ($selfInScan -eq 0 -and $leaked -eq 0) {
|
||||
|
||||
Write-Host ''
|
||||
Write-Host ("TOTAL FLAGS: {0}" -f $script:FlagCount) -ForegroundColor Cyan
|
||||
Write-Host ("INFORM-ONLY (new nets C6 cite-2-tier + H24-4 pending-flip + H24-5 counter-ancestor-classify + C9 hmw-width-drift + C11 h24-flag-form + C12 raw-engine-bypass): {0} - counted SEPARATELY, NOT in TOTAL above (anti-Goodhart, owner-set; fold+sev-raise is post-triage)" -f $script:InformCount) -ForegroundColor DarkGray
|
||||
Write-Host ("INFORM-ONLY (new nets C6 cite-2-tier + H24-4 pending-flip + H24-5 counter-ancestor-classify + C9 hmw-width-drift + C11 h24-flag-form + C12 raw-engine-bypass + C13 carve-out-liveness + C14 stamp-mirror-drift + C15 V-5-encoding + the L7-bolt 'chua do duoc' lines): {0} - counted SEPARATELY, NOT in TOTAL above (anti-Goodhart, owner-set; fold+sev-raise is post-triage)" -f $script:InformCount) -ForegroundColor DarkGray
|
||||
Write-Host 'NOTE: DETECT-only lowering net. Exit 0 always (never fails build). FLAGs are advisory.' -ForegroundColor DarkGray
|
||||
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user