Learning
The choco.tools workflow runtime follows a gateway→NATS→consumer dispatch architecture that decouples the user-facing API from execution:- Gateway publishes —
POST /v1/workflows/runsvalidates workspace membership, wraps the request in a JSON EventEnvelope, and publishes tochoco.events.workflows.triggeredvia JetStream. - Consumer dispatches — The workflows consumer pulls from JetStream, looks up the
workflow_definitions.handlercolumn, and dispatches to a registeredWorkflowRunnerinterface implementation. - Runner executes — Each runner (typo-check, broken-links, style-guide) is ~100 lines of Go that shells out to a CLI tool (
cspell,lychee,vale), parses output into aRunResult, and the handler writes it toworkflow_runs.
- JSON wire format over proto for the envelope — the existing proto envelope had a broken
ProtoReflect()stub. JSON works everywhere, no codegen needed. - Handler column in
workflow_definitionsmaps 1:1 to consumer-side registry keys — the DB schema was designed for this dispatch pattern from v1. - Shared
RepoCheckouthelper (shallow clone + cleanup) prevents temp dir leaks across all runners.
WorkflowRunner + one Register() call in main.go.