Repository navigation
ruff_spo_triplet: predicate roles and a role census - #127
Conversation
Provenance says how sure a triple is; nothing said what a triple is about. `Predicate::role()` classifies every predicate as a bitmask over describes / structure / relates / reads / derives / effects / constrains / requires / authorizes / enables / triggers / presents / opaque, with groups for description, capability, DO arm, precondition and guard. The match is exhaustive with no wildcard, so a new Predicate variant does not compile until its role is decided. `role_census` counts roles over a triple set and reports predicates outside the closed vocabulary instead of guessing a role for them. `examples/predicate_role_census` runs the census and a purity fold (compute functions whose writes are all declared computed fields and that raise nothing) over a harvest corpus whose path is passed in. It states when `calls` is not harvested, because then "no calls fact" means unknown. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPWTwovjYJEUMuGPb4
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Summary
Provenancesays how sure a triple is. Nothing said what a triple is about: whether its predicate describes a node, gives it a capability, makes it act, or guards when it may act. Consumers such asod-ontologyanswer that question by matching raw predicate strings (match t.p.as_str()inogar_actions.rs,mro.rs,recompute_dag.rs).This adds
Predicate::role() -> PredicateRole, a bitmask over 13 roles:It also adds named groups:
DESCRIPTION,CAPABILITY,DO_ARM,PRECONDITION,GUARD,DATAFLOW.writes_if_blankis an effect and a precondition;has_functionplaces a function and gives its model a capability.matchhas no wildcard arm, so a newPredicatevariant does not compile until somebody decides its role.opaqueis not the empty set. The catch-allhas_dsl_callgets its own bit, so "unknown" is never read as "no role".callscounts as an effect. A dispatch to an unresolved target may change state. The doc comment states that a missingcallsfact is not evidence that a body calls nothing.role_census(&[Triple])counts roles and reports predicates outside the closed vocabulary instead of guessing a role for them.examples/predicate_role_censusruns the census and a purity fold over a corpus path passed on the command line; no corpus data is committed.Measured on the Odoo corpus (
lance-graphgraph/spo/odoo_ontology.spo.ndjson, 24 579 triples):groups=) or triggers (onchange, lifecycle).depends_onsubject); 2 439 of them raise nothing; 2 190 of those write exactly one field. The recipe classifier, run independently on the 2 439, puts 2 257 in theComputecentroid.callsand 0writes_fieldfacts. The candidates are unverified on dispatch and on body writes, and the example prints that.Test Plan
cargo test -p ruff_spo_triplet: 183 passed.cargo clippy -p ruff_spo_triplet --all-targets -- -D warnings: clean.requires→a_guarded_write_is_both_an_effect_and_a_preconditionhas_dsl_calllosesopaque→opaque_is_used_only_by_the_catch_alltargetgainseffects→a_description_is_not_an_action_or_a_guardevery_predicate_has_a_role_and_no_stray_bitscensus_counts_each_bit_and_reports_unknown_predicatescensus_counts_each_bit_and_reports_unknown_predicatesuv run prekwas not run: the localuvcannot parse this repo'sexclude-newer. This PR adds no Markdown.Generated by Claude Code