Skip to content

feat(ui): operator event feed — bounded node ring + /api/v1/events + live panel - #152

Merged
arkadianet merged 2 commits into
mainfrom
feat/ui-events-feed
Jul 3, 2026
Merged

feat(ui): operator event feed — bounded node ring + /api/v1/events + live panel#152
arkadianet merged 2 commits into
mainfrom
feat/ui-events-feed

Conversation

@arkadianet

@arkadianet arkadianet commented Jul 3, 2026

Copy link
Copy Markdown
Owner

What

Phase 2B — the last Phase 2 item of the first-class UI effort: the node narrates its own lifecycle through a live Events panel.

Node side (zero new locks)

  • event_feed.rs — bounded EventFeedRing (512, monotonic seq, FIFO eviction) plus a tick-diff deriver. Events are derived, not instrumented: one call site in snapshot_emit diffs successive per-tick observations already collected on the hot path — no subsystem grows an event hook.
  • v1 kinds: blockApplied (newest-4/tick from the committed tail, so initial sync can't flood), reorg (committed-tail comparison — including reorg-with-advance, detected when the tail shows a different id at the previous tip height), peerConnected/peerDisconnected (sorted, deterministic 16/tick cap), indexerStatus transitions. The first tick primes the differ silently.
  • Consistency contract: the differ's tip is derived from the committed recent tail itself — the same source as its block list — so the async-persist window (in-memory tip ahead of committed) defers events by a tick instead of losing them.
  • Ring tail projects into the lock-free snapshot as Arc<ApiNodeEvents>, seq-key-cached so a quiet tick re-publishes the same allocation.

API

  • GET /api/v1/events?since=<seq> — flat camelCase events with optional per-kind fields; latestSeq for cursor polling; gaps = ring eviction; the reorg approximation is documented at the API level. Defaulted NodeReadState::events() keeps the many test fixtures untouched. utoipa-documented, native openapi snapshot regenerated.

UI

  • Overview gains a full-width Events panel: kind-colored pills, block heights deep-linking into the explorer, relative timestamps, newest first — hidden gracefully on nodes without the endpoint.

Review & testing

  • codex adversarial pass found 1 High + 2 Medium + 1 Low + 1 Nit — all fixed in this commit: the High (committed-vs-in-memory tip desync permanently losing block events) is closed by the same-source contract above and pinned by a dedicated test; reorg-with-advance detection added; the differ gained 8 unit tests (priming, idempotent ticks, caps, both reorg shapes, deferred-not-lost lag, peer determinism, indexer transitions); peer caps made deterministic; projection Arc cached by seq.
  • 4-case endpoint test (full tail / strict since / beyond-latest / defaulted-empty); openapi snapshot + runtime-mount + ring tests green.
  • Full workspace gate green (fmt / clippy -D warnings / cargo test --all).
  • Panel verified via the dev proxy with a mocked feed (9063 runs v0.5.0 without the endpoint — which also exercised the hidden-when-absent path).

Closes out Phase 2. Phase 3 (mining panel, light theme completion, responsive/a11y) is next.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added GET /api/v1/events to the operator API, including sequence-based polling via since.
    • Added a live “Events” panel to the dashboard showing the latest events (with links where applicable).
    • Introduced structured event payloads with typed fields and latestSeq.
  • Bug Fixes
    • Ensures consistent event ordering and correct filtering when using since (including empty/zero states).
  • Documentation
    • Updated OpenAPI spec with the new endpoint and response schemas for event feeds.

…live panel

Phase 2B of the first-class UI effort: the node narrates its own lifecycle.

Node side (zero new locks — everything rides the existing snapshot flow):
- event_feed.rs: bounded EventFeedRing (CAP 512, monotonic seq, FIFO
  eviction) + a tick-diff deriver. Events are DERIVED, not instrumented:
  the single call site in snapshot_emit diffs successive per-tick
  observations already collected on the hot path — no subsystem grows an
  event hook. v1 kinds: blockApplied (newest-4-per-tick via the
  recent-blocks tail, so initial sync can't flood), reorg (tip id changed
  at same/lower height), peerConnected/Disconnected (peer-set diff, capped
  16/tick), indexerStatus transitions. First tick primes the differ
  without emitting, so boot doesn't fabricate a connect-event per peer.
- The ring tail (latest 100) projects into SnapshotParts/Snapshot as
  Arc<ApiNodeEvents>; SnapshotReadState serves it as a pure snapshot clone.

API:
- GET /api/v1/events?since=<seq> — flat camelCase ApiNodeEvent with
  optional per-kind fields; latestSeq for cursor polling; seq gaps mean
  ring eviction. Defaulted NodeReadState::events() keeps the many test
  fixtures untouched. utoipa-documented, native openapi snapshot
  regenerated, pinned by a 4-case endpoint test (full tail, strict
  since-filter, beyond-latest, defaulted-empty).

UI:
- Overview gains a full-width Events panel (silent when the endpoint is
  absent — older nodes): kind-colored pills, block heights deep-linking
  into the explorer, relative timestamps, newest first.

fmt / clippy -D warnings / cargo test --all green (full workspace gate,
including the regenerated openapi snapshot). Panel verified via the dev
proxy with a mocked feed; the endpoint's wire shape is test-pinned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6f6e4c88-83c9-4fcb-bfa4-9a44a9bcbb6f

📥 Commits

Reviewing files that changed from the base of the PR and between 7a168a3 and 8355131.

📒 Files selected for processing (3)
  • ergo-api/src/server.rs
  • ergo-api/tests/fixtures/openapi_native.yaml
  • ergo-node/src/node/snapshot_emit.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • ergo-api/tests/fixtures/openapi_native.yaml
  • ergo-node/src/node/snapshot_emit.rs
  • ergo-api/src/server.rs

📝 Walkthrough

Walkthrough

Adds an operator event feed from node snapshot state to a new GET /api/v1/events API, with OpenAPI updates, endpoint tests, and dashboard rendering for recent events.

Changes

Operator event feed feature

Layer / File(s) Summary
Event feed ring buffer and event derivation
ergo-node/src/node/event_feed.rs, ergo-node/src/node/mod.rs
Defines the event feed data model, differencing logic, bounded ring storage, module wiring, and unit tests.
NodeState wiring for event feed
ergo-node/src/node/state.rs, ergo-node/src/node/boot.rs, ergo-node/src/node/tests.rs
Adds event-feed fields to NodeState and initializes them at boot and in test fixtures.
Snapshot projection and publishing
ergo-node/src/snapshot.rs, ergo-node/src/node/snapshot_emit.rs, ergo-node/src/api_bridge.rs
Adds the events snapshot field, builds and caches the API projection during snapshot publication, and clones it through the snapshot bridge.
API endpoint, DTOs, and tests
ergo-api/src/types.rs, ergo-api/src/traits.rs, ergo-api/src/server.rs, ergo-api/tests/events_endpoint.rs, ergo-api/tests/fixtures/openapi_native.yaml
Adds the event DTOs, trait method, handler, router mount, OpenAPI entries, and endpoint tests for /api/v1/events.
Dashboard client and Events panel
ergo-api/web/js/api-client.js, ergo-api/web/js/overview.js, ergo-api/web/dashboard.css
Adds the client fetch, slow-state wiring, dashboard rendering, and CSS for the events panel.

Estimated code review effort: 3 (Moderate) | ~35 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change set: an operator event feed with the node ring, API endpoint, and live UI panel.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ui-events-feed

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ergo-node/src/node/snapshot_emit.rs (1)

139-155: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Handle committed_tip() errors without advancing the event-feed cursor.
Err(e) currently becomes an empty tail, so derive_events sees tip_height = 0 / tip_id = "" and resets FeedPrev; when the read succeeds again, the feed can replay already-emitted blockApplied events. Keep Ok(None) as the genuine no-chain case, but skip derive_events or reuse the last projection on the error path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ergo-node/src/node/snapshot_emit.rs` around lines 139 - 155, The error path
in snapshot emission is being treated like a real empty chain, which advances
the event-feed cursor incorrectly. In `snapshot_emit.rs`, keep `Ok(None)` as the
only case that yields an empty tail, but change the `Err(e)` branch from
`ChainStoreReader::committed_tip()` so it does not feed `derive_events` with a
fake zero tip; instead, skip updating the projection or reuse the previously
computed tail state from `recent_blocks_for_tip`/`FeedPrev` handling. Make the
fix around the `recent_blocks_committed` computation so transient read faults
preserve the last emitted cursor and avoid replaying `blockApplied` events.
🧹 Nitpick comments (2)
ergo-api/tests/events_endpoint.rs (2)

39-141: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reduce duplicated boilerplate between FeedStub and DefaultStub.

The two stubs repeat identical info/status/tip/sync/peers/mempool_summary/mempool_transactions/mempool_transaction/health bodies. Since DefaultStub must keep NOT overriding events() to actually exercise the trait default, full merging into one struct isn't possible, but the shared bodies can be factored into free functions both impls delegate to.

♻️ Suggested refactor (illustrative)
+mod stub_defaults {
+    use super::*;
+    pub fn info() -> ApiInfo { ApiInfo { agent_name: "ergo-rust".into(), node_name: "stub".into(), network: "mainnet".into(), version: "0.1.0".into(), started_at_unix_ms: 0, uptime_seconds: 0, target_block_interval_ms: 120_000 } }
+    pub fn status() -> ApiStatus { ApiStatus { sync_state: SyncStateLabel::AtTip, peer_count: 0, best_header_height: 900_000, best_full_block_height: 900_000, headers_ahead_of_full_blocks: 0, mempool_size: 0, snapshot_age_ms: 0, bootstrap: None, last_block_apply_error: None, block_apply_errors_total: 0, mempool_tx_requested_total: 0, mempool_peer_tx_admitted_total: 0, mempool_peer_tx_rejected_total: 0 } }
+    // ...tip/sync/mempool_summary/mempool_transactions/health likewise...
+}
+
 impl NodeReadState for FeedStub {
     fn events(&self) -> ApiNodeEvents { /* ... */ }
-    fn info(&self) -> ApiInfo { ApiInfo { /* full literal */ } }
+    fn info(&self) -> ApiInfo { stub_defaults::info() }
     // ...same delegation pattern for the rest...
 }
 
 impl NodeReadState for DefaultStub {
-    fn info(&self) -> ApiInfo { ApiInfo { /* full literal, duplicated */ } }
+    fn info(&self) -> ApiInfo { stub_defaults::info() }
     // events() intentionally absent — exercises the trait default.
 }

Also applies to: 205-299

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ergo-api/tests/events_endpoint.rs` around lines 39 - 141, The `FeedStub` impl
duplicates the same `info`, `status`, `tip`, `sync`, `peers`, `mempool_summary`,
`mempool_transactions`, `mempool_transaction`, and `health` bodies already
present in `DefaultStub`; factor these shared return values into helper/free
functions and have both impls delegate to them. Keep `DefaultStub`’s `events()`
unimplemented so it continues to exercise the trait default, and only extract
the repeated non-events methods from the `NodeReadState` impls.

178-195: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a test for a non-numeric since value.

The endpoint's documented contract ("Omitted or non-numeric = the full retained tail") isn't exercised by any test — only the omitted, valid, and beyond-latest cases are covered.

#[tokio::test]
async fn events_since_non_numeric_returns_full_tail() {
    let body = get_json(app(Arc::new(FeedStub)), "/api/v1/events?since=abc").await;
    assert_eq!(body["events"].as_array().unwrap().len(), 3);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ergo-api/tests/events_endpoint.rs` around lines 178 - 195, Add a test in
events_endpoint.rs to cover the non-numeric since query behavior that is part of
the endpoint contract. Extend the events_since_* test coverage by adding a new
tokio::test alongside events_since_filters_strictly_greater and
events_since_beyond_latest_returns_empty_list, using
get_json(app(Arc::new(FeedStub)), "/api/v1/events?since=abc") and asserting the
response returns the full retained tail (all events) rather than filtering or
erroring.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ergo-api/src/server.rs`:
- Around line 1661-1697: The `/api/v1/events` handler documentation currently
describes the retained event tail as if it were the full 512-event ring, but
`build_events_projection()` only exposes `ring.latest(100)`, so the stated
retention is misleading. Update the `events_handler`/`ApiNodeEvents` description
to match the actual 100-event snapshot window, or change
`build_events_projection()` to publish the full 512 if that is the intended
behavior.

In `@ergo-node/src/node/snapshot_emit.rs`:
- Around line 916-979: `build_events_projection` is truncating the event feed to
`ring.latest(100)`, which breaks the intended resume semantics because clients
can miss still-retained events before ring eviction. Update this projection to
expose the full available ring window (or otherwise align the documented
catch-up guarantee with the actual cap) so `events_handler` in the API sees all
events still present in `EventFeedRing`, and keep the seq-keyed cache behavior
unchanged.

---

Outside diff comments:
In `@ergo-node/src/node/snapshot_emit.rs`:
- Around line 139-155: The error path in snapshot emission is being treated like
a real empty chain, which advances the event-feed cursor incorrectly. In
`snapshot_emit.rs`, keep `Ok(None)` as the only case that yields an empty tail,
but change the `Err(e)` branch from `ChainStoreReader::committed_tip()` so it
does not feed `derive_events` with a fake zero tip; instead, skip updating the
projection or reuse the previously computed tail state from
`recent_blocks_for_tip`/`FeedPrev` handling. Make the fix around the
`recent_blocks_committed` computation so transient read faults preserve the last
emitted cursor and avoid replaying `blockApplied` events.

---

Nitpick comments:
In `@ergo-api/tests/events_endpoint.rs`:
- Around line 39-141: The `FeedStub` impl duplicates the same `info`, `status`,
`tip`, `sync`, `peers`, `mempool_summary`, `mempool_transactions`,
`mempool_transaction`, and `health` bodies already present in `DefaultStub`;
factor these shared return values into helper/free functions and have both impls
delegate to them. Keep `DefaultStub`’s `events()` unimplemented so it continues
to exercise the trait default, and only extract the repeated non-events methods
from the `NodeReadState` impls.
- Around line 178-195: Add a test in events_endpoint.rs to cover the non-numeric
since query behavior that is part of the endpoint contract. Extend the
events_since_* test coverage by adding a new tokio::test alongside
events_since_filters_strictly_greater and
events_since_beyond_latest_returns_empty_list, using
get_json(app(Arc::new(FeedStub)), "/api/v1/events?since=abc") and asserting the
response returns the full retained tail (all events) rather than filtering or
erroring.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 771c1c16-8f8e-456e-844a-a3f650ed0457

📥 Commits

Reviewing files that changed from the base of the PR and between 72e3b52 and 7a168a3.

📒 Files selected for processing (16)
  • ergo-api/src/server.rs
  • ergo-api/src/traits.rs
  • ergo-api/src/types.rs
  • ergo-api/tests/events_endpoint.rs
  • ergo-api/tests/fixtures/openapi_native.yaml
  • ergo-api/web/dashboard.css
  • ergo-api/web/js/api-client.js
  • ergo-api/web/js/overview.js
  • ergo-node/src/api_bridge.rs
  • ergo-node/src/node/boot.rs
  • ergo-node/src/node/event_feed.rs
  • ergo-node/src/node/mod.rs
  • ergo-node/src/node/snapshot_emit.rs
  • ergo-node/src/node/state.rs
  • ergo-node/src/node/tests.rs
  • ergo-node/src/snapshot.rs

Comment thread ergo-api/src/server.rs
Comment thread ergo-node/src/node/snapshot_emit.rs
The projection served only latest(100) while the ring retains 512, so a
client whose ?since cursor was 100-512 events stale saw a silent gap that
was NOT eviction — violating the documented 'gaps only mean eviction'
contract. Project EventFeedRing::CAP instead (cloned only when the seq
advances, so cost is unchanged on quiet ticks) and state at the API level
that eviction is the only gap source; openapi snapshot regenerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@arkadianet
arkadianet merged commit 08eb901 into main Jul 3, 2026
8 checks passed
@arkadianet
arkadianet deleted the feat/ui-events-feed branch July 3, 2026 04:36
arkadianet added a commit that referenced this pull request Jul 16, 2026
Removes AI-review-tool attributions (Codex plan finding/follow-up/audit
citations, CodeRabbit PR #152), dangling internal task/milestone labels
(Phase 0/1a/1b/2a/2b/2f-1/2f-3/2j/3a/3b/4/4a/4b/4d, sub-phase 14.6/14.10,
Part 2 spec/§N, "M5 final slice in audit-todo", OBS-1/P2 work-item codes,
bare commit hashes, "spec §7.3/§7.4"), and citations to internal
design/spec docs confirmed absent from the repo (design §2/§5/§6/§6.2,
"operator workload §D", "spec §2 Channel Sizing") across the wallet
bridge, config, boot, api_bridge, snapshot, mining/sync, and node-identity
modules. Doc-only.

Fixes 2 real staleness bugs found along the way:
- node/state.rs: doc comment called drive_popow_bootstrap/
  handle_inbound_popow_proof "both follow-up commits" -- both are already
  implemented (sync_tick.rs, messaging.rs).
- api_bridge/tests.rs: a monitoring-scraper note said a stale-field bug
  was fixed "Pre-r5" -- restated as the direct current-behavior guarantee
  without the version tag, since no such tag is used elsewhere in the repo.

Preserved: every Scala/REST-compat citation, the crate's own stable Mode
1-6 operational-mode taxonomy and R1/R2/R5 Scala-parity validation codes,
mainnet-incident rationale (h=28662 sign-flip, silent-stall and
header-only-reset-stall bugs), and all consensus/sync-safety documentation
(prune-sentinel gating, split-brain best_full_block_height sync, NiPoPoW
resume-state classification).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi
arkadianet added a commit that referenced this pull request Jul 16, 2026
…203)

* docs(ergo-compiler): reference-implementation documentation pass (remaining files)

Elevates the last ~30 uncovered ergo-compiler files (parse/*, typer core,
AST/type/token core, and the transform layer + lib.rs) to the same
documentation standard applied in #202: strips internal planning-artifact
references (dev-docs citations, milestone/task-tracker labels, dangling
finding codes) while preserving all Scala source citations, oracle vectors,
and the crate's deviation ledger. Doc/comment-only, no behavior changes.

Also fixes one real inaccuracy found along the way: lib.rs's module doc
claimed CSE was not yet wired into compile() -- it is (tree/mod.rs:217).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-crypto): strip internal-artifact citations from test comments

Removes Task-N labels and a dangling internal-report/design-doc citation
("Task-4 report", "g25-pegmint-packaging §5.2.5") from group_element.rs and
merkle/mod.rs, restating the same facts directly. Doc-only; all Scala/scrypto
citations and oracle vectors untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-difftest): strip internal-artifact references from doc comments

Removes bare bug-tracker numbers (#97, #108/#115, bug #6), a dangling
"gitignored dev-docs Autolykos note" pointer, and redundant citations into
interface-contracts.md/findings-and-triage.md whose content was already
stated inline, restating each as a direct technical claim. Doc-only.

Preserved: all Scala/JVM-oracle protocol documentation, and the extensive
Bug #N cross-references in gen/mod.rs, gen/sigma_expr.rs, ergo_tree.rs,
box_candidate.rs, transaction.rs, header.rs, constant.rs, asm.rs -- these
map to the checked-in ergo-difftest/docs/known-bug-catalog.md rediscovery
gate and are the crate's own live API contract (Feature::bug_id()), not
development history.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-wallet): strip internal-artifact references from doc comments

Removes a bare uncited bug label, "Task 38" tracker references, and
roadmap-style "lands in following PRs"/"a later slice" phrasing from
scan/mod.rs, scan/predicate.rs, address.rs, secret.rs, and storage.rs --
restated each as a direct statement of current scope. Doc-only.

Preserved: all Fiat-Shamir/Schnorr/DHT protocol documentation, BIP32/BIP39/
EIP-3 citations, and the upstream Ergo issue #1627 legacy-derivation
provenance baked into ExtendedSecretKeyLegacy/use_pre_1627.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-mining): strip internal design-doc citations from doc comments

Removes dangling "v12 §N" / "design §N" internal design-plan citations
from candidate.rs and handle.rs, and an uncited "audit-1" tracker label
from error.rs -- restated each as a direct statement of the invariant.
Doc-only.

Preserved: all Scala consensus citations (CandidateGenerator.scala,
EmissionRules.scala, ReemissionRules.scala), emission/coinbase/reward-script
byte-layout documentation, and the "Component B" subsystem name where it
functions as this crate's (and ergo-mempool's) stable cross-file name for
the suspect-feed/targeted-recheck mechanism rather than a dangling doc
pointer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-mempool): strip internal-artifact references from doc comments

Removes this repo's own PR #139 references, a dangling "§7"/"Phase 2A
guidance" design-doc citation, and two code-review-thread references
("Item 3 of the code-review fixes", "reviewer finding 1") from lib.rs and
admission/tests.rs -- restated each as a direct technical statement.
Doc-only.

Preserved: all Scala mempool-parity citations (OrderedTxPool, MempoolAuditor,
CleanupWorker), the "Component B" and numbered admission-step naming (both
confirmed stable, cross-referenced internal pipeline structure, not dangling
doc pointers), and mempool invariant #7's cross-reference to its real
definition in admission.rs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-p2p): strip internal-artifact references, fix stale connection-limit doc

Removes dangling internal labels (Sync-S3/Lever 1/plan §240 in sync.rs,
Sync-S2 in delivery.rs, an AI-audit-session narrative and a "checklist
contract" pointer in peer_manager/mod.rs) and roadmap phrasing in
handshake.rs test docs, restating each as a direct technical statement.
Doc-only.

Also fixes a real inaccuracy: peer_manager/mod.rs's module doc still said
"Max 80 total / 60 outbound" connections by default; the actual Default
(limits.rs) is 384 total / 96 outbound / up to 256 inbound (decoupled).
Updated to match.

Preserved: all Scala P2P-protocol citations, wire-format byte-layout
documentation, the out96/in256/cap384 connectivity-limit rationale, and
the 2026-07-04 testnet-stall regression note in throttle.rs (genuine
incident documentation, not development history).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-indexer): strip internal-artifact references from doc comments

Removes a dangling "audit-2 M11" milestone label from handle.rs, and an
AI-agent reference plus two citations to an uncommitted internal spec file
(2026-05-01-storage-rent-eligibility.md, confirmed absent from the repo)
from rollback.rs -- restated each as a direct technical statement. Doc-only.

Preserved: all Scala indexer-parity citations, the testnet-431,366 and
h=740,362 mainnet-incident notes, and the crate's own stable Phase 0/Phase
1 rebuild-state naming.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-sync): strip internal-artifact references from doc comments

Removes AI-agent/review-tool references ("Codex supervisor plan", "codex
review notes", "codex round-N guard"), internal task-tracker labels
("M5 final slice tracked in audit-todo"), and dangling internal
increment/design-plan labels ("Sync-S0/S1/S3", "Plan §240") from
executor/mod.rs, block_proc.rs, and coordinator/{mod,tests}.rs -- restated
each as a direct technical statement. Doc-only.

Preserved: all Scala sync-parity citations (ToDownloadProcessor.scala,
ElementPartitioner.distribute), and the operational rationale behind the
real merged "headers-synced stale-tip stall" and "caught-up-to-peers
fallback" fixes, which document actual observed behavior rather than
development history.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-validation): strip internal-artifact references, fix mojibake

Removes dangling internal-plan/spec citations across block/header, voting,
popow, and tx modules ("v12 §5 step N", "spec §8.1", "2026-04-28-voted-
parameters-phase2.md" (confirmed absent from the repo), "R5 security gap /
§11", "14.10", "§6.3", "T4 live differential", "codex P0-1", "§3.5") and an
AI-review-tool tracker label, restating each as a direct technical
statement. Doc-only.

Also fixes a real encoding bug: voting/votes.rs and its oracle test carried
double-encoded UTF-8 em-dashes ("—" instead of "—") -- restored throughout
both files. The same corruption exists in ergo-sigma and will be fixed when
that crate's pass runs.

Preserved: every Scala consensus citation (ErgoStateContext.scala,
NipopowAlgos.scala, Parameters.scala, RuleStatusSerializer.scala, etc.),
mainnet-incident-derived rationale (blocks 290684/422179/1802240,
h=1821696), EIP-27/storage-rent documentation, and all oracle-pinned test
vectors -- this is the workspace's consensus-validation crate and none of
its correctness specification was touched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-ser): strip internal-artifact references, fix broken citation

Removes AI-review-tool tracker labels ("codex P1", "codex review of the
MAX_EXPR_DEPTH=110 fix") from ergo_tree.rs and sigma_value.rs, and dangling
citations to internal spec files confirmed absent from the repo
(.superpowers/sdd/task-1-report.md, dev-docs/context-ext-count-signedness-
recon.md, dev-docs/.../recon-segregation.md, "Phase 0 §11.5") from
address.rs, input.rs, opcode/tests.rs, and popow_proof.rs. Also drops
dangling "sub-phase 14.3"/"§14.3" cross-crate milestone labels from
popow_header.rs, matching the same cleanup already done in
ergo-validation's popow module. Doc-only.

Also fixes a real broken citation: extension.rs's proptest doc comment
named two test functions that don't exist in the file
(extension_too_many_fields_returns_invalid_data /
extension_value_too_long_returns_invalid_data); corrected to the actual
names (extension_field_count_above_u16_returns_invalid_data /
extension_field_value_above_255_returns_invalid_data).

Preserved: every Scala/sigma-state wire-format citation, opcode-by-opcode
byte-layout documentation, oracle-derived test vectors, the KMZ17
interlinks-sizing rationale, and the STypeVar/JVM-UTF8 and MAX_TYPE_DEPTH
divergence notes -- this crate's entire purpose is byte-exact parity with
the Scala reference and none of that specification was touched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-sigma): fix mojibake, strip internal-artifact references

Fixes 42 instances of double-encoded UTF-8 mojibake ("—" -> "—") in
evaluator/opcodes/method_call.rs, matching the same corruption already
fixed in ergo-validation.

Removes AI-review-tool/PR-number dev-history references from
evaluator/tests.rs (codex P1, "per CodeRabbit on PR #38", "Reviewer
finding:", a bare commit hash), evaluator/opcodes/method_call.rs
("PR #13/#14 oracle vectors"), and evaluator/opcodes/binding.rs
("CodeRabbit PR #161 finding") -- restated each as a direct technical
statement. Doc-only.

Preserved: every Scala/sigma-state citation across the evaluator (opcode
dispatch, cost accounting, method_call semantics, Schnorr/DHT proof
verification, AVL+ operations, verify.rs's top-level reduction path),
oracle-pinned test vectors, and the GHSA-hfj8-hjph-7r78 security-advisory
citation. Left one "TODO v6.0: implement" comment untouched in
evaluator/opcodes/errors.rs -- it's a verbatim quote of the Scala
reference source's own class comment (trees.scala:77), not this repo's
dev history.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-state): strip internal-artifact references from doc comments

Removes AI-review-tool attributions (Codex flagged/identified, "codex risk
flag in 2h plan"), dangling internal task/milestone labels (Task 1.6/1.7,
Phase 0/1a/1b/1c/2/2a/2b/3/3a/3b/4/5, sub-phase 14.5/14.10, audit-2 M5,
Task 38), and citations to internal spec/incident docs confirmed absent
from the repo (spec §7.1/§7.4, "2026-05-02-voted-params-first-epoch-
boundary", "dev-docs/incident-2026-06-11-adproofs/") across the store,
digest, avl, wallet, and persist modules -- restated each as a direct
technical statement. Doc-only.

Preserved: every Scala consensus citation, the crate's own stable Mode
2/3/5/6 operational-mode naming and per-function "Phase 1/2/3" step labels
(these describe a single function's own algorithm steps, not a development
roadmap -- same pattern as ergo-sync's kept "Step 2.5"), the mainnet
incident at height 1,805,523 (technical substance kept, only the dangling
doc pointer dropped), and all AVL+/digest-mode byte-layout documentation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-api): strip internal-artifact references, fix 3 stale docs

Removes a systemic pattern found across nearly every v1/* file: citations
to dev-docs/v1-api-design.md and its section numbers (§N.N), work-breakdown
codes (G-N/O-N used as dangling pointers), "locked decision" labels, and a
sibling dev-docs/v1-design-fragments/*.md fragment doc -- all confirmed
absent from the repo. Also strips compat/blockchain module citations to a
nonexistent "spec inventory"/section-12 label, and AI-review-tool references
(CodeRabbit #170, "codex", "see the PR report"). Doc-only.

Fixes 4 real staleness bugs found along the way:
- v1/mod.rs: said v1 "isn't mounted on a route yet" -- it is (server.rs).
- v1/auth.rs: said tiers/boot-warn aren't wired per-group yet -- they are.
- v1/mempool_depth.rs: called stats/mempool-depth "future" -- it's live.
- v1/realtime/bus.rs: called webhooks "a future PR" -- webhooks is built
  and is itself a live RealtimeBus subscriber.

Preserved: every Scala/REST-compat citation, the compat/ module's
byte-for-byte quirk-compatibility documentation, T0/T1/T2 tier naming and
G-N/O-N primitive-numbering (real, pervasively cross-referenced internal
names, not dangling doc pointers), and all storage-rent/wallet/mempool
correctness rationale.

Two residuals flagged but intentionally NOT touched (would be a behavior
change, out of scope for a docs-only pass): three JSON response `detail`/
`note` string literals in operator/node.rs, accounts/mod.rs, and
script/handlers.rs leak the same internal jargon into live API responses;
and decode/registry.rs's `rent` protocol entry has `reference:
"dev-docs/demurrage"`, a nonexistent path returned live via GET
/api/v1/protocols. Both are real product bugs worth a follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* docs(ergo-node): strip internal-artifact references, fix 2 stale docs

Removes AI-review-tool attributions (Codex plan finding/follow-up/audit
citations, CodeRabbit PR #152), dangling internal task/milestone labels
(Phase 0/1a/1b/2a/2b/2f-1/2f-3/2j/3a/3b/4/4a/4b/4d, sub-phase 14.6/14.10,
Part 2 spec/§N, "M5 final slice in audit-todo", OBS-1/P2 work-item codes,
bare commit hashes, "spec §7.3/§7.4"), and citations to internal
design/spec docs confirmed absent from the repo (design §2/§5/§6/§6.2,
"operator workload §D", "spec §2 Channel Sizing") across the wallet
bridge, config, boot, api_bridge, snapshot, mining/sync, and node-identity
modules. Doc-only.

Fixes 2 real staleness bugs found along the way:
- node/state.rs: doc comment called drive_popow_bootstrap/
  handle_inbound_popow_proof "both follow-up commits" -- both are already
  implemented (sync_tick.rs, messaging.rs).
- api_bridge/tests.rs: a monitoring-scraper note said a stale-field bug
  was fixed "Pre-r5" -- restated as the direct current-behavior guarantee
  without the version tag, since no such tag is used elsewhere in the repo.

Preserved: every Scala/REST-compat citation, the crate's own stable Mode
1-6 operational-mode taxonomy and R1/R2/R5 Scala-parity validation codes,
mainnet-incident rationale (h=28662 sign-flip, silent-stall and
header-only-reset-stall bugs), and all consensus/sync-safety documentation
(prune-sentinel gating, split-brain best_full_block_height sync, NiPoPoW
resume-state classification).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

* fix(ergo-api): regenerate OpenAPI golden fixtures after doc cleanup

utoipa embeds doc comments directly into the generated OpenAPI spec, so
the internal-artifact citations stripped from wallet/v1 doc comments in
46cdb66 changed the generated native and v1 specs, drifting them from the
checked-in golden fixtures. CI caught this (openapi_native_matches_snapshot
and openapi_v1_matches_snapshot both failing on all three platforms).
Regenerated both fixtures via the documented `regenerate` test target; no
other change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kw7uCwqmiGna8fpg6TvxGi

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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