fix: resolve UUID secret refs with host contract - #192
Conversation
|
Ready for review at |
There was a problem hiding this comment.
Pull request overview
This PR updates the plugin worker to be compatible with newer Paperclip hosts that require UUID-backed secret references to be passed as structured { type: "secret_ref", secretId } objects (rather than raw UUID strings), while keeping legacy non-UUID references unchanged. It also tightens fallback behavior so the company-scoped token fallback is only used for specific “secret ref unavailable/invalid ref” host errors, and adds targeted regression tests.
Changes:
- Add a wrapper (
resolvePluginSecret) that converts UUID-shaped secret refs into structuredsecret_refobjects before callingctx.secrets.resolve. - Refine the “secret refs unavailable” error classification to include the documented invalid-secret-reference host error.
- Add regression tests for structured secret refs, scoped fallback behavior, and fail-closed resolver/provider errors.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/worker.ts | Adds UUID→structured secret ref conversion and narrows fallback eligibility to specific host error cases. |
| tests/plugin.spec.ts | Adds regression tests covering structured secret refs, fallback gating, and fail-closed resolver errors. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@alvarosanchez Please review the updated head 4f8a497 after CI completes. It resolves both secret-reference threads (UUIDv6/v7/v8 structured refs and resolver method binding); focused regression, typecheck, full test suite, and build passed. |
alvarosanchez
left a comment
There was a problem hiding this comment.
Requesting changes because the patch does not work against either side of the repository's stated host-compatibility range.
-
Blocking — the newer host contract requires an explicit company scope, but every new call omits it (
src/worker.ts:2929-2936). Since Paperclip v2026.720.0,PluginSecretsClient.resolveforwardsoptions.companyId/configPath, and the host rejects a call withoutcompanyIdbefore resolution.resolvePluginSecretwidens only the first argument and invokessecrets.resolve(...)with one argument, so all four changed paths still fail withcompanyId is required for this operation. The new unit tests replaceharness.ctx.secrets.resolvewith a permissive one-argument stub, so they cannot detect this production RPC failure. -
Blocking — the plugin still stores refs as UUID strings, so newer hosts do not create the binding that structured resolution requires (
src/manifest.ts:57-69,src/ui/plugin-config.ts:1-6, and the config writes aroundsrc/ui/index.tsx:12025-12028/12132-12135). Current Paperclip extracts/binds object-shaped{ type: "secret_ref", secretId, version? }values from company-scoped plugin config and deliberately ignores UUID strings outside schema-declared secret fields. This manifest declares these map values as plain strings, and the UI normalizers discard object values. Converting the UUID only atsrc/worker.ts:2923-2926is therefore too late: after addingcompanyId, the host still returnsbinding_missingbecause no plugin binding was registered. -
Blocking — unconditional UUID conversion breaks the repository's enforced Paperclip 2026.626.0 baseline (
src/worker.ts:2923-2926; baseline asserted intests/build-script.spec.mjs:10,54-58). That host accepts only a UUID string. Passing the new object producesInvalid secret reference: [object Object], which the broadened fallback classifier does not recognize because the message contains neithersecret_refnor the old disabled-host wording. GitHub and board secret resolution therefore regress on the supported baseline.
The full local pnpm typecheck, pnpm test (335/335), and pnpm build pass at head 4f8a497e1851a28b774d05144bac246f85173f19, but those tests exercise mocked resolver shapes rather than either real host bridge. Please either implement and test an explicit dual-host path, or intentionally raise/synchronize the minimum host+SDK boundary; for the newer path, persist structured refs in trusted company-scoped config and call resolve(ref, { companyId, configPath }) through an SDK version that forwards those options.
What changed
{ type: "secret_ref", secretId }form required by newer Paperclip hosts.Root cause
The published worker normalizes saved secret refs to UUID strings and passes those strings directly to
ctx.secrets.resolve. Newer Paperclip hosts require UUID-backed refs as structuredsecret_refobjects, so configured GitHub operations fail before the already provisioned company-scoped fallback can be considered.Impact
This restores compatibility with the current host secret-reference contract without rotating, reconnecting, or logging credentials. It does not widen fallback behavior for permission failures or arbitrary resolver errors.
Validation
The originating implementation run passed:
pnpm typecheckpnpm testpnpm buildgit diff --checkPublication recovery verified this branch is exactly one commit ahead of upstream
mainand changes onlysrc/worker.tsandtests/plugin.spec.ts(104 insertions, 9 deletions).