---
description: "v3 canonical template for /multi-agent:analysis. 23 sections. Platform-agnostic concept layer (Pass A) projected per-platform with repo-driven naming (Pass B). Includes Lite mode for small features."
---

# Analysis Template v3 - 23 Sections

`/multi-agent:analysis` renders every output against this template. Document language follows `prefs.global.outputLanguage` (`tr` or `en`). Tables use pipe-syntax markdown; the Confluence channel (`md2confluence-v3.py`) converts them to storage XML at emit time, embeds attachment images, and runs the humanizer punctuation gate before write.

> **Heading style**: plain Arabic numeral numbering: `## 1. Geliştirme Özeti`, `## 2. Hedefler ve Karşı Hedefler`. No special section characters. The section sign codepoint (U+00A7) is banned by `feedback_no-section-sign`.

> **Language**: This file is read as a system prompt. Prose stays English. Example tables and headings carry bilingual TR / EN scaffolds; the runtime renderer picks the right column per `outputLanguage`.

> **Locked decisions that govern this template**: the canonical numbered list lives in `$HOME/.claude/commands/multi-agent/analysis/SKILL.md` (cite decisions by label, not by a number duplicated here, to avoid drift). The template's structure is shaped chiefly by: one-feature-per-run, section omission rule, citation discipline (incl. annotation-as-copy), forward-looking spec, humanizer punctuation policy, standards binding, per-platform output split, repo-evidence reuse-first, Figma 3-tier access, Gherkin user stories, Goals + Non-Goals paired, SVG default, Files-to-Add tag, API response variants exhaustive, screenshots embedded, all Figma variants drilled, localization mode (ownership-aware), References at bottom, platform-agnostic + Pass B render, convention extraction, Pass B footnote mandatory, Lite mode, SwiftUI Preview block (iOS), variant usage explicit, analysis self-contained (no MCP downstream), and business-rule to acceptance-criterion to test traceability.

## Mode selection - Full vs Lite

The renderer picks Full or Lite mode automatically based on signals captured in Phase 1, or honours an explicit `--lite` flag from the user.

| Mode | Sections | When |
|---|---|---|
| Full | all 23 | Default. Used when feature has multi-screen flow, external service contracts, or complex business rules. |
| Lite | 8 of 23: 1, 2, 4, 9, 13, 14, 21, 23 | Used when (a) Confluence spec < 100 lines AND (b) Figma frames <= 1 AND (c) repo evidence direct-match >= 8. Manual override: user passes `--lite`. |

Lite mode sections retain the same scaffold as Full mode; only the section set is reduced.

## Section duplication mode per platform (A3 hybrid)

Locked 9 - one file per selected platform under `analysis/<feature>-<platform>.md`. Sections fall into three duplication categories:

| Category | Sections | Behaviour |
|---|---|---|
| Shared verbatim | 1, 2, 3, 4, 9, 21 | Identical content in every per-platform file. Pass A renders once, Pass B copies verbatim. |
| Per-platform projection | 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 | Logical content shared; expressions (class names, paths, code snippets, test framework, identifier patterns) projected per platform from Phase 1c conventions. |
| Footer | 22, 23 | Optional in Lite mode. In Full mode, identical across platforms. |

Backend-only run drops Sections 5 (Design), 6 (Components), 7 (Tokens), 8 (Assets), 10 (Localization keys can omit if no server-rendered text), 11 (Analytics if no backend telemetry), 12 (Deeplink/Push if no outgoing contracts), 16 (Accessibility N/A), 17 (subset: server-side input validation only).

## Front-matter header (per-platform file)

Every per-platform file starts with this YAML block:

```yaml
---
feature: <FeatureName>
platform: ios | android | backend | frontend | none
profile: global | corporate
language: tr | en
mode: full | lite
ui_tests: true | false
a11y_depth: basic | full
generated: <ISO 8601 UTC timestamp>
jira: <JIRA_KEY>-<id>
branch: <branch-name>
base_branch: <base-branch>
siblings:
  - analysis/<FeatureName>-<other-platform>.md
standards:
  - <absolute path or confluence:title or github-wiki:slug>
evidence_digest: sha256:<digest>
base_commit: <git rev-parse HEAD at emit time>
template_version: v3
---
```

`ui_tests` and `a11y_depth` record the Phase 0 Step 5a opt-ins (defaults `false` / `basic`) so the coverage choice is auditable and the pre-dispatch validator can enforce it: `ui_tests: true` requires Section 15.6, `a11y_depth: full` requires the Section 16.2 walkthrough.

`profile` names the template the document was rendered against (Locked 32) and `platform: none` marks the stack-optional render (Locked 35). Both are read by `validate-analysis-doc.mjs`, which applies a different contract per profile: without the key a corporate document would be judged against the global rules and its backbone would read as a pile of Locked 2 violations.

Phase 1 compares `evidence_digest` against an existing document to decide whether to reuse it (Locked 27). Phase 3 reads `platform` to verify file match, `mode` to know which section set to expect, and both `evidence_digest` and `base_commit` to judge freshness: the digest says the evidence changed, `base_commit` says the repo moved. Phase 2 parses the block but gates only on `template_version`.

## Layer headings (A / B / C)

The 23 sections render under three named layers. This is an **additive heading level**, not a renumbering: section numbers are referenced in 172 places across the repo including two deterministic validators, so they do not move. Layer headings are `#` (h1); sections stay `##`. `validate-analysis-doc.mjs` collects `^#{1,3}` and `md2confluence-v3.py` maps `#{1,6}` to `<h{level}>`, so the extra level is safe in both and gives the Confluence page a two-level table of contents.

| Layer | Sections | What is lost if it is missing |
|---|---|---|
| `# Bölüm A - Analiz` / `# Part A - Analysis` | 1, 2, 3, 4, 18, 19, 20 | **what** to build: user, rule, flow, error scenario |
| `# Bölüm B - Teknik Analiz` / `# Part B - Technical Analysis` | 5, 6, 7, 8, 9, 10, 11, 12, 16, 17 | **what is true**: endpoint, status code, token, variant axis, key |
| `# Bölüm C - Geliştirme Analizi` / `# Part C - Development Analysis` | 13, 14, 15 | **how** to build it: class name, file path, reuse, test row |
| (footer, no heading) | 21, 22, 23 | |

**Boundary rule.** Which layer a row belongs to is settled by one question: remove it, what becomes unclear? A row that is unclear in two layers at once is two rows. `A carries no technology name; C carries no business rationale.`

A layer whose sections all drop for lack of evidence drops its heading too (Locked 2). Numbering still flows 1..N over the rendered set.

**Error scenarios appear in all three, at different altitudes**: what the user sees (4.2), every status code with its body and UI outcome (9.3, exhaustive per Locked 17), and the error-path tests (15.1 error/empty-nil rows, 15.7 negative scenarios). One `BR-<slug>-NN` id ties the three together, so an error described in A cannot reach C untested.

## Omission rules

Locked 2 - no `TBD` / `Not applicable` placeholder. Sections with zero evidence are omitted entirely. Numbering remains sequential `1..N` over the rendered set; numbers re-flow when sections drop. The dispatch report logs the omission list.

| Section | Omission condition |
|---|---|
| 3 Flow Chart | Single screen AND single service AND simple business rule (no state transitions) |
| 5 Design Reference | No Figma URL AND no Code Connect mapping in any selected repo |
| 6 Component Inventory | No Figma URL AND no UI primitive evidence in repo |
| 7 Design Tokens | Sections 5 and 6 both omitted |
| 8 Asset Inventory | No new visual asset planned AND no existing asset modified |
| 10 Localization | No Figma annotation AND no Figma text layer AND no localization key file in repo |
| 11 Analytics | No Firebase input AND no analytics call site in repo |
| 12 Deeplink/Push | No deeplink handler in repo AND no push payload binding AND spec silent |
| 15 Test Plan | Backend-only run with no contract testing planned (rare) |
| 16 Accessibility | Backend-only (no UI surface) |
| 17 Security | No PII / auth / health data touched (rare, document explicit decision) |
| 18 Rollout | Lite mode. In Full mode render the compact checklist only (not prose); drop if the pipeline's own commit/PR/rollout phase already covers it and no staged rollout / feature flag applies |
| 19 Alternatives | Default drop. Render ONLY when a real architectural decision with 2+ genuine options exists; a thin or invented alternatives list is worse than none (a real decision point already lives in Section 20) |
| 22 Glossary | Default drop. Render ONLY on explicit request or when the doc uses more than 5 domain-specific terms a new reader would not know; otherwise define terms inline |
| 23 Changelog | Lite mode (optional even in Full for small revisions) |

Sections 1, 2, 4, 9, 13, 14, 20, 21 are never omitted.

## Pass B footnote format (Locked 24)

Every Pass B-rendered cell carries a footnote pointing to its evidence source:

```
| Cell label | Cell value ^[<convention-key> <confidence>: <evidence-source>] |
```

Examples:

```
| State holder | `UserProfileViewModel` ^[C2 high: 8 örnek; en yakın StandaloneLoginViewModel.swift] |
| Test naming | `@Test func fetch_validInput_returnsIdle()` ^[C4 medium: 4 mevcut örnek, çoğunluk Swift Testing] |
| Identifier | `userProfile.continueButton` ^[C5 high: ui-testing-identifiers.json dot notation] |
| State model | sealed enum `UserProfileUIState` ^[C3 fallback: conventions-defaults.md:C3-iOS, repo evidence none] |
```

Footnote-less cells fail the dispatch gate.

---

# Section scaffolds

## 1. Geliştirme Özeti / Summary

Never omitted. 2-3 paragraphs. Reader-friendly explanation of what the feature does and why it exists.

```markdown
## 1. Geliştirme Özeti   <!-- TR -->
## 1. Summary            <!-- EN -->

<one-sentence definition citing the primary spec source>

<paragraph: what the user gains from the feature>

<paragraph: which platforms and which app versions ship this>
```

Citation: feature definition cites the primary Confluence spec page (`[Confluence:<pageId>:<heading>]`).

## 2. Hedefler ve Karşı Hedefler / Goals and Non-Goals

Never omitted. Locked 13 - both columns mandatory. A row in only one column is not accepted.

```markdown
## 2. Hedefler ve Karşı Hedefler   <!-- TR -->
## 2. Goals and Non-Goals          <!-- EN -->

### İş kapsamı / Business scope

<1-2 sentences: what this feature covers and its boundary, in domain language. Names the platforms in scope (from the provided repos) and what is explicitly out of scope.>

| Hedef / Goal | Karşı Hedef / Non-Goal |
|---|---|
| <goal 1 citing source> | <non-goal 1 citing source> |
| <goal 2> | <non-goal 2> |
```

Each non-goal must say what it does NOT cover, not a vague "out of scope" (AI cannot infer exclusion from omission - state it positively). The scope line frames the goals below; detailed rules live in Section 4.4.

## 3. Akış Diyagramı / Flow Chart

Mermaid diagram(s). At least one is required unless the omission conditions hold (single screen AND single service AND simple business rule). 3.1 covers navigation, 3.2 covers service ordering, 3.3 covers state. Render each one whose subject the feature actually has; a rendered section with no mermaid block fails the dispatch gate.

```markdown
## 3. Akış Diyagramı   <!-- TR -->
## 3. Flow Chart       <!-- EN -->

### 3.1 Navigasyon Akışı / Navigation Flow

\`\`\`mermaid
flowchart TD
    A[Entry] --> B{Validation}
    B -->|valid| C[POST endpoint]
    B -->|invalid| A
    C --> D{Server response}
    D -->|case A| E[Next screen]
    D -->|case B| F[Modal]
\`\`\`

### 3.2 Servis Sırası / Sequence Diagram

\`\`\`mermaid
sequenceDiagram
    actor U as User
    participant A as App
    participant B as BFF
    participant S as Service

    U->>A: action
    A->>B: request
    B->>S: downstream
    S-->>B: response
    B-->>A: aggregated
    A->>U: rendered
\`\`\`

### 3.3 Durum Makinesi / State Machine (conditional)

Render when the screen holds more than one observable state (loading / loaded / empty / error, a multi-step form, or a retry path). A screen with a single state omits 3.3. Omitting it while state transitions exist is the same defect as omitting Section 3 entirely.

\`\`\`mermaid
stateDiagram-v2
    [*] --> Loading
    Loading --> Idle: success
    Loading --> Error: failure
    Idle --> Submitting: action
    Submitting --> [*]: success
    Submitting --> Error: validation
    Error --> Idle: retry
\`\`\`
```

Confluence dispatch wraps each mermaid block in `<ac:structured-macro ac:name="mermaid">`. If the macro is unavailable, `md2confluence-v3.py --mermaid-fallback` converts to a numbered list. The dispatch report carries `mermaid_macro_fallback_used: true/false`.

## 4. Kullanıcı Hikayeleri / User Stories

Never omitted. Locked 12 - Gherkin format mandatory. **Source-story completeness gate**: Gherkin scenarios cover the key happy/error/edge paths, but a `### 4.0 Kaynak Hikaye Izlenebilirligi / Source Story Traceability` table MUST list EVERY source-spec user-story ID (US-1..US-N) verbatim, each mapped to where it is covered (a Gherkin scenario or another section). Condensing into a few Gherkin scenarios is allowed ONLY if this table preserves the full source ID set; no source user story may be silently dropped. A missing source ID is a blocker and emits a Section 20 Risk row.

```markdown
## 4. Kullanıcı Hikayeleri   <!-- TR -->
## 4. User Stories           <!-- EN -->

### 4.1 Mutlu yol / Happy path

\`\`\`gherkin
Given <precondition>
And <additional context>
When <action>
Then <expected outcome>
And <secondary outcome>
\`\`\`

### 4.2 <Hata adı> / <Error name>

\`\`\`gherkin
Given <precondition>
But <conflicting state>
When <action>
Then <business-rule code shown, e.g. ERR-211>
And <user guidance>
\`\`\`

### 4.3 <Edge case>

\`\`\`gherkin
Given <precondition>
When <action>
Then <expected outcome>
\`\`\`

### 4.4 İş Kuralları / Business Rules

Locked 31 - the traceability spine. Every business rule is deterministic and testable (same input always yields the same outcome) and carries a stable id `BR-<slug>-NN`.

**The rule statement itself is written in EARS**, not free prose. EARS (Easy Approach to Requirements Syntax, IEEE RE'09) constrains the sentence to a fixed clause order and a small keyword set, which is what removes the ambiguity a prose rule carries. Five patterns, use the one that fits:

| Pattern | Shape | Use when |
|---|---|---|
| Ubiquitous | `THE SYSTEM SHALL <behaviour>` | always active, no trigger |
| Event-driven | `WHEN <trigger> THE SYSTEM SHALL <behaviour>` | fires on a discrete event |
| State-driven | `WHILE <state> THE SYSTEM SHALL <behaviour>` | holds for as long as a state holds |
| Unwanted | `IF <unwanted condition> THEN THE SYSTEM SHALL <behaviour>` | error and edge handling |
| Optional | `WHERE <feature is included> THE SYSTEM SHALL <behaviour>` | applies only to some configurations |

EARS states the rule; Gherkin states how you check it. Each rule still maps to at least one acceptance criterion written Given / When / Then. In Full mode each acceptance criterion is then realized as unit-test scenarios in Section 15.1; in Lite mode Section 15 is not rendered, so the acceptance criterion stands alone here (it is itself the testable statement) and the 15.1 mapping is deferred to a later Full analysis or to the dev run itself. Rules come from the spec / Confluence / Jira / annotations, never invented; a rule with no source cites `[label TBD - see Open Questions]` and adds a Section 20 row.

| BR ID | Kural / Rule (deterministic, testable) | Kaynak / Source | Kabul kriteri / Acceptance criterion (Given/When/Then) |
|---|---|---|---|
| BR-<slug>-01 | WHEN <trigger> THE SYSTEM SHALL <behaviour> | [Confluence:<pageId>:<heading>] / [Figma annotation <nodeId>] / file:line | Given <state>, When <action>, Then <binary outcome> |
| BR-<slug>-02 | IF <unwanted condition> THEN THE SYSTEM SHALL <behaviour> | <source> | Given ..., When ..., Then ... (+ >=1 failure-mode criterion) |
```

Each scenario in 4.1-4.3 cites the matching `BR-<slug>-NN` id (and, when a server code applies, the Section 9.4 code). Plain-prose user stories without Given/When/Then are rejected by the renderer.

## 5. Tasarım Referansı / Design Reference

Per-platform projection. Omitted if no Figma URL AND no Code Connect mapping. Locked 17 + 18.

```markdown
## 5. Tasarım Referansı   <!-- TR -->
## 5. Design Reference    <!-- EN -->

### 5.1 Frame galerisi / Frame gallery

Drill into every Figma variant (Locked 18). When a section URL is given, list all of its child frames.

| Frame ID | Varyant / Variant | Boyut / Dimensions | Görüntü / Screenshot | Ayırt edici / Distinctive | Code Connect |
|---|---|---|---|---|---|
| <nodeId 1> | <name> (canonical) | <w>x<h> | ![](frame-<prefix>-<id>.png) | <list> | <component name> ^[Figma <nodeId>] |
| <nodeId 2> | <name> | <w>x<h> | ![](...) | <list> | <component name> |
| <nodeId 3> | Error state | <w>x<h> | ![](...) | <list> | <component name> |

The `Code Connect` column is filled from `evidence.codeConnect[]` (Phase 1b.1): the component bound to that frame's `nodeId` (matched by `fileKey` + `nodeId`), or blank when the frame has no existing binding.

### 5.2 Padding ve hizalama / Padding and alignment

Token references for each variant (no raw numbers).

| Varyant | Outer padding | Card gap | Section top | CTA stack |
|---|---|---|---|---|
| Canonical | Spacing.spacing16 | Spacing.spacing12 | Spacing.spacing24 | Spacing.spacing16 / 20 |
| Error | same | same | Spacing.spacing48 | same |

### 5.3 Tier durumu / Tier status

Tier in use: <1 (MCP) | 2 (REST) | 3 (user screenshot)>
Screenshots attached: <count>
Auth retries used: <count>

### 5.4 Yerleşim ve Kaydırma / Layout and Scroll

Precise-enough-to-reproduce layout. Spacing/padding are token names (no raw numbers, Locked bound to Section 7). One row per meaningful component or frame region.

| Bileşen / Component | Node | Auto Layout (yön/wrap) | Padding (kenar/edge -> token) | Boşluk / Gap (token) | Hizalama / Alignment | Boyut / Sizing (fixed/hug/fill) | Konum / Position (constraint) |
|---|---|---|---|---|---|---|---|
| <name> | <nodeId> | vertical | top Spacing.spacing16 / others Spacing.spacing12 | Spacing.spacing8 | leading / center | width fill, height hug | pinned top |

**Scroll and container behavior** (a static Figma frame cannot express this - state it explicitly for both the AI and the human):

- Kaydırma kabı / Scroll container: <which region scrolls; single vertical scroll vs nested>
- Sabit / Sticky: <header/footer/CTA pinned while content scrolls, or none>
- İçerik kenar boşlukları / Content insets: <token or safe-area-relative>
- Güvenli alan / Safe area: <edges respected: top notch / bottom home indicator / status bar>
- Klavye / Keyboard avoidance: <inset-adjust vs scroll-into-view vs none>

Capture order (tokens never hardcoded): `mcp__claude_ai_Figma__get_metadata` (tree) -> `mcp__claude_ai_Figma__get_variable_defs` (resolve spacing/color/type tokens) -> render -> `mcp__claude_ai_Figma__get_screenshot` (visual check). Run per section/frame for fidelity, not per whole page.
```

Frame gallery images are uploaded to Confluence as multipart attachments and referenced via `<ac:image><ri:attachment ri:filename="..." /></ac:image>` (Locked 17). Section URL drilling enumerates all child frames automatically via `mcp__claude_ai_Figma__get_metadata` or `figma-screenshot.sh --section`.

## 6. Bileşen Envanteri / Component Inventory

Per-platform projection.

```markdown
## 6. Bileşen Envanteri   <!-- TR -->
## 6. Component Inventory <!-- EN -->

| Bileşen / Component | Mevcut / Existing | Konum / Location | Kullanım / Usage | Notlar / Notes |
|---|---|---|---|---|
| <Name> | yes | <path> | <where used> | reuse ^[direct-match] |
| <Name> | yes | <path> | <where used> | modify: <variant property to add> |
| <Name> | no | new | <where used> | added to Section 14 ^[Figma <nodeId>] |
```

Locked 11 - existence is resolved against `evidence.codeConnect[]` (the Code Connect index from Phase 1b.1) first: a design `nodeId` (or its `fileKey`) that matches an index entry emits a `reuse` row (`Mevcut/Existing = yes`, pointing at the bound component + path), because figma-to-swiftui already built and bound it. A `nodeId` with no Code Connect match falls back to the Phase 1b `uiComponents` heuristic; only when neither finds a candidate does the row become a new component (`Existing = no`, added to Section 14).

**Code Connect snippet is an existence oracle, not spec truth.** The Code Connect index answers "does this component already exist and is it bound", nothing more. A Code Connect snippet's contents are NOT authoritative for copy or for what the new screen needs - they describe what the codebase currently maps. Drift between a snippet and the current design is logged ONCE as a design-system-maintenance note in Section 20 (Open Questions), never as a per-string verification row.

### 6.X Varyant / prop kapsamı - Variant / property coverage

Completeness audit over the **whole component surface**, not just the part this screen happens to touch. Phase 1b.2 resolves each Code Connect-bound instance to its main component (component set) and reads the full variant axis, so the "all values" column is the component's real axis rather than what the instance revealed. Every value gets exactly one disposition; an unmapped remainder is a Section 20 Risk.

Without the traversal this table could only ever list properties the instance already used, which made "used subset" unverifiable against anything (Locked 29). Phase 2+ cannot re-fetch (Locked 30), so a value missed here is missed for the whole run.

| Bileşen / Component | Eksen / Axis | Tüm değerler / All values | Bu ekranda / Used here | Karar / Disposition | Not / Note |
|---|---|---|---|---|---|
| <Name> | <variant property> | <v1, v2, v3, v4> | <v1, v3> | implement | <mapped concept / param> |
| <Name> | <variant property> | <a, b> | <a> | skip | <why b is not used on this screen> |
| <Name> | <boolean prop> | true, false | true | defer | <open question ref> |

Each used value needs a matching row in Section 13.6 (Preview) and Section 15.2 (Snapshot); expanding the used subset later means updating this table first.

## 7. Tasarım Token'ları / Design Tokens

Per-platform projection. No magic numbers, no raw hex, no raw `.font()`.

```markdown
## 7. Tasarım Token'ları   <!-- TR -->
## 7. Design Tokens        <!-- EN -->

### 7.1 Spacing

| Token | Değer / Value | Kullanım / Usage |
|---|---|---|
| Spacing.spacing12 | 12 pt | <where> |
| Spacing.spacing16 | 16 pt | <where> |

### 7.2 Renkler / Colors

| Token | Hex (reference) | Kullanım / Usage |
|---|---|---|
| Color.Primary.primary | #E31837 | <where> |
| Color.Status.error | #D32F2F | <where> |

### 7.3 Tipografi / Typography

| Token | Kullanım / Usage |
|---|---|
| .h6 | <where> |
| .body1 | <where> |

### 7.4 Karanlık Mod / Dark Mode

Rendered when the design ships a dark variant (else drop with note `(N/A: no dark variant)`). Each row is a semantic token PAIR, never a literal hue - the token resolves per scheme. Re-verify contrast in dark; a light-passing pair can fail dark.

| Rol / Role | Light token | Dark token | Not / Note (elevation, asset variant, contrast) |
|---|---|---|---|
| surface/base | Color.Surface.base | Color.Surface.base (adaptive) | iOS systemBackground; Android tonal elevation (no shadow in dark) |
| content/primary | Color.Content.primary | Color.Content.primary | contrast >= 4.5:1 rechecked in dark |
| border/subtle | Color.Border.subtle | Color.Border.subtle | - |
| <named asset> | icon@light | icon@dark | asset-catalog appearance variant |
```

Per-platform projection translates token names: iOS uses `.Spacing.spacingN` enum + adaptive `Color(.systemBackground)` / asset appearances; Android uses `MaterialTheme.spacing.medium` + Material 3 color roles with tonal elevation in dark; Frontend uses CSS variables `--spacing-md` / `--color-*` per `prefers-color-scheme`; Backend section omitted.

## 8. Asset Envanteri / Asset Inventory

```markdown
## 8. Asset Envanteri   <!-- TR -->
## 8. Asset Inventory   <!-- EN -->

| Asset adı / Name | Format | Mevcut / Existing | Kaynak / Source | Notlar / Notes |
|---|---|---|---|---|
| <name> | SVG | yes | xcassets | reuse |
| <name> | SVG | no | Figma frame <nodeId> | new ^[Figma <nodeId>] |
| <name> | Lottie | no | Figma + motion spec | new, istisna gerekçesi / exception rationale: <reason> |
```

Locked 14 - SVG default for new assets. Lottie or optimized PNG accepted with explicit rationale in the Notes column.

## 9. API Kontratları / API Contracts

Never omitted (if any service is consumed). Locked 16 - response variants exhaustive. **Service-completeness gate**: do NOT rely solely on the supplied Swagger/Confluence inputs - reconcile against the canonical Api Contract page(s) for this screen. Every endpoint listed on the screen's Api Contract page MUST appear in 9.1 (or be explicitly tagged out-of-scope with a reason). An uncovered contract endpoint is a blocker and emits a Section 20 Risk row.

```markdown
## 9. API Kontratları   <!-- TR -->
## 9. API Contracts     <!-- EN -->

**Swagger / OpenAPI**: <url-or-omit>
**Confluence kontrat sayfası / Confluence contract page**: <url-or-omit>

### 9.1 Endpoint

\`\`\`
POST /v1/<endpoint>
Content-Type: application/json
Authorization: Bearer <token>
\`\`\`

### 9.2 Request body

\`\`\`json
{
  "field1": "value",
  "field2": 0
}
\`\`\`

| Alan / Field | Tip / Type | Zorunlu / Required | Validation |
|---|---|---|---|
| field1 | string | yes | <rule> |
| field2 | integer | no | <rule> |

### 9.3 Response varyantları / Response variants

List every HTTP status code one by one.

| HTTP | Senaryo / Scenario | Body | UI sonucu / UI outcome |
|---|---|---|---|
| 200 | success | <body> | <UI> |
| 200 | redirect type A | <body> | <UI> |
| 400 | invalid input | `{"code":"FP-011"}` | <UI> |
| 422 | business rule violated | `{"code":"FP-031"}` | <UI> |
| 500 | server error | `{"code":"GEN-500"}` | <UI> |

### 9.4 Business-rule catalog (when applicable)

| Kod / Code | Anlam / Meaning | UI konumu / UI location |
|---|---|---|
| FP-011 | Invalid format | <screen> |
| ERR-211 | Empty result set | <screen> |
```

## 10. Lokalizasyon Anahtarları / Localization Keys

Per-platform projection. Locked 20 - shape depends on the project `figma-config` `localization.ownership`. The locale set comes from `localization.locales` (default `tr, en, ar, de, es, fr, it, ru`); never hardcode a locale list.

### Mode A - `in-repo` (default): full per-locale grid

New keys carry filled cells for every configured locale.

```markdown
## 10. Lokalizasyon Anahtarları   <!-- TR -->
## 10. Localization Keys          <!-- EN -->

Desteklenen diller / Supported locales: <localization.locales, e.g. TR, EN, AR, DE, ES, FR, IT, RU>

| Key | <loc1> | <loc2> | ... | Source | Status |
|---|---|---|---|---|---|
| <key 1> | <val> | <val> | ... | Figma annotation <nodeId> | new |
| <key 2> | <val> | <val> | ... | repo:Localizable.xcstrings | reuse |
| <key 3> | <tr> | <en> | [bekleniyor: çeviri ekibi] / [pending: translation team] | Figma annotation <nodeId> | partial |
```

| Status | Meaning |
|---|---|
| reuse | Existing key, no new translation needed |
| new | New key, all configured locales must be filled |
| partial | Base locales filled, rest pending translation team. Dispatch flags `i18n_pending: <count>` as blocker. |

### Mode B - `externally-owned`: keys + ownership, values deferred

Per-locale values are owned by `localization.authoringPipeline` and are NOT hand-filled here (they would be overwritten by the owning system and were never the analyst's to write). List the key, its status, the copy source, and the `localization.baseLanguage` value only.

```markdown
## 10. Lokalizasyon Anahtarları   <!-- TR -->
## 10. Localization Keys          <!-- EN -->

Sahiplik / Ownership: <localization.authoringPipeline>  (per-locale values authored there)
Temel dil / Base language: <localization.baseLanguage>

| Key (<keyPattern>) | Durum / Status | Kopya kaynağı / Copy source | Temel değer / Base value | Sahiplik / Ownership |
|---|---|---|---|---|
| <Namespace.Case> | new | Figma annotation <nodeId> | <base-language value> | <authoringPipeline> |
| <Namespace.Case> | reuse | existing catalog | (existing) | <authoringPipeline> |
```

Gate (Mode B): the base-language value is present (sourced from the Figma annotation per Locked 3) AND the ownership reference is cited. A key missing its base-language value is a blocker - at runtime a missing base value renders the raw `Namespace.Case` key on screen. Fabricated per-locale values are rejected.

Label-authoring contract (Mode B): the analysis names each label and its base copy; it does NOT write per-locale values or hand-edit the owning system's files. A `new` key is a pure addition (auto-mergeable by the authoring pipeline). A `reuse` key that needs a copy change is an EDIT - flag it as review-gated (the owning pipeline requires approval) and never silently overwrite. The base copy always comes from the Figma annotation; when the annotation is missing a language the authoring pipeline expects, emit a Section 20 row rather than inventing it.

Per-platform projection (both modes):

| Platform | File format | Key convention | Example |
|---|---|---|---|
| iOS | `Localizable.xcstrings` | hierarchical dot PascalCase | `Feature.Element` ^[C6 high] |
| Android | `strings.xml` | flat snake_case | `feature_element` ^[C6 high] |
| Backend | error code table | per server convention | uppercase enum |
| Frontend | `i18n/*.json` | hierarchical dot camelCase | `feature.element` ^[C6 high] |

## 11. Analytics

```markdown
## 11. Analytics

| Event | Parametreler / Params | Tetiklenme / Trigger (story / rule) | Source | Status |
|---|---|---|---|---|
| <event_name> | <param1, param2> | 4.1 happy path / BR-<slug>-01 | <Firebase schema / repo / Confluence> | new |
| <event_name> | <params> | <story or BR id> | <source> | reuse |

Each event's Trigger cites the user story (Section 4) or business rule (`BR-` id, Section 4.4) it fires on, so the analytics plan traces to behavior (Locked 31).
PII redaction: <list of fields hashed before telemetry>
```

Locked 11 - direct-match events emit reuse rows. Locked 17 - PII fields (email, phone, national ID) hashed before emit.

## 12. Deeplink ve Push Notification / Deeplink and Push

Conditional. Included when: repo grep hits deeplink/push handler, OR Confluence spec mentions deeplink/push routing, OR feature has push payload binding.

```markdown
## 12. Deeplink ve Push Notification   <!-- TR -->
## 12. Deeplink and Push Notification  <!-- EN -->

### 12.1 Deeplink tablosu / Deeplink table

| URL Pattern | Parametreler / Params | Hedef route / Target route | Handler | autoSubmit |
|---|---|---|---|---|
| `<scheme>://<feature>?<params>` | <params> | <screen> | <handler:line> | yes/no |
| `https://<domain>/<feature>?<params>` | <params> | <screen> | <handler:line> | yes/no |

### 12.2 Push payload

| Event | Payload | Hedef route / Target route | Handler | Foreground davranışı / Foreground behaviour |
|---|---|---|---|---|
| <event> | `{...}` | <screen> | <handler> | banner + tap or full screen |

### 12.3 Universal Links / Associated domains

apple-app-site-association: `<path>`
Android intent-filter: `<host>` / `<scheme>`

### 12.4 Routing sequence

\`\`\`mermaid
sequenceDiagram
    participant N as Notification
    participant AD as AppDelegate / FirebaseMessagingService
    participant DR as DeeplinkRouter
    participant C as Coordinator / Navigator
    participant V as View

    N->>AD: payload
    AD->>DR: resolve
    DR->>C: start(route, params)
    C->>V: attach
\`\`\`
```

## 13. Mimari Plan / Architecture Plan

Never omitted. Per-platform projection from Phase 1c conventions.

```markdown
## 13. Mimari Plan        <!-- TR -->
## 13. Architecture Plan  <!-- EN -->

### 13.1 Kavram tablosu / Concept table

Locked 21 - platform-agnostic concept layer rendered with repo conventions.

| Kavram / Concept | Karşılığı / Realization | Confidence | Evidence |
|---|---|---|---|
| Module folder | <repo path> | high | C1 |
| State holder | `<class name>` | high | C2 |
| View / Screen | `<class name>` | high | C2 |
| Navigator | `<class name>` | high | C2 |
| Use case | `<class names>` | high | C2 |
| Repository | `<class name>` | high | C2 |
| DTO | `<class names>` | high | C2 |
| UI state model | <sealed enum / data class / discriminated union> | high | C3 |
| DI registration | <configurator / module / Depends / hook factory> | high | C7 |
| Localization key | `<example>` | high | C6 |
| Accessibility id | `<example>` | high | C5 |
| Test method | `<example>` | high | C4 |

### 13.2 State holder snippet

\`\`\`<lang>
<rendered class skeleton per Pass B>
\`\`\`

### 13.3 State model

\`\`\`<lang>
<rendered state type per Pass B>
\`\`\`

### 13.4 Validation kuralları / Validation rules

| Kural / Rule | Konum / Location | Davranış / Behaviour |
|---|---|---|
| <rule> | <use case class> | <effect> |

### 13.5 Navigator / Coordinator

\`\`\`<lang>
<rendered navigator interface per Pass B>
\`\`\`

### 13.5.1 DI registration

\`\`\`<lang>
<rendered DI register line per Pass B>
\`\`\`

### 13.6 SwiftUI Preview block (iOS projection, SwiftUI views only)

Per Locked 29 - SwiftUI views ship with `#Preview` macro (Swift 5.9+) or `PreviewProvider` (legacy). UIKit view controllers are exempt from this section. Pass B detects the view kind via `import SwiftUI` + `: View` protocol conformance against `evidence.repoEvidence[<repo>].buckets.uiComponents`; if a feature has only UIKit `UIViewController` artefacts, this subsection is omitted with note `(N/A: UIKit-only feature)`.

One preview entry per variant matters for Xcode Canvas and snapshot test alignment. Preview macro convention is read from `conventions[<repo>].previewMacro` (Phase 1c) - the renderer picks `#Preview` for Swift 5.9+ repos and `PreviewProvider` for legacy ones.

| Varyant / Variant | Mode / Trait | Notes |
|---|---|---|
| Default (canonical) | LTR Light | basic happy path |
| Default | LTR Dark | dark mode regression check |
| Default | RTL Light | RTL layout regression |
| Default | Dynamic Type accessibilityLarge | scaling regression |
| Error state | LTR Light | empty state, error message |
| Loading state | LTR Light | skeleton or spinner |
| Edge case (e.g. long copy, single item) | LTR Light | optional, when distinct from canonical |

Preview snippet (Pass B fills variant list per Phase 1c convention):

\`\`\`swift
#Preview("Default") {
    UserProfileView(viewModel: .preview(.idle))
}

#Preview("Error - ERR-211") {
    UserProfileView(viewModel: .preview(.error(.PP_211)))
}

#Preview("Dark") {
    UserProfileView(viewModel: .preview(.idle))
        .preferredColorScheme(.dark)
}

#Preview("RTL") {
    UserProfileView(viewModel: .preview(.idle))
        .environment(\.layoutDirection, .rightToLeft)
}
\`\`\`

Reuse rule (Locked 11 + 24): if `evidence.repoEvidence[<repo>].buckets.uiComponents` shows that the view already has a `#Preview` block, the table cell carries `Reuse existing block at <file:line>` instead of `Add new preview`. Conventions footnote example: `^[C8 high: 6 örnek, #Preview macro convention, en yakın StandaloneLoginView.swift:120]`.

Snapshot test linkage: Section 15.2 Snapshot Tests must enumerate each preview variant listed here so Canvas previews and CI snapshots stay aligned. A preview without a matching snapshot row triggers a Section 20 Risk.

### 13.7 Standards binding

Decisions cite their binding source (Locked 8):

| Decision | Source |
|---|---|
| <decision> | <standards file or wiki page> |
```

## 14. Eklenecek Dosyalar / Files to Add

Never omitted. Locked 16 - every row carries Reuse / Add new / Modify tag.

```markdown
## 14. Eklenecek Dosyalar   <!-- TR -->
## 14. Files to Add         <!-- EN -->

| Dosya / File | Etiket / Tag | Notlar / Notes |
|---|---|---|
| <path> | Add new | <purpose> |
| <path> | Reuse | <where it lives, why no change> ^[direct-match] |
| <path> | Modify | <what changes> |
```

## 15. Test Planı / Test Plan

Per-platform projection.

```markdown
## 15. Test Planı   <!-- TR -->
## 15. Test Plan    <!-- EN -->

### 15.1 Birim testleri / Unit tests (kural bazlı / rule-driven)

Locked 31 - one sub-table per business rule from Section 4.4. Enumerate the cases: happy, boundary (min/max, off-by-one), error/failure, empty/nil. Each row is Given / When / Then plus a framework-correct test name that traces back to the `BR-` id. Boundary rows collapse into one parameterized test.

Framework per platform (from Phase 1c conventions; these are the modern defaults): iOS Swift Testing (`@Test`, `@Suite`, `@Test(arguments:)` for boundary tables, `#expect` / `#require`); Android JUnit5 + MockK (`coEvery` / `coVerify`) + Turbine (`flow.test { awaitItem() }`) + coroutines-test (`runTest`, `StandardTestDispatcher`); Backend pytest (parametrize); Frontend Vitest.

**BR-<slug>-01**

| Senaryo / Case | Given | When | Then | Test adı / name |
|---|---|---|---|---|
| happy | <state> | <action> | <expected> | `func rule_validInput_returnsExpected()` ^[C4 <conf>] |
| boundary | <edge state> | <action> | <expected> | `@Test(arguments:)` parametrized |
| error | <failure state> | <action> | <error/emission> | `func rule_failure_emitsError()` |
| empty/nil | <empty state> | <action> | <default/guard> | `func rule_empty_returnsIdle()` |

(Repeat one sub-table per rule. A rule with no unit-test row fails the dispatch gate, Locked 31.)

### 15.2 Görsel regresyon / Snapshot tests

| Senaryo / Scenario | Mod / Mode |
|---|---|
| Canonical | LTR Light |
| Canonical | LTR Dark |
| Canonical | RTL Light |
| Error state | LTR Light |
| Empty state | LTR Light |

Cihaz boyutları / Device sizes: <list>

### 15.3 Sahte servisler / Mock services

| Service | Mock class / file | Use case |
|---|---|---|
| <service> | <mock> | <UC> |

### 15.4 Kabul senaryoları / Acceptance scenarios

Section 4 Gherkin scenarios + their `BR-` ids mapped to test names.

| Senaryo | BR ID | Test |
|---|---|---|
| 4.1 happy path | BR-<slug>-01 | <unit or UI test name> |

### 15.5 Performans bütçesi / Performance budget

| Metrik / Metric | Hedef / Target |
|---|---|
| Cold start to ready | <ms> |
| Scroll FPS | 60 |
| Memory peak | <MB> |

### 15.6 UI test senaryoları / UI test scenarios (OPTIONAL)

Rendered when `state.analysisSpec.options.uiTests == true`. That option now **defaults to true** for `taskType == component` or any task carrying a Figma reference - UI work without UI test scenarios is the gap this section exists to close - and stays opt-in for everything else. UI tests are the most expensive tier - reserve for high-risk / revenue-connected cross-screen flows, not per-element coverage. Selectors are stable ids (iOS `accessibilityIdentifier`, Android `Modifier.testTag` / `contentDescription`), never localized text, so the flow survives copy/locale changes and an agent can generate it mechanically.

| Flow ID | Öncelik / Priority (why it earns a UI test) | Adımlar / Steps | Seçiciler / Selectors | Doğrulamalar / Assertions | Ön koşullar / Preconditions | BR ID |
|---|---|---|---|---|---|---|
| UI-<slug>-01 | <high-risk reason> | <ordered user actions> | <accessibilityIdentifier / testTag> | <visible state / navigation / error> | <seeded data / launch args / mocked network> | BR-<slug>-NN |

Framework: iOS XCUITest (`waitForExistence`, identifier-driven); Android Compose UI test (`createComposeRule`, `onNodeWithTag`) or Espresso for View-based screens.

### 15.7 Manuel test senaryoları / Manual test scenarios

The scenarios a person runs by hand. Same format the pipeline already posts as the Jira test-scenario comment (`/multi-agent:resume-local`), defined once and read by both. Omitted entirely when the feature has none (Locked 2); never rendered as an empty table.

Each row is executable by someone who did not write the feature: no "verify it works", no implied setup. Cover the happy path, at least one boundary, and every failure mode that reaches the user - the same four-way split Locked 31 requires of unit tests.

| Senaryo / Scenario | Ön koşul / Precondition | Adımlar / Steps | Beklenen / Expected | BR ID |
|---|---|---|---|---|
| MT-<slug>-01 | <account state, seeded data, network condition> | 1. ... 2. ... 3. ... | <observable outcome, incl. exact copy where it matters> | BR-<slug>-NN |
| MT-<slug>-02 (hata / error) | <condition that triggers the failure> | 1. ... 2. ... | <error surface, message, recovery path> | BR-<slug>-NN |
```

Full mode: a manual scenario with no `BR-` id, or a business rule whose failure modes reach the user with no matching MT row, fails the dispatch gate.

## 16. Erişilebilirlik / Accessibility

Per-platform projection. WCAG 2.2 AA + Apple HIG + Material A11y.

```markdown
## 16. Erişilebilirlik   <!-- TR -->
## 16. Accessibility     <!-- EN -->

### 16.1 Kontrol listesi / Checklist (always)

| Madde / Item | Durum / Status | Notlar / Notes | WCAG 2.2 |
|---|---|---|---|
| Unique identifier on every interactive element | required | <per C5 convention> | 4.1.2 |
| Minimum tap target (iOS 44x44 pt / Android 48x48 dp / Web 44x44 px) | required | exceeds AA | 2.5.8 |
| Screen reader label (accessibilityLabel / contentDescription / aria-label) | required | | 1.1.1 / 4.1.2 |
| Hint text (accessibilityHint / stateDescription / aria-description) | optional | | 4.1.2 |
| Dynamic Type / font scaling to 200% | required | | 1.4.4 |
| Contrast ratio >= 4.5:1 (text) / 3:1 (large) | required | recheck in dark | 1.4.3 |
| State expressed beyond colour | required | | 1.4.1 |
| Reduce motion honored | required | | 2.3.3 |
| Keyboard navigation (web only) | required | tabindex + focus order | 2.1.1 / 2.4.3 |
| Voice Over / TalkBack reading order | required | see 16.2 when full depth | 2.4.3 |

### 16.2 Ekran okuyucu gezinme / Screen-reader walkthrough (OPTIONAL)

Rendered ONLY when `state.analysisSpec.options.a11yDepth == "full"` (Phase 0 Step 5a opt-in); otherwise omitted. An ordered reading-order script that is BOTH the implementation spec and the manual VoiceOver / TalkBack test. One row per focus stop, in traversal order.

| # | Odak / Focus target | Seslendirilen / Announced (label + role/trait + value + hint) | Hareket / Gesture | Sonuç / Resulting state |
|---|---|---|---|---|
| 1 | <element + selector> | "<label>, <role>, <value>. <hint>" | swipe right | focus moves to 2 |
| 2 | <element> | "<...>" | double-tap | <navigation / state change> |
```

## 17. Güvenlik ve Gizlilik / Security and Privacy

Per-platform projection. Locked decisions: no PII in logs, HTTPS only, Keychain for secrets, hashing for telemetry, ATT before tracking, KVKK/GDPR compliance.

```markdown
## 17. Güvenlik ve Gizlilik   <!-- TR -->
## 17. Security and Privacy   <!-- EN -->

| Kural / Rule | Uygulama / Implementation |
|---|---|
| Secrets in secure storage (Keychain / KeyStore / encrypted env) | required |
| Sensitive fields hashed before telemetry | required, SHA-256 |
| HTTPS only, no ATS exception | required |
| Certificate pinning (where applicable) | required |
| ATT consent before tracking (iOS) | required if tracking enabled |
| KVKK / GDPR data lifecycle disclosed | required |

OWASP MASVS quick check:

| MSTG | Status |
|---|---|
| AUTH-1 | <status> |
| NETWORK-1 | <status> |
| STORAGE-1 | <status> |
```

## 18. Yayılım Planı / Rollout Plan

Compact checklist only (default-drop per the omission table when the pipeline's own commit/PR/rollout phase already covers it). Include a row ONLY when it carries feature-specific information beyond the standard pipeline flow.

```markdown
## 18. Yayılım Planı   <!-- TR -->
## 18. Rollout Plan    <!-- EN -->

- Staged rollout: <internal -> beta -> production %, or "standard pipeline flow">
- Feature flag / rollback: <remote flag name, or "none">
- QA gate: <feature-specific device/version notes, or "standard">
```

## 19. Değerlendirilen Alternatifler / Alternatives Considered

ADR format.

```markdown
## 19. Değerlendirilen Alternatifler   <!-- TR -->
## 19. Alternatives Considered         <!-- EN -->

### Alternatif <n> / Alternative <n>

| Seçenek / Option | Artı / Pro | Eksi / Con |
|---|---|---|
| <chosen> | <pro list> | <con list> |
| <alternative> | <pro list> | <con list> |

Karar / Decision: <chosen>. Gerekçe / Rationale: <reason>.
```

## 20. Riskler ve Açık Sorular / Risks and Open Questions

Never omitted.

```markdown
## 20. Riskler ve Açık Sorular   <!-- TR -->
## 20. Risks and Open Questions  <!-- EN -->

| Risk / Soru / Risk / Question | Sahibi / Owner | Durum / Status |
|---|---|---|
| <risk or question> | <name or role> | Açık / Open |
| <convention fallback applied> | Pass B (auto) | Açık / Open |
| <existing X candidate found; reuse or document why a new one is needed> | <name> | Açık / Open |
```

Auto-populated rows (Locked 11, 23): repo-evidence direct-match candidates that conflict with planned new-write; convention fallbacks where Phase 1c confidence was none.

## 21. Referanslar / References

Never omitted (Locked 21 - at the bottom, not at the top). Shared verbatim by both profiles.

**Built deterministically, not written by the model.** `~/.claude/scripts/build-references.mjs` reads `state.analysisSpec.evidence.*` and emits this table. A hand-written references table drifts from what the run actually read: it lists what the author remembers consulting, which is a different set from what the evidence gathering fetched. Every row here is a source the run touched.

```markdown
## 21. Referanslar   <!-- TR -->
## 21. References    <!-- EN -->

| Tür / Type | Kaynak / Source | URL / Yol | Sürüm / Ref | Rol / Role | Erişim / Access | Notlar / Notes |
|---|---|---|---|---|---|---|
| Figma | <design name> | <url> | node-id=<nodeId> | UI design | ok (Tier <n>) | <n frames> |
| Confluence | <spec name> | <url> | pageId=<id> v<n> | feature spec | ok | - |
| Confluence | <api contract> | <url> | pageId=<id> v<n> | API contract | ok | <endpoint summary> |
| Jira | <ticket id> | <url> | - | ticket | ok | <summary> |
| Swagger | <api name> | <url> | <spec version> | API contract | ok | <n endpoints> |
| Repo | <module> | <repo path> | <commit sha> | existing implementation | ok | <reuse summary> |
| Standards | <name> | <url or path> | <version> | binding | ok | <kind> |
| Firebase | events | <console url> | - | reference only | erişilemedi (auth) | <n events> |
| Doküman | <file name> | <local path> | <format> | scope document | ok | - |
| Dış kaynak | <name> | <url> | <citation> | referans | ok | <claim> |
| Serbest metin | kullanıcı notu | - | - | <what it settled> | - | "<verbatim quote>" |
| Confluence | <unreachable page> | <url> | - | getirilemedi | erişilemedi (403) | - |
```

These row types are exactly what `build-references.mjs` emits, and the example is kept in step with it deliberately: a shape shown here but never produced would send a reader hand-checking against a table that cannot exist. A wiki source arrives as a `Standards` row carrying `wiki` in its `kind` cell, and a generated OpenAPI client arrives as the `Repo` row of the module that holds it; neither has a row type of its own.

**Column contract.**

- **Sürüm / Ref** is the precision anchor: the node id for a Figma frame, `pageId` plus page version for Confluence, the commit SHA the repo was read at, the spec version for Swagger. Without it a reference points at a moving target, and a reader six weeks later cannot tell whether the document described what they are looking at.
- **Erişim / Access** is `ok` or `erişilemedi (<reason>)`. A source that was declared but could not be fetched still gets a row. Dropping it hides the gap: the reader sees a document that never mentions the API contract and assumes there was none, rather than knowing it was unreachable.
- **Serbest metin** rows carry what the user stated in conversation that no fetched source contains, quoted verbatim, with the decision it settled in the `Rol` column. Scope decisions made in chat are evidence; leaving them out is how a document loses the reason it excluded something.

**Coverage gate (Locked 34).** Before the document is emitted, the validator compares this table against the evidence record. Every entry in `evidence.figma[]`, `evidence.confluence[]`, `evidence.jira[]`, `evidence.swagger[]`, `evidence.repo[]`, `evidence.standards[]`, `evidence.firebase[]`, `evidence.documents[]`, `evidence.outside[]`, `evidence.freeText[]` and every entry in `evidence.fetchErrors[]` must appear as a row. A source that shaped the document but is missing from References fails the dispatch gate, and a row with no matching evidence entry fails it too - an invented reference is worse than a missing one.

## 22. Sözlük / Glossary

Footer. Optional in Lite mode. Alphabetical.

```markdown
## 22. Sözlük   <!-- TR -->
## 22. Glossary <!-- EN -->

| Kısaltma / Abbreviation | Açıklama / Description |
|---|---|
| ATS | App Transport Security |
| BFF | Backend For Frontend |
| CTA | Call To Action |
| DTO | Data Transfer Object |
| SSOT | Single Source of Truth |
| WCAG | Web Content Accessibility Guidelines |
```

Only terms used in this document are listed. Generic IT terms (HTTP, JSON, REST) are excluded.

## 23. Değişiklik Geçmişi / Changelog

Footer.

```markdown
## 23. Değişiklik Geçmişi   <!-- TR -->
## 23. Changelog            <!-- EN -->

| Sürüm / Version | Tarih / Date | Yazar / Author | Değişiklik / Change |
|---|---|---|---|
| v1 | <date> | <author> | İlk taslak / Initial draft |
| v2 | <date> | <author> | <change summary> |
```

---

# Pass B render examples (per platform)

The following examples show how Pass B fills the same Pass A concept layer (state holder + use case + view + state model) for each platform when repo conventions are extracted with `high` confidence.

## iOS render example

Conventions extracted: feature-first + clean arch, `<Feature>ViewModel`, sealed enum state, Swift Testing, dot-notation accessibility identifiers, hierarchical dot PascalCase localization, manual configurator DI.

```swift
@MainActor
final class UserProfileViewModel: ObservableObject {
    @Published private(set) var state: UserProfileUIState = .loading
    private let fetchUseCase: FetchUserProfileUseCaseProtocol

    init(fetchUseCase: FetchUserProfileUseCaseProtocol) {
        self.fetchUseCase = fetchUseCase
    }

    func onAppear() async {
        do {
            let result = try await fetchUseCase.execute()
            state = .idle(profile: result.profile)
        } catch let error as DomainError {
            state = .error(error.code)
        } catch {
            state = .error(.generic)
        }
    }
}

enum UserProfileUIState {
    case loading
    case idle(profile: ProfileEntity)
    case error(DomainErrorCode)
}
```

Folder: `Domains/Profile/Sources/Profile/Screens/ProfileEditor/Presentation/ViewModel/`
Test name: `@Test func fetch_validInput_returnsIdle()`
Identifier: `userProfile.continueButton`
Localization key: `UserProfile.ContinueButton`

## Android render example

Conventions extracted: feature module + clean arch, `<Feature>ViewModel`, sealed interface state, JUnit5 + Turbine, camelCase testTag, snake_case strings.xml, Hilt module DI.

```kotlin
@HiltViewModel
class UserProfileViewModel @Inject constructor(
    private val fetchUseCase: FetchUserProfileUseCase
) : ViewModel() {
    private val _state = MutableStateFlow<UserProfileUiState>(UserProfileUiState.Loading)
    val state: StateFlow<UserProfileUiState> = _state.asStateFlow()

    fun onAppear() {
        viewModelScope.launch {
            try {
                val result = fetchUseCase.execute()
                _state.value = UserProfileUiState.Idle(result.profile)
            } catch (e: DomainException) {
                _state.value = UserProfileUiState.Error(e.code)
            }
        }
    }
}

sealed interface UserProfileUiState {
    data object Loading : UserProfileUiState
    data class Idle(val profile: Profile) : UserProfileUiState
    data class Error(val code: DomainErrorCode) : UserProfileUiState
}
```

Folder: `feature/profile/src/main/java/<package>/userprofile/ui/`
Test name: `fun fetch_validInput_returnsIdle()`
testTag: `userProfileContinueButton`
strings.xml: `user_profile_continue_button`

## Backend render example

Conventions extracted: layered Python FastAPI, router + service + repository, Pydantic DTO, pytest snake_case, FastAPI Depends.

```python
class UserProfileService:
    def __init__(
        self,
        repository: UserProfileRepository,
        validator: ProfileInputValidator,
    ):
        self.repository = repository
        self.validator = validator

    async def fetch(self, request: UserProfileIn) -> UserProfileOut:
        profile = await self.repository.get_profile(request.user_id)
        return UserProfileOut(profile=profile)


@router.post("/update-profile", response_model=UserProfileOut)
async def update_profile(
    request: UserProfileIn,
    service: UserProfileService = Depends(get_user_profile_service),
) -> UserProfileOut:
    return await service.fetch(request)
```

Folder: `app/api/profile/`, `app/services/profile/`, `app/schemas/profile/`
Test name: `def test_fetch_valid_input_returns_profile():`
OpenAPI operationId: `updateProfile`

## Frontend render example

Conventions extracted: Next.js App Router, feature folder, React Query hooks, Zustand stores, Vitest, kebab data-testid, hierarchical dot camelCase i18n.

```tsx
type UserProfileState =
  | { kind: "loading" }
  | { kind: "idle"; profile: Profile }
  | { kind: "error"; code: DomainErrorCode };

export function useUserProfile(userId: string) {
  return useQuery<UserProfileDto, DomainError>({
    queryKey: ["user-profile", userId],
    queryFn: () => userProfileApi.fetch({ userId }),
  });
}

export function UserProfilePage({ userId }: Props) {
  const query = useUserProfile(userId);
  if (query.isLoading) return <LoadingState />;
  if (query.isError) return <ErrorState code={query.error.code} />;
  return <UserProfileContent data={query.data} />;
}
```

Folder: `src/features/profile/user-profile/{components,hooks,api,types}/`
Test name: `it('returns idle state for valid input', ...)`
data-testid: `user-profile-continue-button`
i18n key: `userProfile.continueButton`

---

# Output language matrix

Canonical TR / EN pairs for headings and system strings. The dispatcher reads `outputLanguage` at render time.

| TR | EN |
|---|---|
| Geliştirme Özeti | Summary |
| Hedefler ve Karşı Hedefler | Goals and Non-Goals |
| Hedef | Goal |
| Karşı Hedef | Non-Goal |
| Akış Diyagramı | Flow Chart |
| Navigasyon Akışı | Navigation Flow |
| Servis Sırası | Sequence Diagram |
| Durum Makinesi | State Machine |
| Kullanıcı Hikayeleri | User Stories |
| Mutlu yol | Happy path |
| Tasarım Referansı | Design Reference |
| Frame galerisi | Frame gallery |
| Varyant | Variant |
| Boyut | Dimensions |
| Görüntü | Screenshot |
| Ayırt edici | Distinctive |
| Padding ve hizalama | Padding and alignment |
| Tier durumu | Tier status |
| Bileşen Envanteri | Component Inventory |
| Bileşen | Component |
| Mevcut | Existing |
| Konum | Location |
| Kullanım | Usage |
| Notlar | Notes |
| Tasarım Token'ları | Design Tokens |
| Renkler | Colors |
| Tipografi | Typography |
| Asset Envanteri | Asset Inventory |
| Asset adı | Asset name |
| Format | Format |
| Kaynak | Source |
| API Kontratları | API Contracts |
| Alan | Field |
| Tip | Type |
| Zorunlu | Required |
| Response varyantları | Response variants |
| Senaryo | Scenario |
| UI sonucu | UI outcome |
| Kod | Code |
| Anlam | Meaning |
| UI konumu | UI location |
| Lokalizasyon Anahtarları | Localization Keys |
| Anahtar | Key |
| Yeni | New |
| Kısmi | Partial |
| Tetiklenme | Trigger |
| Parametreler | Params |
| Deeplink ve Push Notification | Deeplink and Push Notification |
| Deeplink tablosu | Deeplink table |
| URL deseni | URL pattern |
| Hedef route | Target route |
| Foreground davranışı | Foreground behaviour |
| Yönlendirme sırası | Routing sequence |
| Mimari Plan | Architecture Plan |
| Kavram tablosu | Concept table |
| Karşılığı | Realization |
| Validation kuralları | Validation rules |
| Kural | Rule |
| Davranış | Behaviour |
| Standards binding | Standards binding |
| Eklenecek Dosyalar | Files to Add |
| Dosya | File |
| Etiket | Tag |
| Test Planı | Test Plan |
| Birim testleri | Unit tests |
| Hedef | Target |
| Görsel regresyon | Snapshot tests |
| Mod | Mode |
| Sahte servisler | Mock services |
| Kabul senaryoları | Acceptance scenarios |
| Performans bütçesi | Performance budget |
| Metrik | Metric |
| Erişilebilirlik | Accessibility |
| Madde | Item |
| Durum | Status |
| Güvenlik ve Gizlilik | Security and Privacy |
| Uygulama | Implementation |
| Yayılım Planı | Rollout Plan |
| Aşama | Stage |
| Aksiyon | Action |
| Değerlendirilen Alternatifler | Alternatives Considered |
| Seçenek | Option |
| Artı | Pro |
| Eksi | Con |
| Karar | Decision |
| Gerekçe | Rationale |
| Riskler ve Açık Sorular | Risks and Open Questions |
| Sahibi | Owner |
| Açık | Open |
| Referanslar | References |
| Tür | Type |
| Rol | Role |
| Sözlük | Glossary |
| Kısaltma | Abbreviation |
| Açıklama | Description |
| Değişiklik Geçmişi | Changelog |
| Sürüm | Version |
| Tarih | Date |
| Yazar | Author |
| Değişiklik | Change |
| İlk taslak | Initial draft |
| bekleniyor: çeviri ekibi | pending: translation team |
| Pass B (auto) | Pass B (auto) |
| convention fallback applied | convention fallback applied |
| existing X candidate found | existing X candidate found |
