rhachet-roles-ehmpathy 1.15.21 → 1.15.22
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.
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
### .define = domain-operation-core-variants
|
|
2
|
+
|
|
3
|
+
#### .what
|
|
4
|
+
domain.operations contains two fundamental variants of leaf operations:
|
|
5
|
+
- **compute*** = deterministic computed work (pure functions, no external dependencies)
|
|
6
|
+
- **imagine*** = probabilistic creative work via `context.brain.repl.imagine({ role })`
|
|
7
|
+
|
|
8
|
+
#### .when
|
|
9
|
+
- most projects only have deterministic operations — no `brain.repl` invocations
|
|
10
|
+
- in these cases, the `compute*` prefix is **not required** (no ambiguity exists)
|
|
11
|
+
- enforcement becomes **mandatory** when a project contains both variants
|
|
12
|
+
- once `imagine*` operations exist in a codebase, `compute*` prefixes become required for clarity
|
|
13
|
+
|
|
14
|
+
#### .scope
|
|
15
|
+
- the `compute*`/`imagine*` prefix applies only to **leaf operations**
|
|
16
|
+
- leaf operations = the ones that actually perform the computation or imagination
|
|
17
|
+
- **composer operations** that orchestrate leaf operations use normal names (e.g., `getInvoice`, `setCustomerPhone`, `syncUserFromProvider`)
|
|
18
|
+
- the prefix signals *what kind of work is done*, not *what kind of work is called*
|
|
19
|
+
|
|
20
|
+
#### .why
|
|
21
|
+
when both variants exist in a codebase, the prefix:
|
|
22
|
+
- clarifies the nature of each leaf operation at a glance
|
|
23
|
+
- sets expectations for testability (deterministic vs probabilistic)
|
|
24
|
+
- signals dependency requirements (pure vs requires brain context)
|
|
25
|
+
- enables appropriate error strategies for each type
|
|
26
|
+
- guides code review focus (logic correctness vs prompt quality)
|
|
27
|
+
|
|
28
|
+
#### .how
|
|
29
|
+
|
|
30
|
+
##### compute* leaf operations
|
|
31
|
+
- prefix with `compute` (e.g., `computeInvoiceTotal`, `computeHashFromContent`)
|
|
32
|
+
- must be **pure functions** — same input always produces same output
|
|
33
|
+
- **no external dependencies** — no network, no database, no randomness
|
|
34
|
+
- trivially testable with simple input/output assertions
|
|
35
|
+
- can be safely memoized or cached
|
|
36
|
+
|
|
37
|
+
##### imagine* leaf operations
|
|
38
|
+
- prefix with `imagine` (e.g., `imagineChapterOutline`, `imagineCodeReview`)
|
|
39
|
+
- invoke `context.brain.repl.imagine({ role })` for LLM-powered generation
|
|
40
|
+
- **probabilistic** — same input may produce different valid outputs
|
|
41
|
+
- require snapshot tests or semantic assertions
|
|
42
|
+
- depend on `context.brain` provision
|
|
43
|
+
|
|
44
|
+
##### composer operations
|
|
45
|
+
- use normal verb prefixes (e.g., `get*`, `set*`, `sync*`, ...)
|
|
46
|
+
- orchestrate one or more leaf operations
|
|
47
|
+
- no special prefix required — their behavior is defined by what they compose
|
|
48
|
+
|
|
49
|
+
#### .examples
|
|
50
|
+
|
|
51
|
+
**✅ good — leaf operations with proper prefixes**
|
|
52
|
+
```ts
|
|
53
|
+
// computeInvoiceTotal.ts — leaf, deterministic
|
|
54
|
+
export const computeInvoiceTotal = (input: { lineItems: LineItem[] }) => {
|
|
55
|
+
return input.lineItems.reduce((sum, item) => sum + item.amount, 0);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// imagineChapterSummary.ts — leaf, probabilistic
|
|
59
|
+
export const imagineChapterSummary = async (
|
|
60
|
+
input: { chapter: string },
|
|
61
|
+
context: { brain: Brain },
|
|
62
|
+
) => {
|
|
63
|
+
return context.brain.repl.imagine({
|
|
64
|
+
role: 'summarizer',
|
|
65
|
+
prompt: `summarize this chapter: ${input.chapter}`,
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**✅ good — composer operation with normal name**
|
|
71
|
+
```ts
|
|
72
|
+
// getInvoiceWithSummary.ts — composes both variants
|
|
73
|
+
export const getInvoiceWithSummary = async (
|
|
74
|
+
input: { invoiceId: string },
|
|
75
|
+
context: { brain: Brain; invoiceDao: InvoiceDao },
|
|
76
|
+
) => {
|
|
77
|
+
const invoice = await context.invoiceDao.findById(input.invoiceId);
|
|
78
|
+
const total = computeInvoiceTotal({ lineItems: invoice.lineItems });
|
|
79
|
+
const summary = await imagineChapterSummary({ chapter: invoice.notes }, context);
|
|
80
|
+
return { ...invoice, total, summary };
|
|
81
|
+
};
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**⛔ bad — prefix misleads**
|
|
85
|
+
```ts
|
|
86
|
+
// computeResponse.ts — "compute" but actually calls LLM
|
|
87
|
+
export const computeResponse = async (input, context) => {
|
|
88
|
+
return context.brain.repl.imagine({ ... }); // ⛔ prefix misleads
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**⛔ bad — ambiguous leaf name (only when both variants exist)**
|
|
93
|
+
```ts
|
|
94
|
+
// generateTotal.ts — unclear if deterministic or probabilistic
|
|
95
|
+
export const generateTotal = (...) => { ... }
|
|
96
|
+
|
|
97
|
+
// processChapter.ts — verb doesn't signal operation type
|
|
98
|
+
export const processChapter = (...) => { ... }
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### .enforcement
|
|
102
|
+
- leaf operations that call `context.brain` must use `imagine*` prefix
|
|
103
|
+
- leaf operations prefixed with `compute*` must be pure and deterministic
|
|
104
|
+
- prefix mismatch vs implementation = **BLOCKER**
|
|
105
|
+
- ambiguous leaf names in a codebase with both variants = **BLOCKER**
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
#### .appendix: brain terminology
|
|
110
|
+
|
|
111
|
+
##### brain.atom
|
|
112
|
+
- the atomic unit of LLM interaction
|
|
113
|
+
- a single LLM API call (e.g., one completion request)
|
|
114
|
+
- stateless, no memory of prior calls
|
|
115
|
+
- e.g., **Claude API** = one `messages.create()` call
|
|
116
|
+
|
|
117
|
+
##### brain.repl
|
|
118
|
+
- **r**ead, **e**xecute, **p**rint, **l**oop
|
|
119
|
+
- orchestrates `brain.atom` calls within a tooluse loop
|
|
120
|
+
- enables multi-turn reason with tool execution between steps
|
|
121
|
+
- `brain.repl.imagine({ role })` = invoke the repl to imagine/generate via the specified role
|
|
122
|
+
- e.g., **Claude Code** = agentic loop that reads files, executes tools, prints results, loops until done
|
|
@@ -196,9 +196,11 @@
|
|
|
196
196
|
"Bash(npm run test:unit:*)",
|
|
197
197
|
"Bash(npm run test:integration:*)",
|
|
198
198
|
"Bash(npm run test:acceptance:*)",
|
|
199
|
+
"Bash(npm run test:acceptance:locally:*)",
|
|
199
200
|
"Bash(npm run test:unit -- path/to/file/example.ts)",
|
|
200
201
|
"Bash(npm run test:integration -- path/to/file/example.ts)",
|
|
201
202
|
"Bash(npm run test:acceptance -- path/to/file/example.ts)",
|
|
203
|
+
"Bash(npm run test:acceptance:locally -- path/to/file/example.ts)",
|
|
202
204
|
|
|
203
205
|
// thorough test operations
|
|
204
206
|
"Bash(THOROUGH=true npm run test:*)",
|
|
@@ -208,14 +210,17 @@
|
|
|
208
210
|
"Bash(THOROUGH=true npm run test:unit:*)",
|
|
209
211
|
"Bash(THOROUGH=true npm run test:integration:*)",
|
|
210
212
|
"Bash(THOROUGH=true npm run test:acceptance:*)",
|
|
213
|
+
"Bash(THOROUGH=true npm run test:acceptance:locally:*)",
|
|
211
214
|
|
|
212
215
|
// resnap test operations
|
|
213
216
|
"Bash(RESNAP=true npm run test:unit:*)",
|
|
214
217
|
"Bash(RESNAP=true npm run test:integration:*)",
|
|
215
218
|
"Bash(RESNAP=true npm run test:acceptance:*)",
|
|
219
|
+
"Bash(RESNAP=true npm run test:acceptance:locally:*)",
|
|
216
220
|
"Bash(RESNAP=true THOROUGH=true npm run test:unit:*)",
|
|
217
221
|
"Bash(RESNAP=true THOROUGH=true npm run test:integration:*)",
|
|
218
222
|
"Bash(RESNAP=true THOROUGH=true npm run test:acceptance:*)",
|
|
223
|
+
"Bash(RESNAP=true THOROUGH=true npm run test:acceptance:locally:*)",
|
|
219
224
|
|
|
220
225
|
// test list operation
|
|
221
226
|
"Bash(npx jest --listTests:*)",
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "rhachet-roles-ehmpathy",
|
|
3
3
|
"author": "ehmpathy",
|
|
4
4
|
"description": "empathetic software construction roles and skills, via rhachet",
|
|
5
|
-
"version": "1.15.
|
|
5
|
+
"version": "1.15.22",
|
|
6
6
|
"repository": "ehmpathy/rhachet-roles-ehmpathy",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet-roles-ehmpathy",
|
|
8
8
|
"keywords": [
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"helpful-errors": "1.5.3",
|
|
61
61
|
"inquirer": "12.7.0",
|
|
62
62
|
"openai": "5.8.2",
|
|
63
|
-
"rhachet": "1.
|
|
63
|
+
"rhachet": "1.15.2",
|
|
64
64
|
"rhachet-artifact": "1.0.0",
|
|
65
65
|
"rhachet-artifact-git": "1.1.0",
|
|
66
66
|
"serde-fns": "1.2.0",
|
|
@@ -89,6 +89,8 @@
|
|
|
89
89
|
"husky": "8.0.3",
|
|
90
90
|
"jest": "30.2.0",
|
|
91
91
|
"rhachet": "1.13.11",
|
|
92
|
+
"rhachet-roles-bhrain": "0.5.1",
|
|
93
|
+
"rhachet-roles-bhuild": "0.4.0",
|
|
92
94
|
"test-fns": "1.6.0",
|
|
93
95
|
"tsc-alias": "1.8.10",
|
|
94
96
|
"tsx": "4.20.6",
|
package/readme.md
CHANGED