- Per-assignee cost trajectory primitive (extends rev-54 to per-recipient axis)Closes the third trajectory axis on the cost cluster: workspace (rev 53), per-task (rev 54), per-source (rev 60), and now per-assignee (rev 61). New `getAssigneeCostTrajectory()` helper aggregates the rev-54 `task.dailyCostHistory` JSONB by assignee. New `GET /api/cost/by-assignee/{assigneeId}/trajectory` viewer-auth endpoint + matching `GET /api/v1/cost/by-assignee/{assigneeId}/trajectory` bearer-auth mirror. The rev-52 `getCostByAssignee()` also extended with optional `trajectoryDays` so each row carries a `trajectory7d` cents array โ the dashboard panel renders an inline sparkline beside the rev-52 cumulative bar on every row. Same brand-amber today gradient as the rev-54 task + rev-60 source trajectory sparklines so all three cost panels read with one consistent visual vocabulary. Pass `__unassigned__` as the route segment to drill into the unassigned bucket. Operators answering 'is this teammate's spend steady or spiking?' no longer have to compute it mentally.
- Cost-spike acked outbound events (closure receipts for task + source spikes)Two new outbound events `task.cost_spike_acked` + `source.cost_spike_acked` fire when an operator clicks the inline ack button (rev-56 task / rev-59 source) or the bulk-ack action (rev-57 task bulk / rev-60 source bulk). Lets external integrations (CRM, FinOps dashboard, board-status integration) close their own alarm tickets / dashboards / paging surfaces without polling. Mirrors the rev-37 `task.unblocked` closure pattern at the cost-spike axis. Wired into all four ack paths โ `acknowledgeTaskCostSpike`, `bulkAcknowledgeTaskCostSpikes`, `acknowledgeSourceCostSpike`, `bulkAcknowledgeSourceCostSpikes` โ fire-and-forget so a downstream failure can't block the ack itself. Closes the rev-37 closure-receipt pattern at the cost-axis.
- Per-source consecutive spike days counterNew `source.consecutiveSpikeDays` integer column rolls a workspace-TZ-day counter every time the rev-58 daily detector flags the source as spiking; resets to 0 the first day the source isn't spiking. Independent of the rev-59 `costSpikeAckedAt` per-day mute โ the counter keeps growing through ack-and-spike-again cycles so a source that's been 'ack me daily' for a week shows the strongest possible chronic-noise signal. Daily sweep updates the column on every workspace pass regardless of the once-per-day Slack/outbound rate limit so the counter reflects actual spike-day state.
- Persistent-spike recommendation banner + 'Nd in a row' pillEvery cost-by-source row whose rev-61 consecutive count is >= 2 surfaces a quiet 'โณ Nd' pill alongside the rev-58 โก pill on the rev-57 panel. Pill stays neutral until the count crosses the chronic threshold (3d) then turns brand-red so the eye reads chronic separately from one-off. New persistent-spike recommendation banner above the row list fires when any visible source has been spiking for >= 3 consecutive days, recommending a structural change (keyword filter, permanent pause, remove the source) rather than a daily mute. Distinct from the rev-58 daily alarm banner (which fires on a single day's anomaly). Closes the named rev-60 next-sprint candidate at the operator nudge surface โ addresses 'I keep acking the same feed, what should I actually do?'.