Skip to content

fix(consensus): short-circuit Coll-equality cost at first mismatch (Scala parity) - #108

Merged
arkadianet merged 1 commit into
mainfrom
fix/colleq-cost-shortcircuit
Jun 19, 2026
Merged

fix(consensus): short-circuit Coll-equality cost at first mismatch (Scala parity)#108
arkadianet merged 1 commit into
mainfrom
fix/colleq-cost-shortcircuit

Conversation

@arkadianet

@arkadianet arkadianet commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Why

EQ/NEQ on a primitive collection (Coll[Byte]/Bool/Int/Long/Short, SString) charged the per-item cost over the full left-operand length, but Scala's DataValueComparer.equalCOA_Prim short-circuits both value and cost at the first unequal element — billing PerItemCost over the compared prefix (the loop's returned count i, via addSeqCost). For two equal-length colls differing at index k<len, Scala bills chunks(k+1); we billed chunks(len).

Over-charge only (never under) → a reject-valid risk: an input whose true cost sits just under the tx/block cost limit but whose collection equality short-circuits early could be over-billed past the limit and rejected where Scala accepts. Coll[Byte] equality (token ids, propositionBytes, digests) is pervasive.

What

Split the typed-Coll arm of eq_with_cost_inner: the primitive carriers walk both arrays, stop at the first unequal element, and charge the per-type PerItemCost over that compared prefix — mirroring eq_coll_fallback/CollSigmaProp, which already track k_eff. All-equal and length-mismatch costs are unchanged. Box/Header/Tokens colls (Scala equalColls path) are untouched.

Test plan

  • RED/GREEN unit tests (prim_coll_eq_tests): early-mismatch costs < late-mismatch; all-equal == last-element-mismatch (full length); length-mismatch bills only MatchType.
  • cargo fmt ✓, clippy --all-targets --all-features -D warnings ✓, cargo test --all ✓.
  • SANTA conformance: clears the 3 Coll.eq_compared_count_coa coals (mismatch-at-0/150/300), no new coals.

Note

The earlier triage lumped 17 h* block-input vectors into this cluster. Verified post-fix: their +1/+2 cost deltas are unchanged by this change — they're a separate cost-model divergence (value byte-identical), not the Coll-eq short-circuit. They need their own root-cause and are not addressed here.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Performance Improvements
    • Improved equality comparisons for primitive collections to stop at the first mismatch, reducing work on large structures.
  • Correctness / Cost Accounting
    • Refined the comparison cost behavior so pricing now reflects only the successfully compared prefix; if lengths differ, the result is determined after charging only the base match cost.
    • Non-primitive string and related types keep the previous full-length cost behavior.
  • Tests
    • Added coverage to verify early vs. late mismatches and length-mismatch scenarios.

@coderabbitai

coderabbitai Bot commented Jun 19, 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: 637dcd75-4a3f-4825-a61c-9d93af716079

📥 Commits

Reviewing files that changed from the base of the PR and between c2568a6 and 7790a8f.

📒 Files selected for processing (1)
  • ergo-sigma/src/evaluator/cost.rs

📝 Walkthrough

Walkthrough

eq_with_cost_inner in cost.rs is updated to implement Scala equalCOA_Prim semantics for primitive collection carriers (CollBytes, CollBool, CollShort, CollInt, CollLong). Cost and value comparison now short-circuit at the first unequal element, charging MATCH_TYPE unconditionally then PerItemCost only over the compared prefix. Two private helpers and a unit-test module are added.

Changes

Primitive collection equality short-circuit cost

Layer / File(s) Summary
Helper functions and dispatch routing
ergo-sigma/src/evaluator/cost.rs
Adds prim_coll_eq charging MATCH_TYPE plus PerItemCost(15, 2, chunk_size) over the compared prefix length with early return on mismatch, and prim_coll_eq_fallback for mismatched carriers. Updates eq_with_cost_inner match arms to route primitive collection types through these helpers with per-type chunk_size, while explicitly excluding Str, CollBox, CollHeader, and Tokens from the short-circuit path.
Unit tests for prim_coll_eq cost behavior
ergo-sigma/src/evaluator/cost.rs
Adds prim_coll_eq_tests validating early vs late mismatch cost scaling, all-equal cost matching full-length mismatch cost, length mismatch charging only MATCH_TYPE, empty collection cost, and cross-chunk-size short-circuit behavior for multiple chunk sizes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • arkadianet/ergo#30: Introduced eq_with_cost/eq_with_cost_inner for Scala-faithful EQ/NEQ cost modeling — the direct predecessor to this PR's eq_with_cost_inner primitive collection dispatch changes.

Poem

🐇 Hop, hop, short-circuit away,
No need to check every byte today!
First mismatch found? We stop right there,
Charging only the cost we dare.
Less work for the rabbit, more speed to spare! 🥕

🚥 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 and concisely summarizes the main change: implementing short-circuit cost calculation for Coll-equality comparisons to match Scala behavior.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 fix/colleq-cost-shortcircuit

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 and usage tips.

@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.

🧹 Nitpick comments (1)
ergo-sigma/src/evaluator/cost.rs (1)

680-743: 💤 Low value

Consider adding test coverage for empty collections and varying chunk sizes.

The tests comprehensively validate the short-circuit behavior for CollBytes, but all three use the same chunk size (128). Since the prim_coll_eq function is generic and handles different chunk sizes (96 for Short, 64 for Int, 48 for Long), a test verifying that early-mismatch savings scale correctly with chunk size would strengthen confidence in the per-item cost formula.

Additionally, the empty collection case (k_eff = 0) is untested. While the logic appears correct, an explicit assertion that eq_cost(&[], &[]) returns the expected cost (MATCH_TYPE + base cost for 0 items) would document the behavior.

🤖 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-sigma/src/evaluator/cost.rs` around lines 680 - 743, Add two new test
functions within the prim_coll_eq_tests module to extend coverage. First, add a
test for empty collections that calls eq_cost with empty byte slices and asserts
the cost matches the expected MATCH_TYPE plus base cost for zero items. Second,
add a parametrized or separate test function that verifies the early-mismatch
cost savings behavior with different chunk sizes (96, 64, and 48) to ensure the
per-item cost formula scales correctly across different collection types,
similar to the existing collbytes_eq_cost_short_circuits_at_first_mismatch test
but using vectors of varying lengths appropriate to each chunk size.
🤖 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.

Nitpick comments:
In `@ergo-sigma/src/evaluator/cost.rs`:
- Around line 680-743: Add two new test functions within the prim_coll_eq_tests
module to extend coverage. First, add a test for empty collections that calls
eq_cost with empty byte slices and asserts the cost matches the expected
MATCH_TYPE plus base cost for zero items. Second, add a parametrized or separate
test function that verifies the early-mismatch cost savings behavior with
different chunk sizes (96, 64, and 48) to ensure the per-item cost formula
scales correctly across different collection types, similar to the existing
collbytes_eq_cost_short_circuits_at_first_mismatch test but using vectors of
varying lengths appropriate to each chunk size.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bc119b51-4856-4935-acff-7d33dd6c8439

📥 Commits

Reviewing files that changed from the base of the PR and between 4c54531 and c2568a6.

📒 Files selected for processing (1)
  • ergo-sigma/src/evaluator/cost.rs

@arkadianet
arkadianet force-pushed the fix/colleq-cost-shortcircuit branch from c2568a6 to 26dd37e Compare June 19, 2026 06:15
…cala parity)

EQ/NEQ on a primitive collection (Coll[Byte]/Bool/Int/Long/Short, SString)
charged the per-item cost over the FULL left-operand length, while Scala's
DataValueComparer.equalCOA_Prim short-circuits BOTH value and cost at the first
unequal element — billing PerItemCost over the elements actually compared (the
loop's returned count i), via addSeqCost. For two equal-length collections that
differ at index k<len, Scala bills chunks(k+1) but we billed chunks(len).

This is an over-charge only (never under), so it is a reject-valid risk: an
input whose true cost sits just under the tx/block cost limit but whose
collection equality short-circuits early could be over-billed past the limit
and rejected where Scala accepts. Coll[Byte] equality (token ids,
propositionBytes, digests) is pervasive in real scripts.

Split the typed-Coll arm of eq_with_cost_inner: the primitive carriers now walk
both arrays, stop at the first unequal element, and charge the per-type
PerItemCost over that compared prefix (mirroring eq_coll_fallback /
CollSigmaProp, which already track k_eff). All-equal and length-mismatch costs
are unchanged. Box/Header/Tokens colls (Scala equalColls path) are untouched.

Found via SANTA: Coll.eq_compared_count_coa + 17 captured h* block-input
vectors (cost +1/+2, value byte-identical). Adds RED/GREEN unit tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@arkadianet

Copy link
Copy Markdown
Owner Author

Addressed the test-coverage nitpick in 7790a8f: added collbytes_eq_cost_empty_collections (k_eff=0 → MatchType + base) and prim_coll_eq_short_circuits_across_chunk_sizes (verifies the short-circuit holds for the Short=96 / Int=64 / Long=48 chunk sizes, not just CollBytes=128). Also folded in the earlier P1 fix (SString stays full-length, not short-circuited). Branch rebased onto current main.

@arkadianet
arkadianet force-pushed the fix/colleq-cost-shortcircuit branch from 26dd37e to 7790a8f Compare June 19, 2026 06:58
@arkadianet
arkadianet merged commit 2af05f1 into main Jun 19, 2026
8 checks passed
@arkadianet
arkadianet deleted the fix/colleq-cost-shortcircuit branch June 19, 2026 07:17
arkadianet added a commit that referenced this pull request Jun 21, 2026
…lease cut (#126)

0.4.3 was version-cut at #117, but #106#114 and #118#125 landed at the same
version without a CHANGELOG entry — so [0.4.3] documented only #115/#116/#117
while the deployed 0.4.3 binary actually contains all 18 PRs since the v0.4.2
cut. Backfills the section to match what shipped:

- New ### Added subsection for the native /api/v1/wallet surface (#112, #113,
  #114).
- ### Fixed now covers the signed-byte parity fixes (#106, #107), the
  Coll-equality cost short-circuit (#108), EIP-27 re-emission enforcement
  (#109 + #111, merged — the P0 fork fix, now across block/mempool/mining), and
  the full v6/EIP-50 + ErgoTree wire-deserialization cluster (#118#125).
- Broadened the release intro to name the EIP-27 enforcement and the native
  wallet surface alongside the v6/EIP-50 conformance work.
- Added the missing (#117) reference to the box-deserialize entry.

Docs only; no code or behavior change. Entries were drafted from each PR's own
commit/description and accuracy-reviewed (e.g. the EIP-27 soak figure is the
corrected 172 reward-box burns, not the repudiated 1,173).

Co-authored-by: arkadianet <rkadias@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
arkadianet added a commit that referenced this pull request Jun 22, 2026
…1001 SigmaProp-root gate (#129)

* test(difftest): add a reduce eval/cost differential surface

The JVM-oracle fuzzer only diffed DESERIALIZE verdicts, so it was blind to the
eval/cost path — exactly where the #108/#115 cost divergences lived. Add a
`reduce` surface that deserializes an ErgoTree, reduces its root to the on-chain
sigma proposition + raw JIT cost under a minimal dummy context, and diffs the
`P:<prop>|<cost>` pair byte-for-byte against the Scala reference's reduction.
This is the reject-arm layer the deserialize-only surfaces cannot reach.

The Rust context mirrors EvalCore.dummyContext field-for-field: preHeader.version
4 / timestamp 3, generator miner key, AvlTreeData.dummy, cost limit =
scriptCostLimitInEvaluator, and SELF = an ErgoBox (value 1M, this tree, txid
zeros, index 0) with its serialized bytes + Blake2b256 id populated — so a script
reading context or SELF.bytes / SELF.id reduces identically on both sides. The
node half reuses the consensus box-script path via a shared
`deserialize_box_script` (read_ergo_tree + the four box gates). The GroupElement
on-curve check is scoped to this surface only: the node's read_ergo_tree codec
defers it to tx-validation (ergo-validation tx::ge), so applying it to the bare
`ergo_tree` codec surface reject-valids a body the JVM wraps-as-Unparsed. `--surface`
now works in the `--oracle` campaign (validated against the oracle surface set;
`--repro` keeps validating against the hermetic registry).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(consensus): reject non-SigmaProp ErgoTree root in sizeless box scripts

Scala's deserializeErgoTree runs CheckDeserializedScriptIsSigmaProp (validation
rule 1001): a root whose static type is not SigmaProp is a ValidationException,
and WITHOUT a size bit there is no declared-size region to wrap into an
UnparsedErgoTree, so it is re-raised as a hard SerializerException. The lenient
read_ergo_tree codec accepted such a tree and the box readers coerced it to a
trivial proposition. A block carrying such an output box would be accepted by
this node and rejected by every Scala node (accept-invalid / fork).

Add a `check_sigma_prop_root` gate (sizeless-only, mirroring check_resolvable_
methods; the has_size path already wraps via determinable_root_type) wired into
every consensus box reader AND the nested SBox-constant inner-script path (box
deserialization uses checkType=true at every level). determinable_root_type now
classifies all STATICALLY-DETERMINABLE non-SigmaProp roots:
  - inline Const / ConstPlaceholder (segregated type),
  - every zero-arg leaf (True/False, Height, Self, MinerPubkey, GroupGenerator,
    Inputs/Outputs, LastBlockUtxoRootHash, Global, Context),
  - operators with an unconditionally non-SigmaProp result (relations,
    arithmetic, hashes, SizeOf, box-field extractors, SigmaPropIsProven/Bytes).
Roots whose type DEPENDS on argument types (If, BlockValue/FuncValue, MethodCall,
field/index access) stay lenient — a full root typechecker is a follow-up; a
non-sigma one fails at evaluation instead.

Found by the new ergo-difftest reduce eval/cost differential and pinned against
the sigma-state 6.0.2 oracle (000173 / 0080 / 00a3 / 009305010501 / 00c1a7 ->
reject; 0008d3, P2PK, BoolToSigmaProp -> accept). Test fixtures that used a
bare-Boolean dummy script are updated to a SigmaProp root (08 d3).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(consensus): complete the rule-1001 gate for all determinable roots

Extend the rule-1001 (CheckDeserializedScriptIsSigmaProp) root-type classifier so
the box-script gate / has_size soft-fork-wrap judge a sizeless or wrapped root's
type the same way Scala's typed deserializer does — closing the remaining
accept-invalid (a non-SigmaProp-rooted output box this node accepts and every
Scala node rejects). Every rule is pinned against the sigma-state 6.0.2 oracle.

DETERMINABLE payload/operator roots (CodeRabbit review):
  - Coll / tuple literals, getVar[T]/box.RX[T] (-> Option[T]), NumericCast, and
    Deserialize{Context,Register}[T] (-> T verbatim: CAN be SigmaProp);
  - fixed-result operators: predicates / Bool logic -> Boolean; hashes/extractors/
    SubstConstants/Append/Filter/MapCollection/Slice -> Coll/bytes; SizeOf -> Int;
    DecodePoint -> GroupElement; TreeLookup -> Option; SigmaPropIsProven/Bytes.

ARG-DEPENDENT roots, typed by RECURSION into the type-determining child (Scala
computes these bottom-up; a non-determinable child stays None=lenient so this can
never reject a Scala-accepted tree):
  - If -> then-branch; BlockValue -> result; Fold -> zero/accumulator;
    SelectField -> tuple component; ByIndex/OptionGet/OptionGetOrElse -> element;
  - ArithOp (Plus/Minus/Multiply/Division/Modulo/Min/Max) -> LEFT operand: Scala
    types these as `left.tpe` with NO operand check, so Plus(sigma, x) IS SigmaProp
    (oracle-verified ACCEPT) — classifying them as fixed-numeric was a reject-valid.

The has_size wrap now recurses too, so a non-SigmaProp-rooted has_size tree
soft-fork-wraps verbatim exactly as the JVM does — this corrects a latent
rust-canonical-vs-JVM-verbatim divergence the STypeVar parity test had pinned
(its function-rooted vectors are non-SigmaProp and wrap; the UTF-8 lossy decode
itself is covered by ergo-ser/src/jvm_utf8.rs unit tests). Still SigmaProp-
capable / heavier arg-dependent roots (MethodCall/PropertyCall — need the method-
signature registry; ValUse/FuncApply — need a binding environment) stay lenient.

Verified: 0 reject-valid over the difftest reduce + ergo_tree campaigns (80k each).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(difftest): address review — oracle repro, SELF-box errors, reduce reject

  - `--oracle --repro <hex>` now replays the single input against the JVM oracle
    (run_oracle_repro) so a reduce finding is reproducible from the CLI.
  - build_dummy_self_box returns Result and propagates a serialization/id failure
    rather than masking it as empty SELF.bytes / a zero SELF.id.
  - the JVM oracle's reduceRepr now REJECTS (throws -> REJECT) a reduced root that
    is neither SigmaProp nor Bool, matching the node's reduce_verdict.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: arkadianet <rkadias@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
arkadianet added a commit that referenced this pull request Jul 16, 2026
…ents

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
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