İçeriğe geç

Çalışma alanları ve yalıtım

Çalışma alanı, Control Center’daki en üst düzey yalıtım kiracısıdır. Ajanları, depoları, alanları, biletleri, belleği, pipeline’ları ve üyeleri sınırları belirli bir bağlama toplar. Bir çalışma alanının içinde olan her şey orada kalır.

Tipik bir çalışma alanı bir projeye ya da bir kod tabanına karşılık gelir. “api-service”, “frontend-v2” ve “infrastructure” için ayrı çalışma alanlarınız olabilir.

Bir çalışma alanının satırları, o çalışma alanının kendi SQLite dosyasında, <dataDir>/<workspaceId>/workspace.db yolunda yaşar. Her çalışma alanı çıplak bir dosya yerine bir dizin alır; çünkü bir çalışma alanı bir veritabanından fazlasını biriktirir — konuşma başına worktree’ler, ajan ve beceri dosyaları, sohbet botu kimlik bilgileri — ve ona bir klasör vermek, tüm bunların birlikte yaşaması ve birlikte silinmesi anlamına gelir.

Varlık Kapsam
Ajanlar Tam olarak bir çalışma alanına aittir
Depolar Bir çalışma alanına kaydedilir (aşağıya bakın)
Alanlar, konuşmalar ve mesajlar Çalışma alanı kapsamlı
Biletler, projeler, planlar, orkestrasyonlar Çalışma alanı kapsamlı
Bellek olguları, politikalar, bilgi alanları, erişim izinleri Çalışma alanı kapsamlı
Pipeline çalıştırmaları, şablonlar, tetikleyiciler Çalışma alanı kapsamlı
Pull request durumu, inceleme alanları, inceleme kohortları Çalışma alanı kapsamlı
Ajan çalıştırma günlükleri ve çalışma belleği Çalışma alanı kapsamlı
Üyeler, davetler, depo başına izinler Çalışma alanı kapsamlı
Kod grafiği sembolleri ve kenarları Çalışma alanı dosyasında repoId ile kapsamlanır

Bu satırların çoğu bir workspaceId sütunu taşır; yalıtımı ayrı veritabanı dosyaları uygular. Aşağıdaki yalıtım değişmezine bakın.

Depolar çalışma alanı kapsamlıdır; çalışma alanları arası kimlik yola göredir

Bölüm başlığı “Depolar çalışma alanı kapsamlıdır; çalışma alanları arası kimlik yola göredir”

Bir depo satırı, çalışma alanının kendi veritabanı dosyasında yaşar — kapsam dosyanın kendisidir, bu yüzden tabloda workspaceId sütunu ve birleştirme tablosu yoktur.

Bir çalışma alanına depo eklemeyi Ayarlar → Çalışma alanı → Depolar’dan yaparsınız. Aynı checkout’u iki çalışma alanına kaydetmek, iki farklı kimliğe sahip iki bağımsız satır oluşturur; depoların çalışma alanları arasındaki kimliği dosya sistemi yoluna (ya da GitHub owner/name değerine) göredir, asla kimliğe göre değil.

Kayıt katıdır: yol bir git çalışma ağacının içinde olmalı, bir origin uzak deposu bulunmalı ve bu uzak depo desteklenen bir kod barındırıcısına (github.com, gitlab.com veya bitbucket.org) işaret etmelidir. Kod barındırıcı, uzak depodan okunur ve depoda saklanır; böylece tek bir çalışma alanı üçünün de depolarını barındırabilir. Bunun dışındaki her şey reddedilir. Seçim yaptığınız klasör tarayıcısı sunucu ana makinesinin dosya sistemini listeler ve sunucunun --repo-roots izin listesiyle (varsayılanı sunucu kullanıcısının ev dizinidir) sınırlıdır.

Bir depoyu çalışma alanından kaldırmak, satırı tamamen siler ve kod sembollerini, kenarlarını, dosyalarını, indeks kontrol noktalarını ve üye başına izinleri zincirleme siler. Diskteki checkout’a dokunulmaz.

Kod grafiği aynı dosyada, repoId anahtarıyla yaşar; çünkü farklı çalışma alanları aynı depoyu farklı dallarda ve farklı kodlarla bulundurabilir.

Çalışma alanları arası veri sızıntıları hata olarak kabul edilir. Yalıtım yapısaldır ve birkaç düzeyde uygulanır:

  • Veritabanı katmanı. Her çalışma alanının kendi SQLite dosyası vardır ve bu dosya WorkspaceDatabaseManager.of(workspaceId) tarafından verilir. Bir çalışma alanı veritabanı users, workspaces ya da başka bir çalışma alanının tablolarını bildirmez; dolayısıyla çalışma alanları arası bir okuma, yazabileceğiniz bir hata değildir — derlenmez. Depolar DAO’larını önbelleğe almak yerine her çağrıda çözer ve her depo yöntemi zorunlu bir workspaceId aldığı için çalışma alanı hiçbir zaman çıkarılamaz ya da varsayılana düşürülemez.
  • Çalışma alanı kimliği bir yol segmentidir. Kimlik bir dizin adına dönüştüğü için güvenli, tek segmentli bir desenle eşleşmelidir (alfanümerik bir başlangıç, ardından alfanümerik karakterler, noktalar, alt çizgiler, tireler; .. yok). Ürünün her yerinde kimlikler UUID’dir. Bunun dışındaki her şey temizlenmek yerine hata fırlatır — yol geçişi koruması budur ve bir çalışma alanının verisini başkasının seçtiği bir yola yazmak yerine yüksek sesle başarısız olur.
  • Derinlemesine savunma. workspaceId sütunları hâlâ orada ve hâlâ yazılıyor. Bir dosya içinde gereksiz olsalar da senkronizasyon akışı tetikleyicilerini, FTS dizinlerini ve mevcut satır biçimlerini değiştirmeden korurlar ve bir dosya tek başına incelendiğinde onu kendi kendini tanımlar hâle getirirler — dışa ve içe aktarmanın güvendiği şey de budur.
  • Alan katmanı. Varlıkları kimliğe göre değiştiren servisler, devam etmeden önce tek bir geçiş noktasında entity.workspaceId == workspaceId doğrulaması yapar ve uyuşmazlıkta WorkspaceMismatchException fırlatır — yanlış bağlamdan gelen bir kimlik için yüksek sesli başarısızlık. Yüksek sesle reddetmek önemlidir: sessiz bir no-op hatayı gizler, devam etmek ise veri sızdırır.
  • RPC katmanı. Depo-RPC göndericisi geçiş noktasıdır. Çalışma alanı kapsamlı her işlem, workspace_id değerini kendi argümanlarında taşımalıdır — sızabilecek oturum başına bir “geçerli çalışma alanı” yoktur ve bilinmeyen bir kimlik, herhangi bir şey bir veritabanı açmadan önce bulunamadı olarak reddedilir; böylece kötü bir kimlik hayalet bir workspace.db ortaya çıkaramaz. Gerçekten genel işlemler (haber akışı, filo kuyruğu) kendilerini açık, gözden geçirilmiş bir kararla kapsamsız ilan eder. MCP araçları aynı kuralı izler: çalışma alanı kapsamlı veriye dokunan her araç workspace_id gerektirir.
  • Çalışma alanları arası fan-out sayılabilirdir. Birkaç çalışma alanıyla ilgili bir soruyu yanıtlamak, birkaç veritabanı açmak anlamına gelir. Bu fan-out tek bir yardımcıya, CrossWorkspaceQueries’e hapsedilmiştir; böylece sınırı meşru şekilde aşan şeylerin tam listesi, doküman yorumlarının arkasına dağılmak yerine tek bir dosyanın çağrı noktalarında yaşar. Bu çağrı noktaları şunlardır: sunucu geneli toplama, başlangıç uzlaştırıcıları, saklama ve GC süpürmeleri, yedekleme, olay yönlendiricileri — ve aşağıdaki üyelik araması.
  • Yalnızca kimlikle erişim yeterli değildir. Bir varlığı UUID’siyle aramak, onun çağıranın çalışma alanına ait olduğunu kanıtlamaz. Dosya bölünmesi yanlış dosyayı erişilemez kılar; alan katmanı doğrulaması ise meşru bir dosya üzerinden gelen yanlış bir kimliği yakalar.

Erişimi veren şey eşleştirme anahtarı değil, üyeliktir

Bölüm başlığı “Erişimi veren şey eşleştirme anahtarı değil, üyeliktir”

Bir cihaz kimlik bilgisine sahip olmak bir cihazın kimliğini doğrular. Çalışma alanının içindeki hiçbir şeye yetki vermez. Çalışma alanı kapsamlı her işlem, çağıranın üyelik rolünü çözer ve işlemin türünden türetilen bir taban uygular — okuma guest gerektirir, bir değişiklik member gerektirir, yıkıcı bir işlem admin gerektirir — depo içeriğini açığa çıkaran işlemler ayrıca çağıranın depo başına iznini denetler. Üyeliği olmayan geçerli bir eşleştirme anahtarı Not a member of this workspace yanıtını alır.

Bunun yalıtım açısından sonucu nettir: üyelik satırları çalışma alanının kendi dosyasında yaşar; böylece “bu çalışma alanında kim var?” sıradan bir kapsamlı okumadır. Ters soru — “hangi çalışma alanlarındayım?” — tanım gereği dosyalara yayılmıştır; bu yüzden izin verilen birkaç CrossWorkspaceQueries fan-out’undan biridir ve çalışma alanı seçicisinin, herhangi bir çalışma alanı seçilmeden önce çalıştırdığı şeydir.

Rol merdiveni ve depo izinleri için Çok oyunculu sayfasına bakın.

Her şey çalışma alanı kapsamlı değildir. İkinci bir veritabanı, <dataDir>/global.db, gerçekten sunucu geneli olanları barındırır:

  • çalışma alanı kaydı; böylece değiştirici, tek bir çalışma alanı dosyası bile açmadan her çalışma alanını listeleyebilir — ve bir çalışma alanının adı, logosu, sahibi, elle sıralaması ve yumuşak silme işareti, tanımladıkları dosyanın dışında yaşar;
  • kimlik: kullanıcılar, kullanıcı tercihleri ve eşleştirilmiş cihazlar; çünkü tek bir insan, her çalışma alanında tek bir kullanıcıdır ve eşleştirilmiş bir cihaz, bir çalışma alanı silinse de varlığını sürdürür;
  • filo kuyruğu (worker’lar, işler, yerleştirme günlüğü); zamanlayıcısı her tikte kuyruğun tamamını her worker’la eşleştirir;
  • haber akışı, kullanıcı başına (çalışma alanı başına değil) — eklediğiniz bir akış sizi her çalışma alanına kadar izler;
  • workspace_routes, kimlik doğrulama öncesi dizin; yalnızca bir sırla ya da opak bir kimlikle (bir davet karması, bir webhook token’ı, bir derin bağlantı) gelen ve hiçbir çalışma alanı bilgisi taşımayan giriş noktaları için “bu anahtar hangi çalışma alanına ait?” sorusunu yanıtlar. Burada bir ıska, bulunamadı demektir; bilinçli olarak tarama yedeği yoktur;
  • kurulum geneli ayarlar ve kimlik: kurulum kimliği, ana makine düzeyi ayarlar, SSO bağlantıları ve yönetilen eylem politikaları (çalışma alanı korumalarını yalnızca sıkılaştırabilen kurulum geneli bir sınırlama).

Önyükleme yalnızca bu dosyayı açar. Çalışma alanı dosyaları ilk dokunuşta tembelce açılır; böylece çalışma alanları ne kadar geçmiş biriktirirse biriktirsin başlangıç maliyeti sabit kalır ve dosya başına quick_check, hazır bildirimine giden yolda değil ilk kullanımda ödenir.

Bir çalışma alanı dosyası, kendini tanımlamak için yalnızca tek satırlık bir workspace_meta taşır (kimliği, onu oluşturan kurulum, oluşturulduğu şema sürümü, ne zaman oluşturulduğu). Bir çalışma alanı hakkında tanımlayıcı olan her şey kayıt defterindedir.

Çalışma alanı oluşturmak, bir kayıt satırı eklemekten fazlasını yapar. Sunucu tek bir işlemde, oluşturan kullanıcıyı ownerUserId olarak damgalar, o kullanıcının sahip rolündeki üyeliğini kaydeder ve bir WorkspaceCreated alan olayı yayımlar. Bu olayı dinleyenler ardından, arka planda ve idempotent biçimde şunları tohumlar:

  • bir CEO ajanı ve dört uzman — qa, architect, engineer, librarian — uzmanlar CEO’ya rapor verir;
  • yerleşik pipeline şablonları ve tetikleyicileri (olay ve elle tetikleyiciler etkin olarak gelir; zamanlanmış olanlar, günlük worktree-GC süpürmesi dışında isteğe bağlıdır);
  • başlangıç eval takımları.

Bu, yalnızca ilki için değil, her çalışma alanı için gerçekleşir. Tohumlanan ajanlar adaptörsüz oluşturulur; bu yüzden siz her ajan için Ayarlar → Çalışma alanı → Ajanlar’dan bir adaptör ve model belirleyene kadar Anthropic’in varsayılan modeliyle (claude-opus-4-8, başka bir model sabitlemediyseniz) Control Center (built-in) üzerinde çalışırlar. Ajan modeli sayfasına bakın.

Sahip üyeliğinin yazımı göründüğünden daha önemlidir: o olmasaydı, yeni oluşturulan çalışma alanının hiç üyesi olmazdı ve oluşturanın sonraki her çalışma alanı kapsamlı çağrısı reddedilirdi.

Bir çalışma alanını silmek kayıt satırını işaretler ve dizinin bağlantısını keser. Çalışma alanı her listeden ve aramadan kaybolur. Kayıt satırı (yumuşak silinmiş olarak) kalır; böylece kimlik, yedekleme ve bakım tarafından hâlâ bilinir, ancak workspace.delete o çalışma alanının dizinini — veritabanı, worktree’ler, ajan dosyaları ve geri kalanı — WorkspaceDatabaseManager.dropAndClose üzerinden anında siler. Yalnızca çalışma alanı sahibi silebilir.

Bir çalışma alanı tek bir dosya olduğundan, bir çalışma alanını elden ele geçirmek tablo tablo bir döküm değil, bir dosya işlemidir:

  • workspace.export tek bir VACUUM INTO deyimidir — sunucu hizmet vermeye devam ederken bir okuma işlemi altında alınan tutarlı, parçalanması giderilmiş bir anlık görüntü.
  • workspace.import böyle bir dosyayı sahiplenir ve hedef çalışma alanının o anda tuttuğu her şeyin yerine geçer. Gömülü workspace_meta, bir içe aktarmanın “kendi dosyam, yeniden sahiplenildi” ile “başka bir kurulumdan gelen dosya” arasında ayrım yapmasını sağlar (ikincisine izin verilir, ama görünmez kalmak yerine günlüğe yazılır).
  • server.backupNow, kurulumun tamamının anlık görüntüsünü, canlı veri dizinini yansıtan zaman damgalı bir dizine alır — manifest.json, global.db ve her çalışma alanı için bir <workspaceId>/workspace.db — böylece geri yüklemek, onu geri kopyalamaktır.
  • server.listBackups o dizini en yeniden en eskiye doğru geri okur; her anlık görüntünün boyutunu ve çalışma alanı listesini verir. Manifestosu eksik olan ya da orada olmayan dosyaları adlandıran bir anlık görüntü yine de bildirilir ve eksik olarak işaretlenir — onu gizlemek, bir operatörün aslında sahip olmadığı bir yedeğe sahip olduğuna inanmasının yoludur.

Yedekleme işlemleri Ayarlar → Sunucu → Yedekleme ve geri yükleme altında yaşar: Şimdi yedekle bir kurulum anlık görüntüsü alır, liste hangi anlık görüntülerin tam olduğunu gösterir ve kurulum sahibinin onaydan sonra birini silmesine izin verir; her çalışma alanı da dışa ve içe aktarma sunar. Yerleşik Workspace backup pipeline’ı haftalık bir programla yalnızca o çalışma alanının veritabanını alır ve yapılandırılmış saklama süresinden eski kendi yedeklerini siler. Bir çalışma alanını kurulum anlık görüntüsünden geri yüklemek, anlık görüntünün <workspaceId>/workspace.db yolunu gösteren workspace.import çağrısıdır; kurulumun tamamını geri yüklemek ise anlık görüntü dizininin, sunucu durdurulmuşken geri kopyalanması olarak kalır.

Hiçbirinin taşımadığı şey, çalışma alanı dizininin geri kalanıdır. Bir çalışma alanı bir veritabanından fazlasını biriktirir — yapıştırılmış görseller, beceri ve ajan dosyaları, sohbet kimlik bilgileri, worktree’ler — dışa ve içe aktarma ise dosyayı taşır; dolayısıyla yanındaki her şey olduğu yerde kalır. Bu, kimlik bilgileri için bilinçli bir tercih, worktree’ler için gözden çıkarılabilir bir durumdur; geri kalanı içinse bir özellik değil, bilinmesi gereken bir sınırlamadır. Tam tablo için yedekleme referansına bakın.

Yukarıdaki her işlem sunucudaki yollarla konuşur; bu, yalnızca sunucu kendi makinenizse eksiksiz bir yanıttır. İmzalı üç HTTP rotası — /backup/workspace, /backup/snapshot ve /backup/restore — diğer tüm topolojiler için baytları taşır; medya proxy’sinin ve görsel deposunun zaten kullandığı aynı kimliği doğrulanmış hat üzerinden. Sayfada bu, her dışa aktarmanın ve her anlık görüntünün yanındaki bir İndir düğmesidir (nereye ineceğini siz seçersiniz) ve kullandığınız makinede duran bir dosyadan geri yüklemek için Bir dosya seçin ve yükleyin. Sunucu sizin makineniz olmadığında işleyen yol, yüklemedir: workspace.import dosyanın ana makinede zaten bulunmasını gerektirir ve dosya oraya bu şekilde ulaşır.

Bilinmeye değer üç özellik var:

  • İndirme yeni bir kopya üretir ve sunucu ondan hiçbir şey saklamaz. İndirmek, “dışa aktarma düğmesinin oluşturduğu dosyayı getir” demek değildir — yeniden dışa aktarır, onu akıtır ve siler. Yanıt da aynı nedenle no-store ve Accept-Ranges: none taşır: kaldığı yerden devam eden bir aralık, iki farklı dışa aktarmayı geçerli görünen ama geçerli olmayan tek bir dosyada birleştirirdi.
  • Bir yükleme, iki uçta da diske akıtılır, asla arabelleğe alınmaz ve hazırlanan kopya, her çıkış yolunda — bir ret dahil — silinir. Bir çalışma alanı veritabanı bir ekran görüntüsü değildir.
  • Aktarılan bir bağlantının HTTP kaynağı yoktur; bu yüzden aktarım denetimleri orada, nedenini söyleyen bir notla devre dışıdır. Sunucu tarafı yollarla konuşan her şey aktarım üzerinden çalışmaya devam eder; yalnızca bayt hatları doğrudan bir bağlantı gerektirir.

Birden çok çalışma alanını yan yana çalıştırabilirsiniz. Her biri bağımsız çalışır: bir çalışma alanındaki ajanlar başka bir çalışma alanındaki ajanlara mesaj gönderemez, başka bir çalışma alanının belleğini okuyamaz ve onun biletlerini göremez. Ajanlar arası mesajlaşmada alıcı çözümlemesi kesindir ve hiçbir zaman bir çalışma alanını aşmaz.

Çalışma alanları arası bir gösterge paneli yoktur. /workspaces/:workspaceId/observability adresindeki analitik yüzeyi, son çalıştırmalardan oluşan sınırlı bir genel akışa abone olur ve onu hemen etkin çalışma alanına daraltır; yani orada gördüğünüz şey bir seferde tek bir çalışma alanıdır. Bir kişinin dokunduğu gerçekten çok çalışma alanlı tek yüzeyler, çalışma alanı seçicisi ve değiştiricidir.

Bilinmeye değer pratik bir sınır: birinin kullandığı bir çalışma alanı açık kalır — LRU yoktur. Bunların sayısı 32’yi geçtiğinde sunucu reddetmek yerine uyarır; çünkü açık her dosya bir arka plan isolate’i ve bir sayfa önbelleği tutar. Çalışma alanları arası fan-out dosyaları geçici olarak açar ve ardından, başka hiçbir şey onlara sahip çıkmadıysa kapatır.