Three parts an example has to show
Pattern catalogues name reflection, tool use and planner-executor loops, and they are good at that. What they leave out is the part that decides whether a workflow holds up in a building with other people in it. An example you can copy carries three visible parts: the row that starts the run, the prompt that row fires, and the lines the run hands back when it is done. The definition covers the loop itself; each of the four runs keeps to those three parts.
A row, a prompt and the lines a session prints are small enough to read in one screen, and specific enough to argue with. If one of the three is missing, the example is a mood board.
One row, in full
The daily-digest row is the whole example, as it sits in kortix.yaml:
triggers:
- slug: daily-digest
type: cron
agent: kortix
cron: "0 0 9 * * 1-5"
timezone: America/Los_Angeles
session_mode: fresh
prompt: |
Summarize yesterday's commits. Open a change request against main.
Nine lines, each field with a job. The slug is the name typed at the command line. type: cron is one of the two trigger types. agent: kortix names the agent the fire starts. The cron expression carries six fields and the timezone is an IANA name. session_mode: fresh says this fire gets a clean session rather than an earlier one. The block under prompt: carries the work: what to read, what to write, and where the result goes.
The trigger sits in the same repo as the agents
In Kortix, triggers live in kortix.yaml next to your agents and sandbox images. The cron expression, the timezone, the agent slug and the prompt sit within a few lines of each other. A reader can copy the shape without opening a dashboard.
That proximity is the difference between an example and a screenshot. Text in git can be diffed, forked and reviewed. It also survives the person who set it up. The row is still there after they change teams, and the comment above it still says what it was for.
Every run boots a machine of its own
A triggered session does not run in a chat window. It does not run on the laptop of whoever configured the trigger. A Linux machine boots from the sandbox image your project declares, and the project repo is cloned into /workspace before the agent reads its prompt. A run never inherits another run's half-finished install, because the machine that held it is gone.
One isolated sandbox per session. Each session has its own isolated machine and branch. A run that installs the wrong dependency or deletes a directory costs nothing outside its own machine. The session's branch holds every edit, commit and stray file it produces, and the machine takes the rest with it when the run ends.
What the run hands back
The part a catalogue cannot show is where the work goes. Session work reaches main through a change request. Merge is default-deny for agents, so a run that only answers, or stops on a question, leaves nothing to merge.
A finished session prints three things: the branch, named after the session; the one commit that survives the machine; and kortix cr reporting the change request it opened. A transcript asks the reader to trust the run. A branch asks them to read it. The change request carries the changed lines against a base, with a place for a comment, which is what a colleague's work already looks like.
Cron, webhook, and what signs a webhook
A trigger has exactly two types: cron and webhook. Cron takes a 6-field expression, second through weekday, in any IANA timezone, or a single run_at timestamp for something that should happen once and then stay quiet. Webhook fires when an external service POSTs to the trigger URL. Every webhook trigger names a project secret that signs it. A trigger without one is rejected at validation, which removes the unauthenticated endpoint someone would otherwise forget to close. Three commands add a trigger, ship the config and start a run by hand:
$ kortix triggers add daily-digest --type cron \
--cron "0 0 9 * * 1-5" \
--timezone America/Los_Angeles \
--prompt "Summarize yesterday. Open a CR."
$ kortix ship
→ kortix.yaml pushed. daily-digest is scheduled.
$ kortix triggers ls
$ kortix triggers fire daily-digest
→ session started
kortix triggers fire exists so nobody waits until Monday morning to find out whether the prompt renders. Firing it by hand starts the same session the clock would have started, on the same kind of machine.
The one field worth thinking about before copying a row is session_mode. A trigger has four session modes: fresh, reuse, pinned, keyed, and the default is fresh. A digest and a shift handoff want a clean slate, so both use fresh. A monthly sweep wants the thread it already owns, which is reuse. A roadmap review wants one exact session named by id, which is pinned. A per-customer conversation wants keyed: the payload renders a key, and the fire lands on the most recent healthy session stamped with it. A fire that cannot reach its pinned session falls to keyed, then to reuse, then to a fresh session, so a fire never disappears.
What to change when you copy a row
Copied rows go wrong in small, predictable places. The slug, the cron, the timezone, the agent name and the prompt are the fields that carry the work, and each one has a failure that shows up in the first week.
The slug is the name you type at the command line, so it should say what the run does. The cron expression and the timezone travel together: 0 0 9 * * 1-5 fires at 09:00 in whatever zone the row names, and a row copied from a colleague abroad keeps their clock until you change it. The agent name has to exist under agents: in the same file, because the fire starts that agent and no other. The prompt is the field where a small edit pays for itself, since it becomes the session's first message.
session_mode is the field people leave alone, and the one worth a second look when the copy changes job. A digest copied into an invoice sweep should change mode along with the prompt.
Cost is the last question and the row answers it: a triggered session stops itself after 5 minutes idle, so an automation at 03:00 does not bill until the office opens. An automation also gets no privileges a person would not get, which keeps what a copied row can reach short.
Starting from a row you already have
The shortest path is to copy one row, change the slug and the cron, and leave the rest. Build your own walks a weekday digest from that first row to the merged change request. It covers the session mode and the prompt template. Run it on Kortix Cloud, in your VPC, or on your own on-prem network. Self-host is free.