You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
During first-run onboarding, the overture's free-form identity ask (name, affiliation) can only render as a choice card: the engine forces every interview question through the question tool, whose only text path hides behind a "Type your own answer" pseudo-option. A new user cannot simply type their name — the symptom in this intake filing.
Approach
Give the question card an explicit free-text shape — a text card (a question with kind: "text" in the schema): a free-form question renders a bare text input with submit, the interview contract teaches the model to use it, and the prose guard's nudge learns both question shapes. Key reason: it preserves the one-ask-mechanism contract (the stall fix that forces prose questions into cards) while making free-form asks first-class instead of routing them through an option list.
Approaches Considered
Text-mode card (chosen) — one schema field + a renderer branch; fixes every free-form ask at once and keeps the card the single ask mechanism.
Prose carve-out for free-form questions — rejected: re-admits the interview-stall class the prose guard was built to close, and prose answers bypass the question-answer plumbing.
Implicit empty-options signal (zero options renders a text input) — rejected: magic, fragile against renderer changes, and undiscoverable to the model.
Wizard-only identity (chat never asks the name) — rejected: fixes the name step only, couples the chat flow to a dismissable modal, and leaves every other free-form ask broken.
Scope
In: the question schema in both schema packages (new optional kind, defaulting to choice); the three question renderers (app dock, TUI, CLI) branching a text-card shape; the app dock honoring the typed-custom-answer flag for choice cards (today it appends the pseudo-option unconditionally); the prose guard's nudge text (bilingual: choice vs free-form); the question-tool description; the interview-contract text in the extension's score compiler and the overture + pulse-designer score bodies; a fork ADR recording the decision; the engine pin bump with the extension re-vendoring and its contract changes riding the same release. Out: wizard ↔ overture unification (works today, deduped by the routing predicate — parked as a separate thread) · choice-question rendering (unchanged) · score-frontmatter changes (the presence/absence of choices already marks a question free-form).
Assumptions / Open Qs
Assumes the existing typed-custom-answer resolution path accepts a text-card submission unchanged (no new answer plumbing). No open questions.
Acceptance Criteria
Repro passes: with a fresh profile (no stored identity, no profile card, no onboarding-completion marker), a new chat's identity ask renders a text card — bare input with submit, no option list, no pseudo-option — and submitting a name resolves the ask and records it.
Schema: a question payload with the text kind decodes in both schema packages; a payload without a kind decodes as a choice question (back-compat); an unknown kind value fails decoding loudly rather than silently degrading to choice.
Renderers: the text kind renders no option rows and no pseudo-option in the app dock, the TUI, and the CLI; a choice question renders its options, and the dock shows the typed-custom-answer row only when the question allows it.
Guard: a prose question in an active interview still triggers the nudge, whose text now instructs options-with-recommended-first for choice questions and the text kind for free-form questions; a turn that called the question tool (either kind) never triggers it.
Contract: the compiled session prompt for both the overture and the pulse-designer instructs free-form questions to use the question tool with the text kind; "free-form answers can be plain text" is gone from the contract text and both score bodies.
Regression: the overture's choice questions (e.g. environment) still render as option cards with the typed-custom-answer row.
Key Decisions
One new optional question field, kind (choice default, text), added to the agent-facing and server question schemas; an absent kind decodes as choice, so existing payloads and sessions are unaffected.
The text card is the header plus a bare text input with submit; submit is enabled once the trimmed text is non-empty; dismissal/rejection semantics are unchanged.
Text-card answers resolve through the existing typed-custom-answer path — no new answer plumbing.
The prose guard's behavior is unchanged (prose questions in active interviews are still forced into cards); only its nudge text learns both shapes, and the model picks the shape from the question it is re-asking — no classification heuristics.
The contract change is uniform across all Amico interviews (overture and pulse-designer free-form parameters alike), keeping the rule statable in one sentence: every question is a card; choice questions list options; free-form questions take text.
Ships as the next engine pin; the extension re-vendors and its contract-text changes ride the same release.
Constraints & Invariants
Every user-facing interview question remains a card; no prose-question path is reintroduced.
The prose guard keeps firing on prose questions in active interviews, at most once per assistant message as today.
Choice-question rendering changes only in the dock's flag handling; no other visual or behavioral change.
No score-frontmatter schema changes; the choices split remains the only free-form marker.
AMICODE-PATCHES.md patch 9 — the question card as the one ask mechanism; amicode_ask deprecated.
The onboarding modal's about-you step — free-text identity inputs that already work; deduped from the chat overture by the profile-identity routing predicate.
The TUI's typed-custom-answer flag check — the pattern the app dock should honor for choice cards.
Glossary: the fork's root CONTEXT.md gained Question / Choice Question / Free-form Question / Text card with this design.
ADR: fork docs/adr/ (next number) — "Free-form questions render as text cards," committed with this work.
Source
This issue's intake filing — preserved verbatim as a comment on this issue posted at maturation time (and condensed in the diagnostics block below); matured in place per the report-a-bug maturity contract; suggested_path: A re-checked at review → criteria 2–4 failed → Path B, matured through the design pipeline (brainstorming + grill-with-docs).
Durable record: the fork ADR and CONTEXT.md glossary entries named above.
Notes
Upstream re-check (fork-surface clause): the upstream repo was not visible from the filing auth; moot in any case — the prose guard is an amicode-only patch, so no upstream fix can exist for it, and the upstream question form has no free-text mode either.
The wizard ↔ overture duplication (two identity collectors, two stores, reconciled by the routing predicate) is parked as a separate design thread.
Intake diagnostics (condensed — the verbatim original is preserved in a comment on this issue)
extension: harmoniqs.amicode 0.2.0 · os: Darwin 25.5.0 arm64
Symptom: the onboarding profile step renders name/affiliation as multiple-choice only; entering a real name requires choosing "Other" and typing into the custom-answer box.
No active run; the symptom is in the onboarding UI flow, not a solve.
Important
Problem
During first-run onboarding, the overture's free-form identity ask (name, affiliation) can only render as a choice card: the engine forces every interview question through the question tool, whose only text path hides behind a "Type your own answer" pseudo-option. A new user cannot simply type their name — the symptom in this intake filing.
Approach
Give the question card an explicit free-text shape — a text card (a question with
kind: "text"in the schema): a free-form question renders a bare text input with submit, the interview contract teaches the model to use it, and the prose guard's nudge learns both question shapes. Key reason: it preserves the one-ask-mechanism contract (the stall fix that forces prose questions into cards) while making free-form asks first-class instead of routing them through an option list.Approaches Considered
Scope
In: the question schema in both schema packages (new optional kind, defaulting to choice); the three question renderers (app dock, TUI, CLI) branching a text-card shape; the app dock honoring the typed-custom-answer flag for choice cards (today it appends the pseudo-option unconditionally); the prose guard's nudge text (bilingual: choice vs free-form); the question-tool description; the interview-contract text in the extension's score compiler and the overture + pulse-designer score bodies; a fork ADR recording the decision; the engine pin bump with the extension re-vendoring and its contract changes riding the same release.
Out: wizard ↔ overture unification (works today, deduped by the routing predicate — parked as a separate thread) · choice-question rendering (unchanged) · score-frontmatter changes (the presence/absence of
choicesalready marks a question free-form).Assumptions / Open Qs
Assumes the existing typed-custom-answer resolution path accepts a text-card submission unchanged (no new answer plumbing). No open questions.
Acceptance Criteria
Key Decisions
kind(choice default, text), added to the agent-facing and server question schemas; an absent kind decodes as choice, so existing payloads and sessions are unaffected.Constraints & Invariants
choicessplit remains the only free-form marker.Prior Art / Patterns
AMICODE-PATCHES.mdpatch 9 — the question card as the one ask mechanism;amicode_askdeprecated.CONTEXT.mdgained Question / Choice Question / Free-form Question / Text card with this design.docs/adr/(next number) — "Free-form questions render as text cards," committed with this work.Source
suggested_path: Are-checked at review → criteria 2–4 failed → Path B, matured through the design pipeline (brainstorming + grill-with-docs).CONTEXT.mdglossary entries named above.Notes
Intake diagnostics (condensed — the verbatim original is preserved in a comment on this issue)