Skip to content
Open
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
53 changes: 53 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# .github/workflows/ci.yml
# Created 2026-08-13: first CI gate for this repo. Until now kb-go had no
# workflows at all — nothing checked formatting, vet, build, or tests on a PR.
# Every step was measured against origin/main before being added: vet clean,
# build clean, tests passing. gofmt flagged 7 files, fixed by `gofmt -w` in this
# same commit so the gate starts green rather than red. Kept to the Go
# toolchain's own checks — no third-party linter — so there is nothing extra to
# install or keep in sync.
name: CI

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: gofmt
run: |
unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then
echo "::error::These files are not gofmt-formatted. Run: gofmt -w ."
echo "$unformatted"
exit 1
fi

- name: go vet
run: go vet ./...

- name: Build
run: go build ./...

- name: Test
run: go test ./...
12 changes: 6 additions & 6 deletions convo.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,9 +782,9 @@ func cmdConvoSearch(args []string) {
results := bm25Search(convoArticles, query, limit)
if jsonOut {
type result struct {
ID string `json:"id"`
Title string `json:"title"`
Summary string `json:"summary"`
ID string `json:"id"`
Title string `json:"title"`
Summary string `json:"summary"`
Concepts []string `json:"concepts"`
}
var out []result
Expand Down Expand Up @@ -826,9 +826,9 @@ func cmdConvoList(args []string) {

if jsonOut {
type item struct {
ID string `json:"id"`
Title string `json:"title"`
Summary string `json:"summary"`
ID string `json:"id"`
Title string `json:"title"`
Summary string `json:"summary"`
Concepts []string `json:"concepts"`
}
var out []item
Expand Down
2 changes: 1 addition & 1 deletion examples/small/go/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (c *Config) Validate() error {

// Sentinel errors for configuration validation.
var (
ErrInvalidPort = &ConfigError{Field: "port", Message: "must be between 1 and 65535"}
ErrInvalidPort = &ConfigError{Field: "port", Message: "must be between 1 and 65535"}
ErrMissingDatabase = &ConfigError{Field: "database_url", Message: "is required"}
)

Expand Down
6 changes: 3 additions & 3 deletions examples/small/go/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const (

// Priority levels.
const (
PriorityLow = 1
PriorityMedium = 2
PriorityHigh = 3
PriorityLow = 1
PriorityMedium = 2
PriorityHigh = 3
PriorityCritical = 4
)

Expand Down
10 changes: 5 additions & 5 deletions glossary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func TestIsGlossarySource(t *testing.T) {
{"docs/glossary/soul.md", true},
{"docs/wiki/glossary/ripple.md", true},
{"src/pocket.go", false},
{"glossary.md", false}, // not inside a glossary/ dir
{"glossary.md", false}, // not inside a glossary/ dir
{"glossaries/pocket.md", false}, // plural — distinct dirname
{"", false},
}
Expand Down Expand Up @@ -582,8 +582,8 @@ func containsIssue(issues []string, needle string) bool {
// and the contract conversation surfaces in code review rather than a buried
// runtime mismatch.
var (
_ func(string, io.Writer) error = glossaryList
_ func(string, string, io.Writer) error = glossaryShow
_ func(string) ([]string, error) = glossaryValidate
_ func(string) bool = isGlossarySource
_ func(string, io.Writer) error = glossaryList
_ func(string, string, io.Writer) error = glossaryShow
_ func(string) ([]string, error) = glossaryValidate
_ func(string) bool = isGlossarySource
)
14 changes: 7 additions & 7 deletions longmemeval_errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import (
)

type MissedQuestion struct {
ID string `json:"id"`
Type string `json:"type"`
Question string `json:"question"`
TopRanked string `json:"top_ranked_session"`
CorrectIDs []string `json:"correct_ids"`
CorrectRank int `json:"correct_rank"` // -1 if not found in any rank
InTop10 bool `json:"in_top_10"`
ID string `json:"id"`
Type string `json:"type"`
Question string `json:"question"`
TopRanked string `json:"top_ranked_session"`
CorrectIDs []string `json:"correct_ids"`
CorrectRank int `json:"correct_rank"` // -1 if not found in any rank
InTop10 bool `json:"in_top_10"`
}

func TestLongMemEval_ErrorAnalysis(t *testing.T) {
Expand Down
40 changes: 20 additions & 20 deletions longmemeval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ import (
// --- LongMemEval data structures ---

type LMEQuestion struct {
QuestionID string `json:"question_id"`
QuestionType string `json:"question_type"`
Question string `json:"question"`
Answer json.RawMessage `json:"answer"`
QuestionDate string `json:"question_date"`
HaystackDates []string `json:"haystack_dates"`
HaystackSessionIDs []string `json:"haystack_session_ids"`
HaystackSessions [][]LMETurn `json:"haystack_sessions"`
AnswerSessionIDs []string `json:"answer_session_ids"`
QuestionID string `json:"question_id"`
QuestionType string `json:"question_type"`
Question string `json:"question"`
Answer json.RawMessage `json:"answer"`
QuestionDate string `json:"question_date"`
HaystackDates []string `json:"haystack_dates"`
HaystackSessionIDs []string `json:"haystack_session_ids"`
HaystackSessions [][]LMETurn `json:"haystack_sessions"`
AnswerSessionIDs []string `json:"answer_session_ids"`
}

type LMETurn struct {
Expand Down Expand Up @@ -284,11 +284,11 @@ func TestLongMemEval_ExportRankings(t *testing.T) {
}

type QuestionRanking struct {
QuestionID string `json:"question_id"`
Question string `json:"question"`
QType string `json:"question_type"`
CorrectIDs []string `json:"correct_ids"`
BM25Top15 []string `json:"bm25_top15"`
QuestionID string `json:"question_id"`
Question string `json:"question"`
QType string `json:"question_type"`
CorrectIDs []string `json:"correct_ids"`
BM25Top15 []string `json:"bm25_top15"`
SessionDocs map[string]string `json:"session_docs"`
}

Expand Down Expand Up @@ -321,11 +321,11 @@ func TestLongMemEval_ExportRankings(t *testing.T) {
}

rankings = append(rankings, QuestionRanking{
QuestionID: q.QuestionID,
Question: q.Question,
QType: q.QuestionType,
CorrectIDs: q.AnswerSessionIDs,
BM25Top15: top15,
QuestionID: q.QuestionID,
Question: q.Question,
QType: q.QuestionType,
CorrectIDs: q.AnswerSessionIDs,
BM25Top15: top15,
SessionDocs: docMap,
})
}
Expand All @@ -350,7 +350,7 @@ func runBenchmark(t *testing.T, name string, questions []LMEQuestion, ranker ran
t.Helper()

ks := []int{1, 3, 5, 10}
hits := make(map[int]int) // k -> hit count
hits := make(map[int]int) // k -> hit count
typeHits := make(map[string]map[int]int) // type -> k -> hits
typeCounts := make(map[string]int)

Expand Down
4 changes: 2 additions & 2 deletions vsearch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func BenchmarkVectorSearch_1k_128d(b *testing.B) {
for i := 0; i < 1000; i++ {
v := make([]float32, 128)
for j := range v {
v[j] = float32((i*7 + j*13) % 100) * 0.01
v[j] = float32((i*7+j*13)%100) * 0.01
}
idx.Add(string(rune(i)), v)
}
Expand All @@ -249,7 +249,7 @@ func BenchmarkVectorSearch_10k_384d(b *testing.B) {
for i := 0; i < 10000; i++ {
v := make([]float32, 384)
for j := range v {
v[j] = float32((i*7 + j*13) % 100) * 0.01
v[j] = float32((i*7+j*13)%100) * 0.01
}
idx.Add(string(rune(i)), v)
}
Expand Down
Loading