The rehearsal's inbound-level totals never moved: the agent reports sing-box tags (inbound-<port>) while the master's agent traffic handler matches inbound rows by their panel tag — which the B1 model renamed to the n<node>-in- scheme, so the lookup silently matched nothing (per-user totals, keyed by email, were unaffected; production on V1 keeps the old tag form and is not hit until the V2 migration itself). The converter now takes the row's panel tag as the fragment tag (migrator passes it through), making one identity serve the DB row, the generated config, core stats and traffic reports. Bare fixtures without a panel tag keep the historical form.
ITEM6 golden fixtures (B0)
Per-protocol × representative-transport fixtures for the xray→sing-box
migration. Consumed by B1 (data model + migrator) and B2 (config builder)
as the acceptance baseline; see ITEM6-CONVERSION-SPEC.md in
~/workspace/xui-lite-work/ for the normative mapping behind every file.
Layout
testdata/golden/<case>/
input.json current-shape sample (see below)
expected-singbox.json expected converter output fragment
expected-link.txt expected share link for the primary client
input.json fields: case, title, source (where the shape was taken
from — frontend defaults / backend tests / production backup traits),
disposition, risk (ITEM6-SCOPE N-number or null), notes, inbound
(a model.Inbound row shape: settings / streamSettings / sniffing
as embedded objects), clientEmail, client (the primary client's
settings-mirror entry — the same object embedded in settings.clients
where the protocol carries one).
expected-singbox.json is a fragment: inbounds[] (and endpoints[]
for WireGuard). Keys starting with _ are fixture metadata (_b0:
disposition, unmapped concepts awaiting Q1, notes) and are stripped
before comparison. Blocked cases intentionally contain no fabricated
output — inbounds is empty and _b0.unmapped records exactly what has
no sing-box carrier, pending the user's Q1 decision.
Provenance of the link baselines
expected-link.txt files were generated on 2026-10-23 by running the
current code (main 8e89960) SubService.GetLink over each
input.json inbound — i.e. they are the pre-migration outputs the
migration must reproduce byte for byte (ITEM6-SCOPE §2.4). A throwaway
harness test produced them and was deleted afterwards; regenerate only
by re-running GetLink against the same inputs on pre-migration code.
Empty files are real current behaviour for http-auth, tun and
tunnel-dokodemo (no share link exists today).
All credentials in this corpus are fake (sequential-byte X25519/WireGuard
keys, fx- passwords, TEST-NET 203.0.113.10). In fixtures, listen
doubles as the resolved share address, mirroring the characterization
tests in internal/sub; bind-address defaults are B2 base-config
business, not fixture content.
Baseline scope: links only
Per the 2026-10-23 product decision, the JSON and Clash subscription families are being deleted wholesale (separate work line); subscriptions converge on the link format only. No Clash/JSON baselines are built or kept here, and ITEM6-SCOPE Q2 is closed by that decision.
Dispositions
direct— full mapping defined; B2 must reproduce the fragment.partial-pending-q1— mappable body is in the fragment;_b0.unmappedlists concepts with no sing-box carrier, awaiting Q1.blocked-pending-q1— no valid output exists until Q1 picks a carrier; fragment is an explicit marker, not a silent drop.external-runtime— protocol never enters the core (mtproto, amneziawg); the migration duty is verbatim data passthrough only.