Project Info
TL;DR We see that LLM can rerank search results, and we should have a way of inspecting the whole chain from retrieval to results. With DuckDB, Python with FastAPI, and GPT-5.6 (Luna), we performed search on synthetic pet food product data with ground truth labeling and item of interest highlighted as protected and inspect each layer in the Relevance Incident Lab (RIL) We found that LLM reranking can be beneficial in some cases, and not others (i.e., hurting the ranking of protected items, or unchanged so that the LLM calls are additional costs we do not need) Codex and GPT-5.6 were used extensively in planning and implementation of the code and synthesizing data, as well as the video demo via plugins and debugging the UI with skills Future direction includes extending RIL's capabilities to be able to run as a containerized companion to a developer’s search stack, support hybrid, semantic, and AI-search pipelines, expose its evidence through an MCP server, and evaluate real public datasets beyond the current synthetic examples
Inspiration
Research such as RankGPT and RankZephyr showed that large language models can rerank search results. That made me wonder: when a ranking looks wrong, is it the LLM's fault or was the issue in retrieval or the deterministic ranking baseline, or some other parts such as output validation? With that, we built Relevance Incident Lab (RIL) to make that whole chain inspectable end-to-end, to see between the layers what each is doing, an essential tool when we might be accusing LLM being the blackbox.
What it does
With DuckDB full-text retrieval, a deterministic baseline, GPT reranking, response validation, and other features like p95 latency, RIL lets a developer be able to trace the search result through each layer from end-to-end. Each test case includes frozen relevance judgments (i.e., our version of ground truth) so RIL can show exactly which items moved, why a protected relevant item matters, and whether the change helped or hurt. The caveat regarding the suggestion and summary or final outcome is that they are pieces of evidence for a human reviewer, not an automatic release decision.
How we built it
We used DuckDB Full-Text Search and BM25 for lexical retrieval, Python with FastAPI and Pydantic for the evidence and validation layer, GPT-5.6 Luna through the OpenAI API for reranking, and React with Vite for the review interface. In addition to the rerunnable nature of the data, the package runs in Docker without an API key or network dependency, while the public site is a read-only demonstration of the same evidence. Codex was part of the development workflow too. Sol at ultra reasoning helped refine the PRD and technical design, Goal mode helped with longer implementation and verification work, installed UI skills (i.e., Impeccable) helped polish the interface and accessibility, and HyperFrames helped produce the demo video. Moreover, we used Sites to deploy a static demo with ease.
Challenges we ran into
The hardest part was producing a truthful BLOCK case. Our first organic case did not regress. A later chicken-free case failed before reranking because its protected item landed at retrieval rank 14, outside the top-12 candidate pool. That was useful evidence: a reranker cannot rescue an item it never receives. The puppy case exposed a different problem when early model attempts returned invalid or hallucinated product IDs. We redesigned the protocol around opaque candidate handles, exact validation, one bounded repair attempt, explicit abstention, and deterministic fallback. Only after freezing a separately motivated beef-exclusion fixture (yet another case) before observing the provider result did we obtain a defensible BLOCK demonstration. This took longer than simply generating a convenient output, but it kept the evidence honest.
Accomplishments we're proud of
We produced both sides of the story: A GPT_PREFERRED case where the protected puppy result moved from baseline rank 11 to GPT rank 1. A BLOCK case where the protected beef-exclusion result began at baseline rank 1 and the GPT reranker demoted it, triggering investigation. A 100-pair response-time campaign for the qualified puppy case, giving us a real p95 measurement instead of relying on one fast call. A provider-free recorded demo that preserves attempts, validation, replay, metrics, policy reasoning, and exact artifacts for review. We are also proud that RIL keeps INCONCLUSIVE as a real outcome. Missing or invalid evidence does not silently become a success.
What we learned
LLM reranking can help, but it is only one part of the search pipeline. Retrieval recall comes first: if the relevant item is outside the candidate pool, reranking cannot recover it. An aggregate metric can improve while a business-critical protected item gets worse, so both views need to be evaluated. Model output should be treated as untrusted input: IDs must be validated, and the system needs abstention and deterministic fallback behavior. One successful response is not enough to establish latency or reliability; repeated, comparable runs matter. Synthetic fixtures are useful for controlled regression tests, but they are not proof of production performance on real customer data. BLOCK should remain an advisory, human-gated decision. RIL explains the evidence; a person owns the release action.
What's next
Turn RIL into a containerized companion for a developer's existing search stack, with a documented fixture/import contract for bringing their own queries, candidates, judgments, and rankings. Extend RIL beyond lexical retrieval to inspect hybrid, semantic, and broader AI-search pipelines. Create an MCP server so a developer can connect a self-hosted RIL instance to Codex and ask questions about recorded incidents and evaluation results. Evaluate broader public datasets such as the Amazon Shopping Queries ESCI dataset, then extend beyond product search to news and other changing corpora. Add connectors that snapshot evidence from production search systems and run RIL as a human-reviewed search-quality gate in CI/CD, without giving it automatic release authority.
Relevance Incident Lab
Relevance Incident Lab (RIL) is a developer tool for debugging search-ranking changes before release. It compares a deterministic lexical baseline with an LLM reranker, validates the response, replays the ranking, computes quality and latency evidence, and presents an advisory outcome for human review.
Try the read-only recorded demo: relevance-incident-lab.nobthiti.chatgpt.site
The demo uses frozen synthetic data. It needs no API key, makes no provider calls, and cannot approve a release.
Run locally
The fastest source-based path runs the same recorded console used by the public demo.
Requirements:
- Node.js 22.13 or newer
- npm 10 or newer
- macOS, Linux, or Windows
git clone https://github.com/tpremrud/relevance-incident-lab.git
cd relevance-incident-lab/site
npm ci
npm run dev -- --host 127.0.0.1 --port 3000
Open http://127.0.0.1:3000. Run the offline site test with:
npm test
No Docker image, database, OpenAI account, or environment variable is required for this judge path. The bundled sample data is synthetic and read-only.
What to inspect
- Beef exclusion · BLOCK — an engineered regression control in which the protected relevant result starts at baseline rank 1 and is demoted by the recorded reranker. RIL recommends investigation; it does not block a release automatically.
- Puppy v2 · GPT preferred — a positive control in which the protected result moves from baseline rank 11 to reranked rank 1 and passes the recorded 100-pair response-time qualification.
- Organic and Chicken-free — honest nonqualifying and inconclusive states that demonstrate fail-closed evidence handling.
Each case exposes retrieval, baseline and reranked positions, validation, replay, metrics, policy reasoning, record details, and exact source artifacts. The final decision form is session-only and keeps the release decision with a human reviewer.
Architecture
Synthetic fixture + judgments
│
▼
DuckDB FTS retrieval
│
├──────────────► deterministic baseline
│
└──────────────► validated GPT-5.6 ranking
│
▼
replay + metrics + policy proof
│
▼
advisory human review UI
The recorded demo replays immutable, digest-verified evidence. Missing or
ambiguous facts remain visibly unavailable or INCONCLUSIVE; the UI does not
infer them.
Canonical Docker package
The container is the canonical reproducible developer-tool package. The public
site is a convenient read-only mirror, not the complete FastAPI/DuckDB runtime.
If you have received or loaded the prebuilt linux/amd64 image named
relevance-incident-lab:recorded, use:
./scripts/incident-lab doctor
./scripts/incident-lab run recorded --port 8000
# open http://127.0.0.1:8000
./scripts/incident-lab status
./scripts/incident-lab stop
Recorded mode is non-root, verifies evidence by digest, uses a read-only root
filesystem and private data directory, and denies application egress. The
prebuilt image archive is intentionally not committed to Git; judges can test
the project without it through the public URL or site/ setup above. See the
runbook for detailed operation and troubleshooting.
Verification
cd site && npm test
cd ../web && npm test && npm run typecheck && npm run build
cd .. && ./scripts/incident-lab verify fast
The security matrix covers query and candidate injection, unknown output IDs, route/source bounds, bundle tampering, unsafe SQL, secret exposure, error channels, and policy bypass. Recorded mode makes zero provider calls.
How Codex and GPT-5.6 were used
- Codex with Sol at ultra reasoning helped refine the PRD and technical design, then implemented, tested, reviewed, and integrated the project under explicit owner gates. Goal mode was used for longer environment and verification work.
- Installed UI-quality skills helped polish accessibility and responsive behavior. The HyperFrames plugin produced the scripted demonstration video.
- GPT-5.6 Luna produced separately authorized ranking observations and the bounded 100-pair puppy response-time campaign.
- The submitted demo is recorded playback: it does not contact Luna or read an API key.
Repository map
site/— installable, provider-free judge demosrc/relevance_incident_lab/— Python contracts, verification, and runtimeweb/— React evidence consolefixtures/— synthetic source and compiled fixturesevidence/recorded/— immutable recorded evidencesecurity/andtests/— security matrix and verification controlspackaging/— container inputs and recorded-package metadataRUNBOOK.md— operation, local development, troubleshooting, and demo flow
Historical milestone IDs remain inside immutable evidence paths and generated records because changing them would invalidate their hashes. They are not required to understand or operate the public project.
License
Original project code, documentation, and synthetic fixtures are available under the MIT License. Recorded model outputs, bundled evidence, and third-party material retain the separate treatment described in NOTICE.md and THIRD_PARTY_NOTICES.md.
Analysis
View
Metric
- 72
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- FastAPIIn code
- HTMLIn code
- Next.jsIn code
- OpenAIIn code
- PythonIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
- DockerClaimed
9 of 10 appear in the indexed code. 1 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
No AI coding agent signals were found in this repository.
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
2.3 MB
Source files
307
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
tpremrud/relevance-incident-lab
940 files · 8.9 MB · @ 01c7208
Structure
Interface
29 files · 3%Screens, components and styles rendered to the user.
Application logic
219 files · 23%Domain rules, services and shared utilities.
+5 moreBackground jobs
1 file · 0%Work run outside a request: tasks, workers and schedules.
Data & schema
204 files · 22%Schema definitions, migrations and data access.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Python77%
- TypeScript19%
- CSS3%
- Markdown1%
- HTML0%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
site/package.json
npm · 19- next
- react
- react-dom
- react-router-dom
- +15 more
web/package.json
npm · 18- react
- react-dom
- react-router-dom
- +15 more
pyproject.toml
pypi · 6- duckdb
- fastapi
- openai
- pydantic
- rfc8785
- uvicorn
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.