Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3b91154
fix(desktop): bind side conversation events to host admission
Astro-Han Aug 24, 2026
4979952
fix(desktop): update side chat story send result
Astro-Han Aug 24, 2026
53cb02d
fix(desktop): preserve side conversation admission identity
Astro-Han Aug 24, 2026
02cdd06
fix(desktop): close side conversation admission races
Astro-Han Aug 24, 2026
30b3aac
fix(side-chat): preserve admission on unknown stop
Astro-Han Aug 24, 2026
7aa4def
fix(side-chat): report Host admission ownership
Astro-Han Aug 24, 2026
80d30ad
fix(side-chat): preserve Host admission across recovery
Astro-Han Aug 24, 2026
52aea70
fix(side-chat): resolve admission outcomes by ticket
Astro-Han Aug 24, 2026
322d79d
fix(side-chat): retain admission fencing after bind
Astro-Han Aug 24, 2026
dffbd84
refactor(side-chat): unify admission outcome events
Astro-Han Aug 24, 2026
25ee0b9
fix(side-chat): isolate admission retry semantics
Astro-Han Aug 24, 2026
b013b41
refactor(side-chat): centralize admission transitions
Astro-Han Aug 24, 2026
974287b
test(side-chat): compress admission race fixtures
Astro-Han Aug 24, 2026
0eea85d
refactor(side-chat): require admission source tickets
Astro-Han Aug 24, 2026
bbc642d
fix(side-chat): scope admission projection
Astro-Han Aug 24, 2026
24d0c27
fix(side-chat): follow replacement Host scope
Astro-Han Aug 24, 2026
507be43
fix(side-chat): replay admission after unknown stop
Astro-Han Aug 24, 2026
7b45f51
fix(side-chat): fence replacement Host profile
Astro-Han Aug 24, 2026
b0d7d23
test(side-chat): preserve streaming after unknown stop
Astro-Han Aug 24, 2026
47551c2
fix(side-chat): keep active turn during admission
Astro-Han Aug 25, 2026
9d4d202
fix(desktop): preserve renderer send identity
Astro-Han Aug 25, 2026
8b25961
fix(desktop): reconnect session observation setup
Astro-Han Aug 25, 2026
93a6824
fix(side-chat): fence overlapping stop results
Astro-Han Aug 25, 2026
b682bc7
fix(side-chat): admit active turn steering
Astro-Han Aug 25, 2026
1313c13
fix(side-chat): replay durable steering admission
Astro-Han Aug 25, 2026
1840516
fix(side-chat): confirm queued admission retraction
Astro-Han Aug 25, 2026
ecba49b
fix(side-chat): consume quotes on admission
Astro-Han Aug 25, 2026
cb56d22
fix(side-chat): admit only durable turn ownership
Astro-Han Aug 25, 2026
920fbf4
fix(side-chat): fence stop by identity kind
Astro-Han Aug 25, 2026
fde6c3b
refactor(side-chat): use durable transcript admission authority
Astro-Han Aug 25, 2026
6f9608c
style(side-chat): format admission projection
Astro-Han Aug 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,24 @@ describe('permission response IPC boundary', () => {
normalizeStopSessionInput({
source: 'stop_button',
expectedTurnId: 'turn-workhub',
expectedAdmissionId: 'side-admission',
extra: true,
}),
{ source: 'stop_button', expectedTurnId: 'turn-workhub' },
{
source: 'stop_button',
expectedTurnId: 'turn-workhub',
expectedAdmissionId: 'side-admission',
},
);
assert.throws(() => normalizeStopSessionInput(null), /stop session input/);
assert.throws(() => normalizeStopSessionInput({ source: 'toolbar' }), /stop session source/);
assert.throws(
() => normalizeStopSessionInput({ expectedTurnId: '' }),
/expectedTurnId/,
);
assert.throws(
() => normalizeStopSessionInput({ expectedAdmissionId: '' }),
/expectedAdmissionId/,
);
});
});
16 changes: 5 additions & 11 deletions apps/desktop/src/main/__tests__/quote-companion-disposal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ function turnDeps(
quotes: undefined,
onForkCommitted: () => undefined,
onBeforeSend: () => undefined,
onQuotesConsumed: () => undefined,
...overrides,
};
}
Expand Down Expand Up @@ -121,7 +120,7 @@ describe('quote companion disposal fencing', () => {
...defaults.sideChat,
send: async () => {
sends += 1;
return { ok: true as const };
return { ok: true as const, turnId: 'side-chat-turn' };
},
};

Expand All @@ -139,10 +138,9 @@ describe('quote companion disposal fencing', () => {
assert.equal(sends, 0);
});

it('does not consume quotes or report success when disposal wins the send race', async () => {
const pendingSend = deferred<{ ok: true }>();
it('does not report success when disposal wins the send race', async () => {
const pendingSend = deferred<{ ok: true; turnId: string }>();
let disposed = false;
let consumed = 0;
const defaults = createFakeWorkbarServices();
const sideChat = {
...defaults.sideChat,
Expand All @@ -151,17 +149,13 @@ describe('quote companion disposal fencing', () => {
const turn = performCompanionTurn(
turnDeps(sideChat, {
isDisposed: () => disposed,
onQuotesConsumed: () => {
consumed += 1;
},
}),
);

disposed = true;
pendingSend.resolve({ ok: true });
pendingSend.resolve({ ok: true, turnId: 'side-chat-turn' });

assert.deepEqual(await turn, { status: 'disposed' });
assert.equal(consumed, 0);
});

it('cleans a fork that resolves after its panel was disposed and never sends', async () => {
Expand All @@ -179,7 +173,7 @@ describe('quote companion disposal fencing', () => {
},
send: async () => {
sends += 1;
return { ok: true as const };
return { ok: true as const, turnId: 'side-chat-turn' };
},
};
const turn = performCompanionTurn(
Expand Down
Loading