Part of #113 (Layer 1 — core).
Node identity stops being global-by-name. Identity = name + discriminator set.
- Discriminators = a small, curated, declared vocabulary of identity-bearing
axes (project, env, client, version). Default discriminator = project
(auto, from #auto-tagging). Per-type override (e.g. Config keyed by
project+env; Vendor keyed by nothing = global).
- Empty discriminator set = global/shared — one node accrues facts across all
projects (Postgres, GDPR, gRPC).
- Facets (all other props/tags: topic, source, status) are free & dynamic and
are NOT part of identity — navigating/filtering only.
- Upsert (
InsertNode) matches on name + discriminators, not name alone.
Migration (discriminator storage on nodes) + store upsert change + core wiring.
Acceptance: Config{project:goroutly} and Config{project:brainiac} are two
distinct nodes; adding a facet tag to a node does not fork its identity;
Postgres (empty discriminators) is a single global node.
Part of #113 (Layer 1 — core).
Node identity stops being global-by-name. Identity =
name + discriminator set.axes (
project,env,client,version). Default discriminator =project(auto, from #auto-tagging). Per-type override (e.g.
Configkeyed byproject+env;Vendorkeyed by nothing =global).projects (Postgres, GDPR, gRPC).
are NOT part of identity — navigating/filtering only.
InsertNode) matches onname + discriminators, not name alone.Migration (discriminator storage on nodes) + store upsert change + core wiring.
Acceptance:
Config{project:goroutly}andConfig{project:brainiac}are twodistinct nodes; adding a facet tag to a node does not fork its identity;
Postgres(empty discriminators) is a single global node.