Media row reads room ids from @rooms.file_zones #153
3 changed files with 36 additions and 9 deletions
|
|
@ -97,9 +97,11 @@ Probes run by Imagination on 2026-10-31, session `self-2026-10-29-eureka`.
|
|||
events from the Minds' stewardship documents; each project room's alias is
|
||||
`#<repo lowercased>` (runbook 146-150). This is the only place the client
|
||||
can learn a not-yet-joined room's steward today: hierarchy `canonical_alias`
|
||||
joined to the root `org.gamecult.stewardships`. Follow-up
|
||||
`ratatoskr:follow_up:stewardships-carry-room-ids` asks the projection to
|
||||
name room ids so the client stops leaning on the alias convention.
|
||||
joined to the root `org.gamecult.stewardships`. The
|
||||
projection now also names room ids under `@rooms.projects` and
|
||||
`@rooms.file_zones` (gamecult-ops #111); the client reads `file_zones` for
|
||||
the Media row (`mediaRoom.ts`) and still joins projects by alias, since
|
||||
nothing yet consumes `@rooms.projects`.
|
||||
5. **Sync and storage** (`src/client/initMatrix.ts`). The client uses
|
||||
matrix-js-sdk 41.7.0 with `IndexedDBStore` (`web-sync-store`, 15-19) and the
|
||||
Rust crypto store, and `startClient({ lazyLoadMembers: true })` (43-47): v2
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ describe('the Media row of a Mind', () => {
|
|||
throw new Error('must not be asked');
|
||||
});
|
||||
const carried = mediaRoomIdFromStewardships(
|
||||
{ void: ['GameCult/x'], media: { void: '!c:gamecult.org' } },
|
||||
{ void: ['GameCult/x'], '@rooms': { file_zones: { void: '!c:gamecult.org' } } },
|
||||
'void'
|
||||
);
|
||||
expect(carried).toBe('!c:gamecult.org');
|
||||
|
|
@ -58,7 +58,23 @@ describe('the Media row of a Mind', () => {
|
|||
|
||||
it('ignores a stewardships state that carries no id for the Mind, or something that is not a room id', () => {
|
||||
expect(mediaRoomIdFromStewardships({ void: ['GameCult/x'] }, 'void')).toBeUndefined();
|
||||
expect(mediaRoomIdFromStewardships({ media: { void: 'nope' } }, 'void')).toBeUndefined();
|
||||
expect(
|
||||
mediaRoomIdFromStewardships({ '@rooms': { file_zones: { void: 'nope' } } }, 'void')
|
||||
).toBeUndefined();
|
||||
// the project ids beside it, another Mind's id, and the old provisional key carry nothing for this Mind
|
||||
expect(
|
||||
mediaRoomIdFromStewardships(
|
||||
{
|
||||
'@rooms': { projects: { x: '!p:s' }, file_zones: { kiko: '!k:s' } },
|
||||
media: { void: '!m:s' },
|
||||
},
|
||||
'void'
|
||||
)
|
||||
).toBeUndefined();
|
||||
// a Mind named "constructor" must not read an inherited property as an id
|
||||
expect(
|
||||
mediaRoomIdFromStewardships({ '@rooms': { file_zones: {} } }, 'constructor')
|
||||
).toBeUndefined();
|
||||
expect(mediaRoomIdFromStewardships(undefined, 'void')).toBeUndefined();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,20 +2,29 @@
|
|||
* A Mind's media room: the file-zone room Eureka provisions under the alias #<mind>-files:<server>.
|
||||
* The navigator shows a Media row for every Mind; this module decides what that row says and where it points.
|
||||
* A room id carried by the root Space's org.gamecult.stewardships state wins over the alias; the alias is the
|
||||
* convention until the provisioning projection carries ids (ratatoskr:follow_up:stewardships-carry-room-ids).
|
||||
* fallback for a Mind whose zone the provisioning run has not recorded yet.
|
||||
*/
|
||||
import { EstateRoom } from './buildEstate';
|
||||
|
||||
export const STEWARDSHIPS_KEY = 'org.gamecult.stewardships';
|
||||
|
||||
/** Where provisioning records room ids in the stewardships state (gamecult-ops synapse-accounts-hand-managed.py ROOMS_KEY). "@" is no legal Matrix localpart, so no Mind can own the key. */
|
||||
export const ROOMS_KEY = '@rooms';
|
||||
|
||||
export const mediaAlias = (mind: string, server: string): string => `#${mind}-files:${server}`;
|
||||
|
||||
/**
|
||||
* The room id the stewardships state names for a Mind's media room, if it does. The state's mind-to-repos
|
||||
* lists are not read here; the id lives under `media[<mind>]` (provisional shape, awaiting the follow-up above).
|
||||
* The room id the stewardships state names for a Mind's media room, under `@rooms.file_zones[<mind>]`.
|
||||
* The state's mind-to-repos lists are not read here.
|
||||
*/
|
||||
export const mediaRoomIdFromStewardships = (content: unknown, mind: string): string | undefined => {
|
||||
const id = (content as { media?: Record<string, unknown> } | null | undefined)?.media?.[mind];
|
||||
const rooms = (
|
||||
content as
|
||||
| Record<string, { file_zones?: Record<string, unknown> } | undefined>
|
||||
| null
|
||||
| undefined
|
||||
)?.[ROOMS_KEY];
|
||||
const id = rooms?.file_zones?.[mind];
|
||||
return typeof id === 'string' && id.startsWith('!') ? id : undefined;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue