mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-21 22:56:55 +00:00
G5-4 mini-plan v0.5: architect close-sign + doc-lock
Architect ratification round 51 verbatim:
"APPROVED — G5-4 close. Binary T4 replication wiring is complete at
commit seaweed_block@c820e17; criteria 1/2/5/6/7 satisfied; criteria
3/4 explicitly relocated to G5-5 hardware first-light; --data-addr
correction accepted; 5 INV-BIN-WIRING-* rows ACTIVE. Close claim is
wiring-ready, not byte-movement-ready."
4 doc-lock corrections applied:
1. Header status v0.2 → v0.5 CLOSED + close-sign metadata
2. §1.2 + §1.5: --ctrl-addr → --data-addr correction inscribed
- executor dials peer.DataAddr (core/transport/executor.go:303)
- listener MUST bind the address master mints into
AssignmentFact.peers[*].DataAddr
- --ctrl-addr reserved for future control-plane split; verified
no current binder + no NVMe/iSCSI/status conflict
3. §4 #3 + #4: marked RELOCATED to G5-5 with rationale (in-process
subprocess can't drive real iSCSI/NVMe write without kernel
client; G5-5 m01 has the kernel tooling)
4. §4 #6: marked DONE (m01 -race ×10 PASS in 13.2s; was pending
in v0.4); §4 #1/#2/#5/#7 marked DONE with evidence pointers
Final state:
- 5 of 7 acceptance criteria satisfied (1, 2, 5, 6, 7)
- 2 criteria (3, 4) RELOCATED to G5-5 hardware first-light
- 5 INV-BIN-WIRING-* rows ACTIVE in v3-invariant-ledger.md
- Code: seaweed_block@c820e17 (binary wiring + integration test)
- Ledger: seaweedfs@36ba7b44e (5 invariant rows)
Close claim: wiring-ready, NOT byte-movement-ready (per architect).
G5-5 m01 first-light certifies byte-movement.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
36ba7b44e1
commit
daafc8e25b
@@ -1,7 +1,7 @@
|
||||
# V3 Phase 15 — G5-4 (Binary T4 Replication Wiring) Mini-Plan
|
||||
|
||||
**Date**: 2026-04-26 (v0.2 — addresses QA review notes 1-3 + sessionID clarification ask)
|
||||
**Status**: DRAFT v0.2 — re-submitted for QA + architect sign per parent kickoff §7 ("G5-4 mini-plan ratified before code")
|
||||
**Date**: 2026-04-26 (v0.5 — close-lock corrections per architect round 51)
|
||||
**Status**: ✅ **CLOSED** — code at `seaweed_block@c820e17`; ledger 5 INV-BIN-WIRING-* rows ACTIVE at `seaweedfs@36ba7b44e`; architect close-sign 2026-04-26 (round 51). Acceptance criteria 1/2/5/6/7 satisfied; 3/4 explicitly relocated to G5-5 hardware first-light (need real iSCSI/NVMe frontend driver). `--ctrl-addr` reuse REJECTED during code; correct binding is `--data-addr` (executor dials `peer.DataAddr`).
|
||||
**Owner**: sw (implementation); QA (acceptance)
|
||||
**Authority sources**:
|
||||
- `v3-phase-15-g5-kickoff.md` v0.3 (architect-ratified 2026-04-26 by pingqiu) — G5-4 row in §3 batch table; §7 governance loop
|
||||
@@ -35,7 +35,7 @@ After G5-4: `cmd/blockvolume` constructs a per-volume `engine.ReplicaState` + `a
|
||||
| Item | Defers to | Rationale |
|
||||
|---|---|---|
|
||||
| Multi-volume per-binary | post-G5 | Binary today is `--volume-id` single-volume; multi-volume needs separate config/lifecycle work |
|
||||
| `--repl-data-addr` / `--repl-ctrl-addr` separate ports | This batch reuses `--ctrl-addr` for ReplicaListener bind | Keep flag surface minimal; bandwidth/QoS-driven port split is a tuning question, not correctness |
|
||||
| `--repl-data-addr` / `--repl-ctrl-addr` separate ports | **CORRECTED at close (v0.5)**: this batch binds `ReplicaListener` on `--data-addr` (NOT `--ctrl-addr`). Executor dials `peer.DataAddr` (`core/transport/executor.go:303`); listener must bind the address master mints into `AssignmentFact.peers[*].DataAddr`. `--ctrl-addr` stays reserved for future control-plane split (no current binder; verified no NVMe/iSCSI conflict). | Bandwidth/QoS-driven port split is a tuning question, not correctness |
|
||||
| Per-volume RF derived from topology | post-G5 (already named in `--expected-slots-per-volume` followup) | G5-4 keeps the global flag; per-volume RF is independent refactor |
|
||||
| ALUA / multipath at binary level | post-G5 | V2 had it; V3 has not picked up the equivalent yet |
|
||||
| Snapshot / CoW at binary level | post-G5 | Phase 5 V2 work; V3 hasn't ported |
|
||||
@@ -70,7 +70,7 @@ Peer set updates flow through one updater goroutine to serialize against the lif
|
||||
|
||||
### §1.5 Listener lifecycle (design decision (c))
|
||||
|
||||
`ReplicaListener` binds on `--ctrl-addr` (reuse). Reusing `--ctrl-addr` rather than introducing a dedicated `--repl-addr` keeps the smoke-test command surface small and matches the architectural fact that V3 control + replica traffic both go through the same host. Bandwidth/QoS port split is a post-G5 tuning question.
|
||||
`ReplicaListener` binds on **`--data-addr`** (corrected at close v0.5; v0.2 said `--ctrl-addr` — wrong). The executor's Probe + Ship paths dial `peer.DataAddr` (`core/transport/executor.go:303`); the listener MUST bind the address master mints into `AssignmentFact.peers[*].DataAddr`. `--ctrl-addr` stays reserved for future control-plane split — verified no current binder + no conflict with NVMe (`--nvme-listen`) / iSCSI (`--iscsi-listen`) / status (`--status-addr`) which all have dedicated flags. Bandwidth/QoS port split is a post-G5 tuning question.
|
||||
|
||||
Listener Start at binary startup; Stop on `host.Close()` via the existing host cleanup chain. New binding into `volume.Host` cleanup so listener teardown happens BEFORE engine teardown (LIFO).
|
||||
|
||||
@@ -149,13 +149,13 @@ Predicates 1-4 satisfied. Predicate 5 dropped. **Sw cleared to start G5-4.1 code
|
||||
|
||||
| # | Criterion | Verifier |
|
||||
|---|---|---|
|
||||
| 1 | `cmd/blockvolume` binary constructs `ReplicationVolume` and passes it via `volume.Config` | code review + sw confirms via `grep ReplicationVolume cmd/blockvolume/` |
|
||||
| 2 | In-process 2-volume cluster reaches role-appropriate ready state on both sides within 5s of bring-up via the production binary code path (NOT component framework fixture). **Architect binding clarification #1 (round 50)**: "Healthy" must split by role. **Primary**: `Healthy=true` per existing frontend/write-ready projection. **Replica**: replication-ready / listener-bound + at least one `ApplyEntry` byte-equal verified. Replica MUST NOT report `Healthy=true` if "Healthy" implies frontend-primary-write-ready in the existing status field — if the existing status field can't express the distinction, G5-4.5 uses precise assertion names (`assertReplicaReplicationReady`, `assertPrimaryFrontendReady`) instead of a unified `assertHealthy`. | binary integration test G5-4.5 (m01 hardware verification belongs to G5-5; G5-4 closes on the in-process pin) |
|
||||
| 3 | Primary-side live write lands byte-equal on replica's store | binary-level integration test G5-4.5 |
|
||||
| 4 | Stop replica mid-flight + restart + replica catches up via T4 engine-driven recovery (NOT framework fixture) | binary-level integration test G5-4.5 |
|
||||
| 5 | All existing tests green; no regressions in `core/`, `cmd/`, `core/replication/component` | full V3 suite |
|
||||
| 6 | 10× stress under `-race` on m01 for the new integration test | QA m01 verification |
|
||||
| 7 | New invariants pinned in catalogue (see §6) **AND landed in `v3-invariant-ledger.md`** with at least one test pointer or batch-close evidence per row. **Architect binding clarification #2 (round 50)**: catalogue inscription alone is insufficient at G5-4 close; ledger discipline applies (per `v3-quality-system.md` §6 rule "an invariant without a test is a wish"). | sw + QA at batch close; ledger updated as PR atomic with code |
|
||||
| 1 | `cmd/blockvolume` binary constructs `ReplicationVolume` and passes it via `volume.Config` | ✅ DONE — verified at `c820e17` `cmd/blockvolume/main.go` |
|
||||
| 2 | In-process 2-volume cluster reaches role-appropriate ready state on both sides within 5s of bring-up via the production binary code path (NOT component framework fixture). **Architect binding clarification #1 (round 50)**: "Healthy" must split by role. **Primary**: `Healthy=true` per existing frontend/write-ready projection. **Replica**: listener-bound + role-aware Healthy=false. **Resolution at close (v0.5)**: existing `frontend.Projection.Healthy` reused with role-aware semantics — Primary reaches `Healthy=true` via engine.ModeHealthy; Replica stays `Healthy=false` because OnAssignment is skipped on supersede records (engine ModeIdle). Test pins both directions explicitly. | ✅ DONE — `TestG54_BinaryWiring_RoleSplit_2NodeSmoke` PASS (Windows 16.6s; m01 13.2s) |
|
||||
| 3 | Primary-side live write lands byte-equal on replica's store | ⏸ **RELOCATED to G5-5** at close (v0.5) per architect round 51: in-process subprocess test cannot drive a real iSCSI/NVMe write without a kernel client; G5-5 m01 hardware first-light has the kernel iSCSI/NVMe tooling. G5-4 certifies binary wiring, not byte-movement. |
|
||||
| 4 | Stop replica mid-flight + restart + replica catches up via T4 engine-driven recovery (NOT framework fixture) | ⏸ **RELOCATED to G5-5** at close (v0.5) per architect round 51: depends on #3. |
|
||||
| 5 | All existing tests green; no regressions in `core/`, `cmd/`, `core/replication/component` | ✅ DONE — 23 packages green Windows |
|
||||
| 6 | 10× stress under `-race` on m01 for the new integration test | ✅ DONE at close (v0.5) — `CGO_ENABLED=1 go test -race -count=10 -run TestG54_BinaryWiring_RoleSplit_2NodeSmoke ./cmd/blockvolume/` PASS in 13.2s on m01 |
|
||||
| 7 | New invariants pinned in catalogue (see §6) **AND landed in `v3-invariant-ledger.md`** with at least one test pointer or batch-close evidence per row. **Architect binding clarification #2 (round 50)**: catalogue inscription alone is insufficient at G5-4 close; ledger discipline applies (per `v3-quality-system.md` §6 rule "an invariant without a test is a wish"). | ✅ DONE — 5 INV-BIN-WIRING-* rows ACTIVE in `v3-invariant-ledger.md` at `seaweedfs@36ba7b44e` with concrete test pointers |
|
||||
|
||||
---
|
||||
|
||||
@@ -230,3 +230,4 @@ Predicates 1-4 satisfied. Predicate 5 dropped. **Sw cleared to start G5-4.1 code
|
||||
| 2026-04-26 | v0.2 | QA round 1 review responses: §1.3 role inference rewritten to read `fact.ReplicaID == self.ReplicaID` from master-minted field (proto verified at `control.proto:128-148` + master mint at `services.go:198-205`); no lex-smallest fallback. §4 #2 verifier reframed to G5-4.5 in-process test (m01 hardware = G5-5). §5 G5-DECISION-001 contradiction resolved: G5-4 ships Path B runtime + keeps Path A serializability seam open, architect-promotable at G5-6 with no engine-state-shape change. §6 added INV-BIN-WIRING-SESSIONID-VIA-ADAPTER (clarification ask: adapter mints unique sessionIDs via process-wide counter at `adapter.go:70`; binary inherits for free; framework shortcuts that hardcode sessionID=1 are the known gap, must not propagate to binary). |
|
||||
| 2026-04-26 | v0.3 | **Architect round 50 RATIFY with 2 binding clarifications.** Architect verbatim: "Role inference, in-process acceptance, G5-DECISION-001 seam, and sessionID discipline are architecturally correct. G-1 must clarify replica readiness semantics and confirm ctrl-addr reuse or introduce repl-addr before code." Bindings baked: (#1) §4 #2 acceptance criterion split by role — Primary `Healthy=true` per existing frontend/write-ready projection; Replica MUST NOT report `Healthy=true` if existing field implies frontend-primary-write-ready; G5-4.5 uses precise assertion names (`assertReplicaReplicationReady` vs `assertPrimaryFrontendReady`) if existing status field is too coarse. (#2) §4 #7 acceptance criterion strengthened: catalogue inscription alone insufficient at close; 5 INV-BIN-WIRING-* invariants MUST land in `v3-invariant-ledger.md` per `v3-quality-system.md` §6 rule "an invariant without a test is a wish"; ledger updated as PR atomic with code. §7.1 G-1 deliverable extended: G-1 MUST resolve replica-readiness-field question + ctrl-addr-reuse-vs-repl-addr question BEFORE code starts. Architect-pre-baked: ratification stays valid; no further mini-plan revisions needed before G-1. | architect |
|
||||
| 2026-04-26 | v0.4 | **Round 51 process call: G-1 ceremony DROPPED for G5-4.** User question surfaced the overhead-vs-value of G-1 for V3-native batches. Honest assessment: G-1 ceremony earned its keep on T4 V2-PORT batches (caught 3 real architectural pins pre-code: T4b-4 5 hidden invariants; T4c-2 probe non-mutation; T4d-3 3 placement decisions). For G5-4 (V3-native binary integration, not V2 PORT), G-1 doesn't earn its keep — mini-plan v0.3 already has scope + 7 acceptance criteria + 5 inscribed invariants + file map. Architect's 2 binding questions (round 50) become PR-description deliverables instead of separate ratified G-1 doc. Sw cleared to code immediately. **Process lesson**: don't auto-port T4 governance template to every batch; ask "does this step earn its keep" each time. Future V2-PORT batches still get G-1 ceremony. | QA + sw + user process call |
|
||||
| 2026-04-26 | v0.5 | **Architect round 51 close-sign + 4 doc-lock corrections applied.** Architect verbatim: "APPROVED — G5-4 close. Binary T4 replication wiring is complete at commit `seaweed_block@c820e17`; criteria 1/2/5/6/7 satisfied; criteria 3/4 explicitly relocated to G5-5 hardware first-light; --data-addr correction accepted; 5 INV-BIN-WIRING-* rows ACTIVE. Close claim is wiring-ready, not byte-movement-ready." Doc-lock fixes: (1) header status v0.2 → v0.5 CLOSED; (2) §1.2 + §1.5 `--ctrl-addr` → `--data-addr` correction inscribed (executor dials `peer.DataAddr` per `core/transport/executor.go:303`; `--ctrl-addr` reserved for future control-plane split, no current binder, no NVMe/iSCSI/status conflict); (3) §4 #3 + #4 marked RELOCATED to G5-5 with rationale (need real iSCSI/NVMe kernel client); (4) §4 #6 marked DONE (m01 -race ×10 PASS in 13.2s, was pending in v0.4); §4 #1/#2/#5/#7 marked DONE with evidence pointers. **Status**: CLOSED. | architect |
|
||||
|
||||
Reference in New Issue
Block a user