Skip to content

ci: reusable repo-eval workflow (validate, scan, tasks check) with dokimi pinned - #113

Open
napetrov wants to merge 15 commits into
intel:mainfrom
napetrov:d8-repo-eval-workflow
Open

napetrov wants to merge 15 commits into
intel:mainfrom
napetrov:d8-repo-eval-workflow

Conversation

@napetrov

@napetrov napetrov commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Part of #41 (step D8).

Summary

A reusable workflow that runs dokimi's no-LLM repository checks on the caller's checkout, with dokimi pinned. It replaces the hand-written self-check workflow a repository carries today (oneDAL's agent-evals.yml was the model).

 .github/workflows/
+├── repo-eval.yml        # on: workflow_call
+│   validate             repo validate (gate) + task selection
+│   ├── scan             repo scan: L0 claims -> job summary + artifact (report only)
+│   └── tasks-check      matrix: repo tasks check --task <id>, docker; check.json + logs as artifact
+└── repo-eval-self.yml   # calls ./repo-eval.yml on .agent-eval/ with the commit under test
 dokimi/docs/repo-evaluation-contract.md
+  end of §9: "CI for a repository", inputs, caller snippet

Task selection (tasks):

changed  (pull_request: origin/<base>...HEAD; push: before..HEAD; other events: all)
  tasks whose <tasks>/<id>/ the diff touches
  + smoke-tasks (empty: all) if the diff touches
      eval_dir outside the tasks (not *.md) | the manifest | the calling workflow | smoke-paths
all | "id1 id2,id3"     unknown ids fail the job
- exclude-tasks

Pinning: dokimi-ref must be a 40-digit SHA or a tag (resolved to its commit once, in validate); a branch is refused. Every job installs

pip install -c "https://raw.githubusercontent.com/intel/dokimi/$SHA/dokimi/requirements.lock.txt" \
  "dokimi @ git+https://github.com/intel/dokimi@$SHA#subdirectory=dokimi"

so the SHA pins the dependency closure too. Moving the pin edits the calling workflow, which selects the smoke set.

What a repository adds (oneDAL's after #3818 is trimmed):

permissions: {}
jobs:
  evals:
    permissions:
      contents: read
    uses: intel/dokimi/.github/workflows/repo-eval.yml@<sha>
    with:
      dokimi-ref: <sha>
      manifest: dev/agent_evals/repo-eval.yaml
      smoke-tasks: build_kmeans_host fix_finiteness_mut review_seeded_fc
      warm: true

Security: permissions: {} at the top of both files, contents: read per job, actions pinned by SHA, persist-credentials: false, every input and event field reaches run: through env:, no pull_request_target, no secrets.

Evidence

  • Before: no reusable workflow; each repository copies the select/matrix/summary logic and calls its own harness.
    After: repo-eval-self on this PR (this PR edits both workflow files, so changed selects the smoke set fix-degrade-pre and review-pr-conventions): green on 056814f (run).

    repo validate        1m37s  install 76s; dokimi intel/dokimi@<merge sha>; tasks: 10
                                outside the task directories: .github/workflows/repo-eval-self.yml .github/workflows/repo-eval.yml; adding the smoke set
                                tasks-check: fix-degrade-pre review-pr-conventions
    repo scan            1m39s  claims: 258 (ok 220, unresolved 38, fail 0)
    tasks check review   4m08s  review-pr-conventions: OK
    tasks check fix      14m57s image build 2.5 min; fix-degrade-pre: OK
    

    Artifacts: repo-eval-scan-dokimi, repo-eval-check-dokimi-<task> (check.json, grade.json, logs; 4 KB).

  • Install: in a clean Python 3.12 venv, pip install -c <lock@sha> "dokimi @ git+https://github.com/napetrov/dokimi@<this branch's sha>#subdirectory=dokimi" installs, dokimi repo validate --help runs, and the resolved litellm, ragas, anthropic match the lock. The same works for a pull request's merge commit fetched from intel/dokimi, which is what the self-call installs.

  • Selection, run locally on the step's script against validate --json of this tree:

    diff / input selected
    .agent-eval/tasks/legacy-keys/task.json + .agent-eval/README.md legacy-keys
    + .agent-eval/run.py fix-degrade-pre legacy-keys (smoke)
    the calling workflow only the smoke set
    all, exclude feat-static-metric,docs-new-page the other 8
    schedule event, changed all 10
    legacy-keys, use-repo-scan nosuch / smoke nosuch error naming nosuch
  • dokimi-ref: a SHA passes; main, v* and a;b are refused before anything installs.

  • Locally, repo validate OK (10 tasks), repo scan 258 claims (0 fail), repo tasks check on fix-degrade-pre, review-pr-conventions, use-repo-scan: 3/3 OK.

  • zizmor --offline --min-severity medium .github/workflows (ci.yml's invocation, 1.30.1): no findings; actionlint clean; the docs tests (test_docs_code_refs, test_docs_links, test_docs_hooks) pass.

Merge Danger

Door: two-way: two new workflow files and an appended doc paragraph; deleting them undoes it, and no caller exists yet.

Blast Radius: CI-only

  • PRs that touch .agent-eval/**, dokimi/dokimi/repos/** or either workflow get a repo-eval-self run: validate, scan, and one docker job per selected task (each builds the eval image and runs the suite twice, 4 to 15 min per task on this PR).
  • The inputs become an interface once a repository pins a SHA; renaming one later breaks only callers that move their pin.
  • smoke-tasks empty means every task, the safe default; a heavy repository should set it.

Checklist

  • Tests added/updated and pytest passes (no Python changed; the self-call run is the test, docs tests pass)
  • ruff, mypy, and schema checks pass (no Python changed)
  • Docs updated (or N/A) — see the docs-drift checklist in CONTRIBUTING.md
  • No ad-hoc run artifacts committed
  • New files carry the SPDX license header (or are exempt in .github/.licenserc.yaml)

🤖 Generated with Claude Code

.github/workflows/repo-eval.yml (on: workflow_call) runs, on the caller's
checkout, `repo validate` (a gate), `repo scan` (report only, job summary
and artifact) and `repo tasks check` as a matrix over the selected tasks:
`changed` (the tasks a PR touches, plus a smoke set when the harness,
graders, manifest, calling workflow or `smoke-paths` change), `all`, or a
list, minus `exclude-tasks`. dokimi is installed from a pinned commit SHA
or tag (a branch is refused), with that commit's requirements.lock.txt as
constraints.

repo-eval-self.yml calls it on dokimi's own .agent-eval/ with the commit
under test, when .agent-eval/, the repository mode or either workflow
changes. The end of contract §9 documents the inputs and the caller
snippet.

Part of intel#41 (step D8).

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Part of intel#41 (step D8).

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@codecov-commenter

codecov-commenter commented Oct 19, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.28%. Comparing base (61e0355) to head (25686c4).
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #113      +/-   ##
==========================================
- Coverage   91.29%   91.28%   -0.01%     
==========================================
  Files         216      216              
  Lines       26565    26568       +3     
  Branches     4337     4338       +1     
==========================================
+ Hits        24252    24253       +1     
- Misses       1645     1646       +1     
- Partials      668      669       +1     
Files with missing lines Coverage Δ
dokimi/dokimi/repos/manifest.py 94.46% <100.00%> (+0.05%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Task selection can silently skip affected tasks, and uploaded results omit stderr diagnostics.

2 open issues
What changed in this PR

Centralizes no-LLM repository evaluation in a reusable workflow, advancing step D8 of #41.

Changes:

  • Adds pinned dokimi installation, validation, scanning, and selected task checks.
  • Runs the workflow against dokimi’s own evals.
  • Documents workflow inputs and caller setup.
File Description
dokimi/​docs/​repo-evaluation-contract.md Documents reusable CI usage and pinning.
.github/​workflows/​repo-eval.yml Implements reusable checks, task selection, summaries, and artifacts.
.github/​workflows/​repo-eval-self.yml Checks dokimi’s evals using the commit under test.

Review effort: Balanced

Comment thread .github/workflows/repo-eval.yml Outdated
Comment thread .github/workflows/repo-eval.yml
Copilot AI balanced review requested due to automatic review settings October 19, 2026 07:59
…r, include .err files in artifacts

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The filename regression tests do not exercise the actual workflow selector, leaving parsing regressions undetected.

1 open issue
2 resolved since last review

Review effort: Balanced

if r.returncode:
print(f"::warning::git diff {' '.join(rng)} failed, checking every task: {r.stderr.strip()}")
return None
return r.stdout.split('\0') if r.stdout else []

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 631ba99. The tests no longer use a local copy of the parser: they lift the Select tasks script out of repo-eval.yml and run it in a scratch git repo with GitHub's env. Cases: a task directory with a space, a quoted file name, a move between tasks (both sides selected), shared helpers and _shared/ under the tasks dir, a deleted task, the eval-dir harness plus a changed task, and a manifest given as ./.... Reverting the -z split to whitespace or dropping --no-renames now fails 4 and 1 tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed on the current head: the tests in test_repo_eval_task_selection.py extract the Select tasks step with yaml.safe_load and run it in a scratch git repo (631ba99), so reverting the NUL split fails them. No change in this round.

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at ffbb6d1. The workflow reads well: pinning, permissions and the env: routing are right, and the summary and upload steps match what repo validate, repo scan and repo tasks check write. Two things are worth fixing before merge: the new tests do not exercise the selector, and a shared file in the tasks directory selects nothing.

What I ran, on a Linux review host at ffbb6d1:

  • make ci-local: 19 passed, 0 failed, 4 skipped (docker/network); 5186 tests.
  • zizmor --offline --min-severity medium .github/workflows: no findings.
  • The Select tasks script extracted from the step and run against throwaway git repos (spaces, quotes, unicode, renames, deletions, push and schedule events, exclusions, unknown ids): the NUL and --no-renames handling is correct.
  • The new tests against a copy of the workflow with line 219 reverted to r.stdout.split(): 7 passed.

Checked, no issues

  • Pinning: a 40-digit SHA is taken as is, a peeled ^{} tag line wins over a lightweight one, short SHAs, branches and injection-shaped values are refused.
  • Artifacts: check/check.json, check/*/grade.json, *.log and *.err match the layout repo tasks check --out writes.
  • Gate: tasks != '[]' skips the matrix for an empty selection and runs it for ["a"].
  • Docs: the new paragraph matches the inputs and defaults in the workflow.

from pathlib import Path


def parse_changed_files(output: str) -> list[str]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests never run the workflow's selector, so the regressions this PR fixed can come back unnoticed. I agree with @copilot-pull-request-reviewer here. New evidence: I reverted .github/workflows/repo-eval.yml:219 to r.stdout.split() in a copy and ran this file: 7 passed. A task directory named my task is then split in two and never selected, and the suite stays green.

  • parse_changed_files is defined in this module, so the four NUL tests check a copy of the logic.
  • test_no_renames_flag_prevents_omission and test_err_files_in_upload_path are substring checks on the YAML text. The *.err check passes if the line is moved into a comment.
  • test_err_files_purpose asserts len([...literal list of 3...]) == 3 and cannot fail.
  • Nothing covers the harness() rules, the smoke union, exclude-tasks, the deleted-task filter or the push and git-failure fallbacks.

Suggestion: load the workflow with yaml.safe_load, take the step with id: select, extract the python - <<'PY' body, and run it in a temp git repo with a fake validate.json and the step's env vars (EVENT, BASE_REF, MANIFEST, TASKS, SMOKE_TASKS, RUNNER_TEMP, GITHUB_OUTPUT, ...). Assert the emitted tasks= for a path with a space, a rename between two tasks, a harness change (smoke set), an .md change in the eval dir, an excluded task and a deleted task. A prototype of this kills the .split() mutant and the mutants that drop the .md exemption, the smoke union and exclude-tasks. Drop test_err_files_purpose.

@napetrov napetrov Oct 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 631ba99: the substring and copy-of-the-parser tests are replaced by tests that run the workflow's Select tasks step against a scratch git repo (path splitting, renames, smoke-set union, shared files, deleted task, manifest normalisation); the upload test now parses the YAML step instead of grepping text. Mutation checks: split() instead of NUL split and no --no-renames both fail. Shared files and manifest normalisation themselves were fixed in 48d103e.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partly addressed. 631ba99 and 48d103e cover the YAML-step extraction, the rename, smoke-set union, shared files, deleted task and manifest cases. 4670ea0 adds the missing selector cases: explicit task lists, all with exclude-tasks, and push with and without a previous tip. Still not covered: the push/git-diff failure fallback and the empty-BEFORE edge beyond the all-zeros case. Left open for a follow-up.

Comment thread .github/workflows/repo-eval.yml Outdated
Comment thread .github/workflows/repo-eval.yml Outdated
Copilot AI balanced review requested due to automatic review settings October 19, 2026 14:02
…st path

- Treat files under tasks dir whose first segment is not a task id as harness
  changes (e.g., tasks/common.py shared by graders, deleted task directories).
  They now trigger the smoke set as intended.
- Normalize manifest path with posixpath.normpath() so changes to manifests
  like './repo-eval.yaml' are correctly detected (git reports normalized paths).
- Add regression tests for shared files and path normalization.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…it repo

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

5 open issues

Review effort: Lite

Comment thread .github/workflows/repo-eval.yml
Comment thread .github/workflows/repo-eval.yml
Comment thread .github/workflows/repo-eval.yml
Comment on lines +72 to +75
with open(wf_path, encoding="utf-8") as f:
workflow = f.read()
# Find the upload artifact section for check results
assert "repo-eval-check-" in workflow

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 4670ea0: explicit task list (TASKS=t1), all with exclude-tasks, and push with a real previous tip and with an all-zeros BEFORE. The TASKS with a task id containing a space case is not added; it depends on the whitespace-id question in the thread on ids(). Leaving this open for that.

Copilot AI balanced review requested due to automatic review settings October 19, 2026 14:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 631ba99. The three threads from my last review are fixed in the code, and the new tests run the real Select tasks step. The test file still leaves most of the selector's branches unchecked, and the new first-segment rule has one inconsistency with the documented Markdown exemption.

What I ran, on a Linux review host at 631ba99:

  • make ci-local: 19 passed, 0 failed, 4 skipped (docker/network).
  • The Select tasks step extracted and run against throwaway git repos, with validate.json faked: new task, task name that prefixes another, push with an all-zero and with an unknown BEFORE, deleted task, renamed task, file in a non-task directory, tasks dir equal to the eval dir. Only the Markdown case below gave a wrong result.
  • A mutation run over the selector: 24 mutants, 15 of which pass the new test file. The -z split, --no-renames, normpath and first-segment mutants are killed.
  • zizmor --offline --min-severity medium .github/workflows: no findings.

Still open from my earlier review:

  • dokimi/tests/test_repo_eval_task_selection.py:148: the file now runs the real step, but these mutants still pass all 11 tests: dropping the .md exemption, dropping exclude-tasks, ignoring an explicit tasks: list or its no such task(s) error, dropping the SMOKE_PATHS check, dropping the calling-workflow comparison, breaking the push range (BEFORE..HEAD), and deleting the git diff failure fallback. Every test uses EVENT=pull_request and TASKS=changed.

I agree with @copilot-pull-request-reviewer that ids() (repo-eval.yml:193) cannot address a task directory with a space in tasks, smoke-tasks or exclude-tasks, although the new tests select one.

Checked, no issues

  • Shared files: tasks/common.py and tasks/_shared/lib.py now select the smoke set; a task added in the PR selects only itself.
  • Manifest: ./repo-eval.yaml and ./.agent-eval/../repo-eval.yaml compare equal to git's path after normpath.
  • Fallbacks: a push with an all-zero BEFORE, and one with an unknown BEFORE, both check every task, the second with a warning.
  • Artifacts: the upload test now reads the step through yaml.safe_load, so a *.err line in a comment is no longer counted (by reading the test; I did not run that mutant).

One nit inline.

Comment thread .github/workflows/repo-eval.yml
…ks-dir Markdown

The changed-task diff uses github.event.pull_request.base.sha instead of a local origin/<base>
ref, dokimi-ref must resolve to a full 40-digit SHA, and Markdown under the eval dir (the tasks
dir included) no longer selects the smoke set. Tests cover explicit lists, all with exclude-tasks,
and push with and without a previous tip; the contract says a deleted task's files select the smoke set.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The workflow's tasks, smoke-tasks and exclude-tasks inputs are split on
whitespace, so a task directory with a space could never be named there.
Reject such ids in repo validate and document the rule in the contract.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…arent

base.sha is the base at PR-open time, so BASE_SHA...HEAD on the merge
checkout also counts every commit the base gained since as the PR's change
and selects those tasks (and the smoke set). HEAD^1 is the base tip the
merge was made on; base.sha stays the fallback for a non-merge HEAD.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
A caller forwarding an unset dispatch input passes '' on pull_request,
which selected an explicit empty list: nothing checked, tasks-check
skipped, run green. Empty, blank or separator-only now means the
documented default.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
Both are what a caller gets without configuring anything, and dropping
`or all_ids` or the guidance-only early exit left every test green.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb

xaleryb commented Oct 20, 2026

Copy link
Copy Markdown
Contributor
  • Ran: the Select tasks step lifted from the head's repo-eval.yml in scratch repos (with merge commits) and on dokimi's .agent-eval, plus repo tasks check on a task with a hung oracle, all merged onto current main.
  • changed on pull_request: base.sha is the base at PR-open time, and the checkout merges into the current base tip. Main edits task t2 and the Dockerfile after the PR opens -> t1 t2 plus the smoke set are checked -> expected t1 only. Fixed in fe09af0 (HEAD^1...HEAD when HEAD is a merge).
  • tasks: '' (a forwarded unset dispatch input) -> nothing checked, green run -> expected changed. Fixed in 498b938.
  • 5e6874f: tests for empty smoke-tasks = every task and for a guidance-only manifest. Each currently survives a mutant.
  • Oracle hangs -> the job timeout fires before dokimi's 3600 s grade timeout, so !cancelled() skips Summary and Upload and there is no check.json or artifact -> expected a recorded timeout verdict. With --grade-timeout 300, check.json says "oracle timed out".
  • A change to commands/repo*.py, schemas/repo_*.json, requirements.lock.txt or pyproject.toml -> repo-eval-self does not run -> the header says it does.
  • Left for the author: the timeout budget, the self-check paths, and the untested fallbacks in 4313965405.

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 5e6874f. The merge-commit range, the empty tasks rule and the whitespace-id check are right, and the new tests pin them. Two behaviour bugs and one nit are left; the selector's test gaps from my earlier thread are still open.

What I ran, on a Linux review host at 5e6874f:

  • make ci-local: 19 passed, 0 failed, 4 skipped (docker/network).
  • The Select tasks step extracted and run against throwaway git repos with a faked validate.json (smoke-paths inside the eval dir, comma ids, merge commits). Reproductions for both bugs below.
  • A mutation run over the step's script: 37 mutants, 12 of which pass all 22 tests in test_repo_eval_task_selection.py.
  • zizmor --offline --min-severity medium .github/workflows: no findings.

Still open from my earlier review:

  • dokimi/tests/test_repo_eval_task_selection.py:148: the file covers more now, but these mutants still pass all 22 tests: dropping the smoke-paths check (repo-eval.yml:246), dropping the calling-workflow comparison (:246, also removeprefix on :238), deleting either unknown-id sys.exit (:262, :268), reversing the push range to [HEAD, BEFORE] or using BEFORE...HEAD (:215), deleting the git diff failure fallback or making it return [] (:219-221), and weakening the BEFORE.strip("0") guard to a bare truthiness test or to strip() (:214). Each needs one _select case; the unknown-id ones need a helper that accepts a non-zero exit.

I agree with @xaleryb that the repo-eval-self path filter and smoke-paths miss parts of the repository-mode code.

Checked, no issues

  • Pull request range: with a merge commit as HEAD, HEAD^1...HEAD ignores what the base gained after the PR opened; without one, BASE_SHA...HEAD is used. Mutants that break either leg fail the tests.
  • Empty tasks: "", " " and "," select changed.
  • Pin check: the resolved SHA must match ^[0-9a-f]{40}$ under the default bash shell; neither workflow sets shell:.
  • Manifest rule: with the whitespace check removed in a copy, test_repo_manifest.py fails on both my task and tab\tid. The repo's own ten tasks still validate.
  • Docs: the contract's section 9 paragraph matches the workflow's inputs and defaults.

Three inline comments.

Comment thread .github/workflows/repo-eval.yml Outdated
Comment thread dokimi/dokimi/repos/manifest.py Outdated
Comment thread dokimi/changelog.d/20261019_144048_napetrov_d8-repo-eval-workflow.md Outdated
…ommas in task ids

A Markdown file named in smoke-paths selected nothing because the
eval-dir Markdown exemption ran first. The explicit smoke path check now
runs before it.

The workflow splits its task inputs on commas as well as whitespace, so a
task id containing a comma passed validation but could not be named, and
exclude-tasks silently ignored it. repo validate now refuses commas too.
The fragment moves to Changed, since this is a new validation error.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 279db0f. The three fixes from my last review hold: a Markdown file named in smoke-paths now selects the smoke set, repo validate refuses a,b, and the changelog fragment is under ### Changed. The selector's test gaps are still open. One new point is worth fixing before merge, and there is one nit.

What I ran, on a Linux review host at 279db0f:

  • make ci-local: 19 passed, 0 failed, 4 skipped (docker/network); 5206 tests, 1 skipped; changed-line coverage 100%.
  • The Select tasks step extracted and run against 45 throwaway git repos with a faked validate.json (smoke-paths with and without a trailing slash, .md files under and outside the eval dir, manifest and calling-workflow paths, push and schedule events, tasks dir equal to the eval dir). check_repo on a task dir a,b returns ok=False with the new message.
  • A mutation run over the step: 24 mutants, 8 of which pass the whole test file. The new smoke-paths test kills the reordering mutant and fails on 5e6874f (2 failed, 22 passed).

Still open from my earlier review:

  • dokimi/tests/test_repo_eval_task_selection.py:148: the smoke-paths check is now pinned, but these mutants still pass all 24 tests: dropping the caller comparison or its removeprefix (repo-eval.yml:238, :244), deleting either unknown-id sys.exit (:262, :268), weakening the BEFORE.strip("0") guard to a bare truthiness test (:214), and BEFORE...HEAD as the push range (:215). The one that matters most is the git diff failure fallback (:219-221): changing return None to return [] passes, and then a push whose previous tip is missing from the clone selects no task and the run is green with nothing checked. Each needs one _select case; the unknown-id ones need a helper that accepts a non-zero exit.

Both inline.

Comment thread dokimi/docs/repo-evaluation-contract.md Outdated
Comment on lines +735 to +736
the eval directory outside its tasks (Markdown anywhere in it excepted), the manifest, the
calling workflow file or a path under `smoke-paths`. A file in the tasks directory that is

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the contract does not say that a smoke-paths entry wins over the Markdown exemption. The paragraph reads "the eval directory outside its tasks (Markdown anywhere in it excepted), the manifest, the calling workflow file or a path under smoke-paths", and a reader takes the exception to cover all four. harness() checks the manifest, the calling workflow and smoke-paths first (repo-eval.yml:244), so with smoke-paths: .agent-eval/prompts/ a PR that changes only .agent-eval/prompts/p.md selects the smoke set (tasks=["t1"]), and the same PR without that entry selects nothing.

Suggestion: add "(Markdown excepted, unless it is the manifest, the calling workflow or under a smoke-paths entry)", and say that smoke-paths entries are space-separated raw prefixes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 84fd3e8. The contract paragraph now says Markdown is excepted only unless it is the manifest, the calling workflow file or under a smoke-paths entry, and that smoke-paths entries are space- or comma-separated prefixes normalised like the manifest path (a trailing slash kept for a directory).

manifest_normalized = posixpath.normpath(env["MANIFEST"])

def harness(f):
if f in (manifest_normalized, caller) or any(f.startswith(r) for r in roots):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smoke-paths entries are raw string prefixes, and a malformed one selects nothing without a message, so the run is green with nothing checked. Reproduced with tasks=changed on a pull request:

  • root .agent-eval/prompts (no trailing slash) with a change to .agent-eval/prompts-old/x.md selects the smoke set; with .agent-eval/prompts/ it selects [].
  • ./vendor/, . and / with a change under vendor/ select []. The manifest goes through posixpath.normpath (:241), the roots do not.
  • a/,b/ (comma-separated, as smoke-tasks and exclude-tasks allow) matches nothing; the same two paths separated by a space match.

Suggestion: normalise each root with posixpath.normpath and split on [\s,]+ as ids() does, or document in the input description that entries need a trailing /, no ./, and spaces only.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 84fd3e8. smoke-paths entries are now split like ids() (whitespace or commas) and normalised with posixpath.normpath, keeping a trailing slash, so ./vendor/ and vendor/,other/ select the smoke set. The two regression tests fail on 279db0f. A root without a trailing slash stays a raw prefix, as the contract now says.

A smoke-paths entry with a ./ prefix or a comma separator matched nothing,
so a change under it ran no task and the run stayed green. Entries are now
split like the other id lists and normalised like the manifest path, with
the trailing slash of a directory kept. The contract says so.

Tests cover the calling workflow, the separators, unknown explicit and
smoke task ids, and an unreadable previous push tip.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

Copy link
Copy Markdown
Contributor Author

Re the review at 279db0f (test gaps, pushed in 84fd3e8):

  1. Calling-workflow comparison and its removeprefix: test_a_change_to_the_calling_workflow_runs_the_smoke_set.
  2. Unknown-id exits, explicit tasks and smoke-tasks: test_an_unknown_explicit_task_fails_the_run and test_an_unknown_smoke_task_fails_the_run.
  3. git diff failure fallback (returning [] instead of None): test_an_unreadable_previous_tip_checks_every_task, a push whose previous tip is missing. The [] mutant fails it.
  4. BEFORE.strip("0") guard: not changed. An all-zeros BEFORE without the guard goes to git diff, which fails, and the step falls back to every task with a warning, so the selected set is the same. Only the warning differs.
  5. BEFORE...HEAD as the push range: not changed. For a linear push it lists the same files as the two-dot range. They differ only after a force-push that diverges the previous tip, which these tests do not model, so I did not add that case here. The [HEAD, BEFORE] reversal gives the same name-only list.
    The smoke-paths normalisation and comma split from the same review are in 84fd3e8.

@napetrov

Copy link
Copy Markdown
Contributor Author

Status against the comment, on the current head 84fd3e8:

  • Merge-commit range for changed on pull_request: fe09af0.
  • tasks: "" treated as changed: 498b938.
  • Tests for an empty smoke set and a guidance-only manifest: 5e6874f.
  • Untested fallbacks (failed git diff on an unreadable previous push tip): covered in 84fd3e8.
  • Oracle hang vs job timeout, and the repo-eval-self paths: not changed here; these need the maintainer decision and are left open.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

# Conflicts:
#	dokimi/docs/repo-evaluation-contract.md
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants