@lernapps/app-templates 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +195 -2
  3. package/dist/appname-Bh23cUuz.mjs +12 -0
  4. package/dist/assessment-By2GGTJC.mjs +1696 -0
  5. package/dist/block-BK_ohsH1.mjs +82 -0
  6. package/dist/blocks-BmRrD7UY.mjs +149 -0
  7. package/dist/blocks.mjs +4 -0
  8. package/dist/check-BkEl-m-F.mjs +254 -0
  9. package/dist/content-cYBPYg_J.mjs +140 -0
  10. package/dist/contract-PONpxJtd.mjs +52 -0
  11. package/dist/e2e-BiMI-pCL.mjs +89 -0
  12. package/dist/engine-BqF2Vffn.mjs +136 -0
  13. package/dist/explainer-e2e.mjs +1297 -0
  14. package/dist/explainer-islands.mjs +197 -0
  15. package/dist/explainer-plugin.mjs +2131 -0
  16. package/dist/explainer.mjs +1246 -0
  17. package/dist/html-mffkHGHh.mjs +89 -0
  18. package/dist/image-CspJVfyQ.mjs +21 -0
  19. package/dist/interactive-e2e.mjs +140 -0
  20. package/dist/interactive-plugin.mjs +242 -0
  21. package/dist/interactive.mjs +75 -0
  22. package/dist/load-C-0hUaSC.mjs +16947 -0
  23. package/dist/needs-BzEahJ6X.mjs +97 -0
  24. package/dist/pages-9RaaomoO.mjs +81 -0
  25. package/dist/questions-e2e.mjs +1 -0
  26. package/dist/questions-engine.mjs +3 -0
  27. package/dist/questions.mjs +6 -0
  28. package/dist/quiz-BKc8JYtC.mjs +70 -0
  29. package/dist/quiz-e2e.mjs +174 -0
  30. package/dist/quiz-plugin.mjs +266 -0
  31. package/dist/quiz.mjs +246 -0
  32. package/dist/render-BJey0bwl.mjs +540 -0
  33. package/dist/render-BL6fV_NI.mjs +507 -0
  34. package/dist/render-DpRO_RKm.mjs +146 -0
  35. package/dist/result-_eQcamoz.mjs +180 -0
  36. package/dist/tasks-DADUYy52.mjs +74 -0
  37. package/dist/validate-COaZso7u.mjs +1072 -0
  38. package/dist/validate-CxtdeQ5S.mjs +146 -0
  39. package/dist/vue-DO1m6q1R.mjs +40 -0
  40. package/dist/vue-code-BkJjW_I_.mjs +320 -0
  41. package/docs/arc42/01-introduction-and-goals.arc42.md +82 -0
  42. package/docs/arc42/02-constraints.arc42.md +228 -0
  43. package/docs/arc42/03-system-context.arc42.md +118 -0
  44. package/docs/arc42/04-solution-strategy.arc42.md +47 -0
  45. package/docs/arc42/05-building-blocks.arc42.md +307 -0
  46. package/docs/arc42/06-runtime-view.arc42.md +98 -0
  47. package/docs/arc42/07-deployment-view.arc42.md +160 -0
  48. package/docs/arc42/08-concepts.arc42.md +123 -0
  49. package/docs/arc42/09-decisions.arc42.md +246 -0
  50. package/docs/arc42/10-quality-requirements.arc42.md +155 -0
  51. package/docs/arc42/11-risks.arc42.md +113 -0
  52. package/docs/arc42/12-glossary.arc42.md +162 -0
  53. package/docs/arc42/architecture-evidence.md +395 -0
  54. package/explainer/.arc42ignore +3 -0
  55. package/explainer/README.md +54 -0
  56. package/explainer/_gitignore +5 -0
  57. package/explainer/docs/arc42/03-explainer-system-context.arc42.md +35 -0
  58. package/explainer/docs/arc42/05-explainer-building-blocks.arc42.md +659 -0
  59. package/explainer/docs/arc42/06-explainer-runtime-view.arc42.md +105 -0
  60. package/explainer/docs/arc42/07-explainer-deployment-view.arc42.md +34 -0
  61. package/explainer/docs/arc42/08-explainer-concepts.arc42.md +17 -0
  62. package/explainer/docs/arc42/09-explainer-decisions.arc42.md +443 -0
  63. package/explainer/docs/arc42/10-explainer-quality-requirements.arc42.md +54 -0
  64. package/explainer/docs/arc42/11-explainer-risks.arc42.md +17 -0
  65. package/explainer/docs/arc42/12-explainer-glossary.arc42.md +185 -0
  66. package/explainer/e2e/explainer.e2e.ts +3 -0
  67. package/explainer/index.html +11 -0
  68. package/explainer/package.json +18 -0
  69. package/explainer/playwright.config.ts +1 -0
  70. package/explainer/src/app.yaml +20 -0
  71. package/explainer/src/components/ProzentFeld.test.ts +30 -0
  72. package/explainer/src/components/ProzentFeld.ts +121 -0
  73. package/explainer/src/components/ProzentFeld.vue +84 -0
  74. package/explainer/src/images/hunderterfeld-klammern.svg +105 -0
  75. package/explainer/src/main.ts +4 -0
  76. package/explainer/src/prozent/chapter.yaml +18 -0
  77. package/explainer/src/prozent/grundwert.yaml +115 -0
  78. package/explainer/src/prozent/prozentsatz.yaml +99 -0
  79. package/explainer/src/prozent/prozentwert.yaml +119 -0
  80. package/explainer/tsconfig.json +1 -0
  81. package/explainer/vite.config.ts +4 -0
  82. package/interactive/.arc42ignore +5 -0
  83. package/interactive/README.md +28 -0
  84. package/interactive/_gitignore +4 -0
  85. package/interactive/docs/arc42/05-interactive-building-blocks.arc42.md +518 -0
  86. package/interactive/docs/arc42/06-interactive-runtime-view.arc42.md +58 -0
  87. package/interactive/docs/arc42/07-interactive-deployment-view.arc42.md +35 -0
  88. package/interactive/docs/arc42/08-interactive-concepts.arc42.md +52 -0
  89. package/interactive/docs/arc42/09-interactive-decisions.arc42.md +130 -0
  90. package/interactive/docs/arc42/10-interactive-quality-requirements.arc42.md +45 -0
  91. package/interactive/docs/arc42/11-interactive-risks.arc42.md +20 -0
  92. package/interactive/docs/arc42/12-interactive-glossary.arc42.md +80 -0
  93. package/interactive/e2e/interactive.e2e.ts +3 -0
  94. package/interactive/index.html +11 -0
  95. package/interactive/package.json +18 -0
  96. package/interactive/playwright.config.ts +1 -0
  97. package/interactive/src/app.yaml +28 -0
  98. package/interactive/src/core/index.ts +101 -0
  99. package/interactive/src/data/lessons.json +4 -0
  100. package/interactive/src/env.d.ts +6 -0
  101. package/interactive/src/main.ts +6 -0
  102. package/interactive/src/messages/de.json +12 -0
  103. package/interactive/src/playthroughs/grundreihe.yaml +33 -0
  104. package/interactive/src/playthroughs/obere-reihe.yaml +14 -0
  105. package/interactive/src/ui/App.vue +85 -0
  106. package/interactive/tsconfig.json +1 -0
  107. package/interactive/vite.config.ts +4 -0
  108. package/package.json +142 -4
  109. package/quiz/README.md +31 -0
  110. package/quiz/_gitignore +5 -0
  111. package/quiz/docs/arc42/05-quiz-building-blocks.arc42.md +283 -0
  112. package/quiz/docs/arc42/06-quiz-runtime-view.arc42.md +21 -0
  113. package/quiz/docs/arc42/07-quiz-deployment-view.arc42.md +33 -0
  114. package/quiz/docs/arc42/09-quiz-decisions.arc42.md +36 -0
  115. package/quiz/docs/arc42/10-quiz-quality-requirements.arc42.md +53 -0
  116. package/quiz/docs/arc42/11-quiz-risks.arc42.md +19 -0
  117. package/quiz/docs/arc42/12-quiz-glossary.arc42.md +27 -0
  118. package/quiz/e2e/quiz.e2e.ts +3 -0
  119. package/quiz/index.html +11 -0
  120. package/quiz/package.json +18 -0
  121. package/quiz/playwright.config.ts +1 -0
  122. package/quiz/src/images/berge-ordnen.jpg +0 -0
  123. package/quiz/src/images/everest-hoehe.jpg +0 -0
  124. package/quiz/src/images/galapagos.jpg +0 -0
  125. package/quiz/src/images/grand-canyon.jpg +0 -0
  126. package/quiz/src/images/totes-meer.jpg +0 -0
  127. package/quiz/src/images/uluru.jpg +0 -0
  128. package/quiz/src/images/wasserfaelle-laender.jpg +0 -0
  129. package/quiz/src/main.ts +4 -0
  130. package/quiz/src/quiz.json +312 -0
  131. package/quiz/tsconfig.json +1 -0
  132. package/quiz/vite.config.ts +4 -0
  133. package/runtime/explainer/assessment-client.ts +478 -0
  134. package/runtime/explainer/assessment-page.ts +446 -0
  135. package/runtime/explainer/assessment.ts +393 -0
  136. package/runtime/explainer/check-page.ts +520 -0
  137. package/runtime/explainer/components/exercise.ts +409 -0
  138. package/runtime/explainer/components/props.ts +230 -0
  139. package/runtime/explainer/components/read.ts +428 -0
  140. package/runtime/explainer/content.ts +277 -0
  141. package/runtime/explainer/e2e.ts +1474 -0
  142. package/runtime/explainer/exercises.ts +324 -0
  143. package/runtime/explainer/explainer.css +1283 -0
  144. package/runtime/explainer/explainer.ts +838 -0
  145. package/runtime/explainer/explainer.v1.schema.json +1165 -0
  146. package/runtime/explainer/expression.ts +407 -0
  147. package/runtime/explainer/fraction.ts +107 -0
  148. package/runtime/explainer/generated/comparator.ts +31 -0
  149. package/runtime/explainer/generated/question.ts +165 -0
  150. package/runtime/explainer/generated/soundness.ts +280 -0
  151. package/runtime/explainer/generated/texts.ts +257 -0
  152. package/runtime/explainer/generated/types.ts +103 -0
  153. package/runtime/explainer/generated/values.ts +136 -0
  154. package/runtime/explainer/islands.ts +281 -0
  155. package/runtime/explainer/load.ts +457 -0
  156. package/runtime/explainer/messages/de.json +200 -0
  157. package/runtime/explainer/messages/en.json +200 -0
  158. package/runtime/explainer/messages.ts +13 -0
  159. package/runtime/explainer/needs.ts +122 -0
  160. package/runtime/explainer/open-task.ts +235 -0
  161. package/runtime/explainer/outline.ts +299 -0
  162. package/runtime/explainer/plugin.ts +488 -0
  163. package/runtime/explainer/position.ts +62 -0
  164. package/runtime/explainer/prompt.ts +75 -0
  165. package/runtime/explainer/render.ts +686 -0
  166. package/runtime/explainer/result.ts +238 -0
  167. package/runtime/explainer/routes.ts +119 -0
  168. package/runtime/explainer/schema.ts +140 -0
  169. package/runtime/explainer/scope.ts +87 -0
  170. package/runtime/explainer/stuck.ts +57 -0
  171. package/runtime/explainer/tasks.ts +109 -0
  172. package/runtime/explainer/tutor.ts +469 -0
  173. package/runtime/explainer/tutorpage.ts +669 -0
  174. package/runtime/explainer/video.ts +123 -0
  175. package/runtime/interactive/contract.ts +121 -0
  176. package/runtime/interactive/e2e.ts +190 -0
  177. package/runtime/interactive/interactive.css +82 -0
  178. package/runtime/interactive/interactive.ts +115 -0
  179. package/runtime/interactive/interactive.v1.schema.json +146 -0
  180. package/runtime/interactive/load.ts +188 -0
  181. package/runtime/interactive/messages/de.json +14 -0
  182. package/runtime/interactive/messages/en.json +14 -0
  183. package/runtime/interactive/messages.ts +11 -0
  184. package/runtime/interactive/playthrough.v1.schema.json +143 -0
  185. package/runtime/interactive/plugin.ts +266 -0
  186. package/runtime/interactive/render.ts +126 -0
  187. package/runtime/quiz/e2e.ts +233 -0
  188. package/runtime/quiz/engine.ts +242 -0
  189. package/runtime/quiz/messages/de.json +23 -0
  190. package/runtime/quiz/messages/en.json +23 -0
  191. package/runtime/quiz/plugin.ts +150 -0
  192. package/runtime/quiz/quiz.css +154 -0
  193. package/runtime/quiz/quiz.ts +56 -0
  194. package/runtime/quiz/quiz.v1.schema.json +72 -0
  195. package/runtime/quiz/render.ts +173 -0
  196. package/runtime/quiz/validate.ts +108 -0
  197. package/runtime/shared/appname.ts +16 -0
  198. package/runtime/shared/blocks/block.ts +162 -0
  199. package/runtime/shared/blocks/blocks.css +190 -0
  200. package/runtime/shared/blocks/blocks.v1.schema.json +432 -0
  201. package/runtime/shared/blocks/code.ts +26 -0
  202. package/runtime/shared/blocks/figures.ts +49 -0
  203. package/runtime/shared/blocks/image.ts +25 -0
  204. package/runtime/shared/blocks/index.ts +13 -0
  205. package/runtime/shared/blocks/messages/de.json +4 -0
  206. package/runtime/shared/blocks/messages/en.json +4 -0
  207. package/runtime/shared/blocks/render.ts +134 -0
  208. package/runtime/shared/blocks/validate.ts +165 -0
  209. package/runtime/shared/content.ts +197 -0
  210. package/runtime/shared/examples.ts +20 -0
  211. package/runtime/shared/html.ts +10 -0
  212. package/runtime/shared/languages.ts +94 -0
  213. package/runtime/shared/page.css +101 -0
  214. package/runtime/shared/pages.ts +114 -0
  215. package/runtime/shared/questions/e2e.ts +115 -0
  216. package/runtime/shared/questions/engine.ts +209 -0
  217. package/runtime/shared/questions/index.ts +39 -0
  218. package/runtime/shared/questions/messages/de.json +26 -0
  219. package/runtime/shared/questions/messages/en.json +26 -0
  220. package/runtime/shared/questions/question.ts +430 -0
  221. package/runtime/shared/questions/question.v1.schema.json +342 -0
  222. package/runtime/shared/questions/questions.css +192 -0
  223. package/runtime/shared/questions/render.ts +247 -0
  224. package/runtime/shared/questions/validate.ts +518 -0
  225. package/runtime/shared/schema.ts +44 -0
  226. package/runtime/shared/text/check.ts +68 -0
  227. package/runtime/shared/text/formula.ts +69 -0
  228. package/runtime/shared/text/markdown.ts +185 -0
  229. package/runtime/shared/text/text.v1.schema.json +34 -0
  230. package/runtime/shared/vue-code.ts +395 -0
  231. package/runtime/shared/vue.ts +38 -0
@@ -0,0 +1,395 @@
1
+ # Architecture evidence
2
+
3
+ Traceability of the facts of the generic architecture (`docs/arc42/`) and its three extensions
4
+ (`quiz/docs/arc42/`, `explainer/docs/arc42/`, `interactive/docs/arc42/`) to their sources. Not an arc42 chapter; the
5
+ validator does not parse it. Owner decisions count as evidence. An app's workspace is the generic files plus its
6
+ archetype's extension; `scripts/arc42.ts` validates each combination with `arc42 validate --strict` and `--root` at the
7
+ repo root (see "Strict validation, paths and input" below).
8
+
9
+ ## Strict validation, paths and input (owner, 2026-10-16)
10
+
11
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
12
+ | --- | --- | --- | --- | --- |
13
+ | owner, 2026-10-16, decision 1 (relayed by the coordinator) | Input is more than keys and mouse: the core's `step(state, input)` takes a typed, extensible input (a key, a pointer or touch action, …); playthroughs record inputs; components translate any device input into inputs | interactive dec-typed-input (supersedes dec-keys-as-input), concept-core-and-shell, concept-playthroughs, if-core-contract, if-root-component, bb-shell, scenario-play, scenario-browser-playthroughs, qs-deterministic-core, term-core, term-playthrough, term-input; ch.3 actor-learner | high | — |
14
+ | `runtime/interactive/contract.ts:15-18,26-31` (`step(state: S, key: string)`, `PlaythroughStep.keys`); `runtime/interactive/interactive.ts:49-59,69` (keydown, `onInput: input` with a key) | The runtime passes only keys today: technical debt against dec-typed-input | interactive risk-input-only-keys | high | — |
15
+ | owner, 2026-10-16, decisions 2 and 3, corrected twice (relayed by the coordinator) | Paths are static and relative to the repo root: runtime blocks at `runtime/...`; blocks and interfaces in a template folder get no path, with an ignore directive ("the template is copied into each app; this block's path is the app's own and is set in the app's architecture"); tooling helpers at their installed location; no placeholders | all ch.5 files | high | Resolved 2026-10-17, see below |
16
+ | `arc42 validate` E011 (`pathIsKnown` over `git ls-files`); `.gitignore` (node_modules/) | A path under `node_modules/@lernapps/tooling` is an error: the validator knows only tracked files. So the tooling helpers carry no path; an ignore directive per element names the location | ch.5 bb-tooling and its six interfaces | high | OPEN: reported to the owner instead of a workaround |
17
+ | owner, 2026-10-16, decision 3 | Strict: 0 errors, 0 warnings, 0 hints per combination; ignore directives only for documented exceptions (table below) | all chapters | high | — |
18
+ | `@doctc/arc42` 0.36.1 rules W026, W027 (a part and an interface in their parent's or provider's file), H017, H018 (one parent with its parts per diagram) | Extension blocks cannot be parts of generic blocks without an ignore each, and a third level cannot be drawn without a hint; so the generic roots are `bb-runtime` and `bb-tooling`, each extension defines `bb-archetype-runtime` with its parts and the creator's parts as roots, and interfaces that cross a root are provided or required by a root or a sibling | ch.5, ch.4 System decomposition, ch.8 concept-archetype-extension | high | — (agent design under the owner's strict rule) |
19
+ | `@doctc/arc42` 0.36.1 rules H015, H016, W019 (per chapter-5 file: at least one diagram, covering every block and interface of the workspace) | The generic chapter-5 file cannot name an extension's blocks; `scripts/arc42.ts` therefore appends each extension's chapter file to the generic one of the same chapter (as an app's single architecture would hold them) and reports findings at their original place | scripts/arc42.ts; ch.5 | high | OPEN: whether apps get the combined files the same way (tooling step) |
20
+ | `git ls-files runtime/` ; `arc42 validate` H021 (coverage of sibling paths) | `runtime/quiz`, `runtime/explainer`, `runtime/interactive` are left out in `.arc42ignore`: each is claimed in its own combination, the others are siblings of `runtime/shared` there | .arc42ignore | high | — |
21
+ | `runtime/*/` imports (`grep from runtime/*/*.ts`) | The interactive build imports the explainer's component rules (`../explainer/components.ts`); the explainer imports the quiz's question types, rendering, engine and checker (`../quiz/quiz.ts`, `render.ts`, `engine.ts`, `validate.ts`); the plugins import `@lernapps/tooling/preset` | interactive bb-component-rules; explainer bb-question-types; bb-archetype-runtime requires if-preset | high | — |
22
+ | `runtime/interactive/contract.ts:20-24` (TICK, STATE_PROPERTY) | The state property is defined next to the core contract | interactive if-state-property, ignore H020 | high | — |
23
+ | owner, 2026-10-16, decision 4 | The architecture check runs in this repo's pre-commit hook when `*.arc42.md` or `.arc42ignore` files are staged, and in CI; `@doctc/arc42` pinned as a devDependency (0.38.0 since 2026-10-20, the tooling's version) | vite.config.ts staged, .github/workflows/check.yml job architecture, package.json; ch.2 con-architecture-current, ch.9 dec-arc42-in-app, ch.11 risk-arc42-checks-not-wired | high | — |
24
+ | agent inference | Removed as blocks: the main.ts glue (thin, kept as generated; named in if-start), the loading indicator and settings (not built, kept in dec-no-size-limit and dec-no-settings), the skills per archetype (one interface if-skills of bb-tooling), low stimulation as a concept (no block implements it; now in risk-interactive-skill-missing) | ch.5, ch.8, interactive ch.11 | medium | — |
25
+
26
+ ### Ignore directives
27
+
28
+ | Rule | Element | Reason |
29
+ | --- | --- | --- |
30
+ | H014 | bb-tooling, if-preset, if-lernapps-check, if-device-storage, if-a11y, if-translator | @lernapps/tooling is installed in the untracked node_modules; a path there is E011 |
31
+ | H014 | explainer bb-explainer-data, if-data-files | optional and not in the template; an app that adds them sets their paths in its own architecture (the components have their paths since the template has ProzentFeld, 2026-10-26) |
32
+ | H014 | interactive if-root-component | no file of its own: its props are set in runtime/interactive/interactive.ts, which carries if-start |
33
+ | H020 | interactive if-core-contract | it and if-state-property are both defined in runtime/interactive/contract.ts |
34
+ | H006 | con-bundled-licences, con-imprint-privacy | organisation rules verified by lernapps check or met by the runtime's footer; no decision responds to them |
35
+ | H001 | dec-no-settings | a scoping decision of the owner; serves no quality goal |
36
+ | H007 | quiz risk-quiz-no-js-not-in-check | accepted without a decision; the quiz's own end-to-end tests check the worksheet |
37
+ | H014 | bb-skills, if-skills | the skills are committed in each app under .agents/skills; this repository has none (owner, 2026-10-16) |
38
+ | W006 | qg-privacy, from the interactive extension (moved to the top of chapter 10 by `scripts/arc42.ts`) | two high-priority goals in the interactive combination is the owner's decision (2026-10-16); quiz and explainer have three, so the directive would be stale there |
39
+ | W014 | quiz qg-quiz-readable-without-js, explainer qg-explainer-readable-without-js | the extension's high goal follows the generic medium goals in the combined chapter 10 |
40
+ | H010 | quiz qg-quiz-readable-without-js, explainer qg-explainer-readable-without-js | the generic solution strategy cannot name an archetype's goal (an error in the other combinations); the archetype's decisions address it |
41
+ | H021 | `.arc42ignore`: runtime/quiz, runtime/explainer, runtime/interactive | another archetype's runtime, claimed in its own combination |
42
+
43
+ ### Ids moved or removed in this step
44
+
45
+ | Before | After |
46
+ | --- | --- |
47
+ | bb-archetype (abstract), if-quiz-bank, if-explainer-content, if-interactive-description | removed; each extension's content block provides `if-archetype-content` |
48
+ | bb-static-description, bb-page-tree, bb-not-found-page, bb-build-checks, bb-examples-check, bb-loading-indicator, bb-settings | `bb-render` (each extension), `bb-runtime` (shared runtime: page trees, 404 page, examples check); loading indicator and settings not modelled |
49
+ | bb-quiz-rendering, bb-quiz-validation, bb-quiz-engine, bb-quiz-tests; bb-explainer-rendering, -validation, -client, -tests; bb-interactive-start-page, -app-page, -validation, bb-core-check, bb-build-playthroughs, bb-browser-playthroughs | `bb-render`, `bb-validation`, `bb-shell`, `bb-e2e`, `bb-build` in each extension, parts of `bb-archetype-runtime` |
50
+ | bb-state-holder, bb-input-router, bb-clock, bb-hash-router, bb-seed | interactive `bb-shell` (one file, runtime/interactive/interactive.ts) |
51
+ | bb-preset, bb-lint-rules, bb-lernapps-check, bb-playwright-config, bb-small-storage, bb-a11y, bb-i18n, bb-skill-app, bb-skill-quiz, bb-skill-explainer, bb-skill-interactive; if-lint-plugin, if-playwright-config, if-skill-* | `bb-tooling` with if-preset, if-lernapps-check, if-skills, if-device-storage, if-a11y, if-translator |
52
+ | bb-quiz-main, bb-explainer-main, bb-interactive-main; if-static-files | removed (main.ts named in if-start; GitHub Pages requires if-pages) |
53
+ | bb-exercise-contract, if-exercise-description, if-question-exports (explainer) | explainer if-exercise-logic (exercise contract), bb-question-types with if-question-types |
54
+ | concept-tutor, actor-learner-assistant, scenario-tutor | explainer extension (08, 03, 06) |
55
+ | risk-size-budget-left (interactive), risk-explainer-component-budget | generic risk-size-budget-left |
56
+ | dec-keys-as-input | superseded by interactive dec-typed-input |
57
+
58
+ ## Skills as a building block (owner, 2026-10-16)
59
+
60
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
61
+ | --- | --- | --- | --- | --- |
62
+ | owner, 2026-10-16, decision (relayed by the coordinator) | The skills are a building block of their own behind `if-skills`: in an app they are committed under `.agents/skills/`, one folder per skill (lernapps-app, the archetype's skill, the content skills, lernapps-listing, the app's own app-content), installed and replaced by `lernapps update`; the tooling's source is its `skills/` folder | ch.5 bb-skills, if-skills (provider moved from bb-tooling); ch.3 actor-creator-assistant; ch.4; ch.6 scenario-skills; ch.7 dn-creator-machine; ch.9 dec-skill-interface | high | — |
63
+ | `git ls-files .agents` in this repository (empty) | This repository has no `.agents/skills`, so `bb-skills` and `if-skills` carry no path; an ignore directive names the reason | ch.5 bb-skills, if-skills (H014) | high | — |
64
+ | tooling `generator/update.ts:12-14,72-76`; tooling `skills/` (`lernapps-app`, `-quiz`, `-explainer`, `-listing`, `-content-research`, `-exercise-patterns`, `-content-growth`) | `lernapps update` replaces the app's `lernapps-*` skills with the tooling's and keeps the app's own (app-content) | ch.5 bb-skills; ch.6 scenario-skills | high | — |
65
+ | `@doctc/arc42` 0.36.1 W026, W027 (a part and an interface in their parent's or provider's file) | `bb-skills` is a third generic root rather than a part of `bb-tooling`, so that no extra diagram is needed; it and `if-skills` are in the same file | ch.5 | medium | — |
66
+ | owner, 2026-10-16, decision; [lernapps/tooling#90](https://github.com/lernapps/tooling/pull/90) | Low stimulation is advice of the skills (no flashing, calm motion, sound off by default, and why); the skill `lernapps-interactive` gives it, provided in tooling#90; the risk of the missing skill stays until it merges | ch.8 concept-low-stimulation (implemented by bb-skills); interactive risk-interactive-skill-missing | high | — |
67
+ | owner, 2026-10-16, correction | The skill keeps only the general principles: no recipes per kind of app | interactive dec-one-archetype (no longer "kinds as recipes"), risk-interactive-skill-missing | high | — |
68
+ | owner, 2026-10-16, decision | `qg-quiz-readable-without-js` and `qg-explainer-readable-without-js` have priority high (both archetypes are text-heavy) | quiz and explainer ch.10 | high | — (resolved) |
69
+ | owner, 2026-10-16, decision | No creator checkpoint for the architecture: the agent keeps the app's architecture current and validated with every change | ch.2 con-architecture-current | high | — |
70
+
71
+ ## Generic architecture and extensions (owner, 2026-10-16)
72
+
73
+ The architecture was first written for the interactive archetype (rows from "Sources inventoried" on). By the owner's
74
+ decision of 2026-10-16 it became the generic architecture of every lernapps app, at the repo root, with one extension
75
+ per archetype. Rows below this section name ids as they were before the split; the table of moved ids maps them.
76
+
77
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
78
+ | --- | --- | --- | --- | --- |
79
+ | owner, 2026-10-16, decision (relayed by the coordinator) | One architecture for every archetype; quiz, explainer and interactive stay separate archetypes and follow it because they share its quality goals; generic part at `docs/arc42/`, one extension per archetype in its template folder that adds only its own blocks (below the generic ones via `parent`), interfaces, decisions, risks and terms, and defines no generic id again | all chapters; dec-generic-plus-extensions; concept-archetype-extension | high | — |
80
+ | owner, 2026-10-16, decision | Only interactive apps write an architecture part of their own; the quiz's and the explainer's notation fixes their structure | ch.2 con-architecture-current; ch.9 dec-arc42-in-app; quiz dec-quiz-only-bank; explainer dec-explainer-only-content | high | — |
81
+ | owner, 2026-10-16, decision | Quality goal priorities confirmed: privacy and checkable high, accessibility and understandable medium | ch.1, ch.10 | high | — (resolved) |
82
+ | owner, 2026-10-16, decision | Readable without JavaScript is a quality goal of the quiz and the explainer (text-heavy), not of the generic architecture and not of interactive apps (only their start page reads without JavaScript) | quiz qg-quiz-readable-without-js, explainer qg-explainer-readable-without-js; ch.8 concept-readable-without-js; ch.6 scenario-pages | high | — (resolved: owner, 2026-10-16, priority high for both, because both archetypes are text-heavy) |
83
+ | owner, 2026-10-16, earlier review (kept in force) | No model in the browser; no IndexedDB; no size limit, the size in the entry and an optional loading indicator; the skill as an interface used by the creator's assistant | ch.5 bb-tutor-handoff, bb-small-storage, bb-loading-indicator, bb-skill-app; ch.9 dec-tutor-variant, dec-small-storage, dec-no-size-limit, dec-skill-interface | high | — |
84
+ | `runtime/shared/pages.ts` header | Page trees per language and 404.html are shared by the archetypes' build steps | ch.5 bb-page-tree, bb-not-found-page | high | — |
85
+ | `runtime/shared/examples.ts` header; `runtime/quiz/validate.ts` header | The examples check runs for the quiz's questions and the explainer's exercises; interactive apps have none | ch.5 bb-examples-check | high | — |
86
+ | `runtime/explainer/components.ts` header ("The interactive archetype runs the same code checks"); `runtime/interactive/plugin.ts` lines 10-13 | Component rules shared by explainer components and the interactive UI; the quiz has no components | ch.5 bb-component-rules; ch.2 con-vue-typescript | high | — |
87
+ | `runtime/quiz/question.ts`, `quiz.ts` headers; `runtime/explainer/exercises.ts` header | The six question types and checker are used by the quiz and by the explainer's quiz-type exercises | ch.5 bb-question-types | high | — |
88
+ | `runtime/explainer/tutor.ts`, `tutorpage.ts`, `prompt.ts`, `tasks.ts`, `components.ts`, `generated.ts` headers; no tutor code in `runtime/quiz/`, `runtime/interactive/` | Tutor handoff, task numbers and exercise contract built for the explainer, not for the quiz and interactive apps | ch.5 bb-tutor-handoff, bb-task-numbers, bb-exercise-contract; ch.3, ch.6, ch.11 | high | — |
89
+ | `runtime/quiz/engine.ts` lines 1-17, 244 | The quiz engine: one question at a time in the seed's order, deep link, stores only the last result when the bank asks | quiz bb-quiz-engine, scenario-quiz-answer | high | — |
90
+ | `runtime/quiz/render.ts` header; skill `lernapps-quiz` "How the quiz works" | Without JavaScript the quiz page is a worksheet with its answer key | quiz bb-quiz-rendering, dec-quiz-worksheet, qg-quiz-readable-without-js | high | — |
91
+ | `runtime/quiz/e2e.ts` header | quizTests check the page without JavaScript in every language | quiz qs-quiz-without-js | high | — |
92
+ | tooling `check/rules/explainer-readable-without-js.ts` header; skill `lernapps-explainer` rule explainer-readable-without-js | lernapps check verifies only explainer pages without JavaScript; the quiz's is checked by its own tests | explainer qs-explainer-without-js; quiz risk-quiz-no-js-not-in-check; ch.5 bb-lernapps-check | high | — |
93
+ | skill `lernapps-quiz` rule quiz-only-data | The quiz's creator writes only src/quiz.json | quiz bb-quiz-bank, dec-quiz-only-bank; ch.2 con-runtime-unchanged | high | — |
94
+ | skill `lernapps-explainer` rules explainer-only-content, prefer-built-in-block, vue-component-*; "Data files"; "Components" | The explainer's creator writes YAML content, data files and Vue components only where no block fits, each within 20 kB gzip | explainer bb-explainer-content, bb-explainer-data, bb-explainer-components, dec-explainer-only-content | high | — |
95
+ | `runtime/explainer/plugin.ts`, `render.ts`, `load.ts`, `explainer.ts`, `islands.ts`, `generated.ts`, `e2e.ts`, `outline.ts` headers | The explainer's rendering (pages, blocks, islands at build), validation, client, islands, generated exercises and tests | explainer ch.5, ch.6 | high | — |
96
+ | `runtime/explainer/components.ts:57` (SIZE_BUDGET = 20_000); `plugin.ts:293-309` | The explainer's build fails a component over 20 kB gzip | explainer ch.9 / dec-explainer-component-size | high | — (resolved: owner, 2026-10-16, a fixed size per component; the figure is an implementation detail) |
97
+ | skill `lernapps-explainer` line 38 ("The explainer stores nothing"); `runtime/explainer/explainer.ts:17,184` | The skill and the runtime differ: the client keeps the chosen way to the tutor on the device | ch.5 bb-small-storage | high | — (resolved 2026-10-26: the skill at tooling 64a8b53 says the explainer stores only the learner's assistant; risk-explainer-storage-doc removed) |
98
+ | `explainer/src/`, `quiz/src/`, `interactive/src/` (template folders) | Superseded (owner, 2026-10-16): template blocks carry no path | extensions ch.5 | high | — |
99
+ | owner, 2026-10-17 (relayed by the coordinator) | Supersedes the 2026-10-16 rule for template blocks: they carry their path with the template prefix (`interactive/src/core`, `quiz/src/quiz.json`, `explainer/src/app.yaml`), which exists in this repo and validates without an ignore; the tooling copies the generic part and the interactive extension into an interactive app, strips the prefix and turns `runtime/...` paths into ignore directives (E011, docToolchain/arc42-language#128). The templates' entries, type declarations and the explainer's example chapter are left out in `.arc42ignore` | extensions ch.5, ch.5 intro, .arc42ignore | high | — |
100
+ | owner, 2026-10-17, second decision (relayed by the coordinator); `@doctc/arc42` 0.36.1 W026 (a part in its parent's section), H015 (every block in a diagram of its chapter-5 file), W012 (every leaf on a deployment node) | An app's own architecture goes into its copy of these chapters, between the markers `<!-- app: begin … -->` and `<!-- app: end … -->`, which the tooling keeps when it replaces the rest: in chapter 5 inside the sections of the core, the UI and the data (named `core`, `ui`, `data`) and at the end of every interactive chapter; not in files of its own, where those rules cannot be met | interactive ch.5 to ch.12 | high | — |
101
+ | agent inference | Extension deployment nodes (`dn-<archetype>-build` below the CI runner, `dn-<archetype>-page` below the learner's browser) host the extension's blocks; the build node also stands for the creator's machine | extensions ch.7 | medium | — |
102
+ | agent inference | `if-archetype-content`, defined by each extension on its content block, stands for what the creator writes | ch.5, ch.3 | medium | — |
103
+ | agent inference | `if-lernapps-check` as an interface the creator's assistant requires | ch.3 actor-creator-assistant, ch.5 | medium | OPEN (narrowed): an interface for `vp build` and `vp dev` |
104
+
105
+ Earlier ignore directives (W002 for bb-not-found-page, bb-loading-indicator, bb-settings; W026 for every extension block with a generic parent) were removed with the restructuring above.
106
+
107
+ ### Moved and renamed ids (from the interactive architecture)
108
+
109
+ | Before | After |
110
+ | --- | --- |
111
+ | bb-app | bb-archetype (abstract, generic) |
112
+ | bb-description, bb-main, bb-core, bb-ui, bb-data, bb-messages, bb-playthroughs | bb-interactive-description, -main, -core, -ui, -data, -messages, -playthroughs (interactive extension) |
113
+ | bb-start-page, bb-app-page | bb-interactive-start-page, bb-interactive-app-page below bb-static-description (interactive extension) |
114
+ | bb-app-validation | bb-interactive-validation (interactive extension) |
115
+ | bb-core-check, bb-build-playthroughs, bb-input-router, bb-clock, bb-hash-router, bb-seed, bb-browser-playthroughs | interactive extension; the shell's mount and state became bb-state-holder |
116
+ | if-start-page, if-app-description, if-app-data, if-start-interactive, if-interactive-tests | if-pages (generic), if-interactive-description, if-interactive-data, if-start (generic), if-e2e-tests (generic) |
117
+ | concept-core-and-shell, concept-playthroughs, concept-hash-routes, concept-low-stimulation | interactive extension |
118
+ | dec-one-archetype, dec-runtime-owns-state, dec-keys-as-input, dec-start-seed-route, dec-playthroughs-as-data | interactive extension |
119
+ | qs-deterministic-core, qs-playthrough-in-browser | interactive extension |
120
+ | risk-time-not-replayed, risk-size-budget-left, risk-no-core-property-tests | interactive extension |
121
+ | term-core, term-app-page, term-route, term-tick, term-playthrough | interactive extension |
122
+
123
+ ## Sources inventoried (the interactive architecture before the split)
124
+
125
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
126
+ | --- | --- | --- | --- | --- |
127
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md`, "Sketch: the interactive archetype (step 12, decided by the owner)" | Scope, the opinionated frame (Vue fixed), shell and app split, arc42 in the app, accessibility default with declared limits, tests | all chapters | high | — |
128
+ | owner, 2026-10-16, conversation | Small storage: localStorage through the tooling wrapper, 100 kB per app; no settings, motion, sound or pause now; low stimulation as advice; architecture English and minimal; note all generic components, optional ones too | ch.2, ch.5, ch.8, ch.9 | high | — |
129
+ | owner, 2026-10-16, review | Tutor: no model in the browser; the tutor is the handoff to the learner's own assistant as in the explainer (bb-tutor-handoff, optional, not built for interactive apps); dec-tutor-variant accepted; bb-tutor-handoff provides the tutor prompt and files that actor-learner-assistant requires | ch.1, ch.3, ch.4, ch.5, ch.6, ch.8, ch.9, ch.11, ch.12 | high | — (resolves OPEN: handoff or model in the browser) |
130
+ | owner, 2026-10-16, review | IndexedDB left out entirely (bb-large-storage and its mentions removed) | ch.2, ch.5, ch.8, ch.9 | high | — |
131
+ | owner, 2026-10-16, review | No size limit: bb-size-budget, con-size-budget, concept-size-budget, qg-small and their scenarios and risks removed; the app's size goes into its catalog entry (fact sheet); optional loading indicator (progress bar at start, not built) in the shell; SIZE_BUDGET in runtime/interactive/plugin.ts is technical debt | ch.1, ch.2, ch.4, ch.5, ch.6, ch.7, ch.8, ch.10, ch.11, ch.12 | high | — (resolves OPEN: size budget scope) |
132
+ | owner, 2026-10-16, review | Low stimulation: the skill lernapps-interactive (not built) is a tooling block providing the skill text that actor-creator-assistant requires; it implements concept-low-stimulation | ch.3, ch.5, ch.8 | high | — |
133
+ | owner, 2026-10-16, review | Quality goals qg-privacy, qg-checkable, qg-accessibility (default with declared limits), qg-understandable (a reviewer or the creator's agent understands an app's structure from its architecture); qg-small dropped | ch.1, ch.4, ch.10 | high | — |
134
+ | owner, 2026-10-16, review | Playthrough time steps (n ticks, build and browser, not built); actor interfaces if-start-page, if-app-address (bb-app-page), if-static-files (bb-build); shared-origin storage risk medium and accepted; core property tests stay planned; interactive apps get the same Pages workflow (check, publish, preview) in step 2 of the plan | ch.3, ch.5, ch.7, ch.8, ch.9, ch.11 | high | — (resolves OPENs on actor interfaces, time steps, storage risk, Pages workflow) |
135
+ | owner, 2026-10-16, review | Exercise contract: the optional exports with which an app describes its tasks (describe(state, lang) gives task and solution text for the tutor and task numbers; examples of accepted and rejected answers checked at build), from the explainer's exercise components | ch.5, ch.6 | high | — |
136
+ | `lernapps/.github ORGANIZATION.md`, "Every page, in every repo" | No cookies, no tracking, no requests to other servers before a click; WCAG 2.1 AA and 360 px for platform pages, default for apps | ch.2 | high | — |
137
+ | `runtime/interactive/contract.ts` | Core contract start(seed, route), step(state, key), tick(state, dt); TICK = 20; playthrough format | ch.5, ch.6 | high | — |
138
+ | `runtime/interactive/interactive.ts` (startInteractive) | Shell: state holder, input routing, clock, hash routes, seed from the address | ch.5, ch.6 | high | — |
139
+ | `runtime/interactive/plugin.ts`, `load.ts`, `render.ts` | Build: start page and app page, validation, core and playthrough checks; SIZE_BUDGET 100 kB still in plugin.ts (debt) | ch.5, ch.6, ch.11 | high | — |
140
+ | `runtime/interactive/e2e.ts` (interactiveTests) | Browser playthroughs, pages without JavaScript, 360 px | ch.5, ch.10 | high | — |
141
+
142
+ ## Rows from the chapters
143
+
144
+ ### Chapter 1
145
+
146
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
147
+ | --- | --- | --- | --- | --- |
148
+ | tooling `.vibe/development-plan-agentic-app-creation.md`, Sketch step 12, section 1 | Scope: apps whose doing is the content (typing game, Kniffel trainer, careful reading) | ch.1 / 1.1 | high | — |
149
+ | same, section 3 | Static start page from src/app.yaml readable without JS; app page; hash routes; app writes core, ui, data, playthroughs; runtime not changed by the app | ch.1 / 1.1 | high | — |
150
+ | `runtime/interactive/interactive.ts` (startInteractive) | Keys and component-emitted input step the core; tick every TICK; seed from ?seed; route from #id | ch.1 / 1.1 | high | — |
151
+ | `ORGANIZATION.md`, "Apps and the app overview" | An app connects to the platform only through its entry in the app overview | ch.1 / 1.1 | high | — |
152
+ | owner, 2026-10-16, review | Optional tutor as a handoff to the learner's own assistant, no model in the browser | ch.1 / 1.1 | high | — |
153
+ | owner, 2026-10-16, review | Quality goals qg-privacy, qg-checkable, qg-accessibility, qg-understandable and their order | ch.1 / 1.2 | high | — |
154
+ | coordinator's proposal; owner, 2026-10-16, confirmed | Priorities: qg-privacy high, qg-checkable high, qg-accessibility medium, qg-understandable medium | ch.1 / 1.2, ch.10 | high | — (resolved: confirmed by the owner, 2026-10-16) |
155
+ | `ORGANIZATION.md` lines 3, 13-21, 35-40 | Stakeholders: learners, creators (and their AI assistant), owner Oliver Jägle, teachers and parents; listing decided by the owner | ch.1 / 1.3 | high | — |
156
+ | tooling `scripts/verdict.ts` header; ORGANIZATION.md line 51 | Reviewers: a review agent before listing; the owner decides the listing | ch.1 / 1.3 | medium | — |
157
+
158
+ ### Chapter 2
159
+
160
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
161
+ | --- | --- | --- | --- | --- |
162
+ | `ORGANIZATION.md` lines 25-28, 46, 50 | Static sites on GitHub Pages at lernapps.net/<repo>/; one repo per app; apps share no code at runtime | ch.2 / con-frontend-only | high | — |
163
+ | `ORGANIZATION.md` line 56; tooling `check/rules/no-request-before-click.ts`, `no-tracking.ts` | No cookies, tracking or requests to other servers before a click, checked on the built app | ch.2 / con-no-request-before-click | high | — |
164
+ | Sketch step 12, section 2; `interactive/package.json` (vite-plus 1.0.0); `vite.config.ts` (tooling preset) | Vue with TypeScript on vite-plus is fixed | ch.2 / con-vue-typescript | high | — |
165
+ | owner, 2026-10-16, conversation | Vue is fixed | ch.2 / con-vue-typescript | high | — |
166
+ | `runtime/explainer/components.ts` header; `runtime/interactive/plugin.ts` lines 9-13 | Component rules on SFC compiler output: no network, eval, new Function, innerHTML, v-html; restricted imports; browser globals only in onMounted | ch.2 / con-component-rules | high | — |
167
+ | Sketch step 12, sections 3-4 | Runtime interactive/ is not changed by the app; the app writes in the template's folders | ch.2 / con-runtime-unchanged | high | — |
168
+ | tooling `archetypes/shared/storage.ts` header; test `app-check-failing.e2e.test.ts` (storage-through-wrapper) | Storage only through the wrapper, localStorage under prefix lernapps:<app>:, failures tolerated | ch.2 / con-state-on-device | high | — |
169
+ | owner, 2026-10-16, conversation; Sketch step 12, section 3 | Quota 100 kB per app, save refuses beyond | ch.2 / con-storage-quota | high | — |
170
+ | tooling `archetypes/shared/storage.ts` (no limit in save) | Quota not built yet | ch.2 / con-storage-quota | high | — |
171
+ | `ORGANIZATION.md` lines 57-58; Sketch step 12, section 5 | WCAG 2.1 AA and 360 px: platform rule, app default, deviations declared in the entry; start page meets both; low stimulation advice only | ch.2 / con-accessibility-default | high | — |
172
+ | tooling `check/rules/accessible.ts:8`, `usable-at-360px.ts:10` (severity error) | Warning mode for apps with declared limits not built yet | ch.2 / con-accessibility-default | high | — |
173
+ | `ORGANIZATION.md` lines 61-64; owner, 2026-10-16, conversation | German for learner text, English for infrastructure; app author decides names inside the repo; architecture in English | ch.2 / con-language | high | — |
174
+ | Sketch step 12, section 2; tooling `check/rules/dependency-licence.ts` (ALLOWED); ORGANIZATION.md lines 70-79 | Libraries bundled, never from a CDN, under allowlisted licences; app repo MIT | ch.2 / con-bundled-licences | high | — |
175
+ | owner, 2026-10-16, review; `runtime/interactive/plugin.ts:41` (SIZE_BUDGET) | No size limit; con-size-budget removed; the build's SIZE_BUDGET is debt (ch.11) | ch.2 | high | — (resolves OPEN: size budget scope) |
176
+ | `ORGANIZATION.md` line 59; `runtime/interactive/render.ts:67` | Links to imprint and privacy notice in the shell's footer | ch.2 / con-imprint-privacy | high | — |
177
+ | Sketch step 12, section 4 | Architecture in docs/arc42, kept current; arc42 diff before commit, arc42 validate in lernapps check | ch.2 / con-architecture-current | high | — |
178
+ | search of tooling for "arc42 diff"/"arc42 validate" outside the plan (only scripts/build.sh, review-summary.ts) | arc42 checks not yet wired into app hooks and check | ch.2 / con-architecture-current | medium | OPEN: confirm the arc42 hook and check for apps are not built yet |
179
+
180
+ ### Chapter 3
181
+
182
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
183
+ | --- | --- | --- | --- | --- |
184
+ | owner, 2026-10-16, review; ch.5 if-start-page, if-app-address, if-static-files, if-tutor-files, if-skill-interactive | Every actor requires an interface of chapter 5 | ch.3 / all actors | high | — (resolves OPEN: interfaces for pages, addresses, static files, tutor handoff); the commands stay open, see below |
185
+ | `ORGANIZATION.md` lines 3, 13-21 (stakeholders); ch.1 1.3 | Learners (adults and students, often in German schools), teachers and parents as users | ch.3 / actor-learner, actor-teacher-parent | high | — |
186
+ | `runtime/interactive/interactive.ts` (startInteractive); `runtime/interactive/render.ts`; owner, 2026-10-16, review | Learner plays the app page with keys and pointer input; start page readable without JavaScript; requires if-start-page, if-app-address | ch.3 / actor-learner | high | — |
187
+ | `ORGANIZATION.md` line 58; decided sketch step 12 section 3; owner, 2026-10-16, review | Start page in German, without JavaScript, for teachers and parents; requires if-start-page | ch.3 / actor-teacher-parent | high | — |
188
+ | decided sketch step 12 section 3 "What the agent writes" | The creator's assistant writes src/core, src/ui, src/data, src/playthroughs (and src/app.yaml) | ch.3 / actor-creator-assistant | high | — |
189
+ | ch.5 if-app-description, if-core-contract, if-root-component, if-playthrough-format, if-skill-interactive; owner, 2026-10-16, review | The assistant's `requires` points at the four contracts it writes against and the skill text | ch.3 / actor-creator-assistant | medium | OPEN: no interface in ch.5 for vp build, vp dev, lernapps check |
190
+ | `ORGANIZATION.md` "What every site shares" line 28; con-frontend-only; owner, 2026-10-16, review | Static files published from gh-pages to lernapps.net/<repo>/, PR previews; requires if-static-files | ch.3 / actor-github-pages | high | — |
191
+ | `ORGANIZATION.md` line 50; `tooling check/rules/entry-links-resolve.ts` header; owner, 2026-10-16, review | App connects to the platform only through its overview entry; entry URL and topic links must resolve; requires if-start-page, if-app-address | ch.3 / actor-app-overview | high | — |
192
+ | tooling `.vibe/development-plan-agentic-app-creation.md` KD-13 (fact sheet, later); `apps/schemas/entry.v1.schema.json` (no size field); owner, 2026-10-16, review | The entry's fact sheet states the app's size; not built yet | ch.3 / actor-app-overview, ch.4, ch.5 / bb-build-checks, ch.12 / term-entry | high | — |
193
+ | owner, 2026-10-16, review; `runtime/explainer/tutor.ts:1-12`, `tutorpage.ts:1-5` | The tutor is the learner's own assistant, receiving the tutor prompt and files after a click; not built for interactive apps | ch.3 / actor-learner-assistant | high | — |
194
+ | arc42 cli W021/W023/W028 (dist/cli.mjs) | Context diagram: boundary subgraph, edges from actors to the boundary, only actor-facing blocks inside | ch.3 / system-context | high | — |
195
+
196
+ ### Chapter 4
197
+
198
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
199
+ | --- | --- | --- | --- | --- |
200
+ | decided sketch step 12, section 2 heading | "Opinionated where it makes the rules checkable, free where the learning happens"; Vue fixed; rendering, logic, decomposition free; libraries bundled | ch.4 / strategy-fixed-frame-free-app | high | — |
201
+ | decided sketch step 12, section 3; con-runtime-unchanged | Runtime frame the app does not change; app writes core, UI, data, playthroughs | ch.4 / strategy-fixed-frame-free-app | high | — |
202
+ | `runtime/interactive/interactive.ts`; `contract.ts` TICK=20 | Shell holds state, routes keys and pointer input, ticks every 20 ms, route and seed from the address | ch.4 / System decomposition | high | — |
203
+ | `runtime/interactive/plugin.ts` (two plays, SIZE_BUDGET, component rules); `e2e.ts` | Build fails on broken description, contract, non-determinism, component rules, size; browser tests via lernapps check --pre-push | ch.4 / Operational approach | high | — |
204
+ | `ORGANIZATION.md` "What every site shares" (Renovate) ; con-runtime-unchanged | Runtime and tooling reach the app as dependency updates | ch.4 / Operational approach | high | — |
205
+ | owner, 2026-10-16, review | Strategy addresses the four goals; goal-to-approach mapping | ch.4 / strategy-fixed-frame-free-app addresses | high | — |
206
+ | con-architecture-current; decided sketch step 12 section 4 | arc42 diff before commit and validate in check decided, not built | ch.4 / Operational approach | medium | OPEN: confirm not built yet for apps |
207
+ | owner, 2026-10-16, review | Tutor as handoff, no model in the browser | ch.4 | high | — |
208
+ | owner, 2026-10-16, review | No size limit; size stated in the catalog entry | ch.4 / Operational approach | high | — |
209
+
210
+ ### Chapter 5
211
+
212
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
213
+ | --- | --- | --- | --- | --- |
214
+ | tooling `.vibe/development-plan-agentic-app-creation.md`, sketch §3 | Runtime `interactive/` the app does not change; app writes src/core, src/ui, src/data, src/playthroughs | ch.5 / bb-runtime, bb-app, bb-core, bb-ui, bb-data, bb-playthroughs | high | — |
215
+ | `runtime/interactive/plugin.ts:1-21`, `interactive()` | Build step: validation, component rules, core and playthrough checks, pages, 404; app adds it via vite.config.ts | ch.5 / bb-build, if-build-plugin, bb-build-checks, bb-not-found-page | high | — |
216
+ | `tooling archetypes/shared/preset.ts:9` (relative URLs); `generator/app/.github/workflows/pages.yml`; owner, 2026-10-16, review | The build's static files, served by GitHub Pages | ch.5 / if-static-files | high | — |
217
+ | `runtime/interactive/render.ts`; `runtime/interactive/interactive.ts` (seedParam, routeOf); owner, 2026-10-16, review | Start page at lernapps.net/<repo>/ and app address app/?seed=<n>#<route> as interfaces for the actors (provider bb-app-page chosen) | ch.5 / if-start-page, if-app-address | high | — |
218
+ | owner, 2026-10-16, review | Size not limited; the build check is removed from the model; optional loading indicator (progress bar at start, not built) | ch.5 / bb-build-checks, bb-loading-indicator | high | — |
219
+ | `runtime/interactive/plugin.ts` `coreProblems`, `play` | Exports checked, every route starts, each playthrough played twice without tick, states compared | ch.5 / bb-core-check, bb-build-playthroughs | high | — |
220
+ | `runtime/interactive/load.ts:1-6`, `loadInteractive` | app.yaml and playthroughs validated against schemas plus German first, languages, unique ids, ≥1 playthrough, known routes | ch.5 / bb-app-validation, if-app-description, if-playthrough-format | high | — |
221
+ | `runtime/interactive/load.ts:106` `languageListProblems(app.languages, Object.keys(MESSAGES))` | An app may declare only languages the runtime has texts for (de, en) | ch.5 / bb-page-tree | high | — |
222
+ | `runtime/interactive/render.ts:1-9, 86, 109-111` | Start page static with noscript and no script; app page with noscript, route anchors, `.interactive-app` with data-routes | ch.5 / bb-start-page, bb-app-page | high | — |
223
+ | `runtime/shared/pages.ts:1-4`, `notFoundPage` (l.67) | Page tree per language, German at root, switch of plain links, relative URLs; 404 page | ch.5 / bb-page-tree, bb-not-found-page | high | — |
224
+ | `runtime/explainer/components.ts:1-15, 17-19`, `codeProblems` (l.407), `sourceScope` | Component rules on SFC compiler output, reused by interactive with scope src/ | ch.5 / bb-component-rules | high | — |
225
+ | `runtime/interactive/interactive.ts`, `startInteractive` | Shell mounts root with props state, lang, onInput; holds state; mirrors STATE_PROPERTY on host | ch.5 / bb-shell, if-start-interactive, if-state-property, if-root-component | high | — |
226
+ | `runtime/interactive/interactive.ts` keydown handler, `CONTROLS`, `input` | Keys to step except on controls or with modifiers; emitted input keys stepped; changed state prevents default | ch.5 / bb-input-router | high | — |
227
+ | `runtime/interactive/contract.ts` `TICK = 20`; `interactive.ts` setInterval | Clock calls tick every 20 ms when the core has it | ch.5 / bb-clock | high | — |
228
+ | `runtime/interactive/interactive.ts` `routeOf`, hashchange | Route from #id else first route; restart on new route | ch.5 / bb-hash-router | high | — |
229
+ | `runtime/interactive/interactive.ts` seedParam | Seed from ?seed=n else random | ch.5 / bb-seed | high | — |
230
+ | `runtime/interactive/contract.ts` `Core`, `Playthrough` | Core contract start(seed, route), step(state, key), tick?(state, dt); playthrough seed, route, steps of keys with state/announce | ch.5 / if-core-contract, if-playthrough-format | high | — |
231
+ | `runtime/interactive/e2e.ts:1-15`, `interactiveTests` | Pages without JS in every language, playthroughs in the browser with state and polite live region; desktop and 360 px | ch.5 / bb-browser-playthroughs, if-interactive-tests | high | — |
232
+ | `runtime/explainer/tutor.ts:1-6`, `tutorpage.ts:1-21`, `position.ts`, `prompt.ts`, `explainer.ts:12-23` | Tutor handoff (start prompt, providers, clipboard, the tutor page per page with its Markdown, Zurück zum Tutor) built for the explainer only; tutor pages and the learner's lines as interface | ch.5 / bb-tutor-handoff, if-tutor-files | high | — |
233
+ | owner, 2026-10-16, review | No model in the browser; bb-tutor-in-browser removed | ch.5 | high | — (resolves OPEN: tutor variant) |
234
+ | `runtime/explainer/tasks.ts:1-7` | Task numbers built for the explainer only | ch.5 / bb-task-numbers | high | — |
235
+ | sketch §3 "Optional, for apps with tasks"; `runtime/explainer/components.ts:9-14`, `shared/examples.ts:1-5`; owner, 2026-10-16, review | Exercise contract: optional exports, describe(state, lang) for task and solution text (tutor, task numbers), examples of accepted and rejected answers checked at build; not built for interactive | ch.5 / bb-exercise-contract | high | — |
236
+ | owner, 2026-10-16, conversation | No settings dialog, less motion, sound or pause in scope now | ch.5 / bb-settings | high | — |
237
+ | brief, "Generic components to cover" | "time limit off" as an example setting | ch.5 / bb-settings | medium | — |
238
+ | `tooling archetypes/shared/preset.ts:1-25` | Preset: lint with lernapps rules, type check, format, tests, pre-commit, relative URLs | ch.5 / bb-preset, if-preset, bb-lint-rules | high | — |
239
+ | `ls tooling/lint/rules` | Eight lint rules (learner-text-german, no-request-before-click, storage-through-wrapper, suppression-reason, four vue-component rules) | ch.5 / bb-lint-rules | high | — |
240
+ | `ls tooling/check/rules`; `check/check.ts:1-4` | lernapps check rules incl. accessible, usable-at-360px, no-request-before-click, no-tracking, links-resolve, entry-links-resolve | ch.5 / bb-lernapps-check | high | — |
241
+ | sketch §4, §7 step 2; `grep arc42 tooling/check` (only comments) | `arc42 validate` in lernapps check planned, not built yet | ch.5 / bb-lernapps-check | medium | — |
242
+ | `tooling archetypes/shared/playwright.ts:1-6` | e2e against built app, Chromium desktop and 360 px | ch.5 / bb-playwright-config | high | — |
243
+ | `tooling archetypes/shared/storage.ts:1-16` | Only storage, localStorage under app prefix, try/catch | ch.5 / bb-small-storage, if-device-storage | high | — |
244
+ | owner, 2026-10-16, conversation; `grep -n quota storage.ts` (no match) | Quota 100 kB per app decided, not built yet | ch.5 / bb-small-storage | high | — |
245
+ | owner, 2026-10-16, review | IndexedDB left out; bb-large-storage removed | ch.5 | high | — |
246
+ | `ls tooling/skills` (no lernapps-interactive); `tooling/guidance` (plan-template.md, increment-template.md); `tooling/skills/lernapps-app/SKILL.md`; owner, 2026-10-16, review | Skill lernapps-interactive not built; the plan template and lernapps-app exist for every archetype, no other guidance for this archetype yet | ch.5 / bb-skill-interactive, if-skill-interactive | high | — |
247
+ | `src/core/index.ts:4`; `src/ui/App.vue:9` | Core imports src/data JSON; UI imports src/messages JSON for the translator | ch.5 / if-app-data, if-messages | high | — |
248
+ | `tooling archetypes/shared/a11y.ts:21,31,37` | announce, moveFocus, prefersReducedMotion | ch.5 / bb-a11y, if-a11y | high | — |
249
+ | `tooling archetypes/shared/i18n.ts:1-6` | translator over src/messages | ch.5 / bb-i18n, if-translator, bb-messages | high | — |
250
+ | `src/ui/App.vue:5-7` | UI imports announce and translator; props state, lang; emits input | ch.5 / bb-ui, if-root-component | high | — |
251
+ | `src/main.ts` | Glue calls startInteractive(core, App) | ch.5 / bb-main | high | — |
252
+ | `src/core/index.ts:1-4` | Core pure, imports data/lessons.json | ch.5 / bb-core, bb-data | high | — |
253
+ | `vite.config.ts`, `e2e/interactive.e2e.ts`, `.arc42ignore` | App bound by thin root files; root files excluded from arc42 claims | ch.5 / bb-app | high | — |
254
+ | `src/ui/App.vue`, grep storage in src/ (none) | Template app does not use the storage | ch.5 / if-device-storage | high | — |
255
+
256
+ ### Chapter 6
257
+
258
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
259
+ | --- | --- | --- | --- | --- |
260
+ | `runtime/interactive/render.ts:1-9`; `runtime/interactive/e2e.ts:7-11` | Start page static from app.yaml, no script, noscript note, link into app, route links, how to play, competencies, background | ch.6 / scenario-start-page | high | — |
261
+ | `runtime/shared/pages.ts:1-4`, `notFoundPage` | Language trees with plain-link switch and alternates; 404 leads to start page | ch.6 / scenario-start-page | high | — |
262
+ | `runtime/interactive/interactive.ts:9-15, 25-70` (`startInteractive`) | Seed from ?seed else random, route from hash else first; keys to step except controls and modifiers; changed state prevents default; emitted input stepped; tick every TICK ms; hashchange restarts core with same seed, marks aria-current | ch.6 / scenario-play | high | — |
263
+ | `src/main.ts`; `src/ui/App.vue:5-7` | Glue calls startInteractive; UI uses translator and announce | ch.6 / scenario-play | high | — |
264
+ | `runtime/interactive/contract.ts` `TICK = 20` | Clock period 20 ms | ch.6 / scenario-play | high | — |
265
+ | `tooling archetypes/shared/storage.ts:1-16` | load/save/remove under prefix; blocked or full storage: save false, app keeps working | ch.6 / scenario-device-storage | high | — |
266
+ | owner, 2026-10-16, conversation; `grep -n quota storage.ts` (no match) | Quota 100 kB decided, not built | ch.6 / scenario-device-storage | high | — |
267
+ | `grep -rn storage src/` (none) | Template app does not use the storage | ch.6 / scenario-device-storage | high | — |
268
+ | `runtime/interactive/plugin.ts:1-21` | Build order: validate, component rules, core in own Vite server, exports, routes start, playthroughs twice without tick, then pages, 404; one line per problem; vp dev renders per request | ch.6 / scenario-build | high | — |
269
+ | `vite.config.ts` | interactive() inside lernapps() preset | ch.6 / scenario-build | high | — |
270
+ | `runtime/interactive/e2e.ts:1-16, 56`; `tooling archetypes/shared/playwright.ts:1-7` | lernapps check --pre-push runs e2e on built app via vp preview on free port, Chromium desktop and 360 px, reduced motion; no-JS checks; playthroughs at app/?seed#route with state and polite live region; check adds axe and width | ch.6 / scenario-browser-playthroughs | high | — |
271
+ | `tooling archetypes/shared/hooks/pre-push`; `generator/app/.github/workflows/pages.yml:3-5` | pre-push hook and CI run lernapps check | ch.6 / scenario-browser-playthroughs | high | — |
272
+ | `runtime/explainer/prompt.ts:1-10`, `tutorpage.ts:1-21` | Explainer tutor: copy button, provider links, the tutor page per page, nothing before a click | ch.6 / scenario-tutor | high | — |
273
+ | owner, 2026-10-16, review | Tutor for interactive apps works as in the explainer, no model in the browser | ch.6 / scenario-tutor | high | — |
274
+
275
+ ### Chapter 7
276
+
277
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
278
+ | --- | --- | --- | --- | --- |
279
+ | `ORGANIZATION.md:46` | A repo x with Pages is served at lernapps.net/x/ | ch.7 / dn-github-pages | high | — |
280
+ | `tooling actions/app-publish/action.yml:3-5` | Publish to gh-pages branch served from root; only lernapps org repos at lernapps.net/<repo>/, others at <owner>.github.io/<repo>/ | ch.7 / dn-github-pages | high | — |
281
+ | `tooling generator/app/.github/workflows/pages.yml:3-18, 33-61` | Jobs app (lernapps check), deploy on main, preview on PRs from the repo at pr-preview/pr-<n>/, not indexed, removed on close; plan/docs-only changes publish nothing | ch.7 / env-ci, dn-ci-runner, dn-pr-preview | high | — |
282
+ | `tooling package.json` `appTemplates.archetypes` = explainer, quiz; `grep interactive generator/create.ts` (none) | Tooling has no interactive archetype yet, so no generated workflow for interactive apps | ch.7 / Deployment overview | high | — |
283
+ | owner, 2026-10-16, review | Interactive apps get the same Pages workflow (check, publish, preview) in step 2 of the plan | ch.7 / env-ci, dn-ci-runner, dn-github-pages, dn-pr-preview | high | — (resolves OPEN: same Pages workflow) |
284
+ | `app-templates .github/workflows/check.yml:1-12` | Template folders are checked by app-templates' CI with lernapps check | ch.7 / Deployment overview | high | — |
285
+ | `tooling archetypes/shared/hooks/pre-commit`, `pre-push`; `install-hooks.ts:1-4` | Pre-commit fast checks, pre-push heavy checks; hooks not installed in a folder inside another repo | ch.7 / dn-creator-machine | high | — |
286
+ | `runtime/interactive/plugin.ts:20-21` | vp dev serves the pages rendered per request | ch.7 / dn-creator-machine | high | — |
287
+ | `tooling archetypes/shared/preset.ts:9` | Build with relative URLs, works under any path | ch.7 / dn-github-pages | high | — |
288
+ | `runtime/interactive/interactive.ts:1-15`; `storage.ts:1-3` | Client module runs shell, core, UI in browser; localStorage under app prefix in shared origin | ch.7 / dn-learner-browser | high | — |
289
+ | `runtime/interactive/plugin.ts:13-17` | The core also runs at build in Node (core check, playthroughs) | ch.7 / dn-creator-machine, dn-ci-runner | high | — |
290
+
291
+ ### Chapter 8
292
+
293
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
294
+ | --- | --- | --- | --- | --- |
295
+ | `runtime/interactive/contract.ts:1-7, Core` | Core pure TS without DOM, state plain JSON; runtime keeps state; components only show it; runs in Node and browser | ch.8 / concept-core-and-shell | high | — |
296
+ | `contract.ts:1-3`; `interactive.ts:29-30`; `plugin.ts:13-17` | Deterministic by seed; seed from ?seed else random; build plays twice | ch.8 / concept-determinism | high | — |
297
+ | `contract.ts:5-7, PlaythroughStep`; `e2e.ts:12-15` | Playthrough = seed, route, steps of keys with state/announcement; build without ticks, browser same keys | ch.8 / concept-playthroughs | high | — |
298
+ | sketch §6; `grep -n -i "property" plugin.ts` (only an unrelated comment); owner, 2026-10-16, review | Core property tests over fixed seeds stay planned; time steps decided, not built | ch.8 / concept-playthroughs | high | — |
299
+ | `render.ts:1-9`; `e2e.ts:7-11` | Start page without script; app page noscript note with link back; plain links; e2e checks without JS per language | ch.8 / concept-readable-without-js | high | — |
300
+ | `pages.ts:1-4`; `load.ts:106`; `i18n.ts:1-6` | German at root, others below /<lang>/; only runtime-supported languages; texts via translator | ch.8 / concept-languages | high | — |
301
+ | `ORGANIZATION.md:57`; sketch §5; owner, 2026-10-16, conversation | WCAG 2.1 AA and 360 px default, limits declared in entry, warnings then | ch.8 / concept-accessibility | high | — |
302
+ | ch.2 con-accessibility-default (wave 1) | Warnings for declared limits not built yet | ch.8 / concept-accessibility | medium | — |
303
+ | `a11y.ts:21,31,37`; `interactive.ts:22,58`; `check/rules/accessible.ts`, `usable-at-360px.ts` | announce, moveFocus; keys on controls stay theirs; check runs axe and width | ch.8 / concept-accessibility | high | — |
304
+ | `plugin.ts:9-12`; `runtime/explainer/components.ts`; sketch §2 | Component rules on SFC output and lint rules; Vue fixed so they hold for every app | ch.8 / concept-component-rules | high | — |
305
+ | `storage.ts:1-3, 16-17`; owner, 2026-10-16, conversation | localStorage via wrapper, prefix lernapps:<app>:, wrapped access; quota 100 kB decided not built | ch.8 / concept-device-storage | high | — |
306
+ | `interactive.ts:31-34, 61-66`; `render.ts` route anchors; sketch §3 | Routes in app.yaml as app/#id, restart on new route; entry topics and entry-links-resolve | ch.8 / concept-hash-routes | high | — |
307
+ | owner, 2026-10-16, review | concept-size-budget removed | ch.8 | high | — (resolves OPEN: size budget scope) |
308
+ | `runtime/explainer/prompt.ts:1-8`; owner, 2026-10-16, review | Tutor optional, not built for interactive; handoff to the learner's own assistant after a click | ch.8 / concept-tutor | high | — |
309
+ | sketch §5; owner, 2026-10-16, conversation; owner, 2026-10-16, review; `ls tooling/skills` (no lernapps-interactive) | Low stimulation only advice of the skill lernapps-interactive (bb-skill-interactive implements it); skill not written yet; no settings now | ch.8 / concept-low-stimulation | high | — |
310
+
311
+ ### Chapter 9
312
+
313
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
314
+ | --- | --- | --- | --- | --- |
315
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:363-368` | Vue with TypeScript fixed so one set of component rules, lint rules and vue-tsc hold; decomposition, data, logic, rendering free | ch.9 / dec-vue-fixed | high | — |
316
+ | owner, 2026-10-16, conversation | Vue is fixed | ch.9 / dec-vue-fixed | high | — |
317
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:357-360` | One archetype, not one per kind; kinds become recipes in the skill; apps needing explanation pages are explainers | ch.9 / dec-one-archetype | high | — |
318
+ | `runtime/interactive/contract.ts:1-22`, `interactive.ts:36,67` | The runtime keeps the state; components only show it; tick(state, TICK) every TICK = 20 ms when the core has tick | ch.9 / dec-runtime-owns-state | high | — |
319
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:384-386` vs `contract.ts:15-18` | Sketch names start(seed), step(state, input), tick(state, dt); the runtime refined them to start(seed, route), step(state, key) and a fixed 20 ms tick | ch.9 / dec-runtime-owns-state, dec-keys-as-input, dec-start-seed-route | medium | refinements made by the runtime (commit c5e7285, 2026-10-16), not separately decided by the owner; status accepted because built and in force |
320
+ | `runtime/interactive/contract.ts:9-14`, `interactive.ts:50-59,69`, `interactive/src/ui/App.vue:12,38` | key = KeyboardEvent.key; ignored key keeps its default (Tab); pointer input as a key emitted as input by the root component | ch.9 / dec-keys-as-input | high | — |
321
+ | agent inference | Keys as input supports qg-accessibility (keyboard operation, Tab keeps focus movement) | ch.9 / dec-keys-as-input addresses | low | OPEN: confirm that dec-keys-as-input should address qg-accessibility |
322
+ | `runtime/interactive/interactive.ts:29-36,61-64`; `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:381` | Seed from ?seed=<n> else random; route of the address passed to start and on hashchange; routes so entry topics point somewhere | ch.9 / dec-start-seed-route | high | — |
323
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:388,423-424`; `runtime/interactive/plugin.ts:14-17`; `e2e.ts:12-15` | Playthroughs as data (keys, expected state/announcement), played twice by the build and with the keyboard in the browser | ch.9 / dec-playthroughs-as-data | high | — |
324
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:378-380`; owner, 2026-10-16, conversation; owner, 2026-10-16, review | localStorage through the wrapper, 100 kB quota per app, shared 5 MiB, save refuses beyond; IndexedDB left out; shared origin accepted | ch.9 / dec-small-storage | high | — |
325
+ | `tooling archetypes/shared/storage.ts:36-45` | save has no quota today | ch.9 / dec-small-storage | high | — |
326
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:412-420`; `dotgithub ORGANIZATION.md:57-58`; owner, 2026-10-16, conversation | WCAG 2.1 AA and 360 px platform rules, app default, deviations declared in the entry, warnings then; start page meets both; low stimulation advice only | ch.9 / dec-accessibility-default | high | — |
327
+ | owner, 2026-10-16, conversation | No settings dialog, less motion, sound or pause in scope now | ch.9 / dec-no-settings | high | — |
328
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:393-408` | arc42 in docs/arc42, English and minimal; frame from tooling, app adds own part; checked only by arc42 diff --staged --strict and arc42 validate; responsibilities not checked | ch.9 / dec-arc42-in-app | high | — |
329
+ | owner, 2026-10-16, review | Tutor as handoff to the learner's own assistant, accepted; a model in the browser rejected | ch.9 / dec-tutor-variant | high | — (resolves OPEN: tutor variant) |
330
+ | owner, 2026-10-16, review | Playthrough time steps accepted, not built | ch.9 / dec-playthroughs-as-data | high | — |
331
+ | owner, 2026-10-25, test on claude.ai with the preview of lernapps/mathe-karte#78 | claude.ai fetches only addresses written in a message of the learner, not those in a fetched file (absolute or relative), and fetches an address with a query, reading the position from it | explainer ch.9 / dec-tutor-page; ch.5 bb-tutor-handoff, if-tutor-files; ch.6 scenario-tutor | high | — (resolved 2026-10-26: no tutor file, task files or llms.txt; the tutor page is the one source) |
332
+ | `runtime/explainer/tutorpage.ts` (`tutorPage`), `result.ts`, `prompt.ts` (`startPrompt`), `position.ts` (`pageQuery`, `taskQuery`), `stuck.ts`, `explainer.ts` (`startTutor`, `startHelp`, `startChoice`, `startBackToTutor`) | One short tutor page per content page, the one source: its guide, every task number, a generated exercise as template and table of tasks; the assistant switched on once, way A with one address in a bar beside the title, way B "Hilfe" in every exercise (new chat or copied lines), the result line with the tutor page; prompts and lines in the learner's voice | explainer ch.9 / dec-tutor-page; ch.12 term-tutor-page, term-table-of-tasks, term-tutor-way, term-stuck-lines, term-result-line | high | — |
333
+ | owner, 2026-10-26, conversation; measured on lernapps/elektrizitaet and lernapps/mathe-karte (feat/explainer) | The tutor gets its values from the exercises alone, once: no doubled instructions; a generated exercise once as text with its inputs and outputs per number; components within the budget until #80 | explainer ch.9 / dec-tutor-page | high | — (risk-tutor-component-numbers resolved 2026-10-26 by dec-component-table) |
334
+ | `runtime/explainer/components/exercise.ts` (`exerciseProblems`), `tutorpage.ts` (`componentTable`, `tableHint`); owner, 2026-10-26, conversation (a hint for a component without its table, a warning later); measured on lernapps/mathe-karte (feat/explainer) with example declarations | An exercise component's table of tasks from template, params, mistakes and show, computed and checked against check for every number; a hint without it | explainer ch.9 / dec-component-table; ch.5 if-exercise-logic | high | — (owner, 2026-10-26: the apps' components are no risk of the template; risk-tutor-component-numbers removed) |
335
+
336
+ ### Chapter 10
337
+
338
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
339
+ | --- | --- | --- | --- | --- |
340
+ | owner, 2026-10-16, review | The four goals qg-privacy, qg-checkable, qg-accessibility, qg-understandable; qg-small dropped with qs-size-budget and qs-storage-quota | ch.10 / all quality goals | high | — |
341
+ | coordinator's proposal; owner, 2026-10-16, confirmed | Priorities high, high, medium, medium | ch.10 / all quality goals | high | — (resolved: confirmed by the owner, 2026-10-16) |
342
+ | `tooling check/rules/no-request-before-click.ts`; `check/visit.ts` | Requests to other hosts during page load are blocked, recorded, errors | ch.10 / qs-no-request-before-click | high | — |
343
+ | `tooling lint/rules/storage-through-wrapper.ts`, `vue-component-no-network.ts`; `archetypes/shared/storage.ts` prefix lernapps:<app>: | Direct storage, cookies and network calls reported; storage through createStorage under the app prefix | ch.10 / qs-state-on-device | high | — |
344
+ | `runtime/interactive/plugin.ts` lines 16, 145-152 | Playthroughs played twice; differing states fail the build | ch.10 / qs-deterministic-core | high | — |
345
+ | `runtime/interactive/e2e.ts` header | Playthroughs at app/?seed=<seed>#<route>, state and polite announcement after each step, no console error, desktop and 360 px, run by lernapps check --pre-push | ch.10 / qs-playthrough-in-browser | high | — |
346
+ | `tooling check/rules/accessible.ts` | axe-core WCAG 2.1 A and AA, severity error | ch.10 / qs-axe-clean | high | — |
347
+ | `tooling check/rules/usable-at-360px.ts` | No page wider than 360 px, severity error | ch.10 / qs-usable-at-360px | high | — |
348
+ | decided sketch step 12 section 5; con-accessibility-default | Warnings for apps with declared limits decided, not built | ch.10 / qs-axe-clean | high | — |
349
+ | decided sketch step 12 section 4 | arc42 diff --staged --strict before commit, ~0.2 s, unclaimed code and blocks without prose fail; not built for apps | ch.10 / qs-architecture-current | medium | OPEN: confirm not built yet for apps |
350
+
351
+ ### Chapter 11
352
+
353
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
354
+ | --- | --- | --- | --- | --- |
355
+ | `runtime/interactive/plugin.ts:17`; `contract.ts:28-38` (PlaythroughStep has only keys, state, announce) | Build never calls tick; playthroughs cannot express time | ch.11 / risk-time-not-replayed | high | — |
356
+ | `runtime/interactive/interactive.ts:67`; `e2e.ts:127-148`; `interactive/src/core/index.ts:89-94`; `src/data/lessons.json:2-3` | In the browser the clock runs between key presses; the template's core counts a letter as a miss after 5 s, so browser playthroughs depend on typing speed | ch.11 / risk-time-not-replayed | high | — |
357
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:436-437` | The pilot is the real-time typing game, which puts the most pressure on real time | ch.11 / risk-time-not-replayed | high | — |
358
+ | owner, 2026-10-16, review | Mitigation: a playthrough step that lets n ticks pass, in the build and in the browser; not built yet | ch.11 / risk-time-not-replayed | high | — (resolves OPEN: time step) |
359
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:416-417,431-435`; ch.2 con-accessibility-default | Entry field for limits and warnings planned, not built; accessible and usable-at-360px are errors for every app today | ch.11 / risk-accessibility-limits-not-built | high | — |
360
+ | `tooling archetypes/shared/storage.ts:36-45`; owner, 2026-10-16, conversation | Quota of 100 kB decided, wrapper has no limit | ch.11 / risk-storage-quota-not-built | high | — |
361
+ | `tooling archetypes/shared/storage.ts:1-3,15-17`; `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:378-379` | All apps share one origin and its 5 MiB localStorage; separation only by the prefix lernapps:<app>: from a name the app chooses | ch.11 / risk-shared-origin-storage | high | — |
362
+ | agent inference; owner, 2026-10-16, review | Clearing site data or browser eviction loses every app's values; a duplicate storage name collides; severity medium, accepted | ch.11 / risk-shared-origin-storage | high | — (resolves OPEN: severity and acceptance) |
363
+ | owner, 2026-10-16, review; ch.5 bb-tutor-handoff | Tutor decided as handoff, built only for the explainer | ch.11 / risk-tutor-not-built | high | — |
364
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:403-405,431-432`; ch.2 con-architecture-current | arc42 diff in pre-commit and arc42 validate in lernapps check planned, not wired | ch.11 / risk-arc42-checks-not-wired | medium | OPEN: confirm not built yet (from ch.2) |
365
+ | owner, 2026-10-16, review; `runtime/interactive/plugin.ts:21-22,41,217-230` | No size limit decided, but SIZE_BUDGET = 100 kB still fails the build; technical debt, to be removed | ch.11 / risk-size-budget-left | high | — |
366
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:423` vs `runtime/interactive/plugin.ts`; owner, 2026-10-16, review | Core property tests over fixed seeds stay planned, not built | ch.11 / risk-no-core-property-tests | high | — |
367
+ | agent inference | Severities and priority order of all risks | ch.11 / all risks | low | OPEN: confirm severities and order |
368
+
369
+ ### Chapter 12
370
+
371
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
372
+ | --- | --- | --- | --- | --- |
373
+ | `runtime/interactive/contract.ts:1-22` | Core: pure TypeScript, no DOM, deterministic by seed, plain JSON state, start/step/tick; TICK = 20 | ch.12 / term-core, term-tick | high | — |
374
+ | `runtime/interactive/interactive.ts:9-15,29-69` | Shell mounts root, holds state, routes keys, ticks, takes route and seed (positive integer, else random) | ch.12 / term-shell, term-seed, term-route | high | — |
375
+ | `lernapps/tooling .vibe/development-plan-agentic-app-creation.md:373`; ch.2 con-runtime-unchanged | Runtime interactive/ of app-templates, not changed by the app | ch.12 / term-runtime | high | — |
376
+ | `dotgithub ORGANIZATION.md:3,14,50-51` | Creators list apps; one entry per app in apps/entries/, schema-checked, the only link to an app; app overview provides the catalog; owner decides listing | ch.12 / term-creator, term-entry, term-catalog | high | — |
377
+ | `runtime/interactive/plugin.ts:18-20`; `e2e.ts:7-11` | Start page without script from app.yaml; app page loads the client module, noscript note links back | ch.12 / term-start-page, term-app-page | high | — |
378
+ | `runtime/interactive/contract.ts:5-7,26-38` | Playthrough: seed, route, steps of keys with expected state or announcement | ch.12 / term-playthrough | high | — |
379
+ | owner, 2026-10-16, review | Tutor: the learner's own assistant, handed the task after a click | ch.12 / term-tutor | high | — |
380
+
381
+ ## Owner, 2026-10-16, size per component
382
+
383
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
384
+ | --- | --- | --- | --- | --- |
385
+ | owner, 2026-10-16, conversation | The explainer keeps a fixed size per component; the figure (20 kB) is an implementation detail and stays out of the architecture | explainer ch.9 / dec-explainer-component-size; ch.11 / risk-size-budget-left | high | — |
386
+
387
+ ## Typed inputs, time steps, libraries, no size limit built (owner decisions, 2026-10-16)
388
+
389
+ | Source path:line, symbol, or command | Derived fact or relationship | Used in | Confidence | Open question / human decision |
390
+ | --- | --- | --- | --- | --- |
391
+ | `runtime/interactive/contract.ts` (`Input`, `KeyInput`, `ActionInput`, `Core.step(state, input)`, `PlaythroughStep` with `keys`, `inputs`, `ticks`, `CLOCK_PROPERTY`) | The core takes a typed input (key or action, extensible); a playthrough step has keys or inputs, then ticks; the tests' clock is the global `lernappsClock` | interactive bb-shell, if-core-contract, if-root-component, if-test-clock, bb-interactive-playthroughs, dec-typed-input, term-input, term-playthrough; risk-input-only-keys removed | high | — |
392
+ | `runtime/interactive/plugin.ts` (`play`), `runtime/interactive/e2e.ts` (`stepTicks`, `emitInput`) | The build calls tick n times per step; the browser presses keys, emits actions through the root component and steps ticks on the tests' clock | interactive bb-build, bb-e2e, scenario-interactive-build, concept-playthroughs, dec-playthroughs-as-data, qs-*, term-tick; risk-time-not-replayed removed | high | — |
393
+ | `runtime/interactive/plugin.ts` (no `SIZE_BUDGET`) | The interactive build limits no size | generic dec-no-size-limit; risk-size-budget-left removed | high | — |
394
+ | owner, 2026-10-16 (relayed by the coordinator); `runtime/explainer/components.ts` (`sourceScope`, `packages`) | An interactive app's components may import the libraries in the dependencies of its package.json; URL imports stay forbidden | interactive dec-libraries, bb-component-rules; generic con-component-rules, concept component rules | high | — |
395
+ | lernapps/tooling#90 merged | The skill lernapps-interactive exists | generic bb-skills, interactive building blocks intro; risk-interactive-skill-missing removed | high | — |
@@ -0,0 +1,3 @@
1
+ # Paths the architecture does not claim (arc42 H021), relative to this template folder.
2
+ # The example chapter of the template: content the creator replaces, part of bb-explainer-content.
3
+ src/prozent
@@ -0,0 +1,54 @@
1
+ # Archetype explainer
2
+
3
+ Chapters of pages that explain a topic, with exercises on every page. Every page is complete without JavaScript.
4
+
5
+ ## What it can do
6
+
7
+ - Text, formulas (also chemistry), drawn figures, your own images with source and licence, figures with numbered
8
+ labels, tables, timelines, definitions with a glossary, quotes, code, boxes for worked examples and hints.
9
+ - YouTube videos behind two clicks: before the click a link with title, channel and a note on privacy, nothing loaded
10
+ from YouTube or Google; "Video abspielen" loads the player from youtube-nocookie.com. The learner may choose to load
11
+ videos directly from then on. The catalog entry of an app with a video says `fitness.thirdParty: on-click`.
12
+ - Exercises of the six question types, with feedback, hints and typical mistakes; a question can show content (`material`: the figures, tables, quotes and code of the page's blocks) between its text and its answers.
13
+ - Generated exercises: each task draws new numbers or records, up to 67 numbered tasks per exercise, with typical
14
+ mistakes, a hint and the way to the solution. The build tests them over fixed seeds.
15
+ - Vue components for what no block can show or check, such as reading a scale, labelling a figure or dragging into
16
+ place; an exercise component draws its own tasks. A component needs its logic module, a test and a text for readers
17
+ without JavaScript. An exercise component also declares its exercise for the tutor (`template`, `params`,
18
+ `mistakes`, `show`), so that its tutor page has a table of every task like a generated one. The example is
19
+ `src/components/ProzentFeld` on the page `prozent/prozentwert`: colour p % of a field of G squares.
20
+ - Navigation, contents and glossary are generated, and for an AI tutor a short tutor page per page
21
+ (`<chapter>/<page>/tutor/`), the one source of what the tutor gets: its guide, the page's content and every task of
22
+ its exercises, a generated one and an exercise component as a table of inputs and outputs. The learner switches an assistant on once, on the
23
+ start page or beside the title of a page (one of the KI assistants the runtime offers), with
24
+ an account of their own. Then two ways lead there: a bar beside the title of each page, for a tutor who helps with
25
+ the page, and "Hilfe" ("Warum?" after a wrong answer) in every exercise, with the task, the input and the app's
26
+ message. "Zurück zum Tutor" copies the page's tutor page and how each task of the session went, for the learner to
27
+ paste into the chat.
28
+ - Optional: a self-assessment per chapter (`selfAssessment` in its `chapter.yaml`, at `<chapter>/einschaetzung/`);
29
+ the app's, at `einschaetzung/`, is every chapter's together. It shows exercises of the pages, best two to five on
30
+ each of its pages, without "Prüfen", and checks them all together: the result says per page whether the learner
31
+ probably knows it, should look at it again or should read it. The last result stays on the device; with a click the
32
+ learner takes it to the tutor, who then guides chapter by chapter: to the pages that do not stick, then into a new
33
+ round of the chapter's self-assessment, whose "Zurück zum Tutor" brings the result back into the chat.
34
+ An exercise component may be in it: it shows the task the run draws, without "Prüfen". The example chapter has
35
+ one, with the exercise component `prozentfeld`, offered on the start page.
36
+ - German, plus English: a page tree per language.
37
+
38
+ ## What it cannot do
39
+
40
+ - No own colours or layout: the look is the runtime's, calm like a worksheet. Dark mode follows the device.
41
+ - No timer, no game.
42
+ - At most two section levels in a page.
43
+ - An exercise component does not count as a page's required exercise: each page also needs a question or a generated
44
+ exercise.
45
+ - Stores nothing but the learner's choice of AI tutor, if they make it, the choice to load videos directly, and the
46
+ last result of each self-assessment they do.
47
+ - A self-assessment needs JavaScript (without it, it is not offered).
48
+ - No video from another platform than YouTube, no thumbnail, no own video files.
49
+
50
+ ## What the app supplies
51
+
52
+ - The content as YAML in `src/`: the app, a folder per chapter with its pages, data files and images
53
+ ([schema](../runtime/explainer/explainer.v1.schema.json)); Vue components in `src/components/` where
54
+ no block fits.
@@ -0,0 +1,5 @@
1
+ node_modules/
2
+ dist/
3
+ _site/
4
+ test-results/
5
+ playwright-report/
@@ -0,0 +1,35 @@
1
+ # System Scope and Context
2
+
3
+ The explainer's actor, besides the generic ones.
4
+
5
+ ## Learner's own AI assistant
6
+
7
+ The explainer's optional tutor is this assistant, which the learner brings and controls; no model runs in the
8
+ browser. After the learner's click, the app hands it the current task through the tutor prompt and the static tutor
9
+ files.
10
+
11
+ ```arc42
12
+ :::actor
13
+ id: actor-learner-assistant
14
+ title: Learner's own AI assistant
15
+ type: system
16
+ description: Receives the page's tutor page with the learner's task after the learner's click
17
+ requires: if-tutor-files
18
+ :::
19
+ ```
20
+
21
+ ## YouTube
22
+
23
+ A video block's player comes from YouTube's privacy-enhanced host, youtube-nocookie.com, and only after the
24
+ learner's click on "Video abspielen", or once they chose "Videos immer direkt laden" (`dec-explainer-video-two-click`).
25
+ Before that the page requests nothing from YouTube or Google; the video is a link to its page on youtube.com.
26
+
27
+ ```arc42
28
+ :::actor
29
+ id: actor-youtube
30
+ title: YouTube
31
+ type: system
32
+ description: Serves a video's player into the page, only after the learner's click or standing choice
33
+ requires: if-video-player
34
+ :::
35
+ ```