Skip to main content

Domain observers

Domain observers are six reactive agents built into the Studio runtime that watch the artifact stream and propose constraints when they detect a gap relevant to their domain. They run in-process, fire-and-forget, and produce only artifacts — they cannot create goals, spawn work units, schedule tasks, or write files.

The six observers

ObserverTriggered by keywords (sample)
Securityauth, authn, authz, login, password, token, jwt, oauth, session, credential, secret, permission, role, acl, encrypt, csrf, xss, sql injection, cors, cookie
Architecturearchitecture, framework, library, module boundary, service boundary, coupling, dependency graph, design pattern, microservice, monolith, scalability, migration
Performanceperformance, latency, throughput, n+1, cache, caching, benchmark, memory leak, allocation, slow query, timeout, concurrency, lock contention, rate limit
Testtest coverage, unit test, integration test, flaky, test gap, regression, mock, test fixture, e2e, untested
Documentationdocumentation, docs, readme, api doc, changelog, undocumented, doc gap
UXux, usability, accessibility, a11y, user flow, ui, design system, user experience, onboarding, error message, confusing

Enabling observers

Observers are disabled by default (empty list). Enable them by adding agent names to Workspace:EnabledDomainAgents in appsettings.json:
{
  "Workspace": {
    "EnabledDomainAgents": ["Security", "Architecture", "Test"]
  }
}
Valid names: Security, Architecture, Performance, Test, Documentation, UX. The value is case-sensitive. Changes require a host restart.

Per-work-unit override

When spawning an orchestrator via POST /studio/agents/spawn, pass enabledDomainAgents to override the session default for that specific work unit’s execution:
{
  "workUnitId": "WU-abc123",
  "agentType": "orchestrator",
  "enabledDomainAgents": ["Security"]
}
This is captured at spawn time and does not change if the session default is later updated.
There is no panel in the VS Code extension to toggle observers per goal today. Configuration is via appsettings.json (global) or the enabledDomainAgents field on agent spawn (per work unit).

How observers trigger

After any Research, Decision, or Constraint artifact is recorded against a work unit, the trigger pipeline runs for each enabled observer:
  1. Type filter — only Research, Decision, Constraint artifacts are considered. Other artifact types (Plan, Task, MergeProposal, etc.) do not trigger observers.
  2. Loop prevention — artifacts whose title starts with an observer’s title prefix (e.g., [SecurityAgent] ) do not re-trigger that observer. This prevents an observer’s own output from cascading back into itself or cross-triggering peers.
  3. Keyword heuristic — the artifact’s title and body are scanned for the observer’s keywords. If no keyword matches, the observer is skipped for that artifact.
  4. Spawn — an observer loop starts fire-and-forget. Failures do not affect the artifact that triggered them.

What an observer can do

Each observer receives exactly four MCP tools:
ToolPurpose
nm_v1_projection_getRead the work unit’s artifact chain + inherited constraints
nm_v1_artifact_querySearch for existing constraints to avoid duplicates
nm_v1_workspace_searchGrep workspace files to corroborate a finding
nm_v1_artifact_recordRecord a Constraint or Research artifact
The observer’s LLM loop (max 8 iterations) uses these tools to decide whether a concrete gap exists. If yes, it records a Constraint; if the gap is already covered or doesn’t apply, it does nothing. Observers never call write, build, test, or merge tools.

What observers produce

Observers emit Constraint artifacts for concrete, specific gaps (e.g., “Missing CSRF protection on the password-reset endpoint”) or Research artifacts for findings that don’t rise to an actionable constraint. Constraints proposed by observers appear in the Decision Lens Context tab’s artifact chain, identifiable by their title prefix — see Reference → Control Tower UI.