# agent-scope-12 — Activity end-state 2: columns, filters, trace-back

> Kickoff: Fable, 2026-07-24. Design settled through THREE mockup rounds +
> the chip-color pick — approved surface: `design/tiles/activity-filters-
> round-3/` amended by DECISIONS "channel chip colors PICKED". Authority:
> DECISIONS 2026-07-24 round-1/2/3 reactions + chip pick. Status lives in
> `plans/rethink/README.md`. **QUEUED** (WIP rule); execution on the
> orchestrator's call.

## The locked frame (all ledgered, DECISIONS 2026-07-24)

- **Column split**: stacked channel/type chips become TWO columns.
- **Channel chips = the PICKED solids ("C D D" + gold)** — this SUPERSEDES
  the round-3 proposal hexes (#BE2F7E/#1660C9):
  WhatsApp `#12824A` white text · Instagram = real IG gradient
  (#F58529→#DD2A7B→#8134AF, white text; the orange end may deepen just
  enough to hold 4.5:1 — the only allowed deviation) · Facebook `#3B5998`
  navy, white text · future web channel = brand gold `#C9A96E` with dark
  ink. Token sheet amended (`design/tokens.md`) — encode these as tokens,
  not inline hexes; this is the one approved use of brand gold outside
  the logo.
- **"From/Text" → "Details" column**: per-row-kind header/value matrix
  (comment → name/comment, DM → name/message, flow run → flow/step,
  moderation → name/comment, …) with honest no-name fallbacks — every
  kind defined, nothing renders "unknown" for a kind we know.
- **Filter Outcome list = the column's displayed words verbatim**
  (replied · draft waiting · skipped · flagged · deleted · failed); raw
  decision values (replied/skipped/queued/hidden/canned) map SERVER-SIDE.
  Same rule for every filter option list: real vocabulary from the code,
  never guessed.
- **Source button lives in the row's DETAILS panel**, not a table column.
- **Trace-back**: every row opens its source (comment → post + parent
  comment · DM → conversation · flow run → flow · moderation → comment).
  Missing/deleted source = honest "source gone" line; genuinely ambiguous
  cases surface to the operator, never guessed.
- **Filter system** incl. the un-UI'd `source` param; **shared post
  picker** component (thumbnail grid, hover caption kept small, search) —
  ONE component reused everywhere posts are selected.
- Saved views: URL-only. Flow runs appear under Activity too (one
  dataset, two lenses — confirmed round-1 ⑫).

## Stages (each: TDD, own oracle, independent review before gate)

**Stage 1 — server**: outcome display-vocabulary mapping (decision →
displayed word) as the one shared mapping both column and filters use;
filter params incl. `source`; per-kind details header/value in the list
payload. Oracle: api tests over the mapping (every decision value maps;
no filter option without a server meaning).

**Stage 2 — chips + tokens**: channel chip tokens per the pick, WCAG
ratios asserted in a test (computed, not eyeballed — incl. the deepened
IG orange end). Oracle: token test green; chips render in all three
channels + no regression on other chip uses.

**Stage 3 — table + filters + trace-back**: column split, Details column,
filter bar, source button in details panel, trace-back navigation with
the "source gone" fallback, shared post picker. Oracle: web tests; e2e
per row kind (each kind shows its defined header/value + its trace-back
target or the honest fallback); 320/375/768 clean.

**Stage 4 — gate**: full sweep, deploy loop + health, web published,
board/README reconciled.

## Out of scope

WhatsApp silence-notification collapse (separate board item, touches the
detector not Activity's table) · Posts comment-reply display (separate
board item + root-cause check) · moderation pipeline changes.

## Risks

- The IG gradient chip is the first gradient in the token sheet — keep it
  a single named token/utility so it can't be re-derived ad hoc.
- Trace-back for flow runs lands before flows have UI (channels-scope-5
  Stage E) — link target may not exist yet; render the honest fallback
  until it does, never a dead link.

## GATE: PASSED (orchestrator, 2026-07-24)

Landed on rethink at `0bf96e9` (rebased onto Stage-B state), deployed,
health green, web published. Independent review found **1 MAJOR — fixed
same session** (`f85adf7`): flow trace-back joined by currently-active
session, so historical rows could name the WRONG flow; now time-bounded
([startedAt, completedAt) covering the turn instant — the per-contact
mutex makes it unambiguous) with honest-gap fallback, both cases tested.
Own oracles on the merged tree: shared 1071/1071 · api 1560/1560 · web
696/696 · typecheck + vite build clean · goldens byte-identical · no
migration.

Open ruling for the operator: **IG gradient pink stop `#DD2A7B` computes
4.48:1** vs white — marginally under 4.5; only the orange end was
authorized to deviate. Accept as-is, or authorize deepening the pink stop
(asserted openly in `chip-tokens.test.ts`).

Follow-ups (boarded): TriggerModuleEditor still uses a raw post `<select>`
(PostPicker adoption sweep) · "failed" OUTCOME FILTER reaches
failsafe-failures only, not comment-send failures (column display covers
both; filter needs a join the feed query lacks) · flow-run "step" shows
the raw node id until Flows UI ships (scope-5 Stage E).
