# Operations

This page covers the tools you'll reach for as the person operating an org day to day: the audit log, retention policy, and connectivity diagnostics.

## Audit log

The Activity tab in the web dashboard is a unified activity feed, open to any org member, covering (among others):

- ACL changes
- History events
- Quarantine incidents - both applied and released
- Branch-protection changes - per-branch flag toggles and glob protection-rule edits
- Org-level audit events (including member role changes and data-plane policy changes)
- Notifications
- Unlock requests
- Changeset commits
- Branch creates, archives, and switches
- Tag creates
- Comments added, resolved, and mentions
- RFI / submittal / approval workflow events (created, assigned, due-soon, overdue, response posted, revisions requested, closed, voided)
- Webhook changes (created, edited, rotated, re-enabled, or removed)

The feed is ACL-filtered server-side: owners see everything, members see events on entries they can read, and quarantine incidents and org-policy events project to empty for non-owners. Everything lands in one feed instead of being scattered across separate logs. It refreshes automatically (within about a minute while the tab is open, paused in background tabs) so new events show up without reloading the page. You can export it to CSV, capped at 100k rows per export. The export endpoint is owner-only *and* gated on the `audit_log` entitlement (Pro plan and above): a non-owner gets a 403, and an owner on a plan without the entitlement is told to upgrade. The live in-dashboard feed and the underlying event capture stay ungated on every plan - only the bulk CSV export is entitlement-gated.

Today the underlying events are stored internally, with CSV as the only bulk-export path - though an [outbound webhook](https://swarmfile.com/docs/admin/webhooks) does let you forward a live stream of the same underlying events to your own endpoint (delivered on a periodic schedule, not in real time), which covers some of the same ground for a system willing to receive and store them itself. See [Security](https://swarmfile.com/docs/admin/security) for the full list of what's still on the roadmap.

### What the CSV export contains

Each export starts with a few `#` provenance rows (format version, generation time, requested window, row cap) that spreadsheet apps skip, then one row per event with these columns: `occurred_at_iso`, `kind`, `actor_user_id`, `actor_display_name`, `actor_email`, `project_id`, `project_name`, `entry_id`, `entry_name`, `summary`, `detail`. The rows are a merged, deliberately un-sorted-across-sources view of every source in the requested window; sort by `occurred_at_iso` after import if you need a single timeline, and check the `X-Activity-Export-Truncated` response header in the web export. The CLI prints the CSV without surfacing that header, so a CLI export is silently capped at 100,000 rows - narrow `--since`/`--until` if you need a complete window.

**Audit-event retention.** Activity, ACL, and audit rows are pruned on the org's retention window - the same 1-3650 day setting that governs history and trash, defaulting to 90 days when nothing is set. Per-user retention preferences apply to history and trash only; these activity/ACL/audit rows follow the org window. Plan for exports or webhook ingestion if your compliance position needs records kept longer than the window in force, and confirm the window on **Settings → Organization** before relying on it.

## Ransomware quarantine

Swarmfile watches for the signature of encryption malware - a large number of *distinct entries* overwritten in a short window, scoped per-(user, machine) - and responds in two tiers. The detection mechanics are covered in [Security](https://swarmfile.com/docs/admin/security); this section is about the admin side of an incident.

- **Alert bar** (a configurable number of distinct entries in the window) - crossing it records an *alert-only* incident and notifies org owners for review. Nothing is blocked.
- **Block bar** (a higher multiple of the alert bar - twice it by default) - crossing it hard-quarantines the user: their writes stop reaching the hub (on Windows the drive stays mounted and saves are accepted locally and held; on macOS and Linux the write is refused), and lock acquire/renew both refuse, so they can't keep working even mid-lock. A single large operation can reach either bar: a 500-entry commit submitted from one machine blocks on the spot, and a 250-entry one alerts. The bars also have an aggregate backstop - one user's combined activity across their machines is judged at the block bar - so two machines doing 250 each block where one machine doing 250 alerts. If your team routinely rewrites that many files in one operation, raise the thresholds (below) rather than leaving them to be quarantined.

Owners and admins can tune either bar per organization under **Settings → Quarantine → Detection thresholds**; a blank field keeps the default, and the card shows the effective value and where it comes from. Raising the alert bar moves the inherited block bar with it (an explicit block bar doesn't move). The org's daily container-preview budget - with today's org-wide spend against it - lives on **Settings → Usage → Preview generation budgets**: previews/day default to 500 per project and 2,000 per org, a blank field keeps the default, and `0` means no limit. The source caps are fixed - video proxies accept sources up to 16 MiB (poster extraction reads the first ~16 MiB), and point-cloud (`.las`/`.laz`) previews up to 32 MiB; [File Previews](https://swarmfile.com/docs/guides/file-previews) covers the rest.

Alert-only incidents that no one acts on auto-expire after 7 days, so a legitimate bulk edit doesn't linger as a flag (and doesn't suppress future alerts for that user). Blocks never auto-expire - they require a human to clear.

Manage incidents from the **Quarantine** view in the web dashboard. It lists active and historical incidents; each row is one click to **Release** (lift a block) or **Dismiss** (clear an alert-only flag). Admins can also manually quarantine a user out-of-band - for example, in response to an incident report that didn't trip the detector. Quarantine management is available to admins and owners.

## Access revocations

Removing a member, revoking a guest, deprovisioning a user through SCIM or LDAP, revoking a device key, or invalidating a directory group membership doesn't just delete one row: Swarmfile sweeps every project in the org so cached peer credentials, wrapped keys, and access grants stop working there too. That sweep is durable - it runs across projects in the background, retries failures with backoff, and parks on a project it can't reach instead of skipping it silently. **Settings → Access revocations** (owners and admins) shows where every sweep stands: in progress, parked projects with the reason, and finished sweeps. A parked project carries a **Retry** - fix the cause and re-run the sweep from the same view; each attempt is recorded in the audit log. Revoking a project API key or a personal access token rides this same sweep to close that credential's live connections.

Because a sweep reaching a client is what makes it delete its cached copy, each engine reports a **purge receipt** when it has applied a revocation: the view shows how many devices confirmed it, how much cached data they removed, and which device each confirmation came from (attributed to the signed-in identity - a machine label is self-declared). So "dispatched" and "applied everywhere" are separate, visible facts. `GET /orgs/:org/admin/security-fanout` returns the sweep view for scripts, and `GET /orgs/:org/admin/revocation-receipts` the receipts. See [Organizations, Projects & Members](https://swarmfile.com/docs/admin/organizations-projects-and-members) for member removal and [End-to-End Encryption](https://swarmfile.com/docs/admin/end-to-end-encryption) for device-key revocation.

## Retention & garbage collection

Trash and soft-delete retention is configurable, from 1 to 3650 days - owners set the org-wide window in **Settings → Organization**, and an individual user can set their own window in account settings, which overrides the org default for them. The end-user side of this - restoring a deleted file, browsing history, rolling back a change - is covered in [Trash, History & Rollback](https://swarmfile.com/docs/guides/trash-history-and-rollback); this page is about the org-level policy knob that governs how long deleted data is kept before garbage collection reclaims it. Set the retention window based on your org's compliance and recovery needs - a longer window costs more storage but gives you (and your users) a longer recovery runway. The default when nothing is set is 90 days.

**New-project history retention.** Independently of the window, every project carries a history-retention choice: **Keep every saved version** (the default) or **Named commits only**. It decides whether individual per-save versions survive the window at all - on a keep-everything project the window controls when aged history moves to cheaper cold storage, not when it is deleted, so a short window no longer means short-lived history there. Owners set the default for newly created projects with **New projects keep every saved version** in **Settings → Organization**; a creator's explicit choice in a creation form still wins, so this is a default, not an enforcement. An org whose data-minimization policy wants saves to expire should turn it off (or clear the flag on existing projects with `PATCH /orgs/:orgId/projects/:projectId` / `swarmfile project set-keep-full-history false`).

## Project storage limit

Separate from your plan's storage allowance (the size of the files themselves - see [Billing & Plans](https://swarmfile.com/docs/admin/billing-and-plans)), each project keeps its file information and history - names, folders, versions, locks, comments - in its own store with a fixed limit. It takes a very large project to approach it: roughly ten million files and versions combined, since a 1 TiB file costs the same here as a 1 KB one. It isn't billed.

- **Where to see it.** A project's **Metadata** tab (owners and admins) shows how much of the limit is used, whether new writes are being accepted, what the last daily cleanup removed, and - when any exist - access revocations still waiting to reach a device (the history window in force lives on the project's **Project settings** tab). **Settings → Project storage** lists every project in the org that is nearing or at its limit, worst first.
- **Early warning.** At about half the limit, the org's owners and admins get a "Project storage" notification (in the inbox, and by email unless muted per kind in Settings). History retention may also start shortening automatically - see [Trash, History & Rollback](https://swarmfile.com/docs/guides/trash-history-and-rollback#when-history-is-kept-for-less-time).
- **At the limit.** Adding files, saving new versions, copying, merging, staging, and git-LFS pushes are paused with an "insufficient storage" (`507`, `project_storage_full`) error. Nothing is lost: the Desktop App keeps changes on each person's computer and syncs them once space is available. Everything needed to recover keeps working - deleting, purging trash, restoring, renaming, moving, locks and commits.
- **Freeing space.** Purge deleted files from Trash, delete old branches, or shorten the history retention window (**Settings → Organization**, owner-only). On a keep-every-version project the window only controls cold archiving; if history genuinely isn't needed, switch the project to **Named commits only** as well. Space is reclaimed as soon as rows are removed, so writes resume without waiting for the next daily pass. A project that keeps growing past this is usually better split into several projects.

Swarmfile also watches these stores from the platform side and pages its own operators when a project approaches its ceiling, so growth is caught before it pauses writes - there is nothing for you to configure.

## Long-running background jobs

Large cascades don't run inline. Above the hub's **5,000-entry** cap, folder delete, restore, purge, revert and checkout - plus `project delete` - run as durable background jobs: the request answers `202 { jobId }`, and the engine, web dashboard and tray follow the job and synthesize the original outcome (the root change lands before the `202`, so the operation's effect is already visible). Jobs are durable and survive a dropped connection, a closed laptop, or an engine restart.

From the CLI, [`swarmfile op`](https://swarmfile.com/docs/cli/swarmfile#op) manages them: `op list` shows recent operations; `op status <id>` reports state and live `done`/`total` progress (exit `0` succeeded, `1` failed, `2` canceled, `3` still running); `op wait <id>` waits and exits as the original command would; and `op cancel <id>` stops the operations that can safely stop part-way (`materialize`, `hydrate free-space`, `git backfill-oids`, `git index`, and `checkout`/`revert` while still staging) - a cancel that lands after the staged apply has begun is declined (`too_late`) and the operation ends with the commit's real outcome, while commits, merges and deletes complete or fail on their own and refuse (`not_cancellable`). A command that starts a long operation and doesn't follow it prints the job id and exits `3` (with `--no-wait`, or when you press Ctrl-C to detach), and the operation carries on in the engine.

## Office caches

A self-hosted seed node runs headless; its operational surface is **Settings → Office caches**. The page lists the fleet with liveness (a cache reads offline after roughly 2.5 minutes without an announce, or **Awaiting approval** when your organization approves nodes), the bytes each cache served this week, and the enrollment wizard that mints a cache's credential and generates its `seed.env`. Owners and admins receive a weekly report email and one alert per day-long outage; each is muteable per-kind under **Settings → Notifications**. Setup, sizing and hardware guidance: [Self-Hosted Seed Nodes](https://swarmfile.com/docs/admin/self-hosted-seed-nodes).

## Connectivity diagnostics

Swarmfile ships two ways to run the same connectivity probe suite:

- **`swarmfile doctor`**, proxied through a running engine.
- **`swarmfile-doctor`**, a standalone binary that doesn't need a running engine at all - useful for a machine that isn't mounting anything yet, or for isolating whether a problem is the engine or the network.

Both run the same checks: DNS, hub reachability, cloud storage, the peer-to-peer layer, mDNS discovery, and OIDC/auth. Output is colorized pass/warn/fail for a human to read, or `--json` for attaching straight to a support ticket.

Diagnostics also run automatically in the background on a periodic basis, not just when you invoke them by hand, and server-side deep-health probes run from the other direction - so a problem can surface from either side. Always-public liveness endpoints exist separately, for basic uptime monitoring.

One probe worth knowing about specifically: the **plan** probe. If a self-hosted seed or NAS node is running under a plan that doesn't include the seed-node entitlement, this probe fails clearly and explicitly, instead of the node just silently misbehaving or repeating the same log line forever. If you're setting up a seed node, see [Self-Hosted Seed Nodes](https://swarmfile.com/docs/admin/self-hosted-seed-nodes) for the plan requirement.

Reach for `swarmfile doctor` any time something feels wrong and you're not sure whether it's your network, your account, or the service - it's the fastest way to narrow that down, and its output is what support will ask for first. Full flag reference is at [swarmfile-doctor](https://swarmfile.com/docs/cli/swarmfile-doctor).
