---
name: wiki-publish-safely
description: >-
  The hard rules and operational pitfalls for editing Adom Wiki pages
  (wiki.adom.inc) without breaking them — write both storage layers, never
  base64 a text file, versions are immutable, soft-delete blocks re-creation, the
  hero gets clobbered on publish, rate limits, and the non-negotiable verify-in-pup
  step. Read this before AND after any publish, file push, README change, or
  metadata edit. Trigger words: wiki publish broke the page, page shows
  placeholder, readme is gibberish, files tab empty, hero disappeared, hero
  unlinked, UNIQUE constraint pages, immutable version, adompkg 429, ghost page,
  verify wiki in pup, wiki publish checklist, don't break the wiki page.
---

Parent skill: **adom-wiki-skillpack**

# Publishing to the wiki without breaking the page

Every item here is a real incident that recurs. Treat them as hard rules. The
mechanics live in **wiki-api**; this is the "don't shoot yourself in the foot"
companion.

## The five rules that prevent broken pages

1. **Write BOTH layers, every publish.** Git repo (`POST /files`) *and* package
   registry (`adompkg publish`). Only one → the page is broken (placeholder Files
   tab, or a README that won't `adompkg install`). See **wiki-anatomy**.

2. **The hero gets clobbered — re-push `page.json` LAST.** `adompkg publish`
   overwrites the repo's `page.json` with the package manifest, which has **no
   `hero`** — so the page-header hero is unlinked on every publish. The PNG is NOT
   deleted; only its reference is dropped. **Fix:** publish first, then push a
   *complete* `page.json` (with `hero:{type:"image",path:"screenshots/hero.png"}`,
   title, brief, tags) as the final commit, and confirm
   `GET /api/v1/pages/<slug>` shows `hero_path` set. Full detail → **wiki-hero**.
   The same clobber resets the page **title and brief** to the package values —
   the complete `page.json` re-push restores those too. Two title traps: (a) put a
   `title` in **package.json** as well — the manifest has none by default, so the
   clobber resets the title to the bare **slug**; (b) the title must be a
   **human, descriptive name — NEVER the slug echo** (`Wiki Hero Image Skill`, not
   `adom-wiki-hero-image`). Cards, search, the homepage, and the screensaver all
   show the title; nobody reads slugs. → **wiki-repo-styles** / **wiki-family**.

3. **Text is plain; only binaries are base64.** Base64-encoding a `.md`/`.json`/
   `.sh` makes the wiki store the base64 string as the file content → README
   renders as gibberish. Images/fonts/archives go base64; everything else plain.

4. **Versions are immutable; never delete-and-recreate.** Once `0.1.0` is
   published it can't be overwritten — `adompkg version patch` before republishing
   changed source. And `DELETE /pages/:slug` only *soft*-deletes (sets
   `deleted_at`), after which republishing the same slug fails with
   `UNIQUE constraint failed: pages.owner, pages.slug`. Bump the version instead
   of deleting. (Hard purge exists — `DELETE /pages/<slug>?hard=true` — but it's
   irreversible and rarely the right move.)

5. **Verify with your eyes — open the live page in pup.** After ANY wiki edit
   (publish, file push, metadata/README/hero change, even a one-file fix), open
   the page in a pup window on the user's laptop and screenshot-confirm it
   rendered. Do not report a wiki edit as done from API JSON alone.

   ```bash
   OWNER=john; SLUG=my-page; LAP=AdomLapper   # `adom-desktop status` shows the laptop host
   adom-desktop browser_open_window \
     "{\"sessionId\":\"wiki\",\"profile\":\"wiki\",\"url\":\"https://wiki.adom.inc/$OWNER/$SLUG\"}" \
     --target "$LAP"
   sleep 3
   adom-desktop browser_screenshot '{"sessionId":"wiki","maxWidth":1500}' --target "$LAP"
   # Read the screenshot; confirm it rendered before telling the user it's done.
   ```

   Reuse `sessionId:"wiki"` / `profile:"wiki"` every time so the login persists;
   `browser_navigate` an already-open window rather than spawning new ones.

## Never show the hero twice

The page header renders the hero from `page.json` automatically. **Do NOT also
embed the hero image in the README body** — the human would see the same image
twice, back to back. It's the most common README mistake on the wiki. Inline
README images must be *other* screenshots/diagrams. Before publishing, grep the
README for the hero filename and delete any line that references it. → **wiki-readme**.

## Other gotchas

- **Cloudflare WAF blocks Python urllib/requests without a `User-Agent`** →
  send `User-Agent: adompkg/2.1.0`. curl sends its own UA and is fine.
- **Publish-only pages create ghost rows.** `adompkg publish` without first
  `POST /pages` makes a tarball but no git repo; a later `POST /files` then
  inserts a *second* page row (a duplicate on the listing). Always create the
  page first.
- **Rate limit: ~10 publishes/minute** → HTTP 429. Space them or retry.
- **Search hyphen bug:** FTS reads `-` as a column operator (`chip-fetcher` →
  "no such column: fetcher"). Most slugs have hyphens; expect this until fixed.
- **Inline images need HEAD support** on `/blob/` routes — a known wiki bug means
  `<img>` can 404 on preflight even though the tag is correct. Verify visually.

## The publish checklist

- [ ] `package.json`: version bumped, `files[]` complete, `dependencies` set
- [ ] Page created (first time only) via `POST /pages`
- [ ] `adompkg publish` succeeded (tarball in registry)
- [ ] ALL source pushed to git (text plain, binaries base64, UA header)
- [ ] **Complete `page.json` pushed LAST** → `hero_path`, title, brief restored
- [ ] **Title is descriptive, NOT the slug** (and `title` is set in `package.json` too, so publish won't reset it to the slug)
- [ ] README does NOT embed the hero image (page header shows it already)
- [ ] Opened in pup + screenshot read: README renders, Files tab full, hero shows
- [ ] `adompkg info <slug>` shows the right version + dependencies
