Repository navigation
Adopting OpenWorkflow in Last Light: feedback, and four proposals we'd like to contribute #877
Description
Hi! We maintain Last Light, an open-source GitHub maintenance agent (MIT, by Nearform). It runs multi-step coding-agent workflows: triage, build → review → fix loops, and PR review pipelines. Approval gates can wait for days, and individual agent steps run 30–40 minutes. It deploys as a single-host docker-compose stack on SQLite by default, with Postgres optional.
We're replacing our home-grown YAML workflow engine with TypeScript workflows, and we've chosen OpenWorkflow as the runtime (design, decision issue). We compared it against DBOS, Absurd, Inngest, Restate, Temporal, Vercel Workflow, Mastra and others. It was the only one that is embeddable, needs no extra infrastructure, supports SQLite, and has real step checkpointing. In a spike on 0.10.1, a run parked at an approval gate survived a process restart, and after a kill -9 mid-step a fresh worker reclaimed the run with only the in-flight step re-running. Thank you for building it.
We'd like to be a public production user and to contribute, rather than work around things in an adapter. Per CONTRIBUTING, here are the gaps we hit, so we can check they fit your thinking before opening any PRs. We're happy to split any of them into separate issues, and to do the implementation.
1. A pluggable logger
Worker-loop errors go to console.error. Our runtime requires structured JSON logging with levels, so we'd like a logger option (for example { debug, info, warn, error }, defaulting to the console) on the client or worker.
2. A configurable lease and heartbeat
The 30 s lease is a constant. That's fine for us today, but deployments with very long steps or slow storage may want to tune it. We'd propose leaseMs / heartbeatMs worker options with the current values as defaults.
3. Signals sent before a workflow waits
sendSignal is dropped when no step is waiting yet. That's a natural race for approvals: a human approves before the run reaches waitForSignal, or during a restart. We currently treat our own approval row as the source of truth and check it before parking. Would you prefer buffered signals (persisted until consumed or expired), or a documented check-before-park pattern? We'd implement whichever fits your model.
4. Sharing a database with an existing application
The table names are fixed (workflow_runs, step_attempts, workflow_signals, openworkflow_migrations). workflow_runs collides with an existing table of ours, so CREATE TABLE IF NOT EXISTS silently no-ops and inserts then fail. As far as we can tell, namespace_id is a column rather than a prefix. Could the backends accept a table prefix or schema?
Relatedly, we want a single database file, our existing driver (libsql / pg), and our existing migration tooling, so we're implementing the Backend interface over Drizzle ORM (SQLite and Postgres). If it's useful, we'd like to contribute it upstream as a generic backend, e.g. @openworkflow/backend-drizzle, that takes an injected Drizzle db. Two questions on that:
- Is there a backend conformance test suite we should target? If not, would you welcome one, extracted from the existing SQLite/Postgres backend tests?
- How stable do you consider the
Backendinterface before 1.0?
We'll pin an exact version until 1.0 and follow the changelog. If any of these conflict with where you're taking the project, we'd rather know now and adapt our design. Thanks!
Activity
jamescmartinez commentedon Oct 11, 2026
Hey @cliftonc, let's do it. Some thoughts:
I agree with 1 & 2 and would love PRs.
re: 4, you can provide a custom schema today in Postgres, but not SQLite. I'm very open to a table-prefix PR, too!
3 (signals) requires a bit more design. I do sort of regret that signals was implemented the way it is without 1) buffering, and 2) addressing a specific run. That said, I'd rather come up with a new name to run alongside the existing signals, since people already use it.
re: your Drizzle questions, I'd be happy to take a look at a PR. There is a backend conformance suite,
testBackendhttps://github.com/openworkflowdev/openworkflow/blob/main/packages/openworkflow/testing/backend.testsuite.ts, that the two implementations use.Backendis constantly evolving, though. See the point on signals above, and two upcoming features, concurrency and schedules.cliftonc commentedon Oct 12, 2026
Awesome; 1 & 2 are on their way.
On 3 - want me to propose something or are you already thinking about it?
I'll give some more thought to the drizzle backend and submit a PR (more I think to walk around it and try it on for size).
cliftonc commentedon Oct 12, 2026
Thanks! Logger and lease are up as #879 and #878. For item 4 and the Drizzle question, I've written up the design in #880; a Drizzle backend with a table prefix covers the shared-database case.
jamescmartinez commentedon Oct 12, 2026
thanks! merged those two PRs
I'm wrapping up schedules/crons and shipping 0.11 today. Let me get back to you on #880 once that's done.
openworkflow/drizzle) #880cliftonc commentedon Oct 12, 2026
No worries; thanks!
jamescmartinez commentedon Oct 12, 2026
replied in #880
jamescmartinez commentedon Oct 12, 2026
I haven't much time thinking about it other than existing feedback, to be honest. I want to chat with some more people to see how they're using signals today, vs. what they need, before making a binding decision here.
I'll send some messages out now and get back to you on this. Open to a proposal in the meantime!
cliftonc commentedon Oct 13, 2026
On item 3: I've written up a proposal for run-addressed, buffered messages alongside signals in #894, as input while you gather feedback on signals. No PR until you've had a look.