sx-gitea Phase 7: search — code + issue/PR search over search-on-sx (TDD, 35/35)

lib/gitea/search.sx: the forge builds document corpora SX-side — code
files from the default branch head (path + blob text), issues (title +
body + comments), PRs (title + body + reviews) — embeds them as one
haskell-on-sx program and asks searchRankTfIdf for ranked doc ids
(terms, AND/OR/NOT, phrases).

Cost model honored: one evaluation parses the Haskell layers
(~20s CPU), extra queries are nearly free — so the core primitive is
gitea/search-multi (any number of corpora and queries in a single
evaluation; each corpus an idxN binding) and only the six layers
searchRankTfIdf needs are compiled, not the full search/src. The test
suite runs its thirteen SX-level queries over five corpora as ONE
evaluation.

Global search spans exactly the repos the caller can read. Web:
/:owner/:name/search page (kind filter), repo + global JSON search.
Suite timeout raised to 900s for the haskell-backed suites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 15:00:36 +00:00
parent b4fbfa5603
commit c8385bd003
3 changed files with 653 additions and 1 deletions

View File

@@ -23,6 +23,7 @@ VERBOSE="${1:-}"
ISSUES_EXTRAS="lib/relations/schema.sx;lib/relations/engine.sx;lib/relations/api.sx;lib/smalltalk/tokenizer.sx;lib/smalltalk/parser.sx;lib/guest/reflective/class-chain.sx;lib/smalltalk/runtime.sx;lib/guest/reflective/env.sx;lib/smalltalk/eval.sx;lib/content/block.sx;lib/content/doc.sx;lib/content/render.sx;lib/content/api.sx;lib/content/meta.sx;lib/content/text.sx;lib/content/section.sx;lib/content/table.sx;lib/content/markdown.sx;lib/content/md-import.sx;lib/gitea/issues.sx"
PR_EXTRAS="$ISSUES_EXTRAS;lib/guest/lex.sx;lib/guest/reflective/quoting.sx;lib/scheme/parser.sx;lib/scheme/eval.sx;lib/scheme/runtime.sx;lib/flow/spec.sx;lib/flow/store.sx;lib/flow/remote.sx;lib/flow/host.sx;lib/flow/api.sx;lib/gitea/pr.sx"
SEARCH_EXTRAS_TAIL="lib/haskell/tokenizer.sx;lib/haskell/layout.sx;lib/haskell/parser.sx;lib/haskell/desugar.sx;lib/haskell/runtime.sx;lib/haskell/match.sx;lib/haskell/eval.sx;lib/haskell/map.sx;lib/haskell/set.sx;lib/haskell/testlib.sx;lib/search/tokenize.sx;lib/search/index.sx;lib/search/query.sx;lib/search/parse.sx;lib/search/rank.sx;lib/search/rankq.sx;lib/search/testlib.sx;lib/gitea/search.sx"
ACT_EXTRAS="$PR_EXTRAS;lib/apl/runtime.sx;lib/feed/normalize.sx;lib/feed/stream.sx;lib/feed/api.sx;lib/feed/fanout.sx;lib/feed/dedupe.sx;lib/feed/aggregate.sx;lib/feed/rank.sx;lib/feed/acl.sx;lib/feed/mute.sx;lib/feed/page.sx;lib/feed/notify.sx;lib/feed/home.sx;lib/feed/fed.sx;lib/events/notify.sx;lib/gitea/activity.sx"
SUITES=(
@@ -32,6 +33,8 @@ SUITES=(
"issues|gitea-issues-pass|gitea-issues-fail|gitea-issues-fails|$ISSUES_EXTRAS"
"pr|gitea-pr-pass|gitea-pr-fail|gitea-pr-fails|$PR_EXTRAS"
"activity|gitea-act-pass|gitea-act-fail|gitea-act-fails|$ACT_EXTRAS"
"search|gitea-search-pass|gitea-search-fail|gitea-search-fails|$PR_EXTRAS;$SEARCH_EXTRAS_TAIL"
"fed|gitea-fed-pass|gitea-fed-fail|gitea-fed-fails|$ACT_EXTRAS;lib/gitea/fed.sx"
)
OUT_JSON="lib/gitea/scoreboard.json"
@@ -102,7 +105,7 @@ run_suite() {
} > "$TMP"
local OUTPUT
OUTPUT=$(timeout 600 "$SX_SERVER" < "$TMP" 2>/dev/null)
OUTPUT=$(timeout 900 "$SX_SERVER" < "$TMP" 2>/dev/null)
rm -f "$TMP"
local LINE