Menu

D69. A new module in another module's charter: the design layer copied, one screen to start (3 Nov 2026)

The app’s « Nouveau module » page lets the author choose the charter of the module they create: a template’s (D68), another module’s of their library, or one made to measure by their AI. « Comme un autre module… » used to be a line of the request: the agent read the other module and redid its look, at the cost of a long task and a look that came out close, never the same. The question was whether copying a module’s style is ambiguous enough to need an agent who judges case by case, or a command.

Decided:

  • A command. The format already separates how a course looks from what it says (docs/design.md, the design layer): the theme in course.json and theme/, the components, the generators of its pictures, and the backdrop’s decoration, a free object that carries no information (pedagogicalRole: "decoration"). copyCharter (@elabora/node/charter) copies that layer into a course just made; the agent is needed only for what depends on the content, which the copy leaves behind.
  • What a charter is: theme whole (tokens, custom tokens, fonts, stylesheet, named styles, effects, backdrop with its layers, variants and decoration), presentation (its widths and fit; its mode unless the author chose one), player (the bars, their items and the logo), and the files these use: the stylesheet’s folder, the fonts with their licences, every component, the decoration’s folder, what a stylesheet’s url(), a component or the decoration names under assets/, a module the decoration imports, and the generators that drew those pictures with their provenance, when what they import comes too.
  • What it is not: the screens, the plan, the narration, the sounds, the sources, the glossary and resources, the translations, the speakers, the ui words, and the free objects the blocks place (a 3D lab, a canal lock: the subject). A generator that draws from one of those stays behind; its picture comes as a plain file.
  • Where it is used: creation only. elabora projects create --charter <project id or folder>, elabora_projects_create with charter, and the library’s createProject / createModule (the app’s « Nouveau module »): a blank course (one screen, as init makes it) that takes the charter, with a note in its AGENTS.md naming the module it comes from. A module of the library is copied under its library lock, as duplicateProject copies it. template and charter exclude each other: a template brings its screens, a charter only the look.
  • Checked on every template and example: a blank course in each of their charters validates without an error and fit passes (test/unit/charter.test.ts). The warnings left are a blank course’s and W_COMPONENT_UNUSED for the components no screen uses yet, which say what is there to use. fit no longer reports a scroll-driven animation of a page that does not scroll as unfinished (a decoration on a first, short page).

Weighed:

  • Keep it a request to the agent. Rejected: the format draws the line already, the copy is exact where an agent’s is approximate, it takes a second instead of a task, and it works without an AI (« Créer manuellement »).
  • Duplicate the module and let the author empty it. Rejected: its screens, plan, narration and sources would go with it, to be removed by hand; a duplicate stays the same course (its course id), which an LMS would take for it.
  • Copy only the components the charter needs (layouts, decorations). Rejected: a component is the module’s « Blocs du module »; the author who wants the same look wants its blocks, and the validator says which are not used yet.
  • Apply a charter to an existing course (a theme apply, D68’s revisit). Later: replacing a charter under screens that use the old one’s components and styles needs those references mapped; creation has none.

Revisit if: authors want to change the charter of a module already written, or keep only some of another module’s components.