diff --git a/web/src/routes/[username]/[workspace]/settings/+page.svelte b/web/src/routes/[username]/[workspace]/settings/+page.svelte index d7a016ed8..f325be700 100644 --- a/web/src/routes/[username]/[workspace]/settings/+page.svelte +++ b/web/src/routes/[username]/[workspace]/settings/+page.svelte @@ -703,17 +703,6 @@ } } - // TASK-3376: system collections are ordinary choices for a restricted - // member. Moving a member from All to Specific starts with them checked, - // so restricting someone does not silently stop their agents loading the - // workspace's rules. A member already restricted keeps their saved list. - function setAccessMode(next: 'all' | 'specific') { - if (next === 'specific' && accessMode !== 'specific' && accessCollectionIds.length === 0) { - accessCollectionIds = systemCollections.map((c) => c.id); - } - accessMode = next; - } - function toggleAccessCollection(collId: string) { if (accessCollectionIds.includes(collId)) { accessCollectionIds = accessCollectionIds.filter(id => id !== collId); @@ -1053,7 +1042,7 @@ id="access-mode-{member.user_id}" class="role-select" value={accessMode} - onchange={(e) => { setAccessMode((e.target as HTMLSelectElement).value as 'all' | 'specific'); }} + onchange={(e) => { accessMode = (e.target as HTMLSelectElement).value as 'all' | 'specific'; }} > @@ -1086,7 +1075,8 @@ {/each} {#if systemCollections.length > 0}
- {systemCollections.map((c) => c.name).join(' and ')} hold the rules and procedures agents load. Unchecked, this member's agents won't receive them. + + Unchecked, {systemCollections.map((c) => c.name).join(' and ')} stay hidden from this member, and their agents won't load the workspace's conventions or playbooks.
{/if} diff --git a/web/src/routes/[username]/[workspace]/settings/task3376SystemCollectionPicker.svelte.test.ts b/web/src/routes/[username]/[workspace]/settings/task3376SystemCollectionPicker.svelte.test.ts index a9e86d84b..bddc45ec9 100644 --- a/web/src/routes/[username]/[workspace]/settings/task3376SystemCollectionPicker.svelte.test.ts +++ b/web/src/routes/[username]/[workspace]/settings/task3376SystemCollectionPicker.svelte.test.ts @@ -6,10 +6,12 @@ import SettingsPage from './+page.svelte'; /** * TASK-3376: system collections (Conventions, Playbooks) are ordinary * collections for a restricted member. In the member access picker they are - * real checkboxes, not a disabled always-checked row, and they start CHECKED - * when an owner switches a member from All to Specific, so that restricting - * someone does not silently stop their agents loading the workspace's rules. - * A member who is ALREADY restricted keeps their saved list as is. + * real checkboxes, not a disabled always-checked row. They start UNCHECKED + * when an owner switches a member from All to Specific (TASK-3384, Dave's + * ruling), like every other collection, and a hint names what leaving them + * unchecked means: that member's agents won't load the workspace's + * conventions or playbooks. A member who is ALREADY restricted keeps their + * saved list as is. */ const meCalls: Array<(value: unknown) => void> = []; @@ -112,21 +114,28 @@ describe('TASK-3376: system collections in the member access picker', () => { window.location.hash = ''; }); - it('All to Specific starts with the system collections checked, and they can be unchecked', async () => { + it('All to Specific starts with nothing checked, the system collections included, and the hint names the consequence', async () => { await openAccessPanel(); setAccessMode('specific'); - await waitFor(() => expect(checkbox('Conventions').checked).toBe(true)); - expect(checkbox('Playbooks').checked).toBe(true); + await waitFor(() => expect(checkbox('Conventions')).toBeTruthy()); + expect(checkbox('Conventions').checked).toBe(false); + expect(checkbox('Playbooks').checked).toBe(false); expect(checkbox('Tasks').checked).toBe(false); // Real choices, not the old disabled always-checked row. expect(checkbox('Conventions').disabled).toBe(false); expect(checkbox('Playbooks').disabled).toBe(false); + const hint = document.querySelector('.access-coll-hint'); + expect(hint?.textContent).toMatch(/agents won.t load .*conventions.*playbooks/i); - checkbox('Conventions').click(); - await waitFor(() => expect(checkbox('Conventions').checked).toBe(false)); + // Checking one is an ordinary choice, saved like any collection. + checkbox('Playbooks').click(); + await waitFor(() => expect(checkbox('Playbooks').checked).toBe(true)); + checkbox('Tasks').click(); + await waitFor(() => expect(checkbox('Tasks').checked).toBe(true)); screen.getByRole('button', { name: /^Save$/ }).click(); await waitFor(() => expect(saves.length).toBe(1)); - expect(saves[0]).toEqual({ mode: 'specific', ids: ['c-pb'] }); + expect([...saves[0].ids].sort()).toEqual(['c-pb', 'c-tasks']); + expect(saves[0].mode).toBe('specific'); }); it('an already-restricted member keeps their saved list; nothing is added for them', async () => {