diff --git a/docs/adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md b/docs/adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md index f9ccd6d570..1f788fc50b 100644 --- a/docs/adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md +++ b/docs/adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md @@ -1,6 +1,6 @@ # Place the machine profile as a claude-ops skill -- Status: accepted for the placement only +- Status: accepted - Date: 2026-09-29 ## Context @@ -38,12 +38,11 @@ Place the profile as a skill in `claude-ops`, not as a new plugin. ## Status scope -Accepted for the placement only. The invocation-mode change (class (ii) and the hidden `setup` -skills) and any change to the setup contract stay deferred to the owner's later decision on the -design document. This record does not authorize the skill, its scripts, or a version bump. +Accepted. The skill, its scripts, its tests and the `claude-ops` version bump are authorized. The +invocation-mode change (class (ii) and the hidden `setup` skills) and any change to the setup +contract are not part of this decision. ## Consequences -The skill's directory is under `plugins/claude-ops/skills/`. Whether its scope is too broad for -`claude-ops` is the owner's call on the design document; if the owner chooses a new plugin, this -record is superseded. +The skill's directory is under `plugins/claude-ops/skills/`. A move to a new plugin would +supersede this record. diff --git a/docs/catalog.md b/docs/catalog.md index 7c30c49f36..51bb4942f4 100644 --- a/docs/catalog.md +++ b/docs/catalog.md @@ -86,7 +86,7 @@ plugin manifests and kept in sync by CI. Never hand-edit it; the category vocabu - [`playbooks`](../plugins/playbooks): Doctrine and knowledge playbooks as on-demand skills, repo-sweep for running a catalog of hygiene skills through a repository one commit per step, plus a maintainer-facing update skill. boris carries Boris Cherny's Claude Code workflow tips (howborisusesclaudecode.com), skill-authoring carries Anthropic's internal skill-authoring playbook, and fable-5 carries Claude Fable 5's operating doctrine (self-authored, no upstream). The boris and skill-authoring packs vendor a verbatim upstream baseline; /playbooks:update drift-checks and syncs those baselines centrally (maintainers). - [`claude-config`](../plugins/claude-config): Nine configuration-health skills (plus setup) for a repo's Claude Code configuration: audit (settings.json / .mcp.json / hooks / plugins / permissions drift), audit-automation-gaps (evidence-gated verdicts on automation gaps), audit-permission-grants (allow-rule / allowed-tools grants for auto-mode durability and portability), audit-permission-state (the permission rules actually in effect: every settings scope merged with per-rule provenance, what auto mode drops on entry, config written where nothing reads it, and which managed intents are enforced versus loosenable), draft-auto-mode-rules (interview and draft a paste-ready autoMode classifier block; prints only, never writes), audit-instructions (locally-owned instruction surfaces vs current model capability, proposing removals/rewrites of instructions the model no longer needs, and detecting cross-surface instruction conflicts), audit-prompting-postures (the additive lane: posture guidance the prompting guide says a component's purpose needs but the component does not carry), audit-pass (one coordinated, ordered, resumable pass over a named target: three-scope inventory, run-time-derived exclusion set, stable finding identity, suppression memory, resume, one human gate, delegating every check to the plugin that owns it), and unhobble (the empirical bare-baseline experiment: reversibly strip a repo's standing instructions, log real stumbles against the current model, re-add only what evidence earns). - [`claude-memory`](../plugins/claude-memory): Keeps a repo's Claude Code memory layer healthy and under your control, against criteria derived from official Claude Code documentation. The audit skill checks the instruction/memory layer (CLAUDE.md, a root AGENTS.md, CLAUDE.local.md, .claude/rules/, auto-memory) with a deterministic script-backed spine plus judgment-tier checks. The stateless skill inspects, disables, and (confirm-gated) purges Claude-written auto memory across all settings scopes. -- [`claude-ops`](../plugins/claude-ops): Claude Code operations toolkit. Fourteen skills: audit-skill-visibility (audit whether each installed skill is actually VISIBLE to the model, and diagnose why most of a fleet never gets used: a skill is invisible when its description is dropped by Claude Code's skill-listing context budget, which sheds descriptions lowest-score-first so an unused skill loses the keywords that would let it be matched, from skills genuinely not wanted, from skills the run cannot observe at all; computes whether the listing overflows from documented settings, and withholds every cold verdict the data cannot support rather than reporting absence of data as absence of use), inventory (read-only enumeration of the complete invocable surface: every built-in CLI command with aliases and hidden/gated status, every bundled skill, every built-in subagent and tool, and every component of every installed plugin across all marketplaces; reads the shipped binary because upstream publishes no built-in command list, and carries an integrity verdict so a drifted build reports counts as floors rather than silently short totals), audit-install-state (read-only audit of the machine-scope ~/.claude installation directory and ~/.claude.json: full inventory split into an authored surface and rolled-up bulk trees, product-managed retention vs genuinely unmanaged state, filename-scheme resolution before any process-liveness check, and deliberate/mid-experiment detection; reports, never deletes), audit-performance (read-only slowness-diagnostic capture run at the moment the machine or a session feels slow: CLI version, retention-sweep health including the unparsable-settings pause, which warns in /status, a timed census walk of the install tree as a sweep-cost proxy, active-session and plugin-fleet counts, a process census, and the fan-out layer, which covers a load-labeled no-op spawn baseline, every hook that will fire bucketed per-tool-call versus per-turn with its invocation shape, the configured statusline, subagent concurrency and spawn-depth ceilings against documented defaults, whether running sessions predate the settings file they are judged by, and orphan attribution by parent liveness rather than age, plus on Windows a kernel-object census (Token objects against uptime, paged pool) that names a host-level leak beneath all four suspects; read against a bundled known-performance-issues reference that also records the causes tested and cleared; separates the four documented suspects of accumulated state, version regression, component bloat, and per-spawn fan-out cost, and routes remediation out; reports, never mutates, and never executes a discovered hook or statusline command), audit-native-overlap (map native Claude Code surfaces, namely built-in CLI commands, bundled skills, plugin-backed built-ins, and session-provided skills, against the current repo's plugin skills and agents, so a custom component never silently duplicates what Claude Code itself ships; bare invocation is a read-only overlap report carrying the extraction's integrity floors and a shared-listing-budget exposure section, verdicts are human-gated in a committed store rendered into a generated registry whose every row carries an observable recheck trigger, and only an explicit apply step bakes presence-gated native references into descriptions and Boundary sections), observability (read locally captured telemetry from the OTEL store, the collector, the per-session hook event log and hook-event JSONL, and ccusage, with trend reports, a per-session report of what fired, what was blocked and the event timeline, and store pruning), known-issues (search known Claude product GitHub bugs, check service health, maintain a persistent tracked-issue registry), changelog (ingest Claude Code changelog entries and turn them into decisions: apply executes those in scope one PR per owner plugin and hands larger ones off as work items, then re-extract the native surface and file its drift as work items), prerequisites (read-only table of external binaries declared by enabled plugins; never installs), check (read-only check that node and jq resolve for the claude-ops hooks; never installs), plugins (bring a machine's plugin fleet current on demand: marketplace refresh, effective-scope updates including in-repo project/local installs, new-plugin install per policy, scope-divergence detection and explicit convergence), morning-brief (read-only gh-based operator morning view: queue-label counts, merge-ready PRs, parked decisions with their RECOMMENDED lines, and loop-lane telemetry freshness), lanes (start/restart/stop/status loop lanes as named background Claude Code sessions seeded from canonical prompt files, with per-lane model/effort, a repo-pull + marketplace-refresh launch step, and a consume-restarts action, an OS-schedulable reader that relaunches stopped lanes whose telemetry carries a restart_request), and a re-runnable setup action that settles where the known-issues registry, the skill-usage log and the hook log root live, places the root's self-ignoring guard, and detects retired conventions. Plus an opt-in, default-off per-session hook event log (one JSON line per hook event on every event the generated registry marks observable, written to /sessions/.jsonl, with SessionEnd retention by session count or age and an optional detached pre-prune command), a family of eight advisory *-audit hooks (API errors, config changes, instruction loads, permission denials, pre-compaction, skill usage, tool failures, and unsurfaced hook failures. The last also warns the user via systemMessage, since a hook that fails to launch enforces nothing and Claude Code surfaces the failure to nobody) that emit the shared hook-telemetry envelope, and a reference sink that routes envelopes under the same root: per session when the envelope carries a session id, else into the shared hook-events.jsonl the observability skill reads. +- [`claude-ops`](../plugins/claude-ops): Claude Code operations toolkit. Fifteen skills: audit-skill-visibility (audit whether each installed skill is actually VISIBLE to the model, and diagnose why most of a fleet never gets used: a skill is invisible when its description is dropped by Claude Code's skill-listing context budget, which sheds descriptions lowest-score-first so an unused skill loses the keywords that would let it be matched, from skills genuinely not wanted, from skills the run cannot observe at all; computes whether the listing overflows from documented settings, and withholds every cold verdict the data cannot support rather than reporting absence of data as absence of use), inventory (read-only enumeration of the complete invocable surface: every built-in CLI command with aliases and hidden/gated status, every bundled skill, every built-in subagent and tool, and every component of every installed plugin across all marketplaces; reads the shipped binary because upstream publishes no built-in command list, and carries an integrity verdict so a drifted build reports counts as floors rather than silently short totals), audit-install-state (read-only audit of the machine-scope ~/.claude installation directory and ~/.claude.json: full inventory split into an authored surface and rolled-up bulk trees, product-managed retention vs genuinely unmanaged state, filename-scheme resolution before any process-liveness check, and deliberate/mid-experiment detection; reports, never deletes), audit-performance (read-only slowness-diagnostic capture run at the moment the machine or a session feels slow: CLI version, retention-sweep health including the unparsable-settings pause, which warns in /status, a timed census walk of the install tree as a sweep-cost proxy, active-session and plugin-fleet counts, a process census, and the fan-out layer, which covers a load-labeled no-op spawn baseline, every hook that will fire bucketed per-tool-call versus per-turn with its invocation shape, the configured statusline, subagent concurrency and spawn-depth ceilings against documented defaults, whether running sessions predate the settings file they are judged by, and orphan attribution by parent liveness rather than age, plus on Windows a kernel-object census (Token objects against uptime, paged pool) that names a host-level leak beneath all four suspects; read against a bundled known-performance-issues reference that also records the causes tested and cleared; separates the four documented suspects of accumulated state, version regression, component bloat, and per-spawn fan-out cost, and routes remediation out; reports, never mutates, and never executes a discovered hook or statusline command), audit-native-overlap (map native Claude Code surfaces, namely built-in CLI commands, bundled skills, plugin-backed built-ins, and session-provided skills, against the current repo's plugin skills and agents, so a custom component never silently duplicates what Claude Code itself ships; bare invocation is a read-only overlap report carrying the extraction's integrity floors and a shared-listing-budget exposure section, verdicts are human-gated in a committed store rendered into a generated registry whose every row carries an observable recheck trigger, and only an explicit apply step bakes presence-gated native references into descriptions and Boundary sections), observability (read locally captured telemetry from the OTEL store, the collector, the per-session hook event log and hook-event JSONL, and ccusage, with trend reports, a per-session report of what fired, what was blocked and the event timeline, and store pruning), known-issues (search known Claude product GitHub bugs, check service health, maintain a persistent tracked-issue registry), changelog (ingest Claude Code changelog entries and turn them into decisions: apply executes those in scope one PR per owner plugin and hands larger ones off as work items, then re-extract the native surface and file its drift as work items), prerequisites (read-only table of external binaries declared by enabled plugins; never installs), check (read-only check that node and jq resolve for the claude-ops hooks; never installs), machine-profile (discover this machine's facts and per-tree identity domains, store them as a re-runnable profile with the observation behind every value, and diff the stored profile against the host now; read-only unless the operator confirms a write, never installs and never reapplies a stored value on its own), plugins (bring a machine's plugin fleet current on demand: marketplace refresh, effective-scope updates including in-repo project/local installs, new-plugin install per policy, scope-divergence detection and explicit convergence), morning-brief (read-only gh-based operator morning view: queue-label counts, merge-ready PRs, parked decisions with their RECOMMENDED lines, and loop-lane telemetry freshness), lanes (start/restart/stop/status loop lanes as named background Claude Code sessions seeded from canonical prompt files, with per-lane model/effort, a repo-pull + marketplace-refresh launch step, and a consume-restarts action, an OS-schedulable reader that relaunches stopped lanes whose telemetry carries a restart_request), and a re-runnable setup action that settles where the known-issues registry, the skill-usage log and the hook log root live, places the root's self-ignoring guard, and detects retired conventions. Plus an opt-in, default-off per-session hook event log (one JSON line per hook event on every event the generated registry marks observable, written to /sessions/.jsonl, with SessionEnd retention by session count or age and an optional detached pre-prune command), a family of eight advisory *-audit hooks (API errors, config changes, instruction loads, permission denials, pre-compaction, skill usage, tool failures, and unsurfaced hook failures. The last also warns the user via systemMessage, since a hook that fails to launch enforces nothing and Claude Code surfaces the failure to nobody) that emit the shared hook-telemetry envelope, and a reference sink that routes envelopes under the same root: per session when the envelope carries a session id, else into the shared hook-events.jsonl the observability skill reads. - [`rate-limit-guard`](../plugins/rate-limit-guard): Shared rate-limit guard for loop lanes: a statusline wrapper tees the subscription rate-limit windows to a fixed machine-scope file, a StopFailure hook records rate-limit stops reactively, and a reader contract fixes how consuming sessions pause and resume. - [`context-guard`](../plugins/context-guard): Per-session context-window observability plus the first shipped consumer: a statusline wrapper tees each session's context_window fields to a per-session snapshot file, a zone resolver classifies usage into smart/acceptable/dumb bands (percentage bands plus window-class token bands, conservative-min combination, zones.json SSOT with shipped defaults), a reader contract fixes how consuming sessions interpret the snapshots, and zone-crossing hooks report once per transition into a worse zone across two channels: the continuation menu to the operator, who owns that choice, and to the model only the zone determination plus the counter-steer that a zone word is not a decay signal (advisory by default; an optional blocking mode gates new mutating work on a fresh dumb-zone snapshot with handoff-writing exempt), with a PostCompact hook persisting an evidence-degraded marker. - [`context-budget`](../plugins/context-budget): Measure a Claude Code session's fixed startup context payload per item, on the consumer's machine at a pinned, version-stamped binary, including per-tool attribution of the built-in tool pools that /context reports only as lump sums, derived live by A/B bare-name-deny differencing with enforced comparability rules (skill-listing signature, one mode, one binary), an SDK-primary exact meter degrading to a version-aware headless /context parser and then to an honest structured error (never a wrong number), and a per-project measure-toggle-remeasure ledger under the plugin data directory recording every lever's real before/after delta. Report-only by default; `fix` applies one approved project-scope trim. diff --git a/docs/out-of-scope/README.md b/docs/out-of-scope/README.md index 11df21babe..83bfb106b7 100644 --- a/docs/out-of-scope/README.md +++ b/docs/out-of-scope/README.md @@ -4,6 +4,6 @@ One file per rejection, matched and appended to as the `/work-items:triage` "Rej ledger" step defines. The ledger records rejections only, never built features or deferred work: a deferral, a park, or an open question is an open tracker item. -Two entries are agent proposals the owner has not ruled on, not settled rejections: -`machine-profile.md` (#4666) and `shared-surface-instruction-governance.md` (#3568). Each says so in -its own text, and the owner's ruling on that issue confirms, reverses, or removes the entry. +One entry is an agent proposal the owner has not ruled on, not a settled rejection: +`shared-surface-instruction-governance.md` (#3568). It says so in its own text, and the owner's +ruling on that issue confirms, reverses, or removes the entry. diff --git a/docs/out-of-scope/machine-profile.md b/docs/out-of-scope/machine-profile.md index e0b4bb1ab2..a22ff06dcc 100644 --- a/docs/out-of-scope/machine-profile.md +++ b/docs/out-of-scope/machine-profile.md @@ -1,79 +1,34 @@ # Re-runnable machine profile for setup skills Record for -[#4666](https://github.com/melodic-software/claude-code-plugins/issues/4666), -a proposed host-fact store that would drive every plugin `setup` skill. - -Status: unratified agent proposal. The placement is accepted under -[ADR 0041](../adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md); the owner has not ruled -on whether to build it or on any setup-contract change, and #4666 is open for that decision. Until -then it is not a settled rejection. +[#4666](https://github.com/melodic-software/claude-code-plugins/issues/4666). ## Decision -**Superseded in part.** The design is now -[machine-profile-design](../specs/machine-profile-design.md) and the placement is -[ADR 0041](../adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md): a skill in -`claude-ops`. Building the skill and any setup-contract or invocation-mode change stay -undecided until the owner rules on that design. Until then, no `machine-profile` skill -exists, no new plugin is added, and the rest of this record stands. - -- **Option 1 (declined):** orchestrate by instruction. The profile would emit - `/:setup check` lines for the operator to type. That respects class - (ii) and is unpaid operator cost, not a skill to ship. -- **Option 2 (declined):** split `check` from `apply` so `check` is - model-invocable. The per-plugin form shipped in `actionlint`, `biome-format`, - `context7`, `go-format` and `markdown-format` (a separate model-invocable `check` - skill beside the manual `setup`) with no invocation-mode amendment; the class list in - `docs/conventions/invocation-mode/README.md` is still three. Whether to keep that - per-plugin split is an open owner question, - [#4240](https://github.com/melodic-software/claude-code-plugins/issues/4240) question 2. -- **Option 3 (declined):** relax `disable-model-invocation` on `check` only. - Same effect as option 2 with less structure. +The profile is built as the `claude-ops` `machine-profile` skill: +[machine-profile-design](../specs/machine-profile-design.md), placed by +[ADR 0041](../adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md). Two options for it are +declined: -**Claim (original park, before the design document):** a re-runnable machine profile that discovers host facts once and -drives the fleet's setup skills has no model-invocable path to them: all 58 -plugin `setup` skills are `disable-model-invocation: true`, which -`scripts/validate-plugin-contracts.mjs` requires. The model-invocable host -checks are `actionlint:check`, `biome-format:check`, `context7:check`, -`go-format:check` and `markdown-format:check` (one per plugin) and -`claude-ops:prerequisites`, a read-only report over the `prerequisites.json` -that 7 plugins declare. Host discovery stays inside each plugin's `setup`. If the idea returns, it is a `claude-ops` skill that feeds -`machine-health`'s declared-configuration drift check, never a second -host-fact store. -**Basis:** origin/main: 58 plugin-level `plugins/*/skills/setup/SKILL.md` -files, all `disable-model-invocation: true`, required at -`scripts/validate-plugin-contracts.mjs:189-190`. The `check` skill of each of -those five plugins and `plugins/claude-ops/skills/prerequisites/SKILL.md` -set `disable-model-invocation: false`. `docs/conventions/invocation-mode/README.md` -still lists three classes, class (ii) among them, and the invocation-reach -invariant (a `true` skill cannot be invoked by any other skill). No -`machine-profile` skill or plugin under `plugins/`. `machine-health` already -owns a `config` category for declared-configuration drift. -**As of:** 2026-09-29. -**Recheck:** a setup skill drops `disable-model-invocation: true` -(`git grep -L 'disable-model-invocation: true' -- 'plugins/*/skills/setup/SKILL.md'` -lists a file; it lists none today), or a maintainer funds a `claude-ops` skill -whose only job is a read-only host-fact document that `machine-health` -consumes. +- **Orchestration by instruction (declined):** the profile does not orchestrate the whole fleet by + instruction, as a driver that has the operator type a command per plugin. Where it cannot safely + reproduce a setup's `check` probes it relays that one `/:setup check` line, the fallback + the design describes. +- **Setup contract change (declined):** no setup skill is changed and + `validate-plugin-contracts.mjs` is untouched. ## Rationale -- Naive orchestration is impossible today: every setup skill is model-hidden. -- Option 3 changes the contract `validate-plugin-contracts.mjs` enforces on all - 58 setup skills. Option 2 adds a `check` skill to each setup plugin that - lacks one. Neither is a claude-ops slice. -- A parallel host-fact document would compete with `machine-health` instead of - feeding it. -- Per-plugin setup already owns prerequisite logic and versions with the - plugin. Absorbing that into one driver is the gotcha the issue named. +- Every setup skill is model-hidden, so the profile cannot drive them directly. +- Changing the setup contract or the invocation-mode class is a fleet change across every `setup` + skill, not a `claude-ops` slice. +- Per-plugin setup owns prerequisite logic and versions with the plugin; the profile reads host + facts and does not absorb that logic. ## Revisit when -- a `setup` skill becomes model-invocable (the Recheck condition above), or -- the owner rules on the check/setup split in #4240 (question 2), or -- an operator go names a read-only host-fact document with no setup-skill - orchestration. +The built profile shows a check that the existing wrappers and reproduction cannot cover. The +setup-contract question is tracked with #4240. ## Prior requests diff --git a/docs/skill-cheat-sheet.md b/docs/skill-cheat-sheet.md index 37ef3c247f..9c12e5c3fe 100644 --- a/docs/skill-cheat-sheet.md +++ b/docs/skill-cheat-sheet.md @@ -312,6 +312,7 @@ owned by [docs/catalog-taxonomy.md](catalog-taxonomy.md). | [`/claude-ops:audit-skill-visibility`](../plugins/claude-ops/skills/audit-skill-visibility/SKILL.md) | `claude-ops` | weekly | Which skills the model can actually see, which are starved, and which are unobservable | | [`/claude-ops:inventory`](../plugins/claude-ops/skills/inventory/SKILL.md) | `claude-ops` | weekly | Enumerate every command, skill, agent, and plugin component this machine can invoke | | [`/claude-ops:lanes`](../plugins/claude-ops/skills/lanes/SKILL.md) | `claude-ops` | daily | Start, restart, stop, and check loop lanes as named background sessions | +| [`/claude-ops:machine-profile`](../plugins/claude-ops/skills/machine-profile/SKILL.md) | `claude-ops` | weekly | Discover, store and diff machine facts and per-tree identity domains. Read-only by default. | | [`/claude-ops:morning-brief`](../plugins/claude-ops/skills/morning-brief/SKILL.md) | `claude-ops` | daily | Print the operator's read-only morning view. Queues, merge-ready PRs, parked decisions | | [`/claude-ops:observability`](../plugins/claude-ops/skills/observability/SKILL.md) | `claude-ops` | weekly | Report on locally captured telemetry. Token burn, cost, hook latency, per-session activity | | [`/claude-ops:plugins`](../plugins/claude-ops/skills/plugins/SKILL.md) | `claude-ops` | weekly | Bring the machine's plugin fleet current. Refresh, update, install per policy | diff --git a/docs/specs/machine-profile-design.md b/docs/specs/machine-profile-design.md index 86d07fb3ef..7556f2bb42 100644 --- a/docs/specs/machine-profile-design.md +++ b/docs/specs/machine-profile-design.md @@ -3,7 +3,8 @@ Design for a re-runnable machine profile that discovers host facts once, stores them, and hands each plugin's `setup` the answers. Tracked by [#4666](https://github.com/melodic-software/claude-code-plugins/issues/4666). This document -records design only: it changes no setup contract, no invocation-mode class, and no plugin. +records the design and its rulings. The build adds a `claude-ops` skill and changes no setup +contract and no invocation-mode class. ## Contents @@ -15,9 +16,9 @@ records design only: it changes no setup contract, no invocation-mode class, and - [Manual-change policy](#manual-change-policy) - [Reuse and machine-health](#reuse-and-machine-health) - [Placement](#placement) -- [Out of scope until the later decision](#out-of-scope-until-the-later-decision) +- [Out of scope](#out-of-scope) - [Acceptance criteria left for the build](#acceptance-criteria-left-for-the-build) -- [Open questions](#open-questions) +- [Rulings](#rulings) - [Verification record](#verification-record) ## Problem @@ -236,20 +237,18 @@ profile's `diff` is the only consumer. **Recommendation: a skill in `claude-ops`, not a new plugin.** **Basis:** `claude-ops` already owns fleet state and ships `prerequisites` and `inventory`, the two skills the profile reads; a new plugin would add a third owner of host facts beside -`machine-health`. Judgment on the remaining half: whether the skill's scope is too broad for -`claude-ops` stays with the owner when ruling on this document. The decision is recorded in +`machine-health`. The owner ratified the placement. The decision is recorded in [ADR 0041](../adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md). -## Out of scope until the later decision +## Out of scope -Held for the owner's later ruling on this document: +Not part of the build: - Any change to the setup contract, and any change to `validate-plugin-contracts.mjs`. - Amending invocation-mode class (ii) or adding a class, and any change to a `setup` skill's `disable-model-invocation` value. - Adding a model-invocable `check` skill for a plugin that lacks one. -- Version bumps and CHANGELOG entries for any touched plugin. -- The skill itself, its scripts, and its tests. +- Version bumps and CHANGELOG entries for any plugin other than `claude-ops`. ## Acceptance criteria left for the build @@ -268,21 +267,17 @@ tree under a scratch `HOME` and no real-host specifics: `npm view ctx7 version` writes `.npm/_logs` and an update-notifier marker under `HOME`. Test: hash both trees before and after. `apply` writes nothing without an explicit confirm. -## Open questions - -Each is for the later decision on this document. Placement is settled by -[ADR 0041](../adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md) and is not open here. - -1. **Class (ii).** Amend class (ii), add a class, or leave the setup skills hidden and rely on - reproduction. Recommendation: leave them hidden until the profile is built and shows a check the - wrappers and reproduction cannot cover. Unblocks: whether the fleet contract change happens at - all. -2. **Keying deviation.** Ratify a non-project-keyed machine section under plugin-data-report-keying. - Recommendation: ratify, with per-domain sections keyed by tree. Unblocks: the store's path scheme. -3. **The machine-health feed.** Whether machine-health ships a `config` check that reads the - profile, or the profile's `diff` stays the only consumer. Recommendation: ship the check only - once the profile exists and runs on an OS whose machine-health checks are implemented. Unblocks: the handoff - contract. +## Rulings + +Placement is settled by +[ADR 0041](../adr/0041-place-the-machine-profile-as-a-claude-ops-skill.md). + +1. **Class (ii).** The setup skills stay hidden and class (ii) is unchanged. The profile relies on + reproduction and relay. +2. **Keying deviation.** A non-project-keyed machine section is ratified under + plugin-data-report-keying, with per-domain sections keyed by tree. +3. **The machine-health feed.** The machine-health `config` check is deferred until the profile + exists and runs on an OS whose machine-health checks are implemented. ## Verification record diff --git a/plugins/claude-ops/.claude-plugin/plugin.json b/plugins/claude-ops/.claude-plugin/plugin.json index f34e402375..f973767722 100644 --- a/plugins/claude-ops/.claude-plugin/plugin.json +++ b/plugins/claude-ops/.claude-plugin/plugin.json @@ -1,8 +1,8 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "claude-ops", - "version": "0.79.4", - "description": "Claude Code operations toolkit. Fourteen skills: audit-skill-visibility (audit whether each installed skill is actually VISIBLE to the model, and diagnose why most of a fleet never gets used: a skill is invisible when its description is dropped by Claude Code's skill-listing context budget, which sheds descriptions lowest-score-first so an unused skill loses the keywords that would let it be matched, from skills genuinely not wanted, from skills the run cannot observe at all; computes whether the listing overflows from documented settings, and withholds every cold verdict the data cannot support rather than reporting absence of data as absence of use), inventory (read-only enumeration of the complete invocable surface: every built-in CLI command with aliases and hidden/gated status, every bundled skill, every built-in subagent and tool, and every component of every installed plugin across all marketplaces; reads the shipped binary because upstream publishes no built-in command list, and carries an integrity verdict so a drifted build reports counts as floors rather than silently short totals), audit-install-state (read-only audit of the machine-scope ~/.claude installation directory and ~/.claude.json: full inventory split into an authored surface and rolled-up bulk trees, product-managed retention vs genuinely unmanaged state, filename-scheme resolution before any process-liveness check, and deliberate/mid-experiment detection; reports, never deletes), audit-performance (read-only slowness-diagnostic capture run at the moment the machine or a session feels slow: CLI version, retention-sweep health including the unparsable-settings pause, which warns in /status, a timed census walk of the install tree as a sweep-cost proxy, active-session and plugin-fleet counts, a process census, and the fan-out layer, which covers a load-labeled no-op spawn baseline, every hook that will fire bucketed per-tool-call versus per-turn with its invocation shape, the configured statusline, subagent concurrency and spawn-depth ceilings against documented defaults, whether running sessions predate the settings file they are judged by, and orphan attribution by parent liveness rather than age, plus on Windows a kernel-object census (Token objects against uptime, paged pool) that names a host-level leak beneath all four suspects; read against a bundled known-performance-issues reference that also records the causes tested and cleared; separates the four documented suspects of accumulated state, version regression, component bloat, and per-spawn fan-out cost, and routes remediation out; reports, never mutates, and never executes a discovered hook or statusline command), audit-native-overlap (map native Claude Code surfaces, namely built-in CLI commands, bundled skills, plugin-backed built-ins, and session-provided skills, against the current repo's plugin skills and agents, so a custom component never silently duplicates what Claude Code itself ships; bare invocation is a read-only overlap report carrying the extraction's integrity floors and a shared-listing-budget exposure section, verdicts are human-gated in a committed store rendered into a generated registry whose every row carries an observable recheck trigger, and only an explicit apply step bakes presence-gated native references into descriptions and Boundary sections), observability (read locally captured telemetry from the OTEL store, the collector, the per-session hook event log and hook-event JSONL, and ccusage, with trend reports, a per-session report of what fired, what was blocked and the event timeline, and store pruning), known-issues (search known Claude product GitHub bugs, check service health, maintain a persistent tracked-issue registry), changelog (ingest Claude Code changelog entries and turn them into decisions: apply executes those in scope one PR per owner plugin and hands larger ones off as work items, then re-extract the native surface and file its drift as work items), prerequisites (read-only table of external binaries declared by enabled plugins; never installs), check (read-only check that node and jq resolve for the claude-ops hooks; never installs), plugins (bring a machine's plugin fleet current on demand: marketplace refresh, effective-scope updates including in-repo project/local installs, new-plugin install per policy, scope-divergence detection and explicit convergence), morning-brief (read-only gh-based operator morning view: queue-label counts, merge-ready PRs, parked decisions with their RECOMMENDED lines, and loop-lane telemetry freshness), lanes (start/restart/stop/status loop lanes as named background Claude Code sessions seeded from canonical prompt files, with per-lane model/effort, a repo-pull + marketplace-refresh launch step, and a consume-restarts action, an OS-schedulable reader that relaunches stopped lanes whose telemetry carries a restart_request), and a re-runnable setup action that settles where the known-issues registry, the skill-usage log and the hook log root live, places the root's self-ignoring guard, and detects retired conventions. Plus an opt-in, default-off per-session hook event log (one JSON line per hook event on every event the generated registry marks observable, written to /sessions/.jsonl, with SessionEnd retention by session count or age and an optional detached pre-prune command), a family of eight advisory *-audit hooks (API errors, config changes, instruction loads, permission denials, pre-compaction, skill usage, tool failures, and unsurfaced hook failures. The last also warns the user via systemMessage, since a hook that fails to launch enforces nothing and Claude Code surfaces the failure to nobody) that emit the shared hook-telemetry envelope, and a reference sink that routes envelopes under the same root: per session when the envelope carries a session id, else into the shared hook-events.jsonl the observability skill reads.", + "version": "0.80.0", + "description": "Claude Code operations toolkit. Fifteen skills: audit-skill-visibility (audit whether each installed skill is actually VISIBLE to the model, and diagnose why most of a fleet never gets used: a skill is invisible when its description is dropped by Claude Code's skill-listing context budget, which sheds descriptions lowest-score-first so an unused skill loses the keywords that would let it be matched, from skills genuinely not wanted, from skills the run cannot observe at all; computes whether the listing overflows from documented settings, and withholds every cold verdict the data cannot support rather than reporting absence of data as absence of use), inventory (read-only enumeration of the complete invocable surface: every built-in CLI command with aliases and hidden/gated status, every bundled skill, every built-in subagent and tool, and every component of every installed plugin across all marketplaces; reads the shipped binary because upstream publishes no built-in command list, and carries an integrity verdict so a drifted build reports counts as floors rather than silently short totals), audit-install-state (read-only audit of the machine-scope ~/.claude installation directory and ~/.claude.json: full inventory split into an authored surface and rolled-up bulk trees, product-managed retention vs genuinely unmanaged state, filename-scheme resolution before any process-liveness check, and deliberate/mid-experiment detection; reports, never deletes), audit-performance (read-only slowness-diagnostic capture run at the moment the machine or a session feels slow: CLI version, retention-sweep health including the unparsable-settings pause, which warns in /status, a timed census walk of the install tree as a sweep-cost proxy, active-session and plugin-fleet counts, a process census, and the fan-out layer, which covers a load-labeled no-op spawn baseline, every hook that will fire bucketed per-tool-call versus per-turn with its invocation shape, the configured statusline, subagent concurrency and spawn-depth ceilings against documented defaults, whether running sessions predate the settings file they are judged by, and orphan attribution by parent liveness rather than age, plus on Windows a kernel-object census (Token objects against uptime, paged pool) that names a host-level leak beneath all four suspects; read against a bundled known-performance-issues reference that also records the causes tested and cleared; separates the four documented suspects of accumulated state, version regression, component bloat, and per-spawn fan-out cost, and routes remediation out; reports, never mutates, and never executes a discovered hook or statusline command), audit-native-overlap (map native Claude Code surfaces, namely built-in CLI commands, bundled skills, plugin-backed built-ins, and session-provided skills, against the current repo's plugin skills and agents, so a custom component never silently duplicates what Claude Code itself ships; bare invocation is a read-only overlap report carrying the extraction's integrity floors and a shared-listing-budget exposure section, verdicts are human-gated in a committed store rendered into a generated registry whose every row carries an observable recheck trigger, and only an explicit apply step bakes presence-gated native references into descriptions and Boundary sections), observability (read locally captured telemetry from the OTEL store, the collector, the per-session hook event log and hook-event JSONL, and ccusage, with trend reports, a per-session report of what fired, what was blocked and the event timeline, and store pruning), known-issues (search known Claude product GitHub bugs, check service health, maintain a persistent tracked-issue registry), changelog (ingest Claude Code changelog entries and turn them into decisions: apply executes those in scope one PR per owner plugin and hands larger ones off as work items, then re-extract the native surface and file its drift as work items), prerequisites (read-only table of external binaries declared by enabled plugins; never installs), check (read-only check that node and jq resolve for the claude-ops hooks; never installs), machine-profile (discover this machine's facts and per-tree identity domains, store them as a re-runnable profile with the observation behind every value, and diff the stored profile against the host now; read-only unless the operator confirms a write, never installs and never reapplies a stored value on its own), plugins (bring a machine's plugin fleet current on demand: marketplace refresh, effective-scope updates including in-repo project/local installs, new-plugin install per policy, scope-divergence detection and explicit convergence), morning-brief (read-only gh-based operator morning view: queue-label counts, merge-ready PRs, parked decisions with their RECOMMENDED lines, and loop-lane telemetry freshness), lanes (start/restart/stop/status loop lanes as named background Claude Code sessions seeded from canonical prompt files, with per-lane model/effort, a repo-pull + marketplace-refresh launch step, and a consume-restarts action, an OS-schedulable reader that relaunches stopped lanes whose telemetry carries a restart_request), and a re-runnable setup action that settles where the known-issues registry, the skill-usage log and the hook log root live, places the root's self-ignoring guard, and detects retired conventions. Plus an opt-in, default-off per-session hook event log (one JSON line per hook event on every event the generated registry marks observable, written to /sessions/.jsonl, with SessionEnd retention by session count or age and an optional detached pre-prune command), a family of eight advisory *-audit hooks (API errors, config changes, instruction loads, permission denials, pre-compaction, skill usage, tool failures, and unsurfaced hook failures. The last also warns the user via systemMessage, since a hook that fails to launch enforces nothing and Claude Code surfaces the failure to nobody) that emit the shared hook-telemetry envelope, and a reference sink that routes envelopes under the same root: per session when the envelope carries a session id, else into the shared hook-events.jsonl the observability skill reads.", "author": { "name": "Melodic Software", "email": "info@melodicsoftware.com" diff --git a/plugins/claude-ops/CHANGELOG.md b/plugins/claude-ops/CHANGELOG.md index 9f09d399ff..c35a239cdb 100644 --- a/plugins/claude-ops/CHANGELOG.md +++ b/plugins/claude-ops/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to the `claude-ops` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.80.0] - 2026-10-01 + +### Added + +- **`/claude-ops:machine-profile` records what this machine has and reports when it changes.** It discovers machine facts and per-tree identity domains, stores them as a profile with the observation behind every value, and diffs the stored profile against the host. Read-only unless the operator confirms: `record --confirm` writes the profile and `apply --confirm` prints what to hand to each setup. It never installs and never reapplies a stored value on its own. + ## [0.79.4] - 2026-10-01 ### Fixed diff --git a/plugins/claude-ops/README.md b/plugins/claude-ops/README.md index aeb5b91094..13d4d8ddfd 100644 --- a/plugins/claude-ops/README.md +++ b/plugins/claude-ops/README.md @@ -11,7 +11,7 @@ - [License](#license) A Claude Code plugin for running Claude Code well over time. One cohesive -capability across fourteen skills and a family of telemetry-emitter hooks, including diagnosing why +capability across fifteen skills and a family of telemetry-emitter hooks, including diagnosing why most of an installed skill fleet never gets used. audit-native-overlap maps native Claude Code surfaces against the current repo's own components so a custom skill never silently duplicates what the @@ -44,6 +44,7 @@ Claude Code's native OTEL cannot see. | `/claude-ops:morning-brief` | Prints the read-only, `gh`-based operator morning view for the current repo in one pass: open counts per queue label (`needs-triage`, `status: ready`, `status: needs-decision`, `needs-human`), the gh-native merge-ready PR list (non-draft + `mergeStateStatus=CLEAN`), parked `status: needs-decision` issues with their RECOMMENDED lines, and loop-lane telemetry freshness (per-lane `last-cycle` age + `flags:`). Never mutates anything; the authoritative PR merge gate stays `/source-control:babysit-prs`. | | `/claude-ops:lanes` | Starts, restarts, stops, and reports loop lanes as named background Claude Code sessions seeded from canonical prompt files. `start` (default) / `restart` pull the repo and refresh the plugin marketplace, then launch each configured lane (`claude --bg -n --permission-mode auto`, plus `--permission-prompts none` on CLI 2.1.259 or later) with its per-lane `model`/`effort`; `status` shows per-lane running state and live sessionId; `stop` ends a lane via `claude stop`; `consume-restarts` is the OS-schedulable restart-request consumer. It reads each configured lane's telemetry `restart_request` and relaunches the stopped lanes that asked, through the same launcher (#1653). Acts only on sessions whose name is a configured lane. Lanes come from a JSON config (`--config`, else `$CLAUDE_OPS_LANES_CONFIG`, else `/.work/lanes/lanes.json`, with a temporary default-only fallback to the pre-move `/.work/lanes.json` under a deprecation warning); config and prompts live in the reserved `lanes/` concern home under a hardcoded `.work` root, which is a sanctioned placement but still session-local, so a durable cross-machine home stays #480's job. | | `/claude-ops:check` | Read-only check that `node` and `jq` resolve for the hooks, with the install route for a missing tool. Model-invocable; never installs. | +| `/claude-ops:machine-profile` | Discovers this machine's facts and identity domains (each tree's git include, `gh` directory and verdicts), stores them as a re-runnable profile that records the observation behind every value, and reports drift between the stored profile and the host now. Actions: `profile` (default), `diff`, `explain `, `apply --option `. Read-only unless the operator confirms a write: `record --confirm` writes the profile document, and `apply --confirm` prints what to hand to each setup and writes nothing. Never installs and never reapplies a stored value on its own. Design: `docs/specs/machine-profile-design.md`. | | `/claude-ops:setup` | `check` reports the effective known-issues-registry, skill-usage-log and hook-log-root destinations, their defaults, path containment, the hook log root's self-ignoring guard, and retired conventions (`retirements.yaml`), and prints the guidance for routing personal option changes through Claude Code's plugin configuration prompt; `apply` writes exactly one file, the guard inside the hook log root, and runs the gated retirement cleanup. | ## The audit hooks diff --git a/plugins/claude-ops/skills/machine-profile/SKILL.md b/plugins/claude-ops/skills/machine-profile/SKILL.md new file mode 100644 index 0000000000..67d7b6139a --- /dev/null +++ b/plugins/claude-ops/skills/machine-profile/SKILL.md @@ -0,0 +1,73 @@ +--- +description: "Discovers this machine's facts and identity domains, stores them as a re-runnable profile, and reports drift between the stored profile and the host now. Read-only unless the operator confirms a write. Use when: 'machine profile', 'profile this machine', 'what does this host have configured', 'has this machine changed', 'diff my machine profile', 'which identity domains exist here', 'hand my machine facts to setup'. Never installs and never reapplies a stored value on its own." +argument-hint: "[profile | diff | explain | apply --option ]" +user-invocable: true +disable-model-invocation: false +metadata: + workflow-stage: operator + summary: Discover, store and diff machine facts and per-tree identity domains. Read-only by default. + cadence: weekly +--- + +## Purpose + +Record, once per machine, what the host has and which identity domains it holds, with the observation behind every value, so a plugin `setup` run starts from observed answers and a kept default says whether anyone looked. The profile drives setups; it never replaces their prerequisite logic. Design and rulings: `docs/specs/machine-profile-design.md`, placement in ADR 0041. + +Everything here is read-only except two steps the operator confirms in that turn: `record --confirm` (writes the profile document) and `apply --confirm` (prints what to hand to each setup; it writes nothing itself). + +## Actions + +`