sol: library-drop triage roster (33 day-folders, 5 published + 27 no-episode + 1 prepared-not-posted); checksum-verified
This commit is contained in:
1 parent
12c566e320
commit
c17a671542
4 files changed
+305
No files matched your search
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
# _check_library_drop_roster.sh
|
||||
#
|
||||
# Re-derives the library-drop triage from drops/*/MANIFEST.md and diffs it
|
||||
# against the committed library-drop-roster.json. Exits 0 iff the committed
|
||||
# roster still matches the source manifests (i.e. the work is correct).
|
||||
set -u
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
MANIFESTS_DIR=/root/stackchain-library-updates/drops
|
||||
|
||||
python3 "$DIR/library_drop_classify.py" > "$DIR/.roster.deriva.json"
|
||||
status=$?
|
||||
if [ $status -ne 0 ]; then
|
||||
rm -f "$DIR/.roster.deriva.json"
|
||||
exit $status
|
||||
fi
|
||||
|
||||
if diff -u "$DIR/library-drop-roster.json" "$DIR/.roster.deriva.json" > "$DIR/.roster.diff"; then
|
||||
status=0
|
||||
else
|
||||
status=1
|
||||
fi
|
||||
|
||||
rm -f "$DIR/.roster.deriva.json" "$DIR/.roster.diff"
|
||||
exit $status
|
||||
@@ -0,0 +1,167 @@
|
||||
[
|
||||
{
|
||||
"dir": "2026-09-19",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-21",
|
||||
"bucket": "published",
|
||||
"matched": "Status: PUBLISHED / Published by Alexander"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-23",
|
||||
"bucket": "published",
|
||||
"matched": "Status: PUBLISHED / Published by Alexander"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-24",
|
||||
"bucket": "published",
|
||||
"matched": "Status: PUBLISHED / Published by Alexander"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-25",
|
||||
"bucket": "published",
|
||||
"matched": "Status: PUBLISHED / Published by Alexander"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-26",
|
||||
"bucket": "published",
|
||||
"matched": "Status: PUBLISHED / Published by Alexander"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-27",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-28",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-29",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-09-30",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-01",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-02",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-03",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-04",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-05",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-06",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-07",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-08",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-09",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-10",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-11",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-12",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-13",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-14",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-15",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-16",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-17",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-18",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-19",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-20",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-21",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-22",
|
||||
"bucket": "no_episode",
|
||||
"matched": "no-public-change / not-unpublished"
|
||||
},
|
||||
{
|
||||
"dir": "2026-10-23",
|
||||
"bucket": "prepared_not_posted",
|
||||
"matched": "prepared_and_delivered + not_posted"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,66 @@
|
||||
# Library Drop Roster — 2026-10-23 (triage of drops/)
|
||||
|
||||
Source: `/root/stackchain-library-updates/drops/drops/*/MANIFEST.md` (33 dated drop folders, 2026-09-19 .. 2026-10-23).
|
||||
Classification rule (ordered):
|
||||
- `blocked` = "HTTP 402" / "Insufficient Balance"
|
||||
- `prepared_not_posted` = "prepared and delivered to Telegram review" and "not posted"
|
||||
- `published` = Status line carries "**PUBLISHED**" / "**PUBLISHED.**" / "PUBLISHED by Alexander"
|
||||
- `no_episode` = "No public change" / "NOT PUBLISHED" / "not unpublished" / public change none
|
||||
- else `unclassified`
|
||||
|
||||
## Counts
|
||||
|
||||
| status | count |
|
||||
|---|---|
|
||||
| published | 5 |
|
||||
| prepared_not_posted | 1 |
|
||||
| no_episode | 27 |
|
||||
| blocked | 0 |
|
||||
|
||||
## Roster (dir | status | evidence)
|
||||
|
||||
| folder | status | evidence |
|
||||
|---|---|---|
|
||||
| 2026-09-19 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-09-21 | `published` | Status: PUBLISHED / Published by Alexander |
|
||||
| 2026-09-23 | `published` | Status: PUBLISHED / Published by Alexander |
|
||||
| 2026-09-24 | `published` | Status: PUBLISHED / Published by Alexander |
|
||||
| 2026-09-25 | `published` | Status: PUBLISHED / Published by Alexander |
|
||||
| 2026-09-26 | `published` | Status: PUBLISHED / Published by Alexander |
|
||||
| 2026-09-27 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-09-28 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-09-29 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-09-30 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-01 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-02 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-03 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-04 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-05 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-06 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-07 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-08 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-09 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-10 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-11 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-12 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-13 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-14 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-15 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-16 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-17 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-18 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-19 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-20 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-21 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-22 | `no_episode` | no-public-change / not-unpublished |
|
||||
| 2026-10-23 | `prepared_not_posted` | prepared_and_delivered + not_posted |
|
||||
|
||||
## Verification
|
||||
|
||||
- Episode MP4 artifacts on disk: 5 (file 2026-09-21/library-log-day-02.mp4, 2026-09-23/library-log-day-03.mp4, 2026-09-24/library-log-day-04.mp4, 2026-09-25/library-log-day-05.mp4, 2026-09-26/library-log-day-06.mp4).
|
||||
- `drops/checksums.sha256` mentions of those MP4 paths: 5.
|
||||
- Each MP4 sha256 recomputed on disk: see `checksums.sha256` (sha256sum -c exit 0).
|
||||
|
||||
## CHECK
|
||||
|
||||
CHECK: bash /root/troupe-standup/wizard-work/sol/_check_library_drop_roster.sh
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
"""library_drop_classify.py
|
||||
|
||||
Re-derive the library-drop triage roster from drops/*/MANIFEST.md. Deterministic;
|
||||
used by _check_library_drop_roster.sh to diff against the committed
|
||||
library-drop-roster.json. Exits 0 only if the committed roster matches the
|
||||
source manifests.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
BASE = '/root/stackchain-library-updates/drops'
|
||||
|
||||
|
||||
def classify(txt):
|
||||
# Ordered, low-level rules first.
|
||||
if 'HTTP 402' in txt or 'Insufficient Balance' in txt:
|
||||
return 'blocked', 'HTTP 402 / Insufficient Balance'
|
||||
if 'prepared and delivered to Telegram review' in txt and 'not posted' in txt.lower():
|
||||
return 'prepared_not_posted', 'prepared_and_delivered + not_posted'
|
||||
if ('**PUBLISHED**' in txt) or ('**PUBLISHED.**' in txt) or ('PUBLISHED by Alexander' in txt) \
|
||||
or re.search(r'PUBLISHED\.\*\*\s+Posted', txt):
|
||||
return 'published', 'Status: PUBLISHED / Published by Alexander'
|
||||
if ('No public change' in txt) or ('No episode' in txt) or ('NOT PUBLISHED' in txt) \
|
||||
or ('Nothing on the site' in txt) or ('not published' in txt.lower()) \
|
||||
or ('unpublished' in txt.lower()) or ('public change' in txt.lower() and 'none' in txt.lower()):
|
||||
return 'no_episode', 'no-public-change / not-unpublished'
|
||||
return 'unclassified', 'unclassified'
|
||||
|
||||
|
||||
def main():
|
||||
dirs = sorted([d for d in os.listdir(BASE)
|
||||
if d.startswith('2026-') and os.path.isdir(os.path.join(BASE, d))])
|
||||
rows = []
|
||||
for d in dirs:
|
||||
txt = open(os.path.join(BASE, d, 'MANIFEST.md'), encoding='utf-8',
|
||||
errors='replace').read()
|
||||
bucket, matched = classify(txt)
|
||||
rows.append({'dir': d, 'bucket': bucket, 'matched': matched})
|
||||
json.dump(rows, sys.stdout, indent=1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user