Worker
The factory runs here.
The directory is prerendered HTML. Jobs run inside this Worker, on a Cloudflare Agent — a SQLite-backed Durable Object — not in a database and not on Pages.
What this is
FactoryRuntime is a single named Durable Object
(default) exported from the Worker. It keeps a short job
log in Agent state and executes four kinds of work:
validate— Zod-check a proposed listing YAML payload.enrich— fetch a primary URL and return a draft skeleton. It will not invent production numbers.build-log— validate a set of proposed YAML files and return a CI-shaped report.issue-to-pr— turn a GitHub issue into a draft listing pull request. It never merges.
GitHub remains the content store. The Worker is where jobs run. A human publishes.
How to invoke a job
POST /factory/jobs with a bearer token. Set the token with
npx wrangler secret put FACTORY_TOKEN.
curl -sS https://softwarefactory.build/factory/jobs \
-H "authorization: Bearer $FACTORY_TOKEN" \
-H "content-type: application/json" \
-d '{"kind":"validate","input":{"yaml":"slug: example\n..."}}' GET /factory/jobs lists recent jobs. GET /factory/jobs/:id
returns one job, including the log.
issue-to-pr also needs GITHUB_TOKEN (repo contents
and pull requests) and optionally GITHUB_REPO
(owner/name, default trevize-dev/softwarefactory.build).
The same draft-PR path runs as a GitHub Action when an issue is labeled
factory-draft, or via workflow_dispatch. Neither
path merges.
What this is not
- Not a CMS, admin panel, or login.
- Not auto-merge. Agents propose; a human publishes.
- Not a second source of truth. Listings still live as one YAML file per tool in Git.