Skip to content

[Fusion] Mark deniable selections with synthetic skip variables and node conditions in the planner - #37

Merged
michaelstaib merged 7 commits into
mst/policy-v2from
mst/auth-planner-marking
Oct 9, 2026
Merged

michaelstaib merged 7 commits into
mst/policy-v2from
mst/auth-planner-marking

Conversation

@michaelstaib

Copy link
Copy Markdown
Owner

Ticket: hc-fork-2-jzk.2 (Planner authorization marking)

The planner marks deniable selections so the middleware (jzk.4) can skip denied data per request without re-planning.

  • Flag. HasAuthorization on FusionOutputFieldDefinition, a FieldDefinitionFlags bit, so an unprotected field costs one flag check. This is the commit that was reviewed earlier under the retracted jzk.7.
  • Skip variables. Every deniable selection in a subgraph operation carries @skip(if: $__fusion_auth_N), with variables allocated by the planner in sequence. Type-conditioned selections of one field share a variable.
  • Node conditions. An execution node whose root selections are all deniable gets a node condition: the shared variable, or one synthetic AND variable.
  • Descriptors. Operation.Authorization (OperationAuthorization) holds the PolicyDescriptor entries per compiled selection. The IPolicy is pinned at plan time through IPolicyResolver. Requirements are read from field-level Authorization only, and composition has already flattened type-level requirements.
  • Requirement gating. A requirement selection that only a protected field consumes is gated by that field's variable, but only when that variable also skips the whole consuming node. This was fixed in review: before, an allowed sibling field could lose its entity.
  • Planner version. OperationPlanner.Version goes from 2.0.0 to 2.1.0, because protected operations plan differently. The plan JSON shape is unchanged, so there is no schema change.

History: the first implementer was lost to a network error, and a second one continued from its uncommitted work.

Verified:

Not verified:

  • Nothing supplies the $__fusion_auth_N variables before jzk.4, so there is no end-to-end execution.
  • There is no allocation benchmark. Unprotected operations get Authorization = null and no variables by design.
  • Tests on net8, net9 and net11 were not run.
  • A NATS JetStream test could not run because there is no Docker.

Open points from review, all minor and not fixed:

  • The existing three-argument OperationPlanner constructor defaults the policy resolver to built-ins only, and 13 call sites were left unchanged. This runs against the "no optional parameters to avoid call sites" rule. The planner needs to rule on it.
  • Operation.Authorization has an internal setter that the planner assigns after compilation. It is not built once.
  • An unregistered policy name is pinned as an UnresolvedPolicy that throws at evaluation, with the policy name in the message. jzk.4 must keep that message out of client errors.
  • A node whose root selections sit under type-conditioned fragments never gets a synthetic node condition.
  • Requirement gating is switched off for operations with deferred parts.
  • Some marker branches have no test.

Copilot AI balanced review requested due to automatic review settings October 7, 2026 04:33

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@michaelstaib
michaelstaib added this pull request to stack #50 October 8, 2026 20:50
@michaelstaib
michaelstaib merged commit 3b443dc into mst/policy-v2 Oct 9, 2026
1 check passed
@michaelstaib
michaelstaib deleted the mst/auth-planner-marking branch October 9, 2026 00:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants