Skip to content

feat(#461): flip null to v2 in production (bump pin → labelle-null 0.2.0) - #474

Merged
apotema merged 3 commits into
mainfrom
feat/cutover-null-v2
Jul 1, 2026
Merged

apotema merged 3 commits into
mainfrom
feat/cutover-null-v2

Conversation

@apotema

@apotema apotema commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor

The first real production flip of the manifest-v2 cutover. Bumps builtinProvider(.null) → labelle-null 0.2.0 (which ships backend.manifest.v2.zon). With the generate cutover (#473) live, production generate now fetches null 0.2.0, auto-detects its v2 manifest, and builds the null backend via the declarative v2 build graph instead of the enum/v1 path.

null is the safest first backend to flip: headless, desktop-only, pure-declarative, hookless, zero-dep.

Validation

The examples-integration CI's null headless + plugin-controllers steps build and run a real project on the fetched external null — after this bump they exercise null-on-v2. Green CI = the v2 null build is equivalent to v1 in production (consistent with the reviewed null_v2 golden + the byte-identical desktop mechanism).

Only .null's version string changes; the other 5 backends stay on their current pins (v1). This is the incremental per-backend cutover.

Ref labelle-assembler#461.

https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw

Summary by CodeRabbit

  • Bug Fixes

    • Updated the built-in null backend to a newer version for improved compatibility and reliability.
    • Adjusted provider contract validation so capability enforcement is skipped when validating the tests-target build, while remaining strict for real executable builds.
  • Tests

    • Updated capability-validation scenarios for manifest-v2 behavior and added coverage for issue #83 to ensure tests-target validation differs correctly from exe validation.

labelle-null 0.2.0 ships backend.manifest.v2.zon. With the generate cutover
(#473) live, bumping builtinProvider(.null) means production `generate` now
fetches null 0.2.0, auto-detects its v2 manifest, and builds the null backend
via the declarative v2 build graph. First real production flip of the epic.
null is the safest first backend (headless, desktop-only, pure-declarative,
hookless). Validated by the null headless examples-integration CI (build+run
on v2).

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

coderabbitai Bot commented Jul 1, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@apotema, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 51d5983e-0d05-4661-8dda-3562ec138ad5

📥 Commits

Reviewing files that changed from the base of the PR and between be826cd and dc2cdbc.

📒 Files selected for processing (2)
  • src/build_files.zig
  • test/build_zig_tests.zig
📝 Walkthrough

Walkthrough

Updates the null backend’s built-in provider version and threads a tests-target flag through provider contract validation so capability checks are skipped for test builds while remaining enforced for real builds.

Changes

Provider mapping and validation flow

Layer / File(s) Summary
Bump null provider version
src/config.zig
The Backend.null builtin provider mapping now references labelle-null version 0.2.0.
Thread tests-target through contract validation
src/root.zig
validateProviderContracts and validateProviderContractsInner accept is_tests_target, and generate forwards it into validation.
Skip capability checks for tests targets
src/root.zig
Capability negotiation is skipped when is_tests_target is true, while provider identity and collision checks still run.
Update contract validation tests
test/build_zig_tests.zig
Existing calls pass the new boolean argument, and new cases cover tests-target skipping versus real-target failure.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Poem

I nibbled the null-backend leaf so light,
Then hopped through contracts by moonlit sight.
For tests I hush the capability drum,
For real builds, checks still clearly come.
Tiny carrots, tidy paths, all snug tonight 🐇

🚥 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 clearly summarizes the main change: cutting over the null backend to v2 by bumping the pin to labelle-null 0.2.0.
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/cutover-null-v2

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 updates the version of the .null provider package in src/config.zig from 0.1.0 to 0.2.0. I have no feedback to provide as there are no review comments.

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.

The tests target (#83) force-substitutes `cfg.backend = .null` as a
headless test harness while keeping the rest of the project config (e.g.
`resolved_gui = imgui`), so `requiredCapabilities(cfg)` still derives the
REAL backend's needs (`.raw_gui_adapter`, …). Now that null ships a v2
manifest declaring only `.headless`, the opted-in capability gate
hard-failed `zig build test` (`UnsupportedCapability`) for every
GUI/gamepad project — surfaced by the null→v2 flip in #474 CI.

Thread `is_tests_target` into `validateProviderContracts` /
`validateProviderContractsInner` and skip ONLY the capability requirement
check for the forced-null tests harness. Identity + id-collision checks
still run (cheap + valid). The real exe target is unaffected: a GUI project
whose CHOSEN backend lacks `.raw_gui_adapter` still fails.

Adds both-directions test: same imgui (raw_backend) project against the
null-v2 fixture passes with `is_tests_target = true` and still errors
`UnsupportedCapability` with `is_tests_target = false`.

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

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be826cd60f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/root.zig
// null harness against the project's real-backend capabilities is wrong.
// Identity + collision checks above stay ON (cheap + still valid). The real
// exe target still enforces the gate.
if (is_tests_target) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Skip the duplicate v2 capability gate for tests

This early return only bypasses the root-level contract check. In the actual generateTestsTarget path for a project with a raw_backend GUI, cfg still carries resolved_gui, so after the null 0.2.0 bump auto-detects null's v2 manifest, build_files.generateBuildZig later runs its own v2 capability validation (src/build_files.zig lines 313-318), derives .raw_gui_adapter, and fails against null's .headless-only capabilities. As a result labelle generate still aborts while emitting .labelle/tests/ for GUI projects; the tests-target exemption needs to be applied to that build.zig validation path too, or otherwise avoid deriving the real backend GUI requirement for the forced-null harness.

Useful? React with 👍 / 👎.

…tests target

The prior fix (be826cd) skipped only the ROOT-level `validateProviderContracts`
capability requirement for the tests target. But `build_files.generateBuildZig`
runs its OWN v2 capability validation (added in the #472 open-config PR), and
the tests target calls `generateBuildZig` directly via `generateTestsTarget`.
So the forced-null (`.headless`-only null-v2) tests harness still hard-failed
`UnsupportedCapability` for GUI/gamepad projects — the #474 examples-integration
gamepad example's tests-target generate.

Guard `generateBuildZig`'s v2 capability REQUIREMENT check with
`if (!opts.is_tests_target)`, consistent with the root-level skip. The provider
IDENTITY check stays ON for the tests target (cheap + still valid); only the
capability requirement is skipped. The real exe target (`is_tests_target =
false`) is unchanged. `is_tests_target` was already threaded from the
tests-target generate call site (root.zig:1006-1007).

Adds two DIRECT `generateBuildZig` tests (via `h.genNullV2BuildZig`): a
raw_backend (imgui) GUI project generating build.zig against forced-null
(null-v2) does NOT error with `is_tests_target = true`, and STILL errors
`UnsupportedCapability` with `is_tests_target = false`. This mirrors the CI
scenario the root-level `validateProviderContracts` tests could not reach.

Also re-points the "#473 finding 2" test to drive the REAL exe target
(`is_tests_target = false`): it was passing only because `generateBuildZig`'s
second gate caught the mismatch on the tests-target path (`generateAndReadBuildZig`
forces `is_tests_target = true`), which this fix now correctly skips. The
finding-2 catch is a resolve-time `validateProviderContracts` concern, so the
exe path errors before any engine-template work.

Claude-Session: https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw
@apotema
apotema merged commit 722b3d5 into main Jul 1, 2026
4 checks passed
@apotema
apotema deleted the feat/cutover-null-v2 branch July 1, 2026 14:19
apotema added a commit that referenced this pull request Jul 1, 2026
…releases) (#476)

wgpu 0.2.0, sdl 0.2.0, bgfx 0.3.0 each ship backend.manifest.v2.zon (+ bgfx's
android hook). With generate auto-detect (#473) + the tests-target-null
capability fix (#474), these backends now build via the declarative v2 build
graph in production. Desktop paths fully CI-validated; bgfx-android cross-build
validated by the bgfx-android-build job (on-device render unchanged from v1 —
same source). wgpu/sdl are desktop-only, hookless, golden-reviewed.

Claude-Session: https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw
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