@open-tomato/rafa 0.32.0 → 0.34.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 (27) hide show
  1. package/README.md +134 -4
  2. package/dist/bundled/agents/build-error-resolver.md +22 -14
  3. package/dist/bundled/agents/code-reviewer.md +22 -14
  4. package/dist/bundled/agents/loop-implementer.md +22 -8
  5. package/dist/bundled/agents/tdd-guide.md +23 -15
  6. package/dist/bundled/operators/agents/rafa-stretch-engineer.md +177 -0
  7. package/dist/bundled/operators/agents/rafa-stretch-watchtower.md +91 -0
  8. package/dist/bundled/operators/skills/rafa-stretch-gap-log/SKILL.md +72 -0
  9. package/dist/bundled/operators/skills/rafa-stretch-pit-stop/SKILL.md +77 -0
  10. package/dist/bundled/operators/skills/rafa-stretch-sweep/SKILL.md +111 -0
  11. package/dist/bundled/skills/dev-planner/SKILL.md +22 -4
  12. package/dist/bundled/skills/git-workflow/SKILL.md +1 -1
  13. package/dist/cli.js +4495 -1789
  14. package/dist/{describe-d31jy6dk.js → describe-5hqfwbjc.js} +3 -3
  15. package/dist/effort/store/index.js +24 -4
  16. package/dist/{index-mt6hpsry.js → index-3mzw3kzh.js} +2 -2
  17. package/dist/{index-qgayjcym.js → index-4b3m7s0z.js} +7148 -4603
  18. package/dist/{index-22stnzde.js → index-b8t7q5hc.js} +666 -1137
  19. package/dist/{index-wvm2s4pr.js → index-bvfbfa63.js} +699 -132
  20. package/dist/{index-rs79dq9e.js → index-fzhd3d4y.js} +22 -4
  21. package/dist/{index-5tftj69y.js → index-k6sd4ym5.js} +2 -2
  22. package/dist/{index-pbeyv281.js → index-v8d7c6sw.js} +2 -2
  23. package/dist/{index-9aph6ft9.js → index-vp0xghk2.js} +167 -5
  24. package/dist/index.js +27 -7
  25. package/dist/plan/index.js +3 -3
  26. package/dist/plan-prompt.md +12 -0
  27. package/package.json +5 -2
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: rafa-stretch-gap-log
3
+ description: "Use when a stretch step needs raw gh, git or shell because no rafa line does it: file it as a module:cli-gap bug."
4
+ provenance: first-party
5
+ source: rafa
6
+ stage: alpha
7
+ prevents: "the same raw command typed every stretch with nobody noticing rafa could own it"
8
+ signal: silent
9
+ when_to_use: "You are rafa-stretch-engineer and a step you just took, or are about to take, has no rafa line: a raw gh, git or shell command, or a config edit by hand. Prevents: the same raw command typed every stretch with nobody noticing rafa could own it"
10
+ tags:
11
+ - rafa
12
+ - stretch
13
+ - cli
14
+ stack:
15
+ - shell
16
+ ---
17
+
18
+ Alpha: tested on rafa's own development, may become a feature.
19
+
20
+ # Gap log
21
+
22
+ A *gap* is a step rafa could own and does not yet: you had to type a raw
23
+ `gh`, `git` or shell line, or edit a config by hand, because no rafa line
24
+ does it. Each one is filed once, so the next bug sweep can turn the ones
25
+ that repeat into commands.
26
+
27
+ ## Is it a gap?
28
+
29
+ - **Yes:** a step every stretch takes the same way, such as creating the
30
+ integration branch, or opening a pull request outside a loop.
31
+ - **Yes:** a flag you add every time, which rafa could read from the
32
+ scenario instead.
33
+ - **No:** a one-off investigation, or a `git` commit, push or rebase,
34
+ which stay `git`'s.
35
+
36
+ ## Filing one
37
+
38
+ Search first, so a gap is filed once:
39
+
40
+ ```bash
41
+ rafa issue list --module=cli-gap --search="<the step in a few words>"
42
+ ```
43
+
44
+ When none matches, file it:
45
+
46
+ ```bash
47
+ rafa issue create --type=bug --module=cli-gap --title="<the step rafa cannot do yet>" --body="<the raw line, the rafa line that came closest, what it lacks>"
48
+ ```
49
+
50
+ When one matches, add the stretch's case to it:
51
+
52
+ ```bash
53
+ rafa issue comment <n> --body="Seen again in stretch <n>: <the raw line>."
54
+ ```
55
+
56
+ The board is public: no local path, host name, user name or secret in the
57
+ title or the body.
58
+
59
+ ## Known at design time
60
+
61
+ These are filed or waiting to be, so search before filing them again:
62
+
63
+ - grouping duplicate bugs;
64
+ - opening a pull request outside a loop;
65
+ - creating the integration branch, and switching `pr.base` to it and back;
66
+ - installing the operators;
67
+ - a per-command log under `.rafa/logs/`, for reading a failure from
68
+ another device;
69
+ - detached loops;
70
+ - `rafa loop list` across projects.
71
+
72
+ List every gap you filed or commented on in the stretch report.
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: rafa-stretch-pit-stop
3
+ description: "Use after each stretch item: check effort, bugs, delivery, conflicts and CI, then go on, insert one fix, or halt."
4
+ provenance: first-party
5
+ source: rafa
6
+ stage: alpha
7
+ prevents: "a stretch that misses a run with no pull request, piles up refiled bugs, or wanders off after one issue"
8
+ signal: silent
9
+ when_to_use: "You are rafa-stretch-engineer and one bucket item's loop has just ended, merged or not. Prevents: a stretch that misses a run with no pull request, piles up refiled bugs, or wanders off after one issue"
10
+ tags:
11
+ - rafa
12
+ - stretch
13
+ - effort
14
+ stack:
15
+ - shell
16
+ ---
17
+
18
+ Alpha: tested on rafa's own development, may become a feature.
19
+
20
+ # Pit stop
21
+
22
+ A pit stop is the check between two items. It fixes the one thing that
23
+ would stop the next item, then rejoins the bucket: it is never a change
24
+ of course, and never a reason to chase one issue down a rabbit hole.
25
+
26
+ ## The five checks
27
+
28
+ | Check | Line | What is wrong |
29
+ |---|---|---|
30
+ | Effort | `rafa effort dashboard` | cost per task drifting up against the baseline, not explained by the item's size |
31
+ | Bugs | `rafa issue list --type=bug --limit=200` | the open count rising, or bugs filed during this loop that repeat an open one |
32
+ | Delivery | `rafa loop status`, `rafa pr list` | the run is done with no pull request, or its pull request did not merge |
33
+ | Conflicts | `rafa pr show <pr>` | the pull request conflicts with the integration branch |
34
+ | CI | `gh run list --branch stretch/<n> --workflow verify.yml --limit 1` | the run failed (use `gh run view <id> --log-failed` to see why), or is still running |
35
+
36
+ A CI failure already red in the local runs is inherited and noted in the pit-stop entry.
37
+ A new failure is filed as one bug after a search for an existing one. A run still in progress
38
+ is read at the next pit stop.
39
+
40
+ A conflict goes to the resolve plans first:
41
+
42
+ ```bash
43
+ rafa pr triage <pr> --resolve
44
+ ```
45
+
46
+ A run that ended with no pull request is a known defect of the loop: say
47
+ so in the pit-stop entry, and open the pull request from the run's branch
48
+ only after reading the run's last `rafa·` lines.
49
+
50
+ ## Deciding
51
+
52
+ 1. **All fine.** Write the entry and take the next item.
53
+ 2. **A blocker a loop can fix.** It stops the next item, and one small
54
+ plan can fix it. It becomes the next item and takes a bucket slot.
55
+ When the bucket is full, the lowest-ranked preparation item leaves it.
56
+ Add a line to `bucket.md` saying so.
57
+ 3. **A halt.** Stop the stretch and alert the person when one failure
58
+ happens twice, when the hook rule fires, when usage runs low, or when
59
+ the fix would touch anything outside the integration branch.
60
+
61
+ Anything else you find is filed, not fixed: one issue, after a search for
62
+ an existing one, and the stretch goes on.
63
+
64
+ ## The entry
65
+
66
+ Append one entry to `.rafa/stretch/<n>/pit-stops.md`:
67
+
68
+ ```markdown
69
+ ## After #485 (item 2 of 10)
70
+
71
+ - Effort: 14 min per task against a 12 min baseline; the plan was large.
72
+ - Bugs: 61 open, 64 at the start; none filed during the loop.
73
+ - Delivery: pull request #612 merged into stretch/3.
74
+ - Conflicts: none.
75
+ - CI: verify.yml passed.
76
+ - Decision: next item, #486.
77
+ ```
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: rafa-stretch-sweep
3
+ description: "Use at a stretch's sweep: group duplicate bugs, rank the board, and fill a bucket of up to 10 issues by tier."
4
+ provenance: first-party
5
+ source: rafa
6
+ stage: alpha
7
+ prevents: "a bucket that refiles the same failing test, chases a feature over a blocker, or pulls in a chain of issues"
8
+ signal: silent
9
+ when_to_use: "You are rafa-stretch-engineer in phase 1 of a stretch, choosing which issues the stretch will run. Prevents: a bucket that refiles the same failing test, chases a feature over a blocker, or pulls in a chain of issues"
10
+ tags:
11
+ - rafa
12
+ - stretch
13
+ - triage
14
+ stack:
15
+ - shell
16
+ ---
17
+
18
+ Alpha: tested on rafa's own development, may become a feature.
19
+
20
+ # Sweep and bucket
21
+
22
+ The sweep reads the board, groups what is filed twice, ranks what is
23
+ left, and proposes a *bucket*: the issues this stretch will run, at most
24
+ 10. It ends with the bucket written and the stretch stopped for the
25
+ person's approval.
26
+
27
+ ## Read the board
28
+
29
+ ```bash
30
+ rafa roadmap --full
31
+ rafa issue list --type=bug --limit=200
32
+ rafa effort report --trend
33
+ ```
34
+
35
+ Read the roadmap's "now" epics first: their members are where the
36
+ project already said the work is.
37
+
38
+ ## The five steps
39
+
40
+ 1. **Group the duplicates.** Bugs naming the same failing test, or the
41
+ same symptom in other words, form one group. The oldest issue of a
42
+ group stays open; the others will close as its duplicates. Most
43
+ duplicate bugs are one failing test filed by several loops, so read
44
+ test file names and case names first.
45
+ 2. **Rank the bugs.** First by how often the group was filed, then by
46
+ impact: what it unblocks, and whether it breaks the loop itself (a run
47
+ with no pull request, a refused pull, a false blocker).
48
+ 3. **Fill 10 slots by tier.** 6 bugs, 3 fixes, 1 preparation item, by the
49
+ tier rules below.
50
+ 4. **Apply the chain rule.** An item that would pull in a chain of other
51
+ items is left out for a later stretch. An item whose absence would
52
+ spread an error, or make a new one, is let in past the cap.
53
+ 5. **Write the bucket report** to `.rafa/stretch/<n>/bucket.md`.
54
+
55
+ ## The tiers
56
+
57
+ | Tier | What belongs | First |
58
+ |---|---|---|
59
+ | Bugs | anything filed as a bug that still happens | refiled most, then biggest impact |
60
+ | Fixes and stabilisation | work that closes a known defect, labelled as a fix or not | fixes, then stabilisation |
61
+ | Preparation | work that readies the next feature, or separates mechanics from interface | only what a target feature needs |
62
+
63
+ **Rebalancing.** When a tier has fewer items than its slots, its spare
64
+ slots split 50-50 between the other two, starting from the highest tier.
65
+ A tier that already split passes its half on to the tier below, so no
66
+ split repeats. The bug share never drops under 20% while bugs remain;
67
+ when every bug left is low impact and touches no workflow, it may drop
68
+ to 20%.
69
+
70
+ ## Bugs reach a loop through one sweep spec
71
+
72
+ `rafa plan create --issue` plans from a `type:spec` issue only. So the
73
+ bucket's bugs go into one sweep spec that lists them, as the project's
74
+ bug sweeps already do, and six bug slots can run as one or two loops.
75
+ Filing that spec is a step with no rafa line yet: log it as a gap.
76
+
77
+ ## The bucket report
78
+
79
+ ```markdown
80
+ # Stretch <n>: bucket
81
+
82
+ | Slot | Issue | Tier | Why it is here |
83
+ |---|---|---|---|
84
+ | 1 | #485 | fix | every loop inherits its red tests |
85
+
86
+ ## Duplicate groups
87
+
88
+ | Kept | Closes as duplicates | The shared test or symptom |
89
+ |---|---|---|
90
+ | #513 | #527, #555, #571, #583 | registry.test.ts HOME case |
91
+
92
+ ## Left out, and why
93
+
94
+ - #28: pulls in a chain of four specs.
95
+
96
+ ## Cost
97
+
98
+ <items> items: <loops> loops, <planner sessions> planner sessions.
99
+ ```
100
+
101
+ Then stop: the person approves the bucket.
102
+
103
+ ## After the approval
104
+
105
+ Close each duplicate with a comment naming the issue kept, so reopening
106
+ is one command:
107
+
108
+ ```bash
109
+ rafa issue comment 527 --body="Duplicate of #513: the same registry.test.ts HOME case."
110
+ rafa issue move 527 done
111
+ ```
@@ -28,7 +28,7 @@ This file is the single source of that format. `rafa plan` inlines it, without i
28
28
  | `<plan.dir>/PLAN-<stub>.md` | Full task checklist with structured blocks and technical context |
29
29
  | `<plan.dir>/PREREQUISITES-<stub>.md` | Non-automatable setup steps required before the plan can run (only when any exist) |
30
30
 
31
- `plan.dir` is `.rafa/plans` unless the project's `.rafa/config.yaml` names another directory. `rafa plan --spec=<spec>.md` generates both files (optionally `--stub=<name>`; the stub defaults to the spec's basename) and writes them into `plan.dir`, creating the directory when it is missing. It reads the spec from the project root, or from `specs.dir` (`.rafa/specs` by default) when the root holds no such file, and refuses to run when `<plan.dir>/PLAN-<stub>.md` already exists.
31
+ `plan.dir` is `.rafa/plans` unless the project's `config.yaml` under `.rafa/` names another directory. `rafa plan --spec=<spec>.md` generates both files (optionally `--stub=<name>`; the stub defaults to the spec's basename) and writes them into `plan.dir`, creating the directory when it is missing. It reads the spec from the project root, or from `specs.dir` (`.rafa/specs` by default) when the root holds no such file, and refuses to run when `<plan.dir>/PLAN-<stub>.md` already exists.
32
32
 
33
33
  Execute a plan with `rafa start --plan=.rafa/plans/PLAN-<stub>.md`. With no `--plan`, `rafa start` runs `PLAN.md` in `plan.dir`, and falls back to a hand-written `PLAN.md` at the project root only when `plan.dir` holds no `PLAN.md`.
34
34
 
@@ -165,7 +165,7 @@ All rafa work follows a consistent naming scheme across specifications, plans, b
165
165
 
166
166
  | Artifact | Pattern | Example |
167
167
  | --- | --- | --- |
168
- | Specification file | `.rafa/specs/rafa-<n>-<slug>.md` | `.rafa/specs/rafa-20-pr-commands.md` |
168
+ | Specification file | `.rafa/specs/rafa-<n>-<slug>.md` | `rafa-20-pr-commands.md`, under `.rafa/specs/` |
169
169
  | Plan stub and directory | `rafa-<n>-<slug>` | `rafa-20-pr-commands` |
170
170
  | `issue:` field in `rafa:plan` | `<n>` (number only) | `issue: 20` |
171
171
  | Git branch | `feat/rafa-<n>-<slug>` | `feat/rafa-20-pr-commands` |
@@ -352,6 +352,7 @@ The strip happens where the loop reads the next task, `findNextTask` in `src/uti
352
352
  | `budget` | US dollars above zero, as a plain decimal of at most six digits each side of the point, such as `0.50` | `--max-budget-usd` | always passed: a definition supplies no budget |
353
353
  | `tools` | tool names, comma-separated with no spaces | `--tools` | never passed: the definition names its tool set |
354
354
  | `skills` | skill names, comma-separated with no spaces | nothing: no flag carries a skill | kept on the record beside the agent |
355
+ | `tests` | `affected`, `module` or `full`; `affected` when absent | nothing: the loop's runner reads it | kept on the record beside the agent |
355
356
 
356
357
  * `agent=<name>` outranks `model` and `tools`, and `effort` only when its
357
358
  definition declares one, as the last column says. The outranked keys
@@ -376,7 +377,7 @@ The strip happens where the loop reads the next task, `findNextTask` in `src/uti
376
377
 
377
378
  There is no default agent. A task with no declaration passes no routing flag and runs at the loop's defaults, as does one whose every value failed to parse.
378
379
 
379
- The recognised keys are the `DECLARATION_KEYS` of `src/utils/declaration.ts`, whose `MODEL_ALIASES` and `EFFORT_LEVELS` hold the aliases and levels in the table, whose `parseBudgetUsd` reads a budget and whose `parseSkillList` reads a skill list; that module is the authority for this section, so change the two together.
380
+ The recognised keys are the `DECLARATION_KEYS` of `src/utils/declaration.ts`, whose `MODEL_ALIASES`, `EFFORT_LEVELS` and `TEST_SCOPES` hold the aliases, levels and test scopes in the table, whose `parseBudgetUsd` reads a budget, whose `parseSkillList` reads a skill list and whose `readTestScope` reads a test scope; that module is the authority for this section, so change the two together.
380
381
 
381
382
  ### `skills=` declaration
382
383
 
@@ -393,6 +394,23 @@ A task with no `skills=` declaration is valid — naming none is the answer when
393
394
 
394
395
  The second example above has no `skills=` and is still a valid task declaration.
395
396
 
397
+ ### `tests=` declaration
398
+
399
+ `tests=` names how much of the suite the loop's runner runs after the task commits. The task's own session runs only the tests its changes reach, whatever the key says; the key sizes the runner's step that follows it.
400
+
401
+ | Value | The runner's step runs |
402
+ | --- | --- |
403
+ | `affected` | the test files the task's diff reaches. The default: a task with no `tests=` runs this |
404
+ | `module` | the tests of every module the task's diff touches |
405
+ | `full` | the whole suite |
406
+
407
+ `tests` is a recognised key that maps to no flag, like `skills`: it stands on its own (`{tests=full}` is a declaration), is stripped from the task text with the rest of the block, and a value outside the three is recorded as an issue and read as absent, so the task runs at `affected`.
408
+
409
+ ```markdown
410
+ - [ ] Drive a real `rafa loop start` over a one-task fixture plan {tests=module}
411
+ - [ ] Move the test preload into `bunfig.toml` {tests=full}
412
+ ```
413
+
396
414
  ---
397
415
 
398
416
  ## Task sizing (session economics)
@@ -431,7 +449,7 @@ The second example above has no `skills=` and is still a valid task declaration.
431
449
 
432
450
  ## Three task-context injection modes
433
451
 
434
- The loop supports three modes of injecting task context, configured at plan start via `--inject=` or in `.rafa/config.yaml`:
452
+ The loop supports three modes of injecting task context, configured at plan start via `--inject=` or in the project's `config.yaml` under `.rafa/`:
435
453
 
436
454
  | Mode | Contents | Use case |
437
455
  | --- | --- | --- |
@@ -38,7 +38,7 @@ For the rafa project specifically, issue numbers are prefixed with `rafa-` and
38
38
  reflected throughout the spec and branch workflow:
39
39
 
40
40
  - **Issue reference** (in prose): `#rafa-<n>` — e.g., `#rafa-20`
41
- - **Spec file**: `.rafa/specs/rafa-<n>-<slug>.md` — e.g., `.rafa/specs/rafa-20-pr-commands.md`
41
+ - **Spec file**: `.rafa/specs/rafa-<n>-<slug>.md` — e.g., `rafa-20-pr-commands.md`, under `.rafa/specs/`
42
42
  - **Plan stub** (in prose): `rafa-<n>-<slug>` — e.g., `rafa-20-pr-commands`
43
43
  - **Branch name**: `feat/rafa-<n>-<slug>` — e.g., `feat/rafa-20-pr-commands`
44
44
  - **PR title**: `rafa-<n>: <title>` — e.g., `rafa-20: Add PR commands`