git-slop 0.16.4

A deterministic repository token-defragmenter for humans and AI agents.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
# GitHub Action

The Git Slop Action publishes repository-health analysis without requiring a
separate package manager or toolchain in the consumer repository. It downloads
the requested prebuilt release, verifies the GitHub release and tag, schema-3
manifest, exact asset inventory, GitHub asset digests,
`SHA256SUMS`, crates.io package provenance, archive contents, and installed
`build-info`. It then runs the detector once and leaves both human and
machine-readable evidence available to later steps.

Crates provenance is verified independently of GitHub release assets. The
installer downloads the canonical static `.crate` without sending the GitHub
token, applies a 16 MiB download bound, checks its SHA-256 against the manifest,
and verifies the package's embedded clean VCS revision. Native archives and
their manifest entries are each limited to 128 MiB.

The examples below pin `v0.16.4`. Use them only after its verified GitHub
Release is public and the Marketplace listing resolves; a source tag or
documentation on `main` is not an availability proof.

## Recommended Workflow

Git Slop uses commit history for churn, age, coupling, and maintenance-pressure
signals. Check out the complete history:

```yaml
name: Repository health

on:
  pull_request:
  push:
    branches: [main]
  schedule:
    - cron: "0 9 * * *"
  workflow_dispatch:

permissions:
  contents: read

jobs:
  git-slop:
    name: Git Slop
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v7
        with:
          fetch-depth: 0

      - name: Analyze repository health
        id: git-slop
        uses: coreycoto/git-slop@v0.16.4
```

The default is advisory:

- `git-slop find` runs exactly once.
- `.slop/latest/health.md` is appended to the job summary.
- an experimental surface-area ledger is generated from tracked paths and
  appended to the job summary; pull requests compare the event's base commit
  with the analyzed head.
- at most 10 workflow annotations are emitted, preserving each finding's
  `notice`, `warning`, or `error` level.
- only `health.md` is uploaded as the `git-slop` artifact.
- the artifact is retained for 14 days.
- pull request comments are disabled.
- findings do not fail the job, but installation, shallow-history, detector, or
  stable renderer errors do. Experimental ledger unavailability remains
  advisory and is stated in the job summary.

The publication sequence is explicit:

1. Run `git-slop find` once, producing the persisted compact bundle.
2. Append the persisted `.slop/latest/health.md` to `GITHUB_STEP_SUMMARY`.
3. Generate and append a multidimensional, advisory surface-area ledger. This
   path-based evidence is separate from schema-5 detector output and policy.
4. When annotations are enabled, run `git-slop health --report
   .slop/latest/report.json --format github --max-annotations <count>` and emit
   its standard output as bounded workflow annotations. This projection does
   not rewrite `health.md` or rerun `find`.
5. Publish the selected artifact and optional pull request comment, then, only
   for `policy: enforce`, apply either native `git-slop check` absolute
   thresholds or the already-produced native comparison regression count.

The dashboard and annotation findings are advisory projections. A successful
`health` render exits 0 even when findings are present; `check` is the step that
turns configured stable thresholds into an enforcing exit status.

### Surface-Area Ledger

The Action's surface-area ledger reports observed dimensions separately: tracked
files, top-level namespaces, documentation, tests, GitHub workflows,
machine-schema files, Agent Skill definitions, CLI/distribution files, and
tooling/automation. Dimensions may overlap intentionally. The report never
combines them into a score and never changes the Action's exit status.

On a pull request, the Action resolves `pull_request.base.sha` from the trusted
event payload and compares that tree with the analyzed checkout. It records
base, head, net delta, and added/removed/retained-changed path counts. On other
events it records the absolute head dimensions. An unavailable base produces an
advisory note rather than a detector failure.

Path counts cannot prove that a command, option, config key, schema, or
compatibility promise is valuable. Use them to prompt review, then record those
semantic contracts and their evidence in the pull request's surface-area
ledger. Growth alone is not a finding.

Treat this as an expiring experiment: reassess it after 10 pull requests in the
adopting repository. Consolidate or remove it if it has not changed a reviewer
decision or if its path dimensions routinely mislead.

### Finding Levels And Annotation Bounds

The health renderer owns finding severity, and the Action streams its bounded
workflow commands without reclassifying them:

| Rendered finding | GitHub workflow command |
| --- | --- |
| `notice` | `::notice` |
| `warning` | `::warning` |
| `error` | `::error` |

`max-annotations` caps the ordered finding stream as a whole; it is not a
per-level quota. An advisory run therefore does not turn an `error` into a
warning, and `policy: enforce` does not turn a notice into an error. Enforcement
is evaluated later by `git-slop check` against the same persisted
`report.json`.

The job-summary Markdown uses **context/load bands** for token and direct-folder
load, **maintenance-pressure** for stable `slop_score`/`slop_band` evidence,
and `notice`/`warning`/`error` for rendered review severity. Surfaced folder
rows name their exact crossed boundary, provide a folder-scoped
`git-slop explain --path <folder>/` command, and preview one deterministically
highest-ranked descendant. Number grouping and decimal precision are fixed by
the Markdown projection; machine-readable JSON values are unchanged.

The Action supports GitHub-hosted Linux x64/ARM64, macOS Apple Silicon, and
Windows x64/ARM64 runners. The release must contain the matching
`git-slop-v<version>-<target>` archive, `SHA256SUMS`,
`release-manifest.json`, and the crates-backed `git-slop.rb` Formula. The
Action installs the prebuilt native archive; it never invokes Homebrew or
compiles the crate on a consumer runner. Release automation builds that archive
from the exact `.crate` bytes recorded in the manifest.

`working-directory` may point anywhere inside a worktree. Git Slop resolves
the worktree's top level and analyzes the complete tracked repository, matching
the CLI contract.

## Provenance And Installation Failures

Installation fails before repository analysis if the requested stable version
is missing, is still a draft, has an unexpected asset inventory, resolves to a
different tag revision, contains a digest mismatch, or packages unsafe archive
members. It also fails when the installed binary's `build-info` does not report
the manifest revision with `source_dirty: false`. Tag resolution uses the exact
`refs/tags/vX.Y.Z` namespace and safely peels bounded annotated tags; a
same-named branch cannot satisfy the release identity. The release workflow
alone uses an explicit internal draft-verification mode before the human
Marketplace gate; consumer runs cannot opt into an unverified draft.

On success, record these outputs when downstream attestations need the release
identity:

- `source-revision`: full 40-character commit shared by the tag and binary
- `crate-sha256`: SHA-256 of the canonical static crates.io package
- `release-manifest-sha256`: SHA-256 of the schema-3 manifest
- `asset-sha256`: SHA-256 of the selected native archive

## Enforcement

Enable the stable detector gate on the same analysis step. The Action still
publishes the report and job summary before it evaluates the gate:

```yaml
      - name: Analyze and enforce repository health
        uses: coreycoto/git-slop@v0.16.4
        with:
          policy: enforce
```

`policy: enforce` runs `git-slop check --report .slop/latest/report.json` after
annotations, artifact upload, and optional comment publication. The default
thresholds come from `.slop/config.yaml`. A consumer can explicitly override
them:

```yaml
        with:
          policy: enforce
          fail-on-context-band: critical
          fail-on-slop-band: critical
```

Exit `0` passes, exit `1` means policy findings, and exit `2` means a usage or
input error. Overlay evidence enriches the report but does not silently change
the stable detector gate.

For a regression ratchet, supply a compatible baseline and select native
regression enforcement:

```yaml
        with:
          policy: enforce
          enforcement: regression
          baseline-report: .ci/git-slop-baseline.json
          max-baseline-age-days: 30
```

The Action invokes `git-slop compare`; it has no second JavaScript comparator.
Scope, tokenizer, analyzer, config, repository, and history mismatches fail
closed. `baseline-force: "true"` records and permits exact intentional mismatches.

## Practical recipes

### Pull-request regression ratchet

Scan the exact pull-request base SHA in an isolated worktree and fail only on
native regression movement:

```yaml
permissions:
  contents: read

steps:
  - uses: actions/checkout@v7
    with:
      fetch-depth: 0
  - uses: coreycoto/git-slop@v0.16.4
    with:
      mode: regression
      baseline-ref: ${{ github.event.pull_request.base.sha }}
      artifact-contents: report
```

`fetch-depth: 0` is required for complete history and ancestor validation. Do
not use an untrusted pull-request artifact as `baseline-report` merely to avoid
fetching the base revision.

### Monorepo package scope

Scope inventory while retaining repository-wide Git evidence:

```yaml
  - uses: coreycoto/git-slop@v0.16.4
    with:
      scope: packages/api
      report-profile: compact
```

Use the same scope, tokenizer, and effective analysis configuration on both
sides of a comparison. A scope change is a compatibility change, not a passing
delta.

### Fork-safe pull requests

Keep the workflow read-only. Job summaries, bounded annotations, and artifacts
need no write token:

```yaml
permissions:
  contents: read

steps:
  - uses: actions/checkout@v7
    with:
      fetch-depth: 0
      persist-credentials: false
  - uses: coreycoto/git-slop@v0.16.4
    with:
      mode: advisory
      pr-comment: "false"
      token-cache: "false"
```

Do not move this analysis to `pull_request_target`, pass repository secrets to
fork code, or enable pull-request comments merely for presentation.

### Scheduled repository health

Use a scheduled full-history run to watch absolute state without changing pull
request policy:

```yaml
on:
  schedule:
    - cron: "23 8 * * 1"
  workflow_dispatch:

permissions:
  contents: read

jobs:
  health:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: coreycoto/git-slop@v0.16.4
        with:
          mode: advisory
          artifact-contents: report
          retention-days: 30
```

### Promotion path

Promote deliberately, using the same report contract throughout:

1. Start with `mode: advisory` to establish runtime and finding quality.
2. Add `baseline-ref` and `mode: regression` to block only new or worsened
   findings.
3. Tune committed configuration from reviewed evidence, not from a desired
   green check.
4. Move to `mode: absolute` only when every current configured breach is owned.
5. Enable `pr-comment` last, with explicit `pull-requests: write`, if comments
   materially improve review beyond summaries and annotations.

## Artifacts

`artifact-contents` always selects from a fixed allowlist; the Action never
uploads `.slop/latest/` or `.slop/runs/` as a directory.

| Value | Uploaded files |
| --- | --- |
| `summary` | `health.md` |
| `report` | `health.md`, `report.json`, plus baseline `comparison.json` |
| `full` | Report set plus `summary.md`, portable `report.html`, and enabled `report.yaml` |

For example:

```yaml
        with:
          artifact-contents: report
          retention-days: 14
```

Use `report.json` for automation. `health.md` is the stable human presentation,
while the job-summary surface ledger is explicitly experimental review
evidence; the JSON `schema_version` remains the machine compatibility boundary.

## Pull Request Comments

Job summaries and annotations require only `contents: read`. Pull request
comments are deliberately opt-in. When enabled, grant write permission and
understand that tokens on pull requests from forks may remain read-only:

```yaml
permissions:
  contents: read
  pull-requests: write

steps:
  - uses: actions/checkout@v7
    with:
      fetch-depth: 0
  - uses: coreycoto/git-slop@v0.16.4
    with:
      pr-comment: "true"
```

The Action creates or updates one marker-based comment containing health,
surface-area evidence, and any baseline summary instead of adding a new comment
on every run. Long reports are truncated in the comment; the complete health
report remains in the artifact, and the complete combined presentation remains
in the job summary.

## Inputs

| Input | Default | Purpose |
| --- | --- | --- |
| `version` | `0.16.4` | Prebuilt release version to download and verify after that release is public |
| `mode` | empty | Simple preset: `advisory`, `absolute`, or `regression`; when set, it overrides `policy` and `enforcement` only |
| `release-repository` | `coreycoto/git-slop` | Repository containing release assets |
| `target` | empty | Compatible release target override |
| `working-directory` | `.` | Directory inside the Git worktree to analyze at its top level |
| `scope` | empty | Optional repository-relative analysis scope |
| `report-profile` | `standard` | `compact`, `standard`, or `full-evidence` report semantics |
| `compression` | `none` | Optional `gzip` or `zstd` report companion |
| `token-cache` | `false` | Opt in to a content-addressed token cache persisted with `actions/cache` |
| `policy` | `advisory` | `advisory` or `enforce` |
| `enforcement` | `absolute` | Absolute thresholds or a native `regression` ratchet |
| `baseline-report` | empty | Compatible base report for annotations or enforcement |
| `baseline-ref` | empty | Git revision or SHA scanned in an isolated baseline worktree |
| `baseline-force` | `false` | Record and allow exact compatibility mismatches |
| `max-baseline-age-days` | `30` | Reject stale baseline evidence |
| `require-baseline-ancestor` | `true` | Require ancestor evidence for regression enforcement unless forced |
| `allow-shallow` | `false` | Explicitly accept incomplete shallow history |
| `fail-on-context-band` | empty | Optional check threshold override |
| `fail-on-slop-band` | empty | Optional check threshold override |
| `annotations` | `true` | Emit workflow annotations |
| `max-annotations` | `10` | Ordered annotation cap from 0 through 50; finding levels are preserved |
| `upload-artifact` | `true` | Upload the bounded artifact |
| `artifact-name` | `git-slop` | Artifact name |
| `artifact-contents` | `summary` | `summary`, `report`, or `full` |
| `retention-days` | `14` | Artifact retention from 1 through 90 days |
| `pr-comment` | `false` | Update one pull request comment |
| `github-token` | `github.token` | Optional token override |

## Outputs

This table is contract-checked against `action.yml`; adding or removing Action
metadata without updating the documentation fails repository validation.

| Output | Purpose |
| --- | --- |
| `status` | Final Action status |
| `version` | Installed Git Slop version |
| `target` | Installed Rust target triple |
| `binary-path` | Absolute verified executable path |
| `asset-sha256` | Verified native archive digest |
| `source-revision` | Full verified source revision |
| `crate-sha256` | Verified crates.io package digest |
| `release-manifest-sha256` | Verified release-manifest digest |
| `cache-hit` | Whether the verified executable was reused from `RUNNER_TOOL_CACHE` |
| `analysis-exit-code` | Exit code from the single analysis invocation |
| `mode` | Effective simple preset, or `advanced` when using policy and enforcement directly |
| `analysis-error-path` | Preserved post-analysis diagnostic path |
| `policy-exit-code` | Exit code from the selected policy gate |
| `finding-count` | Deprecated alias for `selected-policy-finding-count`; retained in v0.15.0 and scheduled for removal only in a future breaking release no earlier than 2026-11-01 |
| `health-finding-count` | Uncapped actionable head-health findings |
| `policy-finding-count` | Deprecated alias for `selected-policy-finding-count`; retained in v0.15.0 and scheduled for removal only in a future breaking release no earlier than 2026-11-01 |
| `absolute-finding-count` | Findings from the absolute head gate |
| `selected-policy-finding-count` | Findings selected by enforcement mode |
| `regression-count` | Native comparator regressions |
| `baseline-compatible` | Deprecated compatibility boolean retained in v0.15.0; use `baseline-status`; removal is limited to a future breaking release no earlier than 2026-11-01 |
| `baseline-status` | Structured baseline evaluation state |
| `comparison-path` | Native comparison JSON path |
| `comparison-error-path` | Preserved baseline-comparison diagnostic path |
| `annotation-count` | Number of emitted annotations |
| `health-path` | Absolute `health.md` path |
| `report-path` | Absolute `report.json` path |
| `report-yaml-path` | Absolute optional `report.yaml` path |
| `compressed-report-path` | Absolute optional `.gz` or `.zst` report path |
| `summary-path` | Absolute `summary.md` path |
| `html-path` | Absolute portable `report.html` path for full artifacts; otherwise empty |
| `artifact-id` | Uploaded artifact ID |
| `artifact-url` | Uploaded artifact URL |
| `artifact-digest` | Uploaded artifact digest |
| `comment-url` | Created or updated pull-request comment URL |

`cache-hit` reports whether the fully verified binary was reused from
`RUNNER_TOOL_CACHE`; release metadata, manifest, checksums, Formula, tag, and
cached binary identity are still revalidated on every run. The provenance
outputs let a consuming workflow record the same source revision and crate
digest used by crates.io, GitHub Releases, the Marketplace Action, and
Homebrew.

## GitHub Marketplace

The Action will be published from this repository's verified stable GitHub
Release under the **Code quality** and **Continuous integration** categories.
That first listing requires a maintainer to select GitHub's Marketplace checkbox
in the draft-release UI, confirm the categories and agreement, and complete
2FA. Marketplace and direct `uses: coreycoto/git-slop@v0.16.4` installation then
resolve the same root `action.yml` and release provenance. For
higher-assurance consumers, pin the Action itself to the full release commit
SHA; the Action's own nested dependencies are already pinned to full commit
SHAs.