Skip to content

feat: PR-5 - entity layer + provenance-chained seed loader - #5

Merged
Eth-Interchained merged 1 commit into
mainfrom
hyperagent/2026-07-07-phase1-pr5-entities-seed
Jul 7, 2026
Merged

feat: PR-5 - entity layer + provenance-chained seed loader#5
Eth-Interchained merged 1 commit into
mainfrom
hyperagent/2026-07-07-phase1-pr5-entities-seed

Conversation

@Eth-Interchained

Copy link
Copy Markdown
Owner

Summary

PR-5 opens Phase 1: the entity layer and the seed loader. Mint on the Avenue's real data — 7-member roster, 8 menu categories, NAP, GBP facts — now flows from data/seeds/ into NEDB with full causal provenance, idempotently.

Why this matters

The engine is now the source of truth for salon data, exactly as the spec demands ("everything editable through Portal" starts with everything living in NEDB). Every seeded document TRACEs back to a content-addressed seed_runs root: which file, which hash, which run. Re-running an unchanged seed writes nothing — proven by sequence number, not by hope.

What's inside

  • src/server/entities.ts — collections, seed-file zod schemas (the salon.template.json contract), typed reads for the render plane (getIdentityByHandle, listTeam, listServiceMenus, getCity)
  • src/server/seed.ts — content-addressed loader: seed_runs provenance root → salon identity + handle → 7 stylist identities + handles → menu docs per category → cities from campaign geography (deduped, campaign-tagged) → indexes. Duplicate handles fail loud.
  • scripts/seed.ts (npm run seed) — summary, writes-this-run counter (0 = no-op), and a verify() gate: a seed run that can't prove integrity fails
  • Identity-shaped storageidentityType/handle/displayName/entity, so Phase 2's defineIdentityType registry lands without migration
  • Flat relation keys (salonHandle, cityId) + NQL WHERE — honest Phase-1 model; the engine's /link+/neighbors edges are queued as an upstream nedb-engine-client feature (the flagship feeds the library)
  • Geography upgrade — campaign cities are {slug, name}; display names curated, never derived ("Dr. Phillips")

Tests run (locally, real engine)

  • tsc --noEmit clean · unit 24/24 (slugify, categorySlug, deterministic ids, content-addressed idem keys, template skipping, schema rejection)
  • Live 3/3 vs nedbd 2.6.1: the seed test loads the REAL Mint file → asserts 8 identities + menus + 13 cities, real NAP intact (+1-407-645-2264), WHERE on flat keys proven on the engine, re-run seq delta = 0, verify() green
  • Seed CLI smoke: 38 writes on a fresh db, verify ok · portal build clean

Follow-up work

  • PR-6: Orlando's server-rendered surfaces consume these reads (salon home, service/city pages, HairSalon/BreadcrumbList JSON-LD, event tracking)
  • Upstream: link()/neighbors() on nedb-engine-client → migrate relations to typed DAG edges + TRAVERSE
  • Phase 2: defineIdentityType registry validation over these documents

Spec: §5 (schema), §6 (identity model), §15 (Phase 1).

…a flows into NEDB

Phase 1 opens: the engine becomes the source of truth for salon data.

- src/server/entities.ts: collections, seed-file zod schemas (the
  salon.template.json contract), slugify/categorySlug, typed reads the
  render plane consumes (resolveHandle, getIdentityByHandle, listTeam,
  listServiceMenus, getCity)
- src/server/seed.ts: content-addressed, idempotent loader — every run
  writes a seed_runs provenance root (id = sha256(file)[:16]); every doc
  chains caused_by to it; idem keys are content-addressed so re-running
  an unchanged seed writes NOTHING; duplicate handles fail loud
- Entities stored identity-SHAPED (identityType/handle/displayName/
  entity) so Phase 2's registry formalizes without migration; relations
  are flat keys (salonHandle, cityId) queried via NQL WHERE — the
  client doesn't wrap /link//neighbors yet (queued upstream for
  nedb-engine-client; flat keys are the honest Phase-1 model)
- scripts/seed.ts (npm run seed): summary + writes-this-run counter
  (0 = idempotent no-op) + verify() gate — a seed run that can't prove
  integrity fails
- campaigns: geography cities are now {slug, name} — display names are
  curated, never slug-derived (Dr. Phillips)
- indexes at seed time: identities.identityType, identities.salonHandle,
  services.salonHandle

Verified locally: tsc clean · unit 24/24 · live 3/3 vs nedbd 2.6.1 —
seed test proves: 8 identities (salon + 7-member roster) + 8 menus +
13 cities land, real NAP intact, WHERE on flat keys works on the real
engine, re-run seq delta = 0, verify green · seed CLI smoke (38 writes,
verify ok) · portal build clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Eth-Interchained
Eth-Interchained merged commit 2520d07 into main Jul 7, 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