D49. The author's sources live in sources/, outside the course, each with a readable version made on this computer (15 Oct 2026)
Revised on 19 Oct 2026: the readable versions use no program of the author’s, neither LibreOffice nor poppler. The founder doubted they were worth keeping and the three reasons held: they are rarely installed on business computers, they cannot ship with Elabora, and no CI could run them (their tests were skipped wherever they were absent, so the code that used them was never tested where the code is built). A deck now gives, slide by slide, its texts, its notes and the pictures the slide places, with the file’s thumbnail; a file in an older office format says to be saved as .docx or .pptx (or as a PDF); a PDF is read as it is. ELABORA_SOFFICE, ELABORA_PDFTOPPM, ELABORA_PDFTOTEXT and the render option are gone. The rest of this entry is kept as it was decided; what changed is marked where it stands.
The core did nothing with the PDFs, Word documents and PowerPoint decks authors bring (a client’s brief, a deck to turn into a module, recorded interviews); Claude reads PDFs and images by itself, Codex reads them less well, and Claude too faced with a .pptx; and a client’s brief may hold personal data. Weighed and decided:
- Where. In the course folder, at its top,
sources/: agents work on files by path, and the sources travel with the module (its copy, its import from a folder, its archive when asked). Not in the project’s data (.elabora/: machine-local, hidden from agents), not elsewhere on disk (lost when the module moves). - Outside the course.
sources/is left out of every snapshot, as tool folders are (@elabora/nodeproject-files.ts;@elabora/coreisSourcePath,SOURCES_DIR): nothing validates, journals, watches, backs up, builds or publishes it, and the engine never hashes or reloads a 300 MB recording added there. Checked before: the build packaged only the files a course points to, but a theme’surl(), a font, a free object’s declared file and the web target’s sharing image could point intosources/and be copied into a package from the disk. Now the validator refuses them (E_SOURCE_REFERENCED, with its fix: import the file intoassets/, where media lose their metadata), the build checks every entry and every file it reads againstsources/, and a test builds SCORM, web and review packages with sources and without them: byte for byte the same. A component’s preview and a translation’s folder no longer copysources/. - Backups. The version store keeps a content once whatever the number of versions (D17): a 300 MB video would not be in each backup but once, free on APFS (a clone), its size again on NTFS. Nothing in Elabora changes a source, so a backup would protect only against its removal, and would keep a removed brief and its personal data for 30 days and more. Sources are not backed up, a restore never touches them, and removing a source (
removeSource,elabora sources remove) deletes it for good. A module in the trash keeps its sources for the trash’s 30 days, with the rest of its folder; a module replaced by an archive that carries none keeps its own. - Archives.
exportProjecttakessources: true(elabora export --sources); without it, the default, an archive carries none: it is what is delivered to a client (D19), and the sources hold personal data and weigh. With it, they are files of the archive undersources/, so an older Elabora imports them as course files and a newer one as sources;ExportResult.sourcesandArchiveSummary.sourcescount them apart from the course’s files. - Adding.
addSources(dir, files)copies files (clones where the file system allows it) and returns at once; a folder brings the files it holds. A file whose content is already there is not copied again (already-there, by SHA-256 among sources of its size); a name taken by another file is numbered, « brief (2).docx »; names are kept as the author knows them (accents, spaces), in NFC, without what Windows refuses (< > : " / \ | ? *, control characters, a trailing dot or space, CON or NUL), 120 characters at most, compared without case as macOS and Windows do. A name is claimed with a hard link, so two processes never take the same one. - Readable versions, beside each source:
sources/<name>.mdand its pictures insources/<name>.files/. Markdown, which every agent reads; its first line a marker (<!-- elabora:readable {…} -->: the source’s SHA-256, size and time, the reader and its version, whether it is complete) by which Elabora tells its readable versions from an author’s own Markdown and knows when one is stale: the source changed (a copied or touched file with the same content is not), or a better reader came. They are written when asked (makeSourcesReadable,readSource,elabora sources add|read|refresh,elabora_source_read), not by a watcher: the app adds sources, then makes their readable versions in the background with its progress.- Word (.docx): headings (by the style’s name, whatever its id: Word’s French styles are « Titre1 »), paragraphs, bulleted and numbered lists with their levels, tables (merged cells), images with their descriptions, footnotes, links, fields’ results, text boxes once; comments where they are anchored (
{>>c0 Marie Dupont: …<<}) and listed at the end with the text they are about and their replies; tracked changes not accepted yet as{++…++}and{--…--}(CriticMarkup), with their authors. - PowerPoint (.pptx): slide after slide in the presentation’s order, each slide’s texts in reading order (its title, then from top to bottom in bands of a twentieth of the slide, left to right; placeholders placed by their layout or master; groups; slide numbers, dates and footers left out), tables, SmartArt’s texts, charts’ titles, pictures with their descriptions, video and sound named, the speaker’s notes, comments (the older ones and 2021’s threads), hidden slides said.
- Older and other office files (.doc, .rtf, .odt, .ppt, .pps, .odp, .key): through LibreOffice when it is installed, then read as .docx or .pptx; else the readable version says what to do. Revised on 19 Oct 2026: never read. Their state is
unsupportedand its notes say it plainly (« DOC is an older word-processing format that Elabora does not read: save the file as .docx (or as a PDF) from the application that made it, and add that file to the sources »); no readable version is written beside them, whatever an earlier Elabora made. The notes are in English like every reader’s: the agent tells the author in the author’s language. - Video and audio: the transcript by D46’s local transcriber (Parakeet), its audio decoded by the ffmpeg media already use (no copy of the audio is kept: an agent cannot read it), in paragraphs that start with their time (
**[02:15]**, cut at a sentence’s end once 30 s are said); a video’s frames, one every two minutes or so (three to twelve), placed where they fall in the transcript. Without the transcriber the readable version ispartial(frames, what it lacks) and is finished at the next read once the model is here; the command line and the MCP tools download it on first use (D46), the API only when asked (install: true), so that the app offers it in one click. ElevenLabs is never used for sources. - PDF: Claude reads PDFs itself; for other agents, its text page by page when poppler’s
pdftotextis installed (Linux, Homebrew), else the PDF is read as it is (native). A text extractor of our own (pdf.js, Apache-2.0) would be a new dependency for a reader agents mostly have: not now. Revised on 19 Oct 2026: always read as it is (native), with no readable version. Agents read PDFs themselves; Codex reads them less well than Claude (above), which is the price, and the extractor of our own is the way back if it proves too high. - Images and text are read as they are; anything else is
unsupported. - The readers are written in TypeScript on a small XML reader of our own (
sources/xml.ts: namespaces resolved to Office’s prefixes, ISO strict files read like transitional ones, no DTD, no entity expanded beyond XML’s five and character references) and the streaming ZIP reader of archives: no new dependency.
- Word (.docx): headings (by the style’s name, whatever its id: Word’s French styles are « Titre1 »), paragraphs, bulleted and numbered lists with their levels, tables (merged cells), images with their descriptions, footnotes, links, fields’ results, text boxes once; comments where they are anchored (
- A picture of each slide needs a program that draws PowerPoint. Weighed: LibreOffice (rarely on freelancers’ Windows and macOS computers, 300 MB and more, cannot ship with Elabora); PowerPoint itself by automation (on most agencies’ computers, but it opens the application, macOS asks for an automation permission, and no CI can test it); the Chromium Elabora uses (cannot draw a deck); a renderer of our own (months); the thumbnail every .pptx carries (the first slide, small). Chosen: LibreOffice when it is installed (
ELABORA_SOFFICE, the PATH, its usual places), with a profile of its own so that it runs beside the author’s, drawing the deck as a PDF with its hidden slides (LibreOffice 7.4 and later) in about 2.5 s for four slides here; a picture per slide (slide-01.png, 1280 px) whenpdftoppmis installed too, else that PDF (Claude reads it); without LibreOffice, the thumbnail of the first slide. The texts, notes and pictures of the deck are there either way. An older LibreOffice that leaves hidden slides out is matched to the visible ones. Revised on 19 Oct 2026: the slides are not drawn and no program is looked for. What an agent gets of a deck, by slide:- its texts and notes as before;
- the pictures the slide places, taken from the deck’s
ppt/mediathrough the slide’s relationships: pictures (in groups too), shapes filled with a picture, and the slide’s own background (not its layout’s or master’s), each at its place in the reading order with its description. A picture linked to a file outside the deck is named, not kept; EMF, WMF and other drawings are named, not extracted; - the file’s thumbnail of the first slide, always kept, and notes that open the readable version: slides are not drawn here, add the deck as a PDF too to see them.
A picture too small to matter is left out and counted in the notes. It is one of three: no side over 32 px (an icon, a bullet); a side under 8 px (a rule drawn as a picture); or, as placed, no side over 3% of the slide’s width or a side under 1% of its height (a dot, a rule). It is judged at each place: a logo is kept where it fills the slide and left out as a dot in a corner. How the sizes were chosen: an agent looks at pictures shrunk to a few hundred pixels (the MCP tool sends eight at most), and 32 px is about one line of a slide’s body text at the 1600 px reference (18 pt is 30 px), 3% of the width is 48 px there, 1% of the height 9 px (5 pt). They were then tried on the decks found on this computer: nine decks (seven templates, python-pptx’s default, Eagle’s blank) with 19 placements of three distinct pictures, the smallest 1080 px and 2.5 cm wide (7% of the slide), so none is left out. That is thin: those decks hold no icon or bullet to calibrate on, so the sizes are set to cut only what is evidently a mark (a wrong call costs a bullet, not a figure), and are tried again on agencies’ real decks (Revisit if). The code is
sources/image-size.ts(the size is read from the header of a PNG, JPEG, GIF or WebP, without a dependency; an SVG is judged by its box alone).
- Privacy. Every readable version is made on this computer; nothing is sent anywhere. The readable version, the skill and the tools say that sources are never published and may hold personal data, and to quote only what the module needs.
- Agents. MCP
elabora_sources(the list),elabora_source_read(the Markdown in parts of 60,000 characters, its pictures withimages: true, eight at most), both read-only, andelabora_source_add; CLIelabora sources list|add|read|refresh|remove. The course’sAGENTS.mdgains rule 11 (revision 2 of the template, so that unedited copies are brought up to date, D34), and the authoring skill and the MCP server’s instructions say the same: the sources are insources/, read them through their readable versions. - For the app.
@elabora/node/sources/index:addSources(dir, files, { onProgress, signal })→{ from, name, status: 'added' | 'already-there', renamed }[], thenmakeSourcesReadable(dir, { names, install, render, onProgress, signal })→ the sources with their state (revised on 19 Oct 2026: norender, no'render'step in the progress, andfindOfficeToolsis no longer exported; an older office format isunsupported, its notes saying what to do);listSources,readSource,removeSource,sourcesSize; errors carrycode(E_NOT_A_COURSE,E_SOURCE_NOT_FOUND,E_SOURCE_NOT_A_FILE).LibraryProject.sourcesSize,ExportOptions.sources,ArchiveSummary.sources. Revisit if: authors ask for the slides drawn (then PowerPoint’s own export by automation, on the computers that have it; since 19 Oct 2026 the deck as a PDF, added by the author, is the way), agencies’ real decks show pictures the sizes above wrongly keep or leave out, authors bring many older office files (then a reader of the .doc and .ppt binary formats of our own, or LibreOffice again as an option the app offers, not one the core looks for), agents other than Claude read PDFs too badly (then a text extractor of our own), agencies bring Excel storyboards (a reader of .xlsx on the same XML reader), a recording longer than an hour proves too heavy (its audio is held whole in memory, 230 MB an hour, before the transcriber cuts it in windows), or authors want removed sources recoverable (then a trash of sources, not backups).