Skip to content

Proposal: let a reviewed receipt carry an approved wording edit past the fidelity gate - #96

Merged
hiciefte merged 8 commits into
bisq-network:mainfrom
hiciefte:proposal/accepted-edit-receipts
Nov 10, 2026
Merged

hiciefte merged 8 commits into
bisq-network:mainfrom
hiciefte:proposal/accepted-edit-receipts

Conversation

@hiciefte

@hiciefte hiciefte commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Replaces #88, which was opened from a branch in this repository. The changes are the same; the commits were re-signed with corrected authorship.

This is a proposal for maintainers to decide. It approves no editorial change and contains no receipts (items is empty). How many people must approve, and in which roles, is your call; the options are below and in CONTRIBUTING.md. Merging this PR adopts the mechanism, not any of the 74 open editorial PRs. Before the first receipt merges, main needs branch protection (see "Approval rule"): the gate can only count the approvals a receipt records.

Why

Each of the 74 open editorial PRs (#100–#173) fails scripts/check-source-fidelity.mjs, and that failure is intended. CONTRIBUTING.md says such a PR can merge only with human approval and "a separately reviewed policy for accepted editorial changes", and that the original hashes must not be refreshed. That policy doesn't exist yet, so today none of these PRs can merge.

The gate's current output for an edited article is also hard to read. Applying PR #145's article diff to main gives:

Source fidelity FAILED (2 findings):
- src/content/docs/wiki/trading-monero.md: formatted source file drift
+ actual - expected

+ 'c06af3744dd5c97b59e3bc970f7d78954192a2c670a95f888c32686ff58fd9f9'
- '2e4a5fa1b052033a2eccddb27433ad539a8be6936a3ba4905498216fce5ea0da'

- migration/restoration-fidelity.json: expected 130 contextual image occurrences

126 !== 130

The second finding is a side effect of the first. The article that failed was never counted, so its four images are missing from the total. Nothing about the images changed.

What this PR does

  • migration/accepted-edits.json (new): holds the receipts. required_approvals is the one configurable value (set to 2 here as a placeholder). items is empty.
  • scripts/lib/accepted-edits.mjs (new): validates receipts, undoes a recorded edit exactly, and describes an edit so the helper can print a receipt.
  • scripts/check-source-fidelity.mjs: an edited article passes only when its receipts rebuild the exact restored original. Every existing check then runs on that rebuilt original, and the edited file is compared with it. An edit without a receipt now gives one finding that names the article and the reason. Image totals are skipped when an article could not be read, because the failing article is already reported. The CLI block at the end is only re-indented; git diff -w shows the real change.
  • scripts/record-accepted-edit.mjs (new): prints a receipt for one article, with hashes and recorded changes taken from git show <base>:<file> and the working tree. Reviewers fill in the summary, approvals, notes and evidence by hand.
  • scripts/accepted-edits.test.mjs (new, added to npm test): 15 tests.
  • PageTitle.astro, SourceHistory.astro, custom.css, review.md: a visible "Edited after restoration" signal, described below.
  • CONTRIBUTING.md: the receipt steps, the approval options and the branch-protection precondition.

Receipt shape

{
  "schema_version": 1,
  "description": "…",
  "required_approvals": 2,
  "items": [
    {
      "slug": "trading-monero",
      "pull_request": "https://github.com/bisq-network/documentation/pull/145",
      "summary": "Correct the XMR auto-confirm defaults and the check_tx_key placeholder syntax for Bisq 1 v1.10.11.",
      "author": "pr-author-login",
      "based_on_file_sha256": "2e4a5fa1b052033a2eccddb27433ad539a8be6936a3ba4905498216fce5ea0da",
      "accepted_file_sha256": "c06af3744dd5c97b59e3bc970f7d78954192a2c670a95f888c32686ff58fd9f9",
      "accepted_on": "2026-11-10",
      "approvals": [
        { "login": "maintainer-login-1", "role": "maintainer" },
        { "login": "reviewer-login-2", "role": "support agent" }
      ],
      "note_ids": ["xmr-auto-confirm-defaults"],
      "evidence": ["https://github.com/bisq-network/bisq/blob/ea9d5dff90c99ac462f2b0a7bf9ef92683956619/core/src/main/java/bisq/core/user/AutoConfirmSettings.java#L49-L65"],
      "changed_image_alt_text": [],
      "changes": [
        { "line": 32, "column": 109, "original": "&lt;TXKEY ADDRESS&gt;", "accepted": "&lt;TXKEY&gt; &lt;ADDRESS&gt;" },
        { "line": 50, "column": 4, "original": "By default auto-confirming trades is turned on in the Bisq app, if you wist to turn if off it can be done in Settings &gt; Preferences:", "accepted": "In Bisq 1 v1.10.11, XMR auto-confirmation is disabled by default. Check or change your saved setting in Settings &gt; Preferences; an existing installation may retain different preferences." },
        { "line": 71, "column": 59, "original": "(default: 1", "accepted": "(Bisq 1 v1.10.11 default: 0.125" }
      ]
    }
  ]
}

(This is the receipt from the proof below. The logins are placeholders.)

  • based_on_file_sha256 is the exact file the PR changed. For a first edit, that is the restored baseline: the restored original with its recorded line-break formatting, if the article has a formatting record. For a later edit, it is the previous receipt's accepted_file_sha256, so edits to the same article form a chain in file order.
  • changes records the exact text that was replaced. The gate puts that text back and requires the result to be the base byte for byte. So the preserved original can still be rebuilt from the current checkout, without git history, and every existing restoration check keeps running on it; reviewers can read the before and after wording in the receipt; and a receipt that misstates what changed fails.
  • pull_request must be a pull request of this repository (hiciefte/bisq-docs, or bisq-network/documentation after the move). accepted_on must be a real date. The summary is shown on the article and may not call the change verified, official, approved, endorsed, certified or guaranteed.
  • Each approval is login and role. Logins are plain text; @ is rejected. The login recorded as author can't count, and the same login can't be counted twice. note_ids must exist in migration/source-review-notes.json for that article. evidence contains https links.
  • Line and column are 1-based and point into the accepted file. Columns are counted in JavaScript string units, as in source-formatting.json.

What the gate accepts

An accepted edit may change article wording inside the article body. Compared with the base file, the only markup it may add or remove is plain lowercase a, strong, em, b, i, code, br, p, ul, ol and li, with new IDs allowed and links only to http(s), relative or same-page targets; empty spans that only carry an ID (a moved anchor) are also allowed. It may not:

  • change front matter, title, slug, the contents list or anything else outside the article body;
  • change the article container;
  • change any heading's level, ID or text (the contents list outside the body repeats heading text);
  • remove an existing ID or move a recorded legacy anchor away from its heading, because section URLs and saved links depend on them;
  • add, remove or resize a figure or image, or point it at a different asset. Alt text may change only for figures listed in changed_image_alt_text;
  • add or remove any other markup: other elements (div, span with content, style, script, iframe, svg, s, pre, tables, "section not recovered" markers), attributes such as hidden, style or on…, or any capitalised tag;
  • add or remove an HTML comment, or a blank line (which ends the article's HTML block and would start Markdown);
  • drop or reorder the last-resort-restore safeguards, or change the 60 characters around any of them.

It also fails when:

  • the file changes after the receipt, even by one byte;
  • the receipt's base is not the current article;
  • the recorded changes don't rebuild the base;
  • a receipt exists for an article that is unchanged;
  • there are fewer approvals than required_approvals;
  • the pull request URL, date or summary breaks the rules above.

What a receipt can still carry, because it is a wording change a human approved: reordered list items, shortened or removed sentences, a link pointed somewhere else. Reviewers see each of these in the receipt's before and after text.

Check Does a receipt change it? Why
Fidelity gate: article file, body, title, anchors, image count Yes, by rebuilding the original from the receipt, running the unchanged checks on it, then comparing the edited file with it This is the only place that pins article bytes
Fidelity gate: public/wiki-source/ raw wikitext and metadata No Immutable sources; the "Original wikitext" link on each page keeps showing the original
Fidelity gate: AI-edited snapshot, manifest records, baseline hash receipts No Not article content
Last-resort-restore safeguards No; now checked on the edited text too, with their surrounding words Safety-critical procedure
Additional articles (additional-articles.mjs, output_sha256) No The 3 additional historical articles are outside this proposal; receipts accept only the 209 restored slugs
check-template-renderings.mjs No Counts unresolved template markers in the article; a wording edit must keep them
check-section-repairs.mjs / renderSectionRepairs No Reviewed repairs expect their link-gap markup and target IDs (see #141 and #170 below)
check-scoped-link-repairs.mjs, check-recovered-category.mjs No They read wikitext and the category page only
check-site.mjs ("source hashes") No It hashes wikitext, images and templates in dist/, not article files; links, fragments and image placement still have to pass
migration/articles.json output_sha256 (originals) Not checked anywhere today Left as the migration-time record
review/proposal-coverage.json restored_sha256 Not checked anywhere today Record of what reviewers read; left unchanged

Visible signal

An edited article must not look like the original. The change is plain wording, with no "verified" or "official" badge:

  • Title area: "Original wiki wording" becomes "Edited after restoration: PR Correct XMR defaults and proof-command syntax #145", linking to the PR.
  • Source and history: the opening sentence says some wording was changed after restoration in the pull request listed below, and that the original wikitext keeps the earlier wording. A new entry, "Edited after restoration", lists date · summary · PR #145 for each accepted edit.
  • Articles without receipts render exactly as before.
  • review.md says article wording is preserved unless an article names an accepted edit.

Approval rule: options for maintainers

required_approvals sets how many distinct approvals each receipt needs. The gate runs offline and counts what the receipt records; it cannot confirm reviews on GitHub. Anyone can type two logins into a receipt, and a PR can also change required_approvals or an earlier receipt. Recorded approvals mean something only once branch protection on main requires the same reviews. Since 10 November 2026 a ruleset on main requires pull requests, signed commits and the check status, with no required approvals, and hiciefte is the only collaborator with write access, so options B and C cannot be enforced through required reviews until more reviewers have write access.

  • A. One maintainer (required_approvals: 1). Fastest. One person can accept a change alone.
  • B. Two people, at least one of them a maintainer (2, the placeholder in this PR). The role mix is a review convention; the check does not enforce roles.
  • C. As B, plus subject review: for payment, dispute, recovery and wallet articles, one approval comes from someone who handles support in that area. CONTRIBUTING already asks for human review "especially for payments, recovery and dispute instructions".

Whichever you pick, before the first receipt merges: require the same number of approving reviews on main, include administrators, dismiss stale approvals when new commits are pushed (so approvals cover the receipt commit), make the check workflow required, and add a CODEOWNERS entry for migration/accepted-edits.json with "require review from code owners". A later CI step could compare the recorded logins and author with the pull request's actual approving reviews and author through the GitHub API; that needs a token and network access, so it is not part of the offline gate and not included here.

Proof

Recorded at the first version of this branch (ad7960a), in a scratch worktree with PR #145's article diff applied (git diff origin/main...origin/pr/46 -- src/content/docs/wiki/). Review re-ran the node-only steps and got the same hashes and messages; the later commits do not change these messages. The page count comes from the earlier environment; this one builds 601 pages from main. Outputs are trimmed to the relevant lines.

$ node scripts/check-source-fidelity.mjs                       # PR #145 applied, no receipt
Source fidelity FAILED (1 finding):
- src/content/docs/wiki/trading-monero.md: Trading Monero changed since restoration (sha256 c06af3744dd5…, restored 2e4a5fa1b052…) and no receipt in migration/accepted-edits.json covers it. A wording change needs human approval and a receipt (see CONTRIBUTING.md); do not refresh the original hashes.
[exit 1]

$ node scripts/record-accepted-edit.mjs trading-monero --pr https://github.com/bisq-network/documentation/pull/145 --author pr-author-login --base HEAD
{ …the receipt shown above, with empty approvals, notes and evidence… }
# filled in summary, two placeholder approvals, note xmr-auto-confirm-defaults, one evidence link

$ DOCS_SITE=https://hiciefte.github.io DOCS_BASE=/bisq-docs/ npm run build
Source fidelity passed: 209 original bodies/titles/raw sources (1 article with 1 accepted edit; originals rebuilt exactly), 1407 explicit anchor additions, 130 image occurrences/120 assets, 98 AI guides (106 snapshot files), 14 recovery safeguards, ordered 27-file list and 8-step order.
[build] Complete!
Checked 609 HTML pages, 212 searchable original articles, 212 source records, 375 compatibility routes, 120 unchanged images, source hashes, links and fragments.
[exit 0]

$ sed -i 's/default: 0.125 BTC/default: 0.126 BTC/' src/content/docs/wiki/trading-monero.md   # one more character
Source fidelity FAILED (1 finding):
- src/content/docs/wiki/trading-monero.md: file changed after its accepted edit: it is sha256 f22ea2a6b444…, but PR #145 accepted c06af3744dd5…. A further change needs its own reviewed receipt.

# reverted that character; receipt based on the pre-formatting original hash (a realistic mistake)
- src/content/docs/wiki/trading-monero.md: PR #145 receipt is based on sha256 b989e40891a9…, but the restored baseline of this article (original plus recorded line-break formatting) is 2e4a5fa1b052…; record the receipt against the current article

# correct base, one approval removed
- migration/accepted-edits.json: receipt 1 (trading-monero, PR #145): 1 recorded approval; required_approvals is 2

# heading id "settings" renamed and a fresh receipt recorded for it
- src/content/docs/wiki/trading-monero.md: PR #145 changes heading 8 (<h3 id="settings"> Settings </h3> became <h3 id="preferences"> Settings </h3>); heading level, id and text must stay as restored

On this branch as committed (empty items):

  • npm test: 52 tests, 52 pass (15 new).
  • DOCS_SITE=https://hiciefte.github.io DOCS_BASE=/bisq-docs/ npm run build: passes (601 pages). The fidelity line is the one main prints, since there are no accepted edits.
  • node scripts/check-source-fidelity.mjs --self-test: the nine existing negative checks still pass.

The 15 new tests cover an approved receipt passing with the original rebuilt; an edit without a receipt; a change after the receipt; a wrong base and recorded text that does not match; too few approvals, self-approval, @ in a login and required_approvals 0; heading, legacy anchor and code ID changes; image alt text with and without a record, an unused record and a resized image; front matter or title changes; chained and misordered receipts; a receipt for an unchanged article; recovery safeguards and the words around them; markup that adds, hides or runs content (<IMG>, hidden spans, <style>, <script>, a style attribute, a javascript: link, <s>, a comment, a blank line), with plain inline markup still passing; the pull request URL, date and summary rules; and describeEdit output.

Changes after review

Review tried to get changes past the gate. Every change without a matching receipt failed, and undoing a receipt rebuilt the original byte for byte against the committed hashes, not the receipt's own. Fixed in this PR (commits after ad7960a):

  • The structure checks matched lowercase patterns only. A receipted edit could add <IMG SRC=…>, <H2>, <svg>, <iframe>, <script> or <style>, wrap sections in <div hidden>, start Markdown after a blank line, or, in Last resort restore, hide the procedure, strike through a safeguard or put "Do not" before an intact one. Added the markup rule and the safeguard-context check above.
  • pull_request accepted any repository's PR; accepted_on accepted 2026-02-31; the summary could say "Verified by Bisq support". Now rejected.
  • The label said "reviewed pull request" and "keeps … step order", which the gate cannot check; reworded. review.md no longer says all wording is preserved.
  • CONTRIBUTING.md and this description now state that recorded approvals are self-declared and need branch protection.

What this would mean for the 74 open PRs

Survey at this branch's head: each PR's article diff applied to a scratch copy, a receipt generated with record-accepted-edit.mjs and placeholder approvals, then the gate run.

Open questions for maintainers

  1. Approval rule: A, B or C, and whether the check should also enforce roles (an allowed_roles list would be a small addition).
  2. Enforcement: branch protection with required reviews including administrators, stale-approval dismissal, a required check, and CODEOWNERS for migration/accepted-edits.json; and whether to add the CI cross-check of recorded approvals against GitHub reviews.
  3. Heading text: this blocks heading text changes (the contents list sits outside the article body). Should a later version allow them, with the matching contents-list change?
  4. Images: only alt text can change. Should replacing or removing a recovered image stay out of scope, or get its own media policy?
  5. Code blocks, tables and recovery markers: the markup rule blocks them (Require a valid signature without assigning ultimate trust #122, Restore the Committee anchor in Project management #141, Clarify when the delayed payout is published #170). Keep that, or allow specific cases?
  6. The 3 additional historical articles: they keep their own strict output_sha256 check. Should they get receipts too?
  7. Evidence: should a receipt require at least one evidence link or note ID? It is optional now, so pure typo fixes are possible.
  8. Showing the original wording: should the page show the original wording inline? The receipts contain it, but this PR only adds the label and the PR link and keeps the original wikitext link.

Every editorial PR fails the fidelity gate by design, and nothing lets
an approved one merge. A receipt in migration/accepted-edits.json now
records one PR's change to one article, including the exact text it
replaced. The gate puts that text back, requires the exact restored
original, runs all original checks on it, and then allows only wording
changes: anchors, headings, images and front matter must stay. The
number of required approvals is one value in the receipts file.

An edited article without a receipt now gives one finding naming the
article and the reason, instead of hash noise and a wrong image total.
The CLI block is only re-indented (see git diff -w).
An accepted edit must not hide that the wording differs from the
recovered wiki. Edited articles replace "Original wiki wording" with
"Edited after restoration" and a PR link, and Source and history lists
each accepted change. Unedited articles render as before.
Contributors need the steps to add a receipt once reviewers approve
the wording, and maintainers need to choose the approval rule. List the
options instead of deciding it here.
…eguards

The structure checks matched lowercase patterns only, so a receipted edit
could add <IMG>, <span hidden>, <style>, <script>, an HTML comment or a
blank line that ends the HTML block and starts Markdown. Compare the
edited body with its base tag by tag: added or removed markup must be
plain a, strong, em, b, i, code, br, p, ul, ol or li, with new IDs and
http(s), relative or same-page links only. The blank-line and comment
counts must stay as restored.

In Last resort restore, the 60 characters around each recovery safeguard
must also stay unchanged, so "Do not" or "(not reversible)" cannot be
added next to an intact phrase.

A receipt must name a pull request of this repository, a real calendar
date and a summary that does not call the change verified, official or
approved.
The gate cannot confirm that a pull request was reviewed, and an accepted
edit may change list items, so an edited article no longer says
"reviewed pull request" or "step order". The review page says article
wording is preserved unless the article names an accepted edit.
A survey of the 74 open proposals with the new markup rule found two
harmless cases it rejected: an empty <span> that only keeps an ID alive,
and removing an <a> without href. Allow both. The proposals that still
fail change code blocks (bisq-network#23) or remove "section not recovered" markers
(bisq-network#42, bisq-network#71), which need their own decision.
The gate counts the approvals a receipt records and cannot check them,
so say plainly that branch protection must require the same reviews
before the first receipt merges, including for administrators and with
a required check and code owners for the receipts file. Describe the new
markup and safeguard rules.
@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 55 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a1de589c-c86f-48de-ad20-5d9e30264d15
Commits

Reviewing files that changed from the base of the PR and between 6752015 and 0c90d00.

Files selected for processing: 11

  • CONTRIBUTING.md
  • migration/accepted-edits.json
  • package.json
  • scripts/accepted-edits.test.mjs
  • scripts/check-source-fidelity.mjs
  • scripts/lib/accepted-edits.mjs
  • scripts/record-accepted-edit.mjs
  • src/components/PageTitle.astro
  • src/components/SourceHistory.astro
  • src/content/docs/review.md
  • src/styles/custom.css
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Resolve package.json by keeping the tests from both sides, and review.md by keeping the new repository link with the accepted-edit sentences.
@hiciefte
hiciefte merged commit 02a05cc into bisq-network:main Nov 10, 2026
2 checks passed
hiciefte added a commit to hiciefte/documentation that referenced this pull request Nov 10, 2026
Resolves two conflicts with the accepted-edit receipts (bisq-network#96):
- CONTRIBUTING.md: keeps this branch's sentence about additional articles
  and the new Accepted editorial changes section from main.
- scripts/check-source-fidelity.mjs: imports both additionalArticles and
  the accepted-edits helpers.

With the article at its formatting-only commit (745df9b), npm test (68)
and npm run build pass, so the remaining check failure is only the
unreceipted wording change this PR proposes.
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