--- url: /mbzoo/docs/guide/what-is-mbz.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # What is an .mbz? An `.mbz` file is a **Moodle course backup**: a package containing the course's sections, activities, files, settings and (optionally) user data. ## Container formats | Format | Since | Notes | | ------ | ------------------------------ | ---------------------------------------------------------- | | ZIP | Moodle 2.0 | No ZIP64 support inside Moodle itself (4 GB practical cap) | | TAR.GZ | default since 2.9 (opt-in 2.6) | POSIX ustar; no size cap in practice | MBZoo detects the format from magic bytes and supports **both**. ## Inside the archive ``` moodle_backup.xml course/section/activity skeleton, and the settings that decide what else is in here files.xml file index (contenthash, component, filearea…) course/course.xml full course metadata (fullname lives here) sections/section_N/ per-section name, summary, activity order activities/_N/ per-activity XML — see below files/<2 hex>/ content-addressed file pool questions.xml the question bank, shared by every quiz gradebook.xml category tree, aggregation, grade letters users.xml the people — only when the backup was taken with user data (see Privacy) ``` An activity directory holds more than its module payload, and the siblings are where several things hide: ``` activities/assign_42/ assign.xml the module's own settings and content module.xml visibility, completion rules, availability, tags grades.xml this activity's grade item: out of, pass, weight grading.xml rubric or marking guide, when one is defined inforef.xml which files.xml records this activity uses calendar.xml roles.xml competencies.xml filters.xml ``` ## The setting that decides everything The single most useful thing to know about a `.mbz` is whether it was taken **with user data**. Every module writes its full XML tree either way; what the `users` setting gates is each element's _data source_. Two modules that look equally rich in the schema can be worlds apart in a real file. A `lesson` writes all of its pages and answers unconditionally — the whole authored lesson is there. A `forum` writes nothing but the forum record; every discussion and post is user data. That is why an empty glossary in a content-only backup is not a bug, and why MBZoo says _why_ it is empty rather than just that it is. | Always in the backup | Only with user data | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | lesson pages and answers, choice options, database fields, workshop instructions and examples, quiz slots and the question bank, grade items and rubrics, the gradebook structure | forum discussions and posts, glossary entries, database records, wiki pages, chat messages, assignment submissions, quiz attempts, everyone's marks | ## Links that point nowhere A backup may be restored onto a different site, so Moodle cannot store absolute URLs for course-internal links. It rewrites them as `$@COURSEVIEWBYID*62@$` tokens at backup time and decodes them at restore time. MBZoo never restores anything, so it decodes them for display instead — in-app navigation when the target travelled in the same backup, otherwise a labelled link to the site the backup came from, never fetched (ADR-0019). The same grammar carries `$@NULL@$`, which is Moodle's serialized SQL NULL — a field value, not a link, and never content. Facts verified against Moodle source (`moodle/moodle`, REPO-005) and against real backups, including courses generated in a real Moodle for the purpose — see `research/` in the repository. ## What MBZoo does with it MBZoo parses the minimum XML subset needed to rebuild the course navigation tree, then extracts content (pages, PDFs, websites, questions…) **on demand, in your browser**. Nothing is uploaded — see [Privacy](/mbzoo/docs/PRIVACY.md). --- url: /mbzoo/docs/es/guide/what-is-mbz.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # ¿Qué es un .mbz? Un archivo `.mbz` es una **copia de seguridad de un curso Moodle**: un paquete con las secciones, actividades, archivos, ajustes y (opcionalmente) datos de usuario del curso. ## Formatos de contenedor | Formato | Desde | Notas | | ------- | --------------------------------------- | ------------------------------------------------------------------ | | ZIP | Moodle 2.0 | Sin soporte ZIP64 dentro del propio Moodle (tope práctico de 4 GB) | | TAR.GZ | por defecto desde 2.9 (opcional en 2.6) | ustar POSIX; sin límite de tamaño en la práctica | MBZoo detecta el formato por los magic bytes y soporta **ambos**. ## Dentro del archivo ``` moodle_backup.xml esqueleto curso/secciones/actividades, y los ajustes que deciden qué más hay aquí dentro files.xml índice de archivos (contenthash, component, filearea…) course/course.xml metadatos completos del curso (el fullname vive aquí) sections/section_N/ nombre, resumen y orden de actividades por sección activities/_N/ XML por actividad — ver abajo files/<2 hex>/ almacén de archivos direccionado por contenido questions.xml el banco de preguntas, compartido por los cuestionarios gradebook.xml árbol de categorías, agregación, letras de calificación users.xml las personas — solo si la copia se hizo con datos de usuario (ver Privacidad) ``` Un directorio de actividad tiene más que su payload, y en los hermanos es donde se esconden varias cosas: ``` activities/assign_42/ assign.xml ajustes y contenido propios del módulo module.xml visibilidad, finalización, restricciones, etiquetas grades.xml ítem de calificación: sobre cuánto, aprobado, peso grading.xml rúbrica o guía de evaluación, si hay inforef.xml qué registros de files.xml usa esta actividad calendar.xml roles.xml competencies.xml filters.xml ``` ## El ajuste que lo decide todo Lo más útil que se puede saber de un `.mbz` es si se hizo **con datos de usuario**. Todos los módulos escriben su árbol XML completo en cualquier caso; lo que el ajuste `users` condiciona es la _fuente de datos_ de cada elemento. Dos módulos que en el esquema parecen igual de ricos pueden ser mundos distintos en un fichero real. Una `lección` escribe todas sus páginas y respuestas sin condiciones: la unidad didáctica entera está ahí. Un `foro` no escribe más que el registro del foro; cada debate y cada mensaje son datos de usuario. Por eso un glosario vacío en una copia sin usuarios no es un fallo, y por eso MBZoo dice _por qué_ está vacío y no solo que lo está. | Siempre en la copia | Solo con datos de usuario | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | páginas y respuestas de lección, opciones de consulta, campos de base de datos, instrucciones y ejemplos de taller, slots de cuestionario y banco de preguntas, ítems de calificación y rúbricas, estructura del libro de calificaciones | debates y mensajes de foro, entradas de glosario, registros de base de datos, páginas de wiki, mensajes de chat, entregas de tareas, intentos de cuestionario, las notas de todos | ## Enlaces que no llevan a ninguna parte Una copia puede restaurarse en otro sitio, así que Moodle no puede guardar URLs absolutas para los enlaces internos del curso. Los reescribe como fichas `$@COURSEVIEWBYID*62@$` al hacer la copia y los descodifica al restaurar. MBZoo no restaura nada, así que los descodifica para mostrarlos: navegación interna cuando el destino viajó en la misma copia, y si no, un enlace etiquetado al sitio del que salió la copia, que nunca se descarga (ADR-0019). La misma gramática lleva `$@NULL@$`, que es el NULL de SQL serializado de Moodle: un valor de campo, no un enlace, y nunca contenido. Hechos verificados contra el código de Moodle (`moodle/moodle`, REPO-005) y contra copias reales, incluidos cursos generados en un Moodle real para este fin — ver `research/` en el repositorio. ## Qué hace MBZoo con ello MBZoo analiza el subconjunto mínimo de XML necesario para reconstruir el árbol de navegación del curso, y extrae el contenido (páginas, PDFs, webs, preguntas…) **bajo demanda, en tu navegador**. Nada se sube — ver [Privacidad](/mbzoo/docs/es/PRIVACY.md). --- url: /mbzoo/docs/guide/activity-support.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # Activity & content support MBZoo renders what the backup actually contains, and is transparent about what it cannot do. Unknown third-party plugins never break the course view. | Moodle module | Inspect | Render / preview | Notes | | --------------------------------------------- | ----------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Page | ✅ | ✅ sanitized HTML | ADR-0012/0013 | | Label | ✅ | ✅ sanitized HTML | | | URL | ✅ | ✅ external link | never fetched automatically | | Resource / File | ✅ | ✅ inline preview | PDF via pdf.js canvas, images, text, sandboxed HTML (ADR-0014) | | Folder | ✅ | ✅ file cards | | | HTML page w/ CSS+JS | ✅ | ✅ sandboxed iframe | opaque origin + CSP; scripts isolated from the app (ADR-0014). Links inside a multi-page site (e.g. an eXeLearning export) navigate through a validated request to MBZoo; the page row is a table of contents (ADR-0022) | | Book | ✅ | ✅ chapters with TOC | | | Forum | ✅ | ✅ typed summary | forum type and settings; discussions only exist if the backup included user data | | Glossary | ✅ | ✅ entries rendered | entries are user-generated, so a backup taken without user data has none — the viewer says so | | Assignment | ✅ | ✅ summary | dates and submission types; submissions only present with user data | | Lesson | ✅ | ✅ branching pages | pages, answers and where each jump leads — all of it travels in a content-only backup | | Choice | ✅ | ✅ question + options | | | Database | ✅ | ✅ field schema | the fields collected; records only exist with user data | | Workshop | ✅ | ✅ instructions + examples | example submissions and both instruction blocks; peer work is user data | | IMS content package | ✅ | ✅ TOC + sandboxed pages | table of contents read from the PHP-serialized `structure` (ADR-0021) | | Subsection | ✅ | ✅ nested in the tree | Moodle 4.5+ delegates a section to a module; MBZoo nests it under its owner rather than listing it as a sibling | | Survey (retired) · Assignment 2.2 (retired) | ✅ | ✅ summary | removed from Moodle core in 5.0 and 4.2; no current Moodle can restore them | | Chat · Wiki | ✅ | ✅ typed summary | schedule / wiki mode; messages and pages are user data. Chat is labelled _retired_: Moodle removed it in 5.0 (MDL-82457) | | Feedback (questionnaire) | ✅ | ✅ items rendered | labels, questions and their options in author order; responses only exist with user data | | Quiz | ✅ metadata + question bank | ✅ read-only question navigation | multichoice/true-false/short answer/essay/match; random slots page through the pool they draw from, captioned with how many an attempt asks; faithful execution requires Moodle's Question Engine — not a goal | | Question bank · External tool · BigBlueButton | ✅ | ✅ typed summary | configuration records; MBZoo never launches an external tool | | SCORM | ✅ metadata + course structure | 🧪 experimental playback | SCOs run in the opaque-origin sandbox with a scorm-again runtime in the same document; nothing is tracked or saved (ADR-0023) | | H5P (mod\_h5pactivity / .h5p files) | ✅ metadata + package | ⚠️ experimental playback | sandboxed player, self-contained packages; see ADR-0018 — unsupported content types fall back to download | | EPUB | ✅ | ✅ chapter by chapter | spine read from the OPF; assets inlined from the package, rendered in the sandbox. No pagination or bookmarks (ADR-0024) | | eXeLearning .elp/.elpx | ✅ classified by contents | ✅ exported site | a .elpx carries the project and its render; the render is shown. A legacy .elp with only content.data says why it cannot be decoded (ADR-0025) | | Unknown third-party plugins | ✅ | ✅ metadata fallback | never break the course view | Legend: ✅ implemented · 🔜 planned next · ⏳ research (Q-012/Q-013/Q-016). Media files (video, audio) preview inline with native controls; a media element decodes its file but never executes it. ## Personal data A backup taken with **users included** carries a root `users.xml` holding names, usernames, email addresses, ID numbers, phone numbers, postal addresses, institutions, the last IP each account logged in from, and profile descriptions. MBZoo says so as soon as such a file is opened: how many people, and which kinds of data are actually populated. The list of names sits behind a disclosure that stays closed, so reading it is deliberate rather than something that happens while screen-sharing. Nothing leaves your device — but the file does. Treat a backup with user data as personal data before emailing it, uploading it or committing it anywhere. ## Grading Every activity's grade item travels in a content-only backup, so MBZoo shows what it is out of, what counts as a pass, its weight and whether it was hidden — read from `grades.xml` beside the module payload. Students' marks (``) are user data and are never read. Rubrics and marking guides live in `grading.xml`, and are often the clearest statement of what a task is assessed on: criteria, levels and their scores are rendered in full. A grading method MBZoo does not decode is named rather than shown as empty. The course-wide gradebook — the category tree, its aggregation method, and the grade letters — is shown in the detail pane before an activity is selected. ## Retired modules Moodle has removed `chat` and `survey` from core (5.0, MDL-82457) and `assignment` (4.2, MDL-72350), so no current Moodle can restore them — but backups written before those releases still carry them. MBZoo reads them like any other module and labels them _retired_ next to the module name, with the release that dropped them. ## Course links Moodle cannot store absolute URLs for links between activities, so a backup carries them as `$@COURSEVIEWBYID*62@$`-style tokens. MBZoo decodes them (ADR-0019): a link to an activity that travelled in the same backup opens that activity in MBZoo, anything else becomes a labelled link to the site recorded in `` — opened in a new tab, never fetched by MBZoo — and a token MBZoo cannot decode keeps its text but leads nowhere, rather than pretending to point somewhere. --- url: /mbzoo/docs/es/guide/activity-support.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # Actividades y contenidos soportados MBZoo renderiza lo que la copia contiene realmente y es transparente con lo que no puede hacer. Los plugins de terceros desconocidos nunca rompen la vista del curso. | Módulo Moodle | Inspeccionar | Vista previa | Notas | | ------------------------------------------ | ---------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Página (Page) | ✅ | ✅ HTML saneado | ADR-0012/0013 | | Etiqueta (Label) | ✅ | ✅ HTML saneado | | | URL | ✅ | ✅ enlace externo | nunca se descarga automáticamente | | Recurso / Archivo | ✅ | ✅ vista integrada | PDF con canvas pdf.js, imágenes, texto, HTML en sandbox (ADR-0014) | | Carpeta (Folder) | ✅ | ✅ tarjetas de archivo | | | Página web con CSS+JS | ✅ | ✅ iframe en sandbox | origen opaco + CSP; el JS queda aislado de la app (ADR-0014). Los enlaces dentro de un sitio de varias páginas (p. ej. una exportación de eXeLearning) navegan mediante una petición validada a MBZoo; la fila de páginas es un índice (ADR-0022) | | Libro (Book) | ✅ metadatos | ✅ capítulos con navegación | TOC + anterior/siguiente (ADR-0013) | | Foro | ✅ | ✅ resumen con tipo | tipo de foro y ajustes; los debates solo existen si la copia incluyó usuarios | | Lección | ✅ | ✅ páginas ramificadas | páginas, respuestas y a dónde salta cada una: todo viaja en una copia sin datos de usuario | | Consulta (Choice) | ✅ | ✅ pregunta + opciones | | | Base de datos | ✅ | ✅ esquema de campos | los campos que recoge; las entradas solo existen con datos de usuario | | Taller (Workshop) | ✅ | ✅ instrucciones + ejemplos | envíos de ejemplo y ambos bloques de instrucciones; el trabajo entre pares es dato de usuario | | Paquete IMS (imscp) | ✅ | ✅ índice + páginas en sandbox | índice leído del campo `structure` serializado en PHP (ADR-0021) | | Subsección | ✅ | ✅ anidada en el árbol | Moodle 4.5+ delega una sección en un módulo; MBZoo la anida bajo su dueño en vez de listarla como hermana | | Encuesta (retirada) · Tarea 2.2 (retirada) | ✅ | ✅ resumen | eliminadas del núcleo en 5.0 y 4.2; ningún Moodle actual puede restaurarlas | | Chat · Wiki | ✅ | ✅ resumen con tipo | horario / modo del wiki; mensajes y páginas son datos de usuario. El chat se marca como _retirado_: Moodle lo eliminó en 5.0 (MDL-82457) | | Glosario | ✅ | ✅ entradas renderizadas | concepto + definición; las entradas las escriben los usuarios, así que una copia hecha sin datos de usuario no trae ninguna y el visor lo indica | | Tarea (Assignment) | ✅ | ✅ resumen | fechas de entrega/cierre y tipos de entrega | | Encuesta (Feedback) | ✅ | ✅ elementos renderizados | etiquetas, preguntas y sus opciones en el orden del autor; las respuestas solo existen con datos de usuario | | Cuestionario (Quiz) | ✅ banco de preguntas | ✅ inspección navegable | preguntas con radios/checkboxes estilo Moodle; opción múltiple/verdadero-falso/respuesta corta/ensayo/relacionar; las preguntas al azar recorren el banco del que se sortean, indicando cuántas pide cada intento; la ejecución fiel requiere el Question Engine de Moodle — no es objetivo | | SCORM | ✅ metadatos + estructura del curso | 🧪 reproducción experimental | los SCO se ejecutan en el sandbox de origen opaco con el runtime de scorm-again en el mismo documento; no se registra ni se guarda nada (ADR-0023) | | H5P | ✅ metadatos + paquete | ⏳ investigación | candidato: h5p-standalone (Q-013) | | EPUB | ✅ | ✅ capítulo a capítulo | el spine se lee del OPF; los recursos se incrustan desde el paquete y se renderiza en el sandbox. Sin paginación ni marcadores (ADR-0024) | | eXeLearning .elp/.elpx | ✅ clasificado por su contenido | ✅ sitio exportado | un .elpx lleva el proyecto y su render; se muestra el render. Un .elp antiguo con solo content.data explica por qué no puede decodificarse (ADR-0025) | | Plugins desconocidos | ✅ | ✅ fallback de metadatos | nunca rompen la vista del curso | Leyenda: ✅ implementado · 🔜 planeado · ⏳ investigación (Q-012/Q-013/Q-016). Los archivos de vídeo y audio se previsualizan en línea con los controles nativos; un elemento multimedia decodifica su archivo pero nunca lo ejecuta. ## Datos personales Una copia hecha **con usuarios** lleva un `users.xml` en la raíz con nombres, nombres de usuario, correos, números de identificación, teléfonos, direcciones postales, instituciones, la última IP desde la que entró cada cuenta y las descripciones de perfil. MBZoo lo dice nada más abrir el archivo: cuántas personas y qué tipos de dato están realmente rellenos. La lista de nombres queda tras un desplegable cerrado, para que leerla sea un acto deliberado y no algo que pasa mientras compartes pantalla. De tu dispositivo no sale nada, pero el archivo sí. Trata una copia con datos de usuario como datos personales antes de enviarla, subirla o commitearla. ## Calificación El ítem de calificación de cada actividad viaja en una copia sin datos de usuario, así que MBZoo muestra sobre cuánto va, qué nota aprueba, su peso y si estaba oculta —leído de `grades.xml`, junto al payload del módulo—. Las notas del alumnado (``) son datos de usuario y no se leen nunca. Las rúbricas y guías de evaluación están en `grading.xml` y suelen ser la declaración más clara de qué se evalúa: criterios, niveles y puntuaciones se muestran completos. Un método de evaluación que MBZoo no descodifica se nombra en vez de mostrarse vacío. El libro de calificaciones del curso —árbol de categorías, agregación y letras— se muestra en el panel de detalle antes de seleccionar una actividad. ## Módulos retirados Moodle ha eliminado `chat` y `survey` del núcleo (5.0, MDL-82457) y `assignment` (4.2, MDL-72350), así que ningún Moodle actual puede restaurarlos, pero las copias anteriores a esas versiones siguen llevándolos. MBZoo los lee como cualquier otro módulo y los marca como _retirado_ junto al nombre del módulo, con la versión que los quitó. ## Enlaces del curso Moodle no puede guardar URLs absolutas para los enlaces entre actividades, así que la copia los lleva como fichas del tipo `$@COURSEVIEWBYID*62@$`. MBZoo las descodifica (ADR-0019): un enlace a una actividad que viajó en la misma copia abre esa actividad en MBZoo; el resto se convierte en un enlace etiquetado al sitio que registra `` —se abre en una pestaña nueva y MBZoo nunca lo descarga—; y una ficha que MBZoo no sabe descodificar conserva su texto pero no lleva a ninguna parte, en vez de fingir que apunta a algún sitio. [English version](/mbzoo/docs/es/guide/activity-support.md) --- url: /mbzoo/docs/ARCHITECTURE.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # Architecture Status: experimental but working end to end (2026-08-25). Durable decisions live in `research/decisions/adr/`; this page summarizes the shape. ``` ┌──────────────────────────────┐ .mbz file ───▶ │ apps/viewer (Vite, vanilla) │ (File/Blob) │ main.ts worker.ts │ │ renderers.ts detail-panel│ └───────┬──────────────┬───────┘ │ │ postMessage(ArrayBuffer) ▼ ▼ ┌──────────────────────────────────┐ │ @mbzoo/core (portable) │ │ openBackup(blob) │ │ ├─ detectFormat (magic bytes) │ │ ├─ ArchiveReader │ │ │ ├─ LazyZipReader (zip) │ │ │ └─ TarGzReader (tar.gz) │ │ └─ moodle/ event XML parsers │ │ → normalized model │ └──────────────────────────────────┘ ▲ apps/cli (Bun) ─┘ same core, local disk ``` `packages/core/src/moodle/` holds one parser per thing the format expresses, each reading the minimum subset it needs: | Area | Modules | | ------------- | ------------------------------------------------------------------------------------------------- | | Structure | `backup-xml`, `course-xml`, `activity-xml`, `files-xml` | | Activities | `lesson-xml`, `book-xml`, `glossary-xml`, `feedback-xml`, `questions-xml` | | Grading | `grades-xml`, `grading-xml` | | People | `users-xml` | | Cross-cutting | `links` (`$@…@$` tokens), `php-serialized`, `legacy-modules`, `availability`, `module-xml`, `xml` | Two rules keep that list from becoming a pile: the normalized model in `packages/core/src/model/backup.ts` is the only contract that crosses a package boundary, and XML library objects never escape `src/moodle`. Key boundaries (see ADRs for rationale): - **Portable core** (ADR-0004): Web-platform primitives only; the normalized model in `packages/core/src/model/backup.ts` is the only cross-package contract. - **Archive abstraction** (ADR-0005): both real `.mbz` containers supported; lazy/streaming access deferred behind `ArchiveReader`. - **XML adapter** (ADR-0006): event-based parsing with input/text budgets; saxes is an implementation detail. - **Security** (ADR-0009): hostile input posture; textContent by default; a single sanitization path for backup HTML (ADR-0012); no content execution in the app origin. - **Sandboxed content** (ADR-0017, ADR-0020, ADR-0022): executable HTML runs only in an opaque-origin iframe with an injected CSP, with assets inlined as `data:` URIs; multi-page sites are navigated within that contract. - **Never guess a URL** (ADR-0019): `$@…@$` link tokens decode from rules read in Moodle source, or not at all — an undecodable one loses its href rather than resolving against MBZoo's own origin. - **Refusing parsers** (ADR-0021): the PHP `serialize()` reader supports the scalar and array subset that appears and refuses objects and back-references outright. Performance model today: parse runs in a Worker; only metadata XML is read eagerly; binary assets are never extracted unless requested. ZIP entries are sliced and inflated on demand (ADR-0029); a TAR.GZ is decompressed into a Blob and indexed as it streams, so no allocation is larger than the entry being read (ADR-0036). Large-file strategy is tracked as TASK-003 / Q-004..Q-007. ## How claims get verified Parsers are written against Moodle source (REPO-005) because it is authoritative for what a backup _can_ contain — and then checked against a real backup, because the schema does not say what one _does_ contain. Real specimens come from institutional and public corpora, from Moodle's own test fixtures, and from courses generated in a real Moodle and backed up through `backup_controller`. They are recorded in `fixtures/manifest.yaml` with provenance and checksums, and never committed. That practice has already caught a bug a synthetic fixture could not: a lesson jump target whose page id collided with a Moodle constant. --- url: /mbzoo/docs/PRIVACY.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # Privacy **Nothing you open in MBZoo leaves your device.** - The viewer is a static web application. Backups are read with the browser File API and parsed inside a Web Worker on your machine. There is no upload path — no backend, no telemetry, no analytics. - The CLI reads local files only. - External resources referenced by course content are not fetched automatically. Course links that Moodle rewrote into `$@…@$` tokens are decoded and offered as links, never requested (ADR-0019). If a future feature needs network access, it will be opt-in and documented here first. This is a product property enforced by architecture (static deployment, no server code), not just a policy statement. ## When a backup contains people Nothing leaves your device — **but the file does.** A course backup taken with _user data included_ carries a root `users.xml`, and it is not a list of names. One record holds: > username · email · first and last name · ID number · two phone numbers · > institution · department · postal address · city · country · the last IP the > account logged in from · a free-text profile description · role assignments Forum posts, glossary entries, assignment submissions, quiz attempts and grades travel the same way when that box was ticked. So MBZoo says so as soon as such a file is opened: **how many people, and which kinds of data are actually populated** — a column that exists but is blank for everyone is not reported, because warning about phone numbers when nobody has one teaches people to ignore the warning. The list of names sits behind a disclosure that stays closed. Knowing a file names four hundred people is what everyone needs; reading their names is a deliberate act, and not one to perform by accident while screen-sharing. "Understood" folds the banner into a one-line pill that keeps the count and the kinds on screen; that choice lives in memory for the page session only and is never written to browser storage. **Treat a backup with user data as personal data** before emailing it, uploading it, or committing it to a repository. ## Exports Per-activity export (module XML, rendered content as a standalone HTML file, attached files as a ZIP) is a deliberate user action: nothing is written without a click, and the file is produced in your browser and handed to your own download folder. See [Activity support](/mbzoo/docs/guide/activity-support.md). ## What this repository never contains Real institution or personal backups are never committed. Committed fixtures are synthetic, deterministic and checksummed in `fixtures/manifest.yaml`. Real specimens used to verify parsers are recorded there with their provenance and left out of the tree. --- url: /mbzoo/docs/es/PRIVACY.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # Privacidad **Nada de lo que abras en MBZoo sale de tu dispositivo.** - El visor es una aplicación web estática. Las copias se leen con la File API del navegador y se analizan dentro de un Web Worker en tu máquina. No existe ruta de subida: sin backend, sin telemetría, sin analíticas. - El CLI solo lee ficheros locales. - Los recursos externos referenciados por el contenido del curso no se descargan automáticamente. Los enlaces del curso que Moodle reescribió como fichas `$@…@$` se descodifican y se ofrecen como enlaces, nunca se piden (ADR-0019). Si una función futura necesitara red, será opcional y se documentará aquí primero. Esto es una propiedad del producto, garantizada por la arquitectura (despliegue estático, sin código de servidor), no solo una declaración. ## Cuando una copia contiene personas De tu dispositivo no sale nada, **pero el archivo sí**. Una copia de curso hecha _con datos de usuario_ lleva un `users.xml` en la raíz, y no es una lista de nombres. Un solo registro guarda: > nombre de usuario · correo · nombre y apellidos · número de identificación · > dos teléfonos · institución · departamento · dirección postal · ciudad · > país · la última IP desde la que entró la cuenta · una descripción libre de > perfil · asignaciones de rol Los mensajes de foro, las entradas de glosario, las entregas de tareas, los intentos de cuestionario y las calificaciones viajan igual cuando esa casilla estaba marcada. Por eso MBZoo lo dice nada más abrir un archivo así: **cuántas personas y qué tipos de dato están realmente rellenos** — una columna que existe pero está vacía para todos no se reporta, porque avisar de teléfonos cuando nadie tiene enseña a la gente a ignorar el aviso. La lista de nombres queda tras un desplegable que permanece cerrado. Saber que un fichero nombra a cuatrocientas personas es lo que todo el mundo necesita; leer sus nombres es un acto deliberado, y no de los que conviene hacer sin querer mientras compartes pantalla. «Entendido» pliega el aviso en una línea que mantiene a la vista el número de personas y los tipos de dato; esa elección vive en memoria solo durante la sesión y nunca se escribe en el almacenamiento del navegador. **Trata una copia con datos de usuario como datos personales** antes de enviarla por correo, subirla o commitearla a un repositorio. ## Exportaciones La exportación por actividad (XML del módulo, contenido renderizado como HTML independiente, archivos adjuntos en ZIP) es una acción deliberada: no se escribe nada sin un clic, y el fichero se genera en tu navegador y va a tu propia carpeta de descargas. Ver [Soporte de actividades](/mbzoo/docs/es/guide/activity-support.md). ## Lo que este repositorio nunca contiene Las copias reales de instituciones o personas nunca se commitean. Los fixtures commiteados son sintéticos, deterministas y con checksum en `fixtures/manifest.yaml`. Los especímenes reales usados para verificar los parsers se registran ahí con su procedencia y se dejan fuera del árbol. [English](/mbzoo/docs/PRIVACY.md) --- url: /mbzoo/docs/es/guide/research.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # Sistema de investigación y evidencia Cada afirmación durable en MBZoo traza a un registro registrado: - `REPO-NNN` / `STD-NNN` / `TECH-NNN` — fuentes inspeccionadas - `AN-NNN` — análisis (hechos vs interpretación) - `EXP-NNN` — experimentos reproducibles (comandos, entorno, medidas) - `ADR-NNNN` — decisiones de arquitectura (cuerpo de decisión legible; investigación en la Adenda; se sustituyen, nunca se reescriben) - `TASK-NNN` / `Q-NNN` — trabajo seguido y preguntas abiertas El sistema se valida automáticamente: `bun run research:validate` comprueba IDs, metadatos requeridos y referencias cruzadas; `bun run research:indexes` genera los índices (CI detecta desviaciones). Ver [research/](https://github.com/ateeducacion/mbzoo/tree/main/research) en el repositorio y `research/AGENTS.md` para las reglas operativas. Copias legibles por máquinas de este sitio: [llms.txt](https://ateeducacion.github.io/mbzoo/docs/llms.txt) (índice) y [llms-full.txt](https://ateeducacion.github.io/mbzoo/docs/llms-full.txt) (todas las páginas). Cada página HTML tiene un `.md` hermano y un control **Copy Markdown**. [Versión en inglés](/mbzoo/docs/es/guide/research.md) ## Especímenes El esquema dice lo que una copia _puede_ contener; solo un fichero real dice lo que una copia _contiene_. Por eso un parser escrito desde el fuente de Moodle no está terminado hasta ejecutarlo contra una copia real, y los especímenes vienen de cuatro sitios: | Fuente | Para qué sirve | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | Copias institucionales (nunca commiteadas) | escala y formas del mundo real: cursos de 100+ actividades, exportaciones de eXeLearning, bancos de preguntas al azar | | `saylordotorg/course_backups` (REPO-004) | corpus público de cursos con mucha página/url/etiqueta, y enlaces `$@…@$` | | Los propios fixtures de test de Moodle (REPO-005) | formas que el core mantiene vivas: un paquete IMS real, una sección delegada real | | Un curso generado en un Moodle real | lo que los corpus no traen: lección, consulta, base de datos, taller, rúbricas, y una copia hecha _con_ datos de usuario | Lo último cuesta unos diez minutos: ```bash docker run -d --name mbzoo-spec -p 8123:8080 -e DB_TYPE=sqlite3 \ -e MOODLE_ADMIN=admin -e MOODLE_ADMIN_PASSWORD='…' erseco/alpine-moodle ``` Después se construye el curso con las APIs de Moodle desde un script CLI y se respalda con `backup_controller`, poniendo el ajuste `users` a un lado u otro. Dos cosas que morderán si no: un script CLI no tiene sesión, así que `add_moduleinfo()` necesita antes `\core\session\manager::set_user(get_admin())`; y un `add_moduleinfo()` que falla deja una transacción abierta que revierte todo lo creado después en la misma petición. Los especímenes se registran en `fixtures/manifest.yaml` con procedencia y checksums, y **nunca se commitean**: las copias reales de instituciones o personas no pertenecen a este repositorio, y un fichero regenerable no es material de fixture. Esta práctica ya se ha ganado el sueldo. Cinco parsers hechos desde el esquema pasaban todos los tests sintéticos; la primera lección real destapó un bug en todos ellos, donde un destino de salto cuyo id de página era 1 o 2 se leía como una constante de Moodle que pertenece a otro campo. --- url: /mbzoo/docs/es/index.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # *** pageType: home hero: name: MBZoo tagline: Mira qué hay dentro de tu MBZ. text: Abre, inspecciona y previsualiza copias de seguridad de Moodle directamente en tu navegador. Local-first, sin subidas. actions: \- theme: brand text: Abrir el visor link: [https://ateeducacion.github.io/mbzoo/](https://ateeducacion.github.io/mbzoo/) \- theme: alt text: ¿Qué es un .mbz? link: /es/guide/what-is-mbz.html \- theme: alt text: GitHub link: [https://github.com/ateeducacion/mbzoo](https://github.com/ateeducacion/mbzoo) features: - title: 100 % local details: Las copias se analizan en tu navegador con un Web Worker. No hay servidor ni telemetría: la privacidad es una propiedad del producto. - title: Los dos formatos reales details: Contenedores ZIP y TAR.GZ (tgz es el formato por defecto de Moodle desde 2.9), con lectura perezosa de metadatos y extracción de contenido bajo demanda. - title: Seguro por diseño details: Postura de entrada hostil: HTML saneado, vistas previas en iframes de origen opaco, sin ejecución de contenido en el origen de la aplicación. - title: Basado en evidencia details: Cada afirmación durable traza a una fuente, experimento o ADR registrado. Índices de investigación validados automáticamente. *** [English](/mbzoo/docs/index.md) --- url: /mbzoo/docs/guide/development.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # Development ## Requirements - [Bun](https://bun.sh) ≥ 1.4 (package manager, test runner, CLI runtime) - Node 20+ — the Playwright runner is invoked through it - `bunx playwright install` for E2E browsers ## Commands | Command | Purpose | | --------------------------------- | -------------------------------------------------- | | `bun install` | install workspace dependencies | | `bun run dev:viewer` | Vite dev server for the viewer | | `bun run build` | build all packages (viewer outputs static `dist/`) | | `bun run preview:viewer` | serve the production build locally | | `bun test packages apps fixtures` | unit tests (bun:test) | | `bun run test:e2e` | Playwright specs against the built viewer | | `bun run cli -- ` | inspect a backup from the terminal | | `bun run lint` / `format` | Biome check/fix | | `bun run typecheck` | strict TypeScript across workspaces | | `bun run research:indexes` | regenerate research indexes | | `bun run research:validate` | validate research records + index freshness | | `bun run check` | the full local CI equivalent | ## Layout See `docs/ARCHITECTURE.md`. Parser work has extra invariants — load `.agents/skills/mbz-parser/SKILL.md` first. ## Fixtures Regenerate with `bun run fixtures/scripts/generate-fixture.ts`; checksums live in `fixtures/manifest.yaml`. Never commit real backups. ## Deployment The viewer is a static site. Pushes to `main` build and deploy it to GitHub Pages via `.github/workflows/deploy-pages.yml`. --- url: /mbzoo/docs/guide/research.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # Research & evidence system Every durable claim in MBZoo traces to a registered record: - `REPO-NNN` / `STD-NNN` / `TECH-NNN` — inspected sources - `AN-NNN` — analyses (facts vs interpretation) - `EXP-NNN` — reproducible experiments (commands, environment, measurements) - `ADR-NNNN` — architecture decisions (readable decision body; investigation in the Addendum; supersede, never rewrite) - `TASK-NNN` / `Q-NNN` — tracked work and open questions The system is machine-validated: `bun run research:validate` checks IDs, required metadata and cross-references; `bun run research:indexes` generates the indexes (drift-checked in CI). See [research/](https://github.com/ateeducacion/mbzoo/tree/main/research) in the repository, and `research/AGENTS.md` for the operational rules. ## Specimens The schema tells you what a backup _can_ contain; only a real file tells you what one _does_. So a parser written from Moodle source is not finished until it has been run against a real backup, and specimens come from four places: | Source | What it is good for | | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | Institutional backups (never committed) | real-world scale and shapes — 100+ activity courses, eXeLearning exports, random quiz banks | | `saylordotorg/course_backups` (REPO-004) | a public corpus of page/url/label-heavy courses, and `$@…@$` links | | Moodle's own test fixtures (REPO-005) | shapes core itself keeps working — a real IMS content package, a real delegated section | | A course generated in a real Moodle | anything the corpora do not contain: lesson, choice, database, workshop, rubrics, and a backup taken _with_ user data | The last one is worth spelling out, because it costs about ten minutes: ```bash docker run -d --name mbzoo-spec -p 8123:8080 -e DB_TYPE=sqlite3 \ -e MOODLE_ADMIN=admin -e MOODLE_ADMIN_PASSWORD='…' erseco/alpine-moodle ``` Then build the course with Moodle's own APIs from a CLI script and back it up through `backup_controller`, setting the `users` plan setting either way. Two things that will bite otherwise: a CLI script has no session, so `add_moduleinfo()` needs `\core\session\manager::set_user(get_admin())` first; and a failed `add_moduleinfo()` leaves an open transaction that rolls back everything created after it in the same request. Specimens are recorded in `fixtures/manifest.yaml` with provenance and checksums, and **never committed** — real institution or personal backups do not belong in this repository, and a regenerable file is not fixture material. This practice has already earned its keep. Five parsers built from the schema passed every synthetic test; the first real lesson tripped a bug in all of them, where a jump target whose page id was 1 or 2 was being read as a Moodle constant that belongs to a different field entirely. Machine-readable copies of this site (for agents): [llms.txt](https://ateeducacion.github.io/mbzoo/docs/llms.txt) (index) and [llms-full.txt](https://ateeducacion.github.io/mbzoo/docs/llms-full.txt) (every page). Each HTML page also has a sibling `.md` file and a **Copy Markdown** control. --- url: /mbzoo/docs/index.md --- > For AI agents: the complete documentation index is available at /mbzoo/docs/llms.txt, the full documentation bundle is available at /mbzoo/docs/llms-full.txt. # MBZoo Open, inspect and preview Moodle course backups right in your browser. Local-first, no upload. > See what's inside your MBZ. [Open the viewer](https://ateeducacion.github.io/mbzoo/) | [What is an .mbz?](/guide/what-is-mbz) | [GitHub](https://github.com/ateeducacion/mbzoo) ## Features - **100% local**: Backups are parsed in your browser via a Web Worker. There is no server and no telemetry — privacy is a product property. - **Both real formats**: ZIP and TAR.GZ containers (tgz is Moodle's default since 2.9), with lazy metadata parsing and on-demand content extraction. - **Reads the whole course**: 22 of Moodle 5.3's 23 activity modules, plus three Moodle has retired — and the grade items, rubrics and gradebook that sit beside them. - **Tells you when a file names people**: A backup taken with user data carries names, emails and IP addresses. MBZoo says how many people and what kinds of data, before you share the file. - **Safe by design**: Hostile-input posture — sanitized HTML, sandboxed opaque-origin previews, no content execution in the app origin. - **Evidence-driven**: Every durable claim traces to a registered source, experiment or ADR. Machine-validated research indexes.