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

Fields

No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions