# Carto Desk > Paste a Mapbox GL style specification document and review it four ways in one sitting: an audit > against the style spec, a cartographic critique, a data-visualization review of the data-driven > layers, and a render-cost pass. A free in-browser prescan parses the style first and the model is > held to what it found. Site: https://carto-desk.skillsafe.ai/ API tutorial: https://carto-desk.skillsafe.ai/api.html Token panel: https://carto-desk.skillsafe.ai/tokens.html (noindex) ## What it is for One work object: a Mapbox GL style JSON, style specification version 8. One user, one sitting, four lanes over that same document — inspect it, decide how it should look, fix the data encoding, then price what it costs to draw. Each lane's result carries into the next through a handoff button. ## The lanes | `task` | Lane | Answers | Source skill | | --- | --- | --- | --- | | `audit` | Audit | Does this style parse, resolve and ship? | `@mapbox/mapbox-style-quality` | | `carto` | Cartography | Will a reader find what they came for? | `@mapbox/mapbox-cartography` | | `dataviz` | Data layers | Are the data layers encoding the data honestly? | `@mapbox/mapbox-data-visualization-patterns` | | `perf` | Render cost | What does this style cost to draw? | `@mapbox/mapbox-web-performance-patterns` | ## What runs for free in the browser, before any model call A real style reader, not a regex pass. It parses the JSON and reports: - layer and source integrity — every layer's `source` resolved against `sources`, `source-layer` required on vector sources, duplicate layer ids, unknown layer types, unused sources - paint versus layout placement — a layout property in `paint` (or the reverse) is silently ignored by the renderer, so the style appears to work while the property does nothing - sprite and glyphs — `icon-image` with no `sprite`, `text-field` with no `glyphs` - zoom ranges — `minzoom` >= `maxzoom` means the layer never draws - embedded credentials — a Mapbox secret token (`sk.`) in a served style is critical; a public token (`pk.`) belongs in the client's init call with URL restrictions - WCAG label contrast — relative luminance and contrast ratio computed from the declared text, halo and background colours - layer hygiene and cost — hidden layers, identical layer bodies, legacy `{property, stops}` functions, ungated expensive layers, symbol-layer count against a draw budget Those findings are sent to the model as `prescan_facts`, and the model must reconcile every one of them — confirmed or set aside — in `coverage_check`. The app shows any it skipped. ## Input contract ```json { "task": "audit | carto | dataviz | perf", "style": "the Mapbox GL style JSON, as text", "usage": "what the map is for; GL JS init code welcome for the perf lane", "audience": "general | analyst | field | print | unknown", "emphasis": "general | legibility | accessibility | data | speed", "carryover": "a digest of a previous lane's review, or an empty string", "prescan_facts": {"stats": {}, "flags": [{"id": "SC-001", "title": "", "severity": "", "layer": "", "detail": ""}]}, "retry_note": "present ONLY on the app's reformat retry: a correction directive about the model's own previous malformed reply, never user content" } ``` `retry_note` is optional and absent from a first attempt. When the app cannot parse a reply it retries once with `retry_note` set to what was wrong with that reply. It is an instruction from the app to the model about its own previous output — it is never something the user wrote, and nothing in it describes the style. ## Output contract One JSON object. The envelope is identical in every lane: `lane`, `title`, `style_name`, `verdict` (`ship` | `fix-first` | `rework`), `headline`, `summary`, `checks[]` ({name, status, note} — the lane's named checks, in order), `findings[]` ({id `CD-nnn`, title, severity, area, layer, detail, fix, snippet}), `coverage_check[]` ({prescan_id, status, note}) and `next_steps[]`. Each lane adds exactly one block: `audit` → `blocking[]`; `carto` → `palette[]`; `dataviz` → `recipes[]`; `perf` → `budget{}` plus `wins[]`. ## Model and cost Model `gpt-terra` (currently `gpt-5.6-terra`), publisher markup 1000 bps. `estimate` is free and is re-taken on every lane switch, because the hold differs per lane. Four of the eight example×lane combinations replay a saved run at zero cost without an account: the delivery ops style for `audit`, `carto` and `perf`, and the air-quality style for `dataviz`. The other four are ordinary paid runs, and the lane bar marks which is which for the style currently loaded. Guest runs are not sponsored, so every non-replay run needs a signed-in account. ## Sources and attribution Carto Desk is a derived work built on four skills from `@mapbox/mapbox-agent-skills`: `@mapbox/mapbox-style-quality`, `@mapbox/mapbox-cartography`, `@mapbox/mapbox-data-visualization-patterns`, `@mapbox/mapbox-web-performance-patterns`. Mapbox and Mapbox GL JS are trademarks of Mapbox, Inc. This app is not affiliated with or endorsed by Mapbox. Nothing about a pasted style is stored anywhere except the user's own SkillSafe account history.