openspec: archive completed add-os-status-plugin change, sync specs to main

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Mb3V8NNzAuns7vgX9A2jU
This commit is contained in:
jared 2026-07-10 10:08:17 -04:00
parent cc450c385b
commit 7dae595526
8 changed files with 130 additions and 0 deletions

View File

@ -0,0 +1,51 @@
# status-banner — SessionStart aggregation, silence rules, snooze/suppress state
## ADDED Requirements
### Requirement: Single aggregated banner
The os-status SessionStart hook SHALL run all registered checks in-process and emit at most
one warning banner per session, containing one short line per `warn` result with its
corrective action. `note` results SHALL be emitted as individual near-zero-token lines outside
the banner. When every check returns `ok` (and no `note`s exist), the hook SHALL emit nothing.
#### Scenario: All checks ok
- **WHEN** every registered check returns `ok`
- **THEN** the hook produces no output
#### Scenario: Multiple warns aggregate
- **WHEN** two or more checks return `warn`
- **THEN** exactly one banner is emitted containing one line per warning
#### Scenario: Note passes through without banner
- **WHEN** one check returns `note` and all others return `ok`
- **THEN** the note line is emitted and no warning banner appears
### Requirement: Per-project snooze and suppress for warns
`warn` output SHALL be governed by per-project state in a gitignored `.cc-os/` directory:
each warning is emitted at most once per day (snooze), and a permanent suppress marker
silences a given check's warnings in that project until removed. `note` results SHALL NOT be
subject to snooze or suppress. Outside a git project, project-scoped checks SHALL be skipped
and no state SHALL be written.
#### Scenario: Warn snoozed same day
- **WHEN** a check's warning was already emitted today in this project
- **THEN** the warning is not emitted again and the banner omits it
#### Scenario: Permanent suppress
- **WHEN** `.cc-os/` contains a suppress marker for a check
- **THEN** that check's warnings are never emitted in this project while the marker exists
#### Scenario: Not a git project
- **WHEN** the session starts outside a git project
- **THEN** project-scoped checks are skipped, environment-scoped checks still run, and no
`.cc-os/` directory is created
### Requirement: Hook safety envelope
The SessionStart hook SHALL complete within its configured timeout, SHALL exit 0 even when
checks warn or fail internally, and SHALL never write to any file outside the project's
`.cc-os/` state directory.
#### Scenario: Internal failure stays safe
- **WHEN** the checks module itself fails to import or crash-loops
- **THEN** the hook exits 0 with either no output or a single generic warning line, and the
session starts normally

View File

@ -0,0 +1,79 @@
# status-checks — in-process check contract + initial checks
## ADDED Requirements
### Requirement: Uniform in-process check contract
Every status check SHALL be a Python function in the os-status plugin with the signature
`check(ctx) -> CheckResult`, where `ctx` provides the project root (or None outside a git
project) and per-project config, and `CheckResult` carries `status` (`ok` | `note` | `warn`)
and `message` (empty for `ok`). Checks SHALL be registered in a single registry list; adding
a check SHALL require only the function and one registry entry.
#### Scenario: Check returns ok
- **WHEN** a registered check finds its precondition satisfied and has no informational output
- **THEN** it returns `status: ok` and contributes no output to the session
#### Scenario: Check failure is isolated
- **WHEN** a registered check raises an exception or exceeds the per-check time budget
- **THEN** the runner records it as `warn` with a generic message naming the check, continues
running the remaining checks, and never blocks or fails the session
### Requirement: ADR system check preserves os-adr behavior
The `adr_system_present` check SHALL reproduce os-adr's SessionStart behavior: in a git
project with `docs/adr/` present it returns `note` with the existing Eval-B-tuned usage-note
wording verbatim; with `docs/adr/` absent it returns `warn` suggesting init/migrate at most
once per day, permanently silenced by `.os-adr/suppress`; outside a git project it returns
`ok`.
#### Scenario: ADR system present
- **WHEN** the session starts in a git project containing `docs/adr/`
- **THEN** the check returns `note` whose message is byte-identical to os-adr's current
PRESENT_NOTE wording
#### Scenario: ADR system absent, not suppressed
- **WHEN** the session starts in a git project without `docs/adr/` and no `.os-adr/suppress`
exists and no suggestion was emitted today
- **THEN** the check returns `warn` naming `/os-adr:init` and `/os-adr:migrate`
#### Scenario: ADR suggestion suppressed
- **WHEN** `.os-adr/suppress` exists in the project
- **THEN** the check returns `ok`
### Requirement: Vault hub-note check
The `vault_hub_note_present` check SHALL determine whether the current project has a hub note
in the SecondBrain vault, preferring an explicit hub slug from per-project config over
inference by `project/<name>` facet tag. Missing hub note in a git project SHALL yield `warn`
naming the corrective action; present SHALL yield `ok` with no context injection.
#### Scenario: Hub note missing
- **WHEN** the session starts in a git project with no matching hub note in the vault
- **THEN** the check returns `warn` telling the user which skill to run to create one
#### Scenario: Hub note present
- **WHEN** a hub note matching the project exists in the vault
- **THEN** the check returns `ok` and injects nothing
### Requirement: Subagent model env-override check
The `subagent_model_env_override` check SHALL return `warn` when `CLAUDE_CODE_SUBAGENT_MODEL`
is set in the process environment or present in the `env` block of `~/.claude/settings.json`,
identifying where it was found; otherwise `ok`. This check SHALL run regardless of whether the
cwd is a git project.
#### Scenario: Override set in settings.json
- **WHEN** `~/.claude/settings.json` contains `CLAUDE_CODE_SUBAGENT_MODEL` in its `env` block
- **THEN** the check returns `warn` naming the variable, its value, and the file it was found in
#### Scenario: No override
- **WHEN** the variable is absent from both the environment and settings.json
- **THEN** the check returns `ok`
### Requirement: os-adr SessionStart hook removed atomically
In the same change that ships the `adr_system_present` check, os-adr's own SessionStart hook
entry SHALL be removed from `plugins/os-adr/hooks/hooks.json`, and the cutover SHALL be
verified against the refreshed plugin cache (not only source), such that exactly one component
emits the ADR status per session.
#### Scenario: No double emission after cutover
- **WHEN** a fresh session starts after `bin/refresh-plugins` with os-status and os-adr both
installed
- **THEN** the ADR usage note or suggestion appears exactly once