@open-tomato/rafa 0.18.0 → 0.20.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/README.md CHANGED
@@ -174,8 +174,8 @@ the next one, so you rarely have to remember it.
174
174
  ### Which agents and skills are involved
175
175
 
176
176
  A task line may end with a declaration, for example
177
- `{agent=tdd-guide effort=medium}`. The planner writes it; you can change
178
- it.
177
+ `{agent=tdd-guide skills=dev-planner effort=medium}`. The planner
178
+ writes it; you can change it.
179
179
 
180
180
  - `agent=` routes the task to a Claude Code subagent. The planner picks
181
181
  by the task's SHAPE: implementation, tests, prose, a red build, a
@@ -196,8 +196,8 @@ it.
196
196
  while the project or a loaded user tier holds a different copy, and a
197
197
  `project` pin while a loaded user tier does; pin the tier the refusal
198
198
  names, or delete or rename the copy it names. `loop start` refuses a
199
- plan that names an agent it cannot resolve before any session is paid
200
- for.
199
+ plan that names an agent or a skill it cannot resolve before any
200
+ session is paid for.
201
201
  - User-tier items are invisible unless `loop.settingSources` includes
202
202
  `user`. `rafa agent list` shows what a run sees, `rafa agent vendor
203
203
  <name>` copies one in or updates it, and `rafa skill check .claude/skills
@@ -205,6 +205,25 @@ it.
205
205
  not resolve, a missing field) before it costs a task.
206
206
  - The plan format itself is a skill, `dev-planner`, shipped in the rafa
207
207
  tier and used when the project has none of its own.
208
+ - **Skills for this task.** A task may declare the skills it needs with
209
+ `skills=skill1,skill2` on its line. At dispatch, one of three resolvers
210
+ picks which skills to offer: `planner` uses the task's `skills=`
211
+ declaration exactly, in order; `tag` ignores `skills=` and ranks every
212
+ enabled skill against the task text to find the top 3 scoring above a
213
+ floor of zero; `none` offers no skills. The resolver is set by
214
+ `task.skills` in `.rafa/config.yaml` (defaulting to `planner`), and the
215
+ `--skills-resolver=` flag overrides it. A compact skill index is listed
216
+ in the planner's prompt so the planner sees what skills are available
217
+ before writing the task. When a task is dispatched, the prompt gains a
218
+ "Skills for this task" section with the skills the resolver picked, or
219
+ stays unchanged if none were picked. The dispatch record stores the
220
+ resolver name and which skills were offered.
221
+ - **Lessons from earlier tasks.** Up to 5 lessons from the learning store
222
+ are added to a task's prompt as a "Lessons from earlier tasks" section
223
+ when `task.lessons` is `on` (the default). The lessons are blessed
224
+ passages from earlier task findings that recurred or reached a
225
+ confidence floor. When neither skills nor lessons appear, the prompt
226
+ stays unchanged from before.
208
227
  - `model=`, `effort=`, `tools=` and `budget=` on a task line set the
209
228
  session's model, reasoning effort, tool list and spending cap when no
210
229
  agent decides them.
@@ -352,9 +371,9 @@ and never none.
352
371
  The build targets bun, and `engines` names `bun` alone: there is no
353
372
  `engines.node`, because no node version runs the binary. The package
354
373
  root, `./cli` and `./store` import `bun:sqlite`, which node's ESM loader
355
- refuses before any module code runs, so only `./plan` and `./ports` load
356
- under node at all. `module` points at `./dist/index.js`, the same build
357
- the root of `exports` names. The package ships no type declarations:
374
+ refuses before any module code runs, so only `./plan`, `./ports` and
375
+ `./learning` load under node at all. `module` points at
376
+ `./dist/index.js`, the same build the root of `exports` names. The package ships no type declarations:
358
377
  `exports` names no `types`, and a TypeScript consumer gets TS7016 under
359
378
  `strict`.
360
379
 
@@ -411,7 +430,7 @@ and a line here is ticked by the change that finishes the feature.
411
430
  - ✅ The right skills reach the right task, chosen when the plan is
412
431
  written
413
432
  - ⬜ Know which skills earn their place and which are ignored
414
- - ⬜ rafa learns from its own runs: what one task works out is handed
433
+ - ✅ rafa learns from its own runs: what one task works out is handed
415
434
  to the tasks that need it later
416
435
  - ⬜ Skills and lessons shared across projects and machines
417
436
  - ⬜ Config as code: a typed `rafa.config.ts` holding your settings, your
@@ -465,12 +484,15 @@ rafa stands on other people's work and on earlier work of ours.
465
484
  evidence, scope) is adapted from the `continuous-learning-v2` skill of
466
485
  [`affaan-m/everything-claude-code`](https://github.com/affaan-m/everything-claude-code)
467
486
  by Affaan Mustafa (MIT).
468
- - **Shared learning (coming).** The design for merging what separate
469
- runs learn (one record per lesson, a rule for conflicting lessons,
470
- promotion on recurrence) follows Open Tomato's hive-learning design.
471
- In rafa it is partly built: lessons are recorded per project today, and
472
- sharing them across runs, projects and machines is on the
473
- [Roadmap](#roadmap) and not available yet.
487
+ - **Shared learning.** The design for merging what separate runs learn
488
+ (one record per lesson, a rule for conflicting lessons, promotion on
489
+ recurrence) follows Open Tomato's hive-learning design. rafa now records
490
+ lessons in `.rafa/instincts/` — one lesson per task finding that carries
491
+ a resolution — and pushes them after each task's report. Lessons that
492
+ meet a confidence floor are blessed and handed to tasks that need them
493
+ later; lessons that recur enough are promoted into the pages that own
494
+ their subjects. Sharing lessons across projects and machines is planned
495
+ for a future version.
474
496
 
475
497
  ## License
476
498
 
package/dist/PROMPT.md CHANGED
@@ -2,7 +2,7 @@ We shared as much of the plan as this run is configured to share — the whole p
2
2
 
3
3
  Do not stage or commit anything: the loop owns staging and committing, and once this session exits cleanly it runs `git add -A` and commits your work under a subject derived from the task text. Leave your changes in the working tree, and leave them in a state the pre-commit hooks accept — a refused hook blocks the task and stops the loop.
4
4
 
5
- End your final message with exactly one `rafa:report` block shaped like the example below, and write nothing after it: the loop stores what it reads there, and a message without the block stores none of your findings. Write all seven fields, `status`, `feedback`, `findings`, `skills_used`, `blockers`, `out_of_scope_bugs` and `changes`, and write a list with nothing in it as `[]` rather than leaving its field out. `status` is `done` or `blocked`. `feedback` says what was done and how it went. `findings` is a list with one entry per distinct observation, never several merged into one; a finding's `kind` is one of `gotcha`, `pattern`, `location` or `skill-suggestion`, its `signal` is `loud` when it surfaced as a failure or `silent` when something passed while wrong, and its `artifact`, when there is one, is the exact string a recurrence would match on, such as an error message. `skills_used` names each skill you invoked. `blockers` lists what stopped the task, each entry a `what` and, when there is one, an `artifact`, `out_of_scope_bugs` the bugs you saw outside it, each bug with `security` set to `true` or `false`, and `changes` is the changelog for your diff, each entry holding the required fields `level` (one of patch, minor, major, none) and `summary` (a quoted line the user would understand), plus optional `area` (the changelog section). Write those closed-set words and `security` bare, as the example does, and double-quote every other value on one line: an unquoted value that opens with a backtick, `@`, `%` or `[` makes the whole block unreadable, and a `#` after a space silently cuts a value short.
5
+ End your final message with exactly one `rafa:report` block shaped like the example below, and write nothing after it: the loop stores what it reads there, and a message without the block stores none of your findings. Write all seven fields, `status`, `feedback`, `findings`, `skills_used`, `blockers`, `out_of_scope_bugs` and `changes`, and write a list with nothing in it as `[]` rather than leaving its field out. `status` is `done` or `blocked`. `feedback` says what was done and how it went. `findings` is a list with one entry per distinct observation, never several merged into one; a finding's `kind` is one of `gotcha`, `pattern`, `location` or `skill-suggestion`, its `signal` is `loud` when it surfaced as a failure or `silent` when something passed while wrong, and its `artifact`, when there is one, is the exact string a recurrence would match on, such as an error message. A finding may also carry a `domain`, the area of work its lesson belongs to, one of `code-style`, `testing`, `git`, `debugging`, `workflow`, `security` or `general-best-practices`; leave it out when none fits. `skills_used` names each skill you invoked. `blockers` lists what stopped the task, each entry a `what` and, when there is one, an `artifact`, `out_of_scope_bugs` the bugs you saw outside it, each bug with `security` set to `true` or `false`, and `changes` is the changelog for your diff, each entry holding the required fields `level` (one of patch, minor, major, none) and `summary` (a quoted line the user would understand), plus optional `area` (the changelog section). Write those closed-set words and `security` bare, as the example does, and double-quote every other value on one line: an unquoted value that opens with a backtick, `@`, `%` or `[` makes the whole block unreadable, and a `#` after a space silently cuts a value short.
6
6
 
7
7
  ```rafa:report
8
8
  status: done
@@ -16,6 +16,7 @@ findings:
16
16
  resolution: "run bun install before the first test"
17
17
  artifact: "Cannot find package"
18
18
  signal: loud
19
+ domain: testing
19
20
  skills_used: ["git-workflow"]
20
21
  blockers: []
21
22
  out_of_scope_bugs:
@@ -223,6 +223,7 @@ findings:
223
223
  resolution: "wrap append in try/finally"
224
224
  artifact: "EMFILE: too many open files"
225
225
  signal: loud
226
+ domain: debugging
226
227
  - trigger: "SQLite schema migration timing"
227
228
  kind: pattern
228
229
  what: "migrations run on every store init, not just schema changes"
@@ -262,6 +263,7 @@ Finding entry fields:
262
263
  | `resolution` | string | no | How to fix or work around it |
263
264
  | `artifact` | string | no | Error message, file path, or code snippet that signals the finding |
264
265
  | `signal` | string | yes | `loud` (it surfaced as a failure) or `silent` (it passed while wrong) |
266
+ | `domain` | string | no | The area of work the finding's lesson belongs to: `code-style`, `testing`, `git`, `debugging`, `workflow`, `security` or `general-best-practices`. A value outside the set is reported as an issue and read as absent |
265
267
 
266
268
  Change note entry fields:
267
269
 
@@ -358,12 +360,19 @@ The recognised keys are the `DECLARATION_KEYS` of `src/utils/declaration.ts`, wh
358
360
 
359
361
  ### `skills=` declaration
360
362
 
363
+ When a task needs help from a skill, name those skills with `skills=`. Skill names must come from the skill index provided in this prompt; naming a skill no tier holds is recorded as an issue. Names are comma-separated with no spaces.
364
+
361
365
  `skills` is a recognised key that maps to no flag: there is no CLI flag for a skill, so the names are parsed, kept on the dispatch record and stripped from the task text with the rest of the block. It stands on its own — `{skills=bun-testing}` is a declaration with no other key beside it — and a value that is not a comma-separated list of skill names is recorded as an issue rather than passed on.
362
366
 
367
+ A task with no `skills=` declaration is valid — naming none is the answer when no skill guides the task.
368
+
363
369
  ```markdown
364
370
  - [ ] Port vitest tests to bun:test {agent=build-error-resolver skills=bun-testing,vitest-migration}
371
+ - [ ] Add the Zod schema for `CreateJobRequest` with its unit tests
365
372
  ```
366
373
 
374
+ The second example above has no `skills=` and is still a valid task declaration.
375
+
367
376
  ---
368
377
 
369
378
  ## Task sizing (session economics)