feat(dashboard): let the owner confirm a validated steward team plan - #4546
Closed
huangruiteng wants to merge 2 commits into
Closed
huangruiteng wants to merge 2 commits into
huangruiteng wants to merge 2 commits into
Conversation
A guard bound with `--todo-id` whose selection cannot be reconciled with the current projection used to raise a bare RuntimeError. That surfaced as `quota_unexpected_collection_error` with the reason "quota collection failed" and a recommended action pointing at heartbeat receipt writeback, so the real cause was invisible to the Agent that hit it. The preflight now raises a typed `QuotaActionSelectionConflictError` that names the requested Todo, the projection's current selection, and the qualification state, and that carries its own `error_code` and `recommended_action`: - `kind=unqualified`: the projection carries no typed qualification at all; - `kind=conflict`: the requested Todo is neither the current selection nor deferred/rejected by it. `quota_error_code` returns `quota_action_selection_conflict`, and `quota_failure_payload` reports the conflict as its own `status` with a typed `action_selection_conflict` block (`kind`, `requested_todo_id`, `selected_todo_id`, `qualification_state`) instead of the generic collection failure. The recommended action is a real next read: rerun without `--todo-id` to see the current selection, then bind that Todo, a deferred Todo, or the Todo the recovery obligation must settle. The neighboring typed paths are unchanged: a Todo that is deferred or rejected by the delivery frontier keeps its existing typed payload, and a qualified selection for the requested Todo still passes the preflight. Covered by `tests/control_plane/test_quota_action_selection_conflict.py`: both raise kinds, the code mapping, the failure payload shape, and the non-conflict case that must keep returning False. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
The steward's team intake produces one validated multi-lane preview, and the Chat action surface already owns `team.plan` with a preview and an apply. The dashboard could not render it: its transport schema accepted a fixed action-kind enum without `team.plan`, so a validated preview failed to parse instead of becoming a card an owner could confirm. That left the one-sentence team flow with no confirmation surface at all. - `src/data/chat.ts`: the transport kind enum accepts `team.plan`. - `personal-workspace-model.ts`: the workspace preview kind matches. - `team-plan-preview.ts` (new): a presentation-only reducer that turns the preview into what an owner reads before confirming — the Goal the plan staffs, its objective, one row per lane (the Agent, that lane's first bounded Todo with its priority and action kind, and its acceptance signal), the declared staffing gaps with the work they did not staff, the quota envelope and the stop condition. It owns no authority and claims no lane already exists. - `personal-workspace-page.tsx`: the proposal card uses that reducer, with a summary, an impact statement that says what confirming does, and a primary label for confirmation. - `i18n.tsx`: the new strings in English and Chinese. Verification: `tsc --noEmit -p tsconfig.json` clean; `npm run smoke:team-plan-proposal` (new) prints `team plan proposal smoke ok`; the existing `smoke:chat-route` and `smoke:action-review-plan` stay green, so the kind addition did not disturb the other proposal surfaces. The card only appears when a validated team plan exists, so the dashboard's first viewport, hero and navigation are unchanged. The user-visible entry point covered here is the dashboard chat/workspace proposal card; the Lark goal channel and the CLI are unchanged by this diff. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Collaborator
Author
|
Closed: this branch still carried the already-merged #4545 commits, so the PR re-showed those files. Reopening from a clean branch based on the current main with only the dashboard change. |
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.
What Was Broken
The steward's team intake produces one validated multi-lane preview, and the Chat action surface already owns
team.planwith a preview and an apply that re-validates atPRE_SETTLEMENT. The dashboard could not render it:typedActionKindSchemainsrc/data/chat.tsis a closed zod enum withoutteam.plan, so a validated preview failed to parse on the client instead of becoming a card an owner could confirm. The one-sentence team flow therefore had no confirmation surface at all — the last missing piece of this lane's P1.What This Changes
typedActionKindSchemaacceptsteam.plan;WorkspaceActionPreview["actionKind"]matches.src/features/personal-workspace/team-plan-preview.tsrenders what an owner must see before confirming:priority · action_kind · text), and its acceptance signal;unstaffed · <reason_code> · <declined work>and never shows invented work;It owns no authority, performs no effects, and never renders a lane as already created.
The generic review-plan compiler already handles a
preview_readynon-lifecycle proposal as applyable, so no authority logic was added or changed.Verification
tsc --noEmit -p tsconfig.json— clean.npm run smoke:team-plan-proposal(new) —team plan proposal smoke ok. It asserts the transport accepts the kind (the exact thing that was broken), that the kind stays exact, that a ready lane shows its first Todo, priority and acceptance, that a gap lane is reported as unstaffed with its reason and declined work, and that the quota envelope and stop condition render.npm run smoke:chat-route—chat-route-smoke: ok;npm run smoke:action-review-plan— PASS. The kind addition does not disturb the other proposal surfaces.loopx canary premerge --from-git-diff— passed (diff hygiene, 8 risk-profile smokes, catalog canaries; one advisory: the known baseline maintainability ratchet).Entry Points And Scope
team.plan).Residual Gaps
regeneratepath handles it; nothing new was added for that flow.