---
description: "Convention fallback defaults for /multi-agent:analysis Phase 2b Pass B. Activated only when repo evidence is none and standards binding is silent. Each application of a default opens a risk row in Section 20."
---

# Convention Defaults - Pass B Fallback Reference

`/multi-agent:analysis` Phase 1c extracts conventions from each selected repo (folder structure, class naming, state model, test naming, accessibility identifier, localization key, DI registration). When `confidence == "none"` AND the standards binding source (`evidence.standards[]`) does not provide an explicit rule, Pass B falls back to the platform defaults catalogued here. Every applied default emits a row in Section 20 Risks of the rendered document.

> **Language**: This file is read as a system prompt. Prose stays English. Examples carry generic placeholder names (`Foo`, `Bar`); the runtime substitutes the actual feature slug.

> **Locked decision 23**: Applying a default is never silent. Pass B writes a footnote on the rendered cell pointing to this file and lists "convention fallback applied" in Section 20.

## How the fallback chain works

```
Phase 1c extract -> confidence == "none" or "low"
   |
   v
Read evidence.standards[]
   |
   +--- match found: cite standards file, use that pattern
   |
   v
Read conventions-defaults.md (this file)
   |
   v
Apply platform default + open Section 20 risk row
```

## C1 - Folder Structure

| Platform | Default pattern | Example | Rationale |
|---|---|---|---|
| iOS | feature-first + clean arch | `Features/<Feature>/Sources/<Feature>/{Common,Data,Domain,Presentation}/` | Mirrors SwiftPM module boundaries; keeps each feature self-contained |
| Android | feature module + clean arch | `feature/<feature>/src/main/java/<package>/{data,domain,ui}/` | Standard Now-in-Android pattern, aligns with Gradle module isolation |
| Backend | layered | `src/{api,services,repositories,schemas,models}/<feature>/` | Standard FastAPI / Express layering, predictable for new contributors |
| Frontend | feature folder | `src/features/<feature>/{components,hooks,api,types}/` | Standard Next.js / React feature-folder convention |

## C2 - Class Naming

### C2a stateHolderNaming

| Platform | Default pattern | Example |
|---|---|---|
| iOS | `<Feature>ViewModel` | `PassengerFlightViewModel` |
| Android | `<Feature>ViewModel` | `PassengerFlightViewModel` |
| Backend | not applicable | (services replace state holders) |
| Frontend | `use<Feature>` hook | `usePassengerFlight` |

### C2b viewNaming

| Platform | Default pattern | Example |
|---|---|---|
| iOS | `<Feature>View` | `PassengerFlightView` |
| Android | `<Feature>Screen` | `PassengerFlightScreen` |
| Backend | not applicable | |
| Frontend | `<Feature>Page` | `PassengerFlightPage` |

### C2c navigatorNaming

| Platform | Default pattern | Example | Notes |
|---|---|---|---|
| iOS | `<Feature>Coordinator` | `PassengerFlightCoordinator` | Conforms to `<Domain>Router` protocol if present |
| Android | `<Feature>Navigator` | `PassengerFlightNavigator` | Compose Navigation destination |
| Backend | not applicable | | |
| Frontend | route file under `app/` | `app/passenger-flight/page.tsx` | Next.js App Router default |

### C2d useCaseNaming

| Platform | Default pattern | Example |
|---|---|---|
| iOS | `<Verb><Feature>UseCase` | `FetchPassengerFlightUseCase` |
| Android | `<Verb><Feature>UseCase` | `FetchPassengerFlightUseCase` |
| Backend | `<Feature>Service` | `PassengerFlightService` |
| Frontend | hook with side effect | `usePassengerFlightQuery` |

### C2e repositoryNaming

| Platform | Default pattern | Example |
|---|---|---|
| iOS | `<Feature>Repository` (protocol) + `<Feature>RepositoryImpl` (class) | `PassengerFlightRepository`, `PassengerFlightRepositoryImpl` |
| Android | `<Feature>Repository` (interface) + `<Feature>RepositoryImpl` (class) | same |
| Backend | `<Feature>Repository` | `PassengerFlightRepository` |
| Frontend | `<feature>Api` | `passengerFlightApi` |

### C2f dtoNaming

| Platform | Default pattern | Example |
|---|---|---|
| iOS | `<Feature>RequestDTO`, `<Feature>ResponseDTO` | `PassengerFlightRequestDTO`, `PassengerFlightResponseDTO` |
| Android | `<Feature>Dto` | `PassengerFlightDto` |
| Backend | Pydantic `<Feature>In`, `<Feature>Out` | `PassengerFlightIn`, `PassengerFlightOut` |
| Frontend | TypeScript `<Feature>Dto` | `PassengerFlightDto` |

## C3 - UI State Model

| Platform | Default | Example |
|---|---|---|
| iOS | sealed enum | `enum PassengerFlightUIState { case loading, idle(...), error(...) }` |
| Android | sealed interface | `sealed interface PassengerFlightUiState { data object Loading; data class Idle(...); data class Error(...) }` |
| Backend | not applicable | services do not hold UI state |
| Frontend | discriminated union | `type PassengerFlightState = { kind: 'loading' } | { kind: 'idle'; ... } | { kind: 'error'; ... }` |

## C4 - Test Method Naming

| Platform | Default pattern | Example |
|---|---|---|
| iOS Swift Testing | `@Test func <scenario>_<expected>()` | `@Test func fetch_validInput_returnsIdle()` |
| iOS XCTest fallback | `test<Scenario>_<Expected>()` | `testFetch_ValidInput_ReturnsIdle()` |
| Android JUnit5 | `fun <funName>_<scenario>_<expectedBehavior>()` | `fun fetch_validInput_returnsIdle()` |
| Backend pytest | `def test_<scenario>_<expected>():` | `def test_fetch_valid_input_returns_idle():` |
| Frontend Vitest | `it('<does X> when <condition>', ...)` | `it('returns idle when input is valid', ...)` |

## C5 - Accessibility Identifier

| Platform | Default pattern | Example | Rationale |
|---|---|---|---|
| iOS | dot notation `<feature>.<element>` | `passengerFlight.continueButton` | XCUITest query syntax friendliness |
| Android | camelCase testTag | `passengerFlightContinueButton` | Compose testTag convention |
| Backend | OpenAPI operationId camelCase | `fetchPassengerFlight` | Code generation friendly |
| Frontend | kebab data-testid `<feature>-<element>` | `passenger-flight-continue-button` | DOM attribute readability |

## C6 - Localization Key

| Platform | Default pattern | Example | Notes |
|---|---|---|---|
| iOS | hierarchical dot PascalCase | `PassengerFlight.ContinueButton` | Matches `Localizable.xcstrings` convention |
| Android | flat snake_case | `passenger_flight_continue_button` | Matches `strings.xml` convention |
| Backend | not applicable (server-side messages live in error code tables) | | |
| Frontend | hierarchical dot camelCase | `passengerFlight.continueButton` | i18next + ICU MessageFormat default |

## C8 - SwiftUI Preview macro (iOS only)

| Platform | Default pattern | Example | Rationale |
|---|---|---|---|
| iOS Swift 5.9+ | `#Preview` macro | `#Preview("Default") { FooView(viewModel: .preview(.idle)) }` | Modern Xcode 15+ Canvas binding, less boilerplate, supports named previews |
| iOS legacy | `PreviewProvider` struct | `struct FooView_Previews: PreviewProvider { static var previews: some View { FooView(viewModel: .preview(.idle)) } }` | Pre-Swift 5.9 fallback |
| Android | not applicable | (Compose `@Preview` is handled under C3 / C4 conventions, no separate field) | |
| Backend | not applicable | | |
| Frontend | not applicable | (Storybook stories live in `.stories.tsx` files, tracked under C2 conventions) | |

Detection: scan up to 10 SwiftUI view files in the candidate set; majority pick wins. Confidence `high` if 5+ matching examples, `medium` if 3-4, `low` if 2, `none` if 0 SwiftUI views found (Pass B then omits Section 13.6 with `(N/A: UIKit-only feature)` note per Locked 29).

## C7 - Dependency Injection

| Platform | Default | Example | Rationale |
|---|---|---|---|
| iOS | Manual configurator | `<Domain>DependencyConfigurator.register<Feature>()` | Avoids framework lock-in; testable |
| Android | Hilt module | `@Module @InstallIn(SingletonComponent::class) class <Feature>Module` | Standard Android DI |
| Backend FastAPI | `Depends(get_<feature>_service)` | `service: PassengerFlightService = Depends(get_passenger_flight_service)` | Native FastAPI pattern |
| Frontend | hook factory | `usePassengerFlightApi()` returns a memoized client | No framework DI needed |

## Risk row template (Section 20)

When Pass B applies any default from this file, it emits the following row in Section 20 Risks of the rendered document:

```markdown
| <Cell name>: convention fallback applied | Pass B (auto) | Open |
```

With a follow-up question in the cell footnote:

```
^[fallback: conventions-defaults.md:C<n>; repo evidence none, standards binding silent. Confirm or override before dev.]
```

The follow-up triggers a human decision: keep the default, override to a different pattern, or update the standards binding source so the question disappears next time.

## Maintenance

When the team standardizes on a different default, update this file directly and rebuild the affected analyses. Avoid storing defaults inline in `analysis-template.md` or `analysis.md`; the indirection through this file keeps the source of truth visible and reviewable.

## Locked decisions that govern this file

- Locked 21: platform-agnostic template + Pass B render
- Locked 22: convention extraction mandatory (Phase 1c)
- Locked 23: convention fallback opens a risk row
- Locked 24: every Pass B cell carries a footnote
- Locked 28: SwiftUI Preview block mandatory for iOS SwiftUI views (Section 13.6, C8 convention)
