Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 26 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ flowchart TB

A label-driven state machine over issues, with all state living in GitHub
labels (visible, maintainer-overridable):

- Issue opened/reopened → the full pipeline (reproduce → diagnose → verify →
fix) runs in a **Cloudflare Sandbox container** holding a real checkout of
the repository: a hardened blobless clone of the default branch, a
Expand Down Expand Up @@ -160,7 +159,6 @@ The code author persona owns any same-repository pull request assigned to
it. Triage assigns it to every fix pull request it opens. See
[Personas](#personas) for how it is addressed and how it works with the
reviewer persona.

- **Adoption.** Assigning the persona to a pull request posts an ownership
status comment and immediately addresses any outstanding requested changes
and failing checks.
Expand Down Expand Up @@ -242,18 +240,17 @@ Personas are assignable GitHub identities in front of capabilities. You
assign an issue or pull request to a persona the way you would to a teammate,
and the assignment is the signal to act:

| Persona | Signal | Action |
|---|---|---|
| `triage` | Issue assigned to it | Runs the triage pipeline, whatever the current label, then unassigns itself. Reassign it to run triage again. |
| `reviewer` | Review requested from it, or pull request assigned to it | Runs the review capability (a label isn't needed), then withdraws the request or assignment. Re-request it to review again. |
| `author` | Same-repository pull request assigned to it | Takes ownership and addresses requested changes and failing checks until unassigned (see [Code author](#code-author-srcauthor)). |
| Persona | Signal | Action |
| ---------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `triage` | Issue assigned to it | Runs the triage pipeline, whatever the current label, then unassigns itself. Reassign it to run triage again. |
| `reviewer` | Review requested from it, or pull request assigned to it | Runs the review capability (a label isn't needed), then withdraws the request or assignment. Re-request it to review again. |
| `author` | Same-repository pull request assigned to it | Takes ownership and addresses requested changes and failing checks until unassigned (see [Code author](#code-author-srcauthor)). |

### The review loop

The reviewer and author personas play GitHub's own review loop, and every
hop between them is a visible GitHub state change a maintainer can step
into:

1. Triage opens a fix pull request, assigns the author persona, and requests
the reviewer persona.
2. The reviewer reviews. With no findings above the least severe configured
Expand Down Expand Up @@ -294,8 +291,8 @@ persona's account, tune the author, or switch a persona off:
```yaml
personas:
triage:
login: my-triage-bot # defaults to astro-triage
reviewer: false # switch a persona off
login: my-triage-bot # defaults to astro-triage
reviewer: false # switch a persona off
author:
# login: astro-author
# skill: .agents/skills/author # overrides the bundled default skill
Expand Down Expand Up @@ -423,9 +420,9 @@ All three YAML spellings mean the same thing — one command per line, no `&&`
needed to sequence them:

```yaml
buildCommand: pnpm build # a single command
buildCommand: [pnpm install, pnpm build] # a list
buildCommand: | # a block scalar
buildCommand: pnpm build # a single command
buildCommand: [pnpm install, pnpm build] # a list
buildCommand: | # a block scalar
pnpm install
pnpm build
```
Expand Down Expand Up @@ -460,7 +457,6 @@ the fix.
A model is named as `<provider>/<model>`. Factory bundles only the
`cloudflare-ai-gateway` provider, which can route to multiple upstreams while
ensuring every inference request passes through the shared gateway:

- Workers AI model ids include a routing prefix and their own vendor segments,
for example
`cloudflare-ai-gateway/workers-ai/@cf/moonshotai/kimi-k2.7-code`.
Expand All @@ -487,13 +483,13 @@ provider's default. The release-security reviewer also defaults to `high`.
Model settings are configurable and default to gateway-routed Workers AI
models:

| Setting | Used by | Default |
| --- | --- | --- |
| `adversary.blueTeam.model` | independent alternative implementation | `CODE_MODEL` |
| `adversary.purpleTeam.model` | qualification and red/blue comparison | `CODE_MODEL` |
| `review.model` | the pull request reviewer | `CODE_MODEL` |
| `triage.model` | the reproduce/diagnose/fix pipeline | `CODE_MODEL` |
| `triage.verificationModel` | fix verification and retriage decisions | `VERIFICATION_MODEL` |
| Setting | Used by | Default |
| ---------------------------- | --------------------------------------- | -------------------- |
| `adversary.blueTeam.model` | independent alternative implementation | `CODE_MODEL` |
| `adversary.purpleTeam.model` | qualification and red/blue comparison | `CODE_MODEL` |
| `review.model` | the pull request reviewer | `CODE_MODEL` |
| `triage.model` | the reproduce/diagnose/fix pipeline | `CODE_MODEL` |
| `triage.verificationModel` | fix verification and retriage decisions | `VERIFICATION_MODEL` |

The matching `thinkingLevel` fields are available for each model-backed agent:
`adversary.blueTeam`, `adversary.purpleTeam`, `review`, `triage`,
Expand Down Expand Up @@ -522,7 +518,6 @@ pushed branch + `needs triage`.
Publishing has to happen in the target repository's own CI — pkg.pr.new
authenticates with that repository's Actions OIDC identity, which a Worker
cannot present. So the factory:

1. dispatches a maintainer-owned `workflow_dispatch` workflow, and
2. polls for a check run on the pushed fix branch commit to collect the result.

Expand All @@ -533,13 +528,19 @@ creating a check run named `factory/preview-release` on the built commit whose
summary contains a fenced `json` block:

```json
{ "packages": [{ "name": "astro", "url": "https://pkg.pr.new/withastro/astro/astro@abc1234" }] }
{
"packages": [
{
"name": "astro",
"url": "https://pkg.pr.new/withastro/astro/astro@abc1234"
}
]
}
```

Three deliberate design choices:

- **The dispatch targets the default branch**, not the fix branch, so the
workflow *definition* is always maintainer-controlled and an agent can never
workflow _definition_ is always maintainer-controlled and an agent can never
rewrite the CI that runs its own code. The fix branch travels as an input.
The workflow still builds LLM-authored code, which is why the whole
capability is opt-in per repository.
Expand Down
7 changes: 5 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.9/schema.json",
"$schema": "https://biomejs.dev/schemas/2.6.2/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"includes": ["**", "!!**/dist"]
"includes": ["**", "!!**/dist", "!!pnpm-lock.yaml"]
},
"formatter": {
"enabled": true,
Expand All @@ -27,6 +27,9 @@
"quoteStyle": "single"
}
},
"markdown": {
"parser": { "frontmatter": true }
},
"assist": {
"enabled": true,
"actions": {
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
"test": "vitest run --config vitest.config.ts"
},
"dependencies": {
"@biomejs/biome": "2.5.9",
"@biomejs/biome": "2.6.2",
"@cloudflare/codemode": "^0.5.1",
"@cloudflare/sandbox": "0.12.5",
"@earendil-works/pi-ai": "^0.87.1",
"@flue/github": "^2.2.2",
"@flue/runtime": "^2.2.2",
"@earendil-works/pi-ai": "^1.3.0",
"@flue/github": "^2.3.0",
"@flue/runtime": "^2.3.0",
"hono": "4.12.32",
"js-yaml": "^5.2.3",
"just-bash": "^3.2.0",
Expand All @@ -30,8 +30,8 @@
},
"devDependencies": {
"@cloudflare/vite-plugin": "^1.51.1",
"@flue/cli": "^2.2.2",
"@flue/vite": "^2.2.2",
"@flue/cli": "^2.3.0",
"@flue/vite": "^2.3.0",
"@types/node": "^22.10.10",
"typescript": "^7.0.2",
"vite": "^8.2.1",
Expand Down
Loading
Loading