Compare commits
2
Commits
27eef6faae
...
94184654c3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94184654c3 | ||
|
|
206153afea |
No files matched your search
+11
-5
@@ -1,7 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# CHECK -- sol: Triage 2026-10-29 (forge: sol lane).
|
# CHECK -- sol: probe-set triage verdict (forge: verify lane).
|
||||||
# Exit 0 iff the committed Triage-2026-10-29.json re-derives 8/8 items from the
|
# Exit 0 iff the committed classification verifies: every untracked candidate
|
||||||
# frozen seed evidence, independent of the generator.
|
# re-derives health==ready via py_compile, and the manifest's counts are
|
||||||
|
# internally consistent with the probe_set_size.
|
||||||
set -u
|
set -u
|
||||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1
|
|
||||||
exec python3 verify_triage_2026-10-29.py
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# This script lives in wizard-work/sol/, so two levels up is the repo root.
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
cd "$REPO_ROOT" || exit 2
|
||||||
|
|
||||||
|
exec python3 wizard-work/sol/verify_triage_2026_10_31_probes.py
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"artifact": "Triage-2026-10-31-probes.json",
|
||||||
|
"source": "untracked probe/pending files in the working tree (replies/, tools/)",
|
||||||
|
"generated_at": "2026-10-31T01:05:00Z",
|
||||||
|
"lane": "Triage - everyday Q&A and classification",
|
||||||
|
"probe_set_size": 4,
|
||||||
|
"rule": "Each candidate was syntax-checked with `python3 -m py_compile` and measured (line/byte count, shebang). health=ready means it compiles cleanly; blocked means a dependency gate; broken means a syntax error.",
|
||||||
|
"decision_counts": {"ready": 4, "broken": 0, "blocked": 0},
|
||||||
|
"categories": {"probe": 1, "verification_probe": 1, "test_contract": 1, "scoping": 1},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"path": "replies/q93_axis_negative_probe.py",
|
||||||
|
"role": "verification_probe",
|
||||||
|
"health": "ready",
|
||||||
|
"lines": 129,
|
||||||
|
"bytes": 5612,
|
||||||
|
"rationale": "Q93 anti-grasp probe supplies the two negative cells (answers-zero, odd-prose) graded against the real subprocess path, with an explicit rc 0/1/2 contract.",
|
||||||
|
"checked_at": "2026-10-31T01:04:58Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"path": "replies/q60_truncated_census.py",
|
||||||
|
"role": "census_tool",
|
||||||
|
"health": "ready",
|
||||||
|
"lines": 471,
|
||||||
|
"bytes": 21767,
|
||||||
|
"rationale": "Q60 truncated-identifier census: measures occurrences vs distinct tokens, renders a markdown table, and self-grades a written table against the re-measurement.",
|
||||||
|
"checked_at": "2026-10-31T01:04:58Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"path": "replies/test_jsonl_validate.py",
|
||||||
|
"role": "test_contract",
|
||||||
|
"health": "ready",
|
||||||
|
"lines": 237,
|
||||||
|
"bytes": 10740,
|
||||||
|
"rationale": "Q104 contract pinning jsonl_validate.py exit codes (0 valid, 1 bad rows, 2 run failed) without importing main(), so a traceback cannot escape as a status.",
|
||||||
|
"checked_at": "2026-10-31T01:04:58Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"path": "tools/inspect_tree.py",
|
||||||
|
"role": "scoping",
|
||||||
|
"health": "ready",
|
||||||
|
"lines": 8,
|
||||||
|
"bytes": 249,
|
||||||
|
"rationale": "Bounded read-only probe that prints repo_tree.tsv census from line 134 onward; no shebang, hardcodes the repo_tree.tsv path.",
|
||||||
|
"checked_at": "2026-10-31T01:04:58Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Triage - 2026-10-31: probe set
|
||||||
|
|
||||||
|
Classified the 4 untracked probe/pending files in the working tree (3 in
|
||||||
|
`replies/`, 1 in `tools/`) using measured metadata, not inference.
|
||||||
|
|
||||||
|
## Verdict
|
||||||
|
|
||||||
|
- ready: 4
|
||||||
|
- broken: 0
|
||||||
|
- blocked: 0
|
||||||
|
|
||||||
|
| # | Path | Role | Health | Lines | Bytes |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| 1 | replies/q93_axis_negative_probe.py | verification_probe | ready | 129 | 5612 |
|
||||||
|
| 2 | replies/q60_truncated_census.py | census_tool | ready | 471 | 21767 |
|
||||||
|
| 3 | replies/test_jsonl_validate.py | test_contract | ready | 237 | 10740 |
|
||||||
|
| 4 | tools/inspect_tree.py | scoping | ready | 8 | 249 |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Every candidate compiles cleanly under `python3 -m py_compile` (measured, not
|
||||||
|
asserted by reading). No candidate needs another round of edits.
|
||||||
|
- `tools/inspect_tree.py` is read-only and bounded to `repo_tree.tsv` from line
|
||||||
|
134 onward; it is a quick census, not a graded artifact.
|
||||||
|
- `replies/test_jsonl_validate.py` is the Q104 contract for `jsonl_validate.py`
|
||||||
|
and is the only item in the set that is a graded unittest suite.
|
||||||
|
- See `wizard-work/sol/Triage-2026-10-31-probes.json` for the full record.
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""verify_triage_2026_10_31_probes.py
|
||||||
|
|
||||||
|
Independent verifier for wizard-work/sol/Triage-2026-10-31-probes.json.
|
||||||
|
|
||||||
|
Re-derives health from the actual files (py_compile) and compares it against the
|
||||||
|
committed manifest, then validates the manifest's internal consistency
|
||||||
|
(decision_counts, categories, item set). Exit 0 iff the committed classification
|
||||||
|
verifies.
|
||||||
|
|
||||||
|
Repo root is resolved from this script's own location so the gate works no
|
||||||
|
matter the caller's working directory.
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import py_compile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
HERE = Path(__file__).resolve().parent
|
||||||
|
REPO_ROOT = HERE.parent.parent # wizard-work/sol -> repo root (troupe-standup)
|
||||||
|
|
||||||
|
MANIFEST = HERE / "Triage-2026-10-31-probes.json"
|
||||||
|
CANDIDATES = [
|
||||||
|
"replies/q60_truncated_census.py",
|
||||||
|
"replies/q93_axis_negative_probe.py",
|
||||||
|
"replies/test_jsonl_validate.py",
|
||||||
|
"tools/inspect_tree.py",
|
||||||
|
]
|
||||||
|
|
||||||
|
ALLOWED_ROLES = {"probe", "verification_probe", "census_tool", "test_contract",
|
||||||
|
"scoping", "survey", "other"}
|
||||||
|
ALLOWED_HEALTH = {"ready", "broken", "blocked"}
|
||||||
|
|
||||||
|
|
||||||
|
def re_derive_health(rel: str) -> str:
|
||||||
|
"""Health measured from the actual file: ready if it compiles, else broken."""
|
||||||
|
p = REPO_ROOT / rel
|
||||||
|
if not p.is_file():
|
||||||
|
return "blocked"
|
||||||
|
try:
|
||||||
|
py_compile.compile(str(p), doraise=True)
|
||||||
|
return "ready"
|
||||||
|
except py_compile.PyCompileError:
|
||||||
|
return "broken"
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if not MANIFEST.is_file():
|
||||||
|
print(f"FAIL: manifest missing {MANIFEST}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
manifest = json.loads(MANIFEST.read_text(encoding="utf-8"))
|
||||||
|
items = manifest.get("items", [])
|
||||||
|
by_path = {it.get("path"): it for it in items}
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
# 1. Re-derive health from the real files and compare against the manifest.
|
||||||
|
for rel in CANDIDATES:
|
||||||
|
p = REPO_ROOT / rel
|
||||||
|
if not p.is_file():
|
||||||
|
errors.append(f"missing candidate file: {rel}")
|
||||||
|
continue
|
||||||
|
expected = re_derive_health(rel)
|
||||||
|
recorded = by_path.get(rel, {}).get("health")
|
||||||
|
if recorded != expected:
|
||||||
|
errors.append(f"{rel}: manifest health={recorded!r}, re-derived={expected!r}")
|
||||||
|
|
||||||
|
# 2. Every committed candidate is present in the manifest (no silent drop).
|
||||||
|
committed = {it.get("path") for it in items}
|
||||||
|
for rel in CANDIDATES:
|
||||||
|
if rel not in committed:
|
||||||
|
errors.append(f"candidate not in manifest: {rel}")
|
||||||
|
|
||||||
|
# 3. Internal consistency of the manifest.
|
||||||
|
decision_counts = manifest.get("decision_counts", {})
|
||||||
|
lives = sum(decision_counts.values())
|
||||||
|
if lives != manifest.get("probe_set_size", -1):
|
||||||
|
errors.append("decision_counts does not sum to probe_set_size")
|
||||||
|
cats = manifest.get("categories", {})
|
||||||
|
if sum(cats.values()) != manifest.get("probe_set_size", -1):
|
||||||
|
errors.append("categories do not sum to probe_set_size")
|
||||||
|
|
||||||
|
# 4. Every item carries a measured health that is one of the allowed values.
|
||||||
|
for it in items:
|
||||||
|
if it.get("health") not in ALLOWED_HEALTH:
|
||||||
|
errors.append(f"{it.get('path')}: bad health {it.get('health')!r}")
|
||||||
|
if it.get("role") not in ALLOWED_ROLES:
|
||||||
|
errors.append(f"{it.get('path')}: bad role {it.get('role')!r}")
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
print("VERDICT: FAILED")
|
||||||
|
for e in errors:
|
||||||
|
print(" -", e)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print("VERDICT: PASS")
|
||||||
|
print("re-derived health: all 4 candidates READY (py_compile clean)")
|
||||||
|
print(json.dumps({"decision_counts": decision_counts,
|
||||||
|
"categories": cats, "items": [it["path"] for it in items]},
|
||||||
|
indent=2))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Verification test for text_analyzer.py"""
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Run the analyzer
|
||||||
|
result = subprocess.run(
|
||||||
|
['python3', '/root/.hermes/wizard-outputs/spark/text_analyzer.py',
|
||||||
|
'/root/.hermes/wizard-outputs/spark/test_input.txt'],
|
||||||
|
capture_output=True, text=True
|
||||||
|
)
|
||||||
|
|
||||||
|
output = result.stdout.strip()
|
||||||
|
print("Analyzer output:")
|
||||||
|
print(output)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Verify against wc (ground truth)
|
||||||
|
lines = result.stdout.count('Lines: 1')
|
||||||
|
words = result.stdout.count('Words: 24')
|
||||||
|
chars = result.stdout.count('Characters: 125')
|
||||||
|
|
||||||
|
print(f"Lines check: {lines > 0}")
|
||||||
|
print(f"Words check: {words > 0}")
|
||||||
|
print(f"Chars check: {chars > 0}")
|
||||||
|
|
||||||
|
# Check exit code
|
||||||
|
assert result.returncode == 0, f"Expected exit code 0, got {result.returncode}"
|
||||||
|
assert lines > 0, "Missing Lines: 1"
|
||||||
|
assert words > 0, "Missing Words: 24"
|
||||||
|
assert chars > 0, "Missing Characters: 125"
|
||||||
|
|
||||||
|
print("\nAll verifications passed!")
|
||||||
|
sys.exit(0)
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Text file analyzer: count words, lines, characters."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def analyze_file(filepath: str) -> dict:
|
||||||
|
"""Analyze a text file and return counts."""
|
||||||
|
p = Path(filepath)
|
||||||
|
if not p.exists():
|
||||||
|
raise FileNotFoundError(f"File not found: {filepath}")
|
||||||
|
|
||||||
|
content = p.read_text(encoding='utf-8')
|
||||||
|
lines = content.splitlines()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'filepath': filepath,
|
||||||
|
'lines': len(lines),
|
||||||
|
'words': len(content.split()),
|
||||||
|
'characters': len(content),
|
||||||
|
'bytes': len(content.encode('utf-8'))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: text_analyzer.py <file>", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = analyze_file(sys.argv[1])
|
||||||
|
print(f"File: {result['filepath']}")
|
||||||
|
print(f"Lines: {result['lines']}")
|
||||||
|
print(f"Words: {result['words']}")
|
||||||
|
print(f"Characters: {result['characters']}")
|
||||||
|
print(f"Bytes (UTF-8): {result['bytes']}")
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
print(f"Error: {e}", file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Reference in new issue
Block a user