Skip to content

Commit 41f8cf3

Browse files
committed
fix(plugin-sharing): createLink asks the mint probe without two new isSystem reads
A system caller's read runs under the system context, and the probe admits only on a row it re-reads the same way, so the two added checks bought nothing and moved the system-context census. Pinned: a system caller keeps its 404 for a missing record with the probe wired. Claude-Session: https://claude.ai/code/session_01DiCSbmJrkzNhuEAier4VoJ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6bf7f10 commit 41f8cf3

2 files changed

Lines changed: 13 additions & 2 deletions

File tree

‎packages/plugins/plugin-sharing/src/share-link-service.test.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,12 @@ describe('[ADR-0111 D8 rule 1 / ruling A′] mint authority: visibility, or the
13181318
expect(link).toMatchObject({ record_id: 'c1', created_by: ADMIN });
13191319
});
13201320

1321+
it('a system caller keeps its 404 for a missing record, with the probe wired', async () => {
1322+
await expect(service.createLink(mintIn('conversations', 'ghost'), { isSystem: true, userId: OWNER } as any))
1323+
.rejects.toMatchObject({ status: 404, code: 'RECORD_NOT_FOUND' });
1324+
expect(minted()).toEqual([]);
1325+
});
1326+
13211327
it('visibility still admits on its own, without asking the owner/bypass probe', async () => {
13221328
const link = await service.createLink(conversation(), as(READER));
13231329
expect(link.created_by).toBe(READER);

‎packages/plugins/plugin-sharing/src/share-link-service.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,6 @@ export class ShareLinkService implements IShareLinkService {
599599
try {
600600
record = await readRecord(context.isSystem ? SYSTEM_CTX : context);
601601
} catch (err) {
602-
if (context.isSystem) throw err;
603602
visibilityRefusal = err;
604603
}
605604

@@ -611,7 +610,13 @@ export class ShareLinkService implements IShareLinkService {
611610
// the record is read under the system context: the caller's authority is
612611
// established, and the eligibility gate below must judge the row the
613612
// anonymous holder will be served (`resolveToken` reads it the same way).
614-
if (!record && !context.isSystem && this.canMintWithoutVisibility) {
613+
//
614+
// A system caller reaches the probe only when its own system-context read
615+
// found nothing or failed, and the probe grants it nothing it lacks: it
616+
// admits only on a row it re-reads under that same system context. So a
617+
// missing record still answers a system caller 404, and a failing read
618+
// still fails.
619+
if (!record && this.canMintWithoutVisibility) {
615620
const admitted = await this.canMintWithoutVisibility(input.object, input.recordId, context)
616621
.catch(() => false);
617622
if (admitted) record = await readRecord(SYSTEM_CTX);

0 commit comments

Comments
 (0)