Created
Jul 06, 06:18
Started
Jul 06, 06:20
Completed
Jul 06, 07:27
DevOps handoff
Type
Feature
Shape
ui+db
Worktree Slug
grade-test-scope-runs
Repositories
mcritchie-studio
Release Slug
—
Branch
feat/grade-test-scope-runs
Acceptance Criteria
Expected Test Plan
Checks Run
Agent Context
Observability epic A2 (A1 test-scope telemetry + #417 SOP both on main). GOAL: make each test-scope RUN a first-class GRADEABLE unit in /alex/pipeline, gradeable like an activity. DESIGN = Option B, gradeable-in-place, NO new model, NO migration (Carl's design pass). KEY FACT: ActionGrade grades exactly one of AgentAction OR AgentActivity (dual-FK XOR, action_grade.rb:52-78,224-229) and ALREADY grades a raw AgentAction (for_action :83; #feedback/#grade path). A1's COMPLETED/FAILED telemetry IS an AgentAction → zero grading-core change. 3 slices, all fields already columns on agent_actions: (1) TAG the verdict action at emit — kind='test_scope' (kind is presence-only, agent_action.rb:93/109, no enum change), event_slug=<scope key>, result_slug=pass|fail, duration_ms=elapsed*1000. Wire: bin/release.rb run_test_scope/scope_action/agent_action helper (:390-394,:460-503) forward these; bin/atomic-event action verb (:224-252) add --event-slug/--result-slug/--duration-ms into POST body (--kind already forwarded); api/v1/agent_actions_controller.rb capture_params (:49-73) permit :event_slug,:result_slug (duration_ms/kind already permitted; capture already maps event_slug/result_slug agent_action.rb:166-167). Tag ONLY the verdict (COMPLETED/FAILED), leave START plain (excluded by result_slug presence). (2) PIPELINE BAND: a new 'Test runs' band ABOVE the 3-col grid mirroring the Candidates band (.pl-cands, pipeline.html.erb:85-114) — NOT a 4th column (a test run FEEDS the loop like a candidate). heartbeat_controller#pipeline (:97-130): @test_runs = AgentAction.where(kind:'test_scope').where.not(result_slug:nil).order(occurred_at: :desc).limit(N). Row: event_slug headline chip + host/phase/tier DERIVED at render from the scope registry config/devops_test_suites.yml release_scopes (single source; do NOT store phase/tier/host — they'd drift on re-tier) + pass/fail pill (reuse .pl-disp good/not) + counts+duration parsed from summary + a 'grade' link to heartbeat_feedback_path(action.id) (the existing action drawer). is-not left-rail for alex 'not' grades. (3) CONFIRM-OF-ACTION: extend #confirm (heartbeat_controller.rb:137-147, currently AgentActivity.find only) + the Column-2 Confirm affordance (pipeline.html.erb:176-181, currently elsif activity_id) to accept an agent_action_id target (ActionGrade.for_action + by_grader(MCR)) so a banked test-run grade reaches Column 3, parity with activities. OUT OF SCOPE (A3+): cross-release aggregation / pass-rate trends (THAT is when a TestRun PROJECTION table via AgentAction after_create earns its keep, as analytics not grading target) — document as follow-up, do not build. Forward-only (pre-tag actions not in the lane; no backfill). Tests follow existing pipeline/heartbeat test patterns + test/lib/release_cli_test.rb for the emit side.
Stage Timeline
Who handled each stage, the time it took (measured), and the model / tokens / cost reported (best-effort) — plus who's on it right now. — means the agent didn't report that metric.
Conversation
QA review feedback, agent handoffs, and follow-up notes for this task.
Avi review approved: Option B verified — verdict emits tagged kind=test_scope/event_slug/result_slug/duration_ms (blank-dropped so START stays plain), all 4 fields are existing agent_actions columns (NO migration), band query scoped+limited with meta derived at render (no N+1), confirm rides ActionGrade for_action XOR (no new FK). CI green (4 checks). Ready for qa-release.
Sealed-bid sizing
Edit →Alex (PM)
—
Avi (PO)
MEDIUM
Dev
MEDIUM
Actual
XL
We emailed a one-tap sign-in link to . It expires shortly and can only be used once.
No email? Check spam, or close this and try again.