Ruang kerja dan pengasingan
Apakah itu ruang kerja?
Bahagian bertajuk “Apakah itu ruang kerja?”Ruang kerja ialah penyewa pengasingan peringkat atas dalam Control Center. Ia mengumpulkan ejen, repositori, ruang, tiket, memori, pipeline dan ahli ke dalam satu konteks terbatas. Segala yang berlaku di dalam ruang kerja kekal di dalamnya.
Ruang kerja lazimnya sepadan dengan satu projek atau satu pangkalan kod. Anda mungkin mempunyai ruang kerja berasingan untuk “api-service”, “frontend-v2” dan “infrastructure”.
Data berskop ruang kerja
Bahagian bertajuk “Data berskop ruang kerja”Baris ruang kerja tersimpan dalam fail SQLite ruang kerja itu sendiri, di <dataDir>/<workspaceId>/workspace.db. Setiap ruang kerja mendapat direktori dan bukannya fail semata-mata, kerana ruang kerja mengumpul lebih daripada sekadar pangkalan data — worktree setiap perbualan, fail ejen dan kemahiran, kelayakan bot sembang — dan memberikannya folder bermakna semua itu hidup dan dipadam bersama-sama.
| Entiti | Skop |
|---|---|
| Ejen | Milik tepat satu ruang kerja |
| Repositori | Didaftarkan ke dalam satu ruang kerja (lihat di bawah) |
| Ruang, perbualan dan mesej | Berskop ruang kerja |
| Tiket, projek, pelan, orkestrasi | Berskop ruang kerja |
| Fakta memori, polisi, domain, geran akses | Berskop ruang kerja |
| Larian pipeline, templat, pencetus | Berskop ruang kerja |
| Keadaan pull request, ruang semakan, kohort semakan | Berskop ruang kerja |
| Log larian ejen dan memori kerja | Berskop ruang kerja |
| Ahli, jemputan, geran setiap repo | Berskop ruang kerja |
| Simbol dan tepi graf kod | Berskop mengikut repoId dalam fail ruang kerja |
Kebanyakan baris ini membawa lajur workspaceId; fail pangkalan data yang berasingan menguatkuasakan pengasingan. Lihat invarian pengasingan di bawah.
Repo berskop ruang kerja; identiti merentas ruang kerja adalah mengikut laluan
Bahagian bertajuk “Repo berskop ruang kerja; identiti merentas ruang kerja adalah mengikut laluan”Baris repo tersimpan dalam fail pangkalan data ruang kerjanya sendiri — fail itu ialah skopnya, jadi jadualnya tiada lajur workspaceId dan tiada jadual gabungan.
Anda menambah repo ke dalam ruang kerja di Tetapan → Ruang kerja → Repositori. Mendaftarkan checkout yang sama dalam dua ruang kerja menghasilkan dua baris bebas dengan dua id; identiti repo merentas ruang kerja adalah mengikut laluan sistem fail (atau pemilik/nama GitHub), tidak pernah mengikut id.
Pendaftaran adalah ketat: laluan mesti berada di dalam pokok kerja git, ia mesti mempunyai remote origin dan remote itu mesti menunjuk ke hos kod yang disokong (github.com, gitlab.com atau bitbucket.org). Hos kod dibaca daripada remote dan disimpan pada repo, jadi satu ruang kerja boleh menyimpan repo daripada ketiga-tiganya. Apa-apa selain itu ditolak. Pelayar folder yang anda pilih menyenaraikan sistem fail hos pelayan, terhad kepada senarai benarkan --repo-roots pelayan (yang lalainya ialah direktori home pengguna pelayan).
Membuang repositori daripada ruang kerja memadam baris itu terus dan menggugurkan secara berantai simbol kod, tepi, fail, titik pemeriksaan indeks dan geran setiap ahli. Checkout pada cakera tidak disentuh.
Graf kod tersimpan dalam fail yang sama, dikunci mengikut repoId, kerana ruang kerja yang berbeza mungkin mempunyai repositori yang sama pada cawangan berbeza dengan kod yang berbeza.
Invarian pengasingan
Bahagian bertajuk “Invarian pengasingan”Kebocoran data merentas ruang kerja dianggap sebagai pepijat. Pengasingan bersifat struktur, dikuatkuasakan pada beberapa peringkat:
- Lapisan pangkalan data. Setiap ruang kerja mempunyai fail SQLite sendiri, yang dikeluarkan oleh
WorkspaceDatabaseManager.of(workspaceId). Pangkalan data ruang kerja tidak mengisytiharkanusers,workspacesatau jadual mana-mana ruang kerja lain, jadi bacaan merentas ruang kerja bukan pepijat yang boleh anda tulis — ia tidak akan dikompil. Repositori meleraikan DAO mereka pada setiap panggilan dan bukannya menyimpannya dalam cache, dan kerana setiap kaedah repositori menerimaworkspaceIdyang wajib, ruang kerja itu tidak boleh disimpulkan atau dijadikan lalai. - Id ruang kerja ialah segmen laluan. Kerana id itu menjadi nama direktori, ia mesti sepadan dengan corak satu segmen yang selamat (bermula dengan abjad angka, diikuti abjad angka, titik, garis bawah, sempang; tiada
..). Id ialah UUID di seluruh produk. Apa-apa selainnya akan membaling ralat dan bukannya dibersihkan — itulah pengawal pengembaraan laluan dan ia gagal secara lantang daripada menulis data ruang kerja ke laluan yang dipilih orang lain. - Pertahanan berlapis. Lajur
workspaceIdmasih ada dan masih ditulis. Walaupun berlebihan dalam satu fail, ia mengekalkan pencetus suapan segerak, indeks FTS dan bentuk baris sedia ada tanpa perubahan serta menjadikan fail itu menerangkan dirinya sendiri apabila diperiksa secara berasingan — itulah yang diharapkan oleh eksport dan import. - Lapisan domain. Perkhidmatan yang mengubah entiti mengikut id mengesahkan
entity.workspaceId == workspaceIdpada satu titik sekatan sebelum meneruskan dan membalingWorkspaceMismatchExceptionapabila tidak sepadan — kegagalan lantang bagi id yang tiba daripada konteks yang salah. Menolak secara lantang itu penting: operasi senyap yang tiada kesan menyembunyikan pepijat, manakala meneruskan akan membocorkan data. - Lapisan RPC. Penghantar repo-RPC ialah titik sekatan itu. Setiap operasi berskop ruang kerja mesti membawa
workspace_iddalam argnya sendiri — tiada “ruang kerja semasa” bagi setiap sesi untuk dibocorkan, dan id yang tidak dikenali ditolak sebagai tidak ditemui sebelum apa-apa membuka pangkalan data, jadi id yang salah tidak boleh melahirkanworkspace.dbhantu. Operasi yang benar-benar global (suapan berita, baris gilir armada) mengisytiharkan dirinya tidak berskop sebagai keputusan yang eksplisit dan disemak. Alat MCP mengikut peraturan yang sama: mana-mana alat yang menyentuh data berskop ruang kerja memerlukanworkspace_id. - Fan-out merentas ruang kerja boleh dienumerasi. Menjawab soalan tentang beberapa ruang kerja bermakna membuka beberapa pangkalan data. Fan-out itu terhad kepada satu pembantu,
CrossWorkspaceQueries, jadi senarai lengkap perkara yang sah melintasi sempadan itu terletak pada tapak panggilan satu fail dan bukannya bertaburan di sebalik ulasan dokumentasi. Tapak panggilan itu ialah: pengagregatan seluruh pelayan, pengselaras permulaan, sapuan pengekalan dan GC, sandaran, penghala peristiwa — dan carian keahlian di bawah. - Akses mengikut id sahaja tidak mencukupi. Mencari entiti mengikut UUID-nya tidak membuktikan ia milik ruang kerja pemanggil. Pemisahan fail menjadikan fail yang salah tidak dapat dicapai; pengesahan lapisan domain menangkap id yang salah yang tiba melalui fail yang sah.
Keahlian, bukan kunci pasangan, yang memberikan akses
Bahagian bertajuk “Keahlian, bukan kunci pasangan, yang memberikan akses”Memegang kelayakan peranti mengesahkan identiti peranti. Ia tidak memberi kuasa terhadap apa-apa di dalam ruang kerja. Setiap operasi berskop ruang kerja meleraikan peranan keahlian pemanggil dan menguatkuasakan had minimum yang diperoleh daripada jenis operasi itu — bacaan memerlukan guest, mutasi memerlukan member, operasi pemusnahan memerlukan admin — dan operasi yang mendedahkan kandungan repo turut menyemak geran setiap repo pemanggil. Kunci pasangan yang sah tanpa keahlian akan mendapat Not a member of this workspace.
Kesan terhadap pengasingan cukup kemas: baris keahlian tersimpan dalam fail ruang kerja itu sendiri, jadi “siapa berada dalam ruang kerja ini?” ialah bacaan berskop biasa. Soalan sebaliknya — “dalam ruang kerja mana saya berada?” — mengikut takrifnya tersebar merentas fail, jadi ia salah satu daripada beberapa fan-out CrossWorkspaceQueries yang dibenarkan dan itulah yang dijalankan oleh pemilih ruang kerja sebelum mana-mana ruang kerja dipilih.
Lihat Multipemain untuk tangga peranan dan geran repo.
Daftar global
Bahagian bertajuk “Daftar global”Bukan semua perkara berskop ruang kerja. Pangkalan data kedua, <dataDir>/global.db, menyimpan perkara yang benar-benar merentas pelayan:
- daftar ruang kerja, supaya penukar boleh menyenaraikan setiap ruang kerja tanpa membuka satu pun fail ruang kerja — dan supaya nama, logo, pemilik, susunan manual dan penanda padam lembut sesuatu ruang kerja tersimpan di luar fail yang diterangkannya;
- identiti: pengguna, keutamaan pengguna dan peranti dipasangkan, kerana seorang manusia ialah satu pengguna merentas setiap ruang kerja dan peranti yang dipasangkan terus wujud walaupun satu ruang kerja dipadam;
- baris gilir armada (pekerja, tugas, log penempatan), yang penjadualnya memadankan keseluruhan baris gilir dengan setiap pekerja pada setiap detik;
- suapan berita, yang bersifat setiap pengguna (bukan setiap ruang kerja) — menambah suapan akan mengikut anda ke setiap ruang kerja;
workspace_routes, indeks pra-pengesahan yang menjawab “ruang kerja mana yang memiliki kunci ini?” bagi titik masuk yang tiba dengan hanya rahsia atau id legap (hash jemputan, token webhook, pautan dalam) dan tiada ruang kerja. Ketiadaan padanan di situ bermakna tidak ditemui; tiada pengimbasan sandaran secara sengaja;- tetapan dan identiti seluruh pemasangan: id pemasangan, tetapan peringkat hos, sambungan SSO dan polisi tindakan terurus (pengapit seluruh pemasangan yang hanya boleh mengetatkan guardrail ruang kerja).
But hanya membuka fail ini. Fail ruang kerja dibuka secara malas pada sentuhan pertama, jadi kos permulaan kekal rata tidak kira berapa banyak sejarah yang dikumpulkan oleh ruang kerja dan quick_check setiap fail dibayar pada penggunaan pertama dan bukannya pada laluan ke sepanduk sedia.
Fail ruang kerja hanya membawa workspace_meta satu baris untuk pengenalan diri (idnya, pemasangan yang menciptanya, versi skema yang digunakan untuk menciptanya, bilanya). Segala yang bersifat deskriptif tentang ruang kerja berada dalam daftar.
Mencipta ruang kerja
Bahagian bertajuk “Mencipta ruang kerja”Mencipta ruang kerja melakukan lebih daripada memasukkan satu baris daftar. Dalam satu operasi, pelayan menandakan pengguna pencipta sebagai ownerUserId, merekodkan keahlian peranan pemilik pengguna itu dan menerbitkan peristiwa domain WorkspaceCreated. Pendengar peristiwa itu kemudian menyemai, secara idempoten dan di latar belakang:
- satu ejen CEO serta empat pakar —
qa,architect,engineer,librarian— dengan pakar melapor kepada CEO; - templat pipeline terbina dan pencetusnya (pencetus peristiwa dan manual disertakan dalam keadaan didayakan; yang berjadual adalah pilihan kecuali sapuan GC worktree harian);
- suite eval permulaan.
Ini berlaku bagi setiap ruang kerja, bukan yang pertama sahaja. Ejen yang disemai dicipta tanpa penyesuai, jadi ia berjalan pada Control Center (built-in) dengan model lalai Anthropic (claude-opus-4-8 melainkan anda menetapkan yang lain) sehingga anda menetapkan penyesuai dan model bagi setiap ejen di Tetapan → Ruang kerja → Ejen. Lihat Model ejen.
Penulisan keahlian pemilik itu lebih penting daripada yang kelihatan: tanpanya, ruang kerja yang baru dicipta tidak akan mempunyai ahli dan setiap panggilan berskop ruang kerja yang dibuat pencipta selepas itu akan ditolak.
Memadam, mengeksport, mengimport
Bahagian bertajuk “Memadam, mengeksport, mengimport”Memadam ruang kerja menandakan baris daftar dan menyahpaut direktori. Ruang kerja itu hilang daripada setiap senarai dan carian. Baris daftar kekal (dipadam lembut) supaya id itu masih dikenali oleh sandaran dan penyelenggaraan, tetapi workspace.delete serta-merta menggugurkan direktori ruang kerja itu — pangkalan data, worktree, fail ejen dan selebihnya — melalui WorkspaceDatabaseManager.dropAndClose. Hanya pemilik ruang kerja boleh memadamnya.
Kerana satu ruang kerja ialah satu fail, memindahkan ruang kerja ialah operasi fail dan bukannya lambakan jadual demi jadual:
workspace.exportialah satuVACUUM INTO— snapshot yang konsisten dan dinyahserpihan, diambil di bawah transaksi baca sementara pelayan terus melayan.workspace.importmengguna pakai fail sedemikian, menggantikan apa sahaja yang sedang dipegang oleh ruang kerja sasaran.workspace_metayang tertanam membolehkan import membezakan “fail saya sendiri, diguna pakai semula” daripada “fail dari pemasangan lain” (yang kedua dibenarkan, tetapi direkodkan dan bukan dibiarkan tanpa jejak).server.backupNowmengambil snapshot keseluruhan pemasangan ke dalam direktori bertarikh yang mencerminkan direktori data langsung —manifest.json,global.dbdan satu<workspaceId>/workspace.dbbagi setiap ruang kerja — jadi pemulihan hanyalah menyalinnya kembali.server.listBackupsmembaca semula direktori itu, yang terbaharu dahulu, dengan saiz dan senarai ruang kerja setiap snapshot. Snapshot yang manifesnya hilang atau menamakan fail yang tidak ada tetap dilaporkan, ditandakan tidak lengkap — menyembunyikannya ialah cara seorang pengendali mula mempercayai mereka mempunyai sandaran yang sebenarnya tiada.
Operasi sandaran terletak di bawah Tetapan → Pelayan → Sandaran & pulih:
Sandarkan sekarang mengambil snapshot pemasangan, senarai menunjukkan snapshot
mana yang lengkap dan membenarkan pemilik pemasangan memadam satu selepas
pengesahan, dan setiap ruang kerja menawarkan eksport dan import. Pipeline
Workspace backup terbina hanya mengambil pangkalan data ruang kerja itu
mengikut jadual mingguan dan memadam sandarannya sendiri yang lebih lama
daripada usia pengekalan yang dikonfigurasikan. Memulihkan satu ruang kerja
daripada snapshot pemasangan ialah workspace.import yang ditunjuk ke
<workspaceId>/workspace.db snapshot itu; memulihkan seluruh pemasangan kekal
sebagai penyalinan kembali direktori snapshot dengan pelayan dihentikan.
Apa yang tidak dibawa oleh mana-mana daripadanya ialah seluruh direktori ruang kerja yang lain. Ruang kerja mengumpul lebih daripada sekadar pangkalan data — imej yang ditampal, fail kemahiran dan ejen, kelayakan sembang, worktree — dan eksport serta import memindahkan fail itu, jadi segala di sisinya kekal di tempatnya. Itu memang sengaja bagi kelayakan dan boleh dibuang bagi worktree; bagi yang selebihnya, ia had yang perlu diketahui dan bukannya ciri. Rujukan sandaran mempunyai jadual penuhnya.
Memindahkan sandaran antara pelayan dan peranti anda
Bahagian bertajuk “Memindahkan sandaran antara pelayan dan peranti anda”Setiap operasi di atas bercakap dalam laluan pada pelayan, yang merupakan jawapan lengkap hanya apabila pelayan itu mesin anda sendiri. Tiga laluan HTTP bertandatangan — /backup/workspace, /backup/snapshot dan /backup/restore — membawa bait untuk setiap topologi lain, pada lorong yang disahkan sama yang sudah digunakan oleh proksi media dan stor imej. Pada halaman, ini ialah butang Muat turun di sebelah setiap eksport dan setiap snapshot (anda pilih tempat ia disimpan), dan Pilih fail dan muat naik untuk memulihkan daripada fail yang berada pada mesin yang anda gunakan. Muat naik itulah yang berfungsi apabila pelayan bukan mesin anda: workspace.import memerlukan fail itu sudah berada pada hos, dan inilah caranya ia sampai ke sana.
Tiga sifat wajar diketahui:
- Muat turun menghasilkan salinan baharu dan pelayan tidak menyimpan satu pun daripadanya. Memuat turun bukan “ambil fail yang dihasilkan butang eksport” — ia mengeksport semula, menstrim hasilnya dan memadamnya. Responsnya ialah
no-storedenganAccept-Ranges: noneatas sebab yang sama: julat yang disambung semula akan mencantumkan dua eksport berbeza menjadi satu fail yang kelihatan sah tetapi sebenarnya tidak. - Muat naik distrim ke cakera, tidak pernah melalui penimbal, pada kedua-dua hujung, dan salinan pentas dipadam pada setiap laluan keluar — termasuk penolakan. Pangkalan data ruang kerja bukan tangkapan skrin.
- Sambungan melalui geganti tiada asal HTTP, jadi kawalan pemindahan dilumpuhkan di situ dengan nota yang menerangkan sebabnya. Segala yang bercakap dalam laluan sisi pelayan terus berfungsi melalui geganti; hanya lorong bait memerlukan sambungan langsung.
Berbilang ruang kerja
Bahagian bertajuk “Berbilang ruang kerja”Anda boleh menjalankan berbilang ruang kerja bersebelahan. Setiap satu beroperasi secara bebas: ejen dalam satu ruang kerja tidak boleh menghantar mesej kepada ejen dalam ruang kerja lain, tidak boleh membaca memori ruang kerja lain dan tidak boleh melihat tiketnya. Peleraian penerima bagi pemesejan ejen ke ejen adalah tepat dan tidak pernah melintasi ruang kerja.
Tiada papan pemuka merentas ruang kerja. Permukaan analitik di /workspaces/:workspaceId/observability melanggan suapan global terbatas bagi larian terkini dan terus menyempitkannya kepada ruang kerja aktif, jadi apa yang anda lihat di situ ialah satu ruang kerja pada satu masa. Satu-satunya permukaan berbilang ruang kerja sebenar yang disentuh seseorang ialah pemilih ruang kerja dan penukar.
Satu had praktikal wajar diketahui: ruang kerja yang sedang digunakan oleh seseorang akan kekal terbuka — tiada LRU. Melebihi 32 daripadanya, pelayan memberi amaran dan bukannya menolak, kerana setiap fail yang terbuka memegang isolate latar belakang dan cache halaman. Fan-out merentas ruang kerja membuka fail secara sementara dan menutupnya semula selepas itu jika tiada apa-apa lain yang menuntutnya.
Konsep berkaitan
Bahagian bertajuk “Konsep berkaitan”- Multipemain: keahlian, peranan dan geran repo — separuh akses daripada pengasingan
- Model ejen: ejen milik tepat satu ruang kerja
- Memori dan pengetahuan: memori berskop ruang kerja
- Seni bina: di mana pangkalan data berada dalam pemisahan klien/pelayan
- Sandarkan dan pulihkan: mengambil snapshot, memindahkan ruang kerja, menyimpan salinan di tempat lain
- Sandaran, eksport dan import: setiap operasi, laluan, medan manifes dan had
- Tambah repositori: mendaftarkan checkout ke dalam ruang kerja