feat: chain-step evidence composition — expand evidence steps in chains
A chain step that references a derived evidence is now expanded at compile
time, keeping the engine a flat edge-traversal evaluator:
- DIRECT evidence step -> renamed to its underlying relation
(member_of(user,*g){ group_read(g,doc) } where group_read = can_view
becomes step 'can_view').
- CHAIN evidence step -> its steps are spliced into the parent chain
(a sub-path flattens into the linear source->...->object traversal).
- Any other evidence type (defeasible/logical/comparator) as a step is a
compile-time error: it is a condition, not an edge traversal.
- Cycles and self-references through chain steps are compile-time errors
(the existing composition cycle guard now covers steps).
Rigor: oracle campaign gains a chain_step_composition construct; illegal
mutations gain a non-lowerable-chain-step case. Fixture suites updated to
retarget the self-recursive 'canRead/canAccess/...' terminals (an unsupported
recursion pattern that now fails loudly) to an any-typed 'reachable' fact,
preserving the nested-pattern parsing intent.
This commit is contained in:
@@ -96,6 +96,14 @@ const MUTATIONS = {
|
||||
'evidence can_read(user: Employee, doc: Doc) { owns(user, doc) }',
|
||||
'fact can_read(user: Employee, doc: Doc)\n evidence can_read(user: Employee, doc: Doc) { owns(user, doc) }'
|
||||
)
|
||||
},
|
||||
non_lowerable_chain_step: {
|
||||
desc: 'a defeasible evidence used as a chain step (cannot lower to an edge)',
|
||||
mustFail: true,
|
||||
apply: () => VALID_DSL.replace(
|
||||
'evidence can_enter(user: Employee, doc: Doc) { member_of(user, *g) { can_access(g, doc) } }',
|
||||
'evidence can_gated(group: Group, doc: Doc) { WHEN can_access(group, doc) UNLESS banned(group) }\n evidence can_enter(user: Employee, doc: Doc) { member_of(user, *g) { can_gated(g, doc) } }'
|
||||
).replace('fact can_access(group: Group, doc: Doc)', 'fact can_access(group: Group, doc: Doc)\n fact banned(group: Group)')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user