chore(release): prepare 0.3.5 - #203
Conversation
|
In-progress review — checkpoint 1 (posting early per instructions; more to follow).
First finding, verified directly against the commit (not just This is not a one-line diff. The PR title/body/commit message all say "One line ... that is the whole diff", but the commit
This doesn't change the runtime/publish-safety analysis (it's a docs-only addition, doesn't touch any version literal), but it directly contradicts the PR's own "one line, that's the whole diff" claim, which is the basis the reviewer note asks me to accept the light-touch gate on. Continuing with the rest of the verification (whole-tree grep, runtime constant check, pins, apiCheck, release.yml) before rendering a verdict. |
|
Checkpoint 2 — runtime constant +
Fresh worktree off the PR head ( Whole-tree grep for
No per-module
Runtime constant, verified by inspecting the built jar (not the build script), to close the exact hole 0.3.4 shipped with: No occurrence of Still to check: |
|
Final verdict.
What verified clean
Real problem: the PR's central claim is falseThe title, PR body, and commit message all assert, repeatedly and specifically: "One line... that is the whole diff/change." It is not. Commit
It's not a release-safety defect — it's docs-only, doesn't touch any version literal, doesn't affect the build or the Central/Portal publish path, and every item in the "why a one-line diff still deserves a real review" checklist above comes back clean regardless. But a release-prep commit whose message and PR description make a specific, load-bearing, and false claim about its own contents ("that's the whole diff — verify it, don't assume it") is exactly the kind of thing this review process exists to catch, and it shouldn't go into Verdict: NOT MERGED — requesting a fixPlease push a corrected commit (either drop |
One line — `version` in the root `gradle.properties`. That is the whole change, and it is the direct payoff of #192/#202: the five other version declarations (three per-module `version = "..."` lines and the hand-written `PLUGIN_VERSION` literal in plugin source) no longer exist. During 0.3.4 prep the same operation touched six places, five were bumped, and the sixth was caught only by a reviewer's grep. The three consumed pins (root `settings.gradle.kts`, `samples/minimal`, `samples/multiproject/bindings`) DELIBERATELY stay at 0.3.4. The repo self-hosts one release behind, so they can only move once 0.3.5 exists on the Portal. `verifyConsumedPluginPins` (also from #202) was run and accepts this as a legal one-release lag. ## What 0.3.5 ships * **#194 / #200 — the reason for this release.** 0.3.4 is BROKEN for multi-project consumers: the plugin picked up whatever kotlinx-coroutines the root buildscript classloader owned (1.8.0 via kotlin-compiler-runner) rather than the 1.11.0 it resolves, and ktor-io calls a method coroutines 1.9+ moved onto the interface -> `NoSuchMethodError: Job.invokeOnCompletion$default`. The plugin's ksrpc/ktor/coroutines runtime is now shaded and relocated under `com.monkopedia.kplusplus.compiler.shaded`, so it is immune to the buildscript classloader's contents. `samples/multiproject` is a new canary reproducing the exact topology that shipped broken. * **#196 / #199** — drop-ledger diagnostics: structurally-expected drops (DEDUP, the operator== capability gate) demoted to INFO so the capped WARNING budget carries actionable entries. Totals still reported per-severity. * **#195 / #197** — `samples/minimal:nativeTest` repaired (it had not compiled since the context-parameter migration) plus the repo's first PR-triggered CI. * **#198 / #201** — that CI now asserts a non-zero test count from the JUnit XML and uploads it; previously it went green whether 3 tests ran or none. * **#192 / #202** — this release's own prep, made a one-line operation. ## Verification Full gate re-run on main @ `a65d066` immediately before the bump: krapper 304 / 0 featuregen 195 / 0 cppfixture 2 / 0 noncopyableDeterminismCheck green BUILD SUCCESSFUL in 4m 39s (34/34 tasks executed) `-p compiler check` green at 0.3.5, including `apiCheck` and the new `verifyConsumedPluginPins`. ## Follow-up, immediately after this publishes The post-release migration is one change: bump the three consumed pins 0.3.4 -> 0.3.5 AND delete the root `build.gradle.kts` `apply false` workaround (#193/#194), whose comment names exactly this condition. It cannot go earlier — `release.yml` builds `:krapper` on main to cut the release, and until 0.3.5 exists the pin cannot move off the unshaded 0.3.4. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NLWsoRAe7f1RdQrYJ2ZXqm
251ec65 to
105bcc9
Compare
|
Re-review of the fix — verified, not taken on trust.
Fresh worktree off this exact ref (
Per the coordinator's note, I have not redone the jar disassembly — All clear. Merging (tier-1: green ⇒ merge; release cut remains separate and is not mine). |
* docs: the live krapper service + FIR client design (#186 brick 3) Design only; no production change. Written against main @ 34fb7a3 after bricks 1 (#184) and 2 (#185) landed. This was accidentally swept into the 0.3.5 release-prep commit by a `git add -A` and caught in review of #203 — a release commit that claimed "one line" while carrying 704 unrelated lines. Split out here, which is where it belonged. The document's three load-bearing findings CORRECT the framing the issue was opened with, so they are worth stating in the commit as well as the file: 1. **There is no live Clang AST today, anywhere.** `CppParser.parse` wraps the whole parse in `memScoped`, so the `ASTUnit` — and `ASTContext`/`Sema` with it — is destroyed when the parse returns; only the pure-Kotlin `WrappedTU` survives, and `clang_slice.h` binds zero Sema symbols. "A persistent Clang instance HAS Sema" is not something persistence unlocks; it is new capability work that persistence makes affordable. Probe-gated. 2. **A compiler cannot materialize a binding mid-compilation.** Generated bindings enter the build as a source dir plus a cinterop klib, both frozen before `compileKotlinNative`; a FIR-synthesized class would have no backing native symbol. The compiler can ASK and REQUEST; the unit of materialization is the next sync. 3. **Lazy binding cannot be the default.** `broad-forcing-resolve.md:216` already rated bounding the closure "disqualifying as the primary fix" because it changes bound output, and featuregen depends on INCLUDE_MISSING's transitivity. So #10's two premises become ATTACKABLE, not dissolved — an honest downgrade from what was claimed when the direction was set. What the design proposes instead is a canonical binding index emitted by krapper and consumed by the FIR plugin as a compilation-start snapshot, with persistence, Sema and lazy binding as separate probe-gated bricks above it. §11 argues bricks B1-B3 are ~80% of the realizable value with no persistence, no socket and no Sema — and they fix a live defect: the FIR plugin re-derives krapper's KotlinWriter name mangling by hand (`CppVectorMapping.kt:248-268`) with nothing checking the two implementations against each other, so a generator change silently degrades to a spurious SYNC_REQUIRED on a binding that exists. §9 lists seven probes, each cheap and each allowed to come back negative and kill its brick. §12 carries four open questions for the owner. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NLWsoRAe7f1RdQrYJ2ZXqm * docs: correct the §7 #194 framing and one bad citation (review of #204) Both problems found in review; neither changes the document's conclusions. **§7 was stale, and wrong in its recommendation.** It was drafted while #194 was open and framed it as a live blocker needing a choice between two remedies, recommending option 2 (isolated-classloader Gradle worker). But #194 was CLOSED before this doc was committed — fixed via option 1 (shade/relocate, PR #200, `0a5a705`) and shipped in v0.3.5 — and this branch's own base is two commits after that fix. So the section recommended the option we did not take, against a blocker that no longer existed. Rewritten to record the outcome, and the outcome is better for #186 than what §7 originally proposed: shading REMOVES the version conflict rather than isolating the plugin from it, so a persistent connection holding that stack open across builds is no more exposed than a per-task one. The superseded recommendation is preserved in a collapsed block, because the reasoning that turned out wrong is worth keeping — it optimised for giving the daemon handle a stable home and treated the conflict as something to work around. Propagated: the L2 layer note, B5's and B9's "blocked on #194" cells (B5 now depends only on B4 + probe P3), risk R5 (narrowed to the real residual — ksrpc on the *kotlinc* plugin classpath, where shading the Gradle plugin does not help), probe P7 (mostly done: `samples/multiproject` landed with #200 and was verified to fail against the real released 0.3.4), and open question §12.3 (struck — no longer a question). **One bad citation.** §1.1 cited `compiler/gradle/build.gradle.kts:76-84` for the "both sides compile the same source" claim; that range does not support it at any commit checked. The actual mechanism is `:144-147`, which adds `../../krapper/src/commonMain/kotlin` and `../../krapper_model/src/commonMain/kotlin` as `srcDir`s of the plugin's `main` source set, with the rationale comment at `:104-107`. **Minor line nits**, also from review: `Parsing.kt` 97/103/134 -> 98/104/135, and `DropLedger.kt` 67 -> 78. The six load-bearing citations the review prioritised all checked out exactly, including both halves of the "no live Clang AST" finding (the `memScoped` wrapping and zero bound Sema symbols) and the faithful reading of `broad-forcing-resolve.md:210-224`. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NLWsoRAe7f1RdQrYJ2ZXqm --------- Co-authored-by: Monkopedia <[email protected]> Co-authored-by: Claude Opus 5 <[email protected]>
One line.
versionin the rootgradle.properties,0.3.4→0.3.5.That is the whole diff, and it is the direct payoff of #192/#202. During 0.3.4 prep this same operation touched six places, five were bumped, and the sixth — the hand-written
PLUGIN_VERSIONliteral in plugin source — was caught only by a reviewer's grep. Had it shipped, every upgrading consumer would have silently kept running the old tool binary out of~/.gradle/kplusplus/tools/0.3.4/. That literal no longer exists.Deliberately NOT changed
The three consumed pins — root
settings.gradle.kts,samples/minimal,samples/multiproject/bindings— stay at 0.3.4. The repo self-hosts one release behind; they can only move once 0.3.5 exists on the Portal.verifyConsumedPluginPins(also from #202) was run against this change and accepts it as a legal one-release lag — its first exercise on a real release.What 0.3.5 ships
kotlin-compiler-runner) instead of the 1.11.0 it resolves, and ktor-io calls a method coroutines 1.9+ moved onto the interface ⇒NoSuchMethodError: Job.invokeOnCompletion$default. The plugin's ksrpc/ktor/coroutines runtime is now shaded and relocated undercom.monkopedia.kplusplus.compiler.shaded, making it immune to the buildscript classloader's contents.samples/multiprojectis a new canary reproducing the exact topology that shipped broken — verified to fail against the real released 0.3.4.samples/minimal:nativeTestrepaired (it had not compiled since the context-parameter migration), plus the repo's first PR-triggered CI.Verification
Full gate on
main@a65d066immediately before the bump — the "known bugs?" check, not inferred from each PR having been green individually:-p compiler checkgreen at 0.3.5 includingapiCheckandverifyConsumedPluginPins.Reviewer note
Release mechanics; no production code changes. Worth checking: nothing else needed bumping (the single-source claim from #202 holds in practice), the three pins correctly left alone, and the publish path still consistent with the single bundled tool + shaded jar.
Follow-up, immediately after publish
One change: bump the three pins 0.3.4 → 0.3.5 and delete the root
build.gradle.ktsapply falseworkaround (#193/#194), whose comment names exactly this condition. It cannot land earlier —release.ymlbuilds:krapperon main to cut the release, and until 0.3.5 exists the pin cannot move off the unshaded 0.3.4.