Handle reused Codex approval request IDs

Treat app-server request IDs as connection-local by reopening reused approval rows when the thread, turn, or item context changes.

Keep duplicate resolved approvals in the same context closed, and add focused approval-path diagnostics without changing the Telegram approval UI.
This commit is contained in:
Codex
2026-05-28 10:11:42 +00:00
parent c00ffb42f2
commit 34e909f9cf
3 changed files with 122 additions and 6 deletions

View File

@@ -267,6 +267,62 @@ func TestUpsertPendingApprovalDoesNotReopenResolved(t *testing.T) {
}
}
func TestUpsertPendingApprovalReopensReusedRequestIDForNewContext(t *testing.T) {
ctx := context.Background()
st, err := Open(ctx, filepath.Join(t.TempDir(), "bot.db"))
if err != nil {
t.Fatal(err)
}
defer st.Close()
first, err := st.UpsertPendingApproval(ctx, PendingApproval{
TelegramUserID: 42,
CodexRequestID: "i:0",
CodexThreadID: "thread-1",
TurnID: "turn-1",
ItemID: "item-1",
Kind: "item/commandExecution/requestApproval",
PayloadJSON: `{"command":"go test ./..."}`,
})
if err != nil {
t.Fatal(err)
}
if err := st.UpdatePendingApprovalMessage(ctx, first.ID, 1001, 2002); err != nil {
t.Fatal(err)
}
if err := st.ResolvePendingApproval(ctx, 42, first.ID, "accept"); err != nil {
t.Fatal(err)
}
second, err := st.UpsertPendingApproval(ctx, PendingApproval{
TelegramUserID: 42,
CodexRequestID: "i:0",
CodexThreadID: "thread-2",
TurnID: "turn-2",
ItemID: "item-2",
Kind: "item/commandExecution/requestApproval",
PayloadJSON: `{"command":"git push"}`,
})
if err != nil {
t.Fatal(err)
}
if second.ID != first.ID {
t.Fatalf("reused request id row = %d, want %d", second.ID, first.ID)
}
if second.Status != "pending" {
t.Fatalf("reused request status = %q, want pending", second.Status)
}
if second.CodexThreadID != "thread-2" || second.TurnID != "turn-2" || second.ItemID != "item-2" {
t.Fatalf("reused request context = thread %q turn %q item %q", second.CodexThreadID, second.TurnID, second.ItemID)
}
if second.MessageChatID != 0 || second.MessageID != 0 {
t.Fatalf("reused request kept stale message: chat=%d message=%d", second.MessageChatID, second.MessageID)
}
if second.ResolvedAt != "" {
t.Fatalf("reused request resolved_at = %q, want empty", second.ResolvedAt)
}
}
func TestValidateWorkspacePath(t *testing.T) {
if _, err := ValidateWorkspacePath("relative/path"); err == nil {
t.Fatal("relative path should be rejected")