Repository navigation
Conversation
… grade optional for dokimi: graders result.json gains `process`, counted by the framework from events.jsonl: tool_calls, commands, failed_commands, denied_commands and guidance_read (read paths the guidance globs match). The manifest's process_metrics maps a name to a regex over command text, output or both; repo validate refuses a regex that does not compile. entry_points.grade is required only when some task's grader is not a built-in dokimi: one. Part of intel#41 (step D4). Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #157 +/- ##
==========================================
+ Coverage 91.54% 91.55% +0.01%
==========================================
Files 222 223 +1
Lines 27369 27423 +54
Branches 4505 4510 +5
==========================================
+ Hits 25054 25108 +54
Misses 1644 1644
Partials 671 671
🚀 New features to boost your workflow:
|
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 343f7ac. The process-metrics code is clean and the counting rules match the contract. Two things are worth fixing before merge: the optional grade entry point has no runtime behind it at this head, and the one runner test cannot tell a working guidance_read / counters wiring from a broken one.
What I ran, on a Linux review host at 343f7ac:
make ci-local: 25 passed, 1 failed, 6 skipped. 6,731 tests, changed-line coverage passes. The failure is pip-audit on virtualenv 21.14.7 (CVE-2026-113722) from the existing locks, fixed onmainby #152.- A reproduction of the first finding through
repo runwith the container runner faked. - A mutation run: 48 mutants of
process_metrics.py,manifest.pyandrunner.pyagainst the three test files that cover them; 18 survive, 17 of them real gaps (the second finding).
Checked, no issues
- Schema: dropping
required: ["grade"]only widensrepo_manifest.v1;process_metricsis validated by both the schema andparse_counter. - Counting rules:
failed_commandsignoresrcnull, denied commands still reach the counters, bad regex / badmatch/ bad name are refused with the metric named. - Offline: the new tests need no network or Docker.
| return report | ||
|
|
||
|
|
||
| def grade_problems(manifest: RepoManifest, tasks: list[TaskSummary]) -> list[str]: |
There was a problem hiding this comment.
A manifest without entry_points.grade and with only dokimi: graders passes repo validate, then every cell of repo run fails as a grader failure.
grade_problems returns [] for such a manifest, but nothing at this head runs a dokimi: grader. run_cell still calls run_entry(ctx, "grade", ...) (runner.py:216), and run_entry raises when the entry point is missing (grading.py:107). grep -rn 'dokimi:' dokimi/dokimi --include=*.py finds only the new BUILTIN_GRADER_PREFIX.
Reproduction: take the test_repo_run.py fixture, remove entry_points.grade, change the task graders to dokimi:calc, and run repo run --task fix_add. The cell's result.json grade is:
{"pass": null, "rc": 125, "status": "grader_failure", "success": false,
"reasons": ["grade run failed: the manifest declares no `grade` entry point"]}
The description says the rule holds whether or not #120 lands first. It holds for validate, but not for run: a repository can pass validation and then pay for agent runs that all fail grading.
Suggestion: land this after the PR that adds the built-in grader dispatch, or keep grade required until then. If the PR stays as it is, add a test that runs a cell with a dokimi: grader and no grade entry point, so the gap is visible. The contract text at repo-evaluation-contract.md:197 also describes a built-in grader that does not exist at this head.
There was a problem hiding this comment.
Resolved by merging intel/main (d9c92f4), which brings the #120 built-in grader dispatch: run_entry runs a dokimi: grader without entry_points.grade, so no runner change is needed. Pinned in 3c8a0cc by test_a_cell_graded_by_a_builtin_grader_needs_no_grade_entry_point (repo run on a manifest with no entry points, cell status graded).
| assert result["grade"]["status"] == "graded" and result["grade"]["success"] is True | ||
| assert result["agent"]["cost_usd"] == 0.01 and result["agent"]["num_turns"] == 3 | ||
| assert result["model_resolved"] == "m-1" | ||
| assert result["process"] == {"tool_calls": 1, "commands": 0, "failed_commands": 0, "denied_commands": 0, |
There was a problem hiding this comment.
The runner test cannot tell a working guidance_read / counters wiring from a broken one.
The fixture manifest has no counters and its trace reads no guidance file, so the assertion expects "guidance_read": [] and "counters": {}. run_process_metrics (runner.py:236) is therefore unpinned.
Mutation check: each of these passes test_repo_process_metrics.py, test_repo_manifest.py and test_repo_run.py (194 tests):
is_guidanceaslambda path: False, and aslambda path: True;globs = ();ctx.manifest.process_metricsreplaced by{};process = {}in place ofNonefor an unreadable trace.
Three smaller gaps in test_repo_process_metrics.py also survive:
match: anythat searches only the text (x_anywhere, line 58, already matches both commands by text, so the output half is never needed);- counters run over all events instead of
commandevents, since no non-command event in the fixture carriestextoroutput; failed_commandscounting onlyrc == 1orrc > 0, since no test uses another non-zerorc.
Suggestion: give the fixture manifest one process_metrics entry and one guidance glob, add a trace that reads a matching file, and assert non-empty guidance_read and counters in result.json. Make x_anywhere match only the output. Add a read event with a text field, an rc of -9, and a trace that fails to convert (process is None).
There was a problem hiding this comment.
Added in 3c8a0cc: the fixture manifest has process_metrics (text and output counters) and the guidance glob; test_process_metrics_reach_result_json asserts non-empty guidance_read and counters in result.json, and test_an_unreadable_trace_leaves_process_null_and_still_grades covers process: null. Unit tests: test_any_matches_the_output_when_the_text_does_not, test_counters_search_command_events_only, test_failed_commands_counts_every_non_zero_rc (rc 2, -9, 137). I did not re-run the mutation set.
… cell without a grade entry point The runner fixture now has process_metrics and a guidance glob, with a trace that reads a guidance file and runs a failing command; a null process for an unreadable trace is covered. Process-metric unit tests gain output-only 'any' matches, command-only counting and non-1 rc values. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Part of #41 (step D4).
Summary
dokimi/repos/process_metrics.py; counts all events (parent and subagents).failed_commands=rcnot 0/null; denied commands still count for counters (the agent asked for them), as in oneDAL'smetrics.py.repo validaterefuses a regex that does not compile, a badmatch, a bad name;process_metricsneeds a runnable manifest.entry_points.gradeno longer schema-required (widening, v1 in place);check_reporequires it only when some task'sgraderdoes not start withdokimi:, and names those tasks. Generic, so it holds whether or not feat(repos): built-in review graders dokimi:review_seeds and dokimi:review_replay #120 lands first.host:blocks were already validated byrepo validate(feat(repo): task host requirements, unsupported instead of a false pass (#41 D3) #112); added a test that pins it.result.jsonprocesstable. Nothing in §3/§5/§8.Evidence
result.jsonhas noprocess; oneDAL recomputes counts in its ownmetrics.py; a manifest withoutentry_points.gradefails the schema.tests/test_repo_process_metrics.py(each metric, counter fields, 6 regex/shape refusals, grade-optional rule, host validation) andtest_repo_run.pyassertingresult["process"]on a real cell.make ci-local --offline: 0 failed, 15 passed, 11 skipped (network/docker).git merge-treeagainst repo scan: L0 rules for parity with oneDAL static_check (D6) #115 and feat(repos): built-in review graders dokimi:review_seeds and dokimi:review_replay #120 heads: clean.Merge Danger
Door: two-way
Additive key in
result.json; schema widened only.Blast Radius: small
Readers of
result.jsonthat reject unknown keys would seeprocess; none in-tree.Checklist
🤖 Generated with Claude Code