# Activity Algorithm — Feedback Log

Real-usage observations that should inform suppression rules and scoring when we next tune the algorithm.

Entries marked **✓ true positive** = algorithm got it right. Entries marked **✗ false positive** = noise.

---

## ✓ [2026-05-12] True positive: Stale discovery-phase item at risk of slipping without a kick-off decision

**Item surfaced:** Notifications V2 — target 2026-05-29, start date passed (May 4), status still "Discovery". No issues in sprint. At risk of slipping without a kick-off decision.

**What happened:**
- Algorithm flagged it as ESCALATE: stale May 29 target, no sprint issues, no kick-off, owner = Pavel
- Suggested: reset target date to no earlier than late June (after V1 ships ~June 8 + buffer), confirm with Dang
- Pavel's verdict: *correct — real risk of stalling. Already booked a meeting with Dang to discuss.*

**Why this is the right shape of escalation:**
1. **Requires a product decision** — kick-off timing, date reset. Nobody else can make this call.
2. **Pavel is the owner** but there's a specific gap: no decision has been made yet. Unlike entries #2/#3 where he was already on top of things, here the algorithm identified something that hadn't been actioned.
3. **Calendar blind spot is expected and acceptable.** The AI doesn't have calendar access, so it couldn't know the meeting was already booked. The escalation was still directionally correct — the action it proposed matched what Pavel was already doing.

**Key signal that made this a true positive:**
- Status = "Discovery" with a hard date already passed and nothing in sprint → a *product gate* is missing, not just code
- Owner = Pavel explicitly → algorithm correctly identified this as his decision, not Dang/Tri's

**Principle reinforced:**
> Escalate when a product decision is missing and Pavel is the named owner. Even if he's already acting on it, surfacing it is not noise — it's confirmation the algorithm is working.

---

## ✗ [2026-05-12] Noise: "Just started" Linear issues surface too early

**Item surfaced:** AWS-584 — Onboarding flow: group verification steps in navigator + meaningful error messages

**What happened:**
- Tri assigned, moved to **In Progress today (May 12)**
- No blockers, no comments, no attachments — early-stage work
- Auto-check verdict: **KEEP** — correctly identified no action needed
- Pavel's verdict: *noise, no action necessary*

**Root cause:**
Discovery has no rule against surfacing items that were just activated. An item moved to "In Progress" within the last 2–3 days with an active assignee is not actionable yet — it only becomes Pavel's problem when it stalls or escalates.

**Proposed suppression rule:**
Skip Linear issues where:
1. Status is "In Progress" (or equivalent active state), AND
2. Last status change was < 3 days ago, AND
3. There is an assigned owner actively on it, AND
4. No blocker or comment requesting input from Pavel

**Where to implement:**
- `server/lib/scan-discovery.ts` — add exclusion clause to the discovery prompt (preferred: stop it entering Activity at all)
- Secondary: scoring penalty in `check-scheduler.ts` before the check pool is built

**Impact:** Less noise in Activity, fewer wasted check calls on non-actionable items.

---

## ✗ [2026-05-12] Noise: Engineering execution tasks escalated to Pavel unnecessarily

**Item surfaced:** AWS-570 — LicenseArn backfill script for legacy subscriptions (Tri, In Progress since Apr 29, deadline today)

**What happened:**
- 13 days silent in Linear, Sprint 25 ending today, P0 label → auto-check verdict: **ESCALATE**
- Suggested next: "Sync with Tri in today's standup. Three questions: is the script written…"
- Pavel's verdict: *shouldn't have been suggested — wrong loop*

**Why the algorithm was wrong despite correct data:**
1. **Already inside the sprint cadence.** AWS-570 is tracked in Sprint 25 with Tri as owner and Dang as Tech Lead. Standup and sprint review are already the escalation mechanism. The algorithm invented a parallel path that duplicates work Dang is already doing.
2. **Engineering execution ≠ product decision.** A backfill script is implementation work. No product decision is blocked — the question "is the code done?" belongs to the Dang → Tri loop, not Pavel's.
3. **Linear silence misleads the stall detector for dev tasks.** 13 days without a Linear comment doesn't mean nothing is happening — code work shows up in PRs and commits, not comments. The stall signal works for product threads (decisions, blockers, approvals) but over-fires on dev tasks.

**Proposed suppression rule:**
Skip Linear issues where:
1. The task is engineering execution (script, fix, implementation — no product decision required), AND
2. It is inside an active sprint with an assigned developer, AND
3. There is no blocker or decision that specifically requires Pavel's input (e.g. scope change, customer commitment at risk, cross-team dependency he owns)

**Key distinction:**
Pavel should be alerted when there's a *product* decision blocked or a customer/business deadline he needs to actively manage. "Code not done by sprint end" is a Dang/Tri loop. The algorithm should only escalate to Pavel when his intervention would unblock something that Dang/Tri cannot unblock themselves.

**Where to implement:**
- `server/lib/scan-discovery.ts` — add heuristic: if item is a dev task (implementation/script/fix label or title pattern) + inside active sprint + assigned developer → suppress or heavily down-score
- Alternatively: post-discovery scoring in `check-scheduler.ts` — penalise items where `source=Linear` + sprint-active + no product-decision signal in the text

---

## ✗ [2026-05-12] Noise: Delivery tasks within a project Pavel already owns and tracks

**Item surfaced:** AWS-569 — Migration strategy: additive schema + staged cut-over for LicenseArn keying (Tri, In Progress since Apr 29, deadline June 1)

**What happened:**
- 13 days silent in Linear, DoD checkboxes unchecked, Sprint 25 ending today → auto-check verdict: **ESCALATE**
- Suggested next: sync with Tri, three specific questions about Stage A/C delivery status
- Pavel's verdict: *noise — "I am product, all is under control"*

**Why the algorithm was wrong:**
Pavel is Head of Product. The June 1 CA deadline is a delivery milestone he owns and is already tracking. Surfacing individual in-flight tasks within a project he owns is not new information — it's telling him something he already knows. The algorithm can't distinguish between "Pavel doesn't know this" and "Pavel owns this and is on top of it."

**Key distinction from entry #2 (engineering execution):**
This isn't just "wrong loop" — it's a deeper issue. Even if the task has dependencies and a real deadline, if it lives inside a project Pavel owns and is actively managing, individual task-level escalations are redundant noise. The algorithm should escalate things Pavel *can't see*, not things he's *responsible for*.

**Proposed suppression rule:**
Don't escalate delivery tasks to Pavel when:
1. The item is within a project/initiative he owns (Concurrent Agreements, sprint delivery), AND
2. There is an active sprint with an assigned developer, AND
3. No new external signal has appeared (customer escalation, missed external commitment, blocker from outside the team)

**Broader principle emerging across entries #2 and #3:**
> The algorithm should surface things Pavel *doesn't know yet* or *can't see from his position*. It should not surface things he already owns, tracks, or has delegated. The question is not "is this stalled?" but "does Pavel have information here that would change his behaviour?"

**Where to implement:**
- Requires project-ownership mapping: which Linear projects/labels are Pavel's delivery responsibility vs. external signals he needs to catch
- `server/lib/scan-discovery.ts` — suppress items from projects tagged as Pavel's own delivery scope unless there's an external escalation signal
