You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2bc3c0e
Browse filesBrowse the repository at this point in the historyBrowse files
feat(bin): release-report, a second opinion on what a deploy box served and for how long
bin/release-report.mjs reads commitwork.release-evidence/1 documents (--evidence, or --fetch
over ssh from the private monitor/private/releases.json, kept under ~/.commitwork/releases),
validates them fail-closed, re-judges every finding under the document's own policy with the
local KEV catalogue, EPSS cache and advisory CVSS index, and writes a self-contained
reports/releases/<product>/index.html plus report.json: serving release, rollback-eligible
releases, blocked/refused/failed/removed history, serving timeline, exposure after the first
blocked evidence and after the KEV date added, disagreements with the box, and what the check
does not cover. Exit 0 ok, 1 serving release blocked or a disagreement, 2 input error,
4 evidence over 26 h old or KEV stale (no agreement is claimed).
Adds schema/release-evidence.schema.json, schema/release-sources.schema.json (bound as a
validator, so the applied-schema floor in schema-required goes 28 to 29),
monitor/releases.example.json, fixtures and tests.
Copy file name to clipboardExpand all lines: bin/README.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -256,6 +256,7 @@ Exposure view runs the same code.
256
256
|`graph.mjs`| Builds the relation store (node:sqlite, `nodes` and `edges`) that joins findings to the lane that found them, their repository and area, the weakness classes each lane covers (`monitor/approach-taxonomy.json`), the lanes that ran on each repository (area rollups) and the opaque sessions that claimed them; `query neighbours` and `query path` answer from it, rebuilding first when an input changed. An edge kind whose input is absent is recorded as not built with the reason. The store holds fleet data, so it lives at `<reports root>/graph/graph.db` (`CW_GRAPH_DB`). Served as `GET /api/graph/neighbours` and the `graph_neighbours` MCP tool. |
257
257
|`build-security-data.mjs`|`rollup.json` → machine-generated counts injected into report md — counts cannot drift from the scan of record. |
258
258
|`render-report.mjs`| Zero-dep Markdown → self-contained themed HTML (prints cleanly to PDF). |
259
+
| `release-report.mjs` | Reports what a deploy box served and whether it should have. Reads `commitwork.release-evidence/1` documents (`--evidence <file>`, or `--fetch` over ssh from the private `monitor/private/releases.json`, shape in `monitor/releases.example.json`; fetched documents are kept under `~/.commitwork/releases/<product>/`), refuses an invalid one without writing anything, re-judges every finding under the document's own policy with commitwork's KEV catalogue, EPSS cache and advisory CVSS index, and writes `reports/releases/<product>/index.html` and `report.json`: serving release and verdict, rollback-eligible releases, blocked/refused/failed/removed history, the serving timeline, exposure (serving time after the first blocked evidence and after the KEV date added), disagreements with the box, and what the check does not cover. Exit 0 ok, 1 the serving release is blocked or the two disagree, 2 input error, 4 evidence over 26 h old or KEV stale (no agreement is claimed). Schema at `schema/release-evidence.schema.json`. |
259
260
| `md-view.mjs` | `md-view.mjs <file.md> [--out <file.html>] [--no-open]`: renders any Markdown file as one self-contained HTML page in the house palette and opens it. The page has a contents rail and a light/dark toggle, and draws the design values the document states. Colours become swatches. `--tokens` declared in a Dark/Light table resolve wherever they are named, and each contrast ratio gets its WCAG grade. Shadows, font stacks, type sizes, weights, tracking, radii, padding, spacing steps, durations, opacities, line heights and measures render as what they describe. A column or section heading decides what a bare number means. A ```lockup fence holds panel markup, which is sanitised against an allowlist and drawn twice, dark and light, with the panel's own stylesheets scoped under each container (`CW_MD_VIEW_ADMIN_DIR`). Fonts and local images are inlined; remote images are never fetched. Every drawn value is a generated class in one hashed `<style>`, so the page runs under a CSP with no `'unsafe-inline'`. Written to `reports/md-view/<path>.html` (`CW_REPORTS_DIR`). The parser is its own (`lib/md-view.mjs`): `lib/render-markdown.mjs` ends a list item at its first wrapped line and is held to docsite parity, so it was not widened. |
260
261
|`parse-runtime.mjs`| One parser for DAST/BOLA reports feeding both the rollup and `runtime.html`. |
261
262
|`mainline-data.mjs`, `slices.mjs`| Sitemap history harvesters (git-graph DAG; versioned state slices). |
Copy file name to clipboardExpand all lines: bin/test/schema-required.test.mjs
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -290,7 +290,7 @@ test('every shipped example of a private record validates against its schema', (
290
290
291
291
test('the count of applied schemas may not fall',()=>{
292
292
// Raise only after a consumer is proven to reject an invalid document through the schema.
293
-
constFLOOR=28;// monitor/release-terms.example.json's schema: compileTerms in bin/lib/release-terms.mjs refuses an invalid list (bin/test/release-terms.test.mjs)
293
+
constFLOOR=29;// monitor/private/releases.json's schema: loadSources in bin/release-report.mjs refuses an invalid list (bin/test/release-report.test.mjs); before it, monitor/release-terms.example.json's: compileTerms in bin/lib/release-terms.mjs (bin/test/release-terms.test.mjs)
Copy file name to clipboardExpand all lines: docs/EXIT-CODES.md
+10-1Lines changed: 10 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ nothing about exit status; `prose` means it does, in a shape the extractor does
8
8
Neither is a claim about what the command returns. What may change between releases is in
9
9
[STABILITY.md](STABILITY.md).
10
10
11
-
344 commands: 147 declared, 12 prose, 185 undeclared. Of the declared, 116 use only codes 0–13, the range Node itself exits with (1 on an uncaught exception), and 31 declare a code of 20 or above.
11
+
345 commands: 148 declared, 12 prose, 185 undeclared. Of the declared, 117 use only codes 0–13, the range Node itself exits with (1 on an uncaught exception), and 31 declare a code of 20 or above.
- Option: `--evidence <file> a saved document; repeatable`
1286
+
- Option: `--fetch pull each source of monitor/private/releases.json over ssh and keep the documents`
1287
+
- Option: `--out <dir> base directory for the reports, default <reports>/releases; one <product>/ each`
1288
+
- Option: `--json print the report JSON (an array when several products) to stdout`
1289
+
- Exit: 0 ok · 1 the serving release is blocked, or commitwork and the box disagree on a finding · 2 usage, unreadable or invalid input, or a failed fetch (invalid input writes nothing) · 4 evidence older than 26 h, or the KEV catalogue stale or undated (no agreement is claimed)
@@ -3266,6 +3277,7 @@ a reader's `env` header section when one has it, otherwise from another file's,
3266
3277
|`CW_REFUTATIONS`| direct |`monitor/store-paths.mjs`| undocumented |
3267
3278
|`CW_REGISTRY`| direct |`bin/hermetic-test.mjs`, `monitor/history-chain.mjs`, `monitor/registry.mjs`, `monitor/store-paths.mjs`| registry, and through it the reports root (`monitor/defect-signature.mjs`) |
|`CW_RELEASES_DIR`| direct |`bin/release-report.mjs`| undocumented |
3269
3281
|`CW_RELEASES_OUT`| direct |`bin/releases-atom.mjs`| undocumented |
3270
3282
|`CW_RELEASES_PATTERN`| direct |`bin/releases-atom.mjs`| undocumented |
3271
3283
|`CW_RELEASES_SELF`| direct |`bin/releases-atom.mjs`| undocumented |
@@ -3277,6 +3289,7 @@ a reader's `env` header section when one has it, otherwise from another file's,
3277
3289
|`CW_RELEASE_REVIEWS_SCHEMA`| direct |`bin/lib/release-reviews.mjs`| undocumented |
3278
3290
|`CW_RELEASE_SCRATCH`| direct |`bin/release-candidate.mjs`| the directory the tests gate makes its scratch HOME in (default ~/.cache/commitwork/release-candidate), read at call time |
3279
3291
|`CW_RELEASE_SOURCE`| direct |`bin/release-candidate.mjs`, `bin/web-roadmap.mjs`| the repository --work reads commits from; default this checkout |
3292
+
|`CW_RELEASE_SOURCES`| direct |`bin/release-report.mjs`| undocumented |
3280
3293
|`CW_RELEASE_TAG_PREFIX`| direct |`bin/release-tag.mjs`| the release tag prefix, default v (`bin/changelog.mjs`) |
3281
3294
|`CW_RELEASE_TERMS`| direct |`bin/lib/release-terms.mjs`| a list file; overrides the sidecar |
0 commit comments