Skip to content

feat: record the adopting model with source_model in adopt mode - #12297

Merged
MarkusNeusinger merged 4 commits into
mainfrom
feat/adopt-source-model
Oct 23, 2026
Merged

MarkusNeusinger merged 4 commits into
mainfrom
feat/adopt-source-model

Conversation

@MarkusNeusinger

@MarkusNeusinger MarkusNeusinger commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • New optional input source_model on impl-generate.yml and bulk-generate.yml names the model that wrote an adopted implementation, for example gemini-4-argon. It must match ^[A-Za-z0-9][A-Za-z0-9._-]{0,39}$; anything else stops the run. Without source_ref it is dropped with a warning.
  • Adopt-mode metadata now writes generated_by: <source_model> (still adopted:<ref> without one) and always adds adopted_from: <ref> (<sha>) right after generated_by, with the full SHA the adopt step resolved. Every other key is unchanged. The PR body line reads **Generation:** adopted from <ref> (<sha>) by <source_model>; the model below runs repair; the issue preview comment, the adopt commit, the step summaries and the ::notice:: lines name the model too.
  • bulk-generate forwards source_model on both dispatch branches exactly like source_ref. impl-generate's dispatch_retry and its three manual rerun hints (infrastructure pause, retry cap, adoption failed) keep it as well.
  • Hardening from review: neither workflow echoes a rejected source_ref or source_model any more (a newline in a dispatch value would start a workflow command), and bulk-generate's plan preview checks both with impl-generate's patterns before it prints anything, so a bad value stops the bulk run before its first dispatch.

Readers

  • automation/scripts/sync_to_postgres.py copies a fixed key list, so adopted_from is ignored and gemini-4-argon syncs into the existing generated_by column (String(100)). No schema change.
  • impl-review's metadata update and the regen write-back load the whole mapping and keep unknown keys. review_retest.py mirrors the key set of a fresh generation; adopted_from is inserted after the dict literal, so that mirror and its test stay as they are.
  • No API model or frontend type parses metadata files; the site shows generated_by as a plain string (debug page) and has no model statistics that filter on it. Nothing in api/ or app/ changes.

Known gap

  • The watchdog's generation rescues forward neither source_ref (as before) nor source_model: a pair the watchdog re-dispatches is generated by Claude. Left as it is on purpose.

Decisions

  • adopted_from carries the full 40-character SHA, the value the adopt step resolves and the PR body already shows. The 20 MUI X files backfilled in chore(muix): name gemini-4-argon as author of 20 adopted files #12298 use the 9-character form 8cfea568c.
  • A malformed source_model fails the run even without source_ref, so a typo never reaches a log line unchecked.
  • The constant error for a rejected source_ref is new too: it had the same echo two lines above the new check.
  • -f source_model= is always sent, empty or not, like -f source_ref=. Gemini Flash pointed out that GitHub answers 422 when a target workflow lacks the input; that only happens for a dispatch from this branch to a main without it, before merge.

Reviews

  • Gemini 3.8 Flash (first review): sound with changes. Adopted: validate early in bulk-generate. Skipped: conditional -f source_model (see Decisions).
  • Copilot round 1: two high findings (raw value echoed into ::error:: in impl-generate; raw value printed by bulk-generate before any check) and one low doc finding. All fixed in 1bd31a8, threads resolved.
  • Copilot round 2 (requested because round 1 had high findings): no open issues. Two low doc notes about the metadata examples were fixed in 7a2ae73. Its headline about an unescaped malformed-model test input does not match the code: every malformed-value test passes the value through the environment. No further round.

Plan

N/A

Test plan

  • tests/unit/workflows/test_impl_generate_adopt.py: input declarations on both workflows; only "Extract inputs" reads the raw input, every consumer reads steps.inputs.outputs.source_model; validation (valid names exported, malformed values including newline injections fail without being echoed, with and without source_ref; a model without source_ref warns and is dropped); the real adopt step names the model in its commit, notice and summary; the metadata writer emits generated_by and adopted_from in that order with all other keys equal to a fresh generation's; the failure handler's retry and its adoption-failed rerun command carry source_model; bulk-generate's dispatch loop, plan preview and its input checks; the generate job depends on the preview; both workflows use the same patterns.
  • tests/unit/workflows/test_model_routing.py: the PR body with source_model round-trips through impl-review's and impl-repair's rescues (repair model opus survives).
  • tests/unit/automation/scripts/test_sync_to_postgres.py: a muix metadata file with generated_by: gemini-4-argon and adopted_from scans cleanly; adopted_from is left out of the row.
  • uv run ruff check ., ruff format --check ., mypy api core, uv run pytest tests/unit -n auto (13292 passed, 3 skipped before the review fixes; workflow and automation tests 2823 passed after them), tools.changelog check --base origin/main.
  • Workflow YAML has no live verification loop. I reasoned through: set -u in bulk-generate's dispatch step (the env var is always defined there, possibly empty); ${SOURCE_MODEL:+…} expansions under bash -e; the inline Python in the metadata step receives only validated values (no quotes possible); the generate job's custom if keeps the implicit success() on needs: preview; a run dispatched by bulk-generate always targets the default branch, so both workflows need to be on main before source_model is used. No branch smoke was run, because one would open a real adopt PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_0175hA62juZoajMcqKxWFGza

Adopt mode (source_ref, #12274) wrote generated_by: adopted:<ref>, which
names a branch, not the model that wrote the code. A new optional input
source_model on impl-generate.yml and bulk-generate.yml names that model
(for example gemini-4-argon):

- "Extract inputs" checks it as a model name
  (^[A-Za-z0-9][A-Za-z0-9._-]{0,39}$) before anything echoes it, and
  drops it with a warning when source_ref is empty.
- The metadata gets generated_by: <source_model> (adopted:<ref> without
  one) and always, in adopt mode, adopted_from: <ref> (<sha>) right after
  generated_by. The key is inserted after the dict literal, so the key
  set review_retest.py mirrors for a fresh generation stays unchanged.
- The PR body's **Generation:** line, the issue preview comment, the
  adopt commit, the step summaries and the ::notice:: lines name the
  model.
- bulk-generate forwards it on both dispatch branches, and the failure
  handler's dispatch_retry and its three manual rerun hints keep it.

Readers need no change: sync_to_postgres copies a fixed key list, so
adopted_from is ignored and gemini-4-argon syncs into the existing
generated_by column; impl-review and regen write-back keep unknown keys.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175hA62juZoajMcqKxWFGza
Copilot AI lite review requested due to automatic review settings October 23, 2026 22:43

Copilot AI 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.

🟡 Changes recommended

Critical workflow-command injection risks remain in the bulk preview/dispatch path and invalid-input error path, with additional documentation inconsistencies.

3 open issues
What changed in this PR

This pull request adds adopt-mode attribution for the model that authored an externally supplied implementation, while preserving its source reference and resolved commit SHA.

Changes:

  • Adds and validates optional source_model inputs across single and bulk generation workflows, including retries and reruns.
  • Records generated_by and adopted_from metadata and surfaces the model in workflow and PR output.
  • Adds workflow, routing, synchronization, documentation, and changelog coverage.
  • Critical: Raw source_model values can be echoed before validation, enabling workflow-command/log injection in bulk dispatch and invalid-input paths.
  • Nits: Two documentation examples describe metadata combinations that the workflow does not produce.
File Summary
tests/​unit/​workflows/​test_model_routing.py Verifies adopted PR bodies preserve repair-model routing.
tests/​unit/​workflows/​test_impl_generate_adopt.py Tests validation, metadata output, propagation, retries, reruns, and bulk dispatch behavior.
tests/​unit/​automation/​scripts/​test_sync_to_postgres.py Confirms generated_by synchronization while ignoring adopted_from.
docs/​workflows/​overview.md Documents adopt-mode model attribution and metadata.
docs/​reference/​repository.md Updates the repository metadata example.
changelog.d/​adopt-source-model.md Adds the feature changelog entry.
agentic/​docs/​project-guide.md Updates agent-facing adopt-mode and metadata guidance.
.github/​workflows/​impl-generate.yml Validates and propagates source_model, records adoption metadata, and updates workflow outputs and retries.
.github/​workflows/​bulk-generate.yml Adds the input, preview output, and dispatch forwarding.
.claude/​skills/​babysit-pipeline/​SKILL.md Documents the new source_model dispatch input.

Review effort: Lite

Comment thread .github/workflows/bulk-generate.yml Resolved
Comment thread .github/workflows/impl-generate.yml Resolved
Comment thread agentic/docs/project-guide.md Resolved
@codecov

codecov Bot commented Oct 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot review of #12297:

- impl-generate's "Extract inputs" printed the rejected value inside its
  ::error:: line; a newline in a dispatch value would start a workflow
  command. Both errors are now constant. Same fix for source_ref, whose
  error had the identical pattern two lines above.
- bulk-generate echoed the raw source_model (and source_ref) in its plan
  preview and dispatch notice before any check. The preview step now
  checks both with impl-generate's patterns before printing anything and
  stops the run; the generate job needs it, so no dispatch starts with a
  bad value. This also fails a bulk run fast instead of failing every
  dispatched impl-generate run one by one (Gemini Flash's finding).
- project-guide: the adopt-mode bullet no longer says generated_by is
  adopted:<ref> unconditionally.

Tests: newline injection cases for both inputs in both workflows, the
bulk preview's checks, the generate job's dependency on the preview, and a
guard that both workflows use the same patterns.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175hA62juZoajMcqKxWFGza

Copilot AI 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.

🔵 Needs a closer look

A malformed-model test case does not safely reach the validator because its shell input is unescaped.

No open issues 🎉

2 previously missed issues

In code that hasn't changed since last review

Low severity Show adopted provenance metadata in example

agentic/​docs/​project-guide.md:255

This example comments out adopted_from, so copying it produces no provenance key, and it labels the ordinary claude-opus-4-7 value as though it were the adopted author. Show the adopted variant as an actual generated_by/adopted_from pair (or clearly separate it as an alternate example) so the documented metadata format is not misleading.

Low severity Show adopted provenance metadata in example

docs/​reference/​repository.md:314

This example comments out adopted_from, so copying it produces no provenance key, and it labels the ordinary claude-opus-4-7 value as though it were the adopted author. Show the adopted variant as an actual generated_by/adopted_from pair (or clearly separate it as an alternate example) so the repository metadata format is not misleading.

3 resolved since last review

Review effort: Lite

Copilot's second round on #12297: the metadata examples labelled the
ordinary claude-opus-4-7 value with an adopted-file comment and showed
adopted_from commented out. They now show the adopted pair as a separate
example above the ordinary generated_by line.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175hA62juZoajMcqKxWFGza
@MarkusNeusinger
MarkusNeusinger merged commit 181fab8 into main Oct 23, 2026
13 checks passed
@MarkusNeusinger
MarkusNeusinger deleted the feat/adopt-source-model branch October 23, 2026 23:15
MarkusNeusinger added a commit that referenced this pull request Oct 23, 2026
## Summary
- The owner authorized this metadata correction on 2026-10-23. Metadata
is normally written by the pipeline; this PR edits it by hand once, for
20 files.
- The 20 MUI X 9 implementations below were migrated by Gemini 4 Argon
in the owner's interactive Antigravity session (issue #12267, draft
#12275) and adopted by the pipeline from `gemini/12267-muix-9-batch1`
(PRs #12276 to #12295). Their metadata recorded `generated_by:
adopted:gemini/12267-muix-9-batch1`, the only form adopt mode had before
`source_model`.
- In each `plots/<spec>/metadata/javascript/muix.yaml`, `generated_by`
becomes `gemini-4-argon` and `adopted_from: gemini/12267-muix-9-batch1
(8cfea56)` follows it. Nothing else changes: 20 files, 40 insertions,
20 deletions.

Specs: alluvial-basic, calibration-beer-lambert, datamatrix-basic,
genome-track-multi, horizon-basic, map-marker-clustered, phase-diagram,
recurrence-basic, sequence-logo-basic, ternary-density, area-basic,
confusion-matrix, hexbin-basic, line-stepwise, scatter-color-mapped,
acf-pacf, calibration-curve, gauge-basic, line-loss-training,
scatter-annotated.

**Merge after #12297**, which adds `source_model` to adopt mode and
documents the `adopted_from` key. Plots-only, so no changelog fragment.

Not touched: `gauge-activity-rings`, whose metadata says `generated_by:
adopted:main` from the adopt-mode smoke run of #12274. That file came
from `main`, not from Gemini.

## Plan
N/A

## Test plan
- [x] Before the edit, each of the 20 files carried `generated_by:
adopted:gemini/12267-muix-9-batch1` exactly once, and no other metadata
file did.
- [x] `8cfea568c` resolves to
`8cfea568c8ff9311e21de7c0133a2e5ee506f089`, the current head of
`gemini/12267-muix-9-batch1` and the SHA on the `**Generation:**` line
of #12276.
- [x] The diff is exactly the two-line change in each of the 20 files
(`git diff` grouped by line: 20 removals and 2 × 20 additions, no other
lines).
- [x] Every file parses as YAML with `generated_by: gemini-4-argon` and
`adopted_from` directly after it.
- [x] `sync_to_postgres` reads a fixed key list, so `adopted_from` is
ignored and the next sync writes `gemini-4-argon` into the existing
`generated_by` column (covered by a test in #12297).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_0175hA62juZoajMcqKxWFGza

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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