Repository navigation
fix(registry-gate): digest a candidate with its own engine defaults - #2589
Merged
Merged
Conversation
The promotion train runs the base's code, and the registry gate copied only the candidate's config and prompts, taking pricing.DEFAULT_MODELS and ENGINE_RETRIEVAL from the running package. A batch that bumps an engine default was therefore digested with the old model and refused. Parse both literals from the candidate's source (never importing it) and thread them through digest_for_actor; refuse a source the gate cannot read as exactly one literal. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GCZXYYDuAk85KKTdV8eMBA
modelmirror
approved these changes
Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by ModelMirror · project thread
What & why
The promotion train (
promotion-prep) runs main's code and callspromotion-gate.sh registry <candidate>.registry_gate.live_actors_atcopied only the candidate'sconfig/predictors.yaml,config/evaluators.yamland prompts into a scratch root. The two code-side digest inputs came from the running package:pricing.DEFAULT_MODELSandprocess_version.ENGINE_RETRIEVAL. A batch that bumps an engine default was therefore digested with the old model and refused.That is why the train refused #2588 (proc-v10, codex → gpt-6.1-sol, gemini → gemini-4-argon) and never dispatched the integration
gatesuite. The CIpromotion-gatecheck runs the head's own code, so its registry stage passed. It went red only on freshness.The fix parses both literals from the candidate's source with
astandliteral_eval, so it never imports the candidate. It threads them throughdigest_for_actoras an optionalCodeInputs, and every other caller keeps the running package's values. It fails closed: the gate refuses a source it cannot read as exactly one literal dict. That covers a missing file, a syntax error, a non-literal value, zero or two assignments, a later mutation (subscript assign,|=,.update()), or a wrong shape.Artifact served: the promotion train's registry verdict, and so whether it dispatches the gate suite and merges a candidate unattended.
Evidence (
fedcourts registry-gate --main-ref origin/main):--at58c6d0a43(#2588 head)58c6d0a43registry: 13 pending, step 0 cleanorigin/maintreeorigin/maintreeregistry: 0 pending, step 0 cleanLimits.
main. Main's current gate will still refuse promote: staging → main (2026-10-20) — 58c6d0a43 #2588, or any candidate that carries proc-v10, whether or not it also carries this fix. That batch needs a maintainer dispatch ofgh workflow run integration-test.yml --ref promote/<date> -f scenario=gate, then a hand merge.Effect check (handover note): after the promotion that carries this lands,
uv run fedcourts registry-gate --at origin/main --main-ref origin/mainprintsstep 0 clean. On the next candidate that moves an engine default, the train's body showsregistry: okand it dispatches thegatesuite itself.Merge: this touches
src/fedcourtsai/registry_gate.pyand its tests, which are maintainer-owned (the process registry the gate's Step 0 reads), so I'm leaving it for your review and merge.Review: I ran
code-reviewer. It found three blockers (format, an E501/SIM102, and mypy on non-exported names in the test), all fixed. I also took its recommendations: refuse mutations after the assignment, wrapSyntaxError/TypeErroras gate refusals, and update the stale docs indocs/cli.mdand the CLI docstring.Checklist
stagingand targetsstaging; this PR is focused on one thing.scripts/gate.sh lint typesis clean.testgives 9158 passed and 2 failed. Both failures are environment-only:test_clientredirect hits the session proxy, andtest_collect's unreadable-file case can't be unreadable when running as root. Both are untouched by this diff.schemas/if a pydantic model changed: no model changed.docs/cli.md, theregistry-gatedocstring, the module docstring).Generated by Claude Code