# REPORT Part C: library search in OMG game builds and OMU app builds (18 Oct 2026, CET afternoon)

## Blocked on you
Nothing to decide. Two deploys for the lead: (1) Factory: copy `omg/factory/library_search.py` + `games_library.py` to gex44 `forge_corp/api/routes/`; (2) Engine: the pack in `integrations/omu-engine/` (README has the Caddy route, patch anchors, verify steps).

## What changed
- **OMG Factory**: words that hit no alias and no class word are now searched in the published library by meaning (new `omg/factory/library_search.py`, BM25 over name, tags, summary, visual description). `pick()` adds up to 6 such models AFTER all alias/class picks (so old picks are always a subset), `semantic=False` gives the old behaviour.
- **Embedding question (checked read-only on gex44)**: Factory image = Python 3.12, **no numpy**; `/srv/forge-assets/repo` has **no vectors/** folder; `forge-embed`, `forge-vertex`, LiteLLM are reachable from the Factory container but none is the gemini-embedding-2 space the vectors use. So shipped **BM25-only**. The code accepts `query_vec` + `vectors` (dict id -> floats, pure Python cosine) to re-rank a word's own hits; nothing feeds it yet. I did not use the asset-to-asset neighbours: they cannot answer a word query.
- **Laws kept**: deterministic (ties on id); score floor + "word in >4% of assets is not a search word" + description-only hits need a word in <=2 assets; a class word the brief names (also classes of kinds the library does not bring, e.g. cow) is never searched (GAP stays GAP); reuse.omg false never picked; vehicles/space rules untouched (search runs on the same cleared set).
- **OMU Engine**: patch pack (new CLI search, new vendor step, 2 prompt/call-site patches, Caddy route for gex44). Same manifest pattern as `asset-manifest`; no ax42 edit.

## Evidence
- `integrations/run_factory_tests.sh`: **145 passed** across `omg/factory` (132 existing incl. the 56 in `test_ohmygames_library.py`, plus 13 new in `test_library_search.py`; 5 of the new fail on the old `games_library.py`). Before my change the existing library tests were 56 of 56 green.
- `integrations/omu-engine/tests`: 6 passed (run against a throwaway package layout).
- `integrations/search-wiring-evidence.txt` (10 briefs, old vs new, current index.json): by-meaning adds on 5 of 10 (farm: cart + fence; "pavilion" -> fish hall; "shelving" -> gondola racks; watch tower + pillars; medieval -> chapel); the other 5 add nothing (gaps stay gaps: tent, campfire, school, windmill, cottage).
- Patches `patch --dry-run` clean on the live ax42 files; patched build.py/fast_build.py compile.

## What would break / limits
- BM25 is lexical: synonyms with no shared word ("settee", "closet", "jetty") still miss. Real meaning needs vectors on gex44 plus a query embedding (publish `vectors/`, add numpy or the pure cosine, call forge-vertex). Not done.
- A setting word can pull a loosely related model (medieval -> chapel). Capped at 6, after real picks.
- Engine: the Caddy route is a gex44 change I did not make; until then the CLI says "library unreachable" and builds go on as today. The agent only uses the library if it reads the new prompt bullet and writes the manifest: unmeasured on a real build.
- The Engine search file duplicates the Factory file (test keeps them equal).

## NOT done
No deploy, no ax42/gex44 edit, no real tenant build, no change to `lib/search.py`. Local mirror `~/forge-monorepo` is 6 weeks stale: left alone.
