-
Notifications
You must be signed in to change notification settings - Fork 2
feat(disk-hygiene): add read-only managed-state owner registry #5562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
bdb7282
feat(disk-hygiene): add managed-state owner registry as data with sch…
kyle-sexton e1b3b93
docs(disk-hygiene): specify the managed-state report for registry mat…
kyle-sexton c68862f
test(disk-hygiene): prove the managed-state registry grants no approv…
kyle-sexton ab62747
Merge remote-tracking branch 'origin/main' into feat/4006-managed-sta…
kyle-sexton e4e9033
feat(disk-hygiene): release the read-only managed-state owner registr…
kyle-sexton 5419f28
test(disk-hygiene): fence deletion and registry commands to the engin…
kyle-sexton 7c98f39
test(disk-hygiene): close the argv, placeholder and launcher gaps in …
kyle-sexton dee6a22
fix(disk-hygiene): mark the owner-registry test executable
kyle-sexton 9e64e25
Merge remote-tracking branch 'origin/main' into feat/4006-managed-sta…
kyle-sexton fdc395d
docs(disk-hygiene): the managed-state report does not show destructiv…
kyle-sexton bc164c0
fix(disk-hygiene): keep the clean skill under the 500-line cap
kyle-sexton f1095a8
Merge remote-tracking branch 'origin/main' into feat/4006-managed-sta…
kyle-sexton 98415b1
test(disk-hygiene): guard the two engine deletion lanes, not one
kyle-sexton 88e71d4
Merge remote-tracking branch 'origin/main' into feat/4006-managed-sta…
kyle-sexton 797bb10
docs(disk-hygiene): give a registry match precedence over the native-…
kyle-sexton ee9661d
docs(disk-hygiene): scope the managed-state handoff text to the no-ma…
kyle-sexton 0355a89
docs(disk-hygiene): name the lane that runs the managed-state report'…
kyle-sexton 331e267
Merge remote-tracking branch 'origin/main' into feat/4006-managed-sta…
kyle-sexton 36d3c17
Merge remote-tracking branch 'origin/main' into feat/4006-managed-sta…
kyle-sexton 79dbe34
fix(disk-hygiene): answer review on the managed-state report and regi…
kyle-sexton e045609
Merge remote-tracking branch 'origin/main' into feat/4006-managed-sta…
kyle-sexton b8a3254
fix(disk-hygiene): resolve the executable for each invocation in a co…
kyle-sexton 2964371
Merge remote-tracking branch 'origin/main' into feat/4006-managed-sta…
kyle-sexton File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
plugins/disk-hygiene/skills/clean/reference/managed-state-report.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # Managed-state report | ||
|
|
||
| The report a managed-state registry match produces. The registry is | ||
| [owner-registry.json](owner-registry.json), validated by | ||
| [owner-registry.schema.json](owner-registry.schema.json). The engine's eligibility rules for | ||
| managed state stay as [the safety model](safety-model.md) states them. | ||
|
|
||
| ## Report per registry match | ||
|
|
||
| 1. **Owner.** The entry's `owner` and `id`, with the matched path. The match is a hint for an | ||
| owner claim, not proof of one. | ||
| 2. **Tool presence.** Before any command, resolve the entry's `tool` to an application executable | ||
| in the lane named under [Who runs the probes](#who-runs-the-probes). Absent: status | ||
| `absent-tool`, and the report offers no command. `manual_step` is an action in the product's | ||
| own interface, not a command, so the report still shows it as information, noting that it | ||
| applies only if the product is installed. Not run: the report says presence is unverified and | ||
| runs nothing further. | ||
| 3. **Read-only command.** When present and `read_only_command` is set, run it in that lane by the | ||
| resolved executable and capture its output into the report verbatim. A null command means the | ||
| product has none; the report shows `manual_step` as information. | ||
| 4. **Destructive native command.** Neither shown nor run by the report. The registry keeps each one | ||
| as data to inspect. The engine blocks a plan that claims a registry owner with | ||
| `native-managed-report-only` and issues no approval token for it. Whether the report may show a | ||
| destructive command, or offer one behind the engine's tier and exact-list approval, is the | ||
| owner's decision, and no route for either is built. | ||
| 5. **Unmatched paths.** A managed-looking path with no registry match is reported as a coverage | ||
| gap. It is never `clean` and never removable. | ||
|
|
||
| ## Who runs the probes | ||
|
|
||
| Steps 2 and 3 are tool calls or operator actions, never shipped code. The clean skill's Bash guard | ||
| denies both, since neither is a bundled engine shape or a listed supporting command (see the Bash | ||
| and PowerShell lane bullets under [Gotchas](../SKILL.md#gotchas)). Where the session has the | ||
| PowerShell tool, run them there (`Get-Command <tool> -CommandType Application`, then the command): that lane is open for | ||
| read-only support work and the guard gives those commands no decision, so the session's ordinary | ||
| permissions, and in auto mode its classifier, still decide. A profile alias or function can shadow | ||
| a tool's name, so resolve with `Get-Command <tool> -CommandType Application`, run the command as | ||
| `& '<Source>' <arguments>` with that resolved path, once for each `;`-separated invocation in a | ||
| compound command (`pulumi about; pulumi plugin ls` is two), and treat a name that resolves only to an alias | ||
| or function as `absent-tool`. Otherwise the operator runs both | ||
| outside the session, presence check first, and the report records what they paste. A probe nobody | ||
| ran is reported as not run, never as a result. | ||
|
|
||
| ## Design check | ||
|
|
||
| | Design constraint | How this report meets it | | ||
| |---|---| | ||
| | Containment is untouched | The report adds no deletion capability; engine eligibility is unchanged. | | ||
| | Read-only and destructive are different gates | Step 3 is a tool call in the PowerShell lane or an operator action, never the engine and never shipped code. Step 4 shows and runs no destructive command, so none is offered outside the engine's approval; offering one behind that approval is not built. The test fence names both kinds of command, so a shipped probe runner would be a reviewed change to that fence. | | ||
| | Tool presence is checked first | Step 2 runs before step 3, in the same lane; absent gives `absent-tool` and no commands; the manual step, which is not a command, stays as information. | | ||
| | An entry is a hint, never authorization | Step 1 treats a match as a claim to prove. | | ||
| | Unmatched stays a coverage gap | Step 5. | | ||
| | The registry is inspectable | Plain JSON plus a schema, readable without running anything. | | ||
|
|
||
| ## Scope | ||
|
|
||
| No destructive command is built. Whether a product-native destructive command is ever run stays | ||
| the owner's decision. |
138 changes: 138 additions & 0 deletions
138
plugins/disk-hygiene/skills/clean/reference/owner-registry.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| { | ||
| "version": 1, | ||
| "note": "An entry is a hint for an owner claim, never authorization. A path matching an entry is a starting point for proving the owning product manages it, not proof. Commands are data for an operator to read; nothing here runs them. Paths are relative to the home directory. A null command means the product has none; manual_step names the in-app or settings action instead.", | ||
| "entries": [ | ||
| { | ||
| "id": "docker-desktop", | ||
| "owner": "Docker Desktop", | ||
| "path_patterns": { | ||
| "windows": ["AppData/Local/Docker"], | ||
| "macos": ["Library/Containers/com.docker.docker"] | ||
| }, | ||
| "tool": "docker", | ||
| "read_only_command": "docker system df", | ||
| "destructive_native_command": "docker image prune; docker builder prune", | ||
|
kyle-sexton marked this conversation as resolved.
|
||
| "manual_step": null, | ||
| "platforms": ["windows", "macos"], | ||
| "verification": { | ||
| "claim": "docker system df reports reclaimable space; docker image prune and docker builder prune are the owner's removal commands; the two data paths were seen on a Windows and a macOS host", | ||
| "basis": [ | ||
| "https://docs.docker.com/reference/cli/docker/system/df/", | ||
| "https://docs.docker.com/reference/cli/docker/image/prune/", | ||
| "https://docs.docker.com/reference/cli/docker/builder/prune/", | ||
| "operator probe of the data paths recorded in issue 4006, no official page found" | ||
| ], | ||
| "as_of": "2026-09-30", | ||
| "recheck": "a Docker CLI release note that renames or removes one of the three commands, or a Docker Desktop release note that moves its data directory" | ||
| } | ||
| }, | ||
| { | ||
| "id": "nvidia-shader-cache", | ||
| "owner": "NVIDIA driver shader cache", | ||
| "path_patterns": { | ||
| "windows": ["AppData/Local/NVIDIA"] | ||
| }, | ||
| "tool": "nvidia-smi", | ||
| "read_only_command": null, | ||
| "destructive_native_command": null, | ||
| "manual_step": "Manual step in Windows Disk Cleanup: select DirectX Shader Cache", | ||
| "platforms": ["windows"], | ||
| "verification": { | ||
| "claim": "the NVIDIA shader cache sits under the listed Windows path and Windows Disk Cleanup offers a DirectX Shader Cache item", | ||
| "basis": ["operator probe recorded in issue 4006, no official page fetched"], | ||
| "as_of": "2026-09-30", | ||
| "recheck": "an NVIDIA driver release note that moves the shader cache, or a Windows build whose Disk Cleanup drops the DirectX Shader Cache item" | ||
| } | ||
| }, | ||
| { | ||
| "id": "cursor", | ||
| "owner": "Cursor", | ||
| "path_patterns": { | ||
| "windows": ["AppData/Roaming/Cursor"], | ||
| "macos": ["Library/Application Support/Cursor"], | ||
| "linux": [".config/Cursor"] | ||
| }, | ||
| "tool": "cursor", | ||
| "read_only_command": null, | ||
| "destructive_native_command": null, | ||
| "manual_step": "In-app cache clearing in Cursor", | ||
| "platforms": ["windows", "macos", "linux"], | ||
| "verification": { | ||
| "claim": "Cursor keeps its state under the listed per-platform user-data paths and offers in-app cache clearing", | ||
| "basis": ["operator probe recorded in issue 4006, no official page fetched"], | ||
| "as_of": "2026-09-30", | ||
| "recheck": "a Cursor changelog entry that moves the user-data directory or removes in-app cache clearing" | ||
| } | ||
| }, | ||
| { | ||
| "id": "openai-codex-cli", | ||
| "owner": "OpenAI Codex CLI", | ||
| "path_patterns": { | ||
| "windows": [".codex"], | ||
| "macos": [".codex"], | ||
| "linux": [".codex"] | ||
| }, | ||
| "tool": "codex", | ||
| "read_only_command": null, | ||
| "destructive_native_command": null, | ||
| "manual_step": "Adjust Codex history retention in its configuration", | ||
| "platforms": ["windows", "macos", "linux"], | ||
| "verification": { | ||
| "claim": "Codex keeps user configuration under ~/.codex and config.toml offers history.max_bytes and history.persistence", | ||
| "basis": [ | ||
| "https://learn.chatgpt.com/docs/config-file/config-basic", | ||
| "https://learn.chatgpt.com/docs/config-file/config-reference" | ||
| ], | ||
| "as_of": "2026-09-30", | ||
| "recheck": "a Codex release note that changes the config directory or the history.* keys" | ||
| } | ||
| }, | ||
| { | ||
| "id": "chezmoi", | ||
| "owner": "chezmoi", | ||
| "path_patterns": { | ||
| "windows": [".cache/chezmoi"], | ||
| "macos": [".cache/chezmoi"], | ||
| "linux": [".cache/chezmoi"] | ||
| }, | ||
| "tool": "chezmoi", | ||
| "read_only_command": "chezmoi doctor", | ||
| "destructive_native_command": null, | ||
| "manual_step": null, | ||
| "platforms": ["windows", "macos", "linux"], | ||
| "verification": { | ||
| "claim": "chezmoi's default cacheDir is ~/.cache/chezmoi on every listed platform and chezmoi doctor checks for problems", | ||
| "basis": [ | ||
| "https://www.chezmoi.io/reference/configuration-file/variables/", | ||
| "https://www.chezmoi.io/reference/commands/doctor/" | ||
| ], | ||
| "as_of": "2026-09-30", | ||
| "recheck": "a chezmoi release note that changes the default cacheDir or the doctor command" | ||
| } | ||
| }, | ||
| { | ||
| "id": "pulumi", | ||
| "owner": "Pulumi", | ||
| "path_patterns": { | ||
| "windows": [".pulumi"], | ||
| "macos": [".pulumi"], | ||
| "linux": [".pulumi"] | ||
| }, | ||
| "tool": "pulumi", | ||
| "read_only_command": "pulumi about; pulumi plugin ls", | ||
| "destructive_native_command": "pulumi plugin rm <unused version>", | ||
| "manual_step": null, | ||
| "platforms": ["windows", "macos", "linux"], | ||
| "verification": { | ||
| "claim": "the plugin cache lives under ~/.pulumi by default, pulumi about prints environment information, pulumi plugin ls lists the cache, and pulumi plugin rm (alias of remove) deletes cached plugins", | ||
| "basis": [ | ||
| "https://www.pulumi.com/docs/iac/cli/commands/pulumi_plugin_ls/", | ||
| "https://www.pulumi.com/docs/iac/cli/commands/pulumi_plugin_rm/", | ||
| "https://www.pulumi.com/docs/iac/cli/commands/pulumi_about/" | ||
| ], | ||
| "as_of": "2026-09-30", | ||
| "recheck": "a Pulumi CLI release note that changes the plugin cache location or the plugin ls, plugin rm or about commands" | ||
| } | ||
| } | ||
| ] | ||
| } | ||
61 changes: 61 additions & 0 deletions
61
plugins/disk-hygiene/skills/clean/reference/owner-registry.schema.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "type": "object", | ||
| "required": ["version", "note", "entries"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "version": {"const": 1}, | ||
| "note": {"type": "string", "minLength": 1}, | ||
| "entries": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "items": { | ||
| "type": "object", | ||
| "required": [ | ||
| "id", "owner", "path_patterns", "tool", "read_only_command", | ||
| "destructive_native_command", "manual_step", "platforms", "verification" | ||
| ], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "id": {"type": "string", "minLength": 1}, | ||
| "owner": {"type": "string", "minLength": 1}, | ||
| "path_patterns": { | ||
| "type": "object", | ||
| "minProperties": 1, | ||
| "propertyNames": {"enum": ["windows", "macos", "linux"]}, | ||
| "additionalProperties": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "items": {"type": "string", "minLength": 1} | ||
| } | ||
| }, | ||
| "tool": {"type": "string", "minLength": 1}, | ||
| "read_only_command": {"type": ["string", "null"]}, | ||
| "destructive_native_command": {"type": ["string", "null"]}, | ||
| "manual_step": {"type": ["string", "null"]}, | ||
| "platforms": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "uniqueItems": true, | ||
| "items": {"enum": ["windows", "macos", "linux"]} | ||
| }, | ||
| "verification": { | ||
| "type": "object", | ||
| "required": ["claim", "basis", "as_of", "recheck"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "claim": {"type": "string", "minLength": 1}, | ||
| "basis": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "items": {"type": "string", "minLength": 1} | ||
| }, | ||
| "as_of": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"}, | ||
| "recheck": {"type": "string", "minLength": 1} | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
plugins/disk-hygiene/skills/clean/scripts/owner_registry.test.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #!/usr/bin/env bash | ||
| # Cross-platform contract wrapper for the owner-registry test suite. | ||
| set -euo pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
|
|
||
| # shellcheck source=../../../scripts/test-wrapper-lib.sh | ||
| source "$SCRIPT_DIR/../../../scripts/test-wrapper-lib.sh" | ||
|
|
||
| ENGINE="$SCRIPT_DIR/hygiene.py" | ||
| FLOOR="" | ||
| test_wrapper::floor_to FLOOR "$ENGINE" | ||
| if [[ -z "$FLOOR" ]]; then | ||
| echo "FAIL: could not parse MIN_PYTHON from $ENGINE" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| PYTHON="" | ||
| test_wrapper::interpreter_to PYTHON | ||
| if [[ -z "$PYTHON" ]]; then | ||
| echo "SKIP: Python ${FLOOR}+ not found" >&2 | ||
| exit 0 | ||
| fi | ||
|
|
||
| FLOOR_CHECK="" | ||
| test_wrapper::floor_check_to FLOOR_CHECK "$FLOOR" | ||
| "$PYTHON" -c "$FLOOR_CHECK" || { | ||
| echo "SKIP: Python ${FLOOR}+ required" >&2 | ||
| exit 0 | ||
| } | ||
| PYFILE="" | ||
| test_wrapper::python_file_to PYFILE "$SCRIPT_DIR/test_owner_registry.py" | ||
| "$PYTHON" -m unittest -v "$PYFILE" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.