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
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ flowchart LR
u2["GitHub, over the API and git"]
u3["Dropbox, over the API"]
end
sched["A scheduler<br/>workflow_dispatch on a cron"] --> host
sched["katoptra/dispatch<br/>workflow_dispatch, on a schedule"] --> host
subgraph job["One GitHub Actions job per run"]
host["The runner: task sync"] --> box["The toolbox image: task pipeline"]
end
Expand Down Expand Up @@ -94,7 +94,7 @@ The same path on a laptop and in Actions. On a laptop it starts at `task sync`.

```mermaid
sequenceDiagram
participant D as A scheduler
participant D as katoptra/dispatch
participant W as sync.yml (reusable)
participant H as Host: task
participant O as op run
Expand Down Expand Up @@ -573,8 +573,9 @@ Three surfaces, all fed by the toolbox.
the failure path. A check on the mirror's schedule, with a grace that covers a queued
run plus a full one, emails when the grace passes without a ping. Nothing sends
`/start`, so the grace does not cap a run; pause the check before a first fill. Because
nothing in a mirror starts a run, the check also watches the scheduler: a cron that
stops firing looks exactly like a pipeline that stops finishing.
nothing in a mirror starts a run, the check also watches the scheduler,
[katoptra/dispatch](https://github.com/katoptra/dispatch): a tick that stops firing
looks exactly like a pipeline that stops finishing.
- **The job summary.** `report` appends one table to the Actions job page in three
layers, the toolbox's rows, the engine's, the mirror's, all counted from `.run/` and
never from the log, whose lines are dropped silently past a limit. It is the first
Expand Down Expand Up @@ -637,7 +638,8 @@ Two reusable workflows and one composite action. A mirror's callers are a few li

### `sync.yml`

One mirror, one run. The caller is a `workflow_dispatch` that a scheduler triggers; it
One mirror, one run. The caller is a `workflow_dispatch` that
[katoptra/dispatch](https://github.com/katoptra/dispatch) triggers; it
passes `vars` through and inherits its repository secrets.

```mermaid
Expand Down
6 changes: 5 additions & 1 deletion docs/superpowers/specs/2026-09-08-toolbox-library-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ is started, contained, secured, rendered and reported comes from here.
| Versioning | Semver tags `vX.Y.Z`; a release moves the floating `v<major>` tag and pushes `<variant>-vX.Y.Z` and `<variant>-v<major>` image tags | Consumers pin `v1` once, in the include URL and the image name |
| Secrets | `op.env` of `op://` references, resolved by `op run` on the host; names cross into the container, never values | Org rule; GitHub secrets still work through the `PASS` var |
| Workflows | Reusable `sync.yml` and `check.yml` under `.github/workflows`, a composite action that installs task and op at the lock's versions | A mirror's caller workflow is ten lines |
| Clock | jshvn/dispatch triggers `workflow_dispatch` on each mirror; no `schedule:` in any mirror | One calendar, no 60-day cron shutoff |
| Clock | katoptra/dispatch triggers `workflow_dispatch` on each mirror; no `schedule:` in any mirror | One calendar, no 60-day cron shutoff |
| The check | `task check` renders the whole pipeline inside the image with `--dry --force` and diffs it against the committed `render.txt` | Any change to what a mirror executes is a visible diff; this is the one check |

The clock was jshvn/dispatch, a Cloudflare Worker, when this was written; since
2026-09-21 it is [katoptra/dispatch](https://github.com/katoptra/dispatch), a Go binary on
a systemd timer. The contract in the row is unchanged.

## The consumer contract

A mirror repository holds:
Expand Down
Loading