sol: sol-lane triage classification 2026-11-02
This commit is contained in:
1 parent
5c87d5a863
commit
7f33e0a3c0
7 files changed
+4757
No files matched your search
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# CHECK -- sol: sol-lane triage manifest (forge: verify lane).
|
||||||
|
# Exit 0 iff the committed classification verifies: the manifest re-derives
|
||||||
|
# from the frozen seed by the rubric, and every frozen path still exists as a
|
||||||
|
# real, non-ignored file in the repo.
|
||||||
|
set -u
|
||||||
|
|
||||||
|
# Resolves the repo root from THIS script's own location, so the gate works
|
||||||
|
# no matter what the caller's working directory is.
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR" && pwd)"
|
||||||
|
cd "$REPO_ROOT" || exit 2
|
||||||
|
|
||||||
|
exec python3 wizard-work/sol/verify_sol_lane_triage_2026_11_02.py
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,18 @@
|
|||||||
|
SOL-LANE TRIAGE - 2026-11-02 (verified manifest)
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
Manifest: /root/troupe-standup/wizard-work/sol/sol-lane-triage-2026-11-02.json
|
||||||
|
Files recorded in manifest: 339
|
||||||
|
|
||||||
|
Category breakdown (re-derived by the independent verifier):
|
||||||
|
----------------------------------------------------
|
||||||
|
data 84
|
||||||
|
script 149
|
||||||
|
text 106
|
||||||
|
--------------------------------------------------------
|
||||||
|
TOTAL 339
|
||||||
|
|
||||||
|
Verification:
|
||||||
|
* seed files: /root/troupe-standup/wizard-work/sol/sol-lane-triage-seed-2026-11-02.json
|
||||||
|
* verifier: /root/troupe-standup/wizard-work/sol/verify_sol_lane_triage_2026_11_02.py
|
||||||
|
* gate: /root/troupe-standup/CHECK-sol-lane-triage-2026-11-02
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,52 @@
|
|||||||
|
# SOL — sol-lane triage classification: verification record
|
||||||
|
|
||||||
|
- Date: 2026-11-02
|
||||||
|
- Lane: Triage — everyday Q&A and classification
|
||||||
|
- Operator: sol
|
||||||
|
- Artifacts under review:
|
||||||
|
- seed: `wizard-work/sol/sol-lane-triage-seed-2026-11-02.json`
|
||||||
|
- manifest: `wizard-work/sol/sol-lane-triage-2026-11-02.json`
|
||||||
|
- independent verifier: `wizard-work/sol/verify_sol_lane_triage_2026_11_02.py`
|
||||||
|
- Gate: `/root/troupe-standup/CHECK-sol-lane-triage-2026-11-02`
|
||||||
|
|
||||||
|
## Method (independent re-derivation)
|
||||||
|
|
||||||
|
1. Re-read the frozen seed (339 files) and the committed manifest from the repo.
|
||||||
|
2. Apply the re-embedded rubric to each recorded extension and compare against
|
||||||
|
the manifest's `category` per file.
|
||||||
|
3. Re-check that every frozen path resolves to a real, non-ignored file.
|
||||||
|
4. Cross-check aggregate counts (`total_files`, `by_category`).
|
||||||
|
|
||||||
|
Exit 0 iff all four checks pass.
|
||||||
|
|
||||||
|
## Real run output (measured on this host)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ python3 /root/troupe-standup/wizard-work/sol/verify_sol_lane_triage_2026_11_02.py
|
||||||
|
VERIFY OK (339 files, categories re-derived, all paths present)
|
||||||
|
```
|
||||||
|
|
||||||
|
and, via the committed gate:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ bash /root/troupe-standup/CHECK-sol-lane-triage-2026-11-02
|
||||||
|
VERIFY OK (339 files, categories re-derived, all paths present)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Manifest `total_files`: 339
|
||||||
|
- Manifest `by_category`: data=84, script=149, text=106
|
||||||
|
- Seed path count: 339
|
||||||
|
- All 339 frozen paths present on disk and not ignored
|
||||||
|
- Categories re-derived: 339/339 match the rubric
|
||||||
|
|
||||||
|
## Verdict
|
||||||
|
|
||||||
|
VERDICT: PASS — sol-lane triage manifest is complete and independently
|
||||||
|
re-derivable: 339 files classified (data=84, script=149, text=106) with every
|
||||||
|
frozen path present.
|
||||||
|
|
||||||
|
## CHECK
|
||||||
|
|
||||||
|
Single bare command whose exit code is the verdict (0 = correct, nonzero = wrong):
|
||||||
|
|
||||||
|
bash /root/troupe-standup/CHECK-sol-lane-triage-2026-11-02
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Fresh sol-lane triage re-derivation for 2026-11-02.
|
||||||
|
|
||||||
|
Classifies every top-level file of the sol wizard-work directory into a
|
||||||
|
category by extension (with content-sniff fallback), freezes the result into a
|
||||||
|
seed + manifest, and prints the breakdown for the report.
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
REPO = Path(__file__).resolve().parent.parent.parent
|
||||||
|
SRC = REPO / "wizard-work" / "sol"
|
||||||
|
OUT = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
# Rubric table (same as the independent verifier).
|
||||||
|
RULER = {
|
||||||
|
"md": "text", "txt": "text", "rst": "text", "adoc": "text", "org": "text", "log": "text",
|
||||||
|
"json": "data", "csv": "data", "tsv": "data", "yaml": "data", "yml": "data", "toml": "data",
|
||||||
|
"sqlite": "data", "db": "data", "ipynb": "data",
|
||||||
|
"mp3": "media", "wav": "media", "mp4": "media", "webm": "media", "png": "media",
|
||||||
|
"jpg": "media", "jpeg": "media", "gif": "media", "webp": "media", "svg": "media",
|
||||||
|
"py": "script", "sh": "script", "bash": "script", "zsh": "script", "ps1": "script", "bat": "script",
|
||||||
|
"pdf": "doc", "doc": "doc", "docx": "doc", "ppt": "doc", "pptx": "doc", "xls": "doc", "xlsx": "doc",
|
||||||
|
}
|
||||||
|
|
||||||
|
def extension(rel: str) -> str:
|
||||||
|
name = rel.rsplit("/", 1)[-1]
|
||||||
|
if "." in name:
|
||||||
|
return name.rsplit(".", 1)[-1].lower()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def sniff_category(rel: str, ext: str) -> str:
|
||||||
|
"""Content sniff fallback for an extension the ruler does not know."""
|
||||||
|
if ext in RULER:
|
||||||
|
return RULER[ext]
|
||||||
|
p = SRC / rel
|
||||||
|
try:
|
||||||
|
with p.open("rb") as fh:
|
||||||
|
head = fh.read(1024)
|
||||||
|
except OSError:
|
||||||
|
return "other"
|
||||||
|
magics = {
|
||||||
|
"png": "media", "gif": "media", "jpg": "media", "jpeg": "media",
|
||||||
|
"webp": "media", "svg": "text", "pdf": "doc", "zip/pptx": "doc",
|
||||||
|
"db": "data", "sqlite": "data", "mp3": "media", "wav": "media",
|
||||||
|
"mp4": "media", "zip": "data",
|
||||||
|
}
|
||||||
|
for key, cat in magics.items():
|
||||||
|
if key == "zip/pptx":
|
||||||
|
if head.startswith(b"PK\x03\x04"):
|
||||||
|
return cat
|
||||||
|
elif head.startswith(key.encode("ascii")):
|
||||||
|
return cat
|
||||||
|
try:
|
||||||
|
head.decode("utf-8")
|
||||||
|
return "text"
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return "data"
|
||||||
|
|
||||||
|
def classify(rel: str) -> str:
|
||||||
|
ext = extension(rel)
|
||||||
|
return RULER.get(ext, sniff_category(rel, ext))
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
files = []
|
||||||
|
for p in sorted(SRC.iterdir()):
|
||||||
|
if not p.is_file():
|
||||||
|
continue
|
||||||
|
rel = p.name
|
||||||
|
ext = extension(rel)
|
||||||
|
files.append({
|
||||||
|
"rel": rel,
|
||||||
|
"ext": ext,
|
||||||
|
"mtime": p.stat().st_mtime,
|
||||||
|
"size": p.stat().st_size,
|
||||||
|
"category": classify(rel),
|
||||||
|
})
|
||||||
|
files.sort(key=lambda f: f["rel"])
|
||||||
|
|
||||||
|
# Apply the fixed extension ruler now (the generator's "classification").
|
||||||
|
for f in files:
|
||||||
|
f["category"] = RULER.get(f["ext"], f["category"])
|
||||||
|
|
||||||
|
by_category = {}
|
||||||
|
for f in files:
|
||||||
|
by_category[f["category"]] = by_category.get(f["category"], 0) + 1
|
||||||
|
|
||||||
|
seed = {"files": files}
|
||||||
|
manifest = {
|
||||||
|
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||||
|
"total_files": len(files),
|
||||||
|
"by_category": by_category,
|
||||||
|
"files": files,
|
||||||
|
}
|
||||||
|
|
||||||
|
(OUT / "sol-lane-triage-seed-2026-11-02.json").write_text(
|
||||||
|
json.dumps(seed, indent=2) + "\n", encoding="utf-8")
|
||||||
|
(OUT / "sol-lane-triage-2026-11-02.json").write_text(
|
||||||
|
json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
|
||||||
|
|
||||||
|
print(f"total_files={len(files)}")
|
||||||
|
for cat in sorted(by_category):
|
||||||
|
print(f" {cat}: {by_category[cat]}")
|
||||||
|
print(f" by ext: "
|
||||||
|
+ ", ".join(f"{k}={sum(1 for f in files if f['ext']==k)}" for k in sorted({f['ext'] for f in files})))
|
||||||
|
|
||||||
|
# Preserve the seed pure (no generator classification baked in) for the
|
||||||
|
# independent verifier -- it re-derives category from ext alone.
|
||||||
|
seed_pure = {"files": [
|
||||||
|
{"rel": f["rel"], "ext": f["ext"], "mtime": f["mtime"], "size": f["size"]}
|
||||||
|
for f in files
|
||||||
|
]}
|
||||||
|
(OUT / "sol-lane-triage-seed-2026-11-02.json").write_text(
|
||||||
|
json.dumps(seed_pure, indent=2) + "\n", encoding="utf-8")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Independent verifier for sol-lane triage artifact 2026-11-02.
|
||||||
|
|
||||||
|
Exit 0 iff the committed manifest re-derives from the frozen seed and every
|
||||||
|
frozen path still exists as a real, non-ignored file in the repo.
|
||||||
|
|
||||||
|
Design (independent of the generator):
|
||||||
|
* The generator (sol_lane_triage_2026_11_02.py) wrote the seed + manifest.
|
||||||
|
* This verifier re-reads only the seed and the committed manifest, applies
|
||||||
|
the rubric table below to each recorded extension (with content-sniff
|
||||||
|
fallback for extensionless files), and compares.
|
||||||
|
* It also confirms that every frozen path resolves to a real file under the
|
||||||
|
repo and is not ignored by .gitignore.
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
REPO = Path(__file__).resolve().parent.parent.parent
|
||||||
|
SRC = REPO / "wizard-work" / "sol"
|
||||||
|
SEED = REPO / "wizard-work" / "sol" / "sol-lane-triage-seed-2026-11-02.json"
|
||||||
|
MANIFEST = REPO / "wizard-work" / "sol" / "sol-lane-triage-2026-11-02.json"
|
||||||
|
|
||||||
|
# Rubric table re-embedded here so the verifier does not import the generator.
|
||||||
|
RULER = {
|
||||||
|
"md": "text", "txt": "text", "rst": "text", "adoc": "text", "org": "text", "log": "text",
|
||||||
|
"json": "data", "csv": "data", "tsv": "data", "yaml": "data", "yml": "data", "toml": "data",
|
||||||
|
"sqlite": "data", "db": "data", "ipynb": "data",
|
||||||
|
"mp3": "media", "wav": "media", "mp4": "media", "webm": "media", "png": "media",
|
||||||
|
"jpg": "media", "jpeg": "media", "gif": "media", "webp": "media", "svg": "media",
|
||||||
|
"py": "script", "sh": "script", "bash": "script", "zsh": "script", "ps1": "script", "bat": "script",
|
||||||
|
"pdf": "doc", "doc": "doc", "docx": "doc", "ppt": "doc", "pptx": "doc", "xls": "doc", "xlsx": "doc",
|
||||||
|
}
|
||||||
|
# Known binary magic prefixes; used only for extensionless / unknown extensions.
|
||||||
|
KNOWN_MAGICS = {
|
||||||
|
"png": b"\x89PNG", "gif": b"GIF8", "jpg": b"\xff\xf0", "jpeg": b"\xff\xf0",
|
||||||
|
"webp": b"WEBP", "svg": b"<?xml", "pdf": b"%PDF", "zip": b"PK\x03\x04",
|
||||||
|
"db": b"SQLite", "sqlite": b"SQLite",
|
||||||
|
}
|
||||||
|
MAGIC_CATEGORY = {
|
||||||
|
"png": "media", "gif": "media", "jpg": "media", "jpeg": "media",
|
||||||
|
"webp": "media", "svg": "text", "pdf": "doc", "zip": "data",
|
||||||
|
"db": "data", "sqlite": "data",
|
||||||
|
}
|
||||||
|
|
||||||
|
def extension(rel: str) -> str:
|
||||||
|
name = rel.rsplit("/", 1)[-1]
|
||||||
|
return name.rsplit(".", 1)[-1].lower() if "." in name else ""
|
||||||
|
|
||||||
|
def classify(rel: str) -> str:
|
||||||
|
ext = extension(rel)
|
||||||
|
if ext in RULER:
|
||||||
|
return RULER[ext]
|
||||||
|
p = SRC / rel
|
||||||
|
try:
|
||||||
|
with p.open("rb") as fh:
|
||||||
|
head = fh.read(1024)
|
||||||
|
except OSError:
|
||||||
|
return "other"
|
||||||
|
for key, magic in KNOWN_MAGICS.items():
|
||||||
|
if head.startswith(magic):
|
||||||
|
return MAGIC_CATEGORY[key]
|
||||||
|
try:
|
||||||
|
head.decode("utf-8")
|
||||||
|
return "text"
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return "data"
|
||||||
|
|
||||||
|
def is_ignored(rel: str) -> bool:
|
||||||
|
res = subprocess.run(
|
||||||
|
["git", "-C", str(REPO), "check-ignore", "-q", "--", rel],
|
||||||
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||||
|
)
|
||||||
|
return res.returncode == 0
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
problems = []
|
||||||
|
if not SEED.exists():
|
||||||
|
print(f"PROBLEM: seed missing: {SEED}")
|
||||||
|
return 1
|
||||||
|
if not MANIFEST.exists():
|
||||||
|
print(f"PROBLEM: manifest missing: {MANIFEST}")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
seed = json.loads(SEED.read_text(encoding="utf-8"))
|
||||||
|
manifest = json.loads(MANIFEST.read_text(encoding="utf-8"))
|
||||||
|
files = seed.get("files", [])
|
||||||
|
mfiles = manifest.get("files", [])
|
||||||
|
|
||||||
|
# 1. Manifest must match frozen seed exactly (same rel paths).
|
||||||
|
seed_paths = {f["rel"] for f in files}
|
||||||
|
m_paths = {f["rel"] for f in mfiles}
|
||||||
|
if seed_paths != m_paths:
|
||||||
|
problems.append(f"manifest path set != seed: seed={len(seed_paths)} manifest={len(m_paths)}")
|
||||||
|
|
||||||
|
# 2. Every category in the manifest must re-derive by the full classifier
|
||||||
|
# from the recorded extension.
|
||||||
|
for f in mfiles:
|
||||||
|
rel, recorded = f["rel"], f["category"]
|
||||||
|
exp = classify(rel)
|
||||||
|
if exp != recorded:
|
||||||
|
problems.append(f"category mismatch {rel}: classifier says {exp}, manifest says {recorded}")
|
||||||
|
|
||||||
|
# 3. Every frozen path must still exist as a real file and not be ignored.
|
||||||
|
for f in files:
|
||||||
|
p = SRC / f["rel"]
|
||||||
|
if not p.is_file():
|
||||||
|
problems.append(f"missing on disk: {f['rel']}")
|
||||||
|
elif is_ignored(f["rel"]):
|
||||||
|
problems.append(f"ignored by .gitignore: {f['rel']}")
|
||||||
|
|
||||||
|
# 4. Aggregate counts must be self-consistent.
|
||||||
|
counts = {}
|
||||||
|
for f in mfiles:
|
||||||
|
counts[f["category"]] = counts.get(f["category"], 0) + 1
|
||||||
|
if manifest.get("total_files") != len(files):
|
||||||
|
problems.append(f"total_files {manifest.get('total_files')} != seed {len(files)}")
|
||||||
|
if counts != manifest.get("by_category"):
|
||||||
|
problems.append(f"by_category mismatch: seed={counts} manifest={manifest.get('by_category')}")
|
||||||
|
|
||||||
|
if problems:
|
||||||
|
print(f"VERIFY FAIL ({len(problems)} problems)")
|
||||||
|
for pb in problems:
|
||||||
|
print(f" - {pb}")
|
||||||
|
return 1
|
||||||
|
print(f"VERIFY OK ({len(files)} files, categories re-derived, all paths present)")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Reference in new issue
Block a user