Munkaterületek és elszigetelés
Mi a munkaterület?
Szekció neve “Mi a munkaterület?”A munkaterület a legfelső szintű elszigetelési bérlő a Control Centerben. Ügynököket, tárolókat, tereket, jegyeket, memóriát, pipeline-okat és tagokat csoportosít egy körülhatárolt kontextusba. Minden, ami egy munkaterületen belül történik, ott is marad.
Egy tipikus munkaterület egy projekthez vagy egy kódbázishoz rendelhető. Lehetnek külön munkaterületei „api-service”, „frontend-v2” és „infrastructure” néven.
Munkaterület-hatókörű adatok
Szekció neve “Munkaterület-hatókörű adatok”Egy munkaterület sorai az adott munkaterület saját SQLite-fájljában élnek, a <dataDir>/<workspaceId>/workspace.db útvonalon. Minden munkaterület könyvtárat kap, nem csupasz fájlt, mert a munkaterület többet halmoz fel egy adatbázisnál — beszélgetésenkénti worktree-k, az ügynök- és készségfájlok, csevegőbot-hitelesítő adatok —, és ha mappát kap, mindez együtt él és együtt törlődik.
| Entitás | Hatókör |
|---|---|
| Ügynökök | Pontosan egy munkaterülethez tartoznak |
| Tárolók | Egy munkaterületbe regisztrálva (lásd alább) |
| Terek, beszélgetések és üzenetek | Munkaterület-hatókörű |
| Jegyek, projektek, tervek, orchestrációk | Munkaterület-hatókörű |
| Memóriatények, szabályzatok, domainek, hozzáférési engedélyek | Munkaterület-hatókörű |
| Pipeline-futtatások, sablonok, eseményindítók | Munkaterület-hatókörű |
| Pull requestek állapota, átnézési terek, átnézési kohorszok | Munkaterület-hatókörű |
| Ügynökfuttatási naplók és munkamemória | Munkaterület-hatókörű |
| Tagok, meghívók, tárolónkénti engedélyek | Munkaterület-hatókörű |
| Kódgráf-szimbólumok és élek | A munkaterület fájlján belül repoId szerint határolva |
E sorok többsége workspaceId oszlopot hordoz; az elszigetelést külön adatbázisfájlok kényszerítik ki. Lásd alább az elszigetelési invariánst.
A tárolók munkaterület-hatókörűek; a munkaterületek közötti azonosságot az útvonal adja
Szekció neve “A tárolók munkaterület-hatókörűek; a munkaterületek közötti azonosságot az útvonal adja”Egy tárolósor a saját munkaterületének adatbázisfájljában él — maga a fájl a hatókör, ezért a táblának nincs workspaceId oszlopa és nincs kapcsolótáblája.
Egy tárolót a Beállítások → Munkaterület → Tárolók menüpontban adhat hozzá egy munkaterülethez. Ugyanazon checkout két munkaterületbe való regisztrálása két független sort hoz létre, két azonosítóval; a tároló azonossága a munkaterületek között a fájlrendszerbeli útvonal (vagy a GitHub tulajdonos/név) alapján áll fenn, soha nem azonosító alapján.
A regisztrálás szigorú: az útvonalnak egy git-munkafán belül kell lennie, rendelkeznie kell origin remote-mal, és annak a remote-nak egy támogatott kódhosztra kell mutatnia (github.com, gitlab.com vagy bitbucket.org). A kódhoszt a remote-ból olvasódik ki, és a tárolón tárolódik, így egy munkaterület mindhárom forrásból tarthat tárolókat. Bármi más elutasításra kerül. A mappaböngésző, amelyből választ, a szerver gazdagépének fájlrendszerét listázza, a szerver --repo-roots engedélyezési listájára szűkítve (amely alapértelmezés szerint a szerverfelhasználó otthoni könyvtára).
Egy tároló eltávolítása egy munkaterületből nyomban törli a sort, és kaszkádolja a kódgráf-szimbólumait, éleit, fájljait, index-ellenőrzőpontjait és a tagonkénti engedélyeit. A lemezen lévő checkout érintetlen marad.
A kódgráf ugyanabban a fájlban él, repoId szerint kulcsolva, mert a különböző munkaterületeken lehet ugyanaz a tároló különböző ágakon, különböző kóddal.
Az elszigetelési invariáns
Szekció neve “Az elszigetelési invariáns”A munkaterületek közötti adatszivárgásokat hibaként kezeljük. Az elszigetelés strukturális, több szinten kikényszerítve:
- Adatbázisréteg. Minden munkaterületnek saját SQLite-fájlja van, amelyet a
WorkspaceDatabaseManager.of(workspaceId)oszt ki. Egy munkaterület adatbázisa nem deklarálja ausers,workspacesvagy bármely más munkaterület tábláit, így a munkaterületek közötti olvasás nem olyan hiba, amit meg lehet írni — le sem fordul. A tárolók hívásonként oldják fel a DAO-jukat ahelyett, hogy gyorsítótáraznák, és mivel minden tárolómetódus kötelezőworkspaceIdparamétert vár, a munkaterület soha nem következtethető ki és nem kaphat alapértelmezett értéket. - A munkaterület-azonosító egy útvonalszegmens. Mivel az azonosítóból könyvtárnév lesz, meg kell felelnie egy biztonságos, egyszeres szegmensű mintának (alfanumerikusan kezdődik, majd alfanumerikus karakterek, pontok, aláhúzások, kötőjelek;
..nem szerepelhet). A termékben mindenhol UUID-k az azonosítók. Bármi más kivételt dob a megtisztítás helyett — ez az elérési út bejárása elleni védelem, és hangosan hibázik, ahelyett hogy egy munkaterület adatait olyan útvonalra írná, amelyet valaki más választott. - Többrétegű védelem. A
workspaceIdoszlopok továbbra is ott vannak, és továbbra is íródnak. Egy fájlon belül redundánsak, de változatlanul hagyják a szinkronfolyam-eseményindítókat, az FTS-indexeket és a meglévő soralakokat, és önleíróvá teszik a fájlt, amikor önmagában vizsgálják meg — erre támaszkodik az exportálás és az importálás. - Domainréteg. Az entitásokat azonosító alapján módosító szolgáltatások egyetlen szűk keresztmetszetnél ellenőrzik, hogy
entity.workspaceId == workspaceId, mielőtt továbblépnének, és eltérés eseténWorkspaceMismatchExceptionkivételt dobnak — ez a hangos hiba egy rossz kontextusból érkező azonosítóra. A hangos elutasítás számít: a csendes no-op elrejti a hibát, a továbblépés pedig szivárogtat. - RPC-réteg. A repo-RPC diszpécser a szűk keresztmetszet. Minden munkaterület-hatókörű műveletnek a saját argumentumai között kell hordoznia a
workspace_id-t — nincs munkamenetenkénti „aktuális munkaterület”, ami szivároghatna, és az ismeretlen azonosítót not-found válaszként utasítja el, mielőtt bármi adatbázist nyitna, így egy rossz azonosító nem hozhat létre szellemworkspace.db-t. A valóban globális műveletek (a hírfolyam, a flottasor) kifejezett, felülvizsgált döntésként hatókör nélkülinek nyilvánítják magukat. Az MCP-eszközök ugyanezt a szabályt követik: minden munkaterület-hatókörű adatot érintő eszközhöz kötelező aworkspace_id. - A munkaterületek közötti fan-out felsorolható. Egy több munkaterületre vonatkozó kérdés megválaszolása több adatbázis megnyitását jelenti. Ez a fan-out egyetlen segédfüggvényre, a
CrossWorkspaceQueries-re korlátozódik, így a határt jogszerűen átlépő dolgok teljes listája egyetlen fájl hívási helyein él, ahelyett hogy dokumentációs megjegyzések mögé szóródna. Ezek a hívási helyek: szerver szintű aggregáció, indítási egyeztetők, megőrzési és GC-seprések, biztonsági mentés, eseményrouterek — és az alábbi tagsági keresés. - A csak azonosító alapján történő hozzáférés nem elegendő. Egy entitás UUID alapján történő kikeresése nem bizonyítja, hogy az a hívó munkaterületéhez tartozik. A fájlszétválasztás elérhetetlenné teszi a rossz fájlt; a domainrétegbeli érvényesítés elkapja a jogos fájlon keresztül érkező rossz azonosítót.
A hozzáférést a tagság adja, nem a párosítási kulcs
Szekció neve “A hozzáférést a tagság adja, nem a párosítási kulcs”Egy eszközhitelesítő adat birtoklása egy eszközt hitelesít. Nem jogosít fel semmire egy munkaterületen belül. Minden munkaterület-hatókörű művelet feloldja a hívó tagsági szerepét, és kikényszerít egy, a művelet fajtájából levezetett minimumot — az olvasáshoz guest, a módosításhoz member, a destruktív művelethez admin szükséges —, a tárolótartalmat felfedő műveletek pedig ezenfelül ellenőrzik a hívó tárolónkénti engedélyét. Egy érvényes párosítási kulcs tagság nélkül Not a member of this workspace hibát kap.
Az elszigetelésre nézve ennek elegáns a következménye: a tagsági sorok a munkaterület saját fájljában élnek, így a „ki van ebben a munkaterületben?” egy közönséges hatókörű olvasás. A fordított kérdés — „mely munkaterületekben vagyok benne?” — értelemszerűen fájlokra szóródik, ezért ez az egyik kevés engedélyezett CrossWorkspaceQueries fan-out, és ezt futtatja a munkaterületválasztó, mielőtt bármelyik munkaterületet kiválasztanák.
A szereplétraihoz és a tárolónkénti engedélyekhez lásd a többszereplős módot.
A globális nyilvántartás
Szekció neve “A globális nyilvántartás”Nem minden munkaterület-hatókörű. Egy második adatbázis, a <dataDir>/global.db tartalmazza azt, ami valóban szerver szintű:
- a munkaterület-nyilvántartás, hogy a váltó fel tudja sorolni az összes munkaterületet anélkül, hogy egyetlen munkaterületfájlt is megnyitna — és hogy egy munkaterület neve, logója, tulajdonosa, kézi sorrendje és soft-delete jelölője az általa leírt fájlon kívül éljen;
- az identitás: felhasználók, felhasználói beállítások és párosított eszközök, mert egy ember egy felhasználó minden munkaterületen, és egy párosított eszköz túléli egy munkaterület törlését;
- a flottasor (workerek, feladatok, elhelyezési napló), amelynek ütemezője minden ciklusban az egész sort összeveti minden workerrel;
- a hírfolyam, amely felhasználónkénti (nem munkaterületenkénti) — egy folyam hozzáadása minden munkaterületre követi Önt;
- a
workspace_routes, a hitelesítés előtti index, amely megválaszolja, hogy „melyik munkaterület birtokolja ezt a kulcsot?” azoknak a belépési pontoknak, amelyek csak egy titokkal vagy egy átlátszatlan azonosítóval (egy meghívó-hash, egy webhook-token, egy deep link) érkeznek, munkaterület nélkül. A kihagyás ott not-found; szándékosan nincs beolvasási tartalék; - telepítés szintű beállítások és identitás: a telepítés-azonosító, gazdagép szintű beállítások, SSO-kapcsolatok és kezelt műveletszabályzatok (egy telepítés szintű korlát, amely csak szigoríthatja a munkaterület korlátait).
Az indítás csak ezt a fájlt nyitja meg. A munkaterületfájlok lustán, az első érintéskor nyílnak meg, így az indítási költség lapos marad, függetlenül attól, mennyi előzményt halmoznak fel a munkaterületek, és a fájlonkénti quick_check árát az első használatkor fizetjük meg, nem a ready bannerhez vezető úton.
Egy munkaterületfájl csak egy egysoros workspace_meta táblát hordoz az önazonosításhoz (az azonosítója, az őt létrehozó telepítés, a létrehozáskor használt sémaváltozat, és hogy mikor). Minden leíró adat egy munkaterületről a nyilvántartásban van.
Munkaterület létrehozása
Szekció neve “Munkaterület létrehozása”Egy munkaterület létrehozása többet tesz, mint egy nyilvántartási sor beszúrása. Egyetlen műveletben a szerver a létrehozó felhasználót ownerUserId értékkel jelöli meg, rögzíti e felhasználó tulajdonosi szerepű tagságát, és közzétesz egy WorkspaceCreated domaineseményt. Az eseményre figyelő hallgatók ezután idempotensen, a háttérben feltöltik:
- egy CEO-ügynököt, valamint négy specialistát —
qa,architect,engineer,librarian—, akik a CEO-nak jelentenek; - a beépített pipeline-sablonokat és azok eseményindítóit (az esemény- és kézi indítók bekapcsolva érkeznek; az ütemezettek külön engedélyezést igényelnek, kivéve a napi worktree-GC seprést);
- a kezdő kiértékelési csomagokat.
Ez minden munkaterületnél megtörténik, nem csak az elsőnél. A feltöltött ügynökök adapter nélkül jönnek létre, így a Control Center (built-in) futtatókörnyezeten futnak az Anthropic alapértelmezett modelljével (claude-opus-4-8, hacsak nem rögzít másikat) addig, amíg be nem állít egy adaptert és modellt ügynökönként a Beállítások → Munkaterület → Ügynökök menüpontban. Lásd az ügynökmodellt.
A tulajdonosi tagság írása jelentősebb, mint amilyennek látszik: nélküle a frissen létrehozott munkaterületnek nem lennének tagjai, és minden munkaterület-hatókörű hívást elutasítanának, amelyet a létrehozó ezután tesz.
Törlés, exportálás, importálás
Szekció neve “Törlés, exportálás, importálás”Egy munkaterület törlése megjelöli a nyilvántartási sort, és leválasztja a könyvtárat. A munkaterület eltűnik minden listából és keresésből. A nyilvántartási sor megmarad (soft-deleted), így az azonosítót továbbra is ismeri a biztonsági mentés és a karbantartás, a workspace.delete azonban azonnal eldobja a munkaterület könyvtárát — adatbázis, worktree-k, ügynökfájlok és a többi — a WorkspaceDatabaseManager.dropAndClose segítségével. Csak a munkaterület tulajdonosa törölheti.
Mivel egy munkaterület egyetlen fájl, a munkaterület továbbadása fájlművelet, nem táblánkénti dump:
- a
workspace.exportegyetlenVACUUM INTO— konzisztens, töredezettségmentesített pillanatkép, amelyet olvasási tranzakció alatt készít, miközben a szerver tovább szolgál. - a
workspace.importátvesz egy ilyen fájlt, felülírva mindazt, amit a cél-munkaterület jelenleg tartalmaz. A beágyazottworkspace_metasegítségével az import meg tudja különböztetni a „saját fájl, újra átvéve” esetet a „másik telepítésből származó fájl” esettől (utóbbi engedélyezett, de naplózott, nem láthatatlan). - a
server.backupNowaz egész telepítésről pillanatképet készít egy időbélyeggel ellátott könyvtárba, amely tükrözi az élő adatkönyvtárat —manifest.json,global.db, valamint munkaterületenként egy<workspaceId>/workspace.db—, így a visszaállítás nem más, mint visszamásolása. - a
server.listBackupsvisszaolvassa ezt a könyvtárat, a legfrissebbel kezdve, az egyes pillanatképek méretével és munkaterületlistájával. Az a pillanatkép, amelynek hiányzik a manifestje, vagy olyan fájlokat nevez meg, amelyek nincsenek ott, akkor is jelentésre kerül, hiányosként megjelölve — elrejtésével egy üzemeltető azt hiheti, hogy van biztonsági mentése, holott nincs.
A biztonsági mentési műveletek a Beállítások → Szerver → Biztonsági mentés és visszaállítás alatt találhatók: a Biztonsági mentés most pillanatképet készít a telepítésről, a lista megmutatja, mely pillanatképek teljesek, és a telepítés tulajdonosának megerősítés után lehetővé teszi azok törlését, valamint minden munkaterület felajánlja az exportálást és az importálást. A beépített Workspace backup pipeline heti ütemezéssel csak az adott munkaterület adatbázisát menti, és törli a beállított megőrzési korosztálynál régebbi saját mentéseit. Egy munkaterület visszaállítása telepítési pillanatképből a workspace.import, a pillanatkép <workspaceId>/workspace.db fájljára irányítva; egy teljes telepítés visszaállítása továbbra is a pillanatképkönyvtár visszamásolása leállított szerver mellett.
Egyik sem viszi magával a munkaterület-könyvtár többi részét. Egy munkaterület többet halmoz fel egy adatbázisnál — beillesztett képek, készség- és ügynökfájlok, csevegőhitelesítő adatok, worktree-k —, az exportálás és az importálás pedig a fájlt mozgatja, így minden, ami mellette van, a helyén marad. Ez a hitelesítő adatoknál szándékos, a worktree-knél eldobható; a többinél inkább tudnivaló korlát, mint szolgáltatás. A teljes táblázat a mentési referenciában található.
Biztonsági mentés mozgatása a szerver és az eszköz között
Szekció neve “Biztonsági mentés mozgatása a szerver és az eszköz között”A fenti műveletek mindegyike a szerveren lévő útvonalakban beszél, ami csak akkor teljes válasz, ha a szerver az Ön saját gépe. Három aláírt HTTP-útvonal — /backup/workspace, /backup/snapshot és /backup/restore — szállítja a bájtokat minden más topológia számára, ugyanazon a hitelesített sávon, amelyet a médiarelé és a képtár már használ. Az oldalon ez minden exportálás és minden pillanatkép mellett egy Letöltés gomb (Ön választja ki, hová kerüljön), valamint a Fájl választása és feltöltése a visszaállításhoz abból a fájlból, amely az éppen használt gépen található. A feltöltés az, amely akkor működik, ha a szerver nem az Ön gépe: a workspace.import megköveteli, hogy a fájl már a gazdagépen legyen, és ez az, ahogyan odakerül.
Három tulajdonságot érdemes ismerni:
- A letöltés friss másolatot készít, és a szerver semmit nem tart meg belőle. A letöltés nem „hozd el az exportálás gomb által készített fájlt” — újra exportál, azt streameli, majd törli. A válasz
no-storeésAccept-Ranges: none, ugyanezen okból: egy folytatott tartomány két különböző exportot fűzne össze egyetlen fájlba, amely érvényesnek látszik, de nem az. - A feltöltés lemezre streamelődik, soha nem pufferelődik, mindkét végén, és az előkészített másolat minden kivezető úton törlődik — az elutasítást is beleértve. Egy munkaterület adatbázisa nem képernyőkép.
- Egy relén átvezetett kapcsolatnak nincs HTTP-eredete, ezért az átvitelvezérlők ott le vannak tiltva, egy megjegyzéssel, amely megindokolja, miért. Minden, ami szerveroldali útvonalakban beszél, továbbra is működik a relén; csak a bájtsávokhoz kell közvetlen kapcsolat.
Több munkaterület
Szekció neve “Több munkaterület”Több munkaterületet futtathat egymás mellett. Mindegyik önállóan működik: az egyik munkaterületen lévő ügynökök nem küldhetnek üzenetet egy másik munkaterület ügynökeinek, nem olvashatják egy másik munkaterület memóriáját, és nem láthatják annak jegyeit. Az ügynökök közötti üzenetküldés címzettfeloldása pontos, és soha nem lép át munkaterületet.
Nincs munkaterületek közötti irányítópult. A /workspaces/:workspaceId/observability címen található elemzőfelület egy korlátos, globális, a legutóbbi futtatásokból álló folyamra iratkozik fel, és azonnal az aktív munkaterületre szűkíti, így ott egyszerre egy munkaterületet lát. Az egyetlen valóban több munkaterületet érintő felület, amelyhez egy ember hozzáfér, a munkaterületválasztó és a váltó.
Egy gyakorlati korlát, amit érdemes tudni: egy használatban lévő munkaterület nyitva marad — nincs LRU. 32 ilyen felett a szerver figyelmeztet, nem pedig elutasít, mert minden nyitott fájl egy háttér-izolátumot és egy lapgyorsítótárat tart. A munkaterületek közötti fan-out csak átmenetileg nyit meg fájlokat, és utána bezárja őket, ha semmi más nem tartotta őket igénybe.
Kapcsolódó fogalmak
Szekció neve “Kapcsolódó fogalmak”- Többszereplős mód: tagság, szerepek és tárolónkénti engedélyek — az elszigetelés hozzáférési fele
- Az ügynökmodell: az ügynökök pontosan egy munkaterülethez tartoznak
- Memória és tudás: a memória munkaterület-hatókörű
- Architektúra: hol helyezkednek el az adatbázisok a kliens/szerver felosztásban
- Mentés és visszaállítás: pillanatkép készítése, munkaterület mozgatása, másolatok tárolása máshol
- Mentés, exportálás és importálás: minden művelet, útvonal, manifestmező és korlát
- Repók hozzáadása: egy checkout regisztrálása egy munkaterületbe