Repository navigation
Conversation
CLI interface change detectedThis PR changes dokimi's user-facing CLI surface (commands and/or options): + added command `dokimi eval tasks generate`
+ argument `source`
+ option `--cache-dir`
+ option `--derives`
+ option `--dry-run`
+ option `--force`
+ option `--from`
+ option `--help/-h`
+ option `--index`
+ option `--max-turns`
+ option `--out`
+ option `--references`
+ option `--seed`Updated on every push; the |
|
OpenCodeReview: Commit 6f77801 was not reviewed. This PR has reached its review limit (6 reviews). CI at `6f77801`: 8 still running, 3 passing, 1 skipped
To review this commit: re-request review from exai-bot in the Reviewers list. <details><summary>Last review (246593a): 1 medium</summary> Open threads from the bot: 0 </details> |
There was a problem hiding this comment.
🟡 Changes recommended
Namespace stripping conflates distinct subclasses, while scope lookup misattributes class-body and same-line method references, producing incorrect gold answers and scoring.
3 open issues
What changed in this PR
3 new findings.
This PR extends dokimi’s repository evaluation flow with eval tasks generate --from graph, building enumeration tasks from a SCIP index of a pinned revision without an LLM or Docker.
Changes:
- Adds seeded task generation for function references and direct subclasses.
- Introduces the
dokimi:graph_enumgrader with F1 scoring and answer normalization. - Registers the CLI command and updates documentation, interface snapshots, and tests.
| File | Description |
|---|---|
dokimi/tests/test_repo_inspect_structure.py |
Updates tests for public helper names. |
dokimi/tests/test_eval_tasks_generate_graph.py |
Tests generation, grading, and CLI behavior. |
dokimi/tests/data/cli_flags_allowlist.txt |
Allows task-count flags. |
dokimi/dokimi/repos/graph_tasks.py |
Plans and writes index-derived tasks. |
dokimi/dokimi/repos/graders/main.py |
Registers graph grading and oracle execution. |
dokimi/dokimi/repos/graders/graph.py |
Implements enumeration scoring and normalization. |
dokimi/dokimi/repos/graders/__init__.py |
Registers the grader and its gold file. |
dokimi/dokimi/repos/environment/structure.py |
Exposes two shared filtering helpers. |
dokimi/dokimi/repos/code_index/symbols.py |
Exposes descriptor names and kinds. |
dokimi/dokimi/repos/code_index/index.py |
Adds symbol enumeration and unreduced bases. |
dokimi/dokimi/commands/tasks.py |
Wires task generation into the CLI. |
dokimi/dokimi/commands/tasks_generate.py |
Implements generation options and command handling. |
dokimi/dokimi/cli_routes.py |
Marks generation as a free operation. |
dokimi/docs/repo-evaluation-contract.md |
Documents task generation and grading semantics. |
dokimi/docs/reference/cli-interface.json |
Records the new command’s interface. |
dokimi/docs/architecture.md |
Describes the graph-task module’s role. |
dokimi/changelog.d/20261104_120000_napetrov_eval-tasks-generate-graph.md |
Announces graph task generation and grading. |
Review effort: Balanced
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #399 +/- ##
==========================================
+ Coverage 94.76% 94.79% +0.03%
==========================================
Files 352 357 +5
Lines 46407 47071 +664
Branches 7949 8056 +107
==========================================
+ Hits 43978 44623 +645
- Misses 1539 1552 +13
- Partials 890 896 +6
🚀 New features to boost your workflow:
|
|
Bot review run marker with no finding text, so nothing to answer. No change. Bot review run marker with no finding text, so nothing to answer. No change. The CLI-surface change is intended: Coverage-tool notice, not a review finding. No change. |
…a SCIP index Writes dokimi:graph_enum tasks with gold read from a code index of a pinned revision: which files (or functions) reference a function, which classes derive directly from a class. No LLM, no docker. The new built-in grader scores F1 against the gold; exclude and accepted lists keep the defining files and a person's additions out of the count. Contract §4.7. Part of intel#41. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…-file method names Self-review fixes: an id is graph_<kind>_<name>_<hash> over the target's symbols, so another seed or revision never reuses a directory for another target; overloads that share a qualified name are one target; function gold names methods as Class.method and the grader reads Class::m() and a unique bare name as the same item. callers is renamed references (the question counts any reference). accepted takes a class's second defining file and a class a scip-clang base reduction dropped. The grader keeps a repo/ path segment, validates gold.json, and code_index records the index sha256. Part of intel#41. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…ames drop namespaces A bare or shorter name in an answer maps to the one gold item of its file whose dotted name ends with it (run -> A.run, Impl -> ns.Impl); B.run no longer maps to A.run. in_file_name keeps every descriptor after the leading namespaces, so a C++ method outside any namespace keeps its class. Hash the index file in chunks. Contract 4.7: say a scip-clang grandchild can land in accepted and that the id hash covers the package version. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
… or outside the tree too Naming such a class was a false positive though section 4.7 says it is neither a hit nor one. Say that bare-name matching is unique over the gold and accepted items of the file. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…pes, blank entries Two same-named subclasses or callers in one file keep their namespaces, so they are two gold items. A reference in a class body is no function's, and a reference is attributed to the innermost scope by its column, so two methods on one line each own their body. The prompt says a function's definition (signature or body) counts, as its gold does. A blank gold entry is a grader error. The contract says the last parseable fence is the answer. Thread: PRRT_kwDOVBg7g86zyvbY Thread: PRRT_kwDOVBg7g86zyvbe Thread: PRRT_kwDOVBg7g86zyvbo Thread: PRRT_kwDOVBg7g86zyvbu Thread: PRRT_kwDOVBg7g86zyx_G Thread: PRRT_kwDOVBg7g86zyyAF Thread: PRRT_kwDOVBg7g86zyyAe Review: PRR_kwDOVBg7g88AAAABWD45Bg.a Review: PRR_kwDOVBg7g88AAAABWD45Bg.b Review: PRR_kwDOVBg7g88AAAABWD45Bg.c Comment: IC_kwDOVBg7g88AAAABi93ULw.a Comment: IC_kwDOVBg7g88AAAABi93ULw.b Comment: IC_kwDOVBg7g88AAAABi93ULw.c Comment: IC_kwDOVBg7g88AAAABi93ULw.d Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…-tasks-generate-graph Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
grade drops every answer in an excluded path, so a gold entry in one could never score: the oracle got F1 0. Reject it when the gold is read. Thread: PRRT_kwDOVBg7g86z7Oif Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
An index with some enclosing ranges chose function granularity, and a reference inside an unranged function was then no function's gold: the gold dropped it silently. Choose functions only when every function the index defines has a range; otherwise file-level gold. Thread: PRRT_kwDOVBg7g86z7Oii Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
6501bfc to
533b582
Compare
|
DCO fix: the branch was rebased with
|
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 533b582. The generator and the grader hold up: every earlier bot point (namespaces, class bodies, same-line scopes, signature references, blank and excluded gold, partial ranges) is fixed and has a test. What is left is thin test coverage on lines that decide the gold and the score, and one doc gap. Two risks and two nits inline.
What I ran, on a Linux review host at 533b582:
make ci-local: 29 passed, 1 failed, 7 skipped; 15,759 tests; changed-line coverage 97%. The one red step istest / Run tests: a 1 s timing test (test_unbalanced_quote_in_hook_completes_quickly) and two 60 s timeouts intest_audit_test_quality.pyhit on a loaded run; all three pass on rerun and none touch this PR's files.tests/test_eval_tasks_generate_graph.pyand the CLI snapshot tests pass; changed-line coverage 97% (462 lines).- Mutation runs of
graph_tasks.py(58 mutants, 25 pass the suite) andgraders/graph.py(49 mutants, 12 real survivors), and CLI edge cases (bad revision, non-git source, unreadable index,--dry-run,--force).
Checked, no issues
- Scope lookup: nested functions, same-line functions and class bodies inside a function give the expected innermost function.
- C++ overloads: one target, defining files are the union, order is deterministic.
- Grader: F1, parse errors, the oracle reaching 1.0 for
Class::m()and./pathforms, and malformed gold are all right. - Repo rules: snapshot, allowlist, changelog fragment and docs pages are consistent; no nav change needed.
- Commits: all non-merge commits carry
Signed-off-by.
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
antonwolfy
left a comment
There was a problem hiding this comment.
I pushed a commit per nit, up to 28e5586, which fix the two nits from my review:
0bbbd3b:dokimi/docs/repo-evaluation-contract.md:1053: the exit-1 sentence now also covers a source that cannot be resolved at the revision.28e5586:dokimi/dokimi/repos/graph_tasks.py:392: the shared-name hint now also shows theClass.nameform.
make ci-local at 28e5586: 30 passed, 0 failed, 7 skipped.
Not approving yet. Still open: the two risks from my review.
…s-399 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRRT_kwDOVBg7g860CoMH A reference on a function's first column is its own, one on its end column is not, and a class range without a span ends before its last line. A function a test file also defines is a target. A definition outside the tree drops the target. Each new test fails on the mutant the review named (the end made inclusive, the start made exclusive, the class end moved, the any-for-all change, the outside definition kept) and passes on head. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRRT_kwDOVBg7g860CoMQ An exclude entry and an answer path are normalised the same way (./, a leading /, a backslash), a gold entry under a non-normalised exclude is refused, and a bare name of an accepted item is neither a hit nor a false positive. Each new test fails on the mutant the review named and passes on head. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Fixed in 94cab68: the two nits are in 0bbbd3b and 28e5586. Both open risks are fixed; see the top comment. @antonwolfy: thanks for the two nit commits. The open risks, each with its fix:
|
vlad-perevezentsev
left a comment
There was a problem hiding this comment.
Review at 9f1bfdc. Both risks from my last review are fixed: the span edges, the target rule, the path normalisation and the exclude list are now pinned by tests. One scoring gap is left in the grader's bare-name rule, and a few smaller points; they are in the line comments.
On the _innermost tie (> to >=): agreed, no test is needed. Two function or class definitions that start at one position do not occur in the indexes this reads, so a test would pin an accident.
What I ran, at 9f1bfdc:
make ci-local --offline: 19 passed, 0 failed, 13 skipped (network and Docker steps); 15,724 tests; changed-line coverage 97% (462 lines).- The mutants from my last review, again on
tests/test_eval_tasks_generate_graph.py: all 11 are now caught; only the tie mutant survives, as said above. - The grader on hand-made gold for the line comments: a bare
a.py::runfor golda.py::Impl.rungives F1 1.0; a barex.h::Childwith goldns1.Childand acceptedns2.Childgives F1 0.5. - The free CI smoke (
docker-oracle,docker-probe) with the changedgraders/main.py: both pass.
Checked, no issues
- Earlier bot points: namespaces, class bodies, same-line scopes, signature references, blank gold, gold in an
excludefile and partly ranged indexes are fixed, each with a test. - Grader in the container:
main.pyloadsgraphby name under-I, as for the other graders, and the test runs it that way. - Repo rules: SPDX headers on the new files, changelog fragment (Added), CLI snapshot and flag allowlist are in order; no new docs page, so no nav change.
…e target per Python symbol Thread: PRRT_kwDOVBg7g860MPFD Thread: PRRT_kwDOVBg7g860MPFO Thread: PRRT_kwDOVBg7g860MPFZ Review: PRR_kwDOVBg7g88AAAABWRJVrw Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…atch up Thread: PRRT_kwDOVBg7g860MPFk Thread: PRRT_kwDOVBg7g860MPFe Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…; group per symbol on scip-python only Self-review finding on the distinct list of the round. Thread: PRRT_kwDOVBg7g860MPFD Thread: PRRT_kwDOVBg7g860MPFZ Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…t items count for the hint Self-review pass 2 on the round. Thread: PRRT_kwDOVBg7g860MPFD Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Thanks: each line comment is fixed with a test; see the threads. |
A gold file's other class with a gold item's last name was unknown to the grader, so a bare `Child` naming a non-subclass scored the gold `Outer.Child` or `ns1.Child` as a hit. Derives now write `distinct` as references do. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
Gold `run` next to a method `Impl.run` of the same file: the method must be `distinct`, or an answer of only wrong methods scores F1 1.0. No test failed when the match compared whole names. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
scip-clang writes a header prototype as a roleless occurrence, so the header is gold, while the prompt defined a reference as a call or a mention. A run that answered as asked lost recall on each function declared in a header. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
An index cut short or built on a sub-root still maps onto the tree, and a reference in a file it lacks is in no gold, so a complete answer scored false positives while the summary read as full coverage. Count those files and print a warning with the first one (contract §1.2: compare with the tree). Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
|
vlad-perevezentsev
left a comment
There was a problem hiding this comment.
Review at 6f77801. All five points from my last review are fixed, each with a test: a bare a.py::run next to gold a.py::Impl.run is now a false positive, and Impl.run and Impl::run() still score 1.0. Two points are left, in the line comments.
Agreed with @xaleryb: an index that lacks a tree file still writes tasks whose gold misses that file. In the line comment I suggest dropping the affected targets rather than exiting 2.
What I ran, at 6f77801:
make ci-local --offline: 18 passed, 1 failed, 13 skipped; 15,739 tests; changed-line coverage 97% (502 lines). The failure isschema_compat: the base drifted after #387 addedrun_idanddokimi_versiononmain, and this PR changes no schema.- On the PR merged into current
main:test_eval_tasks_generate_graph.py,test_cli_flags.py,test_repo_inspect_structure.py,test_docs_code_refs.py: 208 passed. - The grader on generated tasks:
distinctwith a module-levelrun, the over-qualifiedcli.Impl.run, and an index withouttests/test_core.py(the task is still written, without that file in its gold).
Checked, no issues
- Bare names:
distinctis written for function and class answers and checked by_read_gold, and ranking by shared trailing parts resolves only when one item is the longest match. - @xaleryb's commits:
distinctfor derives, therun/Impl.runtest and the declaration wording for scip-clang file answers match the code and the contract. - Docs: §4.7 and the
generatehelp now match the code on the granularity fallback, the grader errors and the exit codes.
| if p.unindexed: | ||
| print(f"⚠ {len(p.unindexed)} tree file(s) of the indexed kinds are not in the index (first: " | ||
| f"{p.unindexed[0]}): a reference in one is in no gold; index the whole tree", file=sys.stderr) |
There was a problem hiding this comment.
A tree file the index lacks still gets tasks written with a gold that misses it.
As @xaleryb noted: with tests/test_core.py in the tree but not in the index, run is still a task with gold src/api.py, src/cli.py, and the command exits 0 after the warning. The prompt says test files count, so a right answer that names tests/test_core.py scores a false positive.
Suggestion: drop a target whose name appears as a word in an unindexed file, as a reference outside the tree already drops it, and keep the warning. Exit 2 for the whole index would also refuse most scip-clang indexes, which leave out files that compile_commands.json does not build.
| if _shares_a_name(c.gold + c.accepted + c.distinct): # what the grader resolves a bare name against | ||
| amb += " Two answers share a name in one file: write each with its namespace or class (`ns::Name`, `Class.name`)." |
There was a problem hiding this comment.
The shared-name hint now says "Two answers" when only one of them is an answer.
Since distinct joined the check, gold src/a.py::Impl.run next to a module-level run in that file (not a referrer) gives "Two answers share a name in one file". An agent that trusts it may add src/a.py::run, which is a false positive (F1 0.89 instead of 1.0).
Suggestion: "A name repeats within one file: write each answer with its namespace or class (ns::Name, Class.name)."
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 6f77801. Both risks from my earlier review stay fixed, and the new distinct mechanism holds up. The merge waits for two points from @vlad-perevezentsev that are still open at this head. I have no new findings of my own.
Waiting on the author:
- @vlad-perevezentsev's point on
tasks_generate.py:77: a tree file the index lacks still gets tasks with a gold that misses it; 6f77801 only warns and exits 0 (repro:src/u9.pyin the tree, not in the index). @xaleryb's choice (drop the targets, or exit 2 with an opt-in) is unanswered. - @vlad-perevezentsev's point on
graph_tasks.py:438: the shared-name hint misleads whendistinctbrings in a function that is not an answer (goldsrc/a.py::Impl.runwith a module-levelsrc/a.py::run: the answersrc/a.py::runscores F1 0.5). The code is unchanged and the author has not replied.
What I ran, on a Linux review host at 6f77801:
make ci-local: 29 passed, 1 failed, 7 skipped; 15,789 tests. The red step istest / Run tests:test_unbalanced_quote_in_hook_completes_quicklytook 1.49 s against a 1 s limit, and two tests intest_audit_test_quality.pyhit the 60 s timeout on a loaded run. None touch this PR's files. The changed-line coverage step passes.- Reproductions for the unindexed-file and hint points above, with the LLM transport mocked, and a mutation run of 23 mutants over the
distinctcode in the grader and the generator: 20 caught, 3 survive. The three only change what is written togold.jsonor are equivalent, so I do not raise them.
Checked, no issues
- Span edges and path normalisation: the two risks from my earlier review stay pinned by tests.
_resolveranking:max/minand tie-handling mutants are caught;cli.Impl.runnamesImpl.runoverrun.- Warning edge cases: extensionless files,
.PY, dotfiles, a sibling root such assub2/, and an empty index give no false warning and no crash. - Docs: §4.7 and the
generatehelp match the code for thedistinctfield, one target per symbol on scip-python, the declaration wording and the exit codes. - Commits: all 21 non-merge commits carry
Signed-off-by.


Summary
PR2 of the code-index work:
eval tasks generate --from graph(D11 on #94). Built on the SCIP reader (#339) andrepo inspect --index(#349). It writes enumeration tasks whose gold comes from a SCIP index. No LLM or docker is involved.Diff by area:
--from history(fail-to-pass in docker) comes in a separate PR.--from replaystaysrepo tasks replayuntil the M2/M3 tombstone.Evidence
Generated from real indexes, then checked with
eval check(null fails, oracle reaches 1.0):eval checkOn oneDAL, merging overloads took the candidate count from 770 to 669;
graph_references_set_*covers 3 overloads.tests/test_eval_tasks_generate_graph.py(40 tests) cover:.pyi, scip-clang reduction), seeded choice, ids per symbol, kept/force;repo/directory kept),Class::m()and bare names, last fence, malformed gold, script mode underpython3 -I;make ci-local: 0 failed, 30 passed, 7 skipped.Merge Danger
Door: one-way for the new public names: the
--references/--derivesflags (allowlisted with a reason), the grader namedokimi:graph_enumwith its metrics, and thetask.json/gold.jsonfields and id scheme of generated tasks. Tasks written now keep these names. The code is two-way. No existing format changes;CodeIndex.basesgains a keywordminimal=True.Blast Radius: additive
Existing commands are unchanged. The
structure.pyrenames are internal.Part of #41
🤖 Generated with Claude Code