Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions internal/quest/scroll.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func Scroll(ctx context.Context, db *sql.DB, projectID, questID string) (*Scroll
// loadNotes returns all task_notes rows for questID, oldest first.
func loadNotes(ctx context.Context, db *sql.DB, projectID, questID string) ([]NoteEntry, error) {
rows, err := db.QueryContext(ctx,
`SELECT agent_id, note, created_at
`SELECT id, agent_id, note, created_at
FROM task_notes
WHERE project_id = ? AND task_id = ?
ORDER BY created_at ASC, id ASC`,
Expand All @@ -85,8 +85,9 @@ func loadNotes(ctx context.Context, db *sql.DB, projectID, questID string) ([]No

var out []NoteEntry
for rows.Next() {
var id int64
var agentID, note, createdAt string
if err := rows.Scan(&agentID, &note, &createdAt); err != nil {
if err := rows.Scan(&id, &agentID, &note, &createdAt); err != nil {
return nil, fmt.Errorf("quest: scroll: scan note: %w", err)
}
t := parseNoteTime(createdAt)
Expand All @@ -101,7 +102,7 @@ func loadNotes(ctx context.Context, db *sql.DB, projectID, questID string) ([]No
// loadEvents returns all task_events rows for questID, oldest first.
func loadEvents(ctx context.Context, db *sql.DB, projectID, questID string) ([]EventEntry, error) {
rows, err := db.QueryContext(ctx,
`SELECT event, COALESCE(agent_id,''), COALESCE(data,''), created_at
`SELECT id, event, COALESCE(agent_id,''), COALESCE(data,''), created_at
FROM task_events
WHERE project_id = ? AND task_id = ?
ORDER BY created_at ASC, id ASC`,
Expand All @@ -114,8 +115,9 @@ func loadEvents(ctx context.Context, db *sql.DB, projectID, questID string) ([]E

var out []EventEntry
for rows.Next() {
var id int64
var event, agentID, data, createdAt string
if err := rows.Scan(&event, &agentID, &data, &createdAt); err != nil {
if err := rows.Scan(&id, &event, &agentID, &data, &createdAt); err != nil {
return nil, fmt.Errorf("quest: scroll: scan event: %w", err)
}
t := parseNoteTime(createdAt)
Expand Down
5 changes: 5 additions & 0 deletions internal/quest/scroll_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"strings"
"testing"
"time"
)

func TestScroll_FullHistory(t *testing.T) {
Expand Down Expand Up @@ -103,6 +104,10 @@ func TestScroll_OrderChronological(t *testing.T) {
if err := Journal(ctx, db, pid, q.ID, "agent", text); err != nil {
t.Fatalf("Journal: %v", err)
}
// Sleep briefly to ensure distinct timestamps for each entry.
// This guards against sub-second timestamp collisions that could
// cause flaky ordering under -race.
time.Sleep(time.Microsecond)
}

res, err := Scroll(ctx, db, pid, q.ID)
Expand Down