rhachet-roles-bhrain 0.1.1 → 0.3.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.
Files changed (159) hide show
  1. package/dist/.test/getContextOpenAI.js +1 -1
  2. package/dist/.test/getContextOpenAI.js.map +1 -1
  3. package/dist/domain.operations/review/compileReviewPrompt.d.ts +22 -0
  4. package/dist/domain.operations/review/compileReviewPrompt.js +95 -0
  5. package/dist/domain.operations/review/compileReviewPrompt.js.map +1 -0
  6. package/dist/domain.operations/review/enumFilesFromDiffs.d.ts +8 -0
  7. package/dist/domain.operations/review/enumFilesFromDiffs.js +74 -0
  8. package/dist/domain.operations/review/enumFilesFromDiffs.js.map +1 -0
  9. package/dist/domain.operations/review/enumFilesFromGlob.d.ts +8 -0
  10. package/dist/domain.operations/review/enumFilesFromGlob.js +31 -0
  11. package/dist/domain.operations/review/enumFilesFromGlob.js.map +1 -0
  12. package/dist/domain.operations/review/estimateTokenCount.d.ts +9 -0
  13. package/dist/domain.operations/review/estimateTokenCount.js +20 -0
  14. package/dist/domain.operations/review/estimateTokenCount.js.map +1 -0
  15. package/dist/domain.operations/review/formatReviewOutput.d.ts +14 -0
  16. package/dist/domain.operations/review/formatReviewOutput.js +42 -0
  17. package/dist/domain.operations/review/formatReviewOutput.js.map +1 -0
  18. package/dist/domain.operations/review/genTokenBreakdownMarkdown.d.ts +19 -0
  19. package/dist/domain.operations/review/genTokenBreakdownMarkdown.js +110 -0
  20. package/dist/domain.operations/review/genTokenBreakdownMarkdown.js.map +1 -0
  21. package/dist/domain.operations/review/genTokenBreakdownReport.d.ts +24 -0
  22. package/dist/domain.operations/review/genTokenBreakdownReport.js +64 -0
  23. package/dist/domain.operations/review/genTokenBreakdownReport.js.map +1 -0
  24. package/dist/domain.operations/review/invokeClaudeCode.d.ts +22 -0
  25. package/dist/domain.operations/review/invokeClaudeCode.js +92 -0
  26. package/dist/domain.operations/review/invokeClaudeCode.js.map +1 -0
  27. package/dist/domain.operations/review/writeInputArtifacts.d.ts +27 -0
  28. package/dist/domain.operations/review/writeInputArtifacts.js +50 -0
  29. package/dist/domain.operations/review/writeInputArtifacts.js.map +1 -0
  30. package/dist/domain.operations/review/writeOutputArtifacts.d.ts +12 -0
  31. package/dist/domain.operations/review/writeOutputArtifacts.js +46 -0
  32. package/dist/domain.operations/review/writeOutputArtifacts.js.map +1 -0
  33. package/dist/roles/architect/briefs/brains.replic/arc000.sources.[catalog].md +178 -0
  34. package/dist/roles/architect/briefs/brains.replic/arc101.concept.llm.[article].md +25 -0
  35. package/dist/roles/architect/briefs/brains.replic/arc102.concept.repl.[article].md +33 -0
  36. package/dist/roles/architect/briefs/brains.replic/arc103.concept.replic-brain.[article].md +35 -0
  37. package/dist/roles/architect/briefs/brains.replic/arc104.concept.context-window.[article].md +40 -0
  38. package/dist/roles/architect/briefs/brains.replic/arc105.concept.system-prompt.[article].md +44 -0
  39. package/dist/roles/architect/briefs/brains.replic/arc106.concept.tool-definition.[article].md +59 -0
  40. package/dist/roles/architect/briefs/brains.replic/arc107.concept.tool-call.[article].md +54 -0
  41. package/dist/roles/architect/briefs/brains.replic/arc108.concept.tool-result.[article].md +58 -0
  42. package/dist/roles/architect/briefs/brains.replic/arc109.concept.agentic-loop.[article].md +62 -0
  43. package/dist/roles/architect/briefs/brains.replic/arc110.concept.reasoning-trace.[article].md +58 -0
  44. package/dist/roles/architect/briefs/brains.replic/arc111.concept.react-pattern.[article].md +65 -0
  45. package/dist/roles/architect/briefs/brains.replic/arc112.concept.reflexion-pattern.[article].md +68 -0
  46. package/dist/roles/architect/briefs/brains.replic/arc113.concept.tree-of-thoughts.[article].md +76 -0
  47. package/dist/roles/architect/briefs/brains.replic/arc114.concept.self-consistency.[article].md +73 -0
  48. package/dist/roles/architect/briefs/brains.replic/arc115.concept.lats-pattern.[article].md +78 -0
  49. package/dist/roles/architect/briefs/brains.replic/arc116.concept.context-compaction.[article].md +71 -0
  50. package/dist/roles/architect/briefs/brains.replic/arc117.concept.subagent.[article].md +71 -0
  51. package/dist/roles/architect/briefs/brains.replic/arc118.concept.extended-thinking.[article].md +69 -0
  52. package/dist/roles/architect/briefs/brains.replic/arc119.concept.mcp.[article].md +78 -0
  53. package/dist/roles/architect/briefs/brains.replic/arc120.concept.session.[article].md +67 -0
  54. package/dist/roles/architect/briefs/brains.replic/arc121.concept.message.[article].md +79 -0
  55. package/dist/roles/architect/briefs/brains.replic/arc122.concept.plan-and-solve.[article].md +80 -0
  56. package/dist/roles/architect/briefs/brains.replic/arc150.concepts.treestruct.[article].md +126 -0
  57. package/dist/roles/architect/briefs/brains.replic/arc201.blueprint.claude-code.[article].md +417 -0
  58. package/dist/roles/architect/briefs/brains.replic/arc201.blueprint.claude-code.zoomin.reason.[article].md +507 -0
  59. package/dist/roles/architect/briefs/brains.replic/arc202.blueprint.codex.[article].md +354 -0
  60. package/dist/roles/architect/briefs/brains.replic/arc300.blueprints.comparison.[catalog].md +284 -0
  61. package/dist/roles/getRoleRegistry.js +2 -1
  62. package/dist/roles/getRoleRegistry.js.map +1 -1
  63. package/dist/roles/getRoleRegistry.readme.js +6 -0
  64. package/dist/roles/getRoleRegistry.readme.js.map +1 -1
  65. package/dist/roles/reviewer/briefs/review.tactics.md +60 -0
  66. package/dist/roles/reviewer/getReviewerRole.d.ts +6 -0
  67. package/dist/roles/reviewer/getReviewerRole.js +80 -0
  68. package/dist/roles/reviewer/getReviewerRole.js.map +1 -0
  69. package/dist/roles/reviewer/skills/review/review.d.ts +57 -0
  70. package/dist/roles/reviewer/skills/review/review.js +445 -0
  71. package/dist/roles/reviewer/skills/review/review.js.map +1 -0
  72. package/dist/roles/reviewer/skills/review/review.sh +21 -0
  73. package/dist/roles/reviewer/skills/review/review.ts +575 -0
  74. package/dist/roles/thinker/briefs/term=brain.atomic_vs_replic.md +8 -0
  75. package/dist/roles/thinker/getThinkerRole.js +1 -1
  76. package/dist/roles/thinker/getThinkerRole.js.map +1 -1
  77. package/dist/roles/thinker/skills/brief.articulate/.demo/article.vision.v2025_08_19..i1.via_chatgpt.md +47 -0
  78. package/dist/roles/thinker/skills/brief.articulate/.demo/article.vision.v2025_08_19.i2.via_rhachet.md +60 -0
  79. package/dist/roles/thinker/skills/brief.articulate/.demo/diverge.v2025_08_17.i1.md +62 -0
  80. package/dist/roles/thinker/skills/brief.articulate/.demo/diverge.v2025_08_17.i1.with_feedback.md +89 -0
  81. package/dist/roles/thinker/skills/brief.articulate/.demo/diverge.v2025_08_17.i2.md +47 -0
  82. package/dist/roles/thinker/skills/brief.articulate/.demo/joke.v2025_08_15.i1.md +44 -0
  83. package/dist/roles/thinker/skills/brief.articulate/.demo/joke.v2025_08_15.i2.md +63 -0
  84. package/dist/roles/thinker/skills/brief.articulate/.demo/joke.v2025_08_15.i3.md +51 -0
  85. package/dist/roles/thinker/skills/brief.articulate/.demo/user-journey.v2025_08_17.i1.md +62 -0
  86. package/dist/roles/thinker/skills/brief.articulate/.demo/user-journey.v2025_08_17.i2.md +49 -0
  87. package/dist/roles/thinker/skills/brief.articulate/.readme.md +0 -0
  88. package/dist/roles/thinker/skills/brief.articulate/stepArticulate.skill.js +1 -1
  89. package/dist/roles/thinker/skills/brief.articulate/stepArticulate.skill.js.map +1 -1
  90. package/dist/roles/thinker/skills/brief.articulate/stepArticulate.skill.ts +168 -0
  91. package/dist/roles/thinker/skills/brief.articulate/stepArticulate.ts +157 -0
  92. package/dist/roles/thinker/skills/brief.catalogize/.demo/joke.types.v2025_08_28.i1.md +93 -0
  93. package/dist/roles/thinker/skills/brief.catalogize/.demo/joke.types.v2025_08_28.i2.md +84 -0
  94. package/dist/roles/thinker/skills/brief.catalogize/.demo/joke.types.v2025_09_28.i1.no_focus_context.md +8 -0
  95. package/dist/roles/thinker/skills/brief.catalogize/.demo/joke.types.v2025_09_28.i2.md +54 -0
  96. package/dist/roles/thinker/skills/brief.catalogize/.demo/persona.usecases.v2025_08_28.i1.md +62 -0
  97. package/dist/roles/thinker/skills/brief.catalogize/.demo/persona.usecases.v2025_08_28.i2.md +64 -0
  98. package/dist/roles/thinker/skills/brief.catalogize/.readme.md +5 -0
  99. package/dist/roles/thinker/skills/brief.catalogize/stepCatalogize.skill.js +1 -1
  100. package/dist/roles/thinker/skills/brief.catalogize/stepCatalogize.skill.js.map +1 -1
  101. package/dist/roles/thinker/skills/brief.catalogize/stepCatalogize.skill.ts +173 -0
  102. package/dist/roles/thinker/skills/brief.catalogize/stepCatalogize.ts +132 -0
  103. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.input.example.i4.md +3 -0
  104. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.input.example.i5.md +3 -0
  105. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.input.example.i6.md +3 -0
  106. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.input.example.md +3 -0
  107. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.v2025_08_27.i1.md +52 -0
  108. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.v2025_08_27.i2.md +51 -0
  109. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.v2025_08_27.i3.md +47 -0
  110. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.v2025_08_27.i4.md +62 -0
  111. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.v2025_08_27.i5.md +47 -0
  112. package/dist/roles/thinker/skills/brief.demonstrate/.demo/user.journey.roadtrip.v2025_08_27.i6.md +53 -0
  113. package/dist/roles/thinker/skills/brief.demonstrate/.readme +3 -0
  114. package/dist/roles/thinker/skills/brief.demonstrate/stepDemonstrate.skill.js +1 -1
  115. package/dist/roles/thinker/skills/brief.demonstrate/stepDemonstrate.skill.js.map +1 -1
  116. package/dist/roles/thinker/skills/brief.demonstrate/stepDemonstrate.skill.ts +190 -0
  117. package/dist/roles/thinker/skills/brief.demonstrate/stepDemonstrate.ts +164 -0
  118. package/dist/roles/thinker/skills/khue.cluster/.demo/user.journeys.input1.cluster.v2025_08_17.i1.md +72 -0
  119. package/dist/roles/thinker/skills/khue.cluster/.demo/user.journeys.input1.cluster.v2025_08_17.i2.md +53 -0
  120. package/dist/roles/thinker/skills/khue.cluster/.demo/user.journeys.input1.cluster.v2025_08_17.i3.which_objectives.md +58 -0
  121. package/dist/roles/thinker/skills/khue.cluster/.demo/user.journeys.input1.cluster.v2025_08_17.i5.which_personas.md +64 -0
  122. package/dist/roles/thinker/skills/khue.cluster/.demo/user.journeys.input2.cluster.v2025_08_17.i1.md +67 -0
  123. package/dist/roles/thinker/skills/khue.cluster/.demo/user.journeys.input2.cluster.v2025_08_17.i2.md +49 -0
  124. package/dist/roles/thinker/skills/khue.cluster/.demo/user.journeys.input2.cluster.v2025_08_17.i3.md +59 -0
  125. package/dist/roles/thinker/skills/khue.cluster/.readme.md +0 -0
  126. package/dist/roles/thinker/skills/khue.cluster/stepCluster.skill.js +1 -1
  127. package/dist/roles/thinker/skills/khue.cluster/stepCluster.skill.js.map +1 -1
  128. package/dist/roles/thinker/skills/khue.cluster/stepCluster.skill.ts +174 -0
  129. package/dist/roles/thinker/skills/khue.cluster/stepCluster.ts +150 -0
  130. package/dist/roles/thinker/skills/khue.decompose/.readme.md +9 -0
  131. package/dist/roles/thinker/skills/khue.diverge/.demo/joke.examples.v2025_08_17.i2.md +23 -0
  132. package/dist/roles/thinker/skills/khue.diverge/.demo/joke.examples.v2025_08_17.i3.md +23 -0
  133. package/dist/roles/thinker/skills/khue.diverge/.demo/joke.varieties.v2025_08_17.i1.md +23 -0
  134. package/dist/roles/thinker/skills/khue.diverge/.demo/userjourney.examples.v2025_08_17.i1.md +9 -0
  135. package/dist/roles/thinker/skills/khue.diverge/.demo/userjourney.examples.v2025_08_17.i2.md +9 -0
  136. package/dist/roles/thinker/skills/khue.diverge/.demo/userjourney.examples.v2025_08_17.i3.md +23 -0
  137. package/dist/roles/thinker/skills/khue.diverge/.demo/userjourney.examples.v2025_08_17.i4.folksy.md +9 -0
  138. package/dist/roles/thinker/skills/khue.diverge/.demo/userjourney.examples.v2025_08_17.i5.folksy.md +23 -0
  139. package/dist/roles/thinker/skills/khue.diverge/.readme.md +0 -0
  140. package/dist/roles/thinker/skills/khue.diverge/stepDiverge.skill.js +1 -1
  141. package/dist/roles/thinker/skills/khue.diverge/stepDiverge.skill.js.map +1 -1
  142. package/dist/roles/thinker/skills/khue.diverge/stepDiverge.skill.ts +149 -0
  143. package/dist/roles/thinker/skills/khue.diverge/stepDiverge.ts +151 -0
  144. package/dist/roles/thinker/skills/khue.encompose/.readme.md +7 -0
  145. package/dist/roles/thinker/skills/khue.instantiate/.readme.md +14 -0
  146. package/dist/roles/thinker/skills/khue.instantiate/stepInstantiate.skill.js +1 -1
  147. package/dist/roles/thinker/skills/khue.instantiate/stepInstantiate.skill.js.map +1 -1
  148. package/dist/roles/thinker/skills/khue.instantiate/stepInstantiate.skill.ts +190 -0
  149. package/dist/roles/thinker/skills/khue.instantiate/stepInstantiate.ts +132 -0
  150. package/dist/roles/thinker/skills/khue.triage/.demo/laughs.v2025_08_18.i1.md +29 -0
  151. package/dist/roles/thinker/skills/khue.triage/.demo/user.journeys.v2025_08_17.i1.md +86 -0
  152. package/dist/roles/thinker/skills/khue.triage/.demo/user.journeys.v2025_08_17.i2.md +68 -0
  153. package/dist/roles/thinker/skills/khue.triage/.readme.md +0 -0
  154. package/dist/roles/thinker/skills/khue.triage/stepTriage.skill.js +1 -1
  155. package/dist/roles/thinker/skills/khue.triage/stepTriage.skill.js.map +1 -1
  156. package/dist/roles/thinker/skills/khue.triage/stepTriage.skill.ts +174 -0
  157. package/dist/roles/thinker/skills/khue.triage/stepTriage.ts +153 -0
  158. package/package.json +9 -7
  159. package/readme.md +55 -0
@@ -0,0 +1,174 @@
1
+ import { enrollThread, genRoleSkill } from 'rhachet';
2
+ import { genArtifactGitFile, getArtifactObsDir } from 'rhachet-artifact-git';
3
+
4
+ import { genContextLogTrail } from '@src/.test/genContextLogTrail';
5
+ import { genContextStitchTrail } from '@src/.test/genContextStitchTrail';
6
+ import { getContextOpenAI } from '@src/.test/getContextOpenAI';
7
+
8
+ import { BRIEFS_FOR_TRIAGE, loopTriage } from './stepTriage';
9
+
10
+ export const SKILL_TRIAGE = genRoleSkill({
11
+ slug: 'triage',
12
+ route: loopTriage,
13
+ threads: {
14
+ lookup: {
15
+ output: {
16
+ source: 'process.argv',
17
+ char: 'o',
18
+ desc: 'the output file to write against',
19
+ type: 'string',
20
+ },
21
+ input: {
22
+ source: 'process.argv',
23
+ char: 'i',
24
+ desc: 'the input file to seed from',
25
+ type: 'string',
26
+ },
27
+ goal: {
28
+ source: 'process.argv',
29
+ char: 'g',
30
+ desc: 'the goal of the request',
31
+ type: '?string',
32
+ },
33
+ references: {
34
+ source: 'process.argv',
35
+ char: 'f',
36
+ desc: 'reference files to to use, if any; delimit with commas',
37
+ type: '?string',
38
+ },
39
+ briefs: {
40
+ source: 'process.argv',
41
+ char: 'b',
42
+ desc: 'brief files to to use, if any; delimit with commas',
43
+ type: '?string',
44
+ },
45
+ },
46
+ assess: (
47
+ input,
48
+ ): input is {
49
+ output: string;
50
+ input: string;
51
+ goal: string;
52
+ references: string;
53
+ briefs: string;
54
+ ask: string;
55
+ } => typeof input.output === 'string',
56
+ instantiate: async (input: {
57
+ output: string;
58
+ input: string;
59
+ goal: string;
60
+ references: string;
61
+ briefs: string;
62
+ ask: string;
63
+ }) => {
64
+ // declare where all the artifacts will be found
65
+ const obsDir = getArtifactObsDir({ uri: input.output });
66
+ const artifacts = {
67
+ goal: {
68
+ concept: genArtifactGitFile(
69
+ { uri: obsDir + '.goal.concept.md' },
70
+ { versions: true },
71
+ ),
72
+ context: genArtifactGitFile(
73
+ { uri: obsDir + '.goal.context.md' },
74
+ { versions: true },
75
+ ),
76
+ },
77
+ feedback: genArtifactGitFile(
78
+ { uri: obsDir + '.feedback.md' },
79
+ { versions: true },
80
+ ),
81
+ 'focus.context': genArtifactGitFile(
82
+ { uri: obsDir + '.focus.context.md' },
83
+ { versions: true },
84
+ ),
85
+ 'focus.concept': genArtifactGitFile(
86
+ { uri: input.output },
87
+ { versions: true },
88
+ ),
89
+ input: genArtifactGitFile({ uri: input.input }, { versions: true }),
90
+ references:
91
+ input.references
92
+ ?.split(',')
93
+ .filter((uri) => !!uri)
94
+ .map((reference) =>
95
+ genArtifactGitFile({ uri: reference }, { access: 'readonly' }),
96
+ ) ?? [],
97
+ briefs:
98
+ input.briefs
99
+ ?.split(',')
100
+ .filter((uri) => !!uri)
101
+ .map((brief) =>
102
+ genArtifactGitFile({ uri: brief }, { access: 'readonly' }),
103
+ ) ?? [],
104
+ };
105
+
106
+ // detect the goal of the caller
107
+ const goalConcept: string = await (async () => {
108
+ // if goal explicitly defined, use it
109
+ if (input.goal)
110
+ return (
111
+ (
112
+ await genArtifactGitFile(
113
+ { uri: input.goal },
114
+ { access: 'readonly' },
115
+ ).get()
116
+ )?.content ?? input.ask
117
+ );
118
+
119
+ // otherwise, assume its the ask
120
+ return input.ask;
121
+ })();
122
+ await artifacts.goal.concept.set({ content: goalConcept });
123
+
124
+ return {
125
+ caller: await enrollThread({
126
+ role: 'caller',
127
+ stash: {
128
+ ask: '',
129
+ art: {
130
+ 'foci.goal.concept': artifacts.goal.concept,
131
+ 'foci.goal.context': artifacts.goal.context,
132
+ 'foci.input.concept': artifacts.input,
133
+ feedback: artifacts.feedback,
134
+ },
135
+ refs: artifacts.references,
136
+ },
137
+ }),
138
+ thinker: await enrollThread({
139
+ role: 'thinker',
140
+ stash: {
141
+ art: {
142
+ 'focus.context': artifacts['focus.context'],
143
+ 'focus.concept': artifacts['focus.concept'],
144
+ },
145
+ briefs: [
146
+ ...artifacts.briefs,
147
+ ...BRIEFS_FOR_TRIAGE, // flow the triage briefs down so that <ponder> has them in context too; this approach does cause duplicate briefs for triage, but thats no biggie
148
+ ],
149
+ },
150
+ }),
151
+ };
152
+ },
153
+ },
154
+ context: {
155
+ lookup: {
156
+ apiKeyOpenai: {
157
+ source: 'process.env',
158
+ envar: 'OPENAI_API_KEY',
159
+ desc: 'the openai key to use',
160
+ type: 'string',
161
+ },
162
+ },
163
+ assess: (input): input is { apiKeyOpenai: string } =>
164
+ typeof input.apiKeyOpenai === 'string',
165
+ instantiate: () => {
166
+ return {
167
+ ...getContextOpenAI(),
168
+ ...genContextLogTrail(),
169
+ ...genContextStitchTrail(),
170
+ };
171
+ },
172
+ },
173
+ readme: '',
174
+ });
@@ -0,0 +1,153 @@
1
+ import { UnexpectedCodePathError } from 'helpful-errors';
2
+ import {
3
+ asStitcherFlat,
4
+ type GStitcher,
5
+ genStepImagineViaTemplate,
6
+ genStitchRoute,
7
+ genTemplate,
8
+ getTemplatePathByCallerPath,
9
+ getTemplateValFromArtifacts,
10
+ getTemplateVarsFromRoleInherit,
11
+ type RoleContext,
12
+ type Threads,
13
+ } from 'rhachet';
14
+ import type { Artifact } from 'rhachet-artifact';
15
+ import type { GitFile } from 'rhachet-artifact-git';
16
+ import { withRetry, withTimeout } from 'wrapper-fns';
17
+
18
+ import type { Focus } from '@src/_topublish/rhachet-roles-bhrain/src/domain/objects/Focus';
19
+ import { type ContextOpenAI, sdkOpenAi } from '@src/access/sdk/sdkOpenAi';
20
+ import { genLoopFeedback } from '@src/domain.operations/artifact/genLoopFeedback';
21
+ import { genStepArtSet } from '@src/domain.operations/artifact/genStepArtSet';
22
+ import { getThinkerBriefs } from '@src/roles/thinker/getThinkerBrief';
23
+
24
+ // exported so that we can pass them through to <ponder> too
25
+ export const BRIEFS_FOR_TRIAGE = getThinkerBriefs([
26
+ 'trait.ocd.md',
27
+ 'cognition/cog401.questions.._.md',
28
+ 'cognition/cog000.overview.and.premise.md',
29
+ 'cognition/cog101.concept.treestruct._.md',
30
+ 'cognition/cog201.cortal.focus.p1.definition.md',
31
+ 'cognition/cog301.traversal.1.motion.primitives._.md',
32
+ 'cognition/cog401.questions.._.md',
33
+ 'cognition/cog401.questions.2.1.primitives.rough._.md',
34
+ 'librarian.tactics/<articulate>._.[article].frame.cognitive.md', // todo: keep or remove
35
+ 'librarian.tactics/<articulate>._.[article].frame.tactical.md',
36
+ 'cognition/cog201.cortal.focus.p2.breadth.md',
37
+ 'cognition/cog301.traversal.1.motion.primitives.breadth.md',
38
+ 'cognition/cog301.traversal.1.motion.primitives.breadth.vary.md',
39
+ 'thinker.tactics/<triage>._.[article].frame.tactical.md',
40
+ 'thinker.tactics/<triage>.persp.implicit_question.[article].md',
41
+ 'thinker.tactics/<triage>.persp.grades_from_context.[article].md',
42
+ 'librarian.tactics/[brief].verbiage.outline.over.narrative.md',
43
+ ]);
44
+
45
+ type StitcherDesired = GStitcher<
46
+ Threads<{
47
+ caller: RoleContext<
48
+ 'caller',
49
+ {
50
+ art: {
51
+ feedback: Artifact<typeof GitFile>;
52
+ 'foci.goal.concept': Focus['concept'];
53
+ 'foci.goal.context': Focus['context'];
54
+ 'foci.input.concept': Focus['concept'];
55
+ };
56
+ refs: Artifact<typeof GitFile>[];
57
+ }
58
+ >;
59
+ thinker: RoleContext<
60
+ 'thinker',
61
+ {
62
+ art: {
63
+ 'focus.concept': Focus['concept'];
64
+ 'focus.context': Focus['context'];
65
+ };
66
+ briefs: Artifact<typeof GitFile>[];
67
+ }
68
+ >;
69
+ }>,
70
+ ContextOpenAI & GStitcher['context'],
71
+ { content: string }
72
+ >;
73
+
74
+ const template = genTemplate<StitcherDesired['threads']>({
75
+ ref: { uri: getTemplatePathByCallerPath({ auto: true }) },
76
+ getVariables: async ({ threads }) => ({
77
+ ...(await getTemplateVarsFromRoleInherit({ thread: threads.thinker })),
78
+
79
+ guide: {
80
+ goal:
81
+ (await threads.caller.context.stash.art['foci.goal.concept'].get())
82
+ ?.content ||
83
+ UnexpectedCodePathError.throw('goal not declared', {
84
+ art: threads.caller.context.stash.art['foci.goal.concept'],
85
+ }),
86
+ feedback:
87
+ (await threads.caller.context.stash.art.feedback.get())?.content || '',
88
+ },
89
+
90
+ focus: {
91
+ context:
92
+ (await threads.thinker.context.stash.art['focus.context'].get())
93
+ ?.content ||
94
+ (await threads.caller.context.stash.art['foci.goal.context'].get()) // fallback to @[caller].focus[goal].context
95
+ ?.content ||
96
+ '',
97
+ concept:
98
+ (await threads.thinker.context.stash.art['focus.concept'].get())
99
+ ?.content || '',
100
+ },
101
+
102
+ seed: {
103
+ concepts:
104
+ (await threads.caller.context.stash.art['foci.input.concept'].get())
105
+ ?.content ||
106
+ UnexpectedCodePathError.throw('input not declared', {
107
+ art: threads.caller.context.stash.art['foci.input.concept'],
108
+ }),
109
+ },
110
+
111
+ skill: {
112
+ briefs: await getTemplateValFromArtifacts({
113
+ artifacts: [
114
+ ...BRIEFS_FOR_TRIAGE,
115
+ ...threads.thinker.context.stash.briefs,
116
+ ],
117
+ }),
118
+ },
119
+
120
+ references: await getTemplateValFromArtifacts({
121
+ artifacts: threads.caller.context.stash.refs,
122
+ }),
123
+ }),
124
+ });
125
+
126
+ const stepImagine = genStepImagineViaTemplate<StitcherDesired>({
127
+ slug: '@[thinker]<triage>',
128
+ stitchee: 'thinker',
129
+ readme: '',
130
+ template,
131
+ imagine: withRetry(
132
+ withTimeout(sdkOpenAi.imagine, { threshold: { seconds: 60 } }), // allow up to 60 sec, for longer files
133
+ ),
134
+ });
135
+
136
+ const stepPersist = genStepArtSet({
137
+ stitchee: 'thinker',
138
+ artee: 'focus.concept',
139
+ });
140
+
141
+ export const stepTriage = asStitcherFlat<StitcherDesired>(
142
+ genStitchRoute({
143
+ slug: '@[thinker]<triage>',
144
+ readme: '@[thinker]<triage> -> [article]',
145
+ sequence: [stepImagine, stepPersist],
146
+ }),
147
+ );
148
+
149
+ export const loopTriage = genLoopFeedback({
150
+ stitchee: 'thinker',
151
+ artee: 'focus.concept',
152
+ repeatee: stepTriage,
153
+ });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "rhachet-roles-bhrain",
3
3
  "author": "ehmpathy",
4
4
  "description": "reliable thought concept navigation roles, briefs, and skills, via rhachet",
5
- "version": "0.1.1",
5
+ "version": "0.3.0",
6
6
  "repository": "ehmpathy/rhachet-roles-bhrain",
7
7
  "homepage": "https://github.com/ehmpathy/rhachet-roles-bhrain",
8
8
  "keywords": [
@@ -25,9 +25,9 @@
25
25
  "fix:format": "npm run fix:format:biome",
26
26
  "fix:lint": "biome check --write",
27
27
  "fix": "npm run fix:format && npm run fix:lint",
28
- "build:clean": "rm dist/ -rf",
28
+ "build:clean": "chmod -R u+w dist 2>/dev/null; rm -rf dist/",
29
29
  "build:compile": "tsc -p ./tsconfig.build.json && tsc-alias -p ./tsconfig.build.json",
30
- "build:complete": "rsync -a --prune-empty-dirs --include='*/' --exclude='**/.route/**' --exclude='**/.scratch/**' --exclude='**/.behavior/**' --exclude='**/*.test.sh' --include='**/*.template.md' --include='**/briefs/**/*.md' --include='**/briefs/*.md' --include='**/skills/**/*.sh' --include='**/skills/*.sh' --include='**/skills/**/*.jsonc' --include='**/skills/*.jsonc' --exclude='*' src/ dist/",
30
+ "build:complete": "rsync -a --prune-empty-dirs --exclude='.test' --exclude='.route' --exclude='.scratch' --exclude='.behavior' --exclude='*.test.*' --include='*/' --include='briefs/**' --include='skills/**' --exclude='*' src/ dist/",
31
31
  "build": "npm run build:clean && npm run build:compile && npm run build:complete --if-present",
32
32
  "test:commits": "LAST_TAG=$(git describe --tags --abbrev=0 @^ 2> /dev/null || git rev-list --max-parents=0 HEAD) && npx commitlint --from $LAST_TAG --to HEAD --verbose",
33
33
  "test:types": "tsc -p ./tsconfig.json --noEmit",
@@ -38,7 +38,7 @@
38
38
  "test:lint:biome:all": "biome check",
39
39
  "test:lint": "npm run test:lint:biome && npm run test:lint:deps",
40
40
  "test:unit": "jest -c ./jest.unit.config.ts --forceExit --verbose --passWithNoTests $([ -z $THOROUGH ] && echo '--changedSince=main') $([ -n $RESNAP ] && echo '--updateSnapshot')",
41
- "test:integration": "echo 'todo: release'",
41
+ "test:integration": "jest -c ./jest.integration.config.ts --forceExit --verbose --passWithNoTests $([ -z $THOROUGH ] && echo '--changedSince=main') $([ -n $RESNAP ] && echo '--updateSnapshot')",
42
42
  "test:acceptance:locally": "npm run build && LOCALLY=true jest -c ./jest.acceptance.config.ts --forceExit --verbose --runInBand --passWithNoTests $([ -n $RESNAP ] && echo '--updateSnapshot')",
43
43
  "test": "npm run test:commits && npm run test:types && npm run test:format && npm run test:lint && npm run test:unit && npm run test:integration && npm run test:acceptance:locally",
44
44
  "test:acceptance": "npm run build && jest -c ./jest.acceptance.config.ts --forceExit --verbose --runInBand --passWithNoTests $([ -n $RESNAP ] && echo '--updateSnapshot')",
@@ -49,7 +49,7 @@
49
49
  "prepare:husky": "husky install && chmod ug+x .husky/*",
50
50
  "prepare": "if [ -e .git ] && [ -z $CI ]; then npm run prepare:husky && npm run prepare:rhachet; fi",
51
51
  "test:format:biome": "biome format",
52
- "prepare:rhachet": "rhachet init && rhachet roles link --role mechanic && rhachet roles init --role mechanic"
52
+ "prepare:rhachet": "rhachet init && rhachet roles link --role mechanic && rhachet roles link --role behaver && rhachet roles init --role mechanic"
53
53
  },
54
54
  "dependencies": {
55
55
  "@ehmpathy/as-command": "1.0.3",
@@ -62,6 +62,7 @@
62
62
  "openai": "5.8.2",
63
63
  "rhachet-artifact": "1.0.0",
64
64
  "rhachet-artifact-git": "1.1.0",
65
+ "rhachet-roles-bhuild": "0.1.3",
65
66
  "serde-fns": "1.2.0",
66
67
  "simple-in-memory-cache": "0.4.0",
67
68
  "type-fns": "1.21.0",
@@ -69,6 +70,7 @@
69
70
  "wrapper-fns": "1.1.0"
70
71
  },
71
72
  "devDependencies": {
73
+ "@anthropic-ai/claude-code": "2.0.76",
72
74
  "@biomejs/biome": "2.3.8",
73
75
  "@commitlint/cli": "19.5.0",
74
76
  "@commitlint/config-conventional": "19.5.0",
@@ -88,8 +90,8 @@
88
90
  "husky": "8.0.3",
89
91
  "jest": "30.2.0",
90
92
  "rhachet": "1.15.0",
91
- "rhachet-roles-ehmpathy": "1.15.14",
92
- "test-fns": "1.6.0",
93
+ "rhachet-roles-ehmpathy": "1.15.15",
94
+ "test-fns": "1.7.2",
93
95
  "tsc-alias": "1.8.10",
94
96
  "tsx": "4.20.6",
95
97
  "typescript": "5.4.5",
package/readme.md CHANGED
@@ -38,6 +38,12 @@ Used to navigate through concept space. See src/roles/thinker/briefs/cognition f
38
38
  ## 📚 Librarian
39
39
 
40
40
  Used to curate knowledge and context. see src/roles/thinker/briefs/librarian.context and src/roles/thinker/briefs/librarian.tactics for details.
41
+
42
+ ---
43
+
44
+ ## 🔍 Reviewer
45
+
46
+ Used to review artifacts against declared rules. Designed to be composed into review skills for other roles.
41
47
  ```
42
48
 
43
49
  ## `ask -r thinker -s instantiate`
@@ -89,3 +95,52 @@ npx rhachet ask -r thinker -s articulate \
89
95
  how to identify a sea turtle?
90
96
  "
91
97
  ```
98
+
99
+ ## `run --repo bhrain --skill review`
100
+
101
+ reviews artifacts against rules using claude-code as the brain. designed to be composed into review skills for other roles.
102
+
103
+ ```sh
104
+ npx rhachet run --repo bhrain --skill review --mode hard --diffs uptil-main --paths '!pnpm-lock.yaml'
105
+ ```
106
+
107
+ produces
108
+
109
+ ```
110
+ 🌊 skill "review" from repo=bhrain role=reviewer
111
+
112
+ 🔭 metrics.expected
113
+ ├─ files
114
+ │ ├─ rules: 60
115
+ │ └─ targets: 69
116
+ ├─ tokens
117
+ │ ├─ estimate: 73122
118
+ │ └─ context: 36.6%
119
+ └─ cost
120
+ └─ estimate: $0.3290
121
+
122
+ 🪵 logs
123
+ ├─ scope: .log/bhrain/review/2025-12-23T00-39-00-673Z/input.scope.json
124
+ ├─ metrics: .log/bhrain/review/2025-12-23T00-39-00-673Z/metrics.expected.json
125
+ └─ tokens: .log/bhrain/review/2025-12-23T00-39-00-673Z/tokens.expected.md
126
+
127
+ 🐢 let's review!
128
+ └─ elapsed: 85s ✓
129
+
130
+ ✨ metrics.realized
131
+ ├─ tokens
132
+ │ ├─ input: 2
133
+ │ ├─ cache.write: 144578
134
+ │ ├─ cache.read: 14316
135
+ │ └─ output: 1090
136
+ └─ cost
137
+ ├─ input: $0.0000
138
+ ├─ cache.write: $0.5422
139
+ ├─ cache.read: $0.0043
140
+ ├─ output: $0.0164
141
+ └─ total: $0.5629
142
+
143
+ 🌊 output
144
+ ├─ logs: .log/bhrain/review/2025-12-23T00-39-00-673Z
145
+ └─ review: .review/bhrain/v2025-12-23T00-39-00-645Z/[feedback].[given].by_robot.md
146
+ ```