Skip to content

Commit 45edc12

Browse files
committed
engine: green the CI baseline (HAL-116) — race fix, dep + toolchain bump, lint
- toc_builder: fix the data race in verifyTitlesConcurrent — each goroutine now accumulates a local Usage and folds it under the mutex, instead of sharing &localUse across errgroup goroutines (concurrent usage.add writes). - deps: golang.org/x/net v0.53.0 -> v0.55.0 (GO-2026-5030); add toolchain go1.25.11 + pin CI go-version (stdlib GO-2026-5039 / GO-2026-5037). - lint: //lint:ignore U1000 the four staged helpers with reasons; drop the genuinely-unused idempotencyCache.mu field. These CI failures were pre-existing (surfaced on PR #35, not caused by the rename). go build + staticcheck green locally; -race verified in CI. Closes HAL-116.
1 parent dd6697b commit 45edc12

9 files changed

Lines changed: 38 additions & 19 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
fail-fast: false
1818
matrix:
1919
os: [ubuntu-latest, macos-latest, windows-latest]
20-
go: ["1.25"]
20+
go: ["1.25.11"]
2121
steps:
2222
- uses: actions/checkout@v6
2323

@@ -70,7 +70,7 @@ jobs:
7070
- name: Set up Go
7171
uses: actions/setup-go@v6
7272
with:
73-
go-version: "1.25"
73+
go-version: "1.25.11"
7474
cache: true
7575

7676
# MinIO can't run as a `services:` container because GitHub Actions
@@ -115,7 +115,7 @@ jobs:
115115
- name: Set up Go
116116
uses: actions/setup-go@v6
117117
with:
118-
go-version: "1.25"
118+
go-version: "1.25.11"
119119
cache: true
120120

121121
- name: staticcheck
@@ -137,7 +137,7 @@ jobs:
137137
- uses: actions/checkout@v6
138138
- uses: actions/setup-go@v6
139139
with:
140-
go-version: "1.25"
140+
go-version: "1.25.11"
141141
cache: true
142142
- name: Install govulncheck
143143
run: go install golang.org/x/vuln/cmd/govulncheck@latest

go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module github.com/hallelx2/vectorless-engine
22

33
go 1.25.0
4+
toolchain go1.25.11
45

56
require (
67
cloud.google.com/go/storage v1.62.1
@@ -26,7 +27,7 @@ require (
2627
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0
2728
go.opentelemetry.io/otel/sdk v1.43.0
2829
go.opentelemetry.io/otel/trace v1.43.0
29-
golang.org/x/net v0.53.0
30+
golang.org/x/net v0.55.0
3031
golang.org/x/sync v0.20.0
3132
google.golang.org/grpc v1.80.0
3233
google.golang.org/protobuf v1.36.11
@@ -118,11 +119,11 @@ require (
118119
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
119120
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
120121
go.uber.org/goleak v1.3.0 // indirect
121-
golang.org/x/crypto v0.50.0 // indirect
122+
golang.org/x/crypto v0.51.0 // indirect
122123
golang.org/x/image v0.39.0 // indirect
123124
golang.org/x/oauth2 v0.36.0 // indirect
124-
golang.org/x/sys v0.43.0 // indirect
125-
golang.org/x/text v0.36.0 // indirect
125+
golang.org/x/sys v0.45.0 // indirect
126+
golang.org/x/text v0.37.0 // indirect
126127
golang.org/x/time v0.15.0 // indirect
127128
google.golang.org/api v0.274.0 // indirect
128129
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect

go.sum

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -257,20 +257,20 @@ go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOV
257257
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
258258
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
259259
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
260-
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
261-
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
260+
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
261+
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
262262
golang.org/x/image v0.39.0 h1:skVYidAEVKgn8lZ602XO75asgXBgLj9G/FE3RbuPFww=
263263
golang.org/x/image v0.39.0/go.mod h1:sIbmppfU+xFLPIG0FoVUTvyBMmgng1/XAMhQ2ft0hpA=
264-
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
265-
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
264+
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
265+
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
266266
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
267267
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
268268
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
269269
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
270-
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
271-
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
272-
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
273-
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
270+
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
271+
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
272+
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
273+
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
274274
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
275275
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
276276
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=

internal/api/treewalk.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,8 @@ func eventToTraceMap(ev retrieval.TreeWalkEvent) map[string]any {
478478
// the in-response trace_token against the canonical input set —
479479
// kept here rather than exported from the retrieval package so
480480
// the API layer owns its own input wiring.
481+
//
482+
//lint:ignore U1000 trace-token verification helper (staged for response-integrity checks)
481483
func treeWalkTraceTokenFromCitations(docID tree.DocumentID, model string, ranges [][2]int) string {
482484
strs := make([]string, 0, len(ranges))
483485
for _, r := range ranges {

internal/middleware/cors.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ func CORS(cfg CORSConfig) func(http.Handler) http.Handler {
8888
// originMatches is a helper that checks if an origin matches any of the
8989
// patterns in the allowed list. It supports exact matches only; for
9090
// wildcard sub-domain patterns extend this function.
91+
//
92+
//lint:ignore U1000 CORS matcher (staged for wildcard-origin support)
9193
func originMatches(origin string, patterns []string) bool {
9294
for _, p := range patterns {
9395
if strings.EqualFold(origin, p) {

internal/middleware/idempotency.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ type cachedResponse struct {
3131

3232
// idempotencyCache is a thread-safe TTL map backed by sync.Map.
3333
type idempotencyCache struct {
34-
mu sync.Mutex // guards reap; reads/writes use sync.Map
35-
entries sync.Map // key -> *cachedResponse
34+
entries sync.Map // key -> *cachedResponse
3635
}
3736

3837
// get returns the cached response if it exists and has not expired.

pkg/ingest/ingest.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ func completeWithTimeout(ctx context.Context, client llmgate.Client, req llmgate
299299
// stop retrying immediately on a timeout: re-issuing a call that just hung
300300
// would only multiply the wall-time cost (N retries × the timeout) without
301301
// changing the outcome, so a timeout is terminal, not retryable.
302+
//
303+
//lint:ignore U1000 timeout classifier (staged for retry decisions, HAL-73)
302304
func isTimeout(err error) bool {
303305
return errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled)
304306
}

pkg/ingest/toc_builder.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,18 @@ func (b *TOCBuilder) verifyTitlesConcurrent(ctx context.Context, nodes []tree.TO
370370
case <-gctx.Done():
371371
return nil
372372
}
373-
startsHere, err := b.runVerifyTitleAtPageStart(gctx, n.Title, pageText, &localUse)
373+
// Accumulate this call's usage into a goroutine-local Usage,
374+
// then fold it into the shared total under the lock — passing
375+
// &localUse directly would race (concurrent usage.add writes).
376+
var u Usage
377+
startsHere, err := b.runVerifyTitleAtPageStart(gctx, n.Title, pageText, &u)
378+
mu.Lock()
379+
localUse.InputTokens += u.InputTokens
380+
localUse.OutputTokens += u.OutputTokens
381+
localUse.TotalTokens += u.TotalTokens
382+
localUse.CostUSD += u.CostUSD
383+
localUse.LLMCalls += u.LLMCalls
384+
mu.Unlock()
374385
if err != nil {
375386
// Transport / stub LLM — treat as "not verified" but
376387
// don't clear the page; the LLM never weighed in.

pkg/parser/pdf.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,8 @@ func hasRepeatedAdjacentChars(s string) bool {
14291429
// isEncryptedPDFError reports whether the given error from
14301430
// ledongthuc/pdf indicates the document is encrypted. The library
14311431
// has no proper error type for this, so we match on the message.
1432+
//
1433+
//lint:ignore U1000 encrypted-PDF detector (staged for OCR/encrypted support, HAL-112)
14321434
func isEncryptedPDFError(err error) bool {
14331435
if err == nil {
14341436
return false

0 commit comments

Comments
 (0)