patch-cc 0.4.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {patch_cc-0.4.0 → patch_cc-0.5.0}/AGENTS.md +12 -6
- {patch_cc-0.4.0 → patch_cc-0.5.0}/PKG-INFO +4 -4
- {patch_cc-0.4.0 → patch_cc-0.5.0}/README.md +3 -3
- {patch_cc-0.4.0 → patch_cc-0.5.0}/docs/INTERNALS.md +75 -13
- {patch_cc-0.4.0 → patch_cc-0.5.0}/docs/PLAYBOOK.md +82 -23
- {patch_cc-0.4.0 → patch_cc-0.5.0}/docs/corpus.md +17 -8
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/__init__.py +1 -1
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/bun/blob.py +228 -42
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/bun/container.py +73 -5
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/cli.py +33 -7
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/doctor.py +109 -2
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/js.py +43 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/menu.py +38 -4
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patcher.py +13 -7
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patches/base.py +14 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patches/chrome.py +33 -2
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patches/streaming.py +103 -92
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/ui.py +31 -5
- {patch_cc-0.4.0 → patch_cc-0.5.0}/.github/workflows/ci.yml +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/.github/workflows/release-watch.yml +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/.github/workflows/release.yml +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/.gitignore +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/CLAUDE.md +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/LICENSE +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/docs/CONDUCT.md +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/docs/demo.gif +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/pyproject.toml +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/bun/__init__.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/bun/elf.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/bun/errors.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/bun/macho.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/cache.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/codex/__init__.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/codex/gateway.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/codex/models.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/codex/oauth.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/codex/translate.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/locate.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patches/__init__.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patches/agents.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patches/codex.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patches/output.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/src/patch_cc/patches/thinking.py +0 -0
- {patch_cc-0.4.0 → patch_cc-0.5.0}/uv.lock +0 -0
|
@@ -17,9 +17,15 @@ point it at the pristine copies in `~/.local/share/patch-cc/backups/` to sweep
|
|
|
17
17
|
older builds). There is no test suite by design — doctor against real bundles
|
|
18
18
|
is the check.
|
|
19
19
|
|
|
20
|
-
Be exact about what that covers: doctor runs the **matchers
|
|
21
|
-
bundle they produce
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
Be exact about what that covers: doctor runs the **matchers**, parses the
|
|
21
|
+
bundle they produce, then **bakes it into a temp binary and executes
|
|
22
|
+
`--version`** — so the sweep also proves every build writes and boots (the
|
|
23
|
+
container layer included; 2.1.246 is why). It still never runs the gateway,
|
|
24
|
+
the translator, the OAuth flow or the menu, so a change under
|
|
25
|
+
`src/patch_cc/codex/` (the bridge — all of it runtime, none of it a patch; the
|
|
26
|
+
Codex *patch* is `patches/codex.py`, which the sweep does cover) or in
|
|
27
|
+
`menu.py` is checked by exercising it — a real `codex serve` against a real
|
|
28
|
+
turn — and a green sweep says nothing about it. Nor does `--version` exercise
|
|
29
|
+
a patch's *feature* at runtime: it proves the patched code loads and runs, not
|
|
30
|
+
that a streamed turn renders — behaviour changes still want a real turn
|
|
31
|
+
watched.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: patch-cc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Interactive patcher for the Claude Code native binary
|
|
5
5
|
Project-URL: Homepage, https://github.com/anfreire/patch-cc
|
|
6
6
|
Project-URL: Repository, https://github.com/anfreire/patch-cc
|
|
@@ -94,7 +94,7 @@ patch-cc # then just run it
|
|
|
94
94
|
| Chrome & branding | Disable spinner tips | No rotating tips on the spinner |
|
|
95
95
|
| | Mark `--version` | Appends `(patched)` — or any marker you choose |
|
|
96
96
|
| | Custom startup name | Defaults to `<your username>'s Code` |
|
|
97
|
-
| | Startup org/email label | Replace the org/email on the welcome screen — or hide it (demo mode keeps the stock line) |
|
|
97
|
+
| | Startup org/email label | Replace the org/email on the welcome screen — or hide it (demo mode keeps the stock line). Upstream stopped drawing the segment in 2.1.246, so newer builds offer this dimmed as *not on this build* |
|
|
98
98
|
|
|
99
99
|
## Usage
|
|
100
100
|
|
|
@@ -113,8 +113,8 @@ uvx patch-cc apply --org-label "Ada's Lab" # ...or show this instead
|
|
|
113
113
|
uvx patch-cc apply --codex gpt-5.6-sol # + a Codex model (see below)
|
|
114
114
|
uvx patch-cc apply --from-cache # replay your last remembered selection
|
|
115
115
|
uvx patch-cc status # exactly what is applied
|
|
116
|
-
uvx patch-cc doctor # do all patches match this build?
|
|
117
|
-
uvx patch-cc doctor path/to/claude # ...
|
|
116
|
+
uvx patch-cc doctor # do all patches match this build, and does it bake + boot?
|
|
117
|
+
uvx patch-cc doctor path/to/claude # ...same, for some other binary
|
|
118
118
|
uvx patch-cc list # every patch, described
|
|
119
119
|
uvx patch-cc restore # put the original back
|
|
120
120
|
```
|
|
@@ -63,7 +63,7 @@ patch-cc # then just run it
|
|
|
63
63
|
| Chrome & branding | Disable spinner tips | No rotating tips on the spinner |
|
|
64
64
|
| | Mark `--version` | Appends `(patched)` — or any marker you choose |
|
|
65
65
|
| | Custom startup name | Defaults to `<your username>'s Code` |
|
|
66
|
-
| | Startup org/email label | Replace the org/email on the welcome screen — or hide it (demo mode keeps the stock line) |
|
|
66
|
+
| | Startup org/email label | Replace the org/email on the welcome screen — or hide it (demo mode keeps the stock line). Upstream stopped drawing the segment in 2.1.246, so newer builds offer this dimmed as *not on this build* |
|
|
67
67
|
|
|
68
68
|
## Usage
|
|
69
69
|
|
|
@@ -82,8 +82,8 @@ uvx patch-cc apply --org-label "Ada's Lab" # ...or show this instead
|
|
|
82
82
|
uvx patch-cc apply --codex gpt-5.6-sol # + a Codex model (see below)
|
|
83
83
|
uvx patch-cc apply --from-cache # replay your last remembered selection
|
|
84
84
|
uvx patch-cc status # exactly what is applied
|
|
85
|
-
uvx patch-cc doctor # do all patches match this build?
|
|
86
|
-
uvx patch-cc doctor path/to/claude # ...
|
|
85
|
+
uvx patch-cc doctor # do all patches match this build, and does it bake + boot?
|
|
86
|
+
uvx patch-cc doctor path/to/claude # ...same, for some other binary
|
|
87
87
|
uvx patch-cc list # every patch, described
|
|
88
88
|
uvx patch-cc restore # put the original back
|
|
89
89
|
```
|
|
@@ -23,17 +23,33 @@ treats every module the container declares to be JavaScript as one surface.
|
|
|
23
23
|
.bun section
|
|
24
24
|
└── [u64 size prefix] (u32 on Bun < 1.3.4)
|
|
25
25
|
└── Bun blob
|
|
26
|
-
├── payload arena name / contents / sourcemap / bytecode / ... bytes
|
|
26
|
+
├── payload arena name / contents / sourcemap / bytecode / ... bytes,
|
|
27
|
+
│ plus the record chain's own payloads (Bun >= 1.4.1)
|
|
27
28
|
├── module table N records × 52 bytes (36 on old Bun)
|
|
29
|
+
├── record chain flag-gated records (Bun >= 1.4.1), see below
|
|
28
30
|
├── compileExecArgv
|
|
29
31
|
├── offsets struct 32 bytes: byteCount, modulesPtr, entryId, argvPtr, flags
|
|
30
32
|
└── "\n---- Bun! ----\n" 15-byte trailer
|
|
31
33
|
```
|
|
32
34
|
|
|
33
35
|
Every pointer is a `(u32 offset, u32 length)` pair relative to the blob start,
|
|
34
|
-
and pointers live in
|
|
35
|
-
That is what makes rewriting tractable — move a
|
|
36
|
-
pointers that describe it.
|
|
36
|
+
and pointers live in exactly three places: the module table, the offsets
|
|
37
|
+
struct, and the record chain. That is what makes rewriting tractable — move a
|
|
38
|
+
payload, fix the handful of pointers that describe it.
|
|
39
|
+
|
|
40
|
+
Two invariants ride on payload *positions* rather than pointers, and `rebuild`
|
|
41
|
+
preserves both by keeping every payload's inter-payload gap and its offset
|
|
42
|
+
phase modulo 128 — so a rebuild with no edits reproduces the blob byte for
|
|
43
|
+
byte, and one with edits moves payloads only in whole alignment steps:
|
|
44
|
+
|
|
45
|
+
- Bytecode payloads (module bytecode, and the record chain's bytecode blobs)
|
|
46
|
+
sit at blob `offset % 128 == 120`, which is 128-byte alignment once the
|
|
47
|
+
section's 8-byte size prefix is in front. Bun ≥ 1.4.1 deserializes bytecode
|
|
48
|
+
in place and calls misalignment "a runtime assertion error or segfault"
|
|
49
|
+
(`append_bytecode_aligned`); older Bun quietly tolerated the phase drift the
|
|
50
|
+
rewriter used to introduce.
|
|
51
|
+
- `count_z` payloads (names, contents) carry a NUL terminator in the gap
|
|
52
|
+
after them.
|
|
37
53
|
|
|
38
54
|
A module record (new 52-byte format) is six such pairs — `name`, `contents`,
|
|
39
55
|
`sourcemap`, `bytecode`, `moduleInfo`, `bytecodeOriginPath` — followed by four
|
|
@@ -41,6 +57,42 @@ A module record (new 52-byte format) is six such pairs — `name`, `contents`,
|
|
|
41
57
|
|
|
42
58
|
Code: `src/patch_cc/bun/blob.py`.
|
|
43
59
|
|
|
60
|
+
## The record chain (Bun ≥ 1.4.1)
|
|
61
|
+
|
|
62
|
+
2.1.246 moved to Bun 1.4.1, whose `StandaloneModuleGraph.rs` chains optional
|
|
63
|
+
records directly after the module table, each announced by a new `flags` bit
|
|
64
|
+
and read back in flag order:
|
|
65
|
+
|
|
66
|
+
| bit | record |
|
|
67
|
+
|---|---|
|
|
68
|
+
| 5 | `[u32; modules]` — each module's WTF hash of its source text (0 = none) |
|
|
69
|
+
| 6 | `u32 count`, then `count` × `{u32 id, ptr}` — internal-module bytecode |
|
|
70
|
+
| 7 | one pointer: the **shared bytecode string table** |
|
|
71
|
+
| 8 | `u32` — how many leading modules load before the first `import()` |
|
|
72
|
+
| 9 | one pointer: the string table `moduleInfo` bodies index |
|
|
73
|
+
|
|
74
|
+
The pointers point back into the arena: the shared string table (~9.9 MB on
|
|
75
|
+
2.1.246) is the string data **every chunk's bytecode references by ordinal**,
|
|
76
|
+
so it is load-bearing for every module we did *not* touch. The hash is JSC's
|
|
77
|
+
SourceCodeKey hash, how a launch that runs from bytecode avoids paging in
|
|
78
|
+
source text just to hash it.
|
|
79
|
+
|
|
80
|
+
patch-cc parses the chain record for record (`_parse_records` — a build with
|
|
81
|
+
none of the bits, which is every Bun before 1.4.1, walks zero records through
|
|
82
|
+
the same code), carries the pointed-at payloads through `rebuild` like any
|
|
83
|
+
module payload, copies the whole tail between table and offsets struct
|
|
84
|
+
verbatim, and re-points the pointers in place. Two details matter:
|
|
85
|
+
|
|
86
|
+
- An **edited** module's hash word is zeroed — upstream's own "none, compute
|
|
87
|
+
it" value — because the pristine text's hash must not key our bytes in JSC's
|
|
88
|
+
source cache.
|
|
89
|
+
- **Unknown** record bits are refused at parse: a record of unknown size
|
|
90
|
+
cannot be walked past nor re-pointed, and rewriting around it is exactly how
|
|
91
|
+
a graph gets corrupted. 2.1.246 against patch-cc ≤ 0.4.0 is the lesson: the
|
|
92
|
+
chain-blind rewriter dropped the records and zero-filled the string table
|
|
93
|
+
while every *module* round-tripped byte-perfect — matcher-green, dead at
|
|
94
|
+
launch, `SIGSEGV` from inside Bun's graph loader.
|
|
95
|
+
|
|
44
96
|
## The 2.1.242 split, and the patchable surface
|
|
45
97
|
|
|
46
98
|
Through 2.1.241 the entrypoint module *was* the app: one ~28 MB `contents`
|
|
@@ -86,9 +138,11 @@ detects the mismatch and recompiles that module from source at launch. So keepin
|
|
|
86
138
|
a stale copy buys nothing — the recompile is paid either way — and dropping it
|
|
87
139
|
reclaims the space and guarantees our edits are what runs. patch-cc drops the
|
|
88
140
|
bytecode of exactly the modules it edited (`rebuild` over `changed_modules`) and
|
|
89
|
-
leaves every untouched module its bytecode and its fast start
|
|
90
|
-
the
|
|
91
|
-
|
|
141
|
+
leaves every untouched module its bytecode and its fast start — which is why
|
|
142
|
+
the shared bytecode string table those modules' bytecode indexes
|
|
143
|
+
([the record chain](#the-record-chain-bun--141)) is never droppable. On Linux,
|
|
144
|
+
where the ELF section is rewritten in place, the binary is smaller by exactly
|
|
145
|
+
the edited modules' bytecode.
|
|
92
146
|
|
|
93
147
|
Measured on 2.1.243, the full patch set:
|
|
94
148
|
|
|
@@ -114,10 +168,12 @@ re-laying `__LINKEDIT`, which is not done yet.
|
|
|
114
168
|
|
|
115
169
|
Every write asserts each **edited** module carries `bytecode == 0` in the binary
|
|
116
170
|
it produced (`container.verify`, beside the round-trip check), and `patch-cc
|
|
117
|
-
status` reports the total for an installed one. `doctor`
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
171
|
+
status` reports the total for an installed one. `doctor`'s dry run cannot — a
|
|
172
|
+
clean bundle still has all its bytecode by definition — but its smoke bake
|
|
173
|
+
writes a temp binary through the same `container.write` and then *executes* it,
|
|
174
|
+
so the sweep exercises the assert, and the loader itself, on every corpus
|
|
175
|
+
build. If a future Bun build makes bytecode authoritative over source, that
|
|
176
|
+
assert is the tripwire — every edit would silently no-op otherwise.
|
|
121
177
|
|
|
122
178
|
## Writing it back without ballooning
|
|
123
179
|
|
|
@@ -196,8 +252,14 @@ rather than from a store of their own.
|
|
|
196
252
|
and dropped rather than aborting the run. See
|
|
197
253
|
[PLAYBOOK.md](PLAYBOOK.md#the-syntax-gate).
|
|
198
254
|
- Every write is verified: patch-cc re-extracts the JS from the binary it just
|
|
199
|
-
wrote and asserts every module equals what it meant to write,
|
|
200
|
-
module it edited carries no leftover bytecode to run instead of the edit
|
|
255
|
+
wrote and asserts every module equals what it meant to write, that each
|
|
256
|
+
module it edited carries no leftover bytecode to run instead of the edit, and
|
|
257
|
+
that the graph around the modules survived — the record chain kept its
|
|
258
|
+
length and flags, its arena payloads (the shared bytecode string table above
|
|
259
|
+
all) round-trip byte-identical, and every source-hash word is the pristine
|
|
260
|
+
one, except an edited module's, which must be zero. The chain checks exist
|
|
261
|
+
because 2.1.246 failed *only* there: every module compared equal while the
|
|
262
|
+
written binary was dead.
|
|
201
263
|
- Patching a binary that is already marked, when no pristine backup exists, is
|
|
202
264
|
refused outright — there is nothing clean to start from, and our edits change
|
|
203
265
|
lengths, so a second pass would corrupt rather than update. `restore` or a
|
|
@@ -309,6 +309,20 @@ isolation was cheaper and could not see the one ordering this project calls
|
|
|
309
309
|
load-bearing — `codex-models` registering the ids `subagent-models` then pins —
|
|
310
310
|
nor anything at all about the bundle the run produced, which it discarded.
|
|
311
311
|
|
|
312
|
+
The composed result is then **baked and executed**: doctor writes it into a
|
|
313
|
+
temp binary through the same `container.write` as a real apply — staging,
|
|
314
|
+
round-trip verification, the container checks — and runs `<binary> --version`,
|
|
315
|
+
expecting the version-marker suffix in the output (our own edit's print, so the
|
|
316
|
+
check proves patched code *executes*, not merely that the binary boots around
|
|
317
|
+
it). Matching and running are different truths with different failure owners:
|
|
318
|
+
matchers break in the patches, the run breaks in the container layer, and
|
|
319
|
+
2.1.246 is the build where they split — every matcher green, every module
|
|
320
|
+
round-tripping byte-perfect, and the written binary `SIGSEGV`ing in Bun's graph
|
|
321
|
+
loader because what the rewrite had destroyed (the Bun 1.4.1 record chain and
|
|
322
|
+
the shared bytecode string table, docs/INTERNALS.md) lives in bytes no module
|
|
323
|
+
owns. The temp binary is always removed; the backup under test is never
|
|
324
|
+
written to.
|
|
325
|
+
|
|
312
326
|
Three readings of the two numbers, kept distinct:
|
|
313
327
|
|
|
314
328
|
| symptom | meaning |
|
|
@@ -608,6 +622,12 @@ that broke a patch along with every note.
|
|
|
608
622
|
enumerated with its hashes in [corpus.md](corpus.md) — so both sides are
|
|
609
623
|
recomputed from the binaries themselves.
|
|
610
624
|
|
|
625
|
+
Each build's report ends with its baked binary's own `--version` output (the
|
|
626
|
+
smoke run above), so the sweep also proves every corpus build still *bakes
|
|
627
|
+
and boots* — the half matcher counts cannot see, and the half 2.1.246 broke
|
|
628
|
+
while every count held. A moved runtime line is as much a finding as a moved
|
|
629
|
+
count.
|
|
630
|
+
|
|
611
631
|
## Patch reference
|
|
612
632
|
|
|
613
633
|
Grouped by source module. The menu's three groups (Output & display, Models &
|
|
@@ -848,28 +868,37 @@ for you. Each entry: what it changes, the stable anchor, and where it lives.
|
|
|
848
868
|
*initialised* to is deliberately not asked: `useState(null)` is every
|
|
849
869
|
build's spelling and `useState(void 0)` would be the same state, while the
|
|
850
870
|
setter is the identity that matters.
|
|
851
|
-
- **The state has two homes, and the
|
|
852
|
-
2.1.235 the scope that hands `onStreamingThinking` declared the
|
|
853
|
-
itself, and the state is the array pattern binding the handed setter
|
|
854
|
-
`useState`'s pair. 2.1.236 moved it into an
|
|
855
|
-
(`subscribe`/`getSnapshot`/`_publish` — the
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
871
|
+
- **The state has two homes, and each is proven by the only name it has.**
|
|
872
|
+
Through 2.1.235 the scope that hands `onStreamingThinking` declared the
|
|
873
|
+
state itself, and the state is the array pattern binding the handed setter
|
|
874
|
+
— `useState`'s pair, which nothing else names. 2.1.236 moved it into an
|
|
875
|
+
external stream store (`subscribe`/`getSnapshot`/`_publish` — the
|
|
876
|
+
`useSyncExternalStore` shape) that a component reads back by destructuring
|
|
877
|
+
a hook call (`{streamingToolUses:…}=useX(<store>)`), so the state is that
|
|
878
|
+
pattern's own `streamingThinking` binding — upstream's the day it takes
|
|
879
|
+
one, the goal achieved, and until then ours, inserted at the front of the
|
|
880
|
+
pattern. The pattern names *itself*: it binds the store's own
|
|
881
|
+
`streamingToolUses` field — the name the store publishes and the
|
|
882
|
+
transcript signature already rests on — and that membership is its whole
|
|
883
|
+
identity, provided its value is a call taking exactly one argument, one
|
|
884
|
+
answer or none (`js.only`). It was once proven by the handing instead —
|
|
885
|
+
"the call's only argument is the very expression the setter was read off"
|
|
886
|
+
— and 2.1.246 moved the handing into the engine
|
|
887
|
+
(`this.stream.setStreamingThinking`), out of every component, without
|
|
888
|
+
moving the state: four renders that plainly draw the conversation read as
|
|
889
|
+
having none in scope, with `onStreamingThinking:` still twice in the
|
|
890
|
+
bundle. The handed setter was `agentDefinitions` again — a neighbour
|
|
891
|
+
standing in for the thing itself, one more fact upstream had to keep.
|
|
892
|
+
Sole argument stays deliberate — a second is a selector whose result is
|
|
893
|
+
no longer the snapshot, and extending a pattern of unknowable provenance
|
|
894
|
+
binds `undefined` with every count green. The insertion also pays for a
|
|
895
|
+
witness the way `thinking-summaries` does: the field it binds must still
|
|
896
|
+
be named by the bundle's own objects (the store's snapshot initialiser,
|
|
897
|
+
its publish call), so a store that renames the field reads as the step
|
|
898
|
+
reporting the store rather than threading `undefined`. Two things come
|
|
899
|
+
free with the store: its setter takes functional updaters — React's own
|
|
900
|
+
contract, which the reducer splices already speak — and it hides a
|
|
901
|
+
finished block itself after 30 s, upstream's own linger.
|
|
873
902
|
|
|
874
903
|
A render was once selected by *position* — the observation that the real sites
|
|
875
904
|
fall after the state's `useState` declaration. That is worth recording as a
|
|
@@ -922,7 +951,19 @@ for you. Each entry: what it changes, the stable anchor, and where it lives.
|
|
|
922
951
|
with no memo at all, and the rewrite reuses the memo's *own* callee rather than
|
|
923
952
|
re-spelling `.useMemo`. What a claim about the *text* around the block
|
|
924
953
|
(`.contentBlock]}`) only approximated is the computation itself: one sibling
|
|
925
|
-
property beside `content` read as the whole thing being gone.
|
|
954
|
+
property beside `content` read as the whole thing being gone. The wrapped
|
|
955
|
+
block is asked by membership among the element's *possible values*
|
|
956
|
+
(`js.values` — the same value routing the codex resolvers read), never asked
|
|
957
|
+
to be the read: 2.1.246 minted stable ids for streamed blocks
|
|
958
|
+
(`ce?{...S.contentBlock,id:V}:S.contentBlock`), and the exact-node question
|
|
959
|
+
read the same wrap one choice deeper as no wrap at all — nine required steps
|
|
960
|
+
to zero, every anchor count standing. The rewrite reuses upstream's callback
|
|
961
|
+
and dependencies verbatim — the callback invoked per entry with the same
|
|
962
|
+
three arguments `flatMap` hands it, each dependency spread rather than
|
|
963
|
+
transcribed — because a rebuilt copy is a copy free to shed whatever
|
|
964
|
+
upstream adds next: the re-spell this replaced would have silently dropped
|
|
965
|
+
the 2.1.246 minting, and with it went the uuid-stamp identity that re-spell
|
|
966
|
+
had to prove and the reuse no longer asks.
|
|
926
967
|
|
|
927
968
|
**`display-mode`** defaults the request's thinking display to `"summarized"`;
|
|
928
969
|
without it the API only streams summary text when the `showThinkingSummaries`
|
|
@@ -1313,6 +1354,24 @@ for you. Each entry: what it changes, the stable anchor, and where it lives.
|
|
|
1313
1354
|
touched: the `/status` Organization/Email rows, the login screen, and the
|
|
1314
1355
|
org's startup message (`"Message from <org>:"`) still show the real account.
|
|
1315
1356
|
|
|
1357
|
+
**2.1.246 retired the surface.** Upstream deleted the welcome-banner variant
|
|
1358
|
+
that composed the segment; the surviving banner draws `model · billing` with
|
|
1359
|
+
no org anywhere — the hidden state an empty `--org-label` asks for, now
|
|
1360
|
+
upstream's own default. That is a semantic change, not a matcher to repair
|
|
1361
|
+
(the `help-title` precedent), and it is *absence*, reported apart from broken
|
|
1362
|
+
(CONDUCT): the patch declares its surface (`Patch.absence`, answered by the
|
|
1363
|
+
same `_org_segments` its candidates count off, so the two cannot disagree),
|
|
1364
|
+
and every surface derives its answer from the bundle in hand — the menu shows
|
|
1365
|
+
the row dimmed (`not on this build`, unselectable), an explicit `--org-label`
|
|
1366
|
+
is refused at the front door with the same sentence, a cached replay skips it
|
|
1367
|
+
with a note, and `doctor` prints a `-` row apart from ✓/✗ and stays green.
|
|
1368
|
+
Nothing is keyed on a version, so a build that composes the segment again
|
|
1369
|
+
un-dims the row with no code change. What absence cannot tell apart is a
|
|
1370
|
+
composition respelled out of the locator's sight — that build would read as
|
|
1371
|
+
absent, visibly dimmed on a screen that still draws the segment — and the
|
|
1372
|
+
sweep over the corpus, where thirty-four builds carry the surface, is what
|
|
1373
|
+
keeps the locator honest.
|
|
1374
|
+
|
|
1316
1375
|
## Removed patches
|
|
1317
1376
|
|
|
1318
1377
|
Kept here so nobody reintroduces them without knowing why they left:
|
|
@@ -21,10 +21,11 @@ matches means the file changed under you, not that a number moved.
|
|
|
21
21
|
|
|
22
22
|
## On disk now
|
|
23
23
|
|
|
24
|
-
The whole published span `2.1.210` → `2.1.
|
|
25
|
-
one pristine binary per version,
|
|
26
|
-
split** (INTERNALS.md): `2.1.242`/`2.1.243` are the first
|
|
27
|
-
they jump ~35 MB over `2.1.241` for it. Several pairs
|
|
24
|
+
The whole published span `2.1.210` → `2.1.246` — 2.1.230 and 2.1.244 were never
|
|
25
|
+
published — one pristine binary per version, 35 in all. It straddles the
|
|
26
|
+
**2.1.242 code split** (INTERNALS.md): `2.1.242`/`2.1.243` are the first
|
|
27
|
+
many-module builds, and they jump ~35 MB over `2.1.241` for it. Several pairs
|
|
28
|
+
share a byte count
|
|
28
29
|
(`2.1.225`/`2.1.226`, `2.1.229`/`2.1.231`, `2.1.239`–`2.1.241`, `2.1.242`/`2.1.243`)
|
|
29
30
|
and are still distinct binaries, which is why the identity column is the hash (of
|
|
30
31
|
the whole file, `sha256sum <version>.orig`) and never the size:
|
|
@@ -64,10 +65,12 @@ the whole file, `sha256sum <version>.orig`) and never the size:
|
|
|
64
65
|
| `2.1.241` | 343 MB | `0771bd866cff82b76581fc0499f6529e1a36845078f144f8c81dccb3bc7037b8` |
|
|
65
66
|
| `2.1.242` | 378 MB | `528ef039aa7d64d7b3fbc06925132755a516b4dcaad784cf0b51fe03167360d4` |
|
|
66
67
|
| `2.1.243` | 378 MB | `4b0dafeedd0b469c41988e200036fd773e7553ba960349c9f02a82c6d1f2ba27` |
|
|
68
|
+
| `2.1.245` | 392 MB | `16ad2b94deaf7b29abed966d981c9991a47af0420f5be8ed4a3f83bea9f678bc` |
|
|
69
|
+
| `2.1.246` | 248 MB | `1a0a662dc1bb938eaec38545abce9a4a69113d7d7f7c5e1a553ea276617b906a` |
|
|
67
70
|
|
|
68
71
|
This set covers the span the playbook's tree-move measurements were taken over
|
|
69
|
-
(`2.1.210` → `2.1.233`)
|
|
70
|
-
rather than historical.
|
|
72
|
+
(`2.1.210` → `2.1.233`), the 2.1.242 split, and the 2.1.246 stream-store
|
|
73
|
+
migration, so each is re-checkable here rather than historical.
|
|
71
74
|
|
|
72
75
|
## Rebuild or extend it
|
|
73
76
|
|
|
@@ -93,5 +96,11 @@ done; }
|
|
|
93
96
|
sweep
|
|
94
97
|
```
|
|
95
98
|
|
|
96
|
-
`doctor`
|
|
97
|
-
|
|
99
|
+
`doctor` never writes to the backup it reads — it runs the matchers, parses
|
|
100
|
+
their output, then bakes the composed result into a *temp* binary and executes
|
|
101
|
+
`<binary> --version` (the smoke run, [PLAYBOOK.md](PLAYBOOK.md#how-resilience-is-detected)),
|
|
102
|
+
removing the temp afterwards — so the sweep is safe to run against every backup
|
|
103
|
+
at any time, and proves each build bakes and boots, not just that it matches.
|
|
104
|
+
Each bake transiently writes a binary-sized temp file (a few hundred MB) to the
|
|
105
|
+
system temp dir — RAM, where that is tmpfs — one at a time; `TMPDIR` steers it
|
|
106
|
+
elsewhere.
|