Repository navigation
fix(console): Show inbox blockers and decision outcomes in the decision inbox - #1086
Merged
Merged
Conversation
Render server blocking_reason_codes in the decision detail with the existing cockpit.blocker copy, fail closed on malformed actionability, split decided items into approved or rejected from decision_state.action, and extract the deep-link target check so it can be tested. Regenerate v2_asset_map.js with sync:v2-assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add console_todo_state, console_load_lifecycle, promotion_queue_partial and the new decision inbox gap tests to the frontend test:operations script. The workflow file is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Map unmapped or malformed inbox blocker codes to the generic "approval unavailable" line instead of rendering the raw code, drop the cockpit.blocker.other_code_label copy, and require actionable to be exactly true before an item with blocker fields is treated as open. Regenerate v2_asset_map.js with sync:v2-assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AI assistance
Claude Code (model: Claude Opus 5.5) wrote the change, the tests and this description. A separate independent review accepted exact head
ebd305d8a0e390b99cccd18c3459d8dabb6818b7.What changed
This change closes four confirmed frontend-only M09 gaps in the legacy decision inbox (
?page=decisions). Paths are underweb/strategy-switch-console/frontend/src/.actionableandblocking_reason_codes. They are now read through a new helper,inboxBlockers()(pages/decisions/helpers.ts).cockpit.blocker.*copy.ul.cockpit-blockersand replaces the generic "server does not allow approval" note.decisionStatusKey()readsdecision_state.action: approve, accept and approve_limited_live_canary show as approved; reject and keep_parked show as rejected.decisions.status.approvedanddecisions.status.rejected.decision_staterecords a decision, the item's actions are hidden.console_todo_state_validation,console_load_lifecycle_validationandpromotion_queue_partial_validationalready passed but did not run in CI. They are now in the frontendtest:operationsscript. No workflow file changed.tests/console_decision_inbox_gaps_validation.mjshas 5node:testcases covering items 1 and 2 and the?page=decisions&decision=<id>deep link. It is also intest:operations.deepLinkTarget(), so it can be tested. Its behaviour is unchanged.web/strategy-switch-console/v2_asset_map.jswas regenerated withnpm run buildfollowed bynpm run sync:v2-assets.Fail-closed semantics
An item that carries either field stays blocked unless
actionable === trueand there are no codes.actionable: falsewith no codes shows "not allowed".actionableshows the generic line.actionable: true.The generic line, "当前不可审批 / Approval is unavailable", is also used for:
Repeats collapse to one line. Machine codes are never rendered on screen, which follows the existing "unknowns never render raw" rule.
A blocked item disables both approve and decline through
decisionActionAllowed(), which also guardsonDecide. This matches the server, which returns emptyallowed_actionswhen an item is not actionable.How verified
All checks ran locally on Node v24.22.1 and Python 3.13.5. CI uses Node 22 and Python 3.12.
Fail-before and pass-after
main(884b780), in a temporary worktreee16df5factionable === truenot blocked)ebd305dChecks at head
npm run build(tsc, vite, size budget)npm run sync:v2-assetsafter a rebuildmainalso gives 0 lines, so the output is deterministic.console_v2_assets_validation,console_v2_worker_validationnpm run test:operations --prefix web/strategy-switch-consolenode --testsubtests 41/41 (33 before, plus 3 newly wired and 5 new)research_promotion_application_worker_validationwas run without--experimental-default-type, a flag Node 24 removed; CI on Node 22 still accepts it.console_v2_i18n,console_frontend_i18n,initial_enrollment_ui,console_cockpit_decision,console_read_recovery_ui,credential_maintenance_presentation,console_inbox_requestspython3 -m unittest discover -s python/testspython3 python/scripts/build_config.py --check;python3 scripts/check_style.pyPublication check
The checker is
publication-check/2.0-advisory, build83d9d1130377, in advisory mode (exit 0). Output is masked.CODEOWNERSowner entries:syntheticcopy keys andaccount.key/className="decision-account-picker", which the masker flags as host-like (false positives).Why
The M09 to-do lifecycle review found that the inbox API already returns blocker reasons and the recorded decision outcome, but the console dropped both:
Three passing tests were not run by CI, and the decision deep link had no test.
Risk
Risk tier: low. The change is frontend display and gating plus tests:
web/strategy-switch-console/frontend/src/pages/decisions/{DecisionsPage.tsx,helpers.ts}frontend/src/i18n/{zh-CN,en}.tsfrontend/package.jsontests/console_decision_inbox_gaps_validation.mjsweb/strategy-switch-console/v2_asset_map.jsNo backend (
worker.js,application/*), schema, settings contract or workflow file changes.Merge only. This is NOT a release.
v2_asset_map.jsonmainonly. Shipping it needs a separate future release with its own acceptance.Behaviour impact:
allowed_actions. If the server ever sent blocker codes while also allowing an action, the client would block it.Known non-blocking P3 follow-ups:
onDecidestill checks the coarseitem.statusinstead of the derived status. The rendered actions are already hidden, anddecisionActionAllowedblocks decided items, so this is defense in depth only.recovery_blockedandrecovery_not_awaiting_confirmationuse the generic "Approval is unavailable" copy. Specific copy can follow.Also, the pending view still lists only items whose
statusis pending or expired. The approved/rejected split therefore shows mainly whendecision_stateis decided while the coarse status lags.🤖 Generated with Claude Code