You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(warp-core): refuse create-from-absence against an orphaned attachment
Two review findings, same root cause: GraphStore::set_node_attachment
never requires the owning node to exist, so an attachment present
with no NodeRecord (an orphan) is a real reachable state, not
hypothetical. Neither admission nor evaluation independently checked
for it when the node itself was absent.
- current_application_basis (Codex, P2): derived "absent" from node
presence, so it never inspected the attachment when the node was
missing. A create-from-absence invocation dishonestly claiming
absence against a real orphan was admitted. Fixed by deriving
absence from the attachment slot alone -- the only thing this
primitive actually mutates -- so an orphan corroborates as present,
using its real value, exactly like the ordinary case.
- prepare_operation_v1's create branch (CodeRabbit, Major): built the
atomic create ops without checking whether the attachment slot was
already occupied, since node absence doesn't imply attachment
absence. A caller with a basis honestly reflecting an orphan's real
present value (passing the now-fixed admission check) could still
reach evaluation and silently overwrite it. Fixed by checking
store.node_attachment(&node.local_id).is_some() before proceeding,
refusing with PreconditionMismatch -- creation is atomic over both
slots or it refuses, per ADR 0024.
New fixture_host_with_orphan_attachment helper backs two tests, one
per layer: admission refuses a dishonest absence claim with
BasisMismatch; evaluation refuses (and leaves the orphan untouched)
when the claimed basis honestly reflects the orphan's real value,
isolating the evaluation-time check specifically. The two fixes had
to land in that order -- before the admission fix, the evaluation
test's premise (an honest "present" basis matching what admission
computes) wasn't reachable, since old admission unconditionally
computed "absent" whenever the node was missing.
22 tests pass (was 20); full pipeline suite green.
0 commit comments