# MCPedia Phase 4 — Operability & Correctness Hardening > Reinterpretation: the PHASES.md "Scale-out" items (OpenSearch, object storage, > multi-tenant, distributed workers) are YAGNI at KB scale (4 docs). Phase 4 = > make the Phase 3 async + revision machinery **correct, secure, observable, and > deployable** — not speculative infra. Each task below fixes a real gap found > by reading the code, not a hypothetical need. ## Tasks ### T1 — `restoreRevision` must rebuild semantic chunks (CORRECTNESS BUG) **Root cause:** `packages/core/src/revision.service.ts` `restoreRevision` writes the old body back into `documents` but never calls `indexChunks(slug, body)`. So after a restore, keyword search (FTS on `documents.body`) is correct but `document_chunks`/embeddings stay on the *new* body → semantic + hybrid search return stale/ghost chunks. **Fix:** - Add `reindexChunks(slug)` to `@mcpedia/core` that re-runs `indexChunks(slug, body)` using the live `documents.body` (the new body after the update). - Call it inside `restoreRevision` after the `documents` update (wrap in try/catch like `indexContentFile` so embed failure doesn't abort the restore). - Add a unit-style assertion to the MCP smoke test or a small script: restore → `document_chunks` count matches re-chunked body. **Files:** `packages/core/src/revision.service.ts`, `packages/core/src/index.ts`, `packages/core/src/document.service.ts` (export existing `indexChunks` if needed). ### T2 — Secure the git-sync webhook (SECURITY) **Root cause:** `apps/api/src/index.ts` `/hooks/reindex` and `/hooks/index` accept any request with no `WEBHOOK_SECRET` check — `.env.example` defines `WEBHOOK_SECRET` but the router never reads it. **Fix:** - In `apps/api/src/index.ts`, compare `c.req.header("x-webhook-secret")` (or `?secret=`) against `WEBHOOK_SECRET` (from `@mcpedia/config`). If unset/mismatch → `401`. If `WEBHOOK_SECRET` env is empty, reject at startup with a clear log (fail-fast, don't run an open endpoint). - Add `WEBHOOK_SECRET` to `packages/config/src/index.ts` export. - Document the header in README + verify with curl (401 without secret, 200 with). **Files:** `apps/api/src/index.ts`, `packages/config/src/index.ts`, README. ### T3 — Web UI revisions view (UX) **Root cause:** Web UI (server components) calls `@mcpedia/core` directly; there is no revisions surface even though `revisions`/`restoreRevision` tRPC + MCP resource exist. **Fix (server-component only, no client JS):** - On the doc page (`apps/web/app/[section]/[...slug]/page.tsx`), fetch `listRevisions(fullSlug, 10)` and render a "History" panel: revision number, reason, createdAt, body length, and a `/api/revisions/restore` link/POST that calls the tRPC `restoreRevision` mutation via a server action or a form POST to a small route handler. Simplest: a `