AiTools.ProfileSyncTool 1.17.0.1153

profile-sync-tool

Catalog agent-config servisinden profil çekip consumer'lara (.claude/rules vb.) dağıtan dotnet tool (T#682). apps/sync-ai-configs'ın yerini alır: dosya-okuma + .sync.json/.workspace.json registry yok; kaynak catalog snapshot, render client-side.

Sıfır lib/registry bağımlılığı (Spectre.Console + System.Text.Json + System.Net.Http).

Kavramsal model + akış şeması (agent-facing): KB domain doc projects/ai-tools/profile-sync/consumer-flow.md (topic profile-sync). Bu README kurulum/çalıştırma için developer-canonical; akış/auth modeli/claude-desktop gotcha'ları için domain doc canonical.

Nasıl çalışır

  1. GET /api/agent-config/snapshot → atoms (roles + instruction groups/shards + skills + profiles).
  2. Client-side resolve (ProfileResolver): selector → specificity ladder → audience-filtreli denormalize. Ladder: profil alanı null = wildcard (her sorgu değerini kabul), dolu alan sorgu değeriyle eşit olmalı, sorgu alanı null iken profil alanı doluysa aday elenir; kazanan = eşleşen dolu alan ağırlık toplamı (stack 4 > work-type 2 > scope 1). İstenen model-tier'da hiç aday yoksa bütünsel frontier profiline düşer. Server ResolveProfileAsync algoritmasının birebir portu; drift parity test ile korunur. (Eski "4/5-seviyeli fallback zinciri" dili RETIRED — hiç implemente edilmemişti, bkz. ADR v3 F7.)
  3. Render (ProfileRenderer + InstructionEmitter): ResolvedProfile → editör formatı (claude-code: .claude/rules/*.md).

Auth — PAT (primary) / session-id (fallback)

Gateway üzerinden iki yöntem (gateway ikisini de kabul eder):

  • PAT (primary): Authorization: Bearer ts_pat_v1_*.
  • session-id (fallback): x-session-id: <GUID> (catalog-loader paterni).

snapshot/resolve allowAuthenticated (admin değil) → read-only yeterli. Tool catalog'a doğrudan değil, gateway'e gider. Env yoksa interaktif prompt: önce yöntem (pat | session-id), sonra değer (gizli).

Kullanım

dotnet tool install --global AiTools.ProfileSyncTool

export PROFILE_SYNC_API_BASE="https://<gateway>/api"
export PROFILE_SYNC_PAT="ts_pat_v1_..."
profile-sync            # interaktif wizard
profile-sync --dry-run  # yazma yok, plan

# Headless (non-interactive) — conductor / script (T#688):
profile-sync prepare --role governance --editors claude-code --target-dir ./repo --api-base https://<gateway>/api --pat ts_pat_v1_...
profile-sync prepare --help   # tum flag'ler + exit kodlari (0 ok / 1 catalog-resolve-ag / 3 kullanim)

# MCP bağlantısı — profil çıktısından ayrı, katalog çağırmaz (AIT-846):
profile-sync mcp api --api-base https://<gateway>/api --agent-pat ts_pat_v1_...
profile-sync mcp conductor --lane-url http://localhost:5100/mcp/lane/<proje>/<yuva>
profile-sync mcp conductor --editors claude-code --conductor-url http://localhost:5100/mcp --conductor-pat <koordinatör PAT'i>
profile-sync mcp api --help ; profile-sync mcp conductor --help

# agent-runtime sandbox yüzeyi — imaj edinimi + tazelik + kit + digest pin'i tek adımda (AIT-897):
profile-sync mcp api --surface sandbox --target-dir ./repo --api-base https://<gateway>/api --agent-pat ts_pat_v1_...
# MCP ve sandbox birlikte (AIT-1250): MCP girişleri korunur, kit + pin yanına yazılır:
profile-sync mcp api --surface mcp,sandbox --target-dir ./repo --api-base https://<gateway>/api --agent-pat ts_pat_v1_...

# Claude Desktop config yolu, makine-okunur (AIT-1250):
profile-sync mcp desktop-path

# agent-runtime kiti yalnız imaj geliştirme/test için — yerel imajdan, pin YAZMAZ (AIT-869):
profile-sync runtime-kit --target-dir ./repo --image agent-runtime:dev
profile-sync runtime-kit --help

prepare alt-komutu interaktif wizard'i BYPASS eder (TTY gerekmez); selector + auth flag'lerden kurulur (auth: flag > env, pat > session). Alt-komut yoksa interaktif mod DEFAULT.

Yayın — publish (AIT-1043)

Ters yön: repo'daki agent-config/ ağacını catalog'a yükler (eski catalog-loader davranışı; loader CI geçişi doğrulanana kadar yerinde kalır). Adımlar ve sırası: roller (+ activate) → gruplar → shard'lar → skill variant'ları → manifest-dışı shard prune → dizin-dışı skill variant prune → profileTree flatten (+ activate, flatten-dışı aktif profil archive) → phase template'ler → tag registry.

profile-sync publish --dry-run                 # api base yoksa OFFLINE plan: ağ ve PAT gerekmez
export PROFILE_SYNC_PUBLISH_PAT="ts_pat_v1_..." # *:catalog:write
profile-sync publish --api-base https://<gateway>/api [--no-prune] [--skip-profiles|--skip-skills|--skip-templates|--skip-tags]
profile-sync publish --help
  • Komut bazlı yetki: publish yalnız env PROFILE_SYNC_PUBLISH_PAT okur (bayrağı yok, argv'ye yazılmaz); PROFILE_SYNC_PAT okuma PAT'idir, publish ona düşmez. Okuma komutları (wizard, prepare, verify) yazma PAT'ini okumaz.
  • Önce doğrula, sonra yaz: manifest birleştirme, shard yolu/audience drift-guard, fail-closed frontmatter ve profileTree şeması ilk istekten önce tamamen okunur; bozuk kaynakta hiçbir istek gitmez (exit 3).
  • Gereken yetki *:catalog:write: rol, skill, talimat, faz şablonu ve tag ortak tanımdır; catalog bunların yazımı için tüm projeleri kapsayan yetkiyi ister. Tek projeli <proje>:catalog:write (örn. ai-tools:catalog:write) ve shared:catalog:write ortak tanım yazamaz.
  • Yetki yoksa yazmadan düşer: publish'in yazdığı uçların hepsi aynı yetkiyi ister; PAT taşımıyorsa ilk yazma reddedilir ve yayın orada durur, katalogda kısmi durum kalmaz (exit 4). Hata satırı gereken yetkiyi adıyla yazar.
  • --agent-config <dizin> verilmezse CWD ve üstlerinde agent-config/manifest aranır.
  • Exit: 0 ok · 1 catalog/ağ · 3 kullanım/kaynak (yazma yok) · 4 yazma yetkisi yok.

MCP bağlantısı — mcp api / mcp conductor (AIT-846)

Profil çıktısı (prepare: instruction + skill) ile MCP bağlantısı ayrı alt komuttur. mcp katalog/snapshot çağırmaz; yalnız MCP config dosyalarını yazar. Karar kaydı: decision/design/profile-sync-mcp-subcommand.

Komut Yazdığı girişler Cred
mcp api --surface kümesi: mcp (default) → agent-ops, knowledge-base · sandbox → kit + .agent-runtime.json imaj pin'i · mcp,sandbox → ikisi; her kümede {target-dir}/.agent-runtime.json kimliği. Kümede olmayan yüzeyin izi silinir (aşağıda). --conductor-sandbox ile sandbox Conductor üzerinden koşar: kit, pin ve .agent-runtime.json yazılmaz (aşağıda) agent-PAT zorunlu (--agent-pat > env PROFILE_SYNC_AGENT_PAT; yoksa exit 3)
mcp desktop-path hiçbir şey yazmaz; Claude Desktop config yolunu tek satır JSON basar (aşağıda) yok
mcp conductor iki ayrık moddan biri: şerit --lane-url → conductor-lane (file editör MCP dosyası) · koordinatör --conductor-url → conductor (seçili her MCP editörü: file editör MCP dosyası ve/veya Claude Desktop) her mod yalnız kendi PAT girdilerini okur · şerit: şerit PAT'i --lane-pat > env PROFILE_SYNC_LANE_PAT, isteğe bağlı (yoksa başlıksız; koruma loopback + LocalHostGuard) · koordinatör: --conductor-pat > env PROFILE_SYNC_CONDUCTOR_PAT (koordinatör PAT'i ya da çalışma klasörünün agent-mcp PAT'i; tür kontrolü yok), yoksa auth'suz + UYARI

Ortak: --editors <csv> (default claude-code; MCP hedefi olanlar claude-code, cursor, trae → {target-dir} altındaki MCP dosyası, claude-desktop → global Claude Desktop config), --target-dir (default CWD), --dry-run. mcp api: --api-base (> env PROFILE_SYNC_API_BASE), --surface <küme> (mcp, sandbox ya da virgülle ikisi; sıra önemsiz; default mcp; boş ya da bilinmeyen eleman exit 3 — eski agent-runtime değeri alias değildir). mcp conductor: --conductor-url, --actor-role, --lane-url, --conductor-pat (yalnız koordinatör modu), --lane-pat (yalnız şerit modu); gateway'e gitmez, --api-base almaz. --conductor-sandbox yalnız mcp api'nindir: mcp conductor girişi PAT'i türüne bakmadan yazar, bayrağın orada etkisi olmazdı (exit 3, bilinmeyen argüman).

  • Hiçbir parametre etkisiz kalamaz — etkisini gösteremeyeceği kombinasyon exit 3: MCP hedefi olmayan editör (codex, local-compose); mcp conductor'da iki mod birlikte ya da hiçbiri; koordinatör PAT'i yoksa --conductor-url --actor-role ister, PAT varsa --actor-role verilemez (rolü conductor PAT'ten okur); --actor-role --conductor-url ister; mcp conductor'da --api-base; şerit modu yalnız file editörle (claude-desktop seçilemez). Mod editör tipiyle değil parametreyle belirlenir: koordinatör modu seçilen her MCP editörüne yazar (claude-code, cursor, trae, claude-desktop).
  • Birleşik yazım + eşitleme: her koşu yazdığı dosyayı okur, yalnız kendi anahtarını o koşunun değerine eşitler (eski URL yenisiyle değişir); diğer girişler (elle eklenenler dahil) korunur. Komut sırası sonucu değiştirmez; bir mod diğer modun girişine dokunmaz (aynı .mcp.json'da conductor ve conductor-lane yan yana durabilir). Mevcut dosya okunamıyorsa (geçersiz JSON) dosyaya dokunulmaz, exit 1.
  • Silme yok — tek istisna mcp api yüzey kümesi: parametre verilmemesi mevcut girişi kaldırmaz; istenmeyen girişin temizliği elle. İstisna mcp api --surface: küme bildirimseldir, kümede olmayan yüzeyin izi bu koşuda silinir (decision/design/agent-runtime-image-acquisition § rev-2026-11-07-combined-surface):
    • kümede mcp yok → kendi agent-ops/knowledge-base girişleri file editör MCP dosyalarından kalkar (yazacak giriş kalmayan dosya yeni oluşturulmaz; conductor/conductor-lane girişlerine dokunulmaz);
    • kümede sandbox yok → {target-dir}/.agent-runtime/ kiti, render-state manifest'indeki kit kaydı ve .agent-runtime.json kök "image" pin'i kalkar; Docker'a dokunulmaz. Kit varken manifest okunamıyorsa hiçbir şey yapılmaz, exit 1.
    • --conductor-sandbox (her kümede) → sandbox işi Conductor'da koşar: Docker çağrılmaz, kit, pin ve .agent-runtime.json yazılmaz; önceki kit ve manifest kaydı kalkar, .agent-runtime.json'dan aracın kendi anahtarları (agent-ops, knowledge-base, image) kalkar, başka anahtar kalmazsa dosya silinir. Kimlik dosyası yazılmadığı için sızıntı kapısı onu istemez. Kümedeki sandbox'ın karşılığı Conductor girişi ve PAT iznidir. --dry-run silmez, silineceği gösterir.
  • Rol başlığı: araç hiçbir girişe X-Actor-Role yazmaz — gateway rolü PAT'in actor: scope'undan kurar. Conductor girişinde koordinatör PAT'i varsa rol başlığı da yazılmaz: rolün tek kaynağı PAT'tir ve conductor onu kendisi okur (AIT-980 F13, AIT-1011). PAT yoksa rol --actor-role değeriyle X-Conductor-Role başlığına yazılır.
  • .agent-runtime.json (AIT-850, decision/design/agent-runtime-operating-model K3): mcp api, --editors seçimi ne olursa olsun {target-dir} köküne editörden bağımsız kimlik dosyasını tek kez yazar: {"servers":{"agent-ops":{"url","token"},"knowledge-base":{"url","token"}}} — MCP dosyalarıyla aynı adres, aynı agent-PAT (ham token, Bearer öneki yok). Tüketicisi agent-runtime run-job'dur. Birleşik yazım burada da geçerli: servers altındaki diğer anahtarlar ve kök anahtarlar korunur. Kümede sandbox varsa kök "image" anahtarına <repo>@sha256:<digest> pin'i yazılır (aşağıda), yoksa anahtar kalkar.
  • Sızıntı koruması (fail-closed): token taşıyan hedef-dizin dosyası (.agent-runtime.json, .mcp.json, .cursor/mcp.json, .trae/mcp.json) bir git çalışma ağacındaysa git check-ignore ile ignore edildiği doğrulanır. Biri ignore edilmiyorsa (izlenen dosya dahil) ya da durum ölçülemiyorsa hiçbir dosya yazılmaz, exit 1 ve mesaj eklenecek ignore satırını verir. .gitignore'a dokunulmaz. Git ağacı olmayan hedef (ör. Claude Desktop global config) kontrol edilmez. Aynı koruma prepare/wizard'ın deprecate agent-PAT yolunda da geçerlidir.

Exit: 0 ok · 1 mevcut config okunamadı / Claude Desktop config yolu çözülemedi / token dosyası git'te ignore edilmiyor / yalnız-sandbox kümede imaj ya da kit edinilemedi · 3 kullanım.

mcp desktop-path — Claude Desktop config yolu (AIT-1250)

Yazıcıların (mcp api / mcp conductor --editors claude-desktop) kullandığı yolun kendisi; conductor yolu kendisi türetmez, buradan sorgular. stdout tek satır JSON, dosyaya dokunmaz:

{"platform":"windows","path":"C:\\Users\\u\\AppData\\Roaming\\Claude\\claude_desktop_config.json","exists":true,"reason":null}

platform: windows (%APPDATA%\Claude) · macos ($HOME/Library/Application Support/Claude) · linux ($HOME/.config/Claude) · null (desteklenmeyen OS). Yol çözülemezse (APPDATA/HOME yok ya da boş, desteklenmeyen OS) path null, reason sebebi adlar. Exit: 0 çözüldü · 1 çözülemedi · 3 parametre verildi.

mcp api --surface sandbox — agent-runtime kurulumu ve tazeliği (AIT-897)

Ajan MCP API'yi agent-runtime sandbox'ı (run-job) üzerinden görür; --surface mcp,sandbox ile MCP girişleri de korunur (aşağıda § Birleşik küme). Kalıcı tüketici kurulumu ve yeni yayına geçiş bu komuttur; her koşu kurar ve tazeler. Karar kaydı: decision/design/agent-runtime-image-acquisition. Ön koşul: Docker ve makine başına bir kez Harbor robot login'i (client/agent-runtime/SETUP.md § A.2).

profile-sync mcp api --surface sandbox --target-dir <hedef> --api-base https://<gateway>/api --agent-pat ts_pat_v1_...
bash .agent-runtime/run-job.sh <mutlak-iş-klasörü>     # <hedef> kökünden; iş sözleşmesi .agent-runtime/USAGE.md

Sıra (bir adım düşerse sonrakiler koşmaz):

  1. Ön doğrulama: token dosyalarının ignore kapısı (yukarıda), sonra mevcut MCP dosyaları ve .agent-runtime.json Docker'dan ÖNCE okunur. Biri geçersiz JSON ise exit 1; ne imaj çekilir ne kit yazılır.
  2. İmaj edinimi + tazelik: imaj env AGENT_RUNTIME_IMAGE'den, yoksa Harbor prod :latest. docker pull registry digest'ini yereldekiyle karşılaştırır: aynıysa katman indirmez, farklıysa çeker. Çıktı satırı durumu (edinildi, guncel, guncellendi (onceki <digest>), dogrulanamadi) ve tazelik kontrolu N ms süresini basar.
  3. Kit aynı digest'ten {target-dir}/.agent-runtime/'a (runtime-kit ile aynı yazıcı: ignore kapısı, yer değiştirme, render-state manifest dahil — aşağıda).
  4. MCP dosyaları: yalnız sandbox kümesinde file editör MCP dosyalarından agent-ops/knowledge-base kaldırılır; mcp,sandbox kümesinde yazılır. Diğer girişler (conductor-lane dahil) korunur.
  5. Kimlik + pin en son: .agent-runtime.json = servers + kök "image": "<repo>@sha256:<digest>". Pin her zaman yerindeki kitin digest'idir; run-job bu pin'i koşar (.agent-runtime/USAGE.md Ayarlar).
  • --editors claude-desktop sandbox içeren her kümede (mcp,sandbox dahil) exit 3 (global config, hedef dizin yok); MCP hedefi olmayan editör de exit 3.
  • --dry-run hedefe yazmaz; docker pull yine koşar (dosya değil Docker deposu değişir).
  • Registry digest'i olmayan imaj (yerel build, AGENT_RUNTIME_IMAGE=agent-runtime:dev) pin'lenemez → exit 1. Yerel imaj denemek runtime-kit --image + run-job'a AGENT_RUNTIME_IMAGE ile yapılır (aşağıda).
Durum Sonuç Çare
docker PATH'te yok / daemon kapalı exit 1, hiçbir dosya yazılmaz Docker'ı kurun / başlatın
İmaj yerelde yok ve docker pull düştü exit 1, hiçbir dosya yazılmaz; mesaj docker login <registry> ve SETUP § A.2'yi adlar Robot login (SETUP § A.2) ya da ağ
İmaj yerelde var, docker pull düştü devam, yerel imaj pin'lenir; UYARI: satırı ham daemon metnini taşır (sebep etiketlenmez: ağ, kimlik, not found aynı exit kodu) Daemon metnini okuyun; kimlikse SETUP § A.2
İmajın registry digest'i yok exit 1, hiçbir dosya yazılmaz AGENT_RUNTIME_IMAGE'i kaldırın (Harbor imajı)
Mevcut MCP dosyası / .agent-runtime.json geçersiz JSON exit 1, Docker'a dokunulmaz Dosyayı düzeltin ya da kaldırın
Kit adımı fail-closed (aşağıdaki tablo) exit 1; kit, MCP dosyaları ve kimlik yazılmaz Tablodaki çare

Tablodaki exit 1 satırları yalnız sandbox kümesi içindir. Birleşik küme (mcp,sandbox): imaj edinimi ya da kit adımı düşerse koşu yalnız MCP ile tamamlanır ve UYARI: sandbox kurulamadi satırı sebebi taşır (exit 0); önceki kit ve pin (varsa) yerinde kalır — sandbox kümede olduğu için izi silinmez. Ön doğrulama (geçersiz JSON, ignore kapısı) birleşik kümede de exit 1'dir.

Geçiş — prepare'in eski MCP girdileri (deprecate, bir sürüm)

Bu sürümde prepare (ve interaktif wizard) eski girdileri bugünkü gibi uygular ama her koşuda stderr'e [DEPRECATED] satırı basar. Sonraki sürüm bunları kaldırır: bayraklar exit 3, env set ise yalnız uyarı. Kaldırma sürümü conductor tarafı (AIT-847) canlıya çıktıktan sonra yayınlanır.

Eski girdi Yerine
prepare --no-mcp bayrağı bırakın (prepare MCP yazmayacak)
prepare --agent-pat / env PROFILE_SYNC_AGENT_PAT profile-sync mcp api (aynı env'i okur)
env PROFILE_SYNC_CONDUCTOR_MCP_URL profile-sync mcp conductor --editors claude-desktop --conductor-url <url> (rol koordinatör PAT'inden: --conductor-pat / env PROFILE_SYNC_CONDUCTOR_PAT; PAT yoksa --actor-role <slug>)
env PROFILE_SYNC_CONDUCTOR_LANE_MCP_URL profile-sync mcp conductor --lane-url <url>

Eski yol da yeni yazıcılardan geçer: birleşik yazım, X-Actor-Role yok, conductor girişinde X-Conductor-Role (snapshot'taki rolün actorRole'u). Agent-PAT yoksa eskisi gibi hiçbir MCP girişi yazılmaz.

Selector semantiği — filtre eklemek daraltır

--work-type / --scope / --stack opsiyoneldir ve vermemek en geniş sonucu verir. Filtresiz sorgu rolün tam kataloğunu getirir; bir eksen doldurmak sonucu daraltır, asla genişletmez. Governance rolünde ölçülen:

komut skill
--role governance 12 (5 tool-call/reaktif taban + 7 mod skill'i)
+ --work-type review 10
+ --work-type review --scope backend 7
+ --work-type closure 6

Ne zaman ne verilir: kendi çalışma dizinini senkronluyorsan (rol başına bir kez) filtre verme — tüm modların skill'leri diskte dursun, hangisinin yükleneceğine runtime tetikleyicisi karar versin. Faz başına dispatch yapıyorsan (conductor) fazın tuple'ını olduğu gibi geçir — dar küme orada istenen şeydir.

Instruction shard'ları bu daralmadan etkilenmez: rol grubunun tamamı her sorguda yazılır, yalnız --stack ek shard grubu getirir. Daralma yalnızca skill kümesindedir. Mekanizma: ladder aday seçer, catalog-loader flatten'ı satırın içeriğini materyalize eder (az-spesifik satır alt ağacının skill'lerini absorbe eder). Kanonik kural: KB agent-ops.design.narrowing-surface-must-not-widen; tasarım gerekçesi decision/design/catalog-role-axis-and-resolve-model § addendum-subtree-union-materialization.

Wizard sırası (data-driven)

modelTier (Faz 1: frontier) → role → workType? → scope|stack? → hedef dizin (boş = CWD) → editör hedefleri (multiselect: cursor / claude-code / trae / codex / claude-desktop). Seçenekler snapshot.Profiles'tan türetilir (var olmayan tuple sunulmaz). T#690: claude-desktop artık editör listesinde (ayrı toggle yok); seçilirse global config + <hedef>/.claude-desktop prompt dizini.

Env / flag Açıklama
PROFILE_SYNC_API_BASE Gateway API kökü (örn. https://host/api). Yoksa prompt.
PROFILE_SYNC_PAT PAT (ts_pat_v1_...). Opsiyonel — primary.
PROFILE_SYNC_SESSION Session id (GUID). Opsiyonel — PAT yoksa fallback.
--dry-run Yazma yok, sadece plan + sayım.
--no-prune Stale silmeyi kapatır. Default: prune AÇIK — yönetilen dizinlerde (rules/skills) bu koşuda üretilmeyen dosyalar silinir (--prune geriye-uyum no-op). Detay: Stale prune.
--help Kullanım.

Auth çözümü: env'de PAT varsa Bearer; yoksa session varsa x-session-id; ikisi de yoksa prompt (yöntem + değer).

Stale prune (T#748)

prepare hedef dizine güncel dosyaları yazar; ancak Catalog'dan silinen/yeniden adlandırılan shard/skill'lerin eski kopyaları hedef dizinde kalırdı ve bu birikinti çelişkili talimat riski yaratıyordu (örn. 00-discipline.md → 00-task-discipline.md rename'inde ikisi de .claude/rules'ta kalırdı). Prune bunu çözer ve default açıktır (T#761 O1 — rapor-only dönem stale dosyanın aylarca kalabildiğini gösterdi):

  • Kapsam: yalnız bu koşuda emit edilen (aktif --editors) file-editörlerin yönetilen alt-dizinleri — MDC rules dizini (.claude/rules, .cursor/rules, .trae/rules) + skills dizinleri (.../skills). --editors ile seçilmeyen editörün dizini dokunulmaz. Monolithic instruction dosyaları (CLAUDE.md, AGENTS.md) kapsam dışı (her koşu overwrite, birikme yok).
  • Tespit: bu koşuda yazılan/atlanan (idempotent skip dahil) dosya kümesi dışında kalan her dosya = stale.
  • Güvenlik: rapor her zaman; silme default (kapatma --no-prune); --dry-run ile silme simüle edilir; prune tüm emit başarıyla bittikten sonra çalışır (yarım koşuda geçerli dosya silinmez).

Not: .claude/rules ve .claude/skills tümüyle sync-owned kabul edilir — bu dizinlere elle dosya eklemeyin; prune onları stale sayıp siler. claude-desktop (global config + prompt dizini) ve local-compose kapsam dışı.

Render-state manifest + verify (T#761)

Her prepare koşusu hedef dizine .sync-ai-configs/render-state.json yazar: selector (role/work-type/scope/stack/model-tier), editor seti ve yönetilen dizinlere yazılan dosyaların hash'leri (text hash TrimEnd-normalize; MCP config'ler ve claude-desktop global dosyaları kapsam dışı — PAT gömülü/koşudan koşuya değişken içerik manifest'e girmez).

profile-sync verify [--target-dir <path>] [--no-remote] üç yönlü staleness kıyası yapar; selector/editor seti flag değil, manifest'ten okunur:

Eksen Bulgu türleri
manifest ↔ disk missing (silinmiş), modified (elle değişmiş), orphan (yönetilen dizinde manifest-dışı dosya)
manifest editor seti ↔ disk unmanaged-editor-dir (seçilmemiş bilinen-editör dizini duruyor — hiçbir koşu yönetmiyor)
manifest ↔ güncel snapshot content-stale (Catalog'daki içerik değişmiş; re-render kıyası, --no-remote ile atlanır)

Manifest agent-runtime kiti taşıyorsa (mcp api --surface sandbox ya da runtime-kit yazar, aşağıda) kit dosyaları manifest ↔ disk eksenine girer (missing / modified; kit klasöründe manifest-dışı dosya orphan). Yalnız kit taşıyan manifest'te (hedefte prepare koşmamış) editor ve snapshot eksenleri koşmaz, auth istenmez. Kit bulgusunun çaresi kiti yazan komutu yeniden koşmaktır (tüketici kurulumunda mcp api --surface sandbox).

Auth yalnız snapshot kıyası için gerekir (--api-base/--pat/--session-id veya env; prepare ile aynı). Exit: 0 temiz · 2 drift bulundu · 1 catalog/ağ hatası · 3 kullanım/manifest hatası — CI/drift-check/conductor pre-dispatch entegrasyonu exit code üzerinden.

Türev token'lar ve fail-closed koruma (AIT-775 F2)

Shard gövdeleri {{token}} taşıyabilir; tool bunları emit anında çözer. İki kaynak var: consumer-boyutu ({{projectRoot}}, {{projectName}}) ve snapshot'tan üretilen türev ({{roleModeSkillTable}} → skill haritası mod tablosu, SkillMapRenderer; AIT-766 F3).

Catalog içeriği tool'dan hızlı değişir: içerik yeni bir türev token'a geçtiğinde eski tool onu tanımaz. Eski davranış ham {{...}} metnini diske yazmaktı — ajan talimatında anlamsız bir token kalır, kayma sessiz olurdu. Artık emit durur:

HATA (render): code=render.placeholder.unresolved :: Cozulmemis turev token: {{roleToolSkillTable}}
(kaynak: 30-skill-haritasi). Arac surumu icerigin gerisinde — ... Cozum: dotnet tool update --global AiTools.ProfileSyncTool.

Hiçbir dosya yazılmaz (render emit'ten önce koşar); exit 1. Çözüm tool'u güncellemektir.

  • Token şekli: {{ad}}, ad = [A-Za-z_][A-Za-z0-9_]*. Boşluklu/noktalı şablon sözdizimi ({{ item.name }}) ve tek süslü parantez token sayılmaz.
  • Kaçış (yanlış pozitif): gerçekten literal {{...}} yazan prose (örn. Postman {{base_url}} örnekleri) için shard gövdesinde \{{base_url}} yazın — çıktıya {{base_url}} düşer, koruma tetiklenmez.
  • Ayrılmış önek (derived:) bilinçli seçilmedi: önek'siz yazılan yeni bir token korumanın dışında kalır, yani kapatılmak istenen delik aynen geri açılırdı.

agent-runtime kiti: runtime-kit (AIT-869)

agent-runtime ile iş koşan hedef ai-tools checkout'una ihtiyaç duymaz: tüketici kiti (run-job betiği, ajan kılavuzu, metot referansı) runtime imajıyla aynı yayında gelir ve yerel imajdan hedefe kopyalanır. Katalog çağırmaz, PAT istemez. Karar kaydı: decision/design/agent-runtime-consumer-kit (P1).

Kurulum yolu runtime-kit DEĞİL. Kalıcı tüketici kurulumu ve yeni yayına geçiş mcp api --surface sandbox'tır (yukarıda, MCP bağlantısı bölümünde): kiti bu bölümdeki yazıcıyla, edindiği imajın digest'inden çıkarır ve pin'i yazar. runtime-kit yalnız imaj geliştirme/test içindir (yerel build'i --image ile denemek). İmajı sabitlemez: .agent-runtime.json'a dokunmaz, digest yazmaz; run-job imajı AGENT_RUNTIME_IMAGE > kimlikteki pin > :latest sırasıyla seçer ve kit o imajdan gelmeyebilir. Komut her başarılı koşuda bunu bir UYARI: satırıyla söyler.

bash client/agent-runtime/scripts/build-image.sh                    # yerel imaj: agent-runtime:dev (SETUP § E.2)
profile-sync runtime-kit --target-dir <hedef> --image agent-runtime:dev
AGENT_RUNTIME_IMAGE=agent-runtime:dev bash .agent-runtime/run-job.sh <mutlak-iş-klasörü>   # pin'i ezer, aynı imaj
Flag Açıklama
--target-dir <path> Opsiyonel; yoksa CWD. Dizin yoksa exit 1.
--image <ref> Opsiyonel; yoksa env AGENT_RUNTIME_IMAGE (run-job'un imaj seçtiği değişkenin aynısı), o da yoksa registry.red-wood.cloud/ai-redwood-prod/ai-tools-agent-runtime:latest.
--dry-run Ön koşulları ve imajdan kopyayı dener; hedefe yazmaz, kaç dosyanın yazılıp kaçının kalkacağını basar.

Ne yazar, nereye:

  • Kaynak imajdaki /agent-runtime/consumer/: docker image inspect ile imaj kimliği okunur, kopya o kimlikten docker create + docker cp ile alınır (arada etiket kaysa da kit sorgulanan imajdan gelir); container her durumda silinir.
  • Hedef <hedef>/.agent-runtime/: run-job.sh, USAGE.md, reference/<sunucu>.json.
  • Kimlik dosyası <hedef>/.agent-runtime.json kit klasörünün kardeşidir ve mcp api'nin işidir (pin'i yalnız --surface sandbox yazar); runtime-kit ona dokunmaz. Kitteki run-job varsayılan kimliği bu yerleşimden bulur (betiğin bir üst dizini); başka bir yerleşimde kök tahmin edilmez, AGENT_RUNTIME_CONFIG=<yol> istenir.
  • Kit klasörü tümüyle kite aittir: yeni kopya kardeş dizinde kurulup eskisiyle yer değiştirir; önceki kitten kalıp yenisinde olmayan dosya kalkar (STALE kaldirildi satırı). Klasöre elle dosya eklemeyin.
  • Linux/macOS/WSL hedefinde *.sh dosyalarına çalıştırma biti verilir; Windows'ta (NTFS) çağrı her zaman bash .agent-runtime/run-job.sh ... biçimindedir.
  • Kit .sync-ai-configs/render-state.json'a runtimeKit bölümü olarak girer (imaj, imaj kimliği, dosya hash'leri); prepare bu bölümü korur, runtime-kit profil alanlarını korur. verify kiti tanır (bkz. Render-state manifest + verify).

Fail-closed: aşağıdakilerden biri olursa hedefe hiçbir dosya yazılmaz, önceki kit yerinde kalır, exit 1 ve mesaj eksik ön koşulu adlar. Aynı kapılar mcp api --surface sandbox'ın kit adımında da geçerlidir:

Durum Çare
Hedef dizin yok Dizini oluşturun ya da --target-dir'i düzeltin
docker PATH'te yok / daemon kapalı Docker'ı kurun / başlatın
İmaj yerelde yok runtime-kit: imajı build edin ya da docker pull <imaj> (araç imaj çekmez). Sandbox kurulumu imajı kendisi edinir.
İmaj kiti taşımıyor (eski yayın) ya da kopyada run-job.sh yok Kiti taşıyan imajı çekin ya da --image ile verin
Hedef bir git ağacı ve kit dosyaları ignore edilmiyor Mesajdaki satırı hedef ağacın .gitignore'una ekleyin: /<kit'in ağaç köküne göre yolu>/ — hedef ağacın kökü ise /.agent-runtime/, alt dizini ise /<alt>/.agent-runtime/. .gitignore'a dokunulmaz.
Render-state manifest okunamıyor Manifest dosyasını düzeltin ya da kaldırın
Kit yerleştirilemedi (yeni kopya eskisiyle yer değiştirirken dosya hatası, ör. kilitli dosya) Kilidi bırakan süreci kapatıp yeniden koşun; önceki kit geri konmuştur

Ignore koşulunun gerekçesi: kit token taşımaz ama imajdan üretilmiş bir kopyadır; commit'e girerse imajla ayrı yaşayan ikinci bir kaynak olur.

Exit: 0 ok · 1 ön koşul eksik / imaj kiti taşımıyor / kit ignore edilmiyor / manifest okunamadı / kit yerleştirilemedi · 3 kullanım.

Güncelleme: tüketici yeni yayına mcp api --surface sandbox'ı yeniden koşarak geçer (imaj, kit ve pin birlikte yenilenir). runtime-kit ile yazılmış bir kit yerel imaj değişince eskir; verify kitin diskte bozulmasını görür, yerel imajın değişmesini görmez.

Claude Desktop hedefi

File-tabanlı editörlerden (cursor/claude-code/…) ayrıdır: Claude Desktop instruction .md'lerini bir klasörden otomatik okumaz. İki çıktısı iki ayrı komuttan gelir:

  1. Prompt dizini (prepare --editors claude-desktop) → <hedef>/.claude-desktop altına {role}-instruction.md + skills/<name>.zip (manuel yükleme için).
  2. Global MCP config (mcp api / mcp conductor --editors claude-desktop) → %APPDATA%/Claude/claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/…, Linux: ~/.config/Claude/…). Mevcut server'lar ve diğer key'ler korunur (merge), yazmadan önce .bak.1..3 yedeği alınır.

Neden stdio-bridge (streamable-HTTP değil)?

Claude Desktop config şeması yalnızca stdio doğrular; gateway'in streamable-HTTP URL'ini doğrudan yazarsan sessizce düşürür. Bu yüzden MCP, npx mcp-remote ile sarmalanır. Remote Custom Connector (Settings → Connectors) bir alternatiftir ama (a) dosyaya yazılamaz, UI'dan eklenir, (b) Anthropic cloud'undan bağlanır → private gateway'e erişemez. Bu yüzden tool dosya-emit edilebilen stdio-bridge'i kullanır.

Auth: env-ref + env bloğu

Auth değeri args'a inline gömülmez; Authorization:${PROFILE_SYNC_MCP_AUTH} referansı + server'ın env bloğunda değer yazılır. mcp-remote ${VAR}'ı process env'den çözer (canlı doğrulandı — log: "Replacing $ with environment value"). Değer env bloğundan gelir; Claude Desktop bu bloğu spawn ettiği child process'e geçirir.

Not (canlı e2e dersi): OS environment variable yolu (config'e değer yazmadan setx ile) Claude Desktop'ta çalışmaz — Desktop, setx'lenen OS env'i full re-login olmadan child'a geçirmiyor. Bu yüzden değer env bloğunda taşınır. Rotation = env alanını düzenle veya tool'u yeniden çalıştır.

Kullanım

claude-desktop artık editör listesinden seçilir (T#690 — ayrı toggle yok); prompt dizini sabit: <hedef>/.claude-desktop.

# Prompt dizini:
profile-sync prepare --role <r> --editors claude-desktop --api-base ... --pat ...
# Global MCP config — ÖNCE --dry-run ile merge önizlemesini gör (global config'e dokunmaz):
profile-sync mcp api --editors claude-desktop --api-base ... --agent-pat ... --dry-run
profile-sync mcp api --editors claude-desktop --api-base ... --agent-pat ...

İki ayrı cred karıştırılmaz: prepare'in --api-base + --pat'i catalog fetch cred'idir; mcp api'nin --agent-pat'i (veya env PROFILE_SYNC_AGENT_PAT) MCP runtime cred'idir.

Sonra Claude Desktop'ı yeniden başlat → agent-ops + knowledge-base server'ları MCP listesinde görünür. conductor yalnız mcp conductor --conductor-url ile görünür (aşağıda). Prompt dizinindeki {role}-instruction.md'yi bir Claude Desktop Project'ine elle ekleyebilirsin.

Emekli skill raporu (AIT-775 F2)

Claude Desktop skill'i diskteki dosyadan değil, hesaba elle yüklenen zip'ten çalışır. Bir skill profilden düştüğünde tool hesaba erişemez — yapabildiği tek şey adını söylemektir:

  Emekli skill: 1 ad onceki kosuda vardi, bu kosuda uretilmedi — Claude Desktop hesabindan ELLE kaldirin:
    EMEKLI closure-flow
  • Karşılaştırma kaynağı .sync-ai-configs/desktop-skill-state.json (bu koşunun skill kümesi + emekli listesi). Manifest yoksa (bu sürümden önceki koşu) .claude-desktop/skills/*.zip taraması fallback'tir.
  • Rapor tek seferliktir: bir sonraki koşunun "önceki"si bu koşunun kümesidir. Ad kaybolmasın diye manifest'e de yazılır.
  • Diskteki eski .zip silinmez — claude-desktop prune kapsam dışı (debt profile-sync-prune-desktop-localcompose-coverage). Rapor tam da bu yüzden gerekli.

Conductor girişi (mcp conductor --conductor-url; AIT-736 F6, AIT-846)

Koordinatör oturumunun tur araçları (dispatch_turn, read_turn_birth, accept_turn, read_accept_gate, list_turns, close_turn, read_turn_events, revive_turn) conductor'ın MCP ucundan gelir. Giriş koordinatörün kullandığı her MCP editörüne yazılır — mod editör tipiyle değil parametreyle belirlenir (araca localhost:5100 gömülü değildir):

# Koordinatör PAT'i ({proje}:conductor:coordinate; AIT-980): --conductor-pat > env PROFILE_SYNC_CONDUCTOR_PAT
# Claude Code koordinatörü: {target-dir}/.mcp.json (cursor -> .cursor/mcp.json, trae -> .trae/mcp.json)
profile-sync mcp conductor --editors claude-code --conductor-url http://localhost:5100/mcp --conductor-pat <koordinatör PAT'i> --target-dir <koordinatör repo>
# Claude Desktop koordinatörü: global config (stdio-bridge, .bak.1..3 yedekli); PAT env'den de verilebilir
export PROFILE_SYNC_CONDUCTOR_PAT=<koordinatör PAT'i>
profile-sync mcp conductor --editors claude-desktop --conductor-url http://localhost:5100/mcp

PAT'li girişte file editörde type: http, verilen URL, başlıklar yalnız Authorization: Bearer <PAT> + X-Client; Claude Desktop'ta X-Client mcp-remote argümanıdır, kimlik Authorization:${PROFILE_SYNC_MCP_AUTH} referansı + env bloğundadır (token argv'de yok; API girişleriyle aynı biçim). Rol başlığı yazılmaz.

  • Kimlik (AIT-1000, AIT-980 kararı A1; AIT-1006): koordinatör PAT'i --conductor-pat bayrağından, bayrak yoksa env PROFILE_SYNC_CONDUCTOR_PAT'ten okunur (mcp api --agent-pat ile aynı kural; bayrak verilince env okunmaz). Bayrak yalnız koordinatör modunda geçerlidir: --lane-url ile verilirse exit 3. Bayrakla verilen token kabuk geçmişinde ve süreç listesinde görünür; paylaşılan makinede env yolunu kullanın. Koordinatör PAT'i agent PAT'inden (PROFILE_SYNC_AGENT_PAT) ayrıdır. Token taşıyan file editör dosyası git ağacındaysa ignore edilmiş olmalı (mcp api ile aynı sızıntı koruması; değilse hiçbir dosya yazılmaz, exit 1).
  • Rol (AIT-1011): PAT verilmişse rolün tek kaynağı PAT'tir ve conductor onu PAT'ten kendisi okur (AIT-980 F13); araç rol okumaz, gateway'e gitmez, X-Conductor-Role yazmaz. Bu yüzden PAT'le birlikte --actor-role verilemez (exit 3, hiçbir dosya yazılmaz). Önceki sürümün yazdığı rol başlığı, giriş yeni değere eşitlendiği için bir sonraki PAT'li koşuda kalkar. PAT yoksa --actor-role zorunlu, rol X-Conductor-Role başlığına yazılır, giriş auth'suz yazılır ve UYARI basılır: conductor kimlik zorlaması açıldığında bu giriş reddedilir.
  • Sıralama: rol başlığı olmayan PAT'li girişle rolü bulabilmek için conductor rolü PAT'ten okuyan sürümde (0.1.11+, AIT-980 F13) olmalı; eski conductor başlıksız isteği reddeder. Koordinatör modu yalnız seçili editörlere yazar. Şerit worktree'sinde koordinatör modu koşmayın: conductor girişi şerit ajanına tur yüzeyi açar; şerit hazırlığının --conductor-url geçmemesi conductor'ın sorumluluğudur (AIT-847). Hiçbir koşu girişi silmez; temizlik elle.
  • Eski yol (deprecate): env PROFILE_SYNC_CONDUCTOR_MCP_URL + prepare --editors claude-desktop bu sürümde hâlâ çalışır; değişken profile-sync'i fiilen koşan sürecin ortamında olmalıydı ve agent-PAT'e bağlıydı.

Sıralı kurulum (yeni makine): client/conductor/COORDINATOR-RUNBOOK.md §7.

Şerit conductor-lane girişi (mcp conductor --lane-url; AIT-816, AIT-846)

Dispatch edilen şerit ajanının kanıt-işi araçları (request_build, read_build_result) conductor'ın şerit ucundan (/mcp/lane/{project}/{slot}) gelir. --lane-url seçili file editör MCP config'lerine (.mcp.json vb.) conductor-lane girişi (type: http, verilen URL) yazar:

profile-sync mcp conductor --lane-url http://localhost:5100/mcp/lane/ai-tools/backend --target-dir <şerit worktree>
  • Rota şeridin kendisini taşır; araç URL'i olduğu gibi yazar, kurmaz.
  • Giriş kimlik taşır ama zorlamaz: şerit PAT'i --lane-pat > env PROFILE_SYNC_LANE_PAT verilirse girişe yalnız Authorization: Bearer başlığı yazılır (dosya git'te ignore edilmiş olmalı, değilse hiçbir dosya yazılmaz, exit 1); verilmezse giriş başlıksızdır ve önceki başlık kalkar. Şerit modu koordinatörün girdilerini okumaz: PROFILE_SYNC_CONDUCTOR_PAT tanımlı olsa da şerit girişine yazılmaz, --conductor-pat şerit modunda kullanım hatasıdır (exit 3). Şerit modu Claude Desktop config'ine ve conductor girişine dokunmaz.
  • Eski yol (deprecate): env PROFILE_SYNC_CONDUCTOR_LANE_MCP_URL + prepare bu sürümde hâlâ çalışır (agent-PAT'e bağlı). Env'in sorunu: bu değişkeni tanımayan eski araç (1.6 öncesi) onu sessizce yok sayar; bayrak ise eski araçta exit 3 ile yüksek sesle düşer.

Uyarı (auth): Global config auth'u env bloğunda gömülü taşır — bu dosyayı paylaşma. Operatör session-id ile auth olduysa MCP runtime'a session gömülür ve expire olunca bağlantı kopar → kalıcı kullanım için PAT önerilir (role-scoped PAT-store: T#684). Config global olduğu için server adları sabittir (agent-ops/knowledge-base); rol girişte değil PAT'in actor: scope'undadır.

local-compose hedefi (T#718 Faz 3)

File-tabanlı editörlerden ve claude-desktop'tan ayrı üçüncü şekil: ambient instruction dosyaları yerine composer-tüketilebilir tek yapısal manifest üretir. Local model prompt kompozisyonu içindir — conductor LocalPromptComposerService bu manifesti okuyup faz-scope'lu prompt'a gömer (ambient CLAUDE.md local tier'da RED; ADR local-frontier-task-boundary §8).

# Headless (conductor'ın çağırdığı şekil; model-tier local zorunlu değil ama beklenen kullanım):
profile-sync prepare --role governance --model-tier local --editors local-compose --target-dir <dir> --api-base ... --pat ...

Çıktı: {targetDir}/.local-compose/context.json — şema (schemaVersion: 1):

{
  "schemaVersion": 1,
  "role": "governance",
  "instruction": "<çözülen profilin monolithic instruction blob'u>",
  "skills": [
    {
      "name": "task-flow-local",
      "description": "...",
      "body": "<SKILL.md gövdesi>",
      "references": [ { "path": "references/x.md", "body": "..." } ]
    }
  ]
}

Sorumluluk sınırı: emitter TÜM çözülen içeriği yazar (audience-filtreli — local profil = local skill seti); faz-scope seçim composer'a aittir (conductor PromptComposer, Whole|PhaseScoped). Probe-gate kararı (record/evidence/t718-p5-composition-gate): frontier gövdesi ÇEKİLMEZ, LLM-distilasyon motoru YOK. docker-unaware: targetDir conductor DataDir cache'i olabilir; pattern-job sandbox'ına mount edilmez. Manifest dosya sözleşmesi tek bağdır — conductor bu paketi kod olarak referans etmez (process + dosya).

Kapsam

frontier + local · çoklu editör (cursor/claude-code/trae/codex/claude-desktop/local-compose) + headless prepare (T#688) · skills dağıtımı (.../skills/<name>/SKILL.md+refs) · mcp config ayrı alt komutta (mcp api / mcp conductor, AIT-846; gateway base'den türetilir, agent-PAT gömülü — commit etmeyin) · Claude Desktop (stdio-bridge global MCP + prompt dizini, Mod A/B auth) · agent-runtime sandbox kurulumu (mcp api --surface sandbox, AIT-897: imaj edinimi + tazelik + kit + digest pin'i) · agent-runtime kiti imaj geliştirme/test için (runtime-kit, AIT-869; yerel imajdan, katalog çağırmaz, pin yazmaz) · hedef dizin opsiyonel (CWD). project-context: yok (drop kararı; catalog shard'ları proje-agnostik). cowork: ertelendi (gerekirse ayrı faz). Faz 3: sync-ai-configs retire + server klasör modeli kaldırma.

Test

dotnet test profile-sync-tool.slnx
# Canlı parity (opt-in): PROFILE_SYNC_API_BASE + PROFILE_SYNC_PAT set edilirse
# client resolve == server /profiles/resolve tüm profillerde doğrulanır.
# publish: gerçek agent-config/ korpusu (frontmatter taraması, flatten envanteri) + catalog-loader parity'si
# (PublishLoaderParityTests: node >= 18 gerekir; loader silinince test de silinir).

AIT-1257: 'mcp api --conductor-sandbox': her kumede docker cagrilmaz; .agent-runtime/ kiti, image pin'i ve .agent-runtime.json yazilmaz, onceki kit, manifest kaydi ve kimlik dosyasindaki kendi anahtarlar kalkar (kalan yoksa dosya silinir). Bayraksiz cikti degismedi. 'mcp conductor --lane-url' serit girisi istege bagli PAT tasir: --lane-pat > env PROFILE_SYNC_LANE_PAT; verilirse yalniz Authorization basligi, verilmezse giris basliksiz. Serit modu koordinator PAT girdilerini (--conductor-pat exit 3, env PROFILE_SYNC_CONDUCTOR_PAT) okumaz; koordinator modu PROFILE_SYNC_LANE_PAT'i okumaz.

This package has no dependencies.

Version Downloads Last updated
1.21.0.145 2 11/10/2026
1.20.0.2228 2 11/09/2026
1.19.0.1710 2 11/08/2026
1.18.0.1357 1 11/08/2026
1.17.0.1153 1 11/08/2026
1.16.0.1710 2 11/07/2026
1.14.0.203 3 10/10/2026
1.13.0.2322 2 10/10/2026
1.12.0.130 2 10/09/2026
1.11.0.1617 3 10/01/2026
1.10.0.1151 1 10/01/2026
1.9.0.1700 3 09/26/2026
1.8.0.2253 4 09/24/2026
1.7.0.2214 3 09/24/2026
1.6.0.107 4 09/18/2026
1.5.0.1852 4 09/12/2026
1.4.0.2344 5 09/03/2026
1.3.0.2139 12 07/16/2026
1.1.0.57 6 07/06/2026
1.0.0.327 7 07/03/2026