@kudzujs/core 0.16.23 → 0.16.25
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.
- package/PERFORMANCE.md +336 -0
- package/README.md +1 -1
- package/RELEASES.md +66 -0
- package/docs/next-architecture/application-capability-release-plan.md +115 -1
- package/docs/next-architecture/compiler-current-architecture.md +3 -1
- package/docs/next-architecture/versioning.md +1 -1
- package/framework/compiler/collection-analysis.mjs +15 -2
- package/framework/compiler/effect-private-ref-pass.mjs +2 -0
- package/framework/compiler/source-compiler.mjs +38 -7
- package/package.json +1 -1
package/PERFORMANCE.md
CHANGED
|
@@ -2,6 +2,284 @@
|
|
|
2
2
|
|
|
3
3
|
Reproducibility classes: `npm run benchmark`, `npm run benchmark:keyed`, `npm run benchmark:native`, `npm run benchmark:module-cache`, `npm run benchmark:project-navigation`, `npm run benchmark:project-state`, `npm run benchmark:source-scale`, `npm run benchmark:ai-delivery`, and `npm run benchmark:ai-delivery-production` are maintained in this repository; `npm run benchmark:commerce` is a maintained paired runner over the public external storefront; older excluded-workspace sections are historical provenance only and are not current framework rankings.
|
|
4
4
|
|
|
5
|
+
## 0.16.25 Release Scope
|
|
6
|
+
|
|
7
|
+
The following r5 compiler follow-up and future-only r6 acceptance alignment ship
|
|
8
|
+
as `@kudzujs/core@0.16.25` with `create-kudzu@0.1.150`. The session records below
|
|
9
|
+
retain their original pre-release scope and verification counts. Publication
|
|
10
|
+
does not rerun a model, rescore r5, upload its local raw archive, or establish a
|
|
11
|
+
timing/cost improvement. Frozen r6 starters remain pinned to released 0.16.24;
|
|
12
|
+
benchmarking the new compiler requires a separately frozen revision and full run.
|
|
13
|
+
|
|
14
|
+
## r5 Compiler Follow-Up (2026-09-07)
|
|
15
|
+
|
|
16
|
+
This is compiler regression work and deterministic source replay against
|
|
17
|
+
`5ed0f9bc875691e4e86e2fab832491c78c2f0c69` (`0.16.24`), not a model rerun,
|
|
18
|
+
release, or replacement benchmark score. The dirty r5 results and separately
|
|
19
|
+
prepared r6 acceptance/protocol changes remain intact. Historical r5 stays
|
|
20
|
+
Kudzu 18/25 versus React + Vite 23/25, with two partial traces; `1.0.0` remains
|
|
21
|
+
blocked. No production prompt, protocol, contract, or acceptance script was
|
|
22
|
+
edited by this compiler follow-up.
|
|
23
|
+
|
|
24
|
+
### Evidence And Reduction
|
|
25
|
+
|
|
26
|
+
Authorizing batch:
|
|
27
|
+
`test-results/ai-delivery-production/0.21.4-gpt-5.6-sol-r5-kudzu-0.16.24-20260907-01/`.
|
|
28
|
+
The reduced checks were run red before their respective compiler edits.
|
|
29
|
+
|
|
30
|
+
| Evidence | Confirmed problem | Existing path used |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `content-kudzu-1/adapter.stdout:35`, first patch; build failure at line 42 | `normalizedQuery = query.trim().toLowerCase()` survives in build scratch when `filteredArticles.length` is read directly in JSX rather than through a count local. It calls a string method on the signal object. | Collection-alias count validation now registers its substituted dependencies in the existing build-value declaration set. Existing binding/conditional/list consumers still subscribe to `query`; build scratch reads `query.value`. |
|
|
33
|
+
| Unchanged content starter `src/pages/topics/performance.tsx:13`, including historically accepted attempts 0/1/4 | A direct imported static `filter().map()` unnecessarily creates list state, prototypes, handler ESM, and a runtime family. | After existing collection/predicate/key analysis, direct imported pipelines with no selector states and no collection aliases remain ordinary build-time map execution. Local state and reactive selectors retain keyed ownership. |
|
|
34
|
+
| `realtime-kudzu-0` and `realtime-kudzu-3`, `src/pages/index.tsx:16` | Zero-initialized version refs have no cleanup reset and are intended to survive `[paused]` effect replacements. | Existing effect-private cleanup diagnostic is correct and remains unchanged. Making the ref invocation-private would reset the version and violate the authored lifetime. No persistent-ref support is added. |
|
|
35
|
+
| `realtime-kudzu-1`, `src/pages/index.tsx:16-17` | An unattached null ref is assigned `1` during render, then mutated by snapshot callbacks. Compilation previously accepted it as a DOM ref. `core.mjs` serializes ref captures by ID, not by numeric `.current`; this does not provide a retained version cell. | Existing ref normalization now rejects render-time writes at the authored source, recommending component state for retained values or cleanup-owned private refs for invocation-local values. This closes a diagnostic gap, not a resource-lifetime extension. |
|
|
36
|
+
|
|
37
|
+
The historical realtime timeout did not record an exact browser exception, so
|
|
38
|
+
none is asserted retroactively. The new negative reduction proves the null-ref
|
|
39
|
+
shape compiled before the guard and is diagnosed afterward. Replays of original
|
|
40
|
+
realtime sources 0/3 retain the cleanup diagnostic, source 1 receives the new
|
|
41
|
+
render-write diagnostic, and unchanged state-based sources 2/4 still build and
|
|
42
|
+
pass the realtime browser journey. Their authoring compromises remain explicit;
|
|
43
|
+
this is not a claim of persistent React ref compatibility.
|
|
44
|
+
|
|
45
|
+
### Output And Browser Proof
|
|
46
|
+
|
|
47
|
+
The new direct-alias-count case uses the existing imported article fixture and
|
|
48
|
+
Chrome journey. All four source variants emit byte-identical JavaScript:
|
|
49
|
+
9 files, 32,190 raw / 12,324 aggregate gzip B. Search by title/topic, whitespace
|
|
50
|
+
and case normalization, singular/plural status, empty branches, retained keys,
|
|
51
|
+
and fresh restored rows pass. The new static topic reduction emits matching
|
|
52
|
+
HTML, no excluded article seed, no state markers, and zero JavaScript files.
|
|
53
|
+
The six existing unsafe collection forms remain source-located diagnostics.
|
|
54
|
+
|
|
55
|
+
The original failing article source was recovered from the first patch event,
|
|
56
|
+
not reconstructed from the agent's final workaround. Recovered page SHA-256:
|
|
57
|
+
`915d825d15d1799b2a6fc891e12e1e84ca366df5a00a7721bd83d1b0f33db4d2`.
|
|
58
|
+
It and all five final content sources pass the separately prepared r6 acceptance
|
|
59
|
+
with all ten static siblings checked. The two combined polite-region sources
|
|
60
|
+
also pass its corrected semantic count check. These source-only results do not
|
|
61
|
+
erase historical budget failures or change model success/cost denominators.
|
|
62
|
+
|
|
63
|
+
| Output | Before raw / gzip B | After raw / gzip B | Delta raw / gzip B |
|
|
64
|
+
|---|---:|---:|---:|
|
|
65
|
+
| Complete content JavaScript, attempts 0/1/2/4 | 55,447 / 20,976 | 34,908 / 13,677 | -20,539 / -7,299 |
|
|
66
|
+
| Complete content JavaScript, attempt 3 | 55,440 / 20,987 | 34,901 / 13,688 | -20,539 / -7,299 |
|
|
67
|
+
| Content runtime files only, all five attempts | 51,357 / 19,100 | 30,895 / 11,896 | -20,462 / -7,204 |
|
|
68
|
+
| `/topics/performance/` JavaScript graph | 20,539 / 7,299 | 0 / 0 | -20,539 / -7,299 |
|
|
69
|
+
| Existing reduced search graph | 32,190 / 12,324 | 32,190 / 12,324 | 0 / 0 |
|
|
70
|
+
|
|
71
|
+
Each content build changes from 11 pages / 2 interactive / 13 JavaScript files
|
|
72
|
+
to 11 pages / 1 interactive / 9 JavaScript files. Removed paths are
|
|
73
|
+
`assets/handlers/pages/topics/performance.js` and the `kudzu.js`, `kudzu-list.js`,
|
|
74
|
+
and `kudzu-collection-selector.js` files in runtime family `432dc692688d09a1`.
|
|
75
|
+
Every retained JavaScript path and byte is identical to its archived r5 output.
|
|
76
|
+
The recovered source emits the same graph as final attempts 0/1/2/4, SHA-256
|
|
77
|
+
`34a34339db48a3da01f67b41fa5a5b0f50ea4d1854e3c30a1569e8e32b2c5270`
|
|
78
|
+
(sorted relative JavaScript paths followed by their bytes). Gzip is summed per
|
|
79
|
+
artifact with Node `gzipSync`, not a compressed archive or network measurement.
|
|
80
|
+
|
|
81
|
+
### Accounting And Verification
|
|
82
|
+
|
|
83
|
+
| Metric | Delta |
|
|
84
|
+
|---|---:|
|
|
85
|
+
| Semantic primitives / ModuleIR kinds / core passes | 0 / 0 / 0 |
|
|
86
|
+
| Core semantic LOC (`source-compiler.mjs`, including comment) | +5 |
|
|
87
|
+
| Focused normalization LOC (`effect-private-ref-pass.mjs`) | +2 |
|
|
88
|
+
| Production compiler LOC total | +7 |
|
|
89
|
+
| Ordered normalization entries / transform rules / adapters | 0 / 0 / 0 |
|
|
90
|
+
| Source diagnostic guards | +1 |
|
|
91
|
+
| Runtime concepts / runtime source LOC / dependencies / public APIs | 0 / 0 / 0 / 0 |
|
|
92
|
+
| Positive reduced cases / negative reduced cases | +2 / +2 |
|
|
93
|
+
| AI score, build-speed, interaction-timing, CPU, heap claims | None |
|
|
94
|
+
|
|
95
|
+
The positive cases extend the existing isolated fixture generator; the two
|
|
96
|
+
negative source fixtures live in `test/realtime-version-ref.test.mjs`. No new
|
|
97
|
+
runtime or generic compiler abstraction was introduced. Static collection
|
|
98
|
+
aliases and cross-invocation mutable refs are not broadened by this change.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
KUDZU_REQUIRE_CHROME=1 node --test test/imported-article-search.test.mjs
|
|
102
|
+
node --test test/realtime-version-ref.test.mjs
|
|
103
|
+
node /tmp/opencode/r5-compiler-followup.mjs
|
|
104
|
+
node /tmp/opencode/verify-r5-compiler-output.mjs
|
|
105
|
+
npm run check
|
|
106
|
+
KUDZU_REQUIRE_CHROME=1 npm test
|
|
107
|
+
npm run test:package
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
All pass on the same Linux x64 / Node 24.14.0 / Chrome 152.0.7977.64 host as r5.
|
|
111
|
+
Check builds 224 pages, two interactive. The final full run passes the standalone
|
|
112
|
+
project ownership gate plus 315/315 tests, including the preserved r6 acceptance
|
|
113
|
+
tests; package smoke installs four packages and builds one zero-JavaScript page.
|
|
114
|
+
Full commands use a 1,200,000 ms timeout. Local replay sources, artifacts, full
|
|
115
|
+
acceptance JSON, errors, path lists, and raw/gzip totals are retained separately
|
|
116
|
+
at `/tmp/opencode/r5-compiler-followup-EQOrpR/report.json` and adjacent directories.
|
|
117
|
+
No model, commit, version bump, publication, or release was run. Build/browser
|
|
118
|
+
timings were not sampled under an interleaved performance protocol, so no timing
|
|
119
|
+
improvement is claimed.
|
|
120
|
+
|
|
121
|
+
## 0.21.4 Released 0.16.24 Rerun (2026-09-07)
|
|
122
|
+
|
|
123
|
+
All 50 scheduled attempts executed, without selective retries, from
|
|
124
|
+
`2026-09-07T04:18:00.678Z` through `2026-09-07T05:36:06.037Z` (78 minutes
|
|
125
|
+
5 seconds). The frozen scorer reports **Kudzu 18/25 (72%) versus React + Vite
|
|
126
|
+
23/25 (92%)**. Execution finished, but `suite.json` correctly says `incomplete`:
|
|
127
|
+
two Kudzu realtime attempts retain partial attribution after their deadlines.
|
|
128
|
+
This is a new local r5 observation, not a rewrite of the published r2 result,
|
|
129
|
+
proof of a statistically significant improvement, or authorization for `1.0.0`.
|
|
130
|
+
The acceptance/prompt and output-contract gaps below also prevent treating this
|
|
131
|
+
score as a clean production-framework ranking.
|
|
132
|
+
|
|
133
|
+
### Protocol And Execution
|
|
134
|
+
|
|
135
|
+
Base revision: `5ed0f9bc875691e4e86e2fab832491c78c2f0c69`, released
|
|
136
|
+
`@kudzujs/core@0.16.24`; no compiler changes during this packet. Although no r4
|
|
137
|
+
execution was found in the local evidence inventory, r4's `0.16.23` pins were
|
|
138
|
+
already release-documented. Revision 5 therefore explicitly changes all five
|
|
139
|
+
Kudzu manifests, lock root dependencies, resolved core versions/tarball URLs,
|
|
140
|
+
registry integrity values, and canonical starter digests. Historical r2/r3 raw
|
|
141
|
+
directories and release records remain untouched. The r4 lifecycle adapter is
|
|
142
|
+
unchanged, SHA-256
|
|
143
|
+
`91c0db691c2f7a7d5c40122e86b2ac7b928e3016a80a202f8c079c2013b3eb0e`.
|
|
144
|
+
|
|
145
|
+
Model remains `openai/gpt-5.6-sol`; exact OpenCode `1.18.27` is selected with
|
|
146
|
+
`OPENCODE_BIN` rather than the host default `1.18.29`. Node `24.14.0`, npm
|
|
147
|
+
`11.9.0`, Chrome `152.0.7977.64`, Linux x64 `7.0.0-30-generic`, Intel i5-9500
|
|
148
|
+
(6 logical CPUs), and 33,491,050,496 bytes RAM were recorded. OAuth presence was
|
|
149
|
+
checked without reading credentials. A separate tool-free model preflight
|
|
150
|
+
returned `READY`; its 6,755 tokens are excluded from task accounting.
|
|
151
|
+
|
|
152
|
+
The model, budgets, tools, prompts, public context, executable acceptance,
|
|
153
|
+
written contracts, all React starters, and alternating schedules are identical
|
|
154
|
+
to r4. Each adapter has a setup-inclusive 300,000 ms deadline and limits of
|
|
155
|
+
400,000 input, 20,000 output, 20,000 reasoning tokens, 40 tool calls, 20 files
|
|
156
|
+
read, 8 files modified, and 5 builds. Tasks execute serially in content, forms,
|
|
157
|
+
CRUD, commerce, realtime order; model processes never run in parallel.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
OPENCODE_BIN=/home/kft/.npm/_npx/3fe6b69ccd55ed58/node_modules/.bin/opencode CHROME_BIN=/usr/bin/google-chrome npm run benchmark:ai-delivery-production -- --out test-results/ai-delivery-production/0.21.4-gpt-5.6-sol-r5-kudzu-0.16.24-20260907-01 > test-results/ai-delivery-production/0.21.4-gpt-5.6-sol-r5-kudzu-0.16.24-20260907-01/suite.stdout 2> test-results/ai-delivery-production/0.21.4-gpt-5.6-sol-r5-kudzu-0.16.24-20260907-01/suite.stderr
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The command exits 0 after all schedules finish; that is not a passing benchmark
|
|
164
|
+
gate. The output directory contains `suite.json`, all five `run.json` and copied
|
|
165
|
+
protocols, 50 attempt results, raw adapter output/traces, build/acceptance logs,
|
|
166
|
+
retained source and deploy artifacts, preflight logs, test logs, and `audit.json`
|
|
167
|
+
(all source diffs, raw-trace review extracts, and artifact/token aggregates).
|
|
168
|
+
The complete local archive is
|
|
169
|
+
`test-results/ai-delivery-production/0.21.4-gpt-5.6-sol-r5-kudzu-0.16.24-20260907-01.tar.gz`,
|
|
170
|
+
SHA-256 `d0190c9c4d6da0bd9676365037cf1a1def72e808010e3b03a94a701138a31205`.
|
|
171
|
+
Gzip integrity passes; all 50 schedule entries, 50 pinned-model attribution
|
|
172
|
+
traces, and 300 recorded command-stream SHA-256 values were verified. The archive
|
|
173
|
+
is local evidence only and was not uploaded or released.
|
|
174
|
+
|
|
175
|
+
| Task | r5 protocol SHA-256 | Kudzu starter SHA-256 |
|
|
176
|
+
|---|---|---|
|
|
177
|
+
| Content | `f63c11e20e21659c25ef99498e13085054565382af9a500e7aa6e6520968b1ec` | `6b56448eb0b9179183aeb433bd3e52538749f1a2e609c37c5a8bdf8e479ccd92` |
|
|
178
|
+
| Forms | `967335af955b23c23e8ce81eed35b3a9426c08047b4286a5328e144f30b6e9aa` | `0a762afe93c77cec2137e956796f47a944b9222e3dcff1178462665cf995291b` |
|
|
179
|
+
| CRUD | `063625fd48442c639a059c240d1edaef63f54176f921dcd297c8daf97086430d` | `1e349e2deb163b8bc52fb8844a989e8f29f1ed12a2857da86119bf89ffa3e5c2` |
|
|
180
|
+
| Commerce | `c35cb1801f5a4b98a644f6f48f7c02b2168ebc9ce901b0b8e74fcf792c3d2e0b` | `d2b6e8d926b3e55d0e3e47c0647fdd75f01b46e3dc4ac705108974c7d3e186b3` |
|
|
181
|
+
| Realtime | `bda2526c95862b8d55045018da70370b9dd9a36d4e7ccfe56b3af56f06dbad10` | `f5adc4cf163a8e9cb838173d718fd21302a474fd70920167c12d64518890b218` |
|
|
182
|
+
|
|
183
|
+
The starter digest is SHA-256 over recursively locale-sorted file names, each
|
|
184
|
+
relative slash-normalized path followed by NUL and file bytes, matching the
|
|
185
|
+
integrity test. Every core lock entry uses registry integrity
|
|
186
|
+
`sha512-qLcVItXkI7vI5ktOC16+87uQ4BqQTQOVrFqR4AK7gz4eMN4imL7o+ocUBc7znuVsMML98ChKLRgMSsUot7GUhg==`.
|
|
187
|
+
|
|
188
|
+
### Scores And Attribution
|
|
189
|
+
|
|
190
|
+
| Task | Kudzu success | React success | Kudzu tokens / success | React tokens / success |
|
|
191
|
+
|---|---:|---:|---:|---:|
|
|
192
|
+
| Content | 3/5 | 5/5 | 591,903 | 77,522 |
|
|
193
|
+
| Forms | 5/5 | 5/5 | 92,087 | 81,111 |
|
|
194
|
+
| CRUD | 3/5 | 3/5 | 250,028 | 197,556 |
|
|
195
|
+
| Commerce | 5/5 | 5/5 | 68,746 | 57,756 |
|
|
196
|
+
| Realtime | 2/5 | 5/5 | unavailable | 142,071 |
|
|
197
|
+
| Overall | 18/25 | 23/25 | unavailable | task median 81,111 |
|
|
198
|
+
|
|
199
|
+
Tokens per success include failed attempts, cache-read input, output, and
|
|
200
|
+
reasoning, following the existing runner's accounting. Recorded totals are
|
|
201
|
+
4,279,911 Kudzu tokens (a lower bound because two traces are partial) and
|
|
202
|
+
2,384,962 React tokens. There are 48 complete and 2 incomplete traces; no raw
|
|
203
|
+
model error event was found. Both timed-out model sessions had already produced
|
|
204
|
+
source and a compiler diagnostic, so they are not model-unavailability failures.
|
|
205
|
+
Provider-reported subscription cost is zero, not a market-price cost comparison.
|
|
206
|
+
Kudzu's aggregate failure-inclusive task cost remains unavailable, not zero.
|
|
207
|
+
Successful-attempt elapsed medians are 69,363/65,918 ms, tool calls 12/10, files
|
|
208
|
+
read 5/4, files modified 2/2, builds 1/1, and correction cycles 0/0 for
|
|
209
|
+
Kudzu/React. These are descriptive scorer subsets, not speed or cost wins.
|
|
210
|
+
|
|
211
|
+
Final builds passed 23/25 Kudzu and 25/25 React; complete executable acceptance
|
|
212
|
+
passed 18/25 and 23/25. Against historical r2's 11/25 and 24/25, the observed
|
|
213
|
+
counts change by +7 and -1, with content and commerce now having scored Kudzu
|
|
214
|
+
successes. Different stochastic runs, compiler pins, lifecycle accounting, and
|
|
215
|
+
the limitations below prevent attributing that entire change to the compiler.
|
|
216
|
+
|
|
217
|
+
### Every Failure
|
|
218
|
+
|
|
219
|
+
| Attempts | Observed failure | Attribution / limitation |
|
|
220
|
+
|---|---|---|
|
|
221
|
+
| `content-kudzu-2`, `content-kudzu-3` | Empty-state live-region text is `0 articlesNo articles match your search.` rather than exactly `0 articles`; all filtering/count transitions otherwise match. Attempt 2 also uses 497,474 input tokens, over 400,000. | Both place separate count and empty-message paragraphs inside one polite region. The grader assumes the entire first live region is the count. Preserve failures, but do not call this broken filtering; the prompt does not explicitly require a count-only region. |
|
|
222
|
+
| `crud-kudzu-1`, `crud-kudzu-3`, `crud-react-vite-2`, `crud-react-vite-4` | Only `initial.group` fails; keyed retention, filters, create/edit/delete, counts, focus, and empty state pass. | All use `role="group" aria-label="Filter memos by status"`. The grader requires exact `Filter memos`. That name exists in the written contract and starter, but the supplied prompt asks only for a named group. The adapter does not supply the written contract. This is a prompt/acceptance alignment gap, not a compiler or missing-group failure. |
|
|
223
|
+
| `realtime-kudzu-0`, `realtime-kudzu-3` | Adapter SIGKILL at about 300,011 ms; final build rejects `src/pages/index.tsx:16:9`: effect-private refs require cleanup that resets or invalidates `.current`. No deploy output. | Version refs initialized with zero are intended to survive pause/resume; current effect-private ownership cannot provide that lifetime. Atomic partial traces retain 117,447 and 175,039 recorded tokens, respectively. No retry or synthetic completion. |
|
|
224
|
+
| `realtime-kudzu-1` | Build passes after changing `useRef(1)` to an unattached `useRef(null)` plus render-time initialization; acceptance times out waiting for the first four-row snapshot. | Generated handler still reads `scope("version").current`. The runtime-ref workaround is not proven safe by its successful build. The frozen timeout path does not serialize browser exception details; do not invent an exact exception or claim a diagnosed compiler fix. |
|
|
225
|
+
|
|
226
|
+
Raw content traces also retain a residual `query.trim is not a function`
|
|
227
|
+
build failure in attempts 1 and 3 when a normalized query alias feeds a filtered
|
|
228
|
+
array whose `.length` is consumed directly. Both agents inline the query
|
|
229
|
+
expression to recover. Attempts 0/2/4 retain the normalized query with a separate
|
|
230
|
+
count local and build. These exact sources, plus the realtime ref cases, are
|
|
231
|
+
future reduced-fixture inputs; this rerun makes no speculative compiler change.
|
|
232
|
+
|
|
233
|
+
### Output And Source
|
|
234
|
+
|
|
235
|
+
| Executable-accepted subset | Kudzu median artifact raw / gzip B | React median artifact raw / gzip B | Kudzu / React median transferred JS B |
|
|
236
|
+
|---|---:|---:|---:|
|
|
237
|
+
| Content (3 / 5 attempts) | 93,274 / 35,226 | 206,504 / 66,425 | 37,608 / 199,132 |
|
|
238
|
+
| Forms (5 / 5) | 23,832 / 9,771 | 202,704 / 64,305 | 15,147 / 198,469 |
|
|
239
|
+
| CRUD (3 / 3) | 48,490 / 16,727 | 203,383 / 64,471 | 35,542 / 198,476 |
|
|
240
|
+
| Commerce (5 / 5) | 53,886 / 21,871 | 201,055 / 64,188 | 30,214 / 197,976 |
|
|
241
|
+
| Realtime (2 / 5) | 45,555 / 16,150 | 202,524 / 64,244 | 36,012 / 199,043 |
|
|
242
|
+
|
|
243
|
+
Artifact totals include every deploy file; gzip is summed per file. Transferred
|
|
244
|
+
JS sums `.js` resource entries from the frozen journey, including protocol
|
|
245
|
+
overhead, not CPU time or a complete multi-route session. All 18 scored Kudzu
|
|
246
|
+
successes have the designated complete, script/marker-free static sibling.
|
|
247
|
+
Content emits 11 HTML pages but only nine are script/marker-free: besides the
|
|
248
|
+
search route, `/topics/performance/` loads a list capability. Its source was not
|
|
249
|
+
edited by the agents, but this violates the broader written content static-route
|
|
250
|
+
expectation and is not checked by executable acceptance. React's
|
|
251
|
+
`staticZeroJavaScript: true` is a bypass in the checker, not evidence of zero
|
|
252
|
+
React JavaScript. No complete 0.9 performance, memory, resilience, or all-route
|
|
253
|
+
accessibility parity claim follows from these artifact observations.
|
|
254
|
+
|
|
255
|
+
All 50 retained source inventories were compared with their starters. Only
|
|
256
|
+
authored TSX/CSS changed (one to three files); manifests, locks, seeded data,
|
|
257
|
+
fake transport, and test infrastructure remain unchanged. Search preserves
|
|
258
|
+
`ArticleCard`/`Shell` composition and imported data; CRUD preserves its shared
|
|
259
|
+
Provider and keyed declarative rows. No imperative list/DOM replacement was
|
|
260
|
+
found. Native form refs, focus, and validity calls are ordinary form behavior.
|
|
261
|
+
Maintainability is not uniformly equivalent: commerce Kudzu attempt 4 adds
|
|
262
|
+
derived display state after a formatting diagnostic; realtime Kudzu attempt 2
|
|
263
|
+
calls `setMemos` inside a version-state updater, while attempt 4 carries version
|
|
264
|
+
through state plus an effect-local copy instead of React's persistent ref.
|
|
265
|
+
These are explicit authoring compromises, not proof of abstraction parity.
|
|
266
|
+
The runner's byte-identical-file retention metric includes lockfile bytes and
|
|
267
|
+
is not a semantic source-retention percentage.
|
|
268
|
+
|
|
269
|
+
Next prerequisite is an acceptance/prompt alignment review, preserving this raw
|
|
270
|
+
batch and changing no scores retroactively. The retained direct-count query and
|
|
271
|
+
cross-invocation version-ref failures then provide concrete compiler intake;
|
|
272
|
+
the static topic output also needs a separately scoped check. `1.0.0` remains
|
|
273
|
+
blocked. This packet adds zero semantic primitives, compiler passes/LOC, runtime
|
|
274
|
+
concepts, or dependencies, and makes no release, speed, price, or superiority claim.
|
|
275
|
+
|
|
276
|
+
Verification: six protocol/runner/lifecycle tests pass; before execution and
|
|
277
|
+
again after the results documentation, `npm run check` builds 224 pages, two
|
|
278
|
+
interactive, and `npm test` passes the standalone project ownership test plus
|
|
279
|
+
308/308 tests. Final logs are `final-check.log` and `final-test.log` in the raw
|
|
280
|
+
directory. `git diff --check` passes. The final archive/checksum metadata update
|
|
281
|
+
does not change model inputs or any recorded artifact.
|
|
282
|
+
|
|
5
283
|
## 0.21.4 Corrected AI Delivery Proof
|
|
6
284
|
|
|
7
285
|
Measured 2026-09-03 on Linux x64 with Node 24.14.0, Chrome 152.0.7977.64,
|
|
@@ -92,6 +370,64 @@ not a new equal-condition model run, so the published 11/25 versus 24/25 result
|
|
|
92
370
|
and the `1.0.0` block remain unchanged pending the complete production rerun.
|
|
93
371
|
This follow-up ships as `@kudzujs/core@0.16.23`.
|
|
94
372
|
|
|
373
|
+
### Imported Search Source Replay (2026-09-07)
|
|
374
|
+
|
|
375
|
+
Compiler follow-up shipping as `0.16.24` to `f88279024e68c875ea35592a1ab363bde1cec9d0`
|
|
376
|
+
(`0.16.23`), on Linux x64, Node 24.14.0 and Chrome 152.0.7977.64. Authorizing
|
|
377
|
+
evidence is the initial aliased search patch at line 50 of
|
|
378
|
+
`test-results/ai-delivery-production/0.21.4-gpt-5.6-sol-r3-kudzu-0.16.23-continuation-20260907/content/attempts/content-kudzu-0/adapter.stdout`.
|
|
379
|
+
The reduced fixture first reproduced both the source-located generic expression
|
|
380
|
+
diagnostic and the direct-filter-count `query.trim is not a function` build error.
|
|
381
|
+
|
|
382
|
+
Imported collection discovery now follows top-level const selector aliases from
|
|
383
|
+
map/count uses. Filter predicates encode proven pure query locals using the
|
|
384
|
+
existing expression language, and count dependencies use signal build values in
|
|
385
|
+
scratch rather than invoking string methods on signal objects. Existing binding,
|
|
386
|
+
selector, keyed, and conditional consumers remain authoritative.
|
|
387
|
+
|
|
388
|
+
| Metric | Result |
|
|
389
|
+
|---|---|
|
|
390
|
+
| Semantic primitives / IR kinds / runtime concepts / APIs | +0 / +0 / +0 / +0 |
|
|
391
|
+
| Core passes / ordered normalization entries / adapters | +0 / +0 / +0 |
|
|
392
|
+
| Existing normalization/proof boundaries extended | 3: import roots, pure filter locals, count build values |
|
|
393
|
+
| Core semantic LOC, unchanged 0.9 file set | +39, 5,466 -> 5,505; source compiler +26, collection analysis +13 |
|
|
394
|
+
| Regression evidence | 1 reduced fixture; 3 positive source variants, 6 negative forms, 4 tests |
|
|
395
|
+
| Reduced route JS | 9 files; 32,190 raw / 12,324 aggregate gzip B in every variant |
|
|
396
|
+
| Delta from fully inlined control | 0 raw / 0 gzip B; identical JS paths and contents |
|
|
397
|
+
| Reduced static sibling | Complete HTML, 0 B JavaScript |
|
|
398
|
+
| Full retained application replay | 11 pages, 2 interactive; build and existing content acceptance pass |
|
|
399
|
+
| Full application JS vs earlier retained inlined artifacts | 13 files; 55,447 raw / 20,976 aggregate gzip B; all paths/bytes identical |
|
|
400
|
+
| Build/browser timing and AI-cost delta | Not measured; no fresh model benchmark or ranking claim |
|
|
401
|
+
|
|
402
|
+
The full replay restores the initial page and stylesheet patch over the content
|
|
403
|
+
starter while preserving the retained application's other source. It uses the
|
|
404
|
+
current workspace compiler and the unchanged existing content acceptance runner,
|
|
405
|
+
not a new adapter invocation. It passes search/count/empty/restore, accessibility,
|
|
406
|
+
zero-JavaScript static output, and no browser exceptions or failed requests.
|
|
407
|
+
Raw build/acceptance output and `replay.json` are retained separately under
|
|
408
|
+
`test-results/ai-delivery-production/imported-article-search-source-replay-20260907/`. Its sorted
|
|
409
|
+
HTML/CSS/JS path-plus-NUL-plus-content SHA-256 is
|
|
410
|
+
`92d96f7cfdd4535de28ff9b7665aa241815ed2649e6db14fc22c5eadc8258904`.
|
|
411
|
+
The original attempt and earlier benchmark results are not rewritten.
|
|
412
|
+
|
|
413
|
+
Release verification: `npm run check` (224 pages, 2 interactive),
|
|
414
|
+
`KUDZU_REQUIRE_CHROME=1 npm test` (standalone project ownership gate, then
|
|
415
|
+
308/308 tests), `npm run test:package` (4 installed packages, one static page),
|
|
416
|
+
and both package dry-runs pass. The release gates ran sequentially with a
|
|
417
|
+
1,200-second tool limit, avoiding overlapping fixture tests.
|
|
418
|
+
Chrome regression checks also prove retained rows and fresh remounts; they are
|
|
419
|
+
correctness checks, not latency samples. Mutable aliases, impure calls, cycles,
|
|
420
|
+
collection escapes, mutating sort, and predicate-parameter state collisions remain
|
|
421
|
+
diagnosed. No general local/callback graph or effect cleanup claim is added.
|
|
422
|
+
The same release includes separate r4 benchmark lifecycle integrity changes:
|
|
423
|
+
atomic partial-usage checkpoints, bounded incremental stdout/stderr evidence,
|
|
424
|
+
setup-inclusive deadlines, owned process-tree termination, and incomplete timeout
|
|
425
|
+
attribution. Two Linux lifecycle regressions cover setup and model timeouts,
|
|
426
|
+
partial usage, descendant termination, and passing acceptance after adapter timeout.
|
|
427
|
+
The Windows `taskkill` path remains untested. Future r4 protocols pin published
|
|
428
|
+
`0.16.23` starters; historical raw evidence remains untouched. The published
|
|
429
|
+
11/25 versus 24/25 comparison and `1.0.0` block remain unchanged.
|
|
430
|
+
|
|
95
431
|
## 0.21.2 Browser Performance And Memory
|
|
96
432
|
|
|
97
433
|
Measured 2026-09-03 at revision
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Kudzu compiles ordinary React-shaped TypeScript and TSX into complete static HTM
|
|
|
14
14
|
|
|
15
15
|
> Experimental `0.16.x`: the compiler API and supported TSX surface may change.
|
|
16
16
|
|
|
17
|
-
**Latest release: 0.16.
|
|
17
|
+
**Latest release: 0.16.25 - static content and acceptance alignment.** Direct imported static selectors emit HTML without list JavaScript, and original query aliases support direct JSX counts. Content source replay removes four files and 20,539 raw / 7,299 aggregate gzip JavaScript bytes. Future-only r6 acceptance covers named groups, combined polite regions, and all ten static siblings. Historical r5 remains 18/25 versus 23/25 with two partial traces; no fresh model rerun or replacement score is claimed, and `1.0.0` remains blocked. Read the [release notes](./RELEASES.md#01625---static-content-and-acceptance-alignment), open the [release page](https://github.com/kudzujs/kudzu/releases/tag/v0.16.25), or follow the [architecture packet](./docs/next-architecture/README.md).
|
|
18
18
|
|
|
19
19
|
- [Documentation](https://kudzujs.cloud/docs)
|
|
20
20
|
- [Installation guide](https://kudzujs.cloud/docs#install)
|
package/RELEASES.md
CHANGED
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
# Kudzu Releases
|
|
2
2
|
|
|
3
|
+
## 0.16.25 - Static Content And Acceptance Alignment
|
|
4
|
+
|
|
5
|
+
Kudzu 0.16.25 closes the r5 static-topic and direct-count compiler gaps and
|
|
6
|
+
aligns future acceptance with communicated requirements. This release includes
|
|
7
|
+
historical r5 observations, not a fresh model rerun or replacement score.
|
|
8
|
+
|
|
9
|
+
### Changed in 0.16.25
|
|
10
|
+
|
|
11
|
+
- Keeps proven direct imported static selector maps at build time and registers
|
|
12
|
+
normalized query build values for collection counts consumed directly in JSX.
|
|
13
|
+
- Removes four topic JavaScript files from each replayed content build: 13 to 9
|
|
14
|
+
files, saving 20,539 raw / 7,299 aggregate gzip bytes. Retained JavaScript is
|
|
15
|
+
byte-identical, and all ten static siblings pass source-replay acceptance.
|
|
16
|
+
- Rejects unsafe render-written mutable refs at authored source locations.
|
|
17
|
+
Persistent realtime version refs across effect replacements remain unsupported;
|
|
18
|
+
existing cleanup diagnostics and state-based realtime sources are preserved.
|
|
19
|
+
- Adds seven production compiler lines across two existing files, no semantic
|
|
20
|
+
primitive, pass, IR kind, runtime concept, public API, or dependency.
|
|
21
|
+
- Aligns named CRUD groups and combined polite count/empty regions, enforces
|
|
22
|
+
static exclusion on all ten content siblings, and freezes r6 protocol hashes.
|
|
23
|
+
Those future-only protocols retain published 0.16.24 starters; no r6 model run
|
|
24
|
+
has been performed.
|
|
25
|
+
- Preserves historical r5's 18/25 Kudzu versus 23/25 React + Vite, with two partial
|
|
26
|
+
Kudzu traces and acceptance limitations. Published r2 remains 11/25 versus
|
|
27
|
+
24/25. Neither is rescored; `1.0.0` remains blocked. No timing or cost win is claimed.
|
|
28
|
+
- Updates `create-kudzu@0.1.150` to generate `@kudzujs/core@^0.16.25` projects.
|
|
29
|
+
|
|
30
|
+
### Upgrade
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm install @kudzujs/core@^0.16.25
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 0.16.24 - Imported Article Search And Benchmark Integrity
|
|
37
|
+
|
|
38
|
+
Kudzu 0.16.24 compiles the original authored imported-article search shape
|
|
39
|
+
without an inlined workaround and hardens evidence lifecycle integrity for
|
|
40
|
+
future AI delivery runs. This is source replay evidence, not a new AI score.
|
|
41
|
+
|
|
42
|
+
### Changed in 0.16.24
|
|
43
|
+
|
|
44
|
+
- Follows imported collection selector aliases, normalizes proven pure query
|
|
45
|
+
locals, and evaluates count dependencies from signal build values.
|
|
46
|
+
- Adds 39 net core semantic lines across two existing compiler files, with no
|
|
47
|
+
new semantic primitive, pass, IR kind, runtime concept, API, or dependency.
|
|
48
|
+
- Covers three byte-identical search variants, six rejected unsafe forms,
|
|
49
|
+
retained keyed identity, fresh remounts, and a zero-JavaScript static sibling.
|
|
50
|
+
- Replays the original authored application search successfully through the
|
|
51
|
+
unchanged content acceptance: 13 JavaScript files, 55,447 raw / 20,976 gzip
|
|
52
|
+
bytes, identical to the retained inlined application's JavaScript.
|
|
53
|
+
- Checkpoints adapter usage atomically, streams bounded output evidence, shares
|
|
54
|
+
the deadline with setup, kills owned process trees on timeout, and prevents
|
|
55
|
+
incomplete or timed-out attempts from becoming successful attribution.
|
|
56
|
+
- Freezes r4 protocols with published 0.16.23 starters for future runs only.
|
|
57
|
+
Historical raw evidence is unchanged. Linux lifecycle regressions cover the
|
|
58
|
+
termination paths; the Windows `taskkill` path remains untested.
|
|
59
|
+
- Makes no fresh timing, cost, or AI performance claim. The published 11/25
|
|
60
|
+
versus 24/25 comparison and the `1.0.0` block remain unchanged.
|
|
61
|
+
- Updates `create-kudzu@0.1.149` to generate `@kudzujs/core@^0.16.24` projects.
|
|
62
|
+
|
|
63
|
+
### Upgrade
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
npm install @kudzujs/core@^0.16.24
|
|
67
|
+
```
|
|
68
|
+
|
|
3
69
|
## 0.16.23 - Reactive Conditional Branch Text
|
|
4
70
|
|
|
5
71
|
Kudzu 0.16.23 removes the second commerce compiler blocker selected by the
|
|
@@ -2183,6 +2183,120 @@ This does not revise the published equal-condition score without a complete
|
|
|
2183
2183
|
rerun, so `1.0.0` remains unauthorized. This follow-up is released as
|
|
2184
2184
|
`@kudzujs/core@0.16.23` with `create-kudzu@0.1.148`.
|
|
2185
2185
|
|
|
2186
|
+
The user-approved 2026-09-07 `0.16.24` continuation addresses the initial r3
|
|
2187
|
+
content patch's imported collection alias and direct filter-count failures.
|
|
2188
|
+
[`imported-article-search`](../../test/fixtures/imported-article-search/README.md)
|
|
2189
|
+
reproduced both failures before changes. The reduction extends existing import
|
|
2190
|
+
discovery, pure selector normalization, and count build-value lowering, with
|
|
2191
|
+
existing BindingIR/DerivedIR/KeyedBlockIR consumers and route/keyed/conditional
|
|
2192
|
+
ownership. It adds no primitive, IR kind, pass, runtime concept, API, or adapter;
|
|
2193
|
+
the two core files grow by net 39 lines. Three source variants produce identical
|
|
2194
|
+
JavaScript (32,190 raw / 12,324 gzip B) and six unsafe neighboring forms remain
|
|
2195
|
+
source-located errors. Required Chrome verifies search/count/empty transitions,
|
|
2196
|
+
retained keys, fresh remounts, and static zero-JavaScript exclusion. Check, the
|
|
2197
|
+
project ownership gate plus 308 tests, package smoke, and both package dry-runs pass.
|
|
2198
|
+
|
|
2199
|
+
The full initial-source replay passes the unchanged content acceptance and emits
|
|
2200
|
+
the same 13 JavaScript files/bytes as the earlier retained inlined workaround
|
|
2201
|
+
(55,447 raw / 20,976 gzip B). This is a source replay, not a fresh model trial or
|
|
2202
|
+
replacement benchmark score; no timing or AI-cost improvement is claimed.
|
|
2203
|
+
[`PERFORMANCE.md`](../../PERFORMANCE.md#imported-search-source-replay-2026-09-07)
|
|
2204
|
+
records commands, provenance, accounting, and limits. Preserve the original r3
|
|
2205
|
+
evidence. The release also includes the reviewed r4 protocol/adapter lifecycle
|
|
2206
|
+
work: atomic partial traces, bounded incremental output, setup-inclusive deadlines,
|
|
2207
|
+
owned process-tree termination, and incomplete timeout attribution. Two Linux
|
|
2208
|
+
lifecycle regressions protect future-run integrity; Windows termination remains
|
|
2209
|
+
untested. The frozen r4 starters stay on published `0.16.23`; old raw records are
|
|
2210
|
+
not reinterpreted. This packet ships as `@kudzujs/core@0.16.24` with
|
|
2211
|
+
`create-kudzu@0.1.149`, without authorizing `1.0.0` or a new AI performance claim.
|
|
2212
|
+
|
|
2213
|
+
The post-release 2026-09-07 r5 rerun now executes all 50 predeclared attempts with
|
|
2214
|
+
published `0.16.24` core pins, registry lock integrity, and canonical hashes in
|
|
2215
|
+
all five Kudzu starters. Revision 5 preserves the release-documented r4 pins as
|
|
2216
|
+
history rather than relabeling them; model `openai/gpt-5.6-sol`, OpenCode 1.18.27,
|
|
2217
|
+
budgets, prompts, public context, acceptance, React starters, schedules, and the
|
|
2218
|
+
r4 lifecycle adapter are unchanged. No compiler or runtime change is made.
|
|
2219
|
+
|
|
2220
|
+
The frozen scorer records Kudzu 18/25 versus React + Vite 23/25, with per-task
|
|
2221
|
+
counts 3/5, 5/5, 3/5, 5/5, 2/5 versus 5/5, 5/5, 3/5, 5/5, 5/5. All tasks finish,
|
|
2222
|
+
but two Kudzu realtime deadline failures retain partial attribution, so suite
|
|
2223
|
+
status and Kudzu aggregate token cost remain incomplete. React's failure-inclusive
|
|
2224
|
+
task-token median is 81,111. Historical r2's published 11/25 versus 24/25 and all
|
|
2225
|
+
r3 raw evidence remain unchanged; no selective retries or replacement scores.
|
|
2226
|
+
|
|
2227
|
+
This is not a clean ranking or `1.0.0` authorization. Four CRUD failures are
|
|
2228
|
+
exact accessible-name mismatches against a requirement absent from the supplied
|
|
2229
|
+
prompt; two content failures arise from the grader reading count and empty copy
|
|
2230
|
+
as one live-region string, one also exceeding the input budget. The next
|
|
2231
|
+
prerequisite is acceptance/prompt alignment review without retroactive rescoring.
|
|
2232
|
+
Real compiler intake remains in raw `query.trim` failures for direct count uses
|
|
2233
|
+
of normalized-query filters and realtime refs intended to survive pause/resume.
|
|
2234
|
+
One null-ref workaround builds but fails the first snapshot; two zero-ref
|
|
2235
|
+
attempts fail cleanup proof and time out. Accepted source retains declarative
|
|
2236
|
+
composition but some Kudzu attempts add derived/version state workarounds.
|
|
2237
|
+
Designated static siblings remain script-free; content's unchanged topic source
|
|
2238
|
+
emits list scripts, leaving the broader static-route contract unproven.
|
|
2239
|
+
|
|
2240
|
+
Exact commands, nine-failure census, hashes, artifact medians, and scope limits:
|
|
2241
|
+
[`PERFORMANCE.md`](../../PERFORMANCE.md#0214-released-01624-rerun-2026-09-07).
|
|
2242
|
+
Local raw evidence is
|
|
2243
|
+
`test-results/ai-delivery-production/0.21.4-gpt-5.6-sol-r5-kudzu-0.16.24-20260907-01/`.
|
|
2244
|
+
Six integrity/lifecycle tests, `npm run check`, and the standalone ownership gate
|
|
2245
|
+
plus 308 tests pass. No commit, version bump, publication, or release is part of
|
|
2246
|
+
this continuation.
|
|
2247
|
+
|
|
2248
|
+
### r5 Compiler Follow-Up
|
|
2249
|
+
|
|
2250
|
+
The evidence-backed follow-up is implemented without changing the dirty r5/r6
|
|
2251
|
+
protocol, prompt, contract, or acceptance work. The two content reductions were
|
|
2252
|
+
confirmed red before compiler changes: direct JSX `.length` over a normalized
|
|
2253
|
+
query filter threw `query.trim is not a function`, and the unchanged static topic
|
|
2254
|
+
filter emitted list state/scripts. Existing count dependency registration now
|
|
2255
|
+
selects signal build values, while direct imported pipelines without selector
|
|
2256
|
+
states or collection aliases stay in ordinary build-time map execution.
|
|
2257
|
+
BindingIR, DerivedIR, KeyedBlockIR, and route/keyed/conditional ownership remain
|
|
2258
|
+
unchanged; reactive selectors retain the existing list path and negative checks.
|
|
2259
|
+
|
|
2260
|
+
Realtime source tracing closes the proposed lifetime extension negatively.
|
|
2261
|
+
Attempts 0/3 correctly reject version refs without cleanup reset; moving them
|
|
2262
|
+
into invocation-private closures would lose the version on pause/resume. Attempt
|
|
2263
|
+
1 exposes a separate diagnostic gap: render-written null refs were accepted as
|
|
2264
|
+
DOM refs, which serialize an ID rather than the retained numeric value. Existing
|
|
2265
|
+
ref normalization now rejects those writes at source. No cross-invocation ref,
|
|
2266
|
+
resource primitive, runtime, or arbitrary callback support was added. Original
|
|
2267
|
+
state-based attempts 2/4 still pass the realtime browser journey.
|
|
2268
|
+
|
|
2269
|
+
Accounting: semantic primitives, IR kinds, core passes, normalization entries,
|
|
2270
|
+
transform/adapter rules, runtime concepts/source, and APIs all +0; core semantic
|
|
2271
|
+
LOC +5, focused normalization LOC +2, one diagnostic guard, two positive and two
|
|
2272
|
+
negative reduced cases. The four search variants emit identical JavaScript at
|
|
2273
|
+
32,190 raw / 12,324 gzip B. All five final content sources plus the recovered
|
|
2274
|
+
first attempt-1 patch pass the prepared r6 acceptance, including every one of the
|
|
2275
|
+
ten static siblings and combined polite regions. Each deploy removes four topic
|
|
2276
|
+
JavaScript files totaling 20,539 raw / 7,299 gzip B, including 20,462 / 7,204 B of
|
|
2277
|
+
runtime files; every retained JavaScript file is byte-identical to r5.
|
|
2278
|
+
|
|
2279
|
+
`npm run check`, the standalone ownership gate plus 315 required-Chrome tests,
|
|
2280
|
+
and package smoke pass with 1,200,000 ms command timeouts. Exact source locations,
|
|
2281
|
+
replay hashes, commands, output tables, diagnostic boundaries, and local evidence
|
|
2282
|
+
are in [`PERFORMANCE.md`](../../PERFORMANCE.md#r5-compiler-follow-up-2026-09-07).
|
|
2283
|
+
This is source replay, not AI rescoring: r5 remains 18/25 versus 23/25 with partial
|
|
2284
|
+
traces, and published r2 remains 11/25 versus 24/25. No model rerun, timing claim,
|
|
2285
|
+
commit, release, or `1.0.0` authorization follows. The next benchmark decision
|
|
2286
|
+
must use the aligned r6 protocol in a separately authorized complete run, not
|
|
2287
|
+
selective retries or broader compiler semantics without new evidence.
|
|
2288
|
+
|
|
2289
|
+
### 0.16.25 Release Transaction
|
|
2290
|
+
|
|
2291
|
+
The user-authorized patch packages the preceding r5 records, compiler fixes,
|
|
2292
|
+
render-ref diagnostic, and future-only r6 acceptance alignment as core 0.16.25
|
|
2293
|
+
and create-kudzu 0.1.150. The pre-release session records above remain historical.
|
|
2294
|
+
R6 accepts semantically named CRUD groups and combined polite count/empty regions,
|
|
2295
|
+
and checks all ten content static siblings. Its hashes and published 0.16.24
|
|
2296
|
+
starter pins remain frozen; testing 0.16.25 in a model run requires a new frozen
|
|
2297
|
+
revision. No fresh model run, score replacement, persistent-ref support, or
|
|
2298
|
+
`1.0.0` authorization is part of this release.
|
|
2299
|
+
|
|
2186
2300
|
## `1.0.0`: Stable Application Model
|
|
2187
2301
|
|
|
2188
2302
|
`1.0.0` is authorized only after every required `0.21.x` gate passes. It means:
|
|
@@ -2328,4 +2442,4 @@ release transaction where possible or document and publish a forward-fix patch.
|
|
|
2328
2442
|
| `0.21.1` | Released as `0.16.16` | Preserve 100/1,000/10,000-route phase, RSS, output, digest, incremental-equivalence, recovery, and bounded canonical-AST retention evidence. | Full 10,000-route report has one complete measured run after two measured-stage diagnostics; no projection used |
|
|
2329
2443
|
| `0.21.2` | Closed by existing semantics | Preserve initial/session/lazy bytes, keyed/range/navigation median alarms, and bounded endurance ownership evidence. | Same-revision absolute gates; structural artifact bytes are not compressed network transfer |
|
|
2330
2444
|
| `0.21.3` | Released as `0.16.17` | Preserve exact package, browser, benchmark, registry, and fresh-install evidence. | One initial navigation benchmark invocation stalled at the outer timeout; its clean seven-profile rerun passed all alarms |
|
|
2331
|
-
| `0.21.4` |
|
|
2445
|
+
| `0.21.4` | r5 executed all 50 attempts; compiler follow-up verified; gate remains blocked | Preserve raw scores and partial traces. Direct-count/static-topic fixes and the render-ref diagnostic are verified; persistent version refs remain unsupported. Use aligned r6 only in a separately authorized complete run. | Local historical r5 scorer: Kudzu 18/25 versus React + Vite 23/25, with two partial Kudzu traces. Source replay passes all ten content static siblings but does not replace scores. Published r2 remains 11/25 versus 24/25. |
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Current Compiler Architecture
|
|
2
2
|
|
|
3
|
-
This maps the current `0.16.
|
|
3
|
+
This maps the current `0.16.25` architecture, built on the completed `0.9.0` semantic-compression release and `0.8.23` Goal A compiler foundation. The `0.21.4` AI delivery gate is measured and blocked; file and function names are the stable references, while line numbers are intentionally omitted because later work may still move code.
|
|
4
|
+
|
|
5
|
+
The r5 follow-up registers direct collection-count query build values and leaves proven direct imported static selectors in build-time map execution. Existing ref normalization rejects render-written mutable refs; persistent cross-effect version refs remain unsupported. These changes add seven compiler lines, no pass, IR kind, or runtime concept.
|
|
4
6
|
|
|
5
7
|
## Responsibility Map
|
|
6
8
|
|
|
@@ -66,7 +66,7 @@ Keep each patch behavior-preserving and independently reviewable. If a boundary
|
|
|
66
66
|
|
|
67
67
|
## Generator Versions
|
|
68
68
|
|
|
69
|
-
`create-kudzu@0.1.
|
|
69
|
+
`create-kudzu@0.1.150` retains the explicit install instructions and generates projects with `@kudzujs/core@^0.16.25`.
|
|
70
70
|
|
|
71
71
|
## Release Boundary
|
|
72
72
|
|
|
@@ -73,7 +73,7 @@ export function analyzeCollectionPipeline(expression, options) {
|
|
|
73
73
|
if (!source) return undefined
|
|
74
74
|
const parameters = collectionParameters(value.arguments[0], "Rendered collection filter()", fail)
|
|
75
75
|
const selectorStates = new Set(source.selectorStates)
|
|
76
|
-
return { ...source, selector: [...source.selector, ["filter", collectionExpression(unwrapExpression(value.arguments[0].body), { parameters, fail, stateNames, selectorStates })]], selectorStates }
|
|
76
|
+
return { ...source, selector: [...source.selector, ["filter", collectionExpression(unwrapExpression(value.arguments[0].body), { parameters, fail, stateNames, selectorStates, declarations })]], selectorStates }
|
|
77
77
|
}
|
|
78
78
|
if (method === "flatMap") {
|
|
79
79
|
if (value.arguments.length !== 1) fail(value, "Rendered collection flatMap() requires one inline projector")
|
|
@@ -122,7 +122,7 @@ export function analyzeCollectionPipeline(expression, options) {
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
export function collectionExpression(expression, { parameters = {}, fail, stateNames = new Set(), selectorStates = new Set() }) {
|
|
125
|
+
export function collectionExpression(expression, { parameters = {}, fail, stateNames = new Set(), selectorStates = new Set(), declarations, aliases = new Set() }) {
|
|
126
126
|
const encode = node => {
|
|
127
127
|
node = unwrapExpression(node)
|
|
128
128
|
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node) || ts.isNumericLiteral(node)) return ["value", ts.isNumericLiteral(node) ? Number(node.text) : node.text]
|
|
@@ -137,6 +137,19 @@ export function collectionExpression(expression, { parameters = {}, fail, stateN
|
|
|
137
137
|
selectorStates.add(node.text)
|
|
138
138
|
return ["state", node.text]
|
|
139
139
|
}
|
|
140
|
+
const entries = declarations?.get(node.text)
|
|
141
|
+
if (entries?.length === 1 && entries[0].node.parent?.parent?.parent === nearestFunction(entries[0].node)?.body) {
|
|
142
|
+
if (aliases.has(node.text)) fail(node, `Rendered collection expression local cycle at "${node.text}"`)
|
|
143
|
+
aliases.add(node.text)
|
|
144
|
+
const dependencies = new Set()
|
|
145
|
+
const result = collectionExpression(entries[0].initializer, { fail, stateNames, selectorStates: dependencies, declarations, aliases })
|
|
146
|
+
for (const name of dependencies) {
|
|
147
|
+
if (name === parameters.item || name === parameters.index) fail(node, `Rendered collection expression local "${node.text}" cannot capture state shadowed by predicate parameters`)
|
|
148
|
+
selectorStates.add(name)
|
|
149
|
+
}
|
|
150
|
+
aliases.delete(node.text)
|
|
151
|
+
return result
|
|
152
|
+
}
|
|
140
153
|
fail(node, `Rendered collection expression identifier "${node.text}" is not allowed`)
|
|
141
154
|
}
|
|
142
155
|
if (ts.isPropertyAccessExpression(node)) {
|
|
@@ -72,6 +72,8 @@ export function normalizeEffectPrivateRefs(sourceFile, factory, context) {
|
|
|
72
72
|
if (frameAssignments.length && invalidReference) throw sourceNodeError(invalidReference, sourceFile, "Animation frame refs may only use direct .current reads and assignments")
|
|
73
73
|
if (frameAssignments.length && !topLevelConst) throw sourceNodeError(node, sourceFile, "Animation frame refs must be one top-level component const")
|
|
74
74
|
if (attachedToJsx && mutations.length) throw sourceNodeError(mutations[0], sourceFile, "JSX object refs may not assign to ref.current")
|
|
75
|
+
const renderWrite = mutations.find(access => nearestFunction(access) === owner)
|
|
76
|
+
if (renderWrite) throw sourceNodeError(renderWrite, sourceFile, "Mutable refs cannot be assigned during render; use component state for values retained across effect replacements, or an effect-private ref with cleanup for invocation-local values")
|
|
75
77
|
if (!topLevelConst || invalidReference || !accesses.length) return
|
|
76
78
|
const effectCalls = owner.body.statements.flatMap(statement => hasUseEffectImport && ts.isExpressionStatement(statement) && ts.isCallExpression(statement.expression) && ts.isIdentifier(statement.expression.expression) && statement.expression.expression.text === "useEffect" && !isShadowedIdentifier(statement.expression.expression, sourceFile) ? [statement.expression] : [])
|
|
77
79
|
const effects = effectCalls.filter(effect => {
|
|
@@ -1149,7 +1149,7 @@ function createKudzuTransformer({ semantic, handlerUrl, file, sourceFiles, sourc
|
|
|
1149
1149
|
if (!isUnshadowedGlobal(roundAccess.expression, sourceFile)) fail(roundAccess.expression, "Reactive JSX Intl.NumberFormat requires the unshadowed global Math object")
|
|
1150
1150
|
collectionExpression(rounded.arguments[0], { fail: (node, message) => fail(node, message.replace("Rendered collection", "Reactive JSX local")), stateNames: allowedNames })
|
|
1151
1151
|
}
|
|
1152
|
-
const resolveReactiveJsxExpression = (expression, owner, setters) => {
|
|
1152
|
+
const resolveReactiveJsxExpression = (expression, owner, setters, buildDeclarations) => {
|
|
1153
1153
|
const declarations = jsxLocalDeclarations.get(owner)
|
|
1154
1154
|
if (!declarations) return expression
|
|
1155
1155
|
const substitutions = new Map()
|
|
@@ -1187,6 +1187,7 @@ function createKudzuTransformer({ semantic, handlerUrl, file, sourceFiles, sourc
|
|
|
1187
1187
|
const captures = captureNames(expanded, expanded, setters, bindingIndex)
|
|
1188
1188
|
const allowedNames = new Set([...setters.values(), ...captures])
|
|
1189
1189
|
validateReactiveJsxExpression(expanded, allowedNames, setters)
|
|
1190
|
+
if (buildDeclarations) for (const name of substitutions.keys()) buildDeclarations.add(declarations.get(name)[0].node)
|
|
1190
1191
|
return expanded
|
|
1191
1192
|
}
|
|
1192
1193
|
const componentSpecializations = new WeakMap()
|
|
@@ -1696,6 +1697,7 @@ function createKudzuTransformer({ semantic, handlerUrl, file, sourceFiles, sourc
|
|
|
1696
1697
|
const collectionAliasUses = rawRenderedLists.flatMap(({ parts }) => parts.aliasUses ?? [])
|
|
1697
1698
|
const collectionAliasDeclarations = new Set(rawRenderedLists.flatMap(({ parts }) => parts.aliasDeclarations ?? []))
|
|
1698
1699
|
const collectionLengthDeclarations = new Set()
|
|
1700
|
+
const collectionValueDeclarations = new Set()
|
|
1699
1701
|
for (const declaration of collectionAliasDeclarations) {
|
|
1700
1702
|
const owner = nearestFunction(declaration)
|
|
1701
1703
|
const unsupported = identifierReferences(owner.body, declaration.name.text).find(reference => {
|
|
@@ -1707,12 +1709,28 @@ function createKudzuTransformer({ semantic, handlerUrl, file, sourceFiles, sourc
|
|
|
1707
1709
|
collectionLengthDeclarations.add(current)
|
|
1708
1710
|
return false
|
|
1709
1711
|
}
|
|
1710
|
-
if (ts.isJsxExpression(current) && current.initializer === undefined)
|
|
1712
|
+
if (ts.isJsxExpression(current) && current.initializer === undefined) {
|
|
1713
|
+
resolveReactiveJsxExpression(reference.parent, owner, settersForNode(reference, settersByFunction), collectionValueDeclarations)
|
|
1714
|
+
return false
|
|
1715
|
+
}
|
|
1711
1716
|
}
|
|
1712
1717
|
return true
|
|
1713
1718
|
})
|
|
1714
1719
|
if (unsupported) fail(unsupported, `Rendered collection alias "${declaration.name.text}" may only be used as a rendered collection source`)
|
|
1715
1720
|
}
|
|
1721
|
+
for (const [owner, declarations] of jsxLocalDeclarations) for (const entries of declarations.values()) {
|
|
1722
|
+
if (entries.length !== 1 || entries[0].node.parent?.parent?.parent !== owner?.body) continue
|
|
1723
|
+
const { node, initializer } = entries[0]
|
|
1724
|
+
const value = unwrapExpression(initializer)
|
|
1725
|
+
if (!ts.isPropertyAccessExpression(value) || value.name.text !== "length") continue
|
|
1726
|
+
const setters = settersForNode(node, settersByFunction)
|
|
1727
|
+
const expression = resolveReactiveJsxExpression(initializer, owner, setters, collectionValueDeclarations)
|
|
1728
|
+
if (!referencedStateNames(expression, setters).size) continue
|
|
1729
|
+
const collection = analyzeCollectionPipeline(unwrapExpression(expression).expression, { setters, declarations, fail, importedCollections, stateNames: new Set(setters.values()), importedCollectionTransforms })
|
|
1730
|
+
if (!collection?.selector.length) continue
|
|
1731
|
+
validateReactiveJsxExpression(expression, new Set(setters.values()), setters)
|
|
1732
|
+
collectionLengthDeclarations.add(node)
|
|
1733
|
+
}
|
|
1716
1734
|
const rejectUnsupportedRenderControl = node => {
|
|
1717
1735
|
if (ts.isIfStatement(node) && containsRenderControl(node, jsxLocalsByFunction.get(nearestFunction(node)) ?? new Set())) {
|
|
1718
1736
|
const setters = settersForNode(node, settersByFunction)
|
|
@@ -2229,12 +2247,12 @@ function createKudzuTransformer({ semantic, handlerUrl, file, sourceFiles, sourc
|
|
|
2229
2247
|
return factory.updateVariableDeclaration(node, node.name, node.exclamationToken, node.type, factory.createIdentifier("undefined"))
|
|
2230
2248
|
}
|
|
2231
2249
|
|
|
2232
|
-
if (ts.isVariableDeclaration(node) && collectionLengthDeclarations.has(node)
|
|
2250
|
+
if (ts.isVariableDeclaration(node) && node.initializer && (collectionLengthDeclarations.has(node) || collectionValueDeclarations.has(node))) {
|
|
2233
2251
|
const setters = settersForNode(node, settersByFunction)
|
|
2234
2252
|
const expression = resolveReactiveJsxExpression(node.initializer, nearestFunction(node), setters)
|
|
2235
2253
|
const stateNames = new Set(setters.values())
|
|
2236
2254
|
const rewrite = current => {
|
|
2237
|
-
if (ts.isIdentifier(current) && stateNames.has(current.text) && isReferenceIdentifier(current)) return factory.createPropertyAccessExpression(current, "value")
|
|
2255
|
+
if (ts.isIdentifier(current) && stateNames.has(current.text) && isReferenceIdentifier(current) && !isShadowedByParameter(current, expression)) return factory.createPropertyAccessExpression(current, "value")
|
|
2238
2256
|
return ts.visitEachChild(current, rewrite, context)
|
|
2239
2257
|
}
|
|
2240
2258
|
return factory.updateVariableDeclaration(node, node.name, node.exclamationToken, node.type, ts.visitNode(expression, rewrite))
|
|
@@ -2449,6 +2467,8 @@ function keyedListParts(expression, setters, declarations, fail, aliases = new S
|
|
|
2449
2467
|
const field = keyExpression && directProperty(keyExpression, parameters.item)
|
|
2450
2468
|
const positional = Boolean(keyExpression && parameters.index && ts.isIdentifier(unwrapExpression(keyExpression)) && unwrapExpression(keyExpression).text === parameters.index)
|
|
2451
2469
|
if (!field && !positional) fail(key ?? root, `Keyed list root must have key={${parameters.item}.<field>} or key={${parameters.index ?? "index"}}`)
|
|
2470
|
+
// Direct build-known imports can execute their map without keyed browser ownership.
|
|
2471
|
+
if (collection.static && !collection.localStatic && !collection.selectorStates.size && !collection.aliasDeclarations?.length) return undefined
|
|
2452
2472
|
return { ...collection, static: collection.static && (!collection.localStatic || collection.selector.length > 0), callback, root, item: parameters.item, index: parameters.index, indexed: Boolean(parameters.index), keyField: positional ? null : field }
|
|
2453
2473
|
}
|
|
2454
2474
|
|
|
@@ -3526,16 +3546,27 @@ function importedSerializableCollections(sourceFile, file, sourceFiles, sourceIn
|
|
|
3526
3546
|
for (const statement of sourceFile.statements) if (ts.isImportDeclaration(statement) && ["react", "@kudzujs/core"].includes(statement.moduleSpecifier.text) && statement.importClause?.namedBindings && ts.isNamedImports(statement.importClause.namedBindings)) {
|
|
3527
3547
|
for (const entry of statement.importClause.namedBindings.elements) if ((entry.propertyName ?? entry.name).text === "useMemo") memoNames.add(entry.name.text)
|
|
3528
3548
|
}
|
|
3549
|
+
const visitedAliases = new Set()
|
|
3529
3550
|
const collectRoot = node => {
|
|
3530
|
-
if (ts.isPropertyAccessExpression(node) && ["filter", "flatMap", "slice", "toSorted", "map"].includes(node.name.text)) {
|
|
3551
|
+
if (ts.isPropertyAccessExpression(node) && ["filter", "flatMap", "slice", "toSorted", "map", "length"].includes(node.name.text)) {
|
|
3531
3552
|
let expression = node.expression
|
|
3532
3553
|
while (ts.isCallExpression(expression) || ts.isPropertyAccessExpression(expression)) expression = expression.expression
|
|
3533
|
-
if (ts.isIdentifier(expression))
|
|
3554
|
+
if (ts.isIdentifier(expression)) {
|
|
3555
|
+
if (!isShadowedIdentifier(expression, sourceFile)) mapped.add(expression.text)
|
|
3556
|
+
const owner = nearestFunction(node)
|
|
3557
|
+
if (owner?.body && ts.isBlock(owner.body)) for (const statement of owner.body.statements) {
|
|
3558
|
+
if (!ts.isVariableStatement(statement) || !(statement.declarationList.flags & ts.NodeFlags.Const)) continue
|
|
3559
|
+
for (const declaration of statement.declarationList.declarations) if (ts.isIdentifier(declaration.name) && declaration.name.text === expression.text && declaration.initializer && !visitedAliases.has(declaration)) {
|
|
3560
|
+
visitedAliases.add(declaration)
|
|
3561
|
+
collectRoot(declaration.initializer)
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
}
|
|
3534
3565
|
}
|
|
3535
3566
|
ts.forEachChild(node, collectRoot)
|
|
3536
3567
|
}
|
|
3537
3568
|
const visit = node => {
|
|
3538
|
-
if (ts.isPropertyAccessExpression(node) && node.name.text
|
|
3569
|
+
if (ts.isPropertyAccessExpression(node) && ["map", "length"].includes(node.name.text)) {
|
|
3539
3570
|
collectRoot(node)
|
|
3540
3571
|
}
|
|
3541
3572
|
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && memoNames.has(node.expression.text) && node.arguments[0]) collectRoot(node.arguments[0])
|