oss-signal 0.3.0 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ - Added a maintainer playbook for audit-to-issue, PR, CI gate, and SARIF workflows.
6
+ - Added a documented release process and tag-triggered release workflow with npm dry-run verification.
7
+
8
+ ## 0.4.0
9
+
10
+ - Added SARIF output for GitHub Code Scanning and other security dashboards.
11
+ - Added Action support for `format: sarif`.
12
+
3
13
  ## 0.3.0
4
14
 
5
15
  - Added GitHub Actions step summary output for readable workflow reports.
package/README.md CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  [![CI](https://github.com/SalmonPlays/oss-signal/actions/workflows/ci.yml/badge.svg)](https://github.com/SalmonPlays/oss-signal/actions/workflows/ci.yml)
4
4
  [![Repository health](https://github.com/SalmonPlays/oss-signal/actions/workflows/repository-health.yml/badge.svg)](https://github.com/SalmonPlays/oss-signal/actions/workflows/repository-health.yml)
5
+ [![GitHub release](https://img.shields.io/github/v/release/SalmonPlays/oss-signal.svg)](https://github.com/SalmonPlays/oss-signal/releases/latest)
5
6
  [![npm version](https://img.shields.io/npm/v/oss-signal.svg)](https://www.npmjs.com/package/oss-signal)
6
7
  [![npm downloads](https://img.shields.io/npm/dm/oss-signal.svg)](https://www.npmjs.com/package/oss-signal)
7
8
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
8
9
 
9
10
  `oss-signal` is a dependency-light CLI for auditing open-source repository maintenance readiness.
10
11
 
11
- It checks the files and automation that reduce maintainer load: README, license, contributing guide, security policy, CI, tests, issue templates, pull request templates, Dependabot, and release notes. The output is a score plus concrete next steps in Markdown or JSON.
12
+ It checks the files and automation that reduce maintainer load: README, license, contributing guide, security policy, CI, tests, issue templates, pull request templates, Dependabot, and release notes. The output is a score plus concrete next steps in Markdown, JSON, or SARIF.
12
13
 
13
14
  ![oss-signal example output](docs/assets/terminal-report.svg)
14
15
 
@@ -24,12 +25,20 @@ Open-source projects often fail quietly because the maintainer workflow is undoc
24
25
  - Foundations and working groups can compare repository hygiene across many projects.
25
26
  - CI maintainers can add it as a GitHub Action, show the score in the workflow summary, and publish the report as an artifact.
26
27
 
28
+ See [docs/maintainer-playbook.md](docs/maintainer-playbook.md) for a concrete maintainer workflow from audit to issue, PR, CI gate, and Code Scanning evidence.
29
+
27
30
  ## Install
28
31
 
29
32
  ```bash
30
33
  npm install --global oss-signal
31
34
  ```
32
35
 
36
+ Try it without installing:
37
+
38
+ ```bash
39
+ npx oss-signal SalmonPlays/oss-signal
40
+ ```
41
+
33
42
  For local development:
34
43
 
35
44
  ```bash
@@ -66,6 +75,12 @@ Use JSON in automation:
66
75
  oss-signal . --format json --fail-under 80
67
76
  ```
68
77
 
78
+ Write SARIF for GitHub Code Scanning or other dashboards:
79
+
80
+ ```bash
81
+ oss-signal . --format sarif --output oss-signal.sarif
82
+ ```
83
+
69
84
  Generate a report that can be attached to an issue:
70
85
 
71
86
  ```bash
@@ -82,11 +97,13 @@ oss-signal . --format markdown --output docs/maintainer-readiness.md
82
97
 
83
98
  See [docs/rules.md](docs/rules.md) for rule details and scoring weights.
84
99
 
100
+ SARIF output reports failed maintainer-readiness checks as warning-level results. This lets teams upload the audit to code scanning dashboards while keeping the Markdown report available for maintainers.
101
+
85
102
  For GitHub URL audits, `oss-signal` reads the repository file tree through the GitHub API and also uses GitHub's community profile signal when available. This lets it detect organization-level files such as a shared code of conduct.
86
103
 
87
104
  ## Real Output
88
105
 
89
- This repository audits itself at **100/100 (A)**:
106
+ This repository audits itself at **100/100 (A)** and dogfoods the public GitHub Action:
90
107
 
91
108
  ```text
92
109
  Score: 100/100 (A)
@@ -97,7 +114,9 @@ Summary:
97
114
  - Total checks: 15
98
115
  ```
99
116
 
100
- See [docs/self-audit.md](docs/self-audit.md) for the full local self-audit report and [docs/examples/github-url-report.md](docs/examples/github-url-report.md) for the GitHub URL audit output.
117
+ See [docs/self-audit.md](docs/self-audit.md) for the full local self-audit report, [docs/examples/github-url-report.md](docs/examples/github-url-report.md) for the GitHub URL audit output, and [docs/examples/self-audit.sarif](docs/examples/self-audit.sarif) for SARIF output.
118
+
119
+ The [Repository health workflow](.github/workflows/repository-health.yml) runs `SalmonPlays/oss-signal@v0.4.0`, uploads the Markdown report as an artifact, and uploads SARIF to GitHub Code Scanning on non-PR runs.
101
120
 
102
121
  ## Field Audits
103
122
 
@@ -138,7 +157,7 @@ oss-signal . --fail-under 80
138
157
  Add `oss-signal` directly to a GitHub Actions workflow:
139
158
 
140
159
  ```yaml
141
- - uses: SalmonPlays/oss-signal@v0.3.0
160
+ - uses: SalmonPlays/oss-signal@v0.4.0
142
161
  id: oss-signal
143
162
  with:
144
163
  fail-under: "80"
@@ -166,7 +185,7 @@ jobs:
166
185
  runs-on: ubuntu-latest
167
186
  steps:
168
187
  - uses: actions/checkout@v4
169
- - uses: SalmonPlays/oss-signal@v0.3.0
188
+ - uses: SalmonPlays/oss-signal@v0.4.0
170
189
  id: oss-signal
171
190
  with:
172
191
  fail-under: "80"
@@ -178,9 +197,28 @@ jobs:
178
197
  path: oss-signal-report.md
179
198
  ```
180
199
 
181
- See [docs/examples/github-action-workflow.yml](docs/examples/github-action-workflow.yml) for a copyable workflow.
200
+ See [docs/examples/github-action-workflow.yml](docs/examples/github-action-workflow.yml) for a copyable workflow and [docs/examples/github-code-scanning-workflow.yml](docs/examples/github-code-scanning-workflow.yml) for a workflow that uploads SARIF to GitHub Code Scanning.
201
+
202
+ Upload SARIF to GitHub Code Scanning:
203
+
204
+ ```yaml
205
+ permissions:
206
+ contents: read
207
+ security-events: write
208
+
209
+ steps:
210
+ - uses: actions/checkout@v4
211
+ - uses: SalmonPlays/oss-signal@v0.4.0
212
+ with:
213
+ format: sarif
214
+ output: oss-signal.sarif
215
+ summary: "true"
216
+ - uses: github/codeql-action/upload-sarif@v3
217
+ with:
218
+ sarif_file: oss-signal.sarif
219
+ ```
182
220
 
183
- This repository dogfoods the public Action tag in [Repository health](.github/workflows/repository-health.yml), which runs `SalmonPlays/oss-signal@v0.3.0` against the repository and uploads the Markdown report artifact.
221
+ This repository dogfoods the public Action tag in [Repository health](.github/workflows/repository-health.yml), which runs `SalmonPlays/oss-signal@v0.4.0` against the repository, uploads the Markdown report artifact, and publishes SARIF to Code Scanning on non-PR runs.
184
222
 
185
223
  You can also run the CLI directly in CI:
186
224
 
@@ -197,8 +235,13 @@ You can also run the CLI directly in CI:
197
235
  ## Roadmap
198
236
 
199
237
  - Ecosystem-specific profiles for Python, Rust, Go, and JavaScript packages
200
- - SARIF output for code scanning dashboards
201
- - Rules for release automation and provenance metadata
238
+ - Release automation and provenance metadata checks
239
+ - Maintainer score trends over time
240
+ - Organization-level repository inventory reports
241
+
242
+ ## Release Process
243
+
244
+ Releases use the checklist in [docs/release-process.md](docs/release-process.md). The repository also includes a tag-triggered [release workflow](.github/workflows/release.yml) that verifies the package, runs `npm publish --dry-run`, and can publish to npm with provenance when `NPM_TOKEN` is configured.
202
245
 
203
246
  ## Contributing
204
247
 
package/action.yml CHANGED
@@ -10,7 +10,7 @@ inputs:
10
10
  required: false
11
11
  default: "."
12
12
  format:
13
- description: Output format, either markdown or json.
13
+ description: Output format, either markdown, json, or sarif.
14
14
  required: false
15
15
  default: markdown
16
16
  output:
@@ -5,13 +5,17 @@ This page collects the public evidence that `oss-signal` is built for real open-
5
5
  ## Project Links
6
6
 
7
7
  - Repository: https://github.com/SalmonPlays/oss-signal
8
- - npm package: https://www.npmjs.com/package/oss-signal
9
- - GitHub Action tag: https://github.com/SalmonPlays/oss-signal/tree/v0.3.0
8
+ - npm package: https://www.npmjs.com/package/oss-signal (`0.3.0` latest)
9
+ - GitHub Release: https://github.com/SalmonPlays/oss-signal/releases/tag/v0.4.0
10
+ - GitHub Action tag: https://github.com/SalmonPlays/oss-signal/tree/v0.4.0
10
11
  - GitHub Action metadata: [action.yml](../action.yml)
11
12
  - Public dogfood workflow: [.github/workflows/repository-health.yml](../.github/workflows/repository-health.yml)
12
13
  - Self-audit report: [docs/self-audit.md](self-audit.md)
14
+ - SARIF self-audit output: [docs/examples/self-audit.sarif](examples/self-audit.sarif)
13
15
  - GitHub URL audit report: [docs/examples/github-url-report.md](examples/github-url-report.md)
14
16
  - GitHub Action workflow example: [docs/examples/github-action-workflow.yml](examples/github-action-workflow.yml)
17
+ - Maintainer playbook: [docs/maintainer-playbook.md](maintainer-playbook.md)
18
+ - Release process: [docs/release-process.md](release-process.md)
15
19
  - Codex for Open Source application brief: [docs/codex-for-oss-application.md](codex-for-oss-application.md)
16
20
  - Rule reference: [docs/rules.md](rules.md)
17
21
 
@@ -24,7 +28,9 @@ The CLI supports two practical modes:
24
28
  - Local repository audit for maintainers working in a clone.
25
29
  - Public GitHub repository audit for quick triage without cloning.
26
30
 
27
- It also ships as a GitHub Action, so maintainers can gate repository hygiene in CI, show the result in the GitHub Actions step summary, and upload a Markdown report as a workflow artifact. This repository dogfoods the public Action tag through the Repository health workflow.
31
+ It also ships as a GitHub Action, so maintainers can gate repository hygiene in CI, show the result in the GitHub Actions step summary, upload a Markdown report as a workflow artifact, and upload failed maintainer-readiness checks as SARIF for GitHub Code Scanning. This repository dogfoods the public Action tag through the Repository health workflow.
32
+
33
+ The [maintainer playbook](maintainer-playbook.md) documents the end-to-end workflow from audit to issue, pull request, CI gate, and Code Scanning evidence. The [release process](release-process.md) documents pre-release verification, tag consistency, npm publish checks, and post-release smoke tests.
28
34
 
29
35
  ## Public Field Audits And PRs
30
36
 
@@ -45,10 +51,12 @@ From this repository:
45
51
  ```bash
46
52
  npm run check
47
53
  npm run audit:github
54
+ node src/cli.js . --format sarif --output docs/examples/self-audit.sarif
48
55
  node src/cli.js platformatic/massimo --format json
56
+ npx --yes oss-signal@0.3.0 SalmonPlays/oss-signal --format json
49
57
  ```
50
58
 
51
- The current repository self-audit score is 100/100, the GitHub community profile health score is 100, and CI verifies the local GitHub Action wrapper.
59
+ The current repository self-audit score is 100/100, the GitHub community profile health score is 100, and CI verifies the local GitHub Action wrapper. The public `v0.4.0` Action tag is used by the repository health workflow for Markdown and SARIF output. The published npm `0.3.0` package has also been executed from a clean temporary directory against the public GitHub repository.
52
60
 
53
61
  Public CI evidence:
54
62
 
@@ -1,6 +1,6 @@
1
1
  # Codex for Open Source Application Brief
2
2
 
3
- Snapshot: 2026-06-02T11:20:40Z
3
+ Snapshot: 2026-06-03T03:06:42Z
4
4
 
5
5
  This document summarizes why `oss-signal` is a fit for OpenAI's Codex for Open Source program. The official program page says open-source maintainers can apply, with emphasis on core maintainers, widely used public projects, and projects that play an important ecosystem role: https://developers.openai.com/community/codex-for-oss
6
6
 
@@ -8,11 +8,14 @@ This document summarizes why `oss-signal` is a fit for OpenAI's Codex for Open S
8
8
 
9
9
  - Repository: https://github.com/SalmonPlays/oss-signal
10
10
  - npm package: https://www.npmjs.com/package/oss-signal
11
- - GitHub Action tag: https://github.com/SalmonPlays/oss-signal/tree/v0.3.0
11
+ - GitHub Release: https://github.com/SalmonPlays/oss-signal/releases/tag/v0.4.0
12
+ - GitHub Action tag: https://github.com/SalmonPlays/oss-signal/tree/v0.4.0
12
13
  - CI workflow: https://github.com/SalmonPlays/oss-signal/actions/workflows/ci.yml
13
14
  - Repository health workflow: https://github.com/SalmonPlays/oss-signal/actions/workflows/repository-health.yml
14
15
  - CodeQL workflow: https://github.com/SalmonPlays/oss-signal/actions/workflows/codeql.yml
15
16
  - Maintainer evidence: [adoption-evidence.md](adoption-evidence.md)
17
+ - Maintainer playbook: [maintainer-playbook.md](maintainer-playbook.md)
18
+ - Release process: [release-process.md](release-process.md)
16
19
 
17
20
  ## What `oss-signal` Does
18
21
 
@@ -22,7 +25,7 @@ This document summarizes why `oss-signal` is a fit for OpenAI's Codex for Open S
22
25
  - CI, tests, issue templates, pull request templates, Dependabot, and CodeQL-style security workflow.
23
26
  - Package metadata and lockfile hygiene.
24
27
 
25
- The output is a deterministic score plus actionable next steps in Markdown or JSON. The GitHub Action also writes a workflow step summary so maintainers and reviewers can see the result without downloading an artifact.
28
+ The output is a deterministic score plus actionable next steps in Markdown, JSON, or SARIF. The GitHub Action also writes a workflow step summary so maintainers and reviewers can see the result without downloading an artifact.
26
29
 
27
30
  ## Why Codex Helps
28
31
 
@@ -31,6 +34,7 @@ This project is designed around repeatable maintainer workflows where Codex is u
31
34
  - Run audits against public repositories without cloning.
32
35
  - Convert findings into focused cleanup issues or pull requests.
33
36
  - Keep repository hygiene visible in CI.
37
+ - Upload failed maintainer-readiness checks to GitHub Code Scanning through SARIF.
34
38
  - Generate small contributor-facing files that maintainers can review quickly.
35
39
  - Use Codex to turn audit findings into scoped documentation and workflow improvements.
36
40
 
@@ -38,12 +42,17 @@ This project is designed around repeatable maintainer workflows where Codex is u
38
42
 
39
43
  The repository currently has:
40
44
 
41
- - A published npm package.
45
+ - A published npm package with `0.3.0` as the latest release.
46
+ - A published GitHub Release for v0.4.0 with SARIF release notes and CI usage guidance.
42
47
  - A reusable GitHub Action with `score`, `grade`, `failed`, and `report-path` outputs.
43
- - A v0.3.0 GitHub Action tag with step summary support.
44
- - A public dogfood workflow that runs `SalmonPlays/oss-signal@v0.3.0` against the repository.
48
+ - SARIF output for GitHub Code Scanning integration.
49
+ - A v0.4.0 GitHub Action tag with step summary and SARIF support.
50
+ - A public dogfood workflow that runs `SalmonPlays/oss-signal@v0.4.0` against the repository, uploads the Markdown report artifact, and uploads SARIF to GitHub Code Scanning on non-PR runs.
51
+ - A maintainer playbook that documents audit, triage, issue, PR, CI, and SARIF workflows.
52
+ - A release process and tag-triggered release workflow that verify package contents and support npm provenance publishing when repository secrets are configured.
45
53
  - CI and CodeQL workflows passing on `main`.
46
54
  - A local self-audit score of 100/100.
55
+ - A clean-directory smoke test of `npx --yes oss-signal@0.3.0 SalmonPlays/oss-signal --format json`, returning 100/100 (A).
47
56
  - Public reports, issues, and PRs created from real repository audits.
48
57
 
49
58
  ## Field Audits And Follow-Up PRs
@@ -71,6 +80,5 @@ Recommended application angle:
71
80
  ## Next Evidence To Collect
72
81
 
73
82
  - One or more merged external PRs.
74
- - A GitHub Release for v0.3.0 with release notes.
75
- - A public workflow run in another repository using `SalmonPlays/oss-signal@v0.3.0`.
83
+ - A public workflow run in another repository using `SalmonPlays/oss-signal@v0.4.0`, ideally with SARIF upload enabled.
76
84
  - npm download data once the registry starts reporting weekly/monthly counts.
@@ -10,7 +10,7 @@ jobs:
10
10
  runs-on: ubuntu-latest
11
11
  steps:
12
12
  - uses: actions/checkout@v4
13
- - uses: SalmonPlays/oss-signal@v0.3.0
13
+ - uses: SalmonPlays/oss-signal@v0.4.0
14
14
  id: oss-signal
15
15
  with:
16
16
  fail-under: "80"
@@ -0,0 +1,38 @@
1
+ name: Repository health
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+ security-events: write
12
+
13
+ jobs:
14
+ oss-signal:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: SalmonPlays/oss-signal@v0.4.0
19
+ id: oss-signal
20
+ with:
21
+ fail-under: "80"
22
+ output: oss-signal-report.md
23
+ summary: "true"
24
+ - uses: SalmonPlays/oss-signal@v0.4.0
25
+ with:
26
+ format: sarif
27
+ output: oss-signal.sarif
28
+ summary: "false"
29
+ - uses: github/codeql-action/upload-sarif@v3
30
+ if: github.event_name != 'pull_request'
31
+ with:
32
+ sarif_file: oss-signal.sarif
33
+ - uses: actions/upload-artifact@v4
34
+ with:
35
+ name: oss-signal-report
36
+ path: |
37
+ oss-signal-report.md
38
+ oss-signal.sarif
@@ -2,7 +2,7 @@
2
2
 
3
3
  Repository: `https://github.com/SalmonPlays/oss-signal`
4
4
  Source: GitHub (SalmonPlays/oss-signal@main)
5
- Generated: 2026-06-02T08:09:34.957Z
5
+ Generated: 2026-06-03T02:26:40.233Z
6
6
 
7
7
  Score: **100/100** (A)
8
8
 
@@ -0,0 +1,407 @@
1
+ {
2
+ "version": "2.1.0",
3
+ "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
4
+ "runs": [
5
+ {
6
+ "tool": {
7
+ "driver": {
8
+ "name": "oss-signal",
9
+ "semanticVersion": "0.4.0",
10
+ "informationUri": "https://github.com/SalmonPlays/oss-signal",
11
+ "rules": [
12
+ {
13
+ "id": "oss-signal/readme",
14
+ "name": "README",
15
+ "shortDescription": {
16
+ "text": "README"
17
+ },
18
+ "fullDescription": {
19
+ "text": "A clear README is the front door for users and contributors."
20
+ },
21
+ "help": {
22
+ "text": "Add setup, usage, contribution, support, and project status sections to README.md.",
23
+ "markdown": "Add setup, usage, contribution, support, and project status sections to README.md."
24
+ },
25
+ "defaultConfiguration": {
26
+ "level": "warning"
27
+ },
28
+ "properties": {
29
+ "tags": [
30
+ "oss-signal",
31
+ "maintainer-readiness"
32
+ ],
33
+ "precision": "high",
34
+ "weight": 12
35
+ }
36
+ },
37
+ {
38
+ "id": "oss-signal/license",
39
+ "name": "License",
40
+ "shortDescription": {
41
+ "text": "License"
42
+ },
43
+ "fullDescription": {
44
+ "text": "A license tells downstream users what they may legally do with the code."
45
+ },
46
+ "help": {
47
+ "text": "Add an OSI-approved license file such as MIT, Apache-2.0, BSD-3-Clause, or MPL-2.0.",
48
+ "markdown": "Add an OSI-approved license file such as MIT, Apache-2.0, BSD-3-Clause, or MPL-2.0."
49
+ },
50
+ "defaultConfiguration": {
51
+ "level": "warning"
52
+ },
53
+ "properties": {
54
+ "tags": [
55
+ "oss-signal",
56
+ "maintainer-readiness"
57
+ ],
58
+ "precision": "high",
59
+ "weight": 10
60
+ }
61
+ },
62
+ {
63
+ "id": "oss-signal/contributing",
64
+ "name": "Contributing guide",
65
+ "shortDescription": {
66
+ "text": "Contributing guide"
67
+ },
68
+ "fullDescription": {
69
+ "text": "Maintainers get better issues and pull requests when expectations are documented."
70
+ },
71
+ "help": {
72
+ "text": "Add CONTRIBUTING.md with local setup, test commands, review expectations, and release notes guidance.",
73
+ "markdown": "Add CONTRIBUTING.md with local setup, test commands, review expectations, and release notes guidance."
74
+ },
75
+ "defaultConfiguration": {
76
+ "level": "warning"
77
+ },
78
+ "properties": {
79
+ "tags": [
80
+ "oss-signal",
81
+ "maintainer-readiness"
82
+ ],
83
+ "precision": "high",
84
+ "weight": 9
85
+ }
86
+ },
87
+ {
88
+ "id": "oss-signal/security",
89
+ "name": "Security policy",
90
+ "shortDescription": {
91
+ "text": "Security policy"
92
+ },
93
+ "fullDescription": {
94
+ "text": "Responsible disclosure needs a private, documented path."
95
+ },
96
+ "help": {
97
+ "text": "Add SECURITY.md with supported versions, reporting instructions, and response expectations.",
98
+ "markdown": "Add SECURITY.md with supported versions, reporting instructions, and response expectations."
99
+ },
100
+ "defaultConfiguration": {
101
+ "level": "warning"
102
+ },
103
+ "properties": {
104
+ "tags": [
105
+ "oss-signal",
106
+ "maintainer-readiness"
107
+ ],
108
+ "precision": "high",
109
+ "weight": 9
110
+ }
111
+ },
112
+ {
113
+ "id": "oss-signal/code-of-conduct",
114
+ "name": "Code of conduct",
115
+ "shortDescription": {
116
+ "text": "Code of conduct"
117
+ },
118
+ "fullDescription": {
119
+ "text": "Community norms reduce ambiguity during difficult interactions."
120
+ },
121
+ "help": {
122
+ "text": "Add CODE_OF_CONDUCT.md, for example the Contributor Covenant.",
123
+ "markdown": "Add CODE_OF_CONDUCT.md, for example the Contributor Covenant."
124
+ },
125
+ "defaultConfiguration": {
126
+ "level": "warning"
127
+ },
128
+ "properties": {
129
+ "tags": [
130
+ "oss-signal",
131
+ "maintainer-readiness"
132
+ ],
133
+ "precision": "high",
134
+ "weight": 6
135
+ }
136
+ },
137
+ {
138
+ "id": "oss-signal/changelog",
139
+ "name": "Changelog",
140
+ "shortDescription": {
141
+ "text": "Changelog"
142
+ },
143
+ "fullDescription": {
144
+ "text": "Users need a durable place to understand release impact."
145
+ },
146
+ "help": {
147
+ "text": "Keep CHANGELOG.md with dated release entries and migration notes.",
148
+ "markdown": "Keep CHANGELOG.md with dated release entries and migration notes."
149
+ },
150
+ "defaultConfiguration": {
151
+ "level": "warning"
152
+ },
153
+ "properties": {
154
+ "tags": [
155
+ "oss-signal",
156
+ "maintainer-readiness"
157
+ ],
158
+ "precision": "high",
159
+ "weight": 6
160
+ }
161
+ },
162
+ {
163
+ "id": "oss-signal/support",
164
+ "name": "Support policy",
165
+ "shortDescription": {
166
+ "text": "Support policy"
167
+ },
168
+ "fullDescription": {
169
+ "text": "Support boundaries help maintainers avoid turning every request into unpaid consulting."
170
+ },
171
+ "help": {
172
+ "text": "Add SUPPORT.md describing where to ask questions, what is in scope, and expected response times.",
173
+ "markdown": "Add SUPPORT.md describing where to ask questions, what is in scope, and expected response times."
174
+ },
175
+ "defaultConfiguration": {
176
+ "level": "warning"
177
+ },
178
+ "properties": {
179
+ "tags": [
180
+ "oss-signal",
181
+ "maintainer-readiness"
182
+ ],
183
+ "precision": "high",
184
+ "weight": 4
185
+ }
186
+ },
187
+ {
188
+ "id": "oss-signal/ci",
189
+ "name": "Continuous integration",
190
+ "shortDescription": {
191
+ "text": "Continuous integration"
192
+ },
193
+ "fullDescription": {
194
+ "text": "CI catches regressions before maintainers merge changes."
195
+ },
196
+ "help": {
197
+ "text": "Add a GitHub Actions workflow that runs linting and tests on pushes and pull requests.",
198
+ "markdown": "Add a GitHub Actions workflow that runs linting and tests on pushes and pull requests."
199
+ },
200
+ "defaultConfiguration": {
201
+ "level": "warning"
202
+ },
203
+ "properties": {
204
+ "tags": [
205
+ "oss-signal",
206
+ "maintainer-readiness"
207
+ ],
208
+ "precision": "high",
209
+ "weight": 12
210
+ }
211
+ },
212
+ {
213
+ "id": "oss-signal/tests",
214
+ "name": "Tests",
215
+ "shortDescription": {
216
+ "text": "Tests"
217
+ },
218
+ "fullDescription": {
219
+ "text": "Tests make review safer and lower the cost of outside contributions."
220
+ },
221
+ "help": {
222
+ "text": "Add focused tests for public behavior and document the test command.",
223
+ "markdown": "Add focused tests for public behavior and document the test command."
224
+ },
225
+ "defaultConfiguration": {
226
+ "level": "warning"
227
+ },
228
+ "properties": {
229
+ "tags": [
230
+ "oss-signal",
231
+ "maintainer-readiness"
232
+ ],
233
+ "precision": "high",
234
+ "weight": 10
235
+ }
236
+ },
237
+ {
238
+ "id": "oss-signal/issue-templates",
239
+ "name": "Issue templates",
240
+ "shortDescription": {
241
+ "text": "Issue templates"
242
+ },
243
+ "fullDescription": {
244
+ "text": "Issue templates collect the facts maintainers need to reproduce and triage."
245
+ },
246
+ "help": {
247
+ "text": "Add bug report and feature request templates under .github/ISSUE_TEMPLATE/.",
248
+ "markdown": "Add bug report and feature request templates under .github/ISSUE_TEMPLATE/."
249
+ },
250
+ "defaultConfiguration": {
251
+ "level": "warning"
252
+ },
253
+ "properties": {
254
+ "tags": [
255
+ "oss-signal",
256
+ "maintainer-readiness"
257
+ ],
258
+ "precision": "high",
259
+ "weight": 5
260
+ }
261
+ },
262
+ {
263
+ "id": "oss-signal/pull-request-template",
264
+ "name": "Pull request template",
265
+ "shortDescription": {
266
+ "text": "Pull request template"
267
+ },
268
+ "fullDescription": {
269
+ "text": "PR templates nudge contributors to include tests, docs, and review context."
270
+ },
271
+ "help": {
272
+ "text": "Add .github/PULL_REQUEST_TEMPLATE.md with a short checklist.",
273
+ "markdown": "Add .github/PULL_REQUEST_TEMPLATE.md with a short checklist."
274
+ },
275
+ "defaultConfiguration": {
276
+ "level": "warning"
277
+ },
278
+ "properties": {
279
+ "tags": [
280
+ "oss-signal",
281
+ "maintainer-readiness"
282
+ ],
283
+ "precision": "high",
284
+ "weight": 5
285
+ }
286
+ },
287
+ {
288
+ "id": "oss-signal/dependabot",
289
+ "name": "Dependency update automation",
290
+ "shortDescription": {
291
+ "text": "Dependency update automation"
292
+ },
293
+ "fullDescription": {
294
+ "text": "Automated dependency updates reduce security and compatibility drift."
295
+ },
296
+ "help": {
297
+ "text": "Add .github/dependabot.yml for the package ecosystems used in the repository.",
298
+ "markdown": "Add .github/dependabot.yml for the package ecosystems used in the repository."
299
+ },
300
+ "defaultConfiguration": {
301
+ "level": "warning"
302
+ },
303
+ "properties": {
304
+ "tags": [
305
+ "oss-signal",
306
+ "maintainer-readiness"
307
+ ],
308
+ "precision": "high",
309
+ "weight": 5
310
+ }
311
+ },
312
+ {
313
+ "id": "oss-signal/codeql",
314
+ "name": "Static security analysis",
315
+ "shortDescription": {
316
+ "text": "Static security analysis"
317
+ },
318
+ "fullDescription": {
319
+ "text": "Static analysis finds common vulnerability patterns before releases."
320
+ },
321
+ "help": {
322
+ "text": "Add a CodeQL or equivalent security scanning workflow.",
323
+ "markdown": "Add a CodeQL or equivalent security scanning workflow."
324
+ },
325
+ "defaultConfiguration": {
326
+ "level": "warning"
327
+ },
328
+ "properties": {
329
+ "tags": [
330
+ "oss-signal",
331
+ "maintainer-readiness"
332
+ ],
333
+ "precision": "high",
334
+ "weight": 4
335
+ }
336
+ },
337
+ {
338
+ "id": "oss-signal/package-json",
339
+ "name": "Node package metadata",
340
+ "shortDescription": {
341
+ "text": "Node package metadata"
342
+ },
343
+ "fullDescription": {
344
+ "text": "Package metadata makes installation, testing, and release automation discoverable."
345
+ },
346
+ "help": {
347
+ "text": "Add package.json with name, description, license, scripts, repository, and engines fields.",
348
+ "markdown": "Add package.json with name, description, license, scripts, repository, and engines fields."
349
+ },
350
+ "defaultConfiguration": {
351
+ "level": "warning"
352
+ },
353
+ "properties": {
354
+ "tags": [
355
+ "oss-signal",
356
+ "maintainer-readiness"
357
+ ],
358
+ "precision": "high",
359
+ "weight": 5
360
+ }
361
+ },
362
+ {
363
+ "id": "oss-signal/lockfile",
364
+ "name": "Dependency lockfile",
365
+ "shortDescription": {
366
+ "text": "Dependency lockfile"
367
+ },
368
+ "fullDescription": {
369
+ "text": "Lockfiles make CI and contributor setup reproducible."
370
+ },
371
+ "help": {
372
+ "text": "Commit the lockfile for application-style projects, or document why this library intentionally omits one.",
373
+ "markdown": "Commit the lockfile for application-style projects, or document why this library intentionally omits one."
374
+ },
375
+ "defaultConfiguration": {
376
+ "level": "warning"
377
+ },
378
+ "properties": {
379
+ "tags": [
380
+ "oss-signal",
381
+ "maintainer-readiness"
382
+ ],
383
+ "precision": "high",
384
+ "weight": 4
385
+ }
386
+ }
387
+ ]
388
+ }
389
+ },
390
+ "automationDetails": {
391
+ "id": "oss-signal/maintainer-readiness"
392
+ },
393
+ "invocations": [
394
+ {
395
+ "executionSuccessful": true
396
+ }
397
+ ],
398
+ "results": [],
399
+ "properties": {
400
+ "score": 100,
401
+ "grade": "A",
402
+ "source": "local",
403
+ "generatedAt": "2026-06-03T02:26:40.315Z"
404
+ }
405
+ }
406
+ ]
407
+ }
@@ -0,0 +1,103 @@
1
+ # Maintainer Playbook
2
+
3
+ This playbook shows the workflow `oss-signal` is designed to support: run a deterministic audit, turn missing maintainer-readiness signals into a focused issue or pull request, then keep the score visible in CI.
4
+
5
+ ## 1. Audit A Repository
6
+
7
+ Run against a local checkout:
8
+
9
+ ```bash
10
+ oss-signal . --format markdown --output oss-signal-report.md
11
+ ```
12
+
13
+ Run against a public GitHub repository without cloning it:
14
+
15
+ ```bash
16
+ oss-signal owner/repo --format markdown --output owner-repo-report.md
17
+ ```
18
+
19
+ Use JSON when another tool needs to consume the score:
20
+
21
+ ```bash
22
+ oss-signal owner/repo --format json
23
+ ```
24
+
25
+ Use SARIF when the findings should appear in Code Scanning:
26
+
27
+ ```bash
28
+ oss-signal . --format sarif --output oss-signal.sarif
29
+ ```
30
+
31
+ ## 2. Triage Findings
32
+
33
+ Prioritize missing checks that reduce maintainer load:
34
+
35
+ - Security policy, so reporters have a private disclosure path.
36
+ - Contributing guide, so contributors know setup, tests, and review expectations.
37
+ - Issue and pull request templates, so maintainers receive reproducible reports.
38
+ - CI, tests, Dependabot, and CodeQL-style scanning, so review cost stays low.
39
+
40
+ Do not treat the score as a code-quality verdict. It is a workflow-readiness signal.
41
+
42
+ ## 3. Turn Findings Into Maintainer-Friendly Follow-Up
43
+
44
+ For an issue, include:
45
+
46
+ - The generated score and report link.
47
+ - The specific missing signal.
48
+ - Why it matters for maintainers.
49
+ - One concrete proposed fix.
50
+
51
+ For a pull request, keep the change narrow. Good PRs add or improve files such as `CONTRIBUTING.md`, `SECURITY.md`, `.github/ISSUE_TEMPLATE/*`, `.github/PULL_REQUEST_TEMPLATE.md`, or a small CI workflow. Avoid broad product-code changes unless the maintainer asked for them.
52
+
53
+ The field-audit examples in [docs/outreach](outreach) show this pattern for public repositories.
54
+
55
+ ## 4. Add A CI Gate
56
+
57
+ Add the GitHub Action to keep the signal visible:
58
+
59
+ ```yaml
60
+ - uses: SalmonPlays/oss-signal@v0.4.0
61
+ id: oss-signal
62
+ with:
63
+ fail-under: "80"
64
+ output: oss-signal-report.md
65
+ summary: "true"
66
+ ```
67
+
68
+ The Action writes `score`, `grade`, `failed`, and `report-path` outputs, and writes a concise GitHub Actions step summary by default.
69
+
70
+ ## 5. Upload SARIF To Code Scanning
71
+
72
+ When maintainers already use GitHub Code Scanning, upload SARIF:
73
+
74
+ ```yaml
75
+ permissions:
76
+ contents: read
77
+ security-events: write
78
+
79
+ steps:
80
+ - uses: actions/checkout@v4
81
+ - uses: SalmonPlays/oss-signal@v0.4.0
82
+ with:
83
+ format: sarif
84
+ output: oss-signal.sarif
85
+ summary: "false"
86
+ - uses: github/codeql-action/upload-sarif@v3
87
+ with:
88
+ sarif_file: oss-signal.sarif
89
+ ```
90
+
91
+ See [docs/examples/github-code-scanning-workflow.yml](examples/github-code-scanning-workflow.yml) for a complete workflow.
92
+
93
+ ## 6. Collect Adoption Evidence
94
+
95
+ Useful evidence for maintainers and reviewers:
96
+
97
+ - A public workflow run that uses `SalmonPlays/oss-signal@v0.4.0`.
98
+ - A generated Markdown report attached as an artifact.
99
+ - A SARIF upload in Code Scanning.
100
+ - A small issue or PR that follows from an audit finding.
101
+ - A release note or changelog entry showing the maintainer workflow improved.
102
+
103
+ Keep the evidence factual. Do not claim adoption from a repository unless that repository actually runs the tool or accepted a related change.
@@ -0,0 +1,26 @@
1
+ # oss-signal v0.4.0
2
+
3
+ `oss-signal` v0.4.0 adds SARIF output so maintainers can send failed maintainer-readiness checks to GitHub Code Scanning while keeping the Markdown report and GitHub Actions step summary available for day-to-day review.
4
+
5
+ ## Highlights
6
+
7
+ - Added `--format sarif` to the CLI.
8
+ - Added `format: sarif` support to the GitHub Action.
9
+ - Added a self-audit SARIF example at `docs/examples/self-audit.sarif`.
10
+ - Added README guidance for uploading `oss-signal.sarif` to GitHub Code Scanning.
11
+ - Updated the repository health workflow to dogfood the public `SalmonPlays/oss-signal@v0.4.0` Action tag.
12
+
13
+ ## Try It
14
+
15
+ ```bash
16
+ git clone https://github.com/SalmonPlays/oss-signal.git
17
+ cd oss-signal
18
+ npm install
19
+ node src/cli.js SalmonPlays/oss-signal --format sarif > oss-signal.sarif
20
+ ```
21
+
22
+ For CI, use `SalmonPlays/oss-signal@v0.4.0` in GitHub Actions, copy `docs/examples/github-code-scanning-workflow.yml`, and adjust `fail-under` for your project.
23
+
24
+ ## Why It Matters
25
+
26
+ Maintainers already use GitHub Code Scanning for actionable repository findings. SARIF support lets `oss-signal` meet that workflow instead of forcing maintainers to inspect a separate report format.
@@ -0,0 +1,82 @@
1
+ # Release Process
2
+
3
+ This process keeps `oss-signal` releases reproducible and easy to verify.
4
+
5
+ ## Pre-Release
6
+
7
+ Run the full local check:
8
+
9
+ ```bash
10
+ npm run check
11
+ ```
12
+
13
+ Verify the public GitHub audit example:
14
+
15
+ ```bash
16
+ npm run audit:github
17
+ ```
18
+
19
+ Verify SARIF output:
20
+
21
+ ```bash
22
+ node src/cli.js . --format sarif --output docs/examples/self-audit.sarif
23
+ node -e "const fs = require('fs'); const sarif = JSON.parse(fs.readFileSync('docs/examples/self-audit.sarif', 'utf8')); if (sarif.version !== '2.1.0') throw new Error('invalid SARIF');"
24
+ ```
25
+
26
+ Inspect the npm tarball before publishing:
27
+
28
+ ```bash
29
+ npm publish --dry-run
30
+ ```
31
+
32
+ ## Tag
33
+
34
+ The package version and tag must match:
35
+
36
+ ```bash
37
+ node src/cli.js --version
38
+ git tag v$(node src/cli.js --version)
39
+ git push origin main --tags
40
+ ```
41
+
42
+ ## GitHub Release
43
+
44
+ Create a GitHub Release for the tag and use the release notes in `docs/release-notes/` when available.
45
+
46
+ For example, `v0.4.0` uses [docs/release-notes/v0.4.0.md](release-notes/v0.4.0.md).
47
+
48
+ ## npm Publish
49
+
50
+ Manual publish path:
51
+
52
+ ```bash
53
+ npm publish --access public
54
+ ```
55
+
56
+ Automation path:
57
+
58
+ The tag-triggered [release workflow](../.github/workflows/release.yml) runs the same checks, verifies the package with `npm publish --dry-run`, and publishes with provenance when `NPM_TOKEN` is configured for the repository.
59
+
60
+ ## Post-Release Verification
61
+
62
+ Check the registry version:
63
+
64
+ ```bash
65
+ npm view oss-signal version dist-tags.latest --json
66
+ ```
67
+
68
+ Run from a clean temporary directory:
69
+
70
+ ```bash
71
+ tmpdir=$(mktemp -d)
72
+ cd "$tmpdir"
73
+ npm exec --yes --package=oss-signal -- oss-signal SalmonPlays/oss-signal --format json
74
+ ```
75
+
76
+ Check the public Action tag:
77
+
78
+ ```bash
79
+ git ls-remote --tags https://github.com/SalmonPlays/oss-signal.git
80
+ ```
81
+
82
+ Download metrics can lag behind package publication. Treat npm download counts as delayed evidence, not immediate proof that a release worked.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Repository: `/Users/amon/Documents/Codex/2026-06-01/openai-s/outputs/oss-signal`
4
4
  Source: local
5
- Generated: 2026-06-02T08:09:32.913Z
5
+ Generated: 2026-06-03T02:26:38.240Z
6
6
 
7
7
  Score: **100/100** (A)
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oss-signal",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A dependency-light CLI that audits open-source repository maintenance readiness.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/action.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { promises as fs } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { auditTarget, renderMarkdown } from "./index.js";
5
+ import { auditTarget, renderMarkdown, renderSarif } from "./index.js";
6
6
 
7
7
  const OUTPUT_DELIMITER = "oss_signal_output";
8
8
 
@@ -12,7 +12,7 @@ export async function runAction(env = process.env, stdout = process.stdout, stde
12
12
  maxFiles: options.maxFiles,
13
13
  ref: options.ref
14
14
  });
15
- const body = options.format === "json" ? `${JSON.stringify(report, null, 2)}\n` : renderMarkdown(report);
15
+ const body = renderReport(report, options.format);
16
16
 
17
17
  if (options.output) {
18
18
  await fs.mkdir(path.dirname(path.resolve(options.output)), { recursive: true });
@@ -42,8 +42,8 @@ export async function runAction(env = process.env, stdout = process.stdout, stde
42
42
 
43
43
  export function parseActionInputs(env = process.env) {
44
44
  const format = getInput(env, "format") || "markdown";
45
- if (!["markdown", "json"].includes(format)) {
46
- throw new Error("format must be either markdown or json");
45
+ if (!["markdown", "json", "sarif"].includes(format)) {
46
+ throw new Error("format must be markdown, json, or sarif");
47
47
  }
48
48
 
49
49
  return {
@@ -57,6 +57,16 @@ export function parseActionInputs(env = process.env) {
57
57
  };
58
58
  }
59
59
 
60
+ function renderReport(report, format) {
61
+ if (format === "json") {
62
+ return `${JSON.stringify(report, null, 2)}\n`;
63
+ }
64
+ if (format === "sarif") {
65
+ return renderSarif(report);
66
+ }
67
+ return renderMarkdown(report);
68
+ }
69
+
60
70
  export async function writeGitHubOutput(outputFile, values) {
61
71
  if (!outputFile) {
62
72
  return;
package/src/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { promises as fs } from "node:fs";
3
- import { auditTarget, renderMarkdown, VERSION } from "./index.js";
3
+ import { auditTarget, renderMarkdown, renderSarif, VERSION } from "./index.js";
4
4
 
5
5
  async function main(argv) {
6
6
  const options = parseArgs(argv);
@@ -18,7 +18,7 @@ async function main(argv) {
18
18
  maxFiles: options.maxFiles,
19
19
  ref: options.ref
20
20
  });
21
- const body = options.format === "json" ? `${JSON.stringify(report, null, 2)}\n` : renderMarkdown(report);
21
+ const body = renderReport(report, options.format);
22
22
 
23
23
  if (options.output) {
24
24
  await fs.writeFile(options.output, body, "utf8");
@@ -85,12 +85,22 @@ function parseArgs(argv) {
85
85
  if (positionals.length === 1) {
86
86
  options.path = positionals[0];
87
87
  }
88
- if (!["markdown", "json"].includes(options.format)) {
89
- throw new Error("--format must be either markdown or json");
88
+ if (!["markdown", "json", "sarif"].includes(options.format)) {
89
+ throw new Error("--format must be markdown, json, or sarif");
90
90
  }
91
91
  return options;
92
92
  }
93
93
 
94
+ function renderReport(report, format) {
95
+ if (format === "json") {
96
+ return `${JSON.stringify(report, null, 2)}\n`;
97
+ }
98
+ if (format === "sarif") {
99
+ return renderSarif(report);
100
+ }
101
+ return renderMarkdown(report);
102
+ }
103
+
94
104
  function requireValue(argv, index, optionName) {
95
105
  const value = argv[index];
96
106
  if (!value || value.startsWith("-")) {
@@ -111,7 +121,7 @@ function helpText() {
111
121
  return `oss-signal audits open-source repository maintenance readiness.
112
122
 
113
123
  Usage:
114
- oss-signal [path-or-github-url] [--format markdown|json] [--output file] [--fail-under score]
124
+ oss-signal [path-or-github-url] [--format markdown|json|sarif] [--output file] [--fail-under score]
115
125
 
116
126
  Examples:
117
127
  oss-signal .
package/src/index.js CHANGED
@@ -2,7 +2,25 @@ import { promises as fs } from "node:fs";
2
2
  import https from "node:https";
3
3
  import path from "node:path";
4
4
 
5
- export const VERSION = "0.3.0";
5
+ export const VERSION = "0.4.0";
6
+
7
+ const SARIF_RULE_LOCATIONS = {
8
+ readme: "README.md",
9
+ license: "LICENSE",
10
+ contributing: "CONTRIBUTING.md",
11
+ security: "SECURITY.md",
12
+ "code-of-conduct": "CODE_OF_CONDUCT.md",
13
+ changelog: "CHANGELOG.md",
14
+ support: "SUPPORT.md",
15
+ ci: ".github/workflows/ci.yml",
16
+ tests: "test/example.test.js",
17
+ "issue-templates": ".github/ISSUE_TEMPLATE/bug_report.md",
18
+ "pull-request-template": ".github/PULL_REQUEST_TEMPLATE.md",
19
+ dependabot: ".github/dependabot.yml",
20
+ codeql: ".github/workflows/codeql.yml",
21
+ "package-json": "package.json",
22
+ lockfile: "package-lock.json"
23
+ };
6
24
 
7
25
  const COMMUNITY_FILES = [
8
26
  {
@@ -276,6 +294,91 @@ export function renderMarkdown(report) {
276
294
  return `${lines.join("\n")}\n`;
277
295
  }
278
296
 
297
+ export function renderSarif(report) {
298
+ const rules = report.checks.map((check) => ({
299
+ id: `oss-signal/${check.id}`,
300
+ name: check.label,
301
+ shortDescription: {
302
+ text: check.label
303
+ },
304
+ fullDescription: {
305
+ text: check.why
306
+ },
307
+ help: {
308
+ text: check.fix,
309
+ markdown: check.fix
310
+ },
311
+ defaultConfiguration: {
312
+ level: "warning"
313
+ },
314
+ properties: {
315
+ tags: ["oss-signal", "maintainer-readiness"],
316
+ precision: "high",
317
+ weight: check.weight
318
+ }
319
+ }));
320
+
321
+ const results = report.checks
322
+ .filter((check) => !check.passed)
323
+ .map((check) => ({
324
+ ruleId: `oss-signal/${check.id}`,
325
+ level: "warning",
326
+ message: {
327
+ text: `${check.label}: ${check.fix}`
328
+ },
329
+ locations: [
330
+ {
331
+ physicalLocation: {
332
+ artifactLocation: {
333
+ uri: SARIF_RULE_LOCATIONS[check.id] ?? "."
334
+ },
335
+ region: {
336
+ startLine: 1,
337
+ startColumn: 1
338
+ }
339
+ }
340
+ }
341
+ ],
342
+ properties: {
343
+ why: check.why,
344
+ fix: check.fix,
345
+ weight: check.weight
346
+ }
347
+ }));
348
+
349
+ return `${JSON.stringify({
350
+ version: "2.1.0",
351
+ $schema: "https://json.schemastore.org/sarif-2.1.0.json",
352
+ runs: [
353
+ {
354
+ tool: {
355
+ driver: {
356
+ name: "oss-signal",
357
+ semanticVersion: report.version,
358
+ informationUri: "https://github.com/SalmonPlays/oss-signal",
359
+ rules
360
+ }
361
+ },
362
+ automationDetails: {
363
+ id: "oss-signal/maintainer-readiness"
364
+ },
365
+ invocations: [
366
+ {
367
+ executionSuccessful: true
368
+ }
369
+ ],
370
+ results,
371
+ properties: {
372
+ score: report.score,
373
+ grade: report.grade,
374
+ source: sourceSummary(report.source),
375
+ generatedAt: report.generatedAt
376
+ }
377
+ }
378
+ ]
379
+ }, null, 2)}\n`;
380
+ }
381
+
279
382
  export async function listRepositoryFiles(root, options = {}) {
280
383
  const maxFiles = options.maxFiles ?? 20000;
281
384
  const files = [];