Skip to content

feat(#461): manifest-v2 PR8 — null + wgpu (generic declarative desktop path) - #469

Merged
apotema merged 2 commits into
mainfrom
feat/453-manifest-v2-pr8-null-wgpu
Jul 1, 2026
Merged

feat(#461): manifest-v2 PR8 — null + wgpu (generic declarative desktop path)#469
apotema merged 2 commits into
mainfrom
feat/453-manifest-v2-pr8-null-wgpu

Conversation

@apotema

@apotema apotema commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR 8 of the manifest-v2 epic (#461, #453 item 3). Converts null + wgpu — pure-declarative, HOOKLESS desktop backends. Beyond the fixtures, this adds the generic declarative desktop path that generalizes v2 desktop codegen beyond sokol.

Fixtures (mirrored from the real external backends)

  • backends/null_v2/backend.manifest.v2.zonid="labelle.null", capabilities={headless}, 4 modules, no artifact/frameworks/dep_options/hook, desktop .loop/.native/.binary (matches null's empty link fragment).
  • backends/wgpu_v2/backend.manifest.v2.zonid="labelle.wgpu", capabilities={compressed_textures}, glfw artifact, frameworks.desktop.macos={Foundation, QuartzCore, Metal}, no hook.

Generic declarative desktop path (load-bearing)

The prior desktop v2 path was sokol-specific (hardcoded IOSurface frameworks, sdl_gamepad overrides, with_imgui prose) to hold the byte anchor. Added renderDesktopDepsDeclsV2/renderDesktopBackendDepGenericV2/renderDesktopLinkGenericV2/emitDesktopOsLinks — a manifest-driven generic path (loop-form unifyCoreDiamond, manifest artifact link, per-OS syslib/framework switch). isDesktopByteAnchor(m) (keyed on dep_name=="labelle_sokol") routes sokol → the unrolled anchor, everything else → the generic path.

Golden cells + assertions

test/goldens/null_v2.build.zig + wgpu_v2.build.zig + asserts: 0 AST parse errors; NO backend_build_hook/resolve_target/post_wire (hookless); generic unifyCoreDiamond present; null links nothing; wgpu links glfw + the macOS Metal/Foundation/QuartzCore block. + unit tests for isDesktopByteAnchor/emitDesktopOsLinks.

Byte-anchor vs golden

The .backend_null/.backend_wgpu/.link_wgpu enum sections DO still exist, but a byte-anchor is not the right gate here: the v2 path deliberately emits the generic loop form (§7), which differs from the enum's unrolled overrides — so a reviewed golden is correct.

Sokol desktop byte anchor + android/ios/wasm goldens unchanged (sokol still routes to the anchor path). v1/enum unchanged (v2 via opt-in). zig build test + zig build exit 0.

Ref #461, #453.

https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw

Summary by CodeRabbit

  • New Features

    • Added new manifest-v2 backends for null (headless) and wgpu (GPU-backed), including desktop-only packaging.
    • Enhanced manifest-v2 build generation with generic desktop dependency/link wiring for non–byte-anchor manifests.
  • Bug Fixes

    • Fixed desktop backend deps and link setup to match declarative manifest-v2 expectations.
    • Improved unified “core diamond” wiring and ensured correct mirroring onto test roots.
  • Tests

    • Added new v2 golden coverage for null and wgpu backends.
    • Added unit tests for desktop routing helpers and identifier sanitization.

Convert the null and wgpu backends to the manifest-v2 build-graph schema
(epic #453 item 3, PR 8). Both are fully-declarative, HOOKLESS desktop
backends — the first cells to exercise the v2 codegen's generic declarative
desktop path (loop-form unifyCoreDiamond walk), as opposed to the sokol
desktop byte anchor (unrolled sokol residual, kept 0-diff).

- backends/null_v2/backend.manifest.v2.zon: headless, pure-Zig, no artifact,
  no frameworks, no dep_options, no build_hook. capabilities = {headless}.
- backends/wgpu_v2/backend.manifest.v2.zon: glfw artifact +
  frameworks.desktop.macos = {Foundation, QuartzCore, Metal}, no build_hook.
  capabilities = {compressed_textures}.

Codegen (manifest_v2_splice.zig):
- Add a generic declarative desktop path (renderDesktopDepsDeclsV2,
  renderDesktopBackendDepGenericV2, renderDesktopLinkGenericV2 +
  emitDesktopOsLinks) mirroring the android/ios/wasm generic emitters: no
  sokol-specific prose, loop-form core-diamond walk, manifest-driven artifact
  + per-OS system-lib/framework switch.
- isDesktopByteAnchor(m) routes the sokol fixture to the unrolled byte-anchor
  path and every other backend to the generic path, so the sokol-desktop
  0-diff anchor is untouched. Wired via desktopUsesGenericV2 in build_files.

Gate: reviewed golden snapshots (test/goldens/{null,wgpu}_v2.build.zig) —
NOT a byte-anchor. Although the .backend_null/.backend_wgpu/.link_wgpu enum
sections still exist in build_zig.txt, the v2 path deliberately emits the
generic loop form (differs from the enum's unrolled overrides), so per design
§7 the reviewed golden is the correct gate. Each golden is asserted
AST-valid, hookless (no backend_build_hook import / resolve_target /
post_wire), carries the generic walk, links wgpu's frameworks, and links
none for null.

zig build test: exit 0. zig build: exit 0. sokol byte anchor + all prior
v2 goldens unchanged.

Claude-Session: https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3020473c-8b07-4195-8c4c-598fa5c064b4

📥 Commits

Reviewing files that changed from the base of the PR and between 81b1f8f and ab266c8.

📒 Files selected for processing (4)
  • src/build_files.zig
  • src/codegen/manifest_v2_splice.zig
  • test/build_zig_tests.zig
  • test/goldens/wgpu_v2.build.zig
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/build_zig_tests.zig
  • src/build_files.zig
  • test/goldens/wgpu_v2.build.zig
  • src/codegen/manifest_v2_splice.zig

📝 Walkthrough

Walkthrough

Adds v2 backend manifests for the null and wgpu backends, plus generic desktop routing in build_files.zig and manifest_v2_splice.zig for manifest-v2 deps/link emission and core-diamond wiring. Also adds golden build scripts, fixture helpers, and validation tests for both backends.

Changes

Manifest-v2 generic desktop backend support

Layer / File(s) Summary
New v2 backend manifests
backends/null_v2/backend.manifest.v2.zon, backends/wgpu_v2/backend.manifest.v2.zon
Defines identity, capabilities, module sources, platform config, and hookless behavior for null and wgpu v2 backends.
Generic desktop v2 routing
src/build_files.zig, src/codegen/manifest_v2_splice.zig
Adds the desktop v2 predicate, routes deps and link emission through generic manifest-v2 helpers, and emits the shared core diamond walk for generic desktop builds.
Null v2 golden build and tests
test/goldens/null_v2.build.zig, test/build_zig_tests.zig, test/helpers.zig
Adds the null v2 golden build script, golden assertions, and fixture helpers used to generate and validate the output.
Wgpu v2 golden build and tests
test/goldens/wgpu_v2.build.zig, test/build_zig_tests.zig, test/helpers.zig
Adds the wgpu v2 golden build script, golden assertions, and fixture helpers used to generate and validate the output.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

Poem

I nibble the builds with a happy little hop,
Two v2 backends now spring into the shop,
One null, one wgpu, both neat and bright,
With goldens that purr and tests that feel right,
Thump thump! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding null and wgpu manifest-v2 support via a generic declarative desktop path.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/453-manifest-v2-pr8-null-wgpu

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the generic declarative path for desktop builds under the manifest-v2 schema, introducing support for hookless backends like null and wgpu. It adds manifest files, updates the build generator to conditionally emit generic desktop dependency declarations and the unifyCoreDiamond walk, and includes comprehensive tests with golden files. The review feedback highlights a potential compilation issue in the generated build.zig where artifact names from the manifest are used directly as Zig variable identifiers. If these names contain hyphens or start with digits, they will produce invalid Zig syntax, so sanitizing these identifiers is recommended.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +216 to +219
for (desktop.artifacts) |art| {
try w.print(" const {s} = backend_dep.artifact(\"{s}\");\n", .{ art.name, art.name });
if (art.pic) try w.print(" {s}.root_module.pic = true;\n", .{art.name});
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Artifact names defined in the manifest (such as art.name) are used directly as Zig variable identifiers. If an artifact name starts with a digit (e.g., 123lib) or contains invalid characters like hyphens (e.g., glfw-native), the generated build.zig will fail to compile.

Following the general rule, Zig identifiers must not start with a digit and must be valid identifiers. We should sanitize the variable name (for example, by replacing hyphens with underscores and prefixing with an underscore if it starts with a digit) while keeping the original string for the backend_dep.artifact(...) call.

References
  1. Zig identifiers must not start with a digit. When converting strings (such as file paths) to Zig identifiers, prefix the result with an underscore if the input starts with a digit to ensure the generated code is valid.

Comment on lines +853 to +855
for (desktop.artifacts) |art| {
try w.print(" exe.root_module.linkLibrary({s});\n", .{art.name});
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similarly to the artifact declaration, the variable name used here to link the library should be sanitized to ensure it matches the sanitized variable identifier, preventing compilation errors if the artifact name contains hyphens or starts with a digit.

References
  1. Zig identifiers must not start with a digit. When converting strings (such as file paths) to Zig identifiers, prefix the result with an underscore if the input starts with a digit to ensure the generated code is valid.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/codegen/manifest_v2_splice.zig (1)

189-241: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Optional: consolidate the four near-identical generic backend-dep emitters.

renderDesktopBackendDepGenericV2 is a structural clone of renderAndroidBackendDepV2, renderIosBackendDepV2, and renderWasmBackendDepV2, differing only in the .target alias string and the platform-entry accessor. The core-diamond walk-call block (Lines 225-239) is byte-identical across all four. A single helper parameterized by (target_alias, platform_entry) would collapse the family and remove drift risk as more backends are added. Deferrable — golden snapshots protect the emitted output today, so this is maintainability-only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/codegen/manifest_v2_splice.zig` around lines 189 - 241, Consolidate the
four near-identical generic backend-dep emitters into one shared helper to
reduce drift risk. `renderDesktopBackendDepGenericV2` is structurally the same
as `renderAndroidBackendDepV2`, `renderIosBackendDepV2`, and
`renderWasmBackendDepV2`, so extract the common emission logic and parameterize
only the target alias and platform-entry accessor. Keep the core-diamond
walk-call block and module/artifact emission behavior unchanged while
centralizing it behind the shared helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/goldens/wgpu_v2.build.zig`:
- Around line 66-108: The test build setup for test_root is missing the same
native linkage that exe.root_module already has, so backend imports can fail at
test link time. Mirror the glfw library and the macOS frameworks onto the
root_module passed to b.addTest in the test_root setup, using the same
conditional switch on target.result.os.tag so zig build test links the
wgpu-backed code correctly.

---

Nitpick comments:
In `@src/codegen/manifest_v2_splice.zig`:
- Around line 189-241: Consolidate the four near-identical generic backend-dep
emitters into one shared helper to reduce drift risk.
`renderDesktopBackendDepGenericV2` is structurally the same as
`renderAndroidBackendDepV2`, `renderIosBackendDepV2`, and
`renderWasmBackendDepV2`, so extract the common emission logic and parameterize
only the target alias and platform-entry accessor. Keep the core-diamond
walk-call block and module/artifact emission behavior unchanged while
centralizing it behind the shared helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 301dab20-7b6e-43d3-9612-1cc332f22b48

📥 Commits

Reviewing files that changed from the base of the PR and between 0f58ac8 and 81b1f8f.

📒 Files selected for processing (8)
  • backends/null_v2/backend.manifest.v2.zon
  • backends/wgpu_v2/backend.manifest.v2.zon
  • src/build_files.zig
  • src/codegen/manifest_v2_splice.zig
  • test/build_zig_tests.zig
  • test/goldens/null_v2.build.zig
  • test/goldens/wgpu_v2.build.zig
  • test/helpers.zig

Comment thread test/goldens/wgpu_v2.build.zig
… test_root links

Three valid findings on the generic declarative desktop path (PR 8, null/wgpu):

- gemini m×2: manifest artifact names were emitted verbatim as Zig variable
  identifiers at both the decl site (`const <name> = backend_dep.artifact(...)`)
  and the link site. Names like `glfw-native` / `123lib` would emit invalid Zig.
  Reuse `scan.sanitizePluginIdent` (hyphens/dots/invalid → `_`, leading digit →
  `_` prefix) via a new `artifactIdent` helper at BOTH sites so the declared
  variable and the link reference match. Unit test added.

- coderabbit Major: the generic desktop link attached linkLibrary(glfw) + the
  macOS frameworks to exe.root_module only, not test_root.root_module — so
  `zig build test` for a wgpu project could fail at link time. Factor the link
  emission into `emitDesktopLinkForTarget(target_var)` and emit it a second time
  onto test_root (after the test step declares it) via
  `renderDesktopTestLinkGenericV2`. Enum/sokol byte-anchor path links only exe;
  the generic path now links both. null emits nothing (no artifact/framework).
  wgpu golden updated to include the test_root links.

Claude-Session: https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw
@apotema
apotema merged commit 64bc9b7 into main Jul 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant