Skip to content

effect-session: allow an empty resource for whole-system verbs - #77

Merged
TroyHernandez merged 3 commits into
masterfrom
effect-session-empty-resource
Aug 20, 2026
Merged

TroyHernandez merged 3 commits into
masterfrom
effect-session-empty-resource

Conversation

@TroyHernandez

Copy link
Copy Markdown
Contributor

HELD draft — landed pending the Part B VM re-run that proves it end to end.

Found by the Part B disposable-VM gate (pkgops issuer run 1): every whole-system commit died at the effect-session open with bad_request: resource.

effect_session_open() (src/effect_session.c) rejected any empty resource:

if (rlen == 0 || rlen >= RUNIX_APT_RES_CAP) { ... bad_request ... }

But whole-system verbs (apt.update/upgrade/dist_upgrade/configure) bind no package and carry resource = "" by contract — the planner returns resource:"", the broker accepts it (rab-exercise passes "" straight through and its update gates pass), and the durable record stores "". The native wrapper was stricter than the broker it fronts.

Fix: scope the empty check with the existing runix_verb_takes_packages() — empty is a bad_request only for the targeted verbs; over-length is still always rejected. The fix belongs in runix, not a pkgops sentinel: a synthesized resource would diverge the durable record from the reference boundary (rab-exercise's resource:""), failing the §5 record-parity check.

Why the hermetic tests missed it: every pkgops commit test uses a fake session-ops whose open accepts any resource. Only a real runix open against the real broker exercises this — exactly what Part B is for.

Tests (inst/tinytest/test_effect_session_api.R): install + "" still runix_broker_bad_request detail resource; update + "" is accepted and proceeds to the transport (runix_broker_unavailable on a dead socket). 358 checks pass in both the production and -DRUNIX_TESTING builds.

Version 0.0.1.13.

effect_session_open() rejected any empty resource as bad_request:resource, but
whole-system verbs (update/upgrade/dist_upgrade/configure) carry an empty resource
by contract -- the planner returns resource:"", the broker accepts it, and the
durable record stores "". The flat rejection failed every whole-system commit at
the effect-session open step, before any intent opened. The native wrapper was
stricter than the broker it fronts.

Scope the check with the existing runix_verb_takes_packages(): an empty resource
is a bad_request only for targeted verbs (install/remove/purge/hold/unhold); an
over-length resource is still always rejected. pkgops writes resource:"" to match
the reference boundary (rab-exercise), so the fix belongs here, not a pkgops
sentinel that would diverge the durable record.

Regression tests (test_effect_session_api.R): install with "" still
bad_request:resource; update with "" is accepted and proceeds to the transport
(runix_broker_unavailable on a dead socket). Found by the Part B disposable-VM
gate -- invisible to the hermetic pkgops tests, whose fake open accepts any
resource. 358 checks pass in both the production and -DRUNIX_TESTING builds.
The native open_intent frame omitted the broker-required outcome and
effect_issued fields, so every native open was schema_invalid at a real broker
-- durable-audit-contract.md (two-phase write) has always specified an intent
record carries effect_issued=false, outcome="intent". The schemaless fake
responder the hermetic suite uses validated nothing and passed the malformed
frame; the disposable-VM (Part B) run caught it.

Add an at-home regression driving native open + write_outcome against the REAL
broker daemon (a must-match negative asserts the daemon rejects a record missing
outcome: broker_error/schema_invalid), plus a dedicated CI job
(effect-session-native) that builds runix with the testing seam and a post-v0.0.1
broker so the native path is exercised for real. The linux job now runs at_home=
TRUE -- test_package() defaults it FALSE, which had been silently skipping the
uid-0 pinning regression and the live-broker round-trips its own comment claims.
@TroyHernandez

Copy link
Copy Markdown
Contributor Author

Part B authoritative run 4: polkit matrix 23/23, §7 gates 68/68, rc=0. Empty-resource + open_intent outcome fixes proven end-to-end against the real broker; the effect-session-native CI job passes. Pins: runix d13842e (this branch + #76 harness), pkgexec 786abdc, pkgops 97307c8.

@TroyHernandez
TroyHernandez marked this pull request as ready for review August 20, 2026 18:33
@TroyHernandez
TroyHernandez merged commit 87fca94 into master Aug 20, 2026
6 checks passed
@TroyHernandez
TroyHernandez deleted the effect-session-empty-resource branch August 20, 2026 18:33
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