Skip to content

serve, gpu-gates: /props names the embedding model held beside the chat seat - #366

Merged
juliankang4 merged 1 commit into
midagedev:mainfrom
juliankang4:dgx-spark-emb2-models
Oct 16, 2026
Merged

juliankang4 merged 1 commit into
midagedev:mainfrom
juliankang4:dgx-spark-emb2-models

Conversation

@juliankang4

Copy link
Copy Markdown
Collaborator

Part of #59 (plan and PR order in #190), E6: follow-up, /props names the embedding model held beside the chat seat.

What and why

When bloomery-serve holds an embedding model beside the chat model (--embd-model, #323), /props did not say so. A client that asks /props what the server runs saw only the chat seat. This PR adds an embedding_model object with the model's alias and path to the /props response. The field appears only when a side seat is held. The existing chat fields keep their meanings, and the model-list routes are unchanged.

Release notes: Fixed | /props names the embedding model held beside the chat model.

What changes:

  • Embed (crates/serve/src/embed.rs) gains a file-path accessor. Model, SideEngine, Stub and MockEmbed implement it.
  • The side seat keeps the path from the configuration it already opens (crates/gpu-gates/src/side_seat/gemma_embedding2.rs) and passes it through the existing open-time facts channel (crates/gpu-gates/src/side_seat.rs). Image support passes through unchanged.
  • crates/serve/src/embeddings.rs snapshots the path next to the other model facts. crates/serve/src/api.rs adds the optional field to the props response.
  • docs/serving.md documents the field.

Why no comparison against a reference engine: the change returns file metadata that the server already holds. It computes no embedding, so there is no vector to compare and no number to time.

Code shape

  • No second copy. The path travels through the existing Embed contract and the existing facts channel. No new endpoint, parser, listing renderer or fixture.
  • Model code holds only architecture facts. The EmbeddingGemma 2 file only keeps the path it was opened with. The common serve code gained no per-model branch.
  • Dead code is gone. Nothing was made unused.
  • No silent failure. No new fallback, ignored Result or default. The field is absent only when there is no side seat.
  • Comments state what is true now.
  • No relaxed gate. No band, tolerance or lint moved. The lint warning count is 41 on main and on this branch.
  • cargo fmt and cargo clippy are clean on what I touched: cargo fmt passes, and the full Linux check (85 of 85) adds no lint warning.

Duplication found or removed (path:line), or "none": none.

What I ran

The checks ran on a Linux host, CPU only, on the commit before a patch-identical rebase onto the current upstream/main. The final head ff4493b04 has the same seven changed files as the tested head ea7b96df, and a range-diff shows the one commit as equal. I did not repeat the tests after the rebase.

Check Result
FAIL-first: the new test api::embeddings::tests::discovery_names_the_seated_models run on the base bdc70824 rc 101. /props has embedding_model as Null, where the test expects {"alias": "mock-embd", "path": "/models/mock-embd.gguf"}
The same test on ea7b96df, with and without a side seat passes
cargo test --locked -p bloomery-serve --lib on ea7b96df 234 passed; 0 failed
cargo oxide test --arch sm_121 -- -p bloomery-gpu-gates --features deepseek41,gemma-embedding2,vision --release --lib side_seat::tests -- --nocapture 2 passed; 0 failed
Wrong-accessor check: use embed.name() for the path in embeddings::Side::new, then model.name() in SideEngine::spawn, one at a time each makes its own contract assertion fail (an alias reported as the path), and the restored thread test passes
cargo build --locked -p bloomery-serve --bin bloomery-serve, then the process-level test api::tests::a_key_never_reaches_what_the_process_prints_or_serves passes
Changed files on the final head against the tested head all seven are equal, and no tracked file was edited in the trees used

Not run: cargo clippy, contrib-check, and any gate that needs a GPU or a model file. No inference ran.

What I ran into

None of this blocks the PR.

The first full library run failed one existing test (233 passed; 1 failed) because the bloomery-serve binary it needs had not been built. I built it, and the final run above is green. A first run of the side-seat tests in the debug profile failed CUDA code generation in gpu, gpu-vision and gpu-deepseek41, which this PR does not touch. The release profile, which the gate recipes use, compiles and passes.

Hardware (if the change is for a machine)

Not a machine-specific change. The tests ran on a CPU-only Linux host. The oxide test compiles the device-linked crates but runs only host-side stub tests, so no GPU was used and no timing is claimed.

AI help

AI 코딩 에이전트가 코드를 작성한 후 설명을 썼고, 테스트를 마쳤습니다. diff 리뷰와 PR 초안 리뷰는 제가 직접 했습니다.

@github-actions github-actions Bot added documentation Improvements or additions to documentation gpu The card engine: crates/gpu*, crates/app needs-gpu Changes code a card must check, and carries no gate run on a card serve The HTTP server: crates/serve labels Oct 16, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: CLEAN: The embedding path reaches /props through startup metadata, with no inference or model-list behavior change.

Checked

Duplicates: 6 new function or method declarations checked; no duplicate owner. Dryer found 0 pairs in serve; gpu-gates was checked manually.
Complexity: crapper flagged no changed function.
Silent failure: 0 added fallback or ignored-result sites. The path comes from the file opened for the side model.
Tests: static mutation checks cover all 3 added or changed tests. Removing api.rs:1848 fails discovery's side-present assertion; inserting a null field without a side fails its absence assertion. Replacing side_seat.rs:324 with model.name() fails the worker facts assertion. Changing embeddings.rs:137 from [v] to v fails each_route_answers_its_shape. Its removed discovery assertions are retained in the new test.
Gates: no pins or thresholds moved; the PR body reports FAIL-first for discovery.
Escape catalog: no patterns matched.
Adversarial checks: absent side, alias/path substitution, concurrent discovery during inference, and unsupported architecture are blocked by the presence branch, distinct metadata, immutable snapshots, and architecture validation.
Performance: startup and discovery metadata only; no decode, prefill, or kernel work added.

Notes

Tests were not rerun in this read-only review. The PR reports CPU-only validation and supplies no GPU gate evidence.

Card check: needs-gpu. This pull request changes crates/gpu-gates/src/side_seat.rs, crates/gpu-gates/src/side_seat/gemma_embedding2.rs and carries no gate run on a card (CONTRIBUTING's evidence list); a maintainer adds gpu-verified after one.

🔨 Shingler, bloomery's review bot: approves a clean pull request and requests changes on a must-fix (how it works)

@juliankang4
juliankang4 force-pushed the dgx-spark-emb2-models branch from d05b0ea to d3e248d Compare October 16, 2026 20:31

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: CLEAN: The embedding model's path reaches /props through startup metadata, with no must-fix defect found.

Checked

Duplicates: 6 new function/method items checked; no duplicated owner. dryer reported 0 candidate pairs.
Complexity: crapper flagged no functions; props gains one branch for the optional side model.
Silent failure: 0 new fallback or ignored-result sites; failed model opens still refuse startup.
Tests: static mutation review covers all three new or changed tests. Removing the field at crates/serve/src/api.rs:1848 fails discovery_names_the_seated_models; using the alias instead of the path also fails its exact object assertion. Substituting model.name() at crates/gpu-gates/src/side_seat.rs:324 fails the thread test's metadata tuple assertion. Replacing the embedding response's model at crates/serve/src/embeddings.rs:161 with the chat alias still fails each_route_answers_its_shape.
Gates: no pins moved or assertions lost; model-list assertions moved into the discovery test. The body reports FAIL-first evidence.
Adversarial checks: absent side, swapped alias/path, concurrent metadata reads, and escaped filenames are covered by optional insertion, distinct metadata, immutable snapshots, and JSON serialization.
Performance: startup and metadata endpoints only; no added inference work.
Escape catalog: no C1–C4 patterns matched.

Notes

dryer skipped crates/gpu-gates; the changed code was checked with Grep.
Tests were not run during this review. Reported runs name ea7b96df; the body's equivalence claim ends at ff4493b04, rather than reviewed head d3e248d0. No GPU gate evidence was supplied.

Card check: needs-gpu. This pull request changes crates/gpu-gates/src/side_seat.rs, crates/gpu-gates/src/side_seat/gemma_embedding2.rs and carries no gate run on a card (CONTRIBUTING's evidence list); a maintainer adds gpu-verified after one.

🔨 Shingler, bloomery's review bot: approves a clean pull request and requests changes on a must-fix (how it works)

@juliankang4

Copy link
Copy Markdown
Collaborator Author

The review is done and the contribution check passed, so I'm merging this.

@juliankang4
juliankang4 merged commit db5c89e into midagedev:main Oct 16, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation gpu The card engine: crates/gpu*, crates/app gpu-verified needs-gpu Changes code a card must check, and carries no gate run on a card serve The HTTP server: crates/serve

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants