[CLAUDE] Skill: YC-021 tron — ring5-audit verified-runtime + day-wake 4-floor (/day + day-probe fault-inject 4/4) + bang-tham-quyen-DRAFT + thu hub re-stamp; REVIEW 8-MAJ va het truoc commit

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-08-10 03:51:22 +07:00
parent 87e979ff02
commit 6bf768da94
18 changed files with 530 additions and 8 deletions

95
scripts/day-probe.ps1 Normal file
View File

@ -0,0 +1,95 @@
#Requires -Version 5.1
<#
.SYNOPSIS
day-probe (W-1 day-wake, adopt hub 2026-07-28 "probe-first-resume"; owner YC-021 @S185).
READ-ONLY probe deciding CHEAP-WAKE vs FULL-RESUME. Prints EXACTLY one DAY-PROBE line.
ALWAYS exit 0 (INFORM layer - the /day command reads the verdict word, nothing blocks).
.DESCRIPTION
Floor F1: pick the LAST session marker by the ts WRITTEN INSIDE the file (never mtime -
Dropbox resync touches mtime). Then check 4 delta signals:
(a) commits after the anchor (git rev-list count)
(b) tracked/untracked dirty files (git status --porcelain, no allowlist - lean DELTA)
(c) is covered by (a)+(b): run-folders/artifacts land as commits or dirty files
(d) closing: sentinel in .claude/WAL.md (San-2)
Floor F3: anchor = the commit that ADDED the marker file (the stop-seal commit), NOT the
head-sha inside the marker (trap-one: head-sha predates the seal commit => false DELTA
100% of the time). Fallback = head-sha field. Anchor must EXIST (cat-file -e) AND be an
ANCESTOR of HEAD (merge-base --is-ancestor); orphaned (post-squash) => verdict ANCHOR-LOST
printed LOUDLY (trap-two: fail-safe must have a voice, not die silent).
Verdict precedence: ANCHOR-LOST > DELTA > CLEAN. Leaning rule: any probe error => DELTA.
Floor F4 lives in /day (the _day-<i>.md marker); this script only measures.
.PARAMETER RepoRoot
Repo root; a temp tree here isolates fault-injection (mirror governance-detectors.ps1).
#>
[CmdletBinding()]
param([string]$RepoRoot = (Get-Location).Path)
$sw = [System.Diagnostics.Stopwatch]::StartNew()
$ErrorActionPreference = 'SilentlyContinue'
function Out-Line([string]$verdict, [string]$detail) {
$script:sw.Stop()
Write-Host ("DAY-PROBE: {0} | {1} | {2}ms" -f $verdict, $detail, $script:sw.ElapsedMilliseconds)
exit 0
}
try {
$sessRoot = Join-Path $RepoRoot '.claude\sessions'
if (-not (Test-Path $sessRoot)) { Out-Line 'DELTA' 'probe-loi: no sessions dir (lean DELTA)' }
# newest logic-session = highest N with a _context file
$sess = Get-ChildItem -Path $sessRoot -Directory -Filter 'session-*' |
Where-Object { Test-Path (Join-Path $_.FullName ("_context-s-" + ($_.Name -replace '^session-','') + ".md")) } |
Sort-Object { [int]($_.Name -replace '^session-','') } -Descending | Select-Object -First 1
if ($null -eq $sess) { Out-Line 'DELTA' 'probe-loi: no logic-session found (lean DELTA)' }
# last marker by ts INSIDE file (F1). _day markers count too (repeat wakes).
$markers = @()
foreach ($f in (Get-ChildItem -Path $sess.FullName -File | Where-Object { $_.Name -match '^_(pause|tiep|snapshot|day)-\d+\.md$' })) {
$ts = $null; $sha = $null
foreach ($ln in (Get-Content -Path $f.FullName -TotalCount 8 -Encoding UTF8)) {
if ($ln -match '^ts:\s*(\S+)') { $ts = $Matches[1] }
if ($ln -match '^head-sha:\s*([0-9a-f]{7,40})') { $sha = $Matches[1] }
}
if ($null -ne $ts) { $markers += [pscustomobject]@{ File = $f.FullName; Name = $f.Name; Ts = $ts; Sha = $sha } }
}
if ($markers.Count -eq 0) { Out-Line 'DELTA' ('no marker with in-file ts under ' + $sess.Name + ' (lean DELTA)') }
$last = $markers | Sort-Object Ts -Descending | Select-Object -First 1
# F3 anchor: the commit that ADDED the marker (stop-seal), fallback in-file head-sha
Push-Location $RepoRoot
try {
$rel = (Resolve-Path -Relative $last.File) -replace '^\.\\', '' -replace '\\', '/'
$anchor = (& git log --diff-filter=A --format=%H -1 -- $rel 2>$null | Select-Object -First 1)
$src = 'seal-commit'
if ([string]::IsNullOrWhiteSpace($anchor)) { $anchor = $last.Sha; $src = 'in-file-sha' }
if ([string]::IsNullOrWhiteSpace($anchor)) { Out-Line 'DELTA' ('marker ' + $last.Name + ' has no resolvable anchor (lean DELTA)') }
& git cat-file -e ($anchor + '^{commit}') 2>$null
if ($LASTEXITCODE -ne 0) {
Out-Line 'ANCHOR-LOST' ('anchor=' + $anchor.Substring(0,[Math]::Min(8,$anchor.Length)) + ' (' + $src + ') MISSING from object store - marker=' + $last.Name + ' - route: FULL /tiep (loud fail-safe, F3 trap-two)')
}
& git merge-base --is-ancestor $anchor HEAD 2>$null
if ($LASTEXITCODE -ne 0) {
Out-Line 'ANCHOR-LOST' ('anchor=' + $anchor.Substring(0,8) + ' (' + $src + ') exists but NOT ancestor of HEAD (post-squash orphan) - marker=' + $last.Name + ' - route: FULL /tiep')
}
# signals
$nCommits = [int](& git rev-list --count ($anchor + '..HEAD') 2>$null)
$dirty = @(& git status --porcelain 2>$null | Where-Object { $_ -and $_.Trim().Length -gt 0 })
$nDirty = $dirty.Count
$walP = Join-Path $RepoRoot '.claude\WAL.md'
$nClosing = 0
if (Test-Path $walP) { $nClosing = @(Select-String -Path $walP -Pattern '^closing:' -Encoding UTF8).Count }
$detail = ('anchor=' + $anchor.Substring(0,8) + '(' + $src + ') alive+ancestor | commits-sau=' + $nCommits + ' | dirty=' + $nDirty + ' | closing=' + $nClosing + ' | marker=' + $last.Name + ' ts=' + $last.Ts)
if ($nCommits -eq 0 -and $nDirty -eq 0 -and $nClosing -eq 0) { Out-Line 'CLEAN' $detail }
Out-Line 'DELTA' $detail
}
finally { Pop-Location }
}
catch {
Out-Line 'DELTA' ('probe-loi: ' + $_.Exception.Message.Substring(0, [Math]::Min(80, $_.Exception.Message.Length)) + ' (lean DELTA)')
}