Report-to-Others Party Discovery: Sentinel Over Inline BT Loop
Context and Problem Statement
The MaybeReportToOthers simulator BT models party identification and
notification as an inline tick-driven loop: identify vendors/coordinators/others
→ iterate → send RS to each. Production Collapse 3 (ADR-0029, issue #1311)
replaced the InjectParticipant family with calls to the suggest-actor-to-case
trigger, but retained the outer loop structure with typed blackboard queues
(identified_vendors, identified_coordinators, identified_others).
Planning of issue #1252 surfaced a fundamental gap: those queues have no
production mechanism to populate them. The identification step
(IdentifyVendors, IdentifyCoordinators, IdentifyOthers) remained as
stub call-out factories with no real implementation path. The SuggestXTrigger
factories require a specific actor ID on the blackboard — something only the
STOCHASTIC fuzzer stub provides.
The design question is: should party discovery and invitation be an inline tick-driven BT subtree, or should it be driven by an external Sentinel capability?
Decision Drivers
- The downstream suggest-actor-to-case protocol cascade (ADR-0026, ADR-0029) already handles the Offer → CaseActor → CaseOwner → Invite → Accept → Record flow correctly; no new BT leaf is needed for the invitation itself
- Populating typed queues (vendor IDs, coordinator IDs) from CPE/NVD/SBOM lookups or LLM evaluation is an inherently external, latency-variable operation — poorly suited to a tick-driven inline BT that must return quickly
- The Sentinel pattern (ADR-0024; reclassified as a call-in pattern rather than a capability shape by ADR-0097) explicitly covers "monitors a condition; when met, calls a trigger endpoint"; this is exactly the party-discovery model
- The existing
create_report_to_others_treemodule (from #1311) has no production callers — it exists only in tests — confirming it was never wired into the real protocol cascade
Considered Options
- Inline BT loop — retain the three-typed-sub-loop tree; fill in real
Retriever implementations (CPE/NVD lookups) for
IdentifyXfactories so the loop executes against real data on every tick - External Sentinel — replace the inline loop entirely; a Sentinel
capability that runs periodically or event-triggered, inspects
the case, and calls
suggest-actor-to-casefor each uninvited candidate - Hybrid — inline BT provides a single-pass Retriever seam (one call-out that returns all candidates at once); Sentinel calls this subtree; no tick loop
Decision Outcome
Chosen option: Option 2 — External Sentinel, because it matches the capability shape taxonomy (ADR-0024), avoids coupling external I/O latency into the BT tick loop, and the downstream trigger cascade already handles the rest. No inline BT loop is needed.
The create_report_to_others_tree module from #1311 was an implementation
artifact of the intermediate Production Collapse 3 design and has been removed
by issue #1848 (see notes/bt-fuzzer-rm-reporting.md § "Sentinel supersession
note").
Consequences
- Good, because party discovery becomes a proper Sentinel — observable, auditable, and independently replaceable without changing the BT tree structure
- Good, because the downstream suggest-actor-to-case cascade already works; no new BT machinery is required
- Good, because the Sentinel can use arbitrarily slow external queries (CPE lookups, LLM evaluation) without blocking the BT tick loop
- Bad, because the Sentinel architecture (#1143) has open design questions (invocation model, authentication, per-case vs global) that must be resolved before a concrete implementation can be built
- Neutral, because the tick-driven
create_report_to_others_treemodule has been removed (issue #1848); tests and bundles were removed with it
More Information
- ADR-0024: Capability Shape Taxonomy (original home of the Sentinel pattern)
- ADR-0026: CaseActor-Routed Actor Suggestion and Invitation Flow
- ADR-0029: Notification Loop Collapse (Production Collapse 3)
- ADR-0097: Sentinel is a call-in pattern, not a capability shape; this decision is unaffected, but the Sentinel's design questions belong to Agentic Participants rather than the capability layer
- Issue #1143: Sentinel pattern design (open; still a child of Epic #1147)
- Issue #2450: Agentic Participants epic — the conceptual home for the Sentinel design questions. The Sentinel issues themselves stay parented to #1147
- Issue #1252: Idea planning session that surfaced this decision (closed)
notes/bt-fuzzer-rm-reporting.md§ "Sentinel supersession note"
Generated spec requirements: specs/behavior-tree-integration.yaml BT-20-003
(amended to record sentinel direction).