Skip to content

fix(vault): #103 follow-up — MapGRPCError + 256MB + tests#106

Merged
couragehong merged 4 commits into
feat/go-migrationfrom
couragehong/feat/vault-fixups
May 7, 2026
Merged

fix(vault): #103 follow-up — MapGRPCError + 256MB + tests#106
couragehong merged 4 commits into
feat/go-migrationfrom
couragehong/feat/vault-fixups

Conversation

@couragehong

Copy link
Copy Markdown
Contributor

#103 후속 PR입니다. Vault 어댑터에서 빠진 항목 + 회귀된 항목 정리했습니다.

  1. MapGRPCError 버그 수정 + server 가 emit 하는 code 전수 커버feat(mcp): envector-go-sdk integration #103 가 envector 쪽은 표준 패턴(status.FromError + codes.*)으로 정리했는데 vault 는 수정이 되지 않아서, 기존 hand-rolled interface (Code() int) 가 실제 gRPC 시그니처(codes.Code = uint32)와 안 맞아 모든 에러가 VAULT_INTERNAL/Retryable=true 로 잘못 분류되고 있었습니다.
  • 특히 토큰 만료가 retryable=true 로 마킹돼 무한 재시도 위험이 있었습니다.
  • 추가로 server 가 실제 emit 하는 PermissionDenied/InvalidArgument/ResourceExhausted 가 매핑 자체에 빠져있어서 default 분기로 흘러가던 것도 같이 정리했습니다.
  1. MaxMessageLength 256MB 복원 — #103에서 16MB 로 줄었는데, 일단 기존 Python rune 과 server의 MaxMessageSize 도 256MB이어서 256MB로 수정했습니다.

  2. vault bufconn unit test + NewBufconnClient injector 추가

  • 기존에 작성했던 feat(vault): rune-vault gRPC client implementation #100 에 있던 테스트를 가져왔습니다. (GetPublickey 등의 변화로 기존 PR은 닫고 103으로 옮겨가면서 테스트만 가져옴)
    • 4 RPC (GetAgentManifest, DecryptScores, DecryptMetadata, HealthCheck) 의 happy path + gRPC error path + response.error string + boundary input
    • decodeAgentDEK 의 3 error path (empty / invalid base64 / length matrix 0~64)
    • MapGRPCError 9-code matrix (server emit + transport + legacy + default) + Cause 보존 + errors.Is/As chain + Message carry-through
    • ParseManifestJSON 직접 (empty / missing field / not-json / forward-compat)
    • 라이프사이클 (Endpoint() / Close() 멱등성 / ctx cancellation)

#103 ported errors.go for envector but missed vault. The hand-rolled
grpcStatuser interface in #95's port required Code() to return int, but
real *status.Status.Code() returns codes.Code (uint32). Type assertion
silently fails for every gRPC error and every call lands in the !ok
branch as ErrVaultInternal — hiding the actual code.

Worst case: Unauthenticated (token revoked/expired) gets mis-flagged as
retryable=true, triggering infinite retry on auth failure.

Switch to status.FromError(err) and codes.* constants from
google.golang.org/grpc, mirroring the pattern in envector/errors.go
MapSDKError. Removes the hand-rolled grpcStatus struct + statusFromError
helper + 4-line code constants block.
#103 lowered MaxMessageLength from 256MB to 16MB without justification.
Python (vault_client.py:L33) and spec (vault.md §256MB) both call for
256MB.

Even with EvalKey no longer in the manifest (Vault now owns EvalKey/SecKey
server-side per the GetAgentManifest rename), the manifest_json still
carries EncKey JSON content which can be on the order of MBs depending
on FHE parameters. The 16MB cap risks ResourceExhausted on future
deployments that legitimately need more headroom; 256MB matches Python
and the spec without measurable cost.
#103 added envector unit tests but skipped vault. Adds 13 test functions
/ 18 subtests covering all 4 RPC paths and the error-mapping matrix:
  - GetAgentManifest: happy path, response.error, malformed JSON, bad DEK
    length 16 (must be 32 for AES-256)
  - ParseManifestJSON: silently drops a stray EvalKey.json field if a
    legacy Vault response includes one (forward compat)
  - DecryptScores: happy path with token/blob/top_k assertions
  - DecryptMetadata: happy path pass-through
  - HealthCheck Tier 1: SERVING / NOT_SERVING
  - MapGRPCError: 6 gRPC code → sentinel matrix (Unauthenticated /
    NotFound / Unavailable / DeadlineExceeded / Internal /
    PermissionDenied default), non-gRPC fallback, nil pass-through

Adds NewBufconnClient(*grpc.ClientConn, token) Client constructor
factored through newWithConn so NewClient and NewBufconnClient share
struct init. Useful for tests + production callers that pool conns
externally.

Test runs in ~0.6s with no real Vault dependency.
Documents the three follow-up items this PR addresses (MapGRPCError fix,
MaxMessageLength 256MB restore, bufconn unit tests + NewBufconnClient
injector) against the post-#103 contract (GetAgentManifest, EvalKey
ownership shifted to Vault).

Includes spec-parity matrix, list of acceptable divergences from Python,
and open follow-up items (RUNEVAULT_GRPC_TARGET env override, health
client caching, response.error retryable nuance, MetadataRef type
asymmetry).
@couragehong couragehong self-assigned this May 7, 2026
@couragehong
couragehong merged commit eb4ccc0 into feat/go-migration May 7, 2026
1 check passed
@couragehong
couragehong deleted the couragehong/feat/vault-fixups branch May 7, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant