Halon watching for you
Halon can keep an eye on something after it answers and tell you how it went. Ask it to tell you when a CI run finishes, when a build or a deploy starts and succeeds, or to keep checking something until a condition holds, and it checks about every minute until everything it follows is done, something fails, or its time runs out.
Asking for a watch
Section titled “Asking for a watch”Ask in a chat in your own words, such as “I started the release. Tell me when run #46 finishes, and when the web deploy starts and succeeds.” Halon finds each thing on the resource map, writes the watch itself and tells you how long it will watch and how often it may read, such as:
This usually takes about 18 minutes, I will watch for up to 40.
You can also ask Halon to keep checking something until a condition holds, in plain words, such as “keep checking web until every instance runs the new version” or “tell me once the error rate has stayed under 1% for ten minutes”. Halon picks the read that shows it, with any read it can make in a chat, and judges from the last few readings together whether the answer to your question is yes, whether it is still going, or whether something went wrong.
Each watch is named for what it waits on, such as Watch “Deploy finished”, and that name heads every line it says.
One watch per release
Section titled “One watch per release”Things that belong together stay in one watch. When you ask Halon to follow more of the same release, deploy, run or incident while a watch you started is going in the chat, such as the release build, then its rollout, then the health checks after it, Halon adds them to that watch rather than starting another, and the watch says Now also following with what joined. Something unrelated gets a watch of its own. Adding steps gives them time of their own to finish, up to a day from when the watch started, unless you set the time yourself, in which case Halon tells you the new steps may not finish within it and offers more.
Steps that wait for each other
Section titled “Steps that wait for each other”A watch can follow steps in order, such as a release run, then the deploy it ships, then a check that the service is healthy after it. Halon sets the order from what you describe. A step that waits is not read until the steps before it have succeeded, and its row says so, such as Waiting for GitHub release run. Once they have, it counts only what came after them, so a health check reads only logs written since the new deploy, and never the old container’s. Steps that do not depend on each other are followed side by side.
When a step fails, the steps that wait on it are skipped rather than followed, such as Skipped because GitHub release run failed., and the watch ends on the real failure.
Waiting for a new deploy
Section titled “Waiting for a new deploy”A step that waits for a deploy counts only one newer than the deploy live when the watch began, so the last release finishing never reads as the new one done. Until a newer deploy starts, the step’s row says so, such as Waiting for a new deploy of web to start (live now: cf0bcbe since 10:24 UTC). When Halon knows the version, such as the commit a release run built, it waits for that version. Only deploys to production count unless you name another environment.
A newer deploy that is cancelled or replaced does not end the step, which waits for the next one. A newer deploy that fails is said at once, and the step stays open, so a fix that goes out before the time limit can still succeed. Where a provider does not say which deploy is live, the step’s row says only a deploy finished after the watch began counts.
Halon keeps what you are trying to achieve with the watch, in your words, such as “get releases deploying through the webhook again”. When something goes wrong, such as a job failing or the time running out, the line tells you where that leaves your goal and the next step it would take, as a question, such as “The manual run worked, but the GitHub path is still broken. Next I would read the webhook’s error, shall I?” It never takes that step until you say yes, and you can say no or ask for something else. Progress never asks you anything, and when everything finished the closing line says what it shows about your goal, such as Done in 7 minutes. web is serving 7676c83. under the watch’s name.
When you start something that takes a while, Halon offers to watch it for you. When Halon starts something itself, such as a workflow run you asked for, it watches that exact run in the same answer, so if it fails you hear about it. The same goes for a run you name by its number. A watch works the same from a chat in the dashboard, in a Slack thread, or from an agent asking Halon over the MCP server.
A watch only ever reads. It checks with the same tools Halon uses in a chat, as you, with exactly your permissions, so it cannot see anything you could not. Each check is in Gateway → Activity under the Halon watch source. Approval rules never hold a watch’s reads, and a watch never makes a change.
How long it watches
Section titled “How long it watches”| What decides | How long |
|---|---|
| You asked for a time, such as “watch it for two hours” | That long, at most a day |
| The provider keeps a history of these runs | About twice as long as they usually take, rounded up to whole five minutes, between ten minutes and a day |
| No history, but Halon remembers how long it takes | About twice what it remembers |
| Neither | An hour, and Halon says so |
Ask Halon for longer at any time, up to a day from when the watch started.
How often it reads
Section titled “How often it reads”Each watch has a ceiling on how often it reads your providers, so it never runs into a provider’s rate limit or runs up its cost. By default that is 120 reads an hour for each thing it follows, which leaves room for a check every minute. Halon sets it lower when a provider documents a tighter limit.
The card shows the ceiling and how many reads the watch has made so far, such as Reads at most 120 times an hour. 14 reads so far. When a watch reads more than usual, such as several things at once, it spaces its checks so its reads last the hour. If it still reaches the ceiling, it says so once and checks again when the hour is up.
What it tells you
Section titled “What it tells you”Halon says one short line when something you asked about happens, and one when the watch ends:
| When | What it says |
|---|---|
| A run you asked to hear about starts | Web deploy started. |
| Jobs or steps inside a run start or pass | One line per check for everything that moved, such as Release run: tag passed, trigger-northflank running. |
| A run or a job in it waits for a person, such as a deploy waiting for approval or a manual job | Once, in the same line as other progress, such as Deploy: build passed, production waiting for someone to approve or start it. |
| A job or step inside a run fails while the rest still runs | At once, which job and step failed, how long in, why from that job’s own log, and a link to it |
| A run succeeds | Release run #46 succeeded after 17 minutes. |
| A run goes well past its usual time | That it is taking longer than usual, once |
| Everything finished | Done, with how long it took |
| Something failed | What failed and why. Halon reads the failed job’s or build’s log first, and the line says what went wrong and links to the run |
| A job or step a reading shows failed while the rest still runs | At once, which one failed and why, from what the reading shows |
| Its time ran out | That it stopped at the time limit, with what it last saw |
| Steps joined the watch | Now also following, with what joined and how long it now watches |
| Halon reopened a step that ended wrongly | Reopened, with why |
| A run it waits for never shows up | After about three minutes, that it could not find it and is finding a better way to follow it |
| The run history it was asked to read holds other kinds of runs | At once, which runs it does hold, such as builds and deploys, so Halon follows it another way |
| The first reading shows nothing to follow, such as an empty list | That the reading showed nothing to follow and it is finding a better way to follow it |
| Halon picked a better read | What actually changed, the read it uses now and the one it replaced, or the same read with what it now asks differently, such as a newer run, and what was wrong with the old one |
| It reached its ceiling on reads | That it made all the reads it allows itself this hour, and when it reads again |
| You stopped it | That you stopped it |
Each line is posted in the chat’s Slack thread when it has one, and in a direct message to you from Firefight in Slack. A direct message about a chat in the dashboard has Open the chat. When the chat is already your direct messages with Firefight, the line is posted there once.
In the dashboard, the watches going in a chat are pinned above the message box under Watching, each with its name, the step it is on and how long it has gone, so they stay in sight however far the chat scrolls. Choose one to open its card there. The strip goes once no watch is going.
Each watch is one card that updates in place as the watch reads, rather than a new line in the chat every minute. Its header names it, such as Watch “Deploy finished”, with how it stands and how long it has gone. Each thing it follows is one row saying where it stands in a few words, such as Building images, 4 of 7 jobs done, and Open the run when the provider gives the run’s page, as each update in Slack does too. A run shows as running as soon as it has begun. Choose Details on the card for how long it watches and why (Up to 40 min. It usually takes about 18 minutes.), its ceiling on reads, and every line it said. Only what you may need to act on shows in the chat on its own: a job or step that failed, something taking longer than usual, and one closing line when the watch ends. Once the watch ends the card shows how, such as Watch “Deploy finished”: done.
When a watch finds nothing to follow
Section titled “When a watch finds nothing to follow”A watch never keeps following nothing. When the run it waits for never shows up, or its first reading shows nothing to follow, such as an empty list or a different run, Halon finds a different way to read it, tries it once, and switches the same watch over to it. The watch says what it changed, and the card shows the step as Finding a better way to follow it while Halon looks. Halon only reads while it does this and changes nothing else.
Halon tries a better read for the same step at most twice. When nothing it can read shows it, or it has not found one within 15 minutes, such as while the chat waits on your answer to something else, the watch stops following that step and says why.
A fresh reading wins
Section titled “A fresh reading wins”When Halon reads in the chat the same thing a watch follows, the watch takes that reading as its own. If the two disagree, such as the watch still saying a run had not started when it had already failed, the watch goes by the fresh reading, the chat in the dashboard shows a line saying so, and Halon tells you in its answer.
Failures are checked twice
Section titled “Failures are checked twice”A reading that looks like a failure ends its step only when the next reading shows the same, so one bad moment does not end a watch. A run’s or a deploy’s own failed status, which the provider reports, ends the step at once. A step reading logs fails only on a line logged as an error or worse, never on a warning or an instance that stopped cleanly.
When a watch ended wrongly
Section titled “When a watch ended wrongly”When you tell Halon a step ended wrongly, or a reading it takes shows so, such as a step marked done from the old container’s logs, Halon reopens it. The step starts over, steps skipped because of it are followed again, and a watch that had already ended goes on with its time limit counted again from now, never past a day from when it started. The watch says Reopened with why. A watch someone stopped stays stopped.
Stopping a watch
Section titled “Stopping a watch”Choose Stop on the card, then Stop watching. In Slack, each update Halon posts while the watch runs has a Stop button, which asks the same question first. You can also tell Halon to stop. The person who asked can always stop a watch. When the chat is in a Slack channel or thread, anyone there can press Stop or tell Halon to stop it too, so a watch never waits on someone who is away. Pressing Stop on an older update after the watch ended tells you it already ended. A chat in the dashboard is yours alone, so only you see its card and can stop it there.
Ask Halon “how is the release going?” at any time. Each watch still going reads again first, so Halon answers from a reading taken then, and says so when it disagrees with what it told you before.
What it can follow
Section titled “What it can follow”Halon follows CI runs and deployments on GitHub, GitLab, Bitbucket and Azure DevOps, CI runs on CircleCI, and builds and deploys on Render, Railway, Fly.io, Vercel, Netlify, DigitalOcean App Platform, Northflank, Cloudflare Workers Builds and Pages, AWS (ECS services, Lambda functions and CodeBuild projects), Google Cloud (Cloud Run and the Cloud Build builds that deploy it) and Azure (App Service and Function apps, and ACR Tasks runs of a container registry), with Trigger.dev task runs and deployments, DigitalOcean App Platform job runs, Render cron runs, one-off jobs and workflow task runs, Railway cron runs, Neon operations, Tinybird jobs, Upstash Workflow runs, ClickHouse service starts and maintenance, PlanetScale deploy requests and branch changes, and Supabase preview branch runs. On a code host, name the environment, such as “tell me when the production deploy finishes”, and when no workflow or pipeline has that name, Halon follows the deployments to it. On GitHub a workflow is found by its name or its file, however long ago it last ran. On Tinybird Halon knows which deployment is live, so “tell me when the new deployment is live” waits for that deployment. On Northflank it also follows a workflow’s runs, the runs of a pipeline stage’s release flow, a job’s runs and a database’s backups, so “tell me when the production release finishes” follows the release itself rather than a build inside it. On AWS it follows CodePipeline executions, CodeDeploy deployments, CloudFormation stack updates, App Runner deployments and Elastic Beanstalk deploys. On Google Cloud it follows Cloud Deploy rollouts and Cloud Run job executions, and on Kubernetes a deployment, statefulset or daemonset rolling out and a job or cronjob running. It can also follow anything Halon can read in a chat, such as a resource coming back to running, a workflow’s newest run through the provider’s API, or one of Firefight’s own reads. When that read answers with a provider’s runs, such as a Northflank job’s runs, the watch goes by that run’s own status, the same as a run history, rather than judging the words. When a provider’s run history does not hold what you want followed, Halon follows it through the provider’s API and only ever reads through it. It can also keep checking a page in its browser until the page loads with no console errors, and a watch never sends anything from a page. A watch that follows the same read as an earlier one learns how long it usually takes from it, which sets its time limit and when it says something is slower than usual.
A watch follows the exact run you or Halon named, however many newer runs started after it, and links to that run’s own page where the provider has one. It also sees the steps inside a run where the provider lists them, so each one is reported as it starts or passes, and the first one that fails is reported at once while the run is still going, with the error it gave, how many times it was retried, and why from that step’s own log:
| Where | The steps a watch sees |
|---|---|
| GitHub, GitLab, Bitbucket, CircleCI | Each job or step of the CI run, and on GitLab each job of the child pipelines it starts in the same project |
| Azure DevOps | Each job of each stage |
| Render | Build, pre-deploy and deploy |
| Railway | Each step of the deployment, such as build, pre-deploy command and healthcheck |
| Vercel | The build, and the checks when the project runs any |
| DigitalOcean App Platform | Each step of the deployment, per component, such as building web. A job run is one step, with its own log |
| Cloudflare Pages | Each stage of the deployment |
| Trigger.dev | Each attempt of the run. A deployment lists no steps |
| AWS | The ECS rollout and any rollback, each phase of a CodeBuild build, each action of a pipeline, each lifecycle step of a deployment and each resource a stack update changes |
| Google Cloud | Each condition of a Cloud Run revision, each step of a Cloud Build build, each job of a rollout and each task of a job execution |
| Azure | Each entry of the deployment’s log |
| Northflank | Each step of a workflow or release flow run, such as a build, a job run, a release or an approval |
| Kubernetes | Each pod of a run |
Fly.io, Netlify, Lambda, ACR Tasks and Cloudflare Workers Builds list no steps inside a run, and neither does a deployment followed on a code host, so a watch says when the whole run starts and ends. A Cloudflare Workers build that fails says why from the build’s log. A Lambda function keeps only its newest update, so a watch follows that update until it succeeds or fails.
A run held for a person is shown as waiting, never as queued, so you can see it needs someone, and it is never called slower than usual while it waits. That covers a GitHub run waiting for an environment’s reviewers or for approval to run at all, a GitLab manual job or a deployment waiting for approval, a Bitbucket pipeline paused or halted at a manual step, and an Azure DevOps stage waiting for an approval. Halon can approve a waiting GitHub, GitLab or Azure DevOps deployment, or start a GitLab manual job, when you ask. Bitbucket offers no way to start a manual step from outside, so you do that in Bitbucket. When a run fails, the reason comes from that run’s own log, never from a newer run’s.
A run on GitHub, GitLab, Bitbucket, Azure DevOps or CircleCI, and a deploy on Netlify or Vercel, is checked the moment the provider says something moved, rather than at the next minute. On Azure DevOps that includes a stage or job moving, an approval waiting and a classic release deploying, and Vercel says so for every deployment, a preview’s too, its checks and a rolling release. So is a PlanetScale deploy request moving, a Railway deployment in any environment of the project, and a Trigger.dev environment when one of the alerts you send to Firefight arrives, such as a run or a deployment failing (see live updates from Trigger.dev). A Cloudflare Pages deployment is checked the moment Cloudflare sends its notification, once you set it up (see live updates from Cloudflare). Workers Builds sends nothing outside Cloudflare, so a watched Worker’s builds are checked every minute. A DigitalOcean app is checked within about 6 minutes of a deployment or an autoscaling moving. A Northflank release flow’s run wakes a watch as it moves, so you hear within seconds. So do AWS pipelines, deployments, stacks, App Runner and Elastic Beanstalk in a region that has Firefight’s stack (see live updates from AWS), and Kubernetes rollouts, jobs and Warning events within a couple of minutes. An ECS deployment finishing in a region without the stack is noticed within about 10 minutes, and a Cloud Build build starting or ending within about 6 minutes. With Azure’s instant updates turned on, an Azure change reaches a watch within about a minute (see live updates from Azure). A Google Cloud rollout or job execution finishing is checked every minute. A Northflank workflow’s run is checked every minute. When Halon follows a run through a provider’s API, it reads that one run, says when it has begun, and reports the jobs or steps the provider lists the same way.
When the provider keeps no history of its runs, Halon says so and what it cannot follow, and watches the rest. A workspace keeps at most 20 watches going at once.