Skip to content

docs: resync docs.decdn.org with the current protocol spec - #232

Merged
alpergundogdu merged 6 commits into
mainfrom
claude/decdn-docs-freshness-5d301a
Sep 24, 2026
Merged

alpergundogdu merged 6 commits into
mainfrom
claude/decdn-docs-freshness-5d301a

Conversation

@yigitdot

@yigitdot yigitdot commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Why

docs/ is the Mintlify source for docs.decdn.org, and per docs/README.md its source of truth is the protocol spec in the sibling repo. The last content resync landed 2026-07-09 (#187, #184); every commit to docs/ since has been SEO or config.

The spec moved substantially in that window — a payment primitive was replaced, a discovery layer was deleted, the reputation model was inverted, a slashable offense was removed, and two decision records landed. The published docs were describing contract functions and message flows that no longer exist, which is a correctness problem on a public site: a reader following /protocol/payments would try to call functions that aren't in the contracts.

What changed

All 14 pages, no new pages, no docs.json change.

Payments — rewritten. Per-pair payment channels are gone. /protocol/payments described openChannel / closeChannel / disputeChannel, voucher nonces, a dispute window, cooperativeClose, and per-stream cadence negotiation — none of which exist. Replaced with the shared pool: one deposit per payer opened once and off the fetch path, capped delegated signers via off-chain capabilities, cumulative node-addressed vouchers, hash-chain (PayWord) metering at a fixed 1 MiB quantum, per-node redemption with no dispute window, the redemption grace window, the credit window, and the dormant minDeposit Sybil knob. The stale vocabulary had leaked into five other pages, all corrected.

Gossip removed. There is no gossip layer in the protocol any more — node discovery is the on-chain registry active set, region comes from the on-chain claim, rates are quoted in signed probe responses. It was referenced in seven places across six pages, including two mermaid diagrams.

Reputation — rewritten. The page described signed peer reports, reporter weighting against on-chain settlement history, per-report clamps and a cold-start bonus. Reputation is now strictly local: an EWMA (α = 0.1) over speed / correctness / reachability, neutral 0.5 for unknown peers, closed-form half-life decay, and explicitly not an eligibility, settlement or governance input.

Slashing — two offenses, not three. Phantom announcement is gone; only rate manipulation and blacklist violation remain. Added the commit–reveal challenge flow (which exists to stop the challenger reward being front-run) and a short section on what is deliberately not slashable — corrupted delivery and refusing to serve.

Multi-source fetch. Was "full holders only for now" with hedged stragglers. Partial holders are now first-class via 64 MiB coverage bitmaps, the scheduler fans out eagerly and admits at most one node per operator, and hedging was rejected by decision — every byte is paid, so the tail is bounded by deadline-based reassignment instead.

Governance. The bootstrap phase was documented as ending at ≥ 30 operators and ≥ 100 Gbps. There is no threshold automation — the multisig ends it by scheduling a single timelock batch as a manual judgment call. Also replaced the dispute-window bounds row with the redemption grace window, added defaults and the missing rows, and corrected the emergency multisig's capability list (blacklist-entry appeals were retired).

Publishers and namespaces, absent from the docs entirely despite namespaceId now riding on every delivery request, folded into architecture, content addressing, takedown and the glossary — along with the positive origin authority (governance vets a publisher wallet; the vetted publisher seats its own origin operators per namespace).

Also: the retired stream-response redirect field; the invented "PostgreSQL or SQLite" content-catalog schema; the privacy page overstating four committed mitigations when two are committed and identity rotation is accepted-not-mitigated; and the ADR index listing two retired records as accepted while missing two new ones.

Notes for review

  • Every claim was checked against the current spec rather than inferred. Things confirmed still accurate and left untouched: bao / 16 KiB chunk groups / the ~0.4% proof overhead, the capacity-bond curve, the three ALPNs, the quorum / timelock / voting-cap / tenure-ramp numbers, the capability-split multisig sunset, the compliance windows and emergency auto-expiry terms, the 5/15/50% slash schedule, and the relay rationale.
  • Scope was deliberately held at corrections plus the namespace fold-in. The two new decision records get index rows only; the one user-visible consequence (a node may decline to serve, and refusing is not slashable) is a line in how-it-works.
  • The pages keep their existing register — short, declarative, "Decision"-led, table- and diagram-led — rather than importing spec-level detail no current page carries. No ADR numbers are cited outside the existing index page.
  • Three mermaid diagrams were redrawn: the architecture gossip edges, the cache-hit channel open/close arrows, and the payments channel lifecycle (now a pool lifecycle).

Verification

All four docs workflow gates pass locally:

  • pnpm exec prettier --check "docs/**/*.{md,mdx,json}"
  • pnpm exec markdownlint-cli2 — 0 errors
  • npx mintlify@4.2.555 broken-links — no broken links
  • pnpm test — 22 files, 463 tests passed

pnpm build is unaffected; docs/ is not part of the static export and website.yml ignores it.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 3, 2026 01:39
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 3, 2026 •

Copy link
Copy Markdown

Deploying website with  Cloudflare Pages  Cloudflare Pages

Latest commit: 07849c7
Status: ✅  Deploy successful!
Preview URL: https://820302b4.website-70y.pages.dev
Branch Preview URL: https://claude-decdn-docs-freshness.website-70y.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

A few internal inconsistencies in the updated payments/slashing docs could mislead readers (voucher/preimage wording, bond flow phrasing, and MB vs MiB unit mixing).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Resyncs the Mintlify documentation under docs/ to match the current protocol spec, removing deprecated protocol concepts (notably gossip discovery and per-peer payment channels) and updating core protocol pages to the new pool/voucher/preimage payment model, local-only reputation, and revised slashing/takedown/governance behavior.

Changes:

  • Rewrites payments from per-pair channels to a shared on-chain pool with capabilities, cumulative vouchers, and hash-chain metering.
  • Removes the gossip-based discovery layer in favor of the on-chain registry active set + DHT discovery/coverage.
  • Updates slashing/reputation/takedown/governance and overview pages to reflect revised evidence paths, local reputation, namespaces/origin assignment, and updated ADR index.
File summaries
File Description
docs/protocol/takedown.mdx Updates takedown model to include positive origin assignment and revised emergency/regional semantics.
docs/protocol/slashing.mdx Revises slashable offenses and adds commit–reveal challenge flow plus “not slashable” section.
docs/protocol/reputation.mdx Rewrites reputation as local-only EWMA scoring with decay-to-neutral behavior.
docs/protocol/privacy.mdx Updates privacy analysis to the pool-based payment model and revises committed mitigations.
docs/protocol/payments.mdx Replaces channel lifecycle with pool lifecycle, capabilities, vouchers, hash-chain metering, and minDeposit.
docs/protocol/network.mdx Replaces gossip discovery with registry active-set discovery and coverage-aware DHT probing/selection.
docs/protocol/governance.mdx Updates bootstrap/governance transition description and expands governable parameter bounds.
docs/protocol/content-addressing.mdx Adds publishers/namespaces framing and updates trust/availability statements.
docs/overview/participants.mdx Aligns role descriptions with registry+DHT discovery and pool/voucher payments.
docs/overview/introduction.mdx Updates introductory framing to pool-backed vouchers and removes gossip wording.
docs/overview/how-it-works.mdx Updates mermaid flows and narrative for pool redemption, namespaces, coverage, and no-hedging multi-source fetch.
docs/overview/glossary.mdx Updates definitions for pools/capabilities/coverage/namespaces and new multi-source behavior.
docs/overview/design-decisions.mdx Updates ADR index rows (removes retired entries; adds new ADR 040/041).
docs/overview/architecture.mdx Updates diagrams and “life of a paid delivery” to match the new discovery and payments model.
Review details
  • Files reviewed: 14/14 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/protocol/payments.mdx Outdated
Comment thread docs/protocol/slashing.mdx Outdated
Comment thread docs/protocol/slashing.mdx Outdated
yigitdot and others added 2 commits September 3, 2026 05:05
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@yigitdot

yigitdot commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

Review pass — 26 corrections in 50780b8

Ran a multi-agent review over the diff. It's 14 prose files and zero code, so four of the usual reviewers had nothing to analyse (no tests, no error handling, no types, nothing to simplify); the review that matters here is a fact-check against the spec, which docs/README.md names as the source of truth. Two agents audited the pages claim-by-claim against it and a third checked conventions, links, terminology and register.

I re-verified the eight highest-impact findings against the spec myself before acting on any of them. All eight held, so I treated the rest as reliable.

Regressions this PR introduced (14)

The substantive ones:

  • Reputation lost the per-interaction clamp. My rewrite dropped it entirely; the spec caps a single interaction at ±0.05, which is what stops one bad exchange sinking a good peer.
  • Voting weight omitted the declared-capacity cap. Each week's counted bytes are capped at what the operator's declared tier could physically deliver — an operator declaring zero capacity earns zero weight however much it served. That's the anti-self-dealing leg, and it was missing.
  • Regional-body suspension had its default inverted. I wrote that it stands unless governance acts; the spec says silence lapses it, precisely so the multisig can't disable a jurisdiction without a vote.
  • The split-sunset paragraph covered three of four multisig powers. I added "decide slash appeals" to the capability list without extending the sunset, leaving the page silent on whether that authority survives month 12.
  • multi-gigabit speeds was invented — no throughput figure appears anywhere in the spec — and the bound being lifted is a holder's uplink, not an origin's.

Plus: chunk_price's sealed-voucher exception, minDeposit bounds, the namespace-0 case for the origin-directory fallback, relays described as protocol rather than operational infrastructure, the outboard import stated unconditionally, ~11-day contradicting the page's own ~10-day, "epoch" used as a unit no page defined, an orphaned Segment glossary row the prose never used, and "slashing window" load-bearing on three pages and defined on none.

Pre-existing errors the resync missed (12)

Left in place by the original resync, all verified wrong:

  • Slash tiers were called "fixed constants, not governable" — the per-offense percentage is governable within 5–50%. What's hardcoded is the escalation on the reset period.
  • "Governance sets rate bounds; a node outside them is ignored by selection" — wrong on both halves. There is no governance ceiling, a node below the floor clamps up and keeps serving, and requester rejection is local policy, not protocol.
  • The 4% quorum rationale cited Compound and Uniswap (absent from the spec) and claimed no single operator can unilaterally pass a proposal — arithmetically false, since the per-operator cap is 5% against the same denominator.
  • A "gray area" and "strictest jurisdiction" guidance for regional takedown that exists nowhere in the spec. Scope follows the operator's declared region; the requester's location is not an input.
  • "the accepted ADRs" — 9 of 26 are Accepted; 16 are Draft and one Proposed.
  • Privacy's adversary model had the wrong T4 (a malicious origin, rather than memory/disk access to one machine), an invented "PIR at O(log N)" figure, SNI/ECH where the spec's surface is ALPN, and the keychain mitigation pointed at the Ethereum key, which is already in an encrypted keystore.

Plus rate manipulation described as a different rather than a higher rate, origin backends said to "ride the same QUIC transport", the client's network key called ephemeral when it's persistent, the who-pays table claiming an origin-backed node never pays, "lowest cost wins" instead of lowest score, and a missing non-goal.

Verification of the corrections

Re-ran the fact-check against the corrected pages rather than assuming the fixes were right. All 26 landed, and the pass caught six problems the corrections themselves introduced — including a real one where I attributed the 1×/2×/4× escalation to the slash tiers when it belongs to the reset period (the tiers escalate 1×/3×/10×), and an overshoot claiming nothing caps a node's rate from above when a wire-layer bound does exist. Those are fixed too.

Gates: prettier --check, markdownlint-cli2, mintlify broken-links (needed — the fixes add a new heading and anchor), pnpm test 463 passed.

Not in this PR

lib/faq.ts still sells payment channels and lists phantom availability as slashable — live copy, mirrored into llms-full.txt, so it ships twice and now contradicts the docs. Filed as #233 rather than pulled in here, since crossing into lib/ would drag the website workflow into a docs-only PR. The blog posts use the old terms too but are dated artifacts and should stay as written.

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

A few internal doc inconsistencies/wording issues remain (notably governance parameter bounds vs explanatory text, and origin-assignment terminology) that should be corrected before merge.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

docs/protocol/takedown.mdx:73

  • This paragraph hard-codes the blacklist violation slash tiers as 5% / 15% / 50%, but governance.mdx now describes the tiers as governable within hardcoded bounds. To keep the docs internally consistent, this line should clarify these are the current/default tiers (and link to the governability note).
## Slash schedule

Blacklist violations use an escalating schedule: **5% / 15% / 50%** for first / second / third offense (capped at 50% per offense). Offenses accumulate over the operator's lifetime; a node whose bond falls below 50% of the minimum is auto-ejected.
  • Files reviewed: 14/14 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread docs/overview/architecture.mdx Outdated
| Role | Operated by | Participates in CDN? |
| ------------------------ | ------------------------------------------------ | ----------------------------------------------------------- |
| **Node (pure cache)** | Independent node operator | Yes — bonds, probes, publishes to the DHT, delivers |
| **Node (origin-backed)** | Content provider _or_ node operator with storage | Yes — same protocol, plus a publisher-seated origin backend |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 6c29e1b. Checked against the spec and the seating attaches to the wrong object: a vetted publisher authorizes an operator for a namespace, and only then does that operator configure its origin store locally. The backend is downstream of the seating and is never seated by anyone — backends are purely operational, and configuring one without authorization just means the bytes serve as cache. The row also contradicted the origin invariant further down the same page. Now reads "plus authorization to serve as an origin for a namespace".

Comment thread docs/protocol/governance.mdx Outdated
| Parameter | Default | Bounds |
| ----------------------------------------- | -------- | ------------ |
| Operator revenue share (`FeeRouter` base) | 60% | 40% – 90% |
| Burn share (`FeeRouter`) | 30% | 5% – 50% |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 6c29e1b. The table contradicted its own explanation four lines below it. The spec carries the qualifier inline for exactly this reason — default "30% (0% while dormant)", min "5% when active", max 50% — so the row now matches that shape: Default 30% (0% dormant), Bounds 5% – 50% when active.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@altanoruc

Copy link
Copy Markdown
Contributor

Review notes after checking the branch against the current ADRs and contract surface:

  1. docs/protocol/payments.mdx:62 drops the sealed-voucher exception. ADR 003 requires a sealed voucher to carry chain_root = 0 and chunk_price = 0; only a metering voucher must match the node's quoted rate. The current “rejects any voucher” wording would tell implementers to reject the normal cooperative close shape. This exception was present after 50780b8 and was accidentally removed again in be02454.

  2. docs/protocol/privacy.mdx:32 describes a future mitigation as already deployed. The current PoC still stores the iroh/Ed25519 key as raw bytes in ~/.decdn/iroh_key with mode 0600; ADR 012/017 specify platform-keychain storage as a pre-mainnet/production commitment. This should distinguish the currently encrypted Ethereum keystore from the currently plaintext network key and use future/roadmap wording for the latter.

  3. docs/protocol/governance.mdx:44 says the 5%/15%/50% slash tiers are governable, but CapacityBond hard-codes SLASH_BPS_TIER_1/2/3 and exposes no setter, while ADR 026 also calls these the escalation tiers. ADR 009's “slash percentage” bounds currently conflict with both of those sources. Since this PR's purpose is to publish the canonical protocol, that source conflict should be resolved rather than stating governability as settled fact.

  4. docs/protocol/slashing.mdx:42 presents the challenge bond as a fixed 100 TOKEN requirement. SlashJudge.challengeBond is governable through setChallengeBond within 1–1,000 TOKEN; 100 TOKEN is only the deployment default. Please label it as the default/current value.

  5. docs/protocol/reputation.mdx:29 says the log-normalized speed score “does not saturate,” but ADR 008 defines clamp(ln(1 + actual_bps) / ln(1 + reference_bps), 0, 1). It does saturate at the configured reference (1 GiB/s by default); the intended claim is only that it does not flatten at the old ~80 Mbps baseline.

  6. docs/protocol/takedown.mdx:31-32 makes the 90-day CSAM/terrorist emergency row look exempt from the 2-hour slash grace. Category changes auto-expiry only; all emergencyAdd entries use emergencyComplianceWindow. Both emergency rows should show the same slash grace.

Validation on 6c29e1b: Prettier and markdownlint pass; Vitest passes all 22 files / 463 tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yigitdot

Copy link
Copy Markdown
Collaborator Author

All six fixed in 07849c7. Verified each against the contracts/ADRs before applying.

  1. Sealed voucher — restored the exception: a node rejects only metering vouchers on chunk_price mismatch; a sealed cooperative-close voucher carries chunk_price = 0 and is exempt. Confirmed against ADR 003 (MUST carry chunk_price = 0; equality check applies to metering vouchers only). This regressed in be02454 — good catch.

  2. Key storage — reworded to design-intent tense: "The design keeps client keys in OS-level secure storage … rather than plaintext files on disk." That answers the not-yet-deployed point without renaming the network key or leaking PoC status. I did not restore the Ethereum-encrypted vs network-key-plaintext distinction — that detail was deliberately cut earlier as below the altitude of a protocol-design page, and naming the key types reintroduces it. If you'd rather the page carry the per-key PoC state explicitly, say so and I'll add it.

  3. Slash ladder — corrected to fixed, not governable, on both governance.mdx and takedown.mdx. Confirmed SLASH_BPS_TIER_1/2/3 are internal constant with no setter; this matches the upstream resolution in docs(adr): the slash ladder is fixed, not governable — align ADR 009/011/026 with CapacityBond decdn#2000 ("the slash ladder is fixed, not governable"). This reverts a wrong change I made in 50780b8.

  4. Challenge bond — now "100 TOKEN by default, governance-set within a 1–1,000 TOKEN band." Confirmed SlashJudge.challengeBond + setChallengeBond (GOVERNANCE_ROLE), bounds [1e18, 1000e18].

  5. Speed score — dropped "does not saturate"; it now reads that the curve reaches its max at the reference and doesn't flatten at a low baseline. Matches ADR 008's clamp(…, 0, 1).

  6. CSAM/terrorist row — added "(with 2 h slash grace)"; category sets auto-expiry only (14 d vs 90 d), and all emergencyAdd entries share the 2 h emergencyComplianceWindow.

Prettier, markdownlint, 463 tests, and mintlify broken-links all pass.

@alpergundogdu
alpergundogdu merged commit 1a8789a into main Sep 24, 2026
7 checks passed
@alpergundogdu
alpergundogdu deleted the claude/decdn-docs-freshness-5d301a branch September 24, 2026 12:42
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.

4 participants