Files
emcp-tools-mapping/docs/14-PROJECT-MEMORY-BLUEPRINT.md
Claude Code 2812cd79ba docs: doc13 Forms Pro (WPForms+Fluent Forms) + doc14 Project Memory blueprints
Fundamentados em código real: WPForms Lite 2.0.0.5 + Fluent Forms 6.2.12
(activos em ecommerce-demo.descomplicar.pt), e CARL+Mem0/Hindsight (sistemas
de memória/governança já em produção neste ecossistema). Achado central doc13:
Fluent Forms já embarca servidor MCP nativo próprio (AbilitiesRegistrar, 9
abilities, dry-run+confirm_token) - recomenda delegar em vez de reimplementar.
INDEX.md actualizado com as 2 novas entradas e totais.
2026-08-19 07:58:31 +01:00

614 lines
48 KiB
Markdown

# 14 — Project Memory (Pro): blueprint de abilities MCP (desenho próprio, não é auditoria EMCP Pro)
Fonte primária: leitura directa (19-08-2026) de **duas fontes reais** fora da árvore `emcp-tools`
propriamente dita — porque, tal como em `docs/11-WOOCOMMERCE-BLUEPRINT.md` e
`docs/12-WIDGET-BUILDER-BLUEPRINT.md`, o código Pro do módulo "Project Memory" está **fisicamente
ausente** desta build Free (confirmado pelo padrão já estabelecido em `docs/10-MODULOS-E-INVENTARIO-PRO.md`:
uma classe `class_exists()`-gated cujo ficheiro nunca existe na árvore instalada — não retentado
nesta tarefa, o mesmo padrão já foi verificado exaustivamente para os outros ~30 módulos Pro). As
duas fontes reais usadas em substituição: **(A)** `~/.omp/agent/AGENTS.md` (e o documento canónico
que importa, `Hub/04-Stack/02.04-Sistemas/AGENTS.md`) — a identidade operacional deste próprio
ambiente OMP, que já opera um sistema de governança de regras com staging/aprovação (CARL) e um
sistema de memória cross-agent em camadas (Mem0), ambos **em produção, não hipotéticos**; **(B)** os
padrões de aprovação humana e de change-ledger já confirmados por código real nesta mesma série
(`docs/04-THEMER.md` §11, `docs/06-SANDBOX-CUSTOM-CODE.md` §1, `docs/05-REDIRECTS-SEARCH-LEDGER.md`
§4).
## 0. Panorama — porque este documento é diferente e o que fundamenta cada peça
A captura de ecrã da UI de administração do EMCP Tools (secção *Project Memory (Pro)*, contador
"0/3") mostra **3 tools MCP**, todas prefixadas `emcp-tools/`:
| Tool id (screenshot) | Badge | Descrição literal do utilizador |
|---|---|---|
| `emcp-tools/recall` | PRO · READ-ONLY | "Read approved guidance + recent session summaries so the agent does not re-guess site context" |
| `emcp-tools/remember` | PRO | "Propose one guardrail/fact/convention/instruction. Stored pending until a human approves it" |
| `emcp-tools/save-session-summary` | PRO | "Record a session summary; the plugin attaches a factual digest of the actual changes" |
Estes 3 nomes e as 3 descrições são usados **apenas como especificação da API-alvo** (nomenclatura,
âmbito e a promessa comportamental de cada tool) — **não** como fonte de implementação. Não há
código Pro nesta árvore para ler, logo não há input schema, mensagens de erro, nem lógica interna
real do EMCP Pro para citar. Qualquer detalhe de *como* cada tool funciona por dentro, neste
documento, é proposta própria.
Em vez de tentar adivinhar o comportamento interno, este documento faz a pergunta inversa dos docs
01-10: **dado que este próprio ambiente de trabalho (OMP/Claude Code, ecossistema Descomplicar) já
resolveu exactamente o mesmo problema** — "como é que um agente de IA lembra contexto de projecto
entre sessões sem inventar factos e sem escrever governança sem supervisão humana" — **com dois
sistemas reais e vivos em produção**, qual é o desenho mais honesto para "Project Memory" que se
pode propor sem fingir conhecer o código Pro?
### As duas fontes reais e o que cada uma fundamenta
1. **CARL** (Sistema de Regras e Governança, com pipeline staging→aprovação) — confirmado como
sistema real vivo por três evidências independentes, todas citadas literalmente ao longo deste
documento:
- O ficheiro canónico `Hub/04-Stack/02.04-Sistemas/AGENTS.md` §4 (errata 26-07-2026), citação
directa: *"As **22 regras CARL `GLOBAL`** só carregavam com o cwd dentro de `04-Stack` — o
CARL resolve scopes pelo cwd e substitui o domínio inteiro. Fora dali, `GLOBAL` tinha 3.
Consolidadas."*
- `Hub/04-Stack/02.04-Sistemas/PIPELINE-QUALIDADE-TOTAL.md` (17-07-2026), citação directa:
*"stack-observer→classify→fingerprint→propostas CARL; (…) CARL v2 GLOBAL com 26 regras"* e,
na matriz de arcos do pipeline (C6, 06→02/01): *"Propostas aprovadas → novas regras CARL /
gates / processos (…) staging CARL funcional"*.
- **O conjunto real de ferramentas MCP CARL disponíveis neste próprio ambiente** (servidor
`carl-mcp`, invocável directamente nesta sessão) — nomes de tool, descrições e schemas de
argumento reais, sem paráfrase, citados na íntegra na secção 2 abaixo. Existem **duas gerações**
coexistentes do mesmo sistema (v1, ficheiro-por-domínio; v2, `carl.json` único) — ambas reais,
ambas activas nesta instalação, e a divergência entre elas é, por si só, um dado relevante para
o desenho de "Remember Guidance" (secção 2.3).
2. **Mem0 / memória cross-agent** — confirmado como sistema real vivo pela secção 5 ("MEMÓRIA") do
`Hub/04-Stack/02.04-Sistemas/AGENTS.md`, citada quase integralmente na secção 1, e pelo conjunto
real de ferramentas MCP `mem0` disponíveis nesta sessão (servidor `mem0`, prefixo
`mcp__mem_*`) — `save_memory`, `search_memories`, `get_all_memories`, `update_memory`,
`delete_memory`, etc.
**Cruzamento adicional com código real desta série** (o mesmo grupo de precedentes já usado por
`docs/12-WIDGET-BUILDER-BLUEPRINT.md` §6.5 para justificar "zero tool de auto-activação"):
`docs/04-THEMER.md` §11 (Themer PHP: *"there is intentionally no attach tool"*) e
`docs/06-SANDBOX-CUSTOM-CODE.md` §1 (PHP Snippets: *"There is intentionally no 'activate' tool"*),
mais o change ledger unificado de `docs/05-REDIRECTS-SEARCH-LEDGER.md` §4
(`EMCP_Tools_Change_Log`/`Change_Recorder`/`Change_Blobs`) como modelo de armazenamento/rollback
para o que uma "guidance" pendente/aprovada precisaria de persistir e desfazer.
> **Convenção usada em todo o documento** (idêntica a docs 11/12): cada afirmação é marcada
> `[REAL]` quando vem directamente de uma fonte verificável nesta sessão (o próprio `AGENTS.md`, os
> ficheiros do Hub citados, ou uma chamada real a uma ferramenta MCP CARL/Mem0 feita nesta tarefa),
> ou `[DESENHO PRÓPRIO]` quando é uma proposta nossa sem equivalente confirmado no EMCP Pro. Onde
> uma peça combina as duas (ex.: mapear uma tool Pro hipotética sobre um fluxo CARL real), isso é
> dito explicitamente — e a maioria das peças deste documento está nessa categoria mista, porque
> **nenhuma das 3 tools Pro foi lida directamente**; só a promessa comportamental (a frase da
> captura de ecrã) é dado de entrada.
**A distinção mais importante de todo o documento:** ao contrário do doc 12 (onde a camada de
armazenamento `EMCP_Tools_Widget_Store` **já existe** e é código real, só a camada de compilação e
a de abilities é que faltam), aqui **nenhuma camada do sistema "Project Memory" existe fisicamente
nesta árvore Free** — nem abilities, nem store, nem CPT, nem option. Este blueprint é, por isso,
mais "desenho próprio" do que o doc 12; a âncora real está inteiramente fora do plugin, nos dois
sistemas de governança/memória que este próprio ambiente de execução já usa para resolver o mesmo
problema.
---
## 1. `recall` — ler orientação aprovada + resumos de sessão recentes
**Promessa da tool (screenshot, PRO READ-ONLY):** *"Read approved guidance + recent session
summaries so the agent does not re-guess site context."*
### 1.1 Fundamentação `[REAL]` — o sistema de memória em camadas já em produção
O `AGENTS.md` canónico documenta explicitamente uma arquitectura de memória por níveis que resolve
precisamente este problema — "não repetir contexto que já foi estabelecido". Citação directa,
`Hub/04-Stack/02.04-Sistemas/AGENTS.md` §5 ("MEMÓRIA"):
> *"### Cross-agent (Mem0)
> - Gateway: `gateway.descomplicar.pt/v1/mem0/mcp`
> - Bridge Hindsight: `localhost:8888` → mem0 local
> - REST API directa: `localhost:8090` (debug/Swagger)
> - OMP usa `memory.backend: hindsight` → bridge → mem0
> - Protocolo Wayland v2: P5=identidade, P4=procedimento, P3=facto atómico
>
> ### Níveis
> | Tier | Sistema | O quê | Automático? |
> |------|---------|-------|-------------|
> | 1 | IJFW/OMP Hindsight | Working memory de sessão | Sim |
> | 2 | Mem0 (via gateway MCP) | Factos duráveis cross-agent | Sim (bridge) |
> | 3 | Mem0 REST API (`:8090`) | Acesso directo para debug/automação | Manual"*
Além disto, o próprio `AGENTS.md` §2 ("HIERARQUIA DE FONTES") estabelece a regra geral que
`recall` deveria implementar do lado de um plugin WordPress: *"NLM-first: consultar NotebookLM
PRIMEIRO antes de perguntas técnicas"* e *"Nunca confiar em docs sem verificar: o que está escrito
pode estar errado. Só o que é verificado no terreno conta."* — ou seja, mesmo um sistema de
memória "aprovada" não é uma licença para parar de verificar; é uma optimização de "não repetir
trabalho de descoberta já feito", não uma substituição da verificação.
**Mapeamento directo:** o Tier 2 (Mem0 via gateway MCP, "factos duráveis cross-agent", automático)
é o análogo funcional mais próximo de "ler orientação aprovada + resumos recentes" — mas com uma
diferença estrutural crítica face ao desenho proposto pela EMCP Pro (ver secção 1.3).
### 1.2 Ferramentas MCP Mem0 reais desta sessão `[REAL]`
A ferramenta `search_memories` (servidor `mem0`, `mcp__mem_search_memories`) é o equivalente mais
directo de `recall`: aceita `query` (pesquisa em linguagem natural), `user_id`/`agent_id`/`run_id`
opcionais para segmentar por âmbito, `top_k` (default 5) e `threshold` (score mínimo de
similaridade). `get_all_memories` (`mcp__mem_get_all_memories`) é o equivalente de "listar tudo o
que está aprovado para este âmbito", sem query — mais próximo do comportamento "devolve a
orientação aprovada" descrito na promessa da tool Pro (uma leitura completa e determinística, não
uma pesquisa semântica top-k que pode omitir algo relevante por baixo do threshold).
### 1.3 Desenho proposto para `recall` `[DESENHO PRÓPRIO, sobre camadas [REAL]]`
| Área | O que cobre | API/sistema real usado como modelo | Nível de risco |
|---|---|---|---|
| Leitura de guardrails/factos/convenções **aprovados** | Devolve só entradas com estado `approved` — nunca `pending`/`rejected` (ver modelo de estados, secção 4) | Equivalente ao filtro implícito de `get-domain-rules`/`get-domain` do CARL real (secção 2.2), que só devolve regras já escritas no domínio, nunca as que ainda estão em staging | readonly, idempotent |
| Leitura de resumos de sessão recentes | Últimos N resumos gravados por `save-session-summary` (secção 3), ordenados por recência, com o "digest factual" já anexado pelo plugin | Análogo ao Tier 1 ("working memory de sessão", `AGENTS.md` §5) tornado persistente entre sessões — o Pro parece fundir aqui o que o ecossistema Descomplicar trata como dois tiers distintos (1 efémero, 2 durável) | readonly, idempotent |
| Filtro por âmbito (página/post/site inteiro) | `[DESENHO PRÓPRIO]` — sem equivalente directo confirmado; proposta: um parâmetro `scope?:{post_id?, site_wide?:bool}`, espelhando o padrão `emcp_themer_selectors` (`docs/04-THEMER.md` §0) de escala larga→granular por filtro | — |
| Recall keyword-driven (activação por intenção) | `[DESENHO PRÓPRIO, precedente REAL forte]` — cada domínio CARL tem `recall` (palavras-chave que o disparam, ver `carl_get_domain_rules`: *"Load rules for a specific CARL domain. Use when user intent matches domain recall keywords"*); um `recall` de Project Memory poderia aceitar `intent_hint?:string` e devolver só entradas cujas keywords casem, evitando devolver TODA a memória aprovada em cada chamada | — |
**Nota sobre "não re-adivinhar contexto"**: a frase da promessa Pro ("so the agent does not
re-guess site context") é, no ecossistema Descomplicar, exactamente o motivo declarado para o
Mem0 Tier 2 existir — "factos duráveis cross-agent" que sobrevivem ao reset de contexto de uma
sessão. A diferença de desenho que este documento propõe adoptar (ver 1.4) é que o Pro parece
restringir `recall` a **só** conteúdo já aprovado por um humano, ao passo que o Mem0 real do
ecossistema grava directamente (`save_memory`) sem esse portão — ver a tensão explícita na secção
2.4.
### 1.4 Porque "aprovado" é o modelo certo aqui, não "gravado directamente"
Ao contrário do Mem0 (Tier 2, escrita automática via bridge, sem revisão humana — apropriado para
factos operacionais de baixo risco, como "o cliente X prefere PT-PT sem gírias"), uma "guidance"
de `recall` num plugin WordPress pode influenciar directamente **decisões de escrita subsequentes
do próprio agente no mesmo site** (ex.: "nunca apagar redirects sem confirmar", "este cliente usa
sempre Multibanco, não activar Stripe"). Este é exactamente o tipo de afirmação que, se errada ou
obsoleta, causa dano real e persistente — o mesmo raciocínio de risco que already levou o Themer
PHP e os PHP Snippets a nunca expor "activar" via MCP (`docs/04-THEMER.md` §11,
`docs/06-SANDBOX-CUSTOM-CODE.md` §1). Por isso o modelo correcto para `recall` **não** é "o que o
Mem0 tem gravado" (Tier 2 puro), é "o subconjunto do Tier 2 que já passou pelo portão humano" —
precisamente o desenho que a secção 2 propõe para `remember`.
---
## 2. `remember` — propor uma guidance, pendente de aprovação humana
**Promessa da tool (screenshot, PRO):** *"Propose one guardrail/fact/convention/instruction. Stored
pending until a human approves it."*
Esta é a peça mais bem fundamentada de todo o documento — a promessa da tool Pro descreve, quase
palavra por palavra, o fluxo **staging→aprovação** que o CARL já implementa como sistema real,
com ferramentas MCP reais chamáveis nesta mesma sessão.
### 2.1 O fluxo CARL real (v1, ficheiro-por-domínio) `[REAL]`
Ferramentas reais do servidor `carl-mcp`, citadas com a descrição exacta tal como declarada nos
seus schemas MCP (sem paráfrase):
| Tool MCP real | Descrição literal | Argumentos |
|---|---|---|
| `carl_stage_proposal` | "Stage a new CARL rule proposal for review. Sources: psmm, decisions, manual." | `domain`, `rule_text`, `rationale`, `source` (enum `psmm`\|`decisions`\|`manual`) |
| `carl_get_staged` | "List all pending rule proposals in the staging pipeline." | — |
| `carl_approve_proposal` | "Approve a staged proposal — writes the rule to the target domain file and removes from staging." | `id` (ex. `prop-001`) |
| `carl_archive_proposal` | "Archive a proposal — keeps it for reference but doesn't activate as a rule." | `id` |
| `carl_kill_proposal` | "Delete a staged proposal permanently." | `id` |
| `carl_log_decision` | "Log a decision to a CARL domain. Auto-creates domain file if new." | `domain`, `decision`, `rationale`, `recall` |
| `carl_get_domain_rules` | "Load rules for a specific CARL domain. Use when user intent matches domain recall keywords." | `domain` |
| `carl_get_manifest` | "Get current CARL manifest showing all domains, states, and recall keywords." | — |
| `carl_toggle_domain` | "Enable or disable a CARL domain by updating the manifest." | `domain`, `state` (`active`\|`inactive`) |
| `carl_create_domain` | "Create a new CARL domain with file and manifest entry." | `domain`, `description`, `recall`, `rules` |
**O ciclo de vida real confirmado por estes nomes de tool, sem qualquer inferência**: uma proposta
nasce por `carl_stage_proposal` (nunca directamente como regra); fica visível a um humano/revisor
via `carl_get_staged`; termina num de **três** destinos possíveis — `carl_approve_proposal`
(promovida a regra activa no domínio), `carl_archive_proposal` (guardada para referência, **nunca**
se torna regra), ou `carl_kill_proposal` (apagada sem deixar rasto). Este é exactamente o modelo de
três saídas (aprovado/arquivado/rejeitado) que se propõe adoptar para `remember` (secção 2.3).
### 2.2 O fluxo CARL v2 real (`carl.json` único) `[REAL]`
Uma segunda geração do mesmo sistema, também real e chamável nesta sessão (prefixo
`carl_v2_*`), que difere em dois pontos relevantes para o desenho de `remember`:
| Tool MCP real (v2) | Descrição literal | Diferença face à v1 |
|---|---|---|
| `carl_v2_stage_proposal` | "Stage a rule proposal in carl.json staging array." | Mesmo conceito, `source` agora opcional (default `manual`) |
| `carl_v2_get_staged` | "List all staged rule proposals from carl.json." | Igual em espírito |
| `carl_v2_approve_proposal` | "Approve a staged proposal — adds rule to target domain and removes from staging." | `id` no formato `stg-001` (não `prop-001`) |
| `carl_v2_reject_proposal` | "Reject (kill) a staged proposal — marks status=rejected, keeps it in staging as an audit trail (does NOT add any rule)." | **Diferença arquitectural real e significativa**: em vez de apagar (como `carl_kill_proposal` v1), o v2 **preserva a entrada rejeitada** com um campo `status='rejected'` — a rejeição fica auditável, não desaparece |
| `carl_v2_get_domain` | "Get a full domain object from carl.json including rules, decisions, recall, state." | Devolve regras + decisões + `recall` + `state` num único objecto — mais próximo do que `recall` (secção 1) precisaria de devolver de uma vez |
| `carl_v2_list_domains` | "List all CARL domains from carl.json with rule counts, decision counts, state, and always_on flag." | Introduz `always_on` (domínios que carregam sempre, independentemente de keyword de recall) — precedente directo para a distinção "guidance global do site" vs "guidance específica de um contexto" |
| `carl_v2_add_rule` | "Add a rule to a domain in carl.json. Auto-assigns next sequential ID." | Escrita **directa**, sem staging — existe em paralelo ao fluxo com aprovação, para uso humano/administrativo explícito |
**Achado relevante para o desenho de `remember`**: a existência de **duas gerações coexistentes**
do mesmo sistema de governança (v1 ficheiro-por-domínio, v2 `carl.json` único) é, ela própria, um
sinal a não ignorar numa réplica — mostra que um modelo de dados de "staging de regras" tende a
evoluir (aqui, de N ficheiros para 1 documento único com contadores agregados) à medida que o
volume de domínios cresce. Uma implementação de `remember` desde o início beneficiaria de escolher
logo o modelo v2 (um único documento JSON por site, com `staged[]` + domínios com `rules[]` +
`decisions[]` + `recall[]` + `state` + `always_on`), evitando a migração que o CARL real precisou
de fazer.
### 2.3 Desenho proposto para `remember` `[DESENHO PRÓPRIO, mapeado 1:1 sobre o fluxo CARL real]`
| Área | O que cobre | Fluxo CARL real usado como modelo | Nível de risco |
|---|---|---|---|
| Propor uma entrada | `remember({type, domain?, text, rationale})` — nunca escreve directamente; cria sempre um registo com estado inicial `pending` | `carl_stage_proposal`/`carl_v2_stage_proposal` — mesmo padrão de "escrita nunca chega directa ao alvo" | write, **não-destructive**, não-idempotent (cada chamada cria uma nova proposta, mesmo repetida) |
| Listar pendentes (uso interno pela UI de aprovação, não necessariamente exposta como tool MCP separada) | Equivalente a `carl_get_staged`/`carl_v2_get_staged` | mesma fonte | readonly |
| Aprovar (**exclusivamente UI de admin, nunca MCP** — ver 2.4) | Promove `pending`→`approved`; só depois disto entra no que `recall` devolve | `carl_approve_proposal`/`carl_v2_approve_proposal` | write, **fora do protocolo MCP** |
| Rejeitar com auditoria (**exclusivamente UI de admin**) | Recomenda-se o comportamento v2 (`carl_v2_reject_proposal`): marca `status:'rejected'` mas **preserva** a entrada, em vez de apagar (`carl_kill_proposal` v1) — auditabilidade é mais valiosa do que limpeza para um sistema que pode influenciar decisões futuras de um agente | `carl_v2_reject_proposal`, citação directa: *"keeps it in staging as an audit trail (does NOT add any rule)"* | write, **fora do protocolo MCP** |
**`type` proposto** (`guardrail`\|`fact`\|`convention`\|`instruction`) reproduz literalmente a
enumeração da própria promessa da tool Pro ("guardrail/fact/convention/instruction") — os quatro
termos usados na descrição do screenshot mapeiam directamente para os dois tipos de conteúdo que o
CARL real já distingue: **regras** (`carl_stage_proposal`/`add_rule` — mais próximo de
`guardrail`/`convention`/`instruction`, afirmações prescritivas de "como agir") e **decisões**
(`carl_log_decision` — mais próximo de `fact`, um registo factual de "o que foi decidido e
porquê", já com `rationale`+`recall` no schema real). Uma implementação completa de `remember`
deveria, portanto, decidir internamente para qual dos dois sub-sistemas encaminhar consoante o
`type`, em vez de tratar as quatro categorias como um único blob indiferenciado.
### 2.4 A decisão de design central: `remember` nunca aprova a si própria
**Justificação, cruzando os dois precedentes reais já confirmados nesta série** para "código/regra
gerado por IA que precisa de portão humano antes de ter efeito":
- Themer PHP (`docs/04-THEMER.md` §11, citação directa): *"AI authors + validates DRAFT PHP
templates; there is intentionally no attach tool — a human selects a template in the Themer
metabox (the execution gate)"*.
- PHP Snippets (`docs/06-SANDBOX-CUSTOM-CODE.md` §1, citação directa): *"There is intentionally no
'activate' tool: a snippet created via MCP is an inactive draft until a human administrator
reviews it and activates it in the Sandbox admin screen."*
O CARL real reforça exactamente o mesmo princípio noutro domínio (não código PHP, mas *regras de
governança que alteram o comportamento futuro de agentes*): `carl_stage_proposal` nunca escreve a
regra final por si — só `carl_approve_proposal` o faz, e nada nas descrições das tools reais
sugere que a própria IA que propôs a regra a possa aprovar dentro do mesmo fluxo MCP. **A promessa
literal da tool Pro confirma isto de forma independente**: "Stored pending until a human approves
it" não deixa ambiguidade — não há tool `approve` no catálogo de 3 mostrado na captura de ecrã.
**Consistência tripla** (Themer PHP real + PHP Snippets real + a própria descrição da tool Pro):
uma réplica de `remember` deve, tal como estas três fontes convergem, **nunca** expor uma ability
MCP `approve-guidance`/`remember-approve` — a aprovação vive exclusivamente na UI de admin, com o
mesmo mecanismo de nonce+sessão humana já usado por `Themer_Metabox::save()`
(`docs/04-THEMER.md` §7) e pelo handler AJAX de `PHP_Snippet_Store::set_status()`
(`docs/06-SANDBOX-CUSTOM-CODE.md` §3.1).
**Tensão explícita a registar** (paralela à da secção 6.5 do doc 12 sobre `set-widget-status`): o
catálogo de 3 tools do screenshot **não inclui** nenhuma tool de aprovação — o que é, na verdade,
uma confirmação a favor desta decisão, não uma tensão como no caso do Widget Builder (onde
`set-widget-status` aparecia no catálogo Pro e ficava ambíguo se aceitaria `'active'`). Aqui os
três nomes de tool observados (`recall`, `remember`, `save-session-summary`) já são, por si só,
evidência de que o EMCP Pro **não** expõe uma quarta tool `approve-guidance` — reforça a decisão
de desenho em vez de a contestar.
---
## 3. `save-session-summary` — registar um resumo de sessão com digest factual anexado
**Promessa da tool (screenshot, PRO):** *"Record a session summary; the plugin attaches a factual
digest of the actual changes."*
A frase-chave é *"a factual digest of the **actual** changes"* — o plugin não confia no resumo
narrativo do agente por si só, **anexa por conta própria** uma prova verificável do que realmente
mudou. Este é o único ponto das 3 tools onde o ecossistema Descomplicar tem **dois** precedentes
reais complementares e não sobrepostos: um sobre *como avaliar se um resultado é real* (SPEC-A) e
outro sobre *onde/como um digest de alterações já é persistido de forma auditável* (o change
ledger, código real do próprio `emcp-tools`).
### 3.1 Fundamentação `[REAL]` #1 — SPEC-A: avaliação de resultado real, não execução nominal
O Pipeline de Qualidade Total do ecossistema (`Hub/04-Stack/02.04-Sistemas/PIPELINE-QUALIDADE-TOTAL.md`)
documenta um sistema chamado **SPEC-A** ("Avaliação de Resultados"), já implementado e a correr em
produção, cujo propósito é exactamente o que a tool Pro promete: não aceitar a alegação de sucesso
de uma acção pelo valor nominal, mas verificar o resultado real. Citações directas:
> *"stack-observer→classify→fingerprint→propostas CARL; **SPEC-A (Avaliação de Resultados) merged
> com baseline T0**; cron `observer-cc` semanal (2ª 08:30)"* (secção 06. SelfImprovement)
> *"**Errata 03-07-2026 (F3.1+F3.2):** L1/F-CODE-02 **fechada** — colector `observer/action_eval.py`
> (commit `38ecc03`) apresenta cada linha da action-log ao **juiz SPEC-A** →
> `evaluations(source='action', entity_id=action_id)` + `actions.result_real`; backfill 5150/5150
> acções (10-jun→03-jul), **130 divergências nominal≠real**; consumidores em
> `COALESCE(result_real, result)`, defaults `pending`, `result` = sensor."*
> *"**Lacunas declaradas:** L1 — `action-log.result` hardcoded `success` (execução ≠ resultado real;
> F-CODE-02)"* — ou seja, a lacuna real que o SPEC-A veio fechar era EXACTAMENTE "o sistema achava
que tudo tinha corrido bem só porque a acção correu até ao fim, sem verificar se o resultado era
o pretendido" — a mesma distinção que "factual digest of the **actual** changes" (não do que o
agente *disse* que mudou) descreve para `save-session-summary`.
**Mapeamento directo:** `result` (sensor/execução nominal, sempre existiu) vs `result_real` (juízo
SPEC-A sobre o resultado verificado, `COALESCE(result_real, result)` como padrão de consumo — usa
o valor verificado quando existe, cai para o nominal quando ainda não foi avaliado) é o precedente
real exacto para a distinção que `save-session-summary` deveria fazer entre "o resumo que o agente
escreveu" (nominal, o que o agente *diz* que fez) e "o digest factual anexado pelo plugin" (real, o
que de facto mudou, verificável independentemente da narrativa do agente).
### 3.2 Fundamentação `[REAL]` #2 — o change ledger como fonte do "digest factual"
`docs/05-REDIRECTS-SEARCH-LEDGER.md` §4 já documentou, por leitura directa de código real do
`emcp-tools`, exactamente o mecanismo que produziria um "digest factual das alterações reais" sem
precisar de nenhuma lógica nova: o **change ledger unificado**
(`EMCP_Tools_Change_Log`/`Change_Recorder`/`Change_Blobs`), já activo e já a registar **toda**
escrita relevante do plugin (Elementor, filesystem, BD, posts/CPT, settings, redirects,
utilizadores, ACF, media) numa única sequência cronológica, com `id, ts, user_login, domain,
action, target, summary`.
**A implicação directa para `save-session-summary`**: em vez de o plugin ter de "adivinhar" o que
mudou numa sessão (uma tarefa de detecção de estado potencialmente frágil), pode simplesmente
**consultar o próprio ledger** entre o timestamp de início e fim da sessão — `list-changes` já
devolve exactamente essa lista, com `summary` e `target` por entrada, e já é ordenado
cronologicamente (`array_reverse`, mais recente primeiro, confirmado em `docs/05` §4.1). O
"digest factual" da promessa Pro não precisa de ser um subsistema novo: é uma **agregação sobre o
ledger já existente**, filtrado pela janela temporal da sessão.
### 3.3 Fundamentação `[REAL]` #3 — precedentes de skills reais do ecossistema
O catálogo de skills deste ambiente (visível na lista completa de skills disponíveis nesta sessão)
contém dois precedentes directos, com descrições literais que se sobrepõem quase totalmente à
promessa de `save-session-summary`:
- **`/worklog`** (e o seu alias `/reflect`): *"Registo de trabalho e reflexão unificado. Analisa
sessão, regista trabalho, identifica padrões, sugere acções, higieniza documentação Hub. (…)
Usar quando (…) 'registar trabalho', 'log', ao parar timer."* — o padrão "regista o que aconteceu
numa sessão, no fim dela", já real e usado.
- **`/qw`**: *"Recapitulação rápida de sessão — resumo conciso do trabalho feito, actualização de
docs e memória mem0. Uso: /qw ao finalizar tarefa ou sessão curta. Complemento leve ao
/worklog."* — nota-se explicitamente que actualiza "memória mem0", ou seja, este ecossistema já
liga "resumir uma sessão curta" a "persistir esse resumo em memória cross-agent" — exactamente a
cadeia `save-session-summary`→`recall` proposta para o EMCP Pro.
- **`/report`**: *"Report 5W2H+PDCA ao terminar tarefa/etapa — estrutura formal de conclusão com
análise de resultados, documentação e memória. **Integrado no domínio TASK-COMPLETION-REPORT do
CARL.**"* — **achado relevante**: o próprio ecossistema já tem um **domínio CARL dedicado a
relatórios de conclusão de tarefa** (`TASK-COMPLETION-REPORT`), confirmando que a família CARL
não serve só para "regras/decisões" (secção 2), serve também como destino natural de resumos de
conclusão estruturados — um precedente real e directo para tratar `save-session-summary` como um
**terceiro tipo de entrada CARL** (ao lado de rules e decisions), em vez de um subsistema
totalmente separado.
### 3.4 Desenho proposto para `save-session-summary` `[DESENHO PRÓPRIO, sobre 3 fontes [REAL]]`
| Área | O que cobre | Fonte real usada como modelo | Nível de risco |
|---|---|---|---|
| Registar o resumo narrativo do agente | `save-session-summary({narrative, session_start?, session_end?})` — texto livre, o que o agente *diz* que fez | Análogo ao campo `result` (nominal) de `actions` no SPEC-A — nunca descartado, mas nunca tratado como única fonte de verdade | write, não-destructive |
| Anexar o digest factual ("actual changes") | Consulta o change ledger (`EMCP_Tools_Change_Log::all()`/`list-changes`, `docs/05` §4.1-4.2) filtrado pela janela temporal da sessão; agrega por `domain`+`action`, conta entradas, lista `target`s únicos | `docs/05-REDIRECTS-SEARCH-LEDGER.md` §4 — reutilização directa de infra-estrutura já existente e já real, não um subsistema novo | readonly (a consulta em si; a gravação do resumo é write) |
| Divergência nominal≠real | Se o `narrative` do agente afirmar uma alteração (ex. "apaguei o redirect X") sem entrada correspondente no ledger na janela temporal, ou vice-versa, marcar a entrada com um flag `divergence:true` — precedente directo: SPEC-A já regista "130 divergências nominal≠real" como métrica de primeira classe, não como excepção a ignorar | `PIPELINE-QUALIDADE-TOTAL.md`, citação já dada em 3.1 | — |
| Alimentar `recall` | Os N resumos mais recentes (com digest anexado) entram directamente no que `recall` (secção 1) devolve — sem portão de aprovação humana explícito, ao contrário de `remember` | `[DESENHO PRÓPRIO]` — decisão de design explícita, ver 3.5 | — |
### 3.5 Porque `save-session-summary` (ao contrário de `remember`) não precisa de aprovação humana
Distinção de risco deliberada: um resumo de sessão é, por desenho, **descritivo e retrospectivo**
("o que aconteceu"), ancorado num facto verificável (o change ledger, secção 3.2) — não é
**prescritivo e prospectivo** como uma `guidance` de `remember` ("o que fazer no futuro"). O risco
de um resumo de sessão errado é limitado (na pior hipótese, um `recall` futuro lê um resumo
impreciso, mas o digest factual anexado automaticamente pelo plugin — secção 3.2 — já mitiga isto,
porque não depende só da honestidade do agente); o risco de uma `guidance` aprovada erradamente é
muito maior, porque molda directamente decisões de escrita futuras. Esta assimetria de risco é o
mesmo raciocínio, aplicado ao domínio inverso, que levou a secção 2.4 a exigir aprovação só para
`remember`.
---
## 4. Modelo de dados proposto — o que uma "memória de projecto" guarda `[DESENHO PRÓPRIO, sobre schema CARL real]`
O modelo de estados abaixo é, deliberadamente, **um mapeamento quase 1:1 sobre o CARL v2 real**
(secção 2.2) — porque replicar um modelo já validado em produção, com uma migração de geração já
feita e documentada (v1 ficheiro-por-domínio → v2 documento único), evita repetir esse mesmo custo
de evolução numa réplica que começasse do zero com o modelo mais simples (v1).
```json
{
"guidance": [
{
"id": "gm-014",
"type": "guardrail", // guardrail | fact | convention | instruction
"domain": "checkout", // livre, análogo aos domínios CARL (ex. GLOBAL, DEVELOPMENT)
"text": "Nunca activar Stripe neste site — cliente só usa Multibanco/MB Way.",
"rationale": "Pedido explícito do cliente em 2026-05-12, confirmado por email.",
"recall": ["stripe", "gateway de pagamento", "multibanco"],
"status": "approved", // pending | approved | rejected | archived
"source": "manual", // manual | agent_proposal | session_summary_derived
"proposed_by": "agent-run-8821",
"proposed_at": "2026-08-19T10:03:00Z",
"reviewed_by": "emanuel", // preenchido só após aprovação/rejeição humana
"reviewed_at": "2026-08-19T14:20:00Z"
}
],
"session_summaries": [
{
"id": "ss-0091",
"session_start": "2026-08-19T09:00:00Z",
"session_end": "2026-08-19T09:47:00Z",
"narrative": "Corrigido bug de redirect em loop no checkout; actualizado texto da página de contactos.",
"digest": {
"source": "change_ledger",
"entries_count": 3,
"by_domain": { "redirect": 1, "content": 2 },
"targets": ["redirect#44", "post#812"],
"divergence": false
},
"agent": "agent-run-8821"
}
]
}
```
### 4.1 Correspondência campo-a-campo com o CARL real
| Campo proposto | Fundamentação | Equivalente CARL real |
|---|---|---|
| `id` | `[DESENHO PRÓPRIO]`, formato inspirado directamente nos ids reais observados nas descrições das próprias tools (`prop-001` v1, `stg-001` v2) | `carl_approve_proposal.id` / `carl_v2_approve_proposal.id` |
| `type` | `[REAL]` — os 4 valores vêm literalmente da descrição da tool Pro ("guardrail/fact/convention/instruction") | — (a própria captura de ecrã) |
| `domain` | `[REAL]` — conceito directo dos domínios CARL (`GLOBAL`, `DEVELOPMENT`, `PROJECTS`, `CONTENT`, exemplos vistos nas descrições reais das tools `carl_get_domain_rules`/`carl_v2_get_domain`) | `domain` em `carl_stage_proposal`/`carl_log_decision`/`carl_v2_stage_proposal` |
| `recall` | `[REAL]` — campo com o mesmo nome exacto em `carl_log_decision`/`carl_v2_log_decision` ("Comma-separated recall keywords"/"Comma-separated keywords for when to recall this decision") e em `carl_create_domain`/`carl_v2_create_domain` (recall keywords do próprio domínio) | `recall` em múltiplas tools CARL reais |
| `status: pending\|approved\|rejected\|archived` | `[REAL, com uma correcção sobre a v1]` — a v1 tem só 3 saídas efectivas (approve/archive/kill-delete); o `status:'rejected'` **preservado** (não apagado) é especificamente o comportamento v2, citação directa já dada em 2.3: *"marks status=rejected, keeps it in staging as an audit trail"* — este documento recomenda o comportamento v2 (preservar) sobre o v1 (apagar) | `carl_v2_reject_proposal` |
| `source: manual\|agent_proposal\|session_summary_derived` | `[DESENHO PRÓPRIO]` — o terceiro valor (`session_summary_derived`) é a extensão própria deste blueprint: uma `guidance` pode nascer não de uma proposta directa (`remember`), mas de um padrão detectado em vários `session_summaries` (ex. "o agente corrigiu o mesmo tipo de bug 3 vezes" → proposta automática de um `guardrail`) — o precedente real mais próximo é o `source` real `psmm` do CARL ("Proactive Session Memory Mining", inferido do nome da enum em `carl_stage_proposal.source`, não confirmado em detalhe nesta tarefa, mas o padrão "a proposta pode vir de mineração de sessões passadas, não só de pedido directo" já existe no CARL real) | `source` (enum `psmm`\|`decisions`\|`manual`) em `carl_stage_proposal` |
| `session_summaries[].digest` | `[DESENHO PRÓPRIO]` — a estrutura em si; a **fonte** dos dados (`source:'change_ledger'`) é `[REAL]`, ver secção 3.2 | `EMCP_Tools_Change_Log::all()` |
| `session_summaries[].digest.divergence` | `[DESENHO PRÓPRIO]` — o campo; o **conceito** (nominal ≠ real) é `[REAL]`, SPEC-A, secção 3.1 | `actions.result` vs `actions.result_real`, `COALESCE()` |
### 4.2 Evolução de estados — paralelo directo ao CARL
```
remember() aprovação humana (UI, nunca MCP)
(pending) ─────────────────► [pending] ──────────────────────────────────► [approved]
│ │
│ rejeição humana (UI, nunca MCP) │ recall() lê SÓ aqui
▼ ▼
[rejected] (visível a recall)
(preservado, auditável,
nunca vira regra — v2)
│ arquivar (referência, nunca activa)
▼
[archived]
```
Este diagrama de estados é uma transcrição directa, para o domínio "Project Memory", do
comportamento real confirmado nas descrições das 5 tools CARL de gestão de propostas citadas em
2.1-2.2 (`stage`/`get_staged`/`approve`/`archive`/`reject-ou-kill`) — nenhum estado ou transição
aqui é inventado sem correspondência directa numa tool CARL real.
---
## 5. Blueprint para réplica
### Reaproveitar quase 1:1 (infra-estrutura já real, `[REAL]`)
1. **O modelo de estados staging→aprovação do CARL** (secção 2, 4) — não inventar um novo
vocabulário de estados; usar exactamente `pending`/`approved`/`rejected`/`archived` e o
princípio "rejeitar preserva para auditoria, não apaga" (comportamento v2, secção 2.2) desde o
primeiro dia, evitando a migração v1→v2 que o CARL real precisou de fazer.
2. **O change ledger unificado como fonte de "digest factual"** (`docs/05-REDIRECTS-SEARCH-LEDGER.md`
§4, `EMCP_Tools_Change_Log`) — `save-session-summary` não precisa de nenhuma lógica nova de
detecção de alterações; é uma consulta agregada sobre infra-estrutura que já existe e já está
documentada nesta série. Reaproveitar directamente `list-changes` filtrado por janela temporal.
3. **O padrão "a flag `partial`/`divergence` é responsabilidade do produtor, não do consumidor"**
(`docs/05` §4.4, sobre `record_db()`) — aplicado aqui à flag `divergence` do digest: quem
constrói o resumo de sessão marca-a explicitamente quando a narrativa e o ledger não batem
certo, o consumidor (`recall`) só propaga.
4. **A ausência deliberada de uma tool `approve`/`activate` no protocolo MCP** — o padrão mais
repetido e mais bem confirmado desta série inteira (Themer PHP, PHP Snippets, e agora também o
próprio CARL real e a própria descrição da tool Pro `remember`, todos convergentes): qualquer
escrita que altere o comportamento futuro de um agente de IA a partir de conteúdo proposto por
um agente de IA deve ter o portão de aprovação **fora** do protocolo MCP, com sessão humana +
nonce (padrão exacto de `Themer_Metabox::save()`, `docs/04-THEMER.md` §7).
### Construir de raiz (`[DESENHO PRÓPRIO]`, sequência recomendada por dependência)
1. **Modelo de dados** (secção 4) primeiro — um único documento JSON por site (seguindo o modelo
v2 do CARL, não o v1 por-ficheiro), com `guidance[]` + `session_summaries[]`; evita a migração
estrutural que o CARL real teve de fazer.
2. **`recall`** — a mais simples das três, é uma leitura filtrada (`status='approved'` +
`session_summaries` mais recentes); implementável e testável isoladamente sem nenhuma escrita.
3. **Ligação ao change ledger** — antes de `save-session-summary`, expor um método interno
`changes_in_window(start, end)` sobre `EMCP_Tools_Change_Log::all()` (código já existe, doc 05);
este é o único bloco de dependência real de código do próprio `emcp-tools`.
4. **`save-session-summary`** — sem portão de aprovação humana (secção 3.5); grava directamente,
com o digest anexado a partir do passo 3.
5. **`remember`** — por último, porque é o único dos três com uma superfície de admin
obrigatória (a UI de aprovação humana) a construir em paralelo; sem essa UI, `remember` cria
propostas que nunca podem sair de `pending` — inútil sem ela.
6. **Detecção de padrões cross-sessão** (`source:'session_summary_derived'`, secção 4.1) — feature
avançada, deixar para uma segunda iteração; o precedente real mais próximo (`psmm` como um dos
três valores reais do enum `source` de `carl_stage_proposal`) sugere que o próprio CARL trata
isto como um caminho de proposta distinto e não trivial, não uma extensão simples do fluxo
manual.
### Deixar de fora ou adiar explicitamente
- **Qualquer tool de aprovação/activação via MCP** (`approve-guidance`, `activate-guidance`, etc.)
— nunca implementar, independentemente de pressão de conveniência; é a decisão de design mais
repetida e mais bem fundamentada de toda a série de documentos EMCP (docs 04, 06, 12 e agora
este).
- **Reranking semântico de `recall`** — o precedente real mais próximo (`EMCP_Tools_Search_Ranker`,
`docs/05` §2.3) já deixa um "seam" explícito no próprio código real do plugin para um reranker
com embeddings como upgrade Pro futuro ("*This is the seam for an embedding-backed reranker (a
future Pro upgrade); the lexical order is the default*"); uma primeira implementação de `recall`
deveria seguir exactamente o mesmo princípio — ordenação lexical/determinística por omissão
(recência para `session_summaries`, correspondência exacta de `recall` keywords para
`guidance`), com um filtro extensível para um reranker semântico mais tarde, sem bloquear o v1
nessa dependência.
- **Migração automática entre gerações de schema** (o equivalente ao `maybe_migrate()` de
`EMCP_Tools_Sandbox_Paths`, `docs/06-SANDBOX-CUSTOM-CODE.md` §3.4, que existe só porque o produto
real mudou de local a meio da vida) — não é necessária numa implementação de raiz que já comece
com o modelo de dados da secção 4 (inspirado directamente na geração v2, mais recente, do CARL).
---
## 6. Fonte
**Fonte A — identidade operacional deste ambiente OMP (lida integralmente nesta sessão):**
- `/home/ealmeida/.omp/agent/AGENTS.md` — ficheiro de import; conteúdo próprio limitado a uma
política de tokens/segredos em sessão, não relevante a este documento.
- `/media/ealmeida/Dados/Hub/04-Stack/02.04-Sistemas/AGENTS.md` (documento canónico importado pelo
anterior) — secção 2 ("HIERARQUIA DE FONTES", regras NLM-first e "nunca confiar em docs sem
verificar"), secção 4 ("ECOSSISTEMA", errata sobre as 22/26 regras CARL `GLOBAL`), secção 5
("MEMÓRIA", tabela completa de tiers Mem0/Hindsight, protocolo Wayland).
- `/media/ealmeida/Dados/Hub/04-Stack/02.04-Sistemas/PIPELINE-QUALIDADE-TOTAL.md` — secções sobre
o arco C6 (propostas CARL, "staging CARL funcional", "CARL v2 GLOBAL com 26 regras"), o arco C7
(SPEC-A, `action_eval`, `result_real`, `COALESCE(result_real, result)`, "130 divergências
nominal≠real"), e a secção 06.SelfImprovement ("SPEC-A (Avaliação de Resultados) merged com
baseline T0").
**Fonte B — ferramentas MCP reais, invocadas ou inspeccionadas directamente nesta sessão:**
- Servidor `carl-mcp` (v1, ficheiro-por-domínio): `carl_stage_proposal`, `carl_get_staged`
(chamada real, resultado `{pending_count:0, archived_count:0}` — sem propostas activas neste
projecto no momento da tarefa), `carl_get_manifest` (chamada real, resultado `{success:false,
"Manifest not found"}` — sem manifesto v1 inicializado neste projecto), `carl_approve_proposal`,
`carl_archive_proposal`, `carl_kill_proposal`, `carl_log_decision`, `carl_get_domain_rules`,
`carl_list_domains`, `carl_create_domain`, `carl_toggle_domain`, `carl_search_decisions`,
`carl_get_decisions`, `carl_archive_decision`, `carl_list_decision_domains` — descrições e
schemas de argumento lidos directamente da definição real da ferramenta, não paraseados de
documentação externa.
- Servidor `carl-mcp` (v2, `carl.json` único): `carl_v2_stage_proposal`, `carl_v2_get_staged`,
`carl_v2_approve_proposal`, `carl_v2_reject_proposal` (citação literal confirmada:
"marks status=rejected, keeps it in staging as an audit trail (does NOT add any rule)"),
`carl_v2_add_rule`, `carl_v2_remove_rule`, `carl_v2_replace_rules`, `carl_v2_log_decision`,
`carl_v2_archive_decision`, `carl_v2_search_decisions`, `carl_v2_get_domain`,
`carl_v2_list_domains`, `carl_v2_create_domain`, `carl_v2_toggle_domain`, `carl_v2_get_config`,
`carl_v2_update_config`.
- Servidor `mem0`: `mcp__mem_save_memory`, `mcp__mem_search_memories`, `mcp__mem_get_all_memories`,
`mcp__mem_get_memory`, `mcp__mem_update_memory`, `mcp__mem_delete_memory`,
`mcp__mem_delete_all_memories`, `mcp__mem_memory_history`, `mcp__mem_reset_memory` — usadas como
modelo do Tier 2 (secção 1.2).
- Catálogo de skills deste ambiente (lista completa disponível nesta sessão) — descrições literais
citadas de `/worklog`, `/reflect`, `/qw`, `/report` (secção 3.3), incluindo o achado do domínio
CARL `TASK-COMPLETION-REPORT` referenciado explicitamente na descrição real da skill `/report`.
**Cruzado com código real do próprio `emcp-tools`, já lido em sessões anteriores desta série (não
relido nesta tarefa):**
- `docs/05-REDIRECTS-SEARCH-LEDGER.md` §4 (integral) — `EMCP_Tools_Change_Log`,
`EMCP_Tools_Change_Recorder`, `EMCP_Tools_Change_Blobs`, `EMCP_Tools_Transaction_Abilities`,
usados como modelo para o "digest factual" de `save-session-summary` (secção 3.2) e como
precedente do padrão de flags-responsabilidade-do-produtor (secção 5).
- `docs/05-REDIRECTS-SEARCH-LEDGER.md` §2.3 — `EMCP_Tools_Search_Ranker`, citação sobre o "seam"
para reranking semântico futuro, usada em §5 ("Deixar de fora") como precedente para não
implementar reranking semântico em `recall` v1.
- `docs/04-THEMER.md` §7, §11 (integral) — `EMCP_Tools_Themer_Metabox::save()` (padrão de
aprovação humana com nonce), `EMCP_Tools_Themer_PHP_Abilities`/`Themer_PHP_Store` (citação
directa "there is intentionally no attach tool"), usados como precedente central da secção 2.4.
- `docs/06-SANDBOX-CUSTOM-CODE.md` §1, §3.1, §3.4 (integral) — `EMCP_Tools_PHP_Snippet_Abilities`
(citação directa "There is intentionally no 'activate' tool"), `EMCP_Tools_PHP_Snippet_Store::set_status()`
(portão de aprovação via handler AJAX admin, nunca MCP), `EMCP_Tools_Sandbox_Paths::maybe_migrate()`
(precedente citado em §5 para justificar não construir migração de schema de raiz).
- `docs/10-MODULOS-E-INVENTARIO-PRO.md` — padrão de `class_exists()`-gated com ficheiro Pro
fisicamente ausente da árvore Free, usado em §0 para justificar por que "Project Memory" não é
auditável directamente (mesmo padrão já confirmado exaustivamente para os outros ~30 módulos
Pro nesse documento, não retentado nesta tarefa).
- `docs/11-WOOCOMMERCE-BLUEPRINT.md` e `docs/12-WIDGET-BUILDER-BLUEPRINT.md` — usados como
referência de **estilo e formato** deste tipo de documento "blueprint, não auditoria" (secção 0
explícita com fontes numeradas, convenção `[REAL]`/`[DESENHO PRÓPRIO]`, tabelas de ability
proposta com coluna de nível de risco, secção final "Blueprint para réplica" estruturada em
copiar/construir/omitir, secção "Fonte" com ficheiros exactos e o que não foi lido).
**Não lido nesta tarefa (lacuna explícita):** qualquer código-fonte do EMCP Pro para "Project
Memory" (`class-project-memory-abilities.php` ou nome equivalente) — **fisicamente ausente da
árvore Free instalada**, mesmo padrão de ausência já confirmado exaustivamente para os outros
módulos Pro nesta série (`docs/10-MODULOS-E-INVENTARIO-PRO.md`), não retentado por leitura directa
nesta tarefa. A implementação interna real de `remember`/`recall`/`save-session-summary` — schema
de input exacto, mensagens de erro, se usa CPT ou tabela SQL própria, se tem tectos de
retenção/paginação como o change ledger (`MAX_COUNT=500`, `MAX_BYTES=2MB`, `docs/05` §4.2) — é
desconhecida e **não** deve ser assumida a partir deste blueprint; tudo aqui é proposta própria
fundamentada nos dois sistemas reais descritos acima, não uma transcrição do comportamento Pro
real.