# Capability Spec Delta: api-secrets-worker-proxy (api-secrets-worker-proxy) **Package**: `@suaveplan/api-secrets-worker-proxy` **Status**: PROPOSED > Every requirement below carries a `**Verified by:**` line at authoring time. ## ADDED Requirements ### Requirement: Proxy preserves SecretsLike surface and forwards every call to main The package SHALL expose `createSecretsProxyClient(port)` returning a `WorkerProxyOf`. Every method call SHALL be marshalled to the main process — there MUST be no worker-side cache of secret values, neither in module state nor in client-instance state. Two sequential `get("X")` calls MUST produce TWO main-side RPC invocations (so a rotated secret is picked up immediately AND a compromised worker cannot exfiltrate cached values). #### Scenario: two gets produce two RPC calls - **WHEN** worker code calls `ctx.secrets.get("X")` twice in succession - **THEN** the stub main-side server records two distinct receive events **Verified by:** `src/client/no-cache.test.ts::"two gets produce two main-side RPC calls"` --- ### Requirement: Non-manifested key throws reconstructed SECRETS_PROXY_NOT_MANIFESTED The package SHALL surface main-side rejection of non-manifested keys as `SECRETS_PROXY_NOT_MANIFESTED` reconstructed via `api-worker-rpc`'s error-reconstruction. Manifested keys whose value is absent in the configured source MUST surface as `SECRETS_PROXY_NOT_FOUND` — the two cases are distinct so the operator can tell "your plugin didn't declare this" from "your plugin declared it but the source is missing it." #### Scenario: non-manifested key is rejected - **WHEN** worker code calls `ctx.secrets.get("NOT_DECLARED")` - **THEN** the call rejects with `SuaveplanError` of code `SECRETS_PROXY_NOT_MANIFESTED` #### Scenario: manifested-but-absent key surfaces SECRETS_PROXY_NOT_FOUND - **WHEN** the manifest declares `STRIPE_KEY` but the source has no value AND worker calls `ctx.secrets.get("STRIPE_KEY")` - **THEN** the call rejects with `SECRETS_PROXY_NOT_FOUND` **Verified by:** `src/client/client.test.ts::"non-manifested key rejects"` AND `src/client/not-found.test.ts::"manifested-but-absent key surfaces NOT_FOUND"` --- ### Requirement: Conformance suite passes against this proxy The package SHALL be runnable as the surface argument to `runSecretsConformance` from `@suaveplan/api-secrets/testing`. Every scenario MUST pass identically to a direct in-process adapter. This is the Stage-4-precondition gate. #### Scenario: runSecretsConformance passes - **WHEN** `runSecretsConformance("worker-proxy", makeFactory)` runs - **THEN** every scenario passes **Verified by:** `tests/conformance/run-secrets-conformance.test.ts::"runSecretsConformance passes against proxy"`