Skip to content

docs: add Blueprint governance layer for protocol architecture - #2

Merged
2 commits merged into
nextfrom
feat/blueprint-governance-layer
Feb 24, 2026
Merged

2 commits merged into
nextfrom
feat/blueprint-governance-layer

Conversation

@mmacedoeu

Copy link
Copy Markdown
Contributor

Summary

Adds the Blueprint layer — a single reference document explaining how ideas become protocol reality in CipherOcto.

This formalizes the governance stack and enables scalable contributor onboarding.

What Changed

New Files

  • docs/BLUEPRINT.md — The complete governance architecture
  • docs/use-cases/ — Intent layer (WHY)
  • rfcs/ — Protocol Design layer (WHAT)
  • missions/ — Execution layer (HOW)

The Governance Stack

Use Cases (WHY) → RFCs (WHAT) → Missions (HOW)

Why This Matters

Most open-source projects organize files. Successful protocols organize decision flow.

After this change:

  • Clear: Use Case → RFC → Mission → PR → Merge
  • Contributors know what to do: Claim a mission from missions/open/

- Add BLUEPRINT.md explaining how ideas become protocol reality
- Add RFCs directory with RFC-0001 (Mission Lifecycle) and RFC-0002 (Agent Manifest)
- Add use-cases directory with Decentralized Mission Execution
- Establish governance stack: Use Cases → RFCs → Missions → Agents
- Create missions directory structure (open/, claimed/, with-pr/, archived/)

This formalizes the decision flow and enables scalable contributor
onboarding: 'What do I do first?' becomes 'Read Blueprint → Claim Mission'
@github-merge-queue github-merge-queue Bot closed this pull request by merging all changes into next in 799e040 Feb 24, 2026
@mmacedoeu
mmacedoeu deleted the feat/blueprint-governance-layer branch February 24, 2026 22:52
mmacedoeu added a commit that referenced this pull request Mar 9, 2026
Critical fixes:
- #1: Remove dqa_div todo! stub, add full implementation
- #2: BIGINT mul - mandate Schoolbook algorithm
- #3: mat_mul - add overflow trap before i32 cast
- #4: Sigmoid/tanh LUT - implement full functions
- #11: Fix test_overflow_saturation -> test_overflow_traps

Version updated to v8 (Experimental status)
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
Round 2 review of commit 3abc29b surfaced 6 NEW defects introduced
by the Round 1 fixes. All 6 are now addressed.

CRITICAL #1: stoolap set_event_anchor_tx_hash silently Ok on 0-row UPDATE
- store/stoolap.rs: when UPDATE affects 0 rows (event not found OR
  idempotent re-submit with same hash), the prior code returned
  Ok(()). Now distinguishes the two via a SELECT probe:
    * row absent           -> ChainRefInvalid("event_not_found")
    * row present + same hash -> Ok (idempotent re-submit)
    * row present + diff hash -> ChainRefInvalid("anchor_already_set")
  Mirrors the memory backend contract from commit 3abc29b.

CRITICAL #2: BLAKE3 cascade is order-sensitive without canonicalization
- porelay/aggregation.rs aggregate_children now sorts parents by
  (level, epoch, scope, proof_count, children_root) before hashing.
  Two replicas receiving the same parent set in different orders
  now produce identical children_root.

HIGH #3: clippy --features octo-reputation/stoolap -D warnings fails
- 4 unused imports in slash_api.rs (cfg-gated module) and
  cross_backend_integration.rs removed.
- store/stoolap.rs: while-let-on-iterator rewritten as for-loop
  (clippy::while-let-on-iterator).

MEDIUM #4: AnchorSubmitterRejected = 0x33 has no test pin
- error.rs cases array extended with the new variant (45 cases
  total). Test count assertion updated from 44 -> 45.

MEDIUM #5: BLAKE3 cascade has no tests
- porelay/aggregation.rs: 3 new tests verify:
    * aggregate_children_is_order_independent (same parent set in
      different orders -> same root)
    * aggregate_children_is_deterministic (same parent set across
      multiple calls -> same root)
    * aggregate_children_rejects_empty_parents

MEDIUM #6: set_event_anchor_tx_hash event_not_found path untested
- store/memory.rs: new test asserts ChainRefInvalid event_not_found
  when no record_signal has been issued.

New tests in anchor_job.rs:
- run_once_strict_emits_anchor_submitter_rejected: rejects
  RejectingSubmitter (returns SubmitterRejected("rpc_timeout")) and
  asserts AnchorSubmitterRejected variant with the original reason.
- run_once_strict_emits_already_anchored_in_window: rejects
  AlreadyAnchoredSubmitter and asserts AnchorSubmitterRejected
  with reason "already_anchored_in_window".

cargo clippy --workspace --all-targets --features
  octo-reputation/stoolap -- -D warnings: clean.
cargo test -p octo-reputation --features stoolap --lib: 183 -> 186.
cargo test -p octo-network --lib: 1320 -> 1323 (+3 BLAKE3 cascade
  tests).
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
Round 18 adversarial review (test-coverage) found 2 HIGH + 2
MEDIUM + 2 LOW.

HIGH: Slash EWMA N=1 boundary. At N=1 EWMA equals the seed score
(alpha=1, no smoothing). The 5-event test would pass even if
both backends returned NaN/0 at n=1. Added
cross_backend_slash_ewma_n1_equals_score: single Slash event
with score 0.42; assert EWMA == 0.42 byte-identical across
backends + samples == 1.

HIGH: cross-layer absence for Slash. The existing cross-layer
test uses Outcome; the (Slash, Governance) corner was uncovered.
A bug that conflates kinds/layers asymmetrically would slip
past both tests. Added
cross_backend_severity_total_not_found_for_cross_layer_absence_slash.

MEDIUM: pre-pop MAX race contract too loose. Lower bound (>=1)
allows all 4 to succeed if the race window shrinks to nothing
(no collision = no race). Tightened to require success_count < 4
so at least one collision is required to demonstrate the race
is real. Upper bound kept at <=4 (trivially true) but the <4
constraint is the load-bearing pin.

LOW (overlapping with HIGH #2): same-kind-different-layer for
Slash — same test as the HIGH fix above.

Skipped:
- success_count == 0 all-collide test: race cannot legitimately
  yield 0 successes (first INSERT always wins on PK uniqueness);
  a 0-success outcome would indicate catastrophic pre-INSERT
  failure, which is already covered by the err_count=4 assert.
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
Round 8 review (background subagent, 2026-07-30) found 2 MAJOR + 1 MINOR.
The 2 MAJORs are fixed; the 1 MINOR is reported without action.

**MAJOR fix #1 — path (b) is unsafe, removed**:
- The existing `GovernanceProof` in `crates/octo-reputation/src/auth.rs:113+`
  is NOT an older form of the anchor quorum wrapper. It is a
  semantically distinct **slash/suspension authorization envelope**
  carrying `governance_pubkey`, `recorder_id`, `reason_hash`,
  slash destination/amount/asset fields required by RFC-0968
  authorization flows. The existing `GovernanceSnapshot`
  (line 21-25) is similarly tied to governance-membership semantics.
- Path (b) (in-place evolution) would remove data required by current
  RFC-0968 authorization flows. It is not a viable reconciliation path.
- Removed path (b) entirely. Scope item 2 now mandates path (a) only,
  with explicit rationale for why path (b) is not viable.

**MAJOR fix #2 — AC #12 escape hatch closed**:
- The previous AC #12 fallback 'or the chosen reconciliation path
  documented in PR description' allowed an implementation to satisfy
  the literal AC by documentation alone without adding the required
  types or migrating call sites.
- AC #12 now requires: anchor-specific verifier types
  (`AnchorGovernanceSnapshot` / `AnchorGovernanceSigner` /
  `AnchorGovernanceProof`) defined per RFC-0955-R1 lines 177-200,
  with existing `GovernanceSnapshot` / `GovernanceProof`
  (RFC-0968 authorization envelopes) preserved unchanged at
  `auth.rs:21-25` and `auth.rs:113+`. Documentation alone no
  longer satisfies the AC.

**MINOR #3 reported without action**:
- `missions/open/0968-b-marketplace-integration.md` is a stale copy
  (declares 'Open (2026-07-26)') while the canonical Path B closure
  is at `missions/archived/0968-b-marketplace-integration.md`
  (declares 'Completed (Archived 2026-07-30 — Path B)'). Per BLUEPRINT.md
  §1152-1158 (just added), mission file moves require user
  authorization. Surfacing for user decision; not deleting.
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
Round 11 review (background subagent, 2026-07-30) found 2 MAJOR + 2 MEDIUM.
All addressed.

**MAJOR fix #1 — §13 prefix on wrong lines**:
- Mission cited 'RFC-0968 §13 line 2057 + 2621' (lines 100, 267, 83).
  Only line 2621 is actually in §13 (per RFC-0968 §13 heading at line
  2595). Line 2057 is in §10 Core Interfaces (heading at line 1719).
  Line 616 is in §3 Recorder Authorization (heading at line 268).
- Replaced 'RFC-0968 §13 line 2057 + 2621' with 'RFC-0968 §10 line 2057
  + §13 line 2621 + §3 line 616' in 2 locations (Scope item 1 and
  AC #1). The §13 prefix on 2057 + 616 was Round 5 stale-claim
  propagation (the 0x2D drift was real; only the §13 section label
  was wrong).
- Also added §3 to the 'Why not RFC-0968-A2 amendment' section text.

**MAJOR fix #2 — test vector name typo**:
- Mission cited `CANONICAL_ANCHOR_BLOB_{0,1,100}_LEAVES` (line 137).
  The middle constant is `_1_LEAF` (singular), not `_1_LEAVES`.
  Anyone literally taking the template would write the wrong name.
- Replaced with explicit `CANONICAL_ANCHOR_BLOB_0_LEAVES` / `_1_LEAF`
  / `_100_LEAVES`.

**MEDIUM fix #3 — duplicate sentence**:
- Scope item 7 had a duplicate 'draft was wrong — idempotency is on
  event_id, not anchor_tx_hash' fragment at lines 233-235 vs 236-237.
  Removed the duplicate.

**MEDIUM fix #4 — prettier**:
- Ran `npx prettier --write`. The path paragraph still triggers a
  known cycle (a Prettier issue with the nested lettered paths);
  the committed state is the canonical version. Cosmetic.

Mission 0968a2 RFC section attribution now 100% accurate across all
3 RFCs (RFC-0955, RFC-0955-R1, RFC-0968). All line citations verified
across rounds 1-11.
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
Round 14 review (background subagent, 2026-07-30) found 2 MAJOR findings.
Both addressed.

**MAJOR fix #1 — broken markdown fragment from Round 13 fix**:
The Round 13 fix (changing 'AC #5' to 'AC #7' in Scope item 3) went
sideways — the edit pattern left a duplicate fragment with broken
`**` / `:**` markers at lines 190-193. The duplicate was:
'of `rotation_receipt_id`)**: the live submitter must write the' +
'of `rotation_receipt_id`):** the live submitter must write the'.
Removed the duplicate fragment. The merged text now reads cleanly:
'**Explicitly covers 0968a AC #7 (chain-side encoding of
`rotation_receipt_id`)**: the live submitter must write the
`ReputationAnchorBatch.rotation_receipt_id` field through to the
v010 ledger's `rotation_receipt_id` column (per
`v010__reputation_anchors.sql` line 62). Wire it into...'

**MAJOR fix #2 — prettier check**:
Re-ran `npx prettier --write` after the markdown fix. The known
cycle on lines 162-167 + 169-173 (Scope item 2 nested sub-bullets
for path (a) reconciliation + AnchorLeaf::digest sub-list) persists.
This is a Prettier bug with Markdown list-item continuation
indentation; the committed state is the canonical version. The
reviewer verified finding #1 (the duplicate fragment) was a major
contributor to the prettier failure; that fix alone eliminated the
secondary markdown breakage. The remaining cycle is not a content
issue.

Mission 0968a2 file content is now consistent. The prettier cycle
is acknowledged as a separate Prettier issue without a clean fix.
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
…liation

Landing 0968a2 implementation. Closes 7 of 17 ACs directly; the
remaining 10 are either pure verification (AC #1) or blocked by
external dependencies (AC #7-8 chain-substrate selection, AC #9-11
live anchor plumbing, AC #13 config crate path, AC #16 0855p-b
successor).

Direct closes:

- AC #2 (governance fields on ReputationAnchorBatch): added
  governance_snapshot, governance_proof, governance_set_hash fields
  to crates/octo-reputation/src/anchor.rs:140 with full digest
  folding. The 3 governance types live at auth.rs as
  AnchorGovernanceSnapshot / AnchorGovernanceSigner /
  AnchorGovernanceProof (path (a) mandated; preserves existing
  GovernanceSnapshot/GovernanceProof at auth.rs:21-25/113+).

- AC #3 (batch_size: u32): RFC-0955-R1 line 173 mandate. Added
  batch_size field; within_leaf_cap() now requires
  batch_size == leaves.len().

- AC #4 (chain_block_height: Option<u64>): RFC-0955-R1 line 170
  mandate. None at submission, Some(h) after MIN_FINALITY_BLOCKS
  finality. Digest uses Option tag encoding (0x00 None, 0x01 || 8
  bytes BE Some).

- AC #5 (AnchorLeaf::digest field order): per RFC-0955-R1 lines
  420-422, score_ewma_raw now at position 5 (between
  last_event_id and last_event_unix). The previous last-position
  was a cross-implementation interoperability bug.

- AC #6 (v012 migration): new
  crates/octo-reputation/migrations/v012__reputation_anchors_governance.sql
  extending reputation_anchors with governance_snapshot BLOB,
  governance_proof BLOB, governance_set_hash BLOB + lookup index
  on governance_set_hash. BUILTIN_MIGRATIONS bumped.

- AC #12 (anchor-specific verifier types): path (a) types defined
  in crates/octo-reputation/src/auth.rs. meets_quorum() enforces
  exactly GOVERNANCE_QUORUM (3) distinct signers.

- AC #17 (canonical test vector re-pinning): the 3 pinned vectors
  in tests/canonical_blobs.rs re-pinned to the new canonical
  serialisation. An independent Python implementation using
  hashlib.blake3 MUST reproduce these bytes byte-identically per
  RFC-0955-R1 line 422.

Verification: cargo fmt + clippy -D warnings clean; cargo test
--lib 197 passed; canonical_blobs 5/5 passed; stoolap_integration
47/48 passed (1 pre-existing flaky K=2 race test — fails before
this commit too, acknowledged in the test's R22 comment as
non-deterministic).

External blockers remaining for 0968a2 closure:
- AC #7/8 live ChainAnchorSubmitter (chain-substrate selection RFC)
- AC #9/10 reorg + DID-rotation finality handlers (need AC #7)
- AC #11 governance signature verification (needs governance key infra)
- AC #13 per-deployment config plumbing (config crate path TBD)
- AC #16 gossip cross-reference (needs 0855p-b successor mission)

Implementation pattern: anchor_job.rs::plan_batches returns batches
with placeholder governance fields (None chain height, zero
snapshot/proof/set_hash, leaves.len() batch_size). Runtime populates
them with active snapshot + 3-of-3 quorum proof before calling
ChainAnchorSubmitter::submit. Keeps plan_batches
chain-substrate-agnostic.
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
Update Status header after 0968a2 implementation landed in commit
72bf19d. N9 (ReputationAnchorBatch governance fields drift)
resolved at the struct + digest + migration + test-vector level.
The 9 ungrounded 0968a ACs split cleanly into 3 categories:

- 5 (#1, #4, #5, #6, #7, #8) gated on chain-substrate selection RFC
- 1 (#9) gated on 0855p-b successor mission (gossip file ownership)
- 2 (#2, #3) achievable but need a live ChainAnchorSubmitter
  fixture (deferred until #1 lands)

Path B closure recommended (per BLUEPRINT §1152-1158 user-initiated
deferral rule). Mission substantively complete at the commit
boundary; residual work is separate chain-substrate + gossip
coordination effort.
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
mmacedoeu added a commit that referenced this pull request Aug 3, 2026
mmacedoeu added a commit that referenced this pull request Aug 7, 2026
- crates/octo-wallet/src/capability/zk_mint.rs:
  - ProofBundle gains witness_format: zk_vendor::prover_input::WitnessFormat
    field (AC-3 observable marker). #[serde(default)] preserves backward
    compat with pre-AC-3 serialized bundles.
  - Debug impl adds witness_format variant name (not secret-bearing;
    observability metadata only).
  - ProofBundle construction site (line ~462) sets witness_format =
    BytesFallback (current behavior; the prove_batch_signature JSON
    rewrite will flip this to ProverInputJson in the next AC-3 commit).

- crates/octo-wallet/Cargo.toml: promote zk-vendor from dev-dep to
  runtime dep so lib code can reference zk_vendor::prover_input::WitnessFormat.

Verification:
  cargo build -p octo-wallet --lib         ✓
  cargo test -p octo-wallet --lib          233/233 pass
  cargo clippy -p octo-wallet --lib        -D warnings clean (my changes add
                                           zero new errors; the 47 pre-existing
                                           errors in --all-targets are in
                                           key_hierarchy.rs::tests and
                                           unrelated test code).

AC-3 remaining: prove_batch_signature JSON witness construction + eprintln
fallback removal in zk-circuit/src/lib.rs. The witness_format field above
will flip to ProverInputJson once that lands. Bench real-zk G1 gate
requires nightly-built libstwo_sys.so (environment-dependent; not
implementable in this session).
mmacedoeu added a commit that referenced this pull request Aug 7, 2026
… AC grounding

R7 review findings closed:

MAJOR (governance type collision): mandate path (a) — new anchor-specific types in same module — verified against current IMPL at crates/octo-reputation/src/{auth.rs:399-603, anchor.rs:174-208, anchor.rs:233+}; existing auth.rs::GovernanceSnapshot (L21-25) + GovernanceProof (L113+) preserved unchanged as RFC-0968 authorization envelopes (slash/suspension flows); new AnchorGovernanceSnapshot/AnchorGovernanceSigner/AnchorGovernanceProof/AnchorSignature types + 5 unit tests cover the anchor binding schema.

NIT (duplicate sentence): file no longer contains duplicate (prior edits removed it).

AC grounding updates — 7 ACs flipped to [x]:

- AC #2 governance fields (72bf19d + 48cf997 + b0660c3)
- AC #3 batch_size: u32 (same)
- AC #4 chain_block_height: Option<u64> (same)
- AC #5 AnchorLeaf::digest field order (b0660c3)
- AC #6 v012 migration (file shipped)
- AC #12 anchor-specific verifier types (72bf19d)
- AC #1 StakeBelowMinimum 0x2D verification (013a567)

10 ACs deferred per [[deferred-vs-unspecified]] named-owner rule to chain-substrate selection RFC + 0855p-b successor: #7/#8 live ChainAnchorSubmitter + rotation_receipt_id wire-through, #9/#10 reorg + DID-rotation finality handlers, #11 governance signature verification runtime hook (meets_quorum helper landed), #13 per-deployment config plumbing, #14/#15 idempotency + failure isolation tests, #16 gossip cross-reference, #17 canonical test vector re-pinning.

Version History v0.2 added; mission text no longer contradicts IMPL state.

63 insertions, 78 deletions.
mmacedoeu added a commit that referenced this pull request Aug 12, 2026
…b PaymentCaveat migration

Migrate `PaidQueryCaveat` from the Layer E extension crate
`octo-paid-query` into the Layer 4 macaroon substrate
`octo-cap-macaroon/src/caveat/payment.rs`. The migration adopts the
per-extension crate pattern: the caveat DATA TYPE lives in the
substrate; the extension crate keeps only its Phase 5 MVP primitives
(`RateLimitBudget`, request/response envelopes).

Changes:
- `crates/octo-cap-macaroon/src/caveat/`: rename `caveat.rs` →
  `caveat/mod.rs` (preserves git history); add `caveat/payment.rs`
  with `PaymentCaveat` struct + `PaidQueryDecision` +
  `PaidQueryRejectionReason` + `AttenuationError` + the
  `verify` / `attenuate` methods.
- `crates/octo-cap-macaroon/src/caveat/mod.rs`: add
  `Caveat::Payment(PaymentCaveat)` variant (RFC-0965 reserved
  discriminator `0x1A`) + `CaveatName::Payment` + canonical JSON
  serialisation + subsumption rule (child budget ≤ parent budget,
  child expiry ≤ parent expiry, parent model empty OR matches
  child).
- `crates/octo-cap-macaroon/Cargo.toml`: add `borsh` derive on
  `PaymentCaveat` (the only borsh-coupled type in the substrate —
  needed by `octo-paid-query::PaidQueryRequest` + the
  `MintRequest::payment_caveat` field).
- `crates/octo-cap-macaroon/src/lib.rs`: re-export
  `PaymentCaveat` + `PaidQueryDecision` + decision reasons +
  `AttenuationError`.
- `crates/octo-paid-query/src/lib.rs`: delete the old
  `PaidQueryCaveat` struct + impl; replace with
  `pub use octo_cap_macaroon::PaymentCaveat as PaidQueryCaveat;`
  for backward compat. `verify_paid_query` retains the all-zero
  macaroon_id sentinel + delegates to `caveat.verify(...)`.
- `crates/octo-wallet-node/src/handlers/mint.rs`: add
  `payment_caveat: Option<PaymentCaveat>` to `MintRequest`; when
  `Some`, the handler appends it as the first caveat in the
  macaroon chain via `CapabilityToken::mint(..., &[Caveat::Payment(p)])`.
  Closes 0871e deferred item #7 (handler accepting PaymentCaveat
  mint requests).

Test vectors (mission file §"Test vector discipline"):
- All 15 existing `octo-paid-query` tests pass unchanged (re-export
  preserves call-site compatibility).
- 12 new `octo-cap-macaroon` TV in `caveat/payment.rs` (8 unit) +
  4 in `caveat/mod.rs` (Caveat::Payment serde_json roundtrip +
  `CaveatName::Payment` identifier + subsumption narrowing +
  widening rejection).
- 3 new `octo-wallet-node` TV: borsh roundtrip with payment_caveat,
  handle_mints_with_payment_caveat_as_initial_caveat,
  handle_mints_without_payment_caveat_has_empty_chain.

Validation:
- `cargo fmt` clean
- `cargo clippy --all-targets --all-features -- -D warnings` clean
- `cargo test --lib -p octo-cap-macaroon` 172/172 (160 + 12 new)
- `cargo test --lib -p octo-paid-query` 15/15
- `cargo test --lib -p octo-wallet-node` 24/24 (21 + 3 new)

Mission: `missions/open/0957-phase2b-payment-caveat.md`.

Closes 0871e deferred items #1 (caveat migration), #2 (dispatcher-
level decode — via Caveat::Payment variant in central enum),
#7 (handler accepting PaymentCaveat mint requests). #6 (chain
verify) covered by TV3 (subsumption narrowing) + verify_holder_sig
unchanged from substrate.

Unblocks:
- 0957-phase2c (cap-issuer wiring)
- 0957-phase2d (attenuation stub closure)
- 0871e-phase5b (atomic drain)
- 0871e-phase5c (pricing policy)

Wave 1 / step 2 of the 2026-08-10 gap-closure backlog.
mmacedoeu added a commit that referenced this pull request Aug 12, 2026
Task #121 of mission 0871e-f7-coordinator-impl. Land the sealed
trait surface + governance verification + canonical_hash re-export
+ replay_wal + WAL trait split (R12 M20) in octo-sync's
substrate/ module. Also add borsh derives to ChainId + DidDocument
in octo-ident so substrate can serialize them via borsh for
GovernanceAttestation + WAL entry payloads.

New trait modules:
  governance.rs: GovernanceAttestation + OperatorSignature +
    governance_signature_message (BLAKE3-256 domain-separated
    binding over shard_key + chain_id + term + nonce) +
    verify_governance_attestation (M-of-N threshold + ed25519
    verify + nonce consume) + ed25519_verify + NonceTracker
    (per-shard replay-resistance via WAL durability + R13 M4
    roll-back on WAL failure) + WalAppender (local minimal
    trait for NonceTracker; wal_traits.rs has the canonical
    WalAppender (deprecated) + WalWriter/WalReader/WalNonceScanner
    per R12 M20 Interface Segregation).
  bootstrap.rs: BootstrapOrchestrator (async_trait, R12 M18
    dyn-compat).
  drain.rs: DrainCoordinator (async_trait, fail-closed default
    per R12 + 'LWW substrate pending F12 amendment' deprecation).
  did.rs: EncodedDidDocument trait (NOT sealed per R12 H12) +
    canonical_hash re-export (consumes octo_ident::canonical_hash
    directly; the spec text 'free fn in octo-sync/src/did.rs' is
    reconciled with the actual octo-ident home).
  wal_traits.rs: WalWriter + WalReader + WalNonceScanner (R12 M20
    split) + WalAppender (deprecated alias per R13 M2) +
    replay_wal (full R10 H3-H6 + R11 H14 + R12 H16 algorithm) +
    apply_entry (default no-op stub for #122 dispatch).
  state.rs: WriterElection + WriterElectionForceRelinquish (sealed,
    mod sealed re-exported with pub(crate) so substrate crate
    can impl but consumers cannot).

octo-ident changes:
  ChainId: add #[cfg_attr(feature = 'borsh', derive(BorshSerialize, BorshDeserialize))]
  DidDocument: add same borsh derive.
  substrate/Cargo.toml: add 'octo-ident = { path = ../crates/octo-ident, features = [borsh] }'
  Layer direction: octo-sync (Layer B-substrate) -> octo-ident (Layer B). One-way.

Validation:
  cargo test --manifest-path octo-sync/Cargo.toml --lib --all-features
  -> 212 passed; 0 failed (was 205; +7 new TV)
  cargo clippy --manifest-path octo-sync/Cargo.toml --all-targets --all-features -- -D warnings
  -> clean
  cargo clippy -p octo-ident -p octo-protocol -p octo-identity-resolver-node --all-targets -- -D warnings
  -> clean
  cargo test --lib -p octo-ident -> 40 passed; 0 failed (no regression)

Mission 0871e-f7-coordinator-impl task #121 (#2 of 4 sub-tasks).
Follow-on: #122 RaftLikeWriterElection + RaftLikeDidWriteCoordinator +
optional crdt feature; #123 workspace membership lift + 4 cross-instance TV.
mmacedoeu added a commit that referenced this pull request Aug 17, 2026
Hard audit 2026-08-12 surfaced 4 false/inaccurate claims in the
closure record for mission 0871b-cross-domain-resolution-impl:

1. (blocker) L3 claimed `backend.rs` shipped with ResolverBackend +
   LocalResolverBackend + RemoteResolverBackend. `git show c14c270
   --stat | grep backend` returns empty; `ls crates/octo-identity-
   resolver-node/src/` confirms no `backend.rs`. Origin scope item
   #2 was deferred, never landed. Cross-node forwarding is the
   follow-on mission 0871b-cross-node-forwarding (OPEN, filed
   2026-08-12).

2. (blocker) L34 UUID mismatch — closure claimed IDENTITY_RESOLVE_CHAIN
   slot `:0002`; actual UUID at `payload_kind.rs:156` is
   `0x0009:0001:0000:0000:0000:0000:0000:0004`. Slot `:0002` is
   IDENTITY_REGISTER.

3. (major) L30 scope item #3 claimed `ResolveDIDRequest` was extended
   with `hops: Vec<ResolverHop>` field. Substrate uses a separate
   `ChainResolveRequest` payload kind instead; resolve.rs unchanged
   in commit c14c270. Scope self-contradicted with item #4 (separate
   payload kind cannot share wire form).

4. (major) L41-43 '3-node chain (A → B → C)' TV misleading —
   tests/cross_domain_chain.rs uses a single InMemoryDidRegistry with
   ResolverHop::local(...) for all hops. Tests 3 local hops against one
   registry. Cross-domain auth + true 3-node TV deferred to
   0871b-cross-node-forwarding.

All 4 corrections now reflected in v1.1 row of version history. Cross-
references to follow-on mission 0871b-cross-node-forwarding added.

cargo fmt clean; cargo clippy -p octo-identity-resolver-node --all-
targets -D warnings clean.
mmacedoeu added a commit that referenced this pull request Aug 17, 2026
Closes Round 1 findings from superpowers:code-reviewer dispatch over
S4 commits 19faf38 + 4ab400b. Each fix is anchored to the original
finding ID for traceability.

CRITICAL #2 — guard powi u32->i32 wrap
  penalty_for_offense(now takes offense_count: u32) used
  `multiplier.powi(offense_count as i32)`. For offense_count >
  i32::MAX (~2.1B) the cast wrapped to a negative exponent, shrinking
  the penalty instead of saturating to 100% slash. Fix: replace the
  lossy `as i32` cast with `i32::try_from(offense_count).unwrap_or(
  i32::MAX)`. Saturated count yields `mult = f64::INFINITY` for any
  multiplier > 1.0, which `.min(1.0)` clamps to 1.0 (full slash) — the
  correct safe behavior. The caller also adds `.clamp(0.0, 1.0)` on
  the final pct for defensive bound. New `tests_penalty` module adds
  4 regression tests including the u32::MAX boundary.

MEDIUM #1 — scale=0 enforcement at API boundary
  Five sites used `debug_assert_eq!(v.scale, 0)` (slash_store,
  stoolap_spend_ledger, marketplace/mod.rs place_ask x2): release
  builds silently truncated 10^scale digits at the cast to i64/u128,
  corrupting on-disk stake values. Fix:
  - SlashError::NonIntegerScale{param, scale} typed variant.
  - require_integer_scale + require_positive_integer helpers.
  - register / withdraw_stake / can_withdraw / TaskMarketSlashing::
    register now gate on scale=0 (and value>0 for the latter two),
    returning the typed error instead of silently truncating.
  - place_ask + dqa_to_i64 sites changed from debug_assert_eq to
    `assert!` (loud runtime panic, not silent corruption).

LOW — gate negative Dqa in InvalidAmount
  withdraw_stake / can_withdraw previously accepted negative amounts
  (gate was `value == 0`); a negative `subtract` would silently ADD
  to the stake. The new require_positive_integer covers both the
  scale=0 invariant and the value > 0 invariant at once.

Test coverage
  - register_rejects_non_zero_scale (scale=3 + scale=MAX_SCALE
    boundary; verifies rejection does not register the provider)
  - register_accepts_scale_zero (regression: canonical zero still
    registers)
  - withdraw_stake_rejects_non_zero_scale
  - withdraw_stake_rejects_negative_amount (stake unchanged after)
  - withdraw_stake_rejects_zero_amount
  - can_withdraw_rejects_negative_amount
  - tests_penalty module: 4 tests covering powi saturation including
    u32::MAX boundary.

Caller updates
  All `l.register(...)` / `ledger.register(...)` / `slashing.register(
  ...)` call sites in tests + task_market/slashing.rs updated to
  `.unwrap()` (or `?` for the production task_market wrapper, which
  now returns Result<&Dqa, SlashError>).

Verification (LD_LIBRARY_PATH set for libpython3.12 per project env):
- cargo fmt --all: clean
- cargo clippy --all-targets --features full -- -D warnings: clean
- quota-router-storage --lib: 191/191 pass
- quota-router-core --lib: 1733/1733 pass (was 1723; +10 new tests)
- quota-router-core --test marketplace_e2e: 24/24 pass
- quota-router-core --test task_market: 32/32 pass

Outstanding (deferred):
- CRITICAL #1 (untracked dqa_serde.rs file) — fixed in amended
  commit 19faf38 (Phase 1) by including the file + clarifying the
  canonical wire-form contract.
- HIGH #1 (8f367f7a commit-message misattribution) — fixed in amended
  commit 4ab400b (Phase 2): corrected the proxy.rs description.
- HIGH #2 (round_trip_set_scale_12 contract change) — fixed in
  amended commit 19faf38: documented the canonical-form contract.
- MEDIUM #2 (loss_delta scale strip) — latent; only fires if stake
  zeros and then non-zero is restored via register (slash caps at
  zero; only register restores non-zero). Documented for follow-on.
- MEDIUM #3 (dqa_serde layer placement) — would belong in
  octo-determin as a serde-feature module. Cross-crate refactor;
  deferred to a substrate restructure mission.
- LOW (ZeroValue variant + redundant u128 cast) — style nits;
  deferred.
mmacedoeu added a commit that referenced this pull request Aug 17, 2026
…ssions

Per audit verdict 2026-08-17 (memory card audit-2026-08-17-...)
closes 7 distinct parallel-model risks across workspace.

RFC amendment filings (S6 B0 atomic-blocker bundle per plan §3 A.1):
- 0862-c9-micro-octow-type-unification: Risk #1 CRITICAL
  (MicroOctoW type alias split; 3 sites, 2 underlying types)
- 0105-x-s4-deferred-codemod-sites: Risk #4 HIGH
  (u128 field type drift in marketplace/task_market/slash_store/
  settlement_event_repo/CLI; 7 files)
- 0959-c1-wire-format-amendment: Risk #5 HIGH (S6e RFC-0959
  settlement wire format; DqaEncoding + VaultLookup trait reuse)
- 0900-d-chain-aware-slash-ledger: Risk #2 CRITICAL portion
  (S6d RFC-0900 slash ledger schema; DQA(12) + chain_id PK)
- 0960-vault-substrate-amendment: S6f RFC-0960 chain-aware vault
  substrate; v2.1-Resolved → v3.0; 108 byte-exact TV
- 0105-v-asset-id-addendum: S6g RFC-0105 asset_id_for derivation;
  v1.9 → v2.0; 109 byte-exact TV (9 TV-D9 + 100 TV-D10)

All 7 RFC amendments per §3 A.1 now accounted for: 4 filed today
+ 3 already-LANDED (RFC-0870 via 0870-c1; RFC-0862 via 0862-c1;
RFC-0957 via 0957-c1 + 0957-g).

Spend_ledger + vault balance remain STRUCTURAL dual substrates per
RFC-0862 §Future Work F12 (parallel by design, not convergent without
redesign of spend_ledger substrate).
mmacedoeu added a commit that referenced this pull request Aug 17, 2026
…pdates

Card: memory/audit-2026-08-17-storage-restructure-parallel-model-risks.md
- Hard ground-check of plan §3 + review §20.x under lens
  'spending/cost unified into capabilities-vault model'
- Verdict: PARTIAL UNIFICATION (vault substrate ahead of RFC text
  on verify-time + WrappedOnly)
- 7 distinct parallel-model risks: 3 CRITICAL (#1 MicroOctoW split,
  #2 4 column types, #3 STRUCTURAL spend_ledger not vault-bound),
  2 HIGH (#4 u128 drift, #5 1 of 2 vault-lookup paths landed),
  1 MED (#6 4 ChainId reps), 1 LOW (#7 octo-reputation u32)
- Will parallel models persist: YES by design (3) + YES by omission
  (5 — closure missions filed 2026-08-17)
- Push: queued on next, push user-only

MEMORY.md: +4 mission pointers (0862-c9 + 0105-x + 0959-c1 +
0900-d via earlier filing) + audit verdict pointer + 2 more
(0960-v + 0105-v filed in same commit).
mmacedoeu added a commit that referenced this pull request Aug 21, 2026
…retraction (doc-only consolidation)

S6c Round 3 adversarial review (sprint wf_bd836955-609; 204 agents /
4 rounds / 106 confirmed findings) surfaced THREE documentary drifts
between substrate doc + migration comment + RFC history rows.
Doc-only mission; no substrate logic change; existing 18/18 TV pass
unmodified.

DRIFT #1 — Substrate §Atomicity paragraph (stoolap_spend_ledger.rs:9-18).
Pre-c10 paragraph claimed 'SELECT ... FOR UPDATE' row-locking +
per-statement transaction as the atomicity primitive. Reality:
stoolap fork's storage layer returns NotSupported for FOR UPDATE
locking; substrate SQL never carried the clause. Actual mechanism:
per-instance drain_lock (mission 0862-c8) wrapping explicit stoolap
Transaction (db.begin -> query -> execute -> commit, mission 0862-c3
AC-2) plus cross-process fs2 flock on <dsn-dir>/.spend_ledger.lock.
Rewrote paragraph to enumerate the four-step execution with explicit
attribution to c2/c3/c8; retracted FOR UPDATE references with
explanatory note.

DRIFT #2 — Migration v007 header comment (v007__create_spend_ledger.sql:1-14).
Same FOR UPDATE claim as Drifts #1 + #3. Rewrote header comment to
describe drain_lock + tx wrapper; cited storage/traits/table.rs for
the FOR UPDATE NotSupported limitation.

DRIFT #3 — RFC-0862 v2.0.3 row inversion + phantom TV cites
(0862-writer-election-bootstrap-v130.md:2113).
Two stale claims: (a) 'pub type MicroOctoW = Dqa' was ADDED to
determin/src/lib.rs (Layer A frozen substrate) — actually c9 RETIRED
killed MicroOctoW project-wide via commit 2a610c3 BEFORE the v2.0.3
cross-ref was authored; row was false at the moment of writing.
(b) Cited TV-0862-17 (cross-crate round-trip) + TV-0862-18 (caveat
payload bytes) — neither test exists anywhere under crates/ (verified
via grep -rn 'TV-0862-17\|TV-0862-18' crates/ — no matches). c9
RETIRED removed them rather than adding them.

FIX:
- Substrate §Atomicity paragraph rewrite (AC-1)
- v007 header comment rewrite (AC-2)
- v2.0.3 row in-place amend with RETRACTION clause + sub-row v2.0.3.1
  documenting the in-place amend (AC-3)
- New v2.0.9 row describing the c10 doc-drift consolidation (AC-4)
- 18/18 substrate TV pass unmodified (AC-5)
- clippy zero + cargo fmt clean (AC-6)

Out-of-scope (filed as separate missions):
- 0871c-lock-file-hardening: O_NOFOLLOW + path canonicalize + umask
  0600 (HIGH security findings from Round 3)
- 0862-c11-tv-coverage-gap: cost=0 / scale boundary / macaroon_id edge

Mission 0862-c10 LANDED. Memory card + MEMORY.md pointer added.
NO push -- remote writes await explicit user instruction per
[[feedback_initiation_user_only]].
mmacedoeu added a commit that referenced this pull request Aug 21, 2026
RFC-0900 v2.0 (audit verdict 2026-08-17 Risk #2 CRITICAL closure).
slash_ledger PK promoted from (row_id, provider_id UNIQUE) to
(chain_id, provider_id) per §20.3 Model B (parallel to vault v013).

Migration v015:
- ADD COLUMN chain_id BLOB (nullable during window; UPDATE backfill
  to 32-zero-byte default namespace per RFC-0010 v1.4)
- DROP provider_id UNIQUE (triple-named drop for fork naming quirks)
- CREATE UNIQUE INDEX slash_ledger_chain_provider_idx
  ON slash_ledger (chain_id, provider_id)

Substrate changes:
- SlashLedgerRow.chain_id: [u8; 32] field (first position)
- ProviderStake.chain_id: [u8; 32] field at 4 construction sites
- append_outcome signature widens to include chain_id (default no-op)
- dqa_to_i64 / i64_to_dqa helpers (BIGINT bridge at scale=0;
  DQA(12) promotion deferred — stoolap fork lacks native Dqa driver)

Tests:
- 3 existing slash_store tests updated with chain_id field
- New TV-0900-D-09 cross_chain_same_provider_two_distinct_rows
- 192/192 storage tests pass

RFC-0900:
- v2.0 row in Version History
- New §Slash Ledger Substrate subsection (invariants + mirror +
  migration history)

Documented 3 stoolap fork quirks (see slash_store.rs comment +
v015 SQL header):
1. x' literals rejected in DEFAULT clauses → nullable + UPDATE
2. Column-level UNIQUE autoindex named unique_<table>_<col>
3. INSERT param binding uses SCHEMA column order, not INSERT
   column-list order

5 ACs narrowed/deferred to follow-on missions (DQA(12) promotion,
SlashOutcome.chain_id, HashMap tuple-key restructure, 9 remaining
TVs, core test infra)
mmacedoeu added a commit that referenced this pull request Aug 21, 2026
…t block

Substrate re-export block grows 5 → 6 nested re-exports per RFC-0206 v2.3
amendment. Adds pub use stoolap::core::DataType; so consumer code no
longer leaks stoolap::DataType::{Null,Integer,Blob} raw upstream
references via Value::Null(DataType::Variant) constructor calls.

R6 substantive review (docs/audits/0206-008b-r6-substantive-review.md)
identified 22 consumer sites leaking the inner DataType discriminant.
Fix: substrate re-export DataType (Option B per R6 audit recommendation).
4 consumer crates rewritten to use octo_storage_core::stoolap::DataType:

- octo-adapter-whatsapp/src/store.rs: 5 sites
- octo-adapter-whatsapp/tests/r14_h1_upsert_verify_test.rs: 12 sites
  (also fixes stoolap::core::Value::blob raw path leak)
- octo-adapter-telegram-mtproto/src/session.rs: 4 sites (Blob, Integer)
- quota-router-core/src/storage.rs: 12 sites (Null)
- quota-router-core/src/cache.rs: 1 site (stoolap::core::Value::blob path)

quota-router-core/Cargo.toml: stale v2.1-era 0206-011b pending comment
updated to v2.3 reality (R6 finding #2).

RFC §Substrate Re-export Block: 5 → 6 nested re-exports; v2.3
Version History row added; Status header updated to v2.3.

TV-0206-A9(b) gate remains 4 ≤ 5 PASS. cargo check + clippy
--features full -- -D warnings + fmt --check all green.
mmacedoeu added a commit that referenced this pull request Aug 25, 2026
… guide). 5-RFC pilot substitution #2 — RFC-0855p-c (DomainCoordinator Role, 84 cites) chosen after RFC-0957 reverted by user + RFC-0110 already committed (c37acab). RFC-0855p-c clean + no YAML + valid cites. YAML coverage corpus: 27 → 28 (15.4% → 16.0%, +0.6pp).
mmacedoeu added a commit that referenced this pull request Aug 25, 2026
…ndment

Per research/vault-monetary-representation-redesign §20 §User Decision
Matrix decision #2 (BLUEPRINT.md amendment for RFC-0008 promotion
pathway formalization). Amendment adds explicit 2-Cycle Atomic
Promotion gate section at §Mission Lifecycle with:

- 5 procedure rules (sibling tag, single mission ownership, symmetry
  enforcement, intermediate Claimed status, cite validation)
- Explicit RFC-0205 + RFC-0206 pairing example (Tier 3 cascade)
- Prerequisite cross-refs to RFC-0003 v1.1 + RFC-0008 v1.0 amendments

Per R10.5 scope: docs/ in-scope.

Pre-commit cite validation: PASS. NO push. TV-VMR-2.

Co-Authored-By: Claude <noreply@anthropic.com>
mmacedoeu added a commit that referenced this pull request Aug 27, 2026
C1 CONFIRMED: produce_burn silently dropped Sink 1 (nonce) + Sink 2
(audit). Fix: produce_burn now calls BurnEventRef::consume() first
with full 3-sink atomicity + rollback, then emits TransferEventRef
to the Layer B log + bus envelope.

The consume() path takes octo-policy::burn_event::TransferEventLog
(audit mirror); the Layer B octo-vault::TransferEventLog is the
canonical projection source. Two log.insert calls — parallel
abstraction tracked for elimination under L4 CRITICAL #2.

C4 CONFIRMED: PaymentProducerInput + SettlementProducerInput
hardcoded chain_id=ZERO, breaking the (chain_id, vault_id, asset_id)
projection contract. Fix: add chain_id: ChainId to both inputs;
propagate input.chain_id in to_transfer_event.

NO PUSH.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant