Change the map
Everything on the map is generated from JSON in one folder of one repository. Change the JSON, open a pull request, and the pages change on the next build. There is no other way to edit them, on purpose — but there is a way to open that pull request without a GitHub account, below.
Without a GitHub account: the map vault
The same map, drawn live from this pack inside an encrypted vault, and on every row — a grant row, a cell the profile does not list, a mandate line, a reduction, an entry above the ceiling — a form that asks what that row can answer and sends one sealed record over a write-only lane. A drain on this site turns each record into a pull request against data/, with your reasoning as the body and nobody named; the row then shows proposals on this row: n open.
Open the map vault read-only in a new tab. Its read key is published on purpose; it cannot write. What it holds is the app and its build, not a copy of the pack.
What is worth contributing, most valuable first
- A measurement that replaces a claim. Most rows are derived. Run the probes on a real instance, attach the evidence file, change the row's tier. This is the single most useful thing anyone can do to this map.
- A profile that is missing. A product you use, or a setup of one — a container, a corporate-managed desktop, confirmations off. One file under
data/profiles/, named<vendor>/<product>/<variant>.json, listed inindex.json. Label every row's tier honestly; a derived profile is welcome and says it is derived. - A mandate you disagree with. Every one under
data/mandates/is a first draft. Change a row from want to do not want, add a note saying why, and that is an argument the site can show. - A capability the set is missing. Only if it is a new verb, object class or reach — a specific path or host is an instance of an existing one. New primitives need a probe.
The files
| File | What it is | Who edits it |
|---|---|---|
data/primitives.json | the capability vocabulary | rarely — a new verb, object or reach |
data/profiles/<vendor>/<product>/<variant>.json | one product in one setup, tool by tool | anyone who runs that product |
data/profiles/index.json | the manifest of profiles | add a line when you add a file |
data/reductions.json | what narrows each capability, and what it costs | anyone with a better setting |
data/ceiling.json | what nothing can do, and the control that stops it | anyone with a counter-example |
data/mandates/<id>.json | what a reasonable person wanted, per setup | anyone who disagrees |
data/mesh/ | the graph the levels are derived from | compiled — edit the sources |
data/pack.json | the manifest the game reads | generated by the build; do not edit |
The shape of a profile row
{ "capability": "read.file.host",
"tier": "derived", // derived · documented · measured · observed
"control": "the tool's own directory restriction and its confirmation prompt",
"control_tier": "setting", // none · expectation · setting · boundary
"note": "outside the working tree only with the prompt, which the shell does not need" }
tier is how the row is known. control_tier is what stands on the path: none; an expectation somebody wrote down; a setting the agent's own account could change; a boundary enforced above it. The matrix is coloured by the second and the tooltip names the first.
What the build checks
The release gate refuses a pull request whose data does not hold together: every capability id in every profile, reduction, mandate and ceiling row must exist in the primitives; every profile in the index must exist on disk; a profile's stated union must equal what its rows imply; a mandate cannot both want and not want the same capability. If it merges, the map is consistent.
Where the data came from
The primitives, profiles, reductions, ceiling and mesh were built at pki.sgit.ai under CC BY 4.0 and vendored here on 6 September 2026 so that this site could be their home for contribution. The mandates were authored here. Provenance.