Discord: thread bindings idle + max-age lifecycle (#27845) (thanks @osolmaz)

* refactor discord thread bindings to idle and max-age lifecycle

* fix: migrate legacy thread binding expiry and reduce hot-path disk writes

* refactor: remove remaining thread-binding ttl legacy paths

* fix: harden thread-binding lifecycle persistence

* Discord: fix thread binding types in message/reply paths

* Infra: handle win32 unknown inode in file identity checks

* Infra: relax win32 guarded-open identity checks

* Config: migrate threadBindings ttlHours to idleHours

* Revert "Infra: relax win32 guarded-open identity checks"

This reverts commit de94126771.

* Revert "Infra: handle win32 unknown inode in file identity checks"

This reverts commit 96fc5ddfb3.

* Discord: re-read live binding state before sweep unbind

* fix: add changelog note for thread binding lifecycle update (#27845) (thanks @osolmaz)

---------

Co-authored-by: Onur Solmaz <onur@textcortex.com>
This commit is contained in:
Onur Solmaz
2026-02-27 10:02:39 +01:00
committed by GitHub
parent 0fb7add7d6
commit a7929abad8
45 changed files with 1656 additions and 402 deletions

View File

@@ -112,7 +112,8 @@ function createFakeThreadBindingManager(initialBindings: FakeBinding[] = []) {
);
const manager = {
getSessionTtlMs: vi.fn(() => 24 * 60 * 60 * 1000),
getIdleTimeoutMs: vi.fn(() => 24 * 60 * 60 * 1000),
getMaxAgeMs: vi.fn(() => 0),
getByThreadId: vi.fn((threadId: string) => byThread.get(threadId)),
listBySessionKey: vi.fn((targetSessionKey: string) =>
[...byThread.values()].filter((binding) => binding.targetSessionKey === targetSessionKey),
@@ -286,7 +287,7 @@ describe("/focus, /unfocus, /agents", () => {
targetSessionKey: "agent:codex-acp:session-1",
metadata: expect.objectContaining({
introText:
"⚙️ codex-acp session active (auto-unfocus in 24h). Messages here go directly to this session.",
"⚙️ codex-acp session active (idle auto-unfocus after 24h inactivity). Messages here go directly to this session.",
}),
}),
);