rolexjs 1.4.0-dev-20260305032702 → 1.4.0-dev-20260305092016
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/README.md +94 -329
- package/dist/index.d.ts +11 -267
- package/dist/index.js +19 -696
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
# rolexjs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Unified entry point for RoleX — the AI Agent Role Management Framework.
|
|
4
4
|
|
|
5
|
-
`rolexjs`
|
|
6
|
-
|
|
7
|
-
- **Rolex** class — stateless API with 24 operations
|
|
8
|
-
- **Render** functions — shared description & hint templates
|
|
9
|
-
- **Feature** types — Gherkin parse/serialize
|
|
5
|
+
`rolexjs` re-exports everything from `@rolexjs/core` and adds the rendering layer. Install this one package to get the full API.
|
|
10
6
|
|
|
11
7
|
## Install
|
|
12
8
|
|
|
@@ -17,393 +13,162 @@ bun add rolexjs
|
|
|
17
13
|
## Quick Start
|
|
18
14
|
|
|
19
15
|
```typescript
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
const rolex = new Rolex({ runtime: createGraphRuntime() });
|
|
24
|
-
|
|
25
|
-
// Born an individual
|
|
26
|
-
const result = rolex.born("Feature: I am Sean");
|
|
27
|
-
console.log(describe("born", "Sean", result.state));
|
|
28
|
-
// → Individual "Sean" is born.
|
|
29
|
-
console.log(hint("born"));
|
|
30
|
-
// → Next: hire into an organization, or activate to start working.
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Architecture
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
@rolexjs/system → primitives (Structure, State, Runtime)
|
|
37
|
-
@rolexjs/core → concept definitions (19 structures, 24 processes)
|
|
38
|
-
@rolexjs/parser → Gherkin parser (wraps @cucumber/gherkin)
|
|
39
|
-
rolexjs → stateless API + render + Feature types ← you are here
|
|
40
|
-
@rolexjs/local-platform → graph-backed Runtime (graphology)
|
|
41
|
-
MCP / CLI → I/O adapters (state management, sessions)
|
|
42
|
-
```
|
|
16
|
+
import { createRoleX } from "rolexjs";
|
|
17
|
+
import { localPlatform } from "@rolexjs/local-platform";
|
|
43
18
|
|
|
44
|
-
|
|
19
|
+
// Create RoleX instance
|
|
20
|
+
const rolex = await createRoleX(localPlatform({ dataDir: "./data" }));
|
|
45
21
|
|
|
46
|
-
|
|
22
|
+
// World-level: create an individual
|
|
23
|
+
await rolex.direct("!individual.born", { content: "Feature: Sean", id: "sean" });
|
|
47
24
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
state: State; // projection of the primary affected node
|
|
51
|
-
process: string; // which process was executed (for render)
|
|
52
|
-
}
|
|
53
|
-
```
|
|
25
|
+
// Activate — returns a stateful Role
|
|
26
|
+
const role = await rolex.activate("sean");
|
|
54
27
|
|
|
55
|
-
|
|
28
|
+
// Execution cycle
|
|
29
|
+
await role.want("Feature: Build Auth", "build-auth");
|
|
30
|
+
await role.plan("Feature: JWT Strategy", "jwt-plan");
|
|
31
|
+
await role.todo("Feature: Implement Login", "login");
|
|
32
|
+
await role.finish("login", "Feature: Login done\n Scenario: OK\n Given login\n Then success");
|
|
56
33
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
const rolex = new Rolex({ runtime: Runtime });
|
|
34
|
+
// Cognition cycle
|
|
35
|
+
await role.reflect(["login-finished"], "Feature: Token insight\n Scenario: Learned\n Given tokens\n Then rotation matters", "token-insight");
|
|
36
|
+
await role.realize(["token-insight"], "Feature: Always rotate tokens\n Scenario: Principle\n Given short-lived tokens\n Then refresh tokens are essential", "rotate-tokens");
|
|
63
37
|
```
|
|
64
38
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- `rolex.society` — root of the world
|
|
68
|
-
- `rolex.past` — container for archived things
|
|
69
|
-
|
|
70
|
-
### Lifecycle — Creation
|
|
71
|
-
|
|
72
|
-
#### `born(source?: string): RolexResult`
|
|
73
|
-
|
|
74
|
-
Born an individual into society. Auto-scaffolds `identity` and `knowledge` sub-branches.
|
|
39
|
+
## Architecture
|
|
75
40
|
|
|
76
|
-
```typescript
|
|
77
|
-
const sean = rolex.born("Feature: I am Sean\n As a backend architect...");
|
|
78
|
-
// sean.state.type === "individual"
|
|
79
|
-
// sean.state.children → [identity, knowledge]
|
|
80
41
|
```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const org = rolex.found("Feature: Deepractice\n A software company...");
|
|
42
|
+
@rolexjs/system → graph engine (Structure, State, Runtime)
|
|
43
|
+
@rolexjs/core → domain model (Role, RoleXService, Commands, structures, processes)
|
|
44
|
+
@rolexjs/parser → Gherkin parser
|
|
45
|
+
@rolexjs/genesis → bootstrap data
|
|
46
|
+
@rolexjs/local-platform → filesystem persistence (SQLite + graphology)
|
|
47
|
+
rolexjs → unified entry + rendering ← you are here
|
|
88
48
|
```
|
|
89
49
|
|
|
90
|
-
|
|
50
|
+
## Core Concepts
|
|
91
51
|
|
|
92
|
-
|
|
52
|
+
### RoleX — World Entry Point
|
|
93
53
|
|
|
94
54
|
```typescript
|
|
95
|
-
const
|
|
55
|
+
const rolex = await createRoleX(platform);
|
|
96
56
|
```
|
|
97
57
|
|
|
98
|
-
|
|
58
|
+
Two methods:
|
|
99
59
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
rolex.charter(orgNode, "Feature: Company Charter\n ...");
|
|
104
|
-
```
|
|
60
|
+
- **`activate(id)`** — activate an individual, returns a stateful `Role`
|
|
61
|
+
- **`direct(locator, args)`** — execute world-level commands (`!individual.born`, `!org.found`, `!census.list`, etc.)
|
|
105
62
|
|
|
106
|
-
|
|
63
|
+
### Role — Rich Domain Model
|
|
107
64
|
|
|
108
|
-
|
|
65
|
+
Role is a self-contained operation domain for one individual. It holds state projection, cursors, and cognitive registries internally. All operations validate ownership — one individual's state never leaks to another.
|
|
109
66
|
|
|
110
67
|
```typescript
|
|
111
|
-
|
|
68
|
+
const role = await rolex.activate("sean");
|
|
112
69
|
```
|
|
113
70
|
|
|
114
|
-
|
|
71
|
+
#### Execution
|
|
115
72
|
|
|
116
|
-
|
|
73
|
+
| Method | Description |
|
|
74
|
+
|--------|-------------|
|
|
75
|
+
| `role.focus(goalId?)` | View or switch focused goal |
|
|
76
|
+
| `role.want(goal, id)` | Declare a goal |
|
|
77
|
+
| `role.plan(plan, id)` | Create a plan for the focused goal |
|
|
78
|
+
| `role.todo(task, id)` | Add a task to the focused plan |
|
|
79
|
+
| `role.finish(taskId, encounter?)` | Complete a task, optionally record encounter |
|
|
80
|
+
| `role.complete(planId?, encounter?)` | Close a plan as done |
|
|
81
|
+
| `role.abandon(planId?, encounter?)` | Drop a plan |
|
|
117
82
|
|
|
118
|
-
####
|
|
83
|
+
#### Cognition
|
|
119
84
|
|
|
120
|
-
|
|
85
|
+
| Method | Description |
|
|
86
|
+
|--------|-------------|
|
|
87
|
+
| `role.reflect(encounterIds, experience?, id?)` | Consume encounters → experience |
|
|
88
|
+
| `role.realize(experienceIds, principle?, id?)` | Consume experiences → principle |
|
|
89
|
+
| `role.master(procedure, id?, experienceIds?)` | Create procedure, optionally consuming experiences |
|
|
121
90
|
|
|
122
|
-
####
|
|
91
|
+
#### Knowledge & Skills
|
|
123
92
|
|
|
124
|
-
|
|
93
|
+
| Method | Description |
|
|
94
|
+
|--------|-------------|
|
|
95
|
+
| `role.forget(nodeId)` | Remove a node under this individual |
|
|
96
|
+
| `role.skill(locator)` | Load full skill content by locator |
|
|
97
|
+
| `role.use(locator, args?)` | Subjective execution — `!ns.method` or ResourceX |
|
|
125
98
|
|
|
126
|
-
####
|
|
99
|
+
#### State
|
|
127
100
|
|
|
128
|
-
|
|
101
|
+
| Method | Description |
|
|
102
|
+
|--------|-------------|
|
|
103
|
+
| `role.project()` | Render the individual's full state tree |
|
|
104
|
+
| `role.snapshot()` | Serialize cursors + cognitive state (KV-compatible) |
|
|
105
|
+
| `role.restore(snapshot)` | Restore from a snapshot |
|
|
129
106
|
|
|
130
|
-
|
|
107
|
+
### Ownership Isolation
|
|
131
108
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
#### `rehire(pastNode: Structure): RolexResult`
|
|
135
|
-
|
|
136
|
-
Rehire a retired individual from past. Creates a fresh individual with the same information.
|
|
109
|
+
Role validates that every operation targets nodes belonging to its own individual:
|
|
137
110
|
|
|
138
111
|
```typescript
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
const back = rolex.rehire(retiredNode);
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Organization — Membership & Appointment
|
|
145
|
-
|
|
146
|
-
These methods create/remove cross-branch **relations** (links between nodes that are not parent-child).
|
|
147
|
-
|
|
148
|
-
#### `hire(org: Structure, individual: Structure): RolexResult`
|
|
149
|
-
|
|
150
|
-
Link an individual to an organization via `membership`.
|
|
112
|
+
const sean = await rolex.activate("sean");
|
|
113
|
+
const nuwa = await rolex.activate("nuwa");
|
|
151
114
|
|
|
152
|
-
|
|
153
|
-
|
|
115
|
+
await sean.want("Feature: Auth", "auth");
|
|
116
|
+
await nuwa.focus("auth"); // throws: Goal "auth" does not belong to individual "nuwa"
|
|
154
117
|
```
|
|
155
118
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
Remove the membership link.
|
|
119
|
+
### World-Level Commands
|
|
159
120
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
Link an individual to a position via `appointment`.
|
|
121
|
+
Commands executed via `rolex.direct()`:
|
|
163
122
|
|
|
164
123
|
```typescript
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
#### `dismiss(position: Structure, individual: Structure): RolexResult`
|
|
169
|
-
|
|
170
|
-
Remove the appointment link.
|
|
171
|
-
|
|
172
|
-
### Role — Activation
|
|
124
|
+
// Individuals
|
|
125
|
+
await rolex.direct("!individual.born", { content: "Feature: Sean", id: "sean" });
|
|
126
|
+
await rolex.direct("!individual.retire", { individual: "sean" });
|
|
173
127
|
|
|
174
|
-
|
|
128
|
+
// Organizations
|
|
129
|
+
await rolex.direct("!org.found", { content: "Feature: Deepractice", id: "dp" });
|
|
130
|
+
await rolex.direct("!org.hire", { organization: "dp", individual: "sean" });
|
|
175
131
|
|
|
176
|
-
|
|
132
|
+
// Positions
|
|
133
|
+
await rolex.direct("!position.establish", { organization: "dp", content: "Feature: CTO", id: "cto" });
|
|
134
|
+
await rolex.direct("!position.appoint", { position: "cto", individual: "sean" });
|
|
177
135
|
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
// role.state contains the full subtree + relations
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Execution — Goal Pursuit
|
|
184
|
-
|
|
185
|
-
#### `want(individual: Structure, source?: string): RolexResult`
|
|
186
|
-
|
|
187
|
-
Declare a goal under an individual.
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
const goal = rolex.want(seanNode, "Feature: Build Auth System\n ...");
|
|
136
|
+
// Census
|
|
137
|
+
const census = await rolex.direct("!census.list");
|
|
191
138
|
```
|
|
192
139
|
|
|
193
|
-
|
|
140
|
+
## Gherkin
|
|
194
141
|
|
|
195
|
-
|
|
142
|
+
All content in RoleX is expressed as Gherkin Feature files.
|
|
196
143
|
|
|
197
144
|
```typescript
|
|
198
|
-
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
#### `todo(plan: Structure, source?: string): RolexResult`
|
|
202
|
-
|
|
203
|
-
Add a task to a plan.
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
const t = rolex.todo(planNode, "Feature: Implement JWT\n ...");
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
#### `finish(task: Structure, individual: Structure, experience?: string): RolexResult`
|
|
210
|
-
|
|
211
|
-
Finish a task. Removes the task and creates an `encounter` under the individual.
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
rolex.finish(taskNode, seanNode, "Learned that JWT refresh is essential");
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
#### `achieve(goal: Structure, individual: Structure, experience?: string): RolexResult`
|
|
218
|
-
|
|
219
|
-
Achieve a goal. Removes the goal and creates an `encounter`.
|
|
220
|
-
|
|
221
|
-
#### `abandon(goal: Structure, individual: Structure, experience?: string): RolexResult`
|
|
222
|
-
|
|
223
|
-
Abandon a goal. Removes the goal and creates an `encounter`.
|
|
224
|
-
|
|
225
|
-
### Cognition — Learning
|
|
226
|
-
|
|
227
|
-
The cognition pipeline transforms raw encounters into structured knowledge:
|
|
228
|
-
|
|
229
|
-
```
|
|
230
|
-
encounter → reflect → experience → realize/master → principle/skill
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
#### `reflect(encounter: Structure, individual: Structure, source?: string): RolexResult`
|
|
234
|
-
|
|
235
|
-
Consume an encounter, create an `experience` under the individual.
|
|
236
|
-
|
|
237
|
-
#### `realize(experience: Structure, knowledge: Structure, source?: string): RolexResult`
|
|
238
|
-
|
|
239
|
-
Consume an experience, create a `principle` under knowledge.
|
|
240
|
-
|
|
241
|
-
#### `master(experience: Structure, knowledge: Structure, source?: string): RolexResult`
|
|
242
|
-
|
|
243
|
-
Consume an experience, create a `skill` under knowledge.
|
|
244
|
-
|
|
245
|
-
### Query
|
|
246
|
-
|
|
247
|
-
#### `project(node: Structure): State`
|
|
248
|
-
|
|
249
|
-
Project any node's full state (subtree + links). Returns `State` directly, not a `RolexResult`.
|
|
250
|
-
|
|
251
|
-
## Render
|
|
252
|
-
|
|
253
|
-
Standalone functions shared by MCP and CLI. The I/O layer just presents them.
|
|
254
|
-
|
|
255
|
-
### `describe(process, name, state): string`
|
|
256
|
-
|
|
257
|
-
What just happened — past tense description.
|
|
258
|
-
|
|
259
|
-
```typescript
|
|
260
|
-
describe("born", "Sean", state) // → 'Individual "Sean" is born.'
|
|
261
|
-
describe("want", "Auth", state) // → 'Goal "Auth" declared.'
|
|
262
|
-
describe("finish", "JWT", state) // → 'Task "JWT" finished → encounter recorded.'
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### `hint(process): string`
|
|
266
|
-
|
|
267
|
-
What to do next — suggestion prefixed with "Next: ".
|
|
268
|
-
|
|
269
|
-
```typescript
|
|
270
|
-
hint("born") // → 'Next: hire into an organization, or activate to start working.'
|
|
271
|
-
hint("want") // → 'Next: plan how to achieve it.'
|
|
272
|
-
hint("finish") // → 'Next: continue with remaining tasks, or achieve the goal.'
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Feature (Gherkin)
|
|
276
|
-
|
|
277
|
-
Own types decoupled from `@cucumber/messages`. All `source` strings in Rolex are Gherkin Features.
|
|
278
|
-
|
|
279
|
-
### Types
|
|
280
|
-
|
|
281
|
-
```typescript
|
|
282
|
-
interface Feature {
|
|
283
|
-
name: string;
|
|
284
|
-
description?: string;
|
|
285
|
-
tags?: string[];
|
|
286
|
-
scenarios: Scenario[];
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
interface Scenario {
|
|
290
|
-
name: string;
|
|
291
|
-
description?: string;
|
|
292
|
-
tags?: string[];
|
|
293
|
-
steps: Step[];
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
interface Step {
|
|
297
|
-
keyword: string; // "Given ", "When ", "Then ", "And "
|
|
298
|
-
text: string;
|
|
299
|
-
dataTable?: DataTableRow[];
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
interface DataTableRow {
|
|
303
|
-
cells: string[];
|
|
304
|
-
}
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### `parse(source: string): Feature`
|
|
308
|
-
|
|
309
|
-
Parse a Gherkin source string into a Feature.
|
|
310
|
-
|
|
311
|
-
```typescript
|
|
312
|
-
import { parse } from "rolexjs";
|
|
145
|
+
import { parse, serialize } from "rolexjs";
|
|
313
146
|
|
|
314
147
|
const feature = parse(`
|
|
315
148
|
Feature: User Authentication
|
|
316
|
-
As a user I want secure login
|
|
317
|
-
|
|
318
149
|
Scenario: Login with email
|
|
319
150
|
Given a registered user
|
|
320
151
|
When they submit credentials
|
|
321
152
|
Then they receive a token
|
|
322
153
|
`);
|
|
323
154
|
|
|
324
|
-
|
|
325
|
-
feature.description // → "As a user I want secure login"
|
|
326
|
-
feature.scenarios // → [{ name: "Login with email", steps: [...] }]
|
|
155
|
+
const source = serialize(feature);
|
|
327
156
|
```
|
|
328
157
|
|
|
329
|
-
|
|
158
|
+
## Rendering
|
|
330
159
|
|
|
331
|
-
|
|
160
|
+
rolexjs provides rendering functions for command results:
|
|
332
161
|
|
|
333
162
|
```typescript
|
|
334
|
-
import {
|
|
335
|
-
|
|
336
|
-
const source = serialize({
|
|
337
|
-
name: "My Goal",
|
|
338
|
-
scenarios: [{
|
|
339
|
-
name: "Success",
|
|
340
|
-
steps: [
|
|
341
|
-
{ keyword: "Given ", text: "the system is ready" },
|
|
342
|
-
{ keyword: "Then ", text: "it should work" },
|
|
343
|
-
],
|
|
344
|
-
}],
|
|
345
|
-
});
|
|
346
|
-
// → "Feature: My Goal\n\n Scenario: Success\n Given the system is ready\n Then it should work\n"
|
|
347
|
-
```
|
|
163
|
+
import { render, describe, hint, renderState } from "rolexjs";
|
|
348
164
|
|
|
349
|
-
|
|
165
|
+
// 3-layer output: status + hint + projection
|
|
166
|
+
const output = render({ process: "born", name: "Sean", state: result.state });
|
|
350
167
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// Structure definitions
|
|
356
|
-
society, individual, organization, past,
|
|
357
|
-
identity, knowledge, goal, plan, task,
|
|
358
|
-
encounter, experience, principle, skill,
|
|
359
|
-
// ... and all process definitions
|
|
360
|
-
} from "rolexjs";
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
## Full Example
|
|
364
|
-
|
|
365
|
-
```typescript
|
|
366
|
-
import { Rolex, describe, hint } from "rolexjs";
|
|
367
|
-
import { createGraphRuntime } from "@rolexjs/local-platform";
|
|
368
|
-
|
|
369
|
-
const rolex = new Rolex({ runtime: createGraphRuntime() });
|
|
370
|
-
|
|
371
|
-
// 1. Born an individual
|
|
372
|
-
const { state: seanState } = rolex.born("Feature: I am Sean");
|
|
373
|
-
const seanNode = seanState.ref; // caller tracks Structure references
|
|
374
|
-
|
|
375
|
-
// 2. Found org + establish position
|
|
376
|
-
const { state: orgState } = rolex.found("Feature: Deepractice");
|
|
377
|
-
const orgNode = orgState.ref;
|
|
378
|
-
const { state: posState } = rolex.establish(orgNode, "Feature: Architect");
|
|
379
|
-
const posNode = posState.ref;
|
|
380
|
-
|
|
381
|
-
// 3. Hire + appoint
|
|
382
|
-
rolex.hire(orgNode, seanNode);
|
|
383
|
-
rolex.appoint(posNode, seanNode);
|
|
384
|
-
|
|
385
|
-
// 4. Activate (pure projection)
|
|
386
|
-
const role = rolex.activate(seanNode);
|
|
387
|
-
console.log(describe("activate", "Sean", role.state));
|
|
388
|
-
// → Role "Sean" activated.
|
|
389
|
-
console.log(hint("activate"));
|
|
390
|
-
// → Next: want a goal, or check the current state.
|
|
391
|
-
|
|
392
|
-
// 5. Goal → plan → task
|
|
393
|
-
const { state: goalState } = rolex.want(seanNode, "Feature: Build Auth");
|
|
394
|
-
const goalNode = goalState.ref;
|
|
395
|
-
const { state: planState } = rolex.plan(goalNode, "Feature: Auth Plan");
|
|
396
|
-
const planNode = planState.ref;
|
|
397
|
-
const { state: taskState } = rolex.todo(planNode, "Feature: Implement JWT");
|
|
398
|
-
const taskNode = taskState.ref;
|
|
399
|
-
|
|
400
|
-
// 6. Finish → reflect → realize
|
|
401
|
-
const { state: encState } = rolex.finish(taskNode, seanNode, "JWT refresh is essential");
|
|
402
|
-
const encNode = encState.ref;
|
|
403
|
-
const { state: expState } = rolex.reflect(encNode, seanNode);
|
|
404
|
-
const expNode = expState.ref;
|
|
405
|
-
const knowledgeNode = /* sean's knowledge child */;
|
|
406
|
-
rolex.realize(expNode, knowledgeNode, "Always use refresh token rotation");
|
|
168
|
+
// Individual layers
|
|
169
|
+
describe("born", "Sean", state); // → 'Individual "Sean" is born.'
|
|
170
|
+
hint("born"); // → 'Next: hire into an organization...'
|
|
171
|
+
renderState(state); // → Markdown projection of the state tree
|
|
407
172
|
```
|
|
408
173
|
|
|
409
174
|
## License
|