Commit bcee667
authored
The `/api/v1/artifacts` handler pushes externals BEFORE locals into the
results vector so the pagination window (`limit`, capped at 1000) cannot
silently drop externals off the tail.
## Root cause
`api_artifacts_external_excluded_under_variant_scope` (REQ-265b) went
red on main after commit 3d03ee3 (#743, ordeal-certificate schema) pushed
rivet's local-artifact count past 996. With local_count = 1002 + 4 spar
externals = 1006 total, the `.take(1000)` truncation cut off every
`external:spar` row — the response body carried 1000 rows all
`origin=local`, indistinguishable from the classifier failing.
The classifier itself is correct — the loop that pushes externals sets
`origin: ext_origin.clone()` (`external:<prefix>`), which appears
unchanged when queried directly via `?origin=external:spar`. What broke
was the assembly order: locals were pushed first, then externals were
appended and immediately truncated.
## Fix
Swap the two loops so externals go into `results` first. Externals are a
small set by construction (separate projects, dozens at most), so this
ordering keeps them consistently visible in any reasonable page without
a special-case pagination path or a raised limit cap.
Also lifts the `origin` grammar into two helpers so the emission site
and the `by_origin` map key cannot desync:
- `LOCAL_ORIGIN: &str = "local"`
- `external_origin(prefix: &str) -> String` → `"external:<prefix>"`
## Tests
Three new unit tests in `serve::api::tests` — matching the issue's ask
for a direct classifier-level unit test so a regression doesn't have to
travel through a full serve integration test to be noticed:
- `external_origin_matches_query_grammar` — the emitted origin string
matches the `?origin=external:<prefix>` filter grammar clients query on
- `local_origin_is_the_string_local` — pins the `LOCAL_ORIGIN` constant
- `externals_precede_locals_in_result_order` — builds the concrete
`Vec<ApiArtifact>` the handler assembles (4 externals + 1002 locals),
applies the 1000-cap slice, and asserts all four externals survive AND
no local precedes any external in the page.
The existing integration test `api_artifacts_external_excluded_under_variant_scope`
now passes; full `cargo test -p rivet-cli` (546 tests) green;
`cargo fmt --all -- --check` and `cargo clippy -p rivet-cli --all-targets -- -D warnings` clean.
## Acceptance criteria (from the issue) → how satisfied
- [x] `api_artifacts_external_excluded_under_variant_scope` passes
locally and on `main` again.
- [x] REQ-265b's exclusion mechanism (variant-scope drops externals)
preserved — the `if include_externals && variant_scope.is_none()`
gate is unchanged; the same integration test verifies both the
unscoped-includes-externals AND scoped-excludes-externals halves.
- [x] Direct unit test on the origin classification added.
Fixes: REQ-265
Refs: #778, #743
1 parent 7ceddef commit bcee667
1 file changed
Lines changed: 149 additions & 38 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
266 | 266 | | |
267 | 267 | | |
268 | 268 | | |
269 | | - | |
| 269 | + | |
270 | 270 | | |
271 | 271 | | |
272 | 272 | | |
273 | | - | |
| 273 | + | |
274 | 274 | | |
275 | 275 | | |
276 | 276 | | |
| |||
492 | 492 | | |
493 | 493 | | |
494 | 494 | | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
495 | 537 | | |
496 | 538 | | |
497 | 539 | | |
| |||
531 | 573 | | |
532 | 574 | | |
533 | 575 | | |
534 | | - | |
| 576 | + | |
535 | 577 | | |
536 | 578 | | |
537 | 579 | | |
| |||
540 | 582 | | |
541 | 583 | | |
542 | 584 | | |
543 | | - | |
544 | | - | |
545 | | - | |
546 | | - | |
547 | | - | |
548 | | - | |
549 | | - | |
550 | | - | |
551 | | - | |
552 | | - | |
553 | | - | |
554 | | - | |
555 | | - | |
556 | | - | |
557 | | - | |
558 | | - | |
559 | | - | |
560 | | - | |
561 | | - | |
562 | | - | |
563 | | - | |
564 | | - | |
565 | | - | |
566 | | - | |
567 | | - | |
568 | | - | |
569 | | - | |
570 | | - | |
571 | | - | |
572 | | - | |
573 | | - | |
574 | | - | |
575 | 585 | | |
576 | 586 | | |
577 | 587 | | |
| |||
683 | 693 | | |
684 | 694 | | |
685 | 695 | | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
686 | 708 | | |
687 | 709 | | |
688 | | - | |
| 710 | + | |
689 | 711 | | |
690 | 712 | | |
691 | 713 | | |
692 | | - | |
| 714 | + | |
693 | 715 | | |
694 | 716 | | |
695 | | - | |
| 717 | + | |
696 | 718 | | |
697 | 719 | | |
698 | 720 | | |
| |||
922 | 944 | | |
923 | 945 | | |
924 | 946 | | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
| 1031 | + | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
925 | 1036 | | |
0 commit comments