.agents/acceptance/common-mistakes.md
Project-specific mistakes only. Read this with the agent-testing skill's generic
references/common-mistakes.md. Stable ids use the L- prefix so they cannot be
confused with the generic M catalogue.
Keep this file at the level of durable LobeHub product and environment invariants. Exact copy, pixel values, component slot order, and one-off review directions belong in feature specifications or historical field notes, not in this living checklist.
Wrong approach: assign a replacement check a new id without supersedes, or
pass a visible UI check from test output or computed styles alone.
Why it fails: Acceptance intentionally does not fuzzy-match titles, and program output does not establish the rendered result.
Correct approach: declare the previous stable id in supersedes; give every
user-visible case opened visual evidence and assert the complete spatial outcome,
including overlap.
Wrong approach: apply a temporary transform to isolate position syncing, then publish a screenshot while the product panel is visibly displaced.
Why it fails: the numeric assertion may pass while the visual evidence depicts a broken product state.
Correct approach: capture the settled result of a real layout transition. Keep synthetic probes as supporting text evidence and restore the DOM before capturing a passing screenshot.
Wrong approach: publish an entry button and source-level evidence as proof that manual check creation is complete.
Why it fails: an entry point does not demonstrate form entry, the resulting check, or where it enters the Acceptance lifecycle.
Correct approach: verify entry, completed input and preview, and the created item in its editable pre-verification state. Keep this path independent from unrelated rubric loading.
Wrong approach: prove behavior in a standalone or harness surface when the requested surface is a Task drawer, or use a small fixture for behavior that changes at a list-size threshold.
Why it fails: the same content composes differently across containers, and small fixtures cannot expose grouping, density, overflow, or master-detail pressure.
Correct approach: capture the requested product container with representative titles, state mix, item count, and both sides of every behavior-changing threshold. Use harnesses only as supporting evidence.
Wrong approach: publish only an aggregate checklist or transcript saying that all checks passed.
Why it fails: reviewers cannot inspect what each verifier saw or why each delivery criterion passed.
Correct approach: capture a readable overview and inspectable detail evidence for each underlying criterion. Map every stable criterion id to its verifier, evidence, and verdict.
Wrong approach: upload a generated document only as Acceptance evidence when the Task requires a durable document deliverable.
Why it fails: audit evidence explains a verdict; it does not create a reusable artifact in the Task workspace.
Correct approach: create and pin the real product artifact to the Task, then attach separate evidence proving its content and association.
Wrong approach: label a screenshot check only as LLM or Agent, with media
requirements and model capability shown elsewhere.
Why it fails: reviewers cannot tell whether the visual evidence was actually inspected by a multimodal model.
Correct approach: present verifier type, multimodal capability, and required evidence media together; explicitly identify screenshot checks as multimodal.
Wrong approach: compare criteria from one Task with results from another and interpret the different item counts as a lifecycle defect.
Why it fails: Tasks may legitimately have different goals, while Acceptance retains later-round checks as delivery history.
Correct approach: capture definition and result states from the same Task, keep the complete cross-round check union visible, and synchronize the Task verification requirement with the aggregate goal.
Wrong approach: publish separately scoped implementation work as a new round on an Acceptance whose delivery has already been accepted.
Why it fails: the closed audit record no longer matches the delivery that was decided, and reviewers cannot independently accept or reject the new work.
Correct approach: inspect Acceptance status before ingest. Create a new Task or subject for a materially new delivery; reopen the existing delivery only when the user explicitly requests it and the lifecycle supports it.
Wrong approach: trust the model shown before Agent assignment, then judge the run without checking the persisted Task configuration and completed message metadata.
Why it fails: Agent assignment can replace the Task provider or model, so the observed behavior may belong to a fallback model.
Correct approach: after every assignment or Task edit, verify both persisted provider/model configuration and the first completed assistant message metadata. Attach the runtime identity to the Acceptance round before judging quality.
Wrong approach: read acceptance run ingest's success JSON, see an
acceptanceId and a round index, and stop — treating a [WARN] evidence upload failed, skipping <file> line above it as noise because the command still exited 0.
Why it fails: a transient storage error skips exactly one artifact and the run
publishes anyway. When the casualty is one half of a comparison pair, the
surviving half renders alone under its role band — a lone before screenshot reads
as "the fix never landed", inverting the round's verdict.
Correct approach: count the evidence items in result.json before publishing
and compare against the ingest JSON's evidence field; treat any WARN line as a
failure of the publish step. Do not retro-attach the missing file with
acceptance run evidence upload — that path carries no comparison metadata, so
the image lands unpaired and unlabeled. Publish a fresh round carrying the complete
evidence set instead, and say in report.md that it re-publishes the same
observations rather than re-running the cases.
verifier enumWrong approach: write a value such as "verifier": "multimodal LLM" in a plan
item to satisfy the requirement that screenshot checks disclose multimodal review.
Why it fails: verifier is a closed set (program / agent / llm) that the
ingest validator rejects outside those values, so the whole payload fails. The
disclosure is not expressible in that field.
Correct approach: set "verifier": "llm" and carry the multimodal disclosure in
the plan item's method prose alongside "requiredEvidence": ["screenshot"].
Wrong approach: copy a sibling surface's appearance without enumerating its semantics, states, affordances, wiring, and authored-data conventions.
Why it fails: visual similarity can hide a second interaction dialect for the same product object and causes later improvements to drift.
Correct approach: inspect the canonical implementation feature by feature, reuse its semantic components where possible, and compare both surfaces side by side.
Wrong approach: add own/workspace scope variants to one maintenance action while leaving sibling actions with different authority semantics.
Why it fails: authority was reviewed per menu item instead of as a role × action × scope matrix.
Correct approach: enumerate every matrix cell; keep members own-only and give owners explicit workspace variants with stronger confirmation for destructive work.
Wrong approach: configure a host to keep a shared composer permanently open while continuing to render the component's Collapse action.
Why it fails: the host contract and the advertised state transition contradict each other.
Correct approach: model collapse capability as an explicit host option. Verify pinned and collapsible hosts independently.
Wrong approach: reuse dense list-row chrome and controls unchanged inside an already-open detail panel.
Why it fails: list affordances such as expansion controls and compact metadata duplicate context and compete with the detail surface's reading and decision tasks.
Correct approach: preserve canonical object semantics and evidence order, but give detail mode its own permanently expanded interaction contract and clear decision hierarchy. Keep exact layout values in the feature specification.
Wrong approach: reserve the measured composer overlay height in the virtualized message list but not in the empty or welcome path.
Why it fails: alerts and trays can overlap welcome content even though overlay items do not overlap each other.
Correct approach: apply the same measured reservation to every content path and capture the real combined overlay state.
Wrong approach: let long outline and detail content expand the document, or rely on one shared outer scroll container.
Why it fails: navigation and reading context drift together, headers disappear, and intermediate flex sizing can hide the intended inner scrollbars.
Correct approach: bound the workspace, keep the frame overflow hidden, assign independent scroll regions to navigation and detail, and verify scroll ownership with DOM measurements as well as visual evidence.
Wrong approach: strip a server environment variable and treat lh whoami as
proof that Acceptance ingest targets production.
Why it fails: lh login persists serverUrl in the CLI settings, and a local
database may contain the user's synchronized profile.
Correct approach: inspect the effective CLI settings or use a data probe that
distinguishes environments. For production publishing without changing a local
login, use an isolated LOBEHUB_CLI_HOME for login and ingest.
Wrong approach: use green Vite and Vitest results as blank-screen insurance for a desktop routing or module-graph change.
Why it fails: browser ESM initialization cycles and nested-router invariants can fail only when the real renderer starts.
Correct approach: boot the real Electron instance, require the project readiness probe to report a non-error UI, and inspect a screenshot. Router-host component tests must also cover the real outer-router composition.
Wrong approach: rebase against a stale local canary pointer and treat its UI as
the latest canary behavior.
Why it fails: already-merged presentation changes may make every screenshot prove the retired product version.
Correct approach: fetch origin canary, record the resolved SHA, and verify it is
an ancestor of the test branch before starting the evidence environment.
Wrong approach: stop the dev server or workflow dependencies when the main agent operation finishes or the first verification snapshot appears stuck.
Why it fails: verification and repair can start minutes later and may still own pending operations.
Correct approach: monitor verification results, repair-operation links, and the bound Task until a stable terminal state. Keep every required dependency alive until the final round settles or a concrete non-progress failure is proven.
Wrong approach: attach to port 9222 and assume it belongs to the LobeHub dev Electron instance.
Why it fails: another Electron project can own the universal default port, while the user's LobeHub instance may expose no debugging port at all.
Correct approach: verify the owning process path and probe a LobeHub-specific renderer marker before collecting evidence. If needed, start an isolated pool instance on a distinct port rather than guessing.
Wrong approach: use useSearchParams, useQueryState, useParams,
useLocation, useNavigate, or a bare <Link> inside a component that a route
layout registers through NavPanelPortal, and verify it only on web.
Why it fails: the desktop shell renders every registered sidebar outside the per-tab routers, so React context binds those hooks to the root router, whose location never moves. A write lands on a router no page reads and a read resolves the boot url. Both are silent: the sidebar renders normally and web is unaffected, so the defect looks like unrelated page logic. Verified twice in this catalogue's lifetime — as a topic-switch failure that made the generation page ignore its own send button, and as a library tree that never expanded to the open folder.
Correct approach: in any shell-rendered tree, read through the active-tab
facades (useActiveLocation, useActiveRouteParams) and navigate through
useWorkspaceAwareNavigate / appNavigate, keeping <Link> only for its href
with the click handled by the facade. Note that no active-tab twin exists for
search params: express a param write as a facade navigation rather than
setSearchParams. When the state is a url ⇄ store sync owned by the page, mount
it in the route layout instead, and cover it with a test that asserts which router
received the write — a test that only asserts a write happened passes on the
broken topology too.
Detailed incident narratives and retired pixel- or component-specific directions belong in the field notes, where they remain available without becoming mandatory rules for every Acceptance run.