Build task Outcome panel

Task 12284 · Queued · Coder · created · updated

Epic 12243 (plan task 12246). Full settled inputs: the PRD (Task 12244) and the Architecture (Task 12245) of this epic — read them with `task_read`/`artifact_read` on those tasks; section numbers below (R…/AC…/§…) cite them. Where PRD and the original proposal (Task 12195) differ, the PRD governs. Reads the metrics child's task-outcomes API and the scan child's link routes; needs the backfill child's run on dev. ## Original requirement (verbatim) > "3. Defect attribution: a revert commit, a later PR/task referencing the PR (forge fixes/reverts link; same files in-window with a defect-shaped title at lower confidence), or an operator's explicit \"caused by\" link. Store confidence; operator confirm/dismiss on the task page; confirmed links are labels." > "5. Surfaces (console UI style guide): Agents › Performance profile per agent/model/configuration; Compare 2–4 configurations on identical strata; org Leaderboard (filters persona, project, period, min n); task Outcome panel shows the ledger row and attribution links; Command center widgets read the ledger in place of the weekly sample; CSV export per org. Operator plane: Fleet › Agent index with cross-org aggregates per configuration, each cell ≥ 5 orgs and ≥ 100 outcomes, never a tenant name." (Settled: D4 show both — ledger widgets beside the unchanged `quality.avg`; D8 Owner/Admin only; Architecture A2 — the pages are tabs of the Command center, not under the grid-gated Agents section; the operator page is "Agent index" in the operator sidebar group.) > Done means (epic, verbatim): "Every build task that settles after release has a `task_outcomes` row with attribution, timeline, gate facts and cost; a settle without one is a gate failure in tests." > Done means (epic, verbatim): "A revert of a merged PR flips its outcome to reverted within one cron pass; a fix-forward PR with a forge link flips the origin to fixed_forward with confidence shown; an operator dismissal reverts it." PRD requirement carried (verbatim): R5.4 "**Task Outcome panel**: on the task detail page (tabs: `apps/web/src/pages/taskDetail/TaskDetailTabs.tsx`). It shows the ledger rows (one per dispatch), the outcome state, the timeline, gate facts, cost and attribution links with their confidence. Owner/Admin get Confirm/Dismiss/\"Caused by\"." R3a.3 Owner/Admin confirm/dismiss/caused-by on the task page; a dismissal returns the outcome to its prior state. D8: the panel follows ordinary task visibility. ## Approach (settled — realize, do not reopen) Architecture §9.3 Task Outcome panel; reads `GET /api/tasks/{id}/outcomes` (metrics child) and calls the link routes (scan child). - Conditional **Outcome** tab in `useTaskDetailTabs.ts` (present when the task has ≥ 1 row): one card per dispatch with attribution chips (agent, model, auth kind, persona, review tier, node class); timeline with "—" for steps not reached; gate facts and cost with units; link list with kind, evidence (commit/PR link), confidence band (High ≥ 0.8 / Medium ≥ 0.5 / Low) with the number in a tooltip, and state ("Dismissed by <name>"); Owner/Admin (`can_decide`) get Confirm / Dismiss / "Caused by…"; Backfilled and Shadow badges. - Live oracle setup: create **`jaah-ai/outcome-ledger-sandbox`** through the console's new-repo flow as a dev project of the Jaah org named "Outcome ledger sandbox" — reuse it if it already exists (never revert on `jaah-ai/jaah`); set its scan interval override to 15 min or use **Scan now**. Credentials & reach: - pytest ACs: none beyond the worktree (`./dc` stack) — verified (worktree). - Dev UI flows as Jaah-org Owner and as operator: `me/jaah/debug/main/operator-login` (operator, switches into tenants); environment `https://app.dev.jaah.ai` (public dev console; the internal `dev.jaah.ai` ALB did not answer from h2 within 15 s) — verified: credential_get ok; `app.dev.jaah.ai` → HTTP 200 from h2. - Member-seat negative checks (AC3.3, AC5.2): `org/console/dev-tpl-member-login`, dev — verified: credential_get ok. - GitHub revert / Fixes-#N flow (AC3.1, 3.2): Repo **`jaah-ai/outcome-ledger-sandbox`**, created through the console's new-repo flow as a dev project of the Jaah org named "Outcome ledger sandbox", so no oracle ever reverts on `jaah-ai/jaah`. Identity: `me/users/roman@gmind.tech/github_admin` (repo creation, and the oracle's `git revert` push to its integration branch); `me/GitHub (ruzhukov)` as the project's connection; `api.github.com` — verified: `github_admin` has role `admin`, state `active` in org jaah-ai; `me/GitHub (ruzhukov)` lists jaah-ai repos with push permission; `api.github.com` → 200. (`me/users/roman@gmind.tech/github` answered "Bad credentials", so it is **not** used.) Out of scope: the detectors, scan and APIs themselves (fix them in their home only if the live oracle exposes a bug, as part of this task); Command center pages; Agent index. Out of scope (epic, verbatim): "any routing behaviour (the routing epic reads this ledger); new production signal sources (the production QA epic writes deployed/incident_linked); a public index or tenant-to-tenant sharing; re-scoring tasks older than a one-off backfill of merge, lane and cost facts." Do NOT touch (PRD A8): no change to `apps/api/app/agent_resolution.py` resolution order, `apps/api/app/jaah_scheduler.py` account placement, or `apps/api/app/jaah_routing/` (`routing_decision_id` stays null); no deploy ingestion, monitor adapters, incidents table or new trigger source kinds (`apps/api/app/triggers.py` untouched; `deployed_at`/`incident_linked` are columns/states nothing writes); no public page, no unauthenticated endpoint, no tenant-to-tenant view, no tenant name on any operator-plane aggregate; no retired or rewritten weekly outcome-review job (`apps/api/app/operator_dashboard/review.py`, `apps/api/app/operator_dashboard/quality.py`, D4); backfill writes merge, lane and cost facts only, never re-runs LLM scoring, never re-opens old tasks; benchmark mode never merges a shadow PR and never changes the origin task's dispatch. No CP forge call (ADR-0156): forge facts come only through the `outcome_scan` runner. Migrations additive only (new tables + nullable/defaulted columns). Done means: - AC1.4 "Dev user flow. **Verify:** on `dev.jaah.ai`, as an Owner of the Jaah org, open a coder task that settled after release. Open its Outcome panel (A5) and observe agent, model, auth kind, persona, review tier and node class. The timeline shows the populated steps with timestamps and \"—\" for steps not reached. Gate facts and cost are shown with units. None of this is truncated." - AC1.5 "Backfill. **Verify:** after the backfill on dev, open a task settled before release. Its Outcome panel shows a \"Backfilled\" marker, with merge and cost facts present and unknowns shown as \"—\"." - AC3.1 "**Verify:** on a GitHub test repo connected to a dev project, merge a coder task's PR, then push `git revert <merge-sha>` to the integration branch. Wait one cron pass of the detector. On `dev.jaah.ai`, open the task's Outcome panel: the state reads \"Reverted\" and a link names the revert commit with \"high\" confidence." - AC3.2 "**Verify:** open a second PR whose body says `Fixes #<origin PR>` and merge it. After one pass, the origin task shows \"Fixed forward\" with the confidence shown as a number or band." - AC3.3 "**Verify:** as Owner/Admin, click Dismiss on that link. The origin returns to its prior state (\"Merged\" or \"Survived\"), and the link shows \"Dismissed by <name>\". As a Member seat, the Confirm and Dismiss controls are absent." - AC5.5 "Open a settled coder task, then its Outcome panel. Observe everything listed in R5.4." - AC5.9 (panel) "At a 390 px viewport, every page above has no horizontal page scroll. Tables scroll inside their own container." - vitest covers: tab absent with zero rows, "—" for missing steps, band thresholds, Member sees no decide controls, Backfilled/Shadow badges. - Gate (epic Done means, verbatim: "Required checks: ./dc check quick green; changed-area tests green; merge lane full gate green.") — `./dc check quick` green; changed-area pytest/vitest green; merge lane `./dc check full` green; Jaah Deploy of the PR succeeds.

Activity

  • Draft
  • Ready