Skip to main content
cc-safety-net gui opens a local dashboard for reviewing what CC Safety Net has been doing on this machine and for editing your policy without hand-writing JSON. It is a single page served from your own computer, and it is the fastest way to answer “what was blocked, why, and what should I change?” This page covers what you can do in the dashboard and which actions are destructive. It does not restate the underlying formats: the policy.json schema lives in Policy, rulebook authoring in Custom rules, and the audit record schema in Audit log.

Launching the dashboard

The command prints the dashboard URL and then opens it in your default browser:
Pass --no-open when you want the URL without a browser launch — for example over SSH, in a container, or when you would rather paste the URL into a specific browser profile:
--no-open is the only flag besides -h, --help. Any other argument is rejected with Usage: cc-safety-net gui [--no-open] and a non-zero exit code. If the browser cannot be launched, that is not fatal — the command prints the underlying error followed by Open this URL manually: <url> and keeps serving. The server runs in the foreground until you stop it with Ctrl-C.

Local-only scope

The dashboard is not a hosted service and does not expose your machine to the network:
  • The server binds to 127.0.0.1 only, on an ephemeral port. Nothing on your LAN can reach it.
  • Each launch mints a fresh random token that is embedded in the URL. Every request must carry that token, and every state-changing request must also send it as a request header. Requests without it are rejected with 403.
  • Responses are served with cache-control: no-store.
The page itself makes no outbound requests for its data — everything it renders comes from your local policy file and audit logs. The only exceptions are opt-in: the update check and the GitHub star action shown on Overview.
Because the token is per-launch, a URL you bookmarked from a previous session will not work. Run cc-safety-net gui again to get a fresh one.

The six views

The sidebar has six views, hash-routed so you can link or bookmark within a session: An unrecognized hash falls back to Overview. Integrations and Rules load their data the first time you visit them.

Overview

Overview summarizes a retained window, not a lifetime total. The window is the last 7 days, or your entire retention window when retention is shorter than 7 days. The heading states the window it used, as Last N day(s). Tiles. Two counters — Blocked and Analyzed — each with a per-day sparkline running oldest to newest. Each sparkline scales to its own maximum, so the two tiles are not visually comparable to each other; read the numbers, not the bar heights. Protection status. A card names your safety level, adds · Customized when your overrides deviate from the preset, and reports how many rules are active and whether secret protection is on. This card reflects saved state only — unsaved toggles staged on the Policy view do not change it until you save. A banner appears when destructive-command protection or secret protection is off, or when a fallback configuration is being enforced because something in your configuration could not be loaded. Health strip. Reports whether the hook is active in your detected agents, or that agents were detected without an active hook, or that no agent hooks were detected at all. It also surfaces an available update. When something needs attention it links to Integrations. Top blocked commands and Top blocked rules. Two top-five ranked panels, counted across the same window as the tiles. Selecting a top command jumps to Activity with an exact, blocked-only command-signature filter applied as a removable pill. Selecting a top rule routes by rule namespace: custom.* rule IDs go to the Rules view, and built-in rule IDs go to Activity with the rule ID prefilled in the search box. Guard errors. When any denial in the window came from a failed evaluation rather than from policy, a button appears reading N guard error(s) in the last N days — commands blocked because evaluation failed, not by policy. Click to view. Selecting it opens Activity filtered to error decisions. These are fail-closed denials: CC Safety Net could not finish the analysis, so it refused the command. See Troubleshooting if they recur.

Activity

Activity lists audited commands from the local log, newest first. Commands are secret-redacted at write time, before anything reaches the log — and redaction is bounded to recognized credential shapes, so entries can still carry paths, hostnames, and names. See Audit log for the record schema and the exact redaction scope before you share anything from this view.

Windows are derived from retention

The window selector is not a fixed set of choices. It is computed from your configured audit retention: the candidate windows 7, 30, 90, 180, and 365 days are filtered to those strictly shorter than your retention. Your retention value itself is always appended as the widest option. That way no option ever promises history the retention sweep has already deleted, and your whole log always stays reachable. Windows are whole local calendar days — today plus the preceding days — so the per-day sparkline buckets on Overview sum exactly to the totals. A request for a window wider than retention is rejected, and if you shorten retention the current selection is re-clamped for you. See Audit log for how retention itself is configured and enforced.

Filters

  • Window — the retention-derived selector described above.
  • Decision chipsAll, Blocked, and Allowed always; Errors only when the window contains guard errors; Likely false positive only when the heuristic finds candidates. The heuristic flags a denial that carries a failure stage, or a command signature denied two or more times in the same session.
  • Agent chips — rendered only when two or more distinct known agents appear in the window, with an All agents chip to clear them.
  • Command pill — an exact, blocked-only command-signature filter, added by clicking through from Overview and removable from here.
  • Search — the top-bar box (Filter by rule or command) matches rule IDs and command text as a case-insensitive substring.
Filters that no longer make sense self-heal on reload. If the agent you filtered on is gone, or the window has no errors or no false-positive suspects, the filter resets rather than showing an empty feed.

Refresh

The refresh button reloads both Overview and Activity, so the tiles and the feed never disagree. It holds a short minimum spin so a fast local refresh still registers as an action.

Rendered entries versus counts

The feed renders at most 500 entries. The cap is split across decision classes — each class is guaranteed half the cap and lends its unused share to the other — so a burst of denials cannot crowd allowed entries out of the view entirely. The counts are not capped by the 500-entry limit. Chips, tiles, and the top panels are computed from full-window aggregates on the server, independent of what the feed renders. The footer states both, as Showing X of Y entries from the last N day(s), adding (capped at 500, newest of each decision) when truncation occurred. There is one case where the counts themselves fall short: when some audit log sources could not be read, the footer appends N audit log source(s) could not be read, so this list is incomplete. The aggregates miss those entries too, so treat both the list and the counts as a floor rather than a total until the sources are readable again.
Read the footer before drawing conclusions from a scan of the list. Showing 500 of 4,120 means the list is a recent slice while every chip and tile still reflects all 4,120 entries.

Per-entry actions

Each entry carries a decision badge (Blocked, Allowed, or Error), an agent badge, a rule-ID chip, a relative timestamp, and a button to copy the raw log entry as JSON. Long commands are clamped with a Show more toggle. The copied entry is the raw audit record — see Audit log for its fields. Denied entries offer Report false positive, which opens a dialog that prepares a prefilled public GitHub issue. Both the command and the log entry are editable before you continue, your project path is replaced with <project> and your home directory with ~, and nothing is submitted until you submit it on GitHub yourself. Allowed entries offer Block this in future, which prefills the prompt composer on the Rules view with that command. It does not create a rule on its own — see Rules below.

Policy

Policy is where you choose what CC Safety Net blocks. Everything on this view is a built-in protection: the safety preset, the destructive-command rules, and the secret-protection patterns that ship with CC Safety Net. Your own rulebooks are a separate mechanism and are not edited here. The full field-by-field contract for the file this view writes lives in Policy.

Saved versus unsaved

Edits accumulate in a draft and apply only when you save.
  • A save bar appears on the Policy view whenever the draft differs from what is on disk, with Discard and Save.
  • An Unsaved policy changes · Review chip appears in the top bar on every other view and jumps here when clicked.
  • The draft survives a reload within the browser session. Saving, discarding, repairing, or resetting clears it.
  • Leaving the page with unsaved changes prompts you first.
Saving writes the policy file and reports the path it wrote. While the on-disk policy has any error, the form does not show your file: every control renders the built-in default, not the valid values the runtime is still salvaging from disk — only the raw JSON mirror still shows the file’s actual contents. Saving is refused in that state, with Repair policy before saving changes., so the defaults on screen cannot be written over your file from here — repair first, then save. After a repair, the form reloads with the settings the repair preserved.

Test a command

Paste a shell command into Test a command to see whether it would be blocked. The test evaluates against your current unsaved edits, so you can check a change before committing to it. The test also enforces your custom rulebook rules, loaded from disk, even though rulebooks are not editable from the dashboard. Treat it as a preview of the real decision, not just of the built-in layer. For the same analysis from the terminal, see explain.

Safety preset

The view offers the three safety presets — labeled Standard, Strict, and Paranoid in the interface — as the inherited defaults you then customize for the workspace. Each is progressively stricter; Modes is the authority on exactly what each preset and capability changes. Environment variables that raise protection are surfaced here as a notice, so a level that looks lower than the behavior you are seeing is explained rather than confusing. An Advanced overrides section, collapsed by default, exposes the individual capabilities the preset resolves to — fail closed, paranoid rm -rf checks, and paranoid interpreters — so you can raise or lower one without changing preset. Workflow exceptions are configured separately from the safety level.

Destructive command protection

A master switch, then the rules grouped into four collapsible tiers: Every tier starts collapsed; searching on the Policy view opens each tier that has a match automatically. The Always enforced tier has no switch and no per-rule checkboxes — its header counts its rules as N protections, and each rule inside is marked Always enforced with a ? example popover. The three configurable tiers show N on · N off counts in the header, next to a tier switch labelled All <tier> protections. That switch is checked while at least one rule in the tier is on, and it is disabled while the master switch is off. Flipping it writes the same per-rule overrides the individual checkboxes use, in bulk — a rule that ends up matching its inherited value keeps no override — so there is no separate stored group setting. While the master switch is on, the panel summary reads N active, N disabled. Turning it off replaces that with Configurable protection disabled. Catastrophic protections remain active; saved rule settings and allow paths are preserved. — the Always enforced tier keeps blocking even then. Each configurable rule card carries a ? popover with a concrete example of a command it blocks, and a status line naming where its current value came from — so a rule reading Off — destructive-command protection disabled tells you the master switch is winning, not your override. Toggling a rule stores an explicit on or off override. Setting a rule back to its inherited value deletes the override rather than storing a redundant one, and each rule offers Use inherited setting to do that directly. A Restore defaults action in the panel head clears every override at once. Allow paths live in this panel. Recursive deletes targeting a listed path are not blocked, which is what makes /tmp workable. Entries must be absolute or ~/-prefixed directories, and your home directory is rejected — see Allow paths for the full validation table and Allowed commands for what an allow path does and does not relax.

Secret protection

A master switch plus per-pattern checkboxes, grouped by category — from the default sensitive paths (home paths, credential basenames, extensions, and variants) to the Coding CLI credential and Coding CLI config locations. Each group header is a collapse button showing N on · N off, next to a group switch labelled All <category> protections that behaves exactly like the destructive tier switches: checked while any rule in the group is on, disabled while the master switch is off, and writing the per-rule overrides in bulk. Groups start collapsed and open automatically during a Policy search. Rules that protect literal file paths carry a ? button opening a Protected paths popover that lists exactly which paths the rule covers. Not every rule defaults to on. Coding CLI config rules ship off — settings and MCP config files carry credentials inline, but agents edit them as routine work, so you opt in per rule. A checkbox stores an override only when it deviates from the rule’s default: checking a default-off rule writes an on override and unchecking it removes the override, while for a default-on rule unchecking writes off and rechecking removes the override. While the master switch is on, the panel summary reads N active, N disabled. When it is off, it reads Protection disabled. Saved rule settings and deny paths are preserved. Deny paths live in this panel. Configured paths and everything inside them are blocked while secret protection is on. Deny paths depend on the master switch — turning secret protection off stops enforcing them. See Deny paths for the accepted entry forms.

What asks for confirmation

Individual rule toggles, preset changes, and adding or removing paths are staged in the draft and gated by Save, so they are not separately confirmed. The dashboard reserves modal confirmation for actions that reduce protection or discard configuration: Cancel is focused by default in every one of these dialogs.
Turning off destructive command protection or secret protection disables every configurable rule in that layer at once until you turn it back on — only the Always enforced destructive tier keeps blocking. Prefer a single rule override, or a lower preset, over the master switch.

Repair

When the policy file on disk has errors, a Policy repair available banner appears on this view with a Repair button. Repair writes canonical JSON, preserving every valid setting and discarding invalid fields. If the JSON cannot be parsed at all, defaults are restored instead. The button is inert when the loaded policy has no errors.
Repair discards invalid fields, and falls back to defaults when the file cannot be parsed. If the file contains hand-written configuration you care about, copy it somewhere safe before repairing.

Reset

Reset is deliberately not on this view. It lives in Settings, under Danger zone.

Rules

Rules covers your custom rulebooks — the rules you author yourself, as distinct from the built-in protections on the Policy view. See Custom rules for the rulebook format, scopes, overrides, and validation; this view does not restate them.
The Rules view is not a rulebook editor. CC Safety Net never writes a rulebook from the dashboard. This view shows rules read-only as they are actually enforced, and composes prompt text for you to copy into a coding agent that does the authoring.

Rulebooks panel (read-only)

Each rulebook card shows its name, a version badge, its source spec when that differs from the name, its scope (All projects or This project), and its rule count. Rules are listed as enforced, after overrides. A rule disabled by an override still belongs to its rulebook and stays in the rulebook’s listing, but it is dropped from the rendered rules — so what you read here is the effective rulebook, not the file contents. A refresh button re-reads from disk. When no rulebooks are configured, the panel points you at cc-safety-net rule init. When rulebooks exist but every one was dropped, it says so and sends you to Diagnostics.

Diagnostics

The Diagnostics panel is hidden when there is nothing to report. When it appears, an error there means a rulebook was dropped and its rules are not enforced. This is the place to look when a rule you wrote is not firing.

Prompt composer (copy only)

The composer builds a prompt for your coding agent. Its only action is Copy prompt — there is no create, save, or write control anywhere in the view, and no server route that writes a rulebook. Inputs:
  • ScopeProject or All projects.
  • Project path — shown in project scope only, prefilled with the directory the dashboard was launched from. Where a native directory picker is available, the field is read-only with a Choose… button; if the picker is unavailable at runtime, the field becomes editable instead.
  • Request — describe the rules you want. Rules match a command, an optional subcommand, and exact arguments — not file paths or patterns.
  • Examples — one-click starters for suggesting rules, blocking a command, and verifying existing rules.
The generated prompt tells your agent to use the CC Safety Net skill, or to run cc-safety-net rule doc and treat that output as the source of truth. It carries the scope, the project path, and the names of your existing rulebooks so the agent picks a name that is not already claimed. It deliberately carries only rulebook names — no rule names, blocked arguments, reasons, or versions leave your machine in that text. Copying is refused, with a specific message, when rules have not loaded yet, when the request is empty, or when project scope is selected with no project path.

Integrations

Integrations installs or removes the CC Safety Net hook for each coding agent on this machine. The Agents panel lists the detected CLIs and their hook status; see Integration architecture for how each agent is wired and Installation for the equivalent steps outside the GUI. Not inspected carries a tooltip spelling this out: This runtime's state file could not be read, so its status is unknown. The CLI itself was found, so installing is still offered. Detection gates the actions: when a CLI is not detected, no button is offered at all, because there is nothing to install a hook into. Install and uninstall are serialized, so two actions cannot interleave, and the button is disabled while its request is in flight. Failures report Install failed or Uninstall failed rather than silently reverting. The refresh button re-detects every agent, which is what you want after installing a CLI or editing an agent config by hand. A System panel below reports the CC Safety Net version, the Node.js version, and the platform detected on this machine.

Settings

Settings covers appearance, file locations, and maintenance. Appearance. A theme control cycling Auto → Light → Dark. The preference is stored in this browser, not in your policy. Files. Two read-only rows showing where CC Safety Net reads and writes on this machine: the policy file and the audit log directory. Audit log retention. How many days of audit records to keep — see Audit log for the accepted range, what gets recorded, and how the sweep enforces it. Unlike the Policy view, retention saves immediately on change — there is no save bar behind it. It cannot be saved while the Policy view has unsaved changes; save or discard those first. Unlike the Policy save button, this control is not blocked while the on-disk policy has errors — and because the form holds defaults in that state, changing retention writes that all-defaults document, with only your new retention, over the file. Repair the policy before touching retention.
Shortening retention is irreversible. Audit entries older than the new window are deleted on the next sweep and cannot be recovered, and the Activity view can then only look back as far as the new value. The dashboard asks you to confirm before shortening, and the confirmation names the logs directory it will prune. Export anything you need first — every entry has a copy-as-JSON button in the Activity feed.
Policy JSON. A read-only mirror of the policy controls, with a copy button. It reflects the controls on the Policy view — it is a mirror for inspecting and sharing, not a second editor. Version. A single read-only row showing the CC Safety Net version you are running. Danger zone. A single action, Reset policy, which restores the default policy JSON at the configured path.
Reset discards your saved configuration. Every preset choice, rule override, allow path, and deny path returns to defaults, and there is no undo. Reset affects the policy file only — your custom rulebooks are separate files and are not touched.
For the policy file schema see Policy; for rulebook authoring see Custom rules; for the audit log format and retention behavior see Audit log; and for gui and every other command see CLI commands.
Last modified on August 3, 2026