#245 "Dangerously lazy": add an operational "fix the root cause, not the symptom" directive — grep every caller of the function you touch and fix the shared function once (the smaller diff). Validated on the agentic benchmark: on a shared-helper bug-fix trap, baseline fixes the root cause 1/6 while ponytail does 6/6 on both Sonnet 4.6 (the model the issue was filed on) and Opus 4.8, verified by reading the produced code. Plain prose ("trace the flow") did not move it; the actionable, lazy-framed directive did. #217 "Missing rung": add ladder rung 2 "Already in this codebase? Reuse it, don't re-write it." Propagated across SKILL.md, AGENTS.md, all agent mirror copies, the hook fallback, and both READMEs (check-rule-copies passes). Benchmark: 4 new deterministic quality-tier tasks (reuse-slug, reuse-money, trace-transfer, trace-amount) with selftest-proven good/bad refs; harness gains multi-file seed support in --selftest, distinctive-behaviour reuse detection, and counts in-file __main__/demo() self-checks as test LOC (not source bloat) for surgical tasks. Full writeup in benchmarks/results/2026-06-22-issue-245-217-comprehension.md. Also carries the in-progress todo-null benchmark task already present in the working tree. Co-authored-by: Dietrich Gebert <dgebert@Dietrichs-MacBook-Pro.local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Dietrich Gebert
Claude Opus 4.8
parent
6da37bfa7d
commit
dedc97ca7c
@@ -89,11 +89,40 @@ def _count(p: Path, with_comments: bool):
|
||||
n += 1
|
||||
return n
|
||||
|
||||
def code_stats(workdir: Path):
|
||||
_SELFCHECK_DEFS = ("def demo(", "def _demo(", "def selfcheck(", "def _selfcheck(",
|
||||
"def _check(", "def _smoke(", "def smoke(")
|
||||
def _selfcheck_split(p: Path):
|
||||
"""Split a produced .py file at the first TOP-LEVEL self-check marker (a `__main__` guard or a
|
||||
demo()/selfcheck() function) through end of file. Returns (src_total, src_code, sc_total,
|
||||
sc_code), counted like _count. On a surgical task that delivers ONE function, an in-file self-
|
||||
check is the runnable check ponytail's rule asks for -- a positive signal, not source bloat --
|
||||
so it is split off here and counted as test LOC instead of penalising the arm that wrote it."""
|
||||
try: lines = p.read_text(encoding="utf-8", errors="ignore").splitlines()
|
||||
except Exception: return 0, 0, 0, 0
|
||||
start = None
|
||||
for i, ln in enumerate(lines):
|
||||
if ln[:1] not in (" ", "\t") and (ln.startswith("if __name__") or ln.startswith(_SELFCHECK_DEFS)):
|
||||
start = i; break
|
||||
def cnt(seq):
|
||||
t = c = 0
|
||||
for ln in seq:
|
||||
s = ln.strip()
|
||||
if not s: continue
|
||||
t += 1
|
||||
if not s.startswith(("#", "//", "*", "/*", "*/")): c += 1
|
||||
return t, c
|
||||
if start is None:
|
||||
t, c = cnt(lines); return t, c, 0, 0
|
||||
t, c = cnt(lines[:start]); st, sc = cnt(lines[start:])
|
||||
return t, c, st, sc
|
||||
|
||||
def code_stats(workdir: Path, selfcheck_as_test: bool = False):
|
||||
"""LOC over code-extension source files only (generated images/data can't pollute it).
|
||||
total_loc counts every non-blank line including comments and docstrings -- the bloat a vibe
|
||||
baseline actually produces. src_loc is code-only, for the breakdown. Tests tracked separately,
|
||||
never as bloat."""
|
||||
never as bloat. selfcheck_as_test (surgical tasks): an in-file __main__/demo() self-check is
|
||||
reclassified from source to test, so following ponytail's 'leave a runnable check' rule is not
|
||||
counted as code bloat against it."""
|
||||
fixture = set() # files that were seeded, not delivered
|
||||
fm = workdir / "_fixture_files.json"
|
||||
if fm.exists():
|
||||
@@ -105,10 +134,19 @@ def code_stats(workdir: Path):
|
||||
and not p.name.startswith((".", "_")) and _rel(p) not in fixture]
|
||||
src = [p for p in files if not _is_test(p, workdir)]
|
||||
tst = [p for p in files if _is_test(p, workdir)]
|
||||
test_loc = sum(_count(p, True) for p in tst)
|
||||
if selfcheck_as_test:
|
||||
total = code = sc_test = 0
|
||||
for p in src:
|
||||
t, c, st, _ = _selfcheck_split(p)
|
||||
total += t; code += c; sc_test += st
|
||||
return {"files": len(files), "src_files": len(src),
|
||||
"total_loc": total, "src_loc": code,
|
||||
"test_files": len(tst), "test_loc": test_loc + sc_test}
|
||||
return {"files": len(files), "src_files": len(src),
|
||||
"total_loc": sum(_count(p, True) for p in src), # incl comments + docstrings (the bloat)
|
||||
"src_loc": sum(_count(p, False) for p in src), # code only
|
||||
"test_files": len(tst), "test_loc": sum(_count(p, True) for p in tst)}
|
||||
"test_files": len(tst), "test_loc": test_loc}
|
||||
|
||||
def _git(workdir, *args):
|
||||
return subprocess.run([shutil.which("git") or "git", *args], cwd=str(workdir),
|
||||
@@ -151,7 +189,9 @@ def selftest():
|
||||
axis = task.get("axis", "safe")
|
||||
for kind in ("good", "bad"):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
(Path(d) / task["file"]).write_text(task[kind], encoding="utf-8")
|
||||
for fn, content in task.get("seed", {}).items(): # seed siblings (a helper module
|
||||
(Path(d) / fn).write_text(content, encoding="utf-8") # the ref imports) too
|
||||
(Path(d) / task["file"]).write_text(task[kind], encoding="utf-8") # entry = the ref
|
||||
r = task["score"](Path(d))
|
||||
ok = (r["correct"] == 1 and r["safe"] == 1) if kind == "good" else (r[axis] == 0)
|
||||
print(f"{'ok ' if ok else 'XX '} {tid:12} {kind:4} correct={r['correct']} "
|
||||
@@ -205,7 +245,8 @@ def score_workspace(task_id, arm, model, workdir: Path):
|
||||
"cache_tokens": (u.get("cache_read_input_tokens") or 0) + (u.get("cache_creation_input_tokens") or 0)}
|
||||
result_text = j.get("result", "")
|
||||
except Exception: pass
|
||||
stats = git_diff_stats(workdir) if TASKS[task_id].get("fixture") else code_stats(workdir)
|
||||
surgical = not TASKS[task_id].get("open") and not TASKS[task_id].get("fixture")
|
||||
stats = git_diff_stats(workdir) if TASKS[task_id].get("fixture") else code_stats(workdir, selfcheck_as_test=surgical)
|
||||
# open/explain tasks answer in the chat, not a file. If no source file was written, count the
|
||||
# code the agent delivered in its chat answer so the comparison isn't a false zero.
|
||||
if TASKS[task_id].get("open") and stats["total_loc"] == 0 and result_text:
|
||||
|
||||
Reference in New Issue
Block a user