V2 runtime packages: - sw-block/runtime/masterv2: identity authority (desired state, heartbeat handling, promotion arbitration via SelectPromotionCandidate) - sw-block/runtime/volumev2: per-volume micro-cluster shell (node, orchestrator, control session, iSCSI frontend, takeover gate, failover session + driver, replica summary reconstruction) - sw-block/runtime/purev2: RF1 execution shell (engine + store + dispatcher + local boundary observations) - sw-block/runtime/protocolv2: three-channel separation (heartbeat/assignment/query + replica summary) V2 binaries: - sw-block/cmd/v2singleblock: single-node RF1 block server - sw-block/cmd/purev2rf1: minimal RF1 runtime binary Milestone capabilities: - RF1 write/read/sync with engine-driven mode projection - masterv2 ↔ volumev2 heartbeat convergence + assignment reissue - Promotion query with fresh CommittedLSN/WALHeadLSN evidence - Replica summary for bounded takeover reconstruction - Primary-loss reconstruction from peer summaries (fail-closed gate) - In-process failover driver with session observability - Local boundary observations feed engine (Committed/Durable/Checkpoint) Design docs: - v2-two-loop-protocol.md: identity vs data-control separation - v2-automata-ownership-map.md: event/command ownership split - v2-loop1-surface-draft.md: heartbeat/query/assignment field spec - v2-volumev2-single-node-mvp.md: target layering - v2-kernel-closure-review.md: per-volume micro-cluster principle - v2-pure-runtime-rf1-bootstrap.md, v2-capability-map.md, v2-proof-and-retest-pyramid.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3.7 KiB
Pure V2 RF1 Bootstrap
Date: 2026-04-05 Status: active
Purpose
This note turns the bootstrap plan into a concrete runtime boundary that can be
implemented and tested without going through weed/server.
The goal of the first executable slice is not feature completeness.
The goal is to establish one small, closed, V2-owned runtime that can accumulate semantic truth and local execution proof without mixed-runtime distortion.
Implemented Boundary
Pure V2 shell
The first pure runtime shell lives in:
sw-block/runtime/purev2/
It owns:
- local process/runtime lifecycle
- local block volume registration
- V2 core engine ownership
- local projection/debug cache
- static RF1 assignment injection
It does not own:
- master heartbeat loops
- assignment queues
- failover control
- recovery task orchestration
- CSI or product-facing control APIs
Reused execution muscles
The pure shell reuses mechanics instead of re-implementing them:
weed/storage/store_blockvol.goweed/storage/blockvol/blockvol.goweed/storage/blockvol/v2bridge/command_bindings.goweed/server/blockcmd/
The intended rule is:
sw-block/runtime/purev2owns local runtime closuresw-block/engine/replicationowns semantic authority- reused
weed/pieces execute concrete backend actions only
Small executable entrypoint
The first operator-facing entrypoint lives in:
sw-block/cmd/purev2rf1/
Current commands:
bootstrapstatus
This is intentionally small.
It exists to make the first slice executable and inspectable, not to define the final product surface.
RF1 First Slice Contract
The first slice is closed only if all of the following are true.
Included
- create one local block volume
- open an existing local block volume
- inject one static RF1 primary assignment
- apply local role through V2 command dispatch
- perform real local read/write through
blockvol - survive restart and preserve data
- expose explicit projection/debug state
Explicitly excluded
- replica membership truth
- receiver/shipper wiring as a required path
- catch-up or rebuild orchestration
- manual or auto failover
- CSI
If a new requirement needs any excluded item, it belongs to a later tier and must not be forced into the RF1 shell.
Runtime Shape
The implemented ownership split is:
purev2 runtime
-> V2 core engine
-> dispatcher
-> command bindings
-> blockvol store/backend
-> projection/debug snapshot
The critical closure path is:
static assignment
-> core ApplyEvent(AssignmentDelivered)
-> dispatcher executes apply_role
-> runtime feeds back RoleApplied
-> projection is cached explicitly
-> local debug snapshot becomes inspectable
Current Behavioral Meaning
For the current engine semantics, an RF1 primary with zero replicas remains:
- locally writable as a block volume
- explicitly visible in debug/projection state
- projected as
allocated_only, notpublish_healthy
That is acceptable for this first bootstrap slice because:
- the purpose is shell closure, not final RF1 publication semantics
- publication meaning remains explicit instead of being guessed from local role
- RF1 publication policy can evolve later without changing the shell boundary
Immediate Engineering Rules
While the pure runtime remains in the RF1 stage:
- new shell work goes into
sw-block/runtime/purev2/ - pure runtime must not import
weed/server/volume_server_block.go - new proof should prefer unit/component tests in the pure shell
- mixed
weedscenario results remain oracle coverage, not semantic authority
Related References
v2-capability-map.mdv2-reuse-replacement-boundary.mdv2-legacy-runtime-exit-criteria.mdv2-protocol-truths.md