Files
pig/packages/core/test/permissions.test.ts
T
karti 516685526c Add Motion: the go-to-market operating system on top of the ledger
The ledger answers which contracted capacity is sold, to whom, at what
margin. It says nothing about the motion — the repeatable practice that
turns a customer conversation into a scoped deployment, and turns that
deployment into something the next one reuses.

Motion is deliberately not a parallel entity tree. DEMAND_STAGES already
is the motion, so Motion binds reusable artefacts to the stages of a
demand deal that already exists: an engagement hangs off one deal,
cascade deleted, one per deal by unique constraint.

Nine closed kinds, each declaring which stages it serves, and a starter
library of twelve templates covering all eight open stages.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 18:27:03 -07:00

232 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { strict as assert } from 'node:assert';
import { describe, it } from 'node:test';
import { TEAM_ROLES, TEAMS, type Team, type TeamRole } from '../src/ontology';
import {
CAPABILITIES,
permissionGranted,
resolvePermissionGrants,
resolveReadPermissionGrants,
resolveWritePermissionGrants,
roleMeets,
type Capability,
type PermissionSubject,
} from '../src/permissions';
describe('role permissions', () => {
it('keeps deal writes on the side where the person is a member', () => {
const grants = resolvePermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'demand', role: 'member' }],
});
assert.equal(permissionGranted(grants, 'deal:write', 'demand'), true);
assert.equal(permissionGranted(grants, 'deal:write', 'supply'), false);
assert.equal(permissionGranted(grants, 'commitment:write', 'demand'), false);
});
it('allows supply leads to commit capacity without letting them sign contracts', () => {
const grants = resolvePermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'supply', role: 'lead' }],
});
assert.equal(permissionGranted(grants, 'commitment:write', 'supply'), true);
assert.equal(permissionGranted(grants, 'contract:sign', 'supply'), false);
});
it('keeps signing and bulk import at team-admin level', () => {
const grants = resolvePermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'demand', role: 'admin' }],
});
assert.equal(permissionGranted(grants, 'contract:sign', 'demand'), true);
assert.equal(permissionGranted(grants, 'contract:sign', 'supply'), false);
assert.equal(permissionGranted(grants, 'data:import', 'demand'), true);
assert.equal(permissionGranted(grants, 'data:import', 'research'), false);
assert.equal(permissionGranted(grants, 'settings:admin'), false);
});
it('gives platform admins global grants without synthetic team memberships', () => {
const grants = resolvePermissionGrants({ isPlatformAdmin: true, teams: [] });
assert.equal(permissionGranted(grants, 'deal:write', 'demand'), true);
assert.equal(permissionGranted(grants, 'commitment:write', 'supply'), true);
assert.equal(permissionGranted(grants, 'data:import', 'research'), true);
assert.equal(permissionGranted(grants, 'settings:admin'), true);
});
});
describe('the three authorities that used to be data:import', () => {
it('does not let a research admin rewrite a commercial book', () => {
const grants = resolvePermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'research', role: 'admin' }],
});
assert.equal(permissionGranted(grants, 'fact:review', 'research'), true);
assert.equal(permissionGranted(grants, 'data:import', 'demand'), false);
assert.equal(permissionGranted(grants, 'data:import', 'supply'), false);
});
it('does not let a commercial admin approve a claim about a person', () => {
const grants = resolvePermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'supply', role: 'admin' }],
});
assert.equal(permissionGranted(grants, 'data:import', 'supply'), true);
assert.equal(permissionGranted(grants, 'integration:connect', 'supply'), true);
// Fact review lives on research alone; being a supply admin buys nothing.
assert.equal(permissionGranted(grants, 'fact:review', 'research'), false);
});
});
describe('reads', () => {
it('resolves read grants platform-wide, never per team', () => {
const grants = resolveReadPermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'demand', role: 'member' }],
});
// A team-scoped read grant would be a promise the query layer does not
// keep: `/api/contracts` returns supply paper to a demand reader either
// way. See READ_CAPABILITIES.
assert.deepEqual(
grants,
[
{ capability: 'book:read', team: null },
{ capability: 'economics:read', team: null },
{ capability: 'team:read', team: null },
],
);
});
it('shows a research contractor the book but not what we pay for capacity', () => {
const grants = resolveReadPermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'research', role: 'lead' }],
});
assert.equal(permissionGranted(grants, 'book:read'), true);
assert.equal(permissionGranted(grants, 'team:read'), true);
assert.equal(permissionGranted(grants, 'economics:read'), false);
});
it('gives a viewer reads and no writes at all', () => {
const subject: PermissionSubject = {
isPlatformAdmin: false,
teams: [{ team: 'demand', role: 'viewer' }],
};
assert.deepEqual(resolveWritePermissionGrants(subject), []);
assert.equal(permissionGranted(resolveReadPermissionGrants(subject), 'book:read'), true);
// Cost economics are a commercial member's tool, not a reader's.
assert.equal(permissionGranted(resolveReadPermissionGrants(subject), 'economics:read'), false);
});
});
/**
* The matrix is pure data, so pinning every cell is cheap — and it is the only
* way a role added later cannot quietly inherit an authority nobody chose to
* give it. Change a rule and this table tells you exactly which cells moved.
*/
describe('the whole role × capability matrix', () => {
const EXPECTED: Readonly<Record<TeamRole, readonly Capability[]>> = {
viewer: ['book:read', 'team:read'],
member: [
'book:read',
'economics:read',
'team:read',
'deal:write',
'activity:write',
'motion:write',
],
lead: [
'book:read',
'economics:read',
'team:read',
'deal:write',
'activity:write',
'commitment:write',
'motion:write',
'motion:publish',
],
admin: [
'book:read',
'economics:read',
'team:read',
'deal:write',
'activity:write',
'commitment:write',
'contract:sign',
'data:import',
'integration:connect',
'motion:write',
'motion:publish',
],
};
/** Held on the supply team, whose rules exercise every rank threshold. */
for (const role of TEAM_ROLES) {
it(`grants a supply ${role} exactly the expected set`, () => {
const grants = resolvePermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'supply', role }],
});
const held = CAPABILITIES.filter((capability) =>
grants.some((grant) => grant.capability === capability),
);
assert.deepEqual(new Set(held), new Set(EXPECTED[role]));
});
}
it('gives research its own shape — evidence review, no commercial reach', () => {
const grants = resolvePermissionGrants({
isPlatformAdmin: false,
teams: [{ team: 'research', role: 'admin' }],
});
const held = CAPABILITIES.filter((capability) =>
grants.some((grant) => grant.capability === capability),
);
assert.deepEqual(
new Set(held),
new Set([
'book:read',
'team:read',
'activity:write',
'data:import',
'fact:review',
'integration:connect',
'motion:write',
'motion:publish',
]),
);
});
it('never grants a lower rank something a higher rank on the same team lacks', () => {
for (const team of TEAMS as readonly Team[]) {
let previous = new Set<Capability>();
for (const role of TEAM_ROLES) {
const held = new Set<Capability>(
resolvePermissionGrants({ isPlatformAdmin: false, teams: [{ team, role }] }).map(
(grant) => grant.capability,
),
);
for (const capability of previous) {
assert.ok(held.has(capability), `${team}/${role} lost ${capability} by promotion`);
}
previous = held;
}
}
});
it('ranks viewer below member, which is what makes it safe to add', () => {
assert.equal(roleMeets('viewer', 'member'), false);
assert.equal(roleMeets('member', 'viewer'), true);
assert.equal(roleMeets('admin', 'admin'), true);
assert.equal(TEAM_ROLES[0], 'viewer');
});
});