···153153 dragOptionAria: "Drag option {number}"
154154 removeOptionAria: "Remove option {number}"
155155 optionsHelp: Drag to reorder, rename in place, and keep between 2 and 10 options.
156156+ branchingTitle: Branching
157157+ branchingDescription: Send respondents to a later block when this answer matches.
158158+ addBranchRule: Add rule
159159+ branchOperator: Operator
160160+ branchWhenAnswer: Condition value
161161+ branchGoTo: Go to block
162162+ branchOtherwise: Otherwise continue to
163163+ branchDefaultLinear: The next block in saved order
164164+ branchNoValueNeeded: No value needed for this operator.
165165+ branchingHelp: "Leave a rule unmatched to use the default path. Example value: \"{value}\"."
166166+ branchingNoTargets: Add a later block before creating branch rules from this question.
167167+ dragBranchRuleAria: "Drag branch rule {number}"
168168+ removeBranchRuleAria: "Remove branch rule {number}"
169169+ branchMissingTarget: Missing target block
170170+ branchingBlockersTitle: "{count} branching blocker(s) must be fixed before publish"
171171+ branchingBlockersDescription: Draft edits are preserved, but publishing stays blocked until these routing errors are fixed.
172172+ branchingWarningsTitle: "{count} branching warning(s) to review"
173173+ branchingWarningsDescription: These warnings do not block draft saves, but they may indicate fragile or confusing routing.
174174+ branchingBlockersForBlockTitle: Blocking issues on this block
175175+ branchingWarningsForBlockTitle: Warnings on this block
176176+ branchOperators:
177177+ equals: Equals
178178+ not_equals: Not equals
179179+ is_empty: Is empty
180180+ is_not_empty: Is not empty
181181+ contains: Contains
182182+ contains_any: Contains any
183183+ gt: Greater than
184184+ gte: Greater than or equal
185185+ lt: Less than
186186+ lte: Less than or equal
187187+ branchOperatorLabels:
188188+ singleChoice:
189189+ equals: Is
190190+ not_equals: Is not
191191+ multipleChoice:
192192+ contains_any: Contains option
193193+ agreement:
194194+ equals: Is agreed
195195+ not_equals: Is not agreed
196196+ date:
197197+ equals: Is on
198198+ not_equals: Is not on
199199+ gt: Is after
200200+ gte: Is on or after
201201+ lt: Is before
202202+ lte: Is on or before
203203+ branchAgreementValues:
204204+ agreed: Agree
205205+ not_agreed: Do not agree
156206 requiredToggle: Mark this question as required
157207 deleteBlock: Delete block
158208 saveBlock: Save block
···183233 LINK: Link
184234 AGREEMENT: Agreement
185235 DATE: Date
236236+branching:
237237+ issueMessages:
238238+ invalid-target: "A rule on \"{blockLabel}\" points to a missing block."
239239+ backward-target: "A rule on \"{blockLabel}\" must point to a later block."
240240+ invalid-default-target: "The default next step on \"{blockLabel}\" points to a missing block."
241241+ backward-default-target: "The default next step on \"{blockLabel}\" must point to a later block."
242242+ invalid-condition: "A rule on \"{blockLabel}\" has an invalid condition value."
243243+ duplicate-condition: "A rule on \"{blockLabel}\" duplicates an earlier condition."
244244+ unsupported-operator: "A rule on \"{blockLabel}\" uses an operator that does not fit this block type."
245245+ unreachable-block: "\"{blockLabel}\" is unreachable from the start of the form."
246246+ fragile-text-match: "Exact text matching on \"{blockLabel}\" may be fragile if respondents vary punctuation or casing."
247247+ overlapping-rule: "A later rule on \"{blockLabel}\" may never run because an earlier broader rule matches first."
248248+ partial-choice-coverage: "Some answers on \"{blockLabel}\" fall through to the default route. Double-check that this is intentional."
186249publicRunner:
187250 responseReceived: Response received
188251 defaultCompletionTitle: Thanks for taking the time.
···226289 title: "Submission #{number} · {date}"
227290 description: Review submitted answers in form order.
228291 backToResponses: Back to responses
292292+ routeContext: Route context
293293+ visitedPath: Visited path
294294+ skippedPath: Skipped sections
295295+ nothingSkipped: No sections were skipped in this submission.
229296 contextBlock: Context block
230297 contextTitle: Context
231298 required: Required
+67
locales/ru.yml
···153153 dragOptionAria: "Перетащить вариант {number}"
154154 removeOptionAria: "Удалить вариант {number}"
155155 optionsHelp: Перетаскивайте варианты для изменения порядка, переименовывайте их на месте и держите количество в диапазоне от 2 до 10.
156156+ branchingTitle: Ветвление
157157+ branchingDescription: Отправляйте респондента к более позднему блоку, если ответ совпадает.
158158+ addBranchRule: Добавить правило
159159+ branchOperator: Оператор
160160+ branchWhenAnswer: Значение условия
161161+ branchGoTo: Перейти к блоку
162162+ branchOtherwise: Иначе продолжить к
163163+ branchDefaultLinear: Следующему блоку в сохранённом порядке
164164+ branchNoValueNeeded: Для этого оператора значение не требуется.
165165+ branchingHelp: "Если ни одно правило не совпало, форма использует маршрут по умолчанию. Пример значения: \"{value}\"."
166166+ branchingNoTargets: Добавьте более поздний блок, прежде чем создавать правила ветвления для этого вопроса.
167167+ dragBranchRuleAria: "Перетащить правило ветвления {number}"
168168+ removeBranchRuleAria: "Удалить правило ветвления {number}"
169169+ branchMissingTarget: Целевой блок отсутствует
170170+ branchingBlockersTitle: "Проблемы с ветвлением, блокирующие публикацию: {count}"
171171+ branchingBlockersDescription: Черновик сохранится, но публикация будет заблокирована, пока вы не исправите ошибки маршрутизации.
172172+ branchingWarningsTitle: "Предупреждения по ветвлению: {count}"
173173+ branchingWarningsDescription: Эти предупреждения не мешают сохранению черновика, но могут указывать на хрупкую или запутанную маршрутизацию.
174174+ branchingBlockersForBlockTitle: Блокирующие ошибки в этом блоке
175175+ branchingWarningsForBlockTitle: Предупреждения в этом блоке
176176+ branchOperators:
177177+ equals: Равно
178178+ not_equals: Не равно
179179+ is_empty: Пусто
180180+ is_not_empty: Не пусто
181181+ contains: Содержит
182182+ contains_any: Содержит любой из вариантов
183183+ gt: Больше чем
184184+ gte: Больше или равно
185185+ lt: Меньше чем
186186+ lte: Меньше или равно
187187+ branchOperatorLabels:
188188+ singleChoice:
189189+ equals: Выбран вариант
190190+ not_equals: Выбран не вариант
191191+ multipleChoice:
192192+ contains_any: Содержит вариант
193193+ agreement:
194194+ equals: Есть согласие
195195+ not_equals: Нет согласия
196196+ date:
197197+ equals: Дата совпадает с
198198+ not_equals: Дата не совпадает с
199199+ gt: После
200200+ gte: В эту дату или позже
201201+ lt: До
202202+ lte: В эту дату или раньше
203203+ branchAgreementValues:
204204+ agreed: Согласен
205205+ not_agreed: Не согласен
156206 requiredToggle: Сделать этот вопрос обязательным
157207 deleteBlock: Удалить блок
158208 saveBlock: Сохранить блок
···183233 LINK: Ссылка
184234 AGREEMENT: Согласие
185235 DATE: Дата
236236+branching:
237237+ issueMessages:
238238+ invalid-target: "Правило в \"{blockLabel}\" ссылается на отсутствующий блок."
239239+ backward-target: "Правило в \"{blockLabel}\" должно вести только к более позднему блоку."
240240+ invalid-default-target: "Маршрут по умолчанию в \"{blockLabel}\" ссылается на отсутствующий блок."
241241+ backward-default-target: "Маршрут по умолчанию в \"{blockLabel}\" должен вести только к более позднему блоку."
242242+ invalid-condition: "В \"{blockLabel}\" задано некорректное значение условия."
243243+ duplicate-condition: "В \"{blockLabel}\" условие дублирует более раннее правило."
244244+ unsupported-operator: "В \"{blockLabel}\" используется оператор, который не подходит этому типу блока."
245245+ unreachable-block: "Блок \"{blockLabel}\" недостижим от начала формы."
246246+ fragile-text-match: "Точное текстовое совпадение в \"{blockLabel}\" может быть хрупким, если респонденты вводят разную пунктуацию или регистр."
247247+ overlapping-rule: "Более позднее правило в \"{blockLabel}\" может никогда не сработать, потому что раньше срабатывает более широкое условие."
248248+ partial-choice-coverage: "Часть ответов в \"{blockLabel}\" уходит по маршруту по умолчанию. Проверьте, что это сделано намеренно."
186249publicRunner:
187250 responseReceived: Ответ получен
188251 defaultCompletionTitle: Спасибо, что уделили время.
···226289 title: "Ответ №{number} · {date}"
227290 description: Просматривайте ответы в порядке формы.
228291 backToResponses: Назад к ответам
292292+ routeContext: Контекст маршрута
293293+ visitedPath: Пройденный путь
294294+ skippedPath: Пропущенные секции
295295+ nothingSkipped: В этой отправке не было пропущенных секций.
229296 contextBlock: Контекстный блок
230297 contextTitle: Контекст
231298 required: Обязательно
···11+## Context
22+33+Lively Forms currently stores form structure as an ordered list of `FormBlock` records, with block-specific settings serialized in each block's `config` JSON. The creator builder edits one block at a time, and the public runner assumes a strictly linear progression by incrementing a numeric step across `form.blocks`.
44+55+Branching is a cross-cutting change because it touches block configuration parsing, builder editing UI, publish validation, runner navigation state, and submission-time validation. The current architecture is a good fit for an incremental implementation because blocks already have stable IDs and a JSON config surface that can absorb routing metadata without introducing a new top-level table.
66+77+Key constraints:
88+- Public forms are anonymous and already validate answers both client-side and server-side.
99+- The builder already saves block configuration per block and reuses stable block IDs across reorder operations.
1010+- The current runner and server submission path both assume every block in saved order is part of the respondent journey, which must change for branching to work.
1111+- The requested behavior needs to cover both simple conditional follow-ups and larger divergent paths, but should avoid infinite loops or graph states that are hard to reason about in v1.
1212+1313+## Goals / Non-Goals
1414+1515+**Goals:**
1616+- Let creators define branching from an answerable block to any later block in the form.
1717+- Support simple follow-up questions and multi-branch flows using the same routing model.
1818+- Keep forms without branching working exactly as they do today.
1919+- Enforce deterministic routing in the public runner and on the submission API.
2020+- Block publishing when branch targets are invalid or the graph leaves blocks unreachable from the form start.
2121+- Preserve reliable back navigation when a respondent revisits earlier answers.
2222+2323+**Non-Goals:**
2424+- Supporting backward jumps, loops, or arbitrary cyclic graphs.
2525+- Adding a visual canvas or node-editor UI in v1.
2626+- Introducing complex condition builders such as numeric ranges, boolean groups, or nested AND/OR logic.
2727+- Changing creator response review beyond what is necessary for branching-safe submissions.
2828+- Versioning published form graphs independently from the draft form model.
2929+3030+## Decisions
3131+3232+### 1. Store branch rules inside each block's existing `config` JSON
3333+Add a shared branching shape to answerable block configs rather than introducing a separate `FormBranch` table.
3434+3535+Proposed model:
3636+- Every answerable block may include `branchRules: BranchRule[]` inside `config`.
3737+- Each rule references a target `blockId` and a condition value interpreted according to the source block type.
3838+- Every answerable block may also include `defaultNextBlockId`, which overrides the normal next-in-order fallback when no branch rule matches and also enables unconditional forward jumps after a question.
3939+- When `defaultNextBlockId` is not set, the runner continues to the next block in saved order.
4040+- Text blocks remain non-answerable and do not expose branch editing.
4141+4242+Why this approach:
4343+- Fits the existing block-centric editing flow and API shape.
4444+- Avoids a database migration for the initial feature.
4545+- Keeps branch rules naturally attached to the question that decides the route.
4646+4747+Alternatives considered:
4848+- A separate relational edge table: more normalized, but adds migration, joins, and more complex CRUD for an initial release.
4949+- A form-level graph document: more flexible, but less aligned with the current block editor and harder to update incrementally.
5050+5151+### 2. Scope v1 routing to forward-only jumps to later blocks
5252+A branch target or configured default next target may point only to a later block in saved order. When no explicit default next target is configured, the implicit fallback remains the next block in saved order.
5353+5454+Why this approach:
5555+- Still satisfies the requested jump-to-X branching for practical form flows.
5656+- Prevents infinite loops and ambiguous revisit semantics.
5757+- Makes validation and route resolution much simpler.
5858+5959+Alternatives considered:
6060+- Allow arbitrary targets, including previous blocks: more expressive, but creates loop detection, repeated-answer semantics, and progress complexity that are not needed for v1.
6161+- Restrict branching to only the immediately next question: too limiting for the requested divergent paths.
6262+6363+### 3. Use simple block-type-aware match conditions instead of a full rule engine
6464+Branch conditions should match the current block's answer using a small set of predictable operators:
6565+- short text / long text / number / link / date: exact normalized value match
6666+- single choice / agreement: exact selected value match
6767+- multiple choice: contains selected option
6868+6969+Rules are evaluated in saved order, and the first matching rule wins.
7070+7171+Why this approach:
7272+- Covers the user request for answer-based branching without building a complex expression language.
7373+- Keeps both builder UI and server validation understandable.
7474+- Gives deterministic behavior for multiple-choice blocks where more than one rule could match.
7575+7676+Alternatives considered:
7777+- Add full comparator support (`>`, `<`, regex, AND/OR groups): powerful, but too large for the first branching release.
7878+- Allow all matching rules to fire: ambiguous when rules target different blocks.
7979+8080+### 4. Validate branch integrity centrally and enforce it at publish time
8181+Introduce a shared graph validation helper used by builder APIs and publish logic. Draft forms may retain invalid branch rules while being edited, but publish MUST fail until issues are resolved.
8282+8383+Validation should cover:
8484+- branch targets and configured default next targets exist
8585+- every target is later than the source block
8686+- no duplicate or impossible rule shapes for the same block type
8787+- every block remains reachable from the first block through at least one possible route
8888+8989+Why this approach:
9090+- Lets creators reorder and edit complex forms without destructive auto-fixes.
9191+- Keeps the hard safety boundary at publish time, where invalid graphs would affect respondents.
9292+- Centralizes logic so the client and server do not drift.
9393+9494+Alternatives considered:
9595+- Reject invalid drafts on every edit: safer but more frustrating during multi-step authoring.
9696+- Auto-delete invalid rules during reorder/delete: simpler operationally, but surprising and lossy.
9797+9898+### 5. Change runner state from numeric linear step to visited-route history
9999+Replace the runner's single `step` index over `form.blocks` with route-aware state:
100100+- `history: string[]` of visited block IDs in order
101101+- `cursor` pointing at the current visited block
102102+- `answers` as today
103103+104104+Advance flow:
105105+1. validate the current visited block
106106+2. resolve the next block from the current answer and branch rules
107107+3. if the respondent had gone back, truncate forward history before appending the new branch result
108108+4. move to the next visited block or submit if no next block exists
109109+110110+Why this approach:
111111+- Supports deterministic back navigation across the actual path taken.
112112+- Correctly recalculates future steps when a respondent changes an earlier answer.
113113+- Avoids leaking skipped blocks into the active route.
114114+115115+Alternatives considered:
116116+- Recompute the entire full route from scratch on every render: possible, but harder to preserve intuitive back behavior.
117117+- Keep a linear numeric index and just skip hidden blocks: brittle once respondents go back and alter branch decisions.
118118+119119+### 6. Validate and persist only visited blocks during submission
120120+The submission API should resolve the respondent's visited route using the same branch engine as the client and validate only blocks that were actually visited. Skipped required questions must not block submission.
121121+122122+Why this approach:
123123+- The current server validation iterates over every block in saved order, which would incorrectly reject branched submissions.
124124+- Server-side route resolution prevents clients from bypassing required questions on the active branch.
125125+126126+Alternatives considered:
127127+- Trust the client-provided route history: simpler, but weaker from an integrity standpoint.
128128+- Keep validating every block and mark branched ones optional: incorrect and hard to reason about.
129129+130130+### 7. Replace full-form percentage with route-relative progress
131131+Because future branches are not always knowable before later answers are given, the runner should present progress relative to the visited route rather than a precise percentage over all saved blocks.
132132+133133+Why this approach:
134134+- Avoids misleading totals when large sections are skipped.
135135+- Keeps progress honest when a prior answer changes the remaining route.
136136+137137+Alternatives considered:
138138+- Keep percentage over the full saved block list: inaccurate for heavily branched forms.
139139+- Predict the entire remaining route ahead of time: unreliable when future routing depends on unanswered questions.
140140+141141+## Risks / Trade-offs
142142+143143+- **Branch rules stored in JSON are less queryable than relational edges** → Mitigation: acceptable for v1 because routing is resolved per form load, not through global reporting queries.
144144+- **Reordering blocks can temporarily invalidate existing branch targets** → Mitigation: preserve draft edits, surface validation issues, and enforce correctness at publish time.
145145+- **First-match rule evaluation may surprise creators if multiple rules could match** → Mitigation: make rule order explicit in the builder and document that evaluation is top-to-bottom.
146146+- **Open-input branching based on exact matches may be less powerful than users eventually want** → Mitigation: design the rule shape so richer comparators can be added later without changing the overall graph model.
147147+- **Route-relative progress is less precise than a classic total-step meter** → Mitigation: favor correctness and consistency over a misleading exact percentage.
148148+149149+## Migration Plan
150150+151151+1. Extend block config parsing/types with shared `branchRules` support for answerable blocks.
152152+2. Add shared branch matching and graph validation helpers in the server/domain layer.
153153+3. Update builder APIs and editor UI to create, edit, and validate branch rules against current form blocks.
154154+4. Update publish validation to reject invalid branch graphs.
155155+5. Refactor the public runner to use visited-route history and branch-aware progression.
156156+6. Refactor submission handling to resolve and validate only the visited route.
157157+7. Verify linear forms still behave identically when no branch rules are configured.
158158+159159+Rollback strategy:
160160+- If the feature must be rolled back before broad usage, ignore `branchRules` in the runner and hide builder controls. Because the data stays in JSON config, rollback does not require a destructive schema reversal.
161161+162162+## Open Questions
163163+164164+- Should the creator builder eventually show a lightweight route preview or mini-map in addition to per-block rule editing?
165165+- Should response review later distinguish between skipped blocks and unanswered visited blocks more explicitly?
166166+- Do we want richer comparators such as numeric ranges or regex-based routing after the initial exact-match release?
···11+## Why
22+33+Lively Forms currently runs every published form as a fixed linear sequence, which makes simple follow-up questions and fully divergent form paths impossible. Adding branching now unlocks more practical onboarding, qualification, and decision-tree flows without forcing creators to duplicate forms for each audience.
44+55+## What Changes
66+77+- Add branching rules and configurable default next targets that let creators send respondents to different later blocks based on the current answer or a saved fallback path.
88+- Support both simple conditional follow-ups and jump-to-any-block branching across the form graph.
99+- Keep a safe default path so forms without custom branch rules still run in their saved order.
1010+- Update the public runner to evaluate branch rules after each answer, navigate through the resulting path, and preserve back navigation across visited steps.
1111+- Prevent creators from publishing forms with invalid branch targets or unreachable end states.
1212+1313+## Capabilities
1414+1515+### New Capabilities
1616+- None.
1717+1818+### Modified Capabilities
1919+- `conversational-form-builder`: creators can configure, review, and validate branch destinations between blocks instead of only editing a linear sequence.
2020+- `anonymous-form-runner`: respondents move through a conditional block graph determined by prior answers rather than always following saved block order.
2121+2222+## Impact
2323+2424+- Builder UI for block editing, branch configuration, and publish-time validation
2525+- Form block data model and API payloads for storing branching rules and targets
2626+- Public form runner navigation, progress behavior, and backtracking state
2727+- Submission validation and response snapshots so completed runs reflect the path actually taken
···11+## MODIFIED Requirements
22+33+### Requirement: Runner presents blocks in a linear one-at-a-time flow
44+The system SHALL present form blocks one at a time starting from the first saved block and SHALL resolve each next block by evaluating the current block's saved branch rules against the respondent's current answer. If no branch rule matches, the system SHALL continue to the block's configured default next target when present, or otherwise continue to the next block in saved order. Text blocks SHALL remain part of the flow but SHALL NOT collect an answer. The system SHALL allow backward navigation across the respondent's visited path and SHALL recalculate future visited steps when a prior answer changes.
55+66+#### Scenario: Respondent sees a conditional follow-up question
77+- **WHEN** a respondent answers a question with a value that matches a saved branch rule pointing to a later follow-up block
88+- **THEN** the system shows that follow-up block as the next step in the runner
99+1010+#### Scenario: Respondent skips a branch-only follow-up
1111+- **WHEN** a respondent answers a question with a value that does not match any saved branch rule
1212+- **THEN** the system continues to the next block in saved order instead of showing the branched follow-up block
1313+1414+#### Scenario: Respondent changes an earlier branching answer
1515+- **WHEN** a respondent navigates backward, changes an answer that controls branching, and continues again
1616+- **THEN** the system recalculates the subsequent route from that changed answer and replaces the no-longer-valid future steps
1717+1818+### Requirement: Runner shows progress across the full flow
1919+The system SHALL display progress based on the respondent's current visited route rather than assuming every saved block will appear, and SHALL update the visible step indicator when branching or backtracking changes that route.
2020+2121+#### Scenario: Respondent skips a section through branching
2222+- **WHEN** a respondent takes a branch that skips one or more later blocks
2323+- **THEN** the system updates the visible progress so it reflects the route the respondent is actually taking rather than the full saved block list
2424+2525+#### Scenario: Respondent changes the route by editing a previous answer
2626+- **WHEN** a respondent goes back and changes an answer that changes the remaining route
2727+- **THEN** the system updates the visible progress to match the recalculated route
2828+2929+### Requirement: Required question blocks are validated before advancement
3030+The system SHALL prevent a respondent from advancing past a visited required question block until a valid answer is provided for that block type. For required agreement blocks, only an explicit agreed response SHALL satisfy the requirement. Question blocks skipped by branching SHALL NOT be required for advancement or submission.
3131+3232+#### Scenario: Respondent skips a required short text question
3333+- **WHEN** a respondent attempts to continue from a visited required text question without an answer
3434+- **THEN** the system blocks advancement and indicates that an answer is required
3535+3636+#### Scenario: Respondent skips a required multiple choice question
3737+- **WHEN** a respondent attempts to continue from a visited required multiple choice block without selecting any options
3838+- **THEN** the system blocks advancement and indicates that an answer is required
3939+4040+#### Scenario: Respondent does not agree to a required agreement block
4141+- **WHEN** a respondent attempts to continue from a visited required agreement block without selecting agreed
4242+- **THEN** the system blocks advancement and indicates that agreement is required
4343+4444+#### Scenario: Required block is skipped by a branch
4545+- **WHEN** a respondent takes a branch that bypasses a required question block
4646+- **THEN** the system does not require an answer for that skipped block before allowing completion or submission
···11+## ADDED Requirements
22+33+### Requirement: Creator can configure answer-based branch rules on question blocks
44+The system SHALL allow an authenticated creator to add, edit, reorder, and remove branch rules on answerable blocks in a form located in an accessible workspace. Each branch rule SHALL compare the current block's answer using behavior appropriate to that block type and SHALL send respondents to a later block in the same form. The system SHALL also allow an authenticated creator to configure a default next target on an answerable block so respondents can continue to a chosen later block when no branch rule matches. If no branch rule matches and no default next target is configured, the respondent flow SHALL continue to the next block in saved order.
55+66+#### Scenario: Creator adds a conditional follow-up for one answer
77+- **WHEN** an authenticated creator configures a single choice question so one option branches to a later follow-up block
88+- **THEN** the system saves that branch rule on the source question and keeps the unconfigured path flowing to the next saved block
99+1010+#### Scenario: Creator defines divergent paths from one question
1111+- **WHEN** an authenticated creator configures different branch rules for different answers on the same question block
1212+- **THEN** the system saves distinct later-block targets for those answers on that source block
1313+1414+#### Scenario: Creator changes branch priority
1515+- **WHEN** an authenticated creator reorders branch rules on a question block
1616+- **THEN** the system saves the updated evaluation order for that block's branch rules
1717+1818+### Requirement: Builder validates branch graphs before publishing
1919+The system SHALL validate saved branch rules before allowing a form to publish. The system SHALL prevent publishing when a branch rule points to a missing, current, or earlier block, or when one or more blocks become unreachable from the first block under the configured branch graph.
2020+2121+#### Scenario: Creator tries to publish with a backward branch target
2222+- **WHEN** an authenticated creator attempts to publish a form containing a branch rule that points to the source block or an earlier block
2323+- **THEN** the system blocks publishing and indicates that the branch target must move forward in the form
2424+2525+#### Scenario: Creator tries to publish with an unreachable block
2626+- **WHEN** an authenticated creator attempts to publish a form whose saved branch rules leave a block unreachable from the form start
2727+- **THEN** the system blocks publishing and indicates that the unreachable block must be reconnected or removed
2828+2929+#### Scenario: Creator saves an invalid draft while editing branching
3030+- **WHEN** an authenticated creator saves draft changes that leave branch validation issues unresolved
3131+- **THEN** the system preserves the draft changes and continues to block publishing until the issues are fixed
···11+## 1. Branching domain model
22+33+- [x] 1.1 Extend block config types, parsers, and block update validation to support ordered `branchRules` on answerable blocks
44+- [x] 1.2 Add shared branch matching, next-block resolution, and graph validation helpers for forward-only routing and reachability checks
55+- [x] 1.3 Update form serialization/helpers so builder and public form payloads include branching data consistently without changing linear forms
66+77+## 2. Builder authoring and publish validation
88+99+- [x] 2.1 Add branching controls to the block editor for answerable blocks, including rule creation, target selection, and rule reordering
1010+- [x] 2.2 Surface branch validation feedback in the builder while preserving draft edits that are not yet publishable
1111+- [x] 2.3 Enforce publish-time branch validation in the form publish flow and return actionable errors for invalid targets or unreachable blocks
1212+1313+## 3. Branch-aware runner and submission
1414+1515+- [x] 3.1 Refactor the public runner to use visited-route history instead of a linear step index
1616+- [x] 3.2 Update runner progress and back-navigation behavior so route changes after edited answers recalculate future steps correctly
1717+- [x] 3.3 Update anonymous submission handling to resolve the visited route server-side and validate only visited required blocks
1818+1919+## 4. Regression checks
2020+2121+- [x] 4.1 Verify unchanged linear forms still build, publish, and submit exactly as before when no branch rules are configured
2222+- [x] 4.2 Verify branched forms cover simple follow-up, divergent path, skipped required question, and backtracking scenarios end to end
···11+## Context
22+33+The initial branching change adds forward-only routing, default next targets, and visited-path runner state, but branch conditions are still intentionally narrow: most blocks only support exact-match semantics. That keeps the first release simple, yet it leaves common real-world routing needs unsolved, such as numeric thresholds, blank-answer handling, or substring matching.
44+55+At the same time, creators currently have limited visibility into what happened after a branched response is submitted. The response review flow can show visited blocks because the submission snapshot already preserves the visited path, but it does not explicitly label the route taken or the sections skipped. Validation is also mostly structural. It blocks obviously invalid graphs, but it does not help creators identify fragile logic, overlapping conditions, or dead-end coverage risks before publishing.
66+77+This follow-up change is cross-cutting because it affects branch rule storage, builder authoring, publish validation, runner evaluation, and response review presentation.
88+99+## Goals / Non-Goals
1010+1111+**Goals:**
1212+- Expand branching with a practical v1 operator set that covers common qualification and routing use cases.
1313+- Keep routing deterministic and forward-only.
1414+- Show creators the visited route and skipped sections for a submitted response.
1515+- Strengthen validation with clearer branching warnings and publish-time blockers.
1616+- Preserve compatibility for existing exact-match branch rules.
1717+1818+**Non-Goals:**
1919+- Adding a full visual graph canvas.
2020+- Supporting arbitrary boolean groups, nested AND/OR logic, or user-defined expressions.
2121+- Adding branching analytics dashboards in this change.
2222+- Introducing backward jumps or loops.
2323+- Reworking the persistence model away from per-block JSON config.
2424+2525+## Decisions
2626+2727+### 1. Extend branch rules with an explicit operator field
2828+Move branch rules from implicit type-specific matching to an explicit rule shape such as:
2929+- `operator`: enum
3030+- `value`: optional operand when the operator needs one
3131+- `targetBlockId`: later block target
3232+3333+Initial operator set:
3434+- all answerable blocks: `equals`, `not_equals`, `is_empty`, `is_not_empty`
3535+- short/long text and link: `contains`
3636+- multiple choice: `contains_any`
3737+- number and date: `gt`, `gte`, `lt`, `lte`
3838+3939+Why this approach:
4040+- Keeps the model evolvable without inventing a second rule format later.
4141+- Lets the builder present operator-appropriate controls and validation.
4242+- Preserves deterministic first-match evaluation.
4343+4444+Alternatives considered:
4545+- Continue inferring operators from block type alone: too limiting for the requested scope.
4646+- Introduce a generic expression DSL: too complex for the next iteration.
4747+4848+### 2. Preserve backward compatibility by upgrading legacy exact-match rules in parsing
4949+Existing branch rules created by the first branching change should continue to work. Parsing should treat legacy exact-match rules as `equals` rules when no operator is present.
5050+5151+Why this approach:
5252+- Avoids breaking saved draft or published forms.
5353+- Keeps the migration lightweight because branch data lives in JSON config.
5454+5555+Alternatives considered:
5656+- Require a one-time data migration over all forms: unnecessary complexity for JSON-backed config.
5757+5858+### 3. Separate validation into publish blockers and advisory warnings
5959+Validation should continue blocking publish for hard graph errors, while also surfacing non-blocking warnings during editing. Proposed split:
6060+6161+**Blockers:**
6262+- missing target
6363+- backward/self target
6464+- unreachable block
6565+- invalid operand for the chosen operator
6666+- operator not supported by the source block type
6767+- no valid continuation from a required route branch where the graph dead-ends unexpectedly before remaining reachable required content is satisfiable
6868+6969+**Warnings:**
7070+- overlapping rules where a broader earlier rule makes a later rule effectively unreachable
7171+- exact-match text/link rules that may be fragile
7272+- choice blocks whose rule coverage is partial and fall through to a default route unexpectedly
7373+- stale branch references caused by reorder/delete operations while still in draft
7474+7575+Why this approach:
7676+- Keeps publish safety strict without making authoring unbearably rigid.
7777+- Helps creators debug complex flows earlier.
7878+7979+Alternatives considered:
8080+- Make every warning a blocker: too frustrating for draft authoring.
8181+- Keep only blockers: not enough guidance for advanced branching.
8282+8383+### 4. Use the response snapshot plus current form order to show route context
8484+Response review should derive path context from the visited block snapshot already stored on submission and compare it against the full form structure in saved order. The UI can then show:
8585+- visited path in order
8686+- blocks skipped by branching
8787+- the answer shown on each visited decision point
8888+8989+Why this approach:
9090+- Avoids adding a new response table or separate route log.
9191+- Keeps review faithful to what the respondent actually saw at submission time.
9292+9393+Alternatives considered:
9494+- Store a separate explicit branch-events log: richer, but unnecessary for the initial review improvement.
9595+9696+### 5. Keep runner evaluation server/client shared through the branching domain layer
9797+The same rule-resolution helper should evaluate advanced operators for both client navigation and server-side submission validation.
9898+9999+Why this approach:
100100+- Prevents drift between what respondents see and what the server accepts.
101101+- Keeps advanced operator semantics consistent across review and validation.
102102+103103+Alternatives considered:
104104+- Duplicate evaluation logic in the client and server: more fragile and harder to test.
105105+106106+## Risks / Trade-offs
107107+108108+- **More operators increase builder complexity** → Mitigation: scope the operator set tightly and show only operators valid for the selected block type.
109109+- **Advisory warnings can be noisy** → Mitigation: limit warnings to high-signal cases and distinguish them clearly from publish blockers.
110110+- **Legacy exact-match rules could behave unexpectedly if interpreted differently** → Mitigation: map legacy rules only to `equals` semantics and keep normalization deterministic.
111111+- **Skipped/visited route display may confuse creators if the current form has changed since submission** → Mitigation: anchor visited-path display to the stored snapshot and use the current form only for supplemental skipped-block context.
112112+113113+## Migration Plan
114114+115115+1. Extend branch rule parsing/types with operator-aware schemas and legacy fallback support.
116116+2. Update shared branch evaluation and validation helpers for the practical v1 operator set.
117117+3. Expand builder authoring UI to choose operators, operands, and show validation warnings/blockers clearly.
118118+4. Update response review shaping to expose visited and skipped route context.
119119+5. Verify existing exact-match branch forms continue to work unchanged.
120120+121121+Rollback strategy:
122122+- If needed, hide advanced operators in the builder and continue honoring already-saved `equals` behavior. Because the model remains JSON-based, rollback does not require destructive schema reversal.
123123+124124+## Open Questions
125125+126126+- Should response review explicitly show which branch rule fired, or is visited/skipped context enough for the first pass?
127127+- Which warning conditions should remain advisory versus becoming publish blockers after creator feedback?
128128+- Do we want date comparisons to interpret values strictly as local calendar dates or normalized UTC date strings in every surface?
···11+## Why
22+33+Branching now supports forward routing and default next targets, but creators still lack the operator range, debugging visibility, and safety checks needed to build and maintain more complex flows confidently. Improving authoring, response review, and validation now will make branching trustworthy enough for production qualification and multi-path forms.
44+55+## What Changes
66+77+- Expand branching conditions with a practical v1 operator set: `equals`, `not equals`, `is empty`, `is not empty`, text `contains`, multiple-choice `contains any`, and number/date comparison operators.
88+- Show branching path context in creator response review so creators can see which route a respondent took and which blocks were skipped.
99+- Strengthen publish-time and builder-time branching validation with clearer issue detection for fragile, overlapping, or incomplete routing setups.
1010+- Improve builder guidance so creators can understand how advanced operators and validation warnings affect route behavior before publishing.
1111+1212+## Capabilities
1313+1414+### New Capabilities
1515+- None.
1616+1717+### Modified Capabilities
1818+- `conversational-form-builder`: branching configuration gains richer operators, stronger validation feedback, and clearer authoring support.
1919+- `anonymous-form-runner`: branching evaluation supports more operator types and preserves route context needed for review.
2020+- `response-review`: creator response inspection exposes the visited branching path and skipped sections for each submission.
2121+2222+## Impact
2323+2424+- Branch rule data model, parsing, and validation logic in the form domain layer
2525+- Builder UI for advanced condition editing and warning presentation
2626+- Public runner route evaluation for richer operator support
2727+- Response detail shaping and creator-facing review pages for path visibility
2828+- Potential translation updates for new branching and review terminology
···11+## ADDED Requirements
22+33+### Requirement: Runner evaluates practical operator-based branching rules consistently
44+The system SHALL evaluate saved branching rules using the configured operator semantics for the active block before determining the next step in the respondent path. The runner and submission validation flow SHALL use the same operator behavior.
55+66+#### Scenario: Respondent triggers a numeric comparison rule
77+- **WHEN** a respondent answers a number or date question with a value that satisfies a saved comparison operator such as greater than or less than
88+- **THEN** the system routes the respondent to that rule's target block
99+1010+#### Scenario: Respondent triggers an empty-answer rule
1111+- **WHEN** a respondent leaves an optional question empty and the current block has a saved `is empty` branch rule
1212+- **THEN** the system routes the respondent using that rule instead of treating the empty answer as unmatched
1313+1414+#### Scenario: Respondent triggers a multiple-choice contains-any rule
1515+- **WHEN** a respondent selects multiple options and at least one selected option matches a saved `contains any` branch rule
1616+- **THEN** the system routes the respondent to that rule's target block
1717+1818+#### Scenario: Client and server evaluate the same rule set
1919+- **WHEN** a respondent completes and submits a branched form using supported advanced operators
2020+- **THEN** the submission validation path accepts or rejects the route using the same branching semantics as the public runner
···11+## ADDED Requirements
22+33+### Requirement: Creator can configure operator-based branch conditions on question blocks
44+The system SHALL allow an authenticated creator to configure branch rules on answerable blocks using operator-aware conditions appropriate to the source block type. The supported operator set SHALL include `equals`, `not equals`, `is empty`, and `is not empty` for answerable blocks; `contains` for text-answer and link blocks; `contains any` for multiple choice blocks; and `greater than`, `greater than or equal`, `less than`, and `less than or equal` for number and date blocks.
55+66+#### Scenario: Creator configures a numeric threshold branch
77+- **WHEN** an authenticated creator configures a number question with a branch rule using a greater-than or less-than style operator
88+- **THEN** the system saves that operator and operand as part of the branch rule for that question
99+1010+#### Scenario: Creator configures an empty-answer branch
1111+- **WHEN** an authenticated creator configures a branch rule using `is empty` or `is not empty` on an answerable block
1212+- **THEN** the system saves that rule without requiring a comparison value
1313+1414+#### Scenario: Creator configures a text contains branch
1515+- **WHEN** an authenticated creator configures a text-answer or link question with a `contains` branch rule
1616+- **THEN** the system saves the rule and limits it to a valid operator for that block type
1717+1818+### Requirement: Builder distinguishes branching blockers from advisory warnings
1919+The system SHALL surface branching validation feedback while a creator edits a form and SHALL distinguish publish-blocking routing errors from non-blocking advisory warnings.
2020+2121+#### Scenario: Creator introduces a publish-blocking branching error
2222+- **WHEN** an authenticated creator edits a branch rule so that its target is missing, invalid for that block type, or unreachable in the form graph
2323+- **THEN** the system preserves the draft change, marks the issue as publish-blocking, and prevents publishing until it is fixed
2424+2525+#### Scenario: Creator introduces a fragile but still valid branch setup
2626+- **WHEN** an authenticated creator creates a branch setup that is structurally valid but likely fragile or overlapping
2727+- **THEN** the system surfaces an advisory warning without preventing the draft from being saved
···11+## ADDED Requirements
22+33+### Requirement: Creator can inspect branching route context for a submission
44+The system SHALL allow an authenticated creator to inspect the visited route and skipped sections for an individual submission from a branched form while preserving the submission's saved form-order context.
55+66+#### Scenario: Creator opens a branched submission
77+- **WHEN** an authenticated creator views a response submitted through a branched form
88+- **THEN** the system shows which blocks were visited in the submission path and which blocks were skipped by branching
99+1010+#### Scenario: Creator reviews a decision point in the visited path
1111+- **WHEN** an authenticated creator inspects a visited branching question in a submission
1212+- **THEN** the system shows the submitted answer in context so the taken route is understandable
···11+## 1. Operator-aware branching model
22+33+- [x] 1.1 Extend branch rule schemas and parsers to support explicit operators with legacy exact-match fallback
44+- [x] 1.2 Update shared branch evaluation helpers for the Practical v1 operator set across builder, runner, and submission validation
55+- [x] 1.3 Expand branch validation to classify publish blockers and advisory warnings for invalid, overlapping, or fragile rules
66+77+## 2. Builder authoring and validation UX
88+99+- [x] 2.1 Update branching controls to let creators choose operators and enter operator-specific operands
1010+- [x] 2.2 Show only valid operators for the selected block type and handle operand-less operators such as `is empty`
1111+- [x] 2.3 Surface blocking errors and advisory warnings clearly in the builder without preventing draft saves
1212+1313+## 3. Response review path visibility
1414+1515+- [x] 3.1 Extend response detail shaping to expose visited path and skipped blocks for branched submissions
1616+- [x] 3.2 Update the creator response detail UI to display route context for visited and skipped blocks in submission order
1717+1818+## 4. Regression coverage
1919+2020+- [x] 4.1 Verify existing exact-match branching forms continue to work unchanged after operator support is added
2121+- [x] 4.2 Verify advanced operator routing, warning/blocker behavior, and branched response review context end to end
+46-15
openspec/specs/anonymous-form-runner/spec.md
···1212- **THEN** the system does not allow public response collection for that form
13131414### Requirement: Runner presents blocks in a linear one-at-a-time flow
1515-The system SHALL present form blocks in saved order and display exactly one block at a time with forward and backward navigation. Text blocks SHALL appear as part of the flow but SHALL NOT collect an answer.
1515+The system SHALL present form blocks one at a time starting from the first saved block and SHALL resolve each next block by evaluating the current block's saved branch rules against the respondent's current answer. If no branch rule matches, the system SHALL continue to the block's configured default next target when present, or otherwise continue to the next block in saved order. Text blocks SHALL remain part of the flow but SHALL NOT collect an answer. The system SHALL allow backward navigation across the respondent's visited path and SHALL recalculate future visited steps when a prior answer changes.
16161717-#### Scenario: Respondent moves through the form
1818-- **WHEN** a respondent advances through a published form
1919-- **THEN** the system shows each block one at a time in the form's saved order
1717+#### Scenario: Respondent sees a conditional follow-up question
1818+- **WHEN** a respondent answers a question with a value that matches a saved branch rule pointing to a later follow-up block
1919+- **THEN** the system shows that follow-up block as the next step in the runner
20202121-#### Scenario: Respondent returns to a previous block
2222-- **WHEN** a respondent navigates backward in the runner
2323-- **THEN** the system returns them to the previous block without breaking the saved in-progress answers for the session
2121+#### Scenario: Respondent skips a branch-only follow-up
2222+- **WHEN** a respondent answers a question with a value that does not match any saved branch rule
2323+- **THEN** the system continues to the next block in saved order instead of showing the branched follow-up block
2424+2525+#### Scenario: Respondent changes an earlier branching answer
2626+- **WHEN** a respondent navigates backward, changes an answer that controls branching, and continues again
2727+- **THEN** the system recalculates the subsequent route from that changed answer and replaces the no-longer-valid future steps
24282529### Requirement: Runner shows progress across the full flow
2626-The system SHALL display progress for the respondent based on the linear block sequence, including non-answerable text blocks.
3030+The system SHALL display progress based on the respondent's current visited route rather than assuming every saved block will appear, and SHALL update the visible step indicator when branching or backtracking changes that route.
3131+3232+#### Scenario: Respondent skips a section through branching
3333+- **WHEN** a respondent takes a branch that skips one or more later blocks
3434+- **THEN** the system updates the visible progress so it reflects the route the respondent is actually taking rather than the full saved block list
27352828-#### Scenario: Respondent views a text block in the flow
2929-- **WHEN** a respondent is on a text block step
3030-- **THEN** the system includes that step in the visible progress through the form
3636+#### Scenario: Respondent changes the route by editing a previous answer
3737+- **WHEN** a respondent goes back and changes an answer that changes the remaining route
3838+- **THEN** the system updates the visible progress to match the recalculated route
31393240### Requirement: Required question blocks are validated before advancement
3333-The system SHALL prevent a respondent from advancing past a required question block until a valid answer is provided for that block type. For required agreement blocks, only an explicit agreed response SHALL satisfy the requirement.
4141+The system SHALL prevent a respondent from advancing past a visited required question block until a valid answer is provided for that block type. For required agreement blocks, only an explicit agreed response SHALL satisfy the requirement. Question blocks skipped by branching SHALL NOT be required for advancement or submission.
34423543#### Scenario: Respondent skips a required short text question
3636-- **WHEN** a respondent attempts to continue from a required text question without an answer
4444+- **WHEN** a respondent attempts to continue from a visited required text question without an answer
3745- **THEN** the system blocks advancement and indicates that an answer is required
38463947#### Scenario: Respondent skips a required multiple choice question
4040-- **WHEN** a respondent attempts to continue from a required multiple choice block without selecting any options
4848+- **WHEN** a respondent attempts to continue from a visited required multiple choice block without selecting any options
4149- **THEN** the system blocks advancement and indicates that an answer is required
42504351#### Scenario: Respondent does not agree to a required agreement block
4444-- **WHEN** a respondent attempts to continue from a required agreement block without selecting agreed
5252+- **WHEN** a respondent attempts to continue from a visited required agreement block without selecting agreed
4553- **THEN** the system blocks advancement and indicates that agreement is required
5454+5555+#### Scenario: Required block is skipped by a branch
5656+- **WHEN** a respondent takes a branch that bypasses a required question block
5757+- **THEN** the system does not require an answer for that skipped block before allowing completion or submission
46584759### Requirement: Structured question answers are validated by block type
4860The system SHALL validate number, link, agreement, and date answers according to the active block kind before allowing a respondent to advance or submit the form. When a text-answer block is configured with custom regex validation, the system SHALL also validate the respondent's text answer against that regex pattern.
···100112#### Scenario: Form has no custom completion content
101113- **WHEN** a respondent submits a published form without customized completion settings
102114- **THEN** the system shows the default completion content after submission
115115+116116+### Requirement: Runner evaluates practical operator-based branching rules consistently
117117+The system SHALL evaluate saved branching rules using the configured operator semantics for the active block before determining the next step in the respondent path. The runner and submission validation flow SHALL use the same operator behavior.
118118+119119+#### Scenario: Respondent triggers a numeric comparison rule
120120+- **WHEN** a respondent answers a number or date question with a value that satisfies a saved comparison operator such as greater than or less than
121121+- **THEN** the system routes the respondent to that rule's target block
122122+123123+#### Scenario: Respondent triggers an empty-answer rule
124124+- **WHEN** a respondent leaves an optional question empty and the current block has a saved `is empty` branch rule
125125+- **THEN** the system routes the respondent using that rule instead of treating the empty answer as unmatched
126126+127127+#### Scenario: Respondent triggers a multiple-choice contains-any rule
128128+- **WHEN** a respondent selects multiple options and at least one selected option matches a saved `contains any` branch rule
129129+- **THEN** the system routes the respondent to that rule's target block
130130+131131+#### Scenario: Client and server evaluate the same rule set
132132+- **WHEN** a respondent completes and submits a branched form using supported advanced operators
133133+- **THEN** the submission validation path accepts or rejects the route using the same branching semantics as the public runner
···119119#### Scenario: Creator opens a form builder in an organization workspace
120120- **WHEN** an authenticated creator opens a form that belongs to an organization workspace
121121- **THEN** the system shows that organization context in the builder chrome
122122+123123+### Requirement: Creator can configure answer-based branch rules on question blocks
124124+The system SHALL allow an authenticated creator to add, edit, reorder, and remove branch rules on answerable blocks in a form located in an accessible workspace. Each branch rule SHALL compare the current block's answer using behavior appropriate to that block type and SHALL send respondents to a later block in the same form. The system SHALL also allow an authenticated creator to configure a default next target on an answerable block so respondents can continue to a chosen later block when no branch rule matches. If no branch rule matches and no default next target is configured, the respondent flow SHALL continue to the next block in saved order.
125125+126126+#### Scenario: Creator adds a conditional follow-up for one answer
127127+- **WHEN** an authenticated creator configures a single choice question so one option branches to a later follow-up block
128128+- **THEN** the system saves that branch rule on the source question and keeps the unconfigured path flowing to the next saved block
129129+130130+#### Scenario: Creator defines divergent paths from one question
131131+- **WHEN** an authenticated creator configures different branch rules for different answers on the same question block
132132+- **THEN** the system saves distinct later-block targets for those answers on that source block
133133+134134+#### Scenario: Creator changes branch priority
135135+- **WHEN** an authenticated creator reorders branch rules on a question block
136136+- **THEN** the system saves the updated evaluation order for that block's branch rules
137137+138138+### Requirement: Builder validates branch graphs before publishing
139139+The system SHALL validate saved branch rules before allowing a form to publish. The system SHALL prevent publishing when a branch rule points to a missing, current, or earlier block, or when one or more blocks become unreachable from the first block under the configured branch graph.
140140+141141+#### Scenario: Creator tries to publish with a backward branch target
142142+- **WHEN** an authenticated creator attempts to publish a form containing a branch rule that points to the source block or an earlier block
143143+- **THEN** the system blocks publishing and indicates that the branch target must move forward in the form
144144+145145+#### Scenario: Creator tries to publish with an unreachable block
146146+- **WHEN** an authenticated creator attempts to publish a form whose saved branch rules leave a block unreachable from the form start
147147+- **THEN** the system blocks publishing and indicates that the unreachable block must be reconnected or removed
148148+149149+#### Scenario: Creator saves an invalid draft while editing branching
150150+- **WHEN** an authenticated creator saves draft changes that leave branch validation issues unresolved
151151+- **THEN** the system preserves the draft changes and continues to block publishing until the issues are fixed
152152+153153+### Requirement: Creator can configure operator-based branch conditions on question blocks
154154+The system SHALL allow an authenticated creator to configure branch rules on answerable blocks using operator-aware conditions appropriate to the source block type. The supported operator set SHALL include `equals`, `not equals`, `is empty`, and `is not empty` for answerable blocks; `contains` for text-answer and link blocks; `contains any` for multiple choice blocks; and `greater than`, `greater than or equal`, `less than`, and `less than or equal` for number and date blocks.
155155+156156+#### Scenario: Creator configures a numeric threshold branch
157157+- **WHEN** an authenticated creator configures a number question with a branch rule using a greater-than or less-than style operator
158158+- **THEN** the system saves that operator and operand as part of the branch rule for that question
159159+160160+#### Scenario: Creator configures an empty-answer branch
161161+- **WHEN** an authenticated creator configures a branch rule using `is empty` or `is not empty` on an answerable block
162162+- **THEN** the system saves that rule without requiring a comparison value
163163+164164+#### Scenario: Creator configures a text contains branch
165165+- **WHEN** an authenticated creator configures a text-answer or link question with a `contains` branch rule
166166+- **THEN** the system saves the rule and limits it to a valid operator for that block type
167167+168168+### Requirement: Builder distinguishes branching blockers from advisory warnings
169169+The system SHALL surface branching validation feedback while a creator edits a form and SHALL distinguish publish-blocking routing errors from non-blocking advisory warnings.
170170+171171+#### Scenario: Creator introduces a publish-blocking branching error
172172+- **WHEN** an authenticated creator edits a branch rule so that its target is missing, invalid for that block type, or unreachable in the form graph
173173+- **THEN** the system preserves the draft change, marks the issue as publish-blocking, and prevents publishing until it is fixed
174174+175175+#### Scenario: Creator introduces a fragile but still valid branch setup
176176+- **WHEN** an authenticated creator creates a branch setup that is structurally valid but likely fragile or overlapping
177177+- **THEN** the system surfaces an advisory warning without preventing the draft from being saved
+11
openspec/specs/response-review/spec.md
···3232#### Scenario: Creator opens responses for an accessible form
3333- **WHEN** an authenticated creator opens the responses view for a form in a workspace they can access
3434- **THEN** the system displays available export actions for the supported response export formats
3535+3636+### Requirement: Creator can inspect branching route context for a submission
3737+The system SHALL allow an authenticated creator to inspect the visited route and skipped sections for an individual submission from a branched form while preserving the submission's saved form-order context.
3838+3939+#### Scenario: Creator opens a branched submission
4040+- **WHEN** an authenticated creator views a response submitted through a branched form
4141+- **THEN** the system shows which blocks were visited in the submission path and which blocks were skipped by branching
4242+4343+#### Scenario: Creator reviews a decision point in the visited path
4444+- **WHEN** an authenticated creator inspects a visited branching question in a submission
4545+- **THEN** the system shows the submitted answer in context so the taken route is understandable