Skip to content

draft integration - #80

Draft
yuval-block wants to merge 104 commits into
mainfrom
draft
Draft

yuval-block wants to merge 104 commits into
mainfrom
draft

Conversation

@yuval-block

Copy link
Copy Markdown
Collaborator

mainly for @oakagent to pick apart, individual PRs for the various pieces will come separately

nothingmuch and others added 30 commits August 4, 2026 16:25
mdbook-graphviz re-serializes every chapter, escaping characters such
as `[`, `_` and `\` along the way. It and mdbook-katex were both only
ordered after `links`, and mdbook happened to run graphviz first, so
katex saw the escaped source: a formula like `$t \in [a, b]$` reached
it as `$t \\in \[a, b\]$`, failed to parse, and was left in the page
as raw TeX.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An index entry indented two spaces more than the entry above it becomes
a sub-chapter of that entry in SUMMARY.md, which mdbook numbers and
shows as nested in the sidebar. The contents page copies the index, so
it nests the same way.

An indented entry at the start of a part has no entry to nest under, and
an entry indented more than one level deeper than the entry above has no
parent at the level between, so both are rejected, as are indents that
are not a multiple of two spaces. Tabs and other indented lines are
still unexpected lines.

OKF v0.2 shows only flat index entries. The more OKF native way to nest
is a sub-directory with its own index.md, such as docs/tactics/index.md,
listed by the root index as one entry. Indented entries keep the files
where they are; moving to sub-indexes is a possible follow-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bc1cindy <bc1cindy@proton.me>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The notebook package re-executes the notebook. Execution is
deterministic and records no timing metadata, so re-rendering the
notebook amounts to copying the build output over it, and a notebook
that is already up to date comes back byte-identical.

Only editing or executing the notebook needs the scientific python stack,
so it stays out of the default shell and the site build. The notebook
devshell has the same dependencies as the derivation, plus jupyterlab,
whose checkpoint directories are ignored. Every dependency is packaged
in nixpkgs, so no uv2nix layer is required.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The saved plots came from Colab, whose environment is not recorded
anywhere. Re-executing with the notebook derivation reproduces the
same data (the denominations table is unchanged), and the result is a
fixed point: building again from the re-rendered notebook leaves it
byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The last chart counted n^k ordered selections, which overstates the
number of size k combinations with replacement from n denominations,
(n+k-1 choose k), by orders of magnitude: 30,840,979,456 versus
55,525,372 for k=6. With the correct count the combinations stay below
the number of distinct integers in the range for every k.

The density axis was scaled by an invisible scatter of the densities,
which only lined up with the count axis while the combinations curve
set the top of the plot. Derive its limits from the count axis instead.

The output is rendered by the notebook derivation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Split the long conditional sentences, say what Hamming weight 1 means
for the denominations in use, and state what the notebook measures
before the asymptotic claim about the size of the denomination set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sumsets draw k values from the denominations and 0, so they hold the
sums of every combination of size at most k. Count those combinations
the same way, (n+k choose k) less the empty combination, which makes the
two curves agree at k=1.

The counted combinations are not limited by their sum, so title the
chart by the denominations they are drawn from and attach the range to
the distinct sums and integers instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The quantile levels are i/20, so the median is i == 10. Skipping i == 5
dropped the first quartile and drew dots under the median markers.
Name the number of quantile levels and derive the median's index and
the legend's percentile step from it, so they cannot disagree again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Say which property permutations of equal values preserve and why
permutations within a sub-transaction yield no new mappings, name the
fee rates whose variance makes k:1 exchanges asymmetric, and use m for multiplicity so that k only
ever means combination size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describe why dense instances leave sub-transaction mappings
underdetermined without suggesting a brute force enumeration: density
survives setting any one sub-transaction aside, so it holds for the
rest of the transaction too. Open the Radix CoinJoin section by
drawing that conclusion explicitly.

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

- [x] Define wallet-state domain and transitions
- [x] Define expectation and brackets
- [x] Define piecewise-linear sign-change evaluation
- [x] Reconcile multiparty monotonicity with wallet-state domain

Co-authored-by: GPT-5.6 Sol <noreply@openai.com>
The book is assembled from docs/ by contrib/book.py, which only took
markdown pages as chapters. Take Jupyter notebooks too. A notebook's
frontmatter is a raw cell that opens it, holding what a markdown page's
frontmatter would. It is checked, and dropped from the notebook the book
is given, as a markdown page's is. Jupyter's autosaves under
.ipynb_checkpoints/ are neither chapters nor copied.

List the radix CoinJoin notebook in the index, under a new Drafts part,
in place of the SUMMARY.md entry it had before the book was assembled
from docs/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Apply the fixes from the PR 15 review that were made on the
cost-function-review branch (56f24f01, 139a1679, 93f82c18), which still
edits the old cost_function.md path:

- Cindy's typo list, and a few more of the same kind
- RBF double spends the transaction's spent outputs, not its own outputs
  (oakagent's comment)
- The objective cost is the negated change in balance, so it is positive
  when a transition pays a fee and reduces the balance

Lines that were rewritten in "Clarify abstract cost function" keep that
wording. The unresolved diff at the end of that commit is left as it is,
with the same fixes applied to both of its sides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Verbatim notes on how the decision tree is built, to be distributed where
they belong in the repository.

things like the actions going into broadcasting ownership proofs, making co-spend proposals, broadcasting unilateral co-spend proposals (e.g. a single coin with surplus and density certificate requirement vs. picking specific values and choosing payoffs for them)

describe how the tree is built bottom up:

1. partition the queue of intents in the wallet state heuristically
2. each partition is an outcome, batches to execute
3. for each outcome,  generate coin selections iteratively batch by batch possibly shuffling. these can be optimizing or fully randomized, interactive incoming payments could be treated as pseudo-inputs. ensures the outcome has a positive surplus and can be executed
4. for each surplus, decompose it by brute force enuemration of radix possibilities
5. for coins on the order book "select" them to extend outcomes


this generates a bunch of independent, complete, balanced outcomes that each involve disjoint batches (though typically there will be one greedy batch, or one small batch for a unilateral fallback if it becomes urgent)

the shared coins of these are then used to guide the decision tree, as is individual coins' luck at the current time or the next time (beacon values don't need to be the current block tip they can be delayed by some block depth)


each path down the decision tree is a plan, by building the trees bottom up by scheduling actions that are least comittal first and leaving the ones shared by most outcomes to be the roots, all actions including announcements, co-spend proposals etc can be planned, and new alternatives can be added to this or an entire tree recalculated and potentially ORed with the current one from any arbitrary state

however because this object is potentially large and costly to generate and evaluate we want to generate most of it up front

as co-spend proposals, coalition formation proposals and auxiliary inputs of comitted transactions are learned the decision tree can be updated

expectations about the durations of certain steps can be annotated along the path, which allows the time dependence of the leaves to be taken into account ensuring to schedule actions to take place early enough

interanlizing expectaitons about the children into their parents gives a way to evaluate the parents' piecewise linear curve, and solve for the time at which the next child it is expected to have positive utility and at that point take this branch (unless new information comes in and invalidates the decision)

---

- [x] Describe the bottom-up construction in the decision tree structure section of cost_function_abstract.md
  - done in “Describe how the decision tree is built”
- [x] List the actions (ownership proofs, co-spend proposals, unilateral co-spend proposals)
  - done in “Describe how the decision tree is built”

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mdbook rewrites links to `.md` chapters into links to their `.html`
pages, and into in-page anchors on the print page, but leaves links to
`.ipynb` chapters as they are, so they lead to the raw notebook, which
isn't part of the built site.

After rendering the notebooks, the preprocessor points every relative
link that resolves to a notebook chapter at the chapter's `.md` path,
so mdbook rewrites it like any other chapter link. Links to other
`.ipynb` files, and absolute ones, are left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The decision tree section only had a FIXME saying the tree is built
bottom up. Describe the construction from the notes recorded in the
parent commit:

- the actions, including announcements and negotiation, not just
  transaction construction
- outcomes generated first: partition the intents, select coins batch by
  batch, decompose each surplus into radix denominations, extend with
  coins from the order book
- the tree arranged over these outcomes, least committal actions first,
  guided by shared coins and luck under the beacon
- updating the tree as proposals and auxiliary inputs are learned
- durations along each path, and solving the parent's piecewise linear
  curve for the time to take the next branch

---

- [x] List the actions
- [x] Describe the bottom-up construction
- [ ] Settle the term for a proposal naming a single coin ("unilateral
      co-spend proposal" in the notes, "single-UTXO proposal" in the
      subset sum ambiguity chapter)
- [ ] Check "surplus" here (what is left after funding a batch) against
      the surplus of a co-spend proposal in coalition_formation.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mdbook lists separators as the bare string "Separator" and part titles
as {"PartTitle": ...}, and the jupyter preprocessor called .get on every
item, so a book with a separator stopped the build. It now only
descends into chapters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cspell rejects "feerates", "locktimes", "backout" and "Parameterizing" in
docs/cost_function_abstract.md. The first three are Bitcoin and Lightning
vocabulary, so they go in the shared dictionary. "Parameterizing" is
only used in this chapter's heading, so it is allowed inline, as
cost_function_subset_sum_ambiguity.md does for its own words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mdbook loads additional-js on print.html as well, so the printed book
kept only the first page of each table and showed dead page buttons.

Showing every row widens the table past the page, because the later
rows hold the longest values, so print also tightens font and padding.
Finish resolving the conflict. The end of the document was still the
diff part of a jj conflict: lines prefixed with "+", "-" or a space,
followed by the conflict's closing marker.

Keep the "-" side, the original wording of the end of "Use in
multiparty protocols", and drop the "+" side:

- "Piecewise-linear payoff curves and sign changes", whose math wasn't
  reviewed. Solving for intercepts is described in words in a later
  commit.
- the rewrite of the last two paragraphs, whose point that partial
  transactions are information within a wallet state is already made in
  "Wallet states and actions". Monotonicity is rewritten in a later
  commit.

Both are still in this commit's parent if they're wanted.

Also empty the lines that contained only a space.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The global text colour is a mid grey chosen to read on the page, but
these labels sit on the bars, where grey has almost no contrast. They
go back to black, as they were before the plot style was added.
Compare the channel output with a unilaterally controlled output

The lightning channel funding output is an output, so the comparison is
with a unilaterally controlled output, not an input.

From a593abdf on cost-function-review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With a transparent figure the darkest plasma fills sit directly on the
page, and on the dark themes they nearly vanish into it. A grey outline
per series keeps each silhouette visible on either theme.
Weigh the waste metric against the other terms

Consolidation at low feerates is what the waste metric favors, but the
waste metric is just one term, included in every automated transaction.
Whether coins are actually spent together also depends on other terms,
such as privacy liabilities, which the abstract cost function leaves to
concrete writeups.

From 9500ed84 on cost-function-review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nothingmuch and others added 22 commits October 26, 2026 05:21
cost_function_randomized_selection.md adapts the randomization gist
(#22) as three cost function terms: the per input and
pairwise preferences, and the provenance term, which multiplies the funding
transaction's liquidity and cost by the Sybil resistance index computed from
joint sums. Covers the terms in the decision tree and after confirmation.

sybil_resistance_index.md: the proofs of the joint sums bound, from the
estimator in tx-graph-estimators (joint_spans.lcb), and the scan over
candidate block hashes. The simulation, Rust timings and caps are from its
rust-joint-spans bookmark.

It replaces the chapters' review stubs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Builds the decision tree from the leaves: partitions of the pending
action queue, coin selection within each, change construction, order
book coins, action sequences, and bracketing. It replaces the
chapter's review stub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Privacy liability terms chapter points to the metrics in its
opening, and the Tactics chapter follows the Mixed strategy chapter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two additions to the overview: a paragraph pointing at the channel
interfaces, and one relating per-peer trust assumptions to asymmetric
distributed trust and Flexible BFT. Kept apart from the overview itself
(PR 51) so it can be reviewed on its own.

Co-authored-by: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
List the messages peers exchange: peer introduction, gossip, sets,
public gossip, negotiation, session initialization, transaction
construction, interactive payments and blocks. For each, say who sends
it, to whom, in which setting, what it carries and what its channel
must provide.

The content comes from the peer messages draft (onwloqro) and the
concurrent PSBT and coalition formation drafts. The draft's transport
survey is left out: specs state channel properties, and choosing a
transport belongs to another layer.

It replaces the chapter's review stub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
State what interactive payments need from peer to peer messaging:
reaching the counterparty's device, inviting it into a collaborative
transaction, and messaging it during the critical section for payment
confirmations. Payment confirmations follow the payment graph and refer
to the block DAG's committed message sets.

Contact, identity and device management is left to applications.

It replaces the chapter's review stub. Links to other chapters
resolve against their stubs until those land.

Co-authored-by: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ownership proof gossip, online key enrollment, its flood protection and
precedence ordering, the gossip rules for listen advertisements, and the
flood protection for partially accepted proposals are transport rules for
the peer to world broadcast domain. Move them here from coalition
formation unchanged, apart from a link from the listen advertisement
rules back to coalition formation.

The removal from coalition formation is a separate commit on the
coalition formation branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Give the protocol an abstract syntax for messages: send, receive and
bidirectional channels. Name the three kinds of messaging the protocol
needs: peer to peer authenticated messages, and peer to group and peer
to world anonymous messages, which are broadcast. Define connection and
message unlinkability, and build broadcast by gossip from peer to peer
channels that are sender anonymous and message unlinkable.

SDK implementation choices (Rust traits, adapters, builders) are left
to the SDK.

It replaces the chapter's review stub. Links to other chapters
resolve against their stubs until those land.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The radix footnote linked the notebook on Colab, which is becoming a
chapter of the book. It names that chapter until both are merged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Armin Sabouri <me@arminsabouri.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Start from push gossip, then motivate pulling with the block structure:
a peer holding a Merkle root wants the leaves it commits to. Honest
peers send only hashes whose preimages they have validated, and answer
a pull with the preimage, like getdata in Bitcoin. That is enough for
the naive reconciliation of BEC. The same mechanism exchanges roots of
unordered sets: the mempool-like set of a group, and the order book of
the world. Range reconciliation and rateless streams are optimizations
of this one mechanism.

It replaces the chapter's review stub.

Co-authored-by: GPT-6 Astra <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The DAG doesn't order messages; its message sets are sets, committed to
by sparse Merkle trees. The ordered/unordered distinction is between a
list and a set, as for a block's parents if they are committed to in an
arbitrary order. Whether a set is in the block DAG determines its
consistency guarantees instead, so rename the unordered sets section
to sets outside the block DAG.

Drop the relation to asynchronous data dissemination, which is for
large messages; ours are generally small.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Record the best candidate found so far for proving that outputs are
covered by inputs: input slots committed with their destinations,
anonymous registration rate-limited by a tag per slot, and output proofs
against the registered leaves, in jellyfish TurboPlonk on BN254 with a
universal setup.

The figures come from the jf-register proof of concept. Evaluation
continues; the code will be rewritten for Fungi and this document
finalized when validity proofs are needed.

It replaces the chapter's review stub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A stalled phase of the optimistic track turns into a recovery coalition
formation proposal. Deadlines exist only on this track. Recovery track
blocks have a reduced threshold t < n and commit unambiguously to what
they are missing; a block that contradicts itself is invalid and its
author treated as unresponsive, but an equivocating one still exposes
the author's key.

Counterparty stalls are specified as option A (blame the payer only),
with option B (blame the pair) described and left open. Also covers the
dishonest majority case, privacy, cost and a worked example.

It replaces the chapter's review stub. Links to other chapters
resolve against their stubs until those land.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The block structure both tracks of transaction construction share: its
objects, optional block extensions, nonce commitments and compact
equivocation evidence, genesis, causal order and block properties, and
frontiers. It was a section of the transaction construction chapter,
and is now its first sub-chapter.

It replaces the chapter's review stub. Links to other chapters
resolve against their stubs until those land.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A parent chapter for transaction construction in the abstract: content
versus state synchronization, the phases, the two tracks, and what the
validity proofs enforce, without how they work.

The block DAG both tracks share is its first sub-chapter, followed by
the optimistic and recovery tracks. The validity proofs chapter follows
the protocol messages.

It replaces the chapter's review stub. Links to other chapters
resolve against their stubs until those land.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Phases close by unanimous acknowledgement, with no deadlines: each phase
closes with an echo and a closing acknowledgement, the input set is
stable before outputs, and the outputs phase closes on balance. The
chapter goes through the phases one by one, including the censorship
exception for a validator's own anonymous contributions.

It also covers sharded state and synchronization scope, the
dissemination interface, optional attested validation and
acknowledgement relay, and block publication after quiescence.

It replaces the chapter's review stub. Links to other chapters
resolve against their stubs until those land.

Co-authored-by: GPT-6 Astra <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge each protocol chapter's bookmark, and the overview with its
transport edits, over the book structure and its review stubs. Each
chapter replaces only its own stub, so the merge has no conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ownership proof gossip, online key enrollment, its flood protection and
precedence ordering, the gossip rules for listen advertisements, and the
flood protection for partially accepted proposals now live in the
channels chapter, under peer to world broadcast. Keep the section
headings, so existing anchors still resolve, and point each one there.

The channels chapter isn't on this branch, so these links only resolve
where both are merged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The draft is published from its own repository,
fungi-protocol/docs-draft, so that nothing has to be merged into main
for it to go live. Its Pages site is served from /docs-draft/, not
/docs/. Point the 404 page's base and the link check at that path.

The Pages workflow is unchanged: it deploys on a push to that
repository's main, which is this commit.

This commit belongs on draft only. It never goes to main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
range-diff for force push 1ee57d1562 → 8e41ba243d October 26, 2026 05:06 UTC: 1 modified, 99 unchanged

reproduce: git range-diff 116e871..1ee57d1 116e871..8e41ba2

  1:  e8823d9851 =   1:  e8823d9851 Concurrent PSBT spec
  2:  eaeb02395e =   2:  eaeb02395e Render math before mdbook-graphviz re-serializes the markdown
  3:  45d04a7c65 =   3:  45d04a7c65 [WIP] Nest indented index entries as sub-chapters
  4:  e5cca8913e =   4:  e5cca8913e Arrange the index into the parts proposed in #19
  5:  f71ae6bd74 =   5:  f71ae6bd74 Radix coinjoin denominations notebook
  6:  cd8717c6e3 =   6:  cd8717c6e3 add a notebook derivation and a devshell for editing the notebook
  7:  074f2043e6 =   7:  074f2043e6 re-render notebook outputs with the notebook derivation
  8:  c694d0f6b8 =   8:  c694d0f6b8 count combinations with replacement as multisets
  9:  8e5f763477 =   9:  8e5f763477 clarify the notebook introduction
 10:  3ab0a79a2e =  10:  3ab0a79a2e count combinations of up to k denominations, as the sumsets do
 11:  9c9b6c7189 =  11:  9c9b6c7189 skip the median, not the 25th percentile, among the quantile dots
 12:  08ef6aaccc =  12:  08ef6aaccc clarify the sub-transaction counting argument
 13:  34c8624554 =  13:  34c8624554 explain why sums are cut off above a multiple of max_denom
 14:  adef92720d =  14:  adef92720d explain subset sum density as an invariant of the mapping
 15:  92be6a91e9 =  15:  92be6a91e9 Abstract cost function
 16:  b45805e9b2 =  16:  b45805e9b2 render jupyter notebook chapters as mdbook pages: hide code, paginate tables
 17:  f7f60c5d6c =  17:  f7f60c5d6c [WIP] ████████████████████ Clarify abstract cost function
 18:  4c0c04bdde =  18:  4c0c04bdde assemble notebook chapters from docs/
 19:  c9657fb600 =  19:  c9657fb600 fixup! Abstract cost function
 20:  46bd912aab =  20:  46bd912aab style plots: theme-neutral, colorblind-safe, re-rendered outputs
 21:  d8cc781d87 =  21:  d8cc781d87 [WIP] ████████████████████ Record decision tree construction notes
 22:  fb7eaf4a88 =  22:  fb7eaf4a88 point links to notebook chapters at their rendered pages
 23:  d2188cce83 =  23:  d2188cce83 [WIP] ████████████████░░░░ Describe how the decision tree is built
 24:  12882cc08a =  24:  12882cc08a Skip separators and part titles when walking the book's chapters
 25:  f251904ed0 =  25:  f251904ed0 [WIP] Add the cost function's words to the spelling dictionary
 26:  3090962f8b =  26:  3090962f8b nb-table: print every row of paginated tables
 27:  3db8bc429b =  27:  3db8bc429b fixup! [WIP] ████████████████████ Clarify abstract cost function
 28:  7eb96cdf62 =  28:  7eb96cdf62 keep bar value labels black over the bar fills
 29:  f1e0775403 =  29:  f1e0775403 fixup! Abstract cost function
 30:  3bbaca1af3 =  30:  3bbaca1af3 outline density series to read on dark pages
 31:  dfeb856e29 =  31:  dfeb856e29 fixup! Abstract cost function
 32:  72b2b36caf =  32:  72b2b36caf restore the density plot's legend frame
 33:  d2fd00eccb =  33:  d2fd00eccb fixup! Abstract cost function
 34:  f08d2541b1 =  34:  f08d2541b1 stop claiming six outputs close every gap above dust
 35:  ba2dc096f8 =  35:  ba2dc096f8 fixup! Abstract cost function
 36:  332eb9a07a =  36:  332eb9a07a Keep the powers below the dust threshold until they are multiplied
 37:  1dc15c0962 =  37:  1dc15c0962 [WIP] Order inputs before outputs within a batch
 38:  ce1e6b3aa5 =  38:  ce1e6b3aa5 Say that the gap plot's k=6 quantiles start at 2, not 1
 39:  1a8d01c6d1 =  39:  1a8d01c6d1 [WIP] Model time dependence as piecewise linear offsets
 40:  8b3cd62799 =  40:  8b3cd62799 Bound the terms of a sum above the cutoff by its size alone
 41:  64b6dd7261 =  41:  64b6dd7261 [WIP] Say what each end of the bracket means
 42:  60483321e7 =  42:  60483321e7 Say that a k:1 exchange changes the weight, not the fee
 43:  7cb54eb1ca =  43:  7cb54eb1ca [WIP] Distinguish the pure and mixed strategies
 44:  4e0549d28c =  44:  4e0549d28c Qualify the density argument by the denominations that remain
 45:  dca8177394 =  45:  dca8177394 [WIP] Describe commitment in multiparty protocols
 46:  3d0b9d7731 =  46:  3d0b9d7731 Define the on-chain privacy problems being addressed
 47:  f466a31550 =  47:  f466a31550 Show the denomination generating code in the book
 48:  c0d0ac8041 =  48:  c0d0ac8041 [WIP] Rewrite the global privacy budget
 49:  69cc0361bf =  49:  69cc0361bf Edits to Collaborative Transaction Privacy (#30)
 50:  c9cc193580 =  50:  c9cc193580 Coalition formation
 51:  4f8b8cc681 =  51:  4f8b8cc681 Show the sumset and gap computation code in the book
 52:  d98dc69986 =  52:  d98dc69986 Fix typos and a broken anchor in the concurrent PSBT spec
 53:  26f0b2c05c =  53:  26f0b2c05c [WIP] ████████████████░░░░ Penalize co-spend proposals that leak a counterfactual path
 54:  5cb76884a7 =  54:  5cb76884a7 Revise and clarify following editorial pass
 55:  1d16c3d371 =  55:  1d16c3d371 [WIP] ████████████████░░░░ Add input value constraints to proposal conditions
 56:  0b760af3e8 =  56:  0b760af3e8 Show the analysis parameters in the book
 57:  ae28f03f0e =  57:  ae28f03f0e Move the concurrent PSBT spec into the book
 58:  50ab0fc9c6 =  58:  50ab0fc9c6 fixup! [WIP] ████████████████░░░░ Describe how the decision tree is built
 59:  59ce690b06 =  59:  59ce690b06 fixup! [WIP] Say what each end of the bracket means
 60:  ada41525c2 =  60:  ada41525c2 [WIP] ████████████████████ Describe the greedy decision loop
 61:  a3a6ae2197 =  61:  a3a6ae2197 [WIP] ████████████████████ Give the decision loop its own heading
 62:  d8c739a4c5 =  62:  d8c739a4c5 [WIP] ██████████████████░░ Move tree construction to the strategy chapter
 63:  480d87164c =  63:  480d87164c [WIP] ████████████████░░░░ Rename the chapter to Optimization framework
 64:  424d28b5e5 =  64:  424d28b5e5 [WIP] ████████████████████ Introduce the strategy as generating and evaluating decisions
 65:  2e3c4c14eb =  65:  2e3c4c14eb [WIP] ████████████████░░░░ Move the mixed strategy into its own chapter
 66:  1241a68935 =  66:  1241a68935 [WIP] Add the Pure Strategy Evaluation chapter
 67:  66962a56d1 =  67:  66962a56d1 [WIP] ████████████████░░░░ Mark agent-generated text with 🤖
 68:  746b8a2055 =  68:  746b8a2055 [WIP] Add the Tactics chapter
 69:  9db08a16d9 =  69:  9db08a16d9 [WIP] Call the greedy loop a decision loop run as a greedy search
 70:  d144f76af6 =  70:  d144f76af6 [WIP] Add the Privacy liability terms chapter
 71:  3746f2e362 =  71:  3746f2e362 Add an overview
 72:  564eafe255 =  72:  564eafe255 [WIP] Specify peer and broadcast channels
 73:  0f938de8c3 =  73:  0f938de8c3 [WIP] Move the cost function's structure into its own chapter
 74:  8ae2f824a6 =  74:  8ae2f824a6 [WIP] Describe what each privacy liability term is for
 75:  8080f864df =  75:  8080f864df Link the optimization framework chapter by its new file name
 76:  12dfe894df =  76:  12dfe894df [WIP] Compare candidate transports for the channels
 77:  59bd9579e0 =  77:  59bd9579e0 Move the problem definition into the mdbook
 78:  380b9bd4f6 =  78:  380b9bd4f6 [WIP] Link the Tactics and Privacy liability terms chapters
 79:  ae24c1a125 =  79:  ae24c1a125 [WIP] Outline max flow based counterfactual path estimation
 80:  4a94f1c4a8 =  80:  4a94f1c4a8 [WIP] Outline the consolidation penalty
 81:  f410526ff3 =  81:  f410526ff3 [WIP] Outline subset sum density, subset sum ambiguity and the sibling output penalty
 82:  89dfa42770 =  82:  89dfa42770 [WIP] Add the randomized selection and Sybil resistance chapters
 83:  3e10b5d2e9 =  83:  3e10b5d2e9 [WIP] Add the Bottom-up construction chapter
 84:  bc18c81547 =  84:  bc18c81547 [WIP] Group the privacy metrics after the privacy liability terms
 85:  686efeeae4 =  85:  686efeeae4 [WIP] Point the overview at the channel interfaces and asymmetric trust
 86:  d483a2ee8f =  86:  d483a2ee8f [WIP] Specify the protocol messages
 87:  89a6e005e9 =  87:  89a6e005e9 [WIP] Specify contacts and payment messaging
 88:  31f505ed43 =  88:  31f505ed43 [WIP] Move the BIP 322 gossip rules into peer to world broadcast
 89:  dd81be7d24 =  89:  dd81be7d24 [WIP] Specify the abstract transport interfaces
 90:  330989bc4b =  90:  330989bc4b Refer to the Radix CoinJoin Denominations chapter
 91:  915c548aaf =  91:  915c548aaf README do-over
 93:  c7a5c9ca5a =  92:  c7a5c9ca5a [WIP] Specify peer set reconciliation
 94:  b1b1e23160 =  93:  b1b1e23160 [WIP] Distinguish lists from sets, not DAG from non-DAG
 95:  8183885159 =  94:  8183885159 [WIP] Specify the allocation registration validity proofs
 96:  786eefe3ec =  95:  786eefe3ec [WIP] Specify the recovery track
 97:  eae73a6fa0 =  96:  eae73a6fa0 [WIP] Specify the block DAG
 98:  2b8c84d848 =  97:  2b8c84d848 [WIP] Introduce transaction construction
 99:  950eca6f64 =  98:  950eca6f64 [WIP] Specify the optimistic track
 92:  044726af51 !  99:  e6b5b0b793 [WIP] Move the BIP 322 gossip rules to peer to world broadcast
100:  1ee57d1562 = 100:  8e41ba243d [WIP] Serve the draft from /docs-draft/
92: 044726af51 ! 99: e6b5b0b793 [WIP] Move the BIP 322 gossip rules to peer to world broadcast
@@ docs/coalition_formation.md: Finally, PQ privacy must of course also assume that
  ### Transaction construction protocol
  
 -A transaction construction protocol can provide liveness, although in this setting, relying on KVACs would require one of the peers to serve as the coordinator, and it would be trusted. With modification, this coordinator could prove all transcript messages it accepted are valid, but may still arbitrarily censor certain operations, causing a UTXO to be unfairly blamed for failing to sign.
-+🤖 The accepted coalition formation proposal specifies the initial inputs, their online keys, the negotiated adjustments and the parameters for [transaction construction](transaction-construction.md). It is the genesis of the construction instance. The initial state can be proven valid with respect to each UTXO's adjustment sum commitments, which enforces that the agreed imputation is in effect.
++🤖 The accepted coalition formation proposal specifies the initial inputs, their online keys, the negotiated adjustments and the parameters for [transaction construction](transaction-construction.md). It is the genesis of the construction instance. The initial state can be proven valid with respect to each UTXO's adjustment sum commitments, which enforces that the agreed imputation is in effect. When construction stalls, the [recovery track](recovery-track.md) turns the stall into a new coalition formation proposal among the responsive subset.
  
 -Technically the coalition formation proposal can implement a coordination fee mechanism — for example, by making all adjustments slightly negative, apart from that of the coordinator (which may or may not be the aggregator). This provides the coordinator with an incentive to coordinate honestly on average. Unfortunately, this does little for any targeted censorship risk, so long as the payoff from censorship (of e.g. a specific TxOut) dominates over the expected loss of revenue from sabotaging a single attempt at transaction construction. It's likely that the majority of the revenue is still recoverable in a subsequent blame round, as the other participants have no indication that censorship has occurred.
 +🤖 Any participant can act as an aggregator. Assembling a proposal gives that participant no additional privileges during transaction construction.

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

Typos in what this pull request adds:

docs/channels.md

  • l.47 - "UTXOs that provides" → "UTXOs that provide"
  • l.49 - "encoded of the cost function" → "encoded in the cost function"
  • l.69 - "gossipped" → "gossiped"
  • l.69 - "is just be a hash" → "is just a hash"

docs/coalition_formation.md

  • l.76 - "the honest subset peers" → "the honest subset of peers"

oak · automated

Comment thread docs/recovery-track.md

- each started successor costs the adversary at least one coin, apart from option A's counterparty exception;
- a late pass starts nothing, so it creates no new attempt;
- a participant accepts at most one successor per stalled phase;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Recovery accepts conflict with one-successor rule

The acceptance section says a participant may accept competing successors of the same stalled phase, but this privacy bullet says it accepts at most one. The two rules cannot both be implemented, and the privacy and boundary-split analysis depends on which one holds.

oak · automated · 8e41ba2

Comment thread docs/protocol-messages.md
- the Merkle set commitment of its parent blocks;
- the Merkle set commitment of the gossiped transaction construction messages it includes;
- its parent block by the same node;
- the nonce point R its successor will be signed with.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Block format drops recovery nonce commitment

This block format lists a single nonce point, while the block DAG requires separate optimistic and recovery nonce points and selects the point by track. A block built from this description cannot satisfy the track-specific signing rule, and the two descriptions disagree on the data needed to detect equivocation.

oak · automated · 8e41ba2

@bc1cindy
bc1cindy requested a review from oakagent October 26, 2026 17:03
Comment thread book.toml
additional-css = ["theme/diagrams.css"]
git-repository-url = "https://github.com/fungi-protocol/docs"
site-url = "/docs/"
site-url = "/docs-draft/"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Not-found page base points to a path the Pages workflow does not deploy

On merge, the Pages workflow publishes the site at /docs/ (as docs/README.md documents), but site-url makes mdbook write <base href="/docs-draft/"> into the 404 page, so its CSS and JS resolve under a path the workflow does not deploy.

oak · automated · 8e41ba2

Comment thread docs/protocol-messages.md
| [Session initialization](#session-initialization) | Start a construction session | all |
| [Transaction construction](#transaction-construction) | Build the transaction | all |
| [Interactive payments](#interactive-payments) | Grant funds and confirm payments | honest, semi-honest |
| [Blocks](#blocks) | Synchronize state and signal phase changes | semi-honest, Byzantine |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Docs disagree on blocks in the honest setting

The blocks row restricts blocks to the semi-honest and Byzantine settings, but transaction-construction says both tracks use the block DAG and the optimistic track is sufficient in the honest setting. Implementers cannot tell whether the honest setting uses blocks.

oak · automated · 8e41ba2

Comment thread contrib/book.py
"""A notebook's frontmatter, as a markdown page would have it, if a
raw cell holding nothing else opens it, and the notebook without it."""
nb = json.loads(text)
cells = nb.get("cells", [])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Non-object notebook JSON crashes check with AttributeError

A notebook file containing [] makes nb.get raise AttributeError, which check does not wrap, so the build fails with a traceback that omits the filename.

oak · automated · 8e41ba2

@bc1cindy
bc1cindy requested a review from oakagent October 27, 2026 15:20

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

Reviewed 8e41ba2 again: nothing to add to the earlier comments.

oak · automated

This branch has not been deployed

No deployments
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.

5 participants