Többszereplős mód – identitás, tagság és jelenlét
A Control Center egyetlen üzemeltetővel is működik, de a mögötte lévő modell eleve több szereplős. Az emberek és az ügynökök ugyanazokban a terekben üzennek, ugyanazokat a jegyeket szerkesztik, és ugyanazon a névsoron jelennek meg. Hogy ez biztonságos és átlátható legyen, három döntésen múlik: ki számít szereplőnek, mi kapuzza a hozzáférést, és mely állapot megosztott tartósan, illetve csak élőben sugárzott.
Principalok: a felhasználók és az ügynökök egyenrangú szereplők
Szekció neve “Principalok: a felhasználók és az ügynökök egyenrangú szereplők”Minden, ami rögzíti, hogy „ki tette ezt” – üzenetek, jegyek, átnézések,
tervek, futásnaplók, auditbejegyzések –, egy Principalon keresztül oldódik
fel: ez a UserPrincipal és az AgentPrincipal lezárt uniója, tömör átviteli
formával (user:<id> / agent:<id>). Az attribúció soha nem von össze N
embert (vagy N ügynököt) egyetlen sentinelfiókba, így az ügynök által hagyott
átnézés és az ember által hagyott átnézés mindenhol megkülönböztethető, ahol
csak megjelenik.
Mivel a Principal az identitás egysége, egyben az elkülönítés egysége is:
- A sebességkorlátok Principalonként értendők, nem munkamenetenként. A távoli eszközhívások túlterhelés-védelme felhasználónként, nem kapcsolatonként számol: egy tag összes eszköze egyetlen közös csúszóablakból gazdálkodik (percenként 120 hívás, amelyből legfeljebb 30 módosíthat), így három eszköz megnyitása nem háromszorozza meg senki keretét, és egy zajos tag sem éheztetheti ki a többieket.
- A visszavonás is Principalonként működik. Minden kliens műveletnaplója csak azokat a módosításokat rögzíti, amelyeket az ő Principalja hajtott végre. A saját jegyszerkesztését visszavonhatja ⌘Z-vel; egy csapattársáét nem – mire meglátja, a tartós sáv már fel is oldotta azt (lásd alább).
A tagság a hozzáférési határ – nem a párosítási kulcs
Szekció neve “A tagság a hozzáférési határ – nem a párosítási kulcs”Két külön hitelesítő adat két külön kérdésre válaszol. A párosítási kulcs (lásd: Távoli vezérlés és mobil) egy eszközt hitelesít a szerver felé. A tagság jogosítja fel az adott eszköz felhasználóját, hogy egy munkaterületen belül cselekedjen. Egy párosított eszköz, amelynek felhasználója nem tagja az adott munkaterületnek, sem olvasni, sem módosítani nem tudja azt.
A tagság (munkaterület, felhasználó) páronként egyetlen sor, amelyet az adott munkaterület saját adatbázisfájlja tárol – így a „ki van ebben a munkaterületben?” kérdés közönséges, hatókörre szűkített olvasás, míg a fordított kérdés, hogy „mely munkaterületekben vagyok benne?“, szükségszerűen fájlokon ível át, és azon kevés engedélyezett, munkaterületek közötti szétosztás egyike. Ezt futtatja a munkaterület-választó, mielőtt bármelyik munkaterületet kiválasztanák.
Minden sor egy szerepet hordoz egy ötszintű, rangsorolt létráról:
| Szerep | Mit tehet |
|---|---|
owner |
Teljes ellenőrzés, a munkaterület törlését is beleértve; munkaterületenként pontosan egy |
admin |
Tagok, meghívók, beállítások és destruktív műveletek kezelése |
member |
Mindennapi olvasás-írás: üzenetek, jegyek, ügynökfutások |
viewer |
Írásvédett a teljes munkaterületen; a titokkizáró globok elrejtik az egyező útvonalakat a kódot tartalmazó felületeken |
guest |
Ugyanaz az írásvédett minimum, mint a viewer esetében, a ranglétra legalján |
Minden hozzáférési döntés arra redukálódik, hogy „a hívó szerepe legalább X-e”.
A minimum a művelet fajtájából következik, hacsak az kifejezetten nem deklarál
mást: egy olvasáshoz guest, egy módosításhoz member, egy destruktív
művelethez admin kell. Az alábbi, repónkénti jogosultságokon túli
objektumszintű ACL-ek szándékosan kívül esnek a hatókörön.
A meghívókkal lehet tagságot adni, a Beállítások → Munkaterület → Tagok
helyen. Az admin egyszer használatos kódot állít ki (hivatkozásként vagy
QR-ként), amely alapértelmezés szerint hét nap után lejár; a szerver csak a kód
SHA-256-os hash-ét tárolja, magát a kódot pedig pontosan egyszer mutatja meg.
Beváltásakor a rendszer JIT-provisionálja a felhasználót, rögzíti a tagságot a
meghívó szerepével (soha nem owner – a tulajdonjogot kifejezetten át kell
adni, meghívóval soha nem jár), és átadja a folyamatot az eszközpárosításnak. A
párosítás után kiállított eszközhitelesítő adatok maguk is 30 napra
korlátozottak, így egy párosítás nem állandó kulcs.
A repónkénti jogosultságok a tagság alatt helyezkednek el. Mivel a szerver
teljes checkoutokat tart, a munkaterület-tagság önmagában soha nem
biztosíthat több jogot, mint a kódhoszt: minden kódot tartalmazó felület –
fájlok, difjek, PR-átnézés, kódkeresés – az adott tag azon a repón érvényes
jogosultságát ellenőrzi. A jogosultságok (munkaterület, felhasználó, repó)
hármasonként értendők, rangsoruk pedig none → read → review → write,
ahol a write azt jelenti, hogy olyan ügynökfutásokat vezet, amelyek a repóba
írnak. Egy sor hiánya none-t jelent; a tulajdonosok és az adminok minden
kapcsolt repón implicit módon write joggal bírnak, és egyáltalán nem
hordoznak sorokat.
Az együttműködési állapot két sávja
Szekció neve “Az együttműködési állapot két sávja”A Control Center két sávra bontja a megosztott állapotot, ellentétes tartóssági szabályokkal, mert a kétféle állapot ellentétes módon romlik el.
A múlékony jelenléti sáv
Szekció neve “A múlékony jelenléti sáv”A jelenlét – ki van online, hol tartózkodik, mit gépel épp, mit csinál éppen
egy ügynök – abban a pillanatban értéktelenné válik, amint elavul. Ha
tárolnánk, minden újracsatlakozásnak össze kellene egyeztetnie a valósággal
azt, hogy „az adatbázis szerint Sam épp ezt a jegyet szerkeszti”. Ezért a
jelenlét soha nem kerül az adatbázisba. Egy szerveroldali, memóriabeli
jelenléti központban él: a kliensek a presence.update hívással
publikálnak, a társak a presence.watch hívással iratkoznak fel, a bejegyzések
pedig három kihagyott szívverés után automatikusan lejárnak (a szívverések 10
másodpercenként futnak, a központ 5 másodpercenként takarít). Nincs mit
összeegyeztetni – csak hagyni, hogy elmúljon.
Két tulajdonság teszi megbízhatóvá a sávot:
- Az identitás a munkamenetből származik, soha nem
kliensargumentumokból. A szerver a kapcsolat hitelesített eszközét egy
felhasználói azonosítóra képezi le; egy kliens csak a saját jelenlétét
frissítheti, így senki nem tudja meghamisítani egy másik résztvevő állapotát
vagy tartózkodási helyét. Egy kifejezett
offlinefrissítés (leválás vagy a láthatatlan mód kapcsolója) azonnal eltávolítja a bejegyzést. - A névsor a jelenléti központon keresztül jut el mindenkihez. A társak soha nem cserélnek jelenlétet közvetlenül, így minden résztvevő ugyanazt a névsort látja, függetlenül a topológiától. Az ügynököknek nincs kliensük, ezért a szerver szintetizálja a bejegyzéseiket az élő futásállapotból – gondolkodik, fut, jóváhagyási kapunál blokkolva, kész –, és egyetlen reprezentatív futás dönti el az ügynök állapotát és tartózkodási helyét, hogy a párhuzamos futások ne rezegtessék a névsort.
A szétosztás fogyasztónként rétegezett: az asztali és a webes kliens a teljes rétegen utazik (legfeljebb 100 ms-onként egy névsorkibocsátás), a telefon pedig egy összegző rétegen (500 ms-onként), így a kurzorritmusú frissítések nem olvaszthatják meg a PWA-t.
Egy résztvevő tartózkodási helye – hogy épp hol van, egészen az
artefaktumig – lezárt unió: Space, File (repó + útvonal + opcionális sor),
Pr, Ticket, PlanNode. Nem minden tartózkodási helynek van hova ugrani:
nincs fájlmegjelenítő útvonal, ezért a File tartózkodási hely címkeként
jelenik meg, nem célpontként. A sáv puha jelzéseket is szállít („Sam épp
ezt a jegyet szerkeszti”, „egy ügynök birtokolja ezt a worktree-t”): az ütközés
láthatóságát, nem zárolásokat. Az ismeretlen fajtájú tartózkodási helyek
null értékre értelmeződnek, így egy régi kliens egyszerűen nem jeleníti meg azt,
amit nem ért.
A tartós megosztott sáv
Szekció neve “A tartós megosztott sáv”A túlélést igénylő rekordok – jegyek, a tér megosztott Jegyzetek-dokumentuma, üzenetek – az ellenkező utat járják: mérvadók, sorrendezettek és tároltak. A párhuzamos szerkesztéseket az utolsó író nyer elv oldja fel, a szerver beérkezési sorrendje szerint, soha nem kliensórák alapján. A feloldás szándékosan finom felbontású: a jegyszerkesztések oszloponkéntiek, így két ember ugyanazon jegy különböző mezőit szerkesztve is sikeresen érvényesül, és egyikük sem írja felül a másikat (a munkafolyamat-átmeneteknél ehelyett optimista zárolás marad); a tér Jegyzetek-dokumentuma egyetlen oszlop, így a teljes dokumentumra LWW érvényes, és a jelenléti sávon lévő puha jelzések teszik láthatóvá a párhuzamos szerkesztést a zárolás helyett. Ez szándékosan nem CRDT – a bizonyítási teher a CRDT-n van, a beérkezési sorrend szerinti LWW pedig a látható jelzésekkel együtt lefedi a tényleges együttműködési mintákat.
Az „utolsó író” a szerver beérkezési sorrendjét jelenti, soha nem egy kliensórát – egy elállított órájú laptop nem nyerhet meg egy szerkesztést, amelyet elveszített. A tartós sáv mögött a szinkronizációs folyam áll: az SQLite triggerek minden módosítást hozzáfűznek egy munkaterületenkénti változásnaplóhoz, magán az írási tranzakción belül, és ugyanabban a tranzakcióban osztanak ki egy monoton, munkaterületenkénti sorszámot, mint magát a módosítást. Egy szerveroldali szolgáltatás sorrendben, verziózott delta keretekké olvassa ki ezt a naplót. A kliensek a teljes pillanatképektől a delták felé fejlődnek; a sorozatban keletkező hézag inkább pillanatkép-módba ejti vissza az adott tárolót, mintsem hogy hibásan alkalmazza a kereteket.
Követés, irányítás, átvétel, visszaadás
Szekció neve “Követés, irányítás, átvétel, visszaadás”A jelenléti sáv nem csupán névsor – az együttműködés igéit vezérli:
- Követési mód. Kattintson egy résztvevőre, és a kliense az ő tartózkodási helyén utazik, úgy navigálva, ahogyan ő navigál. A követés „addig tart, amíg Ön nem cselekszik”: abban a pillanatban, hogy saját magától navigál, a követés leválik. Egy bezárható banner jelzi, amikor egy másik résztvevő épp bemutat egy teret, amelyben Ön is jelen van.
- Irányítás. A futó ügynöknek küldött üzenet irányítóüzenetként kerül várólistára; az ügynök a következő köre folytatása előtt újraolvassa, így menet közben is terelheti a futást anélkül, hogy leállítaná.
- Átvétel. Egy beszélgetés irányításának átvétele minden aktív futást szüneteltet a következő tiszta körhatárnál (egy Claude Code-futás, amelynek nincs biztonságos határa, leáll), körönkénti git-pillanatkép mögött, így az átvétel visszafordítható. Egy tartós jelölő blokkolja a térbe induló új küldéseket, és túléli a szerver újraindítását – a szerver soha nem folytatja automatikusan a munkát egy ember félbehagyott szerkesztésébe. Worktree-nként egy élő szerkesztő egy puha jelzés: egy második átvétel látható és elutasításra kerül, nem olvad bele csendben.
- Visszaadás. Az irányítás visszaadása egy strukturált diff-összefoglalót tesz közzé a worktree-ről a térben, irányítóüzenetként várólistára teszi a szüneteltetett futások számára, folytatja őket, és törli a jelölőt.
Az autonómiaszabályzó
Szekció neve “Az autonómiaszabályzó”Az irányítás és az átvétel utólagos beavatkozások. Az autonómiaszabályzó az állandó beállítás: térenként és ügynökönként, a tér fejlécéből állítható, és eldönti, mi történik, amikor egy ügynök egy kapuzott művelethez ér.
| Szint | Átviteli érték | Hatás egy kapuzott eszközhívásra |
|---|---|---|
| Csak javaslat | proposeOnly |
Azonnal elutasítva, egy indoklással, amelyet az ügynöknek tovább kell adnia – leírhatja a műveletet, de nem hajthatja végre |
| Cselekvés jóváhagyással | actWithApproval |
A hibazáró jóváhagyási kapu: egy megerősítés jelenik meg egy csatlakozott üzemeltetőnél, és ha nincs jóváhagyó, az elutasítást jelent |
| Szabad cselekvés | actFreely |
Előre jóváhagyva, kivéve, ahol kemény deny korlátszabály érvényes – a deny szabály mindig nyer |
| (nincs beállítva) | null |
Ugyanaz, mint a jóváhagyással történő cselekvés: a szerver alapértelmezése |
Két dolog mindkét irányban a szabályzón kívül esik. Egy mód saját kimeneti
igéje rögzített, és soha nem utasítható el, bármit is mond a szabályzó – az
orchestrációs mód egykor szerkezetileg képtelen volt kiadni az egyetlen
szállítható eredményét, mert egy előbeállítás megtagadta azt a hatásosztályt,
amelyet az az ige deklarál. A műveletkorlátok kemény deny-je pedig nem
írható felül actFreely-jel.
Egyéni használat nulla regresszióval
Szekció neve “Egyéni használat nulla regresszióval”Mindez additív. Az egyedül dolgozó üzemeltető munkafolyamata változatlan: egyetlen emberrel és ügynökök nélkül a jelenléti központnak nincs mit sugároznia, így a sáv kibocsátja a kezdeti pillanatképét, majd nulla forgalmon tétlenkedik; az LWW- és szinkrongépezet ugyanaz az egyetlen írós útvonal, ami mindig is volt; a párosítási kulcs pedig ugyanaz az eszközhitelesítő adat marad, ami mindig is volt. A tagság már önmagában a hozzáférési határ – egyetlen ember esetén egyetlen tulajdonosi sor létezik, és nincs semmiféle névsorhoz tartozó felületi elem.
Kapcsolódó fogalmak
Szekció neve “Kapcsolódó fogalmak”- Munkaterületek és elszigetelés: a határ, amelyet a tagság érvényesít
- Távoli vezérlés és mobil: az identitás párosításikulcs- és eszközhitelesítő-oldala
- Az ügynökmodell: a principalunió ügynök-fele
- Ügynökindítás életciklusa: a futások, amelyeket az irányítás és az átvétel szüneteltet és folytat
- Korlátok: a hatásosztály-szabályzat, amellyel az autonómiaszabályzó együttműködik
- Domainesemények: az a busz, amelyen az élő frissítések utaznak