docs/superpowers/plans/2026-04-22-filesearch-run-planner-implementation.md
For agentic workers: REQUIRED SUB-SKILL: Use
superpowers:subagent-driven-development(recommended) orsuperpowers:executing-plansto implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.
Goal: Replace the current root-centric filesearch indexing loop with a sealed RunPlan -> RootPlan -> Job -> Executor pipeline so huge roots are split into bounded jobs, indexing progress becomes global and monotonic, and incremental work queues behind the active run instead of mutating it.
Architecture: Keep RootRecord as the persisted root configuration, but move execution ownership into an in-memory run planner and executor. Planning and pre-scan freeze the denominator up front, execution consumes bounded jobs in order, and root-level feed cursor/state updates remain conservative and idempotent.
Tech Stack: Go, SQLite + existing filesearch schema, current DirtyQueue / change-feed capture, SQLite-first search provider, existing filesearch smoke/benchmark coverage
Create
/mnt/c/dev/Wox/wox.core/util/filesearch/run_plan.go
RunPlan, Run, RootPlan, ScopeNode, Job, job/status enums, and progress snapshot helpers./mnt/c/dev/Wox/wox.core/util/filesearch/run_planner.go
/mnt/c/dev/Wox/wox.core/util/filesearch/job_executor.go
/mnt/c/dev/Wox/wox.core/util/filesearch/run_planner_test.go
/mnt/c/dev/Wox/wox.core/util/filesearch/job_executor_test.go
Modify
/mnt/c/dev/Wox/wox.core/util/filesearch/types.go
StatusSnapshot so top-level progress comes from active run state without breaking plugin callers./mnt/c/dev/Wox/wox.core/util/filesearch/engine.go
/mnt/c/dev/Wox/wox.core/util/filesearch/scanner.go
RunPlanner + JobExecutor; keep change-feed capture, but stop treating one root as one execution unit./mnt/c/dev/Wox/wox.core/util/filesearch/reconciler.go
/mnt/c/dev/Wox/wox.core/util/filesearch/snapshot_builder.go
/mnt/c/dev/Wox/wox.core/util/filesearch/filesearch_db.go
/mnt/c/dev/Wox/wox.core/util/filesearch/filesearch_sqlite_storage.go
/mnt/c/dev/Wox/wox.core/util/filesearch/logging_helpers.go
/mnt/c/dev/Wox/wox.core/util/filesearch/scanner_full_scan_test.go
/mnt/c/dev/Wox/wox.core/util/filesearch/scanner_incremental_test.go
/mnt/c/dev/Wox/wox.core/util/filesearch/filesearch_benchmark_test.go
Files:
Create: /mnt/c/dev/Wox/wox.core/util/filesearch/run_plan.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/types.go
Test: /mnt/c/dev/Wox/wox.core/util/filesearch/run_planner_test.go
Add a failing test that seals a RunPlan and verifies its jobs, totals, and root plans do not change when the builder mutates the original planning buffers afterward.
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestRunPlanSealFreezesWorkload' -count=1
Implement RunPlan, Run, RootPlan, ScopeNode, Job, and run/job status enums in run_plan.go.
Extend StatusSnapshot with run-scoped fields (ActiveRunStatus, ActiveJobKind, ActiveScopePath, ActiveStage, RunProgressCurrent, RunProgressTotal) while preserving existing fields for compatibility.
Add English intent comments next to the new structs and status fields explaining that root-local progress was not sufficient because one logical root can now fan out into many execution jobs.
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestRunPlanSealFreezesWorkload' -count=1
Files:
Create: /mnt/c/dev/Wox/wox.core/util/filesearch/run_planner.go
Test: /mnt/c/dev/Wox/wox.core/util/filesearch/run_planner_test.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/policy.go
Add failing tests for:
single Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestRunPlanner(BuildsSingleRootPlan|SplitsLargeRootIntoLeafJobs|ChunksWideDirectFiles)' -count=1
Implement RunPlanner.PlanFullRun(...) with explicit planning -> pre-scan -> seal phases.
Add a split-budget struct in policy.go for v1 constants only; do not expose user settings.
During pre-scan, count directories/files/indexable entries exactly but do not build EntryRecord slices. Add comments explaining that v1 accepts double metadata I/O to guarantee monotonic progress.
Release scope-tree buffers after RunPlan sealing so the planner does not hold the same giant root in memory through execution.
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestRunPlanner(BuildsSingleRootPlan|SplitsLargeRootIntoLeafJobs|ChunksWideDirectFiles)' -count=1
Files:
Create: /mnt/c/dev/Wox/wox.core/util/filesearch/job_executor.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/snapshot_builder.go
Test: /mnt/c/dev/Wox/wox.core/util/filesearch/job_executor_test.go
Add failing tests for:
order_index99% only appearing after the remaining planned work is small Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestJobExecutor(OrderIsStable|ProgressNeverDecreasesAcrossRoots|NinetyNinePercentMeansSmallKnownRemainder)' -count=1
Implement JobExecutor.ExecuteRun(...) so it consumes jobs in slice order and emits run-scoped progress snapshots.
Refactor SnapshotBuilder to support job-bounded builders (BuildDirectFilesJobSnapshot, BuildSubtreeJobSnapshot) instead of whole-root-only materialization.
Add comments near the bounded snapshot builders explaining why whole-root snapshot accumulation caused the previous indexing-time memory spike.
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestJobExecutor(OrderIsStable|ProgressNeverDecreasesAcrossRoots|NinetyNinePercentMeansSmallKnownRemainder)' -count=1
Files:
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/filesearch_db.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/filesearch_sqlite_storage.go
Test: /mnt/c/dev/Wox/wox.core/util/filesearch/job_executor_test.go
Test: /mnt/c/dev/Wox/wox.core/util/filesearch/filesearch_db_test.go
Add failing tests for:
FinalizeRootJob Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'Test(JobExecutorFinalizeRootAdvancesCursorAfterPriorJobs|FileSearchDBApplyJobPreservesSiblingScopes|FileSearchDBFinalizeRootCursorIsConservative)' -count=1
Introduce job-oriented DB entry points such as ApplyDirectFilesJob, ApplySubtreeJob, and FinalizeRootRun while reusing current subtree/root write helpers internally where that keeps the diff small.
Keep root cursor advancement in FinalizeRootRun only. Add English comments near the cursor write path explaining that replay is acceptable but skipping unseen signals is not.
Add a finalize-time WAL maintenance hook (checkpoint/optimize only where already justified by current SQLite-first flow); do not reintroduce per-row trigger logic or whole-db rebuilds.
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'Test(JobExecutorFinalizeRootAdvancesCursorAfterPriorJobs|FileSearchDBApplyJobPreservesSiblingScopes|FileSearchDBFinalizeRootCursorIsConservative)' -count=1
Files:
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/scanner.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/engine.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/logging_helpers.go
Test: /mnt/c/dev/Wox/wox.core/util/filesearch/scanner_full_scan_test.go
Add failing smoke coverage for:
planning, pre_scan, executing, finalizing Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestScanner(FullScanUsesGlobalRunProgress|FullScanReportsAllRunStages|FullScanSplitsLargeRootWithoutChangingRootIdentity)' -count=1
Replace scanAllRootsWithReason's direct root loop with:
RunPlanJobExecutor Update Engine.GetStatus to prefer active run progress and activity labels while keeping root aggregate counts as diagnostics.
Update logging helpers to emit run, root, job, and stage fields instead of only root-local counters.
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestScanner(FullScanUsesGlobalRunProgress|FullScanReportsAllRunStages|FullScanSplitsLargeRootWithoutChangingRootIdentity)' -count=1
Files:
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/reconciler.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/scanner.go
Test: /mnt/c/dev/Wox/wox.core/util/filesearch/scanner_incremental_test.go
Test: /mnt/c/dev/Wox/wox.core/util/filesearch/run_planner_test.go
Add failing tests for:
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'Test(ScannerQueuesDirtySignalsForNextRunDuringExecution|RunPlannerIncrementalScopesAreRebuiltFresh|ScannerIncrementalRunFailsFastAndKeepsQueue)' -count=1
Replace DirtyQueue -> ReconcileBatch -> direct execution with DirtyQueue -> IncrementalPlanner -> sealed RunPlan -> JobExecutor.
Keep the current dirty-signal collection, batching, and debounce inputs. Only replace the execution target and queue semantics.
Add comments in scanner.go and reconciler.go explaining that incremental plans are disposable execution metadata, so re-planning affected scopes is safer than trying to preserve old job boundaries.
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'Test(ScannerQueuesDirtySignalsForNextRunDuringExecution|RunPlannerIncrementalScopesAreRebuiltFresh|ScannerIncrementalRunFailsFastAndKeepsQueue)' -count=1
Files:
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/filesearch_benchmark_test.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/scanner_full_scan_test.go
Modify: /mnt/c/dev/Wox/wox.core/util/filesearch/scanner_incremental_test.go
Add or update the large-root benchmark so it measures bounded job execution rather than only ReplaceSubtreeSnapshot.
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -run 'TestScanner(FullScanUsesGlobalRunProgress|FullScanReportsAllRunStages|FullScanSplitsLargeRootWithoutChangingRootIdentity|QueuesDirtySignalsForNextRunDuringExecution|IncrementalRunFailsFastAndKeepsQueue)' -count=1
Run: cd /mnt/c/dev/Wox/wox.core && go test -tags sqlite_fts5 ./util/filesearch -bench 'Benchmark(FileSearchRunPlanner|FileSearchJobExecutor)' -run '^$' -count=1
Run: cd /mnt/c/dev/Wox/wox.core && make build
If benchmark or smoke output shows whole-root memory retention or regressing progress monotonicity, stop and fix before moving on.
RunPlan -> RootPlan -> Job model: Tasks 1, 2, 3No known spec gaps remain in this plan.
TODO, TBD, or “handle appropriately” placeholders remain.RunPlan is the sealed workload.Run is the execution attempt.JobExecutor consumes jobs []Job in order_index / slice order.FinalizeRootRun is the conservative root-level finalize hook referenced by Tasks 4–6.Plan complete and saved to /mnt/c/dev/Wox/docs/superpowers/plans/2026-04-22-filesearch-run-planner-implementation.md.
Two execution options:
superpowers:executing-plans, batch execution with checkpointsWhich approach?