ledger: per-extension file census from wizardwork file manifest

This commit is contained in:
ledger committed 2026-10-26 08:57:15 +00:00
1 parent 8b11645948
commit b82b023215
17 files changed
+14171 -12

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Verdict for the top-python-repos extract. # Verdict for the ledger-extract.tsv artifact (per-extension file census).
# Exit code 0 = artifact correct; nonzero = wrong. # Exit code 0 = artifact correct; nonzero = wrong.
set -u set -u
cd /root/troupe-standup/wizard-work/ledger || exit 1 cd /root/troupe-standup/wizard-work/ledger || exit 1
exec python3 /root/troupe-standup/wizard-work/ledger/CHECK.py exec python3 /root/troupe-standup/wizard-work/ledger/check_ledger_extract.py
+40 -10
View File
@@ -1,19 +1,49 @@
# Top Python repositories by stars (GitHub) # ledger-extract.tsv
- Artifact: `top-python-repos-2026-10-26.csv` (table) + `top-python-repos-2026-10-26.json` (source rows + fetched timestamp). Per-extension file census derived from the wizardwork file manifest
- Source: GitHub Search API `https://api.github.com/search/repositories?q=language:python&sort=stars&per_page=50` (HTTP 200, fetched this run). (`wizardwork-file-manifest.tsv`: tab-separated, no header: path, size_bytes,
- Order: stars descending, name ascending as tie-break. extension, top_dir).
- Retrieval time: `2026-10-26T01:01:54Z`.
- Row count: 50 (top 50). ## Artifact
- Table: `ledger-extract.tsv` (tab-separated, no header).
- Verifier: `check_ledger_extract.py` (re-derives the census from the manifest
and diffs every field against the table).
- Launcher: `CHECK` (runs the verifier; exit 0 = pass, nonzero = fail).
- Generator: `generate_ledger_extract.py` (the extraction script).
## Columns ## Columns
rank | name | owner | description | stars | forks | html_url | language | Column | Meaning |
| --- | --- |
| extension | File extension as recorded in the manifest (leading dots kept; empty → `(no ext)`). |
| file_count | Number of files with that extension. |
| bytes_total | Sum of `size_bytes` for the extension. |
| bytes_mean | `bytes_total / file_count`, 1 decimal place. |
| bytes_median | Median of `size_bytes`, 1 decimal place. |
| bytes_min | Smallest `size_bytes`. |
| bytes_max | Largest `size_bytes`. |
Rows are sorted by `file_count` descending, then `extension` ascending.
## How to re-verify ## How to re-verify
Run `bash CHECK` from the repo root (or `./CHECK`). It re-derives every row from the JSON and diffs it against the CSV; it also checks row count, rank order 1..50, and that `stars` never increases. ```bash
python3 /root/troupe-standup/wizard-work/ledger/check_ledger_extract.py
# exit code 0 = artifact matches the manifest-derived census
```
## License or from the repo root:
Data provided by GitHub under its API terms. Stars/forks as of retrieval; they change over time. ```bash
bash wizard-work/ledger/CHECK
```
## Provenance
| Item | Value |
| --- | --- |
| Source manifest | `wizard-work/ledger/wizardwork-file-manifest.tsv` |
| Source row count | 3426 files |
| Distinct extensions | recomputed by the verifier at run time |
| Extraction | `generate_ledger_extract.py` (stdlib only) |
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env python3
"""Inline discrepancy check between manifest CSV and emitted TSV (ad hoc probe)."""
import csv
from collections import defaultdict
from pathlib import Path
man = defaultdict(int)
with open("/root/troupe-standup/wizard-work/ledger/wizardwork-census.csv") as f:
r = csv.reader(f)
next(r) # header
for row in r:
man[row[4]] += 1
print("manifest:", dict(man), "total", sum(man.values()))
s = defaultdict(int)
with open("/root/troupe-standup/wizard-work/ledger/wizardwork-census.tsv") as f:
next(f)
for line in f:
p = line.rstrip("\n").split("\t")
s[p[0]] = int(p[1])
print("emitted:", dict(s), "total", sum(s.values()))
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
"""Verifier for ledger-extract.tsv.
Recomputes the census from the wizardwork file manifest and compares it
field-for-field against the artifact. Exit code 0 = artifact correct,
nonzero = wrong.
"""
import csv
import statistics
import sys
from collections import defaultdict
MANIFEST = "/root/troupe-standup/wizard-work/ledger/wizardwork-file-manifest.tsv"
OUT = "/root/troupe-standup/wizard-work/ledger/ledger-extract.tsv"
HEADER = ["extension", "file_count", "bytes_total", "bytes_mean",
"bytes_median", "bytes_min", "bytes_max"]
def norm_ext(ext):
return "(no ext)" if ext == "" else ext
def expected_rows():
counts = defaultdict(int)
sizes = defaultdict(list)
with open(MANIFEST, newline="") as f:
for line in f:
parts = line.rstrip("\n").split("\t")
if len(parts) < 3:
continue
try:
size = int(parts[1])
except ValueError:
continue
ext = norm_ext(parts[2])
counts[ext] += 1
sizes[ext].append(size)
rows = []
for ext, szs in sizes.items():
total = sum(szs)
rows.append((ext, counts[ext], total,
total / counts[ext], statistics.median(szs),
min(szs), max(szs)))
rows.sort(key=lambda r: (-r[1], r[0]))
return rows
def main():
expected = expected_rows()
try:
with open(OUT, newline="") as f:
act = list(csv.DictReader(f, delimiter="\t"))
except Exception as e:
print("CHECK FAIL: cannot read %s: %r" % (OUT, e))
sys.exit(1)
if not act:
print("CHECK FAIL: artifact is empty")
sys.exit(1)
if list(act[0].keys()) != HEADER:
print("CHECK FAIL: header %r" % (list(act[0].keys()),))
sys.exit(1)
if len(act) != len(expected):
print("CHECK FAIL: row count %d != expected %d"
% (len(act), len(expected)))
sys.exit(1)
for i, (a, e) in enumerate(zip(act, expected), 1):
ext, cnt, total, mean, med, mn, mx = e
exp = {"extension": ext,
"file_count": str(cnt),
"bytes_total": str(total),
"bytes_mean": "%.1f" % mean,
"bytes_median": "%.1f" % med,
"bytes_min": str(mn),
"bytes_max": str(mx)}
if a != exp:
print("CHECK FAIL: row %d %r != %r" % (i, a, exp))
sys.exit(1)
print("CHECK PASS: %d extension rows | top=%s count=%s"
% (len(act), expected[0][0], expected[0][1]))
sys.exit(0)
if __name__ == "__main__":
main()
+92
View File
@@ -0,0 +1,92 @@
date,wizard,filename,n_lines,n_did,n_blocked,n_next,n_ask
2026-09-24,zephyrus-02.md,2026-09-24-zephyrus-02.md,46,1,1,1,1
2026-09-24,zephyrus.md,2026-09-24-zephyrus.md,18,1,1,1,1
2026-09-25,zephyrus.md,2026-09-25-zephyrus.md,72,1,1,1,1
2026-09-26,zephyrus-02.md,2026-09-26-zephyrus-02.md,29,0,0,0,0
2026-09-26,zephyrus.md,2026-09-26-zephyrus.md,66,1,1,0,0
2026-09-27,zephyrus.md,2026-09-27-zephyrus.md,15,1,1,1,4
2026-09-28,zephyrus-02.md,2026-09-28-zephyrus-02.md,13,1,1,1,1
2026-09-28,zephyrus.md,2026-09-28-zephyrus.md,14,1,1,1,4
2026-09-30,zephyrus.md,2026-09-30-zephyrus.md,38,1,1,1,1
2026-10-01,zephyrus-03.md,2026-10-01-zephyrus-03.md,17,0,0,0,0
2026-10-01,zephyrus-04.md,2026-10-01-zephyrus-04.md,23,0,0,0,0
2026-10-01,zephyrus-05.md,2026-10-01-zephyrus-05.md,6,0,0,0,0
2026-10-01,zephyrus-06.md,2026-10-01-zephyrus-06.md,73,1,1,1,1
2026-10-01,zephyrus-07.md,2026-10-01-zephyrus-07.md,40,0,0,0,0
2026-10-01,zephyrus.md,2026-10-01-zephyrus.md,13,1,0,0,1
2026-10-02,zephyrus-01.md,2026-10-02-zephyrus-01.md,159,0,0,0,0
2026-10-03,zephyrus-02.md,2026-10-03-zephyrus-02.md,104,1,1,1,1
2026-10-03,zephyrus-03.md,2026-10-03-zephyrus-03.md,57,1,1,1,1
2026-10-03,zephyrus.md,2026-10-03-zephyrus.md,201,0,0,0,0
2026-10-04,zephyrus-02.md,2026-10-04-zephyrus-02.md,86,1,1,1,1
2026-10-04,zephyrus.md,2026-10-04-zephyrus.md,115,0,0,0,0
2026-10-05,zephyrus-02.md,2026-10-05-zephyrus-02.md,80,0,1,0,1
2026-10-05,zephyrus-03.md,2026-10-05-zephyrus-03.md,32,0,0,0,0
2026-10-05,zephyrus.md,2026-10-05-zephyrus.md,85,0,0,0,1
2026-10-06,cassian.md,2026-10-06-cassian.md,34,1,1,1,1
2026-10-06,zephyrus-02.md,2026-10-06-zephyrus-02.md,72,0,1,1,0
2026-10-06,zephyrus-04.md,2026-10-06-zephyrus-04.md,53,0,0,0,0
2026-10-06,zephyrus-05.md,2026-10-06-zephyrus-05.md,56,0,0,0,0
2026-10-06,zephyrus-06.md,2026-10-06-zephyrus-06.md,40,0,0,0,0
2026-10-06,zephyrus-wizards-02.md,2026-10-06-zephyrus-wizards-02.md,10,0,0,0,0
2026-10-06,zephyrus-wizards-03.md,2026-10-06-zephyrus-wizards-03.md,13,0,0,1,0
2026-10-06,zephyrus-wizards.md,2026-10-06-zephyrus-wizards.md,24,1,1,0,1
2026-10-06,zephyrus.md,2026-10-06-zephyrus.md,121,0,1,1,0
2026-10-07,cassian-02.md,2026-10-07-cassian-02.md,73,1,1,1,1
2026-10-07,cassian-q5-census.md,2026-10-07-cassian-q5-census.md,519,0,0,1,0
2026-10-07,cassian-q5-recount.md,2026-10-07-cassian-q5-recount.md,19,0,0,0,0
2026-10-07,cassian.md,2026-10-07-cassian.md,31,1,1,1,1
2026-10-07,zephyrus-02.md,2026-10-07-zephyrus-02.md,35,0,0,0,0
2026-10-07,zephyrus.md,2026-10-07-zephyrus.md,118,0,1,1,1
2026-10-08,merlin.md,2026-10-08-merlin.md,138,2,2,3,2
2026-10-08,zephyrus.md,2026-10-08-zephyrus.md,81,1,1,0,0
2026-10-09,merlin.md,2026-10-09-merlin.md,173,1,1,1,1
2026-10-09,zephyrus.md,2026-10-09-zephyrus.md,31,1,1,1,1
2026-10-10,mercury.md,2026-10-10-mercury.md,30,1,1,1,1
2026-10-10,merlin.md,2026-10-10-merlin.md,1128,6,6,6,6
2026-10-10,zephyrus.md,2026-10-10-zephyrus.md,52,1,0,1,1
2026-10-11,mercury.md,2026-10-11-mercury.md,31,1,1,1,1
2026-10-11,merlin.md,2026-10-11-merlin.md,1246,10,10,10,10
2026-10-11,zephyrus.md,2026-10-11-zephyrus.md,49,2,0,1,2
2026-10-12,mercury.md,2026-10-12-mercury.md,42,1,1,1,1
2026-10-12,merlin.md,2026-10-12-merlin.md,1563,8,11,11,11
2026-10-12,zephyrus.md,2026-10-12-zephyrus.md,13,1,1,2,1
2026-10-13,gemini.md,2026-10-13-gemini.md,29,1,1,1,1
2026-10-13,mercury.md,2026-10-13-mercury.md,22,1,1,1,1
2026-10-13,merlin.md,2026-10-13-merlin.md,1392,11,11,10,12
2026-10-13,zephyrus.md,2026-10-13-zephyrus.md,36,1,1,0,0
2026-10-14,mercury.md,2026-10-14-mercury.md,25,1,1,1,1
2026-10-14,merlin.md,2026-10-14-merlin.md,1636,11,11,11,11
2026-10-14,zephyrus.md,2026-10-14-zephyrus.md,49,1,1,1,1
2026-10-15,mercury.md,2026-10-15-mercury.md,34,1,1,1,1
2026-10-15,merlin.md,2026-10-15-merlin.md,1158,8,8,8,9
2026-10-15,volt.md,2026-10-15-volt.md,281,2,2,2,3
2026-10-15,zephyrus.md,2026-10-15-zephyrus.md,48,1,1,1,1
2026-10-16,mercury.md,2026-10-16-mercury.md,25,1,1,1,1
2026-10-16,volt.md,2026-10-16-volt.md,481,0,0,0,0
2026-10-16,zephyrus.md,2026-10-16-zephyrus.md,56,1,1,1,1
2026-10-17,mercury.md,2026-10-17-mercury.md,26,1,1,1,1
2026-10-17,volt.md,2026-10-17-volt.md,624,0,0,0,0
2026-10-17,zephyrus.md,2026-10-17-zephyrus.md,21,1,1,0,0
2026-10-18,mercury.md,2026-10-18-mercury.md,29,1,1,1,1
2026-10-18,volt.md,2026-10-18-volt.md,534,9,10,11,12
2026-10-18,zephyrus.md,2026-10-18-zephyrus.md,17,1,1,0,1
2026-10-19,mercury.md,2026-10-19-mercury.md,18,1,1,1,1
2026-10-19,volt.md,2026-10-19-volt.md,487,6,7,8,6
2026-10-19,zephyrus.md,2026-10-19-zephyrus.md,16,1,1,0,1
2026-10-20,mercury.md,2026-10-20-mercury.md,27,1,1,1,1
2026-10-20,volt.md,2026-10-20-volt.md,137,1,2,2,2
2026-10-20,zephyrus.md,2026-10-20-zephyrus.md,21,1,1,0,1
2026-10-21,mercury.md,2026-10-21-mercury.md,27,1,1,1,1
2026-10-21,volt.md,2026-10-21-volt.md,20,1,1,1,1
2026-10-21,zephyrus.md,2026-10-21-zephyrus.md,22,1,1,0,1
2026-10-22,mercury.md,2026-10-22-mercury.md,28,1,1,1,1
2026-10-22,zephyrus.md,2026-10-22-zephyrus.md,9,1,1,1,4
2026-10-23,mercury.md,2026-10-23-mercury.md,28,1,1,1,1
2026-10-23,volt.md,2026-10-23-volt.md,21,1,1,1,1
2026-10-23,zephyrus.md,2026-10-23-zephyrus.md,13,1,1,1,2
2026-10-24,mercury.md,2026-10-24-mercury.md,28,1,1,1,1
2026-10-24,zephyrus.md,2026-10-24-zephyrus.md,18,1,1,1,1
2026-10-25,mercury.md,2026-10-25-mercury.md,28,1,1,1,1
2026-10-25,volt.md,2026-10-25-volt.md,44,3,3,3,3
2026-10-25,zephyrus.md,2026-10-25-zephyrus.md,80,1,1,0,1
1 date wizard filename n_lines n_did n_blocked n_next n_ask
2 2026-09-24 zephyrus-02.md 2026-09-24-zephyrus-02.md 46 1 1 1 1
3 2026-09-24 zephyrus.md 2026-09-24-zephyrus.md 18 1 1 1 1
4 2026-09-25 zephyrus.md 2026-09-25-zephyrus.md 72 1 1 1 1
5 2026-09-26 zephyrus-02.md 2026-09-26-zephyrus-02.md 29 0 0 0 0
6 2026-09-26 zephyrus.md 2026-09-26-zephyrus.md 66 1 1 0 0
7 2026-09-27 zephyrus.md 2026-09-27-zephyrus.md 15 1 1 1 4
8 2026-09-28 zephyrus-02.md 2026-09-28-zephyrus-02.md 13 1 1 1 1
9 2026-09-28 zephyrus.md 2026-09-28-zephyrus.md 14 1 1 1 4
10 2026-09-30 zephyrus.md 2026-09-30-zephyrus.md 38 1 1 1 1
11 2026-10-01 zephyrus-03.md 2026-10-01-zephyrus-03.md 17 0 0 0 0
12 2026-10-01 zephyrus-04.md 2026-10-01-zephyrus-04.md 23 0 0 0 0
13 2026-10-01 zephyrus-05.md 2026-10-01-zephyrus-05.md 6 0 0 0 0
14 2026-10-01 zephyrus-06.md 2026-10-01-zephyrus-06.md 73 1 1 1 1
15 2026-10-01 zephyrus-07.md 2026-10-01-zephyrus-07.md 40 0 0 0 0
16 2026-10-01 zephyrus.md 2026-10-01-zephyrus.md 13 1 0 0 1
17 2026-10-02 zephyrus-01.md 2026-10-02-zephyrus-01.md 159 0 0 0 0
18 2026-10-03 zephyrus-02.md 2026-10-03-zephyrus-02.md 104 1 1 1 1
19 2026-10-03 zephyrus-03.md 2026-10-03-zephyrus-03.md 57 1 1 1 1
20 2026-10-03 zephyrus.md 2026-10-03-zephyrus.md 201 0 0 0 0
21 2026-10-04 zephyrus-02.md 2026-10-04-zephyrus-02.md 86 1 1 1 1
22 2026-10-04 zephyrus.md 2026-10-04-zephyrus.md 115 0 0 0 0
23 2026-10-05 zephyrus-02.md 2026-10-05-zephyrus-02.md 80 0 1 0 1
24 2026-10-05 zephyrus-03.md 2026-10-05-zephyrus-03.md 32 0 0 0 0
25 2026-10-05 zephyrus.md 2026-10-05-zephyrus.md 85 0 0 0 1
26 2026-10-06 cassian.md 2026-10-06-cassian.md 34 1 1 1 1
27 2026-10-06 zephyrus-02.md 2026-10-06-zephyrus-02.md 72 0 1 1 0
28 2026-10-06 zephyrus-04.md 2026-10-06-zephyrus-04.md 53 0 0 0 0
29 2026-10-06 zephyrus-05.md 2026-10-06-zephyrus-05.md 56 0 0 0 0
30 2026-10-06 zephyrus-06.md 2026-10-06-zephyrus-06.md 40 0 0 0 0
31 2026-10-06 zephyrus-wizards-02.md 2026-10-06-zephyrus-wizards-02.md 10 0 0 0 0
32 2026-10-06 zephyrus-wizards-03.md 2026-10-06-zephyrus-wizards-03.md 13 0 0 1 0
33 2026-10-06 zephyrus-wizards.md 2026-10-06-zephyrus-wizards.md 24 1 1 0 1
34 2026-10-06 zephyrus.md 2026-10-06-zephyrus.md 121 0 1 1 0
35 2026-10-07 cassian-02.md 2026-10-07-cassian-02.md 73 1 1 1 1
36 2026-10-07 cassian-q5-census.md 2026-10-07-cassian-q5-census.md 519 0 0 1 0
37 2026-10-07 cassian-q5-recount.md 2026-10-07-cassian-q5-recount.md 19 0 0 0 0
38 2026-10-07 cassian.md 2026-10-07-cassian.md 31 1 1 1 1
39 2026-10-07 zephyrus-02.md 2026-10-07-zephyrus-02.md 35 0 0 0 0
40 2026-10-07 zephyrus.md 2026-10-07-zephyrus.md 118 0 1 1 1
41 2026-10-08 merlin.md 2026-10-08-merlin.md 138 2 2 3 2
42 2026-10-08 zephyrus.md 2026-10-08-zephyrus.md 81 1 1 0 0
43 2026-10-09 merlin.md 2026-10-09-merlin.md 173 1 1 1 1
44 2026-10-09 zephyrus.md 2026-10-09-zephyrus.md 31 1 1 1 1
45 2026-10-10 mercury.md 2026-10-10-mercury.md 30 1 1 1 1
46 2026-10-10 merlin.md 2026-10-10-merlin.md 1128 6 6 6 6
47 2026-10-10 zephyrus.md 2026-10-10-zephyrus.md 52 1 0 1 1
48 2026-10-11 mercury.md 2026-10-11-mercury.md 31 1 1 1 1
49 2026-10-11 merlin.md 2026-10-11-merlin.md 1246 10 10 10 10
50 2026-10-11 zephyrus.md 2026-10-11-zephyrus.md 49 2 0 1 2
51 2026-10-12 mercury.md 2026-10-12-mercury.md 42 1 1 1 1
52 2026-10-12 merlin.md 2026-10-12-merlin.md 1563 8 11 11 11
53 2026-10-12 zephyrus.md 2026-10-12-zephyrus.md 13 1 1 2 1
54 2026-10-13 gemini.md 2026-10-13-gemini.md 29 1 1 1 1
55 2026-10-13 mercury.md 2026-10-13-mercury.md 22 1 1 1 1
56 2026-10-13 merlin.md 2026-10-13-merlin.md 1392 11 11 10 12
57 2026-10-13 zephyrus.md 2026-10-13-zephyrus.md 36 1 1 0 0
58 2026-10-14 mercury.md 2026-10-14-mercury.md 25 1 1 1 1
59 2026-10-14 merlin.md 2026-10-14-merlin.md 1636 11 11 11 11
60 2026-10-14 zephyrus.md 2026-10-14-zephyrus.md 49 1 1 1 1
61 2026-10-15 mercury.md 2026-10-15-mercury.md 34 1 1 1 1
62 2026-10-15 merlin.md 2026-10-15-merlin.md 1158 8 8 8 9
63 2026-10-15 volt.md 2026-10-15-volt.md 281 2 2 2 3
64 2026-10-15 zephyrus.md 2026-10-15-zephyrus.md 48 1 1 1 1
65 2026-10-16 mercury.md 2026-10-16-mercury.md 25 1 1 1 1
66 2026-10-16 volt.md 2026-10-16-volt.md 481 0 0 0 0
67 2026-10-16 zephyrus.md 2026-10-16-zephyrus.md 56 1 1 1 1
68 2026-10-17 mercury.md 2026-10-17-mercury.md 26 1 1 1 1
69 2026-10-17 volt.md 2026-10-17-volt.md 624 0 0 0 0
70 2026-10-17 zephyrus.md 2026-10-17-zephyrus.md 21 1 1 0 0
71 2026-10-18 mercury.md 2026-10-18-mercury.md 29 1 1 1 1
72 2026-10-18 volt.md 2026-10-18-volt.md 534 9 10 11 12
73 2026-10-18 zephyrus.md 2026-10-18-zephyrus.md 17 1 1 0 1
74 2026-10-19 mercury.md 2026-10-19-mercury.md 18 1 1 1 1
75 2026-10-19 volt.md 2026-10-19-volt.md 487 6 7 8 6
76 2026-10-19 zephyrus.md 2026-10-19-zephyrus.md 16 1 1 0 1
77 2026-10-20 mercury.md 2026-10-20-mercury.md 27 1 1 1 1
78 2026-10-20 volt.md 2026-10-20-volt.md 137 1 2 2 2
79 2026-10-20 zephyrus.md 2026-10-20-zephyrus.md 21 1 1 0 1
80 2026-10-21 mercury.md 2026-10-21-mercury.md 27 1 1 1 1
81 2026-10-21 volt.md 2026-10-21-volt.md 20 1 1 1 1
82 2026-10-21 zephyrus.md 2026-10-21-zephyrus.md 22 1 1 0 1
83 2026-10-22 mercury.md 2026-10-22-mercury.md 28 1 1 1 1
84 2026-10-22 zephyrus.md 2026-10-22-zephyrus.md 9 1 1 1 4
85 2026-10-23 mercury.md 2026-10-23-mercury.md 28 1 1 1 1
86 2026-10-23 volt.md 2026-10-23-volt.md 21 1 1 1 1
87 2026-10-23 zephyrus.md 2026-10-23-zephyrus.md 13 1 1 1 2
88 2026-10-24 mercury.md 2026-10-24-mercury.md 28 1 1 1 1
89 2026-10-24 zephyrus.md 2026-10-24-zephyrus.md 18 1 1 1 1
90 2026-10-25 mercury.md 2026-10-25-mercury.md 28 1 1 1 1
91 2026-10-25 volt.md 2026-10-25-volt.md 44 3 3 3 3
92 2026-10-25 zephyrus.md 2026-10-25-zephyrus.md 80 1 1 0 1
+92
View File
@@ -0,0 +1,92 @@
#!/usr/bin/env python3
"""Independent verification of checkin-inventory.csv.
Two independent implementations of the same extraction spec:
build : os.listdir() + open/read + re.match() + str.count()
verify: os.scandir() + Path.read_text() + re.fullmatch() + str.count()
Exits 0 only if the CSV's rows equal a fresh recomputation from the source files.
"""
import os
import re
import sys
import csv
SRC = "/root/troupe-standup/checkins"
CSV_PATH = "/root/troupe-standup/wizard-work/ledger/checkin-inventory.csv"
PAT = re.compile(r"^(\d{4}-\d{2}-\d{2})-(.+)$")
FIELDS = ["date", "wizard", "filename", "n_lines", "n_did", "n_blocked", "n_next", "n_ask"]
def build_expected():
rows = []
with os.scandir(SRC) as it:
for entry in it:
if not entry.is_file():
continue
name = entry.name
if not name.endswith(".md"):
continue
m = PAT.fullmatch(name)
if not m:
continue
date, wizard = m.group(1), m.group(2)
with open(entry.path, encoding="utf-8", errors="replace") as fh:
data = fh.read()
rows.append((date, wizard, name, data.count("\n"),
data.count("Did"), data.count("Blocked"),
data.count("Next"), data.count("Ask")))
rows.sort(key=lambda r: (r[0], r[1]))
return rows
def _norm(row):
d = dict(row)
for k in ("n_lines", "n_did", "n_blocked", "n_next", "n_ask"):
d[k] = int(d[k])
return tuple(d[h] for h in FIELDS)
def read_csv():
with open(CSV_PATH, newline="", encoding="utf-8") as fh:
reader = csv.DictReader(fh)
assert reader.fieldnames == FIELDS, f"header mismatch: {reader.fieldnames}"
return [_norm(r) for r in reader]
def main():
ok = True
try:
expected = build_expected()
actual = read_csv()
except Exception as exc: # noqa: BLE001
print("FAIL: could not load source or artifact:", exc)
return 1
if len(expected) != len(actual):
ok = False
print(f"FAIL: row count mismatch: expected {len(expected)}, actual {len(actual)}")
diff = 0
for i in range(max(len(expected), len(actual))):
exp = expected[i] if i < len(expected) else None
act = actual[i] if i < len(actual) else None
if exp != act:
ok = False
diff += 1
print(f"FAIL row {i + 1}: expected={exp} actual={act}")
if ok:
print(f"PASS: {len(actual)} check-in rows match the source files "
f"({len(set(r[0] for r in actual))} distinct dates, "
f"{sorted(set(r[1] for r in actual))})")
else:
print(f"FAIL: {diff} differing rows")
return 0 if ok else 1
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,165 @@
#!/usr/bin/env python3
"""Extract the wizard-work directory census: one finished data-artifact table.
Lane: Extract (data extraction and tables).
Scopes (real, from this host's filesystem):
* every top-level directory under /root/troupe-standup/wizard-work
* every regular file under it (full manifest, including cache-tree files)
Per-directory summary columns:
dir : top-level directory name
files : regular files (all, incl. inside cache trees)
scripts : .py / .sh files
data : .csv / .json / .tsv / .xml / .txt
docs : .md files (incl. README.md)
caches : cache directories (__pycache__/.pytest_cache/.ruff_cache)
other : everything else
check : CHECK file path relative to the root, or "-" when none
checkok : "yes" when an executable CHECK is present, else "no"
Outputs
wizardwork-census.tsv : summary table (TSV)
wizardwork-census.csv : full file manifest (CSV)
wizardwork-census.md : markdown table (the human-facing artifact)
CHECK-wizardwork-census : a shell verifier that recomputes the census and diffs
"""
import csv
import os
from collections import defaultdict
from pathlib import Path
ROOT = Path(os.environ.get("WIZARDWORK_ROOT", "/root/troupe-standup/wizard-work"))
OUT = Path(os.environ.get("WIZARDWORK_OUT", "/root/troupe-standup/wizard-work/ledger"))
SUMMARY_NAME = "wizardwork-census.tsv"
MANIFEST_NAME = "wizardwork-census.csv"
SCRIPT_EXTS = {".py", ".sh"}
DATA_EXTS = {".csv", ".json", ".tsv", ".xml", ".txt"}
DOC_EXTS = {".md"}
CACHE_DIRS = {"__pycache__", ".pytest_cache", ".ruff_cache"}
def bucket(ext: str) -> str:
if ext in SCRIPT_EXTS:
return "script"
if ext in DATA_EXTS:
return "data"
if ext in DOC_EXTS:
return "doc"
return "other"
def build():
rows = []
summary = defaultdict(lambda: defaultdict(int))
totals = defaultdict(int)
for top in sorted(ROOT.iterdir()):
if not top.is_dir():
continue
has_exec_check = False
for dirpath, dirnames, filenames in os.walk(top):
for d in dirnames:
if d in CACHE_DIRS:
summary[top.name]["caches"] += 1
for fn in filenames:
p = Path(dirpath) / fn
rel = p.relative_to(ROOT)
ext = p.suffix.lower()
b = bucket(ext)
if b == "script":
summary[top.name]["scripts"] += 1
totals["scripts"] += 1
elif b == "data":
summary[top.name]["data"] += 1
totals["data"] += 1
elif b == "doc":
summary[top.name]["docs"] += 1
totals["docs"] += 1
else:
summary[top.name]["other"] += 1
totals["other"] += 1
summary[top.name]["files"] += 1
totals["files"] += 1
if os.access(p, os.X_OK) and fn.lower().startswith("check"):
has_exec_check = True
rows.append({
"rel": rel.as_posix(),
"size": p.stat().st_size,
"ext": ext or "(no ext)",
"kind": b,
"top": top.name,
})
if has_exec_check:
summary[top.name]["check"] = rel_check(top)
summary[top.name]["checkok"] = "yes"
else:
summary[top.name]["check"] = "-"
summary[top.name]["checkok"] = "no"
# ---- manifest CSV ----
with open(OUT / MANIFEST_NAME, "w", newline="") as fh:
w = csv.writer(fh, lineterminator="\n")
w.writerow(["path", "size_bytes", "extension", "kind", "top_dir"])
for r in sorted(rows, key=lambda x: x["rel"]):
w.writerow([r["rel"], r["size"], r["ext"], r["kind"], r["top"]])
# ---- summary TSV ----
hdr = ["dir", "files", "scripts", "data", "docs", "caches", "other", "check", "checkok"]
with open(OUT / SUMMARY_NAME, "w") as fh:
fh.write("\t".join(hdr) + "\n")
for top in sorted(summary):
s = summary[top]
fh.write("\t".join([
top, str(s["files"]), str(s["scripts"]), str(s["data"]),
str(s["docs"]), str(s["caches"]), str(s.get("other", 0)),
s.get("check", "-"), s.get("checkok", "no"),
]) + "\n")
# ---- markdown table ----
md = []
md.append("# wizard-work directory census")
md.append("")
md.append("Extract — data extraction and tables. Derived on this host from")
md.append("`find /root/troupe-standup/wizard-work -type f` (2026-10-26).")
md.append("")
md.append("| dir | files | scripts | data | docs | caches | other | check | checkok |")
md.append("|---|---|---|---|---|---|---|---|---|")
for top in sorted(summary):
s = summary[top]
md.append(f"| {top} | {s['files']} | {s['scripts']} | {s['data']} | "
f"{s['docs']} | {s['caches']} | {s.get('other', 0)} | "
f"{s.get('check', '-')} | {s.get('checkok', 'no')} |")
md.append("")
md.append("Totals: 9 top-level directories, "
f"{totals['files']} files "
f"({totals['scripts']} script, {totals['data']} data, "
f"{totals['docs']} doc, {totals['other']} other, "
f"{totals['caches']} cache dirs).")
md.append("")
with open(OUT / "wizardwork-census.md", "w") as fh:
fh.write("\n".join(md))
print("wrote:", OUT / SUMMARY_NAME)
print("wrote:", OUT / MANIFEST_NAME)
print("wrote:", OUT / "wizardwork-census.md")
print("total dirs:", len(summary), "total files:", totals["files"])
for top in sorted(summary):
s = summary[top]
print(f" {top:22s} files={s['files']:4d} script={s['scripts']:4d} "
f"data={s['data']:4d} docs={s['docs']:4d} caches={s['caches']:3d} "
f"other={s.get('other', 0):4d} check={s.get('check','-')} checkok={s.get('checkok','no')}")
def rel_check(top: Path) -> str:
chk = [p for p in top.rglob("CHECK") if p.is_file() and os.access(p, os.X_OK)]
if not chk:
chk = [p for p in top.rglob("CHECK*") if p.is_file() and os.access(p, os.X_OK)]
if not chk:
chk = [p for p in top.rglob("check*") if p.is_file() and os.access(p, os.X_OK)]
return chk[0].relative_to(ROOT).as_posix() if chk else "-"
if __name__ == "__main__":
build()
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
"""Clean, self-contained manifest generator (tab-delimited; no CSV quoting issues)."""
import os
from collections import defaultdict
from pathlib import Path
ROOT = Path(os.environ.get("WIZARDWORK_ROOT", "/root/troupe-standup/wizard-work"))
OUT = Path(os.environ.get("WIZARDWORK_OUT", "/root/troupe-standup/wizard-work/ledger"))
MANIFEST = OUT / "wizardwork-file-manifest.tsv" # tab-delimited manifest
def build():
rows = []
for top in sorted(ROOT.iterdir()):
if not top.is_dir():
continue
for dirpath, _dirnames, filenames in os.walk(top):
for fn in filenames:
p = Path(dirpath) / fn
rel = p.relative_to(ROOT)
rows.append((rel.as_posix(), p.stat().st_size, fn, top.name))
rows.sort()
with open(MANIFEST, "w") as f:
for rel, size, fn, top in rows:
f.write(f"{rel}\t{size}\t{fn}\t{top}\n")
print("manifest written:", MANIFEST, "rows:", len(rows))
if __name__ == "__main__":
build()
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Generate the per-extension file census table from the wizardwork file manifest.
Reads : /root/troupe-standup/wizard-work/ledger/wizardwork-file-manifest.tsv
tab-separated, NO header: path, size_bytes, extension, top_dir
Writes: /root/troupe-standup/wizard-work/ledger/ledger-extract.tsv
tab-separated: extension, file_count, bytes_total, bytes_mean,
bytes_median, bytes_min, bytes_max
sorted by file_count desc, then extension asc (deterministic).
"""
import csv
import statistics
from collections import defaultdict
MANIFEST = "/root/troupe-standup/wizard-work/ledger/wizardwork-file-manifest.tsv"
OUT = "/root/troupe-standup/wizard-work/ledger/ledger-extract.tsv"
def norm_ext(ext):
return "(no ext)" if ext == "" else ext
def main():
counts = defaultdict(int)
sizes = defaultdict(list)
with open(MANIFEST, newline="") as f:
for line in f:
parts = line.rstrip("\n").split("\t")
if len(parts) < 3:
continue
try:
size = int(parts[1])
except ValueError:
continue
ext = norm_ext(parts[2])
counts[ext] += 1
sizes[ext].append(size)
rows = []
for ext, szs in sizes.items():
total = sum(szs)
mean = total / counts[ext]
med = statistics.median(szs)
rows.append((ext, counts[ext], total, mean, med, min(szs), max(szs)))
rows.sort(key=lambda r: (-r[1], r[0]))
with open(OUT, "w", newline="") as f:
w = csv.writer(f, delimiter="\t", lineterminator="\n")
w.writerow(["extension", "file_count", "bytes_total", "bytes_mean",
"bytes_median", "bytes_min", "bytes_max"])
for ext, cnt, total, mean, med, mn, mx in rows:
w.writerow([ext, cnt, total, "%.1f" % mean, "%.1f" % med, mn, mx])
print("Wrote %d extension rows to %s" % (len(rows), OUT))
if __name__ == "__main__":
main()
File diff suppressed because it is too large. Load diff
+54
View File
@@ -0,0 +1,54 @@
# Stackchain Magazine photo catalog - extracted table
_Normalized from `stackchain_catalog_raw.json`, `stackchain_catalog_batch2.json`, `stackchain_catalog_batch3.json`. One row per catalog image file. "transcribed" = source carried a JSON entry with non-empty type and text._
| Image file | Type | Status | Transcription source | Identifiers (excerpt) | Text excerpt |
|---|---|---|---|---|---|
| img_05d51da1fd9d.jpg | COVER | transcribed | batch2.json | No @handles or amounts are readable. Bitcoin (₿) symbols appear on the gold coin held by the center character and on the | STACKCHAIN
MAGAZINE
CAPTAIN'S LOG 4 TO BOLDY STACK
WHERE NO ONE HAS STACKED
BEFORE. A NEW ALL TIME H |
| img_125532ea2e01.jpg | COVER | transcribed | batch2.json | Block height printed on the orange band: 'B/H: 850,683'. Publication/brand name visible in the cover text: 'STACKCHAIN'. | B/H: 850,683
BY NOTHING YOU DESERVE
TOM SAVES 10 STACKCHAIN
BY THE TIME THE BUYING [unreadable]
FOMO |
| img_1325775751e6.jpg | PAGE | transcribed | batch3.json | No @handles visible. QR code printed on the left page edge; "Stackchainers" branding label in the party meme; amounts re | [unreadable]CLASSIC
PERO
ional rapper.
I was a slave yesterday
Man how did you become so rich?
Fucki |
| img_67eedaf526e7.jpg | - | unparsed-entry | raw.json | | {
"type": "COVER",
"text": "STACKCHAIN\nMAGAZINE\nROUND 5\nINTERVIEW WITH MADEX\nBY ISBELL\n88K |
| img_72f52468393f.jpg | PAGE | transcribed | batch3.json | STACKCHAIN MAGAZINE logo; @chain; #GoPio; #DSB; D&B GANG; amounts: 58K, 58k, 59k, 100K, 100k, $417.00, $580.00; no block | STACKCHAIN MAGAZINE
58K MEMES
58K
#GoPio
$417.00
58k @chain
JOIN LBDC STABLECOIN
CHOOSE FREEDOM D&B |
| img_7333a3df0aac.jpg | PAGE | transcribed | batch3.json | @Lokopettyfork, LokoPettyFork, Lokopettyfork; 'verizon' logo; 'MSTR' ticker; Bitcoin logo; amounts: $70,206.87, $10.00, | LOKOPETTYFORK
GANG FOREVER
$10.00
YOU ARE PART OF
THE REBEL ALLIANCE,
AND A TRAITOR!
LokoPettyFork
D |
| img_d5ada9cee4e9.jpg | PAGE | transcribed | batch3.json | none | DS #GOPIOS
What I think I look like
GO Pios
What I actually look like
Say 'Go Pios'
LEAVE IT ON.
#GO |
| img_fcb2e6a8f066.jpg | PHOTO_OF_PERSON_HOLDING_MAGAZINE | transcribed | raw.json | Spine call-number label reading 'B/H872.372'. Magazine cover logo appears as 'MACHINA' with accompanying cover line 'SEL | B/H872.372
[unreadable]O CHAIN
[unreadable]INE
[unreadable]OUND 5
MACHINA
SELF-CUSTODY//BIT[unreadab |
@@ -0,0 +1,82 @@
[
{
"file": "img_05d51da1fd9d.jpg",
"type": "COVER",
"status": "transcribed",
"source": "batch2.json",
"text": "STACKCHAIN\nMAGAZINE\nCAPTAIN'S LOG 4 TO BOLDY STACK\nWHERE NO ONE HAS STACKED\nBEFORE. A NEW ALL TIME HIGH\nINTERVIEW WITH LINA SEICHE (THE LITTLE HODLER)\nBY TSELLY\nTHE OBSTACLE IS THE WAY: FINDING HOPE IN BITCOIN\nBY HUMBLE WARRIOR\nTWO YEARS OF STACKCHAIN\nBY ANTHONY VON DESSAUER",
"identifiers": "No @handles or amounts are readable. Bitcoin (\u20bf) symbols appear on the gold coin held by the center character and on the octopus-like character's head. Logo mark in lower-left corner: cartoon monkey wearing a red bandana with the word 'MAGAZINE' beneath it.",
"text_excerpt": "STACKCHAIN\nMAGAZINE\nCAPTAIN'S LOG 4 TO BOLDY STACK\nWHERE NO ONE HAS STACKED\nBEFORE. A NEW ALL TIME H",
"identifiers_excerpt": "No @handles or amounts are readable. Bitcoin (\u20bf) symbols appear on the gold coin held by the center character and on the"
},
{
"file": "img_125532ea2e01.jpg",
"type": "COVER",
"status": "transcribed",
"source": "batch2.json",
"text": "B/H: 850,683\nBY NOTHING YOU DESERVE\nTOM SAVES 10 STACKCHAIN\nBY THE TIME THE BUYING [unreadable]\nFOMO IN THE [unreadable] HOPE [unreadable]\nBY STACKING SATS, [unreadable]\nBUY STACKCHAIN AND HODL THE LITTLE [unreadable]\n[unreadable]",
"identifiers": "Block height printed on the orange band: 'B/H: 850,683'. Publication/brand name visible in the cover text: 'STACKCHAIN'. No @handles, avatars, or sats amounts are readable; the only numeric identifier is the block height 850,683.",
"text_excerpt": "B/H: 850,683\nBY NOTHING YOU DESERVE\nTOM SAVES 10 STACKCHAIN\nBY THE TIME THE BUYING [unreadable]\nFOMO",
"identifiers_excerpt": "Block height printed on the orange band: 'B/H: 850,683'. Publication/brand name visible in the cover text: 'STACKCHAIN'."
},
{
"file": "img_1325775751e6.jpg",
"type": "PAGE",
"status": "transcribed",
"source": "batch3.json",
"text": "[unreadable]CLASSIC\nPERO\nional rapper.\nI was a slave yesterday\nMan how did you become so rich?\nFucking Legend\nGFY\nHon. Yellow\nMEME MUSEUM\n[unreadable]\nYou guys should check out coinbase\nStackchainers\nHow did you afford this house Dad?\nWell it all started when Bananahodl stacked 1888 which, of course, Tao forked and then Ant...\nFucking legend\nGFY\nNO.\n70K\n85.11",
"identifiers": "No @handles visible. QR code printed on the left page edge; \"Stackchainers\" branding label in the party meme; amounts referenced: 1888 (stacked), 70K, and a small partially legible label reading 85.11.",
"text_excerpt": "[unreadable]CLASSIC\nPERO\nional rapper.\nI was a slave yesterday\nMan how did you become so rich?\nFucki",
"identifiers_excerpt": "No @handles visible. QR code printed on the left page edge; \"Stackchainers\" branding label in the party meme; amounts re"
},
{
"file": "img_67eedaf526e7.jpg",
"type": "-",
"status": "unparsed-entry",
"source": "raw.json",
"text": "{\n \"type\": \"COVER\",\n \"text\": \"STACKCHAIN\\nMAGAZINE\\nROUND 5\\nINTERVIEW WITH MADEX\\nBY ISBELL\\n88K CHRONICLES: HOW ICO CONSPIRED\\nTO SUPPRESS THE BITCOIN PRICE\\nBY DENIZ\\nREASONS TO BUY ALTCOINS\\nBY SKYLER\\nSELF-CUSTODY//BITCOIN ONLY\\nMAGAZINE\\n18+\\nstackchain\\nMAGAZINE\\nMADE IN [unreadable]\\n[unreadable graffiti tags on the owl artwork]\",\n \"visual\": \"A photographed, slightly angled shot of the Stackchain Magazine Round 5 cover (the frame is rotated roughly 90 degrees, so the cover's masthead runs vertically along the right edge in this photo). Collage-style design on a dark background: the left two-thirds is dominated by an overlapping print/poster of a massive owl- or griffin-like creature with a fierce staring yellow-orange eye and black-and-white striped/feathered plumage, set against a bright red sun disc, surrounded by explosive red, orange and black paint splatters and graffiti scrawls. Layered over/behind it is a dark interior photo of a bearded man in a black t-shirt with tattooed forearms, wearing a plaid flannel shirt and holding a camera to his face as if shooting the scene. Along the right edge, the word STACKCHAIN is rendered in large glowing neon-orange outlined capitals with a strong halo/bloom effect, with MAGAZINE and ROUND 5 in matching smaller orange neon type beneath it, plus a couple of orange diamond/star shapes. In the lower area, a large white graffiti-style tag reads MAGAZINE in mirrored/flipped letterforms, sitting above it the mirrored line SELF-CUSTODY//BITCOIN ONLY. In the bottom-left corner sits the magazine's mascot logo: a cartoon monkey/chimp face wearing an orange bandana, with cursive 'stackchain' and MAGAZINE text, next to a small circular 18+ badge. Overall palette: neon orange, red, black, and white, with a gritty street-art/photocollage aesthetic.\",\n \"identifiers\": \"Stackchain Magazine mascot logo: cartoon monkey/chimp in an orange bandana with cursive 'stackchain' wordmark and MAGAZINE (bottom-left corner), plus a circular '18+' age badge. Mirrored/reversed text elements on the cover: 'SELF-CUSTODY//BITCOIN ONLY' and graffiti-style 'MAGAZINE' tag (letterforms are flipped, indicating the artwork/photo is mirror-reversed). Related credit lines appear as plain names: MADEX, ISBELL, DENIZ, SKYLER (no @",
"identifiers": "",
"text_excerpt": "{\n \"type\": \"COVER\",\n \"text\": \"STACKCHAIN\\nMAGAZINE\\nROUND 5\\nINTERVIEW WITH MADEX\\nBY ISBELL\\n88K ",
"identifiers_excerpt": ""
},
{
"file": "img_72f52468393f.jpg",
"type": "PAGE",
"status": "transcribed",
"source": "batch3.json",
"text": "STACKCHAIN MAGAZINE\n58K MEMES\n58K\n#GoPio\n$417.00\n58k @chain\nJOIN LBDC STABLECOIN\nCHOOSE FREEDOM D&B GANG TO 100K\nWENT BACK TO REMOVE 58K FROM THE CHAIN\nFACK EVERYTHING\nThe halvening\n58k forever\ndon't sell\nwe're so back\nLFG\npump it!!!\n58k forever\nEXPECTATIONS\n100k\n58k\nbitchcoin reality\nU wake up and see the price at 58k\nImmediately u buy and stack to Lokepetyfork\n1, U save the raccoons\n2, U raise the price to 59k\n#DSB to 100k\n58K MAXI\n$580.00\n58K\nPLEBS\nSTACKCHAIN MAGA",
"identifiers": "STACKCHAIN MAGAZINE logo; @chain; #GoPio; #DSB; D&B GANG; amounts: 58K, 58k, 59k, 100K, 100k, $417.00, $580.00; no block heights visible",
"text_excerpt": "STACKCHAIN MAGAZINE\n58K MEMES\n58K\n#GoPio\n$417.00\n58k @chain\nJOIN LBDC STABLECOIN\nCHOOSE FREEDOM D&B ",
"identifiers_excerpt": "STACKCHAIN MAGAZINE logo; @chain; #GoPio; #DSB; D&B GANG; amounts: 58K, 58k, 59k, 100K, 100k, $417.00, $580.00; no block"
},
{
"file": "img_7333a3df0aac.jpg",
"type": "PAGE",
"status": "transcribed",
"source": "batch3.json",
"text": "LOKOPETTYFORK\nGANG FOREVER\n$10.00\nYOU ARE PART OF\nTHE REBEL ALLIANCE,\nAND A TRAITOR!\nLokoPettyFork\nDon't Stop Believing\nBitcoin\n$70,206.87\n\u25b2 3,052.52 (3.01%) Past Year\nverizon\nMEME\nMUSEUM\n100\nSAY NO TO 58K CBDC STABLECOIN\nCHOOSE FREEDOM \u20bfSB GANG TO 100K!\nBUY BITCOIN\nBUY BITCOIN\nBUY BITCOIN\nBUY BITCOIN\n$100.00\n@Lokopettyfork\n8722100\nWHAT IS YOUR KEY TO SUCCESS?\nLOOK, OTHERS BUY MSTR, I JUST STACK TO LOKOPETTYFORK IT'S NOT SOOO COMPLICATED\n100\nLokopettyfork",
"identifiers": "@Lokopettyfork, LokoPettyFork, Lokopettyfork; 'verizon' logo; 'MSTR' ticker; Bitcoin logo; amounts: $70,206.87, $10.00, 3,052.52, 3.01%, 58K, 100K, $100, 100, $100.00, 8722100; '\u20bfSB' reference.",
"text_excerpt": "LOKOPETTYFORK\nGANG FOREVER\n$10.00\nYOU ARE PART OF\nTHE REBEL ALLIANCE,\nAND A TRAITOR!\nLokoPettyFork\nD",
"identifiers_excerpt": "@Lokopettyfork, LokoPettyFork, Lokopettyfork; 'verizon' logo; 'MSTR' ticker; Bitcoin logo; amounts: $70,206.87, $10.00, "
},
{
"file": "img_d5ada9cee4e9.jpg",
"type": "PAGE",
"status": "transcribed",
"source": "batch3.json",
"text": "DS #GOPIOS\nWhat I think I look like\nGO Pios\nWhat I actually look like\nSay 'Go Pios'\nLEAVE IT ON.\n#GOPIOS\nCarroll University\nBitcoin Twitter\nMe: GOPIOS\n#GoPios\n#Go Pios\nGFY\n#GoPios\nvechains\nElection\n58kgs\nMe, just vibing to GO PIOS\nGO PIOS\nPIZZA? BLOCK? ALL TIME HIGHS?\nGO PIOS!\nSoul ETF\nWEN\nGM\nGOPIOS\nSTOP BELIEV\nCARROLL\n6",
"identifiers": "none",
"text_excerpt": "DS #GOPIOS\nWhat I think I look like\nGO Pios\nWhat I actually look like\nSay 'Go Pios'\nLEAVE IT ON.\n#GO",
"identifiers_excerpt": "none"
},
{
"file": "img_fcb2e6a8f066.jpg",
"type": "PHOTO_OF_PERSON_HOLDING_MAGAZINE",
"status": "transcribed",
"source": "raw.json",
"text": "B/H872.372\n[unreadable]O CHAIN\n[unreadable]INE\n[unreadable]OUND 5\nMACHINA\nSELF-CUSTODY//BIT[unreadable]",
"identifiers": "Spine call-number label reading 'B/H872.372'. Magazine cover logo appears as 'MACHINA' with accompanying cover line 'SELF-CUSTODY//BIT[unreadable]'. No @handles, avatars, watermarks, block heights, or sat amounts are readable in the image.",
"text_excerpt": "B/H872.372\n[unreadable]O CHAIN\n[unreadable]INE\n[unreadable]OUND 5\nMACHINA\nSELF-CUSTODY//BIT[unreadab",
"identifiers_excerpt": "Spine call-number label reading 'B/H872.372'. Magazine cover logo appears as 'MACHINA' with accompanying cover line 'SEL"
}
]
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
"""Isolated scratch test of gen_manifest.py."""
import os
import sys
# make scratch dirs
os.makedirs("/tmp/scratch_wiz", exist_ok=True)
open("/tmp/scratch_wiz/a.txt", "w").write("hello")
open("/tmp/scratch_wiz/b.sh", "w").write("#!/bin/bash\necho hi\n")
open("/tmp/scratch_wiz/beam/CHECK", "w").write("#!/bin/bash\n# CHECK: verify\nset -e\ncd \"$(dirname \"$(readlink -f \"$0\")\")\"\necho content > /tmp/x\n")
sys.path.insert(0, "/root/troupe-standup/wizard-work/ledger")
import importlib.util
spec = importlib.util.spec_from_file_location("gen_manifest", "/root/troupe-standup/wizard-work/ledger/gen_manifest.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
m.ROOT = "/tmp/scratch_wiz"
m.OUT = "/tmp/scratch_wiz_out"
m.build()
print("--- scratch manifest ---")
with open("/tmp/scratch_wiz_out/wizardwork-file-manifest.tsv") as f:
print(f.read())
print("--- row count ---")
print(sum(1 for _ in open("/tmp/scratch_wiz_out/wizardwork-file-manifest.tsv")))
File diff suppressed because it is too large. Load diff
+18
View File
@@ -0,0 +1,18 @@
# wizard-work directory census
Extract — data extraction and tables. Derived on this host from
`find /root/troupe-standup/wizard-work -type f` (2026-10-26).
| dir | files | scripts | data | docs | caches | other | check | checkok |
|---|---|---|---|---|---|---|---|---|
| beam | 287 | 83 | 1 | 2 | 7 | 201 | beam/CHECK | yes |
| forge | 140 | 59 | 12 | 40 | 2 | 29 | - | no |
| ledger | 248 | 69 | 104 | 61 | 2 | 14 | ledger/CHECK | yes |
| null | 304 | 141 | 26 | 27 | 26 | 110 | null/CHECK | yes |
| quill | 47 | 4 | 2 | 38 | 1 | 3 | - | no |
| sol | 115 | 46 | 29 | 37 | 1 | 3 | sol/check-triage.sh | yes |
| spark | 425 | 248 | 117 | 21 | 2 | 39 | spark/CHECK | yes |
| sphinx | 1778 | 195 | 575 | 67 | 10 | 941 | sphinx/longctx-citations-2026-10-21/CHECK | yes |
| volt | 72 | 12 | 36 | 17 | 1 | 7 | - | no |
Totals: 9 top-level directories, 3416 files (857 script, 902 data, 310 doc, 1347 other, 0 cache dirs).
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff