@rolexjs/core 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +166 -26
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ interface Scenario extends Scenario$1 {
|
|
|
26
26
|
* A Gherkin Feature enriched with RDD semantics.
|
|
27
27
|
*/
|
|
28
28
|
interface Feature extends Feature$1 {
|
|
29
|
-
readonly type: "persona" | "knowledge" | "experience" | "voice" | "goal" | "plan" | "task";
|
|
29
|
+
readonly type: "persona" | "knowledge" | "experience" | "voice" | "goal" | "plan" | "task" | "duty";
|
|
30
30
|
readonly scenarios: Scenario[];
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -107,6 +107,21 @@ interface Task extends Feature {
|
|
|
107
107
|
readonly type: "task";
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Duty — Responsibilities defined by a Position.
|
|
112
|
+
*
|
|
113
|
+
* A Duty IS-A Feature with type='duty'.
|
|
114
|
+
* Expressed as *.duty.feature files within a position directory.
|
|
115
|
+
* Injected into role identity when the role is on_duty.
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* A duty (responsibility) assigned through a position.
|
|
120
|
+
*/
|
|
121
|
+
interface Duty extends Feature {
|
|
122
|
+
readonly type: "duty";
|
|
123
|
+
}
|
|
124
|
+
|
|
110
125
|
/**
|
|
111
126
|
* Skill — Execution capability for a task.
|
|
112
127
|
*
|
|
@@ -123,57 +138,131 @@ interface Skill {
|
|
|
123
138
|
readonly reference: string;
|
|
124
139
|
}
|
|
125
140
|
|
|
141
|
+
/**
|
|
142
|
+
* states.ts — Role and Position state definitions.
|
|
143
|
+
*
|
|
144
|
+
* Role: free → member → on_duty
|
|
145
|
+
* Position: vacant → filled
|
|
146
|
+
*/
|
|
147
|
+
type RoleState = "free" | "member" | "on_duty";
|
|
148
|
+
type PositionState = "vacant" | "filled";
|
|
149
|
+
/**
|
|
150
|
+
* Derive a role's state from assignment data.
|
|
151
|
+
*/
|
|
152
|
+
declare function getRoleState(assignment: {
|
|
153
|
+
org: string;
|
|
154
|
+
position?: string;
|
|
155
|
+
} | null): RoleState;
|
|
156
|
+
/**
|
|
157
|
+
* Derive a position's state from assignment data.
|
|
158
|
+
*/
|
|
159
|
+
declare function getPositionState(assignedRole: string | null): PositionState;
|
|
160
|
+
|
|
126
161
|
/**
|
|
127
162
|
* Platform — The abstraction layer for role storage.
|
|
128
163
|
*
|
|
129
|
-
* Defines how roles are
|
|
164
|
+
* Defines how roles, organizations, and positions are stored and managed.
|
|
130
165
|
* LocalPlatform uses the filesystem (.rolex/ directories).
|
|
131
166
|
* Future platforms could use databases, cloud storage, etc.
|
|
132
167
|
*
|
|
133
|
-
*
|
|
168
|
+
* Three-entity architecture:
|
|
169
|
+
* Role = WHO (identity, goals)
|
|
170
|
+
* Organization = WHERE (structure, nesting)
|
|
171
|
+
* Position = WHAT (duties, boundaries)
|
|
172
|
+
*
|
|
173
|
+
* All methods are stateless — entity names are passed per call.
|
|
134
174
|
*/
|
|
135
175
|
|
|
136
176
|
/**
|
|
137
|
-
*
|
|
177
|
+
* Assignment — tracks which org/position a role is assigned to.
|
|
138
178
|
*/
|
|
139
|
-
interface
|
|
179
|
+
interface Assignment {
|
|
180
|
+
readonly org: string;
|
|
181
|
+
readonly position?: string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* OrganizationConfig — stored config for an organization.
|
|
185
|
+
*/
|
|
186
|
+
interface OrganizationConfig {
|
|
187
|
+
readonly parent?: string;
|
|
188
|
+
readonly positions: string[];
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* RolexConfig — The single source of truth for society state.
|
|
192
|
+
*
|
|
193
|
+
* Always exists. Defined in core, persisted by Platform.
|
|
194
|
+
*/
|
|
195
|
+
interface RolexConfig {
|
|
196
|
+
roles: string[];
|
|
197
|
+
organizations: Record<string, OrganizationConfig>;
|
|
198
|
+
assignments: Record<string, Assignment>;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Organization info (runtime view).
|
|
202
|
+
*/
|
|
203
|
+
interface OrganizationInfo {
|
|
140
204
|
readonly name: string;
|
|
141
|
-
readonly
|
|
205
|
+
readonly parent?: string;
|
|
206
|
+
readonly positions: string[];
|
|
207
|
+
readonly members: string[];
|
|
142
208
|
}
|
|
143
209
|
/**
|
|
144
|
-
*
|
|
210
|
+
* Position info (runtime view).
|
|
145
211
|
*/
|
|
146
|
-
interface
|
|
212
|
+
interface PositionInfo {
|
|
147
213
|
readonly name: string;
|
|
148
|
-
readonly
|
|
214
|
+
readonly org: string;
|
|
215
|
+
readonly state: PositionState;
|
|
216
|
+
readonly assignedRole: string | null;
|
|
217
|
+
readonly duties: Duty[];
|
|
149
218
|
}
|
|
150
219
|
/**
|
|
151
|
-
*
|
|
220
|
+
* Role directory entry with state information.
|
|
221
|
+
*/
|
|
222
|
+
interface RoleEntry {
|
|
223
|
+
readonly name: string;
|
|
224
|
+
readonly state: RoleState;
|
|
225
|
+
readonly org?: string;
|
|
226
|
+
readonly position?: string;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Society directory — all known roles, organizations, and positions.
|
|
152
230
|
*/
|
|
153
231
|
interface Directory {
|
|
154
232
|
readonly roles: readonly RoleEntry[];
|
|
155
|
-
readonly organizations: readonly
|
|
156
|
-
readonly name: string;
|
|
157
|
-
}[];
|
|
233
|
+
readonly organizations: readonly OrganizationInfo[];
|
|
158
234
|
}
|
|
159
235
|
/**
|
|
160
|
-
* Platform interface — abstracts
|
|
161
|
-
* All methods are stateless — role name identifies the target role.
|
|
236
|
+
* Platform interface — abstracts entity storage and retrieval.
|
|
162
237
|
*/
|
|
163
238
|
interface Platform {
|
|
164
|
-
/**
|
|
165
|
-
found(name: string): void;
|
|
166
|
-
/** Get the organization structure (teams + roles) */
|
|
167
|
-
organization(): Organization;
|
|
168
|
-
/** List all born roles in society (regardless of organization membership) */
|
|
239
|
+
/** List all born roles in society */
|
|
169
240
|
allBornRoles(): string[];
|
|
170
241
|
/** Create a new role with its persona */
|
|
171
242
|
born(name: string, source: string): Feature;
|
|
172
|
-
/**
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
|
|
176
|
-
/**
|
|
243
|
+
/** Found an organization, optionally with a parent org and description */
|
|
244
|
+
found(name: string, source?: string, parent?: string): void;
|
|
245
|
+
/** Get organization info by name */
|
|
246
|
+
getOrganization(name: string): OrganizationInfo | null;
|
|
247
|
+
/** List all organizations */
|
|
248
|
+
allOrganizations(): OrganizationInfo[];
|
|
249
|
+
/** Hire a role into an organization */
|
|
250
|
+
hire(roleId: string, orgName: string): void;
|
|
251
|
+
/** Fire a role from an organization (auto-dismisses if on_duty) */
|
|
252
|
+
fire(roleId: string, orgName: string): void;
|
|
253
|
+
/** Establish a position within an organization */
|
|
254
|
+
establish(positionName: string, source: string, orgName: string): void;
|
|
255
|
+
/** Appoint a role to a position */
|
|
256
|
+
appoint(roleId: string, positionName: string, orgName: string): void;
|
|
257
|
+
/** Dismiss a role from their position (back to member) */
|
|
258
|
+
dismiss(roleId: string): void;
|
|
259
|
+
/** Get duties for a position */
|
|
260
|
+
positionDuties(positionName: string, orgName: string): Duty[];
|
|
261
|
+
/** Get a role's current assignment */
|
|
262
|
+
getAssignment(roleId: string): Assignment | null;
|
|
263
|
+
/** Get position info */
|
|
264
|
+
getPosition(positionName: string, orgName: string): PositionInfo | null;
|
|
265
|
+
/** Load all identity features for a role (includes duties if on_duty) */
|
|
177
266
|
identity(roleId: string): Feature[];
|
|
178
267
|
/** Add a growth dimension to a role's identity */
|
|
179
268
|
growup(roleId: string, type: "knowledge" | "experience" | "voice", name: string, source: string): Feature;
|
|
@@ -204,4 +293,55 @@ interface Platform {
|
|
|
204
293
|
reflect(roleId: string, experienceNames: string[], knowledgeName: string, knowledgeSource: string): Feature;
|
|
205
294
|
}
|
|
206
295
|
|
|
207
|
-
|
|
296
|
+
/**
|
|
297
|
+
* transitions.ts — State machine definitions and transition logic.
|
|
298
|
+
*
|
|
299
|
+
* Role transitions:
|
|
300
|
+
* free --(hire)--> member --(appoint)--> on_duty
|
|
301
|
+
* on_duty --(dismiss)--> member --(fire)--> free
|
|
302
|
+
* on_duty --(fire)--> free (auto-dismiss)
|
|
303
|
+
*
|
|
304
|
+
* Position transitions:
|
|
305
|
+
* vacant --(appoint)--> filled --(dismiss)--> vacant
|
|
306
|
+
*/
|
|
307
|
+
|
|
308
|
+
interface Transition<S extends string> {
|
|
309
|
+
readonly from: S;
|
|
310
|
+
readonly to: S;
|
|
311
|
+
readonly action: string;
|
|
312
|
+
}
|
|
313
|
+
declare const ROLE_MACHINE: Transition<RoleState>[];
|
|
314
|
+
declare const POSITION_MACHINE: Transition<PositionState>[];
|
|
315
|
+
/**
|
|
316
|
+
* Find a transition by current state and action.
|
|
317
|
+
*/
|
|
318
|
+
declare function findTransition<S extends string>(machine: Transition<S>[], from: S, action: string): Transition<S> | null;
|
|
319
|
+
/**
|
|
320
|
+
* Check if a transition is valid.
|
|
321
|
+
*/
|
|
322
|
+
declare function canTransition<S extends string>(machine: Transition<S>[], from: S, action: string): boolean;
|
|
323
|
+
/**
|
|
324
|
+
* Execute a transition — returns new state or throws.
|
|
325
|
+
*/
|
|
326
|
+
declare function transition<S extends string>(machine: Transition<S>[], from: S, action: string): S;
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* relations.ts — One-to-one relationship constraints.
|
|
330
|
+
*
|
|
331
|
+
* - A role can belong to at most one organization
|
|
332
|
+
* - A role can hold at most one position
|
|
333
|
+
* - A position can be held by at most one role
|
|
334
|
+
*/
|
|
335
|
+
interface OneToOneConstraint {
|
|
336
|
+
readonly entity: string;
|
|
337
|
+
readonly relation: string;
|
|
338
|
+
readonly description: string;
|
|
339
|
+
}
|
|
340
|
+
declare const RELATIONS: OneToOneConstraint[];
|
|
341
|
+
/**
|
|
342
|
+
* Validate that a one-to-one assignment does not conflict.
|
|
343
|
+
* Throws if the entity is already assigned.
|
|
344
|
+
*/
|
|
345
|
+
declare function validateOneToOne(entityName: string, currentValue: string | null, newValue: string, constraintDesc: string): void;
|
|
346
|
+
|
|
347
|
+
export { type Assignment, type Directory, type Duty, type Feature, type Goal, type Identity, type OneToOneConstraint, type OrganizationConfig, type OrganizationInfo, POSITION_MACHINE, type Plan, type Platform, type PositionInfo, type PositionState, RELATIONS, ROLE_MACHINE, type Role, type RoleEntry, type RoleState, type RolexConfig, type Scenario, type Skill, type Task, type Transition, canTransition, findTransition, getPositionState, getRoleState, transition, validateOneToOne };
|
package/dist/index.js
CHANGED
|
@@ -1 +1,67 @@
|
|
|
1
|
+
// src/model/states.ts
|
|
2
|
+
function getRoleState(assignment) {
|
|
3
|
+
if (!assignment) return "free";
|
|
4
|
+
if (assignment.position) return "on_duty";
|
|
5
|
+
return "member";
|
|
6
|
+
}
|
|
7
|
+
function getPositionState(assignedRole) {
|
|
8
|
+
return assignedRole ? "filled" : "vacant";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// src/model/transitions.ts
|
|
12
|
+
var ROLE_MACHINE = [
|
|
13
|
+
{ from: "free", to: "member", action: "hire" },
|
|
14
|
+
{ from: "member", to: "on_duty", action: "appoint" },
|
|
15
|
+
{ from: "on_duty", to: "member", action: "dismiss" },
|
|
16
|
+
{ from: "member", to: "free", action: "fire" },
|
|
17
|
+
{ from: "on_duty", to: "free", action: "fire" }
|
|
18
|
+
];
|
|
19
|
+
var POSITION_MACHINE = [
|
|
20
|
+
{ from: "vacant", to: "filled", action: "appoint" },
|
|
21
|
+
{ from: "filled", to: "vacant", action: "dismiss" }
|
|
22
|
+
];
|
|
23
|
+
function findTransition(machine, from, action) {
|
|
24
|
+
return machine.find((t) => t.from === from && t.action === action) ?? null;
|
|
25
|
+
}
|
|
26
|
+
function canTransition(machine, from, action) {
|
|
27
|
+
return findTransition(machine, from, action) !== null;
|
|
28
|
+
}
|
|
29
|
+
function transition(machine, from, action) {
|
|
30
|
+
const t = findTransition(machine, from, action);
|
|
31
|
+
if (!t) {
|
|
32
|
+
throw new Error(`Invalid transition: cannot "${action}" from state "${from}"`);
|
|
33
|
+
}
|
|
34
|
+
return t.to;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/model/relations.ts
|
|
38
|
+
var RELATIONS = [
|
|
39
|
+
{
|
|
40
|
+
entity: "role",
|
|
41
|
+
relation: "organization",
|
|
42
|
+
description: "A role can belong to at most one organization"
|
|
43
|
+
},
|
|
44
|
+
{ entity: "role", relation: "position", description: "A role can hold at most one position" },
|
|
45
|
+
{
|
|
46
|
+
entity: "position",
|
|
47
|
+
relation: "role",
|
|
48
|
+
description: "A position can be held by at most one role"
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
function validateOneToOne(entityName, currentValue, newValue, constraintDesc) {
|
|
52
|
+
if (currentValue && currentValue !== newValue) {
|
|
53
|
+
throw new Error(`${constraintDesc}: "${entityName}" is already assigned to "${currentValue}"`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
POSITION_MACHINE,
|
|
58
|
+
RELATIONS,
|
|
59
|
+
ROLE_MACHINE,
|
|
60
|
+
canTransition,
|
|
61
|
+
findTransition,
|
|
62
|
+
getPositionState,
|
|
63
|
+
getRoleState,
|
|
64
|
+
transition,
|
|
65
|
+
validateOneToOne
|
|
66
|
+
};
|
|
1
67
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/model/states.ts","../src/model/transitions.ts","../src/model/relations.ts"],"sourcesContent":["/**\n * states.ts — Role and Position state definitions.\n *\n * Role: free → member → on_duty\n * Position: vacant → filled\n */\n\nexport type RoleState = \"free\" | \"member\" | \"on_duty\";\nexport type PositionState = \"vacant\" | \"filled\";\n\n/**\n * Derive a role's state from assignment data.\n */\nexport function getRoleState(assignment: { org: string; position?: string } | null): RoleState {\n if (!assignment) return \"free\";\n if (assignment.position) return \"on_duty\";\n return \"member\";\n}\n\n/**\n * Derive a position's state from assignment data.\n */\nexport function getPositionState(assignedRole: string | null): PositionState {\n return assignedRole ? \"filled\" : \"vacant\";\n}\n","/**\n * transitions.ts — State machine definitions and transition logic.\n *\n * Role transitions:\n * free --(hire)--> member --(appoint)--> on_duty\n * on_duty --(dismiss)--> member --(fire)--> free\n * on_duty --(fire)--> free (auto-dismiss)\n *\n * Position transitions:\n * vacant --(appoint)--> filled --(dismiss)--> vacant\n */\n\nimport type { RoleState, PositionState } from \"./states.js\";\n\nexport interface Transition<S extends string> {\n readonly from: S;\n readonly to: S;\n readonly action: string;\n}\n\nexport const ROLE_MACHINE: Transition<RoleState>[] = [\n { from: \"free\", to: \"member\", action: \"hire\" },\n { from: \"member\", to: \"on_duty\", action: \"appoint\" },\n { from: \"on_duty\", to: \"member\", action: \"dismiss\" },\n { from: \"member\", to: \"free\", action: \"fire\" },\n { from: \"on_duty\", to: \"free\", action: \"fire\" },\n];\n\nexport const POSITION_MACHINE: Transition<PositionState>[] = [\n { from: \"vacant\", to: \"filled\", action: \"appoint\" },\n { from: \"filled\", to: \"vacant\", action: \"dismiss\" },\n];\n\n/**\n * Find a transition by current state and action.\n */\nexport function findTransition<S extends string>(\n machine: Transition<S>[],\n from: S,\n action: string\n): Transition<S> | null {\n return machine.find((t) => t.from === from && t.action === action) ?? null;\n}\n\n/**\n * Check if a transition is valid.\n */\nexport function canTransition<S extends string>(\n machine: Transition<S>[],\n from: S,\n action: string\n): boolean {\n return findTransition(machine, from, action) !== null;\n}\n\n/**\n * Execute a transition — returns new state or throws.\n */\nexport function transition<S extends string>(machine: Transition<S>[], from: S, action: string): S {\n const t = findTransition(machine, from, action);\n if (!t) {\n throw new Error(`Invalid transition: cannot \"${action}\" from state \"${from}\"`);\n }\n return t.to;\n}\n","/**\n * relations.ts — One-to-one relationship constraints.\n *\n * - A role can belong to at most one organization\n * - A role can hold at most one position\n * - A position can be held by at most one role\n */\n\nexport interface OneToOneConstraint {\n readonly entity: string;\n readonly relation: string;\n readonly description: string;\n}\n\nexport const RELATIONS: OneToOneConstraint[] = [\n {\n entity: \"role\",\n relation: \"organization\",\n description: \"A role can belong to at most one organization\",\n },\n { entity: \"role\", relation: \"position\", description: \"A role can hold at most one position\" },\n {\n entity: \"position\",\n relation: \"role\",\n description: \"A position can be held by at most one role\",\n },\n];\n\n/**\n * Validate that a one-to-one assignment does not conflict.\n * Throws if the entity is already assigned.\n */\nexport function validateOneToOne(\n entityName: string,\n currentValue: string | null,\n newValue: string,\n constraintDesc: string\n): void {\n if (currentValue && currentValue !== newValue) {\n throw new Error(`${constraintDesc}: \"${entityName}\" is already assigned to \"${currentValue}\"`);\n }\n}\n"],"mappings":";AAaO,SAAS,aAAa,YAAkE;AAC7F,MAAI,CAAC,WAAY,QAAO;AACxB,MAAI,WAAW,SAAU,QAAO;AAChC,SAAO;AACT;AAKO,SAAS,iBAAiB,cAA4C;AAC3E,SAAO,eAAe,WAAW;AACnC;;;ACJO,IAAM,eAAwC;AAAA,EACnD,EAAE,MAAM,QAAQ,IAAI,UAAU,QAAQ,OAAO;AAAA,EAC7C,EAAE,MAAM,UAAU,IAAI,WAAW,QAAQ,UAAU;AAAA,EACnD,EAAE,MAAM,WAAW,IAAI,UAAU,QAAQ,UAAU;AAAA,EACnD,EAAE,MAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAAA,EAC7C,EAAE,MAAM,WAAW,IAAI,QAAQ,QAAQ,OAAO;AAChD;AAEO,IAAM,mBAAgD;AAAA,EAC3D,EAAE,MAAM,UAAU,IAAI,UAAU,QAAQ,UAAU;AAAA,EAClD,EAAE,MAAM,UAAU,IAAI,UAAU,QAAQ,UAAU;AACpD;AAKO,SAAS,eACd,SACA,MACA,QACsB;AACtB,SAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,WAAW,MAAM,KAAK;AACxE;AAKO,SAAS,cACd,SACA,MACA,QACS;AACT,SAAO,eAAe,SAAS,MAAM,MAAM,MAAM;AACnD;AAKO,SAAS,WAA6B,SAA0B,MAAS,QAAmB;AACjG,QAAM,IAAI,eAAe,SAAS,MAAM,MAAM;AAC9C,MAAI,CAAC,GAAG;AACN,UAAM,IAAI,MAAM,+BAA+B,MAAM,iBAAiB,IAAI,GAAG;AAAA,EAC/E;AACA,SAAO,EAAE;AACX;;;AClDO,IAAM,YAAkC;AAAA,EAC7C;AAAA,IACE,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,EAAE,QAAQ,QAAQ,UAAU,YAAY,aAAa,uCAAuC;AAAA,EAC5F;AAAA,IACE,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAMO,SAAS,iBACd,YACA,cACA,UACA,gBACM;AACN,MAAI,gBAAgB,iBAAiB,UAAU;AAC7C,UAAM,IAAI,MAAM,GAAG,cAAc,MAAM,UAAU,6BAA6B,YAAY,GAAG;AAAA,EAC/F;AACF;","names":[]}
|