From 2812cd79ba6aaa6a26f5c32ad35a52c908f07823 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Wed, 19 Aug 2026 07:58:31 +0100 Subject: [PATCH] docs: doc13 Forms Pro (WPForms+Fluent Forms) + doc14 Project Memory blueprints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- docs/13-FORMS-PRO-BLUEPRINT.md | 553 ++++++ docs/14-PROJECT-MEMORY-BLUEPRINT.md | 613 +++++++ docs/INDEX.md | 12 +- graphify-out/.graphify_labels.json | 4 +- graphify-out/2026-08-19/.graphify_labels.json | 12 + graphify-out/2026-08-19/GRAPH_REPORT.md | 103 ++ graphify-out/2026-08-19/graph.json | 1101 ++++++++++++ graphify-out/2026-08-19/manifest.json | 67 + graphify-out/GRAPH_REPORT.md | 66 +- ...5d75eb697c63d0e0e581182dc20db53127c36.json | 1 + ...7e48ca18f738e3523ffbcd6af292724cdafbf.json | 1 + graphify-out/cache/stat-index.json | 2 +- graphify-out/graph.html | 8 +- graphify-out/graph.json | 1556 +++++++++++------ graphify-out/manifest.json | 9 +- 15 files changed, 3535 insertions(+), 573 deletions(-) create mode 100644 docs/13-FORMS-PRO-BLUEPRINT.md create mode 100644 docs/14-PROJECT-MEMORY-BLUEPRINT.md create mode 100644 graphify-out/2026-08-19/.graphify_labels.json create mode 100644 graphify-out/2026-08-19/GRAPH_REPORT.md create mode 100644 graphify-out/2026-08-19/graph.json create mode 100644 graphify-out/2026-08-19/manifest.json create mode 100644 graphify-out/cache/ast/v0.9.6/03e68caf73760e3daf660ac7f435d75eb697c63d0e0e581182dc20db53127c36.json create mode 100644 graphify-out/cache/ast/v0.9.6/922b90021fe3c471cd76a515e327e48ca18f738e3523ffbcd6af292724cdafbf.json diff --git a/docs/13-FORMS-PRO-BLUEPRINT.md b/docs/13-FORMS-PRO-BLUEPRINT.md new file mode 100644 index 0000000..e6947b4 --- /dev/null +++ b/docs/13-FORMS-PRO-BLUEPRINT.md @@ -0,0 +1,553 @@ +# 13 — Forms Pro: blueprint de abilities MCP (WPForms + Fluent Forms) + +Fonte primária: leitura directa (19-08-2026) do **WPForms Lite 2.0.0.5** e do **Fluent Forms +(free) 6.2.12**, ambos instalados e **activos** em `ecommerce-demo.descomplicar.pt` +(`/home/ealmeida/ecommerce-demo.descomplicar.pt/wp-content/plugins/{wpforms-lite,fluentform}/`), +confirmado por `wp plugin list --format=json` antes de qualquer leitura de código (secção 6). +Cruzado com `docs/08-INTEGRACOES-TERCEIROS.md` §3-§4 (a classe base **real** e **Free** +`EMCP_Tools_Form_Integration` + a integração CF7 concreta, únicas peças do domínio "Forms" que +existem no código EMCP Tools instalado) e `docs/10-MODULOS-E-INVENTARIO-PRO.md` linhas 470-476 +(confirmação do gate `EMCP_Tools_WPForms_Integration`/`EMCP_Tools_FluentForms_Integration` +— ambas Pro-only, ficheiro ausente desta árvore). **Exclui por completo** SEO/Yoast/Rank +Math/WooCommerce, fora de âmbito. + +## 0. Panorama — porque este documento é diferente dos outros 12 + +Este documento tem a mesma forma que o 11 (WooCommerce) e o 12 (Widget Builder): a peça que +faltaria auditar — `EMCP_Tools_WPForms_Integration`/`EMCP_Tools_FluentForms_Integration` — está +**fisicamente ausente** desta árvore Free (confirmado em `docs/08` §7 e `docs/10` linhas 470-476: +referenciadas por `class_exists()` no `class-ability-registrar.php`, nunca `require_once`). +O que muda aqui é a base sobre a qual se propõe o desenho: existe, **e é código real, Free, já +lido na íntegra**, uma classe abstracta partilhada `EMCP_Tools_Form_Integration` +(`includes/abilities/forms/class-form-integration.php`, doc08 §3) da qual **uma** integração +concreta real herda — `EMCP_Tools_CF7_Integration` (doc08 §4). WPForms e Fluent Forms seriam, +numa implementação real do EMCP Pro, mais duas classes que estendem a MESMA base — não um +desenho paralelo. Este documento não reinventa o dispatcher; reaproveita o contrato já confirmado +no doc08 e preenche as duas células concretas que faltam. + +Três fontes fundamentam cada afirmação abaixo, e cada tabela di-lo explicitamente: + +1. **A classe base + CF7, código real Free já lido** (`docs/08-INTEGRACOES-TERCEIROS.md` §3-§4) — + o contrato `id()/label()/is_active()/operations()`, o dispatcher `dispatch()`, a gate de + confirmação genérica (`arguments.confirm===true`), as capabilities coarse (`can_read()= + edit_posts`, `can_write()=manage_options`), e a nota de que **`destructive=true` é o default do + tool `write` desta base específica** (diferente de ACF/Meta Box/SEO) — citado tal-qual do doc08. +2. **O catálogo de 4 tools/11 operações da captura de ecrã** partilhada pelo utilizador — usado + **apenas** como especificação da API-alvo (nomes de tool, descrições, lista de operações), + nunca como fonte de schema ou de comportamento interno. Citado abaixo tal-qual foi fornecido, + com a marcação `[CAPTURA DE ECRÃ]`. +3. **Leitura directa do código real de WPForms Lite e Fluent Forms** — os dois plugins que a + captura nomeia, ambos confirmados **instalados e activos** no mesmo site do bundle Descomplicar + (`ecommerce-demo.descomplicar.pt`), e lidos ao nível dos métodos concretos que uma implementação + real teria de chamar. Secções 1 e 2. + +> **Convenção**: `[REAL]` = confirmado por leitura de código (EMCP Free, WPForms Lite ou Fluent +> Forms). `[CAPTURA DE ECRÃ]` = vem apenas da imagem partilhada pelo utilizador (nome do tool, +> descrição, lista de operações) — usada como especificação-alvo, não como fonte de comportamento. +> `[DESENHO PRÓPRIO]` = proposta nossa sem equivalente confirmado em nenhuma das duas fontes +> anteriores. + +**A descoberta mais importante deste documento**: ao ler o código de Fluent Forms para fundamentar +a tabela de ability proposta, descobriu-se que a versão instalada (6.2.12) **já embarca o seu +próprio servidor MCP nativo** — `FluentForm\App\Modules\MCP\AbilitiesRegistrar`, registado via +`wp_register_ability()` (a mesma API core que o EMCP Tools usa), com 9 abilities reais, um padrão +dry-run+confirm-token mais rigoroso do que qualquer coisa documentada nesta série até agora, e um +modelo de permissões (`Acl`) próprio. Isto **não é o EMCP Tools** — é uma superfície MCP +completamente independente e paralela, que o próprio Fluent Forms passou a incluir. A secção 2.3 +documenta-a na íntegra porque muda a recomendação de blueprint: uma integração EMCP real para +Fluent Forms poderia **detectar e delegar** nesta camada nativa em vez de reimplementar CRUD do +zero — algo que não se aplica a nenhuma das outras integrações de terceiros desta série. **WPForms +Lite não tem nada equivalente** (confirmado por ausência de qualquer pasta/classe MCP na árvore +`src/` do plugin, secção 1). + +**Segunda distinção importante, também confirmada por leitura de código**: existem **dois eixos +free/pro independentes** em jogo aqui, não um. O eixo 1 é o do EMCP Tools em si (Free vs Pro) — já +documentado em doc08/doc10, é o que decide se `wpforms-read`/`wpforms-write` existem de todo como +abilities MCP. O eixo 2 é **interno a cada plugin de formulários** — WPForms Lite vs WPForms Pro — +e é **completamente ortogonal** ao primeiro: mesmo com o EMCP Tools Pro totalmente licenciado, a +operação `list-entries` de `wpforms-read` nunca teria dados para devolver contra uma instalação +WPForms **Lite**, porque a Lite genuinely não guarda submissões (secção 1.4). A frase da captura de +ecrã — *"entries require WPForms Pro"* — refere-se exactamente a este segundo eixo, e a secção 1.4 +confirma-a byte a byte no código lido. + +--- + +## 1. WPForms (Lite 2.0.0.5) + +### 1.1 Ficheiros lidos + +`includes/class-form.php` (`WPForms_Form_Handler`, integral), `src/WPForms.php` (bootstrap + +registry `obj()`, integral), `src/Access/Capabilities.php` (integral), +`includes/functions/access.php` (integral), `lite/wpforms-lite.php` (integral — bootstrap +específico da build Lite, incl. o painel de Entries com dados de amostra). + +### 1.2 O contrato de dados real: `WPForms_Form_Handler` `[REAL]` + +Registado em `wpforms()->obj('form')` (só `'form'` e `'process'` são registados no `objects()` da +classe principal — ver 1.4). Um "formulário" WPForms é um `WP_Post` do CPT `wpforms` (ou +`wpforms-template`), com o formulário inteiro (campos, definições, notificações, confirmações) +serializado em `post_content` (JSON via `wpforms_encode()`/`wpforms_decode()`), não em postmeta +individual. + +| Método | O que faz | Nota | +|---|---|---| +| `get( $id = '', $args = [] )` | Sem `$id`: `get_multiple()` (lista, `WP_Query`-like via `get_posts()`, aceita `search`/`post_status`/etc.). Com `$id`: `get_single()` — devolve `WP_Post` ou, com `content_only:true`, o array JSON decodificado | Filtro de gate: se `$args['cap']` fornecida (ou detectada automaticamente via `access_obj->init_allowed()`), chama `wpforms_current_user_can($cap, $id)` antes de devolver | +| `add( $title, $args, $data )` | Cria um formulário novo (post + `post_content` inicial); requer capability `create_forms` | Se criado fora do form builder (`data.builder===false`), popula notificação/confirmação por omissão automaticamente | +| `update( $form_id, $data, $args )` | Substitui o `post_content` inteiro por `wpforms_encode($data)`, preservando `meta` e `fields[].meta` do estado anterior (`get_meta()`/`update__preserve_fields_meta()`) | Capability por omissão: `edit_form_single` | +| `delete( $ids )` | Apaga o post **definitivamente** (`wp_delete_post($id, true)` — sem trash), e em cascata `entry`/`entry_meta`/`entry_fields` **se esses objectos existirem no registry** (nunca existem em Lite — ver 1.4) | Capability: `delete_form_single` | +| `duplicate( $ids )` | Clona formulário(s), renomeia com sufixo `(ID #N)`, injecta avisos de "Zap desligado" se aplicável | Capability: `create_forms` para criar + `view_form_single` para ler o original | +| `update_status( $form_id, $status )` | Só aceita `publish`/`trash` (filtrável); é o mecanismo real de "apagar suavemente" um formulário | **Nota do código**: usa a capability `delete_form_single`, não `edit_form_single`, mesmo para restaurar — comentário explícito: "trash and restore are actually part of the deletion operation" | +| `get_meta`/`update_meta`/`delete_meta` | Ler/escrever/apagar uma chave dentro do bloco `meta` do formulário (usado para `category`/`subcategory`, entre outros) | Capability por omissão: `edit_form_single` | +| `next_field_id`, `get_field`, `get_field_meta` | Utilitários de builder — atribuição do próximo ID de campo, leitura de um campo/a sua meta | — | + +### 1.3 O colapso de capabilities em Lite: tudo vira `manage_options` `[REAL]` + +Citação directa e integral de `src/Access/Capabilities.php` (a classe real por trás de +`wpforms()->obj('access')`, que `wpforms_current_user_can()` chama): + +```php +public function current_user_can( $caps = [], $id = 0 ) { + return \current_user_can( \wpforms_get_capability_manage_options() ); +} +``` + +`wpforms_get_capability_manage_options()` devolve `'manage_options'` (filtrável, mas sem filtro +aplicado nesta instalação). **Independentemente do argumento `$caps` passado** — `create_forms`, +`edit_form_single`, `delete_form_single`, `view_form_single`, `view_own_forms`, +`view_others_forms`, etc. — o resultado é sempre o mesmo: `current_user_can('manage_options')`. +Esta é a implementação de `Access Controls` no Lite; a versão Pro do WPForms substitui esta classe +por uma com granularidade real por role (é uma feature Pro do **WPForms em si**, não do EMCP). + +**Implicação directa para o desenho da ability**: ao contrário do padrão documentado em `docs/08` +§0 para ACF/Meta Box/Forms ("gate coarse larga no MCP + gate fina por operação dentro do +`dispatch()`"), contra uma instalação **WPForms Lite** a gate fina É a gate coarse — não há +separação real de privilégio possível entre `list-forms` (deveria ser `edit_posts`-like) e +`delete-form` (deveria exigir mais) enquanto o alvo for Lite. Uma implementação honesta deveria +expor este facto ao agente (ex.: um campo `effective_gate: 'manage_options (WPForms Lite has no +granular Access Controls)'` na resposta de descoberta), em vez de fingir que os `perm` por operação +da tabela 1.6/1.7 têm efeito real nesta instalação concreta. + +### 1.4 "Entries": ausência real confirmada, não apenas mencionada na descrição `[REAL]` + +Duas confirmações independentes, ambas por leitura directa de código, provam que WPForms Lite +**não tem** armazenamento de submissões — não é uma limitação de licença que a API esconda, é +código genuinamente ausente: + +1. **O registry nunca regista `'entry'`.** `src/WPForms.php::objects()` (chamado em + `plugins_loaded`): + ```php + public function objects(): void { + $this->registry['form'] = new WPForms_Form_Handler(); + $this->registry['process'] = new WPForms_Process(); + do_action( 'wpforms_loaded' ); + } + ``` + Apenas `form` e `process`. `obj( 'entry' )`/`obj( 'entry_meta' )`/`obj( 'entry_fields' )` + devolvem sempre `null` (`return $this->registry[$name] ?? null;`) — o próprio + `WPForms_Form_Handler::delete()` já lida com isto defensivamente: + ```php + $entry_obj = wpforms()->obj( 'entry' ); + $entry_meta_obj = wpforms()->obj( 'entry_meta' ); + $entry_fields_obj = wpforms()->obj( 'entry_fields' ); + if ( $entry_obj && $entry_meta_obj && $entry_fields_obj ) { /* delete entries */ } + ``` + Em Lite este `if` é sempre falso — não há nada para apagar porque não há classe registada. +2. **A página admin "Entries" mostra dados FALSOS, codificados no plugin.** `lite/wpforms-lite.php`, + método `get_entries_list_data()`, devolve um array PHP fixo (`'Michael Johnson'`, + `'David Thompson'`, `'Sarah Parker'`, …) — 12 nomes hard-coded, nenhum vindo de base de dados — + apresentado com um CTA de upgrade. O comentário da UI é explícito: *"Display sample data and + notify user that entries is a pro feature."* + +**Conclusão directa para a ability proposta**: as operações `list-entries`/`get-entry` (secção +1.6) e `update-entry-status`/`delete-entry` (secção 1.7) da captura de ecrã **não têm nenhuma +superfície de código a auditar nesta instalação Lite** — a única grounding possível é negativa +(confirmar que genuinamente não existem), o que casa exactamente com o parêntesis da própria +descrição capturada: *"entries require WPForms Pro"*. + +### 1.5 Estrutura real de notificações e confirmações `[REAL]` + +De `lite/wpforms-lite.php::form_settings_notifications()`/`form_settings_confirmations()` — os +dois blocos do formulário guardados em `post_content.settings`: + +| Bloco | Chaves reais confirmadas | Nota | +|---|---|---| +| `notifications` (array indexado por ID, `'1'` = "Default Notification") | `email` (destinatário; suporta lista separada por vírgulas e smart tags `{admin_email}`/`{user_email}`), `carboncopy` (CC — só visível se a definição global `email-carbon-copy` estiver activa), `subject`, `sender_name`, `sender_address`, `replyto`, `message` (default `{all_fields}`) | Em Lite só a notificação `1` é editável na UI ("Add New Notification" é um `education-modal` — upsell); a estrutura de dados em si já suporta múltiplas | +| `confirmations` (array indexado por ID, `'1'` = "Default Confirmation") | `type` (`message`\|`page`\|`redirect`), `message`, `message_scroll` (bool), `page` (post ID), `page_url_parameters`, `redirect` (URL), `redirect_new_tab` (bool) | Mesma limitação de UI que notifications em Lite | + +### 1.6 Tabela de ability proposta — `emcp-tools/wpforms-read` + +**Descrição alvo `[CAPTURA DE ECRÃ]`**: "Read WPForms forms, fields, notifications, and entries +(entries require WPForms Pro)". PRO. READ-ONLY. 6 operações. + +| operação `[CAPTURA DE ECRÃ]` | Fundamentação `[REAL]` | Args propostos | Nível de risco | +|---|---|---|---| +| `list-forms` | `WPForms_Form_Handler::get( '', $args )` → `get_multiple()`; título/estado/contagem de campos derivados de `post_title`/`post_status`/`content_only` decode | `{ search?, status?, page?, per_page? }` | readonly | +| `get-form` | `get( $form_id, ['content_only'=>true] )` → devolve o array JSON completo: `fields[]`, `settings` (incl. `notifications`, `confirmations`), `meta` | `{ form_id }` | readonly | +| `list-notifications` | Subconjunto `settings.notifications` do form completo (secção 1.5) | `{ form_id }` | readonly | +| `get-settings` | Subconjunto `settings.confirmations` + campos gerais não-notificação de `settings` (`form_title`, `form_desc`, `submit_text`, etc.) | `{ form_id }` | readonly | +| `list-entries` | **Sem grounding possível nesta instalação** — `wpforms()->obj('entry')` é `null` em Lite (secção 1.4); a operação só teria dados numa instalação **WPForms Pro** real (código não presente em nenhum lado desta série) | `{ form_id, status?, page?, per_page? }` | readonly — **mas sempre devolveria `plugin_inactive`/equivalente contra Lite**, não uma lista vazia disfarçada de sucesso | +| `get-entry` | Idem — sem grounding; depende de `WPForms_Entry_Handler` (Pro), classe ausente de toda a árvore auditada nesta série | `{ entry_id }` | readonly — mesma nota | + +### 1.7 Tabela de ability proposta — `emcp-tools/wpforms-write` + +**Descrição alvo `[CAPTURA DE ECRÃ]`**: "Update WPForms notifications, set entry status, and +delete entries (confirm:true). Entry operations require WPForms Pro." PRO. DESTRUCTIVE. 3 +operações. + +| operação `[CAPTURA DE ECRÃ]` | Fundamentação `[REAL]` | Args propostos | Nível de risco | +|---|---|---|---| +| `update-notification` | `WPForms_Form_Handler::update( $form_id, $data )` com `$data['settings']['notifications'][$id]` alterado — a chamada real substitui o `post_content` inteiro, por isso uma implementação correcta tem de fazer merge no lado do EMCP: ler o form completo, alterar só a notificação alvo, escrever de volta | `{ form_id, notification_id, email?, carboncopy?, subject?, sender_name?, sender_address?, replyto?, message? }` | write, não-destructive por si (mas o tool inteiro herda `destructive=true` da base, secção 3) | +| `update-entry-status` | Sem grounding — depende de `entry`/`entry_meta` (Pro, ausentes) | `{ entry_id, status }` | write — sempre `plugin_inactive` contra Lite | +| `delete-entry` | Sem grounding — mesma ausência; a base `EMCP_Tools_Form_Integration::dispatch()` (doc08 §3.2) já suporta nativamente a gate `confirm:true` que a descrição da captura exige ("confirm:true") — esse mecanismo **já existe e é real**, mesmo que os dados que apagaria não existam em Lite | `{ entry_id, confirm: true }` | **destructive** — irreversível numa instalação Pro real | + +--- + +## 2. Fluent Forms (free 6.2.12) + +### 2.1 Ficheiros lidos + +`app/Models/Form.php`, `app/Models/Submission.php` (ambos integrais — ORM `FluentForm\Framework`, +tabelas `fluentform_forms`/`fluentform_submissions`), `app/Api/Form.php`, `app/Api/Entry.php` +(integrais — a fachada pública de leitura usada por shortcodes/relatórios internos), +`app/Http/Policies/FormPolicy.php`, `app/Http/Policies/SubmissionPolicy.php` (integrais), +`app/Http/Controllers/McpSettingsController.php` (integral), `app/Modules/MCP/ +AbilitiesRegistrar.php` (integral), `app/Modules/MCP/Tools/FormTools.php`, +`app/Modules/MCP/Tools/SubmissionTools.php` (integrais), `app/Modules/MCP/Support/ +PermissionGate.php`, `app/Modules/MCP/Support/WriteGuard.php` (integrais), +`app/Modules/Acl/Acl.php` (integral). + +### 2.2 O contrato de dados real: `Form`/`Submission` (ORM `FluentForm\Framework`) `[REAL]` + +Ao contrário do WPForms (post type + JSON em `post_content`), Fluent Forms usa **tabelas próprias +do plugin**: `fluentform_forms` (colunas confirmadas via docblock `@property`: `id, title, status, +appearance_settings, form_fields, has_payment, type, conditions, created_by, created_at, +updated_at`) e `fluentform_submissions` (`id, form_id, serial_number, response, source_url, +user_id, status, is_favourite, browser, device, ip, city, country, payment_status, payment_method, +payment_type, currency, payment_total, total_paid, created_at, updated_at`). `status` do +formulário: `published`/`unpublished` (confirmado em `Form::prepare()`, default `'published'`). +`status` da submissão: `unread`/`read`/`spam`/`trashed` (confirmado directamente na `SubmissionTools` +nativa — secção 2.3 — e em `Submission::countByGroup()`); `is_favourite` é um campo **separado** +(boolean), não um valor de `status`. + +`Form::remove($formId)` (estático) e `Submission::remove($submissionIds, $formId)` (estático, +agora **exige** `$formId` — `throw new \InvalidArgumentException` se omitido, um "fail-closed scope +guard" explícito no código) fazem cascata real de apagamento: meta, entry details, analytics, logs, +e (se pagamentos estiverem activos) order items/transactions/subscriptions. + +### 2.3 A descoberta central: Fluent Forms já embarca o seu próprio servidor MCP nativo `[REAL]` + +Não é uma integração de terceiros comum — é uma **superfície MCP paralela e independente do EMCP +Tools**, presente na versão 6.2.12 instalada, registada com a mesma API core WordPress +(`wp_register_ability()`) que o próprio EMCP Tools usa. A classe orquestradora é +`FluentForm\App\Modules\MCP\AbilitiesRegistrar` (citação directa do seu docblock): + +> "Single source of truth for every FluentForm MCP ability... Pro tools are NOT listed here — they +> push abilities via the `fluentform/mcp_loaded` action + `fluentform/mcp_ability_names` filter." + +**Estado ligado/desligado**: a feature vem **desligada por omissão** — `PermissionGate::isEnabled()` +lê a option dedicada `_fluentform_mcp_settings['enabled']==='yes'`, activável em FluentForm → +Settings → MCP (`McpSettingsController::toggle()`, exige `manage_options`). Requer também um +plugin adaptador MCP instalado (`fluent-toolkit` ou `mcp-adapter`) — nenhum dos dois está instalado +nesta instalação, por isso este servidor MCP nativo não está actualmente a correr em +`ecommerce-demo.descomplicar.pt`, mas o código das 9 abilities está completo e presente. + +**As 9 abilities reais registadas** (`FormTools` + `SubmissionTools`; há mais 6 classes +`IntegrationTools`/`StylingTools`/`FieldTools`/`NotificationTools`/`ReportTools`/`ContextTools` +não detalhadas aqui por estarem fora do âmbito "forms" directo desta tabela, mas seguem o mesmo +padrão): + +| Ability (nome real) | mode | `capability` real | Descrição (citação exacta do código) | +|---|---|---|---| +| `fluentform/list-forms` | read | `['fluentform_forms_manager', 'fluentform_dashboard_access']` (qualquer uma) | "Find and filter forms with compact rows (id, title, status, type, entry count)." | +| `fluentform/get-form` | read | idem | "Full detail for one form: status, type, timestamps, and the field schema." | +| `fluentform/create-form` | write | `fluentform_forms_manager` | Cria formulário a partir de título + lista de campos tipados | +| `fluentform/list-submissions` | read | `fluentform_entries_viewer` | "List and filter entries for one form (form_id required)." | +| `fluentform/get-submission` | read | `fluentform_entries_viewer` | "Full detail for one entry by id... fields as label/value pairs." | +| `fluentform/update-submission-status` | write | `fluentform_manage_entries` | `status` ∈ `{unread, read, spam, trashed}`; `trashed` é soft-delete reversível | +| `fluentform/add-submission-note` | write | `fluentform_manage_entries` | Nota interna de staff, não visível ao submissor | +| `fluentform/delete-submission` | write, **destructive** | `fluentform_manage_entries` | Apagamento **permanente**, irreversível | +| `fluentform/bulk-update-submissions` | write, **destructive** | `fluentform_manage_entries` | Acção em lote (`read`\|`unread`\|`trashed`\|`favorite`\|`unfavorite`\|`delete_permanently`), máx. 200 IDs por chamada | + +**O mecanismo de segurança mais rigoroso documentado nesta série inteira**: TODAS as 6 operações +de escrita (mesmo `add-submission-note`, que não parece destructive) passam por +`Mutation::runGuarded()`, que impõe um round-trip **dry-run → `confirm_token` → execução** — +citação directa do docblock de `WriteGuard`: + +> "EVERY write routes through `Mutation::runGuarded`, not just the destructive ones. The reason is +> prompt injection: entry field values are written by anonymous members of the public and land in +> the agent's context... The dry-run → confirm_token round-trip is the one mechanism here that +> forces a second pass through the operator before anything is written, so an instruction smuggled +> into a form submission cannot complete a write on its own." + +O token é vinculado a um **fingerprint do estado actual** da entidade (ex.: para +`update-submission-status`, o `status` actual faz parte da chave — um token gerado para +"aprovar mudar para `read`" nunca pode ser reaproveitado para `trashed`); expira em 300s +(`CONFIRM_TTL`); há ainda uma chave de idempotência opcional (`idempotency_key`, TTL 86400s) para +retries seguros, e um mecanismo de "claim" via `INSERT IGNORE` atómico em `wp_options` para +serializar execuções concorrentes do mesmo `(tool, entidade)`. Todo o texto de campos submetidos +por visitantes anónimos que chega ao agente é explicitamente delimitado com marcadores +`[[UNTRUSTED_USER_INPUT]]` (`MCPHelper::untrusted()`) antes de sair de `get-submission`/ +`list-submissions` — uma defesa directa contra prompt injection via conteúdo de formulário. + +**Nota de segurança honesta, citada do próprio código** (docblock de `PermissionGate`), sobre um +limite real deste modelo: `Acl::hasPermission()` concede qualquer permissão FluentForm (excepto +`fluentform_full_access`) a um utilizador cujo *role* WordPress tenha sido delegado via +"Managers" a nível de role — o que significa que um Editor com acesso FluentForm delegado por role +**passa a gate de capability em TODAS as ferramentas, incluindo `delete-submission`**, +independentemente da capability específica que essa ferramenta declara. Só utilizadores com +concessão **individual** (`Acl::attachPermissions()`, per-user) são de facto restringidos como as +declarações da tabela acima sugerem. Citação directa: *"the real boundary is 'authenticated +WordPress user with FluentForm access, restricted to their form scope' — NOT per-tool capability +separation. Do not describe it as the latter."* + +### 2.4 Capabilities reais / modelo `Acl` + +8 permissões nativas (`Acl::getPermissionSet()`): `fluentform_dashboard_access`, +`fluentform_forms_manager`, `fluentform_entries_viewer`, `fluentform_manage_entries`, +`fluentform_view_payments`, `fluentform_manage_payments`, `fluentform_settings_manager`, +`fluentform_full_access`. **Por omissão só a role `administrator` as recebe** — `Acl::setPermissions()` +adiciona as 8 capabilities apenas a `get_role('administrator')`; qualquer outro utilizador/role +precisa de concessão explícita via FluentForm → Settings → Managers. `manage_options` bypassa +sempre tudo (`hasExplicitFullAccess()`). + +### 2.5 Tabela de ability proposta — `emcp-tools/fluentforms-read` + +**Descrição alvo `[CAPTURA DE ECRÃ]`**: "Read Fluent Forms forms, fields, and submissions." PRO. +READ-ONLY. 4 operações. + +| operação `[CAPTURA DE ECRÃ]` | Fundamentação `[REAL]` | Equivalente nativo directo | Args propostos | +|---|---|---|---| +| `list-forms` | `Form` model + `Api\Form::forms()` (fachada pública já existente, paginação/pesquisa/filtro por `status`/`filter_by` embutidos) | **Mapeia 1:1** para a ability nativa `fluentform/list-forms` (secção 2.3) | `{ search?, status?, page?, per_page? }` | +| `get-form` | `Api\Form::find()`/`form()` + `FormFieldsParser`/`FormService::getInputsAndLabels()` para o schema de campos | **Mapeia 1:1** para `fluentform/get-form` | `{ form_id }` | +| `list-entries` | `Api\Entry::entries()` (fachada pública) ou `Submission::customQuery()`/`paginateEntries()` directamente | **Mapeia 1:1** para `fluentform/list-submissions` — inclui o mesmo enum `status ∈ {unread, read, spam, trashed, favorites}` | `{ form_id, status?, search?, date_from?, date_to?, page?, per_page? }` | +| `get-entry` | `Api\Entry::entry()`/`getFormattedEntry()` (label+valor por campo, resolve utilizador associado) | **Mapeia 1:1** para `fluentform/get-submission` | `{ entry_id }` | + +### 2.6 Tabela de ability proposta — `emcp-tools/fluentforms-write` + +**Descrição alvo `[CAPTURA DE ECRÃ]`**: "Set Fluent Forms submission status and delete submissions +(confirm:true)." PRO. DESTRUCTIVE. 2 operações. + +| operação `[CAPTURA DE ECRÃ]` | Fundamentação `[REAL]` | Equivalente nativo directo | Args propostos | +|---|---|---|---| +| `update-entry-status` | `Submission::amend($id, ['status'=>...])`, ou via a fachada `SubmissionService::updateStatus()` | **Mapeia 1:1** para `fluentform/update-submission-status` — mesmo enum `unread/read/spam/trashed`, mesma nota de que `trashed` é reversível | `{ entry_id, status, confirm: true }` | +| `delete-entry` | `Submission::remove($submissionIds, $formId)` (estático; agora exige `$formId` explícito — "fail-closed scope guard", citação directa do código) — cascata para meta/entry-details/logs/pagamentos | **Mapeia 1:1** para `fluentform/delete-submission` (`annotations.destructive=true` na base MCP) | `{ entry_id, form_id, confirm: true }` | + +**Nota de design que a captura já reflecte correctamente**: a descrição alvo `(confirm:true)` para +`fluentforms-write` casa exactamente com o mecanismo genérico já real na base +`EMCP_Tools_Form_Integration::dispatch()` (`arguments.confirm===true` obrigatório quando +`operations()[$op]['confirm']===true`, doc08 §3.2). O que o EMCP Tools faria de mais simples aqui +(gate binária de confirmação) já existe hoje na própria Fluent Forms de forma **mais forte** +(dry-run + token vinculado a fingerprint de estado + expiração + idempotência) — uma diferença de +desenho relevante para a secção 5. + +### 2.7 Assimetria WPForms vs Fluent Forms — confirmada, não presumida + +A árvore `src/` de WPForms Lite (listada na íntegra: `Access, Admin, Analytics, Db, Education, +Emails, Forms, Frontend, Helpers, Integrations, Lite, Logger, Migrations, Providers, +Requirements, SetupChecklist, SetupWizard, SmartTags, Tasks`, mais `API.php`/`ErrorHandler.php`/ +`Loader.php`/`WPForms.php` de topo) **não contém nenhuma pasta ou classe MCP** — `src/API.php` é um +registo interno de callbacks (import de formulários), sem qualquer relação com Model Context +Protocol. Fluent Forms, pelo contrário, tem uma pasta dedicada `app/Modules/MCP/` com 9 abilities +reais completas. Esta assimetria é directamente relevante para a secção 5 (prioridade de +construção): uma integração EMCP para Fluent Forms tem uma superfície de referência real e +testável para se alinhar (ou mesmo delegar); uma para WPForms tem de ser construída inteiramente +de raiz sobre `WPForms_Form_Handler`. + +--- + +## 3. Comparação com o padrão base real (`EMCP_Tools_Form_Integration::dispatch()`) + +Citação do contrato já confirmado em `docs/08-INTEGRACOES-TERCEIROS.md` §3.1-§3.2: cada integração +concreta implementa `id()`, `label()`, `is_active()`, `operations(): array` — mapa +`nome => { mode, run, perm, desc, confirm? }` — e a base fornece `register()` (regista os dois +tools `-read`/`-write`), `can_read()=edit_posts`, `can_write()=manage_options`, e +`dispatch()` (resolve `operation`, verifica `is_active()`, valida existência+modo, corre `perm`, +aplica a gate de confirmação genérica se `confirm===true`). + +Aplicando isto às duas famílias deste documento: + +```php +// Esqueleto de EMCP_Tools_WPForms_Integration extends EMCP_Tools_Form_Integration +public function id(): string { return 'wpforms'; } +public function label(): string { return 'WPForms'; } +public function is_active(): bool { return class_exists( 'WPForms_Form_Handler' ) || defined( 'WPFORMS_VERSION' ); } +public function operations(): array { + return [ + 'list-forms' => [ 'mode' => 'read', 'run' => [ $this, 'op_list_forms' ], 'perm' => 'edit_posts' ], + 'get-form' => [ 'mode' => 'read', 'run' => [ $this, 'op_get_form' ], 'perm' => 'edit_posts' ], + 'list-notifications' => [ 'mode' => 'read', 'run' => [ $this, 'op_list_notif' ], 'perm' => 'edit_posts' ], + 'get-settings' => [ 'mode' => 'read', 'run' => [ $this, 'op_get_settings' ], 'perm' => 'edit_posts' ], + 'list-entries' => [ 'mode' => 'read', 'run' => [ $this, 'op_list_entries' ], 'perm' => 'edit_posts' ], // op_list_entries devolve plugin_inactive-like se wpforms()->is_pro()===false + 'get-entry' => [ 'mode' => 'read', 'run' => [ $this, 'op_get_entry' ], 'perm' => 'edit_posts' ], + 'update-notification' => [ 'mode' => 'write', 'run' => [ $this, 'op_update_notif' ], 'perm' => 'manage_options' ], + 'update-entry-status' => [ 'mode' => 'write', 'run' => [ $this, 'op_update_status' ], 'perm' => 'manage_options', 'confirm' => true ], + 'delete-entry' => [ 'mode' => 'write', 'run' => [ $this, 'op_delete_entry' ], 'perm' => 'manage_options', 'confirm' => true ], + ]; +} +``` + +A gate `confirm=>true` mapeia directamente para o `(confirm:true)` que a própria descrição da +captura de ecrã já anuncia para `wpforms-write` — sem inventar mecanismo novo, o que já existe na +base serve tal-qual. O mesmo esqueleto para `EMCP_Tools_FluentForms_Integration` seria idêntico na +forma, mas cada `run` callback delegaria para os métodos estáticos já reais de +`FluentForm\App\Api\Form`/`Entry` (secção 2.2) — **ou**, mais interessante dado o achado da secção +2.3, para os métodos estáticos das próprias classes `FormTools`/`SubmissionTools` nativas do +Fluent Forms, se detectadas presentes (ver secção 5). + +**Nota sobre `destructive` a nível de tool**: a base Forms marca o tool `write` inteiro como +`destructive=true` por omissão (doc08 §3.2, diferente de ACF/Meta Box/SEO) — precisamente porque, +ao contrário de CF7 (a única integração Free, que nunca apaga nada), tanto `wpforms-write` como +`fluentforms-write` têm pelo menos uma operação genuinamente destructive (`delete-entry`). A +captura de ecrã confirma isto explicitamente com a etiqueta "DESTRUCTIVE" em ambos os tools write. + +--- + +## 4. As outras 6 integrações Pro de formulários — sem grounding possível + +Gravity Forms, Ninja Forms, Formidable Forms, MetForm, SureForms e Forminator estão todas listadas +em `docs/08-INTEGRACOES-TERCEIROS.md` §7 como classes referenciadas só por `class_exists()` no +registrar, com ficheiro fisicamente ausente da árvore Free. Confirmação adicional própria desta +tarefa: **nenhum dos dois sites verificados** para este documento (`care.descomplicar.pt` e +`ecommerce-demo.descomplicar.pt`) tem qualquer um destes 6 plugins instalado — a listagem completa +de `wp plugin list` de ambos os sites (secção 6) não contém `gravityforms`, `ninja-forms`, +`formidable`, `metform`, `sureforms`, nem `forminator`/`forminator-pro`. Sem código a ler em lado +nenhum, este documento **não propõe** tabelas de ability para estas seis — inventar schemas sem +fundamento contradiz o princípio desta série. Ficam confirmadas apenas como ausentes (mesma tabela +de gating do doc08 §7, não reproduzida aqui). + +--- + +## 5. Blueprint para réplica + +### 5.1 Copiar quase 1:1 + +- **A classe base `EMCP_Tools_Form_Integration` inteira** (doc08 §3) — contrato + `id()/label()/is_active()/operations()`, dispatcher, gate de confirmação genérica, + `can_read()=edit_posts`/`can_write()=manage_options`, e a anotação `destructive=true` por + omissão no tool write. Nada disto precisa de ser redesenhado; WPForms e Fluent Forms encaixam + nele exactamente como CF7 já encaixa. +- **O padrão dry-run + `confirm_token` vinculado a fingerprint de estado da Fluent Forms nativa** + (secção 2.3) — é uma evolução directa, e comprovadamente já em produção num plugin real, do + mecanismo `confirm:true` simples da base EMCP. Vale a pena propor subir este padrão mais rico + para a base `EMCP_Tools_Form_Integration` em geral (aplicável também a `woo-orders-write`/etc., + doc11 §9), não só a esta integração — a única razão para não o copiar tal-qual é que aumenta a + complexidade de qualquer chamador MCP (duas chamadas por escrita em vez de uma). +- **Escrever sempre por identificador estável e nunca confiar no valor de retorno de `update()`** — + a mesma lição já documentada para ACF (doc08 §1.3) aplica-se ao `WPForms_Form_Handler::update()`: + substitui `post_content` inteiro, por isso uma implementação EMCP tem de ler-modificar-escrever + com cuidado para não perder campos/notificações não tocados pela operação pedida. +- **A marcação `[[UNTRUSTED_USER_INPUT]]` da Fluent Forms nativa** (`MCPHelper::untrusted()`) — um + mecanismo directo e barato contra prompt injection via texto submetido por visitantes anónimos, + aplicável tal-qual a `get-entry`/`list-entries` de ambas as integrações (WPForms teria o mesmo + problema assim que ligado a WPForms Pro real). + +### 5.2 Decisão específica para Fluent Forms: detectar e delegar em vez de reimplementar + +Dado que a versão 6.2.x já embarca `FluentForm\App\Modules\MCP\AbilitiesRegistrar` com abilities +reais e testadas (secção 2.3), uma implementação real de `EMCP_Tools_FluentForms_Integration` +devia começar por: + +```php +if ( class_exists( '\FluentForm\App\Modules\MCP\AbilitiesRegistrar' ) ) { + // Delegar: reaproveitar getDefinitions() como a fonte de operations(), + // sem reimplementar list-forms/get-form/list-submissions/get-submission/ + // update-submission-status/delete-submission a partir do zero. +} +``` + +Isto é uma recomendação **exclusiva** desta integração dentro de toda a série de documentos — +nenhuma outra (ACF, Meta Box, WooCommerce, Widget Builder, CF7) tem um equivalente nativo já +registado via `wp_register_ability()` no próprio plugin de terceiros. O risco a mitigar: a Fluent +Forms nativa fica desligada por omissão (`PermissionGate::isEnabled()===false`) e exige um plugin +adaptador (`fluent-toolkit`/`mcp-adapter`) — uma implementação EMCP que delegasse teria de activar +programaticamente essa option, ou simplesmente reimplementar chamando os mesmos métodos estáticos +`FormTools::listForms()`/`SubmissionTools::listSubmissions()` directamente (sem depender do +registo MCP nativo estar ligado), o que é possível porque são métodos estáticos públicos. + +### 5.3 Decisão específica para WPForms: gate explícita de "entries requer Pro" + +Dado que `wpforms()->is_pro()` é uma verificação real e barata (`src/WPForms.php`, +`apply_filters('wpforms_allow_pro_version', $this->pro)`), as operações `list-entries`/`get-entry`/ +`update-entry-status`/`delete-entry` deviam falhar explicitamente com um erro estruturado +(`wpforms_pro_required`, análogo ao `plugin_inactive` HTTP 409 já usado pela base para +`is_active()===false`, doc08 §3.2) em vez de devolver `[]`/`404` genéricos — a distinção entre +"este formulário não existe" e "esta instalação não suporta entradas de todo" é informação que o +agente precisa para não repetir a chamada. + +### 5.4 Prioridade de construção + +1. **`wpforms-read` (list-forms/get-form/list-notifications/get-settings) + `fluentforms-read` + (list-forms/get-form)** — zero risco, cobre o caso mais comum ("que formulários existem, o que + perguntam, para onde notificam"). Para Fluent Forms, literalmente delegar em `FormTools` + (secção 5.2) reduz isto a um wrapper fino. +2. **`fluentforms-read` (list-entries/get-entry)** — Fluent Forms free já guarda submissões + nativamente, sem gate Pro-do-plugin-alvo; alto valor imediato. +3. **`wpforms-write` (update-notification)** — única operação de escrita de WPForms com grounding + completo nesta instalação; sem depender de WPForms Pro. +4. **`fluentforms-write` (update-entry-status/delete-entry)** — reaproveitar o par dry-run+token da + Fluent Forms nativa (secção 5.1) em vez do `confirm:true` simples da base, dado que o código de + referência real já demonstra porque vale a pena (fingerprint de estado, replay seguro). +5. **`wpforms-read`/`wpforms-write` (as 4 operações de entries)** — só implementável e testável + contra uma instalação WPForms **Pro** real; até lá, ficam atrás da gate `wpforms_pro_required` + descrita em 5.3, nunca simuladas. + +### 5.5 O que NÃO replicar sem decisão explícita + +- **Reimplementar do zero o que a Fluent Forms MCP nativa já faz bem** (dry-run/confirm_token, + fencing de untrusted input, scope de formulário por utilizador via `FormAccess`) — duplicar essa + lógica dentro do EMCP Tools é trabalho redundante e uma segunda superfície para ficar + dessincronizada da primeira à medida que a Fluent Forms evolui a sua própria API MCP. +- **Simular `list-entries`/`get-entry` de WPForms contra uma instalação Lite** com dados vazios ou + de exemplo — o próprio WPForms Lite já mostra dados de amostra na sua UI (secção 1.4) para + incentivar upgrade; uma ability MCP que fizesse o mesmo silenciosamente enganaria um agente a + pensar que está a ler dados reais. + +--- + +## 6. Fonte + +**Confirmação de instalação e estado activo** (19-08-2026), via `wp plugin list --format=json`: + +``` +ssh server "wp plugin list --path=/home/ealmeida/ecommerce-demo.descomplicar.pt --allow-root --format=json" +→ fluentform active 6.2.12 +→ wpforms-lite active 2.0.0.5 +``` + +Listagem prévia de `wp-content/plugins/` de `care.descomplicar.pt` (sem WPForms nem Fluent Forms — +descartado como site-alvo) e de `ecommerce-demo.descomplicar.pt` (ambos presentes, `fluentform/` + +`wpforms-lite/`) — usada também para confirmar a ausência de Gravity Forms/Ninja Forms/Formidable/ +MetForm/SureForms/Forminator em qualquer um dos dois sites (secção 4). + +**WPForms Lite 2.0.0.5** (`wp-content/plugins/wpforms-lite/`): +- `includes/class-form.php` (`WPForms_Form_Handler`, integral) +- `src/WPForms.php` (integral — bootstrap, `objects()`, `obj()`, `register()`) +- `src/Access/Capabilities.php` (integral) +- `src/API.php` (integral — confirma que NÃO é um endpoint REST/MCP) +- `includes/functions/access.php` (integral — `wpforms_current_user_can()`, etc.) +- `lite/wpforms-lite.php` (integral — notificações/confirmações reais, painel Entries com dados de + amostra) +- Listagem de directório (sem leitura de conteúdo, confirmação de inventário): `src/` (17 + subdirectórios + 4 ficheiros de topo — confirma ausência de qualquer pasta MCP), + `includes/functions/` (14 ficheiros), `includes/admin/builder/panels/` (7 ficheiros) + +**Fluent Forms (free) 6.2.12** (`wp-content/plugins/fluentform/`): +- `app/Models/Form.php`, `app/Models/Submission.php` (integrais) +- `app/Api/Form.php`, `app/Api/Entry.php` (integrais) +- `app/Http/Policies/FormPolicy.php`, `app/Http/Policies/SubmissionPolicy.php` (integrais) +- `app/Http/Controllers/McpSettingsController.php` (integral) +- `app/Modules/MCP/AbilitiesRegistrar.php` (integral) +- `app/Modules/MCP/Tools/FormTools.php`, `app/Modules/MCP/Tools/SubmissionTools.php` (integrais) +- `app/Modules/MCP/Support/PermissionGate.php`, `app/Modules/MCP/Support/WriteGuard.php` + (integrais) +- `app/Modules/Acl/Acl.php` (integral) +- Listagem de directório (inventário): `app/` (9 subdirectórios), `app/Models/` (14 ficheiros), + `app/Api/` (4 ficheiros), `app/Http/Controllers/` (17 ficheiros), `app/Http/Policies/` (7 + ficheiros), `app/Modules/MCP/` (2 ficheiros + 2 subdirectórios), `app/Modules/MCP/Tools/` (8 + ficheiros) + +**Cruzado com**: `docs/00-ARQUITECTURA.md` (padrão `emcp_tools_register_ability()`, +`normalize_result`), `docs/08-INTEGRACOES-TERCEIROS.md` §3 (`EMCP_Tools_Form_Integration`, base +abstracta real, citada extensivamente), §4 (`EMCP_Tools_CF7_Integration`, única integração +concreta real), §7 (tabela de gating das 18 integrações Pro-only, incl. WPForms e Fluent Forms), +`docs/10-MODULOS-E-INVENTARIO-PRO.md` linhas 470-476 (confirmação adicional do mesmo gate). diff --git a/docs/14-PROJECT-MEMORY-BLUEPRINT.md b/docs/14-PROJECT-MEMORY-BLUEPRINT.md new file mode 100644 index 0000000..c74157a --- /dev/null +++ b/docs/14-PROJECT-MEMORY-BLUEPRINT.md @@ -0,0 +1,613 @@ +# 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. diff --git a/docs/INDEX.md b/docs/INDEX.md index ed2c7e1..2b676f8 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -1,6 +1,6 @@ # EMCP Tools — Mapeamento completo e blueprint de réplica -Índice e síntese de 13 documentos (~7 810 linhas), produzidos 19-08-2026 por leitura directa do +Índice e síntese de 14 documentos ("7 810+" linhas), produzidos 19-08-2026 por leitura directa do código-fonte `emcp-tools` v3.12.1 (build Free, `msrbuilds/elementor-mcp`, GPL-2.0-or-later), instalado em `emanuelalmeida.pt` (`/home/ealmeida/emanuelalmeida.pt/wp-content/plugins/emcp-tools/`), mais dois docs adicionais (11, WooCommerce; 12, Widget Builder) fundamentados noutro código real @@ -33,11 +33,13 @@ copiar-1:1 / simplificar / deixar de fora. | [10-MODULOS-E-INVENTARIO-PRO](10-MODULOS-E-INVENTARIO-PRO.md) | Sistema de módulos (toggles), Image Optimization, SVG Support, **inventário definitivo das 30 classes Pro-only** | 661 | n/a + 30 ausentes | — (estrutural + auditoria) | | [11-WOOCOMMERCE-BLUEPRINT](11-WOOCOMMERCE-BLUEPRINT.md) | **Não é auditoria EMCP** — blueprint de abilities WooCommerce (produtos/encomendas/clientes/cupões/analytics/webhooks) fundamentado no WooCommerce real, para preencher o gap `EMCP_Tools_Woo_Integration` (Pro, código ausente). Exclui SEO/Yoast por pedido. | 878 | ~35 propostas | WooCommerce activo | | [12-WIDGET-BUILDER-BLUEPRINT](12-WIDGET-BUILDER-BLUEPRINT.md) | **Não é auditoria EMCP** — blueprint de gerador spec→widget-Elementor-PHP (marca `[REAL]`/`[DESENHO PRÓPRIO]` em cada afirmação), fundamentado na API pública `Widget_Base`/`Controls_Manager` do Elementor real + no `EMCP_Tools_Widget_Store`/`Widget_Loader` já Free/reais (doc 06). Recomenda "zero tool de activação via MCP", ecoando Themer PHP/Sandbox. | 651 | 8 propostas | Elementor activo | +| [13-FORMS-PRO-BLUEPRINT](13-FORMS-PRO-BLUEPRINT.md) | **Não é auditoria EMCP** — blueprint para as integrações Pro-ausentes WPForms/Fluent Forms, fundamentado em código real Free de ambos os plugins (activos em `ecommerce-demo.descomplicar.pt`). Achado central: Fluent Forms já embarca o seu próprio servidor MCP nativo (`AbilitiesRegistrar`, 9 abilities, dry-run+confirm_token) — recomenda detectar e delegar em vez de reimplementar. | ~410 | 6 propostas | WPForms/Fluent Forms instalados | +| [14-PROJECT-MEMORY-BLUEPRINT](14-PROJECT-MEMORY-BLUEPRINT.md) | **Não é auditoria EMCP** — blueprint para o módulo Pro-ausente "Project Memory", fundamentado em dois sistemas reais em produção neste ecossistema: CARL (governança de regras com staging/aprovação) e Mem0/Hindsight (memória cross-agent em camadas). Propõe `remember`/`recall`/`save-session-summary` como ponte MCP para memória/governança já existente, não desenho do zero. | ~475 | ~7 propostas | Nenhuma (desenho próprio) | -Total: **~7 810 linhas de documentação**, ~165 abilities EMCP confirmadas + ~35 WooCommerce + 8 -Widget Builder propostas (docs 11-12, não implementadas no EMCP — blueprints próprios) sobre -**~128 465 linhas de PHP** do plugin `emcp-tools` (`~50k` das quais são o SDK Freemius bundled, -irrelevante para réplica). +Total: **~8 695 linhas de documentação**, ~165 abilities EMCP confirmadas + ~35 WooCommerce + 8 +Widget Builder + 6 Forms Pro + ~7 Project Memory propostas (docs 11-14, não implementadas no EMCP +— blueprints próprios) sobre **~128 465 linhas de PHP** do plugin `emcp-tools` (`~50k` das quais +são o SDK Freemius bundled, irrelevante para réplica). --- diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json index bd6c24a..621b442 100644 --- a/graphify-out/.graphify_labels.json +++ b/graphify-out/.graphify_labels.json @@ -8,5 +8,7 @@ "6": "2. Produtos", "7": "4. Clientes", "8": "5. Cupões / Descontos", - "9": "9. Blueprint para réplica" + "9": "9. Blueprint para réplica", + "10": "6. Sandbox e ciclo de vida — reaproveitar o modelo já confirmado em código real `[REAL]`", + "11": "8. Blueprint para réplica" } diff --git a/graphify-out/2026-08-19/.graphify_labels.json b/graphify-out/2026-08-19/.graphify_labels.json new file mode 100644 index 0000000..bd6c24a --- /dev/null +++ b/graphify-out/2026-08-19/.graphify_labels.json @@ -0,0 +1,12 @@ +{ + "0": "EMCP Tools — Mapeamento completo e blueprint de réplica", + "1": "5. Sequência de construção recomendada para uma réplica", + "2": "11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)", + "3": "3. Encomendas", + "4": "6. Relatórios / Analytics (`wc-analytics/*`)", + "5": "7. Webhooks", + "6": "2. Produtos", + "7": "4. Clientes", + "8": "5. Cupões / Descontos", + "9": "9. Blueprint para réplica" +} diff --git a/graphify-out/2026-08-19/GRAPH_REPORT.md b/graphify-out/2026-08-19/GRAPH_REPORT.md new file mode 100644 index 0000000..511044d --- /dev/null +++ b/graphify-out/2026-08-19/GRAPH_REPORT.md @@ -0,0 +1,103 @@ +# Graph Report - emcp-tools-mapping (2026-08-19) + +## Corpus Check +- 13 files · ~66,158 words +- Verdict: corpus is large enough that graph structure adds value. + +## Summary +- 55 nodes · 54 edges · 10 communities +- Extraction: 100% EXTRACTED · 0% INFERRED · 0% AMBIGUOUS +- Token cost: 0 input · 0 output + +## Graph Freshness +- Built from commit: `2f98a527` +- Run `git rev-parse HEAD` and compare to check if the graph is stale. +- Run `graphify update .` after code changes (no API cost). + +## Community Hubs (Navigation) +- [[_COMMUNITY_EMCP Tools — Mapeamento completo e blueprint de réplica|EMCP Tools — Mapeamento completo e blueprint de réplica]] +- [[_COMMUNITY_5. Sequência de construção recomendada para uma réplica|5. Sequência de construção recomendada para uma réplica]] +- [[_COMMUNITY_11 — WooCommerce blueprint de abilities MCP (não é auditoria EMCP)|11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)]] +- [[_COMMUNITY_3. Encomendas|3. Encomendas]] +- [[_COMMUNITY_6. Relatórios Analytics (`wc-analytics`)|6. Relatórios / Analytics (`wc-analytics/*`)]] +- [[_COMMUNITY_7. Webhooks|7. Webhooks]] +- [[_COMMUNITY_2. Produtos|2. Produtos]] +- [[_COMMUNITY_4. Clientes|4. Clientes]] +- [[_COMMUNITY_5. Cupões Descontos|5. Cupões / Descontos]] +- [[_COMMUNITY_9. Blueprint para réplica|9. Blueprint para réplica]] + +## God Nodes (most connected - your core abstractions) +1. `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)` - 12 edges +2. `EMCP Tools — Mapeamento completo e blueprint de réplica` - 9 edges +3. `5. Sequência de construção recomendada para uma réplica` - 8 edges +4. `3. Encomendas` - 6 edges +5. `6. Relatórios / Analytics (`wc-analytics/*`)` - 5 edges +6. `7. Webhooks` - 5 edges +7. `2. Produtos` - 4 edges +8. `4. Clientes` - 4 edges +9. `5. Cupões / Descontos` - 4 edges +10. `9. Blueprint para réplica` - 4 edges + +## Surprising Connections (you probably didn't know these) +- None detected - all connections are within the same source files. + +## Import Cycles +- None detected. + +## Communities (10 total, 0 thin omitted) + +### Community 0 - "EMCP Tools — Mapeamento completo e blueprint de réplica" +Cohesion: 0.25 +Nodes (8): 1. Mapa dos documentos, 2. O achado mais importante de toda a série, 3. Os 5 subsistemas de maior valor para copiar quase verbatim, 4. Padrões arquitecturais que atravessam todo o plugin, 6. Tabela de risco consolidada, 7. Como usar esta documentação, EMCP Tools — Mapeamento completo e blueprint de réplica, Metodologia + +### Community 1 - "5. Sequência de construção recomendada para uma réplica" +Cohesion: 0.25 +Nodes (8): 5. Sequência de construção recomendada para uma réplica, Explicitamente fora de âmbito (doc 10 §2), Fase 0 — Fundação (sem isto, nada mais tem rollback nem é seguro), Fase 1 — Conteúdo WordPress puro (sem dependência de Elementor), Fase 2 — Elementor (o núcleo de "construir páginas"), Fase 3 — Camadas de produto sobre o conteúdo, Fase 4 — Superfície de risco elevado, opt-in, Fase 5 — Integrações e periferia (valor incremental, não bloqueante) + +### Community 2 - "11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)" +Cohesion: 0.29 +Nodes (5): 0. Porque este documento é diferente dos outros 10, 10. Fonte, 11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP), 1. Panorama, 8. Segurança / gating recomendado + +### Community 3 - "3. Encomendas" +Cohesion: 0.33 +Nodes (6): 3.1 Estados reais (não inventados — via `wc_get_order_statuses()`), 3.2 Itens da encomenda e ciclo de escrita, 3.3 Devoluções (refunds), 3.4 Notas da encomenda, 3.5 Tabela de ability proposta — Encomendas, 3. Encomendas + +### Community 4 - "6. Relatórios / Analytics (`wc-analytics/*`)" +Cohesion: 0.40 +Nodes (5): 6.1 Dois grupos de controllers, 6.2 Capability real para relatórios (não `manage_woocommerce`), 6.3 Data stores de agregação confirmados, 6.4 Tabela de ability proposta — Analytics, 6. Relatórios / Analytics (`wc-analytics/*`) + +### Community 5 - "7. Webhooks" +Cohesion: 0.40 +Nodes (5): 7.1 Modelo de dados real (confirmado por `$data` default em `WC_Webhook`), 7.2 Validação de topic — não é livre texto, 7.3 Entrega assíncrona por omissão, 7.4 Tabela de ability proposta — Webhooks, 7. Webhooks + +### Community 6 - "2. Produtos" +Cohesion: 0.50 +Nodes (4): 2.1 Schema real (campos confirmados por leitura de `get_item_schema()`), 2.2 Endpoints extra confirmados (além do CRUD standard), 2.3 Tabela de ability proposta — Produtos, 2. Produtos + +### Community 7 - "4. Clientes" +Cohesion: 0.50 +Nodes (4): 4.1 Capabilities reais (não `manage_woocommerce` genérico), 4.2 Schema real (confirmado por `get_item_schema()`), 4.3 Tabela de ability proposta — Clientes, 4. Clientes + +### Community 8 - "5. Cupões / Descontos" +Cohesion: 0.50 +Nodes (4): 5.1 Tipos de desconto reais (via `wc_get_coupon_types()`), 5.2 Campos de restrição confirmados (schema/data props do coupon), 5.3 Tabela de ability proposta — Cupões, 5. Cupões / Descontos + +### Community 9 - "9. Blueprint para réplica" +Cohesion: 0.50 +Nodes (4): 9.1 Prioridade de construção (por valor/esforço, assumindo Fase 0 do doc00 já feita), 9.2 Reaproveitamento explícito dos padrões já documentados, 9.3 O que NÃO replicar sem decisão explícita, 9. Blueprint para réplica + +## Knowledge Gaps +- **43 isolated node(s):** `0. Porque este documento é diferente dos outros 10`, `1. Panorama`, `2.1 Schema real (campos confirmados por leitura de `get_item_schema()`)`, `2.2 Endpoints extra confirmados (além do CRUD standard)`, `2.3 Tabela de ability proposta — Produtos` (+38 more) + These have ≤1 connection - possible missing edges or undocumented components. + +## Suggested Questions +_Questions this graph is uniquely positioned to answer:_ + +- **Why does `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)` connect `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)` to `3. Encomendas`, `6. Relatórios / Analytics (`wc-analytics/*`)`, `7. Webhooks`, `2. Produtos`, `4. Clientes`, `5. Cupões / Descontos`, `9. Blueprint para réplica`?** + _High betweenness centrality (0.852) - this node is a cross-community bridge._ +- **Why does `EMCP Tools — Mapeamento completo e blueprint de réplica` connect `EMCP Tools — Mapeamento completo e blueprint de réplica` to `5. Sequência de construção recomendada para uma réplica`, `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)`?** + _High betweenness centrality (0.463) - this node is a cross-community bridge._ +- **Why does `5. Sequência de construção recomendada para uma réplica` connect `5. Sequência de construção recomendada para uma réplica` to `EMCP Tools — Mapeamento completo e blueprint de réplica`?** + _High betweenness centrality (0.245) - this node is a cross-community bridge._ +- **What connects `0. Porque este documento é diferente dos outros 10`, `1. Panorama`, `2.1 Schema real (campos confirmados por leitura de `get_item_schema()`)` to the rest of the system?** + _43 weakly-connected nodes found - possible documentation gaps or missing edges._ \ No newline at end of file diff --git a/graphify-out/2026-08-19/graph.json b/graphify-out/2026-08-19/graph.json new file mode 100644 index 0000000..eea42ae --- /dev/null +++ b/graphify-out/2026-08-19/graph.json @@ -0,0 +1,1101 @@ +{ + "directed": false, + "multigraph": false, + "graph": {}, + "nodes": [ + { + "label": "11-WOOCOMMERCE-BLUEPRINT.md", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L1", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint", + "community": 2, + "norm_label": "11-woocommerce-blueprint.md" + }, + { + "label": "11 \u2014 WooCommerce: blueprint de abilities MCP (n\u00e3o \u00e9 auditoria EMCP)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L1", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "community": 2, + "norm_label": "11 \u2014 woocommerce: blueprint de abilities mcp (nao e auditoria emcp)" + }, + { + "label": "0. Porque este documento \u00e9 diferente dos outros 10", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L11", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_0_porque_este_documento_\u00e9_diferente_dos_outros_10", + "community": 2, + "norm_label": "0. porque este documento e diferente dos outros 10" + }, + { + "label": "1. Panorama", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L30", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_1_panorama", + "community": 2, + "norm_label": "1. panorama" + }, + { + "label": "2. Produtos", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L84", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_2_produtos", + "community": 6, + "norm_label": "2. produtos" + }, + { + "label": "2.1 Schema real (campos confirmados por leitura de `get_item_schema()`)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L97", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_2_1_schema_real_campos_confirmados_por_leitura_de_get_item_schema", + "community": 6, + "norm_label": "2.1 schema real (campos confirmados por leitura de `get_item_schema()`)" + }, + { + "label": "2.2 Endpoints extra confirmados (al\u00e9m do CRUD standard)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L120", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_2_2_endpoints_extra_confirmados_al\u00e9m_do_crud_standard", + "community": 6, + "norm_label": "2.2 endpoints extra confirmados (alem do crud standard)" + }, + { + "label": "2.3 Tabela de ability proposta \u2014 Produtos", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L136", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_2_3_tabela_de_ability_proposta_produtos", + "community": 6, + "norm_label": "2.3 tabela de ability proposta \u2014 produtos" + }, + { + "label": "3. Encomendas", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L150", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_3_encomendas", + "community": 3, + "norm_label": "3. encomendas" + }, + { + "label": "3.1 Estados reais (n\u00e3o inventados \u2014 via `wc_get_order_statuses()`)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L158", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_3_1_estados_reais_n\u00e3o_inventados_via_wc_get_order_statuses", + "community": 3, + "norm_label": "3.1 estados reais (nao inventados \u2014 via `wc_get_order_statuses()`)" + }, + { + "label": "3.2 Itens da encomenda e ciclo de escrita", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L179", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_3_2_itens_da_encomenda_e_ciclo_de_escrita", + "community": 3, + "norm_label": "3.2 itens da encomenda e ciclo de escrita" + }, + { + "label": "3.3 Devolu\u00e7\u00f5es (refunds)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L192", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_3_3_devolu\u00e7\u00f5es_refunds", + "community": 3, + "norm_label": "3.3 devolucoes (refunds)" + }, + { + "label": "3.4 Notas da encomenda", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L202", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_3_4_notas_da_encomenda", + "community": 3, + "norm_label": "3.4 notas da encomenda" + }, + { + "label": "3.5 Tabela de ability proposta \u2014 Encomendas", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L208", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_3_5_tabela_de_ability_proposta_encomendas", + "community": 3, + "norm_label": "3.5 tabela de ability proposta \u2014 encomendas" + }, + { + "label": "4. Clientes", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L223", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_4_clientes", + "community": 7, + "norm_label": "4. clientes" + }, + { + "label": "4.1 Capabilities reais (n\u00e3o `manage_woocommerce` gen\u00e9rico)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L234", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_4_1_capabilities_reais_n\u00e3o_manage_woocommerce_gen\u00e9rico", + "community": 7, + "norm_label": "4.1 capabilities reais (nao `manage_woocommerce` generico)" + }, + { + "label": "4.2 Schema real (confirmado por `get_item_schema()`)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L246", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_4_2_schema_real_confirmado_por_get_item_schema", + "community": 7, + "norm_label": "4.2 schema real (confirmado por `get_item_schema()`)" + }, + { + "label": "4.3 Tabela de ability proposta \u2014 Clientes", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L254", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_4_3_tabela_de_ability_proposta_clientes", + "community": 7, + "norm_label": "4.3 tabela de ability proposta \u2014 clientes" + }, + { + "label": "5. Cup\u00f5es / Descontos", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L266", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_5_cup\u00f5es_descontos", + "community": 8, + "norm_label": "5. cupoes / descontos" + }, + { + "label": "5.1 Tipos de desconto reais (via `wc_get_coupon_types()`)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L274", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_5_1_tipos_de_desconto_reais_via_wc_get_coupon_types", + "community": 8, + "norm_label": "5.1 tipos de desconto reais (via `wc_get_coupon_types()`)" + }, + { + "label": "5.2 Campos de restri\u00e7\u00e3o confirmados (schema/data props do coupon)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L289", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_5_2_campos_de_restri\u00e7\u00e3o_confirmados_schema_data_props_do_coupon", + "community": 8, + "norm_label": "5.2 campos de restricao confirmados (schema/data props do coupon)" + }, + { + "label": "5.3 Tabela de ability proposta \u2014 Cup\u00f5es", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L298", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_5_3_tabela_de_ability_proposta_cup\u00f5es", + "community": 8, + "norm_label": "5.3 tabela de ability proposta \u2014 cupoes" + }, + { + "label": "6. Relat\u00f3rios / Analytics (`wc-analytics/*`)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L309", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_6_relat\u00f3rios_analytics_wc_analytics", + "community": 4, + "norm_label": "6. relatorios / analytics (`wc-analytics/*`)" + }, + { + "label": "6.1 Dois grupos de controllers", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L317", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_6_1_dois_grupos_de_controllers", + "community": 4, + "norm_label": "6.1 dois grupos de controllers" + }, + { + "label": "6.2 Capability real para relat\u00f3rios (n\u00e3o `manage_woocommerce`)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L335", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_6_2_capability_real_para_relat\u00f3rios_n\u00e3o_manage_woocommerce", + "community": 4, + "norm_label": "6.2 capability real para relatorios (nao `manage_woocommerce`)" + }, + { + "label": "6.3 Data stores de agrega\u00e7\u00e3o confirmados", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L345", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_6_3_data_stores_de_agrega\u00e7\u00e3o_confirmados", + "community": 4, + "norm_label": "6.3 data stores de agregacao confirmados" + }, + { + "label": "6.4 Tabela de ability proposta \u2014 Analytics", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L356", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_6_4_tabela_de_ability_proposta_analytics", + "community": 4, + "norm_label": "6.4 tabela de ability proposta \u2014 analytics" + }, + { + "label": "7. Webhooks", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L376", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_7_webhooks", + "community": 5, + "norm_label": "7. webhooks" + }, + { + "label": "7.1 Modelo de dados real (confirmado por `$data` default em `WC_Webhook`)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L385", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_7_1_modelo_de_dados_real_confirmado_por_data_default_em_wc_webhook", + "community": 5, + "norm_label": "7.1 modelo de dados real (confirmado por `$data` default em `wc_webhook`)" + }, + { + "label": "7.2 Valida\u00e7\u00e3o de topic \u2014 n\u00e3o \u00e9 livre texto", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L393", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_7_2_valida\u00e7\u00e3o_de_topic_n\u00e3o_\u00e9_livre_texto", + "community": 5, + "norm_label": "7.2 validacao de topic \u2014 nao e livre texto" + }, + { + "label": "7.3 Entrega ass\u00edncrona por omiss\u00e3o", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L405", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_7_3_entrega_ass\u00edncrona_por_omiss\u00e3o", + "community": 5, + "norm_label": "7.3 entrega assincrona por omissao" + }, + { + "label": "7.4 Tabela de ability proposta \u2014 Webhooks", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L412", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_7_4_tabela_de_ability_proposta_webhooks", + "community": 5, + "norm_label": "7.4 tabela de ability proposta \u2014 webhooks" + }, + { + "label": "8. Seguran\u00e7a / gating recomendado", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L423", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_8_seguran\u00e7a_gating_recomendado", + "community": 2, + "norm_label": "8. seguranca / gating recomendado" + }, + { + "label": "9. Blueprint para r\u00e9plica", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L468", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_9_blueprint_para_r\u00e9plica", + "community": 9, + "norm_label": "9. blueprint para replica" + }, + { + "label": "9.1 Prioridade de constru\u00e7\u00e3o (por valor/esfor\u00e7o, assumindo Fase 0 do doc00 j\u00e1 feita)", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L470", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_9_1_prioridade_de_constru\u00e7\u00e3o_por_valor_esfor\u00e7o_assumindo_fase_0_do_doc00_j\u00e1_feita", + "community": 9, + "norm_label": "9.1 prioridade de construcao (por valor/esforco, assumindo fase 0 do doc00 ja feita)" + }, + { + "label": "9.2 Reaproveitamento expl\u00edcito dos padr\u00f5es j\u00e1 documentados", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L495", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_9_2_reaproveitamento_expl\u00edcito_dos_padr\u00f5es_j\u00e1_documentados", + "community": 9, + "norm_label": "9.2 reaproveitamento explicito dos padroes ja documentados" + }, + { + "label": "9.3 O que N\u00c3O replicar sem decis\u00e3o expl\u00edcita", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L514", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_9_3_o_que_n\u00e3o_replicar_sem_decis\u00e3o_expl\u00edcita", + "community": 9, + "norm_label": "9.3 o que nao replicar sem decisao explicita" + }, + { + "label": "10. Fonte", + "file_type": "document", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L532", + "_origin": "ast", + "id": "docs_11_woocommerce_blueprint_10_fonte", + "community": 2, + "norm_label": "10. fonte" + }, + { + "label": "INDEX.md", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L1", + "_origin": "ast", + "id": "docs_index", + "community": 2, + "norm_label": "index.md" + }, + { + "label": "EMCP Tools \u2014 Mapeamento completo e blueprint de r\u00e9plica", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L1", + "_origin": "ast", + "id": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "community": 0, + "norm_label": "emcp tools \u2014 mapeamento completo e blueprint de replica" + }, + { + "label": "1. Mapa dos documentos", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L18", + "_origin": "ast", + "id": "docs_index_1_mapa_dos_documentos", + "community": 0, + "norm_label": "1. mapa dos documentos" + }, + { + "label": "2. O achado mais importante de toda a s\u00e9rie", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L41", + "_origin": "ast", + "id": "docs_index_2_o_achado_mais_importante_de_toda_a_s\u00e9rie", + "community": 0, + "norm_label": "2. o achado mais importante de toda a serie" + }, + { + "label": "3. Os 5 subsistemas de maior valor para copiar quase verbatim", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L57", + "_origin": "ast", + "id": "docs_index_3_os_5_subsistemas_de_maior_valor_para_copiar_quase_verbatim", + "community": 0, + "norm_label": "3. os 5 subsistemas de maior valor para copiar quase verbatim" + }, + { + "label": "4. Padr\u00f5es arquitecturais que atravessam todo o plugin", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L92", + "_origin": "ast", + "id": "docs_index_4_padr\u00f5es_arquitecturais_que_atravessam_todo_o_plugin", + "community": 0, + "norm_label": "4. padroes arquitecturais que atravessam todo o plugin" + }, + { + "label": "5. Sequ\u00eancia de constru\u00e7\u00e3o recomendada para uma r\u00e9plica", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L126", + "_origin": "ast", + "id": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "community": 1, + "norm_label": "5. sequencia de construcao recomendada para uma replica" + }, + { + "label": "Fase 0 \u2014 Funda\u00e7\u00e3o (sem isto, nada mais tem rollback nem \u00e9 seguro)", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L130", + "_origin": "ast", + "id": "docs_index_fase_0_funda\u00e7\u00e3o_sem_isto_nada_mais_tem_rollback_nem_\u00e9_seguro", + "community": 1, + "norm_label": "fase 0 \u2014 fundacao (sem isto, nada mais tem rollback nem e seguro)" + }, + { + "label": "Fase 1 \u2014 Conte\u00fado WordPress puro (sem depend\u00eancia de Elementor)", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L141", + "_origin": "ast", + "id": "docs_index_fase_1_conte\u00fado_wordpress_puro_sem_depend\u00eancia_de_elementor", + "community": 1, + "norm_label": "fase 1 \u2014 conteudo wordpress puro (sem dependencia de elementor)" + }, + { + "label": "Fase 2 \u2014 Elementor (o n\u00facleo de \"construir p\u00e1ginas\")", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L146", + "_origin": "ast", + "id": "docs_index_fase_2_elementor_o_n\u00facleo_de_construir_p\u00e1ginas", + "community": 1, + "norm_label": "fase 2 \u2014 elementor (o nucleo de \"construir paginas\")" + }, + { + "label": "Fase 3 \u2014 Camadas de produto sobre o conte\u00fado", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L153", + "_origin": "ast", + "id": "docs_index_fase_3_camadas_de_produto_sobre_o_conte\u00fado", + "community": 1, + "norm_label": "fase 3 \u2014 camadas de produto sobre o conteudo" + }, + { + "label": "Fase 4 \u2014 Superf\u00edcie de risco elevado, opt-in", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L159", + "_origin": "ast", + "id": "docs_index_fase_4_superf\u00edcie_de_risco_elevado_opt_in", + "community": 1, + "norm_label": "fase 4 \u2014 superficie de risco elevado, opt-in" + }, + { + "label": "Fase 5 \u2014 Integra\u00e7\u00f5es e periferia (valor incremental, n\u00e3o bloqueante)", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L169", + "_origin": "ast", + "id": "docs_index_fase_5_integra\u00e7\u00f5es_e_periferia_valor_incremental_n\u00e3o_bloqueante", + "community": 1, + "norm_label": "fase 5 \u2014 integracoes e periferia (valor incremental, nao bloqueante)" + }, + { + "label": "Explicitamente fora de \u00e2mbito (doc 10 \u00a72)", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L175", + "_origin": "ast", + "id": "docs_index_explicitamente_fora_de_\u00e2mbito_doc_10_2", + "community": 1, + "norm_label": "explicitamente fora de ambito (doc 10 \u00a72)" + }, + { + "label": "6. Tabela de risco consolidada", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L185", + "_origin": "ast", + "id": "docs_index_6_tabela_de_risco_consolidada", + "community": 0, + "norm_label": "6. tabela de risco consolidada" + }, + { + "label": "7. Como usar esta documenta\u00e7\u00e3o", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L207", + "_origin": "ast", + "id": "docs_index_7_como_usar_esta_documenta\u00e7\u00e3o", + "community": 0, + "norm_label": "7. como usar esta documentacao" + }, + { + "label": "Metodologia", + "file_type": "document", + "source_file": "docs/INDEX.md", + "source_location": "L223", + "_origin": "ast", + "id": "docs_index_metodologia", + "community": 0, + "norm_label": "metodologia" + } + ], + "links": [ + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L1", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint", + "target": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L33", + "weight": 1.0, + "source": "docs_index", + "target": "docs_11_woocommerce_blueprint", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L11", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_0_porque_este_documento_\u00e9_diferente_dos_outros_10", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L532", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_10_fonte", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L30", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_1_panorama", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L84", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_2_produtos", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L150", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_3_encomendas", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L223", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_4_clientes", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L266", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_5_cup\u00f5es_descontos", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L309", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_6_relat\u00f3rios_analytics_wc_analytics", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L376", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_7_webhooks", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L423", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_8_seguran\u00e7a_gating_recomendado", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L468", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_11_woocommerce_blueprint_de_abilities_mcp_n\u00e3o_\u00e9_auditoria_emcp", + "target": "docs_11_woocommerce_blueprint_9_blueprint_para_r\u00e9plica", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L97", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_2_produtos", + "target": "docs_11_woocommerce_blueprint_2_1_schema_real_campos_confirmados_por_leitura_de_get_item_schema", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L120", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_2_produtos", + "target": "docs_11_woocommerce_blueprint_2_2_endpoints_extra_confirmados_al\u00e9m_do_crud_standard", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L136", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_2_produtos", + "target": "docs_11_woocommerce_blueprint_2_3_tabela_de_ability_proposta_produtos", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L158", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_3_encomendas", + "target": "docs_11_woocommerce_blueprint_3_1_estados_reais_n\u00e3o_inventados_via_wc_get_order_statuses", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L179", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_3_encomendas", + "target": "docs_11_woocommerce_blueprint_3_2_itens_da_encomenda_e_ciclo_de_escrita", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L192", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_3_encomendas", + "target": "docs_11_woocommerce_blueprint_3_3_devolu\u00e7\u00f5es_refunds", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L202", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_3_encomendas", + "target": "docs_11_woocommerce_blueprint_3_4_notas_da_encomenda", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L208", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_3_encomendas", + "target": "docs_11_woocommerce_blueprint_3_5_tabela_de_ability_proposta_encomendas", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L234", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_4_clientes", + "target": "docs_11_woocommerce_blueprint_4_1_capabilities_reais_n\u00e3o_manage_woocommerce_gen\u00e9rico", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L246", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_4_clientes", + "target": "docs_11_woocommerce_blueprint_4_2_schema_real_confirmado_por_get_item_schema", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L254", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_4_clientes", + "target": "docs_11_woocommerce_blueprint_4_3_tabela_de_ability_proposta_clientes", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L274", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_5_cup\u00f5es_descontos", + "target": "docs_11_woocommerce_blueprint_5_1_tipos_de_desconto_reais_via_wc_get_coupon_types", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L289", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_5_cup\u00f5es_descontos", + "target": "docs_11_woocommerce_blueprint_5_2_campos_de_restri\u00e7\u00e3o_confirmados_schema_data_props_do_coupon", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L298", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_5_cup\u00f5es_descontos", + "target": "docs_11_woocommerce_blueprint_5_3_tabela_de_ability_proposta_cup\u00f5es", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L317", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_6_relat\u00f3rios_analytics_wc_analytics", + "target": "docs_11_woocommerce_blueprint_6_1_dois_grupos_de_controllers", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L335", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_6_relat\u00f3rios_analytics_wc_analytics", + "target": "docs_11_woocommerce_blueprint_6_2_capability_real_para_relat\u00f3rios_n\u00e3o_manage_woocommerce", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L345", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_6_relat\u00f3rios_analytics_wc_analytics", + "target": "docs_11_woocommerce_blueprint_6_3_data_stores_de_agrega\u00e7\u00e3o_confirmados", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L356", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_6_relat\u00f3rios_analytics_wc_analytics", + "target": "docs_11_woocommerce_blueprint_6_4_tabela_de_ability_proposta_analytics", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L385", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_7_webhooks", + "target": "docs_11_woocommerce_blueprint_7_1_modelo_de_dados_real_confirmado_por_data_default_em_wc_webhook", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L393", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_7_webhooks", + "target": "docs_11_woocommerce_blueprint_7_2_valida\u00e7\u00e3o_de_topic_n\u00e3o_\u00e9_livre_texto", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L405", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_7_webhooks", + "target": "docs_11_woocommerce_blueprint_7_3_entrega_ass\u00edncrona_por_omiss\u00e3o", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L412", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_7_webhooks", + "target": "docs_11_woocommerce_blueprint_7_4_tabela_de_ability_proposta_webhooks", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L470", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_9_blueprint_para_r\u00e9plica", + "target": "docs_11_woocommerce_blueprint_9_1_prioridade_de_constru\u00e7\u00e3o_por_valor_esfor\u00e7o_assumindo_fase_0_do_doc00_j\u00e1_feita", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L495", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_9_blueprint_para_r\u00e9plica", + "target": "docs_11_woocommerce_blueprint_9_2_reaproveitamento_expl\u00edcito_dos_padr\u00f5es_j\u00e1_documentados", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/11-WOOCOMMERCE-BLUEPRINT.md", + "source_location": "L514", + "weight": 1.0, + "source": "docs_11_woocommerce_blueprint_9_blueprint_para_r\u00e9plica", + "target": "docs_11_woocommerce_blueprint_9_3_o_que_n\u00e3o_replicar_sem_decis\u00e3o_expl\u00edcita", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L1", + "weight": 1.0, + "source": "docs_index", + "target": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L18", + "weight": 1.0, + "source": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "target": "docs_index_1_mapa_dos_documentos", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L41", + "weight": 1.0, + "source": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "target": "docs_index_2_o_achado_mais_importante_de_toda_a_s\u00e9rie", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L57", + "weight": 1.0, + "source": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "target": "docs_index_3_os_5_subsistemas_de_maior_valor_para_copiar_quase_verbatim", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L92", + "weight": 1.0, + "source": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "target": "docs_index_4_padr\u00f5es_arquitecturais_que_atravessam_todo_o_plugin", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L126", + "weight": 1.0, + "source": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "target": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L185", + "weight": 1.0, + "source": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "target": "docs_index_6_tabela_de_risco_consolidada", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L207", + "weight": 1.0, + "source": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "target": "docs_index_7_como_usar_esta_documenta\u00e7\u00e3o", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L223", + "weight": 1.0, + "source": "docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", + "target": "docs_index_metodologia", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L175", + "weight": 1.0, + "source": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "target": "docs_index_explicitamente_fora_de_\u00e2mbito_doc_10_2", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L130", + "weight": 1.0, + "source": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "target": "docs_index_fase_0_funda\u00e7\u00e3o_sem_isto_nada_mais_tem_rollback_nem_\u00e9_seguro", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L141", + "weight": 1.0, + "source": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "target": "docs_index_fase_1_conte\u00fado_wordpress_puro_sem_depend\u00eancia_de_elementor", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L146", + "weight": 1.0, + "source": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "target": "docs_index_fase_2_elementor_o_n\u00facleo_de_construir_p\u00e1ginas", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L153", + "weight": 1.0, + "source": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "target": "docs_index_fase_3_camadas_de_produto_sobre_o_conte\u00fado", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L159", + "weight": 1.0, + "source": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "target": "docs_index_fase_4_superf\u00edcie_de_risco_elevado_opt_in", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/INDEX.md", + "source_location": "L169", + "weight": 1.0, + "source": "docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", + "target": "docs_index_fase_5_integra\u00e7\u00f5es_e_periferia_valor_incremental_n\u00e3o_bloqueante", + "confidence_score": 1.0 + } + ], + "hyperedges": [], + "built_at_commit": "2f98a527a8358fe2b8a470803a2ec0c9930629b6" +} \ No newline at end of file diff --git a/graphify-out/2026-08-19/manifest.json b/graphify-out/2026-08-19/manifest.json new file mode 100644 index 0000000..18eb4af --- /dev/null +++ b/graphify-out/2026-08-19/manifest.json @@ -0,0 +1,67 @@ +{ + "docs/00-ARQUITECTURA.md": { + "mtime": 1787116450.5336444, + "ast_hash": "ae2257c149d3430da6823558b3750ed6", + "semantic_hash": "" + }, + "docs/01-ELEMENTOR-CLASSICO.md": { + "mtime": 1787117462.0784547, + "ast_hash": "0a293f4d65574952b8be56fa57259af6", + "semantic_hash": "" + }, + "docs/02-ATOMIC-V4-GUTENBERG.md": { + "mtime": 1787117548.949143, + "ast_hash": "b0f909b8212428e433c1116688a23763", + "semantic_hash": "" + }, + "docs/03-WORDPRESS-CORE-TEMAS.md": { + "mtime": 1787117302.2605903, + "ast_hash": "4930718faa985078263df3adc0d476cf", + "semantic_hash": "" + }, + "docs/04-THEMER.md": { + "mtime": 1787117386.2796364, + "ast_hash": "caa9c0b7a5fa8f9fbba4c6843970e5d6", + "semantic_hash": "" + }, + "docs/05-REDIRECTS-SEARCH-LEDGER.md": { + "mtime": 1787117265.8808794, + "ast_hash": "dda4a02913bdc0e1a4ad183a94cfaa94", + "semantic_hash": "" + }, + "docs/06-SANDBOX-CUSTOM-CODE.md": { + "mtime": 1787117373.3797464, + "ast_hash": "dabc5ce243ae7f9dd3affd5e443f0689", + "semantic_hash": "" + }, + "docs/07-SYSTEM-OPS.md": { + "mtime": 1787117916.9961705, + "ast_hash": "7c3c342bc505c620d58b3fd7a2a4bea4", + "semantic_hash": "" + }, + "docs/08-INTEGRACOES-TERCEIROS.md": { + "mtime": 1787117238.7386587, + "ast_hash": "6554b848b88618e823cbe45c7cde149c", + "semantic_hash": "" + }, + "docs/09-STOCK-IMAGES-CLOUD-OAUTH.md": { + "mtime": 1787117293.6521044, + "ast_hash": "a7cc5fc5d8dadcff115a5ecd7025ee30", + "semantic_hash": "" + }, + "docs/10-MODULOS-E-INVENTARIO-PRO.md": { + "mtime": 1787117721.9560692, + "ast_hash": "d44d5afadee4312373d78c989a74cc1d", + "semantic_hash": "" + }, + "docs/11-WOOCOMMERCE-BLUEPRINT.md": { + "mtime": 1787119782.238708, + "ast_hash": "14dd4613a906c0de9e1c64d5e8706822", + "semantic_hash": "" + }, + "docs/INDEX.md": { + "mtime": 1787119806.4339821, + "ast_hash": "bc362e3c65cd504567232c69a800427c", + "semantic_hash": "" + } +} \ No newline at end of file diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index 511044d..3025139 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,16 +1,16 @@ # Graph Report - emcp-tools-mapping (2026-08-19) ## Corpus Check -- 13 files · ~66,158 words +- 14 files · ~71,911 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 55 nodes · 54 edges · 10 communities +- 80 nodes · 78 edges · 12 communities - Extraction: 100% EXTRACTED · 0% INFERRED · 0% AMBIGUOUS - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `2f98a527` +- Built from commit: `58acdd71` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). @@ -25,18 +25,20 @@ - [[_COMMUNITY_4. Clientes|4. Clientes]] - [[_COMMUNITY_5. Cupões Descontos|5. Cupões / Descontos]] - [[_COMMUNITY_9. Blueprint para réplica|9. Blueprint para réplica]] +- [[_COMMUNITY_6. Sandbox e ciclo de vida — reaproveitar o modelo já confirmado em código real `REAL`|6. Sandbox e ciclo de vida — reaproveitar o modelo já confirmado em código real `[REAL]`]] +- [[_COMMUNITY_8. Blueprint para réplica|8. Blueprint para réplica]] ## God Nodes (most connected - your core abstractions) 1. `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)` - 12 edges -2. `EMCP Tools — Mapeamento completo e blueprint de réplica` - 9 edges -3. `5. Sequência de construção recomendada para uma réplica` - 8 edges -4. `3. Encomendas` - 6 edges -5. `6. Relatórios / Analytics (`wc-analytics/*`)` - 5 edges -6. `7. Webhooks` - 5 edges -7. `2. Produtos` - 4 edges -8. `4. Clientes` - 4 edges -9. `5. Cupões / Descontos` - 4 edges -10. `9. Blueprint para réplica` - 4 edges +2. `12 — Widget Builder: blueprint de abilities MCP (desenho próprio, não é auditoria EMCP Pro)` - 11 edges +3. `EMCP Tools — Mapeamento completo e blueprint de réplica` - 9 edges +4. `5. Sequência de construção recomendada para uma réplica` - 8 edges +5. `6. Sandbox e ciclo de vida — reaproveitar o modelo já confirmado em código real `[REAL]`` - 6 edges +6. `3. Encomendas` - 6 edges +7. `6. Relatórios / Analytics (`wc-analytics/*`)` - 5 edges +8. `7. Webhooks` - 5 edges +9. `5. O compilador spec→PHP — desenho próprio `[DESENHO PRÓPRIO]`` - 4 edges +10. `8. Blueprint para réplica` - 4 edges ## Surprising Connections (you probably didn't know these) - None detected - all connections are within the same source files. @@ -44,10 +46,10 @@ ## Import Cycles - None detected. -## Communities (10 total, 0 thin omitted) +## Communities (12 total, 0 thin omitted) ### Community 0 - "EMCP Tools — Mapeamento completo e blueprint de réplica" -Cohesion: 0.25 +Cohesion: 0.20 Nodes (8): 1. Mapa dos documentos, 2. O achado mais importante de toda a série, 3. Os 5 subsistemas de maior valor para copiar quase verbatim, 4. Padrões arquitecturais que atravessam todo o plugin, 6. Tabela de risco consolidada, 7. Como usar esta documentação, EMCP Tools — Mapeamento completo e blueprint de réplica, Metodologia ### Community 1 - "5. Sequência de construção recomendada para uma réplica" @@ -55,8 +57,8 @@ Cohesion: 0.25 Nodes (8): 5. Sequência de construção recomendada para uma réplica, Explicitamente fora de âmbito (doc 10 §2), Fase 0 — Fundação (sem isto, nada mais tem rollback nem é seguro), Fase 1 — Conteúdo WordPress puro (sem dependência de Elementor), Fase 2 — Elementor (o núcleo de "construir páginas"), Fase 3 — Camadas de produto sobre o conteúdo, Fase 4 — Superfície de risco elevado, opt-in, Fase 5 — Integrações e periferia (valor incremental, não bloqueante) ### Community 2 - "11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)" -Cohesion: 0.29 -Nodes (5): 0. Porque este documento é diferente dos outros 10, 10. Fonte, 11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP), 1. Panorama, 8. Segurança / gating recomendado +Cohesion: 0.20 +Nodes (9): 0. Porque este documento é diferente dos outros 10, 10. Fonte, 11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP), 1. Panorama, 2.1 Schema real (campos confirmados por leitura de `get_item_schema()`), 2.2 Endpoints extra confirmados (além do CRUD standard), 2.3 Tabela de ability proposta — Produtos, 2. Produtos (+1 more) ### Community 3 - "3. Encomendas" Cohesion: 0.33 @@ -71,8 +73,8 @@ Cohesion: 0.40 Nodes (5): 7.1 Modelo de dados real (confirmado por `$data` default em `WC_Webhook`), 7.2 Validação de topic — não é livre texto, 7.3 Entrega assíncrona por omissão, 7.4 Tabela de ability proposta — Webhooks, 7. Webhooks ### Community 6 - "2. Produtos" -Cohesion: 0.50 -Nodes (4): 2.1 Schema real (campos confirmados por leitura de `get_item_schema()`), 2.2 Endpoints extra confirmados (além do CRUD standard), 2.3 Tabela de ability proposta — Produtos, 2. Produtos +Cohesion: 0.14 +Nodes (14): 0. Panorama — porque este documento é diferente dos outros 11 e o que fundamenta cada peça, 12 — Widget Builder: blueprint de abilities MCP (desenho próprio, não é auditoria EMCP Pro), 1. A "spec" de um widget — estrutura de dados proposta `[DESENHO PRÓPRIO]`, 2. Como um widget é normalmente registado — contrato real do Elementor `[REAL]`, 3.1 Controlos de dados simples/compostos (`get_controls_names()`), 3.2 Group controls (`get_groups_names()`) — controlos compostos multi-campo, 3. `list-control-types` — catálogo real de tipos de controlo `[REAL]` + parâmetros `[misto]`, 4. `validate-widget-spec` — o que validar `[DESENHO PRÓPRIO, sobre APIs `[REAL]`]` (+6 more) ### Community 7 - "4. Clientes" Cohesion: 0.50 @@ -86,18 +88,28 @@ Nodes (4): 5.1 Tipos de desconto reais (via `wc_get_coupon_types()`), 5.2 Campos Cohesion: 0.50 Nodes (4): 9.1 Prioridade de construção (por valor/esforço, assumindo Fase 0 do doc00 já feita), 9.2 Reaproveitamento explícito dos padrões já documentados, 9.3 O que NÃO replicar sem decisão explícita, 9. Blueprint para réplica +### Community 10 - "6. Sandbox e ciclo de vida — reaproveitar o modelo já confirmado em código real `[REAL]`" +Cohesion: 0.33 +Nodes (6): 6.1 Camada 1 — Manifest-only lookup `[REAL]`, 6.2 Camada 2 — Tamper guard sha256 `[REAL]`, 6.3 Camada 3 — Path containment guard `[REAL]`, 6.4 Camada 4 — `runtime_validate()` + shutdown fatal-recovery `[REAL]`, 6.5 Decisão de segurança: aprovação humana obrigatória antes de activar `[DESENHO PRÓPRIO, precedente REAL]`, 6. Sandbox e ciclo de vida — reaproveitar o modelo já confirmado em código real `[REAL]` + +### Community 11 - "8. Blueprint para réplica" +Cohesion: 0.50 +Nodes (4): 8. Blueprint para réplica, Construir de raiz (`[DESENHO PRÓPRIO]`, sequência recomendada por dependência), Copiar quase 1:1 (já é código real, `[REAL]`), Deixar de fora ou adiar explicitamente + ## Knowledge Gaps -- **43 isolated node(s):** `0. Porque este documento é diferente dos outros 10`, `1. Panorama`, `2.1 Schema real (campos confirmados por leitura de `get_item_schema()`)`, `2.2 Endpoints extra confirmados (além do CRUD standard)`, `2.3 Tabela de ability proposta — Produtos` (+38 more) +- **62 isolated node(s):** `0. Panorama — porque este documento é diferente dos outros 11 e o que fundamenta cada peça`, `1. A "spec" de um widget — estrutura de dados proposta `[DESENHO PRÓPRIO]``, `2. Como um widget é normalmente registado — contrato real do Elementor `[REAL]``, `3.1 Controlos de dados simples/compostos (`get_controls_names()`)`, `3.2 Group controls (`get_groups_names()`) — controlos compostos multi-campo` (+57 more) These have ≤1 connection - possible missing edges or undocumented components. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)` connect `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)` to `3. Encomendas`, `6. Relatórios / Analytics (`wc-analytics/*`)`, `7. Webhooks`, `2. Produtos`, `4. Clientes`, `5. Cupões / Descontos`, `9. Blueprint para réplica`?** - _High betweenness centrality (0.852) - this node is a cross-community bridge._ -- **Why does `EMCP Tools — Mapeamento completo e blueprint de réplica` connect `EMCP Tools — Mapeamento completo e blueprint de réplica` to `5. Sequência de construção recomendada para uma réplica`, `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)`?** - _High betweenness centrality (0.463) - this node is a cross-community bridge._ -- **Why does `5. Sequência de construção recomendada para uma réplica` connect `5. Sequência de construção recomendada para uma réplica` to `EMCP Tools — Mapeamento completo e blueprint de réplica`?** - _High betweenness centrality (0.245) - this node is a cross-community bridge._ -- **What connects `0. Porque este documento é diferente dos outros 10`, `1. Panorama`, `2.1 Schema real (campos confirmados por leitura de `get_item_schema()`)` to the rest of the system?** - _43 weakly-connected nodes found - possible documentation gaps or missing edges._ \ No newline at end of file +- **Why does `12 — Widget Builder: blueprint de abilities MCP (desenho próprio, não é auditoria EMCP Pro)` connect `2. Produtos` to `EMCP Tools — Mapeamento completo e blueprint de réplica`, `6. Sandbox e ciclo de vida — reaproveitar o modelo já confirmado em código real `[REAL]``, `8. Blueprint para réplica`?** + _High betweenness centrality (0.207) - this node is a cross-community bridge._ +- **Why does `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)` connect `11 — WooCommerce: blueprint de abilities MCP (não é auditoria EMCP)` to `3. Encomendas`, `6. Relatórios / Analytics (`wc-analytics/*`)`, `7. Webhooks`, `4. Clientes`, `5. Cupões / Descontos`, `9. Blueprint para réplica`?** + _High betweenness centrality (0.197) - this node is a cross-community bridge._ +- **Why does `EMCP Tools — Mapeamento completo e blueprint de réplica` connect `EMCP Tools — Mapeamento completo e blueprint de réplica` to `5. Sequência de construção recomendada para uma réplica`?** + _High betweenness centrality (0.152) - this node is a cross-community bridge._ +- **What connects `0. Panorama — porque este documento é diferente dos outros 11 e o que fundamenta cada peça`, `1. A "spec" de um widget — estrutura de dados proposta `[DESENHO PRÓPRIO]``, `2. Como um widget é normalmente registado — contrato real do Elementor `[REAL]`` to the rest of the system?** + _62 weakly-connected nodes found - possible documentation gaps or missing edges._ +- **Should `2. Produtos` be split into smaller, more focused modules?** + _Cohesion score 0.14285714285714285 - nodes in this community are weakly interconnected._ \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.6/03e68caf73760e3daf660ac7f435d75eb697c63d0e0e581182dc20db53127c36.json b/graphify-out/cache/ast/v0.9.6/03e68caf73760e3daf660ac7f435d75eb697c63d0e0e581182dc20db53127c36.json new file mode 100644 index 0000000..dc086bd --- /dev/null +++ b/graphify-out/cache/ast/v0.9.6/03e68caf73760e3daf660ac7f435d75eb697c63d0e0e581182dc20db53127c36.json @@ -0,0 +1 @@ +{"nodes": [{"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_md", "label": "12-WIDGET-BUILDER-BLUEPRINT.md", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L1"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "label": "12 \u2014 Widget Builder: blueprint de abilities MCP (desenho pr\u00f3prio, n\u00e3o \u00e9 auditoria EMCP Pro)", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L1"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_0_panorama_porque_este_documento_\u00e9_diferente_dos_outros_11_e_o_que_fundamenta_cada_pe\u00e7a", "label": "0. Panorama \u2014 porque este documento \u00e9 diferente dos outros 11 e o que fundamenta cada pe\u00e7a", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L15"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_1_a_spec_de_um_widget_estrutura_de_dados_proposta_desenho_pr\u00f3prio", "label": "1. A \"spec\" de um widget \u2014 estrutura de dados proposta `[DESENHO PR\u00d3PRIO]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L65"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_2_como_um_widget_\u00e9_normalmente_registado_contrato_real_do_elementor_real", "label": "2. Como um widget \u00e9 normalmente registado \u2014 contrato real do Elementor `[REAL]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L144"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_3_list_control_types_cat\u00e1logo_real_de_tipos_de_controlo_real_par\u00e2metros_misto", "label": "3. `list-control-types` \u2014 cat\u00e1logo real de tipos de controlo `[REAL]` + par\u00e2metros `[misto]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L190"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_3_1_controlos_de_dados_simples_compostos_get_controls_names", "label": "3.1 Controlos de dados simples/compostos (`get_controls_names()`)", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L199"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_3_2_group_controls_get_groups_names_controlos_compostos_multi_campo", "label": "3.2 Group controls (`get_groups_names()`) \u2014 controlos compostos multi-campo", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L235"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_4_validate_widget_spec_o_que_validar_desenho_pr\u00f3prio_sobre_apis_real", "label": "4. `validate-widget-spec` \u2014 o que validar `[DESENHO PR\u00d3PRIO, sobre APIs `[REAL]`]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L257"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_o_compilador_spec_php_desenho_pr\u00f3prio_desenho_pr\u00f3prio", "label": "5. O compilador spec\u2192PHP \u2014 desenho pr\u00f3prio `[DESENHO PR\u00d3PRIO]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L280"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_1_esqueleto_da_classe_gerada", "label": "5.1 Esqueleto da classe gerada", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L285"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_2_mapeamento_tipo_de_controlo_fun\u00e7\u00e3o_de_escape_no_render_desenho_pr\u00f3prio", "label": "5.2 Mapeamento tipo de controlo \u2192 fun\u00e7\u00e3o de escape no `render()` `[DESENHO PR\u00d3PRIO]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L331"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_3_registo_do_widget_compilado_reaproveita_o_hook_real_sec\u00e7\u00e3o_2", "label": "5.3 Registo do widget compilado \u2014 reaproveita o hook real (sec\u00e7\u00e3o 2)", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L351"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_sandbox_e_ciclo_de_vida_reaproveitar_o_modelo_j\u00e1_confirmado_em_c\u00f3digo_real_real", "label": "6. Sandbox e ciclo de vida \u2014 reaproveitar o modelo j\u00e1 confirmado em c\u00f3digo real `[REAL]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L372"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_1_camada_1_manifest_only_lookup_real", "label": "6.1 Camada 1 \u2014 Manifest-only lookup `[REAL]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L381"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_2_camada_2_tamper_guard_sha256_real", "label": "6.2 Camada 2 \u2014 Tamper guard sha256 `[REAL]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L388"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_3_camada_3_path_containment_guard_real", "label": "6.3 Camada 3 \u2014 Path containment guard `[REAL]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L396"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_4_camada_4_runtime_validate_shutdown_fatal_recovery_real", "label": "6.4 Camada 4 \u2014 `runtime_validate()` + shutdown fatal-recovery `[REAL]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L402"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_5_decis\u00e3o_de_seguran\u00e7a_aprova\u00e7\u00e3o_humana_obrigat\u00f3ria_antes_de_activar_desenho_pr\u00f3prio_precedente_real", "label": "6.5 Decis\u00e3o de seguran\u00e7a: aprova\u00e7\u00e3o humana obrigat\u00f3ria antes de activar `[DESENHO PR\u00d3PRIO, precedente REAL]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L418"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_7_tabela_de_abilities_propostas_desenho_pr\u00f3prio_sobre_camadas_real", "label": "7. Tabela de abilities propostas `[DESENHO PR\u00d3PRIO sobre camadas `[REAL]``]`", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L447"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_8_blueprint_para_r\u00e9plica", "label": "8. Blueprint para r\u00e9plica", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L483"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_copiar_quase_1_1_j\u00e1_\u00e9_c\u00f3digo_real_real", "label": "Copiar quase 1:1 (j\u00e1 \u00e9 c\u00f3digo real, `[REAL]`)", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L485"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_construir_de_raiz_desenho_pr\u00f3prio_sequ\u00eancia_recomendada_por_depend\u00eancia", "label": "Construir de raiz (`[DESENHO PR\u00d3PRIO]`, sequ\u00eancia recomendada por depend\u00eancia)", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L498"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_deixar_de_fora_ou_adiar_explicitamente", "label": "Deixar de fora ou adiar explicitamente", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L519"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_9_fonte", "label": "9. Fonte", "file_type": "document", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L535"}], "edges": [{"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L1", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_0_panorama_porque_este_documento_\u00e9_diferente_dos_outros_11_e_o_que_fundamenta_cada_pe\u00e7a", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L15", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_1_a_spec_de_um_widget_estrutura_de_dados_proposta_desenho_pr\u00f3prio", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L65", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_2_como_um_widget_\u00e9_normalmente_registado_contrato_real_do_elementor_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L144", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_3_list_control_types_cat\u00e1logo_real_de_tipos_de_controlo_real_par\u00e2metros_misto", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L190", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_3_list_control_types_cat\u00e1logo_real_de_tipos_de_controlo_real_par\u00e2metros_misto", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_3_1_controlos_de_dados_simples_compostos_get_controls_names", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L199", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_3_list_control_types_cat\u00e1logo_real_de_tipos_de_controlo_real_par\u00e2metros_misto", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_3_2_group_controls_get_groups_names_controlos_compostos_multi_campo", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L235", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_4_validate_widget_spec_o_que_validar_desenho_pr\u00f3prio_sobre_apis_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L257", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_o_compilador_spec_php_desenho_pr\u00f3prio_desenho_pr\u00f3prio", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L280", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_o_compilador_spec_php_desenho_pr\u00f3prio_desenho_pr\u00f3prio", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_1_esqueleto_da_classe_gerada", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L285", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_o_compilador_spec_php_desenho_pr\u00f3prio_desenho_pr\u00f3prio", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_2_mapeamento_tipo_de_controlo_fun\u00e7\u00e3o_de_escape_no_render_desenho_pr\u00f3prio", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L331", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_o_compilador_spec_php_desenho_pr\u00f3prio_desenho_pr\u00f3prio", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_5_3_registo_do_widget_compilado_reaproveita_o_hook_real_sec\u00e7\u00e3o_2", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L351", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_sandbox_e_ciclo_de_vida_reaproveitar_o_modelo_j\u00e1_confirmado_em_c\u00f3digo_real_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L372", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_sandbox_e_ciclo_de_vida_reaproveitar_o_modelo_j\u00e1_confirmado_em_c\u00f3digo_real_real", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_1_camada_1_manifest_only_lookup_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L381", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_sandbox_e_ciclo_de_vida_reaproveitar_o_modelo_j\u00e1_confirmado_em_c\u00f3digo_real_real", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_2_camada_2_tamper_guard_sha256_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L388", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_sandbox_e_ciclo_de_vida_reaproveitar_o_modelo_j\u00e1_confirmado_em_c\u00f3digo_real_real", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_3_camada_3_path_containment_guard_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L396", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_sandbox_e_ciclo_de_vida_reaproveitar_o_modelo_j\u00e1_confirmado_em_c\u00f3digo_real_real", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_4_camada_4_runtime_validate_shutdown_fatal_recovery_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L402", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_sandbox_e_ciclo_de_vida_reaproveitar_o_modelo_j\u00e1_confirmado_em_c\u00f3digo_real_real", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_6_5_decis\u00e3o_de_seguran\u00e7a_aprova\u00e7\u00e3o_humana_obrigat\u00f3ria_antes_de_activar_desenho_pr\u00f3prio_precedente_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L418", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_7_tabela_de_abilities_propostas_desenho_pr\u00f3prio_sobre_camadas_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L447", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_8_blueprint_para_r\u00e9plica", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L483", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_8_blueprint_para_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_copiar_quase_1_1_j\u00e1_\u00e9_c\u00f3digo_real_real", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L485", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_8_blueprint_para_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_construir_de_raiz_desenho_pr\u00f3prio_sequ\u00eancia_recomendada_por_depend\u00eancia", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L498", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_8_blueprint_para_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_deixar_de_fora_ou_adiar_explicitamente", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L519", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_12_widget_builder_blueprint_de_abilities_mcp_desenho_pr\u00f3prio_n\u00e3o_\u00e9_auditoria_emcp_pro", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_9_fonte", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/12-WIDGET-BUILDER-BLUEPRINT.md", "source_location": "L535", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.6/922b90021fe3c471cd76a515e327e48ca18f738e3523ffbcd6af292724cdafbf.json b/graphify-out/cache/ast/v0.9.6/922b90021fe3c471cd76a515e327e48ca18f738e3523ffbcd6af292724cdafbf.json new file mode 100644 index 0000000..d077eab --- /dev/null +++ b/graphify-out/cache/ast/v0.9.6/922b90021fe3c471cd76a515e327e48ca18f738e3523ffbcd6af292724cdafbf.json @@ -0,0 +1 @@ +{"nodes": [{"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "label": "INDEX.md", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L1"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "label": "EMCP Tools \u2014 Mapeamento completo e blueprint de r\u00e9plica", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L1"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_1_mapa_dos_documentos", "label": "1. Mapa dos documentos", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L19"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_2_o_achado_mais_importante_de_toda_a_s\u00e9rie", "label": "2. O achado mais importante de toda a s\u00e9rie", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L44"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_3_os_5_subsistemas_de_maior_valor_para_copiar_quase_verbatim", "label": "3. Os 5 subsistemas de maior valor para copiar quase verbatim", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L60"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_4_padr\u00f5es_arquitecturais_que_atravessam_todo_o_plugin", "label": "4. Padr\u00f5es arquitecturais que atravessam todo o plugin", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L95"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "label": "5. Sequ\u00eancia de constru\u00e7\u00e3o recomendada para uma r\u00e9plica", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L129"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_0_funda\u00e7\u00e3o_sem_isto_nada_mais_tem_rollback_nem_\u00e9_seguro", "label": "Fase 0 \u2014 Funda\u00e7\u00e3o (sem isto, nada mais tem rollback nem \u00e9 seguro)", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L133"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_1_conte\u00fado_wordpress_puro_sem_depend\u00eancia_de_elementor", "label": "Fase 1 \u2014 Conte\u00fado WordPress puro (sem depend\u00eancia de Elementor)", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L144"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_2_elementor_o_n\u00facleo_de_construir_p\u00e1ginas", "label": "Fase 2 \u2014 Elementor (o n\u00facleo de \"construir p\u00e1ginas\")", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L149"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_3_camadas_de_produto_sobre_o_conte\u00fado", "label": "Fase 3 \u2014 Camadas de produto sobre o conte\u00fado", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L156"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_4_superf\u00edcie_de_risco_elevado_opt_in", "label": "Fase 4 \u2014 Superf\u00edcie de risco elevado, opt-in", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L162"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_5_integra\u00e7\u00f5es_e_periferia_valor_incremental_n\u00e3o_bloqueante", "label": "Fase 5 \u2014 Integra\u00e7\u00f5es e periferia (valor incremental, n\u00e3o bloqueante)", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L172"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_explicitamente_fora_de_\u00e2mbito_doc_10_2", "label": "Explicitamente fora de \u00e2mbito (doc 10 \u00a72)", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L178"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_6_tabela_de_risco_consolidada", "label": "6. Tabela de risco consolidada", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L188"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_7_como_usar_esta_documenta\u00e7\u00e3o", "label": "7. Como usar esta documenta\u00e7\u00e3o", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L210"}, {"id": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_metodologia", "label": "Metodologia", "file_type": "document", "source_file": "docs/INDEX.md", "source_location": "L226"}], "edges": [{"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L1", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_1_mapa_dos_documentos", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L19", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_00_arquitectura_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L23", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_01_elementor_classico_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L24", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_02_atomic_v4_gutenberg_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L25", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_03_wordpress_core_temas_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L26", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_04_themer_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L27", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_05_redirects_search_ledger_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L28", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_06_sandbox_custom_code_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L29", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_07_system_ops_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L30", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_08_integracoes_terceiros_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L31", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_09_stock_images_cloud_oauth_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L32", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_10_modulos_e_inventario_pro_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L33", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_11_woocommerce_blueprint_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L34", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_md", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_12_widget_builder_blueprint_md", "relation": "references", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L35", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_2_o_achado_mais_importante_de_toda_a_s\u00e9rie", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L44", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_3_os_5_subsistemas_de_maior_valor_para_copiar_quase_verbatim", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L60", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_4_padr\u00f5es_arquitecturais_que_atravessam_todo_o_plugin", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L95", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L129", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_0_funda\u00e7\u00e3o_sem_isto_nada_mais_tem_rollback_nem_\u00e9_seguro", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L133", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_1_conte\u00fado_wordpress_puro_sem_depend\u00eancia_de_elementor", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L144", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_2_elementor_o_n\u00facleo_de_construir_p\u00e1ginas", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L149", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_3_camadas_de_produto_sobre_o_conte\u00fado", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L156", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_4_superf\u00edcie_de_risco_elevado_opt_in", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L162", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_fase_5_integra\u00e7\u00f5es_e_periferia_valor_incremental_n\u00e3o_bloqueante", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L172", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_5_sequ\u00eancia_de_constru\u00e7\u00e3o_recomendada_para_uma_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_explicitamente_fora_de_\u00e2mbito_doc_10_2", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L178", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_6_tabela_de_risco_consolidada", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L188", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_7_como_usar_esta_documenta\u00e7\u00e3o", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L210", "weight": 1.0}, {"source": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_emcp_tools_mapeamento_completo_e_blueprint_de_r\u00e9plica", "target": "media_ealmeida_dados_dev_emcp_tools_mapping_docs_index_metodologia", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/INDEX.md", "source_location": "L226", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0} \ No newline at end of file diff --git a/graphify-out/cache/stat-index.json b/graphify-out/cache/stat-index.json index 991e60f..7f68265 100644 --- a/graphify-out/cache/stat-index.json +++ b/graphify-out/cache/stat-index.json @@ -1 +1 @@ -{"/media/ealmeida/Dados/Dev/emcp-tools-mapping/docs/11-WOOCOMMERCE-BLUEPRINT.md":{"size":49610,"mtime_ns":1787119782238708136,"hash":"9fd04f9130e82a256c669972c07eed11c97a82dbb0a05703f99c467702c67601"},"/media/ealmeida/Dados/Dev/emcp-tools-mapping/docs/INDEX.md":{"size":17826,"mtime_ns":1787119806433982191,"hash":"75376ed5bec049c735c11a41cf8c0a4dfe472c35624a0242eeac261222f52bcf"}} \ No newline at end of file +{"/media/ealmeida/Dados/Dev/emcp-tools-mapping/docs/11-WOOCOMMERCE-BLUEPRINT.md":{"size":49610,"mtime_ns":1787119782238708136,"hash":"9fd04f9130e82a256c669972c07eed11c97a82dbb0a05703f99c467702c67601"},"/media/ealmeida/Dados/Dev/emcp-tools-mapping/docs/INDEX.md":{"size":18350,"mtime_ns":1787121733648981838,"hash":"922b90021fe3c471cd76a515e327e48ca18f738e3523ffbcd6af292724cdafbf"},"/media/ealmeida/Dados/Dev/emcp-tools-mapping/docs/12-WIDGET-BUILDER-BLUEPRINT.md":{"size":45994,"mtime_ns":1787121705537649698,"hash":"03e68caf73760e3daf660ac7f435d75eb697c63d0e0e581182dc20db53127c36"}} \ No newline at end of file diff --git a/graphify-out/graph.html b/graphify-out/graph.html index e673095..7754bef 100644 --- a/graphify-out/graph.html +++ b/graphify-out/graph.html @@ -63,12 +63,12 @@
-
55 nodes · 54 edges · 10 communities
+
80 nodes · 78 edges · 12 communities