Skip to content

fix(lore): embed-rebuild refuses when no embedder is wired#96

Open
mvanhorn wants to merge 1 commit into
mathomhaus:mainfrom
mvanhorn:osc/88-embed-rebuild-null-embedder
Open

fix(lore): embed-rebuild refuses when no embedder is wired#96
mvanhorn wants to merge 1 commit into
mathomhaus:mainfrom
mvanhorn:osc/88-embed-rebuild-null-embedder

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

Summary

guild lore embed-rebuild previously read meta.embedder_state, saw enabled, then proceeded to wipe lore_vectors and re-encode using embed.NewNullEmbedder() as a placeholder pending QUEST-212. Every encode returned ErrEmbedderDisabled, so coverage stayed at 0% even while lore_health reported the embedder as enabled. Net effect: silent destruction of vectors with no usable rebuild.

This change pulls *EmbedDeps via embedFromDeps(ctx, d) (the same contract appraise_cmd already uses) and refuses to rebuild when the embedder is not wired:

  • meta says disabled OR embedder is not wired -> Disabled: true with a reason explaining the wiring gap, and existing vectors are left untouched.
  • meta says enabled AND embedder is wired -> the real embedder is used for the encode loop and coverage returns >0%.

The previous "placeholder NullEmbedder pending QUEST-212" block is removed.

Acceptance (matches the issue's acceptance section)

  • After embed-rebuild with a wired embedder, vector coverage returns to >0% for projects with active embedders.
  • The "embedder disabled" log line and the lore_health "enabled" report no longer contradict: rebuild now refuses up-front when the embedder isn't wired and emits a clear reason instead of silently no-opping.
  • Regression test covers the rebuild-then-encode happy path AND the new "embedder not wired" refusal path.

Tests

internal/lore/embed_rebuild_test.go (new):

  • TestEmbedRebuild_RefusesWhenEmbedderNotWired - seeds initial vectors through the existing Inscribe path with a fake 384-dim embedder, then calls EmbedRebuildCommand.Handler with stubCommandDeps(nil). Asserts Disabled == true, a non-empty reason, and that the lore_vectors row count is unchanged (no silent wipe).
  • TestEmbedRebuild_HappyPathWithWiredEmbedder - seeds entries without vectors (deps == nil during inscribe), then calls the handler with stubCommandDeps(&EmbedDeps{Embedder: fake, ModelID: "test-model"}). Asserts Disabled == false, Encoded > 0, and that the row count after rebuild matches the reported Encoded.

The fake embedder is a small inline type returning a deterministic 384-dim float32 slice; 384 matches the production BGE dimension so the existing Tx2 vector-write path accepts the encode.

go test ./internal/lore/..., go build ./..., go vet ./...: clean.

Files

  • internal/lore/embed_rebuild_cmd.go - replace the NullEmbedder placeholder with an embedFromDeps + !ed.Enabled() -> Disabled gate.
  • internal/lore/embed_rebuild_test.go (new) - regression tests for both branches.

Closes #88.

Before this change, EmbedRebuildCommand checked meta.embedder_state,
saw "enabled", then proceeded to wipe lore_vectors and re-encode using
embed.NewNullEmbedder() as a placeholder. Every encode returned
ErrEmbedderDisabled, so coverage stayed at 0% even while lore_health
reported the embedder as enabled. Net effect: silent destruction of
vectors with no usable rebuild.

This change pulls *EmbedDeps via embedFromDeps(ctx, d) (the same
contract appraise_cmd uses) and refuses to rebuild when the embedder
is not wired:

- meta says disabled OR embedder is not wired -> Disabled: true with
  a reason explaining the wiring gap, and existing vectors are not
  touched.
- meta says enabled AND embedder is wired -> the real embedder is
  used for the encode loop and coverage returns >0%.

The previous "placeholder NullEmbedder pending QUEST-212" block is
removed.

internal/lore/embed_rebuild_test.go adds two table-free tests:
- TestEmbedRebuild_RefusesWhenEmbedderNotWired: seeds initial vectors,
  calls the handler with stubCommandDeps(nil), asserts Disabled=true
  and vector rows still match the pre-call count.
- TestEmbedRebuild_HappyPathWithWiredEmbedder: seeds entries without
  vectors, calls the handler with a wired EmbedDeps holding a 384-dim
  fake embedder, asserts Encoded>0 and lore_vectors row count matches.

Closes mathomhaus#88
@github-actions github-actions Bot added the area: lore Lore knowledge archive label May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: lore Lore knowledge archive

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] lore embed-rebuild leaves coverage at 0% while lore_health reports embedder enabled

1 participant