def patch(path, old, new, label):
    b = open(path, 'rb').read()
    o, n = old.replace('\n', '\r\n').encode(), new.replace('\n', '\r\n').encode()
    assert b.count(o) == 1, (label, b.count(o))
    open(path, 'wb').write(b.replace(o, n))
    print('patched', label)


# FORK - prose, in the section already tagged [doc->REQ-FORK-CONTROL-SURFACE].
patch(
    'docs-site/src/instances/overview.md',
    '''A fork that happened is reported as `FORKED:` and names the node that made it.
A request that goes unanswered is reported as `FORK_UNCONFIRMED:` — never as
forked:
a node too old to know the verb and a node that declined to admit you are
indistinguishable from the calling side, and calling either one done would be a
fork someone believes they have.
''',
    '''A fork that happened is reported as `FORKED:` and names the node that made it.
A request that goes unanswered is reported as `FORK_UNCONFIRMED:` — never as
forked:
a node too old to know the verb and a node that declined to admit you are
indistinguishable from the calling side, and calling either one done would be a
fork someone believes they have.

A node that *accepts* the request and then answers nothing is a third thing, and
it says so: `FORK_PEER_SILENT:`. The two silences are not the same fact. An
unanswered request came back from a stream the far side finished — an old or
refusing node, and the remedy is at that node's version or its admissions. A
silent one is still holding the stream open, which points at a node that is
wedged or overloaded, and there is nothing to upgrade. Neither is a fork.
<!-- [doc->REQ-WAN-REPLY-BOUND] -->
''',
    'fork sentence')

# REDEEM - the published "What you can be told" closed set.
patch(
    'docs-site/src/networking/knocking.md',
    '''| **unconfirmed** | **no answer came back at all** |
''',
    '''| **unconfirmed** | **no answer came back at all** |
| **peer silent** | **the machine took the redemption and then said nothing** — it is still holding the exchange open, which points at a machine that is wedged or overloaded rather than one too old to understand redemptions. Nothing was decided and **the code was not spent** <!-- [doc->REQ-WAN-REPLY-BOUND] --> |
''',
    'redeem row')

# The paragraph under the table generalises the third row; it now covers a fourth
# without saying anything that stops being true.
patch(
    'docs-site/src/networking/knocking.md',
    '''The third row is the one to remember: **silence is not a refusal.** The minting
machine may be off, unreachable, or running a version old enough that it does
not understand redemptions, and an answer can simply be lost. Nothing was
decided about your code and **it was not spent**, so it is still worth
presenting again. A presenter told "refused" here would throw away a good code
that was never even seen.
''',
    '''The last two rows are the ones to remember: **silence is not a refusal.** The
minting machine may be off, unreachable, running a version old enough that it
does not understand redemptions, or wedged mid-exchange, and an answer can
simply be lost. Nothing was decided about your code and **it was not spent**, so
it is still worth presenting again. A presenter told "refused" here would throw
away a good code that was never even seen.
''',
    'redeem paragraph')
