Repository navigation
ogar-dir-sim: compare-and-set for every property of an existing node; kind stays identity - #319
Conversation
… kind stays identity
Change gains SetActive { from, to: Option<bool> } and SetLocation { from,
to: Option<Dn128> }, beside SetAttribute (whose ValueId-typed from/to
cannot carry a flag or a location without losing type safety). They sort
after renames and before creates: neither frees nor claims a value.
NodeState::apply is the one reference semantics for a property change:
it applies only where the node still holds its from (else Stale), keeps
all three flag values distinct, and refuses SetActive on a group (groups
carry no flag). Memberships, creates and deletes are not property
changes and are refused there.
kind is identity and immutable: separate user and group populations and
ordinal spaces, typed membership endpoints. No change can express it,
and PlanError::Unconvergeable now means exactly a kind mismatch.
Plans lower the new changes to SetEnabled { enabled: bool } and
MoveObject { to: Dn128 }, with EnabledEquals / LocationEquals
preconditions read from the observation. A change towards an unknown flag
or location is reportable by a diff but not actuatable:
ExecutionPlan::from_diff now returns Result and refuses it as
PlanError::NotActuatable (no partial plan).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing (4)
✨ Finishing Touches📝 Generate docstrings
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: ddbee830-53f1-4825-a9a4-99ffb6149191) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 5d9ed9b5-6703-4918-9b7f-af8b94a31159) |
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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 81df77922d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let mut ops = diff | ||
| .into_iter() | ||
| .map(PlannedOp::lower) | ||
| .collect::<Result<Vec<_>, _>>() |
There was a problem hiding this comment.
Choose a deterministic non-actuatable node
When a diff contains multiple SetActive or SetLocation changes whose to is None, this collect short-circuits on whichever change appears first, so reversing the same semantic diff changes the observable PlanError::NotActuatable.node. This undermines the planner's otherwise canonical, input-order-independent behavior and can make reconciliation or audit results unstable; sort before lowering or deterministically select the minimum offending node.
Useful? React with 👍 / 👎.
Summary
Closes the directory-simulation gap for a node that exists in both versions. Before this PR, its enabled flag and its location could not be changed at all. The PR adds that vocabulary only: it contains no executor, storage, Quack code or actuator.
Semantic contract
from → toshape asSetAttribute:Change::SetActive { node, from, to: Option<bool> }.from → topairs over enabled, disabled and unknown, and keeps the three values distinct.Change::SetLocation { node, from, to: Option<Dn128> }.SetAttribute. Itsfrom/toareOption<ValueId>, which hold dictionary values. Folding a flag and a location into it would mean loosening those types until any attribute could be paired with any value.NodeState::applyis the single reference semantics for any change to one node's properties. Every executor must agree with it.fromno longer matches the node (Stale).SetActiveon a group (NoEnabledFlag).NotAPropertyChange), since those aren't property changes.kindis immutable.PlanError::Unconvergeablenow means exactly a kind mismatch.SetActivelowers toOperation::SetEnabled { enabled: bool }, with anEnabledEquals(Option<bool>)precondition.SetLocationlowers toOperation::MoveObject { to: Dn128 }, with aLocationEquals(Option<Dn128>)precondition.ExecutionPlan::from_diffnow returns aResultand refuses such a change asPlanError::NotActuatable, with no partial plan.Ordering
Merge this first. lance-graph
mainwill not compilelance-graph-dir-simfrom the moment this merges until the companion lance-graph PR lands. That crate matchesChangeexhaustively and callsfrom_diffexpecting the old, non-Resultreturn. The companion PR implements the new variants there.Tests
SetActive;SetAttributecompare-and-set;from(active, location, attribute);Nonecollapsed tofalse;from.clippy -D warningsare clean.No actuator or write-back code.
🤖 Generated with Claude Code
https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
Generated by Claude Code