Files
wehub-resource-sync f99010fae1
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Windows) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

685 lines
25 KiB
Go

package db
import (
"context"
"errors"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// unitMsg builds a minimal message row for unit-range corpus seeding.
func unitMsg(sid string, ordinal int, role, content string) Message {
return Message{
SessionID: sid, Ordinal: ordinal, Role: role,
Content: content, ContentLength: len(content), Timestamp: tsZero,
}
}
// asSidechain marks a corpus message as is_sidechain.
func asSidechain(m Message) Message {
m.IsSidechain = true
return m
}
// asSystem marks a corpus message as is_system.
func asSystem(m Message) Message {
m.IsSystem = true
return m
}
// messageIsSidechain reads a message row's is_sidechain flag, the way a
// search enrichment pass carries the anchor's flag alongside the hit.
func messageIsSidechain(t *testing.T, d *DB, sessionID string, ordinal int) bool {
t.Helper()
var sidechain bool
err := d.getReader().QueryRowContext(context.Background(),
"SELECT is_sidechain FROM messages WHERE session_id = ? AND ordinal = ?",
sessionID, ordinal).Scan(&sidechain)
require.NoError(t, err)
return sidechain
}
// unitMembers returns every member ordinal of a scanned unit: the Offsets
// walk for runs, the single ordinal for user units (Offsets is nil there).
func unitMembers(u EmbeddableUnit) []int {
if u.Kind == "user" {
return []int{u.Ordinal}
}
members := make([]int, len(u.Offsets))
for i, o := range u.Offsets {
members[i] = o.Ordinal
}
return members
}
// unitAnchorForMember builds the anchor a search path would construct for a
// member ordinal of a unit: role from the unit kind, sidechain from the
// message row, embeddable by definition of unit membership.
func unitAnchorForMember(
t *testing.T, d *DB, u EmbeddableUnit, ordinal int,
) UnitAnchor {
t.Helper()
role := "user"
if u.Kind == "run" {
role = "assistant"
}
return UnitAnchor{
SessionID: u.SessionID,
Ordinal: ordinal,
Role: role,
Sidechain: messageIsSidechain(t, d, u.SessionID, ordinal),
Embeddable: true,
}
}
// countingUnitQuerier counts seam calls and probes while delegating to a
// real backend, so tests can assert batching behavior.
type countingUnitQuerier struct {
inner UnitBoundsQuerier
boundsCalls int
boundsProbes int
extentCalls int
extentProbes int
}
func (c *countingUnitQuerier) NearestUserBoundaries(
ctx context.Context, probes []UnitProbe,
) ([]UnitBounds, error) {
c.boundsCalls++
c.boundsProbes += len(probes)
return c.inner.NearestUserBoundaries(ctx, probes)
}
func (c *countingUnitQuerier) RunExtents(
ctx context.Context, probes []ExtentProbe,
) ([][2]int, error) {
c.extentCalls++
c.extentProbes += len(probes)
return c.inner.RunExtents(ctx, probes)
}
// noQueryUnitQuerier fails any seam call: anchors that resolve locally
// (rules 1/3, missing anchors) must never reach the backend.
type noQueryUnitQuerier struct{}
func (noQueryUnitQuerier) NearestUserBoundaries(
context.Context, []UnitProbe,
) ([]UnitBounds, error) {
return nil, errors.New("NearestUserBoundaries must not be called")
}
func (noQueryUnitQuerier) RunExtents(
context.Context, []ExtentProbe,
) ([][2]int, error) {
return nil, errors.New("RunExtents must not be called")
}
func TestSubordinateSession(t *testing.T) {
tests := []struct {
name string
relationshipType string
parentSessionID string
want bool
}{
{"Subagent", "subagent", "", true},
{"Fork", "fork", "", true},
{"ForkWithParent", "fork", "parent-1", true},
{"ContinuationWithParent", "continuation", "parent-1", false},
{"ParentLinkedEmptyRelationship", "", "parent-1", true},
{"ParentLinkedOtherRelationship", "related", "parent-1", true},
{"NoParentNoRelationship", "", "", false},
{"ContinuationWithoutParent", "continuation", "", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want,
SubordinateSession(tt.relationshipType, tt.parentSessionID))
})
}
}
// seedUnitRangeCorpus seeds sessions covering every structural case the
// reducer handles: plain runs, runs at session start/end, sidechain flips
// mid-run, a sidechain user boundary, system and system-prefixed rows inside
// runs and adjacent to run boundaries, a prefix-looking assistant row (which
// stays embeddable: SystemPrefixSQL only constrains user rows), single-message
// runs, and automated/subagent/fork/continuation/parent-linked sessions.
// It returns the expected total unit count.
func seedUnitRangeCorpus(t *testing.T, d *DB) int {
t.Helper()
insertSession(t, d, "s-plain", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-plain", 0, "user", "u0"),
unitMsg("s-plain", 1, "assistant", "a1"),
unitMsg("s-plain", 2, "assistant", "a2"),
unitMsg("s-plain", 3, "user", "u3"),
unitMsg("s-plain", 4, "assistant", "a4"),
unitMsg("s-plain", 5, "user", "<task-notification> not a boundary"),
unitMsg("s-plain", 6, "assistant", "a6"),
unitMsg("s-plain", 7, "user", "u7"),
)
// Units: user[0], run[1,2], user[3], run members {4,6} -> [4,6], user[7].
insertSession(t, d, "s-edges", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-edges", 0, "assistant", "a0"),
unitMsg("s-edges", 1, "assistant", "a1"),
unitMsg("s-edges", 2, "user", "u2"),
unitMsg("s-edges", 3, "assistant", "a3"),
unitMsg("s-edges", 4, "assistant", "a4"),
)
// Units: run[0,1] at session start, user[2], run[3,4] at session end.
insertSession(t, d, "s-side", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-side", 0, "user", "u0"),
unitMsg("s-side", 1, "assistant", "a1"),
asSidechain(unitMsg("s-side", 2, "assistant", "a2")),
asSidechain(unitMsg("s-side", 3, "assistant", "a3")),
unitMsg("s-side", 4, "assistant", "a4"),
asSidechain(unitMsg("s-side", 5, "user", "u5")),
unitMsg("s-side", 6, "assistant", "a6"),
)
// Units: user[0], run[1,1], sidechain run[2,3], run[4,4],
// sidechain user[5] (a user boundary regardless of sidechain), run[6,6].
insertSession(t, d, "s-system", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-system", 0, "user", "u0"),
asSystem(unitMsg("s-system", 1, "assistant", "sys adjacent to start")),
unitMsg("s-system", 2, "assistant", "a2"),
unitMsg("s-system", 3, "system", "system-role row"),
unitMsg("s-system", 4, "assistant", "a4"),
asSystem(unitMsg("s-system", 5, "assistant", "sys adjacent to end")),
unitMsg("s-system", 6, "user", "u6"),
unitMsg("s-system", 7, "assistant", "<command-message> prefixed assistant stays embeddable"),
unitMsg("s-system", 8, "assistant", "a8"),
)
// Units: user[0], run members {2,4} -> [2,4], user[6], run[7,8].
insertSession(t, d, "s-auto", "proj", func(s *Session) {
s.EndedAt = Ptr(tsHour1)
s.IsAutomated = true
})
insertMessages(t, d,
unitMsg("s-auto", 0, "user", "u0"),
unitMsg("s-auto", 1, "assistant", "a1"),
unitMsg("s-auto", 2, "assistant", "a2"),
)
// Units: user[0], run[1,2].
insertSession(t, d, "s-subagent", "proj", func(s *Session) {
s.EndedAt = Ptr(tsHour1)
s.RelationshipType = "subagent"
})
insertMessages(t, d,
unitMsg("s-subagent", 0, "assistant", "a0"),
unitMsg("s-subagent", 1, "assistant", "a1"),
)
// Units: run[0,1].
insertSession(t, d, "s-fork", "proj", func(s *Session) {
s.EndedAt = Ptr(tsHour1)
s.RelationshipType = "fork"
s.ParentSessionID = Ptr("s-plain")
})
insertMessages(t, d, unitMsg("s-fork", 0, "user", "u0"))
// Units: user[0].
insertSession(t, d, "s-cont", "proj", func(s *Session) {
s.EndedAt = Ptr(tsHour1)
s.RelationshipType = "continuation"
s.ParentSessionID = Ptr("s-plain")
})
insertMessages(t, d,
unitMsg("s-cont", 0, "user", "u0"),
unitMsg("s-cont", 1, "assistant", "a1"),
)
// Units: user[0], run[1,1].
insertSession(t, d, "s-parent-linked", "proj", func(s *Session) {
s.EndedAt = Ptr(tsHour1)
s.ParentSessionID = Ptr("s-plain")
})
insertMessages(t, d, unitMsg("s-parent-linked", 1, "assistant", "a1"))
// Units: run[1,1].
insertSession(t, d, "s-sys-flip", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-sys-flip", 0, "user", "u0"),
unitMsg("s-sys-flip", 1, "assistant", "a1"),
asSystem(asSidechain(unitMsg("s-sys-flip", 2, "assistant", "sys+sidechain, not a flip"))),
unitMsg("s-sys-flip", 3, "assistant", "a3"),
unitMsg("s-sys-flip", 4, "user", "u4"),
)
// Units: user[0], run members {1,3} -> [1,3] (the is_system=1,
// is_sidechain=1 assistant row at 2 is invisible: it must not act as a
// flip boundary despite its opposite sidechain flag), user[4].
insertSession(t, d, "s-dense", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-dense", 0, "user", "u0"),
unitMsg("s-dense", 1, "assistant", "d1"),
unitMsg("s-dense", 2, "user", "<task-notification> not a boundary"),
unitMsg("s-dense", 3, "assistant", "d3"),
unitMsg("s-dense", 4, "assistant", "d4"),
unitMsg("s-dense", 5, "user", "u5"),
unitMsg("s-dense", 6, "assistant", "d6"),
asSystem(unitMsg("s-dense", 7, "assistant", "sys inside run")),
unitMsg("s-dense", 8, "assistant", "d8"),
unitMsg("s-dense", 9, "assistant", "d9"),
asSidechain(unitMsg("s-dense", 10, "assistant", "sc10")),
asSidechain(unitMsg("s-dense", 11, "assistant", "sc11")),
asSidechain(unitMsg("s-dense", 12, "assistant", "sc12")),
unitMsg("s-dense", 13, "assistant", "d13"),
unitMsg("s-dense", 14, "assistant", "d14"),
unitMsg("s-dense", 15, "assistant", "d15"),
unitMsg("s-dense", 16, "user", "u16"),
)
// The dense-flow session: 12 run-member anchors in one session, so a page
// of all of them clears UnitBoundsFlowFactor. Units: user[0], run members
// {1,3,4} -> [1,4] (spanning the prefixed user row), user[5], run members
// {6,8,9} -> [6,9] (spanning the system row), sidechain run[10,12],
// run[13,15] (flip-bounded on the left, user-bounded on the right),
// user[16].
return 5 + 3 + 6 + 4 + 2 + 1 + 1 + 2 + 1 + 3 + 7
}
// TestDeriveUnitRangesReducerEquivalence is the invariant test: for every
// unit ScanEmbeddableUnits produces over the corpus (includeAutomated=true)
// and every member ordinal of that unit, DeriveUnitRanges must return exactly
// [unit.Ordinal, unit.OrdinalEnd]; user units must map to [o, o]. The units
// are checked both in one batched call over all anchors (exercising probe
// dedup across multi-run sessions) and one call per anchor (no dedup to
// exercise, each call trivially batches a single probe).
func TestDeriveUnitRangesReducerEquivalence(t *testing.T) {
d := testDB(t)
wantUnits := seedUnitRangeCorpus(t, d)
units, _ := scanUnits(t, d, "", true)
require.Len(t, units, wantUnits, "corpus produced an unexpected unit count")
ctx := context.Background()
var anchors []UnitAnchor
var want [][2]int
for _, u := range units {
for _, member := range unitMembers(u) {
anchors = append(anchors, unitAnchorForMember(t, d, u, member))
want = append(want, [2]int{u.Ordinal, u.OrdinalEnd})
if u.Kind == "user" {
assert.Equal(t, u.Ordinal, u.OrdinalEnd,
"user unit %s#%d must be a single-ordinal unit",
u.SessionID, u.Ordinal)
}
}
}
got, err := DeriveUnitRanges(ctx, d, anchors)
require.NoError(t, err)
require.Len(t, got, len(anchors))
for i, a := range anchors {
assert.Equal(t, want[i], got[i],
"batched derivation for anchor %s#%d", a.SessionID, a.Ordinal)
}
for i, a := range anchors {
single, err := DeriveUnitRanges(ctx, d, []UnitAnchor{a})
require.NoError(t, err)
require.Len(t, single, 1)
assert.Equal(t, want[i], single[0],
"per-anchor derivation for anchor %s#%d", a.SessionID, a.Ordinal)
}
}
// TestDeriveUnitRangesReducerEquivalenceDenseFlow is the dense-flow variant
// of the invariant test: a page holding every run-member anchor of the
// structurally rich s-dense corpus session (multi-run, sidechain flip,
// prefixed user row, and system rows) clears UnitBoundsFlowFactor, so
// derivation fetches real user bounds with one NearestUserBoundaries call —
// and must still return exactly the reducer's extents, identical to the
// sparse per-anchor derivation.
func TestDeriveUnitRangesReducerEquivalenceDenseFlow(t *testing.T) {
d := testDB(t)
seedUnitRangeCorpus(t, d)
units, _ := scanUnits(t, d, "", true)
ctx := context.Background()
var anchors []UnitAnchor
var want [][2]int
for _, u := range units {
if u.SessionID != "s-dense" || u.Kind != "run" {
continue
}
for _, member := range unitMembers(u) {
anchors = append(anchors, unitAnchorForMember(t, d, u, member))
want = append(want, [2]int{u.Ordinal, u.OrdinalEnd})
}
}
require.GreaterOrEqual(t, len(anchors), UnitBoundsFlowFactor,
"s-dense must supply at least UnitBoundsFlowFactor distinct run anchors "+
"in one session; extend the corpus session if the factor grows")
q := &countingUnitQuerier{inner: d}
got, err := DeriveUnitRanges(ctx, q, anchors)
require.NoError(t, err)
require.Len(t, got, len(anchors))
for i, a := range anchors {
assert.Equal(t, want[i], got[i],
"dense-flow derivation for anchor %s#%d", a.SessionID, a.Ordinal)
}
assert.Equal(t, 1, q.boundsCalls,
"dense page must fetch real user bounds (dense flow)")
// The sparse flow must agree exactly: one probe per call stays under the
// flow gate and probes with sentinel bounds.
for i, a := range anchors {
single, err := DeriveUnitRanges(ctx, d, []UnitAnchor{a})
require.NoError(t, err)
require.Len(t, single, 1)
assert.Equal(t, want[i], single[0],
"sparse derivation for anchor %s#%d", a.SessionID, a.Ordinal)
}
}
// TestDeriveUnitRangesLocalAnchors asserts rule-1, rule-3, and missing
// anchors resolve to [o, o] without ever touching the backend seam.
func TestDeriveUnitRangesLocalAnchors(t *testing.T) {
tests := []struct {
name string
anchor UnitAnchor
}{
{"EmbeddableUserRule1", UnitAnchor{
SessionID: "s", Ordinal: 3, Role: "user", Embeddable: true,
}},
{"SystemRowInsideRun", UnitAnchor{
SessionID: "s", Ordinal: 4, Role: "assistant", Embeddable: false,
}},
{"ToolRoleRow", UnitAnchor{
SessionID: "s", Ordinal: 5, Role: "tool", Embeddable: true,
}},
{"PrefixedUserRow", UnitAnchor{
SessionID: "s", Ordinal: 6, Role: "user", Embeddable: false,
}},
{"MissingAnchor", UnitAnchor{
SessionID: "s", Ordinal: 42, Missing: true,
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := DeriveUnitRanges(
context.Background(), noQueryUnitQuerier{},
[]UnitAnchor{tt.anchor},
)
require.NoError(t, err)
require.Len(t, got, 1)
assert.Equal(t, [2]int{tt.anchor.Ordinal, tt.anchor.Ordinal}, got[0])
})
}
}
// TestDeriveUnitRangesEmptyAnchors asserts an empty anchor list returns an
// empty result without backend calls.
func TestDeriveUnitRangesEmptyAnchors(t *testing.T) {
got, err := DeriveUnitRanges(
context.Background(), noQueryUnitQuerier{}, nil,
)
require.NoError(t, err)
assert.Empty(t, got)
}
// TestDeriveUnitRangesBatchesRunAnchors pins the DENSE flow's call counts: a
// session-dense page of anchors inside one run costs exactly one
// NearestUserBoundaries CALL (the anchor count is derived from
// UnitBoundsFlowFactor so the single-session page always clears the gate;
// every pending anchor rides one batch with duplicate (session, ordinal)
// anchors sharing one probe) and one RunExtents CALL carrying just ONE
// probe: the anchors share a (session, bounds, sidechain) group, so a single
// representative resolves the run and its extent is handed to every anchor
// it covers with no second round.
func TestDeriveUnitRangesBatchesRunAnchors(t *testing.T) {
d := testDB(t)
// Comfortably past the gate in one session, with the run extending on
// both sides of the anchored ordinals.
anchorCount := 2*UnitBoundsFlowFactor + 4
runLen := anchorCount + 5
insertSession(t, d, "s-batch", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
msgs := []Message{unitMsg("s-batch", 0, "user", "u0")}
for i := 1; i <= runLen; i++ {
msgs = append(msgs, unitMsg("s-batch", i, "assistant", "a"))
}
msgs = append(msgs, unitMsg("s-batch", runLen+1, "user", "u-end"))
insertMessages(t, d, msgs...)
anchors := make([]UnitAnchor, 0, anchorCount+1)
for o := 2; o < 2+anchorCount; o++ {
anchors = append(anchors, UnitAnchor{
SessionID: "s-batch", Ordinal: o, Role: "assistant",
Embeddable: true,
})
}
// Duplicate of the first anchor: must reuse its probe, not add one.
anchors = append(anchors, anchors[0])
q := &countingUnitQuerier{inner: d}
got, err := DeriveUnitRanges(context.Background(), q, anchors)
require.NoError(t, err)
require.Len(t, got, len(anchors))
for i := range got {
assert.Equal(t, [2]int{1, runLen}, got[i], "anchor %d", anchors[i].Ordinal)
}
assert.Equal(t, 1, q.boundsCalls, "NearestUserBoundaries calls (dense page)")
assert.Equal(t, anchorCount, q.boundsProbes, "NearestUserBoundaries probes")
assert.Equal(t, 1, q.extentCalls, "RunExtents calls")
assert.Equal(t, 1, q.extentProbes, "RunExtents probes (one group representative)")
}
// TestDeriveUnitRangesSecondRoundAcrossFlip seeds one user interval holding
// two runs separated by a sidechain flip and anchors both runs' main-chain
// members. The main-chain anchors share one (session, interval, sidechain)
// group but sit in different runs, so the round-one representative's extent
// cannot cover the anchors past the flip: they must resolve in exactly one
// second RunExtents round, with correct per-run extents.
func TestDeriveUnitRangesSecondRoundAcrossFlip(t *testing.T) {
d := testDB(t)
insertSession(t, d, "s-flip2", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-flip2", 0, "user", "u0"),
unitMsg("s-flip2", 1, "assistant", "run1-a"),
unitMsg("s-flip2", 2, "assistant", "run1-b"),
asSidechain(unitMsg("s-flip2", 3, "assistant", "sidechain flip")),
unitMsg("s-flip2", 4, "assistant", "run2-a"),
unitMsg("s-flip2", 5, "assistant", "run2-b"),
unitMsg("s-flip2", 6, "user", "u6"),
)
anchors := []UnitAnchor{
{SessionID: "s-flip2", Ordinal: 1, Role: "assistant", Embeddable: true},
{SessionID: "s-flip2", Ordinal: 2, Role: "assistant", Embeddable: true},
{SessionID: "s-flip2", Ordinal: 4, Role: "assistant", Embeddable: true},
{SessionID: "s-flip2", Ordinal: 5, Role: "assistant", Embeddable: true},
}
// This test pins the SPARSE flow: the page must stay under the gate so no
// NearestUserBoundaries round runs. Guard the coupling explicitly instead
// of letting a lowered UnitBoundsFlowFactor flip the flow silently.
require.Less(t, len(anchors), UnitBoundsFlowFactor,
"across-flip page must stay sparse; restructure the test if the flow factor shrinks")
q := &countingUnitQuerier{inner: d}
got, err := DeriveUnitRanges(context.Background(), q, anchors)
require.NoError(t, err)
require.Len(t, got, len(anchors))
assert.Equal(t, [2]int{1, 2}, got[0], "run 1 anchor 1")
assert.Equal(t, [2]int{1, 2}, got[1], "run 1 anchor 2")
assert.Equal(t, [2]int{4, 5}, got[2], "run 2 anchor 4")
assert.Equal(t, [2]int{4, 5}, got[3], "run 2 anchor 5")
assert.Equal(t, 0, q.boundsCalls,
"NearestUserBoundaries calls (sparse page probes with sentinel bounds)")
assert.Equal(t, 2, q.extentCalls,
"RunExtents calls (representative round + across-flip remainder)")
assert.Equal(t, 3, q.extentProbes,
"RunExtents probes (1 representative + 2 across the flip)")
}
// TestDeriveUnitRangesNonMemberSpan asserts a run whose members are {5, 7}
// (system row at 6) derives [5, 7] from either member anchor, and that
// system rows at 3-4 and 8-9 sitting between the user boundaries do not
// widen the range past the first/last member.
func TestDeriveUnitRangesNonMemberSpan(t *testing.T) {
d := testDB(t)
insertSession(t, d, "s-span", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-span", 2, "user", "u2"),
asSystem(unitMsg("s-span", 3, "assistant", "sys3")),
asSystem(unitMsg("s-span", 4, "assistant", "sys4")),
unitMsg("s-span", 5, "assistant", "member5"),
asSystem(unitMsg("s-span", 6, "assistant", "sys6")),
unitMsg("s-span", 7, "assistant", "member7"),
asSystem(unitMsg("s-span", 8, "assistant", "sys8")),
asSystem(unitMsg("s-span", 9, "assistant", "sys9")),
unitMsg("s-span", 10, "user", "u10"),
)
for _, ordinal := range []int{5, 7} {
got, err := DeriveUnitRanges(context.Background(), d, []UnitAnchor{{
SessionID: "s-span", Ordinal: ordinal, Role: "assistant",
Embeddable: true,
}})
require.NoError(t, err)
require.Len(t, got, 1)
assert.Equal(t, [2]int{5, 7}, got[0], "anchor at ordinal %d", ordinal)
}
}
// TestNearestUserBoundariesSentinels asserts the seam returns Prev=-1 and
// Next=UnitOrdinalMax when no embeddable user row exists on that side, and
// real exclusive boundaries otherwise (ignoring system-prefixed user rows
// and the anchor's own ordinal). The empty-content user row at 5 pins the
// SQLite first-code-point guard's COALESCE path: unicode(”) is NULL, and an
// empty user row is still an embeddable boundary.
func TestNearestUserBoundariesSentinels(t *testing.T) {
d := testDB(t)
insertSession(t, d, "s-b", "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg("s-b", 0, "assistant", "a0"),
unitMsg("s-b", 1, "user", "u1"),
unitMsg("s-b", 2, "assistant", "a2"),
unitMsg("s-b", 3, "user", "<command-message> prefixed, not a boundary"),
unitMsg("s-b", 4, "assistant", "a4"),
unitMsg("s-b", 5, "user", ""),
unitMsg("s-b", 6, "assistant", "a6"),
)
got, err := d.NearestUserBoundaries(context.Background(), []UnitProbe{
{SessionID: "s-b", Ordinal: 0},
{SessionID: "s-b", Ordinal: 2},
{SessionID: "s-b", Ordinal: 4},
{SessionID: "s-b", Ordinal: 1},
{SessionID: "s-b", Ordinal: 6},
})
require.NoError(t, err)
require.Len(t, got, 5)
assert.Equal(t, UnitBounds{Prev: -1, Next: 1}, got[0],
"no user row before session start")
assert.Equal(t, UnitBounds{Prev: 1, Next: 5}, got[1],
"prefixed user row at 3 must not be a boundary; empty user row at 5 is")
assert.Equal(t, UnitBounds{Prev: 1, Next: 5}, got[2],
"empty-content user row is an embeddable boundary")
assert.Equal(t, UnitBounds{Prev: -1, Next: 5}, got[3],
"boundaries are exclusive of the probe ordinal itself")
assert.Equal(t, UnitBounds{Prev: 5, Next: UnitOrdinalMax}, got[4],
"no user row after the last assistant")
}
// TestUnitBoundsQuerierChunkingAlignment seeds more sessions than either
// seam method batches into one statement (unitSessionChunk sessions for
// NearestUserBoundaries, unitExtentChunk probes for RunExtents), so both
// must run their per-chunk loop across multiple statements. Each session k
// gets its own ordinal base (b = 10*k), so its boundary/extent answer is
// unique to that session: {Prev: b, Next: b+3} and extent [b+1, b+2]. A
// chunk-boundary slicing bug (e.g. an off-by-one in the chunk start/end
// arithmetic) either drops a slot (surfacing as an "index out of range" or
// row-count error) or shifts results between neighboring sessions — and
// because every session's expected value differs from its neighbors', a
// shift produces a wrong value rather than a coincidentally correct one.
// Every probe's expected value is asserted individually against its own
// session's base, so a single misattributed slot fails the assertion for
// that specific session.
func TestUnitBoundsQuerierChunkingAlignment(t *testing.T) {
d := testDB(t)
ctx := context.Background()
// >1 chunk boundary crossed for both methods (unitExtentChunk is the
// smaller of the two).
const n = max(unitSessionChunk, unitExtentChunk) + 20
sessionID := func(k int) string { return fmt.Sprintf("s-chunk-%d", k) }
base := func(k int) int { return k * 10 }
for k := range n {
b := base(k)
insertSession(t, d, sessionID(k), "proj", func(s *Session) { s.EndedAt = Ptr(tsHour1) })
insertMessages(t, d,
unitMsg(sessionID(k), b, "user", "u-before"),
unitMsg(sessionID(k), b+1, "assistant", "member1"),
unitMsg(sessionID(k), b+2, "assistant", "member2"),
unitMsg(sessionID(k), b+3, "user", "u-after"),
)
}
boundProbes := make([]UnitProbe, n)
for k := range boundProbes {
b := base(k)
ordinal := b + 1
if k%2 == 1 {
ordinal = b + 2
}
boundProbes[k] = UnitProbe{SessionID: sessionID(k), Ordinal: ordinal}
}
bounds, err := d.NearestUserBoundaries(ctx, boundProbes)
require.NoError(t, err)
require.Len(t, bounds, n)
for k, got := range bounds {
b := base(k)
assert.Equal(t, UnitBounds{Prev: b, Next: b + 3}, got,
"bound probe for session %s", sessionID(k))
}
extentProbes := make([]ExtentProbe, n)
for k := range extentProbes {
b := base(k)
ordinal := b + 1
if k%2 == 1 {
ordinal = b + 2
}
extentProbes[k] = ExtentProbe{
SessionID: sessionID(k), Ordinal: ordinal, Lo: b, Hi: b + 3,
}
}
extents, err := d.RunExtents(ctx, extentProbes)
require.NoError(t, err)
require.Len(t, extents, n)
for k, got := range extents {
b := base(k)
assert.Equal(t, [2]int{b + 1, b + 2}, got,
"extent probe for session %s", sessionID(k))
}
}
// TestRunExtentsAnchorRowMissingErrors asserts the seam fails fast with
// context when a probe's anchor row does not qualify (here: the session does
// not exist), instead of silently returning a zero range.
func TestRunExtentsAnchorRowMissingErrors(t *testing.T) {
d := testDB(t)
_, err := d.RunExtents(context.Background(), []ExtentProbe{{
SessionID: "no-such-session", Ordinal: 3,
Lo: -1, Hi: UnitOrdinalMax,
}})
require.Error(t, err)
assert.Contains(t, err.Error(), "no-such-session")
}