You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/api/v1/artifacts caps limit at 1000 (rivet-cli/src/serve/api.rs:459, same
at :630). The rivet repo now holds 1017 artifacts. A client asking for
everything gets 1000 rows back with no indication that 17 were dropped.
A cap is fine. A silent cap is not. The response carries total: 1017 next to
a 1000-element array, so the data needed to detect truncation is present — but
nothing in the response says "this is a partial view", and every consumer that
reads artifacts as the full set is silently wrong. This is the same shape as
the v0.33.0 gate work: the call succeeds, the payload looks complete, and the
missing part is invisible.
Two concrete consequences already visible:
Tests can encode a false premise.serve_integration.rs:569 asserts externals_unscoped > 0 on origin=all&limit=1000, i.e. it assumes that
window contains every artifact. It does not. The externals happen to sit at
positions 0–3 today, so it passes — by luck of ordering, not by construction.
Combine the two and you get a silently truncated, non-deterministically ordered
"give me everything" response — which is a bad foundation for a dashboard, an
export, or an assertion.
Suggested fix
Cheapest honest version, in order:
Say so in the payload. Add truncated: true (or returned alongside total) whenever artifacts.len() < total. Consumers can then fail loudly
instead of guessing.
Decide the cap deliberately. Either keep 1000 and document it as a
paging boundary with a working offset/cursor, or let limit=0/limit=all
mean "no cap" for the machine-readable endpoint.
Step 1 alone converts this from silent to detectable and is worth doing on its
own.
Summary
/api/v1/artifactscapslimitat 1000 (rivet-cli/src/serve/api.rs:459, sameat
:630). The rivet repo now holds 1017 artifacts. A client asking foreverything gets 1000 rows back with no indication that 17 were dropped.
Reproduce
Why this is a weak-green defect, not just a cap
A cap is fine. A silent cap is not. The response carries
total: 1017next toa 1000-element array, so the data needed to detect truncation is present — but
nothing in the response says "this is a partial view", and every consumer that
reads
artifactsas the full set is silently wrong. This is the same shape asthe v0.33.0 gate work: the call succeeds, the payload looks complete, and the
missing part is invisible.
Two concrete consequences already visible:
serve_integration.rs:569assertsexternals_unscoped > 0onorigin=all&limit=1000, i.e. it assumes thatwindow contains every artifact. It does not. The externals happen to sit at
positions 0–3 today, so it passes — by luck of ordering, not by construction.
main, so which 17 fall off the endvaries run to run. Measured over 3 identical runs against the same store, the
external block came back
PROC, REQ, SYS, THR/REQ, THR, SYS, PROC/PROC, REQ, SYS, THR. (Overlapping sources make every id collide with itself (184 phantom errors masked 6 real); non-deterministic output order breaks report diffing #746 / fix(validate): dedupe overlapping sources + deterministic diagnostic order (#746) #759 addresses the determinism half.)Combine the two and you get a silently truncated, non-deterministically ordered
"give me everything" response — which is a bad foundation for a dashboard, an
export, or an assertion.
Suggested fix
Cheapest honest version, in order:
truncated: true(orreturnedalongsidetotal) wheneverartifacts.len() < total. Consumers can then fail loudlyinstead of guessing.
stable sort by id when no explicit sort is requested. (Overlapping sources make every id collide with itself (184 phantom errors masked 6 real); non-deterministic output order breaks report diffing #746 / fix(validate): dedupe overlapping sources + deterministic diagnostic order (#746) #759 does this
for the source/diagnostic side.)
paging boundary with a working
offset/cursor, or letlimit=0/limit=allmean "no cap" for the machine-readable endpoint.
Step 1 alone converts this from silent to detectable and is worth doing on its
own.
Related
validatePASSes andcoveragereports 100.0% #808 — same "the check passes and checks nothing" family