Skip to content

improve --dry-run must report the effective read-only execution plan #800

Description

@itlackey

0.9.2 planning role

This is a parallel product-correctness lane, not part of the WP3 execution resolver in #807. It shares the same design rule—dry-run and live execution must consume one pure planner—but the improve planner remains subsystem-specific.

Complete this before the 0.9.2 dogfood/release-evidence period so cadence and strategy decisions are based on effective planned work rather than raw candidate counts. Link its parity and no-write evidence from WP8 (#810).


Problem

akm improve --dry-run returns immediately after indexAndCollect, before the live preparation and selection stages. Its plannedRefs are therefore raw type/scope candidates rather than the refs a live run would execute.

This makes dry-run unreliable for strategy and cadence tuning and does not satisfy the command's promise to show planned actions without writing.

Reproduction on 0.9.1

Dry runs against the same live bundle, each invoked with --limit 100, reported:

Strategy Reported plannedRefs
default 16,168
quick 16,168
reflect-distill 16,168
proactive-maintenance 16,168
thorough 16,168
memory-focus 928
consolidate 0

The common full-scope result was 697 memory-cleanup refs plus 15,471 scope-type refs; 1,104 refs were strategy-filtered. The --limit 100 option did not affect the displayed count.

This conflicts with recent live behavior: quick/frequent runs selected zero reflect refs, consolidation was active, and proactive maintenance should select only a bounded due pool.

Cause

In src/commands/improve/improve.ts, the dry-run path returns buildDryRunResult(...) immediately after indexAndCollect. The later preparation stage applies the decision logic that determines the actual work:

  • cleanup exclusion and validation
  • feedback signal-delta and cooldown
  • proactive due selection
  • high-salience fallback
  • ranking and --limit
  • consolidation pool and delta gates

Dry run never reaches that logic.

Proposed behavior

Introduce a side-effect-free planning path that reuses the same pure selection logic as a live run, without:

  • acquiring mutation locks
  • writing events or improve_runs
  • generating or promoting proposals
  • mutating assets or the index
  • dispatching LLM or agent work

The result should distinguish raw scope candidates from effective planned work and include:

  • raw in-scope count
  • per-gate removed counts and reasons
  • final ranked refs after profile and CLI limits
  • lane per ref (scope, signal-delta, proactive, high-salience, or distill-only)
  • whether consolidation, extract, graph, or memory-inference stages would run and why
  • proposal triage mode (queue or promote) and configured caps
  • an explicit estimate/no-dispatch marker

Acceptance criteria

  • --limit N caps effective planned refs in dry-run output.
  • Proactive dry-run reports dueTotal, neverReflected, selected count, and selected refs.
  • Consolidate dry-run reports pool size, minimum-pool/delta gates, whether it would run, and a chunk estimate instead of always reporting zero refs.
  • Dry-run and live execution share the same pure selection functions; regression fixtures assert identical effective refs from the same state snapshot.
  • Dry-run writes no assets, proposals, events, improve_runs, locks, or scheduler state and performs no LLM/agent dispatch.
  • Output clearly separates raw candidates from effective planned refs.
  • A regression test pins the observed defect: default and proactive no longer both report the same raw 16,168 merely because their allowed asset types match.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions