verifyos-cli 0.4.0

AI agent-friendly Rust CLI for scanning iOS app bundles for App Store rejection risks before submission.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
<p align="center">
  <img src="icons/verifyOS.png" alt="verifyOS icon" />
</p>


<p align="center">
  <a href="https://crates.io/crates/verifyos-cli">
    <img src="https://img.shields.io/crates/v/verifyos-cli.svg" alt="Crates.io" />
  </a>
  <a href="https://docs.rs/verifyos-cli">
    <img src="https://img.shields.io/docsrs/verifyos-cli" alt="Docs.rs" />
  </a>
  <a href="https://github.com/0xBoji/verifyos-cli/actions/workflows/rust.yml">
    <img src="https://github.com/0xBoji/verifyos-cli/actions/workflows/rust.yml/badge.svg" alt="CI" />
  </a>
  <a href="https://opensource.org/licenses/MIT">
    <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" />
  </a>
</p>

`verifyOS-cli` is an AI agent-friendly, pure Rust CLI for scanning Apple app bundles (like `.ipa`, `.app`, `Info.plist`, and Mach-O binaries) for App Store rejection risks before submission. It is built for developers, vibecoders, and automation workflows that want fast, local feedback before App Store Connect becomes the bottleneck.

The App Store Connect validation step is historically a "black box" that costs developers hours of waiting. By shifting validation to your local machine, CI runner, or AI agent loop, verifyOS-cli helps teams catch rejection risks early and produce structured output an agent can use to patch issues faster. Unlike Apple's toolchain (`codesign`, `otool`), this tool is built entirely in Rust.

## What it does

- Acts as a local static analysis orchestrator for iOS/macOS apps.
- **Ruleset metadata**: Every finding includes `rule_id`, `severity`, and `category` (Privacy, Entitlements, Metadata, etc.).
- **Privacy Manifests**: Checks for missing `PrivacyInfo.xcprivacy`.
- **Permissions (Info.plist)**: Uses a heuristic Mach-O scan to infer which `NS*UsageDescription` keys are required, then validates presence and non-empty values.
- **LSApplicationQueriesSchemes**: Audits custom URL scheme allowlists for duplicates, invalid entries, and potential private schemes.
- **UIRequiredDeviceCapabilities**: Flags capabilities that don't match observed binary usage.
- **ATS**: Flags overly broad ATS exceptions (global allows, includes subdomains, insecure TLS settings).
- **Bundle leakage**: Fails if sensitive files (e.g., `.p12`, `.pem`, `.mobileprovision`, `.env`) are found inside the app bundle.
- **Versioning**: Ensures `CFBundleShortVersionString` and `CFBundleVersion` are valid and present.
- **Extension entitlements**: Validates extension entitlements are a subset of the host app and required keys exist for common extension types.
- **Privacy SDK cross-check**: Warns if common SDK signatures are detected but PrivacyInfo.xcprivacy lacks declarations.
- **Entitlements**: Detects debug-only entitlements (like `get-task-allow=true`) and flags mismatches between app entitlements and `embedded.mobileprovision` (APNs, keychain groups, iCloud containers).
- **Signing**: Ensures embedded frameworks/extensions are signed with the same Team ID as the app binary.
- **CI-friendly reports**: Outputs `table`, `json`, or `sarif` with evidence and remediation recommendations.

## Installation

### From crates.io

```bash
cargo install verifyos-cli
```

This installs the `voc` binary for the CLI.

## Quick start

Run the CLI tool against your `.ipa` or `.app` path:

```bash
voc --app path/to/YourApp.ipa
```

Bootstrap an `AGENTS.md` file for AI agent workflows:

```bash
voc init
```

If `AGENTS.md` already exists, `voc init` preserves your custom content and replaces only the managed `verifyos-cli` block.

### Profiles

Run a smaller core ruleset or the full scan:

```bash
voc --app path/to/YourApp.ipa --profile basic
```

```bash
voc --app path/to/YourApp.ipa --profile full
```

`full` is the default if `--profile` is omitted.

### Exit thresholds

Control when the CLI exits with code `1`:

```bash
voc --app path/to/YourApp.ipa --fail-on off
```

```bash
voc --app path/to/YourApp.ipa --fail-on warning
```

`error` is the default if `--fail-on` is omitted.

### Rule selectors

Run only specific rules or exclude noisy ones by rule ID:

```bash
voc --app path/to/YourApp.ipa --include RULE_PRIVATE_API,RULE_ATS_AUDIT
```

```bash
voc --app path/to/YourApp.ipa --exclude RULE_PRIVATE_API
```

Selectors apply after the chosen `--profile`, so `basic` plus `--include` can narrow the set even further.

### Rule inventory

List available rules and their default profile membership:

```bash
voc --list-rules
```

Machine-readable inventory for agents and CI:

```bash
voc --list-rules --format json
```

Inspect one rule in detail:

```bash
voc --show-rule RULE_PRIVATE_API
voc --show-rule RULE_PRIVATE_API --format json
```

### Config file

If `verifyos.toml` exists in the current working directory, `voc` will load it automatically. You can also point to a specific config file:

```bash
voc --app path/to/YourApp.ipa --config verifyos.toml
```

Example config:

```toml
format = "table"
profile = "full"
fail_on = "error"
timings = "off"
include = []
exclude = []
```

CLI flags override config file values.

### AGENTS.md bootstrap

Generate or refresh an `AGENTS.md` playbook in the current directory:

```bash
voc init
```

Write to a custom path:

```bash
voc init --path docs/AGENTS.md
```

Use one root directory for generated init assets:

```bash
voc init --output-dir .verifyos --from-scan path/to/YourApp.ipa
```

Scan an app first and inject the current failing rules into `AGENTS.md`:

```bash
voc init --from-scan path/to/YourApp.ipa
```

Use a lighter profile when you only want a quick playbook refresh:

```bash
voc init --from-scan path/to/YourApp.ipa --profile basic
```

Keep only new or regressed risks relative to an older report:

```bash
voc init --from-scan path/to/YourApp.ipa --baseline old-report.json
```

Refresh `AGENTS.md` and generate an agent bundle in one step:

```bash
voc init --from-scan path/to/YourApp.ipa --agent-pack-dir .verifyos-agent
```

Also inject copy-paste follow-up commands for the next agent loop:

```bash
voc init --from-scan path/to/YourApp.ipa --agent-pack-dir .verifyos-agent --write-commands
```

Generate a runnable follow-up script too:

```bash
voc init --from-scan path/to/YourApp.ipa --agent-pack-dir .verifyos-agent --write-commands --shell-script
```

Generate a dedicated AI handoff prompt too:

```bash
voc init --output-dir .verifyos --from-scan path/to/YourApp.ipa --fix-prompt
```

The generated block includes:
- a recommended `voc` workflow for quick and release scans
- AI agent fix-loop rules
- a live rule inventory with `rule_id`, category, severity, and default profiles
- an optional `Current Project Risks` section with priority order and suggested fix scopes from the latest scan
- an optional pointer to `agent-pack.json` and `agent-pack.md` when `--agent-pack-dir` is used
- an optional `Next Commands` section with exact re-scan and report refresh commands when `--write-commands` is used
- an optional `.verifyos-agent/next-steps.sh` when `--shell-script` is used
- an optional `fix-prompt.md` when `--fix-prompt` is used

When `--baseline` is provided with `--from-scan`, the `Current Project Risks` section only keeps findings that are new or regressed compared with the older JSON report. That keeps the playbook focused on what changed in the current branch.

`voc init` uses a managed block, so you can safely keep your own notes above or below it.

### Doctor

Run a quick self-check on the current setup:

```bash
voc doctor
```

Check an output root created by `voc init --output-dir`:

```bash
voc doctor --output-dir .verifyos
```

`voc doctor` validates:
- config parsing
- `AGENTS.md` presence
- referenced agent assets like `agent-pack.json`, `agent-pack.md`, and `next-steps.sh`
- sample `voc` commands inside `AGENTS.md`

### GitHub Actions wrapper

This repo ships a reusable workflow at `.github/workflows/voc-analysis.yml` for CI and PR review flows.

Manual run from the Actions tab:

```text
Workflow: voc Analysis
Inputs:
- app_path
- baseline_path (optional)
- profile
- fail_on
- output_dir
- comment_on_pr
- pr_number (optional)
```

Reusable workflow example:

```yaml
name: App review

on:
  pull_request:
    branches: ["main"]

jobs:
  voc:
    uses: 0xBoji/verifyos-cli/.github/workflows/voc-analysis.yml@main
    with:
      app_path: path/to/YourApp.ipa
      baseline_path: baseline.json
      profile: full
      fail_on: error
      output_dir: .verifyos-ci
      comment_on_pr: true
      pr_number: ${{ github.event.pull_request.number }}
```

The workflow generates and uploads:
- `report.sarif`
- `AGENTS.md`
- `fix-prompt.md`
- `doctor.json`
- `.verifyos-agent/agent-pack.json`
- `.verifyos-agent/agent-pack.md`
- `.verifyos-agent/next-steps.sh`

When `comment_on_pr` is enabled and a PR number is available, the workflow also updates a sticky PR comment with a compact analysis summary and links the review flow to the uploaded assets.

### Output Formats

Table (default):

```bash
voc --app path/to/YourApp.ipa --format table
```

JSON:

```bash
voc --app path/to/YourApp.ipa --format json > report.json
```

SARIF (for GitHub code scanning, etc.):

```bash
voc --app path/to/YourApp.ipa --format sarif > report.sarif
```

Markdown report (agent-friendly):

```bash
voc --app path/to/YourApp.ipa --md-out report.md
```

Agent fix pack:

```bash
voc --app path/to/YourApp.ipa --agent-pack fixes.json
```

The agent pack writes a machine-readable JSON file with failing findings only, including `rule_id`, `message`, `evidence`, `recommendation`, `priority`, `suggested_fix_scope`, `target_files`, `patch_hint`, and `why_it_fails_review`.

Markdown agent pack:

```bash
voc --app path/to/YourApp.ipa --agent-pack fixes.md --agent-pack-format markdown
```

Bundle agent pack:

```bash
voc --app path/to/YourApp.ipa --agent-pack .verifyos-agent --agent-pack-format bundle
```

`--agent-pack-format` supports `json`, `markdown`, and `bundle`. `bundle` writes both `agent-pack.json` and `agent-pack.md`, with the Markdown output grouped by `suggested_fix_scope` so AI agents and humans can work from the same fix queue.
The extra patch-hint fields are designed so an AI agent can jump directly to likely edit targets such as `Info.plist`, `PrivacyInfo.xcprivacy`, entitlements, or bundled SDK/resources without guessing first.

Timing summary:

```bash
voc --app path/to/YourApp.ipa --timings
```

Full timing details:

```bash
voc --app path/to/YourApp.ipa --timings full
```

`--timings` by itself defaults to `summary`, which prints total scan time, slowest rules, and cache activity without adding a per-rule time column. Use `--timings full` when you want the table and markdown outputs to include per-rule execution times too.
JSON and Markdown reports still carry timing data for automation and profiling.
The timing summary also highlights the slowest rules so you can spot hot paths quickly.
It also includes cache hit/miss activity for artifact scans so we can tell whether a slow run is coming from repeated IO or genuinely expensive rules.
JSON and SARIF outputs now expose machine-readable perf metadata too, including `slow_rules`, `total_duration_ms`, and cache telemetry.

### Baseline Mode

Suppress existing findings by providing a baseline JSON report. Only *new* failing findings will be shown:

```bash
voc --app path/to/YourApp.ipa --format json > baseline.json
voc --app path/to/YourApp.ipa --baseline baseline.json
```

Baseline matching currently uses `rule_id + evidence` for failing findings.

### Example Passing Output
```text
Analysis complete!
╭────────────────────────────────────────┬─────────────┬──────────┬────────┬─────────╮
│ Rule                                   ┆ Category    ┆ Severity ┆ Status ┆ Message │
╞════════════════════════════════════════╪═════════════╪══════════╪════════╪═════════╡
│ Missing Privacy Manifest               ┆ Privacy     ┆ ERROR    ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Missing Camera Usage Description       ┆ Permissions ┆ ERROR    ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ LSApplicationQueriesSchemes Audit      ┆ Metadata    ┆ WARNING  ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ UIRequiredDeviceCapabilities Audit     ┆ Metadata    ┆ WARNING  ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ ATS Exceptions Too Broad               ┆ ATS         ┆ WARNING  ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Sensitive Files in Bundle              ┆ Bundling    ┆ ERROR    ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Info.plist Versioning Consistency      ┆ Metadata    ┆ WARNING  ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Extension Entitlements Compatibility   ┆ Entitlements┆ WARNING  ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Privacy Manifest vs SDK Usage          ┆ Privacy     ┆ WARNING  ┆ PASS   ┆ PASS    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Debug Entitlements Present             ┆ Entitlements┆ ERROR    ┆ PASS   ┆ PASS    │
╰────────────────────────────────────────┴─────────────┴──────────┴────────┴─────────╯
```

### Example Failing Output (Exits with code 1)
```text
Analysis complete!
╭────────────────────────────────────────┬─────────────┬──────────┬────────┬────────────────────────────────────────────────────────────╮
│ Rule                                   ┆ Category    ┆ Severity ┆ Status ┆ Message                                                    │
╞════════════════════════════════════════╪═════════════╪══════════╪════════╪════════════════════════════════════════════════════════════╡
│ Missing Privacy Manifest               ┆ Privacy     ┆ ERROR    ┆ FAIL   ┆ Missing PrivacyInfo.xcprivacy                              │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Missing required usage description keys┆ Privacy     ┆ WARNING  ┆ FAIL   ┆ Missing required usage description keys                    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ LSApplicationQueriesSchemes Audit      ┆ Metadata    ┆ WARNING  ┆ PASS   ┆ PASS                                                       │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ UIRequiredDeviceCapabilities Audit     ┆ Metadata    ┆ WARNING  ┆ PASS   ┆ PASS                                                       │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ ATS Exceptions Too Broad               ┆ ATS         ┆ WARNING  ┆ PASS   ┆ PASS                                                       │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Sensitive Files in Bundle              ┆ Bundling    ┆ ERROR    ┆ PASS   ┆ PASS                                                       │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Info.plist Versioning Consistency      ┆ Metadata    ┆ WARNING  ┆ PASS   ┆ PASS                                                       │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Extension Entitlements Compatibility   ┆ Entitlements┆ WARNING  ┆ PASS   ┆ PASS                                                       │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Privacy Manifest vs SDK Usage          ┆ Privacy     ┆ WARNING  ┆ PASS   ┆ PASS                                                       │
╰────────────────────────────────────────┴─────────────┴──────────┴────────┴────────────────────────────────────────────────────────────╯
```

## Architecture

This project is structured with modularity in mind:

- **`core/`**: Orchestrator and logic execution engine.
- **`parsers/`**: Format handlers (`zip` extraction, `plist` mapping, `goblin`/`apple-codesign` Mach-O inspection).
- **`rules/`**: Trait-based rule engine representing the validation checks.

## Conventional Commits

To ensure the automated semantic versioning and changelog parsing through the `release-plz` bot behaves properly, developers MUST use **Git Conventional Commits** format:

*   **`feat:`** A new feature (correlates to a MINOR `v0.X.0` bump).
*   **`fix:`** A bug fix (correlates to a PATCH `v0.0.X` bump).
*   **`docs:`** Documentation only changes.
*   **`chore:`** Changes to the build process or auxiliary tools.

## CI and releases

- CI: fmt + clippy + tests on push and pull request.
- Automated release PRs: `release-plz` workflow.
- Publishing: crates.io + GitHub release artifacts.

## License

MIT