Skip to content

H3 + H4 + H5 closeout; project copyright refresh#12

Merged
david-w-t merged 4 commits intodavidwt-com:mainfrom
david-w-t:develop
May 8, 2026
Merged

H3 + H4 + H5 closeout; project copyright refresh#12
david-w-t merged 4 commits intodavidwt-com:mainfrom
david-w-t:develop

Conversation

@david-w-t
Copy link
Copy Markdown
Contributor

Summary

Closes the remaining HIGH-severity tasks (H3 + H4 + H5) and refreshes
copyright/licensing across the project.

H3 — Multi-parent class inheritance (c48ef92)

  • New graphdb_class:add_superclass/2 writes a 25/26 taxonomy arc pair
    AND appends to the subject class's parents cache atomically;
    idempotent, rejects self-references.
  • do_walk_ancestors rewritten as a BFS over the multi-parent DAG via
    the node.parents cache; diamond inheritance returns shared ancestors
    exactly once.
  • Composition stays a single-chain walk (compositional hierarchy is a
    tree, not a DAG).
  • +10 CT cases under new multi_inheritance group.

H4 + H5 — Multi-class membership + class-resolver ambiguity (220d70e)

  • H4: graphdb_instance:add_class_membership/2 writes a 29/30
    instantiation arc pair AND appends to the instance's classes cache
    atomically (idempotent; rejects non-instance subjects, non-class
    targets, and missing nrefs). class_memberships/1 reads the cache.
  • H5: resolve_from_class/2 reads every membership; for each, walks
    class + taxonomy ancestors. Hits gathered as [{ClassNref, Value}].
    Three outcomes: 0 hits → not_found (fall through to Priority 3);
    single distinct value → {ok, Value}; ≥2 distinct values →
    {error, {ambiguous_class_value, AttrNref, Hits}}.
  • +13 CT cases under new multi_membership group (8 H4 + 5 H5).
  • All H-tasks now landed.

Copyright + licensing refresh (39609eb, 3f012ba)

  • Replace the legacy SeerStone "All rights reserved" proprietary block
    (which contradicted LICENSE.md) with concise SPDX-tagged headers:
    SPDX-License-Identifier: GPL-2.0-or-later.
  • Per-file authorship rule:
    • Files with Dallas content (Rev PA1 by Dallas, even stubs): two
      copyright lines (SeerStone Inc. 2008 + David W. Thomas 2026).
    • Files entirely David's: one line (David W. Thomas 2026).
  • 46 files now carry SPDX headers: 32 .erl + bootstrap.terms + 13 .md.
  • New NOTICE.md at project root: project-level copyright, SPDX
    identifier, attribution to Dallas's 2008 originals and the
    patent / Cogito derivation.
  • Programming-Erlang attribution in dictionary_imp.erl was preserved
    through the sweep, then dropped in a follow-up commit since the
    inline pg. 424 reference made the global divider redundant.
  • Excluded: LICENSE.md, tooling under .wolf/ and .claude/, build
    configs (rebar.config, *.app.src, Makefile, sys.config,
    default.config, ci.yml).

Docs

  • ARCHITECTURE.md §1, §9, §10 updated; multi-class entry retired.
  • TASKS-HIGH.md: H3, H4, H5 marked RESOLVED; preamble notes all
    H-tasks have landed.
  • README.md: test counts (196 → 209), suite descriptions, status
    table refreshed.

Test plan

  • ./rebar3 compile — clean (zero warnings)
  • ./rebar3 ct — 145 CT pass
  • ./rebar3 eunit — 64 EUnit pass
  • Cache invariant verified by every CT suite's end_per_testcase
  • No "All rights reserved" remnants in source/doc files
  • NOTICE.md renders correctly on GitHub
  • CI green on GitHub Actions

🤖 Generated with Claude Code

david-w-t and others added 4 commits May 7, 2026 23:04
graphdb_class:add_superclass/2 atomically writes a 25/26 taxonomy arc
pair and appends to the subject's parents cache; idempotent; rejects
self-references.  do_walk_ancestors rewritten as BFS over the multi-
parent DAG via node.parents, so diamond inheritance returns shared
ancestors exactly once.  Composition stays single-chain (the
compositional hierarchy is a tree).

+10 CT cases under a new multi_inheritance group: basic add, arc
shape, idempotency, self-ref rejection, subject/target validation,
multi-parent BFS, diamond dedup, multi-parent QC inheritance,
class_in_ancestry over added parents.

ARCHITECTURE.md / README.md / TASKS-HIGH.md updated.  Test totals:
196 (132 CT + 64 EUnit).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…s resolver

H4 — graphdb_instance:add_class_membership/2 and class_memberships/1.
add_class_membership/2 atomically writes a 29/30 instantiation arc pair
AND appends to the instance's classes cache; idempotent; rejects
non-instance subjects, non-class targets, and missing nrefs.
class_memberships/1 reads the classes cache (kept consistent with the
29-characterized arcs by the H0c invariant).

H5 — resolve_from_class/2 now reads every class membership and, for
each one, walks the class node plus its taxonomy ancestors. Hits are
gathered as [{ClassNref, Value}] (ClassNref is whichever class actually
held the value). Three outcomes: no hits -> not_found (fall through to
Priority 3); a single distinct value -> {ok, Value}; two or more
distinct values -> {error, {ambiguous_class_value, AttrNref, Hits}}.

Tests: new multi_membership group in graphdb_instance_SUITE — 8 cases
for H4 (basic add, arc shape, idempotent, four reject paths, initial
single-membership readback) and 5 cases for H5 (unique-across-two-
classes, same-value-two-classes, ambiguous-two-classes, local-
overrides-ambiguity, ambiguity-via-taxonomy). 132 -> 145 CT tests.

Docs: ARCHITECTURE §1, §9, §10 updated; §10 multi-class entry retired
(closed). TASKS-HIGH.md: H4 and H5 marked RESOLVED; preamble notes all
H-tasks have landed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…or-later)

Replaced the legacy SeerStone 'All rights reserved' proprietary block
across the project with concise SPDX-tagged copyright headers, reflecting
the project's actual license (LICENSE.md is GPL-2.0 with 'or any later
version' allowed).

Per-file rule (strict per-file authorship):
- Files with Dallas content (Rev PA1 by Dallas, even stubs): two
  copyright lines (SeerStone, Inc. 2008 + David W. Thomas 2026).
- Files entirely David's (no Rev PA1, Created: April 2026): one line
  (David W. Thomas 2026).

Headers carry SPDX-License-Identifier: GPL-2.0-or-later.

Erlang sources (33 files):
- 22 with both lines: apps/{database,dictionary,graphdb,nref,seerstone}/
  src/*.erl (Dallas's modules incl. stubs that David reimplemented).
- 10 with David only: apps/graphdb/src/graphdb_bootstrap.erl plus
  apps/graphdb/test/*.erl (David-authored test infrastructure).
- The Programming-Erlang attribution previously inside the proprietary
  block in dictionary_imp.erl is preserved as a separate divider.

Data:
- apps/graphdb/priv/bootstrap.terms gets both lines (encodes Dallas's
  31-node BFS scaffold design).

Markdown docs (13 files, HTML-comment header so rendered output is
unchanged):
- the-knowledge-network.md: both lines (synthesizes Noyes patents +
  Cogito documentation).
- README.md, ARCHITECTURE.md, arcs-authoritative.md, TASKS-*.md,
  CLAUDE.md (root + 4 app-level), NOTICE.md: David only.

Excluded:
- LICENSE.md (license text itself).
- Tooling under .wolf/ and .claude/.
- Build configs (rebar.config, *.app.src, Makefile, sys.config,
  default.config, ci.yml) per scope agreement.

NOTICE.md is new at project root: project-level copyright, SPDX
identifier, attribution to Dallas's 2008 originals and the patent /
Cogito derivation, pointer to LICENSE.md.

Tests still green: 145 CT + 64 EUnit = 209.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The line was a global note inherited from Dallas's original — but it
explained nothing the inline 'pg. 424' comment two lines below doesn't
already say. Other files with the same kind of inline page references
(dev_lib.erl, lines 46 and 81) never carried this divider, so removing
it makes the convention consistent across the project.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@david-w-t david-w-t merged commit 61c5488 into davidwt-com:main May 8, 2026
1 check passed
david-w-t added a commit to david-w-t/SeerStoneGraphDb that referenced this pull request May 9, 2026
All H-tasks (H0a-H0e, H1+H2, H3, H4+H5) landed in PRs davidwt-com#10 and davidwt-com#12.
Per the task-file retirement workflow (close-out PR keeps the file
with finish markers; the next PR opens with a removal commit), drop
the file and prune cross-references in CLAUDE.md, README.md,
ARCHITECTURE.md, arcs-authoritative.md, TASKS-MEDIUM.md, and the
two app-level CLAUDE.md files.
david-w-t added a commit that referenced this pull request May 9, 2026
* M4: atomic reciprocal attribute pair

graphdb_attr:create_relationship_attribute/3 now writes both attribute
nodes and all four compositional arc rows inside a single Mnesia
transaction.  Previously the forward and reciprocal nodes were created
in separate transactions; if the second aborted, the database was left
with an orphan forward attribute and no usable reciprocal.

New private helper do_create_relationship_attribute_pair/3 allocates
the 2 node nrefs and 4 arc-id nrefs outside the transaction (avoiding
side-effects on retry) and writes 6 rows in one txn.

Test: create_relationship_attribute_pair_atomic asserts the row deltas
on `nodes` and `relationships` after a successful pair creation are
exactly +2 and +4 respectively, and that both nodes have exactly one
parent->child arc into them under nref 8.

Tests green: 146 CT + 64 EUnit = 210.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* M3: validate add_relationship endpoints and target_kind

graphdb_instance:add_relationship now runs an explicit validation pass
before resolving classes/templates and writing arcs.  Five new failure
modes, all returning structured {error, _} tuples:

  - {source_not_found, Nref}
  - {target_not_found, Nref}
  - {characterization_not_found, Nref}
  - {reciprocal_not_found, Nref}
  - {characterization_not_an_attribute, Nref, ActualKind}
  - {reciprocal_not_an_attribute, Nref, ActualKind}
  - {target_kind_mismatch, ExpectedKind, ActualKind}

The four endpoint reads run in one mnesia:transaction.  target_kind is
sourced from the seeded `target_kind` literal-attribute (graphdb_attr);
the nref is fetched once at graphdb_instance init via
graphdb_attr:seeded_nrefs() and cached in a new gen_server state
record.  Arc-label nodes that lack a target_kind AVP (relationship-
type bucket nodes, legacy data) skip the kind check.

The state record is a clean break from the previous `[]` carrier; only
the new validation needs it, but threading it through add_relationship
keeps the gen_server signature consistent.

Tests: +5 CT cases under the `relationships` group covering missing
source/target, non-attribute characterization, non-attribute
reciprocal, and target_kind mismatch (target_kind=class vs. instance
target).  151 CT + 64 EUnit = 215 green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* M5: per-arc AVPs at connection creation

graphdb_instance:add_relationship/6 (S, C, T, R, TemplateNref,
{FwdAVPs, RevAVPs}) -> ok | {error, _} accepts per-direction user AVPs
and stamps them on the connection rows alongside the auto-applied
Template AVP.  Per-direction (asymmetric) is required by §5: connection
metadata such as provenance, confidence, weights, and validity windows
is direction-specific.

The Template AVP stays at index 0 of each row's avps list; user AVPs
follow.  /4 and /5 stay non-breaking and pass {[],[]} to /6 internally.
write_connection_arcs is updated to take {FwdAVPs, RevAVPs} and the
gen_server message form gains AVPSpec as a 7th tuple element.

Tests: +3 CT cases under the `relationships` group:
  - add_relationship_stamps_user_avps -- user AVP is present alongside
    Template AVP on the forward row
  - add_relationship_avps_are_per_direction -- a forward-only AVP must
    not leak into the reverse row, and vice versa
  - add_relationship_default_avps_empty -- /4 still produces a row
    with exactly the Template AVP

154 CT + 64 EUnit = 218 green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Docs: M3 + M4 + M5 closeout in TASKS-MEDIUM, refresh test counts

Mark M3, M4, M5 RESOLVED in TASKS-MEDIUM.md with status blocks
describing the API and test additions for each.  Bump README and
ARCHITECTURE test counts (209 -> 218; 145 CT -> 154 CT).  Update
graphdb_attr_SUITE row to mention atomic reciprocal pair, and
graphdb_instance_SUITE row to mention M3 validation and M5 per-arc
AVPs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Retire TASKS-HIGH.md

All H-tasks (H0a-H0e, H1+H2, H3, H4+H5) landed in PRs #10 and #12.
Per the task-file retirement workflow (close-out PR keeps the file
with finish markers; the next PR opens with a removal commit), drop
the file and prune cross-references in CLAUDE.md, README.md,
ARCHITECTURE.md, arcs-authoritative.md, TASKS-MEDIUM.md, and the
two app-level CLAUDE.md files.

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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