Skip to content

Fail CI when the desktop shell does not forward a default-ON core feature gate #4919

Description

@CodeGhost21

Summary

Add a CI check that fails when the Tauri shell does not forward every default-ON gate from the core crate. Today a missing gate silently removes a whole domain from the shipped desktop app with no build error, no test failure, and no signal until users report it.

Problem / Context

app/src-tauri/Cargo.toml declares the embedded core with default-features = false, so the shell does not inherit the core's default gate set. Every default-ON gate must be forwarded by hand:

openhuman_core = { path = "../..", package = "openhuman", default-features = false, features = [
    "media",
    "voice",
] }

Nothing enforces that list matches the core's default. When they drift, the domain is compiled out of the shipped binary and the failure is invisible at build time — it surfaces only as runtime unknown method errors, or (worse) as silently degraded behaviour with no error at all.

This has already happened twice, independently:

Gate Outcome
voice Not forwarded when #4833 made it default-ON. Shipped broken v0.58.19 → v0.61.x. 56 users, ~93k Sentry events (#25260, #25259). Every openhuman.voice_* RPC was unknown-method. Fixed in #4917 (#4901).
media #4840 forwarded it correctly — its author hit the same trap and documented the rule in a code comment.
tokenjuice-treesitter Still not forwarded. Fails soft (AST compression degrades to a heuristic), so there is no error to notice. #4918

Two of three defaults have been dropped at some point. The media PR proves the trap is discoverable only if the author happens to know about it — a code comment is documentation, not enforcement. The next default-ON gate will hit it again.

#4917 added a VOICE_COMPILED_IN const assert, but that guards one gate. media has no equivalent, and a per-gate assert doesn't scale or auto-cover new gates.

Scope (optional)

In scope: a check that parses the core's [features] default list and the shell's forwarded features list, and fails when a default-ON gate is not forwarded (or is not explicitly allow-listed as intentionally excluded).

Notes / tradeoffs:

Out of scope: fixing tokenjuice-treesitter itself (#4918), and the per-gate const asserts (they can stay as defence in depth, or be retired once this lands).

Acceptance criteria

  • Drift fails CI — removing any forwarded gate from app/src-tauri/Cargo.toml fails the check with a message naming the missing gate. Verify red/green, not just green.
  • New defaults are covered automatically — adding a gate to the core's default without forwarding it fails, with no per-gate wiring needed.
  • Intentional exclusions supported — an explicit allow-list entry with a documented reason passes (tokenjuice-treesitter is the first real case).
  • Slim builds unaffected--no-default-features profiles still build.
  • Wired into CI Lite — runs on PRs touching either manifest.
  • Documented — the rule lives in AGENTS.md "Compile-time domain gates" alongside the existing guidance.
  • Diff coverage ≥ 80% — the implementing PR meets the changed-lines coverage gate when code changes are involved.

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions