| Comment: | Merge remote-tracking branch 'origin/main' into feat/471-seed-refusal
# Conflicts: # CHANGELOG.md |
|---|---|
| Timelines: | family | ancestors | descendants | both | main | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
351bb4f35b9ca4aa05dd33a7698908e3 |
| User & Date: | [email protected] on 2026-10-24 03:22:22.000 |
| Other Links: | branch diff | manifest | tags |
|
2026-10-24
| ||
| 03:44 |
fix(sync): refuse pushed seeds by hash; judge only what a fill grounds (#471)
Horizon F.1, push side, and the fourth review's blocking finding. Refusal by hash: - seedcheck keeps two store-local tables, carried by no config group: seedpending(rid, root) and seedrefused(uuid). - A seed judged after the request that pushed it, because a later push, pull, check-in or tag filled its basis, has its hash refused. Its rows are deleted by Sweep, and only where no receive pass holds rids: end of request, end of sync, check-in, tag and rebuild. A deleted rid is reused by the next row, and a pass's caches are keyed by rid. - Until swept, such a row is withheld and never linked. A delta on a refused seed is left unreadable and pending under no root. - requestPhantoms never asks for a refused hash. ownSeedReadable refuses a re-push of one, and a full-text re-push is refused on its bytes. - A purge still forgets pending rows (ForgetDeleted). Refusals are keyed by hash, so rid reuse cannot pass them on. Judging only what a fill grounds: - JudgeReadable rescanned every pending row on each fill. A pusher could plant dangling deltas without bound and make every later fill pay for all of them. - Pending rows now record the root of their basis chain, re-rooted when that root is itself stored as a dangling delta. - JudgeFilled judges only the rows pending on the rids just stored, and reports how many it examined. - Callers: AfterDephantomize and its batch, manifest.Checkin (its files and manifest) and tag.AddTag. linkArtifact still judges a pending row it reaches, caching which tables exist per transaction. - The sweep no longer judges. A seed-shaped artifact received by pull or clone stays ordinary, per the 0.7.1 B.2. Docs and the HZ-5.2-4 scope note cite F.1. Tests: - A seed package test: one fill examines its own row, not 200 planted elsewhere. Run as a rescan mutant, it fails. - A tag whose control artifact is a seed's basis refuses the seed. - The link step refuses a seed made readable by a raw store. - A re-push refused by hash, and an igot of the hash not gimme'd. - A delta on a refused seed withheld. - A purged pending rid reused by an innocent blob. - Disabling any judge call (cascade, check-in, tag, link) or any Sweep call (request, sync, check-in, tag) fails a test. check-in: ed5e3ce5b5 user: [email protected] tags: main, trunk | |
| 03:22 |
Merge remote-tracking branch 'origin/main' into feat/471-seed-refusal
# Conflicts: # CHANGELOG.md check-in: 351bb4f35b user: [email protected] tags: main, trunk | |
| 03:06 |
Merge pull request #475 from danmestas/fix/clone-dangling-delta
fix(sync): clone an origin that holds a dangling delta check-in: 77c6eb043e user: [email protected] tags: main, trunk | |
| 02:27 |
fix(sync): withhold pending pushed artifacts; judge them when filled (#471)
Third review of the seedcheck design: - Withhold everything recorded, not just refusals. Every serving path (gimme/file, inventory and private igots, both clone paths, the client's file cards) now withholds any rid with a seedcheck row, pending or refused. A seed whose base a local check-in filled was served unjudged before. - Judge promptly. seedcheck.JudgeReadable judges, in one transaction, every pending row that has become readable, of any type: a seed is refused, anything else (files and non-artifacts too) loses its row, so withheld rows do not grow without bound. It runs in the transaction of each path that fills a basis: the dephantomize cascade, the sweep and rebuild (prepareCrosslinkTables), manifest.Checkin and tag.AddTag. Rows are walked in rid order through one cache, so a pending chain is expanded once. A row whose bytes fail their hash stays pending and withheld. - Forget on purge. shun.Purge drops seedcheck rows whose blob is gone (seedcheck.ForgetDeleted), since rids are reused. It is the only place blob rows are deleted. - One existence lookup per transaction. linkArtifact caches whether the table exists in the batch schedule, which is reset on commit and rollback. - Inventories read the withheld set fresh. The per-request cache serves gimme and clone only. Rows a request adds are its own unreadable deltas, which nothing can send, so the store-time and pre-inventory cache resets were unobservable and are gone. - The unsent delete on refusal is removed: only local writes fill unsent, so a pushed artifact is never in it. Tests: - The check-in-fills-base case no longer sweeps explicitly. It shows the seed refused in the check-in's transaction and served to neither a clone nor a pulling peer. - A pending seed is not answered on gimme or announced. - A pending plain file is served once its base arrives. - A purged seed's rid, reused by an innocent blob, is not withheld. - A private inventory withholds a privately pushed seed. - A clone does not send a refused seed as a delta source. - Disabling any serving filter fails a test. A clone of any store holding a dangling delta stalls at clone sequence 1. That is pre-existing and unrelated to seeds, so the pending-seed test checks pull and gimme instead. check-in: c72c1245b8 user: [email protected] tags: main, trunk | |