Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
4d495c8
chore(porch): 1273 init aspir
waleedkadous Jul 28, 2026
de81103
[Spec 1273] Initial specification draft
waleedkadous Jul 28, 2026
79b7b4e
chore(porch): 1273 specify build-complete
waleedkadous Jul 28, 2026
d0dea11
[Spec 1273] Specification with multi-agent review
waleedkadous Jul 28, 2026
bfd5fed
chore(porch): 1273 plan phase-transition
waleedkadous Jul 28, 2026
f9ad258
[Spec 1273] Initial implementation plan
waleedkadous Jul 28, 2026
c5ae519
chore(porch): 1273 plan build-complete
waleedkadous Jul 28, 2026
d89a64c
[Spec 1273] Plan with multi-agent review
waleedkadous Jul 28, 2026
1dbc5ba
chore(porch): 1273 implement phase-transition
waleedkadous Jul 28, 2026
5ca14db
[Spec 1273][Phase: interrupt] feat: afx interrupt — ESC into a wedged…
waleedkadous Jul 28, 2026
4cfe9b0
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
f54e80d
chore(porch): 1273 advance plan phase → phase_2
waleedkadous Jul 28, 2026
3ded0a2
[Spec 1273][Phase: lastDataAt] feat: surface lastDataAt on serialised…
waleedkadous Jul 28, 2026
c0626a8
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
a611577
[Spec 1273][Phase: lastDataAt] test: pin lastDataAt on the GET /api/t…
waleedkadous Jul 28, 2026
49de2bc
chore(porch): 1273 implement re-iter (iter 2)
waleedkadous Jul 28, 2026
5c3358e
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
6ae4273
chore(porch): 1273 advance plan phase → phase_3
waleedkadous Jul 28, 2026
09760e8
[Spec 1273][Phase: receipt] feat: R2 receipt gate — nonce, substance,…
waleedkadous Jul 28, 2026
75c8e10
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
81fa78d
[Spec 1273][Phase: receipt] fix: build the state-file path with path.…
waleedkadous Jul 28, 2026
82f161e
chore(porch): 1273 implement re-iter (iter 2)
waleedkadous Jul 28, 2026
cb6df96
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
1c889eb
chore(porch): 1273 advance plan phase → phase_4
waleedkadous Jul 28, 2026
7fe8244
[Spec 1273][Phase: context] feat: resolve protocol, mode and harness …
waleedkadous Jul 28, 2026
92f26f4
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
8a22987
[Spec 1273][Phase: context] fix: complete the context shape, honour c…
waleedkadous Jul 28, 2026
32a524b
chore(porch): 1273 implement re-iter (iter 2)
waleedkadous Jul 28, 2026
f551360
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
449617c
chore(porch): 1273 advance plan phase → phase_5
waleedkadous Jul 28, 2026
52663ba
[Spec 1273][Phase: reorient] feat: R3 re-orientation assembly, comple…
waleedkadous Jul 28, 2026
2e7c0ed
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
9c27678
[Spec 1273][Phase: reorient] fix: conditional frame markers + verbati…
waleedkadous Jul 28, 2026
dedbb5f
chore(porch): 1273 implement re-iter (iter 2)
waleedkadous Jul 28, 2026
bc9fa19
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
c28a354
[Spec 1273][Phase: reorient] fix: forward issue metadata into the spa…
waleedkadous Jul 28, 2026
b1e99e9
chore(porch): 1273 implement re-iter (iter 3)
waleedkadous Jul 28, 2026
a6ab322
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
5a2c91d
[Spec 1273][Phase: reorient] fix: name the role document and state th…
waleedkadous Jul 28, 2026
f011819
chore(porch): 1273 implement re-iter (iter 4)
waleedkadous Jul 28, 2026
5e976bf
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
8ddde2f
[Spec 1273][Phase: reorient] fix: validate porch identity field by field
waleedkadous Jul 28, 2026
1d46d96
chore(porch): 1273 implement re-iter (iter 5)
waleedkadous Jul 28, 2026
baffcd2
chore(porch): 1273 implement build-complete
waleedkadous Jul 28, 2026
5f4d768
[Spec 1273][Phase: reorient] refactor: type SpawnPromptPort against t…
waleedkadous Jul 28, 2026
6be4ded
chore(porch): 1273 implement re-iter (iter 6)
waleedkadous Jul 29, 2026
f24c97b
chore(porch): 1273 implement build-complete
waleedkadous Jul 29, 2026
ecaf401
[Spec 1273][Phase: reorient] fix: mirror all four of spawn's input_de…
waleedkadous Jul 29, 2026
f34778e
chore(porch): 1273 implement re-iter (iter 7)
waleedkadous Jul 29, 2026
f41cc1f
chore(porch): 1273 implement build-complete
waleedkadous Jul 29, 2026
6977a61
chore(porch): 1273 advance plan phase → phase_6
waleedkadous Jul 29, 2026
4bfaf28
[Spec 1273][Phase: orchestrator] feat: afx reset state machine + CLI …
waleedkadous Jul 29, 2026
8c46d32
chore(porch): 1273 implement build-complete
waleedkadous Jul 29, 2026
3295960
[Spec 1273][Phase: orchestrator] fix: addressing parity + --dry-run s…
waleedkadous Jul 30, 2026
c3cc5c5
[Spec 1273][Phase: orchestrator] fix: reject numeric flags that disab…
waleedkadous Jul 30, 2026
1ad59a9
[Spec 1273][Phase: orchestrator] fix: bind terminal-output reads so /…
waleedkadous Jul 30, 2026
7c1a6d8
[Spec 1273][Phase: orchestrator] test: scenario 14a, wedged builder r…
waleedkadous Jul 30, 2026
a0f8462
[Spec 1273][Phase: orchestrator] fix: preflight terminal writability
waleedkadous Jul 30, 2026
b190fa3
[Spec 1273][Phase: orchestrator] fix: distinguish a vanished terminal…
waleedkadous Jul 30, 2026
0662d06
chore(porch): 1273 implement re-iter (iter 2)
waleedkadous Jul 30, 2026
aff7894
chore(porch): 1273 implement build-complete
waleedkadous Jul 30, 2026
726476e
chore(porch): 1273 implement re-iter (iter 3)
waleedkadous Jul 30, 2026
03ee4d1
chore(porch): 1273 implement build-complete
waleedkadous Jul 30, 2026
1378e6c
chore(porch): 1273 implement re-iter (iter 4)
waleedkadous Jul 30, 2026
9ad2eef
chore(porch): 1273 implement build-complete
waleedkadous Jul 30, 2026
c755960
chore(porch): 1273 implement re-iter (iter 5)
waleedkadous Jul 30, 2026
679b46f
chore(porch): 1273 implement build-complete
waleedkadous Jul 30, 2026
11786d0
chore(porch): 1273 implement re-iter (iter 6)
waleedkadous Jul 30, 2026
25da929
chore(porch): 1273 implement build-complete
waleedkadous Jul 30, 2026
af7e405
chore(porch): 1273 implement re-iter (iter 7)
waleedkadous Jul 30, 2026
b1662d6
chore(porch): 1273 implement build-complete
waleedkadous Jul 30, 2026
c1e6437
chore(porch): 1273 advance plan phase → phase_7
waleedkadous Jul 30, 2026
a968520
[Spec 1273][Phase: docs] docs: wait discipline + afx reset/interrupt …
waleedkadous Jul 30, 2026
9199719
chore(porch): 1273 implement build-complete
waleedkadous Jul 30, 2026
2c971e0
chore(porch): 1273 all plan phases complete → review
waleedkadous Jul 30, 2026
cece30e
[Spec 1273] Review: lessons learned and architecture updates
waleedkadous Jul 30, 2026
25bb296
[Spec 1273] Review: rename lessons section to porch's expected heading
waleedkadous Jul 30, 2026
49b44c4
chore(porch): 1273 review build-complete
waleedkadous Jul 30, 2026
477b447
Merge remote-tracking branch 'origin/main' into builder/aspir-1273
waleedkadous Jul 30, 2026
67f48ca
[Spec 1273] Review: merge main, rebut commit-format finding
waleedkadous Jul 30, 2026
32237c6
chore(porch): 1273 pr gate-requested
waleedkadous Jul 30, 2026
89a0d58
[Spec 1273][Phase: review] fix: clear-confirmation must not match its…
waleedkadous Jul 30, 2026
68b6a9e
[Spec 1273][Phase: review] fix: confirm the clear from post-clear out…
waleedkadous Jul 30, 2026
e40a123
[Spec 1273] Review: rebut thread-file and commit-format findings with…
waleedkadous Jul 30, 2026
54190e0
[Spec 1273] Thread: record PR review rounds and gate state
waleedkadous Jul 30, 2026
10d7406
chore(porch): 1273 pr gate-approved
waleedkadous Jul 30, 2026
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: 51 additions & 0 deletions .claude/skills/afx/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,57 @@ afx send taqwabench:architect "use porch.checks, don't fork protocol.json" # cr
curl -s http://localhost:4100/api/workspaces | python3 -m json.tool # → each .name is a valid <workspace> address
```

## afx interrupt

Sends an ESC keystroke to a builder's PTY — the only thing that reaches it **mid-turn**.

```
afx interrupt <builder>
```

| Flag | Description |
|------|-------------|
| `--no-enter` | Send ESC alone, without the trailing Enter |

A builder chaining foreground waits inside one turn queues every `afx send` unread — including your order
to stop. ESC ends the turn so the queue processes. Distinct from `afx send --interrupt` (Ctrl+C).

```bash
afx interrupt 0042
afx send 0042 "That producer died — stop waiting and report."
```

## afx reset

Resets a builder's context: save working state → `/clear` → re-orient. Use when a builder's context window
is exhausted; `afx spawn --resume` reattaches the *same* conversation and does **not** give it a fresh one.

```
afx reset <builder>
```

| Flag | Description |
|------|-------------|
| `--dry-run` | Print what would be sent; write nothing to the builder |
| `--note <text>` | Extra context appended to the re-orientation |
| `--file <path>` | Append file content (48KB max, read from *your* filesystem) |
| `--interrupt-first` | ESC before the save request, for a builder already wedged |
| `--mode <strict\|soft>` | Override mode if it cannot be detected |
| `--timeout <seconds>` | Wait for the save-state receipt (default 300) |
| `--min-bytes <n>` | Minimum state-file size to accept (default 1000) |
| `--quiet-window <ms>` | Terminal silence counting as turn-ended (default 1500) |

Every gate fails safe: if the state file never arrives, carries a stale nonce, is a stub, is still being
written, or the builder will not go quiet, the command **aborts without clearing** and exits non-zero,
naming the gate. Requires a harness with in-session reset (Claude Code); others abort loudly.

```bash
afx reset 0042 --dry-run # inspect first — touches nothing
afx reset 0042
afx reset 0042 --note "PR #90 merged while you were mid-phase. Rebase first."
afx reset 0042 --interrupt-first # builder is wedged mid-turn
```

## afx cleanup

Removes a builder's worktree and branch after work is done.
Expand Down
51 changes: 51 additions & 0 deletions .codex/skills/afx/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,57 @@ afx send taqwabench:architect "use porch.checks, don't fork protocol.json" # cr
curl -s http://localhost:4100/api/workspaces | python3 -m json.tool # → each .name is a valid <workspace> address
```

## afx interrupt

Sends an ESC keystroke to a builder's PTY — the only thing that reaches it **mid-turn**.

```
afx interrupt <builder>
```

| Flag | Description |
|------|-------------|
| `--no-enter` | Send ESC alone, without the trailing Enter |

A builder chaining foreground waits inside one turn queues every `afx send` unread — including your order
to stop. ESC ends the turn so the queue processes. Distinct from `afx send --interrupt` (Ctrl+C).

```bash
afx interrupt 0042
afx send 0042 "That producer died — stop waiting and report."
```

## afx reset

Resets a builder's context: save working state → `/clear` → re-orient. Use when a builder's context window
is exhausted; `afx spawn --resume` reattaches the *same* conversation and does **not** give it a fresh one.

```
afx reset <builder>
```

| Flag | Description |
|------|-------------|
| `--dry-run` | Print what would be sent; write nothing to the builder |
| `--note <text>` | Extra context appended to the re-orientation |
| `--file <path>` | Append file content (48KB max, read from *your* filesystem) |
| `--interrupt-first` | ESC before the save request, for a builder already wedged |
| `--mode <strict\|soft>` | Override mode if it cannot be detected |
| `--timeout <seconds>` | Wait for the save-state receipt (default 300) |
| `--min-bytes <n>` | Minimum state-file size to accept (default 1000) |
| `--quiet-window <ms>` | Terminal silence counting as turn-ended (default 1500) |

Every gate fails safe: if the state file never arrives, carries a stale nonce, is a stub, is still being
written, or the builder will not go quiet, the command **aborts without clearing** and exits non-zero,
naming the gate. Requires a harness with in-session reset (Claude Code); others abort loudly.

```bash
afx reset 0042 --dry-run # inspect first — touches nothing
afx reset 0042
afx reset 0042 --note "PR #90 merged while you were mid-phase. Rebase first."
afx reset 0042 --interrupt-first # builder is wedged mid-turn
```

## afx cleanup

Removes a builder's worktree and branch after work is done.
Expand Down
107 changes: 107 additions & 0 deletions codev-skeleton/resources/commands/agent-farm.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,113 @@ afx send 42 --file src/api.ts "Review this implementation"

---

### afx interrupt

Interrupt a builder mid-turn by sending an ESC keystroke to its PTY.

```bash
afx interrupt <builder> [options]
```

**Arguments:**
- `builder` - Target builder. Same addressing as `afx send`.

**Options:**
- `--no-enter` - Send ESC alone, without the trailing Enter

**Description:**

This is the only recovery that reaches a builder **mid-turn**. When a builder chains foreground waits
inside a single turn, every `afx send` — including your order to stop — queues unread until that turn
ends. ESC interrupts the running tool and ends the turn, after which the queued messages process. The
trailing Enter (default) is what lets them through.

Distinct from `afx send --interrupt`, which sends Ctrl+C.

**Examples:**

```bash
# Builder is wedged on a foreground wait and not reading messages
afx interrupt 0042

# Then the queued instruction lands
afx send 0042 "That producer died — stop waiting and report."
```

---

### afx reset

Reset a builder's context: have it save its working state, clear the conversation, then re-orient it.

```bash
afx reset <builder> [options]
```

**Arguments:**
- `builder` - Target builder. Same addressing as `afx send`.

**Options:**
- `--note <text>` - Extra context appended to the re-orientation
- `--file <path>` - Append file content to the re-orientation (48KB max, read from *your* filesystem)
- `--dry-run` - Print the save request and both re-orientation payloads; write nothing to the builder
- `--interrupt-first` - Send ESC before the save request, for a builder already wedged mid-turn
- `--mode <strict|soft>` - Override the builder mode if it cannot be detected
- `--timeout <seconds>` - How long to wait for the save-state receipt (default 300)
- `--min-bytes <n>` - Minimum state-file size to accept as substantive (default 1000)
- `--quiet-window <ms>` - Terminal silence that counts as turn-ended (default 1500)

**Description:**

Long-running builders exhaust their context window. `afx spawn --resume` reattaches the *same*
conversation, so a deep session resumes deep — it does not give the builder a fresh window. `afx reset`
does, without losing what the builder knows.

The sequence:

1. Assemble the re-orientation and write it to `.builder-reorient.md` in the worktree.
2. Ask the builder to write its complete working state to `.builder-state.md`, stamped with a one-time
nonce.
3. Wait for that file and **verify** it: correct nonce (not a stale file from an earlier reset),
substantive size, and stable across two observations (not still being written).
4. Wait for the terminal to fall silent, so the clear is not typed mid-turn. If it does not settle, send
**one** ESC and wait again.
5. Send `/clear`.
6. Deliver the re-orientation: role, protocol, mode, project, worktree, branch, the porch re-entry
instruction, and a pointer to the state file.

**Every gate fails safe.** If the state file never arrives, carries the wrong nonce, is a stub, is still
growing, or the builder will not go quiet — the command **aborts without clearing** and exits non-zero,
naming the gate that failed. A builder whose context was not cleared has lost nothing.

Both worktree artifacts use the `.builder-` prefix, so `afx cleanup` still classifies the worktree as
clean, and both are untracked so `porch done`'s staged-file sweep cannot pick them up.

Requires a harness with in-session context reset (Claude Code). Other harnesses abort loudly rather than
substituting a different mechanism — use the boundary-recycle pattern instead (let the builder finish,
then `afx spawn <id> --resume`).

**Examples:**

```bash
# See exactly what would be sent, without touching the builder
afx reset 0042 --dry-run

# Standard reset
afx reset 0042

# Add context that post-dates the builder's saved state
afx reset 0042 --note "PR #90 merged while you were mid-phase. Rebase before continuing."

# The builder is wedged mid-turn and not reading messages
afx reset 0042 --interrupt-first

# A builder that legitimately needs longer to write its state
afx reset 0042 --timeout 600
```

---

### afx open

Open file annotation viewer.
Expand Down
27 changes: 27 additions & 0 deletions codev-skeleton/roles/builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,33 @@ Can't find the auth helper mentioned in spec. Options:
Waiting for Architect guidance.
```

## Waiting on external work

The section above covers being blocked on *the architect*. This one covers being blocked on *an
artifact* — a file another agent is producing, a build, a queue, a sibling builder's output. That case
has its own failure mode, and it is the one that strands builders.

**A wait is a claim that a producer exists.** Before waiting on an artifact, confirm the process meant to
produce it is actually alive. In the incident that motivated this guidance (2026-07-27), a builder waited
45+ minutes on a file whose producing process had already died. The wait could never have succeeded; it
was not slow, it was unsatisfiable. Checking first costs seconds.

**Run waits as tracked background tasks that end your turn.** Start the wait in the background and finish
your turn. You are re-invoked when it completes, so the lane keeps moving *and* you stay addressable in
the meantime. A turn that ends is a turn someone can interrupt.

**Never chain foreground poll loops.** This is the rule that matters most, and the reason is not
efficiency. Every `afx send` to you — including the architect's order to stop, including a reset
request — **queues unread until your current turn ends**. A turn that never ends is a builder that cannot
be reached by anyone, doing work nobody can redirect. You will not notice, because from inside the turn
everything looks fine.

**If you are wedged anyway, you are not unreachable.** The architect can send you an ESC keystroke with
`afx interrupt <your-id>`, which ends the running turn so your queued messages process. They can also run
`afx reset <your-id>` to have you save your working state, clear your context, and be re-oriented — the
supported recovery when your context window is exhausted rather than merely stuck. Neither requires you
to do anything; both are worth knowing exist, so you can suggest them when you notice you are in trouble.

## Multi-PR Workflow

Builders may submit multiple sequential PRs within a single worktree session. The worktree persists across PRs -- it is not cleaned up automatically after merge. This allows builders to do follow-up work (e.g., addressing review feedback in a second PR, or splitting large features across checkpoint PRs).
Expand Down
Loading
Loading