|
| 1 | +--- |
| 2 | +title: "Relation kinds are inverse pairs — one stored string can't speak from both seats" |
| 3 | +lede: "NextLadder is funded_by Ballmer Group; Ballmer Group is funder_of NextLadder — the same edge needs a different kind string per perspective, and today only one pair is special-cased in a read-time map." |
| 4 | +date_created: 2026-07-28 |
| 5 | +date_modified: 2026-07-28 |
| 6 | +authors: |
| 7 | + - Michael Staton |
| 8 | +augmented_with: |
| 9 | + - Claude Code on Claude Fable 5 |
| 10 | +semantic_version: 0.0.0.1 |
| 11 | +tags: |
| 12 | + - Issue |
| 13 | + - Augment-It |
| 14 | + - Org-Relations |
| 15 | + - Data-Modeling |
| 16 | +status: Active |
| 17 | +--- |
| 18 | + |
| 19 | +# Relation kinds are inverse pairs |
| 20 | + |
| 21 | +## The observation (operator, 2026-07-28) |
| 22 | + |
| 23 | +> relationships have the kind/type string. They are often inverse, so need |
| 24 | +> to be written both ways inverted. So NextLadder is funded_by Ballmer |
| 25 | +> Group, Ballmer Group is funder_of NextLadder. |
| 26 | +
|
| 27 | +One org↔org edge, one truth — but the **kind string reads differently |
| 28 | +depending on which card you're standing on.** `rel` (parent/child/peer) |
| 29 | +already gets this right via read-time projection; `kind` mostly doesn't. |
| 30 | + |
| 31 | +## Current state (shipped same day, deliberately partial) |
| 32 | + |
| 33 | +- Kinds are authored ONCE, from the edge's `in` side |
| 34 | + (`ballmer-group —funder_of→ nextladder`). Storage is a single string. |
| 35 | +- `listOrgRelations` inverts at read time via a **hardcoded map** in |
| 36 | + `org-relations.ts` (`KIND_INVERSE`): `funder_of ↔ funded_by`, |
| 37 | + `funds → funded_by`. That fixed the NextLadder card — and nothing else. |
| 38 | +- Every other directional kind still reads wrong from one seat: |
| 39 | + - Hierarchical kinds on the CHILDREN listing: the parent's card shows |
| 40 | + `cfat (initiative_of)` — reading as if CFAT were initiative_of the |
| 41 | + viewer's child, when the honest label from the parent's seat is |
| 42 | + something like `has_initiative`. |
| 43 | + - Any future directional kind (`member_of`, `spun_out_of`, |
| 44 | + `fiscal_sponsor_of`…) silently inherits the defect until someone adds |
| 45 | + a map entry. |
| 46 | +- Symmetric kinds (`partners_with`) are fine — they're their own inverse. |
| 47 | + |
| 48 | +## Design space (log, don't decide) |
| 49 | + |
| 50 | +1. **Extend the read-time map** — cheapest; the vocabulary lives in code: |
| 51 | + `initiative_of → has_initiative`, `fund_of → has_fund`, |
| 52 | + `program_of → has_program`, `agency_of → has_agency`, |
| 53 | + `chapter_of → has_chapter`, symmetric kinds mapping to themselves. |
| 54 | + Con: open-vocabulary kinds (the operator can type anything) get no |
| 55 | + inverse until code changes. |
| 56 | +2. **Store both directions on the edge** (`kind` as authored + |
| 57 | + `kind_inverse`, both writable at relate/update time) — redundancy-over- |
| 58 | + normalization house ethos; the operator can author asymmetric wording; |
| 59 | + reads pick by seat. Con: two fields to keep coherent on update. |
| 60 | +3. **A kind-vocabulary table** (pairs as data, per client like `tag_vocab`) |
| 61 | + — inverse pairs become operator-curated data, the datalist can offer |
| 62 | + both forms, exports/didi read the same source. Most machinery. |
| 63 | + |
| 64 | +Whatever the choice, the UI datalist and didi's slab should present kinds |
| 65 | +in the operator's seat-relative form ("is funded_by…" when relating from |
| 66 | +the recipient's side), and the export's `related_orgs` column has the |
| 67 | +same seat problem. |
| 68 | + |
| 69 | +## See also |
| 70 | + |
| 71 | +- `services/record-surrealdb-resolver/src/org-relations.ts` — the |
| 72 | + `KIND_INVERSE` map (the partial fix) + the shapeRelated projection. |
| 73 | +- [[../plans/Org-Relations-Parent-Child-Peer-Plus-Org-Tags]] — the shipped |
| 74 | + model this refines. |
| 75 | +- Live examples to test any fix against: NextLadder's four funders, the |
| 76 | + National Academy for AI Instruction's three, CFAT ⊂ carnegie-foundation, |
| 77 | + FIPSE ⊂ us-department-of-education. |
0 commit comments