8.4 KiB
Provenance: Derived vs. Questionnaire-Answered Fields
A requirement surfaced from the "Upgrading /impeccable init" landscape doc: the new visual document seed (chat asset/reference upload + local-browser slides for Color, Typography, Motion, Layout, Elevation, Iconography) must be resettable. A user can go back and redo one slide (e.g. Iconography) or the whole seed, without disturbing fields that came from somewhere else.
Everything that isn't scanned off code is a questionnaire answer in the broad sense — nothing in PRODUCT.md or DESIGN.md is invented by the agent unprompted. But "questionnaire" isn't one thing: it happens through different commands and different UIs (chat vs. a local-browser slide). "Planned" vs. "already shipped" is a maturity detail on the specific field (called out in that field's Value/Derived from columns in CONTENTS-TABLE.md), not a different provenance category — the new seed flow's chat portion is more of the same init.md/document.md-style chat interview, just under document.md; its browser portion is more of the same card-UI pattern the Layout-strictness slide already uses today. So provenance is four tags, not seven:
- Derived — read directly off existing code (scanned CSS tokens, component classes). Changing it means re-scanning, not re-asking.
- Questionnaire — In-chat (init) —
PRODUCT.mdfields, asked in chat during/impeccable init's Step 3. Today's mechanism for every non-DerivedPRODUCT.mdfield (Users, Purpose, Positioning, Brand Personality, Anti-references, Conversion & proof, Design Principles, Accessibility). Free-form, not persisted for reset. - Questionnaire — In-chat (document) —
DESIGN.mdfields asked in chat duringdocument.md. Covers both today's qualitative round (North Star name, color role names/strategy, elevation/component feel, signature-component ideas) and the new seed flow's chat portion (asset/logo/moodboard upload, three named references, one named anti-reference, the image-gen capability check). Free-form, not persisted for reset — except where the new seed work adds persistence (see below). - Questionnaire — Browser (document) —
DESIGN.mdfields asked through a visual card UI duringdocument.md. Covers both today's shipped Layout-strictness slide (Simple grid / Balanced / Editorial / Freeform) and the new seed flow's browser slides (Color amount, Visual cues, Palette tokens, Typography, Motion, Layout, Elevation, Iconography). - Computed — generated by the agent from other values (tonal ramps, breakpoints, HTML/CSS snippets). Never directly asked at all.
The persisted/resettable mechanism below is in scope only for the new, not-yet-shipped fields within Browser (document) and In-chat (document) — i.e. the fields CONTENTS-TABLE.md marks (planned). The fields already shipped under those same two tags (today's qualitative round, today's Layout-strictness slide) aren't persisted and stay that way unless retrofitted — see MISSING.md and open question #1 below.
Where it's stored
In design.json, not inline in DESIGN.md. DESIGN.md stays a clean, human-readable artifact; design.json is already the structured sidecar other tooling reads (colorMeta, typographyMeta, shadows, motion, breakpoints, components, narrative), so provenance belongs next to it, not as HTML comments scattered through the markdown.
Proposed schema addition
Two changes to design.json:
1. A source tag on existing per-field metadata, so a value's provenance travels with it:
"extensions": {
"colorMeta": {
"dusty-plum": {
"role": "primary",
"source": "crawl"
}
},
"typographyMeta": {
"display": {
"source": "questionnaire"
}
}
}
Values: "crawl", "chat-init", "chat-document", "browser-document", "computed". A field's (planned) status (i.e. whether it's part of the new, not-yet-shipped seed work) is tracked by whether it has a questionnaire.sections entry at all, not by a separate source value — see the block below.
2. A top-level questionnaire block — the actual answer log, keyed by slide/section, needed for reset at either granularity:
"questionnaire": {
"version": 1,
"lastRunAt": "2026-07-09T22:40:00.000Z",
"sections": {
"assets": { "status": "answered", "answeredAt": "...", "answers": { "logos": [], "referenceImages": [], "moodboards": [] }, "producedPaths": [] },
"references": { "status": "answered", "answeredAt": "...", "answers": { "named": ["Kinfolk", "Cereal"] }, "producedPaths": ["narrative.overview"] },
"antiReference": { "status": "answered", "answeredAt": "...", "answers": { "named": "Squarespace wedding-florist template" }, "producedPaths": ["narrative.donts"] },
"color": { "status": "answered", "answeredAt": "...", "answers": { "amount": "restrained", "visualCue": "...", "paletteTokens": {"...": "..."} }, "producedPaths": ["extensions.colorMeta"] },
"typography": { "status": "answered", "answeredAt": "...", "answers": { "fontPair": "Shippori Mincho / Source Sans 3", "typeDirection": "editorial" }, "producedPaths": ["extensions.typographyMeta"] },
"motion": { "status": "answered", "answeredAt": "...", "answers": { "easing": "ease-standard", "duration": "150ms", "animationType": "crossfade" }, "producedPaths": ["extensions.motion"] },
"layout": { "status": "answered", "answeredAt": "...", "answers": { "radii": "square", "spacingStrategy": "fluid", "boundaryStyle": "position/distance" }, "producedPaths": ["rounded", "spacing"] },
"elevation": { "status": "answered", "answeredAt": "...", "answers": { "shadowSystem": "flat-by-doctrine" }, "producedPaths": ["extensions.shadows"] },
"iconography": { "status": "answered", "answeredAt": "...", "answers": { "pack": "Lucide" }, "producedPaths": ["extensions.iconography"] }
}
}
producedPaths is what makes reset safe: it tells the reset routine exactly which design.json/DESIGN.md fields that section's answer wrote to, so redoing one slide only touches those paths and leaves everything else (crawl-derived or answered in a different slide) untouched.
Reset, both granularities
- Whole-flow reset: clear all
questionnaire.sections, re-run the seed from the assets/references chat step through every browser slide, same as a first-time seed. - Per-section reset: user says "redo iconography" (or picks it from a menu). Agent reads
questionnaire.sections.iconography.answersto show what was previously picked, lets the user redo just that slide, and overwrites onlyproducedPathsfor that section — no re-scan, no touching Color/Typography/etc. - Fields with
source: "crawl": not resettable through this mechanism at all. Changing them means re-running/impeccable document's scan (Step 1-2), or a manual code edit. The questionnaire reset flow should refuse to "reset" a crawl-derived field and say so.
Open questions
- Scope: this spec covers the new, not-yet-shipped fields within
In-chat (document)andBrowser (document)only. Should the fields already shipped under those same two tags (today's qualitative round, today's Layout-strictness slide), plus all ofIn-chat (init), get the same persisted/resettable treatment eventually, so all ofPRODUCT.md/DESIGN.mdbecomes resettable, not just the new seed's slice? That's a bigger lift — it touchesinit.md's chat rounds too, and it would mean retrofitting aquestionnaire.sectionsentry for flows that already shipped without one. - Drift after manual edits: if a user hand-edits a questionnaire-sourced value directly in
DESIGN.mdafter the seed ran, doessourceflip to a fourth state ("manual"), or does the stalequestionnaire.sectionsentry silently go out of sync with the doc? Needs a decision before reset ships, or resets could clobber a deliberate manual change. - Existing repos with
design.jsonbut noquestionnaireblock (every file generated before this ships): reset should degrade gracefully — treat missingquestionnaireas "nothing resettable yet, only a fresh full seed is available" rather than erroring. producedPathsgranularity: paths above are section-level (e.g.extensions.colorMeta). If two slides ever write into the same object (unlikely given the current slide breakdown, but worth checking against the final slide list), path-level conflicts need a tie-break rule.