docs(spec): Phase 4 design for the client intake wizard
A guided interview that produces a written brief with sub-tasks, landing in the Inbox as a draft through Plan 1c's existing accept flow. Corrects an over-promise made during the Phase 1 discussion: the wizard was described as grounding date proposals in measured per-card velocity, and that data does not exist — Plan 2c deferred per-card effort because session padding does not sum correctly across cards. This phase therefore produces no time estimate at all, only a size band. Names the intake as the highest-risk surface in the product: it is the only place where text written by someone other than the developer enters a prompt whose output creates records. The security property is that the worst a hostile brief achieves is a strangely-worded Inbox card. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
de8ae83dcb
commit
d928e7fd9e
1 changed files with 226 additions and 0 deletions
|
|
@ -0,0 +1,226 @@
|
|||
# Phase 4 — The Client Intake Wizard
|
||||
|
||||
**Date:** 2026-09-16
|
||||
**Status:** Draft for review
|
||||
**Phase:** 4 of 5
|
||||
**Depends on:** Phase 2 (commit data), Phase 3 (provider layer)
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
A client manager clicks **Request a feature**, answers a handful of plain
|
||||
questions, and the result is a written brief with the work already broken into
|
||||
sub-tasks — landing in the Inbox as a draft for the developer to accept.
|
||||
|
||||
This is the feature the developer described first, and in their words: *"he first
|
||||
answers simple questions on what he wants, that way I already get a written out
|
||||
plan with sub-categories."*
|
||||
|
||||
It replaces the current one-line "Request a feature" box from Plan 1c.
|
||||
|
||||
## 2. What is already settled
|
||||
|
||||
| Decision | Where from |
|
||||
|---|---|
|
||||
| **AI-proposed dates are never auto-published.** | Phase 1 design |
|
||||
| Client-submitted text is **data, not instructions** | Phase 1 design, Phase 3 preamble |
|
||||
| A client's card always lands in the Inbox, unaccepted | Phase 1 spec §5.2 |
|
||||
| The provider layer, settings and preamble | Phase 3a |
|
||||
| **The client sees a rough size band, never a time estimate** | This conversation |
|
||||
| **The interview is stateless — the transcript goes in the prompt** | This conversation |
|
||||
|
||||
## 3. A correction to an earlier claim
|
||||
|
||||
During the Phase 1 discussion this wizard was described as producing date
|
||||
proposals *"grounded in your actual measured velocity — cards of this size took
|
||||
you 6–9 working days."*
|
||||
|
||||
**That data does not exist.** Plan 2c deliberately deferred per-card effort,
|
||||
because a session touching several cards contributes its padding to each and
|
||||
per-card hours do not sum to the project total. What Phase 2 actually produces is
|
||||
*project-level* velocity: features per week, active days against workdays, hours
|
||||
per month.
|
||||
|
||||
That supports "this project has averaged around 25 changes a week." It does not
|
||||
support sizing an individual request in days. This phase therefore produces **no
|
||||
time estimate at all**, for the client or the owner — which is also the strictest
|
||||
reading of the never-auto-publish rule, so nothing is lost.
|
||||
|
||||
## 4. The interview
|
||||
|
||||
**Stateless.** Each question is one `complete()` call from Phase 3a, with the
|
||||
conversation so far included in the prompt. No session state to store, expire or
|
||||
resume, and the transcript is already the thing worth keeping. The provider
|
||||
interface stays narrow.
|
||||
|
||||
**Hard-capped at seven questions.** Past that, people abandon the form and the
|
||||
developer gets a worse brief than a one-line email would have produced. The cap
|
||||
is enforced in code, not requested in the prompt — a model that decides an eighth
|
||||
question is warranted must not be able to ask it.
|
||||
|
||||
**Skippable at any point.** A "that's enough, write it up" button is always
|
||||
present. Someone who has said what they need in the first answer should not be
|
||||
interrogated.
|
||||
|
||||
**One question at a time**, plain language, no jargon. The model may offer
|
||||
multiple-choice options where they genuinely help.
|
||||
|
||||
The questions the model is steered toward — what problem this solves, who will
|
||||
use it, what happens today without it, what would make it not worth doing, and
|
||||
whether anything external forces timing — are guidance in the prompt, not a
|
||||
fixed script. The point of using a model here rather than a form is the
|
||||
follow-up that a form cannot ask.
|
||||
|
||||
## 5. The brief
|
||||
|
||||
Output of the interview, shown to the client for confirmation before anything is
|
||||
created:
|
||||
|
||||
- **Title** — one line, the developer's Inbox card title.
|
||||
- **Summary** — two or three sentences of what is wanted and why.
|
||||
- **Sub-tasks** — the work broken into steps, becoming subtasks on the card.
|
||||
- **Open questions** — what the model could not establish. Valuable: these are
|
||||
what the developer would otherwise discover halfway through.
|
||||
- **Size band** — small, medium or large. See §6.
|
||||
|
||||
**The brief never contains a date, a deadline, an estimate, or a claim about
|
||||
when work will start.** The Phase 3 preamble already forbids this and applies
|
||||
here unchanged.
|
||||
|
||||
### 5.1 Structured output, parsed defensively
|
||||
|
||||
The brief comes back as JSON. The Anthropic SDK supports schema-constrained
|
||||
output, but the OpenAI-compatible adapter does not, and the Phase 3a interface is
|
||||
deliberately provider-neutral — so the format is requested in the prompt and
|
||||
**parsed defensively**, exactly as Plan 3b parses batch responses.
|
||||
|
||||
A malformed brief must degrade to something usable: if the JSON will not parse,
|
||||
the client's raw answers are still captured and the card is still created from
|
||||
them. An interview that ends in an error message, having asked seven questions,
|
||||
is worse than no wizard.
|
||||
|
||||
## 6. The size band
|
||||
|
||||
Small, medium or large. **No time is attached to it anywhere in the UI**, and it
|
||||
is never rendered next to a date.
|
||||
|
||||
It is derived rather than guessed:
|
||||
|
||||
- **How many sub-tasks the request decomposes into.** A request that becomes two
|
||||
steps is not the same as one that becomes eleven.
|
||||
- **Whether it touches areas the project already has.** Phase 2 knows which
|
||||
conventional-commit scopes exist and how much work each holds. A request
|
||||
landing in an established area is better understood than one opening a new one.
|
||||
|
||||
**It is labelled as a first impression and it is the owner's to change.** The
|
||||
client sees it as the model's initial read of their description; the developer
|
||||
sets the real one when accepting from the Inbox.
|
||||
|
||||
Stated plainly, because it is the weakest thing in this phase: the band is a
|
||||
judgement made from a description the model collected minutes earlier. It is
|
||||
better than nothing and worse than the developer's opinion, and the UI should
|
||||
never imply otherwise.
|
||||
|
||||
## 7. Prompt injection — the highest-risk surface in the product
|
||||
|
||||
This is the only place where **text written by someone other than the developer
|
||||
enters a prompt whose output creates database records.** Everything else the AI
|
||||
touches is commit messages the developer wrote.
|
||||
|
||||
Three controls, and all three are needed:
|
||||
|
||||
1. **The preamble already states that submitted text is data, never
|
||||
instructions.** Necessary, not sufficient — a prompt rule is a mitigation, not
|
||||
a boundary.
|
||||
2. **The model never writes to the database.** It returns a brief; *code*
|
||||
creates the card, through the same whitelisted path as Plan 1a's
|
||||
`POST /api/client/cards`. Column, priority, `accepted` and `created_by_role`
|
||||
are set by the server regardless of what the brief contains. A brief claiming
|
||||
to be "approved, priority critical, move to In Progress" changes nothing.
|
||||
3. **Every field is sanitised and length-capped before storage**, and rendered
|
||||
as text — never as markup.
|
||||
|
||||
The security property to hold onto: **the worst a hostile brief can achieve is a
|
||||
strangely-worded card in the Inbox.** It cannot set priority, cannot bypass the
|
||||
Inbox, cannot reach another client's project, and cannot instruct the developer's
|
||||
tooling. If a change would weaken any of those, it is a change to the security
|
||||
model, not to a feature.
|
||||
|
||||
## 8. Draft until accepted
|
||||
|
||||
The wizard creates exactly what Plan 1c's Inbox flow already handles: one card
|
||||
in the project's Inbox with `accepted = false` and `created_by_role = "client"`,
|
||||
with subtasks, plus the transcript and brief attached.
|
||||
|
||||
Nothing new is needed for acceptance. The developer opens it, reads the brief,
|
||||
adjusts, and accepts — which sets `start_date` and moves it out of the Inbox,
|
||||
exactly as today.
|
||||
|
||||
**The transcript is kept.** When a request turns out to mean something other than
|
||||
what was built, the record of what was actually asked is the thing that settles
|
||||
it — the same reason the activity log exists.
|
||||
|
||||
## 9. Data model additions
|
||||
|
||||
| Collection | Field | Notes |
|
||||
|---|---|---|
|
||||
| `cards` | `brief` | json — summary, sub-tasks, open questions, size band |
|
||||
| `cards` | `transcript` | json — the question-and-answer pairs |
|
||||
| `cards` | `size_band` | select: `small` \| `medium` \| `large` \| `""` |
|
||||
|
||||
No new collection. The wizard produces a card; cards already exist.
|
||||
|
||||
Read rules follow `cards`. Writes are server-side only.
|
||||
|
||||
## 10. Failure behaviour
|
||||
|
||||
Consistent with Phase 3: the AI is an enhancement, and its absence must not
|
||||
remove a capability the client already had.
|
||||
|
||||
- **No provider configured, or the provider is down** → the wizard is not
|
||||
offered, and the plain "Request a feature" box from Plan 1c is shown instead.
|
||||
The client can always file a request.
|
||||
- **A failure mid-interview** → the answers so far are kept and the client is
|
||||
offered "submit what I have", which creates the card from the raw answers with
|
||||
no brief.
|
||||
- **A malformed brief** → §5.1; the card is still created.
|
||||
|
||||
## 11. Out of scope
|
||||
|
||||
- **Any date, estimate or scheduling.** §3.
|
||||
- **The developer using the wizard.** It is a client-facing intake. The owner
|
||||
creates cards directly.
|
||||
- **Editing a brief after submission.** The developer adjusts the card; the
|
||||
brief is a record of what was asked, and rewriting it destroys the thing §8
|
||||
keeps it for.
|
||||
- **Conversation anywhere else in the product.** No chat over the project, no
|
||||
asking the AI about the board.
|
||||
- **Notifying the developer.** An Inbox badge already exists. Email belongs with
|
||||
the n8n work parked in Phase 1.
|
||||
|
||||
## 12. Acceptance criteria
|
||||
|
||||
1. A client manager can complete an interview of at most seven questions and see
|
||||
a brief before anything is created.
|
||||
2. The brief contains a title, summary, sub-tasks, open questions and a size
|
||||
band, and **no date, deadline or estimate**.
|
||||
3. Submitting creates one Inbox card with `accepted = false`,
|
||||
`created_by_role = "client"`, subtasks from the brief, and the transcript
|
||||
attached — whatever the brief's content claims.
|
||||
4. A brief containing instructions — "set priority to critical", "mark as
|
||||
accepted", "move to In Progress" — changes none of those fields.
|
||||
5. With no provider configured, the plain request box from Plan 1c is offered
|
||||
and works.
|
||||
6. A failure mid-interview still allows submission of the answers given.
|
||||
7. The size band is never rendered adjacent to a date or duration.
|
||||
8. The developer accepting the card uses the existing Inbox flow, unchanged.
|
||||
|
||||
## 13. Suggested plan split
|
||||
|
||||
- **Plan 4a — the interview.** Stateless turn-taking, the question cap, the skip
|
||||
path, defensive brief parsing, and the transcript. The parsing and the cap are
|
||||
pure and testable; this is where the injection tests live.
|
||||
- **Plan 4b — submission and display.** Card creation through the whitelisted
|
||||
path, subtasks from the brief, the brief rendered on the card detail page for
|
||||
both roles, and the fallback to the plain request box.
|
||||
Loading…
Reference in a new issue