diff --git a/discussion/index.ndjson b/discussion/index.ndjson index fd1c724a..5ada6974 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,4 +1,4 @@ -{"type":"meta","next_id":{"DSC":47,"AGD":50,"DEC":42,"PLN":173,"LSN":55,"CLSN":1}} +{"type":"meta","next_id":{"DSC":47,"AGD":50,"DEC":42,"PLN":173,"LSN":56,"CLSN":1}} {"type":"discussion","id":"DSC-0044","status":"done","ticket":"hub-suspended-game-kill-affordance","title":"Hub Suspended Game Kill Affordance","created_at":"2026-07-05","updated_at":"2026-07-05","tags":["hub","lifecycle","game","ui"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0054","file":"discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]} {"type":"discussion","id":"DSC-0043","status":"done","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-05","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0053","file":"discussion/lessons/DSC-0043-system-os-cartridge-switch-orchestrator/LSN-0053-game-switching-is-lifecycle-replacement-not-loader-work.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]} {"type":"discussion","id":"DSC-0039","status":"abandoned","ticket":"render-pipeline-family-and-future-3d","title":"Render Pipeline Family and Future 3D","created_at":"2026-06-04","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","architecture","pipeline"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-render-pipeline-family-and-future-3d.md","status":"abandoned","created_at":"2026-06-04","updated_at":"2026-06-04","_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."} @@ -44,4 +44,4 @@ {"type":"discussion","id":"DSC-0033","status":"done","ticket":"system-os-service-ownership-and-module-layout","title":"Agenda - SystemOS Service Ownership and Module Layout","created_at":"2026-05-14","updated_at":"2026-05-15","tags":["runtime","os","services","module-layout","vm","window-manager","logging"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0042","file":"discussion/lessons/DSC-0033-system-os-service-ownership-and-module-layout/LSN-0042-systemos-service-ownership-boundary.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} {"type":"discussion","id":"DSC-0036","status":"done","ticket":"prometeu-hub-ui-direction","title":"Agenda - Prometeu Hub UI Direction","created_at":"2026-05-15","updated_at":"2026-05-22","tags":["hub","ui","shell","system-apps","lifecycle","design-system"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0045","file":"discussion/lessons/DSC-0036-prometeu-hub-ui-direction/LSN-0045-hub-ui-slices-should-prove-os-boundaries.md","status":"done","created_at":"2026-05-22","updated_at":"2026-05-22"}]} {"type":"discussion","id":"DSC-0037","status":"done","ticket":"rgba8888-framebuffer-and-pixel-format-direction","title":"Agenda - RGBA8888 Framebuffer and Pixel Format Direction","created_at":"2026-05-22","updated_at":"2026-05-23","tags":["gfx","framebuffer","rgb565","rgba8888","renderer","assets","host","backend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0046","file":"discussion/lessons/DSC-0037-rgba8888-framebuffer-and-pixel-format-direction/LSN-0046-pixel-format-contracts-must-move-as-one-surface.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23"}]} -{"type":"discussion","id":"DSC-0046","status":"in_progress","ticket":"runtime-owned-variable-glyph-bank-palette-protocol","title":"Runtime-Owned Variable Glyph Bank Palette Protocol","created_at":"2026-07-14","updated_at":"2026-07-14","tags":["runtime","gfx","assets","glyph-bank","palette-serialization","protocol"],"agendas":[{"id":"AGD-0049","file":"AGD-0049-runtime-owned-variable-glyph-bank-palette-protocol.md","status":"accepted","created_at":"2026-07-14","updated_at":"2026-07-14"}],"decisions":[{"id":"DEC-0041","file":"DEC-0041-variable-glyph-bank-palette-protocol.md","status":"accepted","created_at":"2026-07-14","updated_at":"2026-07-14","ref_agenda":"AGD-0049"}],"plans":[{"id":"PLN-0167","file":"PLN-0167-spec-contract-update-for-variable-glyph-palettes.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0168","file":"PLN-0168-glyphbank-variable-palette-resident-model.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0169","file":"PLN-0169-asset-decode-validation-for-variable-glyph-palettes.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0170","file":"PLN-0170-composer-palette-reference-failure-semantics.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0171","file":"PLN-0171-variable-glyph-palette-tests-fixtures-and-residue-scan.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0172","file":"PLN-0172-runtime-spec-handoff-to-packer-and-studio.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0046","status":"done","ticket":"runtime-owned-variable-glyph-bank-palette-protocol","title":"Runtime-Owned Variable Glyph Bank Palette Protocol","created_at":"2026-07-14","updated_at":"2026-07-14","tags":["runtime","gfx","assets","glyph-bank","palette-serialization","protocol"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0055","file":"discussion/lessons/DSC-0046-runtime-owned-variable-glyph-bank-palette-protocol/LSN-0055-runtime-owned-asset-protocols-must-align-payload-residency-and-lookup.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14"}]} diff --git a/discussion/lessons/DSC-0046-runtime-owned-variable-glyph-bank-palette-protocol/LSN-0055-runtime-owned-asset-protocols-must-align-payload-residency-and-lookup.md b/discussion/lessons/DSC-0046-runtime-owned-variable-glyph-bank-palette-protocol/LSN-0055-runtime-owned-asset-protocols-must-align-payload-residency-and-lookup.md new file mode 100644 index 00000000..57708be9 --- /dev/null +++ b/discussion/lessons/DSC-0046-runtime-owned-variable-glyph-bank-palette-protocol/LSN-0055-runtime-owned-asset-protocols-must-align-payload-residency-and-lookup.md @@ -0,0 +1,97 @@ +--- +id: LSN-0055 +ticket: runtime-owned-variable-glyph-bank-palette-protocol +title: Runtime-Owned Asset Protocols Must Align Payload, Residency, and Lookup +created: 2026-07-14 +tags: [runtime, assets, glyph-bank, palette-serialization, protocol] +decision: DEC-0041 +--- + +## Context + +The runtime changed the `GLYPH/indexed_v1` glyph-bank palette contract from a +fixed 64-palette payload and resident table to variable palette serialization +and variable resident palette storage. + +The initiating pressure came from packer/studio: fixed RGBA8888 palette padding +made small glyph banks pay for `64 * 16 * 4` palette bytes even when they used +far fewer palettes. The important architectural point was that the runtime, not +the packer, had to decide the protocol. The packer can only emit payloads that +conform to the runtime contract once the runtime spec is published. + +## Key Decisions + +### Variable Glyph Bank Palette Protocol + +**What:** +`palette_count` became the number of serialized palettes and the number of +resident palettes in the loaded `GlyphBank`. The valid range is `1..=64`. +`palette_id` remains a direct palette identity and is valid only when +`palette_id < palette_count` for the referenced resident bank. + +**Why:** +Keeping serialized count variable while retaining a fixed 64-slot resident +table would preserve two meanings for palette capacity. The runtime would save +payload bytes but still carry a split contract between payload shape, resident +shape, and lookup validity. Making all three agree gives the runtime one +source of truth. + +**Trade-offs:** +Palette validity is now bank-dependent. Scene and sprite composition must check +the referenced loaded bank instead of relying on a global `0..63` rule. This +adds validation work, but it prevents invalid references from silently becoming +transparent or default colors. + +## Patterns and Algorithms + +Let the runtime own runtime-facing asset protocols. Tooling can discover pain, +but the runtime spec must define effective metadata, payload shape, resident +shape, and failure semantics. + +Make count fields material. A count such as `palette_count` should not describe +only what the producer authored or only what the payload happens to include. If +runtime lookup depends on it, the count must also define resident state and +validation boundaries. + +Keep identity direct unless a real remapping problem exists. Sparse-to-dense +palette remapping was rejected because it would add a second identity layer +across scenes, sprites, packer output, and runtime lookup. V1 keeps palette id +`N` as palette slot `N` in the resident bank. + +Separate transparent color from invalid lookup. RGBA alpha is valid color data. +An invalid palette reference must be observable as invalid; it must not be +collapsed into `Color::TRANSPARENT`. + +Use residue scans after protocol migrations. Search for fixed byte formulas, +old constants, fixture helpers, and spec phrases. Legitimate hits should be +renamed as maximum-bound concepts, not left as accidental active contracts. + +## Pitfalls + +Partially variable specs are worse than fixed specs. The asset spec already had +variable size formulas in some places but still required `palette_count = 64` +elsewhere. That contradiction made it unclear which rule was canonical. + +Resident data structures can preserve obsolete protocol assumptions after the +payload changes. A fixed array in `GlyphBank` would have kept the old model +alive even if decode accepted variable payloads. + +Fallback rendering hides contract errors. Returning transparent for an invalid +palette id makes bad assets and bad scene references look like intentional +alpha, which is exactly the wrong failure mode for a runtime protocol. + +Fixture generators are part of the contract surface. Stress cartridges and +test payload builders must express whether they are using a variable count or +the v1 maximum; otherwise they reintroduce fixed-padding assumptions. + +## Takeaways + +- Runtime-facing asset protocols should align payload size, resident memory, + and lookup validity. +- `palette_count` is effective runtime metadata, not producer commentary. +- Direct identity is simpler than remapping until a concrete remapping need + exists. +- Invalid palette references should fail explicitly; transparent remains a + valid RGBA color, not an error substitute. +- Protocol migrations need spec edits, code changes, fixture updates, and + residue scans in the same workflow. diff --git a/discussion/workflow/agendas/AGD-0049-runtime-owned-variable-glyph-bank-palette-protocol.md b/discussion/workflow/agendas/AGD-0049-runtime-owned-variable-glyph-bank-palette-protocol.md deleted file mode 100644 index 3b87a324..00000000 --- a/discussion/workflow/agendas/AGD-0049-runtime-owned-variable-glyph-bank-palette-protocol.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -id: AGD-0049 -ticket: runtime-owned-variable-glyph-bank-palette-protocol -title: Runtime-Owned Variable Glyph Bank Palette Protocol -status: accepted -created: 2026-07-14 -resolved: 2026-07-14 -decision: -tags: - - runtime - - gfx - - assets - - glyph-bank - - palette-serialization - - protocol ---- - -## Contexto - -A agenda `../studio/discussion/workflow/agendas/AGD-0005-variable-tile-bank-palette-serialization.md` -levantou o desperdicio do payload atual de `GLYPH/indexed_v1`: todo glyph bank -carrega `64 * 16 * 4 = 4096` bytes de paletas RGBA8888, mesmo quando o asset -usa poucas paletas. - -Esse problema toca o `packer`, mas a decisao do protocolo pertence ao -`runtime`. A especificacao final deve ser definida aqui, no contrato runtime, -e o `packer` deve seguir a spec quando ela estiver pronta. A agenda de `studio` -serve como entrada factual e motivacao, nao como autoridade normativa sobre o -payload, a memoria residente ou a semantica de `palette_id`. - -Estado atual no runtime: - -- `docs/specs/runtime/15-asset-management.md` documenta `palette_count = 64`; -- `docs/specs/runtime/04-gfx-peripheral.md` documenta `palette_id` em `0..63`; -- `crates/console/prometeu-hal/src/glyph_bank.rs` materializa paletas como - `[[Color; 16]; 64]`; -- `crates/console/prometeu-drivers/src/asset.rs` rejeita metadata cujo - `palette_count` nao seja `64`; -- o decode de glyph bank le um bloco fixo de `64 * 16 * 4` bytes em - `assets.pa`; -- testes de asset e VM ainda calculam payload e decoded size com o bloco fixo. - -Decisoes anteriores relevantes: - -- `DSC-0022` estabeleceu `GlyphBank` como nome canonico do artefato grafico; -- `DSC-0037` estabeleceu RGBA8888 como contrato runtime, com alpha como dado de - cor e sem indice magico reservado. - -## Problema - -O runtime precisa decidir se `GLYPH/indexed_v1` continua sendo um contrato de -64 paletas fixas ou se passa a aceitar uma quantidade variavel de paletas -serializadas. - -Essa decisao nao e apenas uma otimizacao de tamanho de cartucho. Ela muda: - -- o significado de `palette_count`; -- a validacao de `palette_id`; -- a formula de `size` e `decoded_size`; -- a representacao residente de `GlyphBank`; -- o comportamento quando uma cena referencia uma paleta nao carregada; -- a fronteira entre contrato de asset, HAL, composer, testes e tooling. - -## Pontos Criticos - -- Autoridade: o runtime decide o protocolo publicado; o `packer` segue. -- Compatibilidade: o projeto ainda esta em v1, entao nao ha obrigacao - presumida de preservar o padding fixo antigo. -- Identidade: `palette_id` pode continuar sendo uma identidade direta ou pode - virar indice em uma tabela compactada, mas nao pode ter dois significados. -- Materializacao: economizar bytes no payload nao implica automaticamente - economizar memoria residente, mas manter uma tabela fixa pode preservar - semantica simples para renderizacao e cenas. -- Falhas: se `palette_id` apontar para uma paleta ausente, o runtime precisa - definir se isso falha no load, na composicao, ou se resolve para cor default. -- Propagacao: qualquer decisao precisa mover specs, decode, HAL, fixtures e - testes juntos, como ocorreu na migracao RGBA8888. - -## Opcoes - -### Opcao A - Manter 64 paletas fixas no protocolo runtime - -- **Abordagem:** Preservar `palette_count = 64`, bloco fixo de 4096 bytes e - tabela residente fixa. -- **Pro:** Mantem decode, composicao e limites de `palette_id` simples. -- **Contra:** O runtime continua publicando um custo obrigatorio de payload que - nao representa a maioria dos assets. -- **Manutencao:** Boa para estabilidade local, fraca para alinhamento entre - metadata autoral e payload real. - -### Opcao B - Payload variavel, memoria residente fixa de 64 slots - -- **Abordagem:** Fazer `palette_count` representar o numero de paletas - serializadas, mas expandir para uma tabela residente fixa de 64 paletas no - load. Paletas nao serializadas ficam em valor default, e `palette_id` continua - sendo identidade direta `0..63`. -- **Pro:** Reduz payload mantendo o contrato de composicao e cena simples. -- **Contra:** Requer decidir se referencias a paletas nao serializadas sao - invalidas no load, invalidas na composicao ou simplesmente resolvem para a - paleta default. -- **Manutencao:** Boa se a spec declarar que `palette_count` mede somente o - prefixo serializado e que o runtime ainda materializa capacidade fixa. - -### Opcao C - Payload variavel e memoria residente variavel - -- **Abordagem:** Fazer `palette_count` controlar tanto o payload quanto a - quantidade residente de paletas. `palette_id >= palette_count` passa a ser - invalido para aquele glyph bank. -- **Pro:** O contrato fica mais fiel ao asset carregado e reduz memoria - residente por banco. -- **Contra:** A composicao precisa carregar limite por banco e transformar - validacao de `palette_id` em regra dependente do asset. -- **Manutencao:** Forte se o runtime quiser que o banco carregado seja a unica - fonte de verdade; mais invasiva no HAL/composer. - -### Opcao D - Paletas compactadas com remapeamento de identidade - -- **Abordagem:** Serializar somente paletas usadas em uma tabela densa e - introduzir um mapa entre identidade autoral/esparsa e indice residente. -- **Pro:** Pode minimizar payload mesmo quando indices autorais sao esparsos. -- **Contra:** Introduz um segundo contrato de identidade e exige metadata extra - ou reescrita de cenas/assets dependentes. -- **Manutencao:** Fraca para v1 unless haja uma necessidade clara de preservar - indices esparsos sem preencher lacunas. - -## Sugestao / Recomendacao - -Adotar a **Opcao C**. - -`palette_count` deve ser o contrato real do glyph bank carregado: se o payload -serializa `N` paletas, o runtime materializa `N` paletas e `palette_id >= N` -e invalido para aquele banco. - -A **Opcao B** fica descartada porque manter memoria residente fixa preservaria -uma segunda nocao de capacidade que nao corresponde ao asset carregado. A -**Opcao D** tambem fica descartada porque introduzir remapeamento de identidade -transformaria um protocolo simples em uma camada adicional de metadata. - -## Perguntas em Aberto - -- [x] `palette_count` deve definir tambem a quantidade residente de paletas, ou - apenas o prefixo serializado no payload? - - Resolucao: define tambem a quantidade residente. -- [x] `palette_id` deve ser validado contra `palette_count` por glyph bank ou - continuar limitado globalmente a `0..63`? - - Resolucao: validar contra `palette_count` por glyph bank, mantendo um - limite maximo global separado. -- [x] Quando uma cena referencia uma paleta ausente, o erro deve ocorrer no - load do glyph bank, no load/decode da scene, ou na composicao? - - Resolucao: o glyph bank carrega se o proprio payload e valido. A referencia - ausente falha quando uma scene/sprite tenta usar `palette_id >= - palette_count` contra o banco real; o runtime deve tratar isso como erro - explicito, nao como fallback silencioso para transparente/default. -- [x] O limite maximo de paletas por glyph bank continua sendo `64` em v1? - - Resolucao: sim. A variabilidade deve reduzir `N`, nao abrir uma - quantidade ilimitada de paletas em v1. -- [x] `decoded_size` deve contar apenas paletas materializadas ou manter alguma - nocao de capacidade residente? - - Resolucao: contar apenas paletas materializadas: - `width * height + palette_count * 16 * 4`. -- [x] A mudanca deve manter o nome `GLYPH/indexed_v1` como correcao - incompativel de v1, ou o runtime exige uma nova versao de payload? - - Resolucao: manter `GLYPH/indexed_v1` como correcao incompativel, sem - compatibilidade com o padding fixo antigo. - -## Criterio para Encerrar - -A agenda pode virar decisao quando o runtime escolher: - -- o significado normativo de `palette_count`; -- a relacao entre payload serializado e memoria residente; -- a regra de validade de `palette_id`; -- o ponto de falha para paletas referenciadas mas ausentes; -- a estrategia de versao para `GLYPH/indexed_v1`; -- a lista de specs, crates e testes que precisam ser propagados no plano. - -## Discussion - -Entrada do usuario em 2026-07-14: o runtime deve decidir o protocolo com base -no que for melhor para o runtime; o `packer` deve seguir a spec quando pronta. - -Entrada do usuario em 2026-07-14: preferencia pela Opcao C, se possivel. - -Analise atual: a Opcao C e viavel, mas transforma `palette_id` em validacao -dependente do glyph bank carregado. O codigo atual ja centraliza parte desse -risco em `GlyphBank::resolve_color`, que hoje retorna transparente quando a -paleta nao existe. Para a Opcao C virar contrato robusto, a decisao nao deve -depender de fallback silencioso: precisa escolher um ponto explicito de falha -para `palette_id >= palette_count`. - -Entrada do usuario em 2026-07-14: aceitar a recomendacao e seguir com a Opcao -C. - -## Resolution - -Fechar a agenda em favor da **Opcao C - Payload variavel e memoria residente -variavel**. - -Contrato a levar para decisao: - -- o runtime e a autoridade do protocolo `GLYPH/indexed_v1`; -- o `packer` deve seguir a spec runtime quando ela estiver publicada; -- `palette_count` significa o numero de paletas RGBA8888 serializadas e - materializadas no glyph bank carregado; -- `palette_count` deve estar no intervalo `1..=64`; -- cada paleta continua tendo 16 cores RGBA8888; -- `palette_id` e uma identidade direta dentro do glyph bank carregado, valida - somente quando `palette_id < palette_count`; -- o runtime nao deve remapear paletas esparsas para outra identidade; -- `decoded_size` deve contar apenas as paletas materializadas: - `width * height + palette_count * 16 * 4`; -- a mudanca permanece em `GLYPH/indexed_v1` como correcao incompativel de v1; -- payloads antigos com padding fixo e `palette_count = 64` so continuam - validos se tambem satisfizerem o novo contrato por coincidencia, nao por uma - regra de compatibilidade separada; -- referencias a paletas ausentes devem falhar explicitamente quando - scene/sprite/composer tentarem usar `palette_id >= palette_count` contra o - banco real; -- o plano posterior deve propagar specs, `GlyphBank`, decode de assets, - validacao de scene/sprite/composer, fixtures e testes. diff --git a/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md b/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md deleted file mode 100644 index 53e06b57..00000000 --- a/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md +++ /dev/null @@ -1,202 +0,0 @@ ---- -id: DEC-0041 -ticket: runtime-owned-variable-glyph-bank-palette-protocol -title: Variable Glyph Bank Palette Protocol -status: accepted -created: 2026-07-14 -accepted: 2026-07-14 -ref_agenda: AGD-0049 -tags: [runtime, gfx, assets, glyph-bank, palette-serialization, protocol] ---- - -## Status - -Accepted. - -## Contexto - -`AGD-0049` resolved that the runtime must own the `GLYPH/indexed_v1` palette -serialization protocol. `studio` and `packer` may motivate the change, but -they do not define the runtime wire contract. Once this decision is accepted, -the packer must follow the published runtime spec. - -The current runtime still contains fixed-palette assumptions: - -- `docs/specs/runtime/15-asset-management.md` says `palette_count = 64` and - validates `palette_count` as exactly `64`; -- `docs/specs/runtime/04-gfx-peripheral.md` documents `palette_id` as a - runtime-facing palette index; -- `crates/console/prometeu-hal/src/glyph_bank.rs` stores palettes as - `[[Color; 16]; 64]`; -- `crates/console/prometeu-drivers/src/asset.rs` rejects any glyph metadata - whose `palette_count` is not `64`; -- glyph decode reads a fixed `64 * 16 * 4` byte palette block; -- tests and fixtures calculate glyph payload and decoded size with the fixed - palette block. - -Prior decisions remain in force: - -- `DSC-0022` established `GlyphBank` as the canonical artifact name; -- `DSC-0037` established RGBA8888 as the runtime color contract, with alpha as - color data and no reserved magic palette index. - -## Decisao - -The runtime SHALL adopt variable glyph-bank palette serialization for -`GLYPH/indexed_v1`. - -For `BankType::GLYPH` in v1: - -- `palette_count` MUST mean the number of RGBA8888 palettes serialized in the - payload and materialized in the resident `GlyphBank`; -- `palette_count` MUST be in the inclusive range `1..=64`; -- each palette MUST contain exactly `16` RGBA8888 colors in canonical `R, G, B, - A` byte order; -- the serialized payload MUST contain only `palette_count` palettes, not a - fixed 64-palette block; -- resident runtime memory MUST materialize exactly `palette_count` palettes for - the bank; -- `palette_id` MUST be interpreted as a direct palette identity within the - loaded glyph bank; -- `palette_id` MUST be valid only when `palette_id < palette_count` for the - loaded glyph bank being referenced; -- the runtime MUST NOT remap sparse authored palette identities into a separate - dense identity space; -- missing palettes MUST NOT silently resolve to transparent, black, or any - other default color in canonical scene/sprite composition; -- references to `palette_id >= palette_count` MUST fail explicitly when - scene/sprite/composer logic attempts to use that palette against the loaded - bank; -- the format name remains `GLYPH/indexed_v1`; this is an incompatible v1 - correction, not a new v2 format. - -The v1 payload size formulas SHALL be: - -```text -serialized_pixel_bytes = ceil(width * height / 2) -palette_bytes = palette_count * 16 * 4 -size = serialized_pixel_bytes + palette_bytes -decoded_size = (width * height) + palette_bytes -``` - -`width * height` is the number of logical indexed pixels. Serialized pixels -remain packed `u4`; decoded runtime pixels may remain expanded to one `u8` -index per pixel. - -## Rationale - -This makes `palette_count` a real runtime contract instead of a decorative -metadata field. If a glyph bank carries `N` palettes, runtime storage, payload -validation, `decoded_size`, and palette lookup all agree on `N`. - -Keeping a fixed 64-slot resident table while trimming only the payload would -preserve two meanings for palette capacity: serialized count and resident -capacity. That would keep the ambiguity this decision is intended to remove. - -Adding sparse-to-dense palette remapping is also rejected. It would introduce a -second identity layer and force scenes, sprites, packer output, and runtime -lookup to coordinate additional metadata. V1 should keep `palette_id` as a -direct identity inside the loaded glyph bank. - -Keeping the name `GLYPH/indexed_v1` is acceptable because the project is still -in v1 and there is no required compatibility owner for the old fixed-padding -payload. The runtime should correct the v1 contract now instead of publishing a -second format solely to remove padding. - -## Invariantes / Contrato - -- The runtime is the protocol authority for `GLYPH/indexed_v1`. -- The packer is a producer of runtime-conforming payloads, not the source of - truth for the protocol. -- RGBA8888 remains the only valid glyph palette color encoding. -- Palette index `0` remains an ordinary palette index. -- Color index `0` remains an ordinary color index inside a palette. -- Transparency is represented by the RGBA alpha channel. -- `palette_count` is both serialized palette count and resident palette count. -- `palette_count` has a maximum of `64` in v1. -- `palette_id` validity is bank-dependent: `palette_id < palette_count`. -- No compatibility mode for the old fixed 64-palette padding is introduced. -- Old payloads with `palette_count = 64` remain valid only if they satisfy the - new contract directly, not because of a special legacy branch. - -## Impactos - -### Specs - -- `docs/specs/runtime/15-asset-management.md` must remove the exact - `palette_count = 64` requirement and define `palette_count` as `1..=64`. -- The same spec must align `size` and `decoded_size` formulas with variable - `palette_count`. -- `docs/specs/runtime/04-gfx-peripheral.md` must define `palette_id` validity - as dependent on the loaded glyph bank's `palette_count`, not as a standalone - global `0..63` acceptance rule. -- Any public wording that suggests fixed resident `64` palettes per glyph bank - must be updated or marked historical. - -### Runtime Code - -- `GlyphBank` must stop exposing a fixed `[[Color; 16]; 64]` resident palette - table as the canonical representation. -- Glyph decode must accept `palette_count` in `1..=64`. -- Glyph decode must read exactly `palette_count * 16 * 4` palette bytes. -- Glyph decode must validate `size` and `decoded_size` using the variable - formulas. -- Palette lookup must expose enough information for scene/sprite/composer logic - to fail invalid `palette_id` explicitly instead of silently resolving a - default color. - -### Scene, Sprite, and Composer - -- Scene and sprite composition must treat `palette_id >= palette_count` for the - referenced glyph bank as an explicit invalid reference. -- The implementation plan must choose the concrete status/fault path for this - invalid reference using existing runtime error semantics where possible. -- Canonical composition must not continue by substituting transparent/default - colors for invalid palette references. - -### Firmware / Host / Tooling - -- Firmware/system surfaces that expose asset metadata or debug information must - report the variable `palette_count`. -- Packer/studio fixtures must emit runtime-conforming `GLYPH/indexed_v1` - payloads after the runtime spec is updated. -- Tooling must not generate sparse-to-dense remapping metadata for v1 unless a - later decision introduces that feature. - -### Tests - -- Tests must cover minimum and maximum valid palette counts: `1` and `64`. -- Tests must reject `palette_count = 0` and `palette_count > 64`. -- Tests must validate serialized and decoded size formulas for non-64 counts. -- Tests must verify palette bytes are read in RGBA order for variable counts. -- Tests must cover invalid `palette_id >= palette_count` behavior for scene or - sprite composition. -- Residue scans must check for fixed `64 * 16 * 4` payload assumptions that are - still active contract text or code. - -## Referencias - -- Agenda: `AGD-0049` -- Runtime naming precedent: `DSC-0022` -- RGBA8888 contract precedent: `DSC-0037` -- Spec target: `docs/specs/runtime/15-asset-management.md` -- Spec target: `docs/specs/runtime/04-gfx-peripheral.md` -- Code target: `crates/console/prometeu-hal/src/glyph_bank.rs` -- Code target: `crates/console/prometeu-drivers/src/asset.rs` - -## Propagacao Necessaria - -This decision must be followed by an executable plan before spec or code -changes. - -The plan must separate: - -- spec edits; -- runtime decode/materialization changes; -- scene/sprite/composer invalid-palette handling; -- tests and fixtures; -- downstream packer/studio alignment after the runtime spec is updated. - -## Revision Log - -- 2026-07-14: Initial decision draft from `AGD-0049`. diff --git a/discussion/workflow/plans/PLN-0167-spec-contract-update-for-variable-glyph-palettes.md b/discussion/workflow/plans/PLN-0167-spec-contract-update-for-variable-glyph-palettes.md deleted file mode 100644 index c048cf2b..00000000 --- a/discussion/workflow/plans/PLN-0167-spec-contract-update-for-variable-glyph-palettes.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -id: PLN-0167 -ticket: runtime-owned-variable-glyph-bank-palette-protocol -title: Spec Contract Update for Variable Glyph Palettes -status: done -completed: 2026-07-14 -created: 2026-07-14 -ref_decisions: [DEC-0041] -tags: [runtime, gfx, assets, glyph-bank, palette-serialization, protocol, specs] ---- - -## Briefing - -`DEC-0041` accepts variable glyph-bank palette serialization for -`GLYPH/indexed_v1`. The runtime specs must become the canonical source before -code and tooling are changed. - -## Decisions de Origem - -- `DEC-0041` - Variable Glyph Bank Palette Protocol - -## Alvo - -Publish the runtime contract for variable glyph-bank palettes in the canonical -runtime specs. - -## Escopo - -- Update `docs/specs/runtime/15-asset-management.md`. -- Update `docs/specs/runtime/04-gfx-peripheral.md`. -- Remove or reword active spec text that requires exactly 64 serialized or - resident palettes per glyph bank. -- Define `palette_count` as serialized and resident palette count. -- Define `palette_count` as `1..=64`. -- Define `palette_id` validity as `palette_id < palette_count` for the loaded - glyph bank. -- Preserve RGBA8888, alpha-as-data, and ordinary index `0` semantics. - -## Fora de Escopo - -- Runtime code changes. -- Packer or studio code changes. -- New `GLYPH/indexed_v2` format text. -- Sparse-to-dense palette remapping. - -## Plano de Execucao - -### Step 1 - Update asset metadata contract - -**What:** Change the `GLYPH` v1 metadata contract. - -**How:** In `docs/specs/runtime/15-asset-management.md`, replace the exact -`palette_count = 64` requirement with `palette_count` in `1..=64`. State that -the field is both serialized palette count and resident palette count. - -**Files:** `docs/specs/runtime/15-asset-management.md` - -### Step 2 - Update payload and decoded-size formulas - -**What:** Make payload size formulas variable. - -**How:** Define `palette_bytes = palette_count * 16 * 4`, then define -`size = ceil(width * height / 2) + palette_bytes` and -`decoded_size = width * height + palette_bytes`. - -**Files:** `docs/specs/runtime/15-asset-management.md` - -### Step 3 - Update GFX palette reference semantics - -**What:** Document bank-dependent `palette_id` validity. - -**How:** In `docs/specs/runtime/04-gfx-peripheral.md`, make scene and sprite -composition text state that `palette_id` is valid only when it is lower than -the referenced glyph bank's `palette_count`. - -**Files:** `docs/specs/runtime/04-gfx-peripheral.md` - -### Step 4 - Document explicit failure - -**What:** Remove fallback ambiguity for missing palettes. - -**How:** State that canonical composition must not substitute transparent, -black, or default colors for `palette_id >= palette_count`. - -**Files:** `docs/specs/runtime/04-gfx-peripheral.md`, -`docs/specs/runtime/15-asset-management.md` - -### Step 5 - Run spec residue scan - -**What:** Verify no active spec contradicts `DEC-0041`. - -**How:** Search specs for fixed palette phrases and validate remaining hits are -historical or explicitly bounded maximums. - -**Files:** `docs/specs/runtime/*.md` - -## Criterios de Aceite - -- [ ] `15-asset-management.md` defines `palette_count` as `1..=64`. -- [ ] `15-asset-management.md` uses variable size formulas. -- [ ] `04-gfx-peripheral.md` defines bank-dependent `palette_id` validity. -- [ ] Specs do not describe fixed 64 serialized palettes as the active - contract. -- [ ] No v2 format is introduced. - -## Tests / Validacao - -- Run `rg -n "palette_count|64 \\* 16|4096|palette_id" docs/specs/runtime`. -- Run `discussion validate`. - -## Riscos - -- The specs already contain mixed fixed and variable wording; partial edits may - preserve contradiction. -- `palette_id` failure semantics may overlap with existing scene dependency - fatal-failure text and must be worded consistently. diff --git a/discussion/workflow/plans/PLN-0168-glyphbank-variable-palette-resident-model.md b/discussion/workflow/plans/PLN-0168-glyphbank-variable-palette-resident-model.md deleted file mode 100644 index 198d7f0c..00000000 --- a/discussion/workflow/plans/PLN-0168-glyphbank-variable-palette-resident-model.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -id: PLN-0168 -ticket: runtime-owned-variable-glyph-bank-palette-protocol -title: GlyphBank Variable Palette Resident Model -status: done -completed: 2026-07-14 -created: 2026-07-14 -ref_decisions: [DEC-0041] -tags: [runtime, gfx, assets, glyph-bank, hal] ---- - -## Briefing - -`DEC-0041` requires resident `GlyphBank` memory to materialize exactly -`palette_count` palettes. The current HAL model exposes a fixed -`[[Color; 16]; 64]` table and must be changed before decode and composition can -enforce bank-dependent palette validity cleanly. - -## Decisions de Origem - -- `DEC-0041` - Variable Glyph Bank Palette Protocol - -## Alvo - -Replace the fixed resident palette table with a variable resident palette model -that preserves direct `palette_id` identity. - -## Escopo - -- Update `crates/console/prometeu-hal/src/glyph_bank.rs`. -- Keep `GLYPH_BANK_COLORS_PER_PALETTE = 16`. -- Replace the fixed palette table with a variable representation. -- Expose palette count and palette validation helpers. -- Ensure `resolve_color` no longer hides invalid palette references in - canonical paths. -- Update local HAL tests and call sites that construct `GlyphBank` directly. - -## Fora de Escopo - -- Asset payload decode changes. -- Composer status/fault policy. -- Packer/studio changes. -- Sparse palette remapping. - -## Plano de Execucao - -### Step 1 - Introduce variable palette storage - -**What:** Replace fixed palette storage. - -**How:** Change `GlyphBank::palettes` from -`[[Color; GLYPH_BANK_COLORS_PER_PALETTE]; GLYPH_BANK_PALETTE_COUNT_V1]` to a -variable collection such as `Vec<[Color; GLYPH_BANK_COLORS_PER_PALETTE]>`. -Keep a separate maximum constant for v1 if useful. - -**Files:** `crates/console/prometeu-hal/src/glyph_bank.rs` - -### Step 2 - Update constructors - -**What:** Make constructors explicit about palette count. - -**How:** Add or update constructors so tests and loaders can create a bank with -a chosen palette count. Default constructors used only for empty test banks -must choose a valid count and not imply fixed 64 capacity. - -**Files:** `crates/console/prometeu-hal/src/glyph_bank.rs` - -### Step 3 - Add validation helpers - -**What:** Provide canonical palette validity APIs. - -**How:** Add methods such as `palette_count()`, `contains_palette(palette_id)`, -and a fallible color lookup that distinguishes invalid palette references from -transparent colors. - -**Files:** `crates/console/prometeu-hal/src/glyph_bank.rs` - -### Step 4 - Update direct palette mutations in tests - -**What:** Fix tests that write directly into fixed array slots. - -**How:** Replace direct `bank.palettes[id][color] = value` call sites with -helpers or ensure the test bank was created with enough palettes first. - -**Files:** `crates/console/prometeu-drivers/src/frame_composer.rs`, -`crates/console/prometeu-drivers/src/gfx.rs`, -`crates/console/prometeu-system/src/services/vm_runtime/tests.rs` - -### Step 5 - Keep direct identity - -**What:** Preserve `palette_id` identity. - -**How:** Do not introduce maps, compaction tables, or translated palette ids. -Index `N` in the vector is palette identity `N`. - -**Files:** `crates/console/prometeu-hal/src/glyph_bank.rs` - -## Criterios de Aceite - -- [ ] Resident `GlyphBank` stores exactly the loaded palette count. -- [ ] `GlyphBank` exposes bank-dependent palette validity. -- [ ] Invalid palette lookup can be detected separately from a transparent - color. -- [ ] No sparse-to-dense remapping structure is added. -- [ ] Direct test constructors no longer rely on implicit 64 palette capacity. - -## Tests / Validacao - -- Run HAL and driver unit tests that cover glyph bank construction and color - lookup. -- Add focused tests for `palette_count = 1` and `palette_count = 64`. -- Add a test proving invalid palette lookup is not silently equivalent to - transparent color. - -## Riscos - -- Many tests directly mutate `palettes[id]`; the migration can be noisy. -- Existing renderer paths may rely on `resolve_color` returning transparent for - invalid ids, which conflicts with `DEC-0041`. diff --git a/discussion/workflow/plans/PLN-0169-asset-decode-validation-for-variable-glyph-palettes.md b/discussion/workflow/plans/PLN-0169-asset-decode-validation-for-variable-glyph-palettes.md deleted file mode 100644 index 5976ca85..00000000 --- a/discussion/workflow/plans/PLN-0169-asset-decode-validation-for-variable-glyph-palettes.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: PLN-0169 -ticket: runtime-owned-variable-glyph-bank-palette-protocol -title: Asset Decode Validation for Variable Glyph Palettes -status: done -completed: 2026-07-14 -created: 2026-07-14 -ref_decisions: [DEC-0041] -tags: [runtime, assets, glyph-bank, decode, validation] ---- - -## Briefing - -`DEC-0041` changes glyph-bank decode from a fixed 4096-byte palette block to a -variable `palette_count * 16 * 4` block. The asset manager is the runtime gate -that must reject malformed glyph payloads before residency. - -## Decisions de Origem - -- `DEC-0041` - Variable Glyph Bank Palette Protocol - -## Alvo - -Update glyph asset layout validation and decode to accept `palette_count` in -`1..=64` and materialize exactly that many palettes. - -## Escopo - -- Update `crates/console/prometeu-drivers/src/asset.rs`. -- Replace exact `palette_count == 64` validation. -- Replace fixed `GLYPH_BANK_PALETTE_BYTES_V1` usage in decode. -- Validate `size` and `decoded_size` using variable formulas. -- Read exactly `palette_count * 16 * 4` bytes. -- Preserve RGBA byte order. - -## Fora de Escopo - -- HAL storage changes except as required by `PLN-0168`. -- Composer invalid-reference behavior. -- Packer output changes. - -## Plano de Execucao - -### Step 1 - Change layout return data - -**What:** Carry palette count through layout validation. - -**How:** Update `decode_glyph_bank_layout` to return `palette_count` and -palette byte count along with tile size, dimensions, and serialized pixel byte -count. - -**Files:** `crates/console/prometeu-drivers/src/asset.rs` - -### Step 2 - Replace exact palette-count validation - -**What:** Accept only the DEC-0041 range. - -**How:** Reject `palette_count = 0` and `palette_count > 64`; accept all values -in `1..=64`. - -**Files:** `crates/console/prometeu-drivers/src/asset.rs` - -### Step 3 - Use variable size formulas - -**What:** Align entry validation with the spec. - -**How:** Compute `palette_bytes = palette_count * 16 * size_of::()`, -`serialized_size = packed_pixels + palette_bytes`, and -`decoded_size = logical_pixels + palette_bytes`. - -**Files:** `crates/console/prometeu-drivers/src/asset.rs` - -### Step 4 - Decode variable palette data - -**What:** Read only materialized palettes. - -**How:** In buffer and reader decode paths, slice/read exactly `palette_bytes`. -Populate the new variable `GlyphBank` palette representation in order. - -**Files:** `crates/console/prometeu-drivers/src/asset.rs` - -### Step 5 - Remove fixed-byte assumptions - -**What:** Retire the fixed payload block from active decode. - -**How:** Replace helper functions and tests that assume -`GLYPH_BANK_PALETTE_BYTES_V1` is always in the payload. Keep a maximum constant -only if it is named as a maximum, not a payload size. - -**Files:** `crates/console/prometeu-drivers/src/asset.rs` - -## Criterios de Aceite - -- [ ] Decode accepts valid `palette_count` values from `1` through `64`. -- [ ] Decode rejects `palette_count = 0`. -- [ ] Decode rejects `palette_count > 64`. -- [ ] `size` and `decoded_size` validation use variable palette bytes. -- [ ] Buffer and reader decode paths behave consistently. -- [ ] RGBA channel order remains unchanged. - -## Tests / Validacao - -- Add unit tests for `palette_count = 1`, an intermediate count, and `64`. -- Add rejection tests for `0`, `65`, short palette data, oversized metadata - size, and mismatched `decoded_size`. -- Run the crate tests that cover asset manager glyph decode. - -## Riscos - -- Existing tests may use generated glyph payload helpers with fixed 64-palette - size. -- Reader and buffer paths can drift if only one path receives the variable-size - change. diff --git a/discussion/workflow/plans/PLN-0170-composer-palette-reference-failure-semantics.md b/discussion/workflow/plans/PLN-0170-composer-palette-reference-failure-semantics.md deleted file mode 100644 index 4a74f106..00000000 --- a/discussion/workflow/plans/PLN-0170-composer-palette-reference-failure-semantics.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: PLN-0170 -ticket: runtime-owned-variable-glyph-bank-palette-protocol -title: Composer Palette Reference Failure Semantics -status: done -completed: 2026-07-14 -created: 2026-07-14 -ref_decisions: [DEC-0041] -tags: [runtime, gfx, composer, scene, sprite, validation] ---- - -## Briefing - -`DEC-0041` requires invalid palette references to fail explicitly when -scene/sprite/composer logic uses `palette_id >= palette_count` against a loaded -glyph bank. Current color resolution can silently return transparent for -missing palettes, which is no longer canonical behavior. - -## Decisions de Origem - -- `DEC-0041` - Variable Glyph Bank Palette Protocol - -## Alvo - -Define and implement explicit runtime failure behavior for invalid palette -references in canonical composition paths. - -## Escopo - -- Inspect scene binding, scene composition, sprite emission, and render - resolution paths. -- Choose existing status/fault behavior where it fits the current ABI. -- Prevent canonical composition from substituting transparent/default color for - invalid palette references. -- Update tests for scene and sprite invalid palette references. - -## Fora de Escopo - -- Adding new public ABI status values unless existing statuses cannot represent - the error. -- Packer or scene authoring validation. -- Sparse palette remapping. - -## Plano de Execucao - -### Step 1 - Map current composition paths - -**What:** Identify where palette ids are consumed. - -**How:** Trace `composer.emit_sprite`, scene binding/composition, frame -composer packet creation, and software GFX resolution from `Glyph` to -`GlyphBank::resolve_color`. - -**Files:** `crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs`, -`crates/console/prometeu-drivers/src/frame_composer.rs`, -`crates/console/prometeu-drivers/src/gfx.rs`, -`crates/console/prometeu-hal/src/glyph_bank.rs` - -### Step 2 - Select explicit failure behavior - -**What:** Choose the runtime-visible failure route. - -**How:** Use existing semantics where possible: status-returning sprite calls -should use an existing invalid status if it accurately describes the failure; -scene dependency failures that occur during binding/composition should follow -the existing fatal dependency-failure model documented in the GFX spec. - -**Files:** `docs/specs/runtime/04-gfx-peripheral.md`, -`crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs`, -`crates/console/prometeu-drivers/src/frame_composer.rs` - -### Step 3 - Validate sprite references - -**What:** Prevent invalid sprite palette references. - -**How:** When `emit_sprite` has access to the target glyph bank, reject -`palette_id >= palette_count` before the sprite is accepted for canonical -composition. - -**Files:** `crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs`, -`crates/console/prometeu-drivers/src/frame_composer.rs`, -`crates/console/prometeu-drivers/src/hardware.rs` - -### Step 4 - Validate scene references - -**What:** Prevent invalid scene palette references. - -**How:** During scene bind or scene composition, validate tile palette ids -against each referenced loaded glyph bank. Fail explicitly if a scene layer -references a palette not present in its glyph dependency. - -**Files:** `crates/console/prometeu-drivers/src/gfx.rs`, -`crates/console/prometeu-hal/src/scene_viewport_cache.rs`, -`crates/console/prometeu-hal/src/scene_viewport_resolver.rs` - -### Step 5 - Remove silent fallback from canonical paths - -**What:** Stop hiding invalid palette ids as transparent. - -**How:** Use fallible palette lookup in canonical render paths. Transparent is -valid only when produced by an actual RGBA palette entry with alpha `0`. - -**Files:** `crates/console/prometeu-drivers/src/gfx.rs`, -`crates/console/prometeu-hal/src/glyph_bank.rs` - -## Criterios de Aceite - -- [ ] Invalid sprite `palette_id` is rejected before canonical composition. -- [ ] Invalid scene tile `palette_id` fails explicitly against the loaded bank. -- [ ] Canonical render paths do not use invalid palette lookup as transparent. -- [ ] Valid transparent RGBA palette entries still render as transparent. -- [ ] The selected status/fault behavior is documented in the spec. - -## Tests / Validacao - -- Add sprite test for `palette_id == palette_count`. -- Add scene test for a tile palette id above the referenced bank's count. -- Add regression test proving alpha `0` in a valid palette still works. -- Run VM runtime and GFX driver tests. - -## Riscos - -- Some paths may not have easy access to the loaded glyph bank when accepting a - sprite packet. -- Existing ABI statuses may be less precise than a new status, but adding a new - status has wider compatibility cost. diff --git a/discussion/workflow/plans/PLN-0171-variable-glyph-palette-tests-fixtures-and-residue-scan.md b/discussion/workflow/plans/PLN-0171-variable-glyph-palette-tests-fixtures-and-residue-scan.md deleted file mode 100644 index 2aa5a2d8..00000000 --- a/discussion/workflow/plans/PLN-0171-variable-glyph-palette-tests-fixtures-and-residue-scan.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: PLN-0171 -ticket: runtime-owned-variable-glyph-bank-palette-protocol -title: Variable Glyph Palette Tests Fixtures and Residue Scan -status: done -completed: 2026-07-14 -created: 2026-07-14 -ref_decisions: [DEC-0041] -tags: [runtime, tests, fixtures, glyph-bank, palette-serialization] ---- - -## Briefing - -`DEC-0041` changes a cross-cutting asset contract. Tests and fixtures must be -updated as a dedicated pass so fixed 64-palette assumptions do not survive in -helpers, generated data, or residue. - -## Decisions de Origem - -- `DEC-0041` - Variable Glyph Bank Palette Protocol - -## Alvo - -Convert runtime tests and fixtures to exercise variable glyph palette counts -and prove fixed-padding assumptions are gone from active behavior. - -## Escopo - -- Update test helpers that build glyph payloads. -- Add minimum, maximum, and intermediate palette-count tests. -- Add invalid palette-count tests. -- Add invalid palette-reference tests once `PLN-0170` is implemented. -- Run residue scans for fixed palette payload assumptions. - -## Fora de Escopo - -- Production decode implementation. -- Production composer implementation. -- Packer/studio fixture generation. - -## Plano de Execucao - -### Step 1 - Inventory glyph payload helpers - -**What:** Find all runtime test helpers with fixed glyph palette sizes. - -**How:** Search for `GLYPH_BANK_PALETTE_COUNT_V1`, -`GLYPH_BANK_PALETTE_BYTES_V1`, `64 * 16 * 4`, `4096`, and helper names such as -`test_glyph_asset_data`. - -**Files:** `crates/console/prometeu-drivers/src/asset.rs`, -`crates/console/prometeu-system/src/services/vm_runtime/tests.rs`, -`crates/console/prometeu-system/src/services/vm_runtime/tests_asset_bank.rs` - -### Step 2 - Create variable payload builders - -**What:** Make tests express palette count deliberately. - -**How:** Replace fixed helpers with helpers that accept `palette_count`, build -exactly `palette_count * 16 * 4` palette bytes, and compute matching `size` and -`decoded_size`. - -**Files:** Runtime test modules that construct glyph assets. - -### Step 3 - Add decode boundary coverage - -**What:** Prove valid and invalid counts. - -**How:** Add tests for `palette_count = 1`, an intermediate value, `64`, `0`, -and `65`. - -**Files:** `crates/console/prometeu-drivers/src/asset.rs` - -### Step 4 - Add composition coverage - -**What:** Prove invalid palette references fail. - -**How:** After `PLN-0170`, add scene and sprite tests where -`palette_id == palette_count` and confirm explicit failure behavior. - -**Files:** `crates/console/prometeu-drivers/src/gfx.rs`, -`crates/console/prometeu-drivers/src/frame_composer.rs`, -`crates/console/prometeu-system/src/services/vm_runtime/tests.rs` - -### Step 5 - Run residue scan - -**What:** Catch leftover active fixed-palette assumptions. - -**How:** Scan code, tests, and specs for fixed palette byte formulas. Keep only -maximum-bound constants and historical documentation. - -**Files:** `crates/`, `docs/specs/runtime/`, `discussion/` - -## Criterios de Aceite - -- [ ] Tests no longer need a fixed 4096-byte palette payload for every glyph - bank. -- [ ] Decode tests cover `1`, intermediate counts, `64`, `0`, and `65`. -- [ ] Composition tests cover invalid palette references. -- [ ] Residue scan finds no active fixed serialized palette block assumption. -- [ ] Historical or maximum-bound uses of `64` are clearly named. - -## Tests / Validacao - -- Run targeted crate tests for asset decode, GFX, frame composer, and VM asset - bank flows. -- Run `rg -n "4096|64 \\* 16|GLYPH_BANK_PALETTE_BYTES_V1|palette_count"` - against `crates`, `docs/specs/runtime`, and active discussion artifacts. -- Run `discussion validate`. - -## Riscos - -- Residue scans can produce legitimate hits for the v1 maximum of `64`; those - must be classified instead of mechanically removed. -- Test helper churn can obscure the behavioral assertions if not kept focused. diff --git a/discussion/workflow/plans/PLN-0172-runtime-spec-handoff-to-packer-and-studio.md b/discussion/workflow/plans/PLN-0172-runtime-spec-handoff-to-packer-and-studio.md deleted file mode 100644 index e6eaf69f..00000000 --- a/discussion/workflow/plans/PLN-0172-runtime-spec-handoff-to-packer-and-studio.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -id: PLN-0172 -ticket: runtime-owned-variable-glyph-bank-palette-protocol -title: Runtime Spec Handoff to Packer and Studio -status: done -completed: 2026-07-14 -created: 2026-07-14 -ref_decisions: [DEC-0041] -tags: [runtime, packer, studio, handoff, glyph-bank, palette-serialization] ---- - -## Briefing - -`DEC-0041` makes runtime the authority for `GLYPH/indexed_v1`. After the -runtime spec and implementation are updated, packer and studio must align as -downstream producers of runtime-conforming assets. - -## Decisions de Origem - -- `DEC-0041` - Variable Glyph Bank Palette Protocol - -## Alvo - -Prepare a clear runtime-owned handoff for packer/studio without moving protocol -authority out of the runtime repository. - -## Escopo - -- Summarize the accepted runtime contract for downstream repositories. -- Identify exact spec sections packer/studio must follow. -- Identify fixture and payload requirements. -- Capture any compatibility note needed for old fixed-padding payloads. -- Update runtime discussion artifacts with handoff status when implementation - is complete. - -## Fora de Escopo - -- Editing `../studio` or packer code from this plan. -- Reopening `AGD-0005` in `../studio`. -- Defining a v2 payload. -- Adding producer-specific runtime exceptions. - -## Plano de Execucao - -### Step 1 - Wait for runtime spec publication - -**What:** Use runtime specs as handoff source. - -**How:** Do not send or encode downstream requirements until `PLN-0167` has -landed. The published runtime spec is the contract. - -**Files:** `docs/specs/runtime/15-asset-management.md`, -`docs/specs/runtime/04-gfx-peripheral.md` - -### Step 2 - Write downstream contract summary - -**What:** Produce a concise handoff note. - -**How:** Summarize `palette_count`, payload layout, size formulas, -`palette_id` validity, absence of remapping, and incompatibility with the old -padding contract. - -**Files:** Runtime discussion plan or follow-up note as appropriate. - -### Step 3 - Identify downstream fixture updates - -**What:** Define what packer/studio fixtures must prove. - -**How:** Require fixtures with `palette_count = 1`, an intermediate count, and -`64`, plus rejection or regeneration of fixed-padding assumptions where the -metadata does not match the payload. - -**Files:** Handoff note only; actual downstream files are outside this repo. - -### Step 4 - Preserve runtime authority - -**What:** Prevent downstream divergence. - -**How:** State that packer/studio metadata such as authored palette count is -informative unless the runtime spec defines it as effective metadata. - -**Files:** Handoff note; runtime spec references. - -### Step 5 - Close loop after downstream acknowledgment - -**What:** Track completion. - -**How:** Once packer/studio work is done elsewhere, update discussion lessons or -housekeeping artifacts from the runtime side without adding new normative text -to lessons. - -**Files:** `discussion/lessons/` only after implementation is complete. - -## Criterios de Aceite - -- [ ] Runtime specs are updated before downstream handoff. -- [ ] Handoff states that runtime owns the protocol. -- [ ] Handoff lists exact payload formulas and validity rules. -- [ ] Handoff states that no sparse-to-dense remapping exists in v1. -- [ ] Handoff states that old fixed-padding payloads are not compatibility - inputs unless they satisfy the new contract directly. - -## Tests / Validacao - -- Verify handoff references the final spec sections, not agenda text. -- Verify no downstream instruction contradicts `DEC-0041`. -- Run `discussion validate`. - -## Riscos - -- Downstream repositories may still treat `metadata.palette_authored` as - authoritative; this plan must make runtime-effective metadata explicit. -- Creating handoff text too early could freeze pre-implementation details. - -## Handoff Note - -Runtime is the protocol authority for `GLYPH/indexed_v1`. Downstream packer and -studio work must follow the published runtime specs, not the historical studio -agenda. - -Canonical runtime references: - -- `docs/specs/runtime/15-asset-management.md`, section `4.1 GLYPH asset - contract in v1` -- `docs/specs/runtime/04-gfx-peripheral.md`, section `19.4 Palette - Association` -- `docs/specs/runtime/04-gfx-peripheral.md`, section `20.1.b Scene dependency - fatal boundary` -- `docs/specs/runtime/04-gfx-peripheral.md`, section `20.2 - composer.emit_sprite` - -Downstream producers must emit: - -- `codec = NONE` -- packed `u4` indexed pixels -- RGBA8888 palette bytes in `R, G, B, A` order -- root effective metadata fields `tile_size`, `width`, `height`, and - `palette_count` -- `palette_count` in `1..=64` -- exactly `palette_count * 16 * 4` palette bytes -- `size = ceil(width * height / 2) + palette_count * 16 * 4` -- `decoded_size = width * height + palette_count * 16 * 4` - -Downstream producers must not emit: - -- sparse-to-dense palette remapping metadata for v1 -- a `GLYPH/indexed_v2` payload for this change -- fixed 64-palette padding unless `palette_count = 64` and the payload - directly satisfies the runtime v1 contract -- effective runtime behavior based on `palette_authored`; that field is - informative unless a later runtime spec promotes it to an effective root - metadata field - -Required downstream fixture coverage: - -- one glyph bank with `palette_count = 1` -- one glyph bank with an intermediate `palette_count` -- one glyph bank with `palette_count = 64` -- payload-size and decoded-size assertions for each fixture -- a negative fixture or validation case for metadata/payload mismatch