Skip to content

docs(corpus): add data-entity corpus template - #1545

Merged
tucktuck101 merged 1 commit into
launchpadfrom
task/1333-corpus-template-data-entity
Aug 28, 2026
Merged

docs(corpus): add data-entity corpus template#1545
tucktuck101 merged 1 commit into
launchpadfrom
task/1333-corpus-template-data-entity

Conversation

@serina-mcfall

Copy link
Copy Markdown

Summary

Adds launchpad/docs/corpus/templates/data-entity.md, the corpus template for
documenting one Buzz domain concept -- its identity, attribute shape,
invariants and relationships to other entities -- independent of the Nostr
wire contract that mutates it or the storage technology that holds it.
Grounded in JSON Schema 2020-12, NIP-01's event envelope, and this repo's own
thread_metadata/reply-event split as a worked illustration.

Related issue

Closes #1333

Issue type

Task


Agent provenance

Field Value
Harness / provider Claude Code
Model claude-sonnet-5
Session reference N/A - harness does not expose a run id/URL
Initiating human @serina-mcfall (batch dispatch brief for #1329/#1333/#1334/#1343/#1348)

Objective

Create launchpad/docs/corpus/templates/data-entity.md as the corpus
template a future data-entity node (e.g. Channel, Thread) would be authored
from.

Impacted components

  • launchpad/docs/corpus/templates/data-entity.md

Approach and rejected alternatives

Grounded the template in JSON Schema 2020-12 for attribute shape, because this
corpus's own node.schema.json already declares $schema: https://json-schema.org/draft/2020-12/schema -- reusing an already-adopted
convention rather than introducing a second schema language. Checked the
classical entity-relationship model (Peter Chen, 1976, ACM TODS) as the usual
primary source for "entity"/"attribute"/"relationship" terminology and
rejected citing it: its canonical ACM Digital Library page returned HTTP 403
Forbidden on direct fetch (paywalled), and no search for a mirrored free copy
was attempted, so the node states plainly that it was checked, not read, and
does not cite it -- the same treatment issue #1348's specification template
gives ISO/IEC/IEEE 29148 when its own primary source is unreadable. The
research note at launchpad/Research/project-documentation-templates.md
(unmerged PR #1466) does not cover data-entity at all -- confirmed by
re-reading it fresh for this task -- so this required its own primary-source
research rather than citing that note for structure.

Stated the boundary against #1334/datastore (my sibling this batch, not yet
drafted when this node was written) in both directions in the Purpose
section: a data entity is the domain concept, a datastore is the storage
technology holding it. Also stated the boundary against the already-open
#1337/event-kind template (PR #1542) by reading its actual diff rather than
guessing: event-kind documents one Nostr kind's wire contract and claims
type: interfaces-events for its own real instances; this template's real
instances most plausibly take type: implementation instead, reasoned
through in the evidence ledger against both interfaces-events and
architecture (the value both the architecture-container template, #1327/PR
#1529, and the deployment template, #1336/PR #1536, independently claim for
their own real instances).

Used this repository's own thread_metadata table + reply events as a worked,
explicitly-scoped illustration (not a real corpus node) of why the boundary
matters concretely: one entity, two representations -- the reply events are
the source of truth, thread_metadata is a derived projection that root
CLAUDE.md's own "Thread counters" gotcha already warns can drift out of
sync if a code path forgets to update it. Neither the event-kind template
(one kind's wire shape) nor the datastore template (a table's storage
mechanics) has a natural place to say the two representations must agree; a
data-entity node does.

type: governance for this template document itself, matching every other
corpus meta-document at the recorded revision (README.md,
standards/confidence.md, standards/decision-references.md; AGENTS.md is
the sole type: agent exception) -- spot-checked directly against
node.schema.json, schema/README.md and schema/COMPATIBILITY.md rather
than assumed, per the batch dispatch brief.

No relationships declared: at the recorded revision origin/launchpad's
corpus tree carries exactly four validated content nodes (corpus-agents,
corpus-readme, corpus-standard-confidence,
corpus-standard-decision-references), checked directly via git ls-tree,
and none has data modeling as its subject. The batch-4 siblings and the
already-open event-kind/deployment templates are unmerged and therefore not
valid relationship targets per AGENTS.md's rule.

A note on this issue's own definition of done. #1333's DoD checklist
carries a MUST/SHOULD/enforcement/policy block copied verbatim from the
standards-track issues (confidence.md, decision-references.md) -- boilerplate
residue, not a claim that a data-entity template is a policy document. The
node's own "Scope and authority" section names this explicitly and builds
against PRD #605's actual stated acceptance bar for a template task instead:
every template states its purpose, required sections, evidence expectations
and the industry model/standard it adapts.

No alternative structure for the document itself was seriously considered
beyond mirroring the section shape the deployment (#1336) and event-kind
(#1337) templates already established (Scope and authority / Purpose /
Industry model / Required sections / worked illustration / Scope and
omissions) -- consistency across sibling templates was judged more valuable
than a bespoke structure for this one.

Verification

Command run:

python3 -m unittest discover -s launchpad/docs/corpus/schema/tests -p "test_*.py" -v

Raw output:

test_duplicate_audiences_rejected (test_schema.InvalidFixtureTest.test_duplicate_audiences_rejected) ... ok
test_fact_with_forbidden_fields_rejected (test_schema.InvalidFixtureTest.test_fact_with_forbidden_fields_rejected) ... ok
test_inference_missing_confidence_rejected (test_schema.InvalidFixtureTest.test_inference_missing_confidence_rejected) ... ok
test_malformed_id_rejected (test_schema.InvalidFixtureTest.test_malformed_id_rejected) ... ok
test_missing_audiences_rejected (test_schema.InvalidFixtureTest.test_missing_audiences_rejected) ... ok
test_missing_evidence_field_rejected (test_schema.InvalidFixtureTest.test_missing_evidence_field_rejected) ... ok
test_missing_evidence_for_fact_rejected (test_schema.InvalidFixtureTest.test_missing_evidence_for_fact_rejected) ... ok
test_missing_evidence_for_inference_rejected (test_schema.InvalidFixtureTest.test_missing_evidence_for_inference_rejected) ... ok
test_missing_identity_rejected (test_schema.InvalidFixtureTest.test_missing_identity_rejected) ... ok
test_missing_origin_rejected (test_schema.InvalidFixtureTest.test_missing_origin_rejected) ... ok
test_missing_status_rejected (test_schema.InvalidFixtureTest.test_missing_status_rejected) ... ok
test_missing_type_rejected (test_schema.InvalidFixtureTest.test_missing_type_rejected) ... ok
test_team_knowledge_missing_provided_by_rejected (test_schema.InvalidFixtureTest.test_team_knowledge_missing_provided_by_rejected) ... ok
test_unknown_audience_value_rejected (test_schema.InvalidFixtureTest.test_unknown_audience_value_rejected) ... ok
test_unknown_origin_rejected (test_schema.InvalidFixtureTest.test_unknown_origin_rejected) ... ok
test_unknown_relationship_type_rejected (test_schema.InvalidFixtureTest.test_unknown_relationship_type_rejected) ... ok
test_unknown_status_rejected (test_schema.InvalidFixtureTest.test_unknown_status_rejected) ... ok
test_unknown_type_rejected (test_schema.InvalidFixtureTest.test_unknown_type_rejected) ... ok
test_unrecognized_field_rejected (test_schema.InvalidFixtureTest.test_unrecognized_field_rejected) ... ok
test_wrong_direction_relationship_rejected (test_schema.InvalidFixtureTest.test_wrong_direction_relationship_rejected) ... ok
test_every_enum_member_has_metadata (test_schema.RelationshipEnumMetadataTest.test_every_enum_member_has_metadata) ... ok
test_every_metadata_entry_has_directionality_and_inverse (test_schema.RelationshipEnumMetadataTest.test_every_metadata_entry_has_directionality_and_inverse) ... ok
test_relationship_enum_matches_node_schemas_inlined_copy (test_schema.RelationshipEnumMetadataTest.test_relationship_enum_matches_node_schemas_inlined_copy) ... ok
test_node_schema_is_valid_json_schema (test_schema.SchemaMetaValidityTest.test_node_schema_is_valid_json_schema) ... ok
test_relationships_schema_is_valid_json_schema (test_schema.SchemaMetaValidityTest.test_relationships_schema_is_valid_json_schema) ... ok
test_full_fixture_passes (test_schema.ValidFixtureTest.test_full_fixture_passes) ... ok
test_minimal_fixture_passes (test_schema.ValidFixtureTest.test_minimal_fixture_passes) ... ok

----------------------------------------------------------------------
Ran 27 tests in 0.032s

OK

Command run:

python3 launchpad/project-intelligence/corpus/validate.py

Raw output:

UNVERIFIED  corpus-agents: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-agents: evidence entry 20, citation 1: is a graph-edge or tool-result citation, which names no openable file
UNVERIFIED  corpus-readme: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-confidence: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-decision-references: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-template-data-entity: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-template-data-entity: evidence entry 9, citation 1: is a graph-edge or tool-result citation, which names no openable file
UNVERIFIED  corpus-template-data-entity: evidence entry 19, citation 1: is an external URL this validator can neither pin nor open
UNVERIFIED  corpus-template-data-entity: evidence entry 19, citation 2: is an external URL this validator can neither pin nor open
UNVERIFIED  corpus-template-data-entity: evidence entry 21, citation 1: is a graph-edge or tool-result citation, which names no openable file
UNVERIFIED  corpus-template-data-entity: evidence entry 22, citation 1: is a graph-edge or tool-result citation, which names no openable file
PASS  corpus validation found no errors; 11 item(s) reported unverified

The 11 UNVERIFIED notices are expected and non-fatal, per AGENTS.md: commit
citations, tool-result citations (git_ls_tree, the two ACM-paywall
webfetch checks), and external (non-GitHub) URLs are all structurally
un-openable by the checker and always report UNVERIFIED rather than pass or
fail.

  • Tests or checks were run and the raw output is pasted above
  • The diff is confined to the scope of the linked issue
  • No secrets, keys, tokens or hostnames were added to tracked files

Not verified

No real corpus node has been authored from this template yet (Channel is the
most likely first candidate, given it already has a dedicated buzz-core
module) -- whether the six required sections are sufficient, or whether a
real entity surfaces a concern this template does not anticipate, is
untested; the deployment template (#1336) records the identical caveat for
its own first-instance risk. Whether relationships.schema.json's five
relationship types are sufficient for entity-to-entity edges (a foreign key
is arguably closer to depends-on than to references in some cases) was
not settled -- the worked illustration picks references for the
thread-reply case as the more conservative reading, not as a general rule.
Whether a JSON Schema fragment belongs inline in a data-entity node's body or
as a separate generated artifact was not resolved -- until #1316's
generated-artifact mechanism lands, only the inline form is possible. No
search beyond the canonical ACM Digital Library page was made for a free
mirror of Chen 1976, so "paywalled" is established at the canonical source
only, not exhaustively. Cross-model (Codex) review did not run -- #1467
records the Codex workspace is out of credits and no other external-model CLI
is installed on this machine; a same-model adversarial self-review pass (this
document was drafted, then independently re-read against its own evidence
ledger and corrected: the Chen-paywall claim was softened from "no free copy
exists" to "not searched beyond the canonical source," an incorrect
implements-direction reference between sibling instance nodes was fixed to
references, and a body claim about architecture-container/deployment's own
type: architecture choice was given its own ledger citation) substitutes,
per the batch dispatch brief.

Security implications

None. This is a documentation-only change to a corpus template file; it adds
no code, no dependencies, and no runtime behavior.

Escalations

None. No defect in other code, other scope, or deferred work was found while
researching or drafting this node. Checked #1532 and #1538 (the two existing
escalation issues from this track) for overlap with this task's subject
(API-reference-vs-plain-reference and Diátaxis Tutorial gaps, respectively) --
neither is related to data-entity modeling.

Adds launchpad/docs/corpus/templates/data-entity.md, the corpus template
for documenting one Buzz domain concept (identity, attribute shape,
invariants, relationships to other entities) independent of the Nostr
wire contract that mutates it (#1337/event-kind) and the storage
technology that holds it (#1334/datastore). Grounded in JSON Schema
2020-12 (already used by this corpus's own node.schema.json), NIP-01's
event envelope, and this repo's own thread_metadata/reply-event split
as a worked source-of-truth-vs-derived-state illustration. Closes #1333.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
@serina-mcfall serina-mcfall added the by:agent Filed or authored by an AI agent, not a human label Aug 27, 2026
@serina-mcfall
serina-mcfall marked this pull request as ready for review August 27, 2026 05:27
@tucktuck101 tucktuck101 self-assigned this Aug 27, 2026

@tucktuck101 tucktuck101 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — data-entity corpus template

Clean boundary against the datastore template — this node correctly hands column types, indexes
and partitioning to #1548 (:341), and #1548 accepts the handoff. Two findings, both about
accuracy rather than shape.

Medium — the worked Identity illustration is wrong about thread_metadata

:353-357 states that thread_metadata "is primary-keyed
(community_id, event_created_at, event_id) per its own schema, not by root_event_id alone —
every row, including the root's own, carries a root_event_id pointer."

The primary-key half is correct (migrations/0001_initial_schema.sql:527). The second half is
false, verified on launchpad:

  • migrations/0001_initial_schema.sql:519 declares root_event_id BYTEA with no NOT NULL.
  • crates/buzz-db/src/thread.rs:163-172 — the stub insert whose own comment reads "Root (depth=0)
    messages don't get a row on first insert, so we create a stub here" — inserts
    VALUES ($1, $2, $3, $4, NULL, NULL, NULL, NULL, 0, false), i.e. root_event_id NULL for the
    root's own row. The separate root stub uses the same NULL pattern.
  • The Rust field is root_event_id: Option<Vec<u8>>.

This sits in a section explicitly labelled "not a real node" and no ledger FACT covers it, which is
why it is medium rather than high — but it is the template's teaching example for writing an
Identity section, and the first real corpus thread node would copy it verbatim. Fix: "every reply
row carries a root_event_id pointer; the root's own row is a stub with root_event_id NULL."

Low — the schema does not "reserve" implements for instance-to-template edges

:328-332 tells an author to use references and "not implements, which
relationships.schema.json reserves for a node's relationship to the template it was instanced
from." The schema says no such thing: relationships.schema.json:35-36 gives implements'
directionality as "source is the concrete realization of target (e.g. a template instance of a
standard)" — a worked example introduced by "e.g.", not a reservation, and its wording is "a
standard", not "a template".

Sibling #1548 reads the identical line the opposite way (datastore.md:511-521), so the batch
would land two templates telling authors incompatible things about one schema line. The practical
guidance (use references for a sibling-instance edge) is fine; only the justification is wrong.
Drop "reserves".

What is correct

  • The datastore boundary is stated from this side and matches #1548's own text.
  • Instance type guidance names in-enum values; required sections map onto the skeleton, so an
    instance validates.
  • All repo-path citations resolve at head.

Not findings, ruled out on evidence

  • Index registration: the corpus AGENTS.md and README.md both state that indexes are
    generated derived views, never hand-authored, and the ten-step "Creating a node" procedure has
    no registration step. All 26 template PRs leaving AGENTS.md untouched is correct.
  • CI green at head (latest run per check); node validates clean.

Reviewed by tucktuck101's review lane. Every failing claim reported above was reproduced by me against this PR head before posting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

by:agent Filed or authored by an AI agent, not a human

Projects

None yet

Development

Successfully merging this pull request may close these issues.

task: define the data entity corpus template

2 participants