@the-inclusionist/engine 8.0.0-rc.1 → 8.0.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 (50) hide show
  1. package/app/public/vendor/fonts/playwrite-ar.woff2 +0 -0
  2. package/app/public/vendor/fonts/playwrite-br.woff2 +0 -0
  3. package/app/public/vendor/fonts/playwrite-ca.woff2 +0 -0
  4. package/app/public/vendor/fonts/playwrite-cl.woff2 +0 -0
  5. package/app/public/vendor/fonts/playwrite-co.woff2 +0 -0
  6. package/app/public/vendor/fonts/playwrite-mx.woff2 +0 -0
  7. package/app/public/vendor/fonts/playwrite-us-modern.woff2 +0 -0
  8. package/app/public/vendor/fonts/playwrite-us-trad.woff2 +0 -0
  9. package/app/public/vendor/fonts.css +21 -0
  10. package/dist-pkg/boot/create-game.d.ts +33 -4
  11. package/dist-pkg/boot/create-game.js +72 -11
  12. package/dist-pkg/core/contract.d.ts +60 -0
  13. package/dist-pkg/core/contract.js +42 -0
  14. package/dist-pkg/i18n/en.js +11 -0
  15. package/dist-pkg/i18n/es.js +11 -0
  16. package/dist-pkg/i18n/pt.js +14 -0
  17. package/dist-pkg/input/default-bindings.js +20 -12
  18. package/dist-pkg/input/gamepad.d.ts +15 -1
  19. package/dist-pkg/input/gamepad.js +30 -9
  20. package/dist-pkg/input/keyboard.d.ts +32 -0
  21. package/dist-pkg/input/keyboard.js +46 -6
  22. package/dist-pkg/input/keydown.d.ts +13 -0
  23. package/dist-pkg/input/keydown.js +9 -0
  24. package/dist-pkg/input/latch-edge.d.ts +28 -0
  25. package/dist-pkg/input/latch-edge.js +45 -0
  26. package/dist-pkg/input/latch-sync.d.ts +47 -0
  27. package/dist-pkg/input/latch-sync.js +43 -0
  28. package/dist-pkg/input/pad-defaults.d.ts +22 -0
  29. package/dist-pkg/input/pad-defaults.js +34 -0
  30. package/dist-pkg/input/touch-bindings.d.ts +10 -0
  31. package/dist-pkg/input/touch-bindings.js +6 -0
  32. package/dist-pkg/platform/pesados-catalogo.d.ts +14 -0
  33. package/dist-pkg/platform/pesados-catalogo.js +177 -0
  34. package/dist-pkg/platform/pesados.d.ts +31 -0
  35. package/dist-pkg/platform/pesados.js +75 -0
  36. package/dist-pkg/platform/voice-plan.d.ts +20 -1
  37. package/dist-pkg/platform/voice-plan.js +20 -1
  38. package/dist-pkg/platform/vozes-prontas.d.ts +28 -0
  39. package/dist-pkg/platform/vozes-prontas.js +61 -0
  40. package/dist-pkg/ui/fonts.d.ts +24 -0
  41. package/dist-pkg/ui/fonts.js +66 -1
  42. package/dist-pkg/ui/pause-icons.d.ts +36 -2
  43. package/dist-pkg/ui/pause-icons.js +9 -1
  44. package/dist-pkg/ui/settings-motor.d.ts +21 -1
  45. package/dist-pkg/ui/settings-motor.js +22 -4
  46. package/dist-pkg/ui/settings-typo.d.ts +18 -4
  47. package/dist-pkg/ui/settings-typo.js +16 -11
  48. package/docs/CREDITS.md +15 -12
  49. package/docs/LICENSES.md +170 -144
  50. package/package.json +2 -1
@@ -2,6 +2,7 @@
2
2
  import { toggleLabel } from './dom.js';
3
3
  import type { PlayerView } from '../core/entity.js';
4
4
  import type { DomQuery } from '../core/dom-query.js';
5
+ import { type JogadorDaAlternancia as JogadorDaAlternanciaDaAresta } from '../input/latch-sync.js';
5
6
  /** Minimal DOM-selector shape (matches ui/dom.ts's `$`). */
6
7
  export type { DomQuery } from '../core/dom-query.js';
7
8
  /** Minimal platform/storage.ts shape this module needs. */
@@ -26,6 +27,19 @@ export interface SettingsMotorCtx {
26
27
  getNumPlayers: () => number;
27
28
  /** SHARED setter (also used by the pause-menu quick icon `altmove`) — stays in game.js, injected. */
28
29
  setToggleMove?: (i: number, on: boolean) => void;
30
+ /**
31
+ * ESTE JOGO SEGURA ALGUMA TECLA? — `GameDeclaration.seguraTeclas` (ADR-0115). Sem ele a linha da
32
+ * alternância fica AUSENTE deste painel.
33
+ *
34
+ * ⚠️ E A ENGINE NÃO DESENHA ESTA LINHA — o markup do `#opt-altmove` é do CARTUCHO, e a engine só o
35
+ * encontra pelo `$`. Logo «não oferecer» aqui não é deixar de renderizar: é tornar a linha ausente para
36
+ * toda a gente, com `hidden`, que a tira da tela E da árvore de acessibilidade. Um `aria-disabled` seria a
37
+ * resposta errada — essa é a da cláusula 3 do ADR-0113, onde o controle EXISTE e está travado com motivo.
38
+ *
39
+ * ⚠️ OBRIGATÓRIO, pela mesma razão que no `PauseIconsCtx`: não há padrão seguro. `true` deixa a linha num
40
+ * jogo onde ela não faz nada; `false` esconde-a de uma criança que depende dela.
41
+ */
42
+ seguraTeclas: boolean;
29
43
  /**
30
44
  * QUAL APARELHO ESTE JOGADOR ESTÁ A USAR (ADR-0113) — atravessa daqui para a escrita.
31
45
  *
@@ -99,8 +113,14 @@ export declare function toggleMoveKey(i: number): string;
99
113
  * reduzido. Uma fatia mínima é o que deixa os dois passarem sem que nenhum tenha de carregar o do outro.
100
114
  * `MotorPlayer` e `PausePlayer` ganharam `walkDir` — quebra declarada, porque o campo é do `PlayerBase` e
101
115
  * todo jogador da engine já o tem.
116
+ *
117
+ * 📌 A DEFINIÇÃO MUDOU DE CASA (issue #127) e o NOME fica publicado aqui. Ela vive em `input/latch-sync`, ao
118
+ * lado da regra que a usa, porque a sincronização da aresta toca exactamente estes dois campos — duas cópias
119
+ * do mesmo tipo divergiriam no dia em que a regra ganhasse um terceiro. ⚠️ **Alias e não `export ... from`**:
120
+ * o retrato de nomes deixa re-exports de fora e leria a mudança de casa como remoção, que é a lição da etapa
121
+ * 1a do ADR-0106.
102
122
  */
103
- export type JogadorDaAlternancia = PlayerView<'toggleMove' | 'walkDir'>;
123
+ export type JogadorDaAlternancia = JogadorDaAlternanciaDaAresta;
104
124
  /** O que a escrita precisa de saber. Tudo o que está aqui já vive no `SettingsMotorCtx` e no `PauseIconsCtx`. */
105
125
  export interface EscritaDaAlternanciaCtx {
106
126
  readonly players: readonly JogadorDaAlternancia[];
@@ -22,6 +22,7 @@ import { DEFAULTS } from '../core/state.js';
22
22
  // faria o painel escrever num nome torto — que é o defeito que este import acaba de fechar.
23
23
  import { KEYS } from '../platform/storage.js';
24
24
  import { gravarAlternancia } from '../input/latch-store.js';
25
+ import { aplicarAlternancia, BASE_DA_MARCHA, } from '../input/latch-sync.js';
25
26
  import { recusaDaAlternancia } from './latch-refusal.js';
26
27
  // ---------------------------------------------------------------------------------------------
27
28
  // Pure logic (no `document`, testable in node)
@@ -67,7 +68,11 @@ export function definirAlternanciaDeMarcha(ctx, i, on) {
67
68
  const p = ctx.players[i];
68
69
  if (!p)
69
70
  return;
70
- p.toggleMove = on;
71
+ // 📌 A REGRA DE DESLIGAR MORA NUM SÍTIO SÓ desde a issue #127: `aplicarAlternancia` põe o valor E pára quem
72
+ // anda por travamento. Ela era duas linhas aqui, e passou a ser partilhada com a sincronização da aresta
73
+ // (`input/latch-sync`) — que resolve a MESMA pergunta ao trocar de aparelho. Duas cópias do «senão a
74
+ // personagem anda sozinha» divergiriam no dia em que uma delas mudasse.
75
+ aplicarAlternancia(p, on);
71
76
  // ⚠️ AS DUAS CHAVES, E A ANTIGA NÃO SAI AINDA — é a forma do `p.visual` ao lado do `p.viz` (#104 etapa 1a),
72
77
  // e pela mesma razão: quem LÊ ainda é o cartucho, por `KEYS.toggleMoveP(i)` (`main.ts:540`). Parar de a
73
78
  // escrever agora faria a criança perder a escolha no arranque seguinte — o defeito que o ADR-0113 nomeia
@@ -79,9 +84,9 @@ export function definirAlternanciaDeMarcha(ctx, i, on) {
79
84
  // a regra resolve, e é ela que responde `true` naqueles quatro.
80
85
  const transporte = ctx.transporteEmUso ? ctx.transporteEmUso(i) : null;
81
86
  if (transporte)
82
- gravarAlternancia((chave, ligada) => ctx.store.setBool(chave, ligada), 'togglemove', i, transporte, on);
83
- if (!on)
84
- p.walkDir = 0;
87
+ gravarAlternancia((chave, ligada) => ctx.store.setBool(chave, ligada), BASE_DA_MARCHA, i, transporte, on);
88
+ // 📌 O ANÚNCIO É INCONDICIONAL, ao contrário do `aplicarAlternancia`, que devolve «mudou». A criança
89
+ // carregou no ícone: calar-se porque o valor já era esse deixaria o botão sem resposta para quem ouve.
85
90
  ctx.srSay(playerPrefix(i, ctx.getNumPlayers()) + t(on ? 'sr.motor.toggleMoveOn' : 'sr.motor.toggleMoveOff'));
86
91
  }
87
92
  /** Clamps the selected player back to 0 once it falls outside 0..numPlayers-1 (e.g. player count dropped). */
@@ -137,6 +142,19 @@ export function initSettingsMotor(ctx) {
137
142
  const altMoveRow = altMoveBtn?.closest('.ctrl-row') ?? null;
138
143
  const altMoveHint = altMoveRow?.querySelector('.opt-hint') ?? null;
139
144
  const dicaOriginal = altMoveHint?.textContent ?? '';
145
+ /*
146
+ * ADR-0115 · A LINHA SOME NUM JOGO QUE NÃO SEGURA NADA — e some para TODA A GENTE.
147
+ *
148
+ * 🔴 `hidden` e não `aria-disabled`: a criança que depende da alternância abre este painel para a ligar, e
149
+ * num quiz não há nada para ela ligar. Um controle desabilitado com um motivo continua a ser um controle
150
+ * que não faz nada — e ainda ocupa um lugar na navegação por teclado, entre dois que funcionam.
151
+ * 📌 A cláusula 3 do ADR-0113 é o caso oposto e continua intacta: lá o aparelho EXIGE a alternância, o
152
+ * controle existe, e fica `aria-disabled` COM o motivo, alcançável para que ela possa lê-lo.
153
+ * ⚠️ E a linha é do CARTUCHO: a engine não a criou e por isso não a destrói. `hidden` é reversível e
154
+ * idempotente; remover markup alheio não é nenhuma das duas coisas.
155
+ */
156
+ if (!ctx.seguraTeclas && altMoveRow)
157
+ altMoveRow.hidden = true;
140
158
  /** A recusa DESTE jogador agora, ou `null`. Recalculada a cada reflexo: o aparelho em uso muda. */
141
159
  function recusaAgora(i) {
142
160
  return ctx.transporteEmUso ? recusaDaAlternancia(ctx.transporteEmUso(i)) : null;
@@ -29,6 +29,20 @@ export interface SettingsTypoCtx {
29
29
  * continua desenhando. O que ele não pode é desenhar prosa duplicada, e sem casca não há rodapé para duplicar.
30
30
  */
31
31
  fillExplain?: (card: HTMLElement | null) => void;
32
+ /**
33
+ * ESTA FAMÍLIA ESTÁ INSTALADA NO APARELHO? — em produção, `(f) => doc.fonts.check(\`16px "${f}"\`)`.
34
+ *
35
+ * É o que transforma o «enquanto» do ADR-0012 em código: a opção da Ronde fica desabilitada ENQUANTO
36
+ * nenhuma das três faces estiver presente, e volta a ficar disponível quando o adulto instalar uma.
37
+ *
38
+ * ⚠️ INJECTADO E NUNCA `document.fonts` LIDO AQUI, pela regra que este ficheiro já segue para o `$`: um
39
+ * global do navegador num módulo que corre em node é o ACHADO 15, e este projecto já pagou por ele com um
40
+ * boot rebentado.
41
+ * 📌 OPCIONAL, e aqui o padrão é mesmo seguro — ao contrário do `seguraTeclas` do `PauseIconsCtx`, onde os
42
+ * dois lados erravam. Sem detector a linha fica desabilitada COM a mensagem, e a mensagem diz ao adulto as
43
+ * três fontes que resolvem. O estado por omissão é o de hoje, e é accionável.
44
+ */
45
+ fonteInstalada?: (familia: string) => boolean;
32
46
  }
33
47
  export interface SettingsTypoApi {
34
48
  /** Re-renders #typo-list from current selection and (re)wires its buttons. Idempotent. */
@@ -47,7 +61,7 @@ export interface SettingsTypoApi {
47
61
  * `resolveFontKey` de uma chave guardada, um `data-font` num markup de consumidor. «Não está na lista» e «não
48
62
  * pode ser escolhida» têm de ser a mesma afirmação, ou a lista é só uma sugestão.
49
63
  */
50
- export declare function isSelectableFont(k: string): boolean;
64
+ export declare function isSelectableFont(k: string, instalada?: (familia: string) => boolean): boolean;
51
65
  export { resolveFontKey, persistFontKey } from './fonts.js';
52
66
  import type { DomQuery } from '../core/dom-query.js';
53
67
  export interface FontCssTarget {
@@ -84,9 +98,9 @@ export interface TypoGroupView {
84
98
  * três faces estiver instalada, porque duas delas são gratuitas apenas para uso pessoal e não podem ser
85
99
  * empacotadas.
86
100
  */
87
- export declare function linhaDaFonte(it: FontItem, fontKey: string): TypoRow;
101
+ export declare function linhaDaFonte(it: FontItem, fontKey: string, instalada?: (familia: string) => boolean): TypoRow;
88
102
  /** Pure view-model for the typography list: which row is selected/disabled and its note, per catalog group. */
89
- export declare function typoGroups(fontKey: string): TypoGroupView[];
103
+ export declare function typoGroups(fontKey: string, instalada?: (familia: string) => boolean): TypoGroupView[];
90
104
  /**
91
105
  * Full innerHTML for #typo-list, given the currently selected key. Pure string building — no DOM.
92
106
  *
@@ -100,5 +114,5 @@ export declare function typoGroups(fontKey: string): TypoGroupView[];
100
114
  * A TOGGLE […] One font is active; the others are alternatives, not switches.» O `switch` do
101
115
  * `style.css:427` desenha uma chave de 52×28 px com bolinha — era o desenho de um estado que não existe.
102
116
  */
103
- export declare function typoListHTML(fontKey: string): string;
117
+ export declare function typoListHTML(fontKey: string, instalada?: (familia: string) => boolean): string;
104
118
  export declare function initSettingsTypo(ctx: SettingsTypoCtx): SettingsTypoApi;
@@ -8,7 +8,7 @@
8
8
  // (FONT_GROUPS/FONT_BY_KEY) stays in ./fonts.js (Phase 2 extraction) — imported here, never duplicated.
9
9
  // (`toggleLabel` saiu daqui em 2026-09-07: ele devolve «Ligado»/«Desligado», e este menu é uma ESCOLHA.)
10
10
  import { t } from '../core/i18n.js';
11
- import { FONT_GROUPS, FONT_BY_KEY, DEFAULT_FONT_KEY, papelDaFonte } from './fonts.js';
11
+ import { FONT_GROUPS, FONT_BY_KEY, DEFAULT_FONT_KEY, papelDaFonte, faceDisponivel } from './fonts.js';
12
12
  import { markChanged, markMenuChanged, CHANGED_CLASS } from './changed-mark.js';
13
13
  // ---------------------------------------------------------------------------------------------
14
14
  // Pure logic (no `document`, testable in node)
@@ -22,9 +22,9 @@ import { markChanged, markMenuChanged, CHANGED_CLASS } from './changed-mark.js';
22
22
  * `resolveFontKey` de uma chave guardada, um `data-font` num markup de consumidor. «Não está na lista» e «não
23
23
  * pode ser escolhida» têm de ser a mesma afirmação, ou a lista é só uma sugestão.
24
24
  */
25
- export function isSelectableFont(k) {
25
+ export function isSelectableFont(k, instalada) {
26
26
  const it = FONT_BY_KEY[k];
27
- return !!it && !it.off && papelDaFonte(it) === 'geral';
27
+ return !!it && faceDisponivel(it, instalada) && papelDaFonte(it) === 'geral';
28
28
  }
29
29
  // A semantica da chave (validacao + migracao da chave antiga) mora em ui/fonts.ts, que e o dono do
30
30
  // catalogo; re-exportada aqui para quem ja consome este modulo. Uma implementacao, nao duas.
@@ -55,8 +55,11 @@ export function fontCssTarget(k, it) {
55
55
  * três faces estiver instalada, porque duas delas são gratuitas apenas para uso pessoal e não podem ser
56
56
  * empacotadas.
57
57
  */
58
- export function linhaDaFonte(it, fontKey) {
59
- const disabled = !!it.off;
58
+ export function linhaDaFonte(it, fontKey, instalada) {
59
+ // ⚠️ A MESMA pergunta que o `isSelectableFont` faz, pela MESMA função. Duas respostas dariam uma linha
60
+ // clicável que o clique recusa — ou, pior, uma linha cinzenta que o `resolveFontKey` aceita por outro
61
+ // caminho. «Não está disponível» e «não pode ser escolhida» têm de ser a mesma afirmação.
62
+ const disabled = !faceDisponivel(it, instalada);
60
63
  // `d` e `off` também guardam CHAVE. O travessão que junta os dois é pontuação, não frase — as duas
61
64
  // metades são independentes e cada uma traduz por si.
62
65
  const desc = it.d ? t(it.d) : '', motivo = it.off ? t(it.off) : '';
@@ -64,7 +67,7 @@ export function linhaDaFonte(it, fontKey) {
64
67
  return { key: it.k, fam: it.fam, selected: fontKey === it.k, disabled, note };
65
68
  }
66
69
  /** Pure view-model for the typography list: which row is selected/disabled and its note, per catalog group. */
67
- export function typoGroups(fontKey) {
70
+ export function typoGroups(fontKey, instalada) {
68
71
  // ⚠️ SÓ AS GERAIS ENTRAM NA LISTA (emenda do ADR-0012, issue #87). As caligráficas existem para a criança
69
72
  // APRENDER a ler letra cursiva — isso é matéria, e vive DENTRO das atividades, em botões próprios. Oferecê-
70
73
  // las aqui é dar-lhe a matéria como obstáculo em todo lugar onde ela só quer navegar o menu.
@@ -72,7 +75,7 @@ export function typoGroups(fontKey) {
72
75
  // Um grupo que fique sem nenhuma face geral desaparece da lista, em vez de aparecer como título vazio.
73
76
  return FONT_GROUPS.map((g) => ({
74
77
  g: t(g.g), // `g` guarda CHAVE i18n desde o item 14 (ver ui/fonts)
75
- rows: g.items.filter((it) => papelDaFonte(it) === 'geral').map((it) => linhaDaFonte(it, fontKey)),
78
+ rows: g.items.filter((it) => papelDaFonte(it) === 'geral').map((it) => linhaDaFonte(it, fontKey, instalada)),
76
79
  })).filter((grupo) => grupo.rows.length > 0);
77
80
  }
78
81
  /**
@@ -108,8 +111,8 @@ function rowHTML(row) {
108
111
  * A TOGGLE […] One font is active; the others are alternatives, not switches.» O `switch` do
109
112
  * `style.css:427` desenha uma chave de 52×28 px com bolinha — era o desenho de um estado que não existe.
110
113
  */
111
- export function typoListHTML(fontKey) {
112
- const grupos = typoGroups(fontKey)
114
+ export function typoListHTML(fontKey, instalada) {
115
+ const grupos = typoGroups(fontKey, instalada)
113
116
  .map((group) => `<h3 class="panel-sub">${group.g}</h3>` + group.rows.map(rowHTML).join(''))
114
117
  .join('');
115
118
  return `<div role="radiogroup" aria-label="${t('font.grupo.rotulo')}">${grupos}</div>`;
@@ -121,7 +124,9 @@ export function initSettingsTypo(ctx) {
121
124
  let fontKey = resolveFontKey(ctx.store);
122
125
  function setFont(k, announce = false) {
123
126
  const it = FONT_BY_KEY[k];
124
- if (!it || it.off)
127
+ // A MESMA função das outras duas leituras: uma face que a lista mostra clicável tem de ser aceite aqui,
128
+ // e uma que ela mostra cinzenta tem de ser recusada. Três respostas à mesma pergunta divergem.
129
+ if (!it || !faceDisponivel(it, ctx.fonteInstalada))
125
130
  return;
126
131
  fontKey = k;
127
132
  persistFontKey(ctx.store, k);
@@ -141,7 +146,7 @@ export function initSettingsTypo(ctx) {
141
146
  const el = ctx.$('#typo-list');
142
147
  if (!el)
143
148
  return;
144
- el.innerHTML = typoListHTML(fontKey);
149
+ el.innerHTML = typoListHTML(fontKey, ctx.fonteInstalada);
145
150
  el.querySelectorAll('button[data-font]').forEach((b) => {
146
151
  b.addEventListener('click', () => {
147
152
  const k = b.dataset.font;
package/docs/CREDITS.md CHANGED
@@ -61,22 +61,25 @@ A narração por voz roda **inteiramente no navegador/offline** graças ao traba
61
61
  `es_MX` (ADR-0065, que supersede o ADR-0022).
62
62
 
63
63
  > Os pesos das vozes são **baixados uma vez** (de um host público) e rodam **100% localmente** depois — nenhum áudio de
64
- > criança sai do dispositivo. Ver `docs/2-Architecture/adr/ADR-0065-three-neural-voices-owned-by-the-engine-and-cached-on-first-use.yaml`.
64
+ > criança sai do dispositivo. Ver `the-inclusionist-docs · docs/2-Architecture/adr/ADR-0065-three-neural-voices-owned-by-the-engine-and-cached-on-first-use.yaml`.
65
65
 
66
- ## Arte — Liberated Pixel Cup — CC BY-SA 3.0
66
+ ## Arte importada — CC0, CC BY 3.0, CC BY 4.0 ou OGA-BY
67
67
 
68
- A atribuição do [Liberated Pixel Cup](https://github.com/OpenGameArt/LiberatedPixelCup) é **por recurso**, e por
69
- isso não cabe nesta página em prosa: o repositório do LCP guarda ficheiros de autoria separados para originais e
70
- derivados, e a cadeia lê-se recurso a recurso.
68
+ A atribuição da arte que vem de fora é **por recurso**, e por isso não cabe nesta página em prosa: a autoria de um
69
+ acervo lê-se recurso a recurso, e a cadeia de derivações com ela.
71
70
 
72
- **Ela mora em [`../art/lcp/ATTRIBUTION.csv`](../art/lcp/ATTRIBUTION.csv)** — caminho, autor, fonte, licença e de que
73
- recursos cada um derivou. É a mesma forma que o `LICENSES.md` §4 já usa para as 100 gerações do PixelLab: um
71
+ **Ela mora em [`../art/ATTRIBUTION.csv`](../art/ATTRIBUTION.csv)** — caminho, autor, **URL da fonte**, licença e de
72
+ que recursos cada um derivou. É a mesma forma que o `LICENSES.md` §4 já usa para as 100 gerações do PixelLab: um
74
73
  ficheiro tabular ao lado do apontador em prosa, porque um livro-razão que cresce com o catálogo não se mantém à mão.
75
74
 
76
- ⚠️ **Atribuição aqui é condição de uso, não linha de crédito.** Os dois braços da licença exigem-na, e um recurso
75
+ ⚠️ **Atribuição aqui é condição de uso, não linha de crédito.** Três das quatro licenças exigem-na, e um recurso
77
76
  sem autor conhecido **não entra** — «não consegui descobrir» não é licença. O gate
78
- `tests/lcp-quarantine.node.test.js` reprova a entrada vazia, a entrada órfã e o recurso sem entrada, e a árvore
79
- está em **quarentena** por uma razão que o [`LICENSES.md`](LICENSES.md) §3 e o **ADR-0107** explicam: misturar o LCP
80
- com a arte própria licenciaria em share-alike a obra de alguém que não está neste repositório para discordar.
77
+ `tests/arte-licencas-aceites.node.test.js` reprova a entrada vazia, a entrada órfã, o recurso sem entrada, a fonte
78
+ sem URL e **qualquer licença fora das quatro** — com ND, NC e share-alike recusados por nome e com o motivo de
79
+ cada um, que o [`LICENSES.md`](LICENSES.md) §3 e o **ADR-0133** explicam.
81
80
 
82
- **Hoje o livro está vazio** — o LCP foi decidido em 2026-09-08 e ainda não entrou.
81
+ 📌 **Não há quarentena, e já houve.** Até 2026-09-09 o Liberated Pixel Cup ia entrar sob CC BY-SA 3.0 atrás de uma
82
+ parede (ADR-0107). O Dev recusou o share-alike e a parede saiu com ele: sem arte cujo copyleft viaje, não há o que
83
+ segregar.
84
+
85
+ **Hoje o livro está vazio** — nenhum recurso entrou nunca.
package/docs/LICENSES.md CHANGED
@@ -1,144 +1,170 @@
1
- # O que governa o quê
2
-
3
- Este projeto tem **duas licenças e um terceiro regime**, e confundi-los seria afirmar direito que não se
4
- tem. Este ficheiro diz apenas **qual regra alcança qual coisa**. As atribuições estão em
5
- [`CREDITS.md`](CREDITS.md); as razões, nos registros citados em cada linha.
6
-
7
- | o quê | regime | onde se decide |
8
- |---|---|---|
9
- | **Código** | **AGPL-3.0-or-later** | ADR-0064 · texto integral em [`../LICENSE`](../LICENSE) |
10
- | **Arte própria** | **NÃO é FOSS** — direito autoral do autor, uso restrito | ADR-0010 pilar 10 · `research/LICENCAS-GERACAO-IMAGEM.md` |
11
- | **Conteúdo de terceiros** | a licença que o autor escolheu, preservada | requerimento, pedido `g` |
12
-
13
- ---
14
-
15
- ## 1 · O código é AGPL-3.0-or-later
16
-
17
- Todo programa deste repositório. O `-or-later` é deliberado.
18
-
19
- **Por que AGPL e não GPL:** a GPL obriga quem **conveia**, e rodar serviço não é conveiar — a seção 0 da
20
- própria GPL separa `propagate` de `convey`. Um fornecedor que pegasse este código, melhorasse e hospedasse
21
- a sala de aula como serviço **não deveria a fonte a ninguém**. A seção 13 da AGPL fecha exatamente isso, e é
22
- o argumento que o requerimento faz ao Município na alínea `e`. Ver **ADR-0064**.
23
-
24
- ⚠️ **Titularidade patrimonial: o MUNICÍPIO, não o desenvolvedor.** Software produzido no exercício das
25
- funções pertence ao empregador (Lei nº 9.609/1998, art. 4º), e é por isso que a publicação sob AGPL é
26
- objeto de **pedido** no requerimento — ato do Poder Executivo — e não decisão de quem escreveu o código.
27
-
28
- ⚠️ **E é AQUI que essa titularidade fica dita, não no nome do pacote.** O escopo era `@pm-monte` para
29
- carregar esse fato (ADR-0036); passou a ser **`@the-inclusionist`** (**ADR-0071**), porque nome é lido por
30
- quem não vai abrir o repositório, e um escopo com o nome da Prefeitura publicado por servidor **antes do
31
- ato** é reivindicação pública de nome alheio. A regra é a mesma do **ADR-0066 §2**: a posse se declara
32
- DENTRO — neste ficheiro, na `LICENSE` e nos registros —, onde lê quem pretende usar.
33
-
34
- ## 2 · A arte NÃO é AGPL, e isso é decisão, não omissão
35
-
36
- Programa é o que a **Lei nº 9.609/1998** define. **Arte segue a Lei nº 9.610/1998** e pertence a quem a fez.
37
- Estender a AGPL à arte daria mais do que a lei pede **e** disporia de direito alheio.
38
-
39
- ⚠️ **E há uma razão de produto, não só jurídica:** o requisito é que os personagens **não** sejam de uso
40
- livre — não aparecerem em produto adulto, por exemplo. Isso é **incompatível com FOSS por construção**:
41
- licença livre não pode restringir campo de uso (liberdade 0; critério 6 da OSI, "sem discriminação de área
42
- de atuação"). Não existe arte simultaneamente livre e de uso restrito. A escolha foi feita com o
43
- trade-off escrito: **código FOSS + arte não-FOSS**.
44
-
45
- **A proteção é uma pilha de três, do mais forte ao mais fraco** (`research/LICENCAS-GERACAO-IMAGEM.md`):
46
-
47
- 1. **Marca registrada** dos personagens — nome e design-assinatura. É o esteio, porque barra uso que cause
48
- confusão ou diluição **independentemente de copyright**. Seletiva: nem todo personagem é registrado.
49
- 2. **Licença de arte própria**, não-FOSS, sobre os dados de arte e os algoritmos de composição.
50
- 3. **Autoria humana no algoritmo procedural** — quanto mais o humano cria, seleciona e modifica (em vez de
51
- apenas pedir a um gerador), mais forte o copyright, e mais exequível a licença (2).
52
-
53
- ⚠️ **E a ressalva que ordena a pilha:** arte derivada de IA **pode ser incopyrightável** — o US Copyright
54
- Office já o disse —, o que pode tornar a licença (2) **inexequível sozinha**. Por isso a marca é
55
- indispensável, e não um reforço opcional. Escrito aqui porque é o ponto em que a proteção falha em
56
- silêncio se ninguém souber.
57
-
58
- ## 3 · Conteúdo de terceiros mantém a licença de quem o fez
59
-
60
- Nem tudo aqui é nosso, e o que não é **não muda de licença por estar neste repositório**. É o que o pedido
61
- `g` do requerimento pede que conste dos autos: a relação nominal desses elementos e de suas licenças.
62
-
63
- - **Código de terceiros** — Clarity (MIT), sherpa-onnx (Apache-2.0), Piper (MIT), eSpeak NG (GPL-3.0).
64
- Detalhe e atribuição em [`CREDITS.md`](CREDITS.md).
65
- - **Vozes** — licença por voz, no `MODEL_CARD` de cada pacote. **A confirmar por voz antes de distribuição
66
- formal** — está assim no `CREDITS.md` e continua verdade.
67
- - **Pictogramas** — a camada é decidida pela **LICENÇA e por mais nada** (**ADR-0028**): Mulberry,
68
- Blissymbolics e Tawasol sob CC BY-SA são embutíveis; ARASAAC é **baixado, nunca redistribuído**; Sclera,
69
- PCS, SymbolStix e Widgit aparecem no menu como **indisponíveis, aguardando negociação**.
70
- ⚠️ E o **SA** alcança o que nós alterarmos: um pictograma reajustado à paleta de alto contraste
71
- (ADR-0011) ou à grade de pixels continua CC BY-SA.
72
- - **Tipografias** — roster e restrições no **ADR-0012**. ⚠️ Ronde e as alternativas OPTIFrench-Script e
73
- Merveille são **gratuitas só para uso pessoal e NÃO podem ser empacotadas**: oferece-se download, e a
74
- opção fica desabilitada quando nenhuma está presente.
75
- - **Arte de terceiros — o Liberated Pixel Cup** (`github.com/OpenGameArt/LiberatedPixelCup`), sob
76
- **CC BY-SA 3.0** (**ADR-0107**). O conjunto é duplamente licenciado — CC BY-SA 3.0 **ou** GPL-3.0 — e o
77
- projeto toma o braço **CC BY-SA**, para que arte continue governada como arte e não seja puxada para a
78
- licença do CÓDIGO; é a mesma separação de regimes que este ficheiro tem em três linhas.
79
- ⚠️ **E ele vive em QUARENTENA, o que é mecanismo e não arrumação.** Nenhum recurso pode conter ao mesmo
80
- tempo material derivado do LCP e a **arte própria** da autora: o SA alcança o que nós alterarmos — como já
81
- está escrito acima para os pictogramas — e misturar os dois licenciaria a arte DELA em share-alike, que é
82
- precisamente a decisão que o **pilar 10** deixa com ela e não connosco. O CC BY-SA 3.0 também é
83
- **incompatível com a família GPL**, então a mesma quarentena é o que mantém o regime do código limpo.
84
- ⚠️ **Atribuição é condição de uso, por recurso**: o repositório do LCP guarda ficheiros de autoria
85
- separados para originais e derivados. Recurso sem autor conhecido **não entra** — «não consegui descobrir»
86
- não é licença.
87
-
88
- ---
89
-
90
- ## 4 · Inventário da arte — por enquanto, só a do PixelLab
91
-
92
- O ADR-0066 §3 põe este inventário entre as condições para qualquer repositório virar público, e o §2 desta
93
- página dizia que ele ainda não existia. Existe agora, **com o alcance que o Dev deu: apenas a arte gerada
94
- no PixelLab.**
95
-
96
- ### O que foi gerado, e onde está registrado
97
-
98
- **100 gerações**, de 2026-06-01 em diante, com data, ferramenta, custo estimado e **o prompt de cada uma**:
99
- [`research/auditoria-creditos-pixellab.csv`](research/auditoria-creditos-pixellab.csv). O prompt está lá de
100
- propósito — é o que permite a alguém de fora refazer a pergunta *"de onde veio esta imagem?"* sem depender da
101
- memória de ninguém.
102
-
103
- ### O regime, e a restrição que viaja junto
104
-
105
- Conforme a pesquisa de licenças (`research/LICENCAS-GERACAO-IMAGEM.md`), o PixelLab.ai é o gerador com os
106
- termos mais limpos do levantamento: **a titularidade da imagem é de quem gerou**, o uso comercial é
107
- permitido — *"usar, modificar e distribuir … para qualquer fim"* —, e **não há exigência de atribuição**.
108
-
109
- ⚠️ **E há UMA restrição, que não é nossa e por isso não podemos dispensá-la: as imagens não podem ser usadas
110
- para TREINAR MODELO.** Isso importa aqui por dois motivos concretos:
111
-
112
- 1. A arte deste projeto **não é FOSS** (§2), então a licença de arte própria é nossa para escrever — e ela
113
- tem de **carregar esta restrição adiante**, ou concederíamos a terceiros mais do que recebemos.
114
- 2. O alvo declarado é **arte procedural semântica** (`plano-arte-procedural.md`): imagem semântica + paletas.
115
- Se algum dia essa geração passar por um modelo treinado nos próprios assets, esta linha é a que diz que
116
- não pode.
117
-
118
- ### O que este inventário NÃO cobre, e por quê
119
-
120
- **ARTE PRÓPRIA NÃO EXISTE.** Não é que esteja fora do inventário — não há nenhuma para inventariar, e é por
121
- isso que esta seção cobre só o PixelLab.
122
-
123
- O Dev passa a produzi-la **depois de o Município aceitar o arranjo inteiro**: o código sob **AGPL-3.0** e a
124
- arte sob **licença CC adequada**. Enquanto essa aceitação não estiver documentada, não há arte própria e
125
- não há o que licenciar.
126
-
127
- ⚠️ **E arte não vai para AGPL — vai para CC.** A AGPL é licença de PROGRAMA (Lei 9.609); arte é obra da Lei
128
- 9.610 e o instrumento usual dela é o Creative Commons. Está escrito aqui porque a versão anterior deste
129
- parágrafo levantava, como se fosse dúvida em aberto, a hipótese de a arte própria virar AGPL. Não era
130
- dúvida: era erro, sobre uma coisa que ainda não existe.
131
-
132
- **Qual CC** é escolha para quando houver arte a licenciar, e não antes. O §2 desta página fica de pé como
133
- está: ele descreve o regime da arte que EXISTE hoje.
134
-
135
- ---
136
-
137
- ## O que este ficheiro NÃO faz
138
-
139
- - **Não é parecer jurídico.** É a declaração de escopo que um leitor precisa para não assumir que a AGPL da
140
- raiz alcança tudo. Onde há dúvida de propriedade intelectual, a fonte é a Procuradoria — que o requerimento
141
- aciona no pedido `c`.
142
- - **Não substitui o `CREDITS.md`**, que é onde mora a atribuição. Fato duplicado apodrece.
143
- - **Não lista a arte própria peça a peça** — e agora isso é ALCANCE e não omissão: o §4 inventaria a
144
- arte do PixelLab e diz, na mesma seção, por que a arte própria ainda não entrou.
1
+ # O que governa o quê
2
+
3
+ Este projeto tem **duas licenças e um terceiro regime**, e confundi-los seria afirmar direito que não se
4
+ tem. Este ficheiro diz apenas **qual regra alcança qual coisa**. As atribuições estão em
5
+ [`CREDITS.md`](CREDITS.md); as razões, nos registros citados em cada linha.
6
+
7
+ | o quê | regime | onde se decide |
8
+ |---|---|---|
9
+ | **Código** | **AGPL-3.0-or-later** | ADR-0064 · texto integral em [`../LICENSE`](../LICENSE) |
10
+ | **Arte própria** | **NÃO é FOSS** — direito autoral do autor, uso restrito | ADR-0010 pilar 10 · `research/LICENCAS-GERACAO-IMAGEM.md` |
11
+ | **Conteúdo de terceiros** | a licença que o autor escolheu, preservada | requerimento, pedido `g` |
12
+
13
+ ---
14
+
15
+ ## 1 · O código é AGPL-3.0-or-later
16
+
17
+ Todo programa deste repositório. O `-or-later` é deliberado.
18
+
19
+ **Por que AGPL e não GPL:** a GPL obriga quem **conveia**, e rodar serviço não é conveiar — a seção 0 da
20
+ própria GPL separa `propagate` de `convey`. Um fornecedor que pegasse este código, melhorasse e hospedasse
21
+ a sala de aula como serviço **não deveria a fonte a ninguém**. A seção 13 da AGPL fecha exatamente isso, e é
22
+ o argumento que o requerimento faz ao Município na alínea `e`. Ver **ADR-0064**.
23
+
24
+ ⚠️ **Titularidade patrimonial: o MUNICÍPIO, não o desenvolvedor.** Software produzido no exercício das
25
+ funções pertence ao empregador (Lei nº 9.609/1998, art. 4º), e é por isso que a publicação sob AGPL é
26
+ objeto de **pedido** no requerimento — ato do Poder Executivo — e não decisão de quem escreveu o código.
27
+
28
+ ⚠️ **E é AQUI que essa titularidade fica dita, não no nome do pacote.** O escopo era `@pm-monte` para
29
+ carregar esse fato (ADR-0036); passou a ser **`@the-inclusionist`** (**ADR-0071**), porque nome é lido por
30
+ quem não vai abrir o repositório, e um escopo com o nome da Prefeitura publicado por servidor **antes do
31
+ ato** é reivindicação pública de nome alheio. A regra é a mesma do **ADR-0066 §2**: a posse se declara
32
+ DENTRO — neste ficheiro, na `LICENSE` e nos registros —, onde lê quem pretende usar.
33
+
34
+ ## 2 · A arte NÃO é AGPL, e isso é decisão, não omissão
35
+
36
+ Programa é o que a **Lei nº 9.609/1998** define. **Arte segue a Lei nº 9.610/1998** e pertence a quem a fez.
37
+ Estender a AGPL à arte daria mais do que a lei pede **e** disporia de direito alheio.
38
+
39
+ ⚠️ **E há uma razão de produto, não só jurídica:** o requisito é que os personagens **não** sejam de uso
40
+ livre — não aparecerem em produto adulto, por exemplo. Isso é **incompatível com FOSS por construção**:
41
+ licença livre não pode restringir campo de uso (liberdade 0; critério 6 da OSI, "sem discriminação de área
42
+ de atuação"). Não existe arte simultaneamente livre e de uso restrito. A escolha foi feita com o
43
+ trade-off escrito: **código FOSS + arte não-FOSS**.
44
+
45
+ **A proteção é uma pilha de três, do mais forte ao mais fraco** (`research/LICENCAS-GERACAO-IMAGEM.md`):
46
+
47
+ 1. **Marca registrada** dos personagens — nome e design-assinatura. É o esteio, porque barra uso que cause
48
+ confusão ou diluição **independentemente de copyright**. Seletiva: nem todo personagem é registrado.
49
+ 2. **Licença de arte própria**, não-FOSS, sobre os dados de arte e os algoritmos de composição.
50
+ 3. **Autoria humana no algoritmo procedural** — quanto mais o humano cria, seleciona e modifica (em vez de
51
+ apenas pedir a um gerador), mais forte o copyright, e mais exequível a licença (2).
52
+
53
+ ⚠️ **E a ressalva que ordena a pilha:** arte derivada de IA **pode ser incopyrightável** — o US Copyright
54
+ Office já o disse —, o que pode tornar a licença (2) **inexequível sozinha**. Por isso a marca é
55
+ indispensável, e não um reforço opcional. Escrito aqui porque é o ponto em que a proteção falha em
56
+ silêncio se ninguém souber.
57
+
58
+ ## 3 · Conteúdo de terceiros mantém a licença de quem o fez
59
+
60
+ Nem tudo aqui é nosso, e o que não é **não muda de licença por estar neste repositório**. É o que o pedido
61
+ `g` do requerimento pede que conste dos autos: a relação nominal desses elementos e de suas licenças.
62
+
63
+ - **Código de terceiros** — Clarity (MIT), sherpa-onnx (Apache-2.0), Piper (MIT), eSpeak NG (GPL-3.0).
64
+ Detalhe e atribuição em [`CREDITS.md`](CREDITS.md).
65
+ - **Vozes** — licença por voz, no `MODEL_CARD` de cada pacote. **A confirmar por voz antes de distribuição
66
+ formal** — está assim no `CREDITS.md` e continua verdade.
67
+ - **Pictogramas** — a camada é decidida pela **LICENÇA e por mais nada** (**ADR-0028**): Mulberry,
68
+ Blissymbolics e Tawasol sob CC BY-SA são embutíveis; ARASAAC é **baixado, nunca redistribuído**; Sclera,
69
+ PCS, SymbolStix e Widgit aparecem no menu como **indisponíveis, aguardando negociação**.
70
+ ⚠️ E o **SA** alcança o que nós alterarmos: um pictograma reajustado à paleta de alto contraste
71
+ (ADR-0011) ou à grade de pixels continua CC BY-SA.
72
+ - **Tipografias** — roster e restrições no **ADR-0012**. ⚠️ Ronde e as alternativas OPTIFrench-Script e
73
+ Merveille são **gratuitas só para uso pessoal e NÃO podem ser empacotadas**: oferece-se download, e a
74
+ opção fica desabilitada quando nenhuma está presente.
75
+ - **Arte de terceiros — TRÊS PORTAS, e o que decide é compatibilidade com o projeto** (**ADR-0133**), não a
76
+ família a que um nome pertence. Quatro perguntas: podemos **derivar**? pode ser usada **comercialmente**?
77
+ podemos **conveiar** o ficheiro no que publicamos? alguma coisa **viaja** da fonte para a nossa saída?
78
+ - **Porta `licenca`** — uma licença pública já medida: **CC0 1.0**, **CC BY 3.0/4.0**, **OGA-BY 3.0/4.0**,
79
+ e as permissivas de software (**MIT**, **Apache-2.0**) quando a arte carrega uma. ⚠️ A OGA-BY **não é
80
+ Creative Commons** — a própria CC declara que não a endossa — e é a CC BY *menos* a restrição sobre
81
+ medidas técnicas, logo estritamente mais permissiva. 📌 Um nome novo não é recusado: é **referido**, e
82
+ entra assim que um registo responder as quatro perguntas para ele.
83
+ - **Porta `concessao`** — o autor escreveu a permissão, sem nome de licença conhecido. A linha do livro
84
+ guarda a **URL onde a concessão está escrita**, porque uma permissão que ninguém consegue abrir é
85
+ memória e não permissão.
86
+ - **Porta `ponte`** — copyleft **CC BY-SA** entra convertido em **`GPL-3.0-only`** na nossa saída. O
87
+ mecanismo é público e tem três degraus: a CC BY-SA 3.0 §4(b)(ii) deixa uma **adaptação** sair como 4.0;
88
+ a Creative Commons declarou a GPLv3 compatível num sentido só em 08/10/2015; e o **§13 da GPLv3** permite
89
+ combinar obra GPLv3 com obra AGPLv3 num único trabalho. ⚠️ Exige **fonte modificável** — a imagem
90
+ semântica mais o dicionário de paletas —, é de **sentido único e permanente**, e só abre para
91
+ **adaptação**: nenhum ficheiro CC BY-SA entra tal e qual.
92
+ 🔴 **E essa fonte modificável AINDA NÃO EXISTE.** A versão anterior desta linha dizia «o que este projeto
93
+ já mantém», e era falsa: não há `app/js/art/`, não há formato semântico e não há editor. **Enquanto não
94
+ houver, esta porta está descrita e não está aberta** — o LPC não entra. Ver `game-design/plano-arte-procedural.md`.
95
+ 🔴 **E o que não tem porta nenhuma: ND** (proíbe derivar, e recolorir já é derivar) e **NC** (deixaria a
96
+ arte mais estreita que o CÓDIGO — a AGPL permite uso comercial, e quem ela convida seria travado por um
97
+ sprite; e a fronteira do NC é indefinida, com uma implantação municipal em cima dela).
98
+ 📌 **Não há quarentena, e já houve.** O ADR-0107 punha o Liberated Pixel Cup atrás de uma parede; a ponte
99
+ substitui-a, porque a arte que a atravessa **deixa de ser share-alike do nosso lado** em vez de ficar
100
+ murada do resto.
101
+ - **Arte de terceiros — as fontes admitidas** (decisão do Dev, 2026-09-09; detalhe em
102
+ [`../art/README.md`](../art/README.md)). Entram **antes de qualquer arte do próprio projeto**:
103
+ **Kenney** (`kenney.nl/assets`, CC0 1.0, confirmado em três lugares) · **ansimuz** (`ansimuz.itch.io`,
104
+ CC0 1.0 **por pacote** — o perfil não concede nada) · **Tiny Swords** (`pixelfrog-assets.itch.io`), que
105
+ entra **pelas duas portas**: o ficheiro `TS_old version_CC0 Licensed` é CC0, e o **pacote atual** entra
106
+ pela **concessão** do autor, cujos termos permitem uso pessoal e comercial e modificação à vontade sem
107
+ exigir crédito · e o **Liberated Pixel Cup** (`OpenGameArt/LiberatedPixelCup`), pela **ponte**, como
108
+ adaptação sob `GPL-3.0-only`.
109
+ **Quais recursos entram, e para que jogos, é direção de arte** e não se decide aqui.
110
+ ⚠️ **Atribuição é condição de uso, por recurso**, e a **fonte guarda-se como URL**: uma licença declarada
111
+ por quem nos entrega o ficheiro é indício, não autoridade, e sem a origem registada não há contra o que a
112
+ conferir. Recurso sem autor conhecido **não entra** — «não consegui descobrir» não é licença.
113
+
114
+ ---
115
+
116
+ ## 4 · Inventário da arte — por enquanto, só a do PixelLab
117
+
118
+ O ADR-0066 §3 põe este inventário entre as condições para qualquer repositório virar público, e o §2 desta
119
+ página dizia que ele ainda não existia. Existe agora, **com o alcance que o Dev deu: apenas a arte gerada
120
+ no PixelLab.**
121
+
122
+ ### O que foi gerado, e onde está registrado
123
+
124
+ **100 gerações**, de 2026-06-01 em diante, com data, ferramenta, custo estimado e **o prompt de cada uma**:
125
+ [`research/auditoria-creditos-pixellab.csv`](research/auditoria-creditos-pixellab.csv). O prompt está lá de
126
+ propósito — é o que permite a alguém de fora refazer a pergunta *"de onde veio esta imagem?"* sem depender da
127
+ memória de ninguém.
128
+
129
+ ### O regime, e a restrição que viaja junto
130
+
131
+ Conforme a pesquisa de licenças (`research/LICENCAS-GERACAO-IMAGEM.md`), o PixelLab.ai é o gerador com os
132
+ termos mais limpos do levantamento: **a titularidade da imagem é de quem gerou**, o uso comercial é
133
+ permitido — *"usar, modificar e distribuir … para qualquer fim"* —, e **não há exigência de atribuição**.
134
+
135
+ ⚠️ **E há UMA restrição, que não é nossa e por isso não podemos dispensá-la: as imagens não podem ser usadas
136
+ para TREINAR MODELO.** Isso importa aqui por dois motivos concretos:
137
+
138
+ 1. A arte deste projeto **não é FOSS** (§2), então a licença de arte própria é nossa para escrever — e ela
139
+ tem de **carregar esta restrição adiante**, ou concederíamos a terceiros mais do que recebemos.
140
+ 2. O alvo declarado é **arte procedural semântica** (`plano-arte-procedural.md`): imagem semântica + paletas.
141
+ Se algum dia essa geração passar por um modelo treinado nos próprios assets, esta linha é a que diz que
142
+ não pode.
143
+
144
+ ### O que este inventário NÃO cobre, e por quê
145
+
146
+ **ARTE PRÓPRIA NÃO EXISTE.** Não é que esteja fora do inventário — não há nenhuma para inventariar, e é por
147
+ isso que esta seção cobre só o PixelLab.
148
+
149
+ O Dev passa a produzi-la **depois de o Município aceitar o arranjo inteiro**: o código sob **AGPL-3.0** e a
150
+ arte sob **licença CC adequada**. Enquanto essa aceitação não estiver documentada, não há arte própria e
151
+ não há o que licenciar.
152
+
153
+ ⚠️ **E arte não vai para AGPL — vai para CC.** A AGPL é licença de PROGRAMA (Lei 9.609); arte é obra da Lei
154
+ 9.610 e o instrumento usual dela é o Creative Commons. Está escrito aqui porque a versão anterior deste
155
+ parágrafo levantava, como se fosse dúvida em aberto, a hipótese de a arte própria virar AGPL. Não era
156
+ dúvida: era erro, sobre uma coisa que ainda não existe.
157
+
158
+ **Qual CC** é escolha para quando houver arte a licenciar, e não antes. O §2 desta página fica de pé como
159
+ está: ele descreve o regime da arte que EXISTE hoje.
160
+
161
+ ---
162
+
163
+ ## O que este ficheiro NÃO faz
164
+
165
+ - **Não é parecer jurídico.** É a declaração de escopo que um leitor precisa para não assumir que a AGPL da
166
+ raiz alcança tudo. Onde há dúvida de propriedade intelectual, a fonte é a Procuradoria — que o requerimento
167
+ aciona no pedido `c`.
168
+ - **Não substitui o `CREDITS.md`**, que é onde mora a atribuição. Fato duplicado apodrece.
169
+ - **Não lista a arte própria peça a peça** — e agora isso é ALCANCE e não omissão: o §4 inventaria a
170
+ arte do PixelLab e diz, na mesma seção, por que a arte própria ainda não entrou.