Skip to content

feat(audit): let whoever changes the tree rewrite its manifest - #76

Closed
L4XB wants to merge 1 commit into
developfrom
feat/refresh-export-manifest
Closed

L4XB wants to merge 1 commit into
developfrom
feat/refresh-export-manifest

Conversation

@L4XB

@L4XB L4XB commented Sep 14, 2026

Copy link
Copy Markdown
Member

The problem, concretely

Five Dependabot pull requests are red right now, all with the same failure:

community export audit failed: manifest:file-set-or-hash:pyproject.toml

COMMUNITY_EXPORT_MANIFEST.json binds every file under services/api/ to its
digest. A dependency bump rewrites pyproject.toml and uv.lock, so the audit
refuses the tree — correctly. But the message named a path and nothing else, no
command in the repository produced a new manifest, and Dependabot cannot write
one it knows nothing about. The only way through was to reimplement the hashing
by hand, which is what happened on every change to this tree so far.

What changes

--refresh-manifest rewrites the manifest for the current tree, and the failure
message names it.

The ordering is the point: the refresh runs every other gate first — secret
and private-marker scan, hosted-boundary markers and symbols, forbidden
artifacts, the CodeQL regression guards, packaging, and the runtime contract of
400 HTTP operations, one WebSocket and 89 tables. Only once all of them pass
does it record the tree. It can therefore record new hashes, but it can never
grant approval to a tree the audit rejects.

It prints what it recorded rather than a wall of digests:

$ python scripts/audit_community_export.py . --refresh-manifest
community export manifest refreshed: added:tests/test_export_manifest.py, changed:README.md

What it does not change

The manifest still carries source_commit, still binds the exact file set, and
the release workflow still runs the audit in its verifying form. Whether a
per-pull-request digest binding is the right gate for a repository that now
takes contributions is a separate question, and this does not answer it — it
only makes the existing gate satisfiable by the person who tripped it.

Validation

Three new tests cover the failure message naming the fix, the refresh reporting
its own additions and changes, and the export identity surviving a refresh.
ruff is clean and the audit passes in its normal form.

COMMUNITY_EXPORT_MANIFEST.json binds every file under services/api/ to its
digest, so any change there fails the audit until the manifest is rewritten. The
failure named the path and nothing else, and no command in the repository
produced the new manifest — the only way was to reimplement its hashing by hand.

That is not a hypothetical: every dependency update touching pyproject.toml or
uv.lock fails this way, and five open Dependabot pull requests are sitting on
exactly this error right now. Dependabot cannot rewrite a manifest it knows
nothing about.

The audit gains --refresh-manifest, and the failure names it. The refresh runs
every other gate first — secrets, hosted boundary, forbidden artifacts, route
and table counts, packaging, runtime — and records the tree only once they pass.
It can therefore record new hashes but never grant approval to a tree the audit
rejects. It prints which entries it added, changed or removed, so a reviewer
sees what was recorded rather than a wall of digests.

Signed-off-by: L4XB <L4XB@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

Thanks for the pull request. One required step is still open, and it is not one
a maintainer can complete for you.

Contributor License Agreement. This project records acceptance as a public
comment on the pull request itself: there is no external CLA service and no
separately stored token. Read CLA.md and post this exact
sentence as a standalone comment here:

I have read and agree to the SixSentences CLA v1.0.

The CLA / acceptance status is bound to the exact head commit and is
re-evaluated when you post the comment or push again, so nothing else is needed.

Two further gates apply to every contribution and are described in
CONTRIBUTING.md: every commit carries your own
Signed-off-by trailer (git commit -s) and is signed with your own key. A
maintainer must not add either on your behalf.

@L4XB

L4XB commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

I have read and agree to the SixSentences CLA v1.0.

@L4XB

L4XB commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

Landing through #83 with the other four changes that went BEHIND each time one of them merged. The commit is cherry-picked unchanged — message, sign-off and content. #84 carries the same tree to main.

@L4XB L4XB closed this Sep 14, 2026
auto-merge was automatically disabled September 14, 2026 08:30

Pull request was closed

@L4XB
L4XB deleted the feat/refresh-export-manifest branch September 14, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant