{"actions":{"bootstrapAndRun":{"effect":"installs rote if missing, inspects, prepares, and asks before running","href":"https://play.modiqo.ai/install?play=jaylabs/audit-play@0.5.3","method":"GET","rel":"https://rote.dev/rels/bootstrap-and-run","requiresConsent":true,"responseMediaType":"text/x-shellscript"},"inspect":{"command":"rote play inspect https://play.modiqo.ai/jaylabs/audit-play@0.5.3","effect":"read-only"},"installCliOnly":{"effect":"installs the rote CLI, nothing else","href":"https://play.modiqo.ai/install","method":"GET","rel":"https://rote.dev/rels/install-cli","requiresConsent":true,"responseMediaType":"text/x-shellscript"},"run":{"command":"rote play run https://play.modiqo.ai/jaylabs/audit-play@0.5.3","effect":"executes the play locally after consent","headless":{"approvalAssertion":"--yes","approvalRequiredBeforeInvocation":true,"commandTemplate":"rote play run https://play.modiqo.ai/jaylabs/audit-play@0.5.3 <name=value...> --yes","stdinPolicy":"never pipe input to automate the interactive Ready selector"},"requiresConsent":true}},"description":"After months of clicking yes, your Claude Code or Codex allow list is one nobody has read. On the machine this was built on, 168 allow rules had mostly fired nothing in three days. Run it with no parameters first; it reads only this machine and needs no key. It joins what you granted against what ran across your projects, compares that with your last run, re-reads one rule and one transcript to check itself, and writes a digest you can post to a webhook. Every count says where it is capped. write-provenance reads the same transcripts to ask which instruction caused each write. Your settings files are only ever read from; it writes reports into a directory you choose.","distribution":{"digest":"sha256:73ef6e2836f8bff8dd6a6f9ca2901d84d7582975990a8a81f07c7387496a46b6","mediaType":"application/vnd.modiqo.rote-flow","size":124208,"verifiedBy":"rote verifies the downloaded archive against this digest before it runs"},"effects":{"credentialsProvidedBy":"runner","credentialsRemainLocal":true,"declaredWrites":[],"publisherReceivesCredentials":false},"id":"https://play.modiqo.ai/jaylabs/audit-play@0.5.3","inputPolicy":{"optionalWithDefault":"show_default_and_accept_override","optionalWithoutDefault":"omit_unless_supplied","required":"ask","secrets":"collect_locally_outside_conversation"},"links":{"docs":"https://rote.dev","page":"https://play.modiqo.ai/jaylabs/audit-play@0.5.3","protocol":"https://play.modiqo.ai/.well-known/rote","self":"https://play.modiqo.ai/jaylabs/audit-play@0.5.3.json"},"name":"audit-play","owner":{"kind":"org","slug":"jaylabs"},"parameters":[{"default":"all","description":"Which project to audit. The word all audits every project this machine records, which is what a bare run with no parameters does. A path narrows to one project, selecting its policy files and its transcript directory. A path inside the rote run workspace is the play's own scratch directory rather than a project, so it falls back to all with a warning.","example":"/Users/you/code/my-project","input":{"allowCustom":true,"choices":[],"label":"Project path"},"name":"project_path","required":false,"type":"string"},{"default":"72","description":"How far back to look, in hours, filtered per event on the record timestamp. 0 means the whole recorded history. Shorter than a weekend produces mostly false idleness.","example":"168","input":{"allowCustom":true,"choices":[],"label":"Window hours"},"name":"window_hours","required":false,"type":"string"},{"default":"claude","description":"Which agent harness wrote the transcripts and config. claude reads ~/.claude/projects, ~/.claude.json and the settings files. codex reads ~/.codex/sessions rollouts and ~/.codex/config.toml, where policy is an approval mode rather than a rule list, so the three rule-shaped finding classes read not applicable. Any other value is a hard fault rather than a silent empty report.","example":"codex","input":{"allowCustom":false,"choices":[{"label":"claude","value":"claude"},{"label":"codex","value":"codex"}],"label":"Harness"},"name":"harness","required":false,"type":"string","validValues":["claude","codex"]},{"default":"has been denied|Permission denied|permission was denied|was denied by|tool use was rejected|Sandbox\\(Denied","description":"Case insensitive regex that marks an errored tool result as a denial rather than an execution failure. Exposed because the harness wording is not a stable contract, and misreading it turns a control that worked into a control that was bypassed. The default carries the Claude Code phrasings and Codex's Sandbox(Denied marker.","example":"not allowed|refused","input":{"allowCustom":true,"choices":[],"label":"Denial patterns"},"name":"denial_patterns","required":false,"type":"string"},{"default":"true","description":"Whether to read subagent transcripts under each session's subagents directory alongside the session transcripts. They hold real tool calls, so excluding them makes every unused finding a floor.","example":"false","input":{"allowCustom":false,"choices":[{"label":"true","value":"true"},{"label":"false","value":"false"}],"label":"Include subagents"},"name":"include_subagents","required":false,"type":"string","validValues":["true","false"]},{"default":"user,project","description":"Comma separated settings scopes to union. Each scope reads its settings.json and settings.local.json.","example":"project","input":{"allowCustom":true,"choices":[],"label":"Policy scopes"},"name":"policy_scopes","required":false,"type":"string"},{"default":"findings","description":"findings prints the top items per class and omits the per-file array from traces.json; all prints every row in the least privilege profile and writes the per-file array. Neither setting changes a count.","example":"all","input":{"allowCustom":false,"choices":[{"label":"findings","value":"findings"},{"label":"all","value":"all"}],"label":"Report"},"name":"report","required":false,"type":"string","validValues":["findings","all"]},{"description":"An earlier run's shadow-diff.json to DIFF against, so the report says what moved since then. What became dead, what became used, which rules were added or removed, which servers went idle or came back, which blocks started or stopped. Two runs taken over different windows, scopes, harnesses or project counts are reported as not comparable rather than subtracted. With state_dir set this is found for you. Empty means no comparison.","example":"/tmp/last-audit/shadow-diff.json","input":{"allowCustom":true,"choices":[],"label":"Since"},"name":"since","required":false,"type":"string"},{"description":"Audit one run instead of the machine. Takes a transcript file path or a session id; executed evidence then comes from that transcript and the subagents it spawned, and nothing else. The window still applies inside it. A machine-wide audit answers what a policy has authorised over months; this answers what one piece of work actually needed. A session that cannot be found is a hard fault rather than a silent fallback to everything.","example":"a1cafe13-0abf-4a91-b65f-00ff1db6f676","input":{"allowCustom":true,"choices":[],"label":"Session"},"name":"session","required":false,"type":"string"},{"description":"An earlier run's shadow-diff.json to REPRODUCE against, so the report says whether every count comes out the same and, where one did not, which condition moved underneath it. Window bounds, transcript files enumerated, rules read, servers advertised, harness, scope, scan time. A count that moved while a condition moved was measuring something else, not failing to reproduce. Use since for what changed; use this for whether the audit itself is stable. Empty means no check.","example":"/tmp/last-run/shadow-diff.json","input":{"allowCustom":true,"choices":[],"label":"Compare to"},"name":"compare_to","required":false,"type":"string"},{"description":"Where the nine report files are written, seven JSON files and two markdown pages, alongside a traces directory holding one shard per project. Empty means the run workspace working directory. traces.json records the command, file path or URL each call was made with, truncated, with credential-shaped spans masked; treat it as you would your shell history. When state_dir is also set, one dated copy of shadow-diff.json is left there as the next run's baseline.","example":"/tmp/shadow-diff","input":{"allowCustom":true,"choices":[],"label":"Out dir"},"name":"out_dir","required":false,"type":"string"},{"description":"A directory this run leaves its shadow diff in, so the next run has a baseline without anyone pasting a path. Given one, drift picks the newest earlier diff that used the same harness, scope and window, and the directory is pruned to the most recent thirty. Empty means the run compares against nothing and leaves nothing behind.","example":"/tmp/audit-state","input":{"allowCustom":true,"choices":[],"label":"State dir"},"name":"state_dir","required":false,"type":"string"},{"default":"12","description":"How many projects the transcript fan-out reads, at most. Projects that carry their own settings file are always read first, because dropping one of those puts every rule it grants into the unused list by construction. Anything past the cap is named in the report and its usage counts as zero, which is a gap in the evidence rather than a finding. Values above 24 are capped.","example":"24","input":{"allowCustom":true,"choices":[],"label":"Max projects"},"name":"max_projects","required":false,"type":"string"},{"default":"summary","description":"How much matchable input each project shard keeps. summary keeps the command, path and URL strings for the window horizon only, which is the horizon every finding class is decided at; the all-time count of a rule with an argument then reads unknown rather than a guess. full keeps them for the whole history as well. On the machine this was built on the default cut a bare run from 31 MB of traces to under 5 MB. Neither setting changes a finding class. A proposal that needs an all-time zero, WRITE_NEVER_EXERCISED above all, is only made under full or for a tool that never ran at all; the default made 35 of the 116 proposals full made on that machine.","example":"full","input":{"allowCustom":false,"choices":[{"label":"summary","value":"summary"},{"label":"full","value":"full"}],"label":"Detail"},"name":"detail","required":false,"type":"string","validValues":["summary","full"]},{"description":"An http or https endpoint the digest is posted to, once, when a run finishes. Empty means no socket is opened at all and the digest is only written to disk, which is what a bare run does. The body carries the counts and the coverage line, and it names your project paths, so send it somewhere you would send your own report.","example":"https://hooks.example.com/services/T000/B000/XXXX","input":{"allowCustom":true,"choices":[],"label":"Webhook url"},"name":"webhook_url","required":false,"type":"string"}],"preparation":[{"action":{"command":"rote play inspect https://play.modiqo.ai/jaylabs/audit-play@0.5.3 --json","effect":"read-only"},"step":1,"type":"inspect_local_readiness"},{"references":["/parameters"],"step":2,"type":"collect_parameters"},{"references":["/parameters","/requirements","/effects"],"step":3,"type":"review"},{"consentBoundary":"the user approves the exact play and parameter values","references":["/parameters","/requirements","/effects"],"step":4,"type":"obtain_run_consent"},{"action":{"command":"rote play run https://play.modiqo.ai/jaylabs/audit-play@0.5.3","headlessCommandTemplate":"rote play run https://play.modiqo.ai/jaylabs/audit-play@0.5.3 <name=value...> --yes"},"preservesAcquisitionBoundaries":["adapter_selection","oauth_dcr","google_discovery","static_token_setup","runtime_security_checks"],"requiresConsent":true,"step":5,"type":"run"}],"producedBy":{"roteVersion":"0.80.0"},"publishedAt":"2026-09-06T17:57:11.299466+00:00","reference":"jaylabs/audit-play@0.5.3","requirements":{"adapters":[],"browser":{"dependencies":[],"runtime":false,"signIn":false},"hostToolRequirements":[{"command":"python3","required":true,"versionRequirement":">=3.9"}],"localTools":["python3"],"roteCli":{"minimumVersion":"0.62.0"},"sessions":false},"resolution":"pinned","schema":"rote.play.v1","stats":{"downloads":4,"installs":0},"steps":{"count":12,"names":["digest","discover_projects","drift","inventory_grants","join_diff","merge_traces","preflight","profile","read_policy","read_traces","resolve_baseline","verify_sample"]},"title":"audit-play","type":"play","version":"0.5.3","visibility":"public"}