Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TEST-SCENARIOS.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ geçerliliğini yitiren senaryo **silinmez**, `deprecated` işaretlenip sebebi y
| **soap-task-test** | `SoapTask` tipi · SOAP mapping (`SendVipSmsMapping.csx`) · başarı/hata rule'ları ile dallanma | SOAP task tipini uçtan uca doğrulamak <sup>1</sup> (2026-08-13) | — (yalnız `.http`) | — | ⚠️ Integration test yok — kapsam açığı |
| **l1-cache-lab** | Component cache versiyon çözümü: `latest` + artifact/major range (`"1"`) referansları · generation-anahtarlı L1 (in-process) cache'in publish görünürlüğü · pinned instance `flowVersion` kararlılığı · publish-only aktivasyon (re-initialize'sız) · view/task referanslarının sıcak cache'de anında yeni versiyona dönmesi | Runtime'a eklenen L1 component cache'in (vnext `feature/component-cache-l1`, 2026-08-20) "versiyon cache'de kaldı" riskini uçtan uca çürütmek; CD sözleşmesinin (publish bitince yeni sürüm MUTLAKA geçerli) regresyon bekçisi | — (bilinçli: publish-akışı doğruluk senaryosu; api-test yeterli) | `api-tests/l1-cache-lab/l1-cache-behaviour-test.py` (`--minor N` ile tekrar koşulabilir) | ✅ Aktif — 18/18 (2026-08-20, lokal L1 runtime) |
| **authorization-chain-lab** | `authorize` fonksiyonunun **aktif korelasyon zinciri** boyunca verdiği cevap: poll edilen instance'ın kendi `queryRoles`'u **VE** altındaki her seviye (en derin leaf'e kadar) — konjonksiyon · parent subflow override'larının **hop başına** ve **çocuğa damgalanmış** haritadan çözülmesi (A'nın B override'ı C'ye taşınmaz; B'nin C override'ı C'de uygulanır; override **REPLACE** eder, merge etmez) · doğrudan adreslenen leaf'in, parent üzerinden erişilen leaf ile **aynı** verdikti vermesi · `authorize`'ın dördüncü hedefi **`ack`** (long-poll acknowledge ön-kontrolü; `IsAwaitingLongPollAck` ile iner, bekleyen yoksa **allowed**) · aktif subflow varken `cancel`/`exit`/`updateData`/state'te müsait shared transition'ın **parent'ta** cevaplanması (execution ile aynı) · `data`'nın içeriğinin inmemesi ama yetkilendirmesinin inmesi · runtime'ın kendi `queryRoles` ve ack **kapılarının kaldırılmış olması** (on yüzeyin hiçbiri 403 dönmüyor ve hiçbiri kapıya sormuyor), buna karşılık `authorize`'ın **reddetmeyi sürdürmesi** — o, gateway'in danıştığı kâhin, runtime'ın yolundaki bir kapı değil — ve rol **çözümlemesinin** (availableTransitions filtresi, state alias, `x-roles` budama, human-task listesi, `CallerScopeHash`) aynen sürmesi | Council `2026-09-22-remove-execution-authorization`: `authorize` üç canlı kusur taşıyordu ve üçü de aynı sonuca çıkıyordu — **ara katmanın danıştığı cevap, runtime'ın uyguladığı kapıdan farklıydı**. (1) `?queryRoles=true` aktif subflow'a kısa devre yapıp kökün kendi grant'larını hiç değerlendirmiyordu, yani tarif ettiği kapıdan **zayıftı**; (2) parent override'ı eşleşince iniş derinlik 1'de duruyor, torunun kapısı hiç çalışmıyordu; (3) override parent'ın TANIMINDAN okunduğu için doğrudan adreslenen leaf'te hiçbir şey bulamıyor ve `authorize` ile state function aynı instance için **zıt** verdikt veriyordu. Ayrıca ara katmanın long-poll ack'i soramaması. Enforcement önce bir geçiş anahtarına alındı, sonra kullanıcı kararıyla kapılar **tamamen kaldırıldı** (2026-09-23): `queryRoles` silinmedi, yeri değişti — tam ve hop başına, `authorize?queryRoles=true` içinde değerlendirilmeye devam ediyor; silinen şey aynı kararın runtime'daki **ikinci** kopyası | `Tests/AuthorizationChainLab` (7 sınıf, 44 + 5 provider testi) + `Tests/AuthorizationChainLab/README.md` + MockLab seed `morph-idm-roles-collection.json` | — (bilinçli: doğruluk senaryosu, eşzamanlılık/gecikme iddiası yok) | ✅ **44/44 yeşil; ayrıca `morph-idm` provider'ıyla 7/7** (2026-09-23, runtime lokal build `f7a053c8` + `claude/remove-authorize-checks-cc40e5`, `VNEXT_BASE_URL=http://localhost:4201`). Suite önce geçiş anahtarına karşı yazılıp iki duruşta da koşuldu; kapılar kaldırıldıktan sonra anahtarı ölçen testler kaldırmayı ölçenlere dönüştürülüp yeniden koşuldu (ortam değişkeni kalmadı). **İlk koşuda üç runtime kusuru bulundu ve üçü de düzeltildi**: (1) `queryRoles` kapısı `EffectiveState` okuyordu — kendi subflow'u olan bir ara seviyede bu bir TORUNUN state anahtarıdır, parent'ın workflow'u onu çözemez, damgalı override eşleşemez ve kapı sessizce workflow kökünün grant'larına düşerdi (`chain.mid-only`, kök onu `chain.admin`'e daraltmışken mid'i 200 okudu); (2) state transition'ları `availableIn` üzerinden okunuyordu — bu liste onlarda boştur ve "boş = her state" kuralı `approve`'u `intake`'te de allowed gösteriyordu, yani oracle **permissive** yönde yanlıştı; (3) `interaction` bloğu state'in BEYANINA göre yayınlanıyordu, gerçekten ack beklenip beklenmediğine göre değil (`ResponseShapeVersion` v10→v11). `morph-idm` provider'ı için suite'in tamamı DEĞİL, yalnız `MorphIdmProviderTests` koşar (7 test, üçüncü bir başlatma + MockLab seed'i): konjonksiyon ve override'lar provider'dan bağımsızdır — bir rol kümesini tüketirler, nereden geldiğine karar vermezler — provider'a özgü olan hangi kümenin geldiğidir. Kanıtlanan: `role`/`x-roles` header'ı morph-idm `204` dediğinde **hayatta kalmaz** (header fallback yok), aynı şey `role` **query parametresi** için de geçerlidir (bu açık bu koşuda prob atılarak bulundu ve `ICallerRoleResolver.AllowsRoleParameterFallback` ile kapatıldı — ölçülen: `?queryRoles=true` 403 iken `?queryRoles=true&role=chain.admin` 200 dönüyordu), hiç role header'ı olmadan servisin cevabı yetki verir, 5xx boş küme değil **403** üretir, ve okuma yüzeyleri `authorize` ile **aynı** provider'dan rol çözer (kapı kalkınca 403 önermesi düştü; yerine teklif edilen transition kümesinin provider'ın cevabına göre değişmesi ölçülüyor). **Bilinen kapsam açığı:** `interaction.longPoll.rule` kolu **authorlanamıyor** — rule kolu runtime'a #936 ile girdi ama vnext-schema (kurulu 0.0.52 ve sibling 1.0.0) `required: [terminate, roles]` + `additionalProperties: false` diyor; `vnext-meta/features.json`'ın "şema roles|rule tekini zorlar" iddiası **yanlış**. Kolun kendisi `LongPollInteractionGateTests` ile unit seviyede pinli ve `authorize?ack=true` aynı gate'e delege ettiği için ara katman onu sorabiliyor |
| **subflow-override-lab** | Parent'ın SubFlow çocuğuna verdiği **long-poll ve kapsamlı view override'ları**: `overrides.states.<childState>.interaction.longPoll.fallbackTimeoutSeconds` / `.roles` (alan düzeyinde; yazılmayan alan çocuğunkini korur, `roles` bütün olarak değişir, long-poll'u olmayan state'e long-poll **eklenmez** — 20305) · state gövdesinin `interaction.fallbackTimeoutSeconds`'ı, arm edilen fallback job'u ve `authorize?ack=true`'nun **aynı** etkin değeri görmesi · arm'ın da override'lı rolleri okuması · `overrides.states.<s>.views` / `overrides.transitions.<t>.views` (çocuğun kendi kuralının seçtiği view'un referansı; state↔transition birbirine düşmez; çözülemeyen override → çocuğun view'u, 20101) · çözümün **çocuk tarafında** ve kendi `CurrentState`'inde olması: doğrudan adreslenen çocukta da geçerli, **tek hop** (P'nin override'ı torunu etkilemez) · eski `overrides.views` haritasının parent-taraflı davranışının sürmesi | Runtime `feature/subflow-override-interaction-views` (spec 2026-09-23): pencere çocuğun pipeline'ında (order 75) tüketiliyor ve parent'ın onu ayarlamasının yolu yoktu; düz view-key haritası bir view'u her yerde birden değiştiriyordu. `authorization-chain-lab`'i genişletmek o suite'in ack sözleşmesini (leaf `roles=[chain.admin]`) değiştirirdi | `Tests/SubflowOverrideLab` (2 sınıf, 12 test) + `Tests/SubflowOverrideLab/README.md` | — (bilinçli: doğruluk senaryosu) | ✅ **12/12** (2026-09-23, iki koşu, runtime lokal build `feature/subflow-override-interaction-views` @ `e7cb023c`, `VNEXT_BASE_URL=http://localhost:4201`); komşular aynı runtime'da AuthorizationChainLab 44/44, SubflowOrchestration 22/22, TimeoutLab 3/3. Pencere davranışsal ölçülüyor: işlenen job `ModifiedAt−CreatedAt` = 120.2 s (override 120, çocuk 600) ve 5.1 s (override 5). O koşuda long-poll ack `InstanceJobs.ExecuteAt` NULL'dı; runtime `5f60ab4b` ile artık yazılıyor (postgres: düzeltme öncesi 22 satırda 0, sonrası 10/10; `ExecuteAt−CreatedAt` = 600/120/5 s, suite yeniden 12/12). Okuma yüzeyi olmadığı ve suite'in DB erişimi olmadığı için test davranışsal kalır. **Bilinen kapsam açığı:** kurulu vnext-schema 0.0.52 yeni override alanlarını tanımıyor — beş parent akışı `npm run validate`'ten düşer; SDK doğrudan publish ettiği için test engeli değil, şema değişikliği yayınlanmadı. Lab'ın SubFlow mapping'i rol header'larını çocuğa iletir: arm yalnız tetikleyen çağıran etkin rolleri karşılıyorsa durur ve `SubflowStarter` yalnız mapping'in döndürdüğü header'ları gönderir |
| **role-matrix-lab** | Yetkilendirme yüzeylerinin tutarlılığı: root vs state `queryRoles` (state EZER) · `transition.roles` allowlist / blacklist / predefined (`$InstanceStarter`) · `availableIn` rol daraltması (**AND**) · well-known transition'ların (`cancel`/`updateData`/`exit`) configured key + `kind` ile listelenmesi · master şemada `x-roles` alan budaması · `authorize` function'ının üç hedefi (transitionKey / functionKey / queryRoles) · custom function'da rol denetiminin **kaldırılmış** olması | Provider bazlı caller-role çözümü (`default` \| `morph-idm`) + custom function rol gate'inin kaldırılması; rol setinin KAYNAĞI değişirken grant motorunun davranışının değişmediğini pinlemek (2026-08-19, `feature/caller-role-provider`) | `Tests/RoleMatrixLab` (5 sınıf, 59 test) | — (bilinçli: doğruluk senaryosu, eşzamanlılık değil) | 🆕 Yazıldı, henüz koşulmadı |
| **secret-cache-lab** | `ScriptBase.GetSecretAsync` üzerinden in-process secret bundle cache (`ScriptSecretCache`) · bundle başına tek Vault fetch (single-flight) · cache'in request'ler arası (process-wide) yaşaması · TTL süresince bilinçli staleness · TTL dolunca canlı değere tazelenme · script task (type 7) içinden secret erişimi | Script secret fonksiyonlarının her çağrıda vault'a gitmesi yük altında vault'u darboğaza sokuyordu; `Scripting:SecretCache` (TTL 30 sn) geliştirmesinin hem kazancını hem de bayatlık sınırını uçtan uca pinlemek (vnext `claude/scriptbase-secret-cache-y86e03`, 2026-08-20) | — (bilinçli: doğrulama Vault audit log'u + saat ölçümüne dayanıyor, SDK assertion yüzeyinde yok) | `api-tests/secret-cache-lab/secret-cache-behaviour-test.py` | ✅ Aktif — 12/12 (2026-08-20, lokal runtime, TTL 30 sn) |
| **fan-out-documents** | `FanOutTask` (TaskType 21) inline mode · `itemsPath` ile koleksiyon çözümü + `ItemKey` türetimi (`id` → `key` → index) · `IFanOutMapping.ItemInputHandler` ile klonlanmış iç task'ın per-item mutasyonu (HTTP url) · `allSettled` join politikası ve `{resultKey}Summary{total,succeeded,failed,timedOut}` üzerinden auto transition dallanması (`RunAutomaticTransitionsStep`, order 90) · **tek-yazim degismezi**: N item → 1 InstanceData sürümü (`SuppressDataApply` + atılan branch context, tek yazım noktası batch'in çıktı adımı) · **`IFanOutMapping.OutputHandler` geri-düşüşü**: mapping yalnız `ItemInputHandler`'ı override eder, çıktıyı runtime'ın `BuildDefaultOutput`'u üretir · iki seviyeli bulkhead (batch-yerel `maxDegreeOfParallelism` × süreç geneli `Workflow:FanOut:MaxConcurrentItems`) · item journal anahtarları `{fanOutTaskKey}#{index}` · sonuçların `join.ordered`'dan bağımsız olarak her zaman index sıralı dönmesi | Runtime'a eklenen FanOutTask'ın (vnext `feature/fanout-task-design`, 2026-08-21) **tek-yazim degismezini** regresyona karşı sabitlemek: bastırma bozulursa fan-out tek bir aggregate üzerinde yarışan N eş zamanlı yazıcıya döner ve tasarımın var oluş sebebi kaybolur. İkincil olarak `allSettled` + özet + auto transition kısmi-başarısızlık kalıbının çalışır bir örneğini pinler (2026-08-21) | `Tests/FanOut` (`FanOutDocumentsTests`, 4 test) | `api-tests/fan-out-documents/fanout-load.py` (bulkhead tavanı + yük altında tek-yazım + straggler oranı) | ✅ 4/4 yeşil (2026-08-22, `ad72158b`) + yük testi PASS: kuyruksuz profil 6/6 (`--instances 4 --items 3 --max-dop 3`), doygun varsayılan profil 5/5 (BULKHEAD bilinçli SKIP — aşağıya bakın). `npm run validate` TaskType 21'i hâlâ reddediyor (`@burgan-tech/vnext-schema@0.0.52` enum'u `"20"`de bitiyor; şema paketi release bekliyor) — publish yolu validate'ten geçmediği için engel değil: SDK `LocalDomainPublisher` component JSON'ını doğrudan `POST /api/v1/definitions/publish`'e atıyor. Item journal assertion'ı **bilinçli olarak yok**: satırlar yalnız monitoring host'unda (4203) görünüyor, SDK stack'i onu başlatmıyor — `fanout-load.py --monitor-url` ile opt-in. **2026-08-22 düzeltmesi:** `DOC-SLOW` straggler route'u `api/fan-out/documents/process-slow` adresindeydi ve MockLab route'ları **PREFIX** ile eşlediği için `documents/process` mock'u tarafından yutuluyordu — yani gecikme hiç uygulanmıyordu ve `fanout-load.py`'nin **straggler oranı metriği jitter ölçüyordu**. Route `api/fan-out/slow-documents/process`'e taşındı, mapping güncellendi, akış 1.0.2'ye bump edildi (integration testler 4/4 yeşil kaldı). Yük testi bundan sonra ilk kez anlamlı sayı üretti ve **iki metrik hatası ortaya çıktı, ikisi de düzeltildi**: (1) `BULKHEAD` metriği doygunlukta **geçersiz** — `sum(durationMs)/wall` "uçuşta geçen süre" varsayıyor ama `FanOutTaskExecutor` item stopwatch'ini slot beklemelerinden **önce** başlattığı için `durationMs` kuyruk süresini de içeriyor (runtime bu yüzden span'e ayrıca `vnext.fanout.item.queue_wait_ms` basıyor); iddia artık yalnızca kuyruksuz profilde kuruluyor (`items <= max-dop` **ve** `instances*items <= ceiling`), aksi halde sebebiyle SKIP. (2) `STRAGGLER` eşiği (`<= 4.0`) yutulmuş route'a kalibreliydi; gerçek straggler ile oran **tasarım gereği ~10**. Eşik 15.0'a çıkarıldı ve **iki taraflı** yapıldı: yeni `STRAGGLER-VAR` tabanı **mutlak** (`en yavaş item >= 1200ms`), çünkü `max/p50` oranı presence detektörü olarak gürültülü — hiç `DOC-SLOW` yokken bile 9.44 üretti |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"key": "subflow-override-lab-child-confirm-view",
"version": "1.0.0",
"domain": "core",
"flow": "sys-views",
"flowVersion": "1.0.0",
"tags": [
"integration-test",
"subflow-override-lab",
"pseudo-ui"
],
"attributes": {
"type": 1,
"display": "full-page",
"renderer": "pseudo-ui",
"content": {
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
"view": {
"type": "Text",
"content": {
"en": "child confirm view",
"tr": "child confirm view"
},
"variant": "headlineMedium"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"key": "subflow-override-lab-child-lp-view",
"version": "1.0.0",
"domain": "core",
"flow": "sys-views",
"flowVersion": "1.0.0",
"tags": [
"integration-test",
"subflow-override-lab",
"pseudo-ui"
],
"attributes": {
"type": 1,
"display": "full-page",
"renderer": "pseudo-ui",
"content": {
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
"view": {
"type": "Text",
"content": {
"en": "child long-poll view",
"tr": "child long-poll view"
},
"variant": "headlineMedium"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"key": "subflow-override-lab-child-plain-view",
"version": "1.0.0",
"domain": "core",
"flow": "sys-views",
"flowVersion": "1.0.0",
"tags": [
"integration-test",
"subflow-override-lab",
"pseudo-ui"
],
"attributes": {
"type": 1,
"display": "full-page",
"renderer": "pseudo-ui",
"content": {
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
"view": {
"type": "Text",
"content": {
"en": "child plain view",
"tr": "child plain view"
},
"variant": "headlineMedium"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"key": "subflow-override-lab-legacy-view",
"version": "1.0.0",
"domain": "core",
"flow": "sys-views",
"flowVersion": "1.0.0",
"tags": [
"integration-test",
"subflow-override-lab",
"pseudo-ui"
],
"attributes": {
"type": 1,
"display": "full-page",
"renderer": "pseudo-ui",
"content": {
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
"view": {
"type": "Text",
"content": {
"en": "legacy parent-side override",
"tr": "legacy parent-side override"
},
"variant": "headlineMedium"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"key": "subflow-override-lab-parent-confirm-view",
"version": "1.0.0",
"domain": "core",
"flow": "sys-views",
"flowVersion": "1.0.0",
"tags": [
"integration-test",
"subflow-override-lab",
"pseudo-ui"
],
"attributes": {
"type": 1,
"display": "full-page",
"renderer": "pseudo-ui",
"content": {
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
"view": {
"type": "Text",
"content": {
"en": "parent transition-scoped override",
"tr": "parent transition-scoped override"
},
"variant": "headlineMedium"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"key": "subflow-override-lab-parent-lp-view",
"version": "1.0.0",
"domain": "core",
"flow": "sys-views",
"flowVersion": "1.0.0",
"tags": [
"integration-test",
"subflow-override-lab",
"pseudo-ui"
],
"attributes": {
"type": 1,
"display": "full-page",
"renderer": "pseudo-ui",
"content": {
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
"view": {
"type": "Text",
"content": {
"en": "parent state-scoped override",
"tr": "parent state-scoped override"
},
"variant": "headlineMedium"
}
}
}
}
Loading
Loading