Node soft-retire: retire_node/unretire_node (write-path slice A)#42
Merged
Conversation
Design for write-path slice A node deletion as a reversible soft-retire
rather than a hard delete. "Deleting" a runtime node stamps a boolean
`retired` lifecycle AVP; the node and its arcs stay in Mnesia, so nothing
orphans and no environment-vs-project discriminator is needed (the
env/project split is not physically realized yet — one shared nodes table,
instances on the environment runtime allocator, Projects category an empty
scaffold).
Key decisions:
- New ops retire_node/1 + unretire_node/1; delete_node/1 left untouched and
reserved for a future real (hard) delete.
- retire/unretire refuse the whole permanent tier (nref < ?NREF_START) with
a new permanent_node_immutable atom; delete_node + category guard and its
tests are unchanged.
- get_node/1 returns {error, retired}; internal do_get_node stays raw.
- Pragmatic-middle visibility: hide from direct lookup + block new
participation (retired class target/parent/arc endpoint); existing
structural participation deferred.
TASKS.md: mark slice A designed; add follow-ups — retired rules must not
fire, unify permanent-tier immutability, project boundary, retired-node
purge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Five-task TDD plan for write-path slice A soft-retire:
1. graphdb_attr seeds the boolean `retired` marker (+ seeded_nrefs).
2. graphdb_mgr retire_node/1 + unretire_node/1 (tier-1 set_retired_/3 over
the transaction seam; lazy retired-nref cache).
3. graphdb_mgr get_node/1 hides retired nodes ({error, retired}).
4. graphdb_instance refuses retired nodes as new participation.
5. Docs (Architecture, ontology-tree, TASKS).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tion Per review of the soft-retire lifecycle test: the active assertion matches any value=>true AVP (per the plan), which is not a false positive for a fresh class. Add the attribute-specific predicate as an inline comment for future hardening; behavior unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Block-new-participation guards: create_instance rejects a retired class
({class_retired, ClassNref}) or retired parent ({parent_retired, ParentNref});
add_class_membership rejects a retired class; add_relationship rejects any
retired endpoint ({endpoint_retired, Nref}).
+4 CT cases (110 instance, 432 total). Zero warnings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update Architecture.md, ontology-tree.md, TASKS.md, and README to reflect the completed soft-retire implementation: graphdb_mgr retire_node/1 + unretire_node/1, graphdb_attr retired marker seed, graphdb_instance retired-node participation guards. Test count updated to 537 (432 CT + 105 EUnit). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- graphdb_mgr: reformat has_true_avp/1 anon fun to multi-line, matching the sibling is_retired_avp_present/2 style. - graphdb_instance_SUITE: note that future retire-guard tests must be added to the maybe_set_runtime_phase/1 guard list. No behavior change; graphdb_mgr_SUITE + graphdb_instance_SUITE green (147). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements node soft-retire — write-path slice A. "Deleting" a runtime
node is now a reversible soft-retire via a boolean
retiredmarker AVP:the node and all its arcs stay in Mnesia, so no arc or cache is ever
orphaned and no environment-vs-project discriminator is needed (the
env/project split is not physically realized — single shared
nodestable, instances on the environment runtime allocator, Projects category
an empty scaffold).
delete_node/1is deliberately left untouched ({error, not_implemented})and reserved for a future real (hard) delete.
What landed
retiredliteral-attribute (AttributeLiterals sub-group, nref 7), exposed via
seeded_nrefs/0— mirroring L9instantiable.retire_node/1+unretire_node/1: idempotent; tier-1set_retired_/3primitive run through the existingtransaction/1seam;the
retirednref is fetched lazily + cached (graphdb_mgr starts beforegraphdb_attr); refuse the whole permanent tier (
nref < ?NREF_START)with
{error, permanent_node_immutable}; runtime-tier missing node →{error, not_found}.get_node/1returns{error, retired}for aretired node; internal
do_get_node/1stays raw (workers/queries readMnesia directly, so traversal/inheritance visibility is unchanged — the
pragmatic-middle scope).
{class_retired,_}(create_instance / add_class_membership target),{parent_retired,_}(create_instance parent),{endpoint_retired,_}(add_relationship endpoint).
follow-up tasks: retired-rules-must-not-fire, unify-permanent-tier-
immutability), README counts.
Design / plan
docs/designs/delete-node-soft-retire-design.mddocs/superpowers/plans/2026-06-17-delete-node-soft-retire.mdTests
Full suite 537 green — 432 CT + 105 EUnit, zero warnings. Built via
subagent-driven development: per-task spec+quality reviews + a whole-branch
review (Ready to merge: Yes, no Critical/Important). The three existing
delete_nodeguard tests stay green unchanged.🤖 Generated with Claude Code