Repository navigation
Conversation
save_artifact stamps every run kind with run_id, right after schema_version: the run_id argument if given, else one id per dokimi process (current_run_id). A run_id inside the data is not read, so a payload copied from another artifact is written under this run. dokimi_config (authored) and cli_routes (generated) get no envelope. Input kinds (harness_profile, repo_manifest) get none. - Schemas: run_id is declared, optional, on every run kind. The closed run schemas need it to admit the key; the closed-world fixture check needs it on the open ones too. The four named closed schemas (harness_profile, repo_manifest, repo_readiness, tool_preference_groups) name it explicitly. - stamp() also sets run_id for run kinds, so a printed --json document and the saved file carry the same envelope. - Readers: runs list --json and runs show report run_id; artifacts written before the envelope load and list with run_id null. - plan_digest leaves run_id out, like generated_at. Not in this change: grouping by run_id (intel#278), the common cost block (per-kind spend shapes differ today), child-process propagation (repo conformance gives each child its own id), and routing eval/* writers that bypass save_artifact (B1b). Part of intel#94, intel#277 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
There was a problem hiding this comment.
🟢 Approval recommended
There are no active review issues blocking approval.
No open issues 🎉
What changed in this PR
0 new findings; nothing to fix.
This PR adds the first run-envelope support for #277, giving dokimi artifacts a shared per-process run_id and preparing them for future run grouping.
Changes:
- Stamp run artifacts with a generated or explicitly supplied
run_id. - Declare optional envelope fields in schemas and expose recorded IDs through
runs listandruns show, while supporting older artifacts. - Keep plan digests stable and update tests, fixture comparisons, and documentation.
| File | Description |
|---|---|
dokimi/tests/test_task_format_corpus.py |
Exclude process IDs from corpus comparisons. |
dokimi/tests/test_runs_show.py |
Expect recorded IDs in show output. |
dokimi/tests/test_runs_scan.py |
Check IDs according to artifact kind. |
dokimi/tests/test_runs_cli.py |
Expect IDs in list JSON. |
dokimi/tests/test_run_envelope.py |
Cover stamping, validation, scanning, and compatibility. |
dokimi/tests/test_repo_environment.py |
Exclude process IDs from fixture comparisons. |
dokimi/tests/test_questions_artifact.py |
Account for IDs during question round trips. |
dokimi/tests/test_artifacts.py |
Check envelope key ordering. |
dokimi/dokimi/schemas/tool_preference.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/tool_preference_groups.v1.json |
Reserve the envelope field in the closed schema. |
dokimi/dokimi/schemas/task_runs.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/task_inspect.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/subject_scorecard.v2.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/skill_evidence.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/skill_discovery.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/result.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/repo_readiness.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/repo_manifest.v1.json |
Reserve the envelope field for inputs. |
dokimi/dokimi/schemas/repo_ledger.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/repo_hits_judged.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/repo_environment.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/repo_budget.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/redteam.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/reach_matrix.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/questions.v2.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/plugin_delta.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/plan.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/novelty.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/need_graph.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/matrix_rollup.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/headroom.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/harness_profile.v1.json |
Reserve the envelope field for inputs. |
dokimi/dokimi/schemas/guidance_reach.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/explore_runs.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/eval.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/eval_coverage.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/effective_instructions.v1.json |
Distinguish envelope IDs from receipt IDs. |
dokimi/dokimi/schemas/catalog_eval.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/arms.v1.json |
Admit optional run IDs. |
dokimi/dokimi/schemas/answers.v1.json |
Admit optional run IDs. |
dokimi/dokimi/runs/scan.py |
Read and serialize optional run IDs. |
dokimi/dokimi/runner/plan.py |
Exclude run IDs from plan digests. |
dokimi/dokimi/commands/runs.py |
Display recorded IDs or a missing-ID label. |
dokimi/dokimi/artifacts.py |
Generate process IDs and stamp artifact envelopes. |
dokimi/docs/runs.md |
Explain envelope behavior and current limitations. |
dokimi/changelog.d/20261104_120000_napetrov_run_envelope_b1.md |
Announce run-envelope support. |
Review effort: Balanced
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 48 selected item(s). CI at `e82dd60`: 1 still running, 18 passing, 2 skipped
Review details
|
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #398 +/- ##
==========================================
- Coverage 94.75% 94.75% -0.01%
==========================================
Files 352 352
Lines 46507 46427 -80
Branches 7970 7953 -17
==========================================
- Hits 44070 43994 -76
+ Misses 1544 1542 -2
+ Partials 893 891 -2
🚀 New features to boost your workflow:
|
The headroom dedupe keys a file by the digest of its parsed content. A copy of an arms file whose only difference is its run_id counted as a second run. The top-level run_id is left out of that digest, as plan_digest leaves it out. A file from another process still differs in generated_at, so it counts as a run. Docs and changelog: re-saving a questions or repo_ledger file adds a new run_id. Part of intel#94, Part of intel#277 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
scorecard's question_set_hash digests the raw bytes of each question file, so a run_id stamped on every save would change the hash on every re-save and break baseline matching. Question sets feed later runs; the envelope is for run artifacts. questions leaves RUN_KINDS and the questions schema drops its run_id property. Old files that carry one still load (the schema is open). repo_ledger stays a run kind: no code digests its bytes (file_sha256 callers hash only the spec and docs; the ledger writes no digest and its output records the path only). Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
No change needed: this review reports 0 findings and nothing to fix, so there is no claim to act on. No change needed: this summary reports 0 findings, so there is no claim to act on. No change needed: coverage is complete for the modified lines. The Codecov app install is an org setting, not a code change for this PR. |
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. The envelope does what the description says: run_id leads the payload after schema_version for the 28 run kinds, stays off questions, dokimi_config and cli_routes, and both plan_digest and the headroom dedupe digest ignore it. One nit inline.
What I ran, on a Linux review host at d959e56:
make ci-local: 29 passed, 1 failed, 7 skipped. 15,724 tests passed. The one failure istest_repo_environment.py::test_unbalanced_quote_in_hook_completes_quickly(2.08 s against a 1 s limit), a wall-clock assertion on a loaded machine; it passes on its own (2 passed in 1.1 s) and the PR does not touch the code it times. The changed-line coverage,schema_compat, changelog fragment, mypy, docs build and wheel smoke steps passed.- A mutation run on the new code: 23 mutants, 3 of which pass the full suite (one is the nit below; the other two change only the
"- (none recorded)"placeholder text and the empty-stringrun_idread inruns/scan.py). - Schema probe: all 28 run-kind schemas admit a
run_idand reject an empty one and one of 129 characters.
Checked, no issues
stamp()copy: it now returns a copy instead of mutating. All callers (commands/repo.py,commands/tasks.py) use the return value.- Digests: I found no digest of a saved run artifact's bytes; the ones in
scorecard.py,eval_coverage.pyandbundle.pycover question files, rows or node lists. - Tests: the new tests write only under
tmp_path, and the file fails on the base modules (RUN_KINDSdoes not exist there).
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
vlad-perevezentsev
left a comment
There was a problem hiding this comment.
Review at 63062d8. The envelope is right: every run kind gets run_id right after schema_version, question sets stay out of it, and plan_digest and the headroom dedupe ignore it. What is left is small and in the line comments: dataset export drops the id, plus two nits.
What I ran, at 63062d8:
make ci-local --offline: 0 failed, 19 passed, 13 skipped (network and Docker steps).- A repro for the export comment: an
answersartifact saved throughsave_artifact, thenflatten("answers", ...): the rows havegenerated_atand norun_id.
Checked, no issues
- Writers:
catalog evalsavesplanandresultin one process, so both share an id, andplan_digestis the same before and after the save.repo_ledgerandneed_graphare never saved throughsave_artifact(the ledger is hand-written,save_graphwrites plain JSON), so stamping them changes nothing today. - Readers:
runs list --jsonandruns showreadrun_idand givenullfor an old file or a non-string value. The scan's header sniff still works with the extra key. - Schemas: the change only widens them:
run_idis optional everywhere, and the four closed schemas #277 names admit it. - Shape of the id: the regex test from 63062d8 settles the open nit on
test_run_envelope.py:94.
|
@napetrov, it looks like this PR and #387 do the same thing: both add the B1 envelope of #277. They change the same 35 files, among them Where they differ:
Some of this PR is better, and I would be glad to bring it over to #387: question sets as inputs, plan stamped with run_id left out of plan_digest, run_id left out of the headroom digest, and the envelope right after schema_version in stamp(). |
Thread: PRRT_kwDOVBg7g860GCVn Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRRT_kwDOVBg7g860GCVy Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRRT_kwDOVBg7g860GCV6 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…lope-b1-277 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Already fixed in 5274d8d: the nit is the shape test in 63062d8. Fixed in 5274d8d: the export and both nits, each under its thread. Waiting on a decision before I change this: close #398 in favour of #387, or keep both? My recommendation: close #398 and take its three extra pieces into #387 (question sets as inputs, plan run_id out of plan_digest, run_id out of the headroom digest). #387 carries more of the envelope and only one can land. This stays open until you decide. |
|
Thanks, @napetrov. All three are in #387 now, one commit each:
So I think this PR can be closed in favour of #387. Grouping |
|
Agreed, closing this in favour of #387. Thanks for the comparison. Please do bring over the pieces you listed: question sets as inputs (so a re-saved set keeps its |
Summary
Run artifacts get a
run_idright afterschema_version. Input kinds get none: question sets(their
question_set_hashdigests the file's bytes, so a per-save id would change it on everyre-save) and the authored or generated kinds.
Not in this PR (#277 B1b / #278 / follow-ups):
eval/*writers that bypasssave_artifact, grouping rows byrun_id, the common cost block, andchild-process propagation (
repo conformancechildren get their own id).Evidence
save_artifact("questions", ...)wrote arun_id; re-saving a question set changedits bytes and so its
question_set_hash. After:tests/test_run_envelope.pypins it:test_re_saving_a_question_set_keeps_its_hash,test_a_question_set_is_an_input_and_carries_no_run_id,and the RUN_KINDS membership test. Red first: 7 failed before the fix (new and reverted tests on the B1 head), green after.
run_idby an earlier build still loads (schema is open).repo_ledgerkeeps itsrun_id. Nothing digests its bytes:file_sha256callers hash only themanifest spec and docs,
subjects/scorecard.pydigests only question files and subject/arm trees,and the ledger's output records its path, not a hash.
.venv,pytest -q): 15723 passed, 12 skipped, 0 failed.ruff check: passed.mypy dokimi: no issues in 358 files.eval headroom: a copy whose only difference is the top-levelrun_idnow counts once(
test_runs_that_differ_only_in_run_id_count_once).Merge Danger
Door: two-way. Additive optional key; reverting drops the key from new files and nothing else depends on it.
Held item resolved: the owner's call (2026-11-04) keeps question sets out of the envelope. Their
question_set_hashis unchanged by a re-save, so no existing baseline hash moves.repo_ledgeris theone hand-written kind left with a
run_id; its file changes on a re-save, and no digest reads it.Blast Radius: artifact files and
runsoutput. A dokimi build older than this PR that closesa run schema without
run_idwill reject artifacts this one writes. Old artifacts withoutrun_idkeeploading and listing here, and question sets written with one still load.
Part of #94, Part of #277
🤖 Generated with Claude Code