Skip to content

feat(v1): record run provenance on the episode - #2409

Draft
hallerite wants to merge 1 commit into
mainfrom
feat/episode-provenance
Draft

feat(v1): record run provenance on the episode#2409
hallerite wants to merge 1 commit into
mainfrom
feat/episode-provenance

Conversation

@hallerite

@hallerite hallerite commented Aug 20, 2026

Copy link
Copy Markdown
Member

Companion to PrimeIntellect-ai/prime-rl#3297. (prime-rl temporarily pins feat/episode-provenance-pin — this same commit rebased onto its current submodule pin — until this merges.)

Episodes gain consumer-stamped provenance, so an orchestrator can place an episode without wrapping it or synthesizing traces:

  • Episode.task_key / Episode.task_hash — stable identity and content hash of the task the episode ran, recorded at dispatch
  • Episode.group_id: str | None — consumer-assigned rollout-group identity
  • Episode.policy_version: int | None — policy weights version that generated the episode
  • Episode.run: RunInfo | None plus Episode.record_run(run), which also records the run on each trace
  • EnvInfo.name: str | None — the name the consumer runs the env under, next to the package id
  • EnvInfo is exported from verifiers.v1

All fields default to None/unset: wire and record shapes are unchanged until a consumer stamps them (to_record already drops unset fields via exclude_none).

🤖 Generated with Claude Code

Note

Add run provenance fields and record_run method to Episode

  • Adds optional task, group_id, policy_version, and run fields to the Episode model in episode.py, carrying run metadata alongside the episode.
  • Adds Episode.record_run(run) which sets self.run and stamps every contained trace via trace.record_run(run).
  • Adds an optional name field to EnvInfo and exports EnvInfo from init.py so it is reachable via from verifiers.v1 import EnvInfo.
  • Behavioral Change: Episode and EnvInfo gain new optional fields; existing consumers that do not set them are unaffected, but deserialization now accepts the extra keys.
📊 Macroscope summarized 798157b. 7 files reviewed, 2 issues evaluated, 1 issue filtered, 1 comment posted

🗂️ Filtered Issues

verifiers/v1/serve/client.py — 0 comments posted, 1 evaluated, 1 filtered
  • line 92: The new cancellation cleanup only catches CancelledError around asyncio.wait_for; await self.socket.send_multipart(...) occurs before that try. If the caller is cancelled while the send is suspended (including after ZeroMQ has accepted the multipart message but before the await resumes), _send_cancel is never scheduled and _pending[request_id] is never removed. The server-side rollout can therefore continue consuming resources after the client run was abandoned, while the client also retains a stale pending future. Include the send in the cancellation-protected region or otherwise clean up/cancel from an outer try. [ Out of scope ]

Comment thread verifiers/v1/serve/server.py
Episodes gain consumer-stamped provenance: task_key and task_hash,
group_id, policy_version, and a run identity set via Episode.record_run
(which also records the run on each trace). EnvInfo gains the
consumer-facing name next to the package id. All fields default to
None/unset, so wire and record shapes are unchanged until a consumer
stamps them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hallerite
hallerite force-pushed the feat/episode-provenance branch from 798157b to 13c68bc Compare August 20, 2026 15:11
Comment thread verifiers/v1/episode.py
"""Consumer-assigned rollout-group identity."""
policy_version: int | None = None
"""Version of the policy weights the episode was generated with."""
run: RunInfo | None = None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should we remove run info from Trace then?

Comment thread verifiers/v1/episode.py
Comment on lines +37 to +40
task_key: str | None = None
"""Stable identity of the task the episode ran (``Task.key``), consumer-stamped."""
task_hash: str | None = None
"""Content hash of the task's data (``Task.hash``), consumer-stamped."""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we re-use the task info obj which trace uses, ie task.{key,hash,data} (i think)

Comment thread verifiers/v1/episode.py
Comment on lines +41 to +43
group_id: str | None = None
"""Consumer-assigned rollout-group identity."""
policy_version: int | None = None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i wonder if this should not be in a TrainRunInfo so that its not on eval traces, so basically a discriminated union of TrainRunInfo and EvalRunInfo

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.

2 participants