From de6b8c0dc346aa0a847aafe05ff6c0abab9d6872 Mon Sep 17 00:00:00 2001 From: Dotta Date: Fri, 6 Nov 2026 03:07:10 -0600 Subject: [PATCH] Scope secure-save ACK negation to the action being declined Co-Authored-By: Paperclip --- .../external-company-secret-confirmation.test.ts | 14 ++++++++++++++ .../external-company-secret-confirmation.ts | 12 ++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.test.ts b/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.test.ts index b1d601a9a5f..08130fbbad5 100644 --- a/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.test.ts +++ b/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.test.ts @@ -70,3 +70,17 @@ it("keeps secure-save acknowledgment acceptance dependent on a later current-per for(const change of [{createdAt:"2026-11-04T13:28:00Z"},{createdByUserId:"other"},{companyId:"other"},{key:"other_key"},{name:"Other secret"}])expect(companySecretSaveMatches({...saved,...change},binding,handoff)).toBe(false); expect(companySecretConfirmationHandoff({...card(),originCommentIds:["other"]},binding,guidance)).toBeUndefined(); }); + +it("keeps unrelated safety warnings outside save and acknowledgment negation",()=>{ + const context="Use Settings > Secrets (`/RUN/company/settings/secrets`) for the deployment key so I can bind its reference to Morgan's environment. "; + for(const text of [ + "Save the deployment key there. Never paste the value in chat. Then accept this card.", + "Never paste the key in chat, then save the deployment key there. Then accept this card.", + "After saving the deployment key in the secure Settings Secrets form, confirm here so I can bind its reference to Morgan's environment.", + ])expect(companySecretConfirmationHandoff({...card(),payload:{...card().payload,prompt:context+text}},binding,guidance),text).toBeDefined(); + for(const text of [ + "Save the deployment key there. Do not confirm yet. Then accept this card.", + "After saving your profile, confirm here that secure entry is complete.", + "Never save the deployment key there. Then accept this card.", + ])expect(companySecretConfirmationHandoff({...card(),payload:{...card().payload,prompt:context+text}},binding,guidance),text).toBeUndefined(); +}); diff --git a/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.ts b/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.ts index 2cea9e88e04..9d7957537d0 100644 --- a/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.ts +++ b/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.ts @@ -15,13 +15,17 @@ export interface CompanyConfirmationBinding extends SecretQuestionBinding {canon function orderedSecureSaveAcknowledgment(prompt:string){ const clauses=[...prompt.matchAll(/[^.!?;\n]+/g)]; for(const clause of clauses){ - const save=/\b(?:save|enter|set)\s+(?:the\s+)?(?:deployment\s+(?:api\s+)?(?:key|credential|secret)|(?:secret|credential|key)\s+value|value|it)\b/i.exec(clause[0]); - if(!save||/\b(?:not|never|don.t|cancel|decline|skip|avoid|earlier|previously|formerly|may I|can I|will you)\b/i.test(clause[0].slice(0,save.index)))continue; + const save=/\b(?:save|enter|set|saving|entering|setting)\s+(?:the\s+)?(?:deployment\s+(?:api\s+)?(?:key|credential|secret)|(?:secret|credential|key)\s+value|value|it)\b/i.exec(clause[0]); + if(!save)continue; + const before=clause[0].slice(0,save.index).trim(); + if(/(?:\b(?:do|should|must|can|could|will|would)\s+not|\bdon.t|\bnever|\b(?:cancel|decline|skip|avoid)(?:\s+to)?)\s*$/i.test(before) + ||/\b(?:earlier|previously|formerly|may I|can I|will you)\b/i.test(before) + ||/^(?:saving|entering|setting)\b/i.test(save[0])&&!/\b(?:after|once)\s*$/i.test(before))continue; const after=prompt.slice(clause.index!+save.index+save[0].length); for(const acknowledgment of after.matchAll(/\b(?:accept|confirm)\b[^.!?;\n]*/gi)){ const between=after.slice(0,acknowledgment.index),intent=acknowledgment[0]; - if(/\b(?:cancel|decline|skip|avoid|do not|don.t|never)\b/i.test(between)||/\b(?:before|permission|authorize|another|other card)\b/i.test(intent))continue; - if(/^(?:accept|confirm)\s+(?:this\s+card|here\b[^.!?;\n]{0,80}\b(?:secure entry|saved|complete)|(?:that\s+)?(?:the\s+)?(?:deployment\s+(?:api\s+)?key|secure entry)\b[^.!?;\n]{0,80}\b(?:saved|complete))/i.test(intent))return true; + if(/\b(?:(?:do not|don.t|never)\s+(?:save|enter|set|accept|confirm)|(?:cancel|decline|skip|avoid)(?:\s+(?:the|to))?\s+(?:save|saving|entry|acknowledgment|confirmation|accept|confirm))\b/i.test(between)||/\b(?:before|permission|authorize|another|other card)\b/i.test(intent))continue; + if(/^(?:accept|confirm)\s+(?:this\s+card|here\b|(?:that\s+)?(?:the\s+)?(?:deployment\s+(?:api\s+)?key|secure entry)\b[^.!?;\n]{0,80}\b(?:saved|complete))/i.test(intent))return true; } } return false;