@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.
- package/README.md +134 -4
- package/dist/bundled/agents/build-error-resolver.md +22 -14
- package/dist/bundled/agents/code-reviewer.md +22 -14
- package/dist/bundled/agents/loop-implementer.md +22 -8
- package/dist/bundled/agents/tdd-guide.md +23 -15
- package/dist/bundled/operators/agents/rafa-stretch-engineer.md +177 -0
- package/dist/bundled/operators/agents/rafa-stretch-watchtower.md +91 -0
- package/dist/bundled/operators/skills/rafa-stretch-gap-log/SKILL.md +72 -0
- package/dist/bundled/operators/skills/rafa-stretch-pit-stop/SKILL.md +77 -0
- package/dist/bundled/operators/skills/rafa-stretch-sweep/SKILL.md +111 -0
- package/dist/bundled/skills/dev-planner/SKILL.md +22 -4
- package/dist/bundled/skills/git-workflow/SKILL.md +1 -1
- package/dist/cli.js +4495 -1789
- package/dist/{describe-d31jy6dk.js → describe-5hqfwbjc.js} +3 -3
- package/dist/effort/store/index.js +24 -4
- package/dist/{index-mt6hpsry.js → index-3mzw3kzh.js} +2 -2
- package/dist/{index-qgayjcym.js → index-4b3m7s0z.js} +7148 -4603
- package/dist/{index-22stnzde.js → index-b8t7q5hc.js} +666 -1137
- package/dist/{index-wvm2s4pr.js → index-bvfbfa63.js} +699 -132
- package/dist/{index-rs79dq9e.js → index-fzhd3d4y.js} +22 -4
- package/dist/{index-5tftj69y.js → index-k6sd4ym5.js} +2 -2
- package/dist/{index-pbeyv281.js → index-v8d7c6sw.js} +2 -2
- package/dist/{index-9aph6ft9.js → index-vp0xghk2.js} +167 -5
- package/dist/index.js +27 -7
- package/dist/plan/index.js +3 -3
- package/dist/plan-prompt.md +12 -0
- 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
|
|
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` |
|
|
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 `
|
|
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
|
|
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.,
|
|
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`
|