Repository navigation
ci: measure a plugin's rebuild loop on Linux, per backend and incremental - #292
Merged
Merged
Conversation
2 tasks done
A plugin rebuilt under a running fizzy used to be reloaded on the UI thread, and its `dlopen` — on macOS 180-220 ms for a file the system has not seen, which a rebuild always is — froze the person's frame for that long. The `dlopen` was the whole cost: the plugin's `register` takes ~30 us. `PluginLoader` splits into `open` (copy, `dlopen`, ABI and SDK checks; nothing of the host's, so any thread) and `register` (on the UI thread); `loadAndRegister` is the two in a row, so startup is unchanged. The watcher's reload (`PluginReloads`) opens the new build on a worker while the old one keeps running, and a later frame swaps them: ~8 ms on the UI thread (unload ~4 ms, register ~4 ms), the ~175 ms open off it. Part of #250. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntal `.github/workflows/plugin-loop.yml` (on demand, and on PRs touching the loop's files; not part of ci-ok) runs scripts/plugin-loop/bench.py on Linux for `plugins/image`: cold, nothing changed and one-line-edit builds in Debug and ReleaseFast with Zig's default backend, LLVM forced and self-hosted forced, and edits under `zig build --watch -fincremental`, written to the job summary. A `zig_version` input re-measures on a newer Zig — 0.17 is expected to carry incremental compilation further. `FIZZY_PLUGIN_USE_LLVM=1|0` (read by sdk/plugin_sdk.zig) forces a plugin build's code generator. The bench gains `--backend`, `--watch N` and `--summary`, reports a combination that cannot build as a row, and defaults to `plugins/image` (examples/ is moving out of the repo, #282). Compiler experiments run here, not on a shared workstation: forcing the self-hosted backend locally, beside other sessions' compiles, took a machine's memory down. Part of #250. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
foxnne
force-pushed
the
app/reload-off-thread
branch
from
October 9, 2026 18:47
ccded80 to
aba2bc6
Compare
Collaborator
Author
|
Heads-up: 🤖 Generated with Claude Code |
2 of 5 tasks
foxnne
added a commit
that referenced
this pull request
Oct 9, 2026
## What changes Fizzy's plans move to a private repo, [`fizzyedit/plans`](https://github.com/fizzyedit/plans), open to the `fizzyedit` organization. Where fizzy is going can then be worked out without every edit being public. - **Moved (15):** every `docs/*_PLAN.md`, both `REVIEW_*` docs, `TRANSITIONS_HANDOFF.md`, `LIB_CHECKPOINT.md`. The plans repo has them as of `main` `a2b4e0a7`, plus the `AGENTS_PLAN.md` edits from #287, #290, #291 and #292, so those PRs drop their doc changes. - **Staying public:** `PLUGINS.md`, `AUTOMATION.md`, `DEPENDENCIES.md`, the live-resize measurements, release notes, `demos/`. - **Test data:** the markdown layout tests embedded `docs/PLUGIN_MANIFEST_PLAN.md` as their table-heavy sample (and the markdown bench as prose). It moves to `tests/data/markdown_sample_tables.md` as a frozen copy: that text was already public in this repo's history, the plan is essentially done, and later edits to it stay private. I tried a synthetic sample of the same shape first, and it exposed a real preview bug: a large table of wrapping rows gets a different height before and after it is laid out (`block heights do not depend on where the reader is` and `rapid scrolling` fail). That's filed separately rather than fixed here. - **References:** in code comments and docs, a plan path reads `plans/X.md` (48 files). Markdown links point into the plans repo, which works for members. - **`CLAUDE.md`** says what `plans/X.md` means, where to clone it, and that a session without access works from the code and public docs. **`CONTRIBUTING.md`** says plans and their issues live there, and that a PR here carries what a reviewer without access needs. **What this doesn't do:** fizzy's history still holds every plan as it was. Moving them hides future edits only; rewriting history would break every clone. ## SDK impact - [x] None (comments and docs only) ## Verified - [x] macOS: all five gates pass after the sweep. `zig build test-integration`: 33/33 steps, 347/347. No reference to a moved file is left. ## Follow-ups - #282 (another session) edits `docs/AGENTS_PLAN.md` and `docs/WORKSPACES_PLAN.md`. Its plan edits belong in the plans repo once this lands. - My open #287, #290, #291 and #292 drop their `AGENTS_PLAN.md` edits, which are already in the plans repo. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
foxnne
marked this pull request as ready for review
October 10, 2026 01:08
foxnne
enabled auto-merge (squash)
October 10, 2026 01:08
foxnne
added a commit
that referenced
this pull request
Oct 10, 2026
## What changes `sdk_version` goes from 0.2.19 to 0.2.20. Merging tags `sdk-v0.2.20`, publishes its tarball, and asks the store plugins to repin. **Why now.** The plugin boundary's fingerprint has not moved since `sdk-v0.2.19` (`0x7b455e7a…` both), so plugins built against 0.2.19 still load. But `core/` and `sdk/replay` changes merged since then reach plugins only through a release, and the agent plugin (`fizzyedit/agent`, private until it can pin a released SDK) needs one of them: #295's profiler on request. ## SDK impact - [ ] None - [ ] Core-only or additive: reaches plugins at the next SDK release - [ ] Fingerprint moved: recorded in `sdk/src/version.zig`, `sdk_version` untouched, PR labelled `sdk` - [x] SDK release: bumps `sdk_version`, lists the `sdk` PRs since the last `sdk-v*` tag **The `sdk` PRs since `sdk-v0.2.19`:** none; the fingerprint is unchanged. **What reaches plugins (`core/`, `sdk/`):** - #295: the profiler records on request (`core.profile.want`) and reports as ZON (`core.profile.report`). `Profiler` grew a field (`abi` 3 → 4), so a plugin records its own sections into the host's profiler again only once rebuilt against this release. - #310: `replay.Input.synthetic`, which tells a tape's key from the OS's. - #293: the replay `Player` plays and seeks every bundled demo exactly. - #313: `core.dialogs` changes for a run of the real app that plays a tape to a verdict. - #312: `core/gfx`'s programs and the liquid-glass shader, now that the native backend is a package of its own. - #292: `sdk/plugin_sdk.zig` honours `FIZZY_PLUGIN_USE_LLVM`, for measuring a plugin's rebuild loop per code generator. ## Verified - [x] macOS: - `zig build` and `test-sdk-version` on this head. - `scripts/pack-sdk.sh` packs `fizzy-sdk-v0.2.20.tar.gz`. - Every store plugin (fresh clones of pixi, zig, drive, atlas and ghostty `main`) builds against this tree's `sdk/` with `zig build --fork=<sdk>` (31/31 and 28/28 steps), installing into a throwaway profile. The fork matched, and the built plugin reports `pinned fizzy SDK: 0.2.20`. With the fingerprint unchanged, the repins should open as plain version bumps. - The agent plugin (path dependency on `main`'s `sdk/`) builds, 21/21 steps. - [ ] Windows: - [ ] Linux: CI. - [ ] Web: ## Follow-ups - Each repin PR merged and its plugin tagged (the plugin repos' tags stay the maintainer's). - `fizzyedit/agent` repins from its local path to the `sdk-v0.2.20` tarball. - fizzyedit/example-plugin repins once `PLUGIN_DISPATCH_TOKEN` can reach it (#281, still open). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
foxnne
added a commit
that referenced
this pull request
Oct 10, 2026
Part of #281. **Merge after fizzyedit/example-app#2**: this PR's CI clones example-app's `main` and builds its replay app, which lands there in #2. ## What changes `examples/replay-app` moves to fizzyedit/example-app, as `zig build run-replay`, now that SDK 0.2.19 ships `replay`. Fizzy's `examples/` folder is gone. - `scripts/check-examples.sh` also swaps example-app's `fizzy_sdk` pin for this tree's SDK, packed as a release would be, and builds the replay app. So replay is still built against every pull request. - The CI step that built `examples/replay-app` by path is gone. - `sdk/replay_module.zig`, `docs/AUTOMATION_PLAN.md` and `docs/AGENTS_PLAN.md` point at example-app's replay app. **Not changed here:** `scripts/plugin-loop/bench.py` still defaults to `examples/hello-plugin`, which #282 removed. #292 is rewriting that script, so it is noted there rather than changed under it. ## SDK impact - [x] None (a doc comment in `sdk/replay_module.zig`) ## Verified - [x] macOS: - `scripts/check-examples.sh` against this tree and example-app with #2: example-plugin 28/28 steps; minimal, studio, endless 30/30; studio as data 31/31; the replay app 15/15. - `zig build` (43/43), `test-integration` (33/33 steps, 349 tests), `check-web`, `test-sdk-version`. - [ ] Windows: - [ ] Linux: CI, once example-app#2 has merged. - [ ] Web: 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #250. The compile is now nearly all of a plugin's rebuild loop (#285). This sets up its measurement on Linux CI. Stacked on #287, whose reload log the bench's
--appstage reads. Merge #287 first, then this PR's base moves tomain.What changes
.github/workflows/plugin-loop.yml, a measurement, not a gate (not part ofci-ok). It runs on demand, and on PRs touchingscripts/plugin-loop/**, the workflow itself orsdk/plugin_sdk.zig.plugins/image.zig build --watch -fincremental, each timed from save to installed.zig_versioninput: re-measuring on a newer Zig is one manual run (Actions → Plugin rebuild loop → Run workflow →0.17.0ormaster). Zig 0.17 is close to release and expected to carry incremental compilation further. A plugin that no longer builds on a newer Zig fails the run, which is worth knowing early too.FIZZY_PLUGIN_USE_LLVM=1|0(sdk/plugin_sdk.zig) forces a plugin build's code generator. Unset, Zig chooses. It's an environment variable rather than a-Doption because fizzy's own build creates several plugins on one builder, and an option may be declared only once.scripts/plugin-loop/bench.py:--backend,--watch N, and--summary FILE.plugins/image: examples: moved to fizzyedit/example-app and example-plugin #282 movesexamples/out of the repo, which would take the old default with it.--appstill needs a plugin fizzy doesn't bundle, and the docstring says so.plans/AGENTS_PLAN.md: the compile lever points at the workflow, and notes Zig 0.17.Why CI rather than a workstation. Forcing the self-hosted backend on an arm64 Mac, beside other sessions' compiles, coincided with a kernel panic: watchdog timeout, swap exhausted. An experimental backend on a large compile can use far more memory than LLVM. Runners are disposable.
SDK impact
sdk/plugin_sdk.zig(build-side) readsFIZZY_PLUGIN_USE_LLVM. Unset, nothing changes.test-sdk-versionpasses with the recorded fingerprint unchanged.Verified
test-integration33/33 steps, 347/347). A light local run of the bench (Debug,defaultandllvm, no watch,plugins/image) printed and wrote its summary table. I didn't run the self-hosted backend or the watch locally, on purpose.defaultand forcedllvmdiffering on arm64 macOS (one-line edit 2.7 s vs 5.0 s). Machine load also changed during it, so it means nothing until the Linux numbers are in.Follow-ups
--watch(the agent plugin's loop could keep one running), a smaller compile unit for plugins, or waiting for Zig 0.17.🤖 Generated with Claude Code