Nothing enters the catalog without a usable name: the pending store (decision f amended)
Test and deploy / test (push) Successful in 56s
Test and deploy / edge (push) Successful in 2m2s
Test and deploy / deploy (push) Skipped

An unnamed release (no readable file name) is written to pending_releases
(migration 6300, the HDD) with its keys, counts, article span, upload tool
and probe targets, instead of releases, release_texts, posters and a chunk.
The edge sends it with an empty payload and its tool; the batch store splits
a batch by readable. The pending ladder (probes cheapest first, signature
verdicts, the move into the catalog) comes next. The replay report shows the
pending releases.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Daan MeijerandClaude Fable 5.1 committed 2026-10-26 13:18:14 +01:00
1 parent 6860e6ccaf
commit 9cf85e09d8
8 files changed
+286 -15

No files matched your search

+52 -1
View File
@@ -181,7 +181,13 @@ test.group('BatchStore', (group) => {
)
const first = ix.take()
const stored = await BatchStore.store(rangeId, nodeId, first)
assert.deepEqual(stored, { releases: 1, newReleases: 1, finalized: 0, candidates: 2 })
assert.deepEqual(stored, {
releases: 1,
newReleases: 1,
finalized: 0,
candidates: 2,
pending: 0,
})
const release = await db.from('releases').first()
assert.include(release, {
@@ -487,6 +493,51 @@ test.group('BatchStore', (group) => {
assert.notEqual(rows[0].release_key, rows[1].release_key)
})
test('an unnamed release goes to the pending store with its probe targets, not into the catalog', async ({
assert,
}) => {
const { rangeId, nodeId } = await rangeIn(GROUP, 1)
const batch = batchOf(GROUP, 1, [
...upload(10, 'q3B9OrpKiCxUnzgtUGnp.part01.rar', 4, '[1/2]', '2026-10-05T10:00:00Z'),
...upload(20, 'q3B9OrpKiCxUnzgtUGnp.par2', 1, '[2/2]', '2026-10-05T10:01:00Z'),
])
assert.lengthOf(batch.releases, 1)
assert.isFalse(batch.releases[0].readable)
const stored = await BatchStore.store(rangeId, nodeId, batch)
assert.include(stored, { releases: 1, newReleases: 0, candidates: 0, pending: 1 })
assert.equal(Number((await db.from('releases').count('* as n').first())!.n), 0)
assert.equal(Number((await db.from('probe_candidates').count('* as n').first())!.n), 0)
assert.equal(Number((await db.from('release_chunks').count('* as n').first())!.n), 0)
const pending = await db.from('pending_releases').firstOrFail()
assert.include(pending, {
files: 2,
segments: '5',
partial: false,
finished: true,
tool: 'other',
status: 0,
poster: 'p <p@x>',
})
assert.lengthOf(pending.release_key, 20)
assert.deepEqual(
pending.candidates.map((c: { kind: string; file: string }) => [c.kind, c.file]).sort(),
[
['archive', 'q3B9OrpKiCxUnzgtUGnp.part01.rar'],
['par2', 'q3B9OrpKiCxUnzgtUGnp.par2'],
]
)
// Sent again as a later chunk of a tail release: its counts add up while it is open, not once finished.
const again = await BatchStore.store(rangeId, nodeId, {
...batch,
from: batch.next,
next: batch.next + 1000,
releases: [{ ...batch.releases[0], files: 1, segments: 5, bytes: 100 }],
candidates: [],
})
assert.include(again, { pending: 0 })
assert.include(await db.from('pending_releases').firstOrFail(), { files: 2, segments: '5' })
})
test("an album's members stay findable by their own names (release_texts kind member)", async ({
assert,
}) => {