agentrinse 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/adapters/artifacts/adapter.d.ts +24 -0
- package/dist/adapters/artifacts/adapter.d.ts.map +1 -0
- package/dist/adapters/artifacts/adapter.js +342 -0
- package/dist/adapters/artifacts/adapter.js.map +1 -0
- package/dist/adapters/docker/adapter.d.ts +15 -0
- package/dist/adapters/docker/adapter.d.ts.map +1 -0
- package/dist/adapters/docker/adapter.js +121 -0
- package/dist/adapters/docker/adapter.js.map +1 -0
- package/dist/adapters/git/adapter.d.ts +15 -0
- package/dist/adapters/git/adapter.d.ts.map +1 -0
- package/dist/adapters/git/adapter.js +156 -0
- package/dist/adapters/git/adapter.js.map +1 -0
- package/dist/adapters/git/porcelain.d.ts +11 -0
- package/dist/adapters/git/porcelain.d.ts.map +1 -0
- package/dist/adapters/git/porcelain.js +54 -0
- package/dist/adapters/git/porcelain.js.map +1 -0
- package/dist/adapters/provider-adapter.d.ts +22 -0
- package/dist/adapters/provider-adapter.d.ts.map +1 -0
- package/dist/adapters/provider-adapter.js +178 -0
- package/dist/adapters/provider-adapter.js.map +1 -0
- package/dist/adapters/provider-specs.d.ts +16 -0
- package/dist/adapters/provider-specs.d.ts.map +1 -0
- package/dist/adapters/provider-specs.js +157 -0
- package/dist/adapters/provider-specs.js.map +1 -0
- package/dist/adapters/registry.d.ts +4 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +28 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/adapters.d.ts +2 -0
- package/dist/commands/adapters.d.ts.map +1 -0
- package/dist/commands/adapters.js +17 -0
- package/dist/commands/adapters.js.map +1 -0
- package/dist/commands/apply.d.ts +15 -0
- package/dist/commands/apply.d.ts.map +1 -0
- package/dist/commands/apply.js +63 -0
- package/dist/commands/apply.js.map +1 -0
- package/dist/commands/audit.d.ts +13 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +22 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/plan.d.ts +12 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +19 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/config/defaults.d.ts +3 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +29 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/load.d.ts +3 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +31 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/schema.d.ts +84 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +108 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/contracts/action.d.ts +109 -0
- package/dist/contracts/action.d.ts.map +1 -0
- package/dist/contracts/action.js +37 -0
- package/dist/contracts/action.js.map +1 -0
- package/dist/contracts/adapter.d.ts +21 -0
- package/dist/contracts/adapter.d.ts.map +1 -0
- package/dist/contracts/adapter.js +2 -0
- package/dist/contracts/adapter.js.map +1 -0
- package/dist/contracts/diagnostic.d.ts +21 -0
- package/dist/contracts/diagnostic.d.ts.map +1 -0
- package/dist/contracts/diagnostic.js +11 -0
- package/dist/contracts/diagnostic.js.map +1 -0
- package/dist/contracts/finding.d.ts +123 -0
- package/dist/contracts/finding.d.ts.map +1 -0
- package/dist/contracts/finding.js +35 -0
- package/dist/contracts/finding.js.map +1 -0
- package/dist/contracts/plan.d.ts +53 -0
- package/dist/contracts/plan.d.ts.map +1 -0
- package/dist/contracts/plan.js +56 -0
- package/dist/contracts/plan.js.map +1 -0
- package/dist/contracts/report.d.ts +177 -0
- package/dist/contracts/report.d.ts.map +1 -0
- package/dist/contracts/report.js +29 -0
- package/dist/contracts/report.js.map +1 -0
- package/dist/contracts/resource.d.ts +72 -0
- package/dist/contracts/resource.d.ts.map +1 -0
- package/dist/contracts/resource.js +33 -0
- package/dist/contracts/resource.js.map +1 -0
- package/dist/contracts/run.d.ts +108 -0
- package/dist/contracts/run.d.ts.map +1 -0
- package/dist/contracts/run.js +35 -0
- package/dist/contracts/run.js.map +1 -0
- package/dist/core/apply.d.ts +29 -0
- package/dist/core/apply.d.ts.map +1 -0
- package/dist/core/apply.js +120 -0
- package/dist/core/apply.js.map +1 -0
- package/dist/core/artifact-executor.d.ts +39 -0
- package/dist/core/artifact-executor.d.ts.map +1 -0
- package/dist/core/artifact-executor.js +200 -0
- package/dist/core/artifact-executor.js.map +1 -0
- package/dist/core/artifact-revalidation.d.ts +22 -0
- package/dist/core/artifact-revalidation.d.ts.map +1 -0
- package/dist/core/artifact-revalidation.js +113 -0
- package/dist/core/artifact-revalidation.js.map +1 -0
- package/dist/core/audit.d.ts +12 -0
- package/dist/core/audit.d.ts.map +1 -0
- package/dist/core/audit.js +41 -0
- package/dist/core/audit.js.map +1 -0
- package/dist/core/digest.d.ts +7 -0
- package/dist/core/digest.d.ts.map +1 -0
- package/dist/core/digest.js +21 -0
- package/dist/core/digest.js.map +1 -0
- package/dist/core/measure.d.ts +16 -0
- package/dist/core/measure.d.ts.map +1 -0
- package/dist/core/measure.js +79 -0
- package/dist/core/measure.js.map +1 -0
- package/dist/core/mount-boundaries.d.ts +21 -0
- package/dist/core/mount-boundaries.d.ts.map +1 -0
- package/dist/core/mount-boundaries.js +72 -0
- package/dist/core/mount-boundaries.js.map +1 -0
- package/dist/core/plan-verification.d.ts +10 -0
- package/dist/core/plan-verification.d.ts.map +1 -0
- package/dist/core/plan-verification.js +42 -0
- package/dist/core/plan-verification.js.map +1 -0
- package/dist/core/plan.d.ts +6 -0
- package/dist/core/plan.d.ts.map +1 -0
- package/dist/core/plan.js +40 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/core/process-ownership.d.ts +27 -0
- package/dist/core/process-ownership.d.ts.map +1 -0
- package/dist/core/process-ownership.js +140 -0
- package/dist/core/process-ownership.js.map +1 -0
- package/dist/core/safety.d.ts +7 -0
- package/dist/core/safety.d.ts.map +1 -0
- package/dist/core/safety.js +50 -0
- package/dist/core/safety.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +59 -0
- package/dist/main.js.map +1 -0
- package/dist/output.d.ts +4 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +35 -0
- package/dist/output.js.map +1 -0
- package/dist/state/json-file.d.ts +4 -0
- package/dist/state/json-file.d.ts.map +1 -0
- package/dist/state/json-file.js +36 -0
- package/dist/state/json-file.js.map +1 -0
- package/dist/state/layout.d.ts +12 -0
- package/dist/state/layout.d.ts.map +1 -0
- package/dist/state/layout.js +20 -0
- package/dist/state/layout.js.map +1 -0
- package/dist/state/lock.d.ts +9 -0
- package/dist/state/lock.d.ts.map +1 -0
- package/dist/state/lock.js +93 -0
- package/dist/state/lock.js.map +1 -0
- package/dist/state/run-journal.d.ts +10 -0
- package/dist/state/run-journal.d.ts.map +1 -0
- package/dist/state/run-journal.js +57 -0
- package/dist/state/run-journal.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +73 -0
- package/schemas/audit.schema.json +424 -0
- package/schemas/plan.schema.json +184 -0
- package/schemas/run.schema.json +161 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vincent Koc
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# AgentRinse
|
|
2
|
+
|
|
3
|
+
Safe, local-first cleanup for agentic development.
|
|
4
|
+
|
|
5
|
+
AgentRinse inventories agent state and developer residue, explains why
|
|
6
|
+
resources are protected, produces content-addressed cleanup plans, and applies
|
|
7
|
+
only actions that still pass every safety check.
|
|
8
|
+
|
|
9
|
+
> [!IMPORTANT]
|
|
10
|
+
> `0.0.0` is a package-reservation release. It is not supported for cleanup
|
|
11
|
+
> against real developer state. The first supported release will be `0.1.0`.
|
|
12
|
+
|
|
13
|
+
## Reservation Release
|
|
14
|
+
|
|
15
|
+
The implemented mutation boundary under development is intentionally narrow:
|
|
16
|
+
|
|
17
|
+
- removes only exact rebuildable artifact directories declared in config
|
|
18
|
+
- supports `node_modules`, `dist`, `dist-runtime`, `build`, `.next`, `.turbo`,
|
|
19
|
+
`.cache`, `coverage`, `target`, and `.venv`
|
|
20
|
+
- revalidates path, realpath, inode, device, recursive metadata fingerprint,
|
|
21
|
+
newest descendant mtime, measured bytes, configured scope, current working
|
|
22
|
+
directory, and process ownership after acquiring the apply lock
|
|
23
|
+
- rejects artifact roots and descendants that cross filesystem mount
|
|
24
|
+
boundaries
|
|
25
|
+
- rejects sockets, pipes, devices, and other non-regular filesystem entries
|
|
26
|
+
- rechecks size, age, and plan expiration immediately before each mutation
|
|
27
|
+
- atomically renames an artifact to a same-parent tombstone before recursive
|
|
28
|
+
removal, repeats fingerprint and process checks on the isolated tree, and
|
|
29
|
+
performs a final synchronous inode check at the deletion boundary
|
|
30
|
+
- journals every transition and records the recovery path for partial actions
|
|
31
|
+
|
|
32
|
+
Codex, Claude Code, Cursor, GitHub Copilot CLI, Zed, OpenCode, Grok Build, Git,
|
|
33
|
+
and Docker are report-only. Provider state, worktrees, images, containers,
|
|
34
|
+
volumes, branches, stashes, credentials, configuration, plugins, skills, and
|
|
35
|
+
memories are not cleanup targets.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
Do not install `0.0.0` for operational cleanup. Maintainers may verify the
|
|
40
|
+
reservation package with:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install --global agentrinse
|
|
44
|
+
agentrinse --version
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The command must report `0.0.0`. Node.js 22 or newer is required.
|
|
48
|
+
|
|
49
|
+
## Configure
|
|
50
|
+
|
|
51
|
+
Artifact cleanup is disabled until project roots are explicitly declared.
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"schemaVersion": 1,
|
|
56
|
+
"artifacts": {
|
|
57
|
+
"projects": [
|
|
58
|
+
{
|
|
59
|
+
"root": "/absolute/path/to/project",
|
|
60
|
+
"names": ["node_modules", "dist", ".cache"]
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"minAgeMinutes": 1440,
|
|
64
|
+
"minBytes": 67108864,
|
|
65
|
+
"processCheck": "required"
|
|
66
|
+
},
|
|
67
|
+
"plan": {
|
|
68
|
+
"ttlMinutes": 30,
|
|
69
|
+
"maxRisk": "safe"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Project roots must be unique canonical absolute real directories inside the
|
|
75
|
+
audited home; paths reached through symlinked ancestors are rejected. Artifact
|
|
76
|
+
targets cannot overlap. AgentRinse never discovers arbitrary projects or
|
|
77
|
+
expands wildcards.
|
|
78
|
+
|
|
79
|
+
## Use
|
|
80
|
+
|
|
81
|
+
Audit and save immutable evidence:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
agentrinse audit \
|
|
85
|
+
--home "$HOME" \
|
|
86
|
+
--config agentrinse.json \
|
|
87
|
+
--json \
|
|
88
|
+
--output audit.json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Create a bounded cleanup plan:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
agentrinse plan \
|
|
95
|
+
--audit audit.json \
|
|
96
|
+
--config agentrinse.json \
|
|
97
|
+
--output plan.json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Review `plan.json`, then apply it:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
agentrinse apply \
|
|
104
|
+
--plan plan.json \
|
|
105
|
+
--config agentrinse.json \
|
|
106
|
+
--yes
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Without `--yes`, apply requires an interactive terminal confirmation. JSON
|
|
110
|
+
output requires `--yes` so prompts can never corrupt stdout. A plan is rejected
|
|
111
|
+
when it expires, changes, no longer matches the config, or contains inconsistent
|
|
112
|
+
action totals. An action whose authorization expires during a run is recorded
|
|
113
|
+
as `skipped-stale`, not deleted.
|
|
114
|
+
|
|
115
|
+
Run journals are stored under `$XDG_STATE_HOME/agentrinse/runs` or
|
|
116
|
+
`$HOME/.local/state/agentrinse/runs`. Use `--state-dir` to select another
|
|
117
|
+
location.
|
|
118
|
+
|
|
119
|
+
## Safety
|
|
120
|
+
|
|
121
|
+
- discovery and planning never mutate
|
|
122
|
+
- unknown state is protected
|
|
123
|
+
- symlinks are not followed
|
|
124
|
+
- no process is killed
|
|
125
|
+
- no `sudo`
|
|
126
|
+
- no Docker volume deletion
|
|
127
|
+
- no generic `--force`
|
|
128
|
+
- no wildcard deletion
|
|
129
|
+
- one apply run holds the exclusive state lock
|
|
130
|
+
- AgentRinse never removes its own working directory, lock, or journal
|
|
131
|
+
|
|
132
|
+
AgentRinse fails closed around ordinary concurrent developer tools. It does not
|
|
133
|
+
claim isolation from a hostile process already running as the same OS user;
|
|
134
|
+
that process can directly alter the user's files and AgentRinse state.
|
|
135
|
+
|
|
136
|
+
See `docs/safety.md` for the complete mutation contract.
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
pnpm install
|
|
142
|
+
pnpm check
|
|
143
|
+
pnpm smoke
|
|
144
|
+
pnpm pack:check
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Development, tests, smoke runs, and destructive proof use temporary synthetic
|
|
148
|
+
homes only. Never point `0.0.0` or an unreleased development build at a
|
|
149
|
+
workstation home.
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentRinseConfig } from "../../config/schema.js";
|
|
2
|
+
import type { AuditAdapter, AuditContext, CollectionResult } from "../../contracts/adapter.js";
|
|
3
|
+
import type { Finding } from "../../contracts/finding.js";
|
|
4
|
+
import type { AdapterProbe } from "../../contracts/report.js";
|
|
5
|
+
import type { ResourceSnapshot } from "../../contracts/resource.js";
|
|
6
|
+
import { type MountBoundaryResult } from "../../core/mount-boundaries.js";
|
|
7
|
+
import { type ProcessOwnershipResult } from "../../core/process-ownership.js";
|
|
8
|
+
type ArtifactOptions = AgentRinseConfig["artifacts"] & AgentRinseConfig["audit"];
|
|
9
|
+
export type ProcessProbe = (path: string) => Promise<ProcessOwnershipResult>;
|
|
10
|
+
export type MountProbe = (path: string) => Promise<MountBoundaryResult>;
|
|
11
|
+
export declare class ArtifactAuditAdapter implements AuditAdapter {
|
|
12
|
+
private readonly options;
|
|
13
|
+
private readonly processProbe;
|
|
14
|
+
private readonly mountProbe;
|
|
15
|
+
readonly id = "artifacts";
|
|
16
|
+
constructor(options: ArtifactOptions, processProbe?: ProcessProbe, mountProbe?: MountProbe);
|
|
17
|
+
private validProjects;
|
|
18
|
+
probe(context: AuditContext): Promise<AdapterProbe>;
|
|
19
|
+
collect(context: AuditContext, probe: AdapterProbe): Promise<CollectionResult>;
|
|
20
|
+
classify(context: AuditContext, resource: ResourceSnapshot): Promise<Finding>;
|
|
21
|
+
private actionFor;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/artifacts/adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG/F,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,OAAO,EAAuB,KAAK,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AAGzC,KAAK,eAAe,GAAG,gBAAgB,CAAC,WAAW,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAEjF,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAC7E,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAiBxE,qBAAa,oBAAqB,YAAW,YAAY;IAIrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAL7B,QAAQ,CAAC,EAAE,eAAe;IAE1B,YACmB,OAAO,EAAE,eAAe,EACxB,YAAY,GAAE,YAAqC,EACnD,UAAU,GAAE,UAAgC,EAC3D;YAEU,aAAa;IAqDrB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBxD;IAEK,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6GnF;IAEK,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CA6IlF;IAED,OAAO,CAAC,SAAS;CAyBlB"}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { lstat, realpath } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { artifactNameSchema } from "../../contracts/action.js";
|
|
4
|
+
import { sha256 } from "../../core/digest.js";
|
|
5
|
+
import { measurePath } from "../../core/measure.js";
|
|
6
|
+
import { findMountBoundaries } from "../../core/mount-boundaries.js";
|
|
7
|
+
import { findProcessesUsingPath, } from "../../core/process-ownership.js";
|
|
8
|
+
import { isPathInside } from "../../core/safety.js";
|
|
9
|
+
function isMissing(error) {
|
|
10
|
+
return (error instanceof Error && "code" in error && error.code === "ENOENT");
|
|
11
|
+
}
|
|
12
|
+
function rootEvidence(context, code, detail) {
|
|
13
|
+
return {
|
|
14
|
+
code,
|
|
15
|
+
source: "artifacts",
|
|
16
|
+
observedAt: context.now.toISOString(),
|
|
17
|
+
detail,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export class ArtifactAuditAdapter {
|
|
21
|
+
options;
|
|
22
|
+
processProbe;
|
|
23
|
+
mountProbe;
|
|
24
|
+
id = "artifacts";
|
|
25
|
+
constructor(options, processProbe = findProcessesUsingPath, mountProbe = findMountBoundaries) {
|
|
26
|
+
this.options = options;
|
|
27
|
+
this.processProbe = processProbe;
|
|
28
|
+
this.mountProbe = mountProbe;
|
|
29
|
+
}
|
|
30
|
+
async validProjects(context) {
|
|
31
|
+
const roots = [];
|
|
32
|
+
const diagnostics = [];
|
|
33
|
+
for (const project of this.options.projects) {
|
|
34
|
+
const root = resolve(project.root);
|
|
35
|
+
if (!isPathInside(context.home, root)) {
|
|
36
|
+
diagnostics.push({
|
|
37
|
+
severity: "error",
|
|
38
|
+
code: "ARTIFACT_PROJECT_OUTSIDE_HOME",
|
|
39
|
+
message: `Configured project is outside the audited home: ${root}`,
|
|
40
|
+
adapter: this.id,
|
|
41
|
+
});
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const stats = await lstat(root);
|
|
46
|
+
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
47
|
+
diagnostics.push({
|
|
48
|
+
severity: "error",
|
|
49
|
+
code: "ARTIFACT_PROJECT_INVALID",
|
|
50
|
+
message: `Configured project must be a real directory: ${root}`,
|
|
51
|
+
adapter: this.id,
|
|
52
|
+
});
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if ((await realpath(root)) !== root) {
|
|
56
|
+
diagnostics.push({
|
|
57
|
+
severity: "error",
|
|
58
|
+
code: "ARTIFACT_PROJECT_NONCANONICAL",
|
|
59
|
+
message: `Configured project path must not contain symlink aliases: ${root}`,
|
|
60
|
+
adapter: this.id,
|
|
61
|
+
});
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
roots.push(root);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
diagnostics.push({
|
|
68
|
+
severity: isMissing(error) ? "warning" : "error",
|
|
69
|
+
code: isMissing(error) ? "ARTIFACT_PROJECT_MISSING" : "ARTIFACT_PROJECT_UNREADABLE",
|
|
70
|
+
message: error instanceof Error ? error.message : String(error),
|
|
71
|
+
adapter: this.id,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { roots, diagnostics };
|
|
76
|
+
}
|
|
77
|
+
async probe(context) {
|
|
78
|
+
const validation = await this.validProjects(context);
|
|
79
|
+
if (validation.roots.length === 0) {
|
|
80
|
+
return {
|
|
81
|
+
adapter: this.id,
|
|
82
|
+
status: this.options.projects.length === 0 ? "disabled" : "degraded",
|
|
83
|
+
detail: this.options.projects.length === 0
|
|
84
|
+
? "No artifact project roots configured"
|
|
85
|
+
: "No configured artifact project root is safe to inspect",
|
|
86
|
+
diagnostics: validation.diagnostics,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
adapter: this.id,
|
|
91
|
+
status: validation.diagnostics.length === 0 ? "available" : "degraded",
|
|
92
|
+
root: context.home,
|
|
93
|
+
detail: `${validation.roots.length} explicit artifact project root(s) available`,
|
|
94
|
+
diagnostics: validation.diagnostics,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async collect(context, probe) {
|
|
98
|
+
if (!["available", "degraded"].includes(probe.status)) {
|
|
99
|
+
return { resources: [], diagnostics: [] };
|
|
100
|
+
}
|
|
101
|
+
const validation = await this.validProjects(context);
|
|
102
|
+
const resources = [];
|
|
103
|
+
const diagnostics = [];
|
|
104
|
+
for (const project of this.options.projects) {
|
|
105
|
+
const projectRoot = resolve(project.root);
|
|
106
|
+
if (!validation.roots.includes(projectRoot)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const projectStats = await lstat(projectRoot);
|
|
110
|
+
for (const name of project.names) {
|
|
111
|
+
context.signal?.throwIfAborted();
|
|
112
|
+
const path = resolve(join(projectRoot, name));
|
|
113
|
+
if (!isPathInside(projectRoot, path)) {
|
|
114
|
+
diagnostics.push({
|
|
115
|
+
severity: "error",
|
|
116
|
+
code: "ARTIFACT_PATH_ESCAPE",
|
|
117
|
+
message: `Artifact path escaped its project root: ${path}`,
|
|
118
|
+
adapter: this.id,
|
|
119
|
+
});
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const stats = await lstat(path);
|
|
124
|
+
const isDirectory = stats.isDirectory();
|
|
125
|
+
const isSymlink = stats.isSymbolicLink();
|
|
126
|
+
const measurement = isDirectory && !isSymlink && this.options.measureBytes
|
|
127
|
+
? await measurePath(path, {
|
|
128
|
+
maxEntries: this.options.maxEntries,
|
|
129
|
+
...(context.signal === undefined ? {} : { signal: context.signal }),
|
|
130
|
+
})
|
|
131
|
+
: undefined;
|
|
132
|
+
const ownership = isDirectory && !isSymlink
|
|
133
|
+
? await this.processProbe(path)
|
|
134
|
+
: {
|
|
135
|
+
status: "unknown",
|
|
136
|
+
matches: [],
|
|
137
|
+
reason: "resource is not a real directory",
|
|
138
|
+
};
|
|
139
|
+
const mounts = isDirectory && !isSymlink
|
|
140
|
+
? await this.mountProbe(path)
|
|
141
|
+
: {
|
|
142
|
+
status: "unknown",
|
|
143
|
+
paths: [],
|
|
144
|
+
reason: "resource is not a real directory",
|
|
145
|
+
};
|
|
146
|
+
const canonicalKey = `artifacts:build-artifact:${path}`;
|
|
147
|
+
resources.push({
|
|
148
|
+
resource: {
|
|
149
|
+
id: `artifacts:build-artifact:${sha256(canonicalKey)}`,
|
|
150
|
+
adapter: this.id,
|
|
151
|
+
kind: "build-artifact",
|
|
152
|
+
canonicalKey,
|
|
153
|
+
displayName: name,
|
|
154
|
+
path,
|
|
155
|
+
},
|
|
156
|
+
observedAt: context.now.toISOString(),
|
|
157
|
+
exists: true,
|
|
158
|
+
...(measurement === undefined ? {} : { measuredBytes: measurement.bytes }),
|
|
159
|
+
facts: {
|
|
160
|
+
projectRoot,
|
|
161
|
+
name,
|
|
162
|
+
device: stats.dev,
|
|
163
|
+
inode: stats.ino,
|
|
164
|
+
mtimeMs: stats.mtimeMs,
|
|
165
|
+
newestMtimeMs: measurement?.newestMtimeMs ?? stats.mtimeMs,
|
|
166
|
+
fingerprint: measurement?.fingerprint,
|
|
167
|
+
ageMinutes: Math.max(0, (context.now.getTime() - (measurement?.newestMtimeMs ?? stats.mtimeMs)) / 60_000),
|
|
168
|
+
isDirectory,
|
|
169
|
+
isSymlink,
|
|
170
|
+
measurementTruncated: measurement?.truncated ?? false,
|
|
171
|
+
specialEntries: measurement?.specialEntries ?? 0,
|
|
172
|
+
mountBoundaries: measurement?.mountBoundaries ?? 0,
|
|
173
|
+
isMountRoot: stats.dev !== projectStats.dev,
|
|
174
|
+
entries: measurement?.entries,
|
|
175
|
+
processOwnership: ownership,
|
|
176
|
+
mountBoundaryStatus: mounts.status,
|
|
177
|
+
mountBoundaryPaths: mounts.paths,
|
|
178
|
+
mountBoundaryReason: mounts.status === "unknown" ? mounts.reason : undefined,
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (!isMissing(error)) {
|
|
184
|
+
diagnostics.push({
|
|
185
|
+
severity: "warning",
|
|
186
|
+
code: "ARTIFACT_INSPECTION_FAILED",
|
|
187
|
+
message: error instanceof Error ? error.message : String(error),
|
|
188
|
+
adapter: this.id,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return { resources, diagnostics };
|
|
195
|
+
}
|
|
196
|
+
async classify(context, resource) {
|
|
197
|
+
const facts = resource.facts;
|
|
198
|
+
const roots = [];
|
|
199
|
+
const warnings = [];
|
|
200
|
+
let state = "eligible";
|
|
201
|
+
let confidence = "certain";
|
|
202
|
+
if (facts.isSymlink === true) {
|
|
203
|
+
state = "blocked";
|
|
204
|
+
confidence = "certain";
|
|
205
|
+
warnings.push({
|
|
206
|
+
severity: "warning",
|
|
207
|
+
code: "ARTIFACT_SYMLINK_BLOCKED",
|
|
208
|
+
message: "Artifact symlinks are never cleanup candidates.",
|
|
209
|
+
adapter: this.id,
|
|
210
|
+
resourceId: resource.resource.id,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
else if (facts.isDirectory !== true) {
|
|
214
|
+
state = "blocked";
|
|
215
|
+
confidence = "certain";
|
|
216
|
+
warnings.push({
|
|
217
|
+
severity: "warning",
|
|
218
|
+
code: "ARTIFACT_NOT_DIRECTORY",
|
|
219
|
+
message: "Only declared artifact directories are supported.",
|
|
220
|
+
adapter: this.id,
|
|
221
|
+
resourceId: resource.resource.id,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
else if (facts.measurementTruncated === true) {
|
|
225
|
+
state = "blocked";
|
|
226
|
+
confidence = "unknown";
|
|
227
|
+
warnings.push({
|
|
228
|
+
severity: "warning",
|
|
229
|
+
code: "ARTIFACT_MEASUREMENT_TRUNCATED",
|
|
230
|
+
message: "The entry budget was exhausted before measurement completed.",
|
|
231
|
+
adapter: this.id,
|
|
232
|
+
resourceId: resource.resource.id,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
else if (typeof facts.specialEntries === "number" && facts.specialEntries > 0) {
|
|
236
|
+
state = "blocked";
|
|
237
|
+
confidence = "certain";
|
|
238
|
+
warnings.push({
|
|
239
|
+
severity: "warning",
|
|
240
|
+
code: "ARTIFACT_SPECIAL_ENTRY",
|
|
241
|
+
message: "Artifact cleanup only supports directories, regular files, and skipped symlinks.",
|
|
242
|
+
adapter: this.id,
|
|
243
|
+
resourceId: resource.resource.id,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
else if (facts.isMountRoot === true ||
|
|
247
|
+
facts.mountBoundaryStatus === "blocked" ||
|
|
248
|
+
(typeof facts.mountBoundaries === "number" && facts.mountBoundaries > 0)) {
|
|
249
|
+
state = "blocked";
|
|
250
|
+
confidence = "certain";
|
|
251
|
+
warnings.push({
|
|
252
|
+
severity: "warning",
|
|
253
|
+
code: "ARTIFACT_MOUNT_BOUNDARY",
|
|
254
|
+
message: "Artifact cleanup never crosses a filesystem mount boundary.",
|
|
255
|
+
adapter: this.id,
|
|
256
|
+
resourceId: resource.resource.id,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
else if (facts.mountBoundaryStatus !== "clear") {
|
|
260
|
+
state = "blocked";
|
|
261
|
+
confidence = "unknown";
|
|
262
|
+
warnings.push({
|
|
263
|
+
severity: "warning",
|
|
264
|
+
code: "ARTIFACT_MOUNT_INSPECTION_UNKNOWN",
|
|
265
|
+
message: "Filesystem mount boundaries could not be proven absent.",
|
|
266
|
+
adapter: this.id,
|
|
267
|
+
resourceId: resource.resource.id,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
else if (resource.measuredBytes === undefined ||
|
|
271
|
+
resource.measuredBytes < this.options.minBytes) {
|
|
272
|
+
state = "protected";
|
|
273
|
+
roots.push(rootEvidence(context, "artifact-below-size-threshold", `Artifact is smaller than ${this.options.minBytes} bytes.`));
|
|
274
|
+
}
|
|
275
|
+
else if (typeof facts.ageMinutes !== "number" ||
|
|
276
|
+
facts.ageMinutes < this.options.minAgeMinutes) {
|
|
277
|
+
state = "protected";
|
|
278
|
+
roots.push(rootEvidence(context, "recent-resource", `Artifact is newer than ${this.options.minAgeMinutes} minutes.`));
|
|
279
|
+
}
|
|
280
|
+
const ownership = facts.processOwnership;
|
|
281
|
+
if (state === "eligible" && ownership?.status === "busy") {
|
|
282
|
+
state = "protected";
|
|
283
|
+
roots.push(rootEvidence(context, "live-process", "A same-user process owns a cwd or file descriptor under the artifact."));
|
|
284
|
+
}
|
|
285
|
+
else if (state === "eligible" && ownership?.status !== "idle") {
|
|
286
|
+
state = "blocked";
|
|
287
|
+
confidence = "unknown";
|
|
288
|
+
warnings.push({
|
|
289
|
+
severity: "warning",
|
|
290
|
+
code: "PROCESS_OWNERSHIP_UNKNOWN",
|
|
291
|
+
message: "Process ownership could not be proven idle.",
|
|
292
|
+
adapter: this.id,
|
|
293
|
+
resourceId: resource.resource.id,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
const candidateActions = state === "eligible" ? [this.actionFor(resource)] : [];
|
|
297
|
+
return {
|
|
298
|
+
schemaVersion: 1,
|
|
299
|
+
findingId: `${resource.resource.id}:${sha256(context.auditId)}`,
|
|
300
|
+
auditId: context.auditId,
|
|
301
|
+
observedAt: context.now.toISOString(),
|
|
302
|
+
resource: resource.resource,
|
|
303
|
+
state,
|
|
304
|
+
confidence,
|
|
305
|
+
roots,
|
|
306
|
+
facts,
|
|
307
|
+
candidateActions,
|
|
308
|
+
...(resource.measuredBytes === undefined
|
|
309
|
+
? {}
|
|
310
|
+
: {
|
|
311
|
+
measuredBytes: resource.measuredBytes,
|
|
312
|
+
estimatedReclaimBytes: state === "eligible" ? resource.measuredBytes : 0,
|
|
313
|
+
}),
|
|
314
|
+
warnings,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
actionFor(resource) {
|
|
318
|
+
const facts = resource.facts;
|
|
319
|
+
const target = {
|
|
320
|
+
path: resource.resource.path,
|
|
321
|
+
projectRoot: String(facts.projectRoot),
|
|
322
|
+
name: artifactNameSchema.parse(facts.name),
|
|
323
|
+
device: Number(facts.device),
|
|
324
|
+
inode: Number(facts.inode),
|
|
325
|
+
mtimeMs: Number(facts.mtimeMs),
|
|
326
|
+
measuredBytes: resource.measuredBytes,
|
|
327
|
+
newestMtimeMs: Number(facts.newestMtimeMs),
|
|
328
|
+
fingerprint: String(facts.fingerprint),
|
|
329
|
+
};
|
|
330
|
+
return {
|
|
331
|
+
actionId: `artifacts.remove:${sha256(JSON.stringify(target))}`,
|
|
332
|
+
type: "artifacts.remove",
|
|
333
|
+
adapter: "artifacts",
|
|
334
|
+
resourceId: resource.resource.id,
|
|
335
|
+
risk: "safe",
|
|
336
|
+
description: `Remove rebuildable ${target.name} from ${target.projectRoot}`,
|
|
337
|
+
expectedReclaimBytes: target.measuredBytes,
|
|
338
|
+
target,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/adapters/artifacts/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AuditAdapter, AuditContext, CollectionResult } from "../../contracts/adapter.js";
|
|
2
|
+
import type { Finding } from "../../contracts/finding.js";
|
|
3
|
+
import type { AdapterProbe } from "../../contracts/report.js";
|
|
4
|
+
import type { ResourceSnapshot } from "../../contracts/resource.js";
|
|
5
|
+
export type DockerRunner = (args: string[]) => Promise<string>;
|
|
6
|
+
export declare class DockerAuditAdapter implements AuditAdapter {
|
|
7
|
+
private readonly runDocker;
|
|
8
|
+
readonly id = "docker";
|
|
9
|
+
constructor(runDocker?: DockerRunner);
|
|
10
|
+
probe(_context: AuditContext): Promise<AdapterProbe>;
|
|
11
|
+
collect(context: AuditContext, probe: AdapterProbe): Promise<CollectionResult>;
|
|
12
|
+
private toResource;
|
|
13
|
+
classify(context: AuditContext, resource: ResourceSnapshot): Promise<Finding>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/docker/adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC/F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAKlF,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAwB/D,qBAAa,kBAAmB,YAAW,YAAY;IAGzC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,QAAQ,CAAC,EAAE,YAAY;IAEvB,YAA6B,SAAS,GAAE,YAAkC,EAAI;IAExE,KAAK,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CA2BzD;IAEK,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuBnF;IAED,OAAO,CAAC,UAAU;IAiCZ,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBlF;CACF"}
|