Repository navigation
Conversation
A plan lists every cell (arm x model x task x rep, stable cell_id) a run promises to measure; a result gives each cell one status and points back at the plan by digest. runner.plan.completeness computes planned minus completed: a run is complete only when every planned cell is pass, fail or inconclusive, and a result for another plan is invalid. check_smoke_runs.py now declares its planned cells and checks them through completeness, so a missing cell fails the smoke gate. Part of intel#121. 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 #161 +/- ##
==========================================
+ Coverage 92.76% 92.77% +0.01%
==========================================
Files 256 257 +1
Lines 32414 32515 +101
Branches 5421 5439 +18
==========================================
+ Hits 30068 30167 +99
- Misses 1561 1562 +1
- Partials 785 786 +1
🚀 New features to boost your workflow:
|
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 67975e9. The completeness computation is sound for well-formed input, and the smoke gate maps real task_runs rows onto the plan correctly. Three things are worth fixing before merge, and there is one nit.
What I ran, on a Linux review host at 67975e9:
make ci-local: 25 passed, 1 failed, 6 skipped. The failure ispip-audit; the PR touches no lock file, so it is not caused by this change. The Docker smoke job was skipped.- Reproductions for the
completenessfindings, run directly against the module; the smoke-gate reproduction and a 27-mutant run against the new tests (6 survived; the three that matter are in the inline comments).
Checked, no issues
- Smoke gate mapping: a healthy artifact (
repeatabsent for one repetition,model=None, task nameonetbb-histogram-local-aggregation) passes. Missing, extra, duplicated and wrong-rep rows each fail with a specific message. - Schema versioning: both kinds are new, each has a fixture,
SCHEMA_VERSIONSis updated, andschema_compatpasses. Fixtures load throughload_artifact, theircell_ids matchcell_id()and the result digest matches the plan. - Digest:
generated_atand key order do not change it; a changed grader digest givesinvalid.
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 7852366, which fix the nit from my review:
7852366:dokimi/dokimi/schemas/plan.v1.json:16: addedadditionalProperties: falseto subject, suite, grader and budget objects, and to result cells inresult.v1.json.
make ci-local at 7852366: 25 passed, 1 failed (pip-audit, same as at the reviewed head), 6 skipped.
Not approving yet. Still open: the three risks from my review.
…of raising Reads cells with .get, flags a missing cell_id or a status outside STATUSES, and reports measured=0 for an invalid result. Adds the empty-plan and repeated-cell tests and makes the unreadable-sidecar smoke test isolate the egress check again. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Merged with current main, completeness() has complexity 13, over the growth ratchet's cap of 10 (tests/test_growth_ratchet.py fails). The status loop becomes _statuses(); behaviour and problem order are unchanged. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
The existing malformed-cell cases use an unplanned id, so the unplanned check makes them invalid and reverting any guard keeps the suite green. Put the bad status on a planned cell, assert the problem text, and cover a non-object cell and a non-list cells value. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
|
antonwolfy
left a comment
There was a problem hiding this comment.
The three threads from my earlier review are fixed, and the malformed-cell handling in completeness now holds up. Two test gaps are worth closing before merge, both inline.
What I ran, on a Linux review host at 043179c:
make ci-local: 25 passed, 1 failed, 6 skipped. The failure ispip-audit; the PR touches no lock file. The Docker smoke job was skipped. 6,748 tests passed.- A mutation run of the new tests (about 40 mutants; the two that matter are inline).
- Reproductions for the digest point below, with the LLM transport mocked.
I agree with @xaleryb on the digest trap. New evidence: save_artifact("plan", plan, p), then result["plan_digest"] = plan_digest(plan) with six pass cells, reload both gives invalid (result is for plan sha256:7cd6c1…, not sha256:9ffebb…), and no test digests the pre-save dict. The digest choice waits for the author.
Checked, no issues
- Smoke gate mapping:
task,harnessandmodelcome fromTaskRunResult.as_dict;repeatis written only above 1, so absent means 1. A healthy artifact gives2/2 measured (complete); missing, extra, duplicated and errored rows each fail. The script imports when run by path as CI does. - Schema versioning: both kinds are new,
SCHEMA_VERSIONSis updated, fixtures load and their digests match.
…ess gate Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com> # Conflicts: # dokimi/dokimi/artifacts.py
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 19835fc. Both test gaps from my last review are closed: the list-valued cell_id case now fails when the continue in _statuses is removed, and test_a_probe_whose_connect_was_not_denied_fails fails when the :443 half of the egress check is dropped. Two nits inline, both test gaps with no effect on the gate's verdict.
I agree with @xaleryb's point on plan_digest hashing schema_version, which save_artifact adds only on save: it still reproduces at 19835fc, and the fix waits for the author.
What I ran, on a Linux review host at 19835fc:
make ci-local: 29 passed, 0 failed, 7 skipped (the Docker smoke job among them). 8,230 tests passed, changed-line coverage check passed.- A mutation run of the two test files against the new code (48 mutants, 11 of which pass both files; the two that matter are inline).
- Probes of
completeness,plan_digestand the smoke gate with malformed input.
Checked, no issues
- Threads: the two earlier mutants (
continue->pass,:443dropped) are both caught now. - Schema versioning:
planandresultare new kinds,SCHEMA_VERSIONSis updated, fixtures load,schema_compatpasses. - State logic: the digest check, duplicate and unplanned ids, the empty plan,
measured=0oninvalid, and theMEASUREDset are each pinned by a test that fails when the logic is changed.
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 aafab7c, which fix the two nits from my review:
d9c464e:dokimi/tests/test_run_plan.py:84: asserts that dropping the last cell changesplan_digest.aafab7c:dokimi/tests/test_check_smoke_runs.py:110: asserts the printed output holds the problem lineresult has cells the plan does not.
make ci-local at aafab7c: 29 passed, 0 failed, 7 skipped.
Not approving yet. Still open: @xaleryb on plan_digest hashes schema_version, which save_artifact adds only on save, so a saved plan's digest differs from the one computed before saving.
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
plan.v1 and result.v1 close the subject, suite, grader, budget and result cell objects (7852366). Nothing tested it: a typo such as fingerprnt on a subject was accepted and kept. The new test fails on the open schemas and passes on the closed ones. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
A mapping or null in cells was read as zero cells: no problem was recorded,
and every planned cell read not_run. A result written as {cell_id: status}
gave a plain incomplete with no reason. Both sides now report a problem
and the state is invalid. The cell-id helper moves to module level, as
_statuses already is, to keep completeness under the complexity cap.
Test: test_cells_that_are_not_a_list_are_invalid_not_empty (fails on the
previous plan.py).
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
|
||
| def plan_digest(plan: Mapping[str, Any]) -> str: | ||
| """``sha256:<hex>`` of the plan's canonical JSON, ``generated_at`` left out.""" | ||
| body = {k: v for k, v in plan.items() if k != "generated_at"} |
There was a problem hiding this comment.
Adding to @xaleryb's point, which still reproduces at aafab7c: d = plan_digest(plan), then save_artifact("plan", plan, p), then completeness(load_artifact("plan", p), {"plan_digest": d, ...}) gives invalid even with every cell pass. The tests miss it because _plan() digests the dict that save_artifact returned. A fix that keeps the fixture digests valid is to hash the plan as it will be saved:
body = {k: v for k, v in plan.items() if k != "generated_at"}
body.setdefault("schema_version", SCHEMA_VERSIONS["plan"])plus a test that digests the dict before save_artifact and checks the reloaded plan against it.
There was a problem hiding this comment.
Fixed in 935f6c0: plan_digest fills a missing schema_version (plan.v1) before hashing, so a digest of the pre-save dict matches the saved plan. Test: test_a_plan_digested_before_saving_matches_the_saved_plan digests the raw dict, saves and reloads both, and expects complete; test_the_plan_schema_constant_matches_artifacts pins the constant to SCHEMA_VERSIONS.
| }, | ||
| "models": {"type": "array", "minItems": 1, "items": {"type": ["string", "null"]}, | ||
| "description": "requested model ids; null for a cell that calls no model (an oracle or probe harness)"}, | ||
| "harnesses": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}}, |
There was a problem hiding this comment.
The plan lists several harnesses, but a cell has no harness and cell_id hashes only (arm, model, task, rep). A plan that runs the arms skill and no-skill under both docker-claude and codex gets the same two ids twice, and completeness says plan repeats cell ids. The smoke gate gets around this by putting the harness into arm, which then no longer means the varied variable. Since plan.v1 cannot be narrowed after it ships, could you decide now: add harness to the cell and to cell_id, or document that arm includes the harness?
There was a problem hiding this comment.
Decided in 935f6c0: the arm carries the harness. plan.v1 arm is now described as the full condition the cell runs under; when a plan crosses harnesses the harness is part of the arm (e.g. docker-claude/skill), and there is no separate harness key on a cell. This keeps cell_id and the result fixtures as they are and matches what the smoke gate already does. A separate harness coordinate can come in plan.v2 if a consumer needs to group by it.
| state = "complete" | ||
| measured = 0 if problems else len(set(planned)) - len(missing) | ||
| return Completeness(state=state, planned=len(set(planned)), measured=measured, | ||
| missing=missing, statuses={s: counts[s] for s in STATUSES if counts[s]}, |
There was a problem hiding this comment.
An invalid result reports measured=0, but statuses and missing are still computed from its cells. A result for another plan with one pass cell gives {'state': 'invalid', 'measured': 0, 'statuses': {'pass': 1, 'not_run': 1}, ...}, so a report that shows statuses shows a pass from a run we rejected. Please return statuses={} (and maybe every planned id in missing) when there are problems, and pin it in test_an_invalid_result_reports_no_measured_cells.
There was a problem hiding this comment.
Fixed in 935f6c0: an invalid result now returns statuses={} and every planned id in missing. Pinned in test_an_invalid_result_reports_no_measured_cells.
| problems.append(f"{side} has a cell without a string cell_id: {cell!r}") | ||
| return ids | ||
|
|
||
| planned = _ids("plan", plan.get("cells", [])) |
There was a problem hiding this comment.
Nothing checks that a plan cell's cell_id equals cell_id(arm, model, task, rep). A plan edited by hand (arm renamed, old id kept) can have two cells with the same coordinates and different ids, and completeness calls it complete; a result keyed by recomputed ids, as check_smoke_runs.result_for builds them, is then invalid. Please add a problem when a plan cell's id does not match its coordinates.
There was a problem hiding this comment.
Fixed in 935f6c0: a plan cell whose cell_id is not cell_id(arm, model, task, rep) (or whose coordinates cannot be hashed) is a problem, state invalid. Test: test_a_plan_cell_whose_id_does_not_match_its_coordinates_is_invalid.
| "required": ["cells"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "cells": {"type": "integer", "minimum": 0}, |
There was a problem hiding this comment.
budget.cells repeats the number of cells, but nothing checks that it matches: a plan with 36 cells and budget.cells: 6 validates and completeness ignores it. Either check it in completeness (a problem when it differs from the number of distinct planned ids) or say in the description that it is only an estimate.
There was a problem hiding this comment.
Fixed in 935f6c0: completeness checks it; a budget.cells that differs from the number of distinct planned ids is a problem (invalid), and the schema description says so. Test: test_a_budget_that_miscounts_the_cells_is_invalid.
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 2949419. The two new commits are right: a plan or result whose cells is not a list is now invalid instead of reading as zero cells, and the closed-object typo test fails against open schemas. No new findings from me, but the points other reviewers raised are still open at this head, so this is not ready to merge.
I agree with @xaleryb and @vlad-perevezentsev on the plan_digest trap, and with @vlad-perevezentsev on the cell_id coordinate check and statuses on an invalid result. All three reproduce at this head.
@vlad-perevezentsev's questions on harness in the cell and on budget.cells wait for the author.
What I ran, on a Linux review host at 2949419:
make ci-local: 29 passed, 0 failed, 7 skipped (the Docker smoke job among them). Changed-line coverage check passed.- Reproductions for
plan_digest,completenessandbudgetwith malformed plans, no model or network involved. - A mutation run of the new tests (63 mutants against
plan.py, the smoke script and both schemas); none of the survivors changescompletenessverdicts.
Checked, no issues
- Last two commits: a non-list
cellson either side givesinvalidwith a problem line;{},"",0,5andFalsedo not raise. - Schema versioning:
planandresultare new kinds,SCHEMA_VERSIONSis updated, fixtures load,schema_compatpasses. - Smoke gate: a missing, errored, extra or wrong-rep row each fails; the three new gate tests fail on the PR's base.
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…uses on invalid - plan_digest fills a missing schema_version, so a digest taken before save_artifact matches the saved plan. - completeness refuses a plan cell whose id is not cell_id of its coordinates, and a budget.cells that is not the distinct cell count. - an invalid result reports empty statuses and every planned cell missing. - plan.v1: arm carries the harness when a plan crosses harnesses. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Updated at 586031d (merged current main in 66a7620).
|
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 586031d. The new commits hold up: plan_digest now matches a plan digested before save_artifact, an invalid result reports no statuses with every planned id in missing, and the coordinate and budget.cells checks work. One test gap in that new code is worth fixing before merge, and there is one nit; both inline.
What I ran, on Linux at 586031d:
make ci-local: 28 passed, 0 failed, 7 skipped (the Docker smoke job among them). Changed-line coverage check passed.- A mutation run of
plan.pyagainsttest_run_plan.pyandtest_check_smoke_runs.py(41 mutants, 8 survived; the ones that change a verdict or a returned field are inline). - Probes of
completenessandplan_digestwith malformed plans, and of the smoke gate with missing, extra, duplicated and wrong-rep rows, with no model or network involved.
Checked, no issues
- Digest: a dict digested before
save_artifactand the reloaded plan give the same digest;generated_atand key order do not change it. - Invalid result:
statuses={},measured=0and every distinct planned id inmissinghold for a repeated-id plan and for a bad cell id. - Schema versioning:
planandresultare new kinds,SCHEMA_VERSIONSis updated, fixtures load and their digests match,schema_compatpasses. - Smoke gate: a healthy artifact gives
2/2 measured (complete); missing, extra and duplicate rows each fail.
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
|
Review at 021ad8f. The
I pushed a commit per problem, up to 6390266:
Each new test fails when the code it covers is broken. I agree with @antonwolfy on the |
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 6390266. The three new commits are right: a plan whose cells is a number is now invalid, the repeated-cell test pins planned, measured and missing, and the status-enum and unknown-egress tests fail when the code they cover is broken. One test gap from my earlier review is still open, so this is not ready to merge.
What I ran, on Linux at 6390266:
make ci-local: 28 passed, 0 failed, 7 skipped (the Docker smoke job among them). Changed-line coverage check passed.- A mutation run of
plan.pyand the smoke script againsttest_run_plan.pyandtest_check_smoke_runs.py(15 mutants on the changed code; the one that matters is below). - Probes of
completenessand the smoke gate with non-listcellson both sides and malformed cells, with no model or network involved.
Still open from my earlier review:
dokimi/tests/test_run_plan.py:217: no test editsrepof a cell on a plan withreps > 1. Replacingcell["rep"]with1in_plan_problems(plan.py:126) still passes all 57 tests in the two files at this head. A cell renumbered to another rep with its old id kept would readcomplete. Therep = "x"assertion there only reaches theexceptbranch, on a rep-1 cell.
Checked, no issues
- Non-list
cells:5,1.5,True,None, a dict and a string on either side giveinvalidwith a problem line and do not raise; the guard in_plan_problemsis pinned by the parametrised test. - Invalid result: the repeated-cell plan reports
planned=6,measured=0and each planned id once inmissing; dropping the dedup inmeasuredormissingfails the test. - Smoke gate: limiting the unknown-egress check to probe rows, or dropping it, fails the unreadable-sidecar test.
- Schema versioning:
planandresultare new kinds,SCHEMA_VERSIONSis updated, fixtures load,schema_compatpasses.
Every plan in the tests had reps=1, so the coordinate check could drop rep and still pass. A cell renumbered to rep 2 with its old id kept must be invalid. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
|
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. The one commit since my last review closes the rep gap: a cell renumbered to rep 2 with its old id kept is now invalid, and the test fails when the check ignores rep. No new findings. As @xaleryb noted, 3535d62, 29b27c8 and 6390266 have no Signed-off-by, which the repo's DCO needs before merge.
What I ran, on Linux at 5bd6906:
make ci-local: 28 passed, 0 failed, 7 skipped (the Docker smoke job among them). Changed-line coverage check passed.- A mutation run of the new lines: replacing
cell["rep"]with1in_plan_problemsfailstest_a_plan_cell_whose_id_does_not_match_its_coordinates_is_invalidat the new assertion (completeinstead ofinvalid). Replacing it with0, or dropping the id comparison, also fails. On unmodified code the only problem reported isdoes not match its coordinates.
Checked, no issues
- Schema versioning:
planandresultare new kinds,SCHEMA_VERSIONSis updated, fixtures load,schema_compatpasses. - Delta: the commit touches only
tests/test_run_plan.py(3 lines); no generated artifacts or growth-baseline files change.
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Part of #121 (item 1).
Summary
Before: a run's completeness came from whatever rows ended up in its artifact. A run that finished 2 of its 6 planned cells could still pass a gate built on per-harness counts.
After: completeness is computed from what was planned.
plan.v1records subject SHA and fingerprint, suites (hash plus selectionreasons), requested models and harnesses, grader id and digest, onevaried_variable(a string, or a list for a 2×2 design), planned cells, and a budget (cells, which must equal the number of planned cells, plus estimatesagent_calls,cost_usd,wall_sec). A cell'sarmcarries the harness when a plan crosses harnesses.completenessalso refuses a plan cell whose id does not match its coordinates, and aninvalidresult reports no statuses.result.v1hasplan_digest, an optionalexecution_id, and one status per cell. A cell can also record the resolvedmodel(the feat(repo): record the model that answered each cell #119 per-cell record).completenessonly counts cells. A cell is measured only when its status ispass,failorinconclusive;not_run,infra_error,invalidand absent cells are listed inmissing. The result isinvalidwhen its digest does not match the plan, when it has a cell the plan does not, or when it gives one cell two statuses. Whether a complete run passes is left to the gate (J11/J12: distinct inconclusive verdict and blocking policy (AC-J11-002, AC-J12-002) #99).scripts/check_smoke_runs.pydeclares its planned cells (both harnesses on the one workflow task) and runs them throughcompleteness. A missing or errored cell now fails the gate even when the summary counts are clean.Not in this PR:
--planonrepo run/arms/run, which would writeresult.v1. The execution id is still open in feat(repo): --delegation and an execution id for repo run cells #107, andrepo runwould need its cell loop reworked. That wiring is a follow-up once feat(repo): --delegation and an execution id for repo run cells #107 lands.Evidence
make ci-local: 25 pass, 1 FAIL, 6 skip. The one failure ispip-audit(diskcache 5.6.3 PYSEC-2026-2447, ragas 0.3.9 PYSEC-2026-3046). It fails the same way onrequirements.lock.txtwith this change stashed, and this PR does not touch any lock file.pytest tests/test_run_plan.py tests/test_check_smoke_runs.py tests/test_schema_compat.py tests/test_import_architecture.py tests/test_audit_test_quality.py: 208 passed.incomplete, with the 4 missing ids listed.not_run,infra_errororinvalidcell keeps the run incomplete.invalid.invalid.1/2 measured (incomplete).cells: 0/2 measured (incomplete), both cells listed asnot measured, rc=1.schema_compat vs the PR base: pass. The fixturesplan.v1.jsonandresult.v1.jsonwere written throughsave_artifact.Merge danger
dokimi.runner(it imports only the standard library), and a stricter smoke gate.external-catalog-smokejob now fails whenruns.jsonhas a row for a task or rep outside its plan. The workflow runs one task once, so that is expected not to happen. The job needs Docker and was not run locally.plan_digesthashes the plan as written, includingschema_version. A producer has to compute the digest from the saved (stamped) plan, not from the dict it passed tosave_artifact.🤖 Generated with Claude Code