docs(P00): plan — v0.7 vertical-slice phase plans (P1..P6)
PLAN stage for v0.7. Vertical-slice plans for 5 execution phases + 1 final: - P1 Cover Pool Factory + firewall + floors + gates + tagging (v0.6.1) REQ-046/047/049/050 — firewall-first, NEW x/cover module (D-039/D-084) - P2 Cover-Charter + Pool governance + category staging (v0.6.2) REQ-048/052/062/065 — extends x/cover + x/council - P3 Guild Charter + Chapter Federation + Household/Confederation (v0.6.3) REQ-051/053/057/058/061 — extends x/guild + x/stand - P4 MAB + Cover Claims Voucher + Shadow vouch + MAB seniority (v0.6.4) REQ-054/055/060/063 — extends x/bond + x/cover + x/standing - P5 Anti-Capture Bill + secession cooling + Stand->Pier + Pier selection (v0.6.5) REQ-056/059/064/066 — cross-cutting, lands last (constrains all prior) - P6 final review/audit/ship (v0.6.6 = v0.7 milestone release) MVP/UX CHECK sections embedded in PLANS.md: - User-Facing Surface: simtest is the executable demonstration (no UI) - Happy Path: 10-step end-to-end Cover Pool lifecycle (launch -> charter -> elect -> route fee -> issue MAB -> release proceeds -> file call -> secede -> Pier escalation -> dissolve) - UX Acceptance Criteria: 11 criteria verified in P6 audit Cross-phase dependency map + 11 locked-const additions table included. D-085 escalation (13th right) flagged for lead-developer before P5. ---ci--- project: oy phase: 0 milestone: v0.7 status: plan ---/ci---
This commit is contained in:
@@ -6,9 +6,9 @@
|
||||
"project": "oy",
|
||||
"phase": 0,
|
||||
"phase_role": "pre_execution",
|
||||
"stage": "research",
|
||||
"stage": "plan",
|
||||
"attempts": 0,
|
||||
"updated_at": "2026-08-19T00:02:00Z",
|
||||
"updated_at": "2026-08-19T00:03:00Z",
|
||||
"next_milestone": null,
|
||||
"previous_milestone": {
|
||||
"milestone": "v0.6",
|
||||
|
||||
+246
-1
@@ -2149,4 +2149,249 @@ The v0.6 deliverable MUST meet these explicit criteria (verified in P6 audit):
|
||||
5. **Standing score computed from locked formula constants**: the Standing screen score uses `x/standing/types` constants (`PriorMean=4.0`, `PriorWeight=10`, decay buckets, `ComputeDiversityBonus`, `GetVoucherWeight`, `GetStandingBucket`) — NOT hardcoded; the standing-score computed-from-locked-constants test (P4-03-01) asserts this.
|
||||
6. **Freeholder-eligible badge reflects `IsFreeholderEligible()`**: the Standing screen badge is green when `FreeholderSignals.IsFreeholderEligible()==true` and grey when false; the Freeholder-eligible badge test (P4-03-01) asserts the rendered badge matches the method output.
|
||||
7. **Window lifecycle transitions match `Window.Activate/Revoke/Expire`**: the Window screen lifecycle buttons call the real `x/window/types.Window.Activate/Revoke/Expire` methods (NOT a reimplementation); `Revoke()` on an Expired window is a no-op (v0.2 type contract); the lifecycle correctness test (P3-03-01) asserts the real methods are invoked.
|
||||
8. **No banned terms in any rendered page**: the per-handler rendered-HTML lexicon checks (P1-04-03, P2-03-01, P3-03-01, P4-03-01, P5-03-01) scan each screen's HTTP response body via `lexicon.FindBannedTerm` and pass; the `lexicon_meta_web/` file-scan firewall passes on all `web/**/*.{html,js,go}` files.
|
||||
8. **No banned terms in any rendered page**: the per-handler rendered-HTML lexicon checks (P1-04-03, P2-03-01, P3-03-01, P4-03-01, P5-03-01) scan each screen's HTTP response body via `lexicon.FindBannedTerm` and pass; the `lexicon_meta_web/` file-scan firewall passes on all `web/**/*.{html,js,go}` files.
|
||||
|
||||
---
|
||||
|
||||
# Plans: OpenYield (oy) — v0.7 (Fraternal Groups Foundation)
|
||||
|
||||
## Milestone Summary
|
||||
|
||||
- **Milestone**: v0.7 — Fraternal Groups Foundation
|
||||
- **Type**: Feature (≥1 `feat` phase; REQ-046..REQ-066 are feat-class primitives + a test adjunct for the Anti-Crowding-Out firewall in P1)
|
||||
- **Tag base**: `v0.6.x` patch line (P0 ships as `v0.6.0`; execution phases `v0.6.1..v0.6.5`; final phase `v0.6.6` IS the v0.7 milestone release per D-008)
|
||||
- **Phases**: 6 — P1..P5 (execution) + P6 (final review/audit/ship). Phase 0 (PLAN) is in progress.
|
||||
- **Depth**: simtest-grade runtime (D-054 continues) — keeper MsgServer handlers + simtest end-to-end flows for `x/cover` (NEW) + extensions to `x/bond`, `x/guild`, `x/standing`, `x/stand`. No live chain launch, no `app.go`/`cmd/oyd`.
|
||||
- **Coverage target**: ≥80% on `x/cover` + extensions (D-033 carries forward); lexicon assertion (REQ-012) in `x/cover` test file + the 4th meta-test (`lexicon_meta_cover`) for the Anti-Crowding-Out firewall doc-drift (D-079).
|
||||
- **New modules**: 1 (`x/cover` — Cover Pool Factory + Anti-Crowding-Out firewall + Anti-Capture Bill of Rights + Cover Claims Voucher). **Extended**: 4 (`x/bond` MAB, `x/guild` Chapter Federation, `x/standing` Shadow vouch + slash reason, `x/stand` Household/Confederation keeper logic + Stand→Pier const). **Unchanged**: 1 (`x/pact` — PactCover enum stays as cross-reference, D-084).
|
||||
- **Phase ordering** (D-082): P1 Cover Pool Factory + firewall + locked floors + gates + tagging (firewall-first) → P2 Cover-Charter + Pool governance + category staging → P3 Guild Charter + Chapter Federation + Household/Confederation + disclaimer → P4 MAB + Cover Claims Voucher + Shadow vouch + MAB seniority → P5 Anti-Capture Bill + secession cooling + Stand→Pier boundary + Pier selection → P6 final review/audit/ship.
|
||||
- **Personas**: backend-engineer (all phases), lead-developer (all phases — coordination + D-085 escalation + pen-test assumption), security-engineer (all phases — highest security density since v0.5), cosmos-engineer (all phases — advisory; x/cover follows x/hub pattern).
|
||||
|
||||
### Cross-Phase Dependency Map
|
||||
|
||||
```
|
||||
P1 (x/cover Factory + firewall + floors + gates + tagging)
|
||||
│
|
||||
├─► P2 (x/cover Charter + governance hybrid + category staging)
|
||||
│ │
|
||||
│ └─► P3 (x/guild Chapter Federation + Household + Confederation + disclaimer)
|
||||
│ │ (Chapter liens reference Cover Pool covenants)
|
||||
│ │
|
||||
│ └─► P5 (x/cover Anti-Capture Bill + x/guild secession cooling + x/stand Pier boundary + Pier selection)
|
||||
│
|
||||
└─► P4 (x/bond MAB + x/cover Cover Claims Voucher + x/standing Shadow vouch + MAB seniority)
|
||||
│ (MAB depends on Cover Pool reserve for use-of-proceeds;
|
||||
│ Voucher slash depends on x/standing.Slash existing)
|
||||
│
|
||||
└─► P5 (Anti-Capture Bill constrains MAB no-Voice + Voucher independence + secession)
|
||||
```
|
||||
|
||||
### v0.7 Locked-Const Firewall Additions (pending GRILL ratification at P0)
|
||||
|
||||
11 new locked consts (all net-new, no amendments to existing consts — per oy-state §3 + ARCHITECTURE.md v0.7 section):
|
||||
|
||||
| Const | Value | Module | REQ | Locked? |
|
||||
|-------|-------|--------|-----|---------|
|
||||
| CoverReserveFloorAnnualContribX | 1.5 | x/cover | REQ-047 | yes |
|
||||
| CoverReserveCeilingAnnualContribX | 2.5 | x/cover | REQ-048 | no (bounded [1.5, 2.5]) |
|
||||
| CoverStandingGateTrusted | 4.0 | x/cover | REQ-049 | yes |
|
||||
| CoverStandingGatePreferred | 4.5 | x/cover | REQ-049 | yes |
|
||||
| MABIssuanceCeilingAnnualSurplusMultiple | 3 | x/bond | REQ-054 | yes |
|
||||
| CoolingSecessionCoverActiveDays | 21 | x/guild | REQ-064 | yes |
|
||||
| CoolingSecessionNonCoverDays | 14 | x/guild | REQ-064 | yes |
|
||||
| StandPierEscalationAnnualPassVolumeCents | 10000000 | x/stand | REQ-059 | no |
|
||||
| CoverClaimsVoucherBondMultipleAvgCall | 10 | x/cover | REQ-055 | no |
|
||||
| AntiCaptureBillOfRightsCount | 13 | x/cover | REQ-056 | yes |
|
||||
| ShadowVouchWeightMultiplier | 0.5 | x/standing | REQ-060 | yes |
|
||||
|
||||
---
|
||||
|
||||
## Phase P0 — Pre-Execution
|
||||
|
||||
- **Type**: docs
|
||||
- **Tag**: `v0.6.0`
|
||||
- **REQs**: none (pre-execution)
|
||||
- **Status**: IN PROGRESS (SPECIFY ✓, CLARIFY ✓, RESEARCH ✓, PLAN in progress, GRILL pending, MVP/UX pending, SHIP pending)
|
||||
|
||||
---
|
||||
|
||||
## Phase P1 — Cover Pool Factory + Firewall + Locked Floors + Gates + Tagging
|
||||
|
||||
- **Type**: feat + test (firewall-first vertical slice)
|
||||
- **Tag**: `v0.6.1`
|
||||
- **REQs**: REQ-046, REQ-047, REQ-049, REQ-050
|
||||
- **Module**: NEW `x/cover` (mirrors x/hub D-039 layout)
|
||||
- **Personas**: backend-engineer (types + keeper + module + simtest), security-engineer (firewall + locked floors + gates), cosmos-engineer (AppModule + expected_keepers + Msg*), lead-developer (regression guards)
|
||||
|
||||
### P1 Must-Haves
|
||||
|
||||
1. **`x/cover` module skeleton** — `x/cover/types/types.go` (CoverPool, CoverFeeTag, CoverCategory, CoverCategoryPhase structs + locked consts), `x/cover/types/expected_keepers.go` (StandingKeeper, WatcherKeeper, BondKeeper, StillKeeper interfaces — G-003 shims), `x/cover/types/msg_cover.go` (MsgLaunchCoverPool, MsgRouteCoverFee, MsgFileCoverCall — `sdk.Msg` impls with ValidateBasic), `x/cover/keeper/keeper.go` (store-backed), `x/cover/keeper/msg_server.go` (one handler per Msg*), `x/cover/keeper/firewall.go` (Anti-Crowding-Out firewall enforcement), `x/cover/module.go` (AppModule + RegisterServices + MsgServer() accessor). Layout mirrors `x/hub/` (D-039 precedent).
|
||||
2. **Anti-Crowding-Out firewall (D-079)** — `x/cover/firewall/` subpackage with `CheckCoverFeeRouting(path) error` that rejects any code path routing Cover-Fees outside contributor-pool semantics. Called at the start of every `MsgRouteCoverFee` handler. PLUS `lexicon_meta_cover/` meta-test (4th lexicon meta-test, mirrors `lexicon_meta_web/` pattern) scanning `x/cover/**` docstrings + `x/cover/firewall/**` for doc drift. Defense in depth: runtime rejects code path, meta-test rejects doc drift.
|
||||
3. **Reserve floor 1.5× (REQ-047 locked)** — `CoverReserveFloorAnnualContribX = 1.5` const in `x/cover/types`. `MsgRouteCoverFee` handler invokes `checkReserveFloor(ctx, poolID)`; if `pool.ReserveAnnualContribRatio < 1.5`, REJECT routing AND emit `PoolBelowFloor` event that triggers auto-pause for subsequent routings until reserve replenished. Below-floor auto-pause = the handler sets a `PoolPaused bool` on the CoverPool; subsequent `MsgRouteCoverFee` handlers reject while paused.
|
||||
4. **Standing gate minimums (REQ-049 locked, D-077)** — `CoverStandingGateTrusted = 4.0` + `CoverStandingGatePreferred = 4.5` consts in `x/cover/types` (cross-documented to `x/standing.BucketTrusted`/`BucketPreferred`). `MsgLaunchCoverPool` handler invokes `StandingKeeper.GetStandingBucket(hostReachID, category)` for each category the Pool covers; if any category's gate is below the locked minimum (Trusted 4.0 for Travel, Preferred 4.5 for Health-MCS), REJECT the launch. Gate binds at Factory runtime (D-077). Pool MAY tighten (a `PoolStandingGate` Params field ≥ protocol minimum); NEVER loosen (the const floor).
|
||||
5. **Cover-Fee category tagging (REQ-050 locked)** — `CoverFeeTag` struct in `x/cover/types` (`{GrainAmount int64, CategoryTag string, PoolID string}`). `MsgRouteCoverFee` handler validates the tag against the Pool's allowed categories; category-mismatch → REJECT (FR-COVER-11). Pool-level fungibility preserved for net-reserve accounting.
|
||||
6. **Factory runtime (REQ-046)** — `MsgLaunchCoverPool` handler: validates reserve floor (REQ-047), validates Standing gate per category (REQ-049), validates category is in an allowed phase (REQ-065 staging — placeholder in P1, full staging lands in P2), witnesses Cover-Charter (REQ-052 — Charter hash placeholder in P1, full Charter lands in P2). Watcher attestation pipeline: `WatcherKeeper.Attest(poolID, launchPayload)` called at launch; stubbed in simtest.
|
||||
7. **Simtest** — `x/cover/keeper/msg_server_simtest_test.go` exercising: (a) successful Pool launch with valid Standing + reserve; (b) rejected launch below Standing gate; (c) rejected launch below reserve floor; (d) rejected Cover-Fee routing with category mismatch; (e) auto-pause on below-floor + recovery on reserve replenishment; (f) firewall rejection of an out-of-pool routing path.
|
||||
8. **Lexicon + locked-const regression** — `x/cover/types/types_test.go` asserts the 4 new consts + lexicon assertion (no banned terms in `x/cover/**` — "Cover", "Cover-Fee", "Cover Call", "Cover-Charter" are the lexicon-clean names; NOT "insurance", "premium", "claim", "policy"). The `lexicon_meta_cover/` meta-test is the 4th lexicon firewall.
|
||||
9. **Coverage ≥80%** on `x/cover/types` + `x/cover/keeper` + `x/cover/firewall`.
|
||||
|
||||
### P1 Firewall-First Rationale
|
||||
|
||||
P1 lands the Anti-Crowding-Out firewall + locked floors + Standing gates BEFORE any Cover surface that could route around them (P2 Charter, P3 Federation, P4 MAB, P5 Bill of Rights). This is the D-044/D-069 firewall-first pattern: the firewall is in place before the content it guards.
|
||||
|
||||
---
|
||||
|
||||
## Phase P2 — Cover-Charter + Pool Governance Hybrid + Category Staging
|
||||
|
||||
- **Type**: feat
|
||||
- **Tag**: `v0.6.2`
|
||||
- **REQs**: REQ-048, REQ-052, REQ-062, REQ-065
|
||||
- **Modules**: extends `x/cover` (Charter + governance + staging) + `x/council` (Pool Council seat — no struct change, keeper logic)
|
||||
- **Personas**: backend-engineer (Charter + staging types + keeper), security-engineer (Charter validation + governance observer quorum), cosmos-engineer (Msg* + keeper handlers)
|
||||
|
||||
### P2 Must-Haves
|
||||
|
||||
1. **Cover-Charter (REQ-052 locked)** — `CoverCharter` struct in `x/cover/types` (`{CharterID, PoolID, StatementOfBeliefsHash []byte, DisputePath string, Gate string, HoldingPeriodDays uint32, HostReachID string, WatcherWitnessHash []byte, Amendments []CharterAmendment}`). `MsgSignCoverCharter` handler: signed by Pool Host + witnessed by Watcher. Amendments require Pool supermajority + 7-day cooling + Watcher + Counsel (a `CharterAmendment` struct with `Status` enum: Proposed/Cooled/Ratified). **Protocol does NOT enforce SoB content** (FR-CHTR-5) — the `StatementOfBeliefsHash` is opaque bytes; validation checks structural fields only.
|
||||
2. **Reserve ceiling 2.5× (REQ-048 not locked)** — `CoverReserveCeilingAnnualContribX = 2.5` const (the bounded upper limit). Pool Council MAY vote within [1.5×, 2.5×] via a `PoolReserveTarget` Params field. Watcher escalation to 2.5× after 12 months operating history (a `MsgEscalateReserveCeiling` handler requiring Watcher attestation + 12-month age check). The 1.5× floor (P1) is NOT tunable; only the target within the bounded range.
|
||||
3. **Pool governance hybrid (REQ-062 locked)** — `PoolCouncil` struct in `x/cover/types` (`{PoolID, HostReachID, ElectedMasonReachIDs [3]string, WatcherObserverReachID string}`). `MsgElectPoolMason` handler (Pool-eligible Masons elect 3). `MsgVoteCoverCall` handler: majority required with Watcher observer present (a `WatcherObserverPresent bool` field on the vote; if false, vote rejects). **No Anchor seat** (§5). No MAB-holder seat (REQ-063 — lands in P4 but the governance struct excludes them now).
|
||||
4. **Category staging (REQ-065 locked)** — `CoverCategoryPhase` enum in `x/cover/types` (`Phase2`/`Phase3`/`Phase4`). `CoverCategory` enum (`Travel`/`HealthMCS`/`IncomePause`/`EquipmentLoss`/`LifeBurial`/`RoadSide`/`CyberSkimming`/`GuildInternalMutualAid`). Phase 2 = Travel + HealthMCS + IncomePause; Phase 3 = EquipmentLoss + LifeBurial + RoadSide; Phase 4 = CyberSkimming + GuildInternalMutualAid. `FactoryAllowedPhases` Params field. `MsgLaunchCoverPool` handler (extended from P1) rejects out-of-phase launches.
|
||||
5. **Simtest** — (a) successful Charter signing + Watcher witness; (b) Charter amendment with 7-day cooling + supermajority; (c) Pool Council election (3 Masons); (d) Cover Call vote with Watcher observer present (succeeds) + absent (rejects); (e) Factory rejects out-of-phase category launch; (f) reserve ceiling escalation after 12-month age check.
|
||||
6. **Lexicon + locked-const regression** — `x/cover/types/types_test.go` extended with the ceiling + phase + category consts. Lexicon assertion on new Msg* names.
|
||||
7. **Coverage ≥80%** on the extended `x/cover` surface.
|
||||
|
||||
---
|
||||
|
||||
## Phase P3 — Guild Charter + Chapter Federation + Household/Confederation + Disclaimer
|
||||
|
||||
- **Type**: feat
|
||||
- **Tag**: `v0.6.3`
|
||||
- **REQs**: REQ-051, REQ-053, REQ-057, REQ-058, REQ-061
|
||||
- **Modules**: extends `x/guild` (Parent/Chapter + secession terms + liens + Household + Confederation) + `x/stand` (Household/Confederation keeper logic)
|
||||
- **Personas**: backend-engineer (Guild extension + keeper), security-engineer (lien bounding + secession cooling consts), cosmos-engineer (Msg* + keeper handlers)
|
||||
|
||||
### P3 Must-Haves
|
||||
|
||||
1. **Guild Charter + Common Bond (REQ-051 locked)** — extend `x/guild/types.Guild` with `CommonBondHash []byte` + `PublicProfile GuildPublicProfile` fields. `GuildPublicProfile` struct (`{BondSummary string, Disclaimers []string, MasonCount uint32_or_Private bool, PierWrapperID string}`). `MsgCreateGuild` handler (extended): Common Bond declared + hash-pinned at creation; Public Profile published. `MasonCount` is either a count or a `"private"` sentinel.
|
||||
2. **Chapter Federation (REQ-053)** — extend `x/guild/types.Guild` with `ParentGuildID string` (empty for Parent Guilds) + `IsChapter bool` + `SecessionTermsHash []byte` + `GoodStandingLiens []Lien`. `Lien` struct (`{Amount int64, CreditorReachID string, SecuredAtFounding bool}`). `MsgCreateChapter` handler: Parent Guild + Chapter model; Chapter inherits Parent's policies + MAY tighten but NOT loosen. Secession terms coded at founding (a `SecessionTerms` struct: `{CoolingCoverActiveDays uint32, CoolingNonCoverDays uint32, LienAuditRequired bool, CovenantClearanceRequired bool}` — hash-pinned at creation, immutable). Good-standing liens at founding (NOT freely increasable — `SecuredAtFounding=true` liens reject `MsgAddLien`). Chapter retains mesh-level Voice (Pier does NOT carry Voice per FR-VOICE-6 — a `PierCarriesVoice bool` const `false` in `x/guild/types`).
|
||||
3. **Household simplified (REQ-057)** — `x/stand` keeper: `IsHousehold(standID)` check (switch on `StandType == StandHousehold`). Household Stands skip the formal-Council requirement. `MsgOneTapExitStand` handler — the dispute path for Household. One-tap exit = the Stand is dissolved + assets returned to the Holder's Stash; no Council vote required.
|
||||
4. **Confederation Voice (REQ-058 locked)** — `x/stand` keeper: `GetConfederationVoice(confederationStandID) []Voice` aggregates member-Stand Voice one-per-Stand. Internal bundle delegation via §19 delegation (existing `x/council` Voice mechanics — a `MsgDelegateConfederationVoice` handler). One-Stand-one-Vote: each member Stand gets exactly 1 Voice in the Confederation's aggregate, regardless of size.
|
||||
5. **Disclaimer cadence (REQ-061 locked)** — `MsgCreateGuild` + `MsgCreateChapter` + `MsgSignCoverCharter` handlers all surface a jurisdictional disclaimer at every charter signing (a `Disclaimer string` field on each Msg; the handler returns the disclaimer in the response). NOT session-bounded.
|
||||
6. **Simtest** — (a) Guild creation with Common Bond hash + Public Profile; (b) Chapter creation with secession terms hash-pinned + good-standing liens; (c) Chapter inherits Parent policy + tightens (allowed) + loosens (rejected); (d) Household one-tap exit; (e) Confederation Voice aggregation (one-per-Stand); (f) disclaimer surfaced at every signing.
|
||||
7. **Lexicon + locked-const regression** — `x/guild/types/types_test.go` extended with the cooling consts (`CoolingSecessionCoverActiveDays=21`, `CoolingSecessionNonCoverDays=14`). Lexicon assertion on new Msg* names.
|
||||
8. **Coverage ≥80%** on the extended `x/guild` + `x/stand` surfaces.
|
||||
|
||||
---
|
||||
|
||||
## Phase P4 — Mutual Aid Bond + Cover Claims Voucher + Shadow Vouch + MAB Seniority
|
||||
|
||||
- **Type**: feat
|
||||
- **Tag**: `v0.6.4`
|
||||
- **REQs**: REQ-054, REQ-055, REQ-060, REQ-063
|
||||
- **Modules**: extends `x/bond` (MAB), `x/cover` (Cover Claims Voucher + MAB seniority waterfall), `x/standing` (Shadow vouch weight + slash reason)
|
||||
- **Personas**: backend-engineer (MAB + Voucher + Shadow vouch types + keeper), security-engineer (MAB use-of-proceeds lock + Voucher slashing + Shadow vouch const), cosmos-engineer (Msg* + keeper handlers)
|
||||
|
||||
### P4 Must-Haves
|
||||
|
||||
1. **Mutual Aid Bond (REQ-054 locked)** — `MAB` struct in `x/bond/types` (anonymous embed of `Bond` + `CouponKind CouponDenom` + `AnnualSurplusAtIssuance int64` + `UseOfProceedsTag string`). `CouponDenom` enum (`CouponDenomCoverCall`/`CouponDenomMutualAidCredit`/`CouponDenomBread` — the last exists ONLY to be rejected at `ValidateBasic` with "FR-MAB-3: MAB coupons NEVER Bread", mirroring `MissionLockAmendmentRejected`). `MABIssuanceCeilingAnnualSurplusMultiple = 3` const in `x/bond/types`. `MsgIssueMAB` handler: `checkMABIssuanceCeiling(ctx, poolID, newPrincipal)` asserts `sum(issuedMABPrincipal) + newPrincipal <= 3 × AnnualSurplus` (re-check at every issuance). Coupon rate bounded by `CouponCapBps=800` (existing locked const — no new const, cross-const test extends).
|
||||
2. **D-080 tagged streaming + Watcher-witnessed release** — `UseOfProceedsTag` field locked to `"reserve_build_out"` (a const `MABUseOfProceedsReserveBuildOut`). `MsgDebitMABProceeds` handler: checks destination account is the Pool's `ReserveAccount`; else invokes `StillKeeper.Still(poolID, "MAB misuse")` for auto-Still. `MsgWitnessMABProceedsRelease` handler: requires Watcher quorum (6-of-9, `x/watcher/types/types.go:23` `Quorum=6`) before proceeds move from tagged staging to reserve. Watcher attestation at deployment + quarterly audit (a `MsgWatcherAttestMAB` handler).
|
||||
3. **Cover Claims Voucher (REQ-055)** — `CoverClaimsVoucher` struct in `x/cover/types` (`{VoucherReachID string, PoolID string, BondAmount int64, BondMultipleAvgCall uint32}`). `CoverClaimsVoucherBondMultipleAvgCall = 10` const. Bond = 10× avg Call size per Pool. `MsgRegisterCoverClaimsVoucher` handler: bonds the Voucher. `MsgFileCoverCall` handler: assigns a Call to a Voucher; **no self-adjudication** (FR-CPCV-2) — rejects if `voucherReachID == claimantReachID`. Slashing via existing `x/standing.Slash` struct with new `SlashReasonFraudulentCoverCall` const — cross-Pool applicability (the slash drops the Voucher's Standing bucket, disqualifying them from other Pools). Bounded earnings (a `MaxVoucherEarningsPerCall` Params field).
|
||||
4. **Shadow vouch 50% weight (REQ-060 locked)** — extend `x/standing/types.Vouch` with `IsShadow bool` field. `ShadowVouchWeightMultiplier = 0.5` const in `x/standing/types`. Modify `GetVoucherWeight` to apply the multiplier as a post-step: `if isShadow { weight *= ShadowVouchWeightMultiplier }`. The const makes the 0.5× mission-locked (REQ-060 locked) and regression-testable. New test `TestShadowVouchWeight` in `x/standing/types/types_test.go`.
|
||||
5. **MAB holder seniority no-Voice (REQ-063 locked)** — `PoolDissolutionWaterfall` function in `x/cover/keeper`: returns `[{Tier: "CoverFeeContributors", ...}, {Tier: "MABHolders", ...}, {Tier: "BreadHolders", ...}]` (FR-MAB-4 seniority chain). MAB holders excluded from the Pool Council voice set (the `PoolCouncil` struct from P2 already excludes them; P4 adds the waterfall + a `MsgDissolveCoverPool` handler that invokes the waterfall). MAB holders have NO Voice in dissolution decisions.
|
||||
6. **Simtest** — (a) MAB issuance with valid Cover-Call coupons; (b) MAB issuance rejected with Bread coupons (FR-MAB-3); (c) MAB issuance rejected above 3× annual surplus ceiling; (d) tagged streaming misuse → auto-Still; (e) Watcher-witnessed release (quorum present: succeeds; absent: rejects); (f) Cover Claims Voucher registration + bond; (g) Cover Call adjudication (no self-adjudication); (h) Voucher slash for fraudulent Call → Standing bucket drop; (i) Shadow vouch 0.5× weight applied; (j) Pool dissolution waterfall (Cover-Fee contributors > MAB > Bread holders).
|
||||
7. **Lexicon + locked-const regression** — `x/bond/types/types_test.go` extended with `MABIssuanceCeilingAnnualSurplusMultiple=3` + `CouponDenom` enum count. `x/standing/types/types_test.go` extended with `ShadowVouchWeightMultiplier=0.5`. `x/cover/types/types_test.go` extended with `CoverClaimsVoucherBondMultipleAvgCall=10`. Cross-const test: MAB coupon cap == `CouponCapBps` (extends REQ-030 pattern).
|
||||
8. **Coverage ≥80%** on the extended `x/bond` + `x/cover` (Voucher + waterfall) + `x/standing` (Shadow vouch) surfaces.
|
||||
|
||||
---
|
||||
|
||||
## Phase P5 — Anti-Capture Bill of Rights + Secession Cooling + Stand→Pier Boundary + Pier Selection
|
||||
|
||||
- **Type**: feat
|
||||
- **Tag**: `v0.6.5`
|
||||
- **REQs**: REQ-056, REQ-059, REQ-064, REQ-066
|
||||
- **Modules**: extends `x/cover` (Anti-Capture Bill of Rights + Pier Selection Index), `x/guild` (secession cooling enforcement), `x/stand` (Stand→Pier boundary const + escalation)
|
||||
- **Personas**: backend-engineer (Bill of Rights + secession + Pier types + keeper), security-engineer (Bill of Rights firewall + secession lien audit + Pier Selection Index), lead-developer (D-085 escalation — 13th right identification before P5 lands), cosmos-engineer (Msg* + keeper handlers)
|
||||
|
||||
### P5 Must-Haves
|
||||
|
||||
1. **Anti-Capture Bill of Rights v0.2 (REQ-056 locked)** — `x/cover/types/rights.go`: 13 `RightID` consts + 13 `Waivable*` bool consts (all `false`) + `RightIsWaivable(id RightID) bool` function that always returns `false`. `AntiCaptureBillOfRightsCount = 13` const. The 12 enumerated rights: `RightOneTapExit`, `RightNoTaxOnPersonalStash`, `RightAuditableVoice`, `RightCooling`, `RightWatcherInspection`, `RightFreeholderVoucher`, `RightCounselEscalation`, `RightAnchoredBreadConversion`, `RightWayfarersRecord`, `RightSecessionFoundingTerms`, `RightNonCoverAccess`, `RightCategoryMismatchRefusal`. **The 13th right** — D-085 escalation candidate: `RightNonParticipationNoDenial` (confidence 0.55; "non-participation MUST NOT deny other mesh products" per REQ-085/FR-NORM-4). **Lead-developer surfaces D-085 to PO before P5 lands.** If unresolved at full autonomy, log as assumption with `RightNonParticipationNoDenial` and proceed.
|
||||
2. **Dual firewall (const + ValidateBasic)** — `MsgSignCoverCharter.ValidateBasic` (extended from P2): checks the charter's `WaivedRights []RightID` field; if ANY right is in the list, REJECT with "REQ-056: rights non-amendable, non-waivable by any Charter". Mirrors `MissionLockAmendable=false` + `MissionLockAmendmentRejected` (D-064). The 13 `Waivable*` consts are the const firewall; the `ValidateBasic` gate is the runtime firewall.
|
||||
3. **Secession cooling enforcement (REQ-064 locked)** — `x/guild/keeper`: `MsgInitiateSecession` handler records `secessionStartedAt` + invokes `lienAudit(poolID)`. `MsgCompleteSecession` handler checks: (a) `now >= secessionStartedAt + coolingSeconds` where `coolingSeconds = CoolingSecessionCoverActiveDays*86400` (21d) if the Chapter is Cover-active, else `CoolingSecessionNonCoverDays*86400` (14d); (b) lien-audit-passed; (c) Cover Call / Bond covenant clearance passed. Cooling secured at founding (the `SecessionTerms` from P3 is immutable), NOT reducible. Parent Guild Treasury receives pro-rata Cover-Fee settlement for in-flight Cover Calls (a `ProRataSettlement` function in `x/cover/keeper`).
|
||||
4. **Stand→Pier boundary (REQ-059, D-074)** — `StandPierEscalationAnnualPassVolumeCents = 10000000` const in `x/stand/types` (placeholder for $100k in Grain-cents at simtest; the PO ruling D-074 is $100k USD which is converted at the current USD/Grain oracle rate — but no oracle exists in simtest). The handler `MsgEscalateStandToPier` (or a keeper-level `checkStandPierEscalation(standID)` invoked on Pass routing): when annual Pass volume > the const, the Stand is *invited* to Hub API (a `StandPierEligible bool` flag + a `MsgAcceptPierInvitation` handler). Soft upgrade, not a ban — the Stand may decline.
|
||||
5. **Pier selection (REQ-066)** — `PierSelectionIndex` struct in `x/cover/types` (`{PierID string, JurisdictionalReliabilityScore float64, FiduciaryRecordHash []byte, IntegrationQualityScore float64, OverallScore float64}`). `MsgSelectPier` handler: Guild Council chooses Pier at formation. `MsgRevokePierSelection` handler: reversible by Cover Pool supermajority + Counsel witness. Mesh maintains the Pier Selection Index (a keeper-level `GetPierSelectionIndex(pierID)` query). **Pier-Routed Legal Wrapper is OPTIONAL** (§5 default-no-wrapper — no code required; a `PierWrapperID string` field on Guild from P3 is optional, empty by default).
|
||||
6. **Simtest** — (a) Charter signing with waived rights → REJECT (dual firewall); (b) Charter signing with no waived rights → succeeds; (c) `RightIsWaivable` returns false for all 13 rights; (d) secession initiation + 21d cooling (Cover-active) + lien audit + covenant clearance + completion; (e) secession rejected before cooling expires; (f) secession rejected with outstanding liens; (g) Stand→Pier escalation at >10M Grain-cents annual Pass volume; (h) Stand declines Pier invitation (soft upgrade); (i) Pier selection by Guild Council; (j) Pier selection revoked by Cover Pool supermajority + Counsel.
|
||||
7. **Lexicon + locked-const regression** — `x/cover/types/types_test.go` extended with `AntiCaptureBillOfRightsCount=13` + 13 `Waivable*` consts all false. `x/stand/types/types_test.go` extended with `StandPierEscalationAnnualPassVolumeCents=10000000`. Lexicon assertion on new Msg* names.
|
||||
8. **Coverage ≥80%** on the extended `x/cover` (Bill of Rights + Pier Index) + `x/guild` (secession) + `x/stand` (Pier boundary) surfaces.
|
||||
|
||||
---
|
||||
|
||||
## Phase P6 — Final Review + Audit + Milestone Ship
|
||||
|
||||
- **Type**: final (REVIEW + AUDIT + milestone SHIP)
|
||||
- **Tag**: `v0.6.6` (= v0.7 milestone release per D-008)
|
||||
- **REQs**: all REQ-046..REQ-066 marked complete
|
||||
- **Personas**: lead-developer (review + audit + ship), ci-security-auditor (REACTIVATED — feature purity gate + pen-test), backend-engineer (P1+ fixes if review flags), security-engineer (P1+ fixes if review flags)
|
||||
|
||||
### P6 Must-Haves
|
||||
|
||||
1. **`ciagent-review`** — multi-persona code review across P1..P5. Reviews all changes in `milestone/v0.7-fraternal-groups`. Auto-applies P0 fixes, flags P1+ for post-hoc review. If P1+ issues found: fix in P6.
|
||||
2. **`ciagent-audit`** — reconstruction test (git log matches `.ciagent/` files), `.ciagent/` file discipline, branch hygiene, commit discipline.
|
||||
3. **Feature purity gate** — no breaking schema changes to EXISTING locked consts; G-003 production firewall intact; G-006/G-028 go.mod diff EMPTY; lexicon firewall green (4 meta-tests: x/, docs/, web/, cover/). The 11 new locked consts are net-new (not amendments).
|
||||
4. **§7 acceptance criteria verified**:
|
||||
- ≥1 Cover Pool live on testnet with reserve enforcement + Standing gate + category tagging (simtest-grade — P1+P2)
|
||||
- ≥1 Parent Guild with Chapter in secession-eligible formation with good-standing liens declared at founding (P3)
|
||||
- ≥1 Mutual Aid Bond issuance with Cover-Call coupon settlement + use-of-proceeds lock to reserve build-out (P4)
|
||||
- Anti-Capture Bill v0.2 reviewed by bonded Counsel (simtest — the Counsel review is a `MsgCounselReviewBillOfRights` handler; "bonded" = the Counsel's Standing bond is staked)
|
||||
- **pen-test ≥1 independent third party** — at full autonomy with no external third party available, run self-administered adversarial review (ci-griller persona) and log as assumption (oy-state §7 remaining-open item 4). The ci-griller red-teams the Anti-Capture Bill + Anti-Crowding-Out firewall + MAB use-of-proceeds lock + secession cooling + Voucher slashing.
|
||||
- high/critical findings remediated (the ci-griller's binding P0 fixes are applied in P6; P1+ flagged for post-hoc review)
|
||||
5. **`ciagent-ship` (milestone ship)** — merge `phase/06` → `milestone/v0.7-fraternal-groups` → `main`. Tag `v0.6.6` (= v0.7 milestone release). Create release with full milestone summary. Delete all milestone branches (local + remote).
|
||||
6. **Milestone completion** — REQUIREMENTS.md marks REQ-046..REQ-066 complete. ROADMAP.md marks v0.7 complete. Commit `docs(milestone): complete v0.7-fraternal-groups-foundation`. Clear CHECKPOINT.json.
|
||||
|
||||
---
|
||||
|
||||
## User-Facing Surface
|
||||
|
||||
(MVP/UX CHECK section 1 of 3 — per run.md MVP/UX CHECK gate)
|
||||
|
||||
v0.7 is a protocol milestone with NO user-facing UI surface (the v0.6 web UI is complete; v0.7 does not touch `web/`). The user-facing surface for v0.7 is the **simtest** — the `x/cover/keeper/msg_server_simtest_test.go` file is the executable demonstration that a Cover Pool can be launched, a Charter signed, a MAB issued, a Cover Call adjudicated, and a Chapter seceded. The simtest IS the "user-facing surface" for a protocol milestone: it's the artifact a developer reads to understand the Cover Pool lifecycle.
|
||||
|
||||
- **CLI flag**: none (no `oyd` daemon exists; D-020 continues). The simtest is run via `go test ./x/cover/keeper/...`.
|
||||
- **README quickstart**: the v0.7 milestone adds a section to `docs/reference/` (lead-developer territory, not v0.7 scope — docs-content is deactivated per PERSONAS.md; the ARCHITECTURE.md v0.7 section is the reference). The simtest is the quickstart.
|
||||
- **Docs**: `.ciagent/oy/ARCHITECTURE.md` v0.7 section (the component index + cross-component dependencies + locked-const additions) is the developer-facing reference for the Cover Pool surface.
|
||||
- **`.feature` Scenario**: the simtest functions are named as scenarios: `TestCoverPoolLaunch_ValidStanding`, `TestCoverPoolLaunch_BelowStandingGate_Rejected`, `TestMABIssuance_BreadCoupons_Rejected`, `TestSecession_21DayCooling_CoverActive`, `TestAntiCaptureBill_WaivedRights_Rejected`, etc.
|
||||
|
||||
## Happy Path
|
||||
|
||||
(MVP/UX CHECK section 2 of 3 — per run.md MVP/UX CHECK gate)
|
||||
|
||||
The v0.7 happy path (end-to-end scenario, written BEFORE execute, verified by simtest in P6):
|
||||
|
||||
1. **A Guild Council creates a Cover Pool** via `MsgLaunchCoverPool` for the Travel category (Phase 2). The Factory validates: reserve floor 1.5× (REQ-047), Standing gate Trusted 4.0 for the Pool Host (REQ-049), category Travel is in Phase 2 (REQ-065). The Watcher attests the launch. The Pool is live (simtest-grade).
|
||||
2. **The Pool Host signs a Cover-Charter** via `MsgSignCoverCharter` with a Statement-of-Beliefs hash, a dispute path, a 30-day holding period, and a Watcher witness. The Charter is distinct from the Guild's governance charter. The protocol does NOT parse the SoB content (FR-CHTR-5). The Anti-Capture Bill of Rights is non-waivable — the Charter's `WaivedRights` field is empty (REQ-056).
|
||||
3. **Pool-eligible Masons elect 3 Masons to the Pool Council** via `MsgElectPoolMason`. The Pool Council = Pool Host + 3 elected + Watcher observer. No Anchor seat (§5). No MAB-holder seat (REQ-063).
|
||||
4. **Cover-Fees are routed to the Pool** via `MsgRouteCoverFee` with a `CoverFeeTag{CategoryTag: "Travel", PoolID: "pool-1"}`. The Anti-Crowding-Out firewall (D-079) checks the routing path — the fee goes to the Pool's contributor-pool reserve, NOT to Root-Pool operating expenses. The reserve floor check passes (1.5×). The category-tag matches the Pool's allowed categories (FR-COVER-11).
|
||||
5. **The Pool issues a Mutual Aid Bond** via `MsgIssueMAB` with `CouponKind: CouponDenomCoverCall`, `PrincipalGrain: 50000000`, `UseOfProceedsTag: "reserve_build_out"`. The issuance ceiling check passes (`sum(existing MAB principal) + 50M <= 3 × AnnualSurplus`). The coupon rate is bounded by `CouponCapBps=800` (8%). The proceeds are tagged for reserve build-out (D-080).
|
||||
6. **The MAB proceeds are released** via `MsgWitnessMABProceedsRelease` — the Watcher quorum (6-of-9) witnesses the release. The proceeds move from the tagged staging account to the Pool's reserve account. If the proceeds were routed elsewhere, the auto-Still would fire (simtest tests this in a negative case).
|
||||
7. **A Cover Call is filed** via `MsgFileCoverCall` — a Holder files a Cover Call against the Travel Pool. A Cover Claims Voucher is assigned (bond 10× avg Call size). The Voucher is NOT the claimant (FR-CPCV-2 no self-adjudication). The Voucher adjudicates the Call. If the Voucher commits fraud, they are slashed via `x/standing.Slash` with `SlashReasonFraudulentCoverCall` — the Standing bucket drops, disqualifying them from other Pools (cross-Pool applicability).
|
||||
8. **A Parent Guild's Chapter secedes** — the Chapter was founded with `SecessionTerms{CoolingCoverActiveDays: 21, LienAuditRequired: true, CovenantClearanceRequired: true}` + a good-standing lien secured at founding. The Chapter initiates secession via `MsgInitiateSecession`. After 21 Mesh-days (Cover-active), the lien audit passes, the Cover Call / Bond covenants are cleared, and the secession completes via `MsgCompleteSecession`. The Parent Guild Treasury receives pro-rata Cover-Fee settlement for in-flight Cover Calls.
|
||||
9. **A Stand's annual Pass volume exceeds $100k** (10M Grain-cents) — the Stand is invited to the Hub API via `MsgEscalateStandToPier`. The Stand accepts the Pier invitation. The Stand→Pier boundary is a soft upgrade, not a ban.
|
||||
10. **The Pool dissolves** — the Pool Council (Host + 3 elected + Watcher observer, MAB holders excluded) votes to dissolve. The `PoolDissolutionWaterfall` pays: Cover-Fee contributors first, MAB holders second, Bread holders third (FR-MAB-4 seniority). MAB holders have NO Voice in the dissolution decision (REQ-063).
|
||||
|
||||
This happy path is verified by the P6 simtest suite. The simtest is the executable spec.
|
||||
|
||||
## UX Acceptance Criteria
|
||||
|
||||
(MVP/UX CHECK section 3 of 3 — per run.md MVP/UX CHECK gate)
|
||||
|
||||
The v0.7 deliverable MUST meet these explicit criteria (verified in P6 audit):
|
||||
|
||||
1. **`go build ./...` + `go test ./...` GREEN** — all packages (v0.1-v0.6 baseline + v0.7 `x/cover` + extensions). No FAIL. The simtest is the executable demonstration.
|
||||
2. **`x/cover` module exists with the full Cover surface** — Factory + firewall + floors + gates + tagging (P1) + Charter + governance + staging (P2) + Bill of Rights + Voucher + Pier Index (P5). Layout mirrors `x/hub` (D-039 precedent verified at `x/hub/types/types.go:33-57`).
|
||||
3. **Anti-Crowding-Out firewall operational** — `x/cover/firewall/` subpackage rejects any code path routing Cover-Fees outside contributor-pool semantics; `lexicon_meta_cover/` meta-test rejects doc drift. 4 lexicon meta-tests green (x/, docs/, web/, cover/). Defense in depth (D-079).
|
||||
4. **11 new locked consts in place + regression tests** — all 11 consts from the v0.7 const firewall additions table, with regression tests asserting their values. No existing locked consts amended.
|
||||
5. **MAB coupons NEVER Bread** — `CouponDenomBread` rejected at `ValidateBasic` (FR-MAB-3). The simtest `TestMABIssuance_BreadCoupons_Rejected` passes. MAB issuance ceiling 3× annual surplus enforced at keeper (`TestMABIssuance_AboveCeiling_Rejected` passes).
|
||||
6. **Anti-Capture Bill of Rights = 13 rights, non-amendable, non-waivable** — `RightIsWaivable` always returns false; Charter `WaivedRights` field rejected at `ValidateBasic` (REQ-056). `AntiCaptureBillOfRightsCount=13` regression test passes. D-085 (13th right) logged as assumption with `RightNonParticipationNoDenial` candidate if PO did not rule before P5.
|
||||
7. **Coverage ≥80%** on `x/cover` + all extensions (`x/bond`, `x/guild`, `x/standing`, `x/stand`).
|
||||
8. **G-003 production firewall intact** — `x/cover` references `x/standing`/`x/watcher`/`x/bond`/`x/still` via `expected_keepers.go` shims; no struct imports across `x/<module>/types`. Verified by the lexicon_meta + a G-003 regression test. `x/pact.PactCover` stays as cross-reference (D-084).
|
||||
9. **G-006/G-028 go.mod diff EMPTY** — no new Go deps; `x/cover` uses existing cosmos-sdk v0.50.8 + ibc-go v8.2.1. `git diff v0.5.6..v0.6.6 -- go.mod` shows no new require lines.
|
||||
10. **Pen-test (self-administered adversarial review via ci-griller)** — the ci-griller red-teams the Anti-Capture Bill + Anti-Crowding-Out firewall + MAB use-of-proceeds lock + secession cooling + Voucher slashing. High/critical findings remediated in P6; P1+ flagged for post-hoc review. Logged as assumption per oy-state §7 remaining-open item 4.
|
||||
11. **§7 acceptance criteria met** — ≥1 Cover Pool live (simtest), ≥1 Parent+Chapter secession-eligible (simtest), ≥1 MAB issuance (simtest), Anti-Capture Bill reviewed by bonded Counsel (simtest `MsgCounselReviewBillOfRights` handler), pen-test complete (self-administered), high/critical remediated.
|
||||
Reference in New Issue
Block a user