# 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`, `label` and `description` follow `outputLanguage`; only `header` stays English (<=12-char chip). 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: "Web"          -> platform id `web`
  - label: "Backend"
  - label: "No platform yet"
    description: <localized: "Derive the channels from the sources. Analysis and technical analysis only - the development analysis waits for a repo.">
```
Empty submit → re-ask. Result: `state.analysisSpec.platforms[]`.

`web` is the canonical id; the pre-rename `frontend` is still read back (older state,
`:stack frontend`, the `ai-frontend-toolkit` plugin id) and normalises to `web`.

**`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.

**The channel split is then derived from the evidence, not abandoned** (Locked 35,
which carries the reasoning). After evidence collection, classify the run's channels
from what the sources say:

| Signal | Reads as |
|---|---|
| Figma frames at a phone viewport or named for an app flow; text naming an app store, push, a deep link, a native permission | `mobile` |
| Figma frames at desktop / tablet width or named for a browser page; text naming a browser, a URL route, SEO, a breakpoint | `web` |
| A Swagger contract consumed by a named client | that client's channel |

`mobile` is one channel here, not iOS plus Android; once a repo is selected the normal
`ios` / `android` split applies.

**Confirm the derivation, do not act on it silently.** The evidence proposes; the
user decides how many documents this run produces:

```
header: "Channels"   question: <localized: "Hangi kanallar icin dokuman uretilsin?">
options (label + description in outputLanguage; semantics, not literals):
  "Mobile and web" | "Mobile only" | "Web only" | "One combined"
```

Each description names the evidence behind that channel (`8 frame, 2 dokuman`), so the
answer is informed. The derived set is the recommended option; autopilot takes it
without asking and logs what it picked and why. One channel: ask only split-out or
channel-agnostic. None: emit `analysis/<feature>.md` and say no channel signal was
found.

**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 `Web`, read `prefs.projects[<key>].webRepos[]` (falling back to the pre-rename `frontendRepos[]`) as the primary source (since Web 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 sources (7 questions, 2 fixed batches)

`AskUserQuestion` accepts at most **4 questions per call**, so the seven source types
are asked as two fixed batches. Do not improvise the split: seven at once is an invalid
tool call, and an improvised retry separates the spec sources from each other.

- **Batch 1/2  -  what the feature IS**: Figma, Confluence, Document, Jira. A written
  spec arrives as an attached `.docx` / `.pdf` at least as often as a Confluence page,
  so both are on the same screen.
- **Batch 2/2  -  what constrains it**: Swagger, Standards, Firebase.

**Development-layer questions are gated on a platform being selected.** With
`platforms[]` empty that layer does not render (Locked 35), so a question feeding only
it spends attention on an answer nothing consumes.

Two questions feed only that layer and are therefore skipped:

| Skipped question | Feeds |
|---|---|
| Standards | global 13.7 Standards binding = corporate 17 (Part C) |
| UI Tests (Step 5a) | global 15.6 = corporate 19 (Part C) |

Everything else is still asked: Firebase (global 11 = corporate 13) and A11y depth
(global 16 = corporate 15) land in Part B, and the five source questions feed Parts A
and B.

With no platform, batch 2 is a 2-question call (Swagger, Firebase) and Step 5a a
1-question call (A11y depth). Name the skipped questions and the reason in the batch
breadcrumb, the way an auto-resolved step still prints its own line
(`picker-contract.md` Step narration).

Announce which batch is showing (`1/2`, `2/2`) in the narrator line above the picker.
Each question carries a skip option plus the host's auto-added `Other` for free-text
input. Skipped questions yield no entry in `state.analysisSpec.contextLinks[]`.

Option `label`s and `description`s render in `outputLanguage`; `header` stays English
per the `rules.md` matrix. The quoted strings below are the option SEMANTICS, not
literals to print, and the run branches on which option was chosen, never on its text.

```
BATCH 1/2  -  what the feature is

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

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

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

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

BATCH 2/2  -  what constrains it

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

Q6: 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)

Q7: 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 each batch is submitted, pipe every Other-provided string into
`~/.claude/lib/context-link-extractor.sh` on **stdin** (`printf '%s' "$answer" | ~/.claude/lib/context-link-extractor.sh`)  -  it takes no argv, and an
argv call silently returns `[]` rather than erroring. Results are typed and written to `state.analysisSpec.contextLinks[]`. Standards-question 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).

**Type detection rules for every Other input** (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) |
| Starts with `/` or `~` and ends with `.docx` / `.pdf` / `.md` / `.markdown` / `.txt` | `document` (`metadata.source: path`) | `~/.claude/lib/fetch-document.sh <path>`  -  see the `evidence.md` fetch table |
| An `http(s)://` URL whose path ends with `.docx` / `.pdf` / `.md` / `.markdown` / `.txt` | `document` (`metadata.source: url`) | Same fetcher; the file is downloaded first |
| 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` |

Standards question  -  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`

Firebase question  -  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, 3 questions)

One `AskUserQuestion` call with 3 parallel questions  -  or 2 when
`state.analysisSpec.platforms[]` is empty, since `uiTests` only gates a section the
development layer would have carried (see the gating table in Step 5). 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"   (skipped entirely when platforms[] is empty)
    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"

Q3: header="Redesign"
    question: <localized: "Does this replace something that already exists? A redesign also records what v1 does today and where each behaviour goes.">
    options:
      - label: "New work"  -> state.analysisSpec.options.redesign = false (default)
      - label: "Redesign"  -> state.analysisSpec.options.redesign = true
```

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

`options.redesign` gates Sections 4.5, 4.6 and 9.5 and loads `analysis/redesign.md`, read
on no other run (Locked 37).

#### 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.
