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.
Files changed (174) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +153 -0
  3. package/dist/adapters/artifacts/adapter.d.ts +24 -0
  4. package/dist/adapters/artifacts/adapter.d.ts.map +1 -0
  5. package/dist/adapters/artifacts/adapter.js +342 -0
  6. package/dist/adapters/artifacts/adapter.js.map +1 -0
  7. package/dist/adapters/docker/adapter.d.ts +15 -0
  8. package/dist/adapters/docker/adapter.d.ts.map +1 -0
  9. package/dist/adapters/docker/adapter.js +121 -0
  10. package/dist/adapters/docker/adapter.js.map +1 -0
  11. package/dist/adapters/git/adapter.d.ts +15 -0
  12. package/dist/adapters/git/adapter.d.ts.map +1 -0
  13. package/dist/adapters/git/adapter.js +156 -0
  14. package/dist/adapters/git/adapter.js.map +1 -0
  15. package/dist/adapters/git/porcelain.d.ts +11 -0
  16. package/dist/adapters/git/porcelain.d.ts.map +1 -0
  17. package/dist/adapters/git/porcelain.js +54 -0
  18. package/dist/adapters/git/porcelain.js.map +1 -0
  19. package/dist/adapters/provider-adapter.d.ts +22 -0
  20. package/dist/adapters/provider-adapter.d.ts.map +1 -0
  21. package/dist/adapters/provider-adapter.js +178 -0
  22. package/dist/adapters/provider-adapter.js.map +1 -0
  23. package/dist/adapters/provider-specs.d.ts +16 -0
  24. package/dist/adapters/provider-specs.d.ts.map +1 -0
  25. package/dist/adapters/provider-specs.js +157 -0
  26. package/dist/adapters/provider-specs.js.map +1 -0
  27. package/dist/adapters/registry.d.ts +4 -0
  28. package/dist/adapters/registry.d.ts.map +1 -0
  29. package/dist/adapters/registry.js +28 -0
  30. package/dist/adapters/registry.js.map +1 -0
  31. package/dist/cli.d.ts +3 -0
  32. package/dist/cli.d.ts.map +1 -0
  33. package/dist/cli.js +8 -0
  34. package/dist/cli.js.map +1 -0
  35. package/dist/commands/adapters.d.ts +2 -0
  36. package/dist/commands/adapters.d.ts.map +1 -0
  37. package/dist/commands/adapters.js +17 -0
  38. package/dist/commands/adapters.js.map +1 -0
  39. package/dist/commands/apply.d.ts +15 -0
  40. package/dist/commands/apply.d.ts.map +1 -0
  41. package/dist/commands/apply.js +63 -0
  42. package/dist/commands/apply.js.map +1 -0
  43. package/dist/commands/audit.d.ts +13 -0
  44. package/dist/commands/audit.d.ts.map +1 -0
  45. package/dist/commands/audit.js +22 -0
  46. package/dist/commands/audit.js.map +1 -0
  47. package/dist/commands/plan.d.ts +12 -0
  48. package/dist/commands/plan.d.ts.map +1 -0
  49. package/dist/commands/plan.js +19 -0
  50. package/dist/commands/plan.js.map +1 -0
  51. package/dist/config/defaults.d.ts +3 -0
  52. package/dist/config/defaults.d.ts.map +1 -0
  53. package/dist/config/defaults.js +29 -0
  54. package/dist/config/defaults.js.map +1 -0
  55. package/dist/config/load.d.ts +3 -0
  56. package/dist/config/load.d.ts.map +1 -0
  57. package/dist/config/load.js +31 -0
  58. package/dist/config/load.js.map +1 -0
  59. package/dist/config/schema.d.ts +84 -0
  60. package/dist/config/schema.d.ts.map +1 -0
  61. package/dist/config/schema.js +108 -0
  62. package/dist/config/schema.js.map +1 -0
  63. package/dist/contracts/action.d.ts +109 -0
  64. package/dist/contracts/action.d.ts.map +1 -0
  65. package/dist/contracts/action.js +37 -0
  66. package/dist/contracts/action.js.map +1 -0
  67. package/dist/contracts/adapter.d.ts +21 -0
  68. package/dist/contracts/adapter.d.ts.map +1 -0
  69. package/dist/contracts/adapter.js +2 -0
  70. package/dist/contracts/adapter.js.map +1 -0
  71. package/dist/contracts/diagnostic.d.ts +21 -0
  72. package/dist/contracts/diagnostic.d.ts.map +1 -0
  73. package/dist/contracts/diagnostic.js +11 -0
  74. package/dist/contracts/diagnostic.js.map +1 -0
  75. package/dist/contracts/finding.d.ts +123 -0
  76. package/dist/contracts/finding.d.ts.map +1 -0
  77. package/dist/contracts/finding.js +35 -0
  78. package/dist/contracts/finding.js.map +1 -0
  79. package/dist/contracts/plan.d.ts +53 -0
  80. package/dist/contracts/plan.d.ts.map +1 -0
  81. package/dist/contracts/plan.js +56 -0
  82. package/dist/contracts/plan.js.map +1 -0
  83. package/dist/contracts/report.d.ts +177 -0
  84. package/dist/contracts/report.d.ts.map +1 -0
  85. package/dist/contracts/report.js +29 -0
  86. package/dist/contracts/report.js.map +1 -0
  87. package/dist/contracts/resource.d.ts +72 -0
  88. package/dist/contracts/resource.d.ts.map +1 -0
  89. package/dist/contracts/resource.js +33 -0
  90. package/dist/contracts/resource.js.map +1 -0
  91. package/dist/contracts/run.d.ts +108 -0
  92. package/dist/contracts/run.d.ts.map +1 -0
  93. package/dist/contracts/run.js +35 -0
  94. package/dist/contracts/run.js.map +1 -0
  95. package/dist/core/apply.d.ts +29 -0
  96. package/dist/core/apply.d.ts.map +1 -0
  97. package/dist/core/apply.js +120 -0
  98. package/dist/core/apply.js.map +1 -0
  99. package/dist/core/artifact-executor.d.ts +39 -0
  100. package/dist/core/artifact-executor.d.ts.map +1 -0
  101. package/dist/core/artifact-executor.js +200 -0
  102. package/dist/core/artifact-executor.js.map +1 -0
  103. package/dist/core/artifact-revalidation.d.ts +22 -0
  104. package/dist/core/artifact-revalidation.d.ts.map +1 -0
  105. package/dist/core/artifact-revalidation.js +113 -0
  106. package/dist/core/artifact-revalidation.js.map +1 -0
  107. package/dist/core/audit.d.ts +12 -0
  108. package/dist/core/audit.d.ts.map +1 -0
  109. package/dist/core/audit.js +41 -0
  110. package/dist/core/audit.js.map +1 -0
  111. package/dist/core/digest.d.ts +7 -0
  112. package/dist/core/digest.d.ts.map +1 -0
  113. package/dist/core/digest.js +21 -0
  114. package/dist/core/digest.js.map +1 -0
  115. package/dist/core/measure.d.ts +16 -0
  116. package/dist/core/measure.d.ts.map +1 -0
  117. package/dist/core/measure.js +79 -0
  118. package/dist/core/measure.js.map +1 -0
  119. package/dist/core/mount-boundaries.d.ts +21 -0
  120. package/dist/core/mount-boundaries.d.ts.map +1 -0
  121. package/dist/core/mount-boundaries.js +72 -0
  122. package/dist/core/mount-boundaries.js.map +1 -0
  123. package/dist/core/plan-verification.d.ts +10 -0
  124. package/dist/core/plan-verification.d.ts.map +1 -0
  125. package/dist/core/plan-verification.js +42 -0
  126. package/dist/core/plan-verification.js.map +1 -0
  127. package/dist/core/plan.d.ts +6 -0
  128. package/dist/core/plan.d.ts.map +1 -0
  129. package/dist/core/plan.js +40 -0
  130. package/dist/core/plan.js.map +1 -0
  131. package/dist/core/process-ownership.d.ts +27 -0
  132. package/dist/core/process-ownership.d.ts.map +1 -0
  133. package/dist/core/process-ownership.js +140 -0
  134. package/dist/core/process-ownership.js.map +1 -0
  135. package/dist/core/safety.d.ts +7 -0
  136. package/dist/core/safety.d.ts.map +1 -0
  137. package/dist/core/safety.js +50 -0
  138. package/dist/core/safety.js.map +1 -0
  139. package/dist/index.d.ts +9 -0
  140. package/dist/index.d.ts.map +1 -0
  141. package/dist/index.js +9 -0
  142. package/dist/index.js.map +1 -0
  143. package/dist/main.d.ts +4 -0
  144. package/dist/main.d.ts.map +1 -0
  145. package/dist/main.js +59 -0
  146. package/dist/main.js.map +1 -0
  147. package/dist/output.d.ts +4 -0
  148. package/dist/output.d.ts.map +1 -0
  149. package/dist/output.js +35 -0
  150. package/dist/output.js.map +1 -0
  151. package/dist/state/json-file.d.ts +4 -0
  152. package/dist/state/json-file.d.ts.map +1 -0
  153. package/dist/state/json-file.js +36 -0
  154. package/dist/state/json-file.js.map +1 -0
  155. package/dist/state/layout.d.ts +12 -0
  156. package/dist/state/layout.d.ts.map +1 -0
  157. package/dist/state/layout.js +20 -0
  158. package/dist/state/layout.js.map +1 -0
  159. package/dist/state/lock.d.ts +9 -0
  160. package/dist/state/lock.d.ts.map +1 -0
  161. package/dist/state/lock.js +93 -0
  162. package/dist/state/lock.js.map +1 -0
  163. package/dist/state/run-journal.d.ts +10 -0
  164. package/dist/state/run-journal.d.ts.map +1 -0
  165. package/dist/state/run-journal.js +57 -0
  166. package/dist/state/run-journal.js.map +1 -0
  167. package/dist/version.d.ts +2 -0
  168. package/dist/version.d.ts.map +1 -0
  169. package/dist/version.js +2 -0
  170. package/dist/version.js.map +1 -0
  171. package/package.json +73 -0
  172. package/schemas/audit.schema.json +424 -0
  173. package/schemas/plan.schema.json +184 -0
  174. 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"}