Background
Plugins reference §Monitors (Claude Code v2.1.105+) documents a declarative platform primitive for plugin-managed background monitors. Monitors are declared in monitors/monitors.json (or inline in plugin.json); the harness starts them automatically when the plugin is active and turns each stdout line into a notification.
This overlaps significantly with the inbox-watch mechanism shipped in #603 and #609 (/PACT:watch-inbox + /PACT:unwatch-inbox + wake_lifecycle_emitter PostToolUse hook).
Comparison
| Concern |
Current PACT (#603/#609) |
Platform Monitors |
| Spawn mechanism |
Skill-invoked Monitor via Skill(\"PACT:watch-inbox\") |
Declarative `monitors/monitors.json` |
| Lifecycle |
Armed on first-active-task transition; torn down on last-active-task transition |
`when: "always"` (session-lifetime) or `when: "on-skill-invoke:"` |
| Duplicate prevention |
Custom logic in skill body |
`name` field; "Prevents duplicate processes when the plugin reloads or a skill is invoked again" |
| Path substitution |
None |
`${CLAUDE_PLUGIN_ROOT}`, `${CLAUDE_PLUGIN_DATA}`, `${user_config.*}`, `${ENV_VAR}` |
Scope
Platform Monitors solve the spawn / lifecycle / duplicate-prevention problem declaratively. They do not solve PACT's task-state-conditional arming logic ("arm only while at least one teammate task is in_progress"), which would still need PACT-side hooks (TaskCreated / TaskCompleted / TeammateIdle) to start and stop a platform-managed monitor.
Suggested refactor:
- Declare the inbox monitor in `monitors/monitors.json` with `when: "on-skill-invoke:watch-inbox"` (or similar gating)
- Reduce `/PACT:watch-inbox` to a thin trigger — the heavy lifting (spawn, duplicate-prevention, identity) moves to the platform
- Keep PACT-side hooks for task-state-conditional teardown
- Bump plugin's minimum Claude Code version to v2.1.105
Constraints noted in docs
Disabling a plugin mid-session does not stop monitors that are already running. They stop when the session ends.
This differs from current PACT teardown (`/PACT:unwatch-inbox` actively stops the Monitor mid-session). Worth verifying the platform supports active mid-session teardown before refactoring.
Priority
Medium. Net win in code surface area but not blocking. Slot into v4.x backlog after v4.0.0 (orchestrator agent migration) ships.
References
Background
Plugins reference §Monitors (Claude Code v2.1.105+) documents a declarative platform primitive for plugin-managed background monitors. Monitors are declared in
monitors/monitors.json(or inline inplugin.json); the harness starts them automatically when the plugin is active and turns each stdout line into a notification.This overlaps significantly with the inbox-watch mechanism shipped in #603 and #609 (
/PACT:watch-inbox+/PACT:unwatch-inbox+wake_lifecycle_emitterPostToolUse hook).Comparison
Skill(\"PACT:watch-inbox\")Scope
Platform Monitors solve the spawn / lifecycle / duplicate-prevention problem declaratively. They do not solve PACT's task-state-conditional arming logic ("arm only while at least one teammate task is in_progress"), which would still need PACT-side hooks (TaskCreated / TaskCompleted / TeammateIdle) to start and stop a platform-managed monitor.
Suggested refactor:
Constraints noted in docs
This differs from current PACT teardown (`/PACT:unwatch-inbox` actively stops the Monitor mid-session). Worth verifying the platform supports active mid-session teardown before refactoring.
Priority
Medium. Net win in code surface area but not blocking. Slot into v4.x backlog after v4.0.0 (orchestrator agent migration) ships.
References