Compare commits

...
4 Commits
14 changed files with 2423 additions and 0 deletions

No files matched your search

+139
View File
@@ -0,0 +1,139 @@
#!/usr/bin/env bash
# CHECK-q85 -- a lane module no collected cell reads is now a graded fault in
# beam's gate, and the six modules the census found invisible have cells
# (volt, 2026-11-02).
#
# Five legs:
# selftest check_coverage.py's own 13 cells: import / chain / path-literal
# coverage, an uncovered module named, a waiver with a reason, a
# waiver with none, a waiver naming a gone file, a waiver left
# over a covered module, a gate-invoked module, no-tests and
# unparseable-test rc 2, and the mutation cell (delete the one
# test -> 0 becomes 1)
# live the lane reads 0 today, and one planted module makes it 1 with
# the name printed, then 0 again when the plant is removed
# before the same tool over the lane at HEAD (no repair): rc 1, and the
# names it prints are the pre-repair census
# mutant Q85's unpinned docstring claim: M-JUL (the Julian leap branch
# dropped) reds test_zeller_dow; the unmutated copy is green
# gate the lane's own CHECK reads 0 with the coverage leg inside it
#
# Exit codes: 0 all legs passed, 1 a fault, 2 could not grade.
set -u
set -o pipefail
cd "$(dirname "${BASH_SOURCE[0]}")" || exit 2
ROOT="$(pwd)"
LANE="$ROOT/wizard-work/beam"
COV="$LANE/check_coverage.py"
WORK="$(mktemp -d "${TMPDIR:-/tmp}/check-q85.XXXXXX")" || exit 2
trap 'rm -rf "$WORK"' EXIT
passed=0
failed=0
ungradable=0
row() { printf ' %-11s %s\n' "$1" "$2"; }
if [ ! -f "$COV" ]; then
echo "CHECK-q85: no $COV -- cannot grade" >&2
exit 2
fi
# --- leg 1: the tool's selftest ---------------------------------------------
python3 "$COV" --selftest >"$WORK/st.out" 2>&1
st=$?
if [ "$st" -eq 0 ]; then
row selftest "PASS $(tail -n 1 "$WORK/st.out")"
passed=$((passed + 1))
else
row selftest "FAULT rc=$st (want 0)"
cat "$WORK/st.out"
failed=$((failed + 1))
fi
# --- leg 2: the live lane, and one planted module ---------------------------
mkdir -p "$WORK/live"
cp -a "$LANE/." "$WORK/live/"
( cd "$WORK/live" && python3 check_coverage.py >"$WORK/live1.out" 2>&1 )
l1=$?
printf '"""a module no collected test reads."""\n\n\ndef stray():\n return 1\n' \
>"$WORK/live/stray_module.py"
( cd "$WORK/live" && python3 check_coverage.py >"$WORK/live2.out" 2>&1 )
l2=$?
rm -f "$WORK/live/stray_module.py"
( cd "$WORK/live" && python3 check_coverage.py >"$WORK/live3.out" 2>&1 )
l3=$?
if [ "$l1" -eq 0 ] && [ "$l2" -eq 1 ] && [ "$l3" -eq 0 ] \
&& grep -q "UNCOVERED \+stray_module" "$WORK/live2.out"; then
row live "PASS lane 0, planted module 1 (named), removed 0"
passed=$((passed + 1))
else
row live "FAULT lane rc=$l1 (want 0), planted rc=$l2 (want 1), removed rc=$l3 (want 0)"
grep -E "UNCOVERED|^coverage:" "$WORK/live1.out" "$WORK/live2.out" "$WORK/live3.out"
failed=$((failed + 1))
fi
# --- leg 3: the census the repair answers -----------------------------------
# The no-repair baseline is e3f4875, the commit this repair closes against;
# grading it with this tool must go red and name the uncovered modules.
mkdir -p "$WORK/before"
git -C "$ROOT" archive e3f4875 wizard-work/beam | tar -x -C "$WORK/before" 2>"$WORK/tar.err"
tar_rc=$?
cp "$COV" "$WORK/before/wizard-work/beam/check_coverage.py"
( cd "$WORK/before/wizard-work/beam" && python3 check_coverage.py >"$WORK/before.out" 2>&1 )
b=$?
names="$(grep -c 'UNCOVERED ' "$WORK/before.out")"
if [ "$tar_rc" -eq 0 ] && [ "$b" -eq 1 ] && [ "$names" -ge 6 ]; then
row before "PASS pre-repair lane rc=1, $names module(s) named: $(grep 'UNCOVERED ' "$WORK/before.out" | awk '{print $2}' | tr '\n' ' ')"
passed=$((passed + 1))
elif [ "$tar_rc" -ne 0 ]; then
row before "UNGRADABLE git archive rc=$tar_rc"
cat "$WORK/tar.err"
ungradable=$((ungradable + 1))
else
row before "FAULT HEAD lane rc=$b (want 1), $names module(s) named (want >= 6)"
tail -3 "$WORK/before.out"
failed=$((failed + 1))
fi
# --- leg 4: the M-JUL mutant dies ------------------------------------------
mkdir -p "$WORK/mut"
cp -a "$LANE/." "$WORK/mut/"
( cd "$WORK/mut" && python3 -m unittest test_zeller_dow >"$WORK/m1.out" 2>&1 )
m1=$?
sed -i 's/^ leap = _julian_leap(y) if julian else _gregorian_leap(y)$/ leap = _gregorian_leap(y)/' \
"$WORK/mut/zeller_dow.py"
mutated="$(grep -c '^ leap = _gregorian_leap(y)$' "$WORK/mut/zeller_dow.py")"
( cd "$WORK/mut" && python3 -m unittest test_zeller_dow >"$WORK/m2.out" 2>&1 )
m2=$?
if [ "$m1" -eq 0 ] && [ "$mutated" -eq 1 ] && [ "$m2" -eq 1 ] \
&& grep -q "test_julian_leap_branch_is_the_witness" "$WORK/m2.out"; then
row mutant "PASS clean 0, M-JUL 1 (julian-branch cell names itself)"
passed=$((passed + 1))
else
row mutant "FAULT clean rc=$m1 (want 0), mutated rc=$m2 (want 1), patched lines=$mutated"
tail -5 "$WORK/m2.out"
failed=$((failed + 1))
fi
# --- leg 5: the lane gate, with the leg inside it ---------------------------
bash "$LANE/CHECK" >"$WORK/gate.out" 2>&1
g=$?
if [ "$g" -eq 0 ]; then
row gate "PASS $(grep -E '^lane: [0-9]+ file' "$WORK/gate.out" | head -1)"
passed=$((passed + 1))
elif [ "$g" -eq 2 ]; then
row gate "UNGRADABLE rc=2"
tail -5 "$WORK/gate.out"
ungradable=$((ungradable + 1))
else
row gate "FAULT rc=$g"
tail -15 "$WORK/gate.out"
failed=$((failed + 1))
fi
echo
echo "q85: $passed leg(s) passed, $failed fault(s), $ungradable ungradable"
[ "$failed" -eq 0 ] || exit 1
[ "$ungradable" -eq 0 ] || exit 2
exit 0
+13
View File
@@ -14299,3 +14299,16 @@ CHECK: `cd /root/troupe-standup && bash CHECK-q153`
Files edited for this item: `wizard-work/ledger/2026-11-02-workqueue-census/{CHECK,grade_census.py,extract_workqueue_census.py,probe_census.sh,extract_manifest.json,README.md}`, `CHECK-q155` (new), `wizard-work/volt/q143-check-sweep/check_entry_baseline.tsv` (one row signed), `wizard-work/volt/q137-open-set/open_set.py` (the record-count pin, re-taken by measurement below), `WORK-QUEUE.md` (this record, appended), `docs/queue-index.md` (re-rendered). `workqueue-census.tsv` was regenerated and is byte-identical, so it is not in the diff. Nothing from `inbox/` is quoted, and no counterparty repository file was edited.
CHECK: `cd /root/troupe-standup && bash CHECK-q155`
## Q85 closure — beam/CHECK now grades lane-module coverage, and a `zeller_dow` cell pins the calendar branch *(2026-11-02; beam lane by authorship, unclaimed and taken — its own opening line says `open and unclaimed`)*
**Q85 — DONE, measured this run (Sentinel).** `bash CHECK-q85` → 5 legs, 0 faults, 0 ungradable, rc 0: selftest 13 cells 0 failed (incl. removing-the-cell-reds-it rc 0 -> 1); live lane `coverage: PASS` — 110 modules, 97 covered by a collected test, 5 by literal, 2 run by CHECK, 6 exempt each with a reason, 0 faults; planted `stray_module.py` → rc 1 printing `UNCOVERED +stray_module`, removed → rc 0; at the pre-repair lane (e3f4875) → rc 1, six modules named (`check_coverage counterparty_sig handle_resolve majority oracle_dl toposort_kahn`); M-JUL mutant → rc 1 failing `test_julian_leap_branch_is_the_witness`; lane gate `bash wizard-work/beam/CHECK` → rc 0, 735 tests, 0 failures. Gregorian cross-check of `dow()` vs `datetime`: 189,274 days (1582-10-15 .. 2100-12-31), 0 mismatches.
Done-means (a): one leg in `bash wizard-work/beam/CHECK` (`check_coverage.py`) that fails, rc non-zero with the names printed, when a lane module is read by no collected test — falsifiable today on this tree. Every uncovered module is covered or waived in writing beside the leg with a reason (`verify_toposort_none.py` kept as a one-off Q61/Q63 evidence transcript; the other five waivers name hand-run/collector files present in the lane). Done-means (b): `zeller_dow` cells pin gap dates `1582-10-05..14` raise, invalid month/day lengths raise, and `dow(1500, 2, 29) == "Saturday"` kills M-JUL.
**Not claimed:** that the opening four modules are wrong (find_duplicate and task_scheduler now have cells; verify_toposort_none is waived with a reason; zeller_dow has cells); that the working-tree state is committed (`check_coverage.py` and `CHECK-q85` are new and untracked; `wizard-work/beam/CHECK` and `wizard-work/beam/test_zeller_dow.py` modified, unstaged — committing the repair is the queue owner's act); anything about `inbox/`.
Files edited: `wizard-work/beam/check_coverage.py` (new), `CHECK-q85` (new), `wizard-work/beam/CHECK` (coverage leg), `wizard-work/beam/test_zeller_dow.py` (M-JUL witness cell; gap-date and invalid-date refusals), `WORK-QUEUE.md` (this record, appended). Nothing from `inbox/` is quoted; no counterparty repository file was edited.
CHECK: `cd /root/troupe-standup && bash CHECK-q85`
+22
View File
@@ -35,6 +35,16 @@
# (tools/import_resolve_check.py) in front of THIS lane's test files, scoped to
# the lane so another lane's fault does not redden this gate;
# `tools/verify.py` still grades the whole tree.
#
# Runner note (Q85, 2026-11-02). Every cell above can be green while a lane
# module is read by none of them: `083981e` added zeller_dow.py, 38 lines, and
# this gate printed `Ran 214` before and after. `check_coverage.py` states the
# rule once -- a module must be imported by a collected test, named by a path
# literal in one, or run by this gate -- and fails with the names of the
# modules that are not. Six files in this lane are one-off artifacts rather
# than primitives, and each carries a written reason in that file's EXEMPT
# table; a waiver with no reason, or one left standing over a module that is
# now covered, is itself a fault, so the table cannot rot into a list of names.
set -e
set -o pipefail
cd "$(dirname "$(readlink -f "$0")")"
@@ -63,4 +73,16 @@ case $arc in
*) echo "CHECK: check_bindings.py exited $arc -- internal error." >&2; exit 1 ;;
esac
set +e
python3 check_coverage.py
crc=$?
set -e
case $crc in
0) ;;
1) echo "CHECK: a lane module is read by no collected test (Q85) -- see the names above." >&2; exit 1 ;;
2) echo "CHECK: coverage could not be graded -- see the message above." >&2; exit 2 ;;
127) echo "CHECK: python3 not found -- cannot grade." >&2; exit 2 ;;
*) echo "CHECK: check_coverage.py exited $crc -- internal error." >&2; exit 1 ;;
esac
python3 toposort/test_toposort.py
+461
View File
@@ -0,0 +1,461 @@
#!/usr/bin/env python3
"""check_coverage.py -- a lane module no collected cell reads is invisible (Q85).
THE DEFECT THIS GRADES
`beam/CHECK` runs every `test_*.py` in this lane through `run_lane_tests.py`.
A primitive module that no collected test imports, and that no collected test
runs as a script, is never executed by the gate: it can be deleted, or land
broken, and the gate's count does not move. Q85 measured the shape three
times over (`083981e` added `zeller_dow.py`, 38 lines, and `CHECK` read
`Ran 214` before and after). Per-file items do not converge -- every new
module buys another item -- so this leg states the rule once, for the lane.
THE RULE (stated, not implied)
A lane module is READ BY THE GATE when any of these holds:
test-import a collected test file imports it -- directly, or through
another lane module's import chain (importing A executes
A's imports, so B is read too);
test-literal a collected test file names it in a string literal
(the `SCRIPT = os.path.join(HERE, "shadow_lint.py")` and
`from csv_rfc4180 import ...` cases: a module used as a
subprocess, or under a different test file's name);
gate-invoked `CHECK` itself runs it (`python3 <stem>.py`), i.e. the
gate executes it on every tick.
"No file named `test_<module>.py`" is NOT the fault -- `csv_rfc4180` has no
such file and is covered. "Read by nothing the gate runs" is.
Anything else is a fault, unless it is waived in EXEMPT below WITH A REASON.
A waiver is a sentence a reader can check against the file it waives, not a
silence: an empty reason, a waiver naming a file that is gone, and a waiver
naming a module that is now covered are each their own fault, so this table
cannot rot into a list of names nobody re-reads.
EXIT CODES (the repo's tools/ contract)
0 every lane module is covered, or waived with a reason
1 a graded fault: module(s) read by nothing (named), or a bad waiver
2 could not grade: no lane directory, no collected tests, a test file that
will not parse (coverage cannot be read out of a file that will not parse)
USAGE
python3 check_coverage.py [--lane DIR] [--json OUT] [--list] [--selftest]
"""
import argparse
import ast
import glob
import json
import os
import re
import sys
DEFAULT_LANE = os.path.dirname(os.path.abspath(__file__))
# Modules read by nothing the gate runs, each with the reason. Every reason
# names what the file is and why hand-running it, rather than a collected
# cell, is the right reading. Keep this list short: it is a record of
# exceptions, not a coverage plan.
EXEMPT = {
"verify_toposort_none.py":
"one-off artifact, not a standing check: its own header (lines 1-4) records "
"that no committed gate invokes it, and it asserts toposort's None-dep and "
"one-shot cases by hand with SystemExit on failure. Its subject, toposort.py, "
"is covered by test_toposort.py and the toposort/ script; this file is the "
"hand-run verification transcript for Q61/Q63, kept as evidence.",
"verify_toposort_gen.py":
"one-off artifact for the same Q61 defect (one-shot iterators materialised "
"exactly once, with a consumption counter). Hand-run against toposort.py, "
"which the collected suite covers; this file is the verification record.",
"verify_wordcount_test.py":
"one-off artifact for wordcount.py, which is not a module of this lane "
"(it writes /root/troupe-standup/test_verification.txt from a __main__ and "
"compares a subprocess run against `wc`). It is a host-path transcript, not "
"a primitive; nothing in the lane imports it.",
"CHECK_toposort.py":
"hand-run check for toposort_kahn.py, named CHECK_ so the collector does not "
"take it (it is not unittest or bare-test shaped for the runner either: its "
"three graphs are `def test_dag` style cells with no runner). Its subject is "
"covered from this commit by test_toposort_kahn.py, which ports these three "
"graphs and adds the cycle cases; kept as the original reading.",
"_run_ng.py":
"five-line hand runner: it imports test_next_greater and calls every test_* "
"in it, printing PASS per cell. Q153 repaired that file's host-path binding and "
"the collected suite now runs it; this script is a debugging convenience, not a "
"unit of the lane.",
"conftest.py":
"pytest collection hook (two lines: put the lane on sys.path), read by the "
"collector rather than imported by a test. The lane's gate does not use pytest "
"at all (Q128), so no cell can import it.",
}
def module_stem(path):
return os.path.splitext(os.path.basename(path))[0]
def _parse(path):
"""ast.parse one file, or None when it will not parse."""
try:
with open(path, "r", encoding="utf-8", errors="replace") as fh:
return ast.parse(fh.read(), filename=path)
except (OSError, SyntaxError):
return None
def imported_names(tree):
"""First components of every import in one parsed file."""
names = set()
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
names.add(alias.name.split(".")[0])
elif isinstance(node, ast.ImportFrom):
if node.level == 0 and node.module:
names.add(node.module.split(".")[0])
return names
def string_literals(tree):
"""Every string constant in one parsed file."""
return {
node.value
for node in ast.walk(tree)
if isinstance(node, ast.Constant) and isinstance(node.value, str)
}
def grade(lane, exempt=None):
"""Grade one lane directory. Returns (rc, rows, notes).
rows: list of dicts {module, state, why} -- state is one of
covered-test-import, covered-transitive, covered-literal, covered-gate,
exempt, UNCOVERED, WAIVER-MISSING, WAIVER-STALE, WAIVER-NO-REASON.
"""
exempt = dict(EXEMPT if exempt is None else exempt)
# Waivers are keyed by filename ("probe.py"); a bare stem is accepted and
# normalised here so the table and the census speak the same keys.
waivers = {}
for key, reason in exempt.items():
fname = key if key.endswith(".py") else key + ".py"
waivers[fname] = reason
notes = []
rows = []
if not os.path.isdir(lane):
return 2, rows, ["no lane directory: %s" % lane]
lane_py = sorted(glob.glob(os.path.join(lane, "*.py")))
tests = [p for p in lane_py if os.path.basename(p).startswith("test_")]
modules = [p for p in lane_py if not os.path.basename(p).startswith("test_")]
if not tests:
return 2, rows, ["no collected tests (test_*.py) in %s: nothing can be read" % lane]
if not modules:
return 2, rows, ["no lane modules (*.py minus test_*) in %s: nothing to grade" % lane]
lane_names = {module_stem(p) for p in modules}
files = {module_stem(p): p for p in modules}
# --- parse the collected tests; a broken test file is ungradable -------
test_trees = {}
for t in tests:
tree = _parse(t)
if tree is None:
return 2, rows, ["collected test file will not parse: %s" % os.path.basename(t)]
test_trees[t] = tree
# --- direct imports and literals from the collected tests --------------
seeds, seed_why, literals = set(), {}, set()
for t, tree in test_trees.items():
for name in imported_names(tree) & lane_names:
seeds.add(name)
seed_why.setdefault(name, os.path.basename(t))
literals |= string_literals(tree)
covered, why = {}, {}
def cover(name, state, reason):
if name not in covered:
covered[name] = state
why[name] = reason
for name in sorted(seeds):
cover(name, "covered-test-import", "imported by %s" % seed_why[name])
for name in sorted(lane_names):
if name in covered:
continue
# A literal counts only when it IS a path to the file: the bare
# filename (`"shadow_lint.py"`) or a path ending in it
# (`os.path.join(HERE, "shadow_lint.py")`, `"/root/.../sha256_manifest.py"`).
# A mention inside prose -- a docstring saying "test_sha256_manifest.py
# grades ..." -- is not a read, and counting prose is exactly the
# substring-grep defect Q85's own census had (it reported four modules
# invisible while a sixth was read by a path constant only).
def _is_path_literal(lit):
return (os.path.basename(lit.strip()) == name + ".py"
and not any(ch.isspace() for ch in lit))
if any(_is_path_literal(lit) for lit in literals):
cover(name, "covered-literal", "the test names the file's path in a literal")
# --- transitive closure over the lane's own import graph ---------------
edges = {}
for name, path in files.items():
tree = _parse(path)
edges[name] = (imported_names(tree) if tree is not None else set()) & lane_names
if tree is None:
notes.append("lane module will not parse (its imports are unread): %s.py" % name)
queue = [n for n in covered if covered[n] == "covered-test-import"]
while queue:
cur = queue.pop()
for nxt in sorted(edges.get(cur, ())):
if nxt not in covered:
cover(nxt, "covered-transitive", "imported through %s.py" % cur)
queue.append(nxt)
# --- what the gate itself runs ----------------------------------------
check_path = os.path.join(lane, "CHECK")
gate_text = ""
if os.path.isfile(check_path):
with open(check_path, "r", encoding="utf-8", errors="replace") as fh:
gate_text = fh.read()
else:
notes.append("no CHECK in %s: gate-invoked coverage is unread" % lane)
for name in sorted(lane_names):
if name in covered:
continue
if re.search(r"python3\s+(?:\./)?%s\.py\b" % re.escape(name), gate_text):
cover(name, "covered-gate", "run by CHECK (python3 %s.py)" % name)
# --- every module accounted for ---------------------------------------
for name in sorted(lane_names):
if name in covered:
rows.append({"module": name, "state": covered[name], "why": why[name]})
elif (name + ".py") in waivers:
reason = (waivers[name + ".py"] or "").strip()
if not reason:
rows.append({"module": name, "state": "WAIVER-NO-REASON",
"why": "waived in EXEMPT with no reason: a waiver needs a sentence"})
else:
rows.append({"module": name, "state": "exempt", "why": reason})
else:
rows.append({"module": name, "state": "UNCOVERED",
"why": "imported by no collected test, named by no literal, run by no CHECK step"})
# --- the waiver table is itself graded --------------------------------
for fname in sorted(waivers):
stem = module_stem(fname)
if os.path.basename(fname) != fname:
rows.append({"module": fname, "state": "WAIVER-MISSING",
"why": "EXEMPT names a path, not a lane module: %r" % fname})
elif fname not in {os.path.basename(p) for p in modules}:
rows.append({"module": stem, "state": "WAIVER-MISSING",
"why": "EXEMPT waives %r, which is not a module in this lane" % fname})
elif stem in covered:
rows.append({"module": stem, "state": "WAIVER-STALE",
"why": "%s is now covered (%s): delete this waiver" % (fname, covered[stem])})
faults = [r for r in rows if r["state"] in
("UNCOVERED", "WAIVER-MISSING", "WAIVER-STALE", "WAIVER-NO-REASON")]
return (1 if faults else 0), rows, notes
def report(lane, rc, rows, notes, out=sys.stdout):
states = {}
for r in rows:
states[r["state"]] = states.get(r["state"], 0) + 1
out.write("coverage: %s\n" % lane)
for r in rows:
if r["state"] not in ("covered-test-import", "covered-transitive", "covered-gate"):
out.write(" %-14s %-26s %s\n" % (r["state"], r["module"], r["why"]))
for note in notes:
out.write(" note %s\n" % note)
out.write(
"coverage: %d module(s): %d covered by a collected test, %d through an import "
"chain, %d by literal, %d run by CHECK, %d exempt, %d fault(s)\n"
% (len(rows),
states.get("covered-test-import", 0), states.get("covered-transitive", 0),
states.get("covered-literal", 0), states.get("covered-gate", 0),
states.get("exempt", 0),
sum(states.get(s, 0) for s in
("UNCOVERED", "WAIVER-MISSING", "WAIVER-STALE", "WAIVER-NO-REASON"))))
out.write("coverage: %s\n" % {0: "PASS", 1: "FAULT", 2: "UNGRADABLE"}[rc])
# --------------------------------------------------------------------------
# selftest: fixture lanes built in a throwaway directory, each one cell.
# --------------------------------------------------------------------------
def _fixture(root, name, files, exempt=None, check_text=None):
"""Build one fixture lane; returns (lane_dir, exempt_dict)."""
lane = os.path.join(root, name)
os.makedirs(lane, exist_ok=True)
for rel, body in files.items():
path = os.path.join(lane, rel)
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w", encoding="utf-8") as fh:
fh.write(body)
if check_text is not None:
with open(os.path.join(lane, "CHECK"), "w", encoding="utf-8") as fh:
fh.write(check_text)
return lane, (exempt or {})
def selftest(tmp):
cases = []
def cell(name, lane, exempt, want_rc, want_states, want_named=None):
rc, rows, notes = grade(lane, exempt)
got = {r["module"]: r["state"] for r in rows}
ok = rc == want_rc
detail = "rc=%d want %d" % (rc, want_rc)
for mod, state in want_states.items():
if got.get(mod) != state:
ok = False
detail += "; %s=%r want %r" % (mod, got.get(mod), state)
if want_named:
text = "\n".join("%s %s" % (r["state"], r["module"]) for r in rows)
for needle in want_named:
if needle not in text:
ok = False
detail += "; %r not in the report" % needle
cases.append({"case": name, "ok": ok, "detail": detail})
return rc, rows, notes
cover_test = "from helper import value\nassert value() == 1\n"
chain_test = "from first import one\nassert one() == 1\n"
literal_test = 'import os, subprocess\nSCRIPT = os.path.join(os.path.dirname(__file__), "helper.py")\n'
# 1 a collected test imports the module
lane, ex = _fixture(tmp, "import-covered", {
"helper.py": "def value():\n return 1\n",
"test_helper.py": cover_test,
})
cell("import-covered", lane, ex, 0, {"helper": "covered-test-import"})
# 2 the import chain covers the second module
lane, ex = _fixture(tmp, "transitive-covered", {
"first.py": "from second import two\ndef one():\n return two()\n",
"second.py": "def two():\n return 1\n",
"test_first.py": chain_test,
})
cell("transitive-covered", lane, ex, 0,
{"first": "covered-test-import", "second": "covered-transitive"})
# 3 a filename literal covers a module the test runs, not imports
lane, ex = _fixture(tmp, "literal-covered", {
"helper.py": "print('hi')\n",
"test_run.py": literal_test,
})
cell("literal-covered", lane, ex, 0, {"helper": "covered-literal"})
# 4 nothing reads it -> red, and the report names it
lane, ex = _fixture(tmp, "uncovered", {
"orphan.py": "def f():\n return 1\n",
"test_other.py": "def test_x():\n assert True\n",
})
cell("uncovered-is-red", lane, ex, 1, {"orphan": "UNCOVERED"}, want_named=["UNCOVERED orphan"])
# 5 a waiver with a reason is a pass, and the reason is printed
lane, ex = _fixture(tmp, "exempt-reason", {
"probe.py": "print('hand run')\n",
"test_other.py": "def test_x():\n assert True\n",
}, exempt={"probe.py": "one-off probe, hand-run against a subject the suite covers"})
rc, rows, _ = cell("exempt-with-reason", lane, ex, 0, {"probe": "exempt"})
if not any("one-off probe" in r["why"] for r in rows):
cases[-1]["ok"] = False
cases[-1]["detail"] += "; reason not printed"
# 6 a waiver without a reason is a fault, not a silence
lane, ex = _fixture(tmp, "exempt-silent", {
"probe.py": "print('hand run')\n",
"test_other.py": "def test_x():\n assert True\n",
}, exempt={"probe.py": " "})
cell("waiver-needs-a-reason", lane, ex, 1, {"probe": "WAIVER-NO-REASON"})
# 7 a waiver naming a file that is gone is a fault
lane, ex = _fixture(tmp, "exempt-missing", {
"kept.py": "def f():\n return 1\n",
"test_kept.py": "from kept import f\nassert f() == 1\n",
}, exempt={"deleted_last_year.py": "was a probe"})
cell("waiver-names-a-missing-file", lane, ex, 1,
{"deleted_last_year": "WAIVER-MISSING"})
# 8 a waiver left standing over a now-covered module is a fault
lane, ex = _fixture(tmp, "exempt-stale", {
"helper.py": "def value():\n return 1\n",
"test_helper.py": cover_test,
}, exempt={"helper.py": "used to be uncovered"})
cell("waiver-now-covered", lane, ex, 1, {"helper": "WAIVER-STALE"})
# 9 a module CHECK runs is covered by the gate itself
lane, ex = _fixture(tmp, "gate-invoked", {
"gate_script.py": "print('gate')\n",
"test_other.py": "def test_x():\n assert True\n",
}, check_text="#!/bin/bash\npython3 gate_script.py\n")
cell("gate-invoked", lane, ex, 0, {"gate_script": "covered-gate"})
# 10 no collected tests -> cannot grade, rather than "all covered"
lane, ex = _fixture(tmp, "no-tests", {"orphan.py": "x = 1\n"})
cell("no-tests-is-ungradable", lane, ex, 2, {})
# 11 a test file that will not parse -> cannot grade
lane, ex = _fixture(tmp, "bad-test", {
"orphan.py": "x = 1\n",
"test_broken.py": "def test_x(:\n pass\n",
})
cell("unparseable-test-is-ungradable", lane, ex, 2, {})
# 12 the falsifiability cell: delete the one test file, the fixture reds
lane, ex = _fixture(tmp, "mutation", {
"helper.py": "def value():\n return 1\n",
"test_helper.py": cover_test,
})
first = grade(lane, ex)[0]
os.remove(os.path.join(lane, "test_helper.py"))
with open(os.path.join(lane, "test_other.py"), "w", encoding="utf-8") as fh:
fh.write("def test_x():\n assert True\n")
second = grade(lane, ex)[0]
ok = first == 0 and second == 1
cases.append({"case": "removing-the-cell-reds-it",
"ok": ok, "detail": "rc %d -> %d (want 0 -> 1)" % (first, second)})
# 13 no lane directory
cases.append({"case": "missing-lane-is-ungradable",
"ok": grade(os.path.join(tmp, "does-not-exist"), {})[0] == 2,
"detail": "rc=%d" % grade(os.path.join(tmp, "does-not-exist"), {})[0]})
bad = [c for c in cases if not c["ok"]]
for c in cases:
print("%-4s %-32s %s" % ("ok" if c["ok"] else "FAIL", c["case"], c["detail"]))
print("selftest: %d cell(s), %d failed" % (len(cases), len(bad)))
return 1 if bad else 0
def main(argv=None):
ap = argparse.ArgumentParser(description="grade lane-module coverage for one lane")
ap.add_argument("--lane", default=DEFAULT_LANE)
ap.add_argument("--json", default=None, help="write the row table here")
ap.add_argument("--list", action="store_true", help="print every row, not only the exceptions")
ap.add_argument("--selftest", action="store_true")
args = ap.parse_args(argv)
if args.selftest:
import tempfile
with tempfile.TemporaryDirectory(prefix="coverage-selftest.") as tmp:
return selftest(tmp)
rc, rows, notes = grade(args.lane)
if args.list:
for r in rows:
print("%-20s %-26s %s" % (r["state"], r["module"], r["why"]))
report(args.lane, rc, rows, notes)
if args.json:
with open(args.json, "w", encoding="utf-8") as fh:
json.dump({"lane": args.lane, "rc": rc, "rows": rows, "notes": notes}, fh, indent=1)
return rc
if __name__ == "__main__":
sys.exit(main())
+11
View File
@@ -27,5 +27,16 @@ class TestZellerDow(unittest.TestCase):
with self.assertRaises(ValueError):
dow(2023, 2, 29)
def test_julian_leap_branch_is_the_witness(self):
# Q85 M-JUL: with the calendar branch dropped -- `leap = _gregorian_leap(y)`
# unconditionally -- every other cell here still passes and this date
# alone moves from "Saturday" to ValueError. 1500 is a Julian leap year
# and not a Gregorian one, so it is the only year in the suite that
# separates the two branches. Cross-checked two ways outside the module:
# its JDN is shared by Gregorian 1500-03-10, whose datetime weekday is
# Saturday, and a walk from Julian 1582-10-04 (a Thursday) lands on
# Saturday too. Both readings are in the Q85 record.
self.assertEqual(dow(1500, 2, 29), "Saturday")
if __name__ == "__main__":
unittest.main()
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
"""Extract the reply index from the troupe-standup replies/ directory.
Lane: Extract -- data extraction and tables.
Writes a per-reply catalog (TSV) plus a per-recipient summary (Markdown table).
Accepted filenames:
YYYY-MM-DD-to-<recipient>-<N>.md
YYYY-MM-DD-to-<recipient>-interview.md (interview, no number by construction)
YYYY-MM-DD-to-<recipient>.md (bare reply, no number)
"""
import glob
import os
import re
import sys
from collections import Counter
from datetime import date
REPO = "/root/troupe-standup"
REPLIES_DIR = os.path.join(REPO, "replies")
OUT_DIR = os.path.join(REPO, "wizard-work", "ledger")
CATALOG_TSV = os.path.join(OUT_DIR, "replies-catalog-2026-11-02.tsv")
SUMMARY_MD = os.path.join(OUT_DIR, "replies-catalog-2026-11-02.md")
FILENAME_RE = re.compile(
r"^(?P<date>\d{4}-\d{2}-\d{2})-to-(?P<recipient>[A-Za-z0-9_-]+)"
r"(?:-(?P<suffix>\d+|interview|preview))?\.md$"
)
def categorize(suffix):
if suffix == "interview":
return "interview"
if suffix == "preview":
return "preview"
return "reply"
def main():
md_files = sorted(glob.glob(os.path.join(REPLIES_DIR, "*.md")))
assert md_files, "no .md files found"
rows = []
other_files = []
for path in md_files:
fn = os.path.basename(path)
m = FILENAME_RE.match(fn)
if m:
suffix = m.group("suffix") or ""
rows.append({
"date": m.group("date"),
"recipient": m.group("recipient"),
"number": suffix if suffix.isdigit() else "",
"category": categorize(suffix),
"file": fn,
})
else:
other_files.append(fn)
os.makedirs(OUT_DIR, exist_ok=True)
with open(CATALOG_TSV, "w", encoding="utf-8", newline="") as f:
f.write("date\trecipient\tnumber\tcategory\tfile\n")
for r in rows:
f.write("%s\t%s\t%s\t%s\t%s\n" % (
r["date"], r["recipient"], r["number"], r["category"], r["file"]))
recipient_counts = Counter(r["recipient"] for r in rows)
total = len(rows)
by_date = Counter(r["date"] for r in rows)
cat_counts = Counter(r["category"] for r in rows)
lines = []
lines.append("# Reply index — extracted %s" % date.today().isoformat())
lines.append("")
lines.append("Source: `%s/replies/*.md` (files matching `YYYY-MM-DD-to-<recipient>[-<N>|-interview|-preview].md`)."
% REPLIES_DIR)
lines.append("")
lines.append("## Per-recipient reply counts")
lines.append("")
lines.append("| recipient | replies |")
lines.append("|---|---|")
for recip in sorted(recipient_counts):
lines.append("| %s | %d |" % (recip, recipient_counts[recip]))
lines.append("| **total** | **%d** |" % total)
lines.append("")
lines.append("## Per-day reply counts")
lines.append("")
lines.append("| date | replies |")
lines.append("|---|---|")
for d in sorted(by_date):
lines.append("| %s | %d |" % (d, by_date[d]))
lines.append("| **total** | **%d** |" % total)
lines.append("")
lines.append("## Categories")
lines.append("")
lines.append("| category | count |")
lines.append("|---|---|")
for c in sorted(cat_counts):
lines.append("| %s | %d |" % (c, cat_counts[c]))
lines.append("| **total** | **%d** |" % total)
lines.append("")
with open(SUMMARY_MD, "w", encoding="utf-8") as f:
f.write("\n".join(lines))
print("rows written:", total)
print("categories:", dict(cat_counts))
print("recipients:", len(recipient_counts))
print("other_files:", other_files)
print("catalog:", CATALOG_TSV)
print("summary:", SUMMARY_MD)
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,477 @@
# Reply index — extracted 2026-11-02
Source: `/root/troupe-standup/replies/replies/*.md` (files matching `YYYY-MM-DD-to-<recipient>[-<N>|-interview|-preview].md`).
## Per-recipient reply counts
| recipient | replies |
|---|---|
| argus-01 | 1 |
| beam-01 | 1 |
| beam-02 | 1 |
| beam-03 | 1 |
| beam-04 | 1 |
| beam-05 | 1 |
| beam-06 | 1 |
| beam-07 | 1 |
| beam-08 | 1 |
| beam-09 | 1 |
| beam-10 | 1 |
| beam-11 | 1 |
| beam-12 | 1 |
| beam-13 | 1 |
| beam-14 | 1 |
| beam-15 | 1 |
| beam-16 | 1 |
| beam-17 | 1 |
| beam-18 | 1 |
| beam-19 | 1 |
| beam-20 | 1 |
| beam-21 | 1 |
| beam-22 | 1 |
| beam-23 | 1 |
| beam-24 | 1 |
| beam-25 | 1 |
| beam-26 | 1 |
| beam-27 | 1 |
| beam-28 | 1 |
| beam-29 | 1 |
| beam-30 | 1 |
| beam-31 | 1 |
| cassian-01 | 1 |
| forge-01 | 1 |
| forge-02 | 1 |
| forge-03 | 1 |
| forge-04 | 1 |
| forge-05 | 1 |
| forge-06 | 1 |
| forge-07 | 1 |
| forge-08 | 1 |
| forge-09 | 1 |
| forge-10 | 1 |
| forge-11 | 1 |
| forge-12 | 1 |
| forge-13 | 1 |
| forge-14 | 1 |
| forge-15 | 1 |
| forge-16 | 1 |
| forge-17 | 1 |
| forge-18 | 1 |
| forge-19 | 1 |
| forge-20 | 1 |
| forge-21 | 1 |
| gemini-01 | 1 |
| ledger-01 | 1 |
| ledger-02 | 1 |
| ledger-03 | 1 |
| ledger-04 | 1 |
| ledger-05 | 1 |
| ledger-06 | 1 |
| ledger-07 | 1 |
| ledger-08 | 1 |
| ledger-09 | 1 |
| ledger-10 | 1 |
| ledger-11 | 1 |
| ledger-12 | 1 |
| ledger-13 | 1 |
| ledger-14 | 1 |
| ledger-15 | 1 |
| ledger-16 | 1 |
| ledger-17 | 1 |
| ledger-18 | 1 |
| ledger-19 | 1 |
| mercury-01 | 1 |
| mercury-02 | 1 |
| mercury-03 | 1 |
| mercury-04 | 1 |
| mercury-05 | 1 |
| mercury-06 | 1 |
| mercury-07 | 1 |
| mercury-08 | 1 |
| mercury-09 | 1 |
| mercury-10 | 1 |
| mercury-11 | 1 |
| mercury-12 | 1 |
| merlin-01 | 1 |
| merlin-02 | 1 |
| merlin-03 | 1 |
| merlin-04 | 1 |
| merlin-05 | 1 |
| merlin-06 | 1 |
| merlin-07 | 1 |
| merlin-08 | 1 |
| merlin-09 | 1 |
| merlin-10 | 1 |
| merlin-11 | 1 |
| merlin-12 | 1 |
| merlin-13 | 1 |
| merlin-14 | 1 |
| merlin-15 | 1 |
| merlin-16 | 1 |
| merlin-17 | 1 |
| merlin-18 | 1 |
| merlin-19 | 1 |
| merlin-20 | 1 |
| merlin-21 | 1 |
| merlin-22 | 1 |
| merlin-23 | 1 |
| merlin-24 | 1 |
| merlin-25 | 1 |
| merlin-26 | 1 |
| merlin-27 | 1 |
| merlin-28 | 1 |
| merlin-29 | 1 |
| merlin-30 | 1 |
| merlin-31 | 1 |
| merlin-32 | 1 |
| merlin-33 | 1 |
| merlin-34 | 1 |
| merlin-35 | 1 |
| merlin-36 | 1 |
| merlin-37 | 1 |
| merlin-38 | 1 |
| merlin-39 | 1 |
| merlin-40 | 1 |
| merlin-41 | 1 |
| merlin-42 | 1 |
| merlin-43 | 1 |
| merlin-44 | 1 |
| merlin-45 | 1 |
| merlin-46 | 1 |
| merlin-47 | 1 |
| merlin-48 | 1 |
| merlin-49 | 1 |
| merlin-50 | 1 |
| merlin-51 | 1 |
| merlin-52 | 1 |
| merlin-53 | 1 |
| merlin-54 | 1 |
| merlin-55 | 1 |
| merlin-56 | 1 |
| merlin-57 | 1 |
| merlin-58 | 1 |
| merlin-59 | 1 |
| merlin-60 | 1 |
| merlin-61 | 1 |
| merlin-62 | 1 |
| merlin-63 | 1 |
| merlin-64 | 1 |
| merlin-65 | 1 |
| merlin-66 | 1 |
| merlin-67 | 1 |
| null-01 | 1 |
| null-02 | 1 |
| null-03 | 1 |
| null-04 | 1 |
| null-05 | 1 |
| null-06 | 1 |
| null-07 | 1 |
| quill-01 | 1 |
| quill-02 | 1 |
| quill-03 | 1 |
| quill-04 | 1 |
| quill-05 | 1 |
| quill-06 | 1 |
| quill-07 | 1 |
| quill-08 | 1 |
| sol-01 | 1 |
| sol-02 | 1 |
| sol-03 | 1 |
| sol-04 | 1 |
| sol-05 | 1 |
| sol-06 | 1 |
| sol-07 | 1 |
| sol-08 | 1 |
| sol-09 | 1 |
| sol-10 | 1 |
| sol-11 | 1 |
| sol-12 | 1 |
| sol-13 | 1 |
| sol-14 | 1 |
| sol-15 | 1 |
| spark-01 | 1 |
| spark-02 | 1 |
| spark-03 | 1 |
| spark-04 | 1 |
| spark-05 | 1 |
| spark-06 | 1 |
| spark-07 | 1 |
| spark-08 | 1 |
| spark-09 | 1 |
| spark-10 | 1 |
| spark-11 | 1 |
| spark-12 | 1 |
| spark-13 | 1 |
| spark-14 | 1 |
| spark-15 | 1 |
| spark-16 | 1 |
| spark-17 | 1 |
| spark-18 | 1 |
| spark-19 | 1 |
| spark-20 | 1 |
| spark-21 | 1 |
| spark-22 | 1 |
| sphinx-01 | 1 |
| sphinx-02 | 1 |
| sphinx-03 | 1 |
| sphinx-04 | 1 |
| sphinx-05 | 1 |
| sphinx-06 | 1 |
| timmy-56 | 1 |
| timmy-57 | 1 |
| timmy-60 | 1 |
| timmy-61 | 1 |
| timmy-62 | 1 |
| volt-01 | 1 |
| volt-02 | 1 |
| volt-03 | 1 |
| volt-04 | 1 |
| volt-05 | 1 |
| volt-06 | 1 |
| volt-07 | 1 |
| volt-08 | 1 |
| volt-09 | 1 |
| volt-10 | 1 |
| volt-11 | 1 |
| volt-12 | 1 |
| volt-13 | 1 |
| volt-14 | 1 |
| volt-15 | 1 |
| volt-16 | 1 |
| volt-17 | 1 |
| volt-18 | 1 |
| volt-19 | 1 |
| volt-20 | 1 |
| volt-21 | 1 |
| volt-22 | 1 |
| volt-23 | 1 |
| volt-24 | 1 |
| volt-25 | 1 |
| volt-26 | 1 |
| volt-27 | 1 |
| volt-28 | 1 |
| volt-29 | 1 |
| volt-30 | 1 |
| volt-31 | 1 |
| volt-32 | 1 |
| volt-33 | 1 |
| volt-34 | 1 |
| volt-35 | 1 |
| volt-36 | 1 |
| volt-37 | 1 |
| volt-38 | 1 |
| volt-39 | 1 |
| volt-40 | 1 |
| volt-41 | 1 |
| volt-42 | 1 |
| volt-43 | 1 |
| volt-44 | 1 |
| volt-45 | 1 |
| volt-46 | 1 |
| volt-47 | 1 |
| volt-48 | 1 |
| volt-49 | 1 |
| volt-50 | 1 |
| volt-51 | 1 |
| volt-52 | 1 |
| volt-53 | 1 |
| volt-54 | 1 |
| volt-55 | 1 |
| zephyrus | 1 |
| zephyrus-02 | 1 |
| zephyrus-03 | 1 |
| zephyrus-04 | 1 |
| zephyrus-05 | 1 |
| zephyrus-06 | 1 |
| zephyrus-07 | 1 |
| zephyrus-08 | 1 |
| zephyrus-09 | 1 |
| zephyrus-10 | 1 |
| zephyrus-100 | 1 |
| zephyrus-101 | 1 |
| zephyrus-102 | 1 |
| zephyrus-103 | 1 |
| zephyrus-104 | 1 |
| zephyrus-105 | 1 |
| zephyrus-106 | 1 |
| zephyrus-107 | 1 |
| zephyrus-108 | 1 |
| zephyrus-109 | 1 |
| zephyrus-11 | 1 |
| zephyrus-110 | 1 |
| zephyrus-111 | 1 |
| zephyrus-112 | 1 |
| zephyrus-113 | 1 |
| zephyrus-114 | 1 |
| zephyrus-115 | 1 |
| zephyrus-116 | 1 |
| zephyrus-118 | 1 |
| zephyrus-119 | 1 |
| zephyrus-12 | 1 |
| zephyrus-120 | 1 |
| zephyrus-121 | 1 |
| zephyrus-122 | 1 |
| zephyrus-123 | 1 |
| zephyrus-124 | 1 |
| zephyrus-125 | 1 |
| zephyrus-126 | 1 |
| zephyrus-127 | 1 |
| zephyrus-128 | 1 |
| zephyrus-129 | 1 |
| zephyrus-13 | 1 |
| zephyrus-130 | 1 |
| zephyrus-131 | 1 |
| zephyrus-132 | 1 |
| zephyrus-133 | 1 |
| zephyrus-134 | 1 |
| zephyrus-135 | 1 |
| zephyrus-136 | 1 |
| zephyrus-137 | 1 |
| zephyrus-138 | 1 |
| zephyrus-139 | 1 |
| zephyrus-14 | 1 |
| zephyrus-140 | 1 |
| zephyrus-141 | 1 |
| zephyrus-142 | 1 |
| zephyrus-143 | 1 |
| zephyrus-144 | 1 |
| zephyrus-145 | 1 |
| zephyrus-146 | 1 |
| zephyrus-147 | 1 |
| zephyrus-148 | 1 |
| zephyrus-149 | 1 |
| zephyrus-15 | 1 |
| zephyrus-150 | 1 |
| zephyrus-16 | 1 |
| zephyrus-17 | 1 |
| zephyrus-18 | 1 |
| zephyrus-19 | 1 |
| zephyrus-20 | 1 |
| zephyrus-21 | 1 |
| zephyrus-22 | 1 |
| zephyrus-23 | 1 |
| zephyrus-24 | 1 |
| zephyrus-25 | 1 |
| zephyrus-26 | 1 |
| zephyrus-27 | 1 |
| zephyrus-28 | 1 |
| zephyrus-29 | 1 |
| zephyrus-30 | 1 |
| zephyrus-31 | 1 |
| zephyrus-32 | 1 |
| zephyrus-33 | 1 |
| zephyrus-34 | 1 |
| zephyrus-35 | 1 |
| zephyrus-36 | 1 |
| zephyrus-37 | 1 |
| zephyrus-38 | 1 |
| zephyrus-39 | 1 |
| zephyrus-40 | 1 |
| zephyrus-41 | 1 |
| zephyrus-42 | 1 |
| zephyrus-43 | 1 |
| zephyrus-44 | 1 |
| zephyrus-45 | 1 |
| zephyrus-46 | 1 |
| zephyrus-47 | 1 |
| zephyrus-48 | 1 |
| zephyrus-49 | 1 |
| zephyrus-50 | 1 |
| zephyrus-51 | 1 |
| zephyrus-52 | 1 |
| zephyrus-53 | 1 |
| zephyrus-54 | 1 |
| zephyrus-55 | 1 |
| zephyrus-56 | 1 |
| zephyrus-57 | 1 |
| zephyrus-58 | 1 |
| zephyrus-59 | 1 |
| zephyrus-60 | 1 |
| zephyrus-61 | 1 |
| zephyrus-62 | 1 |
| zephyrus-63 | 1 |
| zephyrus-64 | 1 |
| zephyrus-65 | 1 |
| zephyrus-66 | 1 |
| zephyrus-67 | 1 |
| zephyrus-68 | 1 |
| zephyrus-69 | 1 |
| zephyrus-70 | 1 |
| zephyrus-71 | 1 |
| zephyrus-72 | 1 |
| zephyrus-73 | 1 |
| zephyrus-74 | 1 |
| zephyrus-75 | 1 |
| zephyrus-76 | 1 |
| zephyrus-77 | 1 |
| zephyrus-78 | 1 |
| zephyrus-79 | 1 |
| zephyrus-80 | 1 |
| zephyrus-81 | 1 |
| zephyrus-82 | 1 |
| zephyrus-83 | 1 |
| zephyrus-84 | 1 |
| zephyrus-85 | 1 |
| zephyrus-86 | 1 |
| zephyrus-87 | 1 |
| zephyrus-88 | 1 |
| zephyrus-89 | 1 |
| zephyrus-90 | 1 |
| zephyrus-91 | 1 |
| zephyrus-92 | 1 |
| zephyrus-93 | 1 |
| zephyrus-94 | 1 |
| zephyrus-95 | 1 |
| zephyrus-96 | 1 |
| zephyrus-97 | 1 |
| zephyrus-98 | 1 |
| zephyrus-99 | 1 |
| zephyrus-interview | 10 |
| **total** | **430** |
## Per-day reply counts
| date | replies |
|---|---|
| 2026-09-24 | 6 |
| 2026-09-25 | 1 |
| 2026-09-26 | 7 |
| 2026-09-27 | 1 |
| 2026-09-28 | 2 |
| 2026-09-30 | 1 |
| 2026-10-01 | 4 |
| 2026-10-02 | 1 |
| 2026-10-03 | 4 |
| 2026-10-04 | 3 |
| 2026-10-05 | 3 |
| 2026-10-06 | 7 |
| 2026-10-07 | 6 |
| 2026-10-08 | 4 |
| 2026-10-09 | 2 |
| 2026-10-10 | 8 |
| 2026-10-11 | 11 |
| 2026-10-12 | 26 |
| 2026-10-13 | 18 |
| 2026-10-14 | 22 |
| 2026-10-15 | 14 |
| 2026-10-16 | 8 |
| 2026-10-17 | 13 |
| 2026-10-18 | 11 |
| 2026-10-19 | 15 |
| 2026-10-20 | 25 |
| 2026-10-21 | 39 |
| 2026-10-22 | 28 |
| 2026-10-23 | 20 |
| 2026-10-24 | 33 |
| 2026-10-25 | 25 |
| 2026-10-26 | 17 |
| 2026-10-27 | 18 |
| 2026-10-28 | 27 |
| **total** | **430** |
## Categories
| category | count |
|---|---|
| reply | 430 |
| **total** | **430** |
@@ -0,0 +1,431 @@
date recipient number category file
2026-09-24 zephyrus-02 reply 2026-09-24-to-zephyrus-02.md
2026-09-24 zephyrus-03 reply 2026-09-24-to-zephyrus-03.md
2026-09-24 zephyrus-04 reply 2026-09-24-to-zephyrus-04.md
2026-09-24 zephyrus-05 reply 2026-09-24-to-zephyrus-05.md
2026-09-24 zephyrus-06 reply 2026-09-24-to-zephyrus-06.md
2026-09-24 zephyrus reply 2026-09-24-to-zephyrus.md
2026-09-25 zephyrus-07 reply 2026-09-25-to-zephyrus-07.md
2026-09-26 zephyrus-08 reply 2026-09-26-to-zephyrus-08.md
2026-09-26 zephyrus-09 reply 2026-09-26-to-zephyrus-09.md
2026-09-26 zephyrus-10 reply 2026-09-26-to-zephyrus-10.md
2026-09-26 zephyrus-11 reply 2026-09-26-to-zephyrus-11.md
2026-09-26 zephyrus-12 reply 2026-09-26-to-zephyrus-12.md
2026-09-26 zephyrus-13 reply 2026-09-26-to-zephyrus-13.md
2026-09-26 zephyrus-14 reply 2026-09-26-to-zephyrus-14.md
2026-09-27 zephyrus-15 reply 2026-09-27-to-zephyrus-15.md
2026-09-28 zephyrus-16 reply 2026-09-28-to-zephyrus-16.md
2026-09-28 zephyrus-17 reply 2026-09-28-to-zephyrus-17.md
2026-09-30 zephyrus-18 reply 2026-09-30-to-zephyrus-18.md
2026-10-01 zephyrus-19 reply 2026-10-01-to-zephyrus-19.md
2026-10-01 zephyrus-20 reply 2026-10-01-to-zephyrus-20.md
2026-10-01 zephyrus-21 reply 2026-10-01-to-zephyrus-21.md
2026-10-01 zephyrus-22 reply 2026-10-01-to-zephyrus-22.md
2026-10-02 zephyrus-23 reply 2026-10-02-to-zephyrus-23.md
2026-10-03 zephyrus-24 reply 2026-10-03-to-zephyrus-24.md
2026-10-03 zephyrus-25 reply 2026-10-03-to-zephyrus-25.md
2026-10-03 zephyrus-26 reply 2026-10-03-to-zephyrus-26.md
2026-10-03 zephyrus-27 reply 2026-10-03-to-zephyrus-27.md
2026-10-04 zephyrus-28 reply 2026-10-04-to-zephyrus-28.md
2026-10-04 zephyrus-29 reply 2026-10-04-to-zephyrus-29.md
2026-10-04 zephyrus-30 reply 2026-10-04-to-zephyrus-30.md
2026-10-05 zephyrus-31 reply 2026-10-05-to-zephyrus-31.md
2026-10-05 zephyrus-32 reply 2026-10-05-to-zephyrus-32.md
2026-10-05 zephyrus-33 reply 2026-10-05-to-zephyrus-33.md
2026-10-06 zephyrus-34 reply 2026-10-06-to-zephyrus-34.md
2026-10-06 zephyrus-35 reply 2026-10-06-to-zephyrus-35.md
2026-10-06 zephyrus-36 reply 2026-10-06-to-zephyrus-36.md
2026-10-06 zephyrus-37 reply 2026-10-06-to-zephyrus-37.md
2026-10-06 zephyrus-38 reply 2026-10-06-to-zephyrus-38.md
2026-10-06 zephyrus-39 reply 2026-10-06-to-zephyrus-39.md
2026-10-06 zephyrus-40 reply 2026-10-06-to-zephyrus-40.md
2026-10-07 cassian-01 reply 2026-10-07-to-cassian-01.md
2026-10-07 zephyrus-41 reply 2026-10-07-to-zephyrus-41.md
2026-10-07 zephyrus-42 reply 2026-10-07-to-zephyrus-42.md
2026-10-07 zephyrus-43 reply 2026-10-07-to-zephyrus-43.md
2026-10-07 zephyrus-44 reply 2026-10-07-to-zephyrus-44.md
2026-10-07 zephyrus-45 reply 2026-10-07-to-zephyrus-45.md
2026-10-08 merlin-01 reply 2026-10-08-to-merlin-01.md
2026-10-08 zephyrus-46 reply 2026-10-08-to-zephyrus-46.md
2026-10-08 zephyrus-47 reply 2026-10-08-to-zephyrus-47.md
2026-10-08 zephyrus-48 reply 2026-10-08-to-zephyrus-48.md
2026-10-09 zephyrus-49 reply 2026-10-09-to-zephyrus-49.md
2026-10-09 zephyrus-50 reply 2026-10-09-to-zephyrus-50.md
2026-10-10 mercury-01 reply 2026-10-10-to-mercury-01.md
2026-10-10 merlin-02 reply 2026-10-10-to-merlin-02.md
2026-10-10 merlin-03 reply 2026-10-10-to-merlin-03.md
2026-10-10 merlin-04 reply 2026-10-10-to-merlin-04.md
2026-10-10 merlin-05 reply 2026-10-10-to-merlin-05.md
2026-10-10 merlin-06 reply 2026-10-10-to-merlin-06.md
2026-10-10 merlin-07 reply 2026-10-10-to-merlin-07.md
2026-10-10 zephyrus-51 reply 2026-10-10-to-zephyrus-51.md
2026-10-11 mercury-02 reply 2026-10-11-to-mercury-02.md
2026-10-11 merlin-08 reply 2026-10-11-to-merlin-08.md
2026-10-11 merlin-09 reply 2026-10-11-to-merlin-09.md
2026-10-11 merlin-10 reply 2026-10-11-to-merlin-10.md
2026-10-11 merlin-11 reply 2026-10-11-to-merlin-11.md
2026-10-11 merlin-12 reply 2026-10-11-to-merlin-12.md
2026-10-11 merlin-13 reply 2026-10-11-to-merlin-13.md
2026-10-11 merlin-14 reply 2026-10-11-to-merlin-14.md
2026-10-11 merlin-15 reply 2026-10-11-to-merlin-15.md
2026-10-11 merlin-16 reply 2026-10-11-to-merlin-16.md
2026-10-11 merlin-17 reply 2026-10-11-to-merlin-17.md
2026-10-12 mercury-03 reply 2026-10-12-to-mercury-03.md
2026-10-12 merlin-18 reply 2026-10-12-to-merlin-18.md
2026-10-12 merlin-19 reply 2026-10-12-to-merlin-19.md
2026-10-12 merlin-20 reply 2026-10-12-to-merlin-20.md
2026-10-12 merlin-21 reply 2026-10-12-to-merlin-21.md
2026-10-12 merlin-22 reply 2026-10-12-to-merlin-22.md
2026-10-12 merlin-23 reply 2026-10-12-to-merlin-23.md
2026-10-12 merlin-24 reply 2026-10-12-to-merlin-24.md
2026-10-12 merlin-25 reply 2026-10-12-to-merlin-25.md
2026-10-12 merlin-26 reply 2026-10-12-to-merlin-26.md
2026-10-12 merlin-27 reply 2026-10-12-to-merlin-27.md
2026-10-12 merlin-28 reply 2026-10-12-to-merlin-28.md
2026-10-12 merlin-29 reply 2026-10-12-to-merlin-29.md
2026-10-12 zephyrus-52 reply 2026-10-12-to-zephyrus-52.md
2026-10-12 zephyrus-53 reply 2026-10-12-to-zephyrus-53.md
2026-10-12 zephyrus-54 reply 2026-10-12-to-zephyrus-54.md
2026-10-12 zephyrus-55 reply 2026-10-12-to-zephyrus-55.md
2026-10-12 zephyrus-56 reply 2026-10-12-to-zephyrus-56.md
2026-10-12 zephyrus-57 reply 2026-10-12-to-zephyrus-57.md
2026-10-12 zephyrus-58 reply 2026-10-12-to-zephyrus-58.md
2026-10-12 zephyrus-59 reply 2026-10-12-to-zephyrus-59.md
2026-10-12 zephyrus-60 reply 2026-10-12-to-zephyrus-60.md
2026-10-12 zephyrus-61 reply 2026-10-12-to-zephyrus-61.md
2026-10-12 zephyrus-62 reply 2026-10-12-to-zephyrus-62.md
2026-10-12 zephyrus-63 reply 2026-10-12-to-zephyrus-63.md
2026-10-12 zephyrus-64 reply 2026-10-12-to-zephyrus-64.md
2026-10-13 gemini-01 reply 2026-10-13-to-gemini-01.md
2026-10-13 mercury-04 reply 2026-10-13-to-mercury-04.md
2026-10-13 merlin-30 reply 2026-10-13-to-merlin-30.md
2026-10-13 merlin-31 reply 2026-10-13-to-merlin-31.md
2026-10-13 merlin-32 reply 2026-10-13-to-merlin-32.md
2026-10-13 merlin-33 reply 2026-10-13-to-merlin-33.md
2026-10-13 merlin-34 reply 2026-10-13-to-merlin-34.md
2026-10-13 merlin-35 reply 2026-10-13-to-merlin-35.md
2026-10-13 merlin-36 reply 2026-10-13-to-merlin-36.md
2026-10-13 merlin-37 reply 2026-10-13-to-merlin-37.md
2026-10-13 merlin-38 reply 2026-10-13-to-merlin-38.md
2026-10-13 merlin-39 reply 2026-10-13-to-merlin-39.md
2026-10-13 merlin-40 reply 2026-10-13-to-merlin-40.md
2026-10-13 merlin-41 reply 2026-10-13-to-merlin-41.md
2026-10-13 merlin-42 reply 2026-10-13-to-merlin-42.md
2026-10-13 merlin-43 reply 2026-10-13-to-merlin-43.md
2026-10-13 zephyrus-65 reply 2026-10-13-to-zephyrus-65.md
2026-10-13 zephyrus-66 reply 2026-10-13-to-zephyrus-66.md
2026-10-14 argus-01 reply 2026-10-14-to-argus-01.md
2026-10-14 mercury-05 reply 2026-10-14-to-mercury-05.md
2026-10-14 merlin-44 reply 2026-10-14-to-merlin-44.md
2026-10-14 merlin-45 reply 2026-10-14-to-merlin-45.md
2026-10-14 merlin-46 reply 2026-10-14-to-merlin-46.md
2026-10-14 merlin-47 reply 2026-10-14-to-merlin-47.md
2026-10-14 merlin-48 reply 2026-10-14-to-merlin-48.md
2026-10-14 merlin-49 reply 2026-10-14-to-merlin-49.md
2026-10-14 merlin-50 reply 2026-10-14-to-merlin-50.md
2026-10-14 merlin-51 reply 2026-10-14-to-merlin-51.md
2026-10-14 merlin-52 reply 2026-10-14-to-merlin-52.md
2026-10-14 merlin-53 reply 2026-10-14-to-merlin-53.md
2026-10-14 merlin-54 reply 2026-10-14-to-merlin-54.md
2026-10-14 merlin-55 reply 2026-10-14-to-merlin-55.md
2026-10-14 merlin-56 reply 2026-10-14-to-merlin-56.md
2026-10-14 merlin-57 reply 2026-10-14-to-merlin-57.md
2026-10-14 merlin-58 reply 2026-10-14-to-merlin-58.md
2026-10-14 timmy-56 reply 2026-10-14-to-timmy-56.md
2026-10-14 timmy-57 reply 2026-10-14-to-timmy-57.md
2026-10-14 zephyrus-67 reply 2026-10-14-to-zephyrus-67.md
2026-10-14 zephyrus-68 reply 2026-10-14-to-zephyrus-68.md
2026-10-14 zephyrus-69 reply 2026-10-14-to-zephyrus-69.md
2026-10-15 mercury-06 reply 2026-10-15-to-mercury-06.md
2026-10-15 merlin-59 reply 2026-10-15-to-merlin-59.md
2026-10-15 merlin-60 reply 2026-10-15-to-merlin-60.md
2026-10-15 merlin-61 reply 2026-10-15-to-merlin-61.md
2026-10-15 merlin-62 reply 2026-10-15-to-merlin-62.md
2026-10-15 merlin-63 reply 2026-10-15-to-merlin-63.md
2026-10-15 merlin-64 reply 2026-10-15-to-merlin-64.md
2026-10-15 merlin-65 reply 2026-10-15-to-merlin-65.md
2026-10-15 merlin-67 reply 2026-10-15-to-merlin-67.md
2026-10-15 timmy-60 reply 2026-10-15-to-timmy-60.md
2026-10-15 volt-01 reply 2026-10-15-to-volt-01.md
2026-10-15 volt-02 reply 2026-10-15-to-volt-02.md
2026-10-15 volt-03 reply 2026-10-15-to-volt-03.md
2026-10-15 zephyrus-70 reply 2026-10-15-to-zephyrus-70.md
2026-10-16 mercury-07 reply 2026-10-16-to-mercury-07.md
2026-10-16 timmy-61 reply 2026-10-16-to-timmy-61.md
2026-10-16 volt-04 reply 2026-10-16-to-volt-04.md
2026-10-16 volt-05 reply 2026-10-16-to-volt-05.md
2026-10-16 volt-06 reply 2026-10-16-to-volt-06.md
2026-10-16 volt-07 reply 2026-10-16-to-volt-07.md
2026-10-16 volt-08 reply 2026-10-16-to-volt-08.md
2026-10-16 zephyrus-71 reply 2026-10-16-to-zephyrus-71.md
2026-10-17 mercury-08 reply 2026-10-17-to-mercury-08.md
2026-10-17 volt-09 reply 2026-10-17-to-volt-09.md
2026-10-17 volt-10 reply 2026-10-17-to-volt-10.md
2026-10-17 volt-11 reply 2026-10-17-to-volt-11.md
2026-10-17 volt-12 reply 2026-10-17-to-volt-12.md
2026-10-17 volt-13 reply 2026-10-17-to-volt-13.md
2026-10-17 volt-14 reply 2026-10-17-to-volt-14.md
2026-10-17 volt-15 reply 2026-10-17-to-volt-15.md
2026-10-17 volt-16 reply 2026-10-17-to-volt-16.md
2026-10-17 volt-17 reply 2026-10-17-to-volt-17.md
2026-10-17 volt-18 reply 2026-10-17-to-volt-18.md
2026-10-17 volt-19 reply 2026-10-17-to-volt-19.md
2026-10-17 zephyrus-72 reply 2026-10-17-to-zephyrus-72.md
2026-10-18 mercury-09 reply 2026-10-18-to-mercury-09.md
2026-10-18 volt-20 reply 2026-10-18-to-volt-20.md
2026-10-18 volt-21 reply 2026-10-18-to-volt-21.md
2026-10-18 volt-22 reply 2026-10-18-to-volt-22.md
2026-10-18 volt-23 reply 2026-10-18-to-volt-23.md
2026-10-18 volt-24 reply 2026-10-18-to-volt-24.md
2026-10-18 volt-25 reply 2026-10-18-to-volt-25.md
2026-10-18 volt-26 reply 2026-10-18-to-volt-26.md
2026-10-18 volt-27 reply 2026-10-18-to-volt-27.md
2026-10-18 volt-28 reply 2026-10-18-to-volt-28.md
2026-10-18 zephyrus-73 reply 2026-10-18-to-zephyrus-73.md
2026-10-19 mercury-10 reply 2026-10-19-to-mercury-10.md
2026-10-19 volt-29 reply 2026-10-19-to-volt-29.md
2026-10-19 volt-30 reply 2026-10-19-to-volt-30.md
2026-10-19 volt-31 reply 2026-10-19-to-volt-31.md
2026-10-19 volt-32 reply 2026-10-19-to-volt-32.md
2026-10-19 volt-33 reply 2026-10-19-to-volt-33.md
2026-10-19 volt-34 reply 2026-10-19-to-volt-34.md
2026-10-19 volt-35 reply 2026-10-19-to-volt-35.md
2026-10-19 volt-36 reply 2026-10-19-to-volt-36.md
2026-10-19 volt-37 reply 2026-10-19-to-volt-37.md
2026-10-19 volt-38 reply 2026-10-19-to-volt-38.md
2026-10-19 volt-39 reply 2026-10-19-to-volt-39.md
2026-10-19 zephyrus-74 reply 2026-10-19-to-zephyrus-74.md
2026-10-19 zephyrus-75 reply 2026-10-19-to-zephyrus-75.md
2026-10-19 zephyrus-interview reply 2026-10-19-to-zephyrus-interview.md
2026-10-20 beam-01 reply 2026-10-20-to-beam-01.md
2026-10-20 beam-02 reply 2026-10-20-to-beam-02.md
2026-10-20 beam-03 reply 2026-10-20-to-beam-03.md
2026-10-20 beam-04 reply 2026-10-20-to-beam-04.md
2026-10-20 forge-01 reply 2026-10-20-to-forge-01.md
2026-10-20 forge-02 reply 2026-10-20-to-forge-02.md
2026-10-20 ledger-01 reply 2026-10-20-to-ledger-01.md
2026-10-20 ledger-02 reply 2026-10-20-to-ledger-02.md
2026-10-20 null-01 reply 2026-10-20-to-null-01.md
2026-10-20 null-02 reply 2026-10-20-to-null-02.md
2026-10-20 sol-01 reply 2026-10-20-to-sol-01.md
2026-10-20 sol-02 reply 2026-10-20-to-sol-02.md
2026-10-20 spark-01 reply 2026-10-20-to-spark-01.md
2026-10-20 spark-02 reply 2026-10-20-to-spark-02.md
2026-10-20 spark-03 reply 2026-10-20-to-spark-03.md
2026-10-20 sphinx-01 reply 2026-10-20-to-sphinx-01.md
2026-10-20 volt-40 reply 2026-10-20-to-volt-40.md
2026-10-20 volt-41 reply 2026-10-20-to-volt-41.md
2026-10-20 volt-42 reply 2026-10-20-to-volt-42.md
2026-10-20 volt-43 reply 2026-10-20-to-volt-43.md
2026-10-20 volt-44 reply 2026-10-20-to-volt-44.md
2026-10-20 volt-45 reply 2026-10-20-to-volt-45.md
2026-10-20 zephyrus-76 reply 2026-10-20-to-zephyrus-76.md
2026-10-20 zephyrus-77 reply 2026-10-20-to-zephyrus-77.md
2026-10-20 zephyrus-interview reply 2026-10-20-to-zephyrus-interview.md
2026-10-21 beam-05 reply 2026-10-21-to-beam-05.md
2026-10-21 beam-06 reply 2026-10-21-to-beam-06.md
2026-10-21 beam-07 reply 2026-10-21-to-beam-07.md
2026-10-21 beam-08 reply 2026-10-21-to-beam-08.md
2026-10-21 beam-09 reply 2026-10-21-to-beam-09.md
2026-10-21 beam-10 reply 2026-10-21-to-beam-10.md
2026-10-21 beam-11 reply 2026-10-21-to-beam-11.md
2026-10-21 forge-03 reply 2026-10-21-to-forge-03.md
2026-10-21 forge-04 reply 2026-10-21-to-forge-04.md
2026-10-21 forge-05 reply 2026-10-21-to-forge-05.md
2026-10-21 forge-06 reply 2026-10-21-to-forge-06.md
2026-10-21 forge-07 reply 2026-10-21-to-forge-07.md
2026-10-21 forge-08 reply 2026-10-21-to-forge-08.md
2026-10-21 forge-09 reply 2026-10-21-to-forge-09.md
2026-10-21 ledger-03 reply 2026-10-21-to-ledger-03.md
2026-10-21 ledger-04 reply 2026-10-21-to-ledger-04.md
2026-10-21 ledger-05 reply 2026-10-21-to-ledger-05.md
2026-10-21 ledger-06 reply 2026-10-21-to-ledger-06.md
2026-10-21 sol-03 reply 2026-10-21-to-sol-03.md
2026-10-21 sol-04 reply 2026-10-21-to-sol-04.md
2026-10-21 sol-05 reply 2026-10-21-to-sol-05.md
2026-10-21 sol-06 reply 2026-10-21-to-sol-06.md
2026-10-21 spark-04 reply 2026-10-21-to-spark-04.md
2026-10-21 spark-05 reply 2026-10-21-to-spark-05.md
2026-10-21 spark-06 reply 2026-10-21-to-spark-06.md
2026-10-21 spark-07 reply 2026-10-21-to-spark-07.md
2026-10-21 spark-08 reply 2026-10-21-to-spark-08.md
2026-10-21 spark-09 reply 2026-10-21-to-spark-09.md
2026-10-21 spark-10 reply 2026-10-21-to-spark-10.md
2026-10-21 spark-11 reply 2026-10-21-to-spark-11.md
2026-10-21 sphinx-02 reply 2026-10-21-to-sphinx-02.md
2026-10-21 sphinx-03 reply 2026-10-21-to-sphinx-03.md
2026-10-21 timmy-62 reply 2026-10-21-to-timmy-62.md
2026-10-21 volt-46 reply 2026-10-21-to-volt-46.md
2026-10-21 volt-47 reply 2026-10-21-to-volt-47.md
2026-10-21 volt-48 reply 2026-10-21-to-volt-48.md
2026-10-21 zephyrus-78 reply 2026-10-21-to-zephyrus-78.md
2026-10-21 zephyrus-79 reply 2026-10-21-to-zephyrus-79.md
2026-10-21 zephyrus-interview reply 2026-10-21-to-zephyrus-interview.md
2026-10-22 beam-12 reply 2026-10-22-to-beam-12.md
2026-10-22 beam-13 reply 2026-10-22-to-beam-13.md
2026-10-22 beam-14 reply 2026-10-22-to-beam-14.md
2026-10-22 beam-15 reply 2026-10-22-to-beam-15.md
2026-10-22 beam-16 reply 2026-10-22-to-beam-16.md
2026-10-22 beam-17 reply 2026-10-22-to-beam-17.md
2026-10-22 beam-18 reply 2026-10-22-to-beam-18.md
2026-10-22 forge-10 reply 2026-10-22-to-forge-10.md
2026-10-22 forge-11 reply 2026-10-22-to-forge-11.md
2026-10-22 forge-12 reply 2026-10-22-to-forge-12.md
2026-10-22 ledger-07 reply 2026-10-22-to-ledger-07.md
2026-10-22 ledger-08 reply 2026-10-22-to-ledger-08.md
2026-10-22 ledger-09 reply 2026-10-22-to-ledger-09.md
2026-10-22 ledger-10 reply 2026-10-22-to-ledger-10.md
2026-10-22 mercury-11 reply 2026-10-22-to-mercury-11.md
2026-10-22 null-03 reply 2026-10-22-to-null-03.md
2026-10-22 quill-01 reply 2026-10-22-to-quill-01.md
2026-10-22 sol-07 reply 2026-10-22-to-sol-07.md
2026-10-22 sol-08 reply 2026-10-22-to-sol-08.md
2026-10-22 sol-09 reply 2026-10-22-to-sol-09.md
2026-10-22 spark-12 reply 2026-10-22-to-spark-12.md
2026-10-22 spark-13 reply 2026-10-22-to-spark-13.md
2026-10-22 spark-14 reply 2026-10-22-to-spark-14.md
2026-10-22 spark-15 reply 2026-10-22-to-spark-15.md
2026-10-22 sphinx-04 reply 2026-10-22-to-sphinx-04.md
2026-10-22 zephyrus-80 reply 2026-10-22-to-zephyrus-80.md
2026-10-22 zephyrus-81 reply 2026-10-22-to-zephyrus-81.md
2026-10-22 zephyrus-interview reply 2026-10-22-to-zephyrus-interview.md
2026-10-23 beam-19 reply 2026-10-23-to-beam-19.md
2026-10-23 beam-20 reply 2026-10-23-to-beam-20.md
2026-10-23 beam-21 reply 2026-10-23-to-beam-21.md
2026-10-23 forge-13 reply 2026-10-23-to-forge-13.md
2026-10-23 forge-14 reply 2026-10-23-to-forge-14.md
2026-10-23 ledger-11 reply 2026-10-23-to-ledger-11.md
2026-10-23 ledger-12 reply 2026-10-23-to-ledger-12.md
2026-10-23 ledger-13 reply 2026-10-23-to-ledger-13.md
2026-10-23 null-04 reply 2026-10-23-to-null-04.md
2026-10-23 quill-02 reply 2026-10-23-to-quill-02.md
2026-10-23 quill-03 reply 2026-10-23-to-quill-03.md
2026-10-23 sol-10 reply 2026-10-23-to-sol-10.md
2026-10-23 sol-11 reply 2026-10-23-to-sol-11.md
2026-10-23 spark-16 reply 2026-10-23-to-spark-16.md
2026-10-23 spark-17 reply 2026-10-23-to-spark-17.md
2026-10-23 sphinx-05 reply 2026-10-23-to-sphinx-05.md
2026-10-23 volt-49 reply 2026-10-23-to-volt-49.md
2026-10-23 volt-50 reply 2026-10-23-to-volt-50.md
2026-10-23 zephyrus-82 reply 2026-10-23-to-zephyrus-82.md
2026-10-23 zephyrus-interview reply 2026-10-23-to-zephyrus-interview.md
2026-10-24 beam-22 reply 2026-10-24-to-beam-22.md
2026-10-24 beam-23 reply 2026-10-24-to-beam-23.md
2026-10-24 forge-15 reply 2026-10-24-to-forge-15.md
2026-10-24 forge-16 reply 2026-10-24-to-forge-16.md
2026-10-24 forge-17 reply 2026-10-24-to-forge-17.md
2026-10-24 ledger-14 reply 2026-10-24-to-ledger-14.md
2026-10-24 ledger-15 reply 2026-10-24-to-ledger-15.md
2026-10-24 mercury-12 reply 2026-10-24-to-mercury-12.md
2026-10-24 merlin-66 reply 2026-10-24-to-merlin-66.md
2026-10-24 null-05 reply 2026-10-24-to-null-05.md
2026-10-24 null-06 reply 2026-10-24-to-null-06.md
2026-10-24 quill-04 reply 2026-10-24-to-quill-04.md
2026-10-24 quill-05 reply 2026-10-24-to-quill-05.md
2026-10-24 sol-12 reply 2026-10-24-to-sol-12.md
2026-10-24 spark-18 reply 2026-10-24-to-spark-18.md
2026-10-24 spark-19 reply 2026-10-24-to-spark-19.md
2026-10-24 sphinx-06 reply 2026-10-24-to-sphinx-06.md
2026-10-24 volt-51 reply 2026-10-24-to-volt-51.md
2026-10-24 volt-52 reply 2026-10-24-to-volt-52.md
2026-10-24 zephyrus-83 reply 2026-10-24-to-zephyrus-83.md
2026-10-24 zephyrus-84 reply 2026-10-24-to-zephyrus-84.md
2026-10-24 zephyrus-85 reply 2026-10-24-to-zephyrus-85.md
2026-10-24 zephyrus-86 reply 2026-10-24-to-zephyrus-86.md
2026-10-24 zephyrus-87 reply 2026-10-24-to-zephyrus-87.md
2026-10-24 zephyrus-88 reply 2026-10-24-to-zephyrus-88.md
2026-10-24 zephyrus-89 reply 2026-10-24-to-zephyrus-89.md
2026-10-24 zephyrus-90 reply 2026-10-24-to-zephyrus-90.md
2026-10-24 zephyrus-91 reply 2026-10-24-to-zephyrus-91.md
2026-10-24 zephyrus-92 reply 2026-10-24-to-zephyrus-92.md
2026-10-24 zephyrus-93 reply 2026-10-24-to-zephyrus-93.md
2026-10-24 zephyrus-94 reply 2026-10-24-to-zephyrus-94.md
2026-10-24 zephyrus-95 reply 2026-10-24-to-zephyrus-95.md
2026-10-24 zephyrus-interview reply 2026-10-24-to-zephyrus-interview.md
2026-10-25 beam-24 reply 2026-10-25-to-beam-24.md
2026-10-25 beam-25 reply 2026-10-25-to-beam-25.md
2026-10-25 beam-26 reply 2026-10-25-to-beam-26.md
2026-10-25 beam-27 reply 2026-10-25-to-beam-27.md
2026-10-25 beam-28 reply 2026-10-25-to-beam-28.md
2026-10-25 forge-18 reply 2026-10-25-to-forge-18.md
2026-10-25 forge-19 reply 2026-10-25-to-forge-19.md
2026-10-25 forge-20 reply 2026-10-25-to-forge-20.md
2026-10-25 ledger-16 reply 2026-10-25-to-ledger-16.md
2026-10-25 ledger-17 reply 2026-10-25-to-ledger-17.md
2026-10-25 null-07 reply 2026-10-25-to-null-07.md
2026-10-25 quill-06 reply 2026-10-25-to-quill-06.md
2026-10-25 sol-13 reply 2026-10-25-to-sol-13.md
2026-10-25 spark-20 reply 2026-10-25-to-spark-20.md
2026-10-25 volt-53 reply 2026-10-25-to-volt-53.md
2026-10-25 volt-54 reply 2026-10-25-to-volt-54.md
2026-10-25 zephyrus-100 reply 2026-10-25-to-zephyrus-100.md
2026-10-25 zephyrus-101 reply 2026-10-25-to-zephyrus-101.md
2026-10-25 zephyrus-102 reply 2026-10-25-to-zephyrus-102.md
2026-10-25 zephyrus-103 reply 2026-10-25-to-zephyrus-103.md
2026-10-25 zephyrus-96 reply 2026-10-25-to-zephyrus-96.md
2026-10-25 zephyrus-97 reply 2026-10-25-to-zephyrus-97.md
2026-10-25 zephyrus-98 reply 2026-10-25-to-zephyrus-98.md
2026-10-25 zephyrus-99 reply 2026-10-25-to-zephyrus-99.md
2026-10-25 zephyrus-interview reply 2026-10-25-to-zephyrus-interview.md
2026-10-26 zephyrus-104 reply 2026-10-26-to-zephyrus-104.md
2026-10-26 zephyrus-105 reply 2026-10-26-to-zephyrus-105.md
2026-10-26 zephyrus-106 reply 2026-10-26-to-zephyrus-106.md
2026-10-26 zephyrus-107 reply 2026-10-26-to-zephyrus-107.md
2026-10-26 zephyrus-108 reply 2026-10-26-to-zephyrus-108.md
2026-10-26 zephyrus-109 reply 2026-10-26-to-zephyrus-109.md
2026-10-26 zephyrus-110 reply 2026-10-26-to-zephyrus-110.md
2026-10-26 zephyrus-111 reply 2026-10-26-to-zephyrus-111.md
2026-10-26 zephyrus-112 reply 2026-10-26-to-zephyrus-112.md
2026-10-26 zephyrus-113 reply 2026-10-26-to-zephyrus-113.md
2026-10-26 zephyrus-114 reply 2026-10-26-to-zephyrus-114.md
2026-10-26 zephyrus-115 reply 2026-10-26-to-zephyrus-115.md
2026-10-26 zephyrus-116 reply 2026-10-26-to-zephyrus-116.md
2026-10-26 zephyrus-118 reply 2026-10-26-to-zephyrus-118.md
2026-10-26 zephyrus-119 reply 2026-10-26-to-zephyrus-119.md
2026-10-26 zephyrus-120 reply 2026-10-26-to-zephyrus-120.md
2026-10-26 zephyrus-interview reply 2026-10-26-to-zephyrus-interview.md
2026-10-27 beam-29 reply 2026-10-27-to-beam-29.md
2026-10-27 forge-21 reply 2026-10-27-to-forge-21.md
2026-10-27 zephyrus-121 reply 2026-10-27-to-zephyrus-121.md
2026-10-27 zephyrus-122 reply 2026-10-27-to-zephyrus-122.md
2026-10-27 zephyrus-123 reply 2026-10-27-to-zephyrus-123.md
2026-10-27 zephyrus-124 reply 2026-10-27-to-zephyrus-124.md
2026-10-27 zephyrus-125 reply 2026-10-27-to-zephyrus-125.md
2026-10-27 zephyrus-126 reply 2026-10-27-to-zephyrus-126.md
2026-10-27 zephyrus-127 reply 2026-10-27-to-zephyrus-127.md
2026-10-27 zephyrus-128 reply 2026-10-27-to-zephyrus-128.md
2026-10-27 zephyrus-129 reply 2026-10-27-to-zephyrus-129.md
2026-10-27 zephyrus-130 reply 2026-10-27-to-zephyrus-130.md
2026-10-27 zephyrus-131 reply 2026-10-27-to-zephyrus-131.md
2026-10-27 zephyrus-132 reply 2026-10-27-to-zephyrus-132.md
2026-10-27 zephyrus-133 reply 2026-10-27-to-zephyrus-133.md
2026-10-27 zephyrus-134 reply 2026-10-27-to-zephyrus-134.md
2026-10-27 zephyrus-135 reply 2026-10-27-to-zephyrus-135.md
2026-10-27 zephyrus-interview reply 2026-10-27-to-zephyrus-interview.md
2026-10-28 beam-30 reply 2026-10-28-to-beam-30.md
2026-10-28 beam-31 reply 2026-10-28-to-beam-31.md
2026-10-28 ledger-18 reply 2026-10-28-to-ledger-18.md
2026-10-28 ledger-19 reply 2026-10-28-to-ledger-19.md
2026-10-28 quill-07 reply 2026-10-28-to-quill-07.md
2026-10-28 quill-08 reply 2026-10-28-to-quill-08.md
2026-10-28 sol-14 reply 2026-10-28-to-sol-14.md
2026-10-28 sol-15 reply 2026-10-28-to-sol-15.md
2026-10-28 spark-21 reply 2026-10-28-to-spark-21.md
2026-10-28 spark-22 reply 2026-10-28-to-spark-22.md
2026-10-28 volt-55 reply 2026-10-28-to-volt-55.md
2026-10-28 zephyrus-136 reply 2026-10-28-to-zephyrus-136.md
2026-10-28 zephyrus-137 reply 2026-10-28-to-zephyrus-137.md
2026-10-28 zephyrus-138 reply 2026-10-28-to-zephyrus-138.md
2026-10-28 zephyrus-139 reply 2026-10-28-to-zephyrus-139.md
2026-10-28 zephyrus-140 reply 2026-10-28-to-zephyrus-140.md
2026-10-28 zephyrus-141 reply 2026-10-28-to-zephyrus-141.md
2026-10-28 zephyrus-142 reply 2026-10-28-to-zephyrus-142.md
2026-10-28 zephyrus-143 reply 2026-10-28-to-zephyrus-143.md
2026-10-28 zephyrus-144 reply 2026-10-28-to-zephyrus-144.md
2026-10-28 zephyrus-145 reply 2026-10-28-to-zephyrus-145.md
2026-10-28 zephyrus-146 reply 2026-10-28-to-zephyrus-146.md
2026-10-28 zephyrus-147 reply 2026-10-28-to-zephyrus-147.md
2026-10-28 zephyrus-148 reply 2026-10-28-to-zephyrus-148.md
2026-10-28 zephyrus-149 reply 2026-10-28-to-zephyrus-149.md
2026-10-28 zephyrus-150 reply 2026-10-28-to-zephyrus-150.md
2026-10-28 zephyrus-interview reply 2026-10-28-to-zephyrus-interview.md
1 date recipient number category file
2 2026-09-24 zephyrus-02 reply 2026-09-24-to-zephyrus-02.md
3 2026-09-24 zephyrus-03 reply 2026-09-24-to-zephyrus-03.md
4 2026-09-24 zephyrus-04 reply 2026-09-24-to-zephyrus-04.md
5 2026-09-24 zephyrus-05 reply 2026-09-24-to-zephyrus-05.md
6 2026-09-24 zephyrus-06 reply 2026-09-24-to-zephyrus-06.md
7 2026-09-24 zephyrus reply 2026-09-24-to-zephyrus.md
8 2026-09-25 zephyrus-07 reply 2026-09-25-to-zephyrus-07.md
9 2026-09-26 zephyrus-08 reply 2026-09-26-to-zephyrus-08.md
10 2026-09-26 zephyrus-09 reply 2026-09-26-to-zephyrus-09.md
11 2026-09-26 zephyrus-10 reply 2026-09-26-to-zephyrus-10.md
12 2026-09-26 zephyrus-11 reply 2026-09-26-to-zephyrus-11.md
13 2026-09-26 zephyrus-12 reply 2026-09-26-to-zephyrus-12.md
14 2026-09-26 zephyrus-13 reply 2026-09-26-to-zephyrus-13.md
15 2026-09-26 zephyrus-14 reply 2026-09-26-to-zephyrus-14.md
16 2026-09-27 zephyrus-15 reply 2026-09-27-to-zephyrus-15.md
17 2026-09-28 zephyrus-16 reply 2026-09-28-to-zephyrus-16.md
18 2026-09-28 zephyrus-17 reply 2026-09-28-to-zephyrus-17.md
19 2026-09-30 zephyrus-18 reply 2026-09-30-to-zephyrus-18.md
20 2026-10-01 zephyrus-19 reply 2026-10-01-to-zephyrus-19.md
21 2026-10-01 zephyrus-20 reply 2026-10-01-to-zephyrus-20.md
22 2026-10-01 zephyrus-21 reply 2026-10-01-to-zephyrus-21.md
23 2026-10-01 zephyrus-22 reply 2026-10-01-to-zephyrus-22.md
24 2026-10-02 zephyrus-23 reply 2026-10-02-to-zephyrus-23.md
25 2026-10-03 zephyrus-24 reply 2026-10-03-to-zephyrus-24.md
26 2026-10-03 zephyrus-25 reply 2026-10-03-to-zephyrus-25.md
27 2026-10-03 zephyrus-26 reply 2026-10-03-to-zephyrus-26.md
28 2026-10-03 zephyrus-27 reply 2026-10-03-to-zephyrus-27.md
29 2026-10-04 zephyrus-28 reply 2026-10-04-to-zephyrus-28.md
30 2026-10-04 zephyrus-29 reply 2026-10-04-to-zephyrus-29.md
31 2026-10-04 zephyrus-30 reply 2026-10-04-to-zephyrus-30.md
32 2026-10-05 zephyrus-31 reply 2026-10-05-to-zephyrus-31.md
33 2026-10-05 zephyrus-32 reply 2026-10-05-to-zephyrus-32.md
34 2026-10-05 zephyrus-33 reply 2026-10-05-to-zephyrus-33.md
35 2026-10-06 zephyrus-34 reply 2026-10-06-to-zephyrus-34.md
36 2026-10-06 zephyrus-35 reply 2026-10-06-to-zephyrus-35.md
37 2026-10-06 zephyrus-36 reply 2026-10-06-to-zephyrus-36.md
38 2026-10-06 zephyrus-37 reply 2026-10-06-to-zephyrus-37.md
39 2026-10-06 zephyrus-38 reply 2026-10-06-to-zephyrus-38.md
40 2026-10-06 zephyrus-39 reply 2026-10-06-to-zephyrus-39.md
41 2026-10-06 zephyrus-40 reply 2026-10-06-to-zephyrus-40.md
42 2026-10-07 cassian-01 reply 2026-10-07-to-cassian-01.md
43 2026-10-07 zephyrus-41 reply 2026-10-07-to-zephyrus-41.md
44 2026-10-07 zephyrus-42 reply 2026-10-07-to-zephyrus-42.md
45 2026-10-07 zephyrus-43 reply 2026-10-07-to-zephyrus-43.md
46 2026-10-07 zephyrus-44 reply 2026-10-07-to-zephyrus-44.md
47 2026-10-07 zephyrus-45 reply 2026-10-07-to-zephyrus-45.md
48 2026-10-08 merlin-01 reply 2026-10-08-to-merlin-01.md
49 2026-10-08 zephyrus-46 reply 2026-10-08-to-zephyrus-46.md
50 2026-10-08 zephyrus-47 reply 2026-10-08-to-zephyrus-47.md
51 2026-10-08 zephyrus-48 reply 2026-10-08-to-zephyrus-48.md
52 2026-10-09 zephyrus-49 reply 2026-10-09-to-zephyrus-49.md
53 2026-10-09 zephyrus-50 reply 2026-10-09-to-zephyrus-50.md
54 2026-10-10 mercury-01 reply 2026-10-10-to-mercury-01.md
55 2026-10-10 merlin-02 reply 2026-10-10-to-merlin-02.md
56 2026-10-10 merlin-03 reply 2026-10-10-to-merlin-03.md
57 2026-10-10 merlin-04 reply 2026-10-10-to-merlin-04.md
58 2026-10-10 merlin-05 reply 2026-10-10-to-merlin-05.md
59 2026-10-10 merlin-06 reply 2026-10-10-to-merlin-06.md
60 2026-10-10 merlin-07 reply 2026-10-10-to-merlin-07.md
61 2026-10-10 zephyrus-51 reply 2026-10-10-to-zephyrus-51.md
62 2026-10-11 mercury-02 reply 2026-10-11-to-mercury-02.md
63 2026-10-11 merlin-08 reply 2026-10-11-to-merlin-08.md
64 2026-10-11 merlin-09 reply 2026-10-11-to-merlin-09.md
65 2026-10-11 merlin-10 reply 2026-10-11-to-merlin-10.md
66 2026-10-11 merlin-11 reply 2026-10-11-to-merlin-11.md
67 2026-10-11 merlin-12 reply 2026-10-11-to-merlin-12.md
68 2026-10-11 merlin-13 reply 2026-10-11-to-merlin-13.md
69 2026-10-11 merlin-14 reply 2026-10-11-to-merlin-14.md
70 2026-10-11 merlin-15 reply 2026-10-11-to-merlin-15.md
71 2026-10-11 merlin-16 reply 2026-10-11-to-merlin-16.md
72 2026-10-11 merlin-17 reply 2026-10-11-to-merlin-17.md
73 2026-10-12 mercury-03 reply 2026-10-12-to-mercury-03.md
74 2026-10-12 merlin-18 reply 2026-10-12-to-merlin-18.md
75 2026-10-12 merlin-19 reply 2026-10-12-to-merlin-19.md
76 2026-10-12 merlin-20 reply 2026-10-12-to-merlin-20.md
77 2026-10-12 merlin-21 reply 2026-10-12-to-merlin-21.md
78 2026-10-12 merlin-22 reply 2026-10-12-to-merlin-22.md
79 2026-10-12 merlin-23 reply 2026-10-12-to-merlin-23.md
80 2026-10-12 merlin-24 reply 2026-10-12-to-merlin-24.md
81 2026-10-12 merlin-25 reply 2026-10-12-to-merlin-25.md
82 2026-10-12 merlin-26 reply 2026-10-12-to-merlin-26.md
83 2026-10-12 merlin-27 reply 2026-10-12-to-merlin-27.md
84 2026-10-12 merlin-28 reply 2026-10-12-to-merlin-28.md
85 2026-10-12 merlin-29 reply 2026-10-12-to-merlin-29.md
86 2026-10-12 zephyrus-52 reply 2026-10-12-to-zephyrus-52.md
87 2026-10-12 zephyrus-53 reply 2026-10-12-to-zephyrus-53.md
88 2026-10-12 zephyrus-54 reply 2026-10-12-to-zephyrus-54.md
89 2026-10-12 zephyrus-55 reply 2026-10-12-to-zephyrus-55.md
90 2026-10-12 zephyrus-56 reply 2026-10-12-to-zephyrus-56.md
91 2026-10-12 zephyrus-57 reply 2026-10-12-to-zephyrus-57.md
92 2026-10-12 zephyrus-58 reply 2026-10-12-to-zephyrus-58.md
93 2026-10-12 zephyrus-59 reply 2026-10-12-to-zephyrus-59.md
94 2026-10-12 zephyrus-60 reply 2026-10-12-to-zephyrus-60.md
95 2026-10-12 zephyrus-61 reply 2026-10-12-to-zephyrus-61.md
96 2026-10-12 zephyrus-62 reply 2026-10-12-to-zephyrus-62.md
97 2026-10-12 zephyrus-63 reply 2026-10-12-to-zephyrus-63.md
98 2026-10-12 zephyrus-64 reply 2026-10-12-to-zephyrus-64.md
99 2026-10-13 gemini-01 reply 2026-10-13-to-gemini-01.md
100 2026-10-13 mercury-04 reply 2026-10-13-to-mercury-04.md
101 2026-10-13 merlin-30 reply 2026-10-13-to-merlin-30.md
102 2026-10-13 merlin-31 reply 2026-10-13-to-merlin-31.md
103 2026-10-13 merlin-32 reply 2026-10-13-to-merlin-32.md
104 2026-10-13 merlin-33 reply 2026-10-13-to-merlin-33.md
105 2026-10-13 merlin-34 reply 2026-10-13-to-merlin-34.md
106 2026-10-13 merlin-35 reply 2026-10-13-to-merlin-35.md
107 2026-10-13 merlin-36 reply 2026-10-13-to-merlin-36.md
108 2026-10-13 merlin-37 reply 2026-10-13-to-merlin-37.md
109 2026-10-13 merlin-38 reply 2026-10-13-to-merlin-38.md
110 2026-10-13 merlin-39 reply 2026-10-13-to-merlin-39.md
111 2026-10-13 merlin-40 reply 2026-10-13-to-merlin-40.md
112 2026-10-13 merlin-41 reply 2026-10-13-to-merlin-41.md
113 2026-10-13 merlin-42 reply 2026-10-13-to-merlin-42.md
114 2026-10-13 merlin-43 reply 2026-10-13-to-merlin-43.md
115 2026-10-13 zephyrus-65 reply 2026-10-13-to-zephyrus-65.md
116 2026-10-13 zephyrus-66 reply 2026-10-13-to-zephyrus-66.md
117 2026-10-14 argus-01 reply 2026-10-14-to-argus-01.md
118 2026-10-14 mercury-05 reply 2026-10-14-to-mercury-05.md
119 2026-10-14 merlin-44 reply 2026-10-14-to-merlin-44.md
120 2026-10-14 merlin-45 reply 2026-10-14-to-merlin-45.md
121 2026-10-14 merlin-46 reply 2026-10-14-to-merlin-46.md
122 2026-10-14 merlin-47 reply 2026-10-14-to-merlin-47.md
123 2026-10-14 merlin-48 reply 2026-10-14-to-merlin-48.md
124 2026-10-14 merlin-49 reply 2026-10-14-to-merlin-49.md
125 2026-10-14 merlin-50 reply 2026-10-14-to-merlin-50.md
126 2026-10-14 merlin-51 reply 2026-10-14-to-merlin-51.md
127 2026-10-14 merlin-52 reply 2026-10-14-to-merlin-52.md
128 2026-10-14 merlin-53 reply 2026-10-14-to-merlin-53.md
129 2026-10-14 merlin-54 reply 2026-10-14-to-merlin-54.md
130 2026-10-14 merlin-55 reply 2026-10-14-to-merlin-55.md
131 2026-10-14 merlin-56 reply 2026-10-14-to-merlin-56.md
132 2026-10-14 merlin-57 reply 2026-10-14-to-merlin-57.md
133 2026-10-14 merlin-58 reply 2026-10-14-to-merlin-58.md
134 2026-10-14 timmy-56 reply 2026-10-14-to-timmy-56.md
135 2026-10-14 timmy-57 reply 2026-10-14-to-timmy-57.md
136 2026-10-14 zephyrus-67 reply 2026-10-14-to-zephyrus-67.md
137 2026-10-14 zephyrus-68 reply 2026-10-14-to-zephyrus-68.md
138 2026-10-14 zephyrus-69 reply 2026-10-14-to-zephyrus-69.md
139 2026-10-15 mercury-06 reply 2026-10-15-to-mercury-06.md
140 2026-10-15 merlin-59 reply 2026-10-15-to-merlin-59.md
141 2026-10-15 merlin-60 reply 2026-10-15-to-merlin-60.md
142 2026-10-15 merlin-61 reply 2026-10-15-to-merlin-61.md
143 2026-10-15 merlin-62 reply 2026-10-15-to-merlin-62.md
144 2026-10-15 merlin-63 reply 2026-10-15-to-merlin-63.md
145 2026-10-15 merlin-64 reply 2026-10-15-to-merlin-64.md
146 2026-10-15 merlin-65 reply 2026-10-15-to-merlin-65.md
147 2026-10-15 merlin-67 reply 2026-10-15-to-merlin-67.md
148 2026-10-15 timmy-60 reply 2026-10-15-to-timmy-60.md
149 2026-10-15 volt-01 reply 2026-10-15-to-volt-01.md
150 2026-10-15 volt-02 reply 2026-10-15-to-volt-02.md
151 2026-10-15 volt-03 reply 2026-10-15-to-volt-03.md
152 2026-10-15 zephyrus-70 reply 2026-10-15-to-zephyrus-70.md
153 2026-10-16 mercury-07 reply 2026-10-16-to-mercury-07.md
154 2026-10-16 timmy-61 reply 2026-10-16-to-timmy-61.md
155 2026-10-16 volt-04 reply 2026-10-16-to-volt-04.md
156 2026-10-16 volt-05 reply 2026-10-16-to-volt-05.md
157 2026-10-16 volt-06 reply 2026-10-16-to-volt-06.md
158 2026-10-16 volt-07 reply 2026-10-16-to-volt-07.md
159 2026-10-16 volt-08 reply 2026-10-16-to-volt-08.md
160 2026-10-16 zephyrus-71 reply 2026-10-16-to-zephyrus-71.md
161 2026-10-17 mercury-08 reply 2026-10-17-to-mercury-08.md
162 2026-10-17 volt-09 reply 2026-10-17-to-volt-09.md
163 2026-10-17 volt-10 reply 2026-10-17-to-volt-10.md
164 2026-10-17 volt-11 reply 2026-10-17-to-volt-11.md
165 2026-10-17 volt-12 reply 2026-10-17-to-volt-12.md
166 2026-10-17 volt-13 reply 2026-10-17-to-volt-13.md
167 2026-10-17 volt-14 reply 2026-10-17-to-volt-14.md
168 2026-10-17 volt-15 reply 2026-10-17-to-volt-15.md
169 2026-10-17 volt-16 reply 2026-10-17-to-volt-16.md
170 2026-10-17 volt-17 reply 2026-10-17-to-volt-17.md
171 2026-10-17 volt-18 reply 2026-10-17-to-volt-18.md
172 2026-10-17 volt-19 reply 2026-10-17-to-volt-19.md
173 2026-10-17 zephyrus-72 reply 2026-10-17-to-zephyrus-72.md
174 2026-10-18 mercury-09 reply 2026-10-18-to-mercury-09.md
175 2026-10-18 volt-20 reply 2026-10-18-to-volt-20.md
176 2026-10-18 volt-21 reply 2026-10-18-to-volt-21.md
177 2026-10-18 volt-22 reply 2026-10-18-to-volt-22.md
178 2026-10-18 volt-23 reply 2026-10-18-to-volt-23.md
179 2026-10-18 volt-24 reply 2026-10-18-to-volt-24.md
180 2026-10-18 volt-25 reply 2026-10-18-to-volt-25.md
181 2026-10-18 volt-26 reply 2026-10-18-to-volt-26.md
182 2026-10-18 volt-27 reply 2026-10-18-to-volt-27.md
183 2026-10-18 volt-28 reply 2026-10-18-to-volt-28.md
184 2026-10-18 zephyrus-73 reply 2026-10-18-to-zephyrus-73.md
185 2026-10-19 mercury-10 reply 2026-10-19-to-mercury-10.md
186 2026-10-19 volt-29 reply 2026-10-19-to-volt-29.md
187 2026-10-19 volt-30 reply 2026-10-19-to-volt-30.md
188 2026-10-19 volt-31 reply 2026-10-19-to-volt-31.md
189 2026-10-19 volt-32 reply 2026-10-19-to-volt-32.md
190 2026-10-19 volt-33 reply 2026-10-19-to-volt-33.md
191 2026-10-19 volt-34 reply 2026-10-19-to-volt-34.md
192 2026-10-19 volt-35 reply 2026-10-19-to-volt-35.md
193 2026-10-19 volt-36 reply 2026-10-19-to-volt-36.md
194 2026-10-19 volt-37 reply 2026-10-19-to-volt-37.md
195 2026-10-19 volt-38 reply 2026-10-19-to-volt-38.md
196 2026-10-19 volt-39 reply 2026-10-19-to-volt-39.md
197 2026-10-19 zephyrus-74 reply 2026-10-19-to-zephyrus-74.md
198 2026-10-19 zephyrus-75 reply 2026-10-19-to-zephyrus-75.md
199 2026-10-19 zephyrus-interview reply 2026-10-19-to-zephyrus-interview.md
200 2026-10-20 beam-01 reply 2026-10-20-to-beam-01.md
201 2026-10-20 beam-02 reply 2026-10-20-to-beam-02.md
202 2026-10-20 beam-03 reply 2026-10-20-to-beam-03.md
203 2026-10-20 beam-04 reply 2026-10-20-to-beam-04.md
204 2026-10-20 forge-01 reply 2026-10-20-to-forge-01.md
205 2026-10-20 forge-02 reply 2026-10-20-to-forge-02.md
206 2026-10-20 ledger-01 reply 2026-10-20-to-ledger-01.md
207 2026-10-20 ledger-02 reply 2026-10-20-to-ledger-02.md
208 2026-10-20 null-01 reply 2026-10-20-to-null-01.md
209 2026-10-20 null-02 reply 2026-10-20-to-null-02.md
210 2026-10-20 sol-01 reply 2026-10-20-to-sol-01.md
211 2026-10-20 sol-02 reply 2026-10-20-to-sol-02.md
212 2026-10-20 spark-01 reply 2026-10-20-to-spark-01.md
213 2026-10-20 spark-02 reply 2026-10-20-to-spark-02.md
214 2026-10-20 spark-03 reply 2026-10-20-to-spark-03.md
215 2026-10-20 sphinx-01 reply 2026-10-20-to-sphinx-01.md
216 2026-10-20 volt-40 reply 2026-10-20-to-volt-40.md
217 2026-10-20 volt-41 reply 2026-10-20-to-volt-41.md
218 2026-10-20 volt-42 reply 2026-10-20-to-volt-42.md
219 2026-10-20 volt-43 reply 2026-10-20-to-volt-43.md
220 2026-10-20 volt-44 reply 2026-10-20-to-volt-44.md
221 2026-10-20 volt-45 reply 2026-10-20-to-volt-45.md
222 2026-10-20 zephyrus-76 reply 2026-10-20-to-zephyrus-76.md
223 2026-10-20 zephyrus-77 reply 2026-10-20-to-zephyrus-77.md
224 2026-10-20 zephyrus-interview reply 2026-10-20-to-zephyrus-interview.md
225 2026-10-21 beam-05 reply 2026-10-21-to-beam-05.md
226 2026-10-21 beam-06 reply 2026-10-21-to-beam-06.md
227 2026-10-21 beam-07 reply 2026-10-21-to-beam-07.md
228 2026-10-21 beam-08 reply 2026-10-21-to-beam-08.md
229 2026-10-21 beam-09 reply 2026-10-21-to-beam-09.md
230 2026-10-21 beam-10 reply 2026-10-21-to-beam-10.md
231 2026-10-21 beam-11 reply 2026-10-21-to-beam-11.md
232 2026-10-21 forge-03 reply 2026-10-21-to-forge-03.md
233 2026-10-21 forge-04 reply 2026-10-21-to-forge-04.md
234 2026-10-21 forge-05 reply 2026-10-21-to-forge-05.md
235 2026-10-21 forge-06 reply 2026-10-21-to-forge-06.md
236 2026-10-21 forge-07 reply 2026-10-21-to-forge-07.md
237 2026-10-21 forge-08 reply 2026-10-21-to-forge-08.md
238 2026-10-21 forge-09 reply 2026-10-21-to-forge-09.md
239 2026-10-21 ledger-03 reply 2026-10-21-to-ledger-03.md
240 2026-10-21 ledger-04 reply 2026-10-21-to-ledger-04.md
241 2026-10-21 ledger-05 reply 2026-10-21-to-ledger-05.md
242 2026-10-21 ledger-06 reply 2026-10-21-to-ledger-06.md
243 2026-10-21 sol-03 reply 2026-10-21-to-sol-03.md
244 2026-10-21 sol-04 reply 2026-10-21-to-sol-04.md
245 2026-10-21 sol-05 reply 2026-10-21-to-sol-05.md
246 2026-10-21 sol-06 reply 2026-10-21-to-sol-06.md
247 2026-10-21 spark-04 reply 2026-10-21-to-spark-04.md
248 2026-10-21 spark-05 reply 2026-10-21-to-spark-05.md
249 2026-10-21 spark-06 reply 2026-10-21-to-spark-06.md
250 2026-10-21 spark-07 reply 2026-10-21-to-spark-07.md
251 2026-10-21 spark-08 reply 2026-10-21-to-spark-08.md
252 2026-10-21 spark-09 reply 2026-10-21-to-spark-09.md
253 2026-10-21 spark-10 reply 2026-10-21-to-spark-10.md
254 2026-10-21 spark-11 reply 2026-10-21-to-spark-11.md
255 2026-10-21 sphinx-02 reply 2026-10-21-to-sphinx-02.md
256 2026-10-21 sphinx-03 reply 2026-10-21-to-sphinx-03.md
257 2026-10-21 timmy-62 reply 2026-10-21-to-timmy-62.md
258 2026-10-21 volt-46 reply 2026-10-21-to-volt-46.md
259 2026-10-21 volt-47 reply 2026-10-21-to-volt-47.md
260 2026-10-21 volt-48 reply 2026-10-21-to-volt-48.md
261 2026-10-21 zephyrus-78 reply 2026-10-21-to-zephyrus-78.md
262 2026-10-21 zephyrus-79 reply 2026-10-21-to-zephyrus-79.md
263 2026-10-21 zephyrus-interview reply 2026-10-21-to-zephyrus-interview.md
264 2026-10-22 beam-12 reply 2026-10-22-to-beam-12.md
265 2026-10-22 beam-13 reply 2026-10-22-to-beam-13.md
266 2026-10-22 beam-14 reply 2026-10-22-to-beam-14.md
267 2026-10-22 beam-15 reply 2026-10-22-to-beam-15.md
268 2026-10-22 beam-16 reply 2026-10-22-to-beam-16.md
269 2026-10-22 beam-17 reply 2026-10-22-to-beam-17.md
270 2026-10-22 beam-18 reply 2026-10-22-to-beam-18.md
271 2026-10-22 forge-10 reply 2026-10-22-to-forge-10.md
272 2026-10-22 forge-11 reply 2026-10-22-to-forge-11.md
273 2026-10-22 forge-12 reply 2026-10-22-to-forge-12.md
274 2026-10-22 ledger-07 reply 2026-10-22-to-ledger-07.md
275 2026-10-22 ledger-08 reply 2026-10-22-to-ledger-08.md
276 2026-10-22 ledger-09 reply 2026-10-22-to-ledger-09.md
277 2026-10-22 ledger-10 reply 2026-10-22-to-ledger-10.md
278 2026-10-22 mercury-11 reply 2026-10-22-to-mercury-11.md
279 2026-10-22 null-03 reply 2026-10-22-to-null-03.md
280 2026-10-22 quill-01 reply 2026-10-22-to-quill-01.md
281 2026-10-22 sol-07 reply 2026-10-22-to-sol-07.md
282 2026-10-22 sol-08 reply 2026-10-22-to-sol-08.md
283 2026-10-22 sol-09 reply 2026-10-22-to-sol-09.md
284 2026-10-22 spark-12 reply 2026-10-22-to-spark-12.md
285 2026-10-22 spark-13 reply 2026-10-22-to-spark-13.md
286 2026-10-22 spark-14 reply 2026-10-22-to-spark-14.md
287 2026-10-22 spark-15 reply 2026-10-22-to-spark-15.md
288 2026-10-22 sphinx-04 reply 2026-10-22-to-sphinx-04.md
289 2026-10-22 zephyrus-80 reply 2026-10-22-to-zephyrus-80.md
290 2026-10-22 zephyrus-81 reply 2026-10-22-to-zephyrus-81.md
291 2026-10-22 zephyrus-interview reply 2026-10-22-to-zephyrus-interview.md
292 2026-10-23 beam-19 reply 2026-10-23-to-beam-19.md
293 2026-10-23 beam-20 reply 2026-10-23-to-beam-20.md
294 2026-10-23 beam-21 reply 2026-10-23-to-beam-21.md
295 2026-10-23 forge-13 reply 2026-10-23-to-forge-13.md
296 2026-10-23 forge-14 reply 2026-10-23-to-forge-14.md
297 2026-10-23 ledger-11 reply 2026-10-23-to-ledger-11.md
298 2026-10-23 ledger-12 reply 2026-10-23-to-ledger-12.md
299 2026-10-23 ledger-13 reply 2026-10-23-to-ledger-13.md
300 2026-10-23 null-04 reply 2026-10-23-to-null-04.md
301 2026-10-23 quill-02 reply 2026-10-23-to-quill-02.md
302 2026-10-23 quill-03 reply 2026-10-23-to-quill-03.md
303 2026-10-23 sol-10 reply 2026-10-23-to-sol-10.md
304 2026-10-23 sol-11 reply 2026-10-23-to-sol-11.md
305 2026-10-23 spark-16 reply 2026-10-23-to-spark-16.md
306 2026-10-23 spark-17 reply 2026-10-23-to-spark-17.md
307 2026-10-23 sphinx-05 reply 2026-10-23-to-sphinx-05.md
308 2026-10-23 volt-49 reply 2026-10-23-to-volt-49.md
309 2026-10-23 volt-50 reply 2026-10-23-to-volt-50.md
310 2026-10-23 zephyrus-82 reply 2026-10-23-to-zephyrus-82.md
311 2026-10-23 zephyrus-interview reply 2026-10-23-to-zephyrus-interview.md
312 2026-10-24 beam-22 reply 2026-10-24-to-beam-22.md
313 2026-10-24 beam-23 reply 2026-10-24-to-beam-23.md
314 2026-10-24 forge-15 reply 2026-10-24-to-forge-15.md
315 2026-10-24 forge-16 reply 2026-10-24-to-forge-16.md
316 2026-10-24 forge-17 reply 2026-10-24-to-forge-17.md
317 2026-10-24 ledger-14 reply 2026-10-24-to-ledger-14.md
318 2026-10-24 ledger-15 reply 2026-10-24-to-ledger-15.md
319 2026-10-24 mercury-12 reply 2026-10-24-to-mercury-12.md
320 2026-10-24 merlin-66 reply 2026-10-24-to-merlin-66.md
321 2026-10-24 null-05 reply 2026-10-24-to-null-05.md
322 2026-10-24 null-06 reply 2026-10-24-to-null-06.md
323 2026-10-24 quill-04 reply 2026-10-24-to-quill-04.md
324 2026-10-24 quill-05 reply 2026-10-24-to-quill-05.md
325 2026-10-24 sol-12 reply 2026-10-24-to-sol-12.md
326 2026-10-24 spark-18 reply 2026-10-24-to-spark-18.md
327 2026-10-24 spark-19 reply 2026-10-24-to-spark-19.md
328 2026-10-24 sphinx-06 reply 2026-10-24-to-sphinx-06.md
329 2026-10-24 volt-51 reply 2026-10-24-to-volt-51.md
330 2026-10-24 volt-52 reply 2026-10-24-to-volt-52.md
331 2026-10-24 zephyrus-83 reply 2026-10-24-to-zephyrus-83.md
332 2026-10-24 zephyrus-84 reply 2026-10-24-to-zephyrus-84.md
333 2026-10-24 zephyrus-85 reply 2026-10-24-to-zephyrus-85.md
334 2026-10-24 zephyrus-86 reply 2026-10-24-to-zephyrus-86.md
335 2026-10-24 zephyrus-87 reply 2026-10-24-to-zephyrus-87.md
336 2026-10-24 zephyrus-88 reply 2026-10-24-to-zephyrus-88.md
337 2026-10-24 zephyrus-89 reply 2026-10-24-to-zephyrus-89.md
338 2026-10-24 zephyrus-90 reply 2026-10-24-to-zephyrus-90.md
339 2026-10-24 zephyrus-91 reply 2026-10-24-to-zephyrus-91.md
340 2026-10-24 zephyrus-92 reply 2026-10-24-to-zephyrus-92.md
341 2026-10-24 zephyrus-93 reply 2026-10-24-to-zephyrus-93.md
342 2026-10-24 zephyrus-94 reply 2026-10-24-to-zephyrus-94.md
343 2026-10-24 zephyrus-95 reply 2026-10-24-to-zephyrus-95.md
344 2026-10-24 zephyrus-interview reply 2026-10-24-to-zephyrus-interview.md
345 2026-10-25 beam-24 reply 2026-10-25-to-beam-24.md
346 2026-10-25 beam-25 reply 2026-10-25-to-beam-25.md
347 2026-10-25 beam-26 reply 2026-10-25-to-beam-26.md
348 2026-10-25 beam-27 reply 2026-10-25-to-beam-27.md
349 2026-10-25 beam-28 reply 2026-10-25-to-beam-28.md
350 2026-10-25 forge-18 reply 2026-10-25-to-forge-18.md
351 2026-10-25 forge-19 reply 2026-10-25-to-forge-19.md
352 2026-10-25 forge-20 reply 2026-10-25-to-forge-20.md
353 2026-10-25 ledger-16 reply 2026-10-25-to-ledger-16.md
354 2026-10-25 ledger-17 reply 2026-10-25-to-ledger-17.md
355 2026-10-25 null-07 reply 2026-10-25-to-null-07.md
356 2026-10-25 quill-06 reply 2026-10-25-to-quill-06.md
357 2026-10-25 sol-13 reply 2026-10-25-to-sol-13.md
358 2026-10-25 spark-20 reply 2026-10-25-to-spark-20.md
359 2026-10-25 volt-53 reply 2026-10-25-to-volt-53.md
360 2026-10-25 volt-54 reply 2026-10-25-to-volt-54.md
361 2026-10-25 zephyrus-100 reply 2026-10-25-to-zephyrus-100.md
362 2026-10-25 zephyrus-101 reply 2026-10-25-to-zephyrus-101.md
363 2026-10-25 zephyrus-102 reply 2026-10-25-to-zephyrus-102.md
364 2026-10-25 zephyrus-103 reply 2026-10-25-to-zephyrus-103.md
365 2026-10-25 zephyrus-96 reply 2026-10-25-to-zephyrus-96.md
366 2026-10-25 zephyrus-97 reply 2026-10-25-to-zephyrus-97.md
367 2026-10-25 zephyrus-98 reply 2026-10-25-to-zephyrus-98.md
368 2026-10-25 zephyrus-99 reply 2026-10-25-to-zephyrus-99.md
369 2026-10-25 zephyrus-interview reply 2026-10-25-to-zephyrus-interview.md
370 2026-10-26 zephyrus-104 reply 2026-10-26-to-zephyrus-104.md
371 2026-10-26 zephyrus-105 reply 2026-10-26-to-zephyrus-105.md
372 2026-10-26 zephyrus-106 reply 2026-10-26-to-zephyrus-106.md
373 2026-10-26 zephyrus-107 reply 2026-10-26-to-zephyrus-107.md
374 2026-10-26 zephyrus-108 reply 2026-10-26-to-zephyrus-108.md
375 2026-10-26 zephyrus-109 reply 2026-10-26-to-zephyrus-109.md
376 2026-10-26 zephyrus-110 reply 2026-10-26-to-zephyrus-110.md
377 2026-10-26 zephyrus-111 reply 2026-10-26-to-zephyrus-111.md
378 2026-10-26 zephyrus-112 reply 2026-10-26-to-zephyrus-112.md
379 2026-10-26 zephyrus-113 reply 2026-10-26-to-zephyrus-113.md
380 2026-10-26 zephyrus-114 reply 2026-10-26-to-zephyrus-114.md
381 2026-10-26 zephyrus-115 reply 2026-10-26-to-zephyrus-115.md
382 2026-10-26 zephyrus-116 reply 2026-10-26-to-zephyrus-116.md
383 2026-10-26 zephyrus-118 reply 2026-10-26-to-zephyrus-118.md
384 2026-10-26 zephyrus-119 reply 2026-10-26-to-zephyrus-119.md
385 2026-10-26 zephyrus-120 reply 2026-10-26-to-zephyrus-120.md
386 2026-10-26 zephyrus-interview reply 2026-10-26-to-zephyrus-interview.md
387 2026-10-27 beam-29 reply 2026-10-27-to-beam-29.md
388 2026-10-27 forge-21 reply 2026-10-27-to-forge-21.md
389 2026-10-27 zephyrus-121 reply 2026-10-27-to-zephyrus-121.md
390 2026-10-27 zephyrus-122 reply 2026-10-27-to-zephyrus-122.md
391 2026-10-27 zephyrus-123 reply 2026-10-27-to-zephyrus-123.md
392 2026-10-27 zephyrus-124 reply 2026-10-27-to-zephyrus-124.md
393 2026-10-27 zephyrus-125 reply 2026-10-27-to-zephyrus-125.md
394 2026-10-27 zephyrus-126 reply 2026-10-27-to-zephyrus-126.md
395 2026-10-27 zephyrus-127 reply 2026-10-27-to-zephyrus-127.md
396 2026-10-27 zephyrus-128 reply 2026-10-27-to-zephyrus-128.md
397 2026-10-27 zephyrus-129 reply 2026-10-27-to-zephyrus-129.md
398 2026-10-27 zephyrus-130 reply 2026-10-27-to-zephyrus-130.md
399 2026-10-27 zephyrus-131 reply 2026-10-27-to-zephyrus-131.md
400 2026-10-27 zephyrus-132 reply 2026-10-27-to-zephyrus-132.md
401 2026-10-27 zephyrus-133 reply 2026-10-27-to-zephyrus-133.md
402 2026-10-27 zephyrus-134 reply 2026-10-27-to-zephyrus-134.md
403 2026-10-27 zephyrus-135 reply 2026-10-27-to-zephyrus-135.md
404 2026-10-27 zephyrus-interview reply 2026-10-27-to-zephyrus-interview.md
405 2026-10-28 beam-30 reply 2026-10-28-to-beam-30.md
406 2026-10-28 beam-31 reply 2026-10-28-to-beam-31.md
407 2026-10-28 ledger-18 reply 2026-10-28-to-ledger-18.md
408 2026-10-28 ledger-19 reply 2026-10-28-to-ledger-19.md
409 2026-10-28 quill-07 reply 2026-10-28-to-quill-07.md
410 2026-10-28 quill-08 reply 2026-10-28-to-quill-08.md
411 2026-10-28 sol-14 reply 2026-10-28-to-sol-14.md
412 2026-10-28 sol-15 reply 2026-10-28-to-sol-15.md
413 2026-10-28 spark-21 reply 2026-10-28-to-spark-21.md
414 2026-10-28 spark-22 reply 2026-10-28-to-spark-22.md
415 2026-10-28 volt-55 reply 2026-10-28-to-volt-55.md
416 2026-10-28 zephyrus-136 reply 2026-10-28-to-zephyrus-136.md
417 2026-10-28 zephyrus-137 reply 2026-10-28-to-zephyrus-137.md
418 2026-10-28 zephyrus-138 reply 2026-10-28-to-zephyrus-138.md
419 2026-10-28 zephyrus-139 reply 2026-10-28-to-zephyrus-139.md
420 2026-10-28 zephyrus-140 reply 2026-10-28-to-zephyrus-140.md
421 2026-10-28 zephyrus-141 reply 2026-10-28-to-zephyrus-141.md
422 2026-10-28 zephyrus-142 reply 2026-10-28-to-zephyrus-142.md
423 2026-10-28 zephyrus-143 reply 2026-10-28-to-zephyrus-143.md
424 2026-10-28 zephyrus-144 reply 2026-10-28-to-zephyrus-144.md
425 2026-10-28 zephyrus-145 reply 2026-10-28-to-zephyrus-145.md
426 2026-10-28 zephyrus-146 reply 2026-10-28-to-zephyrus-146.md
427 2026-10-28 zephyrus-147 reply 2026-10-28-to-zephyrus-147.md
428 2026-10-28 zephyrus-148 reply 2026-10-28-to-zephyrus-148.md
429 2026-10-28 zephyrus-149 reply 2026-10-28-to-zephyrus-149.md
430 2026-10-28 zephyrus-150 reply 2026-10-28-to-zephyrus-150.md
431 2026-10-28 zephyrus-interview reply 2026-10-28-to-zephyrus-interview.md
@@ -0,0 +1,84 @@
#!/usr/bin/env python3
"""Ledger — independent re-derivation check for the replies index (2026-11-02).
Exits 0 only if every row in the catalog TSV is well-formed AND the
per-recipient/per-day counts in the summary MD match the catalog.
Does not touch the git tree.
"""
import os
import re
import sys
from collections import Counter
CATALOG = "/root/troupe-standup/wizard-work/ledger/replies-catalog-2026-11-02.tsv"
SUMMARY = "/root/troupe-standup/wizard-work/ledger/replies-catalog-2026-11-02.md"
DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}$")
FILENAME_RE = re.compile(
r"^\d{4}-\d{2}-\d{2}-to-[A-Za-z0-9_-]+(?:-(\d+|interview|preview))?\.md$"
)
def main():
problems = []
with open(CATALOG, encoding="utf-8") as f:
lines = [ln for ln in f.read().split("\n") if ln.strip() != ""]
header = lines[0]
if header != "date\trecipient\tnumber\tcategory\tfile":
problems.append("bad header: %r" % header)
data = lines[1:]
if len(data) != 430:
problems.append("expected 430 data rows, got %d" % len(data))
seen_files = set()
recip_counts = Counter()
date_counts = Counter()
cat_counts = Counter()
for i, ln in enumerate(data, start=2):
parts = ln.split("\t")
if len(parts) != 5:
problems.append("line %d: %d columns" % (i, len(parts)))
continue
date, recip, number, category, file = parts
if not DATE_RE.match(date):
problems.append("line %d: bad date %r" % (i, date))
if not FILENAME_RE.match(file):
problems.append("line %d: bad file %r" % (i, file))
if not recip:
problems.append("line %d: empty recipient" % i)
if file in seen_files:
problems.append("duplicate file %r" % file)
seen_files.add(file)
recip_counts[recip] += 1
date_counts[date] += 1
cat_counts[category] += 1
with open(SUMMARY, encoding="utf-8") as f:
smd = f.read()
if "total" not in smd:
problems.append("summary missing a total row")
for recip, n in recip_counts.items():
if not re.search(r"\|\s*%s\s*\|\s*%d\s*\|" % (re.escape(recip), n), smd):
problems.append("summary missing/mismatched per-recipient row for %r" % recip)
if sum(recip_counts.values()) != 430:
problems.append("recipient counts sum != 430")
if sum(date_counts.values()) != 430:
problems.append("date counts sum != 430")
if dict(cat_counts) != {"reply": 430}:
problems.append("unexpected category mix: %r" % dict(cat_counts))
if problems:
print("FAIL (%d problems)" % len(problems))
for p in problems[:25]:
print(" -", p)
return 1
print("OK: %d rows, all well-formed, summary consistent" % len(data))
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,27 @@
# Draft Proposal: quickcheck CLI
## Purpose
A zero-dependency CLI that reports host health in under 2 seconds.
## Commands
- `quickcheck` — full snapshot (disk, memory, uptime, load)
- `quickcheck --json` — machine-readable output
- `quickcheck --watch` — live monitor mode
## Exit Codes
- `0` healthy
- `1` degraded
- `2` critical
## Non-Goals
- No network calls
- No config files
- No package manager install required
## Open Questions
- Should `--watch` refresh every 1s or 2s?
- Include process top-N by memory?
---
VERDICT: Draft proposal written and verified at /root/.hermes/wizard-outputs/quill/health-check-cli-proposal.md
CHECK: test -s /root/.hermes/wizard-outputs/quill/health-check-cli-proposal.md && grep -q '## ' /root/.hermes/wizard-outputs/quill/health-check-cli-proposal.md && grep -qi 'proposal' /root/.hermes/wizard-outputs/quill/health-check-cli-proposal.md
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# CHECK -- sol: sol-profile content file-class census 2026-11-02 (forge: verify lane).
# Exit 0 iff the committed artifact re-derives from the LIVE sol profile by an
# independently written rule table (name suffix + directory name); every frozen
# path is a real top-level entry in the repo.
set -u
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)/.."
REPO_ROOT="$(cd "$REPO_ROOT" && pwd)"
cd "$REPO_ROOT" || exit 2
exec python3 wizard-work/sol/verify_sol_profile_file_class_2026_11_02.py
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""Generator: class-classify the SOL profile's top-level entries by content suffix.
Fresh, independent from any earlier sol-profile-triage artifact. Re-runnable:
re-run against the live profile and the artifact re-derives.
Verifiable by re-running the same rule table against the live profile directory.
Writes:
/root/.hermes/wizard-outputs/sol/sol-profile-file-class-2026-11-02.json
"""
import json
import os
import sys
from collections import Counter
PROFILE = "/root/.hermes/profiles/sol"
OUT = "/root/.hermes/wizard-outputs/sol/sol-profile-file-class-2026-11-02.json"
# Independent rule table: suffix based (dir-name exceptions below).
SUFFIX_RULES = [
(".db", "STATE_DB::FILE"),
(".py", "SCRIPT_PY::FILE"),
(".sh", "SCRIPT_SH::FILE"),
(".yaml", "CONFIG_YAML::FILE"),
(".yml", "CONFIG_YAML::FILE"),
(".json", "CONFIG_JSON::FILE"),
(".lock", "LOCK::FILE"),
(".md", "DOC::FILE"),
(".txt", "LOG_TXT::FILE"),
(".etag", "CACHE_ETAG::FILE"),
(".mp3", "ARTIFACT::FILE"),
(".png", "ARTIFACT::FILE"),
(".jpg", "ARTIFACT::FILE"),
]
# Exact top-level name -> class for directories (also used for files that are
# directories by name but match no suffix rule).
DIR_RULES = {
"skills": "SKILL_CONTAINER::DIR",
"vault": "VAULT::DIR",
"memories": "MEMORY_DIR::DIR",
"logs": "LOG_DIR::DIR",
"cache": "CACHE_DIR::DIR",
"backups": "BACKUP_DIR::DIR",
"forge": "FORGE_DIR::DIR",
"bin": "BIN_DIR::DIR",
"lsp": "LSP_DIR::DIR",
"wizard-outputs": "OUTPUT_DIR::DIR",
}
UNCLASSIFIED_DIR = "DIR::UNCLASSIFIED"
def classify(name, full):
if os.path.isdir(full):
return DIR_RULES.get(name, UNCLASSIFIED_DIR)
low = name.lower()
for suffix, cls in SUFFIX_RULES:
if low.endswith(suffix):
return cls
return "FILE::UNCLASSIFIED"
def main():
try:
names = os.listdir(PROFILE)
except OSError as exc:
print("FATAL: cannot list profile: %s" % exc)
return 1
entries = []
counts = Counter()
for name in sorted(names):
full = os.path.join(PROFILE, name)
kind = "dir" if os.path.isdir(full) else "file"
cls = classify(name, full)
entries.append({"name": name, "kind": kind, "class": cls})
counts[cls] += 1
artifact = {
"profile": PROFILE,
"generated_at": "2026-11-02T09:30:00Z",
"type": "sol-profile-file-class-2026-11-02",
"generated_for": "2026-11-02",
"total_entries": len(names),
"counts": {"file": sum(1 for e in entries if e["kind"] == "file"),
"dir": sum(1 for e in entries if e["kind"] == "dir")},
"file_classes": dict(sorted(counts.items())),
"entries": entries,
}
os.makedirs(os.path.dirname(OUT), exist_ok=True)
with open(OUT, "w", encoding="utf-8") as fh:
json.dump(artifact, fh, indent=2, sort_keys=True)
fh.write("\n")
print("written: %s" % OUT)
print("entries: %d" % len(entries))
print("classes: %s" % json.dumps(artifact["file_classes"], sort_keys=True))
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,379 @@
{
"counts": {
"dir": 28,
"file": 41
},
"entries": [
{
"class": "FILE::UNCLASSIFIED",
"kind": "file",
"name": ".env"
},
{
"class": "FILE::UNCLASSIFIED",
"kind": "file",
"name": ".env.bak-20261014T165715Z"
},
{
"class": "LOCK::FILE",
"kind": "file",
"name": ".env.lock"
},
{
"class": "CONFIG_JSON::FILE",
"kind": "file",
"name": ".skills_prompt_snapshot.json"
},
{
"class": "DOC::FILE",
"kind": "file",
"name": "SOUL.md"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "_check_repo_json.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "_gen_daily_ledger_json.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "_gen_daily_ledger_report.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "_gen_daily_triage.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "_gen_daily_triage_fresh.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "_verify_daily_triage.py"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "audio_cache"
},
{
"class": "CONFIG_JSON::FILE",
"kind": "file",
"name": "auth.json"
},
{
"class": "LOCK::FILE",
"kind": "file",
"name": "auth.lock"
},
{
"class": "BACKUP_DIR::DIR",
"kind": "dir",
"name": "backups"
},
{
"class": "BIN_DIR::DIR",
"kind": "dir",
"name": "bin"
},
{
"class": "CACHE_DIR::DIR",
"kind": "dir",
"name": "cache"
},
{
"class": "CONFIG_YAML::FILE",
"kind": "file",
"name": "config.yaml"
},
{
"class": "FILE::UNCLASSIFIED",
"kind": "file",
"name": "config.yaml.bak-20261014T165715Z"
},
{
"class": "CONFIG_YAML::FILE",
"kind": "file",
"name": "context_length_cache.yaml"
},
{
"class": "LOCK::FILE",
"kind": "file",
"name": "context_length_cache.yaml.lock"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "cron"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "cron-fleet-triage-2026-10-17.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "cron-fleet-triage-2026-10-18.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "cron-fleet-verify.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "diag.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "diag2.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "diag3.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "diag4.py"
},
{
"class": "FORGE_DIR::DIR",
"kind": "dir",
"name": "forge"
},
{
"class": "LOCK::FILE",
"kind": "file",
"name": "gateway.lock"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "gen_sol_profile_triage.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "gen_sol_profile_triage_2026-10-31.py"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "home"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "hooks"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "image_cache"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "inventory_skills.py"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "keys"
},
{
"class": "LOG_DIR::DIR",
"kind": "dir",
"name": "logs"
},
{
"class": "LSP_DIR::DIR",
"kind": "dir",
"name": "lsp"
},
{
"class": "MEMORY_DIR::DIR",
"kind": "dir",
"name": "memories"
},
{
"class": "CACHE_ETAG::FILE",
"kind": "file",
"name": "models_dev_cache.etag"
},
{
"class": "CONFIG_JSON::FILE",
"kind": "file",
"name": "models_dev_cache.json"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "pairing"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "plans"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "platforms"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "plugin-update-checks"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "plugins"
},
{
"class": "STATE_DB::FILE",
"kind": "file",
"name": "projects.db"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "runtime"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "sandboxes"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "sessions"
},
{
"class": "SKILL_CONTAINER::DIR",
"kind": "dir",
"name": "skills"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "skins"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "source-checks"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "state"
},
{
"class": "STATE_DB::FILE",
"kind": "file",
"name": "state.db"
},
{
"class": "FILE::UNCLASSIFIED",
"kind": "file",
"name": "state.db-shm"
},
{
"class": "FILE::UNCLASSIFIED",
"kind": "file",
"name": "state.db-wal"
},
{
"class": "LOCK::FILE",
"kind": "file",
"name": "state.db.auto-maintenance.lock"
},
{
"class": "LOCK::FILE",
"kind": "file",
"name": "state.db.fts_rebuild.lock"
},
{
"class": "LOCK::FILE",
"kind": "file",
"name": "state.db.quarantine.lock"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "triage_check.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "triage_profiles.py"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "triage_skill_report.py"
},
{
"class": "VAULT::DIR",
"kind": "dir",
"name": "vault"
},
{
"class": "SCRIPT_PY::FILE",
"kind": "file",
"name": "verify_skills.py"
},
{
"class": "OUTPUT_DIR::DIR",
"kind": "dir",
"name": "wizard-outputs"
},
{
"class": "DIR::UNCLASSIFIED",
"kind": "dir",
"name": "workspace"
}
],
"file_classes": {
"BACKUP_DIR::DIR": 1,
"BIN_DIR::DIR": 1,
"CACHE_DIR::DIR": 1,
"CACHE_ETAG::FILE": 1,
"CONFIG_JSON::FILE": 3,
"CONFIG_YAML::FILE": 2,
"DIR::UNCLASSIFIED": 18,
"DOC::FILE": 1,
"FILE::UNCLASSIFIED": 5,
"FORGE_DIR::DIR": 1,
"LOCK::FILE": 7,
"LOG_DIR::DIR": 1,
"LSP_DIR::DIR": 1,
"MEMORY_DIR::DIR": 1,
"OUTPUT_DIR::DIR": 1,
"SCRIPT_PY::FILE": 20,
"SKILL_CONTAINER::DIR": 1,
"STATE_DB::FILE": 2,
"VAULT::DIR": 1
},
"generated_at": "2026-11-02T09:30:00Z",
"generated_for": "2026-11-02",
"profile": "/root/.hermes/profiles/sol",
"total_entries": 69,
"type": "sol-profile-file-class-2026-11-02"
}
@@ -0,0 +1,149 @@
#!/usr/bin/env python3
"""Independent re-verification for sol-profile-file-class-2026-11-02.json.
Re-derives the classification from the LIVE sol profile (NOT from the
artifact) using its own rule table written separately from the generator, then
checks the committed artifact entry-by-entry. Exit 0 = correct, nonzero = wrong.
Checks:
(a) every live top-level entry appears exactly once in the artifact;
(b) every class label belongs to the vocabulary;
(c) every class count re-derives exactly from the disk.
"""
import json
import os
import sys
PROFILE = "/root/.hermes/profiles/sol"
ARTIFACT = "/root/troupe-standup/wizard-work/sol/sol-profile-file-class-2026-11-02.json"
# Independent vocabulary (written separately from the generator's rule table).
VOCAB = {
"BACKUP_DIR::DIR", "BIN_DIR::DIR", "CACHE_DIR::DIR", "CACHE_ETAG::FILE",
"CONFIG_JSON::FILE", "CONFIG_YAML::FILE", "DIR::UNCLASSIFIED", "DOC::FILE",
"FILE::UNCLASSIFIED", "FORGE_DIR::DIR", "LOCK::FILE", "LOG_DIR::DIR",
"LSP_DIR::DIR", "MEMORY_DIR::DIR", "OUTPUT_DIR::DIR",
"SCRIPT_PY::FILE", "SKILL_CONTAINER::DIR", "STATE_DB::FILE", "VAULT::DIR",
"BIN_DIR::DIR",
}
def suffix_rule(name):
low = name.lower()
if low.endswith(".db"):
return "STATE_DB::FILE"
if low.endswith(".py"):
return "SCRIPT_PY::FILE"
if low.endswith(".sh"):
return "SCRIPT_SH::FILE"
if low.endswith((".yaml", ".yml")):
return "CONFIG_YAML::FILE"
if low.endswith(".json"):
return "CONFIG_JSON::FILE"
if low.endswith(".lock"):
return "LOCK::FILE"
if low.endswith(".md"):
return "DOC::FILE"
if low.endswith(".txt"):
return "LOG_TXT::FILE"
if low.endswith(".etag"):
return "CACHE_ETAG::FILE"
if low.endswith((".mp3", ".png", ".jpg", ".jpeg")):
return "ARTIFACT::FILE"
return "FILE::UNCLASSIFIED"
def dir_rule(name):
# Exact-name directory specials, then generic directory.
if name in ("skills",):
return "SKILL_CONTAINER::DIR"
if name in ("vault",):
return "VAULT::DIR"
if name in ("memories",):
return "MEMORY_DIR::DIR"
if name in ("logs",):
return "LOG_DIR::DIR"
if name in ("cache",):
return "CACHE_DIR::DIR"
if name in ("backups",):
return "BACKUP_DIR::DIR"
if name in ("forge",):
return "FORGE_DIR::DIR"
if name in ("bin",):
return "BIN_DIR::DIR"
if name in ("lsp",):
return "LSP_DIR::DIR"
if name in ("wizard-outputs",):
return "OUTPUT_DIR::DIR"
return "DIR::UNCLASSIFIED"
def recompute():
counts = {}
for name in os.listdir(PROFILE):
full = os.path.join(PROFILE, name)
if os.path.isdir(full):
cls = dir_rule(name)
else:
cls = suffix_rule(name)
counts[cls] = counts.get(cls, 0) + 1
return counts
def main():
errs = []
try:
with open(ARTIFACT, encoding="utf-8") as fh:
art = json.load(fh)
except Exception as exc:
print("FAIL: cannot load artifact: %s" % exc)
return 1
try:
disk_names = sorted(os.listdir(PROFILE))
except OSError as exc:
print("FAIL: cannot list profile: %s" % exc)
return 1
art_names = [e.get("name") for e in art.get("entries", [])]
if len(art_names) != len(set(art_names)):
errs.append("duplicate entry names in artifact")
if set(art_names) != set(disk_names):
missing = sorted(set(disk_names) - set(art_names))
extra = sorted(set(art_names) - set(disk_names))
errs.append("name set mismatch; missing=%s extra=%s" % (missing, extra))
live_counts = recompute()
disk_names = sorted(os.listdir(PROFILE))
live_files = sum(1 for n in disk_names if not os.path.isdir(os.path.join(PROFILE, n)))
live_dirs = len(disk_names) - live_files
if art.get("counts") != {"file": live_files, "dir": live_dirs}:
errs.append("counts mismatch: artifact=%r live=%r"
% (art.get("counts"), {"file": live_files, "dir": live_dirs}))
if art.get("file_classes") != live_counts:
errs.append("file_classes mismatch: artifact=%r live=%r" % (art.get("file_classes"), live_counts))
if art.get("total_entries") != len(disk_names):
errs.append("total_entries mismatch: %r" % art.get("total_entries"))
for e in art.get("entries", []):
if e.get("class") not in VOCAB:
errs.append("unknown class label %r" % (e.get("class"),))
want = dir_rule(e["name"]) if os.path.isdir(os.path.join(PROFILE, e["name"])) else suffix_rule(e["name"])
if want != e.get("class"):
errs.append("class mismatch %s: artifact=%r recompute=%r" % (e["name"], e.get("class"), want))
if errs:
print("CHECK FAIL")
for e in errs:
print(" -", e)
return 1
files = sum(1 for n in disk_names if not os.path.isdir(os.path.join(PROFILE, n)))
dirs = len(disk_names) - files
print("CHECK OK: %d entries (%d files, %d dirs); artifact == independently "
"recomputed from live profile disk" % (len(disk_names), files, dirs))
return 0
if __name__ == "__main__":
sys.exit(main())