---
title: Local Audit Results
published: true
index: 90
---

# Open local audit results

After any local Core or Comprehensive audit, including focused runs, open the saved results in the bundled viewer. This is a presentation step after evaluation and JSON validation, not a storefront preview or an audit executor. In Glue and other guarded runners, retain host rendering and the bare-object protocol; do not start this server or bypass capability guards.

## Prepare the saved results

Follow [Glue JSON output](../core/glue-output.md) first. Keep the canonical `report.json` unchanged in an external run directory. Record local screenshot URLs as real `file:` URLs and put the corresponding raster images in that directory or its descendants. The viewer serves only images explicitly referenced by the report and contained within that directory; it cannot display arbitrary files elsewhere. Retain unavailable image locations as evidence text. Remote HTTP(S) screenshots load from their recorded source.

Alongside the report, save `viewer-context.json` from the run's already pinned catalog and provenance. It is presentation context, not a replacement result schema or a source of Check outcomes. Include every selected Check exactly once, with its exact title, canonical category and positive integer version. Optional fields identify the title, target, actual scope, timestamp and source:

```json
{
  "title": "Core Shopify Audit",
  "targetUrl": "https://store.example.com",
  "coverage": "Basic, focused: accessibility",
  "generatedAt": "2026-11-10T15:30:00Z",
  "source": "Pinned source revision or external instruction snapshot identity",
  "checks": [
    {
      "id": "selected-check-id",
      "title": "Exact selected Check title",
      "category": "accessibility",
      "version": 1
    }
  ]
}
```

Replace example values with the actual run identity and full selected set. Never infer a complete Basic/Full scope from the number of recorded outcomes. The viewer expands grouped `coverageIds` into individual rows; filters change only what is visible. Without context, older saved reports remain viewable by ID with scope marked as unavailable. Do not reconstruct missing titles or provenance from an unpinned current catalog.

## Start and open the viewer

Use available host command execution with Python 3.9 or newer; no package installation or network service is required. Resolve `<installed-skill>` to this installed skill directory, not a developer checkout or a sibling skill. The launcher and HTML are included in each audit skill independently:

```sh
python3 "<installed-skill>/scripts/open_audit.py" "/absolute/external/run/report.json"
```

The [launcher](../../scripts/open_audit.py) uses the bundled [viewer](../../assets/audit-viewer.html), chooses an available port on `127.0.0.1`, prints the URL and attempts to open the default browser. Use `--no-open` when the host supplies browser opening; open the printed URL with that host capability. `--context /absolute/path/viewer-context.json` selects a separately saved context file. `--port` may select a known free port; do not stop an unrelated listener to free it.

Run the launcher in a host-managed persistent process and retain its handle. Verify the printed URL responds and the browser shows this report's Issues and selected Check count. Keep the process running for review, provide the URL and `report.json` link in the final chat, and follow the existing issue-summary requirements. Use the exact Check titles from context when describing failed Checks. Stop only this owned process when requested or when its host session ends; closing the tab does not stop it. Results remain saved and can be reopened with the same command.

If Python, command execution, a persistent process, browser opening or localhost reachability is unavailable, preserve the complete report and useful chat readout. State the precise viewer limitation and provide the reopen command when useful. A viewer failure never changes Check outcomes or becomes a storefront Limitation. Do not claim the site opened unless the host confirms it; a printed URL alone establishes only the server handoff.

## Review behavior

The viewer uses packaged Kobra-rendered controls and styles. Click a result row or choose the open action from its ellipsis menu to see the details. The dialog body scrolls between a fixed header and footer. Use the arrows on the left of the footer to navigate between results in the current tab. On wider screens, evidence and recommendations appear beside the tags and accordions. Choose **View affected page** from the Issue dialog’s ellipsis menu. Issues appear as compact rows grouped by category, with priority badges beside their titles. Use the status icon on an Issue row or the labeled control on the right of the dialog footer to change its status. New Issues start in Triage. Changes appear in the row and dialog and are saved in `report.json.issue-statuses.sqlite3` beside `report.json`. Reopening the same report restores these statuses. Cancelled and Resolved Issues start hidden. Use **Show cancelled issues** and **Show resolved issues** at the bottom of the Issues tab to show or hide each group. Each button displays its group’s count. The issue dialog arrows skip hidden rows. Select Issues with the row checkboxes, then open **Change status** in the floating bulk menu to set their status together. Use the category carets to expand or collapse the rows. Open a linked Issue from the Check dialog’s ellipsis menu. Copy contents and Download JSON both use the canonical report. The toolbar beneath the lightbox image offers Copy image and a View source menu item when the source is supplied.

Categories and their Issues start in report order. Drag an Issue row to move it within its category. On touch screens, press and hold before dragging. With an Issue row focused, press Shift+Space to pick up, Up or Down to move, and Shift+Space again to drop. Escape cancels. A colored divider marks the drop position. The dialog follows the manual order until the page is reloaded. Hover over a shortcut-enabled control to see its keyboard hint.

Tabs appear when the report has results of that type. The Check ledger includes every individual selected ID, including Blocked and Not applicable. The launcher does basic input checks, with full schema and semantic validation required before presentation.
