feat(fleet): add shared role semantics (#768)
This commit was merged in pull request #768.
This commit is contained in:
@@ -203,6 +203,91 @@ describe('loadProfiles with a temp override dir', () => {
|
||||
await rm(dir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('canonicalizes approved aliases across lead, floor, roster, and topology', async () => {
|
||||
await writeFile(
|
||||
join(dir, 'aliases.yaml'),
|
||||
[
|
||||
'id: aliases',
|
||||
'title: Aliases',
|
||||
'description: legacy class compatibility',
|
||||
'lead: operator-interaction',
|
||||
'floor: [operator-interaction]',
|
||||
'roster:',
|
||||
' - class: operator-interaction',
|
||||
' - class: implementer',
|
||||
' reports_to: operator-interaction',
|
||||
' - class: reviewer',
|
||||
' reports_to: operator-interaction',
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
const profile = await loadProfile('aliases', {
|
||||
profilesDir: dir,
|
||||
rolesDir,
|
||||
overrideDir: join(dir, 'roles.local'),
|
||||
});
|
||||
expect(profile.lead).toBe('interaction');
|
||||
expect(profile.floor).toEqual(['interaction']);
|
||||
expect(profile.roster).toEqual([
|
||||
{ class: 'interaction', multiplicity: 1 },
|
||||
{ class: 'code', reportsTo: 'interaction', multiplicity: 1 },
|
||||
{ class: 'review', reportsTo: 'interaction', multiplicity: 1 },
|
||||
]);
|
||||
});
|
||||
|
||||
it('rejects roster entries that collapse to the same canonical class', async () => {
|
||||
await writeFile(
|
||||
join(dir, 'alias-collision.yaml'),
|
||||
[
|
||||
'id: alias-collision',
|
||||
'title: Alias collision',
|
||||
'description: ambiguous canonical topology',
|
||||
'lead: orchestrator',
|
||||
'floor: [orchestrator]',
|
||||
'roster:',
|
||||
' - class: orchestrator',
|
||||
' - class: code',
|
||||
' reports_to: orchestrator',
|
||||
' - class: implementer',
|
||||
' reports_to: orchestrator',
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
await expect(
|
||||
loadProfile('alias-collision', {
|
||||
profilesDir: dir,
|
||||
rolesDir,
|
||||
overrideDir: join(dir, 'roles.local'),
|
||||
}),
|
||||
).rejects.toThrow(/duplicate classes after canonicalization/);
|
||||
});
|
||||
|
||||
it('allows a readable lead or floor persona that is not itself a roster seat', async () => {
|
||||
await writeFile(
|
||||
join(dir, 'external-topology.yaml'),
|
||||
[
|
||||
'id: external-topology',
|
||||
'title: External topology',
|
||||
'description: structural compatibility',
|
||||
'lead: orchestrator',
|
||||
'floor: [enhancer]',
|
||||
'roster:',
|
||||
' - class: code',
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
const profile = await loadProfile('external-topology', {
|
||||
profilesDir: dir,
|
||||
rolesDir,
|
||||
overrideDir: join(dir, 'roles.local'),
|
||||
});
|
||||
expect(profile.lead).toBe('orchestrator');
|
||||
expect(profile.floor).toEqual(['enhancer']);
|
||||
});
|
||||
|
||||
it('throws when a profile references an unknown class (validated against real roles)', async () => {
|
||||
await writeFile(
|
||||
join(dir, 'bad.yaml'),
|
||||
|
||||
Reference in New Issue
Block a user