docs: nightly doc-gardening sweep 2026-06-08 - #704
Conversation
Automated sweep via .claude/skills/doc-gardening. Updates per-package CLAUDE.md/AGENTS.md, docs/index.md entries, and ARCHITECTURE.md as needed.
There was a problem hiding this comment.
Code Review
This pull request updates the project's documentation across several AGENTS.md and CLAUDE.md files to reflect recent architectural changes. These include concurrent worker pools for durable actors, startup reconciliation of unilateral-exit VTXOs, spending reservation stores for orphan sweeps, and shared retry primitives for mailbox pull loops. The review feedback correctly identifies a typo in a referenced method name and points out an inaccuracy regarding transaction confirmation retry behaviors, noting that the persistent retry behavior for no-mempool transactions applies specifically to anchor (CPFP) transactions.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| overcome. Only a structurally permanent error | ||
| (`isPermanentBroadcastError`, currently `ErrNonTRUCParent`) fails | ||
| terminally; `ErrParentAlreadyBroadcast` advances to | ||
| `AwaitingConfirmation` (a live parent exists on another path). Rationale: |
There was a problem hiding this comment.
The statement that only structurally permanent errors fail terminally is slightly inaccurate. According to the implementation in txconfirm/actor.go (lines 539-544), any non-anchor direct broadcast failure (other than ErrParentAlreadyBroadcast) will also fail terminally immediately. This "never give up" behavior only applies to anchor (CPFP) transactions.
| overcome. Only a structurally permanent error | |
| (`isPermanentBroadcastError`, currently `ErrNonTRUCParent`) fails | |
| terminally; `ErrParentAlreadyBroadcast` advances to | |
| `AwaitingConfirmation` (a live parent exists on another path). Rationale: | |
| overcome. For anchor transactions, only a structurally permanent error | |
| (`isPermanentBroadcastError`, currently `ErrNonTRUCParent`) fails | |
| terminally; `ErrParentAlreadyBroadcast` advances to | |
| `AwaitingConfirmation` (a live parent exists on another path). Non-anchor | |
| direct broadcasts will fail terminally on any broadcast error. Rationale: |
| - `DurableActor` — Actor variant with crash-safe mailbox backed by SQL persistence. Provides `Wait(ctx)` to block until the actor stops and `StopAndWait(ctx)` to request a graceful shutdown and then wait. | ||
| - `DurableActorConfig[M, R]` — Configuration struct for `DurableActor`: behavior, store, codec, clock, DLO, WaitGroup, `TellRetryPolicy`, lease/heartbeat/poll durations, max attempts, cleanup timeout, and deduplication TTL. | ||
| - `DurableActorConfig[M, R]` — Configuration struct for `DurableActor`: behavior, store, codec, clock, DLO, WaitGroup, `TellRetryPolicy`, lease/heartbeat/poll durations, max attempts, cleanup timeout, deduplication TTL, and `NumWorkers`. | ||
| - `DurableActorConfig.NumWorkers` — How many concurrent worker loops drain the actor's single mailbox. Default and any value `<= 1` is one worker (strictly-sequential processing). A value `> 1` turns the actor into a competing-consumer pool: that many goroutines each lease distinct messages via `LeaseNextMailboxMessage`, so independent messages run in parallel while per-correlation-key FIFO still keeps same-key messages ordered. Only for behaviors whose handlers are concurrency-safe and hold no writer across their side effects (e.g. the serverconn egress sender on the Read/Commit path). `NewDurableActor` **fails closed** with `ErrConcurrentClassicBehavior` when `NumWorkers > 1` is paired with a classic (`Left`) `ActorBehavior`, since the classic path wraps the whole `Receive` in one write transaction and assumes sequential delivery; pools are only valid on the Read/Commit (`TxBehavior`) path. The test-only `DurableActorConfig.AllowConcurrentClassicBehavior()` escape hatch bypasses the guard for the egress benchmark that measures the forbidden config; production code must never call it. |
There was a problem hiding this comment.
The method name LeaseNextMailboxMessage is a typo. The actual method implemented on the store and called in durable_mailbox.go is LeaseNextMessage.
| - `DurableActorConfig.NumWorkers` — How many concurrent worker loops drain the actor's single mailbox. Default and any value `<= 1` is one worker (strictly-sequential processing). A value `> 1` turns the actor into a competing-consumer pool: that many goroutines each lease distinct messages via `LeaseNextMailboxMessage`, so independent messages run in parallel while per-correlation-key FIFO still keeps same-key messages ordered. Only for behaviors whose handlers are concurrency-safe and hold no writer across their side effects (e.g. the serverconn egress sender on the Read/Commit path). `NewDurableActor` **fails closed** with `ErrConcurrentClassicBehavior` when `NumWorkers > 1` is paired with a classic (`Left`) `ActorBehavior`, since the classic path wraps the whole `Receive` in one write transaction and assumes sequential delivery; pools are only valid on the Read/Commit (`TxBehavior`) path. The test-only `DurableActorConfig.AllowConcurrentClassicBehavior()` escape hatch bypasses the guard for the egress benchmark that measures the forbidden config; production code must never call it. | |
| - `DurableActorConfig.NumWorkers` — How many concurrent worker loops drain the actor's single mailbox. Default and any value `<= 1` is one worker (strictly-sequential processing). A value `> 1` turns the actor into a competing-consumer pool: that many goroutines each lease distinct messages via `LeaseNextMessage`, so independent messages run in parallel while per-correlation-key FIFO still keeps same-key messages ordered. Only for behaviors whose handlers are concurrency-safe and hold no writer across their side effects (e.g. the serverconn egress sender on the Read/Commit path). `NewDurableActor` **fails closed** with `ErrConcurrentClassicBehavior` when `NumWorkers > 1` is paired with a classic (`Left`) `ActorBehavior`, since the classic path wraps the whole `Receive` in one write transaction and assumes sequential delivery; pools are only valid on the Read/Commit (`TxBehavior`) path. The test-only `DurableActorConfig.AllowConcurrentClassicBehavior()` escape hatch bypasses the guard for the egress benchmark that measures the forbidden config; production code must never call it. |
Automated nightly doc-gardening sweep for 2026-06-08.
What changed
p-models/durableactor/bridge,serverconn/mailboxpull,scripts/check-sample-darepod-confvtxo,unroll,db,oor,round,ledger,baselib/actor,serverconn,txconfirm,p-models/durableactorserverconn/mailboxpullandp-models/p-models/durableactor/bridgeto the layer tablesKey changes reflected:
vtxo: startup orphan-reservation sweep, unilateral-exit reconcile,SpendingReservationStore,ExitOutcomeResolverunroll:VTXOUnrollActormigrated to Read/CommitTxBehaviorpathdb: migration 000017 (spending_reservationstable),SpendingReservationPersistenceStore,LatestMigrationVersion = 17oor:ReservationStoreinterface,IncomingSnapshot.MetadataAttempts, bounded backoff for metadata resolutionround:RoundClientConfig.RegistrationTimeout, lazy reaping of failed rounds viareapFailedRoundsledger:LedgerActormigrated to Read/CommitTxBehaviorpathReview notes
Please review the updated CLAUDE.md and AGENTS.md diffs and ARCHITECTURE.md for accuracy.
make doc-checkpasses cleanly on this branch.