Spesifiser nodereferanser: n:-konvensjon, tilgangsprompt, privacy-signalering

Ny feature-spec for universelle nodereferanser i Synops:
- n:<id> syntaks for å linke til enhver node fra enhver kontekst
- 🔗-knapp på alle noder for kopier-lim, n:-autocomplete i editor
- Tilgangsprompt ved linking av privat node i delt kontekst
  (del som lesbar / behold privat / del utdrag)
- Privacy-signalering: privat=🔒, delt=ren, delt+lenket=👁
- Inversert markering: privathet signaliseres, fravær=trygt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-18 10:50:59 +00:00
parent cee97c105f
commit d532e048b1

View file

@ -0,0 +1,164 @@
# Feature: Nodereferanser (`n:`-konvensjonen)
## Konsept
Enhver node i Synops kan refereres fra enhver annen node via
`n:<id>`-syntaksen. Det er systemets interne lenkeformat — som
URL-er for webben, men for grafen. Referanser oppretter
`mentions`-edges og er traverserbare for bot og brukere med
tilgang.
## Syntaks
```
n:d3eebc99 → UUID-prefix (8 tegn, unikt nok)
n:synops-transcribe → slug/title-match
#Skolepolitikk → eksisterende mention (topic-noder)
```
`n:` er den universelle varianten. `#` forblir en snarvei for
topics. Begge oppretter `mentions`-edges.
## To veier inn
### 1. Kopier-lim (🔗-knappen)
Hver node har en lenke-knapp (🔗) i header/hover — universelt,
overalt (kanban-kort, chat, kalender, work items, dagbok, alt).
```
Klikk 🔗 → clipboard: "n:d3eebc99"
→ Lim inn i chat/editor/anywhere
→ Systemet gjenkjenner, oppretter mentions-edge
```
### 2. Autocomplete
```
Skriv "n:" i editor/chat
→ Dropdown med nylige/relevante noder
→ Søkbart (som #-mentions, bare for alle noder)
→ Velg → settes inn som n:d3eebc99
```
## Rendering
```
Raw: "Se n:d3eebc99 for detaljer"
Rendered: "Se [Forbedre lydkvalitet] for detaljer"
↑ klikkbar, hover viser node-kort
```
Hvis brukeren ikke har tilgang til noden:
```
Rendered: "Se [Privat node 🔒] for detaljer"
```
## Edge-opprettelse
Ved parsing av `n:<id>` i content:
- Slå opp noden i PG
- Opprett `mentions`-edge fra denne noden → referert node
- Edge er ikke `system` — synlig i grafvisning
## Tilgangskontroll ved linking
Når en bruker limer inn en referanse til en privat node i en
delt kontekst, må systemet håndtere tilgangsgapet.
### Prompt ved privat node i delt kontekst
```
A limer inn n:d3eebc99 (sin private dagboknotis) i en samtale
→ Systemet sjekker: synlig for alle i konteksten?
→ Nei — noden er privat
→ A ser prompt:
┌──────────────────────────────────────────┐
│ Denne noden er privat. │
│ │
│ [Del som lesbar] │
│ → Deltakerne får lesetilgang │
│ │
│ [Behold privat] │
│ → Andre ser "Privat node 🔒" │
│ │
│ [Del utdrag] │
│ → Velg tekst som siteres inline │
│ → Originalen forblir privat │
└──────────────────────────────────────────┘
```
### Tre valg
| Valg | Hva skjer | Edge |
|------|-----------|------|
| **Del som lesbar** | Deltakerne får `reader`-edge til noden | `reader` per deltaker |
| **Behold privat** | Lenken vises, andre ser "Privat node 🔒" | Ingen ny edge |
| **Del utdrag** | Sitat inline, originalen privat | `source_material` med excerpt |
"Del utdrag" er universell overføring — innhold dras *ut* av en
privat node som et sitat, ikke som originalen.
### Trekk tilbake
Deling kan alltid angres: fjern `reader`-edges, noden går tilbake
til privat. Lenker i andres kontekst viser igjen "Privat node 🔒".
## Privacy-signalering
Private noder markeres visuelt. Delte noder er *rene* — fravær av
markering betyr "dette er ikke privat."
### Visuell konvensjon
| Tilstand | Signal | Betydning |
|----------|--------|-----------|
| **Privat** (ingen delte edges) | 🔒 + subtil bakgrunnsfarge | "Bare du ser dette" |
| **Delt** (har reader/member-edges) | Ren, ingen markering | Normal tilstand |
| **Delt + lenket** (aktivt referert fra annen kontekst) | 👁 + "Delt med: ..." | "Andre ser dette via en lenke" |
### Eksempel i dagbok
```
┌─────────────────────────────────┐
│ 🔒 Tanker om episoden i dag │ ← privat
├─────────────────────────────────┤
│ Notater fra møtet med Trond │ ← delt
├─────────────────────────────────┤
│ 🔒 Personlig refleksjon │ ← privat
├─────────────────────────────────┤
│ 👁 Lydkvalitet-problemet │ ← delt + lenket
│ "Delt med: #Redaksjonen" │
└─────────────────────────────────┘
```
### Designprinsipp
De fleste systemer markerer det *delte* ("denne er offentlig!").
Synops markerer det *private* — slik at fravær av markering er
den normale, trygge tilstanden. Du ser umiddelbart hva som er
bare ditt, og du glemmer ikke at noe er delt.
### Teknisk
Ingen ny datamodell. Ren frontend-logikk basert på eksisterende
data:
- `visibility: hidden` + ingen delte edges → 🔒
- Har `reader`/`member_of`-edges fra andre → ren
- Har edges + er `source_material`-target fra annen node → 👁
## Bot-oppførsel
Boten følger samme tilgangsregler:
- Kan bare se noder den har tilgang til
- Kan traversere `mentions`-edges fra `n:`-referanser
- Hvis noen linker en node boten ikke kan se: "Jeg har ikke
tilgang til den noden"
## Bygger på
- `docs/primitiver/edges.md``mentions`-edge
- `docs/retninger/bruker_ikke_workspace.md` — visibility + tilgangsmatrise
- `docs/features/universell_overfoering.md` — "del utdrag" er innholdstransfer
- `docs/proposals/editor.md``#`-mentions og autocomplete