# Intake (analysis Phase 0)

> The picker chain that fills `state.analysisSpec.*` before any fetch runs. Loaded by `/multi-agent:analysis`. Pipeline Phase 1 does NOT load this file: in a pipeline run the account, project, repos and task already came from the orchestrator's own Phase 0, and only the source and coverage batches below are asked (see `phase-1-analysis.md` Step 4).

### Phase 0 - Intake

Sequential `AskUserQuestion` chain. Each answer is written to state under `state.analysisSpec.*`.

**Step narration (required, per `$HOME/.claude/multi-agent-refs/picker-contract.md`)**: the chain length is known up front  -  1 analysis-name + 1 profile + 1 account + 1 platform + 1 repo-round per selected platform + 1 input-URL batch + 1 coverage-options batch (so a single-platform run is 7 steps; account is skipped for local-only flows and the profile step auto-resolves when only one profile is available, either of which lowers the total). Before each step's `AskUserQuestion`, print the narrator line `<localized: "Step <i>/<n>: <what this step decides>">` in `outputLanguage`. Auto-resolved steps (single account, local-only) still print their breadcrumb with the resolution noted. This is what makes the picker show, step by step, what it is doing.

#### Step 0 - Language resolution (BLOCKING, runs before any picker)

Before emitting the first `AskUserQuestion`, read `prefs.global.outputLanguage` (`tr` or `en`, default `tr`). Every `<localized: "...">` marker in the Phase 0 picker chain (Steps 1-5) MUST be rendered in the resolved language - this is not deferred to Phase 3. Per the Language note above: `question` and `description` follow `outputLanguage`; `label` and `header` stay English. If `outputLanguage == tr`, the user sees Turkish question text; do not emit the English literal inside the `<localized:>` marker.

#### Step 1 - Analysis name

If `$ARGUMENTS` is empty, ask via AskUserQuestion (single question, user types via Other).
Result: `state.analysisSpec.featureName` (state key kept for backward compatibility; user-facing label is "analysis name").

#### Step 1b - Analysis profile

Asked once, immediately after the analysis name and before anything is fetched, because the profile decides which template the whole run renders against (Locked 32). Never re-asked mid-run.

Read the available profiles from `prefs.global.analysisProfiles` (default `["global", "corporate"]`). When only one is available, auto-resolve and print the breadcrumb with the resolution noted rather than asking a question whose answer is already settled.

AskUserQuestion (single-select):
```
header: "Profile"
question: <localized: "Which analysis standard should this document follow?">
options:
  - label: "Global"
    description: <localized: "Development handoff, 23 sections. Business rules with Gherkin acceptance criteria, architecture plan, files to add, test plan. Sections with no evidence are dropped.">
  - label: "Corporate"
    description: <localized: "Requirements document. Business requirement to use case to functional requirement spine with three traceability matrices, current and target state with impact analysis, then technical analysis and development analysis. Backbone sections always render.">
```

Result: `state.analysisSpec.profile` (`global` | `corporate`). Empty submit re-asks; an empty answer does not imply the default (`feedback_no-inferred-defaults-from-empty-answer`).

The profile changes nothing about intake, fetching, repo evidence or convention extraction - those are shared. It selects the template at Phase 3 and switches the omission rule for the corporate backbone (Locked 33).

**Corporate profile bindings.** Publication targets and house terminology are read from `prefs.global.analysisProfile.corporate` when present: `confluenceSpaceKey`, `confluenceParentPageId`, `titleFormat`, `titlePrefix`, `apiSpecCommand` and a `glossary` map. The key set is closed in `prefs.schema.json`, so a typo is caught by `validate-prefs.mjs` rather than silently ignored at emit time. They are deployment configuration, not part of the shipped template: an unconfigured corporate run still renders the full document and asks for the destination at Phase 3.5 like any other run.

#### Step 2 - Account picker

Reuse `_account-picker.md`. Skipped if the resolved flow is local-only.

#### Step 3 - Platform (derived; asked only when it cannot be)

**Derive first.** Every repo selected in Step 2 already carries a stack tag from the orchestrator's project scan (`[iOS]`, `[Android]`, ...), so the platform set is the distinct tags of the selected repos. Print the breadcrumb with the resolution noted and move on - a question whose answer is already on screen is a question not worth asking.

Ask only when the derivation is ambiguous (a repo whose stack the scan could not tag) or when the user wants **fewer** platforms than the repos imply (one repo carrying both an app and its backend). The question below is that fallback.

#### Step 3 (fallback) - Platform multi-select

AskUserQuestion (multiSelect=true):
```
header: "Platforms"
question: <localized: "Which platforms is this analysis for?">
options:
  - label: "iOS"
  - label: "Android"
  - label: "Backend"
  - label: "Frontend"
  - label: "No platform yet"
    description: <localized: "Analysis and technical analysis only. The development analysis is skipped until a repo is chosen.">
```
Empty submit → re-ask. Result: `state.analysisSpec.platforms[]`.

**`No platform yet` is a real answer, not a cancel** (Locked 35). It leaves `platforms[]` empty, skips Step 4 entirely, and the run continues: evidence is still fetched from every declared source, and the document renders every layer that does not need a target repository. Only the development layer and the Pass B projection drop, and Section 20 records that they await a repo selection. Output is a single `analysis/<feature>.md` rather than one file per platform, since the per-platform split exists to carry per-platform projections and there are none.

**Platform coverage = provided platforms.** The analysis renders exactly one per-platform file (Locked 9) for each platform selected here and given a repo in Step 4: select iOS only -> a single iOS document; select iOS + Android -> one iOS and one Android document, each projected through that repo's own conventions (Phase 1c) and its own Code Connect index (Phase 1b.1, discovered from that repo's `*.figma.swift` / `*.figma.kt`). Do not analyze a platform the user did not select, and do not drop a selected platform that has a repo.

#### Step 4 - Repos (from Phase 0, not re-asked)

Repos come from the orchestrator's Step 2 project selection plus `_dev-context.md`; both already handle multi-select, `canPush`, submodules and `frontendRepos[]`. Analysis does **not** ask its own repo question - that was a third place asking the same thing, and the platform-to-repo mapping falls straight out of the stack tags anyway.

Map `state.analysisSpec.repos[]` from the Phase 0 selection: one entry per repo with `platform` (its stack tag), `name`, `path`, `canPush`. If a selected platform has no repo, ask for that one platform only.

When `platforms[]` is empty (Step 3 resolved to `No platform yet`), skip Steps 4 and 4 (fallback) entirely and print the breadcrumb noting that repo selection is deferred.

#### Step 4 (fallback) - Repo multi-select per platform

For each selected platform, run one AskUserQuestion round. Reuse `_dev-context.md` logic:
- Run `~/.claude/lib/submodule-detector.sh "$REPO_PATH"` to enumerate submodules + `canPush`
- Augment with `prefs.projects[<key>].editableRelatedRepos[]` for iOS / Android / Backend
- For `Frontend`, read `prefs.projects[<key>].frontendRepos[]` as the primary source (since Frontend is rarely in the iOS submodule tree); fall back to Other input
- If no repos are detectable for a platform, present a single Other input asking for `<owner>/<repo>`

Result: `state.analysisSpec.repos[]` (each entry has `platform`, `name`, `path`, `canPush`).

#### Step 5 - Input URLs (single 6-question batch)

One AskUserQuestion call with **7 parallel questions**, one per source type. Each question shows a `Skip` option plus auto-available `Other` for free-text input. Empty / `Skip` selections yield no entry in `state.analysisSpec.contextLinks[]`.

```
Q1: header="Figma URL"
    question: <localized: "Do you have a Figma URL for this feature?">
    options:
      - label: "No Figma input"
      - label: "Use repo Code Connect only"
    (Other: paste URL - comma-separated for multiple frames)

Q2: header="Swagger URL"
    question: <localized: "Do you have a Swagger / OpenAPI URL?">
    options:
      - label: "No Swagger input"
      - label: "Extract from Confluence instead"
    (Other: paste URL)

Q3: header="Confluence"
    question: <localized: "Do you have a Confluence page URL for the feature spec?">
    options:
      - label: "No Confluence input"
    (Other: paste URL - comma-separated for multiple pages)

Q4: header="Jira"
    question: <localized: "Do you have a related Jira ID?">
    options:
      - label: "No Jira input"
    (Other: type Jira ID like {JIRA_KEY}-12345 - comma-separated for multiple)

Q4b: header="Document"
    question: <localized: "Do you have a spec document? A .docx, .pdf, .md or .txt file, as a local path or a URL.">
    options:
      - label: "No document input"
    (Other: absolute or tilde path, or a URL - comma-separated for multiple)

Q5: header="Standards"
    question: <localized: "Do you have coding documentation or standards to bind the development plan? Confluence URL, GitHub wiki URL, or local file path.">
    options:
      - label: "No standards input"
      - label: "Auto-detect from repo"
        description: "Searches the auto-detect probe list below (canonical home-dir Standards file, repo CLAUDE.md / CONTRIBUTING.md, docs/architecture/*.md, and the wiki Home.md / Navigation.md if a GitHub wiki is configured)"
    (Other: comma-separated mix of Confluence URLs, GitHub wiki URLs, and absolute / tilde-expanded local file paths)

Q6: header="Firebase"
    question: <localized: "Do you have Firebase Analytics events for this feature? Comma-separated event-name list, a JSON schema file path, or a Firebase Console URL.">
    options:
      - label: "No Firebase input"
      - label: "Auto-detect from repo"
        description: "Greps Analytics.logEvent / firebaseAnalytics.logEvent / logEvent(analytics, ...) call sites in the selected repos and extracts event names"
    (Other: comma-separated mix of event names like 'profile.view,profile.opened', a /path/to/events.json, or a console.firebase.google.com URL)
```

After submit, run `~/.claude/lib/context-link-extractor.sh` on each Other-provided string. Results are typed and written to `state.analysisSpec.contextLinks[]`. Q5 entries are additionally tagged `binding: true` so Phase 2 Section 7 treats them as hard constraints (see the Phase 1 type table and the Phase 2 Section 7 row).

**Q5 + Q6 type detection rules** (also documented in `~/.claude/lib/context-link-extractor.sh`):

| Input shape | Detected type | Phase 1 strategy |
|---|---|---|
| Starts with `/` or `~` and ends with `.md` / `.markdown` / `.txt` | `local-file` | `Read` tool on the absolute path (tilde-expanded) |
| Host = `github.com` AND path matches `/<owner>/<repo>/wiki/<PageName>` (no `.md`) | `wiki` | `git clone --depth 1 https://github.com/<owner>/<repo>.wiki.git /tmp/<repo>-wiki && Read /tmp/<repo>-wiki/<PageName>.md` (URL `-` to ` ` decoding) |
| Host matches `confluence*.<tld>` AND path contains `/display/` or `/pages/viewpage.action?pageId=` | `standards-confluence` | Same fetcher as `confluence` but bucket goes to `evidence.standards[]` |
| Comma-separated lowercase tokens with `.` or `_` (e.g. `profile.view,screen_view`) and no slash / no scheme | `firebase-events:names` | Scaffold rows from names alone |
| Starts with `/` or `~`, ends with `.json`, path contains `events` or `analytics` | `firebase-events:schema` | `Read` + JSON parse `events[]` |
| Host `console.firebase.google.com` with `/analytics/` in path | `firebase-events:console` | Reference-only; INFO warning printed, no fetch |
| Any other `http(s)://` URL | `generic-doc` | `WebFetch` |

Q5 Auto-detect mode probe order (option 2):
1. `~/<project>-Standards.md` - canonical home-dir reference file; the exact filename comes from `prefs.projects[<project>].standardsFile` (no hardcoded project name in this command)
2. `<repo>/CLAUDE.md`, `<repo>/CONTRIBUTING.md`
3. `<repo>/docs/architecture/*.md`
4. If a `*.wiki.git` mirror is reachable for the primary repo, clone and ingest `Home.md` + any page named `Navigation*.md`

Q6 Auto-detect mode probe order (option 2):
1. Per-repo grep for `Analytics\.logEvent\(`, `firebaseAnalytics\.logEvent\(`, `logEvent\(analytics,` and harvest the first string literal in each call as the event name
2. Generated `AnalyticsEvents/*.swift` / `AnalyticsEvents/*.kt` if present (treat each public struct conforming to `AnalyticsEvent` as one event)
3. Repo-level `firebase-events.json` / `analytics/events.json` files

#### Step 5a - Coverage options (opt-in, 2 questions)

One `AskUserQuestion` call with 2 parallel yes/no questions. These are opt-INs, not source intake: an empty answer is NOT consent (per `feedback_no-inferred-defaults-from-empty-answer`) - re-ask on empty rather than defaulting silently once the picker is shown.

```
Q1: header="UI Tests"
    question: <localized: "Should the analysis include UI test scenarios (XCUITest / Compose UI test)? Optional; unit + snapshot coverage is always included.">
    options:
      - label: "No UI tests"          -> state.analysisSpec.options.uiTests = false (default)
      - label: "Write UI test scenarios" -> state.analysisSpec.options.uiTests = true

Q2: header="A11y depth"
    question: <localized: "How detailed should accessibility be? Basic checklist always ships; full adds a VoiceOver / TalkBack reading-order walkthrough.">
    options:
      - label: "Basic checklist"       -> state.analysisSpec.options.a11yDepth = "basic" (default)
      - label: "Full walkthrough"      -> state.analysisSpec.options.a11yDepth = "full"
```

`options.uiTests` gates Section 15.6 (UI test flows); `options.a11yDepth` gates the Section 16 VoiceOver / TalkBack walkthrough. Both default to the lighter choice so the doc stays lean unless the user opts in.

#### Step 5b - Repo-evidence collector (automatic, no prompt)

Runs after Step 5a submits and before Phase 1 begins. Reads from `state.analysisSpec.repos[]`. For each repo, walks the platform whitelist and produces a 13-bucket evidence catalogue. No user interaction. Output: `state.analysisSpec.evidence.repoEvidence[<repo>]`. See Phase 1b for the bucket list and tagging rules.

#### Step 6 - REMOVED in v8.10.0

The output-destination picker moved to **Phase 3.5**, which runs after Phase 3 finishes the per-platform draft buffers. See Phase 3.5 below for the picker definition.
