Repository navigation
fix(v2): preserve permission request wire shapes - #40
Conversation
The v1 and v2 APIs share a permission gate, but its stored request shape was being serialized directly at both boundaries. Project requests and events into each frozen schema, accept either field vocabulary for shared always-grants, and reject malformed v2 payloads before persistence. Serves K-V2-PERM-SHAPE. The malformed-field regression was observed red before validation was tightened; tests pin the v1 and v2 read shapes, event shape, and always-grant cascade. Local verification: fmt, clippy, permission-focused tests, guard script, and traceability matrix pass. Full workspace tests on macOS hit existing Linux /proc and cgroup assumptions; Linux PR CI must confirm the workspace gate.
V2 permission creation must store its own action/resources/save/source shape. Boundary projectors own the v1 and v2 translations; storing duplicate v1 fields made the gate and always-grant paths ambiguous. The session detail route also needs the session id to enforce request ownership. Serves K-V2-PERM-SHAPE. The v2 surface regressions cover create, both read grammars, event projection, and the shared always-grant cascade.
The permission PR included the adjacent drain acceptance row because both additions shared one patch hunk. Remove that row here so the permission PR documents only the permission behavior; the drain branch adds it with its implementation and tests.
Amendment to the contributor's branch (credited @jrzmurray), reviewed before merge on the evidence each arm provides: * DELETE the `v2_twin("permission.asked")` arm. permission.asked is emitted only through emit_durable/emit_durable_http, and neither calls v2_twin, so the arm was unreachable and its test proved a path production never takes. The real v2 projection is the /api/event encoder (encode_event_frame), which the envelope test already covers. A new assertion keeps the dead arm from returning; the encoder test carries a proven negative control (remove the projector -> "left: Null, right: \"bash\""). * add D-PERM-SOURCE-KEY and D-PERM-EVENT-NAME to the ledger. The two frozen contracts disagree (v1 PermissionV2Source is callID, v2 Permission.Source is id; event name permission.v2.asked at 1.19.5 vs permission.asked at 2.2.5), and both are additionalProperties:false, so no single body satisfies both. The row also records why the event-name split is currently unreachable: the 1.19.5/2.2.5 web app probes /global/health and treats {healthy:true} as v1, so it consumes the v1 payload. * add v2_created_ask_is_readable_in_both_grammars: drives the real v2 create handler and reads the stored ask back through BOTH grammars, asserting source.id on v2 and tool.callID on v1. The existing test seeded the gate directly, so it never exercised the create path. Requirement: K-V2-PERM-SHAPE. Verified: v2_surface 18/18, core lib 162/162, fmt, matrix.
|
Thanks — this is a careful piece of work and the shape reasoning is right. I approved the workflows (fork runs had never executed; CI was also red on What I changed and why
One correction to my own earlier review, for the record: I had claimed this PR wrongly rejects The event-name matrix is now a named divergence rather than an unproven claim. If you want the 1.19.5-era event name emitted as well, that is a new decision, not a bug fix, and I would want the live consumer first. |
Comment-only: rustdoc's doc_lazy_continuation (new in 1.100) rejects the paragraph without a blank line. No behaviour change, no requirement change.
Kept both sides in CHANGELOG, PLAN section 18 and TESTING 1.6: the permission rows from Reliary#40 and the drain/delete rows from this branch are independent.
What this changes
The v1 and v2 HTTP surfaces share the permission gate, but the gate stores different field names for each API family. Requests and events now project into the frozen v1 or v2 shape at the boundary. The shared always-grant logic accepts both field vocabularies, and v2 permission creation rejects malformed fields and values before storing a request.
Issue
No linked issue. Serves
K-V2-PERM-SHAPE.Verification
cargo fmt --check— passcargo clippy --workspace -- -D warnings— passcargo test -p ocserve-core permission— passcargo test -p ocserve-http --test v2_surface— pass (17 tests)cargo test -p ocserve-http --lib v2_permission_event_projects_the_permission_request_shape— passuv run --with jsonschema bash ./scripts/check-guards.sh— pass./scripts/check-matrix.sh— passcargo test --workspace— macOS run fails in Linux/procand cgroup-dependent tests; the subsequent broad run also hitshutdown::sigterm_logs_the_drain_linebefore reaching the HTTP suite. Linux PR CI must confirm the workspace gate.Checklist
crates/**/*.rschange stages aTRACEABILITY.mdrowCHANGELOG.mdfeat:,fix:,docs:,test:,chore:)