@alphacoder-v0/pi-loops 0.17.6 → 0.18.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/CHANGELOG.md +39 -0
- package/README.md +8 -1
- package/README.zh-CN.md +14 -1
- package/docs/agents/issue-tracker.md +34 -0
- package/docs/cli.md +16 -0
- package/docs/design.md +43 -0
- package/docs/recipes.md +239 -0
- package/docs/web-ui-parity.md +2 -0
- package/package.json +2 -1
- package/recipes/_tracker/issue-tracker-github.md +31 -0
- package/recipes/_tracker/issue-tracker-local.md +38 -0
- package/recipes/_tracker-setup.md +12 -0
- package/recipes/autoresearch/README.md +27 -0
- package/recipes/autoresearch/RESEARCH.template.md +37 -0
- package/recipes/autoresearch/example/RESEARCH.md +31 -0
- package/recipes/autoresearch/example/eval.py +60 -0
- package/recipes/autoresearch/example/eval.sh +3 -0
- package/recipes/autoresearch/example/solution.py +20 -0
- package/recipes/autoresearch/experiment.md +82 -0
- package/recipes/autoresearch/recipe.toml +15 -0
- package/recipes/changelog-draft/recipe.toml +9 -0
- package/recipes/changelog-draft/release.md +35 -0
- package/recipes/issue-loop/README.md +16 -0
- package/recipes/issue-loop/implement.md +135 -0
- package/recipes/issue-loop/labels.sh +21 -0
- package/recipes/issue-loop/recipe.toml +18 -0
- package/recipes/issue-loop/triage.md +147 -0
- package/skills/pi-loops/SKILL.md +1 -0
- package/src/cli.ts +66 -1
- package/src/pi-loops.ts +321 -0
- package/src/recipe.ts +651 -0
- package/src/store.ts +2 -0
- package/src/tools.ts +3 -0
- package/src/web.mjs +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,45 @@
|
|
|
3
3
|
All notable changes to pi-loops are documented here. The format follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow SemVer.
|
|
5
5
|
|
|
6
|
+
## [0.18.0] - 2026-09-14
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- **Recipes: a project run on loops, installed in one command.** A recipe is a directory —
|
|
10
|
+
`recipe.toml`, one playbook per job, an optional setup script — and `/recipe add <name>` installs
|
|
11
|
+
it into the open project: one question (the autonomy level, `report` / `propose` / `act`, written
|
|
12
|
+
as the first line of each playbook), one confirmation showing every file, the setup script and
|
|
13
|
+
every `/cron add` line, then the jobs through the same code path `/cron add` uses. The playbooks
|
|
14
|
+
are copied to `.agents/skills/<name>/` — where pi also discovers them as `/skill:` commands — and
|
|
15
|
+
the directory is listed in `.git/info/exclude`, so the repository is untouched; a job's prompt is
|
|
16
|
+
a pointer to its playbook, read fresh on every run, so editing the file changes the next run.
|
|
17
|
+
`/recipe update` is a three-way merge against the untouched copy kept at install (under `.orig/`), and a conflict
|
|
18
|
+
is handed to the agent to resolve with you rather than left as markers in a file a loop would
|
|
19
|
+
follow. `/recipe remove` takes the jobs and leaves the files unless `--purge`. Each `[[job]]` in a
|
|
20
|
+
manifest is validated by building the `/cron add` line it stands for and parsing it with the same
|
|
21
|
+
parser. The one step no template can do — describing this project's tracker — is handed to the
|
|
22
|
+
session with the prompt in `recipes/_tracker-setup.md`, the way `/inbox claim` hands over a
|
|
23
|
+
finding, written to `docs/agents/issue-tracker.md` in the layout Matt Pocock's engineering
|
|
24
|
+
skills use and excluded from the repository like the playbooks — and the wizard resumes on its
|
|
25
|
+
own once that turn ends with the file in place. `pi-loops recipe list|show|add` in a shell does the deterministic part and stops
|
|
26
|
+
before the setup script and the jobs. `docs/recipes.md`; vocabulary in `CONTEXT.md`, decisions in
|
|
27
|
+
`docs/design.md` §15–18.
|
|
28
|
+
- **Two recipes.** `issue-loop`: the tracker as a state machine (Matt Pocock's five triage states
|
|
29
|
+
plus `agent-working`, `in-review`, `agent-blocked`) that two loops turn, a triage loop that
|
|
30
|
+
reproduces, checks `.out-of-scope/` and writes agent briefs, and an implement loop that claims
|
|
31
|
+
one issue per run, builds it in a worktree and opens the pull request; a person promotes and
|
|
32
|
+
merges. `autoresearch`: one experiment per run against a `RESEARCH.md` contract you wrote, a
|
|
33
|
+
`results.tsv` ledger where retired ideas stay as negative evidence, a worktree per experiment,
|
|
34
|
+
and promotion only when the `--verify` checker has re-run the held-out command itself; with a
|
|
35
|
+
pure-Python exact k-NN example whose baseline is a speedup of 1.0. `changelog-draft` is packaged
|
|
36
|
+
as the release-side half of the issue loop.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
- **The browser front end reported a slash command as timed out while it waited in a dialog.** A
|
|
40
|
+
`/…` prompt is answered by pi when the command has finished, and a command that shows a setup
|
|
41
|
+
script and asks for a yes finishes when the person answers; sixty seconds later the feed said
|
|
42
|
+
`timed out after 60000ms` and the install went on to succeed. A slash command now gets fifteen
|
|
43
|
+
minutes; everything else keeps sixty seconds.
|
|
44
|
+
|
|
6
45
|
## [0.17.6] - 2026-09-14
|
|
7
46
|
|
|
8
47
|
### Added
|
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ the first sign of credentials that do not work should not be an empty inbox tomo
|
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
pi install npm:@alphacoder-v0/pi-loops # from npm, following new releases
|
|
41
|
-
pi install git:github.com/alphacoder-v0/pi-loops@v0.
|
|
41
|
+
pi install git:github.com/alphacoder-v0/pi-loops@v0.18.0 # or from GitHub, at a pinned tag
|
|
42
42
|
pi install /path/to/pi-loops # or a local checkout — `pi install .` in this repo
|
|
43
43
|
pi -e /path/to/pi-loops # or none of them: try it for one run, installing nothing
|
|
44
44
|
```
|
|
@@ -138,6 +138,11 @@ A job records its directory and model at creation, so it is not tied to the wind
|
|
|
138
138
|
`--cwd` runs it in another checkout (absolute, or relative to this project — no shell, so nothing
|
|
139
139
|
expands `~`), and `--model` pins it whatever this session is on (`/cron set <ref> --model -` unpins).
|
|
140
140
|
|
|
141
|
+
And two you do not write at all: `/recipe add issue-loop` runs the issue tracker as a state machine
|
|
142
|
+
that two loops turn, `/recipe add autoresearch` runs one experiment per run against a contract you
|
|
143
|
+
wrote — each a directory of playbooks copied into the project, installed with one question and one
|
|
144
|
+
confirmation ([docs/recipes.md](docs/recipes.md)).
|
|
145
|
+
|
|
141
146
|
Two that are not loops:
|
|
142
147
|
|
|
143
148
|
```text
|
|
@@ -289,6 +294,7 @@ State stays in `~/.pi/agent/loops` until you delete it.
|
|
|
289
294
|
| `/triggers panel [on\|off]` | The same panel, toggled from the trigger side |
|
|
290
295
|
| `/session-export [path]`, `/session-import <path>` | Portable `.pisession` archive: transcript + jobs + rules + loop state |
|
|
291
296
|
| `/session-share [--public]` | Upload a redacted transcript as a GitHub gist via `gh`, after showing you what it contains. (pi has its own `/share`, which sends the raw session elsewhere first — see [docs/session-archive.md](docs/session-archive.md)) |
|
|
297
|
+
| `/recipe [list\|show\|add\|update\|remove <name>]` | Install a packaged way of running this project on loops — the issue tracker as a state machine, or one research experiment per run — with one question and one confirmation ([docs/recipes.md](docs/recipes.md)) |
|
|
292
298
|
| `/pi-loops [install-launcher]` | Version and paths; `install-launcher` puts the `pi-loops` command on your `PATH` |
|
|
293
299
|
|
|
294
300
|
A schedule is a 5-field cron expression, or one of `hourly` / `daily` / `weekly` (also `每天`), or
|
|
@@ -317,6 +323,7 @@ notifications, and lifecycle hooks — each has a page here.
|
|
|
317
323
|
- [docs/mcp.md](docs/mcp.md) — MCP notification sources and tool registration (`mcp.toml`)
|
|
318
324
|
- [docs/hooks.md](docs/hooks.md) — lifecycle hooks (`hooks.toml`), including `run_start` / `run_end` for scheduled runs
|
|
319
325
|
- [docs/goal.md](docs/goal.md) — `/goal`: holding a session to a stop condition
|
|
326
|
+
- [docs/recipes.md](docs/recipes.md) — `/recipe`: a project run on loops, installed in one command; the issue loop and autoresearch, and how to write your own
|
|
320
327
|
- [docs/session-archive.md](docs/session-archive.md) — `/session-export`, `/session-import`
|
|
321
328
|
- [docs/cli.md](docs/cli.md) — the `pi-loops` command line: export, import, and looking in on the host
|
|
322
329
|
- [docs/web-ui-parity.md](docs/web-ui-parity.md) — what the browser front end owes you, line by line
|
package/README.zh-CN.md
CHANGED
|
@@ -45,7 +45,7 @@ pi-loops 自己没有任何运行时依赖。
|
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
pi install npm:@alphacoder-v0/pi-loops # 从 npm 装,跟着新版本走
|
|
48
|
-
pi install git:github.com/alphacoder-v0/pi-loops@v0.
|
|
48
|
+
pi install git:github.com/alphacoder-v0/pi-loops@v0.18.0 # 或者从 GitHub 装,钉住一个 tag
|
|
49
49
|
pi install /path/to/pi-loops # 或者本地检出;本仓库里就是 pi install .
|
|
50
50
|
```
|
|
51
51
|
|
|
@@ -215,6 +215,19 @@ pi update --extensions # 对齐已安装的包
|
|
|
215
215
|
|
|
216
216
|
任务在创建时就记下自己的目录和模型,所以它不绑在敲出它的那个窗口上。`--cwd` 让它在另一个检出里跑——绝对路径,或相对当前项目;这里没有 shell,`~` 不会展开。`--model` 把模型钉死,`/cron set <ref> --model -` 解钉。
|
|
217
217
|
|
|
218
|
+
### 不用自己写的:recipe
|
|
219
|
+
|
|
220
|
+
```text
|
|
221
|
+
/recipe 有哪些打包好的 recipe,这个项目装了哪些
|
|
222
|
+
/recipe add issue-loop 把 issue tracker 跑成状态机:分诊成 agent brief、在 worktree 里实现、开 PR;推进和合并留给人
|
|
223
|
+
/recipe add autoresearch 按你写的研究合同每次跑一个实验,账本记下每次尝试,只凭 held-out 数据提议晋升
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
一个 recipe 是一组 loop 加上它们各自每次 run 都会读的 playbook。安装只问一个问题(自治级别
|
|
227
|
+
`report` / `propose` / `act`)、确认一次(每个要写的文件、setup 脚本全文、每一行 `/cron add`),
|
|
228
|
+
playbook 拷到 `.agents/skills/<name>/`,通过 `.git/info/exclude` 排除在仓库之外——你随时可以改它,
|
|
229
|
+
下一次 run 就照改后的做。见 [docs/recipes.md](docs/recipes.md)。
|
|
230
|
+
|
|
218
231
|
## 用法
|
|
219
232
|
|
|
220
233
|
会话里的命令分几摊:`/cron` 管任务,`/inbox` 管分诊,`/goal` 管「做到什么算完」,`/triggers` 管不看钟的那些规则,`/session-share` 把这次会话脱敏后发出去。
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Issue tracker: GitHub
|
|
2
|
+
|
|
3
|
+
Work items for this repository live as GitHub Issues in `alphacoder-v0/pi-loops`; pull requests
|
|
4
|
+
are the review surface. Use the `gh` CLI for every operation; it infers the repository from the
|
|
5
|
+
remote when run in a clone. Loops shell out to `gh`, so the account must be authenticated in the
|
|
6
|
+
environment a loop runs in — `gh auth status` answers that.
|
|
7
|
+
|
|
8
|
+
## Operations
|
|
9
|
+
|
|
10
|
+
- **List**: `gh issue list --state open --limit 200 --json number,title,labels,updatedAt,author` (add `--label <state>` to filter by state)
|
|
11
|
+
- **Read**: `gh issue view <n> --comments --json number,title,body,labels,author,createdAt,comments`
|
|
12
|
+
- **Comment**: `gh issue comment <n> --body "..."` (a heredoc for multi-line bodies)
|
|
13
|
+
- **Change state**: `gh issue edit <n> --add-label "<new state>" --remove-label "<old state>"` — exactly one state label at a time
|
|
14
|
+
- **Claim**: `gh issue edit <n> --add-label agent-working --remove-label ready-for-agent --add-assignee @me`
|
|
15
|
+
- **Close**: `gh issue close <n> --comment "..."`
|
|
16
|
+
- **Pull requests**: `gh pr create`, `gh pr list --state open --json number,url,headRefName,reviewDecision,comments,updatedAt`, `gh pr view <n> --comments`, `gh pr diff <n>`
|
|
17
|
+
|
|
18
|
+
## State vocabulary
|
|
19
|
+
|
|
20
|
+
One category label (`bug` | `enhancement`) and exactly one state label per open issue. The state
|
|
21
|
+
labels are `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `agent-working`,
|
|
22
|
+
`in-review`, `agent-blocked`, `wontfix`. They already exist in this repository; `labels.sh`
|
|
23
|
+
refreshes their colour and description and touches no issue. A playbook that moves an issue names
|
|
24
|
+
the label it moves to.
|
|
25
|
+
|
|
26
|
+
## Blocking
|
|
27
|
+
|
|
28
|
+
A `Blocked by: #<n>, #<m>` line near the top of an issue body (or the tracker's native
|
|
29
|
+
dependency) gates it: the item is unblocked when every listed issue is closed.
|
|
30
|
+
|
|
31
|
+
## Who counts as the agent
|
|
32
|
+
|
|
33
|
+
Comments and assignments made by loops are made as the account `gh` is signed in as — currently
|
|
34
|
+
`alphacoder-v0`. Every comment a loop posts starts with a line saying it was generated by AI.
|
package/docs/cli.md
CHANGED
|
@@ -260,3 +260,19 @@ accepted). `host stop` ends the host; the next pi to open would have taken the c
|
|
|
260
260
|
|
|
261
261
|
The channel is a unix socket at `host.sock` in the loops directory, created 0600, and it is
|
|
262
262
|
read-mostly on purpose: a host you could prompt would be a second chat.
|
|
263
|
+
|
|
264
|
+
## recipe
|
|
265
|
+
|
|
266
|
+
```sh
|
|
267
|
+
pi-loops recipe list # the packaged recipes, and which are installed in this directory
|
|
268
|
+
pi-loops recipe show issue-loop # its files, jobs, levels, setup script
|
|
269
|
+
pi-loops recipe add issue-loop [--cwd <dir>] [--level report|propose|act] [--overwrite]
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`add` is the deterministic half of `/recipe add` ([recipes.md](recipes.md)): it copies the
|
|
273
|
+
playbooks to `.agents/skills/<name>/`, lists that directory in `.git/info/exclude` and writes the
|
|
274
|
+
record — and stops. The setup script and the jobs need a pi open in the project: `/recipe add
|
|
275
|
+
<name>` there finds the copies in place, shows the script and the `/cron add` lines, and creates
|
|
276
|
+
them after you say yes. Without `--level` the lowest level the recipe supports is written; an edited
|
|
277
|
+
copy is kept unless `--overwrite` says otherwise.
|
|
278
|
+
|
package/docs/design.md
CHANGED
|
@@ -117,6 +117,49 @@ machine. Everything here follows from that, and each one has a price.
|
|
|
117
117
|
failed — the slot is still owed and the failure streak does not advance. Diagnostics go to
|
|
118
118
|
`logs/pi-<pid>.log` rather than only to a chat notification that a new session erases.
|
|
119
119
|
|
|
120
|
+
15. **Recipes are files, not code.** A recipe (`CONTEXT.md` has the vocabulary) is a directory:
|
|
121
|
+
a `recipe.toml` manifest whose `[[job]]` fields are the arguments of `/cron add` and nothing
|
|
122
|
+
else, one playbook per job, an optional setup script. Anything the wizard does with one is
|
|
123
|
+
something a person could have done by hand with `/cron add` and `cp`. The first catalogue is
|
|
124
|
+
seven: issue-loop, daily-digest, changelog-draft, pr-watch, ci-sweeper, autoresearch, and
|
|
125
|
+
ecosystem — the last capped at `propose`, because every outward word it drafts is a finding a
|
|
126
|
+
person claims before it is said.
|
|
127
|
+
|
|
128
|
+
The cost: a project cannot add a recipe by writing TypeScript, only by writing a directory,
|
|
129
|
+
and the wizard can only ask what a manifest can declare.
|
|
130
|
+
|
|
131
|
+
16. **Playbooks are copied into the project and kept out of its history.** `/recipe add` copies
|
|
132
|
+
them to `<project>/.agents/skills/<recipe>/` — where pi also discovers them as `/skill:`
|
|
133
|
+
commands, so a person can run one step by hand — and lists the directory in
|
|
134
|
+
`.git/info/exclude`, so the repository is not touched. A loop's prompt is a pointer to that
|
|
135
|
+
file; the procedure is read fresh on every run. The tracker description the playbooks read
|
|
136
|
+
(`docs/agents/issue-tracker.md`, in the layout Matt Pocock's engineering skills use, so a
|
|
137
|
+
repository that has those reads the same file) is excluded the same way: it names an account
|
|
138
|
+
and a workflow, which are the project's to keep and not the repository's to publish.
|
|
139
|
+
|
|
140
|
+
The cost: two clones of one project each install the recipe, and a playbook edited on one
|
|
141
|
+
machine is not on the other. Upgrading pi-loops upgrades the packaged recipes, not the copies:
|
|
142
|
+
`/recipe update` is a three-way merge against the untouched copy kept at install (under
|
|
143
|
+
`.orig/` beside the playbooks), silent when the person changed nothing, and conflicts are handed to the
|
|
144
|
+
session as a prompt to resolve with the person rather than left as markers in a file the next
|
|
145
|
+
run will read.
|
|
146
|
+
|
|
147
|
+
17. **The wizard is deterministic; one step is not.** Choosing a recipe, its autonomy level, the
|
|
148
|
+
copy and the `/cron add` lines run with no model and end in a confirmation that shows exactly
|
|
149
|
+
what will be created. The one thing a template cannot do — describe *this* project's tracker —
|
|
150
|
+
is handed to the running session with `sendUserMessage`, the way `/inbox claim` hands over a
|
|
151
|
+
finding: explore the remote, propose, confirm, write the file — and when that turn settles with
|
|
152
|
+
the file there, the wizard resumes by itself, so the command is typed once. `pi-loops recipe`
|
|
153
|
+
in the terminal does the deterministic part only.
|
|
154
|
+
|
|
155
|
+
18. **One autonomy dial, three positions, in prose.** `report` reads and files findings; `propose`
|
|
156
|
+
may also write to the tracker and open draft pull requests but never reach a terminal state;
|
|
157
|
+
`act` may. A manifest declares which positions a recipe supports, the wizard defaults to the
|
|
158
|
+
lowest, and the chosen one is a line at the top of each playbook — text the model reads and a
|
|
159
|
+
person edits, enforced by nothing in code. The cost is exactly that: the level is an instruction,
|
|
160
|
+
not a permission, and the permissions that exist (the danger policy, the daily budget, branch
|
|
161
|
+
protection on the remote) are the ones that hold.
|
|
162
|
+
|
|
120
163
|
## Where the browser front end came from
|
|
121
164
|
|
|
122
165
|
pi owns the `pi` command and its terminal, so a second front end cannot replace the first one. It
|
package/docs/recipes.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Recipes: a project run on loops, installed in one command
|
|
2
|
+
|
|
3
|
+
A **recipe** is a packaged way of running a project on loops: one or more jobs, the **playbook**
|
|
4
|
+
each of them reads on every run, a **manifest** that says what to create, and sometimes a setup
|
|
5
|
+
script. `/recipe add <name>` installs one into the project you have open; what you get is exactly
|
|
6
|
+
what you could have made by hand with `cp` and `/cron add`, which is the point — a recipe cannot do
|
|
7
|
+
anything a person could not have typed.
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
/recipe what is packaged, and what is installed here
|
|
11
|
+
/recipe show issue-loop the files, the jobs, the levels, the setup script
|
|
12
|
+
/recipe add issue-loop install it: a question, a confirmation, done
|
|
13
|
+
/recipe update issue-loop merge a newer pi-loops' playbooks into your copies
|
|
14
|
+
/recipe remove issue-loop its jobs go; the files stay unless you say --purge
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Two recipes ship in this version, and the shape is meant to be copied:
|
|
18
|
+
|
|
19
|
+
| recipe | jobs | what it runs | levels |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| [issue-loop](../recipes/issue-loop/) | `issue-triage` every 30 min, `issue-implement` every 30 min offset | the issue tracker as a state machine: triage into agent briefs, build accepted issues in a worktree, open pull requests | `propose`, `act` |
|
|
22
|
+
| [autoresearch](../recipes/autoresearch/) | `autoresearch` every hour, with `--verify` | one experiment per run against a contract you wrote, a ledger of every attempt, promotion only on held-out evidence | `propose`, `act` |
|
|
23
|
+
|
|
24
|
+
`changelog-draft` (a nightly changelog entry and version proposal) is packaged with its playbook
|
|
25
|
+
and manifest but is still the release-side half of the issue loop; it and four more — a daily
|
|
26
|
+
digest, a pull-request watch, a CI sweeper, an ecosystem scan — are the next batch.
|
|
27
|
+
|
|
28
|
+
## What `/recipe add` does, in order
|
|
29
|
+
|
|
30
|
+
1. **Tracker first, if the recipe needs one.** issue-loop reads `docs/agents/issue-tracker.md` on
|
|
31
|
+
every run to learn where the project's work items live — GitHub Issues, or one Markdown file
|
|
32
|
+
per item under `.scratch/issues/` — and how to list, comment, label and close them. If the file
|
|
33
|
+
is missing, the wizard hands that one step to the agent in your chat (the way `/inbox claim`
|
|
34
|
+
hands over a finding): it looks at the remote, proposes, writes the file after you agree — and
|
|
35
|
+
the moment that turn ends with the file in place, the wizard resumes on its own with the
|
|
36
|
+
question below. Everything else is done without a model. The file's layout
|
|
37
|
+
is the one Matt Pocock's engineering skills use, so a repository that has `/triage` reads the
|
|
38
|
+
same description. Like the playbooks it is kept out of the repository through
|
|
39
|
+
`.git/info/exclude`: it names an account and a workflow, which are the project's to keep and
|
|
40
|
+
not the repository's to publish. Another clone is asked the same questions once.
|
|
41
|
+
2. **The autonomy level.** One question, defaulting to the lowest the recipe supports (below).
|
|
42
|
+
`--level act` skips it.
|
|
43
|
+
3. **A name check.** A job with the same name already in `jobs.json` stops the install and says
|
|
44
|
+
which recipe or `/cron add` it came from.
|
|
45
|
+
4. **The confirmation.** Every file that will be written and where, every `/cron add` line that
|
|
46
|
+
will be run, the budget hint. The setup script is printed into the transcript first, whole and
|
|
47
|
+
as written — it will run with this session's environment, and a dialog clips what does not fit,
|
|
48
|
+
so it is not put in one; a script too long to show is not run at all. A recipe installed from a path
|
|
49
|
+
rather than by name is flagged as not shipped with pi-loops, with the playbooks to read first.
|
|
50
|
+
Nothing has happened yet.
|
|
51
|
+
5. **The install.** The playbooks are copied to `.agents/skills/<recipe>/`, with an untouched copy of each
|
|
52
|
+
under `.orig/` and a `.recipe.json` record (version, level, when). The directory (and the
|
|
53
|
+
tracker description) is listed in `.git/info/exclude` — git's own place for a rule that belongs to one clone — so the repository
|
|
54
|
+
is not touched and nothing shows in `git status`. pi discovers the copies as `/skill:` commands,
|
|
55
|
+
which is how a person runs one step by hand when the loop's judgement needs checking — once the
|
|
56
|
+
project is trusted: a directory that gains `.agents/skills/` is one pi asks about at its next
|
|
57
|
+
start (`/trust`). The loops do not depend on that; they read the files by path.
|
|
58
|
+
6. **The setup script**, if any, runs once in the project (issue-loop's creates the tracker's
|
|
59
|
+
labels; it is idempotent). A failure stops before any job is created and prints the output; the
|
|
60
|
+
files stay in place and `/recipe add` again resumes.
|
|
61
|
+
7. **The jobs**, through the same code path as `/cron add`, each carrying `recipe: "<name>"` so
|
|
62
|
+
`/recipe list` and `/recipe remove` can find them. Each prompt is a pointer:
|
|
63
|
+
`Read .agents/skills/issue-loop/triage.md and do what it says for this repository.` The
|
|
64
|
+
procedure is read fresh on every run; edit the file and the next run follows the edit.
|
|
65
|
+
|
|
66
|
+
`pi-loops recipe list|show|add` in a shell does steps 5 and nothing after: the setup script and the
|
|
67
|
+
jobs are things a person should see before they exist, and only the pi inside `/recipe add` can show
|
|
68
|
+
them. It leaves the files in place and says so; `/recipe add` then finds nothing to copy.
|
|
69
|
+
|
|
70
|
+
## The autonomy level
|
|
71
|
+
|
|
72
|
+
One dial with three positions, declared per recipe in its manifest and written as the first line
|
|
73
|
+
of each playbook — `Autonomy: propose` — where the model reads it and a person can change it:
|
|
74
|
+
|
|
75
|
+
| level | may |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `report` | read, and file findings; nothing is written outside the inbox |
|
|
78
|
+
| `propose` | also write to the tracker (comments, non-terminal labels) and open draft pull requests; never reach a terminal state |
|
|
79
|
+
| `act` | also promote, close and merge — the terminal states |
|
|
80
|
+
|
|
81
|
+
It is an instruction, not a permission. What actually holds an unattended run are the things that
|
|
82
|
+
were there before recipes: the [dangerous-command policy](loops.md#when-something-looks-wrong),
|
|
83
|
+
`[limits] daily_budget_usd`, and branch protection on the remote. Set the budget before the first
|
|
84
|
+
night ([loops.md](loops.md#what-it-costs-and-capping-it)); each recipe's `show` says roughly what
|
|
85
|
+
its default schedules cost.
|
|
86
|
+
|
|
87
|
+
## Editing, updating, removing
|
|
88
|
+
|
|
89
|
+
The copies are yours. `/recipe update <name>` after a pi-loops upgrade is a three-way merge of the
|
|
90
|
+
packaged playbook against your copy with the untouched copy in `.orig/` as the base: files you never touched are
|
|
91
|
+
replaced silently, your edits are kept where they do not overlap the upstream change, and a file
|
|
92
|
+
with overlapping edits is **not written** — git's merge with markers goes to `.orig/<file>.merge`,
|
|
93
|
+
and the agent in your chat is handed the four paths (yours, the base, the packaged version, the
|
|
94
|
+
merge) to resolve with you, because conflict markers in a playbook are text the next run would follow.
|
|
95
|
+
A playbook installed by hand, with no untouched copy, is left alone and named.
|
|
96
|
+
|
|
97
|
+
`/recipe remove <name>` removes the recipe's jobs and keeps the files and the loops' notes;
|
|
98
|
+
`--purge` deletes both — of the files, only what the install wrote, since `.agents/skills/` may
|
|
99
|
+
hold the project's own. `/cron` shows recipe jobs like any other, and `/cron set` edits them like
|
|
100
|
+
any other — a recipe is how they were made, not what they are.
|
|
101
|
+
|
|
102
|
+
## Writing a recipe
|
|
103
|
+
|
|
104
|
+
A directory with a `recipe.toml`; `/recipe add ./path/to/it` installs from a directory as readily
|
|
105
|
+
as from the packaged set (no git URLs: a playbook is an instruction a model will follow unattended,
|
|
106
|
+
and should be read before it is installed).
|
|
107
|
+
|
|
108
|
+
```toml
|
|
109
|
+
name = "issue-loop" # lowercase, digits, dashes; also the install directory
|
|
110
|
+
summary = "one line"
|
|
111
|
+
needs_tracker = true # gate on docs/agents/issue-tracker.md
|
|
112
|
+
levels = ["propose", "act"] # which positions of the dial the playbooks understand
|
|
113
|
+
setup = "labels.sh" # optional; shown, then run once, before the jobs exist
|
|
114
|
+
files = ["RESEARCH.template.md"] # optional; copied beside the playbooks unchanged
|
|
115
|
+
budget_hint_usd = 10 # optional; only a hint in `show` and the confirmation
|
|
116
|
+
|
|
117
|
+
[[job]]
|
|
118
|
+
name = "issue-triage" # the /cron add --name
|
|
119
|
+
schedule = "*/30 * * * *" # anything /cron add takes, except in/at (a recipe job recurs)
|
|
120
|
+
playbook = "triage.md" # the file this job's runs read
|
|
121
|
+
timeout = "45m" # optional: verify, timeout, thinking, tools, prompt
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Each `[[job]]` is checked by building the `/cron add` line it stands for and parsing it with the
|
|
125
|
+
same parser: a bad schedule, a `--timeout` that is not a duration, an expression that never
|
|
126
|
+
matches, is refused when the manifest is read, not on the first run. A playbook is Markdown with
|
|
127
|
+
pi's skill frontmatter (`name`, `description`) and an `Autonomy:` line the wizard will set; the
|
|
128
|
+
rest is what a run should do, written for a sub-agent that has only its notes, the files, and the
|
|
129
|
+
tools. The two packaged recipes are the reference for the voice.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## issue-loop
|
|
134
|
+
|
|
135
|
+
The tracker becomes a state machine that two loops turn, with the two decisions that need a person
|
|
136
|
+
— *is this worth building?* and *is this worth merging?* — left in the inbox with everything
|
|
137
|
+
prepared. The state machine is Matt Pocock's `triage` skill's (five states, one category, a brief
|
|
138
|
+
that outlives the codebase it describes) plus three states for the implement side. Every open issue
|
|
139
|
+
carries one category label (`bug` | `enhancement`) and **exactly one** state label:
|
|
140
|
+
|
|
141
|
+
```mermaid
|
|
142
|
+
stateDiagram-v2
|
|
143
|
+
[*] --> needs_triage: triage loop, first sighting
|
|
144
|
+
needs_triage --> needs_info: triage loop asks
|
|
145
|
+
needs_info --> needs_triage: reporter replies
|
|
146
|
+
needs_triage --> ready_for_agent: maintainer, after reading the brief (act: the loop, for a reproduced bug)
|
|
147
|
+
needs_triage --> ready_for_human: maintainer
|
|
148
|
+
needs_triage --> wontfix: maintainer (act: the loop, for a duplicate or an already-built request)
|
|
149
|
+
ready_for_agent --> agent_working: implement loop claims
|
|
150
|
+
agent_working --> in_review: implement loop opens the PR
|
|
151
|
+
agent_working --> agent_blocked: implement loop cannot finish
|
|
152
|
+
agent_blocked --> ready_for_agent: maintainer answers
|
|
153
|
+
in_review --> agent_working: reviewer requests changes
|
|
154
|
+
in_review --> [*]: maintainer merges (Closes #n)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
| state | meaning | leaves it |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| *(none)* | never looked at | the triage loop labels it `needs-triage` |
|
|
160
|
+
| `needs-triage` | being evaluated; a brief or questions get posted here | the triage loop (→ `needs-info`) or the maintainer (→ the three below) |
|
|
161
|
+
| `needs-info` | waiting on the reporter | the triage loop, once the reporter has replied |
|
|
162
|
+
| `ready-for-agent` | the brief is accepted; an agent may build it | the implement loop claims it |
|
|
163
|
+
| `ready-for-human` | judgement, access, design, manual testing | a person |
|
|
164
|
+
| `agent-working` | claimed: a worktree and a branch exist | the implement loop (→ `in-review` or `agent-blocked`) |
|
|
165
|
+
| `in-review` | a pull request is open | the maintainer merges, or a reviewer requests changes |
|
|
166
|
+
| `agent-blocked` | the loop stopped; its last comment says what it needs | the maintainer answers and moves it back |
|
|
167
|
+
| `wontfix` | closed; the reason is on the issue, and for a rejected enhancement in `.out-of-scope/` | — |
|
|
168
|
+
|
|
169
|
+
Four rules make it run unattended:
|
|
170
|
+
|
|
171
|
+
- **The tracker is the truth; a loop's notes are a cache.** Every run reads labels and comments
|
|
172
|
+
fresh. Notes hold only what the tracker cannot say — the comment timestamp a run last handled,
|
|
173
|
+
the worktree a run was cut off in. A person can move any issue at any time, from the web, and
|
|
174
|
+
the next run sees the new state; two machines sharing a `$HOME` see the same thing.
|
|
175
|
+
- **The claim is the first write.** `agent-working` plus an assignee; a run that finds the label
|
|
176
|
+
already gone picks the next issue. Nothing is held in memory across runs. It is a soft lock —
|
|
177
|
+
the tracker has no compare-and-swap — and at thirty-minute cadence that has been enough.
|
|
178
|
+
- **The brief is the contract.** An *Agent Brief* comment describes behaviour, interfaces and
|
|
179
|
+
acceptance criteria, never file paths or line numbers, so it is still right after the weeks it
|
|
180
|
+
may wait. The implement loop builds from the latest brief; when the brief and the code disagree
|
|
181
|
+
in a way the brief did not foresee, that is `agent-blocked`, not a guess.
|
|
182
|
+
- **Every AI comment says so** on its first line.
|
|
183
|
+
|
|
184
|
+
The two checkpoints are pushed as far right as they go. `#14 brief posted — recommend
|
|
185
|
+
ready-for-agent (bug, reproduced by npm test)` arrives after the loop has reproduced the bug,
|
|
186
|
+
checked `.out-of-scope/` and the open issues for a prior answer, and written the brief; your
|
|
187
|
+
click on the label is the whole approval (`act` makes that click for reproduced bugs). `#12 PR
|
|
188
|
+
opened — <url> (3 commits, checks green)` arrives after the build, the project's check command and
|
|
189
|
+
a test plan; requesting changes sends it back to the loop, which addresses each comment and
|
|
190
|
+
re-requests review. Merging stays with a person at every level.
|
|
191
|
+
|
|
192
|
+
What a run looks like when it goes wrong is in the playbooks themselves: a run cut off
|
|
193
|
+
mid-implementation resumes from its branch and notes; a check command failing twice on one issue
|
|
194
|
+
is a block, not a third attempt; the loop and you editing the same issue is settled by the
|
|
195
|
+
tracker, which wins.
|
|
196
|
+
|
|
197
|
+
Specific to this repository: the labels are on
|
|
198
|
+
[github.com/alphacoder-v0/pi-loops](https://github.com/alphacoder-v0/pi-loops/labels), the check
|
|
199
|
+
command is `npm run ci`, and a release needs a one-time password — so the release side can only
|
|
200
|
+
propose, which is what `changelog-draft` does everywhere.
|
|
201
|
+
|
|
202
|
+
## autoresearch
|
|
203
|
+
|
|
204
|
+
The shape Karpathy's autoresearch and Arbor made familiar, without a kernel: a **research
|
|
205
|
+
contract** a person writes, a **ledger** of every attempt including the failed ones, one isolated
|
|
206
|
+
worktree per experiment, and a rule that the held-out number decides — never the dev number a run
|
|
207
|
+
was tuning against.
|
|
208
|
+
|
|
209
|
+
- **`RESEARCH.md`** at the project root is the contract: objective, metric and direction, the dev
|
|
210
|
+
and held-out commands (each prints `metric=<number>`), which files may change, which are
|
|
211
|
+
protected, the promotion rule, the time budget. The loop never writes it; a run that finds it
|
|
212
|
+
missing files one finding and stops, and a run that finds a protected file's hash changed does
|
|
213
|
+
the same. `RESEARCH.template.md` is installed beside the playbook; `example/` is a filled-in one
|
|
214
|
+
with a naive exact k-NN in pure Python whose baseline speedup is 1.0.
|
|
215
|
+
- **`results.tsv`** (the path the contract names) is the ledger: one row per experiment with its
|
|
216
|
+
branch, hypothesis, dev and held-out numbers and a status — `baseline`, `running`, `retired`,
|
|
217
|
+
`kept`, `promoted`. A retired row is negative evidence the next run reads before choosing; the
|
|
218
|
+
loop writes the file and never commits it.
|
|
219
|
+
- **One run, one experiment.** Choose a hypothesis the ledger has not retired, write its row as
|
|
220
|
+
`running`, branch in a worktree, change only the editable files, commit, measure on dev. Not
|
|
221
|
+
better: `retired`, worktree removed, branch deleted, no finding — a retired experiment is the
|
|
222
|
+
normal outcome and the row is what matters. Better on dev: measure on held-out; a dev-only gain
|
|
223
|
+
is `retired` too, with that note.
|
|
224
|
+
- **Promotion** is the checkpoint. Under `propose` the finding names the branch and both numbers
|
|
225
|
+
and a person merges; under `act` the loop merges into the checkout's current branch and the
|
|
226
|
+
finding says so. The job runs with `--verify`, and the playbook's *For the checker* section tells
|
|
227
|
+
the checker what verifying means here: check out the branch, run the held-out command yourself,
|
|
228
|
+
keep the finding only if your number satisfies the rule.
|
|
229
|
+
|
|
230
|
+
Try it on the example before your own problem:
|
|
231
|
+
|
|
232
|
+
```sh
|
|
233
|
+
cp -r .agents/skills/autoresearch/example /tmp/knn && cd /tmp/knn && git init -q && git add -A && git commit -qm baseline
|
|
234
|
+
pi # /recipe add autoresearch, then /cron run autoresearch
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The first run measures the baseline and creates the ledger; each later one tries one idea. With
|
|
238
|
+
the example's five-percent rule and a four-second evaluation, a promotion arrives within a few
|
|
239
|
+
runs — and so do the retired ideas, in the ledger, which is what makes the runs after that better.
|
package/docs/web-ui-parity.md
CHANGED
|
@@ -173,6 +173,8 @@ weaker, and worth converting whenever one of them breaks.
|
|
|
173
173
|
be read as prose and waved through. `test/web-page.test.ts`: *a confirmation shows what is
|
|
174
174
|
about to run*.
|
|
175
175
|
- [x] Enter does not approve: the focus starts on cancel.
|
|
176
|
+
- [x] A slash command that waits in a dialog is not reported as timed out while the person reads:
|
|
177
|
+
the browser waits up to fifteen minutes for a `/…` prompt, sixty seconds for anything else.
|
|
176
178
|
- [x] Clicking away from any dialog closes it. `test/web-page.test.ts`: *clicking outside a dialog
|
|
177
179
|
closes it*.
|
|
178
180
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alphacoder-v0/pi-loops",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "An automation layer for pi: cron + stateful loops with a triage inbox, maker/checker verification, dynamic triggers, MCP notifications and tools, lifecycle hooks, session archives. A non-invasive pi extension.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"skills",
|
|
33
33
|
"docs",
|
|
34
34
|
"examples",
|
|
35
|
+
"recipes",
|
|
35
36
|
"README.md",
|
|
36
37
|
"README.zh-CN.md",
|
|
37
38
|
"CHANGELOG.md",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Issue tracker: GitHub
|
|
2
|
+
|
|
3
|
+
Work items for this repository live as GitHub Issues; pull requests are the review surface. Use
|
|
4
|
+
the `gh` CLI for every operation; it infers the repository from the remote when run in a clone.
|
|
5
|
+
|
|
6
|
+
## Operations
|
|
7
|
+
|
|
8
|
+
- **List**: `gh issue list --state open --limit 200 --json number,title,labels,updatedAt,author` (add `--label <state>` to filter by state)
|
|
9
|
+
- **Read**: `gh issue view <n> --comments --json number,title,body,labels,author,createdAt,comments`
|
|
10
|
+
- **Comment**: `gh issue comment <n> --body "..."` (a heredoc for multi-line bodies)
|
|
11
|
+
- **Change state**: `gh issue edit <n> --add-label "<new state>" --remove-label "<old state>"` — exactly one state label at a time
|
|
12
|
+
- **Claim**: `gh issue edit <n> --add-label agent-working --remove-label ready-for-agent --add-assignee @me`
|
|
13
|
+
- **Close**: `gh issue close <n> --comment "..."`
|
|
14
|
+
- **Pull requests**: `gh pr create`, `gh pr list --state open --json number,url,headRefName,reviewDecision,comments,updatedAt`, `gh pr view <n> --comments`, `gh pr diff <n>`
|
|
15
|
+
|
|
16
|
+
## State vocabulary
|
|
17
|
+
|
|
18
|
+
One category label (`bug` | `enhancement`) and exactly one state label per open issue. The state
|
|
19
|
+
labels are `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `agent-working`,
|
|
20
|
+
`in-review`, `agent-blocked`, `wontfix`. The recipe's setup script creates them; a playbook that
|
|
21
|
+
moves an issue names the label it moves to.
|
|
22
|
+
|
|
23
|
+
## Blocking
|
|
24
|
+
|
|
25
|
+
A `Blocked by: #<n>, #<m>` line near the top of an issue body (or the tracker's native
|
|
26
|
+
dependency) gates it: the item is unblocked when every listed issue is closed.
|
|
27
|
+
|
|
28
|
+
## Who counts as the agent
|
|
29
|
+
|
|
30
|
+
Comments and assignments made by loops are made as the account `gh` is signed in as. Every comment
|
|
31
|
+
a loop posts starts with a line saying it was generated by AI.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Issue tracker: local Markdown
|
|
2
|
+
|
|
3
|
+
Work items for this repository live as Markdown files in `.scratch/issues/`, one file per item,
|
|
4
|
+
committed with the code. There are no pull requests: a change is a branch, and the review
|
|
5
|
+
checkpoint is a finding in the inbox that names the branch.
|
|
6
|
+
|
|
7
|
+
## Layout
|
|
8
|
+
|
|
9
|
+
- `.scratch/issues/<NN>-<slug>.md`, numbered from `01`; the number is the item's id (`#07`)
|
|
10
|
+
- The first lines of a file:
|
|
11
|
+
|
|
12
|
+
```markdown
|
|
13
|
+
# 07: <title>
|
|
14
|
+
|
|
15
|
+
**Category:** bug | enhancement
|
|
16
|
+
**Status:** needs-triage
|
|
17
|
+
**Blocked by:** 03, 05 (or "none")
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- Discussion appends to the bottom under `## Comments`, one `### <date> — <who>` heading per
|
|
21
|
+
comment; a comment by a loop starts with a line saying it was generated by AI
|
|
22
|
+
- An *Agent Brief* is a `## Agent Brief` section in the file, not a comment
|
|
23
|
+
|
|
24
|
+
## Operations
|
|
25
|
+
|
|
26
|
+
- **List**: read every file in `.scratch/issues/`; the `**Status:**` line is the state
|
|
27
|
+
- **Read**: read the file
|
|
28
|
+
- **Comment**: append under `## Comments`
|
|
29
|
+
- **Change state**: edit the `**Status:**` line — exactly one state
|
|
30
|
+
- **Claim**: set `**Status:** agent-working` and add `**Assignee:** <who>`, and commit that edit on the work branch before any other work
|
|
31
|
+
- **Close**: set the status to `wontfix` or `done` and move the file to `.scratch/issues/closed/`
|
|
32
|
+
- **Review**: push the branch (or leave it local) and file a finding that names the branch and the item; a person merges with git
|
|
33
|
+
|
|
34
|
+
## State vocabulary
|
|
35
|
+
|
|
36
|
+
`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `agent-working`, `in-review`,
|
|
37
|
+
`agent-blocked`, `wontfix`, plus `done` for a merged item. A playbook that moves an item names the
|
|
38
|
+
state it moves to.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
`/recipe add {recipe}` stopped before installing anything: that recipe's playbooks read `docs/agents/issue-tracker.md` on every run to learn where this project's work items live and how to list, read, comment on, label and close them — and `{project}` has no such file yet. Write it with me now. This is a conversation, not a template fill: explore first, propose, and write only after I have agreed.
|
|
2
|
+
|
|
3
|
+
1. **Explore.** Run `git remote -v` in `{project}`. Look for an existing `.scratch/` directory (a sign the local Markdown tracker is already in use), and for an `## Agent skills` section in `AGENTS.md` or `CLAUDE.md` (a sign Matt Pocock's engineering skills were set up here; if so, their `docs/agents/issue-tracker.md` convention is the one we are writing, and it may already be partly there).
|
|
4
|
+
|
|
5
|
+
2. **Propose, one question.** Lead with the recommendation so I can accept it in a word:
|
|
6
|
+
- a GitHub remote → recommend **GitHub Issues** (the `gh` CLI; check `gh auth status` works);
|
|
7
|
+
- no remote, or I say so → recommend **local Markdown**: one file per item under `.scratch/issues/`, a `**Status:**` line as the state.
|
|
8
|
+
Anything else (GitLab, Jira, Linear): ask me to describe the workflow in a paragraph and record it as prose.
|
|
9
|
+
|
|
10
|
+
3. **Write `docs/agents/issue-tracker.md`** from the matching template in `{templates}/` (`issue-tracker-github.md` or `issue-tracker-local.md`), adjusted to what we agreed. Show me the draft before writing. Keep the state vocabulary section as it is: the playbooks name those states. The file stays out of the repository (the wizard lists it in `.git/info/exclude`, like the playbooks), but it is still read by every run: keep it to how the tracker works — no secrets, no tokens.
|
|
11
|
+
|
|
12
|
+
4. **Stop there.** The wizard is waiting for this file: as soon as this turn ends with it in place, `/recipe add {recipe}` resumes on its own — the level question, the setup script, the confirmation. Do not create cron jobs, labels, worktrees or branches yourself, and do not tell me to run anything; the wizard does the rest after showing me exactly what it will do.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# autoresearch — one experiment per run, a ledger, held-out evidence before promotion
|
|
2
|
+
|
|
3
|
+
The shape is the one Karpathy's autoresearch and Arbor made familiar: a **research contract** a
|
|
4
|
+
person writes (objective, metric, which files may change, which are protected, dev and held-out
|
|
5
|
+
commands, a promotion rule), a **ledger** of every attempt including the failed ones, an isolated
|
|
6
|
+
worktree per experiment, and a rule that the held-out number decides — never the dev number a run
|
|
7
|
+
was tuning against. What pi-loops adds is that nothing here needs a kernel: the contract and the
|
|
8
|
+
ledger are files in the repository, each run is one stateful loop run, and the checker of
|
|
9
|
+
`--verify` is the evaluator that re-measures before a promotion reaches you.
|
|
10
|
+
|
|
11
|
+
| file | what it is |
|
|
12
|
+
|---|---|
|
|
13
|
+
| [recipe.toml](recipe.toml) | one job, `every 1h`, `--verify`, 40-minute timeout |
|
|
14
|
+
| [experiment.md](experiment.md) | the playbook: contract → ledger → one hypothesis → worktree → measure → row → maybe promote |
|
|
15
|
+
| [RESEARCH.template.md](RESEARCH.template.md) | copy to the project root as `RESEARCH.md` and fill in; the loop stops until it exists |
|
|
16
|
+
| [example/](example/) | a filled-in contract with a naive exact k-NN in pure Python: `bash eval.sh dev` prints `metric=<speedup>` |
|
|
17
|
+
|
|
18
|
+
Try it on the example first:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
cp -r .agents/skills/autoresearch/example /tmp/knn && cd /tmp/knn && git init -q && git add -A && git commit -qm "baseline"
|
|
22
|
+
pi # then: /recipe add autoresearch and /cron run autoresearch
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The first run measures the baseline and writes `results.tsv`; the next ones each try one idea.
|
|
26
|
+
Under `propose` a promotable branch arrives in `/inbox` with both numbers; under `act` it is
|
|
27
|
+
merged into the checkout and the finding says so.
|