---
title: "What Halon can do"
description: "The tools Halon reaches through your integrations and the resource map, how it picks a connection, when it asks you first, and where every call it makes is recorded."
canonical: https://firefight.app/docs/ai/tools-and-approvals
---

# What Halon can do

Halon works through tools. Some are Firefight's own, such as declaring an incident or reading the resource map, and the rest come from the integrations your workspace connects, such as reading a service's logs or rolling it back.

What Halon can reach depends on which tools are switched on for each connection, what the person asking may do, and the approval rules on your workspace. This page covers all three. For chatting with Halon see [Chat](https://firefight.app/docs/ai/chat.md), and for investigations and fixes see [Investigations](https://firefight.app/docs/ai/investigations.md).

## Tools from your integrations

Every capability of a connection arrives switched on, and an admin can switch any of them off under **Configure → Integrations**, described in [Connect an integration](https://firefight.app/docs/api/integrations.md). In a chat Halon works as the person asking, so it reads every connected tool for any member, and it changes something only for someone who holds that tool, usually through the connection's changes pack. When it is not allowed to, it names the pack you need and your workspace admins, and offers **Ask an admin**, see [Asking an admin for a pack](https://firefight.app/docs/gateway/permissions#asking-an-admin-for-a-pack). To see what Halon does with a provider before you connect it, choose the info button on its card. The dialog has a **With Halon** section naming what Halon can do through it, and a **What it may change** section.

The Integrations page groups providers by what they are. Halon reaches the same groups.

| Category | What Halon reads | Changes it can make, when you allow them |
|---|---|---|
| Cloud and hosting | Logs, metrics, deploys and status of the services, workers, jobs, sites and databases a provider runs, with their builds, cron runs, one-off jobs and other runs. On Railway also request traces, and on Convex the deployment's usage beside its limits | Roll back, restart or scale them, and cancel, redeploy, stop or suspend them where the provider allows it. In Cloudflare, also block IPs, add rules, purge the cache, retry a Pages deployment, cancel a Workers build or split a Worker's traffic. See [Changes on each platform](#changes-on-each-platform) |
| Observability | Logs, metrics, traces and errors of the services a tool watches, plus monitors and uptime checks | Any write tool you switch on |
| Alerting and on-call | Who is on call, and the alerts and incidents paging them | In PagerDuty, acknowledge, escalate or add responders. In Opsgenie, acknowledge, escalate or add a note |
| Product analytics | How many users an incident reaches, what they did and saw, and recent feature flag changes | Turn a feature flag off in PostHog, or change one in Mixpanel |
| Databases | Read-only queries, schemas, state and metrics, the slowest and costliest queries, usage, backups, and changes such as schema deploys and resizes | Restart, start, resize or restore a Neon branch's compute or data, scale, start or stop a ClickHouse service, restore a Turso or Upstash database, pause a QStash schedule, act on PlanetScale deploy requests and branches, and restart or restore a Supabase project. See [Changes to databases](#changes-to-databases) |
| Code | Pull or merge requests, commits, deployments, CI runs and the code itself. On GitHub and GitLab also each repository's deployment environments and what holds a deploy to them. On GitHub also issues, checks, releases, branches and security alerts. On GitLab also releases and tags. On Bitbucket also tags and a step's test reports. On Azure DevOps also pipeline runs with their stages and jobs, the approvals a run waits on, what each environment received and classic release deployments | Rerun, start or cancel a GitHub workflow, or rerun one of its jobs. On GitHub, comment on, review, label, close, reopen or merge a pull request, open, comment on, label, assign or close an issue, write a draft release, make or delete a branch, dismiss a Dependabot alert, and approve or reject a deployment waiting for an environment's reviewers. Retry, run or cancel a GitLab pipeline, retry, start or cancel one GitLab job, approve or reject a GitLab deployment waiting for approval, and stop a GitLab environment. Rerun, run or stop a Bitbucket pipeline, also on one commit. Run, rerun the failed jobs of or cancel an Azure DevOps pipeline run, and approve or reject an approval it waits on. Deploy an earlier deployment again on any of them |
| CI | CircleCI projects with their runs, workflows and failing jobs with their logs and tests, how each branch stands, and what each project deployed to each environment | Rerun or cancel a CircleCI workflow, approve a job a workflow holds for a person, run a project's pipeline, or roll a deployed component back |
| Coding agents | The session or run Firefight handed a code change to | Hand a fix's code change to Devin, Cursor or Factory, which writes it and opens the pull request |
| Issues | Linear and Jira issues, projects and cycles | Open an issue for follow-up work |
| Knowledge | Notion and Confluence pages, such as runbooks and architecture notes | Any write tool you switch on |
| Custom | Whatever tools you allowlist on your own MCP server | Whatever tools you allowlist on your own MCP server |

Providers can offer more tools than the table names, and each one that changes something is marked **write** on the connection. With GitHub connected, Halon can also read the source and bundled docs of a library your repository depends on, at the exact version the repository installs.

When Halon opens an issue in a chat about an incident, Firefight keeps that issue on the incident as an action while the incident is live, or as a follow-up once it is over. Closing the issue in the tracker completes it on the incident.

### Reading your databases

Ask Halon for something stored in a connected database, such as "how many workspaces signed up this week", and it first reads the table and column names from your application's repository on a connected code host, such as `db/schema.rb`, `db/structure.sql`, `prisma/schema.prisma` or your migrations. Then it writes the query. When no repository it can read holds them, it reads the database's own schema for those tables first. It never guesses a table or column name.

Halon queries the primary database, which has the latest data. It reads a replica only when the primary is slow or refuses the query, and then says the answer came from a replica, which can lag behind the primary.

A read from ClickHouse, Neon, PlanetScale, Supabase, Turso or Upstash that has not answered after 15 seconds is stopped, so one slow provider does not hold up the chat. Halon tries the read once more, and if the provider is still slow it gets what it needs another way, such as from your repository or another of the provider's tools. Its answer says the provider was slow and what it did instead. A database you connect by its URL already stops any query after 10 seconds, see [Connect an integration](https://firefight.app/docs/api/integrations.md).

### GitHub pull requests and issues

Ask Halon in a chat to act on a pull request, such as "close PR 412, it is superseded by 413" or "approve PR 412", and it calls the tool for that, never a code change. Each one runs as you, so a member needs the connection's changes pack, and an approval rule can hold it like any other change.

- **Merging** happens only when GitHub says the pull request can merge, with no conflicts, no failing required check and no missing review. When its branch is behind, Halon can bring it up to date first when you ask.
- **Labels** are added only when the repository already has them. Halon names the ones it has when you ask for one it does not.
- **Releases** Halon writes are drafts. You publish them on GitHub.
- **Branches** Halon makes are named under `halon/`, and it deletes only those, never the default branch, a protected one or one an open pull request comes from.
- **Secret scanning alerts** say what kind of secret was found and whether it still works, never the secret itself.

To change the code of an open pull request, ask Halon to make the change on that pull request. Its agent writes the change from the pull request's latest commit, adds it to the pull request's branch as a new commit, and comments on the pull request with what changed. It never pushes to a pull request from a fork, the default branch or a protected branch, and if someone pushes to the branch while the agent works, nothing is overwritten and Halon tells you.

An issue Halon opens on GitHub in a chat about an incident is kept on the incident the same way as a Linear or Jira issue, and closing it from a chat completes it.

### One tool for each question

Halon asks for logs, metrics or a rollback the same way whichever provider holds the resource. It names the resource as it appears on the [resource map](https://firefight.app/docs/catalog/map.md), and Firefight sends the call to the connection that runs it or watches it.

| Tool | What it does |
|---|---|
| `search_logs` | Log lines of a resource, newest first, filtered by text or a pattern. It can read what the app prints, its builds, the requests reaching it, calls between services, CDN logs, a database's backups and restores, or a backend's own sign-in, file storage and realtime services, where the provider keeps them. For a Northflank job, a Cloud Run job, a Cloud Deploy rollout, a Render one-off job or a Render workflow's task run it can read one run's lines alone |
| `query_metrics` | Metrics over time, such as CPU, memory, requests, 4xx and 5xx responses, p95 latency, network, open connections and disk, each with its low, average, high and latest value. You see each metric as a chart |
| `search_traces` | Request traces through a resource, slowest or failed first |
| `search_errors` | Errors a resource raised, grouped by kind with how often each happened. For a database it lists the queries that cost the most or failed, such as the slowest queries on a Neon branch, a Turso database's top queries, a PostgreSQL database's costliest queries beside its rollbacks and deadlocks, or PlanetScale's failing queries |
| `recent_deploys` | What went out to a resource, newest first, with when, which commit or version, and who. For a repository that deploys to several environments, such as production and staging, Halon can ask for one |
| `resource_status` | How a resource is set up and how it stands now |
| `run_history` | Recent CI runs, builds, deploys or release runs of a resource, each with how it went and how long it took, and how long they usually take, or one run with its steps. Halon uses it to [watch](https://firefight.app/docs/ai/watching.md) a run and to learn how long to watch |
| `rollback` | Puts a resource back on an earlier build or version |
| `restart` | Restarts a resource that is stuck while its code is fine |
| `scale` | Sets how many instances a resource runs, or the size it runs at where the provider has one, such as a Northflank plan, a Fly.io machine size, a Neon compute's size, a ClickHouse service's memory per replica or a PlanetScale Postgres branch's cluster size |

Each of these runs as the provider's own tool. That tool has to be switched on, the person asking needs permission to use it, and its approval rules apply, exactly as if Halon had called the provider's tool by name. If the tool behind it is switched off, Halon says so and that an admin can switch it on in Integrations.

Rolling back, restarting and scaling are available where the provider supports them.

| Change | Providers |
|---|---|
| Roll back | AWS (ECS services, Lambda functions, a CodePipeline stage, a CodeDeploy deployment and a CloudFormation stack update), Azure, Azure DevOps, Bitbucket, CircleCI, Cloudflare (Workers and Pages), DigitalOcean, Fly.io, GitHub, GitLab, Google Cloud (Cloud Run, and a Cloud Deploy stage), Kubernetes, Modal, Neon (branches, to a snapshot, their parent or a moment), Netlify, Northflank, PlanetScale (deploy requests), Railway, Render, Supabase (preview branches, and a project's database to a moment), Trigger.dev, Turso (as a new database from a moment), Upstash (a Redis database, to one of its backups), Vercel |
| Restart | AWS (ECS services, and a reboot for EC2 instances and RDS databases), Azure (apps and PostgreSQL servers), DigitalOcean (apps, and a reboot for Droplets), Fly.io, Google Cloud (Cloud SQL and virtual machines), Kubernetes, Modal, Neon (computes, and starting a suspended one), Northflank (services and databases), Railway (services and databases), Render (services and databases), Supabase (projects) |
| Scale | AWS (ECS services), Azure, ClickHouse (a service's replicas and memory), DigitalOcean, Fly.io (how many machines an app runs, and their size), Google Cloud (Cloud Run), Kubernetes, Neon (a compute's size), Northflank (services, database replicas, and a job's plan), PlanetScale (a Postgres branch's cluster size and replicas), Railway (region by region for a service in several regions), Render |

On AWS, a rollback of a release that is still going stops it and undoes it. Name an ECS deployment from **recent deploys** and the service goes back to the revision it ran before, name a CodeDeploy deployment and what it changed is rolled back, and on a CloudFormation stack the update going now is cancelled and the stack goes back to how it was. A CodePipeline stage goes back to what an earlier successful execution deployed there, named as the stage and the execution, such as `Deploy:1a2b3c4d-...`, or the execution alone when only one stage deploys. Halon can also stop a pipeline execution, an ECS deployment or a CodeDeploy deployment without rolling anything back. A Lambda function rolls back by pointing its alias at an earlier version. A weighted split on that alias, such as a canary sending 10% to a newer version, is taken off at the same time, so every request reaches the version you named, and Halon's answer names the split it took off and how to set it again. Halon can reboot an EC2 instance, which keeps its addresses and disks, and an RDS database, which drops its connections until it is available again, usually within a few minutes. For a Multi-AZ database it can reboot by failing over to its standby instead. A reboot always asks first and has nothing to undo. App Runner services and Elastic Beanstalk environments are read, and Halon makes no changes to them.

On Google Cloud, a Cloud Deploy stage rolls back to an earlier release, which runs the stage's jobs again and may wait for an approval like any rollout. Halon can also cancel a rollout that has not finished. When you ask, it approves a rollout waiting for an approval, or starts the next phase of a canary waiting to be advanced, after reading the rollout and asking you to confirm. Approval rules apply as to any change, and Halon never approves or advances on its own, while investigating or while watching.

On Azure, an App Service or Function app rolls back by swapping a deployment slot with production. Halon reads which settings differ between the slot and production, which you can also ask for on its own, and the answer after the swap lists them. An app setting or a connection string is named, never shown. Halon follows the swap for up to 25 seconds and tells you whether it finished, failed and why, or is still going. Do not swap again while it is still going, since a second swap puts production back. An app with no deployment slots has no rollback through Halon, so redeploy the earlier build from your pipeline instead.

On Kubernetes, Halon can pause and resume a deployment's rollout, suspend and resume a cronjob, and start a cronjob's job now, the way `kubectl create job --from=cronjob` does. A paused deployment cannot be rolled back or restarted until it is resumed.

A Northflank service that runs an image from a registry is rolled back to the earlier image, and one in the middle of a canary rollout is rolled back by ending the rollout and returning to an earlier deployment. A release flow's own **roll back to this release** is only in Northflank's dashboard, so Halon rolls back the service it released instead, or gives you that step.

An observability tool such as Datadog answers for a service on the map that it watches under the same name. When both an observability tool and the platform running a service could answer, logs, metrics, traces and errors come from the observability tool, and deploys, status and changes come from the platform. If the observability tool has nothing, Halon asks the platform instead and tells you where the answer came from.

Agents you connect over the [MCP server](https://firefight.app/docs/api/mcp-server.md) get the same tools.

### Changes on each platform

Beyond rolling back, restarting and scaling, Halon can make these changes when you allow them. Each asks you first unless this page or [Halon's safe changes](https://firefight.app/docs/ai/safe-changes.md) says otherwise, and stopping something someone else started asks them too, see [Stopping something someone else started](https://firefight.app/docs/ai/safe-changes#stopping-something-someone-else-started).

**Cloudflare.** Halon can run a failed Pages deployment again, cancel a queued or running Workers build, and split a Worker's traffic between two of its versions by percentage. It also reads a Worker's builds with their logs, and its newest versions, including any not deployed yet.

**Convex.** Halon reads the deployment's usage today and this month beside its limits, and can pause or unpause the deployment. While it is paused, every function call fails, scheduled functions wait and cron jobs are skipped, and its data is kept. A pause is a [temporary change](https://firefight.app/docs/ai/safe-changes#temporary-changes).

**DigitalOcean.** Before Halon rolls an App Platform app back, it checks with DigitalOcean that the app can go back to that deployment, and tells you why when it cannot. A rollback pins the app, so nothing new deploys, not even on a push, until you keep the rollback or undo it, and Halon can do either. Keeping it means the newer deployment can no longer be put back. Undoing it deploys the app as it was before the rollback, as a new deployment. Halon can also cancel a deployment that is still building or deploying, so the deployment live before it keeps serving, cancel an autoscaling that is still going so each component keeps the instances it runs now, deploy the newest commit of each component's branch again, building it from source when a cached build went bad, and cancel a run of one of the app's jobs that has not finished. A redeploy waits until a rollback pinning the app is kept or undone.

**Fly.io.** Halon can start an app's stopped or suspended machines, stop or suspend its running ones, or one machine you name. It works one machine at a time, waits up to 50 seconds for each, and stops at the first that does not reach the state it asked for. It can also cordon one machine, which keeps it running while Fly's proxy sends it no requests, and uncordon it again. To scale an app, Halon adds machines that copy the app's newest machine, at most 10 at a time, in its region unless you name another, or removes machines, stopped ones first and then the newest. Removing a machine destroys it and keeps its volume. An app with more than one process group, such as app and worker, is scaled one group at a time. Halon does not add a machine that needs a volume, since each new one would need its own, so that step is yours in Fly.io. To resize, Halon gives an app's machines another size, such as shared-cpu-2x or performance-2x, or another amount of memory, one machine at a time. A running machine restarts on its new size, and a stopped one stays stopped. For a Managed Postgres cluster, Halon reads the 20 queries that took the most time in all and the queries running now in each database, with how long each has run and what it waits on, such as a lock. Fly does not offer a cluster's logs or metrics outside its dashboard, so those are on the cluster's **Metrics** tab in Fly.io.

**Modal.** Halon reads the containers an app runs now and one container's logs. It can stop one container, letting it finish the work it holds first when you ask, and stop an app. Stopping an app is for good. It cannot be started again, only deployed anew from its code. Halon reaches only the apps in the environment the connection reads.

**Netlify.** Halon can lock auto publishing on the deploy that is live, so a push to your production branch builds without going live, for example right after a rollback, and unlock it once the fix has shipped. It can cancel a deploy that is still building and start a new build of the production branch or a branch you name, without the build cache when you ask.

**Trigger.dev.** Halon can cancel a run that has not finished, start a run again with the same payload on the current version, and cancel or start again many runs at once, by their ids, up to 500, or by task, status or version, within a time range if you like. It never does that to every run in the environment at once, and it can stop such a bulk action while it is still working, leaving the runs it already did as they are. It can pause and resume a queue or a concurrency limit, set how many of its runs execute at once until it is reset, and reset it to what your code declares. Pausing is a [temporary change](https://firefight.app/docs/ai/safe-changes#temporary-changes), so the queue or limit is resumed after the time you pick unless someone keeps it paused. Halon can also mark an error group resolved, ignored (for good, for a while, or until it happens more often or a number more times) or unresolved again. Marking an error group is a safe change, so it runs without asking, except that ignoring one asks once Halon has read anything from outside in the chat. Resolving or ignoring a group that was unresolved offers **Undo now**. To let Halon make these changes, give the connection an API key whose preset can, such as No restrictions.

**Vercel.** Halon charts a project's requests, 4xx and 5xx responses, function invocations, their duration, time to first byte, CPU time and peak memory, for production unless you ask for every environment. If Vercel does not answer metrics for your team, Halon tells you, with Vercel's reason. It can cancel a deployment that is still building, so it never goes live, and build a deployment again with its current settings, or from the newest commit of its branch. Cancelling asks the person who started the deployment first. When a project runs rolling releases, Halon reads the rolling release and, when you ask, moves it to its next stage, sends all traffic to the new deployment, or stops it by rolling back to the deployment it replaced. After a rolling release is stopped, new deployments no longer go live on their own until you promote one. Halon also reads your team's Vercel CI runs, each job's outcome and its log.

### Render and Railway

On Render, Halon reads your workflows as well as your services and datastores, and follows three kinds of runs besides deploys. A cron job's runs over the last 30 days show how each one ended and why a failed run failed, such as running out of memory. A service's one-off jobs, such as a migration you ran by hand, show their command and how they ended. A workflow's task runs show each task, its retries and the error it gave. When you ask how a service is doing, Halon names the instances running right now, and its metrics include the CPU and memory the service is allowed, how many instances ran, bandwidth for a web service or a static site, and how far a Postgres replica is behind.

| Change on Render | What happens |
|---|---|
| Deploy again | Render builds and deploys the latest commit, one commit you name, or one image tag. Halon can clear the build cache first, or deploy the last build again without building. Autodeploy stays as it is |
| Cancel a deploy | A deploy that is still building or going live stops, and the deploy that was live keeps serving. When Render recorded who started it, they are asked first. A cron job's deploys cannot be cancelled |
| Turn autodeploy off | Render stops deploying each new commit on its own, so after a rollback the next push does not bring the bad code back. This is a safe change, so it runs without asking and offers **Undo now** |
| Turn autodeploy on | Render deploys each commit again, or each commit once its checks pass |
| Autoscaling | Halon turns autoscaling on or off, or changes the fewest and most instances and the CPU and memory use it aims for. What you do not mention stays as it is. While autoscaling is on, Render ignores a set number of instances, so Halon changes autoscaling instead of scaling |
| Run a cron job now | Render starts a run outside its schedule, and cancels a run of it that is already going first |
| Cancel a run | A cron job's run, a one-off job or a workflow's task run that is still going stops. What it already did stays done, and a cron job's next scheduled run still starts |
| Run a one-off job | Halon runs one command on a copy of a service, such as a migration or a script that repairs data. The job runs with every secret the service holds, so a person is asked every time, even when you allowed Halon's changes for the rest of the chat. The request shows the exact command and the service |
| Run a task | Halon starts a run of one of a workflow's tasks with the input it takes, such as running again a task that failed on something now fixed |
| Suspend | A service, Postgres database or Key Value instance stops running and serving until it is resumed |
| Resume | A suspended service, Postgres database or Key Value instance starts again. A service comes back on its last deploy |

A command or task input that looks like it holds a secret is refused, since Firefight never sends a credential through Render.

On Railway, Halon also reads request traces and each cron job's runs, and median, 95th and 99th percentile latency for traffic through a public domain. Railway traces a service only once tracing is on for it in that environment, on its **Traces** page in Railway.

| Change on Railway | What happens |
|---|---|
| Redeploy | Railway builds the same code with the same settings as a new deployment |
| Cancel | A deployment still queued, building or deploying stops. The deployment serving before it keeps serving |
| Stop | The deployment serving now stops, and the service serves nothing until it is redeployed or a new deployment goes live |
| Approve | A deployment Railway holds for approval, such as a push by a GitHub user with no linked Railway account, builds and deploys |

When Railway names who started a deployment, they are asked before Halon cancels or stops it. A Railway service that runs in several regions is scaled one region at a time. Name the region, such as "scale web to 3 replicas in us-west2", and the other regions keep their replicas. A region can go to 0 while another still runs replicas, and the total across regions is at most 50. Adding a region the service does not run in yet is done in the service's settings on Railway.

### Changes to databases

Every change to a database asks you first. A pause of a QStash schedule is also a [temporary change](https://firefight.app/docs/ai/safe-changes#temporary-changes).

**Neon.** Halon rolls a branch back to one of its snapshots, resets it to its parent, or restores it to how it was at a moment within the project's history window. When other branches were made from it, or when it restores to a moment, Halon keeps the branch's state before as a new branch named like `main-before-rollback-10201500`, branches made from it move onto that one, and the confirmation names it before you agree. Restoring to a moment drops open connections while the computes move onto the restored data. Halon resizes a compute to one size, such as `2` compute units, or an autoscaling range, such as `0.25-4`. Neon restarts the compute to apply it, so open connections drop for a moment. Asked to restart a compute that Neon has suspended, Halon starts it instead. Halon also reads a project's compute time and data sent out as charts, where Neon keeps consumption history for your account. Restoring to a moment and reading consumption need Neon connected with an API key, see [Connect an integration](https://firefight.app/docs/api/integrations#one-click).

**ClickHouse.** Halon scales a ClickHouse Cloud service's replicas, from 1 to 50, the memory each replica scales between, from 8 to 356 GiB in steps of 4, and whether it scales to zero when idle and after how many minutes, at least 5. It tells you how the service scaled before and after. It can start a stopped service or wake an idle one, and stop one. A stopped service answers no query until it is started again. Halon also reads your organization's activity log, such as who started, stopped, scaled or upgraded a service and when, and a service's backups. These need ClickHouse connected with an API key whose role allows each one. A connection made by signing in only reads, and Halon says so if you ask it for one.

**Turso.** Turso never changes a database in place to undo something. When you ask Halon to roll back a Turso database to a moment, it makes a new database from it as it was then, named like `orders-restored-20261020143000`, within Turso's point in time window, and leaves the original as it is. Check the data in the new database, then point your application at it. Halon also reads a database's usage, rows read and written, storage and bytes synced, for this month or a period you name.

**Upstash.** Halon can pause a QStash schedule that keeps sending to a destination that is down. When Upstash Workflow runs failed and their cause is fixed, it can resume them from the step that failed, or restart them from the beginning. When QStash messages ended in the dead letter queue because their destination was down, it can deliver them again once the destination answers, and says how many and where. It can restore a Redis database from one of its backups, which replaces everything written since, so Halon can take a backup first. Restoring a backup needs Upstash connected with an API key. Halon also reads Upstash Workflow runs and the logs and metrics of a Box.

**PlanetScale.** Halon reads a database's deploy requests with each schema change they make and why one failed, the changes made to a branch's size and settings, a branch's CPU, memory and disk, and its failing queries. It rolls a schema change back by reverting its deploy request, named by its number, while PlanetScale still keeps its revert window open. When you ask, it cancels a queued deploy request, cuts a waiting one over, applies a gated one, completes one that errored, ends a deploy request's revert window, resizes a Vitess keyspace or its VTGates, and promotes or demotes a branch. A Vitess database is sized per keyspace, so Halon names the keyspace rather than using **scale**. Cancelling a deploy request names who opened it on the confirmation, so you can check with them first. These reach PlanetScale's API, which a connection made with a service token reaches only with the token's id, see [Connect an integration](https://firefight.app/docs/api/integrations#one-click).

**Supabase.** Halon resets a preview branch to an earlier migration, and restores a project's database to a moment you name with point-in-time recovery, which must be on for the project. Every change after that moment is lost, and the project is unavailable while it restores. It can also restart a project. Halon reads a preview branch's runs, the ones that clone, migrate, seed and deploy it, with what each printed, each of a project's services with whether it is healthy, the project's CPU, memory and disk use now, and its backups with how far back it can be restored.

### Code hosts and CI

On GitHub, GitLab, Bitbucket and Azure DevOps, a repository rolls back by deploying an earlier deployment again. Ask Halon for a repository's recent deploys, name the one to go back to, and Halon runs again what made it, on that deployment's commit. On GitHub that is the GitHub Actions job that made the deployment, with the jobs that depend on it. A deployment another system made, such as a hosting platform that records its deploys on GitHub, is rolled back on that system instead. On GitLab it is the job that made the deployment. On Bitbucket it is the pipeline that made it, from the start, and a deployment step you start by hand still waits for you in Bitbucket. On Azure DevOps it is the stage that made it, or the classic release's stage. When the environment needs an approval, the deploy waits for it like any other.

On GitLab, Halon can also start a manual job, approve or reject a deployment waiting for approval where your GitLab offers deployment approvals, and stop an environment.

On Azure DevOps, a pipeline is on the map as well as its repository, so `recent_deploys`, `run_history`, `search_logs`, `resource_status` and `rollback` answer for either. Name the pipeline, such as checkout-ci, and Halon reads its own runs. A CircleCI project is on the map as a pipeline and answers the same way, see [CircleCI](https://firefight.app/docs/api/integrations#circleci).

## The map and search

Halon finds where something lives on the resource map before it asks you. Asked about a domain, a service or a database, it looks it up on the map, the catalog, what the workspace remembers and past incidents, then tells you what it found and asks only to confirm it or to choose between what it found. It asks outright only when nothing in Firefight can tell it.

| Tool | What it does |
|---|---|
| `get_resource_map` | Reads the map, starting from the connections, for where something runs and which provider and account hold it |
| `search_map` | Searches the map, the catalog and confirmed memories at once, by a name, an id or what a service does |
| `find_resources` | Finds resources by what they are, where they run and who owns them |
| `get_resource` | Reads one resource, with its key checks and the log lines it usually prints |
| `get_resource_links`, `get_resource_neighbours` | What a resource depends on and what depends on it |
| `traverse_resource_map`, `blast_radius` | Walks the links further, and lists what fails with a resource |
| `resource_map_stats` | The map in numbers, by provider, kind, account or environment |
| `suggest_resource_link` | Suggests a link Halon found evidence for, which someone confirms on the Map page |
| `run_key_query` | Runs one of a resource's [key checks](https://firefight.app/docs/catalog/map#key-checks) and compares the reading with what is normal for it |
| `new_log_patterns` | Finds the log lines a resource printed recently that it did not print in the last week, see [Usual log lines](https://firefight.app/docs/catalog/map#usual-log-lines) |

Halon only sees the resources in the environments the person asking can read. See [The resource map](https://firefight.app/docs/catalog/map.md) for the map itself.

## Firefight's own tools

Halon also uses Firefight's own tools, the ones an agent gets over MCP. It can search and read incidents, run one (declare, post an update, resolve, escalate, invite people, assign roles), manage action items and runbooks, work on postmortems, search alerts and try routing rules, read and edit the catalog, and change workspace setup, permissions, agents, API keys and Firefight's outbound webhooks. Each one needs the same permission it needs anywhere else.

## Providers' documentation

Before Halon works out how a provider does something, such as which parameters a webhook takes or which API call exists, it searches that provider's documentation and cites the page it used. See [Providers' documentation](https://firefight.app/docs/ai/provider-documentation.md).

When Halon cannot do or check something, it says first, in one line, exactly what is missing, such as a tool that is switched off or a permission a connection lacks, and how to add it, then gives you the steps.

## The web

Halon can search the public web and read a page, such as a library's documentation, a provider's status page or an error message nobody on your team has seen, and it cites the address of what it used. A search never carries anything that looks like a credential.

Web search is on by default. Admins turn it off with **Let Halon search the web** under **Settings → Workspace**. When it is off, Halon works only from what your connections and code show. A workspace can make 1,000 web lookups a day.

## The terminal

Halon runs commands and scripts in a sandbox of its own, to work through a large result, call your tools in a loop or check an address from outside. Its calls to your tools go through Firefight like any other, and a command that changes something asks you first. See [Halon's terminal](https://firefight.app/docs/ai/terminal.md).

## The browser

Halon opens your site in a real browser on a desktop and a phone screen, follows the steps a person takes and shows you a screenshot. Looking never asks, and a step that would send data, such as submitting a form, stops until you confirm it. See [Halon's browser](https://firefight.app/docs/ai/browser.md).

## Who Halon acts as

In a chat, every call Halon makes runs as the person who asked. Halon reaches exactly what that person can reach in the dashboard, so it can do for an admin what an admin can do, and it is refused where a member would be refused. When a call is refused, Halon tells you and that a workspace admin can grant it. See [Permissions](https://firefight.app/docs/gateway/permissions.md).

An investigation runs as Halon itself rather than as a person, and only reads. See [Investigations](https://firefight.app/docs/ai/investigations.md).

## Asking before a change

In a chat, Halon stops and asks you before it:

- Makes a risky change through a connection, such as a rollback, a merge or purging a cache. A safe change, such as assigning someone to an issue or restarting a service that runs more than one copy, runs without asking and shows in the chat, with Undo where there is a fixed way to put it back, and your admins can list risky changes Halon may make without asking. See [Changes without asking](https://firefight.app/docs/ai/changes-without-asking.md)
- Deletes something in Firefight, revokes a token or a grant, or changes workspace settings
- Makes a call an approval rule covers and you are allowed to approve yourself
- Changes who may do what, a credential, an approval or a webhook, such as granting a permission, creating an API key or an agent, approving a request or changing an approval rule

Reads never ask, and neither do ordinary changes inside Firefight such as posting an incident update.

### Halon reads before it proposes a change

Before Halon changes something real in a chat, such as a rollback, a restart, scaling, a change to data or configuration through a connection, or resolving, cancelling, deleting or revoking something in Firefight, it reads what shows the change will help and names those reads with the change. Smaller writes in Firefight, such as an action item, an incident update or a timeline note, need no read first.

When you agree to what Halon proposed in its previous answer within 10 minutes, it goes ahead on the reads it already made. After that, it reads again before it asks. What a [specialist](https://firefight.app/docs/ai/helpers#specialists) reported is not enough, so Halon makes the read that backs the change itself.

**Details** on the question shows those reads under **Why**, each with what it showed, so you approve the reasoning and not only the call. The same list is in the details of the question Halon posts in Slack.

### Before a rollback

A deploy carries every commit since the one before it, even when its title names only the newest. When Halon reads a resource's deploys and a code host holds its repository, it also reads what the live deploy carried: how many commits and changed files, the newest commits and any migrations. Before Halon asks you to roll back, it says what rolling back to that deploy undoes, every commit and migration included, and that the old version would then run against the database those migrations left. A rollback whose span cannot be read is put to you as it is.

The question is short. It says what Halon wants to do, such as "Halon wants to: add a commit to PR #856", and one line under it. That line says what the change does when Firefight knows it does more than a plain change, such as "Changes rows in PlanetScale.", otherwise Halon's own reason, such as "Address the review comments on PR #856 as you asked." When Halon read text from outside Firefight before asking, such as an issue, a pull request comment or a web page, and that text names something in the change, the line ends with "It read text from GitHub that other people wrote. Check this is what you want." Check the request is yours before you approve it.

**Details** holds everything else: what the call reaches, such as the resource and connection it runs through, Halon's sentence in full, what the change touches, the reads Halon based it on, the tool and exactly what it was given, and everything it read from outside before asking. In Slack, **Details** opens it in a window.

Answer it with one of these:

| Dashboard | Slack | What happens |
|---|---|---|
| **Approve** | **Approve** | Runs this call |
| Tick **Allow for the rest of this chat**, then **Approve** | **Allow for this chat** | Runs this call, and the same tool stops asking for the rest of the chat |
| **Cancel** | **Cancel** | Nothing runs, and Halon carries on without it |

In Slack, the question is posted in the thread. Allowing for the chat is offered only where it may be. It never covers a call an approval rule holds, a change to permissions, credentials, approvals or webhooks, a write to database rows or a send from a page in [Halon's browser](https://firefight.app/docs/ai/browser.md). Once anything from outside has reached the chat, it stops covering later calls and is no longer offered, so those ask every time. That includes the answer of any tool, Firefight's own included, a file someone attached, a memory nobody has confirmed, the incident's name and what its investigations found, so in a chat about an incident it is not offered at all. See [Until Halon reads something from outside](https://firefight.app/docs/ai/changes-without-asking#until-halon-reads-something-from-outside).

Once you answer, the same Slack message changes to say how the call stands, so you can see it without scrolling:

| The message says | When |
|---|---|
| Approved by you, working | The call is running |
| A checklist (**Write the change**, **Check the change**, **Open a pull request**) | A code change is running. Each part is ticked as it finishes, with how many files changed |
| **Done**, with a link | The call ran. A code change links to its pull request |
| **Failed**, with why | The call did not go through |
| **Cancelled by** you | Nothing ran |

**Details** stays on the message after you answer.

When an approval rule covers a call and you may approve your own request, confirming it is your approval, recorded on the **Approvals** page under your name. When the rule needs someone else, Halon does not ask you first. The request goes straight to its approvers as described in [Approvals](https://firefight.app/docs/gateway/approvals.md), so nobody is asked twice. Their request shows the warning your card would have, when Halon read text from outside first, and for a change to database rows, the rows it touches. A change to who can reach something or to a secret still asks you on your card as well. Halon tells you the call is waiting for approval and carries on with what it can reach without it.

### Waiting for someone else's approval

When an approval rule needs someone else to approve a call, Halon asks for it where you are talking to it. In a Slack thread, the request is posted in the thread, such as "Halon wants to: scale web to zero", with who may approve it and **Approve**, **Deny** and **Details**. Its approvers are asked wherever the approval rule says. On **Default**, which a new rule starts on, that is a direct message to each approver, so the request stays out of the shared incidents channel. On the dashboard, the card in the chat shows it waiting.

As soon as an approver approves it, the call runs, with nothing else to press. It runs as you, since you asked for it. The same message then shows the run as it goes, a checklist for a code change, and ends by saying it is done with a link to what it made, or that it failed and why. Every direct message an approver got says the same once it ends. If the request is denied, the message says who denied it and that nothing ran. When the chat is on the dashboard, you get a direct message in Slack once it starts running, with a link to open the chat.

When an agent connected over MCP asks Halon through `ask_halon`, a call an approval rule holds does not run later, even once approved.

## When you have several connections to one provider

A workspace can connect the same provider more than once, such as two Northflank projects or two Cloudflare accounts. Firefight names each connection by its name and the provider's, such as Faylee (Northflank), and that name is shown on:

- Each step in a chat or an investigation that went through a connection, such as "Api request · Faylee (Northflank)"
- The confirmation question, together with what the connection reaches, such as a project
- Approval requests in Slack and on the **Approvals** page
- Rows in [Activity](https://firefight.app/docs/gateway/activity.md), and the `search_activity` and `search_approvals` MCP tools

Each connection's tool reaches only that connection's account. When more than one connection could answer for a resource and the call does not say which, it does not run. Halon then picks one, following your [instructions](https://firefight.app/docs/ai/instructions.md) when they say which to ask, or asks you which you mean. A read can ask every connection at once, with each answer headed by the connection it came from. A change always goes through exactly one.

Two checks stop a change from reaching the wrong account. If what Halon wrote about a change names a different connection to the same provider from the one the call would run through, the call is refused before you are asked. If what a confirmed call reaches changes between your answer and the call running, because a connection or the map changed, it does not run, and Halon tells you and asks again.

When an admin adds, removes or renames a connection, or switches tools on or off, during a chat, the change applies from Halon's next step, without starting a new chat.

## What shows as failed

A step in a chat shows **Failed** when the call was refused, by permissions or by one of the checks above, and when the tool answered with an error of its own. A step one of Firefight's own rules stopped shows **Refused** with the rule's reason, in the dashboard and in Slack. When the tool answered with an error, Halon reads it and tries another way before telling you something is out of reach.

A refusal is final. Halon tells you plainly that Firefight refused the call and why, and does not look for another way around it. Firefight's own rules include the paths Halon may not change in a code host's repositories, never pushing to the default branch or a protected branch, deleting only a branch Halon made, merging only a pull request that is ready, only reading a connected database, and only reading while investigating. When the rule is a setting, such as the paths Halon may not change, Halon names where an admin changes it.

In [Activity](https://firefight.app/docs/gateway/activity.md), a call refused for lack of permission shows as `deny`, a call one of Firefight's own rules stopped shows as `refused` with the rule's reason, and a call the tool answered with an error shows as `error` with the first line of what the tool said.

## Every call is recorded

Every call Halon makes to a connected tool is in [Activity](https://firefight.app/docs/gateway/activity.md) under **Gateway → Activity**, reads included.

| Call | Recorded under |
|---|---|
| A chat | Halon with whose access it used, such as Halon, for Maya Ortiz |
| An investigation | Halon, with the source **Investigation** |
| Reading what a connection holds onto the map, including the daily read of usual log lines | Firefight map sweep, with the source **Map sweep** |
| A key check you run from the Map page | You |

The map sweep only runs tools that are switched on, with Firefight's own fixed reads. Web searches and pages Halon reads are recorded too.
