cc-os/openspec/changes/add-os-status-plugin/proposal.md

4.2 KiB

Proposal: add-os-status-plugin

Why

Two real incidents show that cc-os plugins have per-project and per-environment preconditions that nothing verifies: (1) the WS1 orchestration audit found CLAUDE_CODE_SUBAGENT_MODEL=haiku had silently downgraded all 23 verified subagent spawns for weeks — the E1 canary proved this is unobservable to the model at spawn time, so protection must be deterministic; (2) projects routinely lack the artifacts plugins assume (no ADR system, no vault hub note), and each plugin currently invents its own SessionStart reminder in isolation (os-adr, os-doc-hygiene) or has none (os-vault hub notes, os-orchestration env checks). A single aggregated status check at SessionStart closes this class of gap; WS2's eval work also depends on it (hub-note presence becomes a checked artifact).

What Changes

  • New global plugin os-status (per the cc-os os-[domain] naming convention): one SessionStart hook that runs all cc-os status checks in-process and emits at most one short banner.
  • Checks are plain Python functions in a shared module inside os-status — NOT per-plugin subprocess scripts and NOT project-local copies. This was pressure-tested 2026-07-06 by simplifier and implementer perspective reviews (see design.md): per-project copies are the proven copy-drift failure class, and a subprocess/JSON enumeration protocol is overbuilt for the current three checks. The function signature is convention-shaped (each check returns a status + message), so extraction to per-plugin status/check.py enumeration later is mechanical if a check ever needs isolation.
  • Initial checks (Phase 1):
    • adr-system-present — refactors os-adr's existing existence-check behavior into a conforming check; BREAKING (internal): os-adr's own SessionStart hook is removed in the same change (atomic cutover, to avoid double banners).
    • vault-hub-note-present — new: warns when the current project has no hub note in the SecondBrain vault, naming the corrective skill.
    • subagent-model-env-override — new: warns when CLAUDE_CODE_SUBAGENT_MODEL (or a model-forcing equivalent) is set in the environment or ~/.claude/settings.json. Would have caught the WS1 Cluster 1 incident at SessionStart.
  • Per-project state dir .cc-os/ (gitignored) for snooze/suppress of warnings — state only, never code. Existing .os-adr/ and .dochygiene/ dirs are left untouched (consolidation deliberately deferred).
  • Explicitly deferred to a later change: context injection field (no consumer yet), state-dir consolidation, cache-freshness verification (Phase 2 "collection manager"), subprocess/enumeration protocol.

Capabilities

New Capabilities

  • status-checks: the in-process check contract (function signature, ok/warn/note semantics, timeout/failure-isolation rules) and the three initial checks.
  • status-banner: SessionStart aggregation — silence rules, single-banner output, per-project snooze/suppress state in .cc-os/.

Modified Capabilities

Impact

  • New: plugins/os-status/ (hooks/hooks.json + session_start.py entry point, shared checks module, model-free Python tests, invariants.md).
  • Modified: plugins/os-adr/hooks/hooks.json + hooks/session_start.py (SessionStart entry removed; usage-note behavior preserved via the new check's note semantics — the perspective review flagged that a naive "silent on ok" would regress os-adr's present-state usage note).
  • Unchanged: os-doc-hygiene's reminder (converted in a follow-up, not this change, to keep the migration surface small); os-vault hooks (its wiring inconsistency — absolute-path source wiring vs cache — is documented in design.md as a known issue but not a blocker for the in-process shape, which reads nothing from other plugins' caches).
  • Requires bin/refresh-plugins + marketplace manifest entry + claude plugin install for the new plugin; fresh-session smoke test.
  • ADR to be added in docs/memory-system/03-architecture-decisions.md (status-check convention + in-process code-location decision).