Name the line budget as a gate, even while it fails
p1-6's acceptance names bench/filesize_check, and the file did not exist: the 500-line rule was enforced by memory. It now runs, and it fails on training.py 1639, benchmarks.py 619, bench/run.py 609 and db.py 503. That is the honest state of the tree, not a passing gate invented after the work. The console work passed independent review on round three: the reviewer re-ran the smoke, then broke the pager three ways and watched each break go red - a pager that does nothing, a pager that appends, and a Previous button that stops restoring.
This commit is contained in:
1 parent
b0895eb36f
commit
330e801e92
2 files changed
+54
No files matched your search
@@ -317,6 +317,7 @@
|
||||
- 独立 review(herdr 里的 pi,模型 `strata/qwen3.8-flash-next-abliterated-iq3_s:high`)。第 1 轮 FAIL 两条,都在我那条提交里:`schemas.py` 被我从 498 顶到 534 行,破了「单文件 ≤500 行」;同一提交净增 3 条多行 docstring(114→117)。修在 `6df713d`:自报家族(`CacheLayerStatus`/`MemoryStatus`/`RuntimeStatus`/三个 state 别名/`SenseStatus`/`SystemStatus`)搬进 `backend/src/ely_eye/status_schemas.py`(它只需要 `schemas.py` 的 `TrainingAdapterKind`,反向不依赖),schemas.py 回到 469;三条 docstring 各压成一行,全仓多行 docstring 回到 114,与父提交同数。
|
||||
- 第 2 轮 FAIL 三条:① **翻页其实没被测到**——E2E 等的是「行数变化」,而搜索列表与浏览列表共用 `.atom-row`,那一刻的 13 行里有一条是搜索命中;把 `nextPage()` 里的 `setCursor`+`loadBrowse` 删掉、或把翻页改成追加而不是替换,E2E 都还 PASS。改成 `data-testid="browse-list"` + 每行 `data-atom`,断言第一页正好 12 行、下一页零重叠、末页 = `total−12`、Prev 复原;两个变异现在各自红:`Next page did not swap the page: the pager is not paging` 与 `the next page repeated 12 of 12 atoms from the first page` ② CHECKLIST 写 `App.tsx`「130 行的壳」,`wc -l` 是 131 ③ CHECKLIST 引的拒绝挂载原文被 smoke 的 `.slice(0,120)` 砍掉了后半句 `; set ELY_EYE_MODEL_DIR to the model snapshot`,改成 slice 200 并照原文记。
|
||||
- 同一轮实测为真:263 passed;ruff 干净;全仓 mypy 24 错/6 文件(净新增 0);go build/vet/test+gofmt 干净;`npm run build`+`eslint .` 干净;`ui_smoke.sh` PASS(4.0s);`mcp_write_smoke.sh` PASS(3.2s);30 条路由与 `HTTP_SURFACE` 一致;senses 单一真相(`api.py:52/:105` 与 `maintenance.py:238` 都只渲染 `sense_facts()`);26 个 `types.ts` 接口对着 pydantic 模型逐个 diff 零编造字段;8 条被删路由无人引用,它们背后的函数都还从 CLI/proof 可达。pyright 在那 8 个文件:reviewer 的工作树 **0 errors**,我这棵树多两条 `runtime.py:283` 的 tuple 告警——它只在 `qwen_vl_utils` 那个无类型导入被解析时出现,HEAD 的副本同样有,不是本轮引入;两边都不是新增。
|
||||
- 第 3 轮 **PASS**(`9f91ff7..b0895eb`,~40 条 shell / 14 次工具调用,本轮 34 分钟)。reviewer 是跑过不是读过:`ui_smoke.sh` exit 0(4.26s,拒绝挂载整句可见);三个变异各自红——删 `nextPage()` 的 setCursor+loadBrowse → `the pager is not paging`,翻页改追加 → `repeated 12 of 12`,它自己加的第三个(删 `previousPage()` 的复原)→ `Timeout 15000ms`;改完 `git checkout` 后回到 exit 0。门禁重跑:263 passed、npm build+lint 干净、go build/vet/test+gofmt 干净、`mcp_write_smoke.sh` PASS 3.26s、ruff 干净、mypy 冷缓存查 8 个文件 Success、全仓 mypy 24 错/6 文件。数字全对:schemas.py 469、status_schemas.py 74(只从 schemas 拿 `TrainingAdapterKind`,反向无导入)、多行 docstring 114、App.tsx 131、拒绝文案与 `cartridge.py:169-173` 逐字一致、30 条路由与 `HTTP_SURFACE` 完全相等且 8 条删掉的都报 gone、`PAGE_SIZE=12` 两处同值、末页 135−12=123 行、`types.ts` 26 个接口、前端最大文件 `styles.css` 492。它同时指出两点不是缺陷但记着:`PAGE_SIZE` 是手拄到 harness 的(组件改了会变红不会变绿,已在记录里写明);末页的 `total−12` 读的是未过滤的 `GET /api/atoms?limit=1`,只对是因为前一行刚好把 modality 清掉了。
|
||||
- [ ] **p1-6** 代码卫生
|
||||
- [ ] p1-6.1 `evals.py` 2413 行拆到 ≤500 行/文件
|
||||
- [ ] p1-6.2 删 dead code 与未调用函数
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
"""Fail when a tracked source file outgrows the line budget the repo agreed to."""
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
LINE_LIMIT = 500
|
||||
CODE_SUFFIXES = (".py", ".go", ".ts", ".tsx", ".mjs", ".css", ".sh", ".ps1")
|
||||
|
||||
|
||||
def tracked_files() -> list[Path]:
|
||||
"""Every file git tracks under the repository root."""
|
||||
listing = subprocess.run(
|
||||
["git", "ls-files"],
|
||||
cwd=Path(__file__).resolve().parents[1],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
if listing.returncode != 0:
|
||||
raise SystemExit(f"git ls-files failed: {listing.stderr.strip()}")
|
||||
return [Path(name) for name in listing.stdout.split() if name.endswith(CODE_SUFFIXES)]
|
||||
|
||||
|
||||
def line_count(path: Path) -> int:
|
||||
return len(path.read_text(encoding="utf-8", errors="replace").splitlines())
|
||||
|
||||
|
||||
def offenders(root: Path, files: list[Path] | None = None) -> list[tuple[int, str]]:
|
||||
"""Files over the budget, biggest first."""
|
||||
rows: list[tuple[int, str]] = []
|
||||
for name in files if files is not None else tracked_files():
|
||||
path = root / name
|
||||
if not path.is_file():
|
||||
continue
|
||||
lines = line_count(path)
|
||||
if lines > LINE_LIMIT:
|
||||
rows.append((lines, str(name)))
|
||||
return sorted(rows, reverse=True)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
over = offenders(root)
|
||||
if not over:
|
||||
print(f"OK: no tracked source file exceeds {LINE_LIMIT} lines")
|
||||
return
|
||||
for lines, name in over:
|
||||
print(f"{lines:5d} {name}")
|
||||
raise SystemExit(f"{len(over)} files exceed the {LINE_LIMIT}-line budget")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user