Permanent-tier nref allocation via switchable graphdb_nref facade#29
Merged
Conversation
Bundles several in-progress streams that were uncommitted in the working
tree:
- Permanent-tier nref groundwork (label_start): bootstrap.terms gains a
{label_start, 10001} directive, nref_start bumped 100000 -> 1000000;
graphdb_bootstrap builds the label symbol table from a local counter
before set_floor(nref_start); classify_terms/validate_label_start +
tests and ARCHITECTURE/CLAUDE updated (390 tests green as of last
session).
- F4 graphdb_rules design refinements (docs/designs/f4-graphdb-rules-design.md).
- New design spec: permanent-tier nref allocator via compute-from-DB,
which supersedes the label_start directives with graphdb_nrefs.hrl
macros during implementation
(docs/designs/permanent-tier-nref-allocator-design.md).
- docs/diagrams/ontology-tree.md -- environment ontology visual reference.
- docs/resiliency-notes.md -- nref-stability threads to revisit.
Note: per the new allocator spec (D2), the bootstrap.terms directives
committed here will be reversed in favour of header macros when that
spec is implemented.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Revise the permanent-tier nref design from a threaded permanent-only allocator to a single switchable graphdb_nref facade, per the recalled least-impact/most-reuse approach: - One entry point (graphdb_nref:get_next/0) for all graphdb node-nref allocation; every create function changes by one token, no seed-vs-runtime branching (D8). - Phase decides the tier: permanent during init (compute-from-DB), runtime after the flip (delegates to nref_server). Flip lives in graphdb:start/2, bracketing the boot (D9). - Bootstrap loader keeps its local counter; coexists safely since the facade computes-from-DB past the loader's labels (D10). - Phase held in persistent_term, not volatile state, so a single facade restart at runtime cannot resurrect permanent mode and write permanent-tier nrefs as runtime nodes (D11 -- closes a corruption hole in the scan invariant). Verified: graphdb is a peer app (start/2 invoked); all permanent seeding is synchronous in init/1 (temporal invariant). Survives from the prior draft: compute-from-DB core, scan invariant + forward constraint, lazy-compute timing, spillover, header macros (D2), D6/D7. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bite-sized task-by-task plan for the graphdb_nref switchable allocation facade per docs/designs/permanent-tier-nref-allocator-design.md: new facade module + CT suite, supervision wiring, graphdb:start/2 phase flip, uniform get_nref->get_next swaps across the worker modules, bootstrap revert to macro-sourced tier boundaries, and the full test/doc fallout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…DB, persistent_term phase) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…c); strengthen test
…nesses Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r); flip tier assertions Three live nref_server:get_nref() calls in do_create_attribute/3 and do_create_relationship_attribute_pair/3 replaced with graphdb_nref:get_next() so all attribute seeds land in the permanent tier [?NREF_ENGLISH, ?NREF_START). Test assertions updated from ">= 1000000" (runtime) to the permanent-tier range check; TDD verified: tests failed before the swap and pass after. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…assertions Swap all three nref_server:get_nref() calls in graphdb_language.erl to graphdb_nref:get_next() so that Language Literals sub-group, base_language, and project_language seeds land in the permanent tier during init/1. Update graphdb_language_SUITE assertions to expect permanent-tier nrefs (> NREF_ENGLISH and < NREF_START) and replace bare 1000000 literals with ?NREF_START throughout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s + loader set_floor
Tier boundaries (?LABEL_START, ?NREF_START) are now compile-time macros in
graphdb_nrefs.hrl rather than {nref_start,_}/{label_start,_} directives in
bootstrap.terms. classify_terms/1 now returns a 2-tuple {Nodes, Rels};
do_load/0 passes the macros directly to validate/2 and build_symbol_table/4
and no longer calls nref_server:set_floor/1 (that is handled by
graphdb:start/2 via graphdb_nref:set_runtime_phase/0). validate_label_start/2
removed. Tests updated accordingly: 61 EUnit + 19 CT pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… stale start/2 claim Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e erase in bootstrap suite) 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.
Summary
Routes all graphdb node-nref allocation through a new switchable
graphdb_nreffacade so that moduleinit/1one-time seeds land in the permanent tier[?LABEL_START, ?NREF_START)=[10001, 1000000)instead of the runtime tier (≥ 1000000). Resolves the first of two long-pending nref topics (init-seed nref tier).Design
graphdb_nref(new gen_server, first child ofgraphdb_sup) — two phases:init/1): compute-from-DB cursor overnodeskeys< ?NREF_START, starting at?LABEL_START.nref_server:get_nref/0.persistent_term({graphdb_nref, phase}), restart-safe underone_for_one.graphdb:start/2brackets boot:set_permanent_phase/0beforegraphdb_sup:start_link/0,set_runtime_phase/0after (which raises the runtime floor to?NREF_START).?NREF_START, the facade callsnref_server:set_floor(N+1)(monotonic) so the runtime tier never collides.?LABEL_START/?NREF_STARTingraphdb_nrefs.hrl; the oldbootstrap.termsdirectives and the loaderset_floorcall are removed. The bootstrap loader keeps its own local symbol-table counter.All graphdb workers (
graphdb_attr,graphdb_class,graphdb_instance,graphdb_language) now allocate viagraphdb_nref:get_next/0.Testing
378 green (277 CT + 101 EUnit). New
graphdb_nref_SUITEcovers compute-from-empty/populated, sequential uniqueness/monotonicity, spillover floor-raise, runtime delegation, and restart safety.Docs
Spec:
docs/designs/permanent-tier-nref-allocator-design.md(Status: Implemented).Plan:
docs/superpowers/plans/2026-05-28-permanent-tier-nref-facade.md.ARCHITECTURE.md,CLAUDE.md, andapps/graphdb/CLAUDE.mdupdated for the facade, permanent-tier seeds, and macro-sourced boundaries.🤖 Generated with Claude Code