Skip to content

fix(stella-cli): make the resume frame impossible to forget (#1672) - #1930

Merged
macanderson merged 2 commits into
mainfrom
fix/1672-frame-v2
Aug 7, 2026
Merged

fix(stella-cli): make the resume frame impossible to forget (#1672)#1930
macanderson merged 2 commits into
mainfrom
fix/1672-frame-v2

Conversation

@macanderson

@macanderson macanderson commented Aug 6, 2026

Copy link
Copy Markdown
Owner

fix(stella-cli): make the resume frame impossible to forget

The pipeline frame that lets a resume say what it is not restoring was declared
at exactly one of four Pipeline::new call sites. The Command Deck, the goal
loop and fleet workers declared nothing, so a checkpoint any of them left read
as a plain engine turn and any resume from it degraded in silence — the exact
failure #1615 closed for stella run alone.

A mechanism, not a convention

The obvious fix is one resume_frame::declare line beside each construction.
That is what I wrote first, and the file-size gate rejected it: two of the four
sites are in grandfathered god files closed to growth, and +1 line each put
command_deck.rs and fleet_cmd.rs over their ceilings.

The issue anticipated this and suggested routing through a helper. That turns
out to be the better design regardless: resume_frame::pipeline declares and
constructs in one call, so a surface cannot come to hold a pipeline whose
checkpoints do not say what they are
. Remembering is no longer part of the
contract.

One call replaces one call, so all three god files land exactly at their
ceilings with no baseline bump:

command_deck.rs  4621 / 4621
fleet_cmd.rs     1504 / 1504
agent.rs         2266 / 2266

agent.rs needed one line back to get there; extending its existing
use crate::{…} group rather than adding an import line is where it came from.
Callers still chain what is genuinely theirs — the deck and fleet workers add
with_turn_gate, because the gate is per-surface while the frame is not.

Witness

every_pipeline_construction_declares_its_resume_frame walks stella-cli/src
and fails on any Pipeline::new( outside the one helper, naming file and line.

Verified to catch the regression it exists for by deleting the goal loop's
call:

these sites call `Pipeline::new` directly and so declare no resume frame …
["…/crates/stella-cli/src/agent/goal.rs:775"]

It greps the source rather than driving a turn, deliberately, and the issue
asks for exactly this: what went wrong was wiring, not logic. Every unit
test here already passed while three surfaces never called the function. A
behavioural test would need one scripted run per surface and would still only
cover the surfaces somebody remembered to write a test for — the same gap one
level up. The repo uses source-grep guards for this shape already (the
stella fullauto wrapper guards from #1619).

The guard skips its own file: the needle appears in its string literal, so it
would otherwise report itself forever. Found by running it.

One rustdoc repair

Dropping the now-unused Pipeline imports orphaned an intra-doc link in
goal.rs that resolved through one of them; it is fully qualified now. Caught
by RUSTDOCFLAGS="-D warnings" cargo doc, which is a gate step — and which is
also how I found that main was already red for an unrelated broken link of
mine (PR #1929, which this branch is stacked on).

cargo test -p stella-cli — 1446 passed, 0 failed. Clippy -D warnings,
fmt --check, workspace rustdoc -D warnings, check-file-size,
check-god-files and check-left-behind all clean.

Closes #1672
Refs #1615, #1671

Summary by Sourcery

Ensure all stella-cli pipelines declare their resume frame via a single construction helper to prevent silent degradation when resuming from checkpoints.

Bug Fixes:

  • Prevent checkpoints created by certain stella-cli surfaces (command deck, goal loop, fleet workers) from resuming as plain engine turns without indicating missing stages by centralizing resume frame declaration.
  • Fix an intra-doc link in the goal agent module after removing direct Pipeline imports.

Enhancements:

  • Introduce a resume_frame::pipeline helper that couples resume frame declaration with pipeline construction so surfaces cannot forget to declare the frame.
  • Add a source-grep test that enforces all Pipeline constructions go through the new helper and flags any direct uses as errors.

Tests:

  • Add a test that scans stella-cli sources to ensure every Pipeline::new call goes through the resume-frame-aware helper and fails if any direct constructions remain.

…ot guard

`main` fails the gate's `doc-warnings` step:

    error: could not document `stella-cli`
      --> crates/stella-cli/src/daemon/boot.rs:130
       |
       |     /// ([`supervised::APPROVAL_REQUEST`]).
       |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `supervised` in scope
       |
       = note: `-D rustdoc::broken-intra-doc-links` implied by `-D warnings`

`boot.rs` imports `stella_store::{SessionRecord, SessionRegistry, SessionStatus}`
but not the `supervised` module, so the shortened path does not resolve. Fully
qualified, it does.

This is mine, from PR #1920 (#1698). I ran `cargo test`, clippy, `fmt --check`
and four guard scripts on that branch and reported them — but not
`RUSTDOCFLAGS="-D warnings" cargo doc`, which is a separate gate step, and the
one this needed.

It reached `main` because the required checks never ran: every `ci.yml` run
since 19:03 is still `queued` (#1899), so the branch merged on stale/absent
contexts. That is #1645's failure mode arriving by a different road — not a red
check that was overridden, but no check at all.

Verified: `RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps` exits 0.
`cargo test -p stella-cli --bin stella boot` — 24 passed.
The pipeline frame that lets a resume say what it is not restoring was declared
at exactly one of four `Pipeline::new` call sites. The Command Deck, the goal
loop and fleet workers declared nothing, so a checkpoint any of them left read
as a plain engine turn and any resume from it degraded in silence — the exact
failure #1615 closed for `stella run` alone.

## A mechanism, not a convention

The obvious fix is one `resume_frame::declare` line beside each construction.
That is what I wrote first, and the file-size gate rejected it: two of the four
sites are in grandfathered god files closed to growth, and +1 line each put
`command_deck.rs` and `fleet_cmd.rs` over their ceilings.

The issue anticipated this and suggested routing through a helper. That turns
out to be the better design regardless: `resume_frame::pipeline` declares and
constructs in one call, so a surface **cannot come to hold a pipeline whose
checkpoints do not say what they are**. Remembering is no longer part of the
contract.

One call replaces one call, so all three god files land exactly at their
ceilings with no baseline bump:

    command_deck.rs  4621 / 4621
    fleet_cmd.rs     1504 / 1504
    agent.rs         2266 / 2266

`agent.rs` needed one line back to get there; extending its existing
`use crate::{…}` group rather than adding an import line is where it came from.
Callers still chain what is genuinely theirs — the deck and fleet workers add
`with_turn_gate`, because the gate is per-surface while the frame is not.

## Witness

`every_pipeline_construction_declares_its_resume_frame` walks `stella-cli/src`
and fails on any `Pipeline::new(` outside the one helper, naming file and line.

Verified to catch the regression it exists for by deleting the goal loop's
call:

    these sites call `Pipeline::new` directly and so declare no resume frame …
    ["…/crates/stella-cli/src/agent/goal.rs:775"]

It greps the source rather than driving a turn, deliberately, and the issue
asks for exactly this: what went wrong was **wiring**, not logic. Every unit
test here already passed while three surfaces never called the function. A
behavioural test would need one scripted run per surface and would still only
cover the surfaces somebody remembered to write a test for — the same gap one
level up. The repo uses source-grep guards for this shape already (the
`stella fullauto` wrapper guards from #1619).

The guard skips its own file: the needle appears in its string literal, so it
would otherwise report itself forever. Found by running it.

## One rustdoc repair

Dropping the now-unused `Pipeline` imports orphaned an intra-doc link in
`goal.rs` that resolved through one of them; it is fully qualified now. Caught
by `RUSTDOCFLAGS="-D warnings" cargo doc`, which is a gate step — and which is
also how I found that `main` was already red for an unrelated broken link of
mine (PR #1929, which this branch is stacked on).

`cargo test -p stella-cli` — 1446 passed, 0 failed. Clippy `-D warnings`,
`fmt --check`, workspace rustdoc `-D warnings`, `check-file-size`,
`check-god-files` and `check-left-behind` all clean.

Closes #1672
Refs #1615, #1671

@sourcery-ai sourcery-ai Bot 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.

Sorry @macanderson, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
stella-cli-docs Ignored Ignored Aug 6, 2026 10:05pm

@sourcery-ai

sourcery-ai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Centralizes pipeline construction through a new resume_frame::pipeline helper that always declares the resume frame before building a Pipeline, updates all existing call sites to use it (while preserving per-surface turn-gate wiring), and adds a source-grep test to enforce that no other direct Pipeline::new usages exist, plus a minor rustdoc link fix.

File-Level Changes

Change Details Files
Introduce resume_frame::pipeline helper to couple resume-frame declaration with Pipeline construction.
  • Add a new resume_frame::pipeline function that takes durability, ports, events, and PipelineConfig, calls resume_frame::declare, and returns stella_pipeline::Pipeline::new(...).
  • Document the helper as the single construction path for Pipelines so checkpoints always record what they restore.
  • Keep the events sender construction at call sites so callers can still add per-surface behavior (e.g., with_turn_gate).
crates/stella-cli/src/resume_frame.rs
Add a test that enforces all Pipeline construction goes through resume_frame::pipeline.
  • Implement every_pipeline_construction_declares_its_resume_frame test that recursively scans stella-cli/src for "Pipeline::new(" usages.
  • Skip resume_frame.rs itself to avoid matching the helper’s own string literal.
  • Fail the test with a descriptive message listing any direct Pipeline::new call sites, guiding reviewers toward the enforced pattern.
crates/stella-cli/src/resume_frame.rs
Update all stella-cli call sites to construct pipelines via resume_frame::pipeline instead of calling Pipeline::new directly.
  • In agent.rs, stop importing Pipeline, extend the existing crate:: use group to include resume_frame, build the events sender locally, and call resume_frame::pipeline(...) in run_pipeline_one_shot.
  • In command_deck.rs, stop importing Pipeline and construct the pipeline via crate::resume_frame::pipeline(...).with_turn_gate(...), keeping the turn gate wiring comment but pointing to resume_frame::pipeline for the seam.
  • In fleet_cmd.rs, remove Pipeline from the local use list and build the pipeline via crate::resume_frame::pipeline(...).with_turn_gate(...), preserving the gate wiring and task-run behavior.
  • In agent/goal.rs, replace the direct Pipeline::new(...) call in run_goal_pipeline_turn with crate::resume_frame::pipeline(...).
crates/stella-cli/src/agent.rs
crates/stella-cli/src/command_deck.rs
crates/stella-cli/src/fleet_cmd.rs
crates/stella-cli/src/agent/goal.rs
Fix a rustdoc intra-doc link broken by removing the Pipeline import.
  • Change an intra-doc link from [Pipeline::run] to [stella_pipeline::Pipeline::run] so it resolves without an in-scope Pipeline type alias.
crates/stella-cli/src/agent/goal.rs

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@macanderson
macanderson changed the base branch from unbreak/rustdoc-boot-approval to main August 6, 2026 22:28
@macanderson

Copy link
Copy Markdown
Owner Author

Retargeted to main (was stacked on my unbreak/rustdoc-boot-approval branch, whose PR #1929 I closed as a duplicate of #1927).

This branch therefore still carries two commits:

d3ab8822  fix(stella-cli): make the resume frame impossible to forget
977506f3  fix(stella-cli): unbreak main — a broken intra-doc link in #1698's boot guard

The second is byte-identical to #1927's fix. If #1927 merges first, rebasing this branch drops it automatically (git recognises the identical patch); if this merges first, #1927 becomes the no-op. Either order is safe — I have kept it rather than dropping it now, because removing it would leave this branch red on the doc-warnings gate for a break that is not its own.

Note that the #1672 change itself also repairs a doc link — dropping the now-unused Pipeline imports orphaned one in goal.rs that resolved through them. That one belongs to this PR and stays regardless.

cargo test -p stella-cli --bin stella resume_frame — 5 passed, including the wiring guard.

@macanderson

Copy link
Copy Markdown
Owner Author

Merging this does double duty — it is probably the one to take first.

main is red on the doc-warnings gate (no item named supervised in scope, crates/stella-cli/src/daemon/boot.rs), which fails every open PR in the repo regardless of content. CI confirms it directly: run 31129335899 on fix/1787-bound-reasoning failed with that single cause, and every "error" line in its log is the cargo doc step — zero test failures, zero clippy failures.

This branch already carries the one-line fix (977506f3) and the #1672 work. So:

Either unblocks all seven of my open PRs at once. The duplicated one-liner resolves itself — whichever lands second, git recognises the identical patch on rebase, and I have kept it here deliberately rather than dropping it, so this branch is not itself red on a break it did not cause.

For what it is worth the break is mine, from #1920, which merged during the window when ci.yml runs were queuing and never starting — so it landed on absent required contexts rather than green ones. That mechanism is written up on #1899.

Verified locally on this branch: cargo test -p stella-cli 1446 passed, plus clippy -D warnings, fmt --check, workspace rustdoc, check-file-size, check-god-files and check-left-behind — with all three god files landing exactly at their ceilings and no baseline bump.

@macanderson
macanderson merged commit d900213 into main Aug 7, 2026
4 checks passed
@macanderson
macanderson deleted the fix/1672-frame-v2 branch August 7, 2026 00:11
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.

Only stella run declares a pipeline frame — the deck, the goal loop, and fleet workers still resume silently degraded

1 participant