Scope secure-save ACK negation to the action being declined

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-11-06 03:19:36 -06:00
1 parent f026c43175
commit de6b8c0dc3
2 files changed
+22 -4

No files matched your search

@@ -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();
});
@@ -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;