Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 05 Sep 16:12
· 41 commits to main since this release

0.2.0 (2026-09-05)

Every repository section of the Markdown report now opens with a plain-language paragraph for the person who will read the report and does not write software. It is assembled from the figures by a fixed rule with no model call, so it is deterministic, states no opinion about quality, keeps commit share and surviving lines apart, and ends with the command that recomputes it. It is derived from the hashed figures rather than added to them, so the hash is unchanged.

verify now prints what it proves and what it does not: that the figures were recomputed from the repository and the document was not edited, and not that the repository is honest history or that the work was good. When figures differ it says that a difference is not proof of dishonesty, because every figure except tenure is computed at HEAD and HEAD moves.

npm run bench:adversarial runs the gaming instead of describing it: commit padding, whitespace churn, an unmarked generated file, the same file marked linguist-generated, and a co-author trailer against its own control, each applied to a copy of the fixture with every gaming commit dated inside the existing tenure so the window does not move. Sixty padding commits take cadence from 1.0 to 21.0 a week and add one surviving line while the median commit halves; re-indenting every line moves nothing because blame runs with -w; 2,000 machine-written lines under a name the lists miss take surviving lines from 51.6% to 99.3%, and marking the file removes them again; the trailer moves only the co-authored count. The README carries the table and test/adversarial.test.ts pins the last two findings.

Verification that means something: workproof check validates the report against a published JSON Schema and recomputes the hash offline over RFC 8785 canonical JSON; verify runs it first and refuses to recompute figures for an edited document, then compares the repository fingerprint (a mismatch stops before figures) and HEAD. attest writes an in-toto statement whose subject is the report hash, signs it with an SSH key (--local) into a DSSE envelope, and the Action signs it keylessly with Sigstore when attest: "true".

Honest denominators: bot commits leave every figure; lock files, snapshots, minified assets, generated outputs and vendored directories (built-in lists plus linguist-generated and linguist-vendored in .gitattributes) leave every count and the blame sample; the report prints how much was excluded. --no-exclusions, --exclude, --seed, --copies and --ignore-revs-file are new, and .git-blame-ignore-revs at the root is honoured automatically. Every git call runs with pinned diff settings and the report records the git version, blame flags, ignore-revs file and seed.

Seven new figures, each with its bias in its limits: files authored (degree of authorship), major-contributor components, commit size, co-authored commits, absence factor, AI-assisted commits and survival by cohort. Two labels stop overclaiming: "documents authored" is now "documents created" (oldest commit is the author's) and the test figure is titled test-file changes. The badge reads surviving lines and tenure days.

Privacy: the fingerprint is keyed (HMAC-SHA256 under a per-report key printed once and stored nowhere; --fingerprint-key reuses one) and GitHub noreply addresses are never written. Reports carry schemaVersion: 2; 0.1.x reports fail check by design.

The Action writes the Markdown report to the job summary and uploads the report files as the workproof-report artifact, so a run leaves something readable behind even without a pull request to comment on. npm run release now also moves the v0 tag that uses: Bubblegunn/workproof@v0 resolves to, and the release workflow starts on full version tags only, so the moving tag cannot start a second publish.

Full Changelog: v0.1.3...v0.2.0