@@ -21,45 +21,115 @@ export default function Home() {
2121
2222 const examplePayload = {
2323 report : {
24- ruleset_version : "0.8.1 " ,
25- generated_at_unix : 0 ,
26- total_duration_ms : 842 ,
24+ ruleset_version : "0.8.2 " ,
25+ generated_at_unix : 1710604800 ,
26+ total_duration_ms : 1240 ,
2727 cache_stats : {
28- nested_bundles : { hits : 1 , misses : 0 } ,
29- usage_scan : { hits : 2 , misses : 0 } ,
28+ nested_bundles : { hits : 2 , misses : 1 } ,
29+ usage_scan : { hits : 0 , misses : 4 } ,
3030 private_api_scan : { hits : 0 , misses : 1 } ,
3131 } ,
3232 results : [
33+ {
34+ rule_id : "RULE_XCODE_26_MANDATE" ,
35+ rule_name : "Xcode 26 / iOS 26 SDK Mandate" ,
36+ category : "Compliance" ,
37+ severity : "Error" ,
38+ status : "Fail" ,
39+ message : "App was built with Xcode 15.4 (15F31d) and iOS 17.5 SDK" ,
40+ recommendation : "From April 2026, all apps must be built with Xcode 26 and the iOS 26 SDK." ,
41+ duration_ms : 5 ,
42+ } ,
3343 {
3444 rule_id : "RULE_PRIVACY_MANIFEST" ,
3545 rule_name : "Missing Privacy Manifest" ,
3646 category : "Privacy" ,
3747 severity : "Error" ,
3848 status : "Fail" ,
39- message : "Missing PrivacyInfo.xcprivacy" ,
40- recommendation : "Add a PrivacyInfo.xcprivacy manifest to the bundle." ,
41- duration_ms : 12 ,
49+ message : "PrivacyInfo.xcprivacy was not found in the main bundle " ,
50+ recommendation : "Add a PrivacyInfo.xcprivacy file to your app bundle to declare data collection and and accessed APIs ." ,
51+ duration_ms : 8 ,
4252 } ,
4353 {
44- rule_id : "RULE_USAGE_DESCRIPTIONS " ,
45- rule_name : "Missing Usage Description Keys " ,
54+ rule_id : "RULE_PRIVACY_SDK_CROSSCHECK " ,
55+ rule_name : "Privacy Manifest vs SDK Usage " ,
4656 category : "Privacy" ,
47- severity : "Warning" ,
57+ severity : "Error" ,
58+ status : "Fail" ,
59+ message : "Detected GoogleAnalytics and FirebaseSDK but they are not declared in the manifest." ,
60+ recommendation : "Ensure PrivacyInfo.xcprivacy declares data collection and accessed APIs for all included third-party SDKs." ,
61+ duration_ms : 450 ,
62+ } ,
63+ {
64+ rule_id : "RULE_ENTITLEMENTS_MISMATCH" ,
65+ rule_name : "Debug Entitlements Present" ,
66+ category : "Entitlements" ,
67+ severity : "Error" ,
68+ status : "Fail" ,
69+ message : "Found get-task-allow=true in app entitlements" ,
70+ recommendation : "Remove the get-task-allow entitlement for App Store production builds." ,
71+ duration_ms : 15 ,
72+ } ,
73+ {
74+ rule_id : "RULE_BUNDLE_RESOURCE_LEAKAGE" ,
75+ rule_name : "Sensitive Files in Bundle" ,
76+ category : "Bundle" ,
77+ severity : "Error" ,
78+ status : "Fail" ,
79+ message : "Found .env and development.p12 inside the app bundle" ,
80+ recommendation : "Remove certificates, provisioning profiles, or secret files from the app bundle before submission." ,
81+ duration_ms : 25 ,
82+ } ,
83+ {
84+ rule_id : "RULE_CAMERA_USAGE" ,
85+ rule_name : "Missing Camera Usage Description" ,
86+ category : "Privacy" ,
87+ severity : "Error" ,
4888 status : "Fail" ,
49- message : "Missing required usage description keys " ,
50- recommendation : "Add NS*UsageDescription keys to Info.plist ." ,
51- duration_ms : 9 ,
89+ message : "NSCameraUsageDescription is missing from Info.plist " ,
90+ recommendation : "Add NSCameraUsageDescription with a clear, user-facing reason why your app needs camera access ." ,
91+ duration_ms : 4 ,
5292 } ,
5393 {
54- rule_id : "RULE_ATS_GRANULARITY " ,
55- rule_name : "ATS Exceptions Too Broad " ,
94+ rule_id : "RULE_ATS_AUDIT " ,
95+ rule_name : "ATS Exceptions Detected " ,
5696 category : "Ats" ,
5797 severity : "Warning" ,
5898 status : "Fail" ,
59- message : "AllowsArbitraryLoads is enabled" ,
60- recommendation : "Scope ATS exceptions to specific domains." ,
61- duration_ms : 8 ,
99+ message : "NSAllowsArbitraryLoads is enabled globally" ,
100+ recommendation : "Remove global ATS exceptions or scope them to specific domains with strong justification." ,
101+ duration_ms : 12 ,
102+ } ,
103+ {
104+ rule_id : "RULE_LSAPPLICATIONQUERIES_SCHEMES_AUDIT" ,
105+ rule_name : "LSApplicationQueriesSchemes Audit" ,
106+ category : "Metadata" ,
107+ severity : "Warning" ,
108+ status : "Fail" ,
109+ message : "Found 5+ potentially generic or private schemes in allowlist" ,
110+ recommendation : "Keep LSApplicationQueriesSchemes minimal and aligned with actual app handoff requirements." ,
111+ duration_ms : 10 ,
62112 } ,
113+ {
114+ rule_id : "RULE_EXPORT_COMPLIANCE" ,
115+ rule_name : "Export Compliance Declaration" ,
116+ category : "Metadata" ,
117+ severity : "Warning" ,
118+ status : "Fail" ,
119+ message : "ITSAppUsesNonExemptEncryption is not set" ,
120+ recommendation : "Explicitly set ITSAppUsesNonExemptEncryption in Info.plist to avoid App Store Connect prompts." ,
121+ duration_ms : 5 ,
122+ } ,
123+ {
124+ rule_id : "RULE_PRIVATE_API" ,
125+ rule_name : "Private API Usage Detected" ,
126+ category : "Private API" ,
127+ severity : "Warning" ,
128+ status : "Fail" ,
129+ message : "Potential usage of _GSSystemAdditions detected in binary" ,
130+ recommendation : "Remove private API usage or replace with public alternatives to avoid rejection." ,
131+ duration_ms : 600 ,
132+ }
63133 ] ,
64134 } ,
65135 } ;
@@ -464,11 +534,20 @@ export default function Home() {
464534 </ div >
465535 < div className = "tree-finding-meta" >
466536 < span > Rule: { item . rule_id } </ span >
467- { item . duration_ms && < span > { item . duration_ms } ms</ span > }
537+ { typeof item . duration_ms === "number" && (
538+ < span > { item . duration_ms } ms</ span >
539+ ) }
468540 </ div >
469541 < div className = "tree-finding-desc" >
470542 { item . message }
471543 </ div >
544+ { item . evidence && (
545+ < pre className = "tree-finding-evidence" >
546+ { typeof item . evidence === "string"
547+ ? item . evidence
548+ : JSON . stringify ( item . evidence , null , 2 ) }
549+ </ pre >
550+ ) }
472551 { item . recommendation && (
473552 < div className = "tree-finding-rec" >
474553 { item . recommendation }
0 commit comments