Repository navigation
fix: private secrets keep their spaces exactly as typed - #31722
juliusmarminge wants to merge 4 commits into
Conversation
These tests reproduce #31690: a saved secret should be delivered exactly as typed. Today the client trims it (and refuses a whitespace-only value) and the wire contract trims it again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The secret card trimmed the value in the client and again in the wire contract, so leading/trailing whitespace was lost and a whitespace-only secret could not be saved. Only an empty value now counts as empty: the contract uses Schema.NonEmptyString, the client stops trimming, and the web and mobile "Save securely" buttons enable for any non-empty value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ty secret Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Secret submissions now retain whitespace exactly as entered across web, mobile, and the shared input contract. Existing private storage and delivery behavior remain unchanged, and empty values are still rejected. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
Problem
The private secret card (shown when an agent calls
request_secret) would not accept a secret made only of whitespace: with a single space typed, Save securely stayed disabled. Secrets with leading or trailing spaces were silently trimmed before they were stored. On main (938b4d4) in the web dev app, typing" "left Save disabled, and saving" pw "delivered a 2-byte file containingpw.Change
The secret is now kept exactly as typed, and only an empty field counts as empty:
packages/contracts: thesaveanswer'ssecretisSchema.NonEmptyStringinstead ofTrimmedNonEmptyString, so the server no longer trims it or rejects whitespace-only values on decode.packages/client-runtime:secretRequestAnswerInputno longer trims the secret.SecretRequestCard: Save is disabled only whensecret.length === 0.Storage and file delivery already passed the value through unchanged.
Scope and approval
Fixes #31690
Verification
vp test run packages/client-runtime/src/secretRequest.test.ts: the new test sends values throughsecretRequestAnswerInputand then the wire contract decode. On main it fails withexpected 'pass word' to be ' pass word '. With the fix, 4/4 tests pass, including a direct check that the contract still rejects"".vp test run apps/server/src/secrets/SecretRequests.test.ts: 17/17.vp run check:changedon the merged head: format, lint, knip, typecheck (36 packages), tests and react compiler all pass.Delivered file bytes (real app, fresh databases, an agent calling
request_secretwithdelivery: "file";od -An -tx1 -vandwc -con the returned file):" pw "70 77" "20" pw "20 20 70 77 20 20" "20" pw "20 20 70 77 20 20" "20" pw "20 20 70 77 20 20On main,
" "cannot be submitted at all.Evidence (Chrome, 1280×900 CSS px, DPR 2, dark; Pixel 9 and iPhone 17 Pro from the device pool, dark, large text). The images are attached below:
Not checked: interaction recordings were made but could not be published, so clear/retype and Enter/Done ordering rest on the stills and byte table above. Only the web single-space pair has diff images, and those diffs also include the unrelated run differences listed above. There is no unpadded
pwcontrol capture. Mobile was captured only after the fix; the mobile change is the same one-line predicate as web. A newer client talking to an older server still has the old trimming on the server side.AI-assisted; verified with the tests and tools listed above.
🤖 Generated with Claude Code