Wieloosobowość — tożsamość, członkostwo i obecność
Control Center działa dla jednego operatora, ale model pod spodem od samego początku zakłada wielu aktorów. Ludzie i agenci piszą w tych samych przestrzeniach, edytują te same zgłoszenia i pojawiają się na tej samej liście. Aby było to bezpieczne i zrozumiałe, trzeba rozstrzygnąć trzy kwestie: kto liczy się jako aktor, co warunkuje dostęp oraz który stan jest współdzielony trwale, a który tylko rozgłaszany na żywo.
Podmioty: użytkownicy i agenci to równorzędni aktorzy
Dział zatytułowany „Podmioty: użytkownicy i agenci to równorzędni aktorzy”Wszystko, co zapisuje „kto to zrobił” — wiadomości, zgłoszenia, recenzje,
plany, dzienniki uruchomień, wpisy audytu — przechodzi przez Podmiot,
zapieczętowaną unię UserPrincipal i AgentPrincipal o zwartej postaci
transmisyjnej (user:<id> / agent:<id>). Przypisanie nigdy nie sprowadza
N ludzi (ani N agentów) do jednego konta zastępczego, więc recenzję
pozostawioną przez agenta i recenzję pozostawioną przez człowieka można
odróżnić wszędzie, gdzie się pojawiają.
Ponieważ podmiot jest jednostką tożsamości, jest też jednostką izolacji:
- Limity szybkości obowiązują na podmiot, nie na sesję. Zabezpieczenie przed zalaniem dla zdalnych wywołań narzędzi rozlicza limit według użytkownika, a nie według połączenia: wszystkie urządzenia członka czerpią z jednego wspólnego przesuwnego okna (120 wywołań na minutę, z czego najwyżej 30 może coś zmienić), więc otwarcie trzech urządzeń nie potraja niczyjego przydziału, a jeden hałaśliwy członek nie odbierze przydziału pozostałym.
- Cofanie działa na podmiot. Dziennik działań każdego klienta rejestruje wyłącznie modyfikacje wykonane przez jego podmiot. Własną zmianę zgłoszenia cofniesz przez ⌘Z; zmiany współpracownika nie cofniesz — zanim ją zobaczysz, tor trwały już ją rozstrzygnął (patrz poniżej).
Członkostwo to granica dostępu — nie klucz parowania
Dział zatytułowany „Członkostwo to granica dostępu — nie klucz parowania”Dwa osobne poświadczenia odpowiadają na dwa osobne pytania. Klucz parowania (patrz Zdalne sterowanie i mobile) uwierzytelnia urządzenie wobec serwera. Członkostwo upoważnia użytkownika tego urządzenia do działania w obszarze roboczym. Sparowane urządzenie, którego użytkownik nie ma członkostwa w obszarze roboczym, nie może go ani odczytać, ani zmienić.
Członkostwo to jeden wiersz na parę (obszar roboczy, użytkownik), przechowywany w własnym pliku bazy danych tego obszaru roboczego — dzięki temu pytanie „kto jest w tym obszarze roboczym?” to zwykły odczyt w zakresie, a pytanie odwrotne, „w których obszarach roboczych jestem?”, z konieczności obejmuje wiele plików i jest jednym z nielicznych sankcjonowanych rozproszeń między obszarami roboczymi. To ono uruchamia się w selektorze obszarów roboczych, zanim zostanie wybrany jakikolwiek obszar.
Każdy wiersz niesie rolę z pięciostopniowej, uporządkowanej rangowo drabinki:
| Rola | Może |
|---|---|
owner |
Pełna kontrola, w tym usuwanie obszaru roboczego; dokładnie jeden na obszar roboczy |
admin |
Zarządzanie członkami, zaproszeniami, ustawieniami, operacjami niszczącymi |
member |
Codzienny odczyt i zapis: wiadomości, zgłoszenia, uruchomienia agentów |
viewer |
Tylko odczyt w całym obszarze roboczym; wzorce wykluczania sekretów ukrywają pasujące ścieżki na powierzchniach z kodem |
guest |
Ten sam minimalny poziom tylko do odczytu co viewer, na najniższym szczeblu drabinki |
Każda decyzja o dostępie sprowadza się do pytania „czy rola wywołującego to
co najmniej X”. Minimalny poziom wynika z rodzaju operacji, chyba że operacja
zadeklaruje go wprost: odczyt wymaga guest, modyfikacja wymaga member,
operacja niszcząca wymaga admin. ACL-e na poszczególnych obiektach poza
grantami na repozytoria opisanymi poniżej są celowo poza zakresem.
Zaproszenia to sposób przyznawania członkostwa, w Ustawienia → Obszar
roboczy → Członkowie. Administrator generuje jednorazowy kod (jako link lub
kod QR), który domyślnie wygasa po siedmiu dniach; serwer przechowuje
wyłącznie skrót SHA-256 kodu, a sam kod pokazuje się dokładnie raz.
Wykorzystanie go tworzy użytkownika w trybie JIT, zapisuje członkostwo na
poziomie roli z zaproszenia (nigdy owner — własność przekazuje się jawnie,
nigdy przez zaproszenie) i przekazuje dalej do parowania urządzenia.
Poświadczenia urządzenia utworzone po sparowaniu same mają limit 30 dni, więc
sparowanie nie jest kluczem na stałe.
Granty na repozytoria leżą poniżej członkostwa. Ponieważ serwer
przechowuje pełne kopie robocze, samo członkostwo w obszarze roboczym nie może
dawać większych uprawnień niż host kodu: każda powierzchnia z kodem — pliki,
diffy, recenzja PR, wyszukiwanie kodu — sprawdza grant członka na tym
repozytorium. Granty są przyznawane na trójkę (obszar roboczy, użytkownik,
repozytorium) i mają rangi none → read → review → write, gdzie
write oznacza prowadzenie uruchomień agentów, które zapisują do
repozytorium. Brak wiersza oznacza none; właściciele i administratorzy
domyślnie mają write na każdym połączonym repozytorium i nie mają żadnych
wierszy.
Dwa tory stanu współpracy
Dział zatytułowany „Dwa tory stanu współpracy”Control Center rozdziela stan współdzielony na dwa tory o przeciwnych zasadach trwałości, ponieważ oba rodzaje stanu zawodzą w przeciwny sposób.
Ulotny tor obecności
Dział zatytułowany „Ulotny tor obecności”Obecność — kto jest online, gdzie jest, co pisze i co agent robi właśnie
teraz — traci wartość w chwili, gdy staje się nieaktualna. Gdyby była
utrwalana, każde ponowne połączenie musiałoby uzgadniać „baza danych mówi, że
Sam edytuje to zgłoszenie” z rzeczywistością. Dlatego obecność nigdy nie
trafia do bazy danych. Żyje w działającym w pamięci hubie obecności na
serwerze: klienci publikują przez presence.update, inni subskrybują przez
presence.watch, a wpisy wygasają automatycznie po trzech pominiętych
sygnałach życia (sygnały życia biegną co 10 sekund; hub czyści co 5). Nie ma
czego uzgadniać — można tylko pozwolić wpisom wygasnąć.
Dwie właściwości czynią ten tor godnym zaufania:
- Tożsamość pochodzi z sesji, nigdy z argumentów klienta. Serwer mapuje
uwierzytelnione urządzenie połączenia na identyfikator użytkownika; klient
może aktualizować wyłącznie własną obecność, więc nikt nie podszyje się pod
status ani lokalizację innego uczestnika. Jawna aktualizacja
offline(rozłączenie lub przełącznik trybu niewidocznego) usuwa wpis natychmiast. - Lista uczestników jest obsługiwana przez hub serwera. Uczestnicy nigdy nie wymieniają obecności bezpośrednio, więc każdy widzi tę samą listę niezależnie od topologii. Agenci nie mają klienta, więc serwer syntetyzuje ich wpisy na podstawie bieżącego stanu uruchomień — myśli, działa, czeka zablokowany na bramce zatwierdzenia, gotowe — przy czym stan i lokalizację agenta wyznacza jedno reprezentatywne uruchomienie, aby równoległe uruchomienia nie powodowały migotania listy.
Rozprowadzanie ma poziomy zależne od odbiorcy: pulpit i sieć jadą na pełnym poziomie (co najwyżej jedno rozgłoszenie listy na 100 ms), a telefon na poziomie skróconym (co 500 ms), dzięki czemu aktualizacje w tempie kursora nie roztopią PWA.
Lokalizacja uczestnika — gdzie aktualnie jest, aż do konkretnego artefaktu
— to zapieczętowana unia: Space, File (repozytorium + ścieżka + opcjonalny
wiersz), Pr, Ticket, PlanNode. Nie każda lokalizacja ma dokąd przenieść:
nie istnieje trasa podglądu plików, więc lokalizacja File renderuje się jako
etykieta, a nie cel nawigacji. Tor przenosi też miękkie zastrzeżenia
(„Sam edytuje to zgłoszenie”, „agent zajmuje to worktree”): widoczność
konfliktu, a nie blokady. Nieznane rodzaje lokalizacji są parsowane do null,
więc stary klient po prostu nie renderuje tego, czego nie rozumie.
Trwały tor współdzielony
Dział zatytułowany „Trwały tor współdzielony”Zapisy, które muszą przetrwać — zgłoszenia, wspólny dokument notatek przestrzeni, wiadomości — idą przeciwną drogą: są autorytatywne, uporządkowane i utrwalane. Równoczesne zmiany rozstrzyga ostatni zapis, w kolejności odbioru przez serwer, nigdy zegary klientów. Rozstrzygnięcie jest celowo drobnoziarniste: zmiany w zgłoszeniu są osobne dla każdej kolumny, więc gdy dwie osoby edytują różne pola tego samego zgłoszenia, obie zmiany przechodzą i żadna nie nadpisuje drugiej (przejścia przepływu zachowują natomiast blokadę optymistyczną); dokument notatek przestrzeni to jedna kolumna, więc cały dokument podlega regule ostatniego zapisu, a miękkie zastrzeżenia w torze obecności czynią równoczesną edycję widoczną, zamiast ją blokować. Celowo nie jest to CRDT — ciężar dowodu spoczywa na CRDT, a ostatni zapis rozstrzygany kolejnością odbioru plus widoczne zastrzeżenia pokrywają rzeczywiste wzorce współpracy.
„Ostatni zapisujący” oznacza kolejność odbioru przez serwer, nigdy zegar klienta — laptop z przekrzywionym zegarem nie wygra edycji, którą przegrał. Za torem trwałym stoi strumień synchronizacji: wyzwalacze SQLite dopisują każdą modyfikację do dziennika zmian danego obszaru roboczego wewnątrz transakcji zapisującej, przydzielając monotoniczny numer sekwencji obszaru roboczego w tej samej transakcji co sama modyfikacja. Usługa serwera śledzi ten dziennik i zamienia go na wersjonowane ramki różnicowe w kolejności sekwencji. Klienci przechodzą od pełnych migawek do różnic; luka w sekwencji cofa ten magazyn do trybu migawek, zamiast błędnie stosować ramki.
Podążaj, kieruj, przejmij, oddaj
Dział zatytułowany „Podążaj, kieruj, przejmij, oddaj”Tor obecności to nie tylko lista — napędza czasowniki współpracy:
- Tryb podążania. Kliknij uczestnika, a twój klient jedzie za jego lokalizacją, nawigując tak jak on. Podążanie trwa „do twojego pierwszego działania”: w chwili, gdy zaczniesz nawigować samodzielnie, podążanie się odłącza. Zamykalny baner informuje, gdy inny uczestnik pokazuje na pierwszym planie (prezentuje) przestrzeń, w której jesteś.
- Kierowanie. Wiadomość do działającego agenta trafia do kolejki jako wskazówka sterująca; agent odczytuje ją ponownie przed wznowieniem kolejnej tury, więc możesz podprowadzić uruchomienie w locie, nie zabijając go.
- Przejęcie. Przejęcie kontroli nad rozmową wstrzymuje każde aktywne uruchomienie na jego następnej czystej granicy tury (uruchomienie Claude Code, które nie ma bezpiecznej granicy, zostaje zatrzymane) za migawką git z każdej tury, dzięki czemu przejęcie jest odwracalne. Trwały znacznik blokuje nowe wysyłki do przestrzeni i przetrwa restart serwera — serwer nigdy nie wznawia automatycznie pracy w na wpół dokończonej edycji człowieka. Jeden aktywny edytor na worktree to miękkie zastrzeżenie: drugie przejęcie jest widoczne i odrzucane, a nie po cichu scalane.
- Oddanie. Zwrócenie kontroli publikuje w przestrzeni ustrukturyzowane podsumowanie diffu worktree, umieszcza je w kolejce jako wskazówkę sterującą dla wstrzymanych uruchomień, wznawia je i czyści znacznik.
Pokrętło autonomii
Dział zatytułowany „Pokrętło autonomii”Kierowanie i przejmowanie to interwencje po fakcie. Pokrętło autonomii to ustawienie stałe: osobne dla przestrzeni i dla agenta, ustawiane z nagłówka przestrzeni; decyduje o tym, co się dzieje, gdy agent dotrze do bramkowanego działania.
| Poziom | Wartość transmisyjna | Wpływ na bramkowane wywołanie narzędzia |
|---|---|---|
| Tylko propozycje | proposeOnly |
Odmawiane wprost, z uzasadnieniem, które agent ma przekazać — może opisać działanie, ale nie może go wykonać |
| Działa po zatwierdzeniu | actWithApproval |
Bramka zatwierdzenia domyślnie odmawiająca: jedno potwierdzenie trafia do połączonego operatora, a brak zatwierdzającego oznacza odmowę |
| Działa swobodnie | actFreely |
Wstępnie zatwierdzone, z wyjątkiem sytuacji, gdy ma zastosowanie twarda reguła deny z guardraili — reguła odmowy zawsze wygrywa |
| (nieustawione) | null |
To samo co działanie po zatwierdzeniu: ustawienie domyślne serwera |
Dwie rzeczy znajdują się poza pokrętłem w obu kierunkach. Własny czasownik
wyjściowy trybu jest przypięty i nigdy nie może zostać odrzucony, niezależnie
od tego, co mówi pokrętło — tryb orkiestracji przez pewien czas był
strukturalnie niezdolny do wyemitowania swojego jedynego rezultatu, bo preset
odmawiał klasie efektów, którą deklaruje ten czasownik. A twardej odmowy
deny z guardraili działań nie może uchylić actFreely.
Praca solo bez regresji
Dział zatytułowany „Praca solo bez regresji”Wszystko to jest dodatkiem. Przepływ pracy pojedynczego operatora się nie zmienia: przy jednym człowieku i bez agentów hub obecności nie ma czego rozgłaszać, więc tor emituje początkową migawkę, a potem pozostaje bezczynny przy zerowym ruchu; mechanika ostatniego zapisu i synchronizacji to ta sama ścieżka jednego piszącego, co zawsze; a klucz parowania pozostaje poświadczeniem urządzenia, którym zawsze był. Członkostwo jest już granicą dostępu — przy jednym człowieku istnieje jeden wiersz właściciela i żadnych elementów listy.
Powiązane koncepcje
Dział zatytułowany „Powiązane koncepcje”- Obszary robocze i izolacja: granica, którą egzekwuje członkostwo
- Zdalne sterowanie i mobile: strona tożsamości związana z kluczem parowania i poświadczeniem urządzenia
- Model agentów: agentska połowa unii podmiotów
- Cykl życia wysyłania agentów: uruchomienia, które kierowanie i przejęcie wstrzymują i wznawiają
- Guardraile: polityka klas efektów, z którą współgra pokrętło autonomii
- Zdarzenia domenowe: magistrala, po której jadą aktualizacje na żywo