tasks.md 7.4 KB

Tasks: darkirc-delivery-status

1. Compatibility and protected-area review prerequisites

  • 1.1 Verify unknown-message tolerance: using the event-graph test harness (src/event_graph/test_helpers.rs), connect two nodes where only one registers an EventPutStatus dispatch, send a status from that node to the unregistered receiver, and confirm the receiving channel stays up (no stop/strike/ panic). Record the outcome in the change notes; if unknown ids destabilize channels, stop and re-discuss gating before proceeding. Verify via a new test in src/event_graph/tests.rs.
  • 1.2 Before implementation changes touching RLN, crypto, circuits, or canonical serialization, stop for human review of the affected path, especially reservation/recovery for head materialization and recreation. Record the review outcome and constraints. Do not treat planning approval or an agent verdict as crypto sign-off. Flag any required dependency, build-script, or proc-macro change for human review rather than silently expanding scope.

2. Event-graph layer (src/event_graph)

  • 2.1 Define EventPutStatus/EventPutResult/NackReason in proto.rs with explicit u8 discriminants, impl_p2p_message! with default metering, and register dispatch/subscription in ProtocolEventGraph::init. Verify wire tags with round-trip and explicit-byte tests without modifying canonical serialization code; run make and make clippy.
  • 2.2 Emit statuses from handle_event_put at every outcome per the design table (NotSynced, Has{false} duplicate, historical-slot check before TooOld, Invalid, Busy, Has{true} inserted), unicast on the receiving channel; strike/flood paths unchanged and silent. Verify each emission point with a two-node test asserting the exact reply variant, including the retained-slot Has{false} case across a rotation. Distinguish established invalidity (Invalid) from transient parent-fetch/processing failure (Busy) in tests.
  • 2.3 Add receipt_pub: Publisher<(EventPutStatus, ChannelPtr)> and receipt_subscribe() to EventGraph; republish every inbound status unfiltered from the per-channel handler. Verify with a test that receives both own-origin and relayed statuses on the subscription.
  • 2.4 Decode hardening: unknown EventPutResult/NackReason variant or malformed body is dropped with a warning, no panic, no strike, channel stays connected. Verify with a fuzz-style unit test feeding truncated/random payloads through the decoder and a channel test confirming the connection remains usable after malformed input.

3. Durable darkirc FIFO (bin/darkirc)

  • 3.1 Add the darkirc_outbound ordered logical-message records and durable enqueue/head/dequeue operations, with plaintext rebuild fields, stable queue position, optional active event/blob, generation links, and retry/parked state. Verify serialization, concurrent enqueue ordering, and reopen/restart preservation with local tests.
  • 3.2 Route every accepted outgoing chat message through durable enqueue, including offline and initial-sync sends. Report enqueue failure explicitly; do not create events for later entries. Verify that accepted messages survive restart, failed enqueues do not report success, and neither direct broadcast nor DAG relay/sync exposes a later queued message.
  • 3.3 Persist the head's exact event/blob independently of DAG retention, and commit replacements with the active-generation pointer and old-to-new superseded_by link before network exposure. Verify fault-injected persistence failures, restart before/after commit, unchanged rebroadcast after all local slots prune the event, and one active generation at the original queue position.
  • 3.4 Enforce a storage bound covering queued plaintext, active event/blob data, and generation metadata. Explicitly reject new enqueues at capacity; park recreation if it cannot fit. Verify no unacknowledged entry or required correlation data is evicted, and ACK'd entries can be removed to reclaim queue space.

4. ACK-driven head-only worker (bin/darkirc)

  • 4.1 Subscribe to receipts and accepted foreign events; filter to tracked head generations and use ephemeral connection identity, not channel addresses, for any aggregation. Verify ACK from both Has variants and foreign ancestry, and no ACK from locally generated events or unrelated ids. Do not persist or log peer addresses.
  • 4.2 Serialize ACK/dequeue with head materialization and recreation. Verify exactly-once durable advancement, ACK processing while sends are gated, duplicate/late replies after restart, and an old-generation ACK racing with replacement work without resurrecting the entry or removing the next head.
  • 4.3 Service only the head when synced and connection count reaches K. Materialize its initial event only then; otherwise retry its exact active event with doubling backoff up to R_MAX, then a capped slow rate indefinitely. Verify with controlled-time tests that negative replies cannot bypass backoff, no retry/lifetime limit discards the head, and later entries never create or expose events before ACK.
  • 4.4 Recreate only after local expiry or TooOld and a completed rebroadcast round without ACK. Keep queue position, use fresh parents/timestamp/nonce and the reviewed existing RLN path, and retain old-generation correlation. Verify silent expiry, retained-slot Has cancellation, multiple rotations without an attempt cap, and no recreation from silence/Invalid/NotSynced/Busy alone.
  • 4.5 Park the head on budget exhaustion, missing identity, and processing/storage errors; retry at bounded rate without skipping it. Verify enabled-RLN budget rollover and identity recovery under the human-reviewed path, unchanged retries consuming no new slot, and no unproven enabled-RLN replacement. Verify blocked-send notices do not imply dequeue or terminal failure, and later messages remain queued.

5. End-to-end FIFO scenarios

  • 5.1 Test offline enqueue of A then B, restart, and reconnect in a multi-node harness with the configured connectivity threshold met. Assert only A materializes/sends, B stays unexposed until A's ACK, and B subsequently becomes the head. Repeat with A parked to confirm cross-conversation head-of-line blocking rather than implicit skip.
  • 5.2 Test an already-materialized, unacknowledged head spanning disconnection and rotation: first rebroadcast the original, then recreate without advancing the queue if no holder ACKs. In a separate scenario a peer retains the original and replies Has{inserted:false}: assert dequeue without recreation. Include a late ACK for an older generation after replacement and verify the next message advances only once. Do not assume recipient display order or deduplication.

6. Hardening and review gates

  • 6.1 Full workspace gates green: make, make clippy, make test (proofs + contracts built first per AGENTS.md); confirm no unwrap/expect/panic! on any new attacker-controlled decode path and no secrets or peer addresses logged with queue/receipt state.
  • 6.2 Invoke @anon-security-review on the full implementation diff; treat FAIL as blocking and address findings before marking the change ready to apply/archive. Verify the review verdict is recorded in the change notes; planning-only review does not satisfy this implementation gate.