# Kami Agent Guide

> Personal/global agent rules may live outside this repository. This file records Kami-specific repository maps, Working Rules, Current Risk Areas, Verification, Release Flow, and Fonts.

## Project

Kami is a document-generation skill and template system. It ships editorial HTML templates, reference guides, demo assets, and a packaged skill archive.

## Repository Map

- `SKILL.md` - skill routing and operating rules.
- `CHEATSHEET.md` - quick design reference.
- `CLAUDE.md` - Claude-specific notes pointing to AGENTS.md.
- `references/` - design, writing, diagram, and production guidance.
- `references/design.md`, `writing.md`, `production.md`, `diagrams.md` - full specs.
- `references/resume-writing.md` - resume-specific bullet/project framing rules.
- `references/anti-patterns.md` - six-category checklist for reviewing drafts.
- `references/tokens.json` - canonical color tokens (drift-checked by `scripts/tokens.py`).
- `references/checks_thresholds.json` - rhythm / density / orphan check thresholds (loaded by `scripts/checks.py`).
- `references/brand-profile.md` and `references/brand.example.md` - optional brand profile behavior and public example.
- `.claude-plugin/marketplace.json` - Claude Code plugin marketplace metadata.
- `.agents/plugins/marketplace.json` - **generated** Codex repo marketplace. Points Codex at `plugins/kami`; never hand-edit.
- `plugins/kami/` - **generated** Codex plugin tree. Mirrors the lightweight skill package under `plugins/kami/skills/kami/`; edit source files and run `python3 scripts/build_metadata.py`.
- `assets/templates/` - document templates including browser-only landing page variants.
- `scripts/highlight.py` - Pygments-based syntax highlighting for code blocks at build time.
- `assets/demos/` - README showcase demos.
- `assets/showcase/` - README and public-site-only screenshots; excluded from `dist/kami.zip`.
- `assets/diagrams/` - diagram prototypes and generated diagram assets.
- `assets/fonts/` and `assets/illustrations/` - bundled visual assets.
- `styles.css` - shared web-facing styles.
- `index.html`, `index-zh.html`, `index-en.html`, `index-ja.html`, `index-ko.html`, `index-tw.html` - public site entrypoints.
- `robots.txt`, `sitemap.xml`, and `vercel.json` - public crawler, deployment, and AI visibility files.
- `llms.txt` - AI crawler and model-facing project summary.
- `scripts/build.py` - CLI shell: build targets and dispatch to lint / verify / checks / tokens modules.
- `scripts/verify.py` - end-to-end render verification (page count, embedded fonts, advisory density scan).
- `scripts/lint.py` - template CSS lint rules and base/variant cross-template `:root` consistency check (CN↔EN and CN↔KO).
- `scripts/tokens.py` - `tokens.json` drift check across HTML templates and PPTX slide scripts.
- `scripts/checks.py` - PDF-side checks: placeholders, orphans, density, slide-deck rhythm.
- `scripts/optional_deps.py` - centralized loader for weasyprint / pypdf / PyMuPDF with consistent install hints.
- `scripts/shared.py` - shared constants and the canonical `HTML_TEMPLATES` registry used by the build scripts.
- `scripts/ensure-fonts.sh` - verified font recovery helper (portable across bash 3.2+).
- `scripts/package-skill.sh` - package builder for the release archive.
- `scripts/build_metadata.py` - codegen for Codex marketplace metadata and plugin mirror files. Run after changing `SKILL.md`, `CHEATSHEET.md`, `VERSION`, `references/`, `scripts/`, or shipped lightweight assets.
- `scripts/draft-release-notes.py` - bilingual release notes scaffold from `git log`.
- `scripts/tests/test_build.py` - zero-dependency test suite for build and shared helpers.
- `.github/workflows/check.yml` - PR/push CI that runs `--check` and the test suite.
- `.github/workflows/release.yml` - tag-triggered workflow that builds and attaches `dist/kami.zip` to the release.
- `dist/kami.zip` - tracked release archive.

Reference docs are English-only. Language-specific output differences (CN/EN/KO) belong in templates, not duplicated reference files.

## Commands

```bash
python3 scripts/build.py
python3 scripts/build.py --check
python3 scripts/build.py --verify
python3 scripts/build.py --check-placeholders path/to/filled.html
python3 scripts/build.py --check-orphans path/to/doc.pdf
python3 scripts/build.py --check-density path/to/doc.pdf
python3 scripts/build.py --check-rhythm slides slides-en
python3 scripts/build_metadata.py
python3 scripts/build_metadata.py --check
python3 scripts/tests/test_build.py
python3 scripts/draft-release-notes.py V1.4.0..HEAD --version V1.4.1 --title "Steadier Hand"
bash scripts/ensure-fonts.sh
bash scripts/package-skill.sh
```

## Working Rules

- Style changes must update `references/design.md` and the matching template tokens.
- Landing or documentation-site work follows `references/design.md` Section 11: «Documentation site» for the doc shell (sidebar rail, on-this-page TOC, borderless prev/next pager, build-time zero-JS code highlighting) and «Responsive screenshot verification» (screenshot at 375px / 1280px per locale, objective line-widow scan) before shipping.
- For hosted Kami site or public landing changes, first separate generic template work from Kami's own website. Generic behavior lives in `assets/templates/landing-page*` and `references/`; Kami site facts live across `index*.html`, `styles.css`, README, `llms.txt`, `robots.txt`, `sitemap.xml`, and `vercel.json`.
- Public facts are wider than the hero. Pricing, install path, version, release, support, analytics, FAQ, and positioning claims must move together across pages, metadata, AI files, and download links. Do not leave site-only analytics or tracking changes contradicting "no analytics" or app/package privacy copy.
- Content changes should avoid CSS churn unless layout behavior is part of the task.
- For document or template tasks, lock the output contract before editing: language, template, output format, page or length target, visual acceptance check, and verification command.
- Prefer the nearest existing template and deterministic verifier. Do not add a template, shared CSS layer, dependency, script flag, or optional mode unless the current request cannot be satisfied without it.
- New templates should copy the nearest existing template, stay aligned with `references/design.md`, and add demo coverage.
- Do not use graphic emoticons in docs, template comments, or script output.
- Use `OK:` and `ERROR:` for status text in scripts.
- Use `scripts/ensure-fonts.sh` to recover required fonts with retry and size validation when local font files are missing or truncated. It downloads to the XDG user font dir (`${XDG_DATA_HOME:-~/.local/share}/fonts/kami`), never into the skill's `assets/fonts`, so an installed Claude Desktop skill stays small; inside a repo checkout it is a no-op because the committed large fonts already satisfy the templates' relative path.
- Do not bundle large CJK font files into `dist/kami.zip`; package scripts should exclude them while templates keep stable local-preview paths. The skill ZIP uploaded to Claude Desktop must be the `scripts/package-skill.sh` output under the 6MB package ceiling; a hand-zipped checkout includes the tracked large fonts and Claude Desktop rejects it.
- Do not bundle README/public-site-only showcase screenshots into `dist/kami.zip`; keep them under `assets/showcase/` and exclude that directory in `scripts/package-skill.sh`.
- Keep multilingual public pages, `llms.txt`, `robots.txt`, sitemap, JSON-LD, and FAQ content aligned when changing public positioning or install instructions.
- Brand profile support is optional context. Keep public examples in `references/`; do not hard-code a maintainer's private local profile content.
- Slides default to WeasyPrint HTML-to-PDF templates unless the user explicitly needs editable PPTX output.
- Templates intentionally inline their CSS rather than share a `_kami.css` partial: each template must remain a single self-contained HTML file so users can copy-paste it without a build step. When fixing CSS drift, apply the same change across affected templates rather than introducing a build-time include.
- The canonical `HTML_TEMPLATES` registry lives in `scripts/shared.py`; `build.py` derives its target dicts from it. Update the registry, not the per-script dicts, when adding or removing templates.

## Refactor And Packaging Hard Stops

- When refactoring `scripts/build.py` or package helpers into new modules, confirm every new helper file is tracked by Git. `scripts/package-skill.sh` packages from `git ls-files`, so untracked modules pass local imports but disappear from `dist/kami.zip`.
- Any source change that adds scripts, templates, reference JSON, workflows, or package inputs must refresh and inspect `dist/kami.zip`; package freshness is part of release readiness, not a later cleanup step.
- Changes to `SKILL.md`, templates, scripts, references, or package inputs must decide explicitly whether `dist/kami.zip` needs refresh. If the behavior is shipped through the skill package, rebuild and inspect the ZIP before handoff.
- Marketplace, plugin path, version, or generated mirror changes require runtime installation proof, not metadata proof only. For Codex changes, use an isolated `CODEX_HOME=/tmp/...` smoke with `codex plugin marketplace add <path>`, `codex plugin add kami@kami`, and `codex plugin list`; keep the generator, mirror tree, package audit, and install path aligned.
- If `python3 scripts/build.py --verify` fails only because the host Python lacks PPTX fallback dependencies such as `python-pptx`, verify `slides` and `slides-en` from a temporary venv instead of treating the environment miss as a source regression.
- Do not commit one-off review reports or diagnostic snapshots as durable docs. Extract stable rules into `AGENTS.md`, `CLAUDE.md`, `SKILL.md`, or `references/` and discard the stale report.

## CI And Verification Discipline

- Tests that need `weasyprint` / `pypdf` / `PyMuPDF` must run in a CI job that installs those deps (currently `verify-render`). The `lint-and-test` job ships only Pygments, so a `find_spec(...) is not None` skip-guard there silently skips the test while still printing `OK:`. A green `lint-and-test` does not mean the solver / render tests ran.
- Edits to `.github/workflows/*.yml` should be validated on a feature branch (push, watch the run go green) before merging to `main`. Local font / dependency / runner assumptions diverge from CI more often than expected: this project has already burned commits on `pip` cache requiring a manifest, the `fallback_present` set missing Ubuntu defaults (DejaVu / Liberation), and CI never having commercial fonts (Charter / TsangerJinKai02).
- Differences between CI and host behavior are expressed as a single explicit opt-in env var (`KAMI_ALLOW_FALLBACK_ONLY=1` for missing primary fonts). When a third such flag is needed, migrate to `references/verify_profile.json` or a `--ci-mode` CLI flag instead of letting `KAMI_*` env vars sprawl.

## Current Risk Areas

- WeasyPrint rendering is sensitive to font availability, solid hex tag backgrounds, page breaks, CJK fallback, and synthetic bold. Verify visually for template changes.
- Slide output has three paths: `slides-weasy*.html` for default PDF decks, `slides*.py` for editable PPTX fallback, and `assets/templates/marp/slides-marp*.{md,css}` for Markdown-first Marp decks.
- Marp theme CSS (`assets/templates/marp/slides-marp.css` and `-en`) inlines a full copy of the design tokens (`--parchment`, `--brand`, `--serif`, rhythm modules) because Marp themes must be self-contained. `build.py --sync` / `--check` now token-sync the `marp/*.css` files (`tokens.py` globs them), so token-value drift from `references/design.md` / `tokens.json` is caught, not silent. The remaining gap: the CSS lint and off-palette guard still scan only `.html` templates, so non-token CSS in the Marp themes (new rules, off-palette colors) is not lint-checked, review those by hand.
- AI/public visibility spans `index*.html`, `llms.txt`, `robots.txt`, `sitemap.xml`, FAQ JSON-LD, README install text, diagram counts, and release archive links.
- `scripts/shared.py` centralizes constants used by the build scripts; keep paths and target names in sync before adding templates or diagrams.
- `dist/kami.zip` is a tracked release archive. Packaging changes must update and inspect it deliberately.
- Codex plugin files are generated artifacts. Do not edit `plugins/kami/` or `.agents/plugins/marketplace.json` directly; regenerate from the root source files and let `python3 scripts/build_metadata.py --check` catch drift.

## Hotspot Ownership

- `references/design.md` and `plugins/kami/skills/kami/references/design.md` own the Kami visual system, including large landing-page and documentation-site rules. Boundary: edit only the root source, and use the plugin path only as a generated mirror. Verification: `python3 scripts/build.py --check` plus screenshots for screen surfaces, then `python3 scripts/build_metadata.py --check`.
- `styles.css` owns the hosted Kami public site shell, language switcher, gallery, and shared responsive behavior. Boundary: do not move generic template rules here. Verification: serve the site and screenshot 375px / 1280px per locale touched.
- `assets/templates/landing-page.html`, `assets/templates/landing-page-en.html`, `assets/templates/landing-page-ko.html`, `plugins/kami/skills/kami/assets/templates/landing-page.html`, `plugins/kami/skills/kami/assets/templates/landing-page-en.html`, and `plugins/kami/skills/kami/assets/templates/landing-page-ko.html` own the generic screen-first template shipped to users. Boundary: edit root templates, keep real product-site facts in filled sites, and treat plugin paths as generated mirrors. Verification: `python3 scripts/build.py landing-page`, browser screenshots for changed breakpoints, and `python3 scripts/build_metadata.py --check`.
- `references/production.md` and `plugins/kami/skills/kami/references/production.md` own production troubleshooting, pre-ship review, and known render pitfalls. Boundary: add stable invariants only, not dated review notes. Verification: `python3 scripts/build.py --check`, `python3 scripts/build_metadata.py --check`, and the relevant render command named by the rule.
- `assets/templates/resume.html`, `assets/templates/resume-ko.html`, `plugins/kami/skills/kami/assets/templates/resume.html`, and `plugins/kami/skills/kami/assets/templates/resume-ko.html` own high-density resume layout. Boundary: preserve the two-page contract and do not fix overflow by generic shrinking first. Verification: `python3 scripts/build.py --verify resume` and `python3 scripts/build.py --verify resume-ko`.
- `assets/demos/demo-resume-ko.html` owns the Korean resume demo content, not the template contract. Boundary: regenerate demo outputs when the demo changes, but put durable resume rules in templates or references. Verification: build the affected demo and confirm page count plus rendered screenshot.
- `scripts/tests/test_build.py` and `plugins/kami/skills/kami/scripts/tests/test_build.py` own the zero-dependency test suite. Boundary: edit the root test file and regenerate the plugin mirror. Verification: `python3 scripts/tests/test_build.py` and `python3 scripts/build_metadata.py --check`.

## High-Risk Pitfalls

See `references/production.md` Part 4.

1. Tag rgba double rectangle: use solid hex backgrounds.
2. Thin border plus border-radius double ring: border < 1pt with border-radius can trigger it.
3. Resume 2-page overflow: tiny font, fallback, line-height, or margin changes can break it.
4. `break-inside` fails inside flex: wrap content in a block wrapper.
5. `height: 100vh` is unreliable under `@page`: use explicit mm values.
6. SVG marker `orient="auto"` does not rotate in WeasyPrint: draw arrowheads manually.
7. Section body text should not use `max-width`: `.manifesto`, `.section-lede`, and similar text should fill the `.page` container. Exceptions: `.type-sample` and `.footer .colophon`.
8. Diagram template changes must sync to index showcase SVGs: any visual fix to `assets/diagrams/*.html` must also be applied to the matching mini SVG in `index.html`, `index-zh.html`, `index-ja.html`, `index-ko.html`, `index-tw.html`.

## Demo Screenshots

All demo PNG files use **1241x1754px** (first A4 portrait page at 150dpi).

For one-page and multi-page documents (one-pager / letter / resume / portfolio / long-doc / equity-report), capture page 1:

```bash
pdftoppm -r 150 -f 1 -l 1 -png <pdf> /tmp/p && cp /tmp/p-1.png <target>.png
```

For landscape slides, capture the first 2 pages, resize each to 867px high, add a 20px gap, then extend to 1241px wide:

```bash
pdftoppm -r 150 -f 1 -l 2 -png <pdf> /tmp/sl
magick /tmp/sl-1.png -resize x867 /tmp/sl1.png
magick /tmp/sl-2.png -resize x867 /tmp/sl2.png
magick -size $(identify -format '%w' /tmp/sl1.png)x20 xc:'#f5f4ed' /tmp/gap.png
magick /tmp/sl1.png /tmp/gap.png /tmp/sl2.png -append /tmp/stacked.png
magick /tmp/stacked.png -gravity Center -background '#f5f4ed' -extent 1241x1754 <target>.png
```

## Verification Details

- Expected page counts: one-pager 1, letter 1, resume 2 strict, long-doc 7 plus or minus 2, portfolio 6 plus or minus 2, slides 7 plus or minus 3, equity-report 2 to 3, changelog 1 to 2. Landing pages are browser-only HTML with no PDF page count.
- `scripts/build.py` sets PDF `/Author` from `git config user.name` or `KAMI_AUTHOR` only when the template still has an author placeholder. `/Producer` and `/Creator` should remain `Kami`.
- Demo PNGs under `assets/demos/` are first-page previews at 1241x1754px. For slide demos, capture the first two landscape pages, stack them with a parchment gap, then extend to 1241x1754px.
- Diagram count and names must stay aligned across `SKILL.md`, `CHEATSHEET.md`, `README.md`, `index*.html`, and `assets/diagrams/`.

## Verification

- Template, CSS, or script changes: run `python3 scripts/build.py --check` (CSS lint + token sync + base/variant cross-template `:root` consistency, currently CN↔EN and CN↔KO) and `python3 scripts/build.py --verify`.
- Demo changes: regenerate the affected demo outputs and confirm page counts stay in range.
- Font issues: run `bash scripts/ensure-fonts.sh`, then rebuild the affected target.
- Slide rhythm or deck changes: run `python3 scripts/build.py --check-rhythm slides slides-en` plus the affected render command.
- Public site or AI visibility changes: check `index*.html`, README, `llms.txt`, `robots.txt`, `sitemap.xml`, JSON-LD, FAQ, install links, and release/download links together. Serve the page and screenshot 375px / 1280px per locale, plus 320px when CTA width or mobile nav changes.
- Packaging changes: run `bash scripts/package-skill.sh` and confirm `dist/kami.zip` stays small enough for release upload. Inspect `unzip -l dist/kami.zip` for accidental large fonts, showcase screenshots, cache files, or missing new helper files.
- Codex marketplace changes: run `python3 scripts/build_metadata.py --check` and confirm `plugins/kami/.codex-plugin/plugin.json` plus `.agents/plugins/marketplace.json` stay generated. If install behavior, version selection, or source path changed, also run an isolated Codex install smoke.
- Documentation-only changes: check links and references.

## Release Notes

- For public releases, keep notes concise and bilingual. Use one-to-one English and Chinese changelog items, 5 to 8 items, one sentence each.
- Generate the scaffold with `python3 scripts/draft-release-notes.py V<prev>..V<new> --version V<new> --title "<Codename>"`, then regroup the raw commit list into 5 to 8 product-themed bullets and translate each to Chinese. Do not paste raw commit subjects.
- Match the established shape: title is `V<x.y.z> <Two-Word Codename>` (e.g. `V1.7.2 Cleaner Resumes`), body is the centered logo block + `### Changelog` (English numbered list) + `### 更新日志` (Chinese numbered list) + the closing tagline line.

## Release Flow

- `bash scripts/package-skill.sh` writes the tracked `dist/kami.zip` release archive and excludes large TsangerJinKai / Source Han Serif K font files plus README/public-site-only showcase screenshots.
- `dist/kami.zip` should be committed with release changes and uploaded to the latest GitHub release asset when refreshing the Claude Desktop package.
- When refreshing a GitHub release asset, download the uploaded `kami.zip` and compare ZIP entry names plus per-entry SHA-256 digests against local `dist/kami.zip`; do not rely on release-page text, file size, or container SHA alone.
- README and public site download links use `https://github.com/tw93/kami/releases/latest/download/kami.zip`; prefer refreshing that asset for small packaging or documentation fixes instead of creating a new tag.
- Create a new version tag only when the maintainer explicitly wants a versioned release. Tag the commit that already contains the final refreshed `dist/kami.zip`; do not tag a source-only commit and refresh the archive afterward.
- On tag push, `.github/workflows/release.yml` builds and attaches `dist/kami.zip`, creates the release if missing, and adds the house-style reactions (`+1 eyes heart hooray laugh rocket`, one each). Do not `gh release create` by hand; let CI create the placeholder, then set the real title and notes with `gh release edit V<x> --title "V<x> <Codename>" --notes-file <file>`.
- If reactions are ever missing (older release, CI skipped), add them manually: `rid=$(gh api repos/tw93/Kami/releases/tags/V<x> --jq .id); for r in +1 eyes heart hooray laugh rocket; do gh api -X POST repos/tw93/Kami/releases/$rid/reactions -f content="$r"; done`.

## Fonts

- Chinese templates use TsangerJinKai02 W04/W05. Commercial use requires the appropriate font license.
- If TsangerJinKai is unavailable, fall back through Source Han Serif SC, Noto Serif CJK SC, Songti SC, STSong, then Georgia.
- English templates use Charter serif. Japanese output uses YuMincho first, then Hiragino Mincho ProN, Noto Serif CJK JP, Source Han Serif JP, TsangerJinKai02, and generic serif.
- Korean templates use Source Han Serif K (Adobe, also distributed as Noto Serif KR by Google). Fallback chain: Source Han Serif K, Source Han Serif KR, Noto Serif KR, Apple SD Gothic Neo, AppleMyungjo, Charter, Georgia. `Source Han Serif KR` is the actual family name inside the bundled OTFs and must stay in the chain so fontconfig can resolve the `ensure-fonts.sh`-downloaded font by name on an offline Linux skill install.
- Claude Desktop ZIPs do not bundle TsangerJinKai TTF or Source Han Serif K OTF files (the OTFs are OFL-licensed and git-tracked for the CDN `@font-face` fallback, but excluded from the package to keep it small). Run `bash scripts/ensure-fonts.sh` before building Chinese or Korean documents when fonts are missing; it drops them in the XDG user font dir (fontconfig-scanned, outside the skill), so the installed skill stays small and online renders still use the jsDelivr `@font-face` fallback.
