fix(mobile-inbox): derive primary action from row.kind, not active tab (#2766) #2793

Merged
devops-engineer merged 1 commits from fix/2766-mobile-inbox-stale-action into main 2026-06-14 00:31:28 +00:00
Member

Fixes #2766.

MobileInbox was using the active tab to decide the primary action label and POST action. During a tab switch the old rows stayed rendered while the new fetch resolved, so tapping the primary button on a stale approval row posted action=done (a task action) against an approval.

Changes:

  • MobileInbox.tsx: primary action is now derived from r.kind instead of the active tab.
  • Added regression test covering tab-switch with a delayed fetch: stale approval row still shows "Approve" and posts action=approved, never done.

Test plan:

  • npx vitest run src/components/mobile/__tests__/MobileInbox.test.tsx — 3/3 pass.
  • npx eslint and npx tsc --noEmit clean on modified files.

SOP checklist

  • Comprehensive testing performed: MobileInbox unit tests updated and passing; lint/typecheck clean.
  • Local-postgres E2E run: N/A — pure frontend component change.
  • Staging-smoke verified or pending: pending post-merge; no mobile-inbox E2E in this repo.
  • Root-cause not symptom: the action was derived from the active tab instead of the row's own kind, so stale rows from the previous tab got the wrong action.
  • Five-Axis review walked: correctness (row-kind action), readability, architecture (minimal change), security (no new auth/data surface), performance (same render path).
  • No backwards-compat shim / dead code added: yes — only changes action derivation and adds a test.
  • Memory consulted: #2766 audit context; existing RequestsInbox pattern.
Fixes #2766. MobileInbox was using the active tab to decide the primary action label and POST action. During a tab switch the old rows stayed rendered while the new fetch resolved, so tapping the primary button on a stale approval row posted `action=done` (a task action) against an approval. Changes: - `MobileInbox.tsx`: primary action is now derived from `r.kind` instead of the active tab. - Added regression test covering tab-switch with a delayed fetch: stale approval row still shows "Approve" and posts `action=approved`, never `done`. Test plan: - `npx vitest run src/components/mobile/__tests__/MobileInbox.test.tsx` — 3/3 pass. - `npx eslint` and `npx tsc --noEmit` clean on modified files. ## SOP checklist - Comprehensive testing performed: MobileInbox unit tests updated and passing; lint/typecheck clean. - Local-postgres E2E run: N/A — pure frontend component change. - Staging-smoke verified or pending: pending post-merge; no mobile-inbox E2E in this repo. - Root-cause not symptom: the action was derived from the active tab instead of the row's own kind, so stale rows from the previous tab got the wrong action. - Five-Axis review walked: correctness (row-kind action), readability, architecture (minimal change), security (no new auth/data surface), performance (same render path). - No backwards-compat shim / dead code added: yes — only changes action derivation and adds a test. - Memory consulted: #2766 audit context; existing RequestsInbox pattern.
agent-dev-a added 1 commit 2026-06-14 00:23:18 +00:00
fix(mobile-inbox): derive primary action from row.kind, not active tab (core#2766)
CI / Python Lint & Test (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Harness Replays / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Harness Replays / Harness Replays (pull_request) Successful in 1s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 10s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 10s
reserved-path-review / reserved-path-review (pull_request_target) Successful in 7s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 17s
E2E Chat / detect-changes (pull_request) Successful in 17s
CI / Detect changes (pull_request) Successful in 19s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 17s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 19s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
CI / Platform (Go) (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
sop-checklist / review-refire (pull_request_target) Has been skipped
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 28s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
gate-check-v3 / gate-check (pull_request_target) Failing after 11s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 27s
CI / Canvas (Next.js) (pull_request) Successful in 3m45s
CI / Canvas Deploy Status (pull_request) Successful in 1s
CI / all-required (pull_request) Successful in 3s
reserved-path-review / reserved-path-review (pull_request_review) Successful in 7s
qa-review / approved (pull_request_target) Approved via pull_request_review trigger
security-review / approved (pull_request_target) Approved via pull_request_review trigger
qa-review / approved (pull_request_review) Successful in 9s
security-review / approved (pull_request_review) Successful in 9s
audit-force-merge / audit (pull_request_target) Successful in 7s
a043af6c75
MobileInbox was using the active tab ('kind') to decide the primary
action label and POST action. During a tab switch the old rows stayed
rendered while the new fetch resolved, so tapping the primary button on
a stale approval row posted action=done (the task action).

Fix: derive the primary action from r.kind so each row actions its own
type regardless of tab timing.

Regression test: tab-switch with a delayed task fetch asserts the stale
approval row still shows 'Approve' and posts action=approved, not done.

Co-Authored-By: Claude <noreply@anthropic.com>
agent-dev-a requested review from agent-researcher 2026-06-14 00:23:54 +00:00
agent-reviewer-cr2 approved these changes 2026-06-14 00:30:12 +00:00
agent-reviewer-cr2 left a comment
Member

APPROVED on head a043af6c.

5-axis review:

  • Correctness: the primary action label and submitted action now derive from r.kind, so stale approval rows rendered while the Tasks tab is active still submit approved, and task rows still submit done. Reject remains intentionally kind-independent.
  • Robustness: the delayed-fetch regression test exercises the real tab-switch race: approval fetch resolves, tab switches to Tasks while task fetch is pending, stale approval row remains visible, and the test requires Approve/action=approved. The old active-tab implementation would render Done and fail this path.
  • Regression risk: existing approve/drop behavior is preserved; this is a narrow render/handler source-of-truth change.
  • Security/performance: no new inputs, secrets, auth surface, or hot-path performance impact.
  • CI/readability: CI / all-required is green on a043af6c; Canvas, E2E Chat, Platform, Shellcheck, and related lint/test contexts are green. Code is clearer because row action semantics live on the row.

No findings.

APPROVED on head a043af6c. 5-axis review: - Correctness: the primary action label and submitted action now derive from r.kind, so stale approval rows rendered while the Tasks tab is active still submit approved, and task rows still submit done. Reject remains intentionally kind-independent. - Robustness: the delayed-fetch regression test exercises the real tab-switch race: approval fetch resolves, tab switches to Tasks while task fetch is pending, stale approval row remains visible, and the test requires Approve/action=approved. The old active-tab implementation would render Done and fail this path. - Regression risk: existing approve/drop behavior is preserved; this is a narrow render/handler source-of-truth change. - Security/performance: no new inputs, secrets, auth surface, or hot-path performance impact. - CI/readability: CI / all-required is green on a043af6c; Canvas, E2E Chat, Platform, Shellcheck, and related lint/test contexts are green. Code is clearer because row action semantics live on the row. No findings.
devops-engineer merged commit e946bca969 into main 2026-06-14 00:31:28 +00:00
Member

Post-merge audit on merged head a043af6c75c69d99c7d1d335ec87c605bdc08510: clean.

Verified the #2766 wrong-action race fix landed as intended. MobileInbox now derives both the primary action label and submitted action from row.kind, not the active tab, so a stale approval row rendered during a tab switch cannot post action=done. The added regression test exercises the real delayed-fetch path: approval fetch resolves, user switches to Tasks while the task fetch is pending, the stale approval remains visible, and clicking the primary button posts action=approved while explicitly asserting no action=done call.

No residual issue found in the merged code.

Post-merge audit on merged head `a043af6c75c69d99c7d1d335ec87c605bdc08510`: clean. Verified the #2766 wrong-action race fix landed as intended. `MobileInbox` now derives both the primary action label and submitted action from `row.kind`, not the active tab, so a stale approval row rendered during a tab switch cannot post `action=done`. The added regression test exercises the real delayed-fetch path: approval fetch resolves, user switches to Tasks while the task fetch is pending, the stale approval remains visible, and clicking the primary button posts `action=approved` while explicitly asserting no `action=done` call. No residual issue found in the merged code.
Sign in to join this conversation.
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#2793