Batch 7: Command dispatch binding extraction - New weed/server/blockcmd package: CommandHandler interface + DispatchCommands - volume_server_block.go applyCoreCommandsWithAssignment delegates to dispatcher - weed/server still owns RecordCommand, EmitCoreEvent, PublishProjection - v2bridge NOT given command-switch or event-emission semantics Phase 16C: Rebuilding assignment enters core command path Phase 16D: Rebuild recovery-task startup is command-driven Phase 16E: Catch-up recovery-task startup is command-driven Engine refinements: - RecoveryTarget on AssignmentDelivered event - shouldStartRecoveryTask / shouldStartReceiver guards - bootstrapReason: awaiting_rebuild_start Bridge/contract updates: - control_adapter.go: refined translation helpers - contract.go: executor port alignment Migration design docs (Batch 1-3 delivered, design artifacts): - v2-first/second/third-migration-batch.md + task-pack.md - v2-assignment-translation-unification.md - v2-execution-muscles-inventory.md - v2-separation-port-layer-audit.md - v2-legacy-runtime-exit-criteria.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6.2 KiB
V2 Third Migration Task Pack
Date: 2026-04-04 Status: active
Purpose
This note turns the third separation batch into validate-able engineering tasks.
The key remaining concentration is no longer in v2bridge, but in
weed/server/block_recovery.go, where host wiring and reusable recovery
coordination still live together.
Shared Rules
All tasks in this pack inherit these rules:
weed/servershould remain the runtime host shell- reusable coordination should move toward
sw-block - legacy no-core support may stay, but only as compatibility-only logic
- no task in this pack may redefine recovery policy or core semantics
Task H: Pending Execution Coordinator Extraction
Goal
Extract pending-execution caching and fail-closed command matching from
weed/server/block_recovery.go into reusable runtime helpers.
Source
weed/server/block_recovery.gopendingRecoveryExecutionstorePendingExecutiontakePendingExecutionpeekPendingExecutionhasPendingExecutioncancelPendingExecutionExecutePendingCatchUpExecutePendingRebuild
Destination
- reusable coordinator helpers in
sw-block/engine/replication/runtime - thin host-side wiring in
weed/server/block_recovery.go
Authority Rule
Pending execution ownership is runtime coordination logic. It belongs closer to the engine/runtime boundary than to the product adapter shell.
The host shell may store concrete handles, but it should not own the reusable matching/cancelation semantics.
Adapter Boundary
weed/ may:
- supply concrete volume IDs, replica IDs, and IO bindings
- trigger coordinator actions from host callbacks
weed/ must not:
- keep the only implementation of fail-closed pending command matching
- duplicate target-mismatch cancellation logic in multiple host sites
Acceptance
- pending execution matching/cancelation logic is reusable outside
weed/server weed/server/block_recovery.goshrinks to host-side calls into that helper- fail-closed mismatch behavior remains explicit and covered
Validation
go test ./sw-block/engine/replication/...go test ./weed/server -run "TestP16B_|TestP4_"
Current proof anchors
TestP16B_RunCatchUp_EscalatesNeedsRebuildIntoCoreProjectionTestP16B_RunRebuild_FailClosedWithoutFreshStartRebuildCommandTestP4_LivePath_RealVol_ReachesPlan
Task I: Recovery Execution Helper Extraction
Goal
Extract reusable catch-up/rebuild plan execution helpers so weed/server
supplies only:
- concrete IO bindings
- host callbacks
- logging/context shell
Source
weed/server/block_recovery.gorunCatchUprunRebuildexecuteCatchUpPlanexecuteRebuildPlan
Destination
- reusable execution helpers in
sw-block/engine/replication/runtime - thin host-side volume/session access in
weed/server
Authority Rule
The engine still decides plan outcome. This task does not move policy.
What moves is the reusable execution-path coordination that applies an existing plan using supplied IO and emits the corresponding completion callbacks.
Adapter Boundary
weed/ may:
- fetch real
BlockVoland build concreteReader/Pinner/Executor - look up sender/session state
- host goroutines and cancellation contexts
weed/ must not:
- remain the sole owner of reusable catch-up/rebuild execution wiring
- mix host concerns and execution-helper concerns in one large function
Acceptance
- reusable execution helper logic no longer requires
weed/serverownership runCatchUpandrunRebuildbecome noticeably smaller host-shell methods- catch-up and rebuild still preserve the current bounded command-driven path
Validation
go test ./sw-block/engine/replication/...go test ./weed/server -run "TestP16B_|TestP4_"go test ./weed/server -run "TestBlockService_ApplyAssignments_(PrimaryRole_UsesCoreStartRecoveryTaskForCatchUp|RebuildingRole_UsesCoreRecoveryPathWithoutLegacyDirectStart)"
Current proof anchors
TestP16B_RunCatchUp_UpdatesCoreProjectionFromLiveRecoveryTestP16B_RunRebuild_UsesCoreStartRebuildCommandOnLivePathTestP4_SerializedReplacement_DrainsBeforeStartTestP4_ShutdownDrain
Task J: Legacy No-Core Isolation
Goal
Make no-core startup behavior explicitly legacy-scoped so the core-present path and the compatibility path are structurally separate.
Source
weed/server/block_recovery.goHandleAssignmentResult- no-core branches inside
runCatchUpandrunRebuild sw-block/design/v2-legacy-runtime-exit-criteria.md
Destination
- explicit legacy-only entry points or helper section in
weed/server - updated design note if the isolation shape needs to be recorded
Authority Rule
Legacy compatibility may remain, but it must stop looking like part of the mainline runtime owner path.
Adapter Boundary
weed/ may:
- keep no-core compatibility while the product still needs it
- retain
legacy P4coverage as compatibility guard
weed/ must not:
- hide compatibility startup inside the same mainline path used for core-present ownership
- let no-core behavior continue to blur the supported owner model
Acceptance
- no-core startup paths are clearly labeled and structurally separated
- core-present runtime ownership remains the obvious default path
- legacy proofs remain compatibility-only and are not strengthened into semantic-authority claims
Validation
go test ./weed/server -run "TestP4_"go test ./weed/server -run "TestP16B_|TestBlockService_ApplyAssignments_"
Current proof anchors
TestP4_LivePath_RealVol_ReachesPlanTestP4_SerializedReplacement_DrainsBeforeStartTestP4_ShutdownDrainTestBlockService_ApplyAssignments_PrimaryRole_UsesCoreStartRecoveryTaskForCatchUpTestBlockService_ApplyAssignments_RebuildingRole_UsesCoreRecoveryPathWithoutLegacyDirectStart
Recommended Execution Order
Recommended order:
- Task H
- Task I
- Task J
Reason:
- the pending coordinator is the narrowest reusable slice
- execution helper extraction should build on that coordinator boundary
- legacy isolation should happen after the mainline path is already cleaner