Skip to content

Commit e682dcd

Browse files
fix(notices): order published() by parsed createdAt instant
1 parent 66bd041 commit e682dcd

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

‎packages/rsc-runtime/src/notices/ledger.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,13 @@ const publishedProgram = Effect.fnUntraced(function*(
536536
principal: request.principal,
537537
recipient: notice.recipient,
538538
}).pipe(Effect.map((decision) => ({ decision, notice }))));
539+
// Chronological by instant, not by string: `createdAt` is whatever valid
540+
// ISO-8601 the publishing invocation started with, offsets included.
539541
return Object.freeze(decisions
540542
.filter(({ decision }) => decision.state === 'authorized')
541543
.map(({ notice }) => notice)
542-
.toSorted((left, right) => left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id))
544+
.toSorted((left, right) =>
545+
Date.parse(left.createdAt) - Date.parse(right.createdAt) || left.id.localeCompare(right.id))
543546
.map((notice) => currentlyDisclosedNotice(notice, 'mcp-inbox', undefined).notice));
544547
});
545548

‎packages/rsc-runtime/tests/notices-ledger.test.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1951,6 +1951,27 @@ describe('publisher-scoped visibility (#460)', () => {
19511951
await driver.close();
19521952
});
19531953

1954+
it('orders published notices by the instant they were created, whatever offset the invocation spelled', async () => {
1955+
const { driver, ledger } = await openLedger();
1956+
const publishAt = (id: string, startedAt: string) => run(ledger, { actorId: 'author', id, kind: 'tool', startedAt },
1957+
async () => (await agent()).notices!.publish({
1958+
content: document(id),
1959+
priority: 'normal',
1960+
recipient: { actor: { id: 'recipient' } },
1961+
}, { idempotencyKey: `publish:${id}` }));
1962+
// Lexically the +02:00 stamp sorts after the Z stamp; chronologically it is 90 minutes earlier.
1963+
const later = await publishAt('later', '2026-01-01T00:30:00.000Z');
1964+
const earlier = await publishAt('earlier', '2026-01-01T01:00:00.000+02:00');
1965+
const own = await run(ledger, {
1966+
actorId: 'author',
1967+
id: 'published-order',
1968+
kind: 'tool',
1969+
startedAt: '2026-01-01T03:00:00.000Z',
1970+
}, async () => (await agent()).notices!.published());
1971+
expect(own.map((notice) => notice.id)).toEqual([earlier.notice.id, later.notice.id]);
1972+
await driver.close();
1973+
});
1974+
19541975
it('discloses published content under the default internal ceiling and never another author\'s deduped content', async () => {
19551976
const { driver, ledger } = await openLedger();
19561977
const publishAs = (actorId: string, id: string, input: AgentNoticePublishInput) =>

0 commit comments

Comments
 (0)