Subchapter 27.18
references/phases/clarify/clarify-assemble.mdMarkdown60 KBView on GitHub
Assembler unit. The single creator of
preferences.jsonand the owner of its final contract. Seeclarify.mdfor how it is composed into the phase.
Schema reference: references/shared/schema-preferences.md.
Fragments compute rows. The assembler is the only thing that talks to the user, and it
runs three gates in order, plus the two GCP-specific mechanisms (fast paths, Full Flow
opt-out) that live in clarify.md and short-circuit before reaching this file. See
clarify.md § Step 2 for why presentation is centralised here.
One extraction step does not belong to any single fragment because it gates a report callout, not a design constraint:
BigQuery / analytics warehouse — Set bigquery_present to true if any of: (a) a
resource in gcp-resource-inventory.json has gcp_type (or equivalent type field) starting
with google_bigquery_; (b) billing-profile.json lists a service/SKU that clearly indicates
BigQuery (e.g., service name or SKU contains BigQuery). Otherwise bigquery_present is
false. Record in metadata.inventory_clarifications.bigquery_present.
When to run: Always in wizard mode, after all triggered fragments return their rows — whenever at least one row is DETECTED or PROPOSED.
Skip Gate 1 only when every active row is ESSENTIAL or N/A (rare — e.g., empty discovery with Category A only). Proceed directly to Gate 2.
HARD GATE — do NOT ask any essential question until the user responds to this sheet.
Present the sheet in two sections (omit rows for questions that are ESSENTIAL or N/A). Keep each consequence to one line — use the consequence text supplied by each row’s fragment:
### Migration assumptions — confirm or correct
**Detected from your Terraform, billing, and code:**
| Setting | Value | Source | What it decides |
| ------- | ----- | ------ | --------------- |
| Region | us-west-2 (GCP us-west1) | gcp-resource-inventory.json | All AWS resources deploy here |
| Database availability | Single-AZ (Cloud SQL `ZONAL`) | Terraform `availability_type` | RDS single-AZ topology |
| Database size | up to 10 GB allocated (actual data may be less) | Terraform `disk_size` | Migration tool ceiling; script measures actual size |
| DB traffic / I/O | Steady / Low (dev-tier `db-f1-micro`) | Terraform tier + ZONAL | gp3 storage, no replicas |
| Cloud SQL HA | Zonal (1 instance) | billing-profile.json | No Aurora Multi-AZ failover |
| AI model | gemini-2.5-flash | ai-workload-profile.json | Bedrock mapping baseline |
**Assumed (documented defaults — correct anything that's wrong):**
| Setting | Assumed value | Consequence if left as-is |
| ------- | ------------- | ------------------------- |
| Multi-cloud | AWS-only | ECS Fargate eligible; multi-cloud would force EKS |
| Cloud Run spend | $100–$500/mo | Feeds migrate-vs-stay analysis |
| AI priority | Balanced | Sonnet-class default model |
| AI latency | Important (<2s) | Sonnet + streaming; <500ms would force Haiku/Nova |
| WebSockets | None (unverified — no code scan) | Standard ALB config |
Q27 (AWS Activate credits) is **not** on this sheet — it is asked in Gate 2 when AI
workloads are detected.
Reply:
1. **Confirm all** (or "looks good") — I'll record these and ask only the [N] essential
questions.
2. **Change a setting** — name it precisely (**"availability: mission-critical"**, **"ai
priority: cost"**, **"websockets: yes"**) or just describe it in plain words (**"our
database going down would be really bad"** — I'll map it or ask the full question). You
can fix several in one message.
3. **"ask me about [setting]"** — I'll ask the full question with all options for that item.
4. **"ask me everything"** — discard all assumptions and run the full question-by-question
flow.Present these as selectable options via the structured question tool (e.g. AskUserQuestion) when the IDE provides one; otherwise show the numbered list above verbatim. Free-text corrections are always accepted in either mode — the menu supplements the override grammar, it never replaces it.
Computing [N]: Count ESSENTIAL dispositions across all triggered fragments, plus any rows
converted to ESSENTIAL via user correction (“ask me about X”), plus conflict rows. Subtract
any ESSENTIAL questions that were already answered by a user correction on the sheet (e.g.,
user said "availability: mission-critical" — the availability question no longer needs
asking).
Multi-instance Cloud SQL conflicts: When instances disagree, replace the single-row summary with a per-instance table and keep the conflicting question ESSENTIAL until resolved:
| Instance | availability_type | tier | disk_size (GB) |
| -------- | ----------------- | ---- | -------------- |
| google_sql_database_instance.main | ZONAL | db-f1-micro | 10 |
| google_sql_database_instance.analytics | REGIONAL | db-n1-standard-4 | 100 |
These instances disagree on availability. Which posture should we use for the migration design?
1\) Most conservative (highest HA) | 2\) Use [instance name] as primary | 3\) Ask me the full availability questionOverride handling — when the user corrects a value (detected or assumed):
| User correction (examples) | Update constraint | Re-ask? |
|---|---|---|
availability: mission-critical / multi-az-ha | availability: "multi-az-ha", chosen_by: "user" | No — value is explicit |
availability: significant / multi-az | availability: "multi-az", chosen_by: "user" | No |
availability: dev / single-az | availability: "single-az", chosen_by: "user" | No |
db size: <10GB / 10-100GB / etc. | Set db_size to stated band, chosen_by: "user" | No if band is explicit |
region: [AWS region] | Set target_region, chosen_by: "user" | No |
model: [model name] | Set ai_model_baseline, chosen_by: "user" | No if maps cleanly |
websockets: yes | Set websocket: "required", chosen_by: "user" | No |
spend: $5K-$20K | Set gcp_monthly_spend, chosen_by: "user" | No if band is explicit |
ai priority: cost / speed / quality | Set ai_priority, chosen_by: "user" | No |
multi-cloud: yes | compute: "eks", chosen_by: "user"; Q8 → N/A; Q7b → N/A (App Engine → EKS) | No |
| “ask me about [setting]” | Convert that row to ESSENTIAL | Yes — full question |
| Vague correction (“that’s wrong”) | Convert that row to ESSENTIAL | Yes — full question |
For each override: set chosen_by: "user" on the constraint (this removes the source
field since it’s no longer extracted/default). For extracted rows, also remove the question
ID from metadata.questions_skipped_extracted; for assumed rows, remove it from
metadata.questions_defaulted.
When the user confirms (“looks good”): no further action needed — the constraint objects
already carry their chosen_by and source fields.
“Ask me everything”: clear questions_skipped_extracted and questions_defaulted; set
all previously extracted/assumed constraints to pending; set metadata.clarify_mode: "full"
and run the Full Flow variant (below) instead of Gate 2.
Constraint source field: When writing a constraint with chosen_by: "extracted" or
chosen_by: "default", include the source field on the constraint object itself:
"terraform:availability_type=ZONAL",
"billing:region=us-west1", "ai-profile:integration.pattern=direct_sdk")"default:<Qid>" (e.g. "default:Q16")Omit source when chosen_by is "user" or "derived".
After the user responds, write preferences-draft.json with all resolved values and
metadata.wizard_stage: "essentials_pending", then proceed to Gate 2.
Fire when: User explicitly opts in. Default behavior when disabled: Apply conservative defaults — no HA upgrades, no right-sizing.
Superseded by clarify-global.md‘s cost-optimization-appetite row for the right-sizing
half: per references/vendored/clarify/clarify-cost-appetite.md § “What a consuming skill
supplies” item 1, a run that resolved that row to aggressive should behave as if it opted
into right_sizing: true here without asking Q-E2 separately. Q-E1 (HA upgrade opt-in)
remains a distinct opt-in.
If the user opts in, present after the essentials:
1) Yes — upgrade to Multi-AZ for higher availability | 2) No — keep current topology
Interpret → ha_upgrade: 1 → true, 2 → false. Default: 2 → false.
Skip when the cost-optimization-appetite row already resolved to aggressive — apply
right_sizing: true directly per the supersession rule above instead of asking.
1) Yes — right-size based on utilization | 2) No — match current capacity
Interpret → right_sizing: 1 → true, 2 → false. Default: 2 → false.
Prerequisite: Gate 1 sheet confirmation must be complete (user said “looks good” or finished correcting) before asking anything. Do not re-show the full sheet here unless the user asks for a recap.
COMPLIANCE SELF-CHECK (do this before emitting any question): Verify both: (1) the Assumption Sheet was presented in a previous turn, and (2) the user has responded to it. If either is false, STOP — present the sheet and wait. Never combine the sheet and essential questions in a single message, and never ask a question that has a sheet row unless the user converted it via a correction or “ask me about X”.
BigQuery / deferred analytics (mandatory callout): If bigquery_present is true,
output this block once, before any questions (same turn as the essentials), then
continue:
BigQuery / analytics warehouse: Your discovery inputs include BigQuery. This skill does not select an AWS analytics or data-warehouse target (no Athena, Redshift, Glue, or EMR recommendation from the plugin). Before warehouse, data lake, SQL analytics, or BI cutover planning, engage your AWS account team and/or a data analytics migration partner to assess query patterns, data volumes, ETL/ELT, and downstream consumers. Design will mark these resources as
Deferred — specialist engagement.
Present the essential questions (from each fragment’s disposition, plus any rows converted by “ask me about X”) in batches of at most 4 per turn, numbered from 1, with the question text, context, and options from the fragment files. Typical total: 2–7.
Batch composition: core first (Q1/Q2/Q3/Q3.5/Q7 + conflicts, from clarify-global.md),
then AI/agentic (Q15, Q23–Q25, multi-workload confirmations, from clarify-ai.md). Q27 is
not batched — ask it as its own short follow-up after the last batch, per the presentation
rule in clarify-ai.md Q27 (it’s a funding question, not a technical one). Write
preferences-draft.json between batches (same schema as preferences.json plus
metadata.wizard_stage). When more than one batch is needed, open each with a progress line:
“Batch [i] of [k].”
Open the first batch with:
That leaves [N] decisions only you can make — then we're ready to design.
You can answer in shorthand ("1A 2C 3 skip"), describe answers in plain words,
skip individual ones (I'll use the documented default), or say
"use defaults for the rest."
Question 1: [Q2 text with context and options]
Question 2: [Q7 text with context and options]
...Present each question’s options via the structured question tool (e.g. AskUserQuestion) when the IDE provides one — one tool call per batch, identical option text. Otherwise use the lettered options in chat as shown. Shorthand and plain-word answers are accepted in either mode.
This ≤4 cap applies to wizard essentials only. The Full Flow variant below keeps its documented three-batch structure — the user explicitly opted into the long path and has shorthand answering.
Wait for the user’s response. Do NOT proceed to Design without a response or an explicit “use defaults for the rest.”
“Use defaults for the rest” handling: Apply documented defaults for all unanswered essential questions except those marked “never assumed” in each fragment when a safe default genuinely does not exist:
compliance: {value: ["unknown"], chosen_by: "default", source: "default:Q2"}. Never record silent “no requirements”; ["unknown"]
behaves like “none” for service selection but triggers the report compliance caveat. See
references/vendored/clarify/clarify-compliance.md.startup_program_status: "unknown" with chosen_by: "default" and
source: "default:Q27"; downstream artifacts must use neutral Activate copy (both tiers, no
“your status: eligible_*”).chosen_by: "default".
Then run the Answer Recap (below) with the defaulted rows included, then Category E
opt-in, then Step 5.Interpret answers using the interpret rules in each fragment file. Apply early-exit rules
triggered by answers (e.g., the multi-cloud row’s correction to “yes” → compute: "eks", Q8 →
N/A).
After the last essential batch is answered and interpreted (and after Q27 when it fired), play back what was recorded — the essentials are the only answers in the flow the user states rather than confirms, and shorthand (“1A 2C”) plus plain-word answers pass through an interpretation step the user never sees. One compact table, questions asked in Gate 2 only (sheet rows were already confirmed at Gate 1 — do not repeat them):
### What I recorded — last check before design
| Question | Your answer | Recorded as |
| -------- | ----------- | ----------- |
| Compliance (Q2) | "2A" | None |
| Cutover window (Q7) | "monthly is fine" | Monthly maintenance window |
| AI spend (Q15) | "about a grand" | $500–$2K/month |
Anything wrong? Name it ("cutover: weekly") — or say "looks good" and I'll proceed to design.Always wait. Present the recap and wait for the user’s response (“looks good” or a
correction) before continuing — interpretation is exactly where a misread silently becomes a
design constraint, and the batch opener invites shorthand and plain-word answers, so nearly
every real run involves interpretation. One extra turn at the single highest-stakes commit in
the flow is the intended cost. Corrections use the Gate 1 override grammar and set
chosen_by: "user".
Sequence (fixed — do not reorder or combine):
billing-profile.json exists) → waitpreferences.json“Use defaults for the rest” still gets a recap: when the user defaults remaining
questions, include those rows with (default applied) in the “Your answer” column and the
defaulted value in “Recorded as” — bulk-defaulting is the highest-risk interpretation of all,
and this is the user’s one chance to see what “the rest” actually meant. Then wait as above.
GCP-specific — azure-to-aws has no equivalent opt-out flow. When the user opted out of
the wizard, run the progressive-batch flow: present ALL active questions (no dispositions) in
up to three batches — Strategic (Q1–Q7, minus Q4), Infrastructure (Q8–Q13b including Q11b
Graviton and Category B), AI (Q14–Q27, Q23–Q26 only if agentic) — writing
preferences-draft.json
between batches with metadata.batches_completed / metadata.batches_remaining (values:
"strategic", "infrastructure", "ai"). Per-question skip and “use defaults for the rest”
behave as documented. Set metadata.clarify_mode: "full". The Answer Recap above runs
after the final batch here too (all answered questions as rows; skipped/defaulted ones
summarized in one line, not per-row — intentional compression so a 20+ question full-flow
recap stays scannable; the wizard already shows every defaulted essential as a (default applied) row because that set is small. Do not silently drop answered questions into the
one-liner).
After the essentials are answered (but before writing final preferences.json), offer
Category E if billing-profile.json exists:
“Would you also like HA upgrade and right-sizing recommendations based on your billing data? If not, I’ll use conservative defaults (no upgrades, match current capacity).”
If user opts in, present Q-E1, and Q-E2 unless the cost-optimization-appetite row
already resolved to aggressive (then apply right_sizing: true without asking Q-E2).
Otherwise, apply Category E defaults (ha_upgrade: false, right_sizing: false).
| Scenario | Key Answers | Recommendation |
|---|---|---|
| Early-stage funding path | Q3 = lower spend band | Entry-tier migration funding program review |
| Growth-stage funding path | Q3 = higher spend band | Migration funding/support program review based on spend profile |
| Managed platform preference | Q7b = 1 (managed platform) | Elastic Beanstalk for App Engine compute targets |
| Container orchestration pref | Q7b = 2 (container orchestration) | ECS Fargate for App Engine targets (overrides default EB mapping) |
| Serverless pref | Q7b = 3 (serverless) | Lambda for App Engine targets (overrides default EB mapping) |
| Must stay portable | Multi-cloud row = Yes | EKS only, no ECS Fargate; App Engine also routes to EKS (Q7b N/A, overrides default EB mapping) |
| Kubernetes-averse | Multi-cloud row = No + Q8 = Frustrated | ECS Fargate strongly recommended |
| WebSocket app | Q9 = Yes | ALB WebSocket config required |
| Low-traffic Cloud Run | Q10 = Business hours + Q11 < $100 | Recommend staying on Cloud Run |
| Cloud SQL Postgres — dev/low HA | Availability row = Inconvenient + Cloud SQL in inventory | RDS PostgreSQL single-AZ |
| Cloud SQL Postgres — prod HA (RDS) | Availability row = Significant Issue + Cloud SQL in inventory | RDS PostgreSQL Multi-AZ |
| Cloud SQL Postgres — mission-critical | Availability row = Mission-Critical + Cloud SQL in inventory | Aurora PostgreSQL Multi-AZ; apply Q12/Q13 |
| Cloud SQL Postgres — global catastrophic | Availability row = Catastrophic + user_geography = Global + Cloud SQL in inventory | Aurora PostgreSQL Global Database |
| High I/O database (RDS path) | Availability = Inconvenient/Significant + Q13 = High | RDS io2 or Provisioned IOPS |
| High I/O database (Aurora path) | Availability = Mission-Critical/Catastrophic + Q13 = High | Aurora I/O-Optimized |
| Write-heavy global DB | Availability = Mission-Critical/Catastrophic + Q12 = Write-heavy/global | Aurora DSQL architecture review (RDS path only: size writer; flag review) |
| Rapidly growing DB (RDS path) | Availability = Inconvenient/Significant + Q12 = Rapidly growing | RDS with headroom on instance class |
| Rapidly growing DB (Aurora path) | Availability = Mission-Critical/Catastrophic + Q12 = Rapidly growing | Aurora Serverless v2 |
| Zero downtime required | Q7 = No downtime | Blue/green + AWS DMS required (RDS or Aurora blue/green per availability row) |
| HIPAA compliance | Q2 = HIPAA | BAA services only, specific regions |
| FedRAMP required | Q2 = FedRAMP | GovCloud regions only |
| CCPA / CPRA | Q2 = 7 (CCPA / CPRA) | Consumer privacy, logging/retention, data-inventory posture; confirm regions with legal review |
| Gateway-only AI | Q14 = 2 only (LLM router/gateway) | Config change only; skip SDK migration |
| LangChain/LangGraph AI | Q14 includes 3 | Provider swap via ChatBedrock; 1–3 days |
| OpenAI Agents SDK | Q14 includes 5 | Highest AI effort; AgentCore (Harness/Runtime); 2–4 weeks |
| Multi-agent + MCP | Q14 = 4 + 6 | AgentCore to unify orchestration + MCP (Gateway) |
| Voice platform AI | Q14 includes 7 | Check native Bedrock support; Nova 2 Sonic if needed |
| GPT-5.5 migration | Q19 = GPT-5.5 | Claude Opus 4.6 — Bedrock 17% cheaper on output; or Sonnet 5 for 68% savings |
| GPT-5.5 Pro migration | Q19 = GPT-5.5 Pro | Nova 2 Pro — 95% cheaper on Bedrock |
| GPT-5.4 migration | Q19 = GPT-5.4 | Claude Sonnet 5 — ~36% cheaper blended; AWS consolidation |
| GPT-5.4 Mini/Nano migration | Q19 = GPT-5.4 Mini or Nano | Nova Lite/Micro — 87-94% cheaper on Bedrock |
| GPT-4 Turbo migration | Q19 = GPT-4 Turbo | Claude Sonnet 5 — 80% cheaper on input |
| o-series migration | Q19 = o-series | Claude Sonnet 5 with extended thinking |
| High-volume cost-critical AI | Q18 = High + cost critical | Nova Micro or Haiku 4.5 + provisioned throughput |
| Reasoning/agent workload | Q17 = Extended thinking | Claude Sonnet 5 extended thinking; Opus 4.6 for hardest |
| Speech-to-speech AI | Q17 = Real-time speech | Nova 2 Sonic |
| RAG workload | Q17 = RAG optimization | Bedrock Knowledge Bases + Titan Embeddings |
| Vision workload | Q20 = Vision required | Claude Sonnet 5 (multimodal) |
| Latency-critical AI | Q21 = Critical | Haiku 4.5 or Nova Micro + streaming |
| Complex reasoning tasks | Q22 = Complex | Claude Sonnet 5; Opus 4.6 for hardest |
Assemble all resolved values — sheet confirmations, corrections, essential answers, and
defaults — into the final $MIGRATION_DIR/preferences.json. Every constraint object MUST
include prompt and design_consequence per references/shared/schema-preferences.md
(use the constraint catalog when the user did not see the verbatim question).
If preferences-draft.json exists, use it as the base — merge in the final answers, remove
the draft-specific metadata fields (draft, wizard_stage, batches_completed,
batches_remaining), and set metadata.timestamp to the current time. Write
$MIGRATION_DIR/preferences.json:
{
"metadata": {
"migration_type": "full",
"timestamp": "<ISO timestamp>",
"discovery_artifacts": ["gcp-resource-inventory.json", "ai-workload-profile.json"],
"questions_asked": ["Q2", "Q7", "Q15", "Q27"],
"questions_defaulted": ["Q5", "Q9", "Q11", "Q11b", "Q16",
Full schema and constraint catalog: references/shared/schema-preferences.md.
design_constraints, ai_constraints, and startup_constraints (when
present) is an object with value, chosen_by, prompt, and
design_consequence fields. Optional question_id when mapped to the Q1–Q27
catalog. Optional source when chosen_by is "extracted" or "default".prompt: verbatim question from the fragment file when chosen_by is "user";
detection label when "extracted"; question + " (default applied)" when "default";
derivation label when "derived".design_consequence: one sentence from the fragment’s Recommendation Impact for the
selected answer, or the catalog template in schema-preferences.md with [value]
substituted.chosen_by values: "user" (explicitly answered or corrected on the sheet), "default"
(documented default applied — includes sheet-confirmed defaults and “I don’t know”
answers), "extracted" (inferred from inventory), "derived" (computed from combination
of answers + detected capabilities).source field on constraints: Every constraint with chosen_by: "extracted" or
chosen_by: "default" MUST include a source field. Extracted: raw provenance signal
(prefix terraform:, billing:, code:, inventory:, ai-profile:, or artifact
filename). Default: "default:<Qid>". Omit source for "user" and "derived". Report
generation uses source prefixed default: to flag unverified assumptions.design_constraints / ai_constraints if the answer produces a
constraint. Absent keys mean “no constraint — Design decides.”prompt or design_consequence on any written
constraint.metadata.inventory_clarifications records Category B
answers.metadata.questions_skipped_early_exit records questions skipped due to early-exit logic
(e.g., Q8 skipped because the multi-cloud row resolved to “yes”).metadata.questions_skipped_extracted records questions resolved because inventory
already provided the answer.metadata.questions_defaulted records questions resolved by documented default — whether
sheet-confirmed (wizard) or skipped (full flow / “use defaults”).metadata.questions_skipped_not_applicable records questions skipped because the
relevant service wasn’t in the inventory or their firing condition wasn’t met.ai_constraints section is present ONLY if Category F fired. Omit entirely if no AI
artifacts exist.ai_constraints.ai_capabilities_required is the UNION of detected capabilities from
ai-workload-profile.json + critical feature from Q17 + vision from Q20. chosen_by is
"derived".ai_constraints.ai_framework is an array (Q14 is select-all-that-apply). If
auto-detected, chosen_by is "extracted" with source.metadata.clarify_mode is one of "wizard", "full", "fast_path",
"simple_hybrid".After writing preferences.json, delete $MIGRATION_DIR/preferences-draft.json and
$MIGRATION_DIR/preferences-superseded.json if they exist (the superseded backup has served
its purpose once a new complete file exists).
Documented defaults for every question. Used by: PROPOSED sheet rows (wizard), per-question skips, “use defaults for the rest”, and the fast paths.
| Question | Default | Constraint |
|---|---|---|
| Q1 — Location | 1 (single region) | target_region: closest AWS region to GCP region |
| Q2 — Compliance | unknown (unconfirmed) | compliance: ["unknown"] — treated as no-constraint for service selection; report caveat (essential — defaulted only via “use defaults for the rest”) |
| Q3 — GCP spend | 2 ($1K–$5K) | gcp_monthly_spend: "$1K-$5K" (essential when no billing — same caveat rule as Q2) |
| Q3.5 — GCP CUDs | 5 (none) | cud_status: "none" (essential when it fires — billing shows CUDs, so only defaulted via “use defaults for the rest”) |
| Q4 — Funding stage | (skip in IDE mode) | no constraint |
| Q5 — Multi-cloud | 2 (AWS-only) | no constraint |
| Q6 — Availability | 2 (significant) — GCP-specific default; see references/vendored/clarify/clarify-availability.md § 2 | availability: "multi-az" |
| Q7 — Maintenance | 4 (flexible) | cutover_strategy: "flexible" |
| Q7b — Compute model | 1 (managed platform) | compute_model: "managed_platform" (App Engine only; N/A if no App Engine, or if the multi-cloud row = yes → App Engine routes to EKS) |
| Cat B — Cloud SQL HA | Zonal | metadata.inventory_clarifications |
| Cat B — Cloud Run count | 1 service | metadata.inventory_clarifications |
| Cat B — Memorystore memory | estimate from usage | metadata.inventory_clarifications |
| Cat B — Functions gen | Gen 1 | metadata.inventory_clarifications |
| Q8 — K8s sentiment | 3 (Fargate) | kubernetes: "ecs-fargate" |
| Q9 — WebSocket | 2 (no) | no constraint |
| Q10 — Cloud Run traffic | 3 (24/7) | cloud_run_traffic_pattern: "constant-24-7" |
| Q11 — Cloud Run spend | 2 ($100–$500) | cloud_run_monthly_spend: "$100-$500" |
| Q11b — CPU architecture | 1 (Graviton) | cpu_architecture: "graviton" (or "mixed" if any service is incompatible; "x86" if no compatible compute) — usually auto-defaulted without asking; see clarify-compute.md Q11b decision table |
| Q12 — DB traffic | 1 (steady) | database_traffic: "steady" |
| Q13 — DB I/O | 2 (medium) | db_io_workload: "medium" |
| Q13b — DB size | 5 (unknown) | db_size: "unknown" → default to pgcopydb |
| Q14 — AI framework | (auto-detect) | ai_framework from code detection, fallback ["direct"] |
| Q15 — AI spend | 2 ($500–$2K) | ai_monthly_spend: "$500-$2K" (essential — defaulted only via “use defaults for the rest”) |
| Q16 — AI priority | 5 (balanced) | ai_priority: "balanced" |
| Q17 — Critical feature | 10 (none) | no additional override |
| Q18 — Volume + cost | 1 (low + quality) | ai_token_volume: "low" |
| Q19 — Current model | (auto-detect) | ai_model_baseline from code detection |
| Q20 — Input types | 1 (text only) | no constraint |
| Q21 — AI latency | 2 (important) | ai_latency: "important" |
| Q22 — Task complexity | 2 (moderate) | ai_complexity: "moderate" |
| Q23 — Agentic approach | (framework-based auto-detect; see clarify-ai.md) | ai_constraints.agentic.migration_approach |
| Q24 — Agent memory | 2 (session) | ai_constraints.agentic.memory_requirement: "session" |
| Q25 — Task duration | 2 (medium) | ai_constraints.agentic.task_duration: "medium" |
| Q26 — Incremental | path-based | incremental_migration: true for Harness path, false for retarget |
| Q27 — Activate credits | (essential when Category H fires — ask in Gate 2; skip only via explicit answer or “use defaults for the rest”) | startup_program_status per answer; skip → "unknown" with neutral downstream copy |
| Q-E1 — HA upgrade | 2 (no) | ha_upgrade: false |
| Q-E2 — Right-sizing | 2 (no) | right_sizing: false |
Before handing off to Design:
chosen_by: "extracted" or chosen_by: "default" has a source
field with the correct prefix (terraform:, billing:, inventory:, ai-profile:,
or default:<Qid>)preferences.jsonbigquery_present was true, the mandatory BigQuery specialist advisory was
shown before questions — or, if clarify.md Step 0 option 1 (reuse preferences),
the same advisory was shown after BigQuery detectionpreferences.json written to $MIGRATION_DIR/design_constraints.target_region is populated with value and chosen_bydesign_constraints.compliance is populated (never silently absent — the compliance
question always fires per references/vendored/clarify/clarify-compliance.md)design_constraints.availability is populated when Cloud SQL PostgreSQL/MySQL is in
inventory (asked, extracted, or defaulted — Design must not run with absent/null
availability)design_constraints.cpu_architecture is set to
graviton, x86, or mixed per the Q11b decision tabledesign_constraintsdesign_constraints and ai_constraints has value and chosen_by
fieldsmetadata.inventory_clarifications (billing mode only)metadata.questions_skipped_early_exitai_constraints section present ONLY if Category F firedai_constraints.ai_framework is populated (from detection or Q14)ai_capabilities_required is derived from detection + Q17 + Q20ai_constraints.ai_framework is an array (Q14 is multi-select)preferences-draft.json has been deleted (if it existed)metadata.clarify_mode is set to "wizard", "full", "fast_path", or
"simple_hybrid"Load shared/handoff-gates.md. Re-read from disk before checking.
Re-entry guard: If aws-design.json (or aws-design-ai.json / aws-design-billing.json)
exists and phases.design is "completed": STOP unless the user explicitly confirms
re-running Clarify. Emit GATE_FAIL | phase=clarify | field=aws-design.json | reason=stale_downstream.
Checks (all must PASS):
preferences.json exists and parses as JSON.metadata.clarify_mode).gcp-resource-inventory.json contains google_sql_database_instance →
design_constraints.availability.value is set (non-null, non-empty).metadata.clarify_mode is "wizard" → at least one constraint has a source field OR
every active question was essential.metadata.questions_asked contains no question ID that also
appears in metadata.questions_skipped_extracted or metadata.questions_defaulted. (A
question may move between lists only if the user converted its sheet row — in which case
the override handling moved it to questions_asked.)gcp-resource-inventory.json, or billing-source compute) → design_constraints .cpu_architecture.value is set (graviton | x86 | mixed), per the Q11b decision table
in clarify-compute.md — written even when Q11b was auto-defaulted.metadata.clarify_mode is
"full" — the user explicitly opted into the full question flow): If every
google_sql_database_instance in gcp-resource-inventory.json carries an unambiguous disk
size (config.disk_size_gb or legacy variants, all mapping to the same Q13b band) →
Q13b must NOT appear in metadata.questions_asked unless design_constraints.db_size .chosen_by is "user" (the user converted the sheet row via “ask me about X” or corrected
it). If instances map to different bands (e.g. an 8 GB dev instance and a 200 GB prod
instance), the size is ambiguous — this check does NOT fire, and asking Q13b is the
expected behavior (matching the clarify-database.md auto-detect rule “if multiple
instances disagree, ask Q13b”). Otherwise: GATE_FAIL | phase=clarify | field=metadata.questions_asked | reason=extractable_question_asked_Q13b.metadata.clarify_mode is "full"): If
ai-workload-profile.json exists with models[0].model_id set at confidence ≥ 0.8 →
Q19 must NOT appear in metadata.questions_asked unless ai_constraints .ai_model_baseline.chosen_by is "user". Otherwise: GATE_FAIL | phase=clarify | field=metadata.questions_asked | reason=extractable_question_asked_Q19. (Detect-confirm
cards for sub-threshold or tied detection per clarify-ai.md are not affected — they fire
only when confidence < 0.8.)On any FAIL: Emit GATE_FAIL | phase=clarify | field=<path> | reason=missing. Do NOT
modify artifacts to pass the gate. Do NOT update .phase-status.json. Tell the user to
answer the missing question or re-run Clarify.
On PASS: Emit HANDOFF_OK | phase=clarify | artifacts=preferences.json.
Only after HANDOFF_OK. In the same turn as the output message below, use the Phase
Status Update Protocol (Write tool) to write .phase-status.json with phases.clarify set
to "completed".
Output to user: “Phase 2 of 6 complete (Clarify). Remaining: Design → Estimate → Generate (+ optional Feedback). Next artifact: aws-design.json. Proceeding to Phase 3: Design AWS Architecture.”
Breadcrumbs are emitted only after outer-run HANDOFF_OK — never on GATE_FAIL, never from
inner workshop reprices.
This phase covers requirements gathering ONLY.
FORBIDDEN — Do NOT include ANY of:
Your ONLY job: Understand what the user needs. Nothing else.
Implemented. This file absorbs everything the prior monolithic clarify.md did after
extraction — the Assumption Sheet, the essential-questions batching, the Answer Recap,
Category E, the Full Flow variant, the preferences.json write, the Defaults Table, the
Validation Checklist, and the Completion Handoff Gate — matching the responsibility split
azure-to-aws‘s clarify-assemble.md already has, adapted to GCP’s larger built-in
structure (fast paths, Full Flow opt-out, Category E) that Azure’s assembler does not need.
No firing rule, default, or interpretation rule changed in this move.