# agent-scope-14 — Situations becomes Behaviour; Activity gets honest

> **Operator order, 2026-07-27, verbatim intake.** Two surfaces, one package,
> because they share the review/label data. Nothing here is a design round
> EXCEPT the two items he explicitly asked for mockups on.

## A. Situations → Behaviour

1. **Rename `Situations` to "Behaviour"** everywhere the operator can see it —
   nav entry, page heading, route. ⚠ **Flag before building:** a legacy
   `routes/agent/BehaviourTab.tsx` already exists and is **unrouted** (HANDOFF
   loose end). It must be deleted or absorbed in the same commit, or the app
   ships two things called Behaviour. Do not leave both.
2. **Delete the Global channel-chip banner** (his screenshot 1): the
   `Global [WhatsApp][Instagram][Facebook][Website] — "Applies underneath every
   situation below, on every channel."` strip. Remove it on **all tabs**, not
   just Global.
3. ~~**Delete the Knowledge-search section.**~~ **DONE 2026-07-28.** The whole
   screen is gone, not just the section: `/agent/knowledge*` redirects into
   Behaviour and the nav entry is deleted.
4. **Fields take FULL markdown, not just `##`.** Today the field contract
   recognises heading lines only. Reformat the fields to render/accept real
   markdown (lists, bold, links, code) end to end — editor, stored value, and
   the assembled prompt.
5. **Move `See the exact prompt` + `Edit` to the LEFT** (his screenshot 2) —
   "where it is most expected". Currently right-aligned.

## B. Knowledge (KB) — scoping is wrong, and the content is worse

6. ~~**KB currently renders identically on every tab.**~~ **DONE 2026-07-28.**
   The model was not buildable as written until now: `KnowledgeDocument` had a
   `channels[]` column but NO situation scope at all. Migration
   `20260728120000_knowledge_document_situations` adds `situations TEXT[]`
   (empty = Global), keyed on the engine's own `SITUATION_IDS`. The library now
   reads under the Knowledge heading of the tab a fact belongs to, with a
   channel filter and channel chips, and the editor sets both scopes.
   - **common KB → Global tab only** — done;
   - **situation-specific KB → that situation's tab** — done;
   - **channel-specific AND situation-specific → shown in the appropriate tab,
     visibly marked as channel-specific** — done.
   ⚠ Retrieval is unchanged: `search_knowledge` still searches every enabled
   document regardless of situation OR channel. Both scopes are display + author
   scopes today. Narrowing retrieval is a behaviour change nobody has ordered.
7. **Delete every existing KB document and rewrite from zero.** His words:
   "all KBs some unnecessary, generic, unspecific or maybe meant to be a prompt
   (idk)." ⚠ **Destructive and operator-ordered** — take a backup of the
   `KnowledgeDocument` rows before deleting, and keep it. The rewrite is not a
   bulk-generate: each new document must earn its place, and anything that was
   really prompt text belongs in a Behaviour field instead, not in the KB.

## C. Prompt correction driven by real labels

8. ~~Go through the labelled/marked activities and reason their labels.~~
   **DONE 2026-07-27 — read, surfaced, and RULED. Rulings in `docs/DECISIONS.md`
   ("Comments: the moderation bar, and how a DM actually starts").**
   All 8 labels (7 `wrong`, 1 `right`) carried a null note, so intent was asked
   for, not inferred. What must now change in the prompts:
   - **`skip` stops being the catch-all.** Personal, unrelated, flirtatious or
     unprofessional comments are MODERATED, not skipped and not answered. All
     four `wrong` labels were `skipped: policy` and all four should have been
     hidden/deleted — including "Influencer email if possible?", which is a
     personal approach and NOT the partnership lead it looks like.
   - **The first comment on a post carries extra weight** — it "can affect the
     movement of the comments section", so junk in that slot is moderated, not
     tolerated.
   - **Delete the public DM-CTA.** `comment-behaviour.ts:22,26,37,41` currently
     end every Tier-2 reply by asking the customer to DM us. That is now wrong:
     we open the DM ourselves via a private reply, and the public reply tells
     them to check their DMs. ⚠ This is BLOCKED on the comment→DM package
     below — do not strip the CTA until the private-reply path is live, or the
     comment reply becomes a dead end that points nowhere.
   - Do NOT add any language-matching rule (settled dead end, 2026-07-20).

## D. Activity — defects and one redesign

> **9–13 are DONE** — built 2026-07-27 in `6ac1894`, shipped (prod `9d130b5`
> contains it). Re-verified 2026-07-28 by mutation testing: eight mutations
> across the four files, seven went red; the one that did not (the feed query's
> where-clause was unpinned, so defect 11 could be reintroduced test-clean) is
> closed in `124c4c4`. **Item 12 is still operator-glance-gated** — "visually
> separate but subtle" is a look, and every test is jsdom.

9. ~~Interpretation column header reads "no name".~~ It gets its own header
   ("Post caption") and Details label ("caption") — a caption interpretation is
   context prep for a post, never a contact.
10. ~~Needs-action tab shows no source and states there is no source.~~
    `ReviewItemRow` never carried `mediaId` at all; it is joined now.
11. ~~Rejecting a draft that is waiting does not change the outcome.~~ The feed
    joined a turn's review only while `status: "waiting"`, so a decided review
    fell back to the turn's stale original decision. The join is status-agnostic
    now and `computeOutcome` reads `reviewStatus`.
12. ~~The label/mark tag sits under the outcome and reads wrong.~~ Its own line
    (`.cm-activity__markrow`) inside the outcome cell, never a new column.
13. ~~Reversible decisions must be overridable.~~ Scoped to `approve` only —
    `moderate` deletes are irreversible Graph calls and `dm_opener`/`crm_action`
    stay terminal (HANDOFF loose end).
14. **Redesign the right-hand review detail panel completely — mockup rounds
    required** (operator asked for them explicitly).
15. **The filtration UI is disliked outright.** "The filtration system changed
    but not the UI." Rework the UI to match the system that now exists — also a
    mockup item.

## Sequencing note

**9–13 are done and shipped** (see the block above — verified 2026-07-28). 1–3
landed in `868e0bb`; 4–5 not re-verified here. 14–15 need mockups first. 6–8 are
the substantive half still open: 7 is destructive, 8 needs the operator in the
loop.

## Oracle

Per-package: `cd apps/web && npx vitest run --pool=forks --poolOptions.forks.maxForks=2`,
`cd apps/api && npx vitest run --pool=forks --poolOptions.forks.maxForks=2`, plus
`corepack pnpm --filter @channels/web build`. Prompt goldens must be re-pinned
deliberately for items 4 and 8 — those DO move the assembled prompt, and the
operator has already signed off that it may move (2026-07-25).
