import sys
root = r'C:\Users\decid\Documents\projects\spt-core\.worktrees\w6-divulge' + '\\'

def patch(rel, pairs):
    p = root + rel
    b = open(p, 'rb').read()
    crlf = b'\r\n' in b
    s = b.decode().replace('\r\n', '\n')
    for a, n in pairs:
        c = s.count(a)
        if c != 1:
            sys.exit(f'{rel}: {c} hits for {a!r}')
        s = s.replace(a, n)
    if crlf:
        s = s.replace('\n', '\r\n')
    open(p, 'wb').write(s.encode())

patch('docs-site/src/shells/frames.md', [(
'''unreadable contributes nothing rather than an error line. This rides a
turn-boundary hook, where a diagnostic you cannot act on is just noise.
''',
'''unreadable contributes nothing rather than an error line. This rides a
turn-boundary hook, where a diagnostic you cannot act on is just noise.

<!-- [doc->REQ-NOW-SIGNAL-UPDATE-DIVULGE] the moved-subject row: its shape, where old/when come from, the degrade arms, and the no-new-surface ruling -->
**A subject that moved is told as a move** *(since v0.73.0)*. When the version
you are told is one an update just landed, the row reads

```text
UPDATED <subject> <old> → <new> at <HH:MMAM|PM YYYY-MM-DD> — changelog: <url>
```

for example `UPDATED spt-core 0.72.0 → 0.73.0 at 09:58AM 2026-09-24 —
changelog: http://localhost:5474/<node>/docs/changelog.html`. The time is your
node's local clock. spt-core links its node-served changelog (or the release
page when the node's docs are not being served); an adapter links its
`/<node>/a/<adapter>/changelog` page **only** when its manifest declares
`[adapter].changelog` — with no declaration the row ends after the time. An
adapter's post-update notice (its `[update].message`, or what its
`[update.post]` step printed) follows on the same line.

The old version and the time come from an **apply record** that every path
that can apply an update writes — `spt update apply` (and `--finish`), the
daemon's promotion of a swapped core, and every adapter update, including the
bundled adapters a release lands — so a subject moved by any of them reads the
same. The record never decides that something moved: the seen-set above is
still the only event detector, so a move is told once and never again. A
subject whose version did not move keeps its one-line shape exactly, and so
does a moved subject whose record is missing, unreadable, carries no old
version, or belongs to a different version (a rolled-back update). There is no
separate notification for an update — this row is the whole divulge.
'''
)])

patch('docs-site/src/self-update/overview.md', [(
'''naming the source asked first. It asks no peer and no channel.
''',
'''naming the source asked first. It asks no peer and no channel.

<!-- [doc->REQ-UPDATE-STATUS-TRUST-ANCHOR] -->
When `identity/release-keys.json` exists, it **overrides the release trust
anchor** compiled into spt — its keys join the built-in ones, its revocations
remove them, and its `channel` replaces `stable` — and `spt update status` says
so on its own line:

```text
trust anchor OVERRIDDEN (identity/release-keys.json, key dev-debug-2026, channel debug)
  to return to the built-in anchor, delete <SPT_HOME>/identity/release-keys.json
```

`key` lists every key id the file adds, comma-separated (`none` when it adds
none), followed by `revoked <ids>` when the file revokes any; `channel` is the
file's pin, or `stable` when it names none. A file that exists but does not
parse is reported too, as present but unreadable with the built-in anchor in
effect, since it still means someone meant to override. A healthy node has no such file,
and without one the verb prints nothing new. The line reports the override and
nothing more: the file carries no expiry, so none is shown (a release's own
expiry belongs to the signed release, not to the anchor). The verb only reads
the file — it never edits or removes it — and `--json` carries the same facts
under `trust_anchor_override`.
'''
)])
print('ok')
