Inspecting a Policy
Three commands, none of which execute anything.
explain — every effective rule
Section titled “explain — every effective rule”wardcell policy explain -- git pushIt lists which fragments were applied and why, then every rule they produced, per platform:
fragments applied (4): - base - integrations-core/git (selects_on command: git) - toolchains/apple-toolchain-core (required by: integrations-core/git) - workspace
== Linux (29 rules) == CATEGORY DETAIL DESCRIPTION FRAGMENT LAYER fs AllowRead /usr base base fs AllowRead ~/.gitconfig User gitconfig read by... integrations-core/git selected net.host host="github.com" allow_h... integrations-core/git selectedThe “fragments applied” block answers why a rule is present at all. The
net.host rows are the request-level rules inside each allow_http block, and
the DESCRIPTION column is the same-line comment from the fragment.
| Flag | |
|---|---|
--os linux|macos | restrict to rules that apply on that platform |
--output json | the stable, scriptable format |
--output pretty | the default; a full policy per OS, coloured on a terminal |
--output text | the same, never coloured |
--profile, --zone, --app-bundle | select as run would |
Use --os when a rule works on one platform and not the other — an untagged
block appears under both, a tagged one under only one.
render — the actual profile
Section titled “render — the actual profile”wardcell policy render -- git pushPrints the compiled backend profile: SBPL on macOS, the bwrap configuration on Linux. This is verbatim what gets applied.
explain tells you what the policy says; render tells you what the backend
was told. When those seem to disagree, render is the ground truth.
Add --os to render for the other platform from either host.
verify — validate without running
Section titled “verify — validate without running”wardcell policy verifywardcell policy verify --policy-root ./policies --output jsonParses and merges the whole root, checking schema_version and the merge
invariants — no unresolved same-layer ties, no base overrides. Suitable for CI.
It checks the root alone: no workspace policy is read, because a policy root is
shared and the directory a command will run in is not known here.
Debugging a rule that is not working
Section titled “Debugging a rule that is not working”explain | grep <the thing>— is the rule there at all? If not, the fragment was not selected.- Check the layer. A
selectedrule can be beaten by abasedeny. - Check the OS column. An
[macos]-tagged rule does nothing on Linux. - Check for a deny. Deny wins from anywhere;
explainnames the fragment. render— if the rule is inexplainbut not inrender, that is a backend bug worth reporting.
Network coverage notes
Section titled “Network coverage notes”explain prints what each grant costs on each platform — which grants are
transparent and which need client cooperation. Worth reading before assuming an
allow_tcp grant works everywhere. See
Platform Support.