Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
a337ce4
chore(porch): 1307 init aspir
waleedkadous Jul 31, 2026
e5b1459
[Spec 1307] Initial specification draft
waleedkadous Jul 31, 2026
d0156e8
chore(porch): 1307 specify build-complete
waleedkadous Jul 31, 2026
4150edb
[Spec 1307] Specification with multi-agent review
waleedkadous Jul 31, 2026
1f11f79
[Spec 1307] Design out the autocomplete hazard; state the worst case
waleedkadous Jul 31, 2026
de043df
[Spec 1307] Pruning as a save requirement; reorientation delivery reo…
waleedkadous Jul 31, 2026
93bd2a9
[Spec 1307] Codex review: fix two wrong premises, add --begin/--bound…
waleedkadous Jul 31, 2026
4356c40
chore(porch): 1307 plan phase-transition
waleedkadous Jul 31, 2026
b361dea
[Spec 1307] Specify phase rebuttals; specify complete
waleedkadous Jul 31, 2026
f5c1932
[Spec 1307] Reference #1310 at each named observability gap
waleedkadous Jul 31, 2026
09975b9
[Spec 1307] Descope: afx send --delay + a skill replaces the Tower jo…
waleedkadous Jul 31, 2026
2cd35d0
chore(porch): 1307 plan build-complete
waleedkadous Jul 31, 2026
2b9d969
[Spec 1307] Plan review: fix two ordering/addressing defects both rev…
waleedkadous Jul 31, 2026
2790eb7
chore(porch): 1307 implement phase-transition
waleedkadous Jul 31, 2026
08926b2
[Spec 1307][Phase: phase_1] feat: afx send --delay (Tower-side deferr…
waleedkadous Jul 31, 2026
48852b1
[Spec 1307][Phase: phase_1] test: route-level coverage for delayed de…
waleedkadous Jul 31, 2026
b83375e
chore(porch): 1307 implement build-complete
waleedkadous Jul 31, 2026
1419c20
[Spec 1307][Phase: phase_1] fix: review round 1 — real FIFO guards, i…
waleedkadous Jul 31, 2026
133b3a5
[Spec 1307][Phase: phase_1] docs: phase 1 review rebuttals
waleedkadous Jul 31, 2026
a536642
chore(porch): 1307 implement re-iter (iter 2)
waleedkadous Jul 31, 2026
7de02d3
chore(porch): 1307 implement build-complete
waleedkadous Jul 31, 2026
bf4040b
[Spec 1307][Phase: phase_1] fix: review round 2 — per-terminal serial…
waleedkadous Jul 31, 2026
ae55347
[Spec 1307][Phase: phase_1] docs: iteration 2 review rebuttals
waleedkadous Jul 31, 2026
29abc16
[Spec 1307][Phase: phase_1] fix: serialise actual writes, not just th…
waleedkadous Jul 31, 2026
e0ff15a
[Spec 1307][Phase: phase_1] docs: state the ordering guarantee precis…
waleedkadous Jul 31, 2026
17db2e9
[Spec 1307][Phase: phase_1] fix: close the mid-flush interleave window
waleedkadous Jul 31, 2026
68ea743
chore(porch): 1307 implement re-iter (iter 3)
waleedkadous Jul 31, 2026
0d8ee64
[Spec 1307][Phase: phase_1] fix: cancel due-but-not-started deliverie…
waleedkadous Jul 31, 2026
df70f62
chore(porch): 1307 implement build-complete
waleedkadous Jul 31, 2026
0eaf668
[Spec 1307][Phase: phase_1] docs: correct the stale guarantee comment…
waleedkadous Jul 31, 2026
093f678
[Spec 1307][Phase: phase_1] fix: --delay error echoes the user's inpu…
waleedkadous Aug 1, 2026
343a69d
[Spec 1307][Phase: phase_1] docs: iteration 3 rebuttals (covers round…
waleedkadous Aug 1, 2026
c28e397
chore(porch): 1307 implement force-advance (safety ceiling reached at…
waleedkadous Aug 1, 2026
dfd9408
chore(porch): 1307 advance plan phase → phase_2
waleedkadous Aug 1, 2026
bfd1c00
[Spec 1307] Adopt 1273's submission lock; do not build a rival mechanism
waleedkadous Aug 1, 2026
e30eb9c
[Spec 1307][Phase: phase_2] feat: /arch-save skill in four trees + st…
waleedkadous Aug 1, 2026
0f7bcc8
[Spec 1307] Record #1320 adoption plan with measured merge surface
waleedkadous Aug 1, 2026
2d297a4
chore(porch): 1307 implement build-complete
waleedkadous Aug 1, 2026
b4c5d08
[Spec 1307][Phase: phase_2] fix: drift guard for arch-save; correct t…
waleedkadous Aug 1, 2026
45f946e
[Spec 1307][Phase: phase_2] fix: do not end the turn if scheduling th…
waleedkadous Aug 1, 2026
71cf40a
[Spec 1307] Correct the #1320 adoption plan: it is a replacement, not…
waleedkadous Aug 1, 2026
884eebd
Merge remote-tracking branch 'origin/main' into builder/aspir-1307
waleedkadous Aug 1, 2026
18fa843
[Spec 1307] Thread: phases 1-2 complete, 1273 coordination, main merged
waleedkadous Aug 1, 2026
9343e3d
[Spec 1307][Phase: phase_3] docs: --delay reference; update Spec 1280…
waleedkadous Aug 1, 2026
364b90e
[Spec 1307][Phase: phase_3] docs: live-run runbook written ahead of t…
waleedkadous Aug 1, 2026
a7e682a
[Spec 1307] Consolidate the three queued merge actions; verify the #1…
waleedkadous Aug 1, 2026
e0f0c34
Merge remote-tracking branch 'origin/main' into builder/aspir-1307
waleedkadous Aug 1, 2026
5bcf52b
[Spec 1307][Phase: phase_3] docs: relocate --delay out of the always-…
waleedkadous Aug 1, 2026
2ed62c4
[Spec 1307][Phase: phase_2] docs: iteration 1 rebuttals
waleedkadous Aug 1, 2026
610bcad
chore(porch): 1307 implement re-iter (iter 2)
waleedkadous Aug 1, 2026
4a36ea8
chore(porch): 1307 implement build-complete
waleedkadous Aug 1, 2026
f444073
chore(porch): 1307 advance plan phase → phase_3
waleedkadous Aug 1, 2026
e4d3a13
Merge remote-tracking branch 'origin/main' into builder/aspir-1307
waleedkadous Aug 2, 2026
7d66ba4
[Spec 1307] Thread: phase 2 closed, --delay relocated, main found red
waleedkadous Aug 2, 2026
6d79c5a
Merge remote-tracking branch 'origin/main' into builder/aspir-1307
waleedkadous Aug 2, 2026
97aa265
[Spec 1307][Phase: phase_3] refactor: adopt #1320's submission lock; …
waleedkadous Aug 2, 2026
4ac2712
[Spec 1307][Phase: phase_3] spec: record why the live e2e is architec…
waleedkadous Aug 2, 2026
06342d3
chore(porch): 1307 implement build-complete
waleedkadous Aug 2, 2026
ddf02ab
[Spec 1307][Phase: phase_3] refactor: finish the deletion; correct co…
waleedkadous Aug 2, 2026
cc82638
[Spec 1307][Phase: phase_3] docs: phase 3 iteration 1 rebuttals
waleedkadous Aug 2, 2026
fc8046f
chore(porch): 1307 implement re-iter (iter 2)
waleedkadous Aug 2, 2026
48d34da
chore(porch): 1307 implement build-complete
waleedkadous Aug 2, 2026
2702954
[Spec 1307][Phase: phase_3] fix: fold the delayed interrupt into the …
waleedkadous Aug 2, 2026
a0c1709
[Spec 1307][Phase: phase_3] docs: review file with verify plan and un…
waleedkadous Aug 2, 2026
1bde2b6
[Spec 1307][Phase: phase_3] docs: phase 3 iteration 2 rebuttals
waleedkadous Aug 2, 2026
b5c7c79
chore(porch): 1307 implement re-iter (iter 3)
waleedkadous Aug 2, 2026
0384dbc
chore(porch): 1307 implement build-complete
waleedkadous Aug 2, 2026
905bc9f
[Spec 1307][Phase: phase_3] fix: await shutdown flush; test the route…
waleedkadous Aug 2, 2026
8851644
[Spec 1307][Phase: phase_3] docs: phase 3 iteration 3 rebuttals
waleedkadous Aug 2, 2026
7701a66
chore(porch): 1307 implement force-advance (safety ceiling reached at…
waleedkadous Aug 2, 2026
0421e06
chore(porch): 1307 all plan phases complete → review
waleedkadous Aug 2, 2026
8bd563b
[Spec 1307][Phase: phase_3] fix: shutdown ordering + real stop-awaits…
waleedkadous Aug 2, 2026
c7219c5
[Spec 1307][Phase: phase_3] refactor: flush() returns void; drop the …
waleedkadous Aug 2, 2026
d1c327d
chore(porch): 1307 record PR #1335
waleedkadous Aug 2, 2026
97d805f
[Spec 1307][Phase: phase_3] docs: rename review heading to 'Lessons L…
waleedkadous Aug 2, 2026
0d01947
chore(porch): 1307 review build-complete
waleedkadous Aug 2, 2026
a4ffbbc
[Spec 1307][Phase: phase_3] fix: log swallowed write failures; correc…
waleedkadous Aug 2, 2026
d6a2247
[Spec 1307][Phase: phase_3] test: cover the write-throw logging path
waleedkadous Aug 2, 2026
9c931fb
[Spec 1307][Phase: phase_3] chore: log the shutdown-cancelled delayed…
waleedkadous Aug 2, 2026
ea95b28
chore(porch): 1307 pr gate-requested
waleedkadous Aug 2, 2026
e504f3f
[Spec 1307] Thread: at the pr gate, waiting for approval
waleedkadous Aug 3, 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
31 changes: 22 additions & 9 deletions .claude/skills/arch-init/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ not choose; a state save happens at a boundary **you** pick, with a summary
**you** curate. That is strictly better, so use it:

```
/arch-init (recover) → work → save at a checkpoint → suggest /clear → human /clears → /arch-init → …
/arch-init (recover) → work → save at a checkpoint → refresh → /arch-init (recover) → …
packaged: /arch-save ─────────────────┤ stops monitors, saves, clears,
│ schedules /arch-init
manual: suggest /clear → human clears ┘ then human runs /arch-init
```

**When to save.** Save at a *resumable boundary* — a point a fresh session
Expand Down Expand Up @@ -99,17 +103,26 @@ plus the most recent dated section*, so a save must leave exactly that behind:
dumps or raw tool output. Include only: current focus, open loops, and the
instructions a fresh session needs to resume.

**Then — and only then — suggest `/clear`.** Save first, *then* tell the human
it is a good time to clear. You cannot clear your own context and must never
decide unilaterally to lose it; keeping the irreversible step behind a human
keystroke means accepting the suggestion can never lose anything, because the
save already happened. Make the suggestion **advisory, never nagging**, and
only right after a save — e.g.:
**Then — and only then — suggest the refresh.** Save first, *then* tell the
human it is a good time to clear. You must never decide unilaterally to lose
your context; keeping the irreversible step behind a human decision means
accepting the suggestion can never lose anything, because the save already
happened. Make the suggestion **advisory, never nagging**, and only right
after a save — e.g.:

> State saved to `codev/state/<name>.md` — good time to `/clear` if this
> State saved to `codev/state/<name>.md` — good time to refresh if this
> session is feeling heavy.

Do not repeat it, and do not prompt to `/clear` at any other time.
Do not repeat it, and do not prompt for it at any other time.

**`/arch-save` packages this whole loop**, and is the preferred path when the
owner directs a refresh: it stops your monitors, writes the pruned state file,
clears, and schedules `/arch-init` to bring you back — in that order, which is
the part that matters. The save discipline above is what it performs at its
step 3, so this section remains the source of truth for *how to write the
file*; `/arch-save` is the source of truth for *the sequence*. The manual path
(save → human clears → `/arch-init`) stays valid and is the fallback when
Tower is unavailable.

## Guardrails (architect-wide; the state file may add more)

Expand Down
183 changes: 183 additions & 0 deletions .claude/skills/arch-save/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
---
name: arch-save
description: Save an architect's state, clear its context, and re-init automatically — the packaged save→clear→re-init refresh cycle. Use when the owner directs a context refresh, or says "/arch-save", "save and clear", "refresh your context". Runs on the owner's direction; an architect does not invoke it autonomously mid-task. Counterpart to /arch-init, which recovers the state this writes.
argument-hint: "[name] (e.g. main; omit to auto-detect via afx whoami)"
---

# /arch-save — save state, clear, and come back as yourself

Long sessions accumulate stale context. This is the deliberate cure: you choose the
moment, you choose what survives, and a fresh session resumes from what you wrote.

`$ARGUMENTS` is the architect name (e.g. `main`). Omit it to auto-detect.

## When NOT to run this

**On the owner's direction, or when the owner runs it themselves.** Do not invoke this
autonomously mid-task on your own judgement — the irreversible step is a human decision,
relocated from "press `/clear`" to "invoke `/arch-save`", not removed. If the owner tells
you to run it, run it; if you think it is time, *suggest* it and wait.

**Only at a resumable boundary** — a gate approval, a PR merge, a completed investigation,
the end of a long tool-heavy stretch. **Never mid-task.** Nothing here can check that; the
state file must describe a point a fresh session can resume *from*, not a half-finished
action. A mid-task snapshot resumes into confusion.

## The procedure

Do these in order. **The order is the feature** — step 3 must precede step 4, because the
context that knows what to write is the one about to be destroyed.

### 1. Resolve your name

If `$ARGUMENTS` is non-empty, that is your name. Otherwise run `afx whoami` and use the
reported `name` when `type: architect`.

- `type: builder` → **STOP.** This terminal is a builder. Report the mismatch.
- Non-zero exit → **STOP** and ask which architect you are. Do **not** guess, and do not
default to `main` — writing another architect's state file is the exact failure
`/arch-init` exists to prevent (#1094).

**Validate the name before building any path**: `[a-z][a-z0-9-]*`, at most 64 characters.
Reject slashes, `..`, uppercase, spaces. Never interpolate an unvalidated name into
`codev/state/<name>.md`.

### 2. Stop your own monitors

Enumerate every monitor, watcher or background task you armed, and stop it.

This is the half that only *you* can do. Monitors are **session-bound, not
context-bound**: they survive `/clear` and keep firing into a context that cannot evaluate
their alerts. `pgrep` cannot see them — they are harness background tasks, not shell
processes — so the instance after the clear has no handle on them. You do. Use it.

### 3. Write the pruned state file

Rewrite `codev/state/<name>.md`. **Pruning is part of the save, not polish afterwards — a
save that only appends has not done its job.**

- **Rewrite the current-state / open-loops section in place.** Do not accumulate stale
"current state" blocks. Never leave two sections with the same heading — a duplicated
"How to resume" means you appended where you should have overwritten.
- **Delete resolved loops outright.** A closed item's record is the log entry, not a
lingering line in current state.
- **Append one short dated entry** for what changed this stretch.
- **Collapse older entries into one-line summaries that point at durable artifacts** — the
merged PRs, closed issues and reviews where the detail actually lives.
- **Aim for one screen.** If the file has grown past easy reading, prune as part of *this*
save rather than leaving it for next time.

**Prune by pointer, never by deletion.** These files are gitignored (`.gitignore:15`), so
there is no history to recover from — pruned prose is gone for good. Replace detail with a
pointer to something durable; never delete the only record of something. Copying the file
first (`cp codev/state/<name>.md codev/state/.<name>.bak.md`) is cheap insurance.

**Content guardrails.** No secrets — tokens, keys, credentials. No transcript dumps, no
raw tool output. Only: current focus, open loops, and what a fresh session needs to resume.

Use the template at the end of this document.

### 4. Clear

```bash
afx send architect:<name> --raw '/clear'
```

**`architect:<name>`, never bare `architect`.** For a non-builder sender the bare form
resolves to `main`, or to the first registered architect — so a *sibling* architect
running this would clear **main's** terminal instead of its own. That destroys the context
of someone who never asked for anything, and it is one word away from correct.

**`--raw`, never the escape channel.** The escape route writes a bare ESC and discards the
message body, so `/clear` sent that way delivers an interrupt: the command appears to
succeed and nothing is cleared.

### 5. Schedule the re-init

```bash
afx send architect:<name> --delay 15 --raw '/arch-init <name>'
```

Tower holds this for 15 seconds and then delivers it. It has to come from outside the
session, because the clear destroys the context that would otherwise send it.

**Tower does not know whether the clear landed** — it waits out a delay, it does not
observe the result. 15 seconds is a value chosen because it works in practice, not a
guarantee about the clear's completion. If the timing is wrong the re-init arrives at the
wrong moment, which costs one manual message (see below) and nothing else. That is the
whole reason this cycle can be built on a delay rather than on machinery.

Delayed sends are **not persisted** — if Tower restarts inside the window, the message is
dropped. That is recoverable; see below.

**If this send fails, do not end your turn.** Step 4 queued the `/clear`, but it does not
take effect until your turn ends — so at this moment you still have your full context and
the failure is recoverable. Retry the send; if it keeps failing (Tower down, for example),
tell the owner that the clear is queued with no re-init scheduled, and give them the
command to send by hand once Tower is back. Ending the turn here is the one way to turn a
recoverable failure into a cleared session nobody is coming back for.

### 6. Stop

Do not start new work. End your turn so the clear can take effect.

## After the clear

`/arch-init` will read your state file and resume. Two things it should do first, in this
order:

1. **Reconcile monitors.** You stopped yours in step 2, but treat any alert you cannot
account for from the state block's monitor list as **stale** — disregard it, and stop
it if you can. An alert from a decommissioned target is indistinguishable from a live
one.
2. **Then re-arm** the monitors the block lists, and let each one **self-test once** before
trusting its alerts. A freshly-armed monitor's first alert has been a false positive in
practice.

## If `/arch-init` never arrives

Nothing is lost. The state file is on disk, the terminal is alive. Send it by hand:

```bash
afx send architect:<name> --raw '/arch-init <name>'
```

This is the recovery the whole design leans on, which is why the cycle can accept imprecise
timing rather than needing machinery to guarantee it.

**If the clear did not take effect** — you still have your full context and a stray
`/arch-init` arrived — nothing was destroyed. Check whether `/clear` was submitted as its
own message rather than merged into another one, and report it; a `/clear` that arrives as
literal text on the front of the next message never executes.

## State block template

The structure below comes from a live run of this cycle. Every element earns its place;
keep them all, including a `MONITORS:` line even when the answer is "none armed" — an
omitted monitor list is indistinguishable from a forgotten one.

```
# <lane> architect — state (vNN, <date> ~HH:MM UTC — <milestone>, DELIBERATE /clear cycle)
# ⭐ THIS /clear IS INTENTIONAL (owner-directed context refresh). On re-init: normal
# /arch-init flow, then:
# 1. MONITORS: <what to stop if it is still firing, then what to re-arm> — watch target,
# cadence, alert pattern. Self-test once before trusting alerts. ("none armed" is a
# valid and complete answer.)
# 2. DONE pre-clear, with receipts: <PR> MERGED (<sha>, verified on origin/<branch>);
# <branch> PUSH-VERIFIED (<sha> local==origin). Distinguish "written" from "verified" —
# a cold reader cannot tell.
# 3. ACTIVE LANES: <builder-id> = <workstream> (<brief file on disk>; <standing rule>).
# Name the file, so no instruction lives only in the context being destroyed.
# 4. LATEST RESULTS: <the decision-relevant numbers>, so the first post-resume decision
# needs no archaeology.
# 5. QUEUED, with ordering: <item> — WAITS for <verdict>; <item> — <when>.
# 6. ENVELOPE: <standing authorization that survives>; <what expired with the completed
# work>.
```

## Guardrails (architect-wide)

- **Never auto-approve porch gates.** A gate notification is for the human, not you.
- **Touch only your own builders / spawns / filings.**
- **Never `cd` into a builder worktree**; use `git -C` and absolute paths.
- **Stay on the default branch at the workspace root.**
31 changes: 22 additions & 9 deletions .codex/skills/arch-init/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ not choose; a state save happens at a boundary **you** pick, with a summary
**you** curate. That is strictly better, so use it:

```
/arch-init (recover) → work → save at a checkpoint → suggest /clear → human /clears → /arch-init → …
/arch-init (recover) → work → save at a checkpoint → refresh → /arch-init (recover) → …
packaged: /arch-save ─────────────────┤ stops monitors, saves, clears,
│ schedules /arch-init
manual: suggest /clear → human clears ┘ then human runs /arch-init
```

**When to save.** Save at a *resumable boundary* — a point a fresh session
Expand Down Expand Up @@ -99,17 +103,26 @@ plus the most recent dated section*, so a save must leave exactly that behind:
dumps or raw tool output. Include only: current focus, open loops, and the
instructions a fresh session needs to resume.

**Then — and only then — suggest `/clear`.** Save first, *then* tell the human
it is a good time to clear. You cannot clear your own context and must never
decide unilaterally to lose it; keeping the irreversible step behind a human
keystroke means accepting the suggestion can never lose anything, because the
save already happened. Make the suggestion **advisory, never nagging**, and
only right after a save — e.g.:
**Then — and only then — suggest the refresh.** Save first, *then* tell the
human it is a good time to clear. You must never decide unilaterally to lose
your context; keeping the irreversible step behind a human decision means
accepting the suggestion can never lose anything, because the save already
happened. Make the suggestion **advisory, never nagging**, and only right
after a save — e.g.:

> State saved to `codev/state/<name>.md` — good time to `/clear` if this
> State saved to `codev/state/<name>.md` — good time to refresh if this
> session is feeling heavy.

Do not repeat it, and do not prompt to `/clear` at any other time.
Do not repeat it, and do not prompt for it at any other time.

**`/arch-save` packages this whole loop**, and is the preferred path when the
owner directs a refresh: it stops your monitors, writes the pruned state file,
clears, and schedules `/arch-init` to bring you back — in that order, which is
the part that matters. The save discipline above is what it performs at its
step 3, so this section remains the source of truth for *how to write the
file*; `/arch-save` is the source of truth for *the sequence*. The manual path
(save → human clears → `/arch-init`) stays valid and is the fallback when
Tower is unavailable.

## Guardrails (architect-wide; the state file may add more)

Expand Down
Loading
Loading