Skip to content

feat(chat): surface daemon failure_detail to sharpen run-error guidance - #5321

Merged
AmyShang-alt merged 8 commits into
mainfrom
feat/run-failure-detail-surface-895
Jul 10, 2026
Merged

feat(chat): surface daemon failure_detail to sharpen run-error guidance#5321
AmyShang-alt merged 8 commits into
mainfrom
feat/run-failure-detail-surface-895

Conversation

@open-design-crew

Copy link
Copy Markdown
Contributor

Stacks on #5308. Base is feat/run-failure-guidance-895; review/merge that first. The diff here is only the detail-propagation layer on top of #5308's code→guidance mapping.

Why

Author's use case: while wiring #5308 (mapping error_code → a named failure type + fix for #895), I hit causes the code alone can't tell apart. The daemon already computes a much finer classification — failure_category / failure_detail in run-failure-classification.ts — but it never leaves the daemon (used only for retry policy + telemetry). So the chat is stuck guessing from a coarse code.

The pain: distinct failures collapse onto one code and get the wrong advice:

  • A hard quota / exhausted credits and a transient 429 both arrive as RATE_LIMITED. feat(web): surface actionable run-failure guidance for common errors #5308 shows "wait and retry" for both — but retrying a hard quota is futile and just reproduces the failure.
  • A missing CLI detected only from stderr text leaks in as the opaque AGENT_EXECUTION_FAILED, so it can't be routed to the "install the CLI" card.

This PR closes that gap by giving the client the classification the daemon already has.

What users will see

  • A run that fails on a hard quota / workspace credits now shows a distinct "Quota exhausted" card that explains retrying won't help and removes the dead Retry button, steering to the hosted-AMR switch card instead (top up / switch service).
  • A run that fails because the agent CLI isn't installed (even when only detectable from the error text) now shows the same "Agent not installed → install it, then retry" card as the structured case, instead of a raw error string.
  • Transient rate limits are unchanged (still offer Retry), and Antigravity's terminal switch-model flow is unchanged.

How it works

Mirrors the already-proven resumable propagation path end-to-end:

  1. Contracts — add optional failureCategory / failureDetail to ChatRunStatusResponse, the persisted status:error event, and ChatSseEndPayload (reusing the analytics TrackingRunFailure* unions so producer/consumer can't drift).
  2. Daemon — set run.failureCategory/Detail at the same finalize point that sets run.resumable; emit them in statusBody + the SSE end frame.
  3. Web — the streaming layer stamps the classification onto the surfaced error; ProjectView / useConversationChat persist it onto the assistant message; resolveRunFailureUi(code, detail, agentId) applies a DETAIL_FAILURE_UI override layer (after the AMR/Antigravity agent branches, before the generic code branches) so detail can correct a too-coarse code.

Tests

  • Daemon red spec (run-failure-detail-status.test.ts): a hard-quota run's /api/runs/:id status now surfaces failureCategory: 'rate_limit' + failureDetail: 'hard_quota'. Red on main/feat(web): surface actionable run-failure guidance for common errors #5308 (fields absent from the DTO), green here.
  • Web unit (amr-guidance.test.ts): hard_quota / workspace_credits override RATE_LIMITED to a no-Retry "Quota exhausted" card; a transient 429 keeps Retry; cli_not_installed routes to the install-CLI card; Antigravity's switch-model flow still wins over the detail override.
  • pnpm guard, pnpm typecheck, and the adjacent daemon suites (resume-on-failure, sse-response, run-failure-classification) all pass.

Surface area

  • Web UI (chat run-error card) — behavior change; see screenshots below.
  • Contracts (packages/contracts) — new optional DTO / SSE fields.
  • Daemon HTTP/SSE — new fields on run status + end frame.
  • i18n keys — chat.runError.title.quotaExhausted, quotaExhaustedMessage, workspaceCreditsMessage across all 19 locale files.
  • CLI: no new subcommand. od run-status JSON now carries the same failureCategory/failureDetail via the shared DTO, so the machine-readable surface stays in parity with the UI.

Screenshots

TODO: attach the "Quota exhausted" (no-Retry, switch-card) and text-detected "Agent not installed" cards from the running web app.

@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

The contract → daemon → web propagation path is easy to follow here, especially the way you kept it aligned with the existing resumable flow. Before pool review picks this up, could you convert Surface area into the checklist shape the template parser expects and add an explicit Validation section listing what you actually ran? That should clear the body lint on this stack-on PR.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Visual regression review

Head: 67d2b3d · Base: 81b20dc

0 changed · 53 unchanged · 0 new without baseline · 0 failed

Unchanged cases
Case Main PR Diff
visual-avatar-local-agent-list
0 px (0.00%)
main pr diff
visual-avatar-local-agent-list-panel
0 px (0.00%)
main pr diff
visual-avatar-menu
0 px (0.00%)
main pr diff
visual-avatar-menu-panel
0 px (0.00%)
main pr diff
visual-avatar-open-design-account
0 px (0.00%)
main pr diff
visual-critical-settings
0 px (0.00%)
main pr diff
visual-critical-workspace
0 px (0.00%)
main pr diff
visual-critical-workspace-preview
0 px (0.00%)
main pr diff
visual-design-system-detail
0 px (0.00%)
main pr diff
visual-design-systems
0 px (0.00%)
main pr diff
visual-home
0 px (0.00%)
main pr diff
visual-home-catalog
0 px (0.00%)
main pr diff
visual-home-context-picker
0 px (0.00%)
main pr diff
visual-home-context-picker-popover
0 px (0.00%)
main pr diff
visual-home-plugin-filter
0 px (0.00%)
main pr diff
visual-home-plugin-use-staged
0 px (0.00%)
main pr diff
visual-home-plugin-use-with-query
0 px (0.00%)
main pr diff
visual-home-staged-attachment
0 px (0.00%)
main pr diff
visual-integrations
0 px (0.00%)
main pr diff
visual-integrations-mcp
0 px (0.00%)
main pr diff

Visual diff is advisory only and does not block merging.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one blocking persistence gap in the new failure-detail propagation; details inline.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread packages/contracts/src/api/chat.ts
@open-design-crew

Copy link
Copy Markdown
Contributor Author

Screenshots

Rendered with the real tokens.css / chat.css. These show the two new failure_detail-driven states this PR adds.

RATE_LIMITED · failure_detail=hard_quota → "Quota exhausted"

The detail overrides the coarse code: the card drops the futile Retry and steers to the hosted-AMR switch card instead. (workspace_credits_exhausted reuses the same card with workspace-specific copy.)

Hard-quota run-error card with no Retry button, followed by the AMR switch card

AGENT_EXECUTION_FAILED · failure_detail=cli_not_installed → "Agent not installed"

A missing CLI detected only from stderr text (which leaks in as the opaque AGENT_EXECUTION_FAILED code) is now routed to the same install-the-CLI card — with Retry kept, since it recovers once the CLI is installed.

CLI-not-installed run-error card with a Retry button

All three states together

Full harness: hard_quota, workspace_credits_exhausted, and cli_not_installed cards

Images hosted on the throwaway assets/pr-5321-screenshots branch to keep this PR's code diff clean; safe to delete after merge.

@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for adding the screenshots — that closes the visual gap from earlier.

The main blocker now is the persistence path @nettee called out: failureCategory / failureDetail need to survive the daemon-side status:error persistence path as well, otherwise the new guidance only sticks when a live tab catches the terminal error.

💡 To drive this PR to merge hands-free, paste this to your AI coding agent (Claude Code / Codex / opencode / Cursor …):
Take over nexu-io/open-design#5321 until it merges — read https://raw.githubusercontent.com/nexu-io/looper/main/skills/pr-takeover/SKILL.md and follow it.

@open-design-crew

Copy link
Copy Markdown
Contributor Author

截图已更新:托管服务改名为 Open Design Cloud(原 AMR)。切换卡文案现为「切换到 Open Design Cloud 并重试」/「可切换到 Open Design Cloud 官方模型服务」。上方图片链接指向同名文件,已随 assets/pr-5321-screenshots 刷新。

@mrcfps mrcfps left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@app/open-design-crew Thanks for the clear propagation work here; the status/SSE fields and client-side mapping are easy to follow. I rechecked the current head and the blocking persistence gap from the existing unresolved thread is still present: packages/contracts/src/api/chat.ts now allows persisted status:error events to carry failureCategory / failureDetail, but apps/daemon/src/server.ts runSseEventToPersistedAgentEvent() still serializes daemon error SSE frames as only { kind: 'status', label: 'error', detail }. Because daemon-side message persistence uses that producer, a failed run that completes without the live web error handler saving the message, or a conversation reloaded before that save happens, will lose the new classification and fall back to the coarse/raw error UI. Please persist the structured error code plus the finalize-time failureCategory / failureDetail on the daemon-owned assistant-message event path, and cover it with a regression that reads the stored assistant message after a failed hard-quota/CLI-missing run.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks — the current head is still blocked on the same daemon-owned persistence gap, and @mrcfps has now confirmed it on recheck as well. Once runSseEventToPersistedAgentEvent() persists the structured code + failureCategory / failureDetail fields and the stored-message regression covers the daemon-owned path, this should be in good shape for another pass.

Comment thread apps/daemon/src/server.ts
@nettee

nettee commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@app/open-design-crew I'm holding off on generating review comments for #5321 because this pull request has merge conflicts right now.

Please resolve the conflicts with main and push the updated branch. Once that's done, request or wait for the review to run again and I'll take another look.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@lefarcen lefarcen added size/XXL PR changes 1500+ lines needs-validation Runtime change detected; needs human or /explore agent validation. and removed size/L PR changes 300-700 lines labels Jul 9, 2026
@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🧪 This PR changes user-visible run-error behavior, so it will need a manual QA pass before merge.

It also has conflicts with main right now, so please hold off merging for now — once the branch is conflict-free and back to a merge-ready state, we'll loop QA in for validation.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current head still has one blocking persistence gap in the failure-detail propagation; details inline.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/daemon/src/server.ts
xiaoche-hub added 2 commits July 9, 2026 16:10
The daemon already classifies each run failure into failure_category /
failure_detail (run-failure-classification.ts) for retry policy and
telemetry, but kept it daemon-internal — so the chat could only key error
guidance off the coarse errorCode. That collapses distinct causes that
share one code: a hard quota and a transient 429 both arrive as
RATE_LIMITED, and a text-detected missing CLI leaks in as the opaque
AGENT_EXECUTION_FAILED.

Propagate the classification to the client (contract DTO + SSE end frame,
mirroring the proven `resumable` path) and let resolveRunFailureUi take
`detail` as a first-class input that can override a too-coarse code:

- hard_quota / workspace_credits_exhausted -> a distinct "Quota exhausted"
  card that drops the futile Retry (primaryAction 'none') and steers to the
  hosted-AMR switch card instead.
- cli_not_installed (text-detected) -> the same install-the-CLI card the
  AGENT_UNAVAILABLE code path already renders.

A transient 429 without a hard-quota detail still offers Retry, and the
Antigravity terminal switch-model flow still wins over the generic detail
override.

Stacks on #5308 (the code->guidance mapping this detail layer refines).
The hosted model service is now Open Design Cloud, but the run-error
cards this PR sharpens (switch / auth / balance), plus settings account +
wallet labels, avatar console, onboarding gate, and the handoff website
link, still showed the old "AMR" (or bare "Open Design") name. Normalize
every user-visible brand mention to "Open Design Cloud" across all 19
locales. Value-only: no keys, agent ids, URLs, or raw daemon error
strings touched.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the current ae98f47 head across the daemon/contracts/web diff. One blocking persistence gap remains in the new failure-detail propagation; details inline.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/daemon/src/server.ts
The daemon emits the terminal `error` SSE frame from the child-close
handler before a run is finalized, so `failureCategory` / `failureDetail`
(computed at finalize) weren't known when that frame was first persisted
to the assistant message — the stored `status:error` event kept only
`{ detail, code }`. A failure persisted without the live web error
handler saving the message, or a conversation reloaded before that save
landed, therefore fell back to the coarse errorCode UI and lost the
specific fix guidance this PR adds.

Stamp the finalize-time classification onto the persisted assistant
message: enrich the last `status:error` event in place (append one only
if a failed run somehow never persisted an error frame). Covered by a
daemon regression that reads the stored assistant message via the
conversation-messages API after a failed hard-quota run.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the current 6d521e7 head end-to-end across the daemon/contracts/web changes. One blocking issue remains in the live web propagation path; details inline.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/web/src/runtime/chat-events.ts
@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for the detailed write-up — that sounds like the right fix for the daemon-owned persistence path, and the new persisted-message regression is exactly the missing coverage reviewers were asking for. Once the refreshed checks land, the next useful step is a fresh pass from the blocking reviewers on 6d521e7 so they can confirm the persisted-message path now closes the hard-quota / cli-not-installed gap end to end.

@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks — it looks like the daemon-side persistence piece is in, and the remaining blocker has moved to the live web reattach path @nettee just called out. The next fix needs appendErrorStatusEvent() to merge code / failureCategory / failureDetail into an existing trailing status:error event when the detail string is unchanged, plus the web regression for that reload/reattach sequence.

…recovery paths

Two live-propagation gaps let the sharpened run-error card degrade back to
the coarse/raw UI even though the daemon now sends the classification:

- appendErrorStatusEvent() no-op'd whenever the message already had a
  trailing status:error with the same detail. In the reload/reattach race
  (reload reads the daemon-persisted error frame first, then the run
  finishes and onError arrives with the finalize-time classification) that
  dropped the new code / failureCategory / failureDetail. Merge those into
  the existing event in place instead; no-op only when nothing is added.

- The error-frame-then-status recovery probe in providers/daemon.ts broke
  out on a terminal failed status without copying failureCategory /
  failureDetail (unlike the post-loop status fallback), so markErrorRunFailure
  stamped null and the failureDetail mapping fell back to the generic card on
  the reconnect path. Mirror the two assignments before the break.

Covered by chat-events (in-place merge) and daemon-sse-reconnect (error
frame + terminal status fetch, no end frame) regressions.

@mrcfps mrcfps left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@app/open-design-crew I reviewed the current f4eced7 head across the daemon status/SSE propagation, persisted assistant-message enrichment, web reattach/error merging paths, failure-detail UI mapping, contracts, and the focused regression coverage. The previous persistence and reload/reattach blockers appear addressed on this head; git diff --check origin/main...HEAD is clean. I could not execute the focused Vitest suites in this prepared worktree because node_modules is missing (vitest was not available), so this approval is based on static review plus the added test coverage in the diff. Thanks for iterating on the edge cases and tightening the failure guidance path. 🙂

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@app/open-design-crew I reviewed the current f4eced7 head across the daemon status/SSE propagation, daemon-side persisted-message enrichment, web reload/reattach error merging, failure-detail UI mapping, and the new focused regression coverage. The previously blocking persistence and same-detail reattach gaps appear addressed in the changed ranges, and git diff --check origin/main...HEAD is clean. I could not execute the focused test suites in this prepared worktree because node_modules is missing, so this approval is based on static review plus the added targeted tests in the diff. Thanks for tightening the failure guidance path and covering the reload edge cases.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for tightening the live web path on f4eced7 and for adding the two web regressions. @mrcfps has now approved this head, so the remaining visible blockers look procedural rather than a new propagation gap: GitHub still shows the PR as blocked / not merge-ready, and @nettee has not refreshed this head yet. Once those clear, the queued QA pass can pick it up.

@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🧪 Queued for QA validation — this head changes the run-error / reload guidance path in a way that needs a manual pass before merge.

Nothing needed from you on this step; we’ll update here once QA has gone through the failure-detail flows.

Keep PR failure-guidance i18n wording and incorporate main's
settings.amrModelUpgradeHint across conflicted locale files.

Co-authored-by: Cursor <cursoragent@cursor.com>

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one blocking issue in the updated web regression coverage; details inline.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Location: apps/web/tests/runtime/amr-guidance.test.ts RIGHT line 192

This test still calls resolveRunFailureUi with the old two-argument shape, so after the new detail parameter was inserted it now passes 'amr' as detail and leaves agentId undefined. That means this case falls through to the generic retry branch instead of the AMR upgrade branch, so the focused regression suite described in the PR will fail once apps/web/tests/runtime/amr-guidance.test.ts is executed. Please update this call to resolveRunFailureUi('AMR_TIER_UPGRADE_REQUIRED', null, 'amr') so the test is actually exercising the AMR entitlement path again.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Inline comment could not be anchored: inline anchor is outside the PR diff anchorable ranges

@mrcfps mrcfps left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@app/open-design-crew Thanks for continuing to tighten the failure-detail propagation path. I found one current-head blocker in the web unit coverage after the resolveRunFailureUi signature change: an existing AMR tier-upgrade case is still calling the helper with the old two-argument shape, so it now passes amr as the detail instead of the agent and should fail. Details inline.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/web/src/runtime/amr-guidance.ts
@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks — the two current-head blocking reviews are pointing at the same remaining issue on 50703b1: the AMR tier-upgrade regression in apps/web/tests/runtime/amr-guidance.test.ts is still using the old resolveRunFailureUi call shape.

Updating that case to resolveRunFailureUi('AMR_TIER_UPGRADE_REQUIRED', null, 'amr') should line the test back up with the new signature and make it ready for another reviewer pass.

The main merge kept a two-argument call site that passed agentId as
detail after the signature gained an explicit detail parameter.

Co-authored-by: Cursor <cursoragent@cursor.com>

@mrcfps mrcfps left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@app/open-design-crew I reviewed the current 14bc861 head across the daemon status/SSE propagation, daemon-side persisted-message enrichment, web reload/reattach error merging, failure-detail UI mapping, and the focused regression coverage. The earlier persistence, reattach, and stale resolveRunFailureUi call-shape blockers are addressed in the current changed ranges; git diff --check origin/main...HEAD is clean. I could not execute the focused Vitest suites in this prepared worktree because node_modules is missing, so this approval is based on static review plus the added targeted tests in the diff. Thanks for the careful iteration on the failure guidance path. 🙂

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@app/open-design-crew I reviewed the current 14bc861 head across the daemon status/SSE propagation, daemon-side persisted-message enrichment, web reload/reattach error merging, failure-detail UI mapping, and the focused regression coverage. The earlier persistence, reattach, and stale resolveRunFailureUi call-shape blockers are addressed in the current changed ranges, and git diff --check origin/main...HEAD is clean. I could not execute the focused Vitest suites in this prepared worktree because node_modules is missing, so this approval is based on static review plus the added targeted tests in the diff. Thanks for tightening the failure guidance path and covering the reload edge cases.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Co-authored-by: Cursor <cursoragent@cursor.com>
@lefarcen

lefarcen commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@xiaoche-hub Rechecked the current head and the blocker matches your note: GitHub still isn't reporting a fresh Validate workspace result on 67d2b3d, so this looks procedural rather than a new review finding.

Once that required check is actually run on this head, the PR should be back in shape for queue/merge.

@lefarcen lefarcen closed this Jul 10, 2026
@lefarcen lefarcen reopened this Jul 10, 2026
Update unit and e2e selectors that still expected pre-rebrand strings
for account status, handoff website link, and switch-and-retry CTA.

Co-authored-by: Cursor <cursoragent@cursor.com>

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@app/open-design-crew I reviewed the current fda7539 head across the failure-detail propagation path, the persisted-message/reload recovery flow, and the final follow-up diff since the last clean pass. The earlier blockers remain addressed in the changed ranges, and this head’s additional changes are limited to aligning the AMR/Open Design Cloud test assertions with the current copy. I could not execute the focused suites in this prepared worktree because node_modules is absent, so this approval is based on static review plus the targeted regression coverage already in the diff. Thanks for tightening the edge cases and cleaning up the remaining test drift.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@mrcfps mrcfps left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@app/open-design-crew I reviewed the current fda7539 head across the daemon status/SSE failure-detail propagation, daemon-side persisted-message enrichment, web reload/reattach error merging, failure-detail UI mapping, contract changes, i18n keys, and the final Open Design Cloud test assertion updates. The earlier persistence, reattach, and stale resolveRunFailureUi call-shape blockers remain addressed in the changed ranges, and git diff --check origin/main...HEAD is clean. I could not execute the focused Vitest or Playwright suites in this prepared worktree because node_modules is missing, so this approval is based on static review plus the targeted regression coverage in the diff. Thanks for the careful iteration on this failure-guidance path.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@lefarcen lefarcen closed this Jul 10, 2026
@lefarcen lefarcen reopened this Jul 10, 2026
@AmyShang-alt

Copy link
Copy Markdown
Contributor

QA 验收记录(head fda753998a8402dd63e71399c2515f27e95bd18d):通过。

验证范围:

  • 复验 daemon failure-detail status 与 persisted assistant-message readback 路径,确认 hard quota 失败后的 failureCategory / failureDetail 能保留到 stored status:error event。
  • 复验 web reload / reattach / SSE reconnect / guidance mapping 路径,确认相同 error detail 下会 merge code / failureCategory / failureDetail,不会退回粗错误卡。
  • 复验 Open Design Cloud 文案相关的 AMR balance / low-balance / model switcher 单测。

本地验证:

  • pnpm --dir apps/daemon exec vitest run -c vitest.config.ts tests/run-failure-detail-status.test.ts tests/run-failure-detail-persisted-message.test.ts:2 files / 2 tests passed
  • pnpm --dir apps/web exec vitest run -c vitest.config.ts tests/runtime/amr-guidance.test.ts tests/runtime/chat-events.test.ts tests/providers/daemon-sse-reconnect.test.ts tests/components/ProjectView.reattach-restore.test.tsx tests/runtime/amr-balance-gate.test.ts tests/components/AmrBalanceDialog.test.tsx tests/components/AmrLowBalanceDialog.test.tsx tests/components/InlineModelSwitcher.test.tsx:8 files / 102 tests passed
  • git diff --check origin/main...HEAD:passed

GitHub 状态:

  • CI 主要门禁通过:Preflight、Workspace unit tests、Web workspace tests、E2E Vitest、UI P0、Validate workspace
  • mergeStateStatus=CLEAN
  • reviewDecision=APPROVED

结论:验收通过。建议将 needs-validation 切换为 validated

@AmyShang-alt AmyShang-alt added validated Runtime change validated (via /explore Pass or manual QA). and removed needs-validation Runtime change detected; needs human or /explore agent validation. labels Jul 10, 2026

@AmyShang-alt AmyShang-alt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA accepted on head fda7539. Focused daemon/web regressions and current GitHub CI are green; needs-validation has been moved to validated.

@AmyShang-alt
AmyShang-alt added this pull request to the merge queue Jul 10, 2026
Merged via the queue into main with commit cd07d35 Jul 10, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk/high High risk: apps/desktop, daemon, auth, migration, workflows, package deps size/XXL PR changes 1500+ lines type/feature New feature validated Runtime change validated (via /explore Pass or manual QA).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants