Phase 3, part 2 (docs/design.md, "Next"): file blocks. Moderators block a file network-wide by its sha256, so a removed product can't come back under another name or catalog.
Blocking
A file's page (Console → Blocks → a file) shows whether it's blocked and the products using it, so a moderator sees what a block removes before confirming ("Block and remove 2 products").
Moderators reach it from a product's files (each has a Block link for them) or by pasting a sha256 into the Blocks tab, which also lists blocked files.
Blocking a file:
removes every product with a revision using it. Each removal is audited as product.remove with the file, so creators are notified and can appeal it as before.
puts a {type: "block", sha256} change in the changes feed of every catalog hosting it, meaning: delete it whatever uses it. (t5de-catalog doesn't read the feed yet.)
refuses uploads with it from then on (409 blocked). Each attempt is audited as file.blocked_upload with the person and catalog, so moderators see who tried.
Unblocking lets the file in again. The products it removed stay removed until a moderator restores them, one by one.
Who: product:remove hub-wide (moderators and admins). The Blocks tab shows only for them.
API: GET /api/v1/blocks, and GET/PUT/DELETE /api/v1/blocks/:sha256 (docs/products.md).
Migration0013_file_blocks: the file_block table, and a GIN index on revisions' file lists, so finding the products using a file doesn't scan every revision.
Checks
53 API tests pass. The new blocks.test.ts covers:
who may block
the preview of what a block removes
removal of every product using the file, across catalogs and creators
the changes feed, notifications and appeals
refused uploads and their audit entry
unblocking, and restoring a removed product afterwards
Type checks pass.
On a local hub, through the website's own forms:
the Block link on a product's files, for moderators only
the Blocks tab, for moderators only (404 for the creator)
the file's page, then blocking: the product is gone, its creator notified and offered Appeal
a re-upload through the catalog API: refused, and audited
unblocking, then Restore
Fixed along the way: an empty reason gave a generic "Some of that isn't right"; it now says "Give a reason."
Phase 3, part 2 (`docs/design.md`, "Next"): file blocks. Moderators block a file network-wide by its sha256, so a removed product can't come back under another name or catalog.
**Blocking**
- A file's page (Console → Blocks → a file) shows whether it's blocked and the products using it, so a moderator sees what a block removes before confirming ("Block and remove 2 products").
- Moderators reach it from a product's files (each has a Block link for them) or by pasting a sha256 into the Blocks tab, which also lists blocked files.
- Blocking a file:
- removes every product with a revision using it. Each removal is audited as `product.remove` with the file, so creators are notified and can appeal it as before.
- puts a `{type: "block", sha256}` change in the changes feed of every catalog hosting it, meaning: delete it whatever uses it. (t5de-catalog doesn't read the feed yet.)
- refuses uploads with it from then on (409 `blocked`). Each attempt is audited as `file.blocked_upload` with the person and catalog, so moderators see who tried.
- Unblocking lets the file in again. The products it removed stay removed until a moderator restores them, one by one.
- Who: `product:remove` hub-wide (moderators and admins). The Blocks tab shows only for them.
**API**: `GET /api/v1/blocks`, and `GET`/`PUT`/`DELETE /api/v1/blocks/:sha256` (`docs/products.md`).
**Migration** `0013_file_blocks`: the `file_block` table, and a GIN index on revisions' file lists, so finding the products using a file doesn't scan every revision.
**Checks**
- 53 API tests pass. The new `blocks.test.ts` covers:
- who may block
- the preview of what a block removes
- removal of every product using the file, across catalogs and creators
- the changes feed, notifications and appeals
- refused uploads and their audit entry
- unblocking, and restoring a removed product afterwards
- Type checks pass.
- On a local hub, through the website's own forms:
- the Block link on a product's files, for moderators only
- the Blocks tab, for moderators only (404 for the creator)
- the file's page, then blocking: the product is gone, its creator notified and offered Appeal
- a re-upload through the catalog API: refused, and audited
- unblocking, then Restore
- Fixed along the way: an empty reason gave a generic "Some of that isn't right"; it now says "Give a reason."
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Moderators block a file network-wide by its sha256, from a product's files or the console's new Blocks tab, which
first shows the products using it. Blocking removes those products (their creators are told and may appeal), puts
a `block` change in the changes feed of every catalog hosting it, and refuses uploads with it; moderators see who
tried. Unblocking lets it in again; the products it removed stay removed until restored.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
dhkatz
merged commit 58a3e70a63 into main2026-11-05 22:48:08 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Phase 3, part 2 (
docs/design.md, "Next"): file blocks. Moderators block a file network-wide by its sha256, so a removed product can't come back under another name or catalog.Blocking
product.removewith the file, so creators are notified and can appeal it as before.{type: "block", sha256}change in the changes feed of every catalog hosting it, meaning: delete it whatever uses it. (t5de-catalog doesn't read the feed yet.)blocked). Each attempt is audited asfile.blocked_uploadwith the person and catalog, so moderators see who tried.product:removehub-wide (moderators and admins). The Blocks tab shows only for them.API:
GET /api/v1/blocks, andGET/PUT/DELETE /api/v1/blocks/:sha256(docs/products.md).Migration
0013_file_blocks: thefile_blocktable, and a GIN index on revisions' file lists, so finding the products using a file doesn't scan every revision.Checks
blocks.test.tscovers:🤖 Generated with Claude Code