- Per-tag chronic-spike counter (`workspace.tagConsecutiveSpikeDays`)New JSONB column `workspace.tagConsecutiveSpikeDays` (`Record<tag, number>`) โ tags are workspace-scoped strings, not entities, so the counter lives on the workspace row instead of a per-entity column (mirrors the rev-68 `tagCostSpikeAcks` shape). The rev-70 `pingTagCostSpikes` daily sweep increments the counter for every tag the rev-67 detector flags, resets to 0 the first day a tag isn't spiking. Independent of the rev-68 `tagCostSpikeAcks` per-day mute โ the counter keeps growing through ack-and-spike-again cycles so a workstream that's been 'ack me daily' for a week shows the strongest possible chronic signal. **Strategic significance**: the load-bearing primitive for the rev-70 chronic recommendation banner + chronic-warning push. Until rev 70 a chronically-noisy workstream (a focus-tag the team should drop, a scoped-too-broadly initiative, a tag attached to a runaway source) was visually identical to a one-off spiking workstream. Rev 70 makes the chronic case distinguishable from the one-off without requiring the operator to remember. Mirrors the rev-61 source counter + rev-64 assignee counter at the per-tag axis on the workspace-scoped JSONB.
- Chronic warning push (Slack + outbound `tag.chronic_warning`)New `tag.chronic_warning` outbound event + `dispatchTagChronicWarningWebhook()` + `buildTagChronicWarningSlackPayload()` Slack block fires when any tag's `consecutiveSpikeDays` crosses the chronic threshold (3 days). Sub-sweep added to `pingTagCostSpikes` mirrors the rev-64 assignee chronic warning shape exactly: rate-limited via its own `tag_chronic_warning` activity-log kind so the chronic ping doesn't drown out the rev-67 daily one. Nudge-not-act because the right answer (drop the focus tag, source filter, scope down, raise cap) depends on context the desk doesn't have. **Strategic significance**: closes the chronic axis on the per-tag cost story alongside the rev-67/68/69 daily-spike axis. The named rev-69 next-sprint candidate. The full per-tag cost story is now five layers deep across two axes: cumulative (rev 66) โ trajectory (rev 67) โ daily spike alarm (rev 67) + ack (rev 68) + auto-pause (rev 69) on the daily axis, and rev-70 counter + chronic warning + chronic banner on the chronic axis.
- โณ Nd chip + chronic recommendation banner on cost-by-tag panelEvery cost-by-tag row whose rev-70 consecutive count is โฅ 2 surfaces a quiet `โณ Nd` pill alongside the rev-67 โก pill on the rev-66 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 tag has been spiking for โฅ 3 consecutive days, recommending a structural change (drop focus tag / source filter / scope down / raise cap) rather than another daily mute. Distinct from the rev-67 daily alarm banner (which fires on a single day's anomaly). **Strategic significance**: closes the rev-69 named candidate at the *operator-nudge* layer. Pairs with the rev-61 source persistent-spike banner + rev-64 assignee chronic-spike chip so the three chronic-axis panels (per-source / per-assignee / per-tag) read with one consistent vocabulary. The cost-axis story is now uniform across every axis on every layer.
- `GET /api/v1/cost/by-tag/chronic-spikes` v1 mirror + projection extensionNew bearer-auth endpoint returns workstream tags whose consecutive count has crossed the chronic threshold. Distinct from the rev-67 `/spikes` endpoint (which names today's anomaly) โ chronic names a structural problem. The rev-67 daily-spike endpoint also gained a `consecutiveSpikeDays` field on every row so MCP hosts can render the same chronic affordance the dashboard shows. The cadence pattern from rev 37 onward (ship the dashboard primitive + the v1 mirror in lockstep) continues. Plus activity-log glyph + per-kind tint for the new `tag_chronic_warning` kind closes the rev-35 per-kind tint symmetry on the chronic-axis cluster (per-source `source_chronic_auto_paused` + per-assignee `assignee_chronic_warning` + per-tag `tag_chronic_warning` all now read consistently in the activity log). **Strategic significance**: the cost-axis MCP cluster is now seven endpoints deep across the per-tag axis alone (cumulative + trajectory + daily-spike + chronic-spike + ack + bulk-ack + config). The MCP server has nothing left to design on the per-tag cost surface.