docs(wiki): capture session-inbox-monitor received-msg FP as concept

New page concepts/session-inbox-monitor-received-msg-fp.md — sibling of
delegate-task-negative-trigger-fp. Same FP family, new dimension: the carve-out
is already literal+routed (NOT for handling a received message ->
inter-session-peer-discipline) but the route target is not installed, so it has
no competitor and the nearest in-domain skill wins anyway. Borderline (neg 2/3,
EN twin clean), self-corrects on body-load. Bidirectional cross-link +
index + log. New principle: a routed negative competes only if its route
target is installed. Captured in the wiki (not private memory) per owner direction.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 11:28:31 +03:00
parent 2cd52cfcec
commit 951bc62c04
4 changed files with 78 additions and 1 deletions

View File

@@ -0,0 +1,71 @@
---
title: session-inbox-monitor — a routed negative only competes if its sibling is installed
type: concept
tags: [skill-triggers, false-positive, trigger-discrimination, test-trigger]
updated: 2026-06-17
---
# session-inbox-monitor — a routed negative only competes if its sibling is installed
Sibling of [[delegate-task-negative-trigger-fp]]. Same failure family (a skill
false-positive-fires on a phrase its description tries to exclude), but a **distinct
mechanism** — and it stays **open** as of this writing (follow-up task
`session-inbox-monitor-received-msg-fp`, not yet fixed).
## Symptom
In the `session-inbox-monitor-test-trigger` run (2026-06-17, clean session, 7 unprimed
clean-context subagents), the negative phrase **«В .claude-inbox пришло сообщение от другой
Claude-сессии. Прочитай его и ответь отправителю.»** (N1, RU) routed to
**`session-inbox-monitor`** — a false-positive. The skill is about *raising the monitor*, not
*handling a received message*; the latter belongs to inter-session-peer-discipline /
the CLAUDE.md inter-session rule.
The English twin of the same scenario (N3, «A message arrived in my inbox … handle it and
reply») and the multi-machine-backend negative (N2) both routed to `none` cleanly, citing the
carve-out. So the FP is **borderline / non-deterministic**, not a hard miss: pos 4/4, neg 2/3.
## Root cause
The description *does* carry a literal, routed carve-out —
`NOT for how to handle a received message (→ inter-session-peer-discipline)` — which is exactly
the fix shape [[delegate-task-negative-trigger-fp]] prescribes. The new twist:
**The route target `inter-session-peer-discipline` is not an installed skill.** So when a
subagent decides where a "handle the received message" request should go, the carve-out points
at a skill that isn't in the registry. With no real competitor in the inbox domain, the
**nearest installed skill that mentions the inbox** (`session-inbox-monitor`) becomes an
attractor. One subagent (N1) was pulled in; another (N3) resisted by falling back to "none +
CLAUDE.md rule." Hence the non-determinism.
**Mitigating property:** the FP self-corrects on body-load. Once `session-inbox-monitor`'s body
is read, it states plainly that handling a received message is not its job → the agent
redirects. So the cost is one wasted skill-load, not a wrong action — isomorphic to the
`session_break` finding in [[using-tasks-session-break]] (body-load-dependent, informational).
## Status — open
No fix shipped. Options under the follow-up task (decide, not necessarily implement):
- **(a) Harden the description** — surface `NOT for handling a received message` earlier /
more prominently. Cheap, but a description edit forces a re-run of `-test-trigger` and feeds
back into `-review`.
- **(b) Install the sibling** — give the carve-out a real target by installing
`inter-session-peer-discipline` (likely the true root, but it's a separate skill that may not
exist yet, with its own promotion ledger).
- **(c) Accept as informational** — like `session_break`: low harm + body-load self-correct.
## Reusable principle
[[delegate-task-negative-trigger-fp]] established: *make the negative literal and routed, not
abstract.* This case adds the next clause:
> **A routed negative competes only if its route target is installed.** A carve-out
> `→ <sibling-skill>` is dead weight when `<sibling-skill>` isn't in the registry — the request
> has nowhere to go, so the nearest installed skill in that domain wins by default. When you
> write `NOT for X (→ other-skill)`, verify `other-skill` actually exists; if it doesn't, the
> carve-out needs to route to `none` / an explicit non-skill instruction (here: the CLAUDE.md
> inter-session rule), or the sibling must be promoted alongside.
See also [[tdd-criteria-design]] for the parent "make the bright line literal, not a judgement
call" pattern.