Skip to content

L7: Literals subtree restructuring (Attribute Literals + Language Literals sub-groups)#27

Merged
david-w-t merged 11 commits into
davidwt-com:mainfrom
david-w-t:develop
May 25, 2026
Merged

L7: Literals subtree restructuring (Attribute Literals + Language Literals sub-groups)#27
david-w-t merged 11 commits into
davidwt-com:mainfrom
david-w-t:develop

Conversation

@david-w-t
Copy link
Copy Markdown
Contributor

Summary

L7 — Literals subtree restructuring — prerequisite for F4 Phase A (graphdb_rules data model).

Partitions the Literals subtree (nref 7) by owning subsystem so each worker seeds its literal attributes under a dedicated sub-group. Adds two attribute-kind sub-group nodes under nref 7:

  • Attribute Literals — seeded by graphdb_attr:init/1, contains literal_type, target_kind, relationship_avp, attribute_type
  • Language Literals — seeded by graphdb_language:init/1, contains base_language, project_language

F4 Phase A will add Rule Literals as the third sub-group following the same pattern.

Key changes

Change File
New create_literal_attribute/3 arity with explicit parent graphdb_attr.erl
/2 form delegates to /3 with ?NREF_LITERALS default graphdb_attr.erl
ensure_seed/1/2 taking ParentNref graphdb_attr.erl
Attribute Literals sub-group seeded; 4 existing attrs reparented graphdb_attr.erl
New public API retro_stamp_attribute_types/0 graphdb_attr.erl
ensure_literal_seed/1/2 taking ParentNref graphdb_language.erl
Language Literals sub-group seeded; 2 existing attrs reparented graphdb_language.erl
init/1 calls retro_stamp_attribute_types/0 after seeding graphdb_language.erl
seeded_nrefs/0 maps gain sub-group keys in both workers graphdb_attr.erl, graphdb_language.erl
+5 new CT cases (sub-group + reparenting + attribute_type stamp) both worker SUITEs
L7 RESOLVED entry TASKS.md
Worker descriptions updated apps/graphdb/CLAUDE.md

Clean-slate seeding — no runtime migration code, per user instruction (no live environment to preserve).

Symmetry pattern for F4 Phase A

graphdb_rules:init/1 (Phase A) will:

  1. Seed Rule Literals sub-group under ?NREF_LITERALS via graphdb_attr:create_literal_attribute("Rule Literals", group, ?NREF_LITERALS) (see note below).
  2. Seed its 6 literal attrs under the sub-group via create_literal_attribute(Name, Type, RuleLiteralsNref).
  3. Call graphdb_attr:retro_stamp_attribute_types() to ensure new nodes carry attribute_type=literal.

(L7 uses the existing ensure_seed/ensure_literal_seed pattern within each worker for the sub-group; F4 Phase A can do the same.)

Test plan

  • All 272 existing CT cases + 5 new CT cases = 273 PASS
  • All 103 EUnit cases PASS
  • ./rebar3 compile clean — zero warnings
  • Cache invariant holds (verified in every CT case's end_per_testcase)
  • Idempotency: re-running init/1 on an already-seeded env is a no-op (verified by seeds_idempotent_on_restart and the suite's per-test setup)
  • Cross-worker consistency: graphdb_attr and graphdb_language both expose <subsystem>_literals_group keys in seeded_nrefs/0

Commits

8 commits across 9 plan tasks (Task 7 was a no-op — no existing graphdb_language tests asserted the old parent for base_language/project_language). Final review surfaced one Important issue (attribute_type stamp asymmetry) — fixed in d41ec2e.

Commit Subject
c6ca921 L7 Task 1: add create_literal_attribute/3 with explicit parent
933d5a1 L7 Task 2: seed Attribute Literals sub-group; reparent attr seeds
e66d475 L7 Task 3: CT cases for Attribute Literals sub-group + reparenting
c411e72 L7 Task 4: update graphdb_attr CT cases for sub-group parent
6361d9e L7 Task 5: seed Language Literals sub-group; reparent lang seeds
133a8d3 L7 Task 6: CT cases for Language Literals sub-group + reparenting
516e0cd L7 Task 8: TASKS.md L7 entry RESOLVED + doc refresh
d41ec2e L7 fix: stamp attribute_type=literal on graphdb_language seeds

🤖 Generated with Claude Code

david-w-t and others added 11 commits May 25, 2026 12:17
Adds /3 arity so workers can seed literal attributes under their own
sub-group within the Literals subtree.  /2 delegates to /3 with
?NREF_LITERALS as the default parent, preserving the existing
public API for graphdb_mgr's L4 routing and any other /2 callers.

The new gen_server message is a 4-tuple; old callers are removed by
the /2 delegation.

+1 CT case under the creators group.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ensure_seed/1 -> ensure_seed/2 taking ParentNref. init/1 seeds the
new Attribute Literals sub-group under Literals (7) first, then
seeds literal_type, target_kind, relationship_avp, attribute_type
as children of that sub-group.  attribute_literals_group_nref
field added to #state{} and exposed via seeded_nrefs/0.

retro_stamp_bootstrap_attribute_types is unchanged -- it walks
parents up to nref 7, so the new sub-group depth is transparent.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two CT cases:
- seeds_attribute_literals_subgroup verifies the sub-group attribute
  node exists and is a direct child of nref 7.
- reparents_attr_literal_seeds_under_subgroup verifies literal_type,
  target_kind, relationship_avp, attribute_type all have the
  sub-group as their direct parent.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Existing assertions of parents=[7] on seeded literal attrs updated to
use the new Attribute Literals sub-group nref. seeds_created_on_first_
start now fetches attribute_literals_group from seeded_nrefs() and
asserts [AttrLitNref]. list_attributes_includes_bootstrap_and_runtime
count updated from 27+4 to 27+5 (sub-group node included in tally).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ensure_literal_seed/1 -> /2 taking ParentNref. init/1 seeds the
new Language Literals sub-group under Literals (7) first, then
seeds base_language and project_language as children of that
sub-group. language_literals_group_nref field added to #state{}
and exposed via seeded_nrefs/0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two CT cases mirroring the Attribute Literals coverage:
- seeds_language_literals_subgroup verifies the sub-group attribute
  node exists and is a direct child of nref 7.
- reparents_language_literal_seeds_under_subgroup verifies
  base_language and project_language have the sub-group as parent.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Engineering Hygiene L7 added to TASKS.md and marked RESOLVED
(landed in this PR). apps/graphdb/CLAUDE.md worker descriptions
updated to mention the Attribute Literals and Language Literals
sub-groups, and create_literal_attribute/3 added to the attr API list.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
graphdb_attr:retro_stamp_bootstrap_attribute_types runs at the end
of graphdb_attr:init/1 -- but graphdb_language:init/1 (which runs
later) was adding three attribute-kind nodes (Language Literals
sub-group + base_language + project_language) after the retro-stamp
had already finished, leaving them without attribute_type=literal.

Adds graphdb_attr:retro_stamp_attribute_types/0 public API.
graphdb_language:init/1 calls it after its own seeding completes,
ensuring symmetry with graphdb_attr's own seeded nodes.  Establishes
the pattern for F4 Phase A's graphdb_rules:init/1 to follow.

+1 CT case (language_seeds_carry_attribute_type_literal).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Companion to docs/f4-graphdb-rules-design.md.  Records the 9-task
bite-sized plan that drove the L7 implementation (subagent-driven
development).  Frozen historical record; not actively maintained.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
L7 final-review Minor item: seeded_nrefs_present and
seeded_nrefs_above_floor used non-exhaustive map patterns that
asserted only the pre-L7 keys (lang_code, base_language,
project_language, env_language_code).  They now also assert
language_literals_group (added by L7 Task 5) and lang_human (gap-fill
added by L7 Task 5 -- previously held in #state{} but missing from
the seeded_nrefs/0 reply map).

No new test cases; both pattern matches and assertions extended in
place.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
reparents_*_under_subgroup read as active operations but their
bodies only assert the parent cache; no reparenting happens at
test time -- it happened during the worker's init/1 seeding.

Rename:
  reparents_attr_literal_seeds_under_subgroup
    -> attr_literal_seeds_parented_under_subgroup
  reparents_language_literal_seeds_under_subgroup
    -> language_literal_seeds_parented_under_subgroup

The new names ("parented") describe the verified state, matching
the suite's neighbor convention where verification tests name what
they check rather than what they cause.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@david-w-t david-w-t merged commit 006948a into davidwt-com:main May 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant