#Agent execution layer
How an agent applies this law: the order of reasoning, the evidence that supports a finding, the scope boundary that stops one, and the exact shape a report has to emit.
#Agent directive
When implementing an interactive frontend feature:
- Identify the user task.
- Inspect existing product capabilities.
- Map expected flow states.
- Implement implied completeness.
- Preserve established conventions.
- Surface expected failures.
- Provide recovery where necessary.
- Preserve user work where feasible.
- Verify responsive and accessible operation.
- Stop before introducing new product scope.
#Severity
#Low
Flow works but continuity or feedback is weaker than it should be.
#Medium
A common path becomes confusing, inefficient, or unrecoverable.
#High
The flow can cause:
- data loss,
- unsafe action,
- blocked task,
- misleading state,
- duplicate transaction,
- inaccessible critical behavior.
#Confidence
#High
Repository/runtime clearly proves the missing state.
#Medium
Product patterns strongly suggest it.
#Low
Reviewer is guessing that a feature might be useful.
Low-confidence product ideas are questions, not findings.
#Review directive
Do not ask:
Does every component have every possible state?
Ask:
Which states can occur in this task, and are the important ones designed?
A strong finding contains:
- observable evidence
- +
- task context
- +
- missing state
- +
- user consequence
- +
- specific correction
#Human checklist
Before calling a feature complete:
- Can the user get into the task?
- Can they tell what can be done?
- Can they perform the action?
- Is required input understandable?
- Is pending work visible?
- Is success observable?
- Are expected failures represented?
- Is recovery possible where necessary?
- Does the user remain oriented afterward?
- Does it work on mobile?
- Does it work by keyboard?
- Are permissions respected?
- Is user work preserved on failure?
- Did we avoid adding unsupported capability?
#Required behavior
- Identify the user task the requested surface belongs to, not only the surface named in the prompt.
- Inspect the repository for states the product already implements, and reuse those conventions rather than inventing new ones.
- Map the nine flow stages against the implementation and record which stages a real path reaches.
- Report a missing state only when a real path reaches it; name the path in the finding.
- Name the user consequence of the missing state, not the omission alone.
- Propose the smallest correction that completes the task, reusing existing components.
- Classify every addition as interaction completeness, existing product capability, or new product scope.
- Stop at the scope boundary: raise new product scope as a question, never as a finding.
#Prohibited agent behavior
- Do not require every component to implement every conceivable state.
- Do not invent product capability the repository does not support.
- Do not report a missing state without naming the path that reaches it.
- Do not treat a design choice you would have made differently as an incomplete flow.
- Do not replace an established product pattern with a generic one while adding a state.
- Do not report speculative features as findings; they are questions.
#Evidence hierarchy
#High-confidence evidence
- A mutation with no pending state in the component that triggers it.
- A form that discards user input when the request fails.
- A destructive action with no confirmation and no undo.
- An error branch that renders nothing the user can read.
- A route that can be reached with no data and renders no empty state.
#Medium-confidence evidence
- A flow whose success is announced only by a transient toast the user can miss.
- A long-running action with a pending state but no progress or cancel path.
- A list that handles loading and success but not partial failure.
- An entry point that exists in one surface and is missing from the equivalent one.
#Low-confidence evidence
- A feature you believe users would want that the product does not offer.
- A state that no observed path reaches.
- A preference for a different interaction pattern with equivalent completeness.
#Finding contract
finding:
rule_id: LAYR-002
title: string
task: string
surface: string
location: string
stage:
- entry
- discovery
- action
- input
- system-state
- outcome
- failure
- recovery
- continuation
evidence:
observable:
- string
path: string
missing_state: string
consequence: string
correction:
change: string
reuses: string | null
scope:
level: interaction-completeness | existing-product-capability | new-product-scope
within_boundary: true | false
severity: low | medium | high
confidence: low | medium | high
#Worked findings
#Finding A: a failed save discards the user's edits
finding:
rule_id: LAYR-002
title: Failed save discards the user's edits
task: Correct a customer address before invoicing
surface: EditCustomerForm
location: components/customer/edit-form.tsx
stage:
- failure
- recovery
evidence:
observable:
- The mutation's catch branch calls reset() on the form.
- No error is rendered next to any field.
path: Submit with a server-side validation error on postcode.
missing_state: A failure state that keeps the entered values and names the rejected field.
consequence: The user retypes the whole form and cannot tell which value was rejected.
correction:
change: Keep form state on error and render the field-level message the API already returns.
reuses: FieldError, already used by the billing form.
scope:
level: interaction-completeness
within_boundary: true
severity: high
confidence: high
#Finding B: a long import reports no progress
finding:
rule_id: LAYR-002
title: Import runs with no progress and no way out
task: Import a contacts CSV
surface: ImportDialog
location: components/import/import-dialog.tsx
stage:
- system-state
- continuation
evidence:
observable:
- The dialog renders a spinner for the whole upload.
- The job endpoint returns processed and total counts that the UI never reads.
path: Import a file large enough to take more than a few seconds.
missing_state: Determinate progress, and a path that survives closing the dialog.
consequence: The user cannot tell whether the import is advancing or stalled, and closing the dialog appears to lose the job.
correction:
change: Render the counts the endpoint already returns and keep the job resumable from the imports list.
reuses: ProgressMeter, already used by the export flow.
scope:
level: interaction-completeness
within_boundary: true
severity: medium
confidence: high
#Finding C: a missing capability that is not a finding
finding: null
reason: >
The reviewer expected bulk editing from the invoice list. The product has no
bulk mutation anywhere, and no path in this task reaches a bulk state. This is
new product scope, so it is raised as a question rather than reported as an
incomplete flow.
question: Should the invoice list support bulk actions? No existing surface implies it.
scope:
level: new-product-scope
within_boundary: false
#Agent routing hints
Route to this rule when the work adds or reviews an interactive surface: a form, a mutation, a destructive action, an upload, a long-running job, or any control that changes server state. Route to LAYR-001 instead when the question is whether an element should exist at all.
#Before and after
Each pair is one task, written twice: the surface the prompt asked for, and the flow the task actually needs.
#Deleting a record
#Surface-only
#Complete flow
→ pending state on the button, list still readable
→ row removed, undo offered for a bounded window
→ failure: row stays, reason shown, action still available
#Saving a form
#Surface-only
#Complete flow
→ success: the record reflects the new values in place
→ failure: field-level messages, nothing retyped
→ the user stays where the next step happens
#Uploading a file
#Surface-only
#Complete flow
→ determinate progress, cancel available
→ rejected file: reason and the same control ready to retry
→ partial success: what landed, what did not, what to do
#Research foundation
The Complete Flow Law is a Layr synthesis. It restates no single source; it draws the task-as-unit-of-completion idea from task analysis and use-case modelling, and grounds the failure, status and recovery stages in accessibility success criteria.