En la raíz, la estructura de carpetas es la siguiente:

Contiene los archivos propios de cada una de las aplicaciones.
Contiene los archivos javascript y css compilados por la extensión Assets.
Contiene todo tipo de librerías de uso común entre las aplicaciones.
Contiene los recursos estáticos administrados por las aplicaciones. Pueden ser: imágenes, videos, documentos, etc.
Contiene archivos que almacenan los datos que personalizan el sitio. Algunos de estos datos pueden ser: configuraciones, traducciones, logs, temas, caché, temporales, etc.
Contiene las librerías cargadas con composer.
Archivo con las configuraciones para inicializar el sistema.
Un modelo de archivo de configuraciones del servidor, sirve, por ejemplo, para activar el módulo mod_rewrite y reescribir las url. Para ponerlo en funcionamiento, debe renombrarlo colocándole un punto al comienzo.
Archivo único de acceso a los recursos dinámicos.
La licencia para el uso de este software.
Contiene todos los archivos propios de una aplicación, vale decir, no compartidos con otras aplicaciones. Estos archivos serán reemplazados en cada actualización.
Dentro de la carpeta de app/ cada extensión tendrá su propia carpeta. Esta es una imagen de app/ al momento de instalar el CMS:

Ahora bien, en cada carpeta de app/ se encuentran los archivos que forman parte de la aplicación. Todos los archivos estarán ordenados con patrones de diseños predefinidos.
A continuación, a modo de ejemplo, mostramos el contenido de la carpeta app/settings/:

En general, las carpetas describen el contenido de las mismas y sólo los controladores se encuentran en la raíz.
Los modelos se encuentran en la carpeta app/{{extension}}/models/. Un ejemplo podría ser:

El archivo php y la clase en su interior deberá tener un nombre con la siguiente estructura «{{Component}}{{Subcomponent}}Model».
Muchas veces, por rendimiento, necesidad o mayor claridad, es útil organizar los modelos. Para ello, es posible utilizar subcarpetas. Dentro de las subcarpetas, el nombre del modelo será «{{Subfolder}}{{Component}}{{Subcomponent}}Model».
Para que el controlador incluya las vistas de modo automático, es necesario tener en cuenta algunas convenciones.
El primer nivel de carpetas está dado por el punto de acceso en que el controlador se ejecuta. Luego, se debe tener en cuenta si es un componente o un subcomponente.
Si la vista pertenece a un componente, ya no es necesario seguir agregando carpetas. El nombre de la vista será el de la tarea que ejecutará el controlador en formato PascalCase.
La ruta quedará definida como «app/{{extension}}/views/{{access_point}}/{{Task}}.php».
Si la vista pertenece a un subcomponente se debe crear otra carpeta con el nombre del mismo. El nombre de la vista será, como en el caso anterior, el de la tarea que ejecutará el controlador en formato PascalCase.
La ruta quedará quedará definida como «app/{{extension}}/views/{{access_point}}/{{subcomponent}}/{{Task}}.php».
Los controladores quedarán dispuestos en la raíz de la carpeta. Esto permite tener una idea rápida de los componentes disponibles en una aplicación.
El nombre del archivo tendrá el formato «{{Accesspoint}}{{Component}}{{Subcomponent}}Controller».
Existe una posibilidad de definir url por fuera de las convenciones del CMS. Para ello, se debe crear una carpeta llamada routes/ y colocar allí los archivos donde se definirán las nuevas rutas.
Los archivos deberán ser nombrados como «{{Accesspoint}}{{Component}}Routes.php».
Contiene todo tipo de librerías de uso común entre las aplicaciones. Actualmente, estas librerías son las siguientes:

Contiene las librerías del lado del servidor, es decir, las librerías PHP.
Contiene funciones encargadas de modificar el flujo de salida. Por lo general, son utilizadas para que la salida de una extensión sea enriquecida por el aporte de otras extensiones.
Contiene las librerías y recursos del lado del cliente, es decir, todo lo que no sea PHP, por ejemplo: css, javascript, imágenes, tipografías, pre-procesadores de hojas de estilos, etc.
Contiene clases que generan dinámicamente una porción de html, como ser: un formulario, una lista o un paginador.
Contiene las librerías del lado del servidor, es decir, las librerías PHP.
Las librerías están agrupadas por la extensión a las que pertenecen. Por lo tanto, si observamos dentro de la carpeta cms/libraries/, podemos ver algo similar a:

En cada una de esas carpetas, las librerías deberán ser nombradas comenzando con el nombre de la extensión, por ejemplo «cms/libraries/settings/Settings.php».
Contiene funciones encargadas de modificar el flujo de salida. Por lo general, son utilizadas para que la salida de una extensión sea enriquecida por el aporte de otras extensiones.
La organización de las carpetas tiene tres niveles, esto es así para lograr generar código intercambiable. Los niveles corresponden a:
La ruta completa a un plugin estará dada por:
cms/plugins/{{extension_alias}}/{{plugin_name}}/{{alter_plugin}}/{{plugin_name}}.{{plugin_hook}}.php
Como podemos observar, el nombre del archivo que contiene el plugin también tiene su convención.
Dentro de un plugin, es posible que debamos ejecutar varias tareas, para ello declaramos varios archivos con un hook diferente para cada uno de ellos. Por ejemplo, si definimos un editor bbcode para un formulario, debemos considerar el hook para cargar el editor en dicho formulario y un hook para procesar el contenido del editor.
Contiene las librerías y recursos del lado del cliente, es decir, todo lo que no sea PHP, por ejemplo: css, javascript, imágenes, tipografías, pre-procesadores de hojas de estilos, etc.
Las librerías están agrupadas por la extensión a las que pertenecen. Por lo tanto, si observamos dentro de la carpeta cms/scripts/, podemos encontrar algo similar a:

Dentro de cada extensión, no hay convenciones, aunque es una buena práctica separar el código según su tipo: css/, font/, js/, sass/, etc.
Contiene clases que generan dinámicamente una porción de html, como ser: un formulario, una lista o un paginador. Su estructura de tres niveles, similar a la de plugins, tiene como fin generar fragmentos intercambiables entre sí.
Los tres niveles corresponden a:
La ruta completa a un fragmento estará dada por:
cms/snippets/{{extension_alias}}/{{snippet_name}}/{{alter_snippet}}/snippet.php
La alternativa por defecto para los fragmentos será master.
Contiene los recursos estáticos administrados por las aplicaciones. Pueden ser: imágenes, videos, documentos, etc. El contenido está agrupado por la extensión a las que pertenecen.
Para la compilación, puede ser útil utilizar el archivo .gitignore. Las directivas que permite el compilador son: *, **, !. Para más información gitignore.
Contiene archivos que almacenan los datos que personalizan el sitio. Algunos de estos datos pueden ser: configuraciones, traducciones, logs, temas, caché, temporales, etc.
En su interior, las carpetas dependen de las extensiones, no hay convenciones, aunque sí existen algunas carpetas que utiliza el sistema, como ser:
Utilizada por la extensión homónima para almacenar los datos de compilación y los temas.
Utilizada por la extensión homónima para almacenar el caché.
Utilizada por la extensión language para almacenar las traducciones.
Puesta a disposición por el sistema para que sea utilizada por aquellas extensiones que deseen almacenar registros.
Utilizada por la extensión homónima para almacenar las configuraciones.
Utilizada por la extensión settings para crear, a partir de textos, un código PHP que contenga las funciones de gettext. De este modo, los textos se hacen "visibles" para la herramientas de traducción, como por ejemplo poedit.
Carpeta temporal utilizada por la extensión extensions para la descarga e instalación de actualizaciones.