Repository navigation
feat(runed): runed daemon gRPC client implementation - #101
Merged
Merged
Conversation
couragehong
marked this pull request as draft
May 5, 2026 23:12
couragehong
force-pushed
the
wip/go-impl-runtime
branch
from
May 6, 2026 22:33
12a7b11 to
6d2a85a
Compare
couragehong
force-pushed
the
couragehong/feat/runed-grpc
branch
from
May 6, 2026 22:35
0bb61d0 to
ecce24e
Compare
couragehong
marked this pull request as ready for review
May 6, 2026 22:40
Adds github.com/CryptoLabInc/runed via local replace (../runed) — the
runed module is a sibling project not yet published to a public registry.
buf-generated stubs at runed/gen/runed/v1 are gitignored in runed and
materialized via 'buf generate' at build setup time.
In the embedder adapter:
- import runedv1 and grpc{,/credentials/insecure}
- New() dials 'unix://'+sockPath with insecure creds (UDS = same machine)
- client struct gains conn / pb / info (sync.Once cache) fields
- info_cache gains svc runedv1.RunedServiceClient field
EmbedSingle / EmbedBatch / Info / Health are still stubs; subsequent
commits implement them. Close() now drains conn.
infoCache.Get() calls runedv1.RunedServiceClient.Info on first invocation and caches both snapshot and error for the lifetime of the adapter. Subsequent Get() calls return the cached values without RPC. slog breadcrumb 'embedder info loaded' (daemon_version / model_identity / vector_dim / max_batch_size) records model identity for post-MVP re-embedding migration tooling per spec/components/embedder.md §Info 캐시 + D30. Automatic model-change detection is deferred. client.Info() now delegates to c.info.Get() (was zero stub).
EmbedSingle wraps runedv1.RunedServiceClient.Embed in the D7 retry schedule [0, 500ms, 2s] (retry.go). EmbedBatch splits inputs that exceed Info.MaxBatchSize into chunks and submits each via embedBatchOnce (each chunk gets its own retry budget). Empty texts returns nil. Order is preserved across chunks. embedBatchOnce verifies len(resp.Embeddings) == len(texts) — defensive against a daemon contract violation that would otherwise misalign results with their inputs (silent corruption).
Health() calls runedv1.RunedServiceClient.Health and translates the proto enum HealthResponse_Status into the 'STATUS_'-stripped string documented by the adapter contract (OK / LOADING / DEGRADED / SHUTTING_DOWN / UNSPECIFIED). Health is NOT retried (D8 — first embed call drives connectivity; this RPC backs the diagnostic surface only). Callers (service/lifecycle.go) classify LOADING vs DEGRADED downstream.
12 test functions / 17 subtest cases against an in-process bufconn-backed
RunedServiceServer:
- EmbedSingle: happy path, retry-then-success on Unavailable,
non-retryable error returns immediately, retries-exhausted (3 attempts),
respects cancelled context
- EmbedBatch: no-split when len ≤ MaxBatchSize, splits 9-into-(4+4+1)
when above MaxBatchSize=4, resp count mismatch errors out, empty
input no-op
- Info: sync.Once caches across 5 calls (1 RPC), cached error path
(1 RPC for two failed calls)
- Health: 5-case enum→string matrix (OK/LOADING/DEGRADED/SHUTTING_DOWN/
UNSPECIFIED), uptime/total_requests pass-through
Adds NewBufconnClient(*grpc.ClientConn) Client constructor (factored
through newWithConn) so tests can inject a bufconn-backed conn without
a unix socket. Useful in production too for callers that pool conns.
Notes:
- Two retry tests (RetryThenSuccess: 0.5s, RetriesExhaust: 2.5s) wait on
the real D7 backoff schedule [0, 500ms, 2s]. Total test suite ~3.5s.
- Tests use status.FromError + codes.* for assertions; doesn't depend on
any embedder/errors.go (which doesn't exist yet — see runed audit P2.4).
go test ./internal/adapters/embedder/... ok
13 direct spec-parity items (5 RPCs, batch split, retry, info cache, slog breadcrumb, resp count guard, status enum mapping). 3 acceptable divergences (raw stub vs runed/client wrapper, no Health retry, no Shutdown call). 4 open follow-up gaps (vector_dim verification, Health-aware classification, typed error sentinels, socket path resolver). No Python equivalent — D30 designates runed as a Go-native sibling; audit baseline is docs/v04/spec/components/embedder.md and the runed proto contract.
couragehong
force-pushed
the
couragehong/feat/runed-grpc
branch
from
May 7, 2026 03:23
ecce24e to
3c7a140
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약
v0.4 go-migration의 외부 runed 데몬(임베딩 전담 sibling 프로세스) gRPC 클라이언트 구현입니다.
Embed/EmbedBatch/Info/Health)[0, 500ms, 2s]+sync.OnceInfo 캐시 + batch split (len > MaxBatchSize일 때) + Status enum→string 매핑.runed 모듈이 아직 public registry 에 publish 안 돼서 (go get이 안됨) 로컬
replacedirective 사용../runed위치에 sibling repo clone 하고 한 번buf generate돌려서gen/runed/v1/*.pb.go만들어줘야 빌드됨 (runed 의gen/은 gitignore).runed/clientPlan A wrapper 안 쓰고 rawrunedv1.RunedServiceClientstub 직접 사용 — wrapper 가Health()안 노출해서 (rune_diagnosticsMCP tool 에 필요).base 는
wip/go-impl-runtime. #93/95/96 머지 후 retarget 예정입니다.Scope
Task 3 of the v0.4 Go migration runtime impl: implement the runed embedding daemon gRPC client.
6 commits, 3 files of source + 1 audit doc (~659 LoC):
build(runed): add runed dep + initial gRPC dial wiring—github.com/CryptoLabInc/runed/gen/runed/v1import; UDS dialfeat(runed): implement Info RPC + sync.Once cache—slog.Info "embedder info loaded"breadcrumb (D30)feat(runed): implement EmbedSingle + EmbedBatch (batch split + retry)— D7[0, 500ms, 2s]; resp count guardfeat(runed): implement Health RPC + enum→string mapping— STATUS_* → 5-string mappingtest(runed): mock-server unit tests + NewBufconnClient injection— 12 fn / 17 subtest (retry, split, cache, enum)docs(v04): add spec parity audit for runed-grpc— 13 spec parity items, 4 follow-up gapsStacked-PR base
Base =
wip/go-impl-runtime, an integration branch that local-mergesthe still-under-review #93/#95/#96. With this base, the PR diff is exactly
the runed-grpc work — no noise from the prerequisite ports.
When #93/#95/#96 merge upstream, the cleanup is the same as the vault PR:
rebase wip + retarget this PR's base.
Spec
docs/v04/spec/components/embedder.md(post docs(v04): align spec with shipped runed/vault/envector SDKs #97)docs/v04/notes/audit-runed-grpc.mdLocal dep replace
go.modadds:The
runedmodule isn't yet published. Local replace points to the siblingcheckout. Developers must (1) clone
runedat../runed, and (2) runcd ../runed && buf generate(ormake proto) once to materializegen/runed/v1/*.pb.go(gitignored upstream).Notes
runedv1.RunedServiceClientstub rather than theruned/clientPlan A wrapper. The wrapper does its own Connect-time Health verify but does not expose a publicHealth()— which we need for therune_diagnosticsMCP tool.runedrequiresgo 1.26.2. This PR keepsgo 1.25.9in ourgo.mod(replace bypasses the toolchain check); a separate bump should land before publishing.