Add fact-load error helpers and PolicyBuilder::new_static - #52
Conversation
Expose AccessEvaluation::fact_load_errors / denied_due_to_fact_load_error so callers can map infrastructure failure without hand-walking the trace. Add PolicyBuilder::new_static for zero-allocation fixed policy names on the trace path; new() remains the dynamic-name path.
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
There was a problem hiding this comment.
Pull request overview
This PR adds convenience APIs to expose fact-loading failures from an evaluation trace (without changing fail-closed authorization semantics) and introduces PolicyBuilder::new_static to avoid allocations for fixed policy names by storing them as Cow::Borrowed.
Changes:
- Add
AccessEvaluation::fact_load_errors()andAccessEvaluation::denied_due_to_fact_load_error()to surfaceFactOutcome::Errorprovenance across the full result tree. - Add
PolicyBuilder::new_static(&'static str)and convert builder/internal policy name storage fromStringtoCow<'static, str>to keep static names allocation-free on the trace path. - Update docs/examples/bench comments and add unit tests covering the new helpers and
new_staticbehavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/tests.rs | Adds unit tests for fact-load error helpers and PolicyBuilder::new_static name storage/tagging. |
| src/results.rs | Implements trace-walking helpers for collecting/flagging fact-load errors from FactProvenance. |
| src/builder.rs | Introduces new_static and switches builder/internal policy name handling to Cow<'static, str>. |
| README.md | Updates examples and guidance to prefer PolicyBuilder::new_static for fixed names; documents new fact-load helpers. |
| MIGRATION.md | Notes new_static and the allocation accounting difference vs new. |
| examples/policy_builder.rs | Updates example policies to use new_static for fixed names. |
| CHANGELOG.md | Documents the newly added helper methods and new_static. |
| benches/permission_checker.rs | Updates commentary to reflect new_static availability and intended usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Take impl Into<Cow<'static, str>> so new("AdminOnly") stores Borrowed
without a separate constructor. Keep new_static as a thin alias. Tighten
denied_due_to_fact_load_error docs to describe any-error-in-trace semantics.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/results.rs:443
denied_due_to_fact_load_error()currently allocates aVecand walks the entire trace viafact_load_errors()just to compute a boolean. This can be implemented as an early-exit tree walk with no allocation, which matters when traces are large or on hot paths (e.g. per-request HTTP mapping).
pub fn denied_due_to_fact_load_error(&self) -> bool {
matches!(self, Self::Denied { .. }) && !self.fact_load_errors().is_empty()
}
- denied_due_to_fact_load_error early-exits without allocating a Vec - PolicyBuilder::new_owned restores non-'static &str ergonomics - Clarify owned-name allocation is paid when building the trace
Summary
AccessEvaluation::fact_load_errors()/denied_due_to_fact_load_error()— walk the evaluation trace forFactOutcome::Errorprovenance so callers can map infrastructure failure (e.g. HTTP 503) without hand-destructuring combinators. Authorization remains fail-closed; these helpers only expose why.PolicyBuilder::new_static(&'static str)— stores the policy name asCow::Borrowedso fixed-name builder policies are zero-allocation end-to-end on the trace /ctx.grantpath.PolicyBuilder::newremains the dynamic-name path.Note: the undeclared-forbid
tracing::warn!adoption guardrail from the original review is already onmain(0.5).Test plan
new_static(Cow::Borrowed) vsnew(Cow::Owned) and grant-path name taggingcargo fmt --allcargo clippy --all-targets --all-features -- -D warningscargo test --all-targets --all-features