# AGENTS.md

## Purpose

This repository is a plain vanilla JS static blog starter. Optimize for small, safe edits and browser-only validation.

## Hard Constraints

- Do not add Node.js, npm, package managers, or build tooling.
- Keep the runtime browser-only and dependency-free.
- Do not introduce remote script dependencies.

## Contract Authority And Conflict Resolution

When contracts disagree, resolve in this order:

1. `agent-manifest.json` policy resolution rules
2. `agent-capabilities.json` operation-level policy (`operations`)
3. This file (`AGENTS.md`) for human workflow guidance
4. `README.md` and `agents/index.html` as summaries

If file-level capability lists conflict with operation-level rules, operation-level rules are authoritative.

## Canonical Data Model

Source of truth:

- `data/site.json`
- `data/posts.json`
- `schemas/site.schema.json`
- `schemas/posts.schema.json`

Generated artifacts (must stay in sync with canonical data):

- `posts.js`
- `robots.txt`
- `sitemap.xml`
- `rss.xml`

Machine contracts:

- `sanitization-policy.json`
- `agent-capabilities.json`

## Safe Edit Zones (Default)

- `data/site.json`
- `data/posts.json`
- `config.js`
- `content/*.html`
- `agents/index.html`
- `README.md`
- `AGENTS.md`
- `agent-manifest.json`
- `schemas/*.json`
- `sanitization-policy.json`
- `agent-capabilities.json`
- `themes/*.css`
- `templates/*`

## Protected Files (Edit only when explicitly requested)

- `blog.js`
- `styles.css`
- `animations.js`
- `index.html`
- `agent-tools.js`
- `generate.html`
- `verify.html`
- `seo-preview.html`

## Metadata Contract

For each post in `data/posts.json`, keep required fields valid:

- `title`: non-empty string
- `date`: `YYYY-MM-DD`
- `slug`: unique kebab-case
- `tags`: string array
- `excerpt`: non-empty string
- `contentFile`: `content/<name>.html`

Optional fields:

- `previewImage`: string
- `previewAlt`: string
- `draft`: boolean

## Runtime Invariants (AgentTools)

In addition to schema structure checks, runtime validation in `agent-tools.js` is required for:

- Real calendar date validity (`YYYY-MM-DD` that parses to an actual date)
- Unique post slug across the full `data/posts.json` array
- Safe `contentFile` paths constrained to `content/<name>.html`
- Tag normalization checks (non-empty, no duplicates after normalization)

## Valid And Invalid Post Objects

Valid:

```json
{
  "title": "Ship Weekly Product Updates",
  "date": "2026-02-16",
  "slug": "ship-weekly-product-updates",
  "tags": ["product", "workflow"],
  "excerpt": "A repeatable weekly cadence for publishing customer-facing updates.",
  "contentFile": "content/ship-weekly-product-updates.html",
  "draft": false
}
```

Invalid (duplicate slug + bad date):

```json
{
  "title": "Bad Example A",
  "date": "02-16-2026",
  "slug": "welcome-to-your-new-blog",
  "tags": ["ops"],
  "excerpt": "This will fail validation.",
  "contentFile": "content/bad-example-a.html"
}
```

Invalid (unsafe contentFile + empty excerpt):

```json
{
  "title": "Bad Example B",
  "date": "2026-02-16",
  "slug": "bad-example-b",
  "tags": ["security"],
  "excerpt": "",
  "contentFile": "../outside/bad-example-b.html"
}
```

## Common Failure Modes

- `contentFile` is missing, unsafe, or points outside `content/`
- `slug` is missing, malformed, or duplicated
- `date` is not valid `YYYY-MM-DD`
- Canonical JSON and generated artifacts are out of sync
- Post HTML uses unsupported tags/attributes and gets stripped by sanitization

## Failure Recovery Decision Tree

1. Run `verify.html` and identify the first FAIL class.
2. If FAIL is schema or metadata related:
   - Fix canonical fields in `data/site.json` or `data/posts.json` only.
   - Re-run `verify.html`.
3. If FAIL is `contentFile` safety or missing content:
   - Ensure `contentFile` matches `content/<name>.html` and does not use traversal/protocol paths.
   - Ensure referenced `content/*.html` exists.
   - Re-run `verify.html`.
4. If FAIL is artifact drift:
   - Open `generate.html` and refresh `posts.js`, `robots.txt`, `sitemap.xml`, and `rss.xml`.
   - Re-run `verify.html`.
5. If FAIL occurs during route checks:
   - Confirm canonical data and generated artifacts are in sync.
   - Re-test home/post/tag/search routes in `index.html`.
6. If resolution requires protected file edits (`blog.js`, `styles.css`, `animations.js`, `index.html`, `agent-tools.js`, `generate.html`, `verify.html`, `seo-preview.html`):
   - Stop and request explicit user approval before editing.

## Deterministic Editing Rules

- Use UTF-8 text with LF newlines and end files with a trailing newline.
- Use 2-space indentation for JSON and keep valid strict JSON (no comments, no trailing commas).
- In each `data/posts.json` post object, keep this key order when present:
  `title`, `date`, `slug`, `tags`, `excerpt`, `contentFile`, `previewImage`, `previewAlt`, `draft`.
- Do not reorder existing posts unless explicitly requested.
- Keep tags as trimmed, non-empty strings; prefer lowercase kebab-case tags for consistency.
- Keep edits focused; avoid unrelated rewrites or formatting-only churn in untouched sections.

## Definition Of Done (Agent Changes)

- Canonical files conform to `schemas/site.schema.json` and `schemas/posts.schema.json`
- Generated artifacts are refreshed via `generate.html` when canonical data changes
- `verify.html` machine report indicates `publishReady: true`
- `index.html` smoke test completed for home, post, tag, and search routes
- No Node/npm/build tooling or remote script dependency changes introduced

## Browser-Only Workflow

1. Edit canonical files (`data/site.json`, `data/posts.json`) and matching `content/*.html`.
2. Open `generate.html` and copy generated artifacts into:
   - `posts.js`
   - `robots.txt`
   - `sitemap.xml`
   - `rss.xml`
3. Open `verify.html` over local `http(s)` and require machine report `publishReady: true`.
4. Open `index.html` and manually test:
   - Home route
   - At least one post route
   - At least one tag route
   - Search route
5. Optionally open `seo-preview.html` for route metadata previews.

Publish readiness note:

- Running only under `file://` is not publish-ready because `verify.html` cannot complete required fetch-based checks.
- Before publishing, run `verify.html` over local `http://` or `https://` and ensure `publishReady: true`.

## Template To Instance Migration (Repeatable)

Use this workflow when migrating template/tooling updates from this repo into an existing blog instance such as `/Users/ivancampos/Code/home/blog` without overwriting user-facing data.

Default preserve policy in destination:

- Preserve `data/*`
- Preserve `content/*`
- Preserve `images/*`
- Preserve `config.js`
- Preserve `posts.js`, `robots.txt`, `sitemap.xml`, `rss.xml` during sync (these are regenerated after sync)

Default sync policy from template source:

- Sync only: `AGENTS.md`, `README.md`, `agent-manifest.json`, `agent-capabilities.json`, `sanitization-policy.json`, `agent-tools.js`, `verify.html`, `generate.html`, `agents/index.html`, `schemas/site.schema.json`, `schemas/posts.schema.json`
- Runtime files (`blog.js`, `index.html`, `styles.css`, `themes/*.css`) are optional and must be explicitly approved per run.

Recommended repeatable command sequence:

```bash
SOURCE=/Users/ivancampos/Code/static
DEST=/Users/ivancampos/Code/home/blog

FILES=(
  AGENTS.md
  README.md
  agent-manifest.json
  agent-capabilities.json
  sanitization-policy.json
  agent-tools.js
  verify.html
  generate.html
  agents/index.html
  schemas/site.schema.json
  schemas/posts.schema.json
)

for f in "${FILES[@]}"; do
  install -D "$SOURCE/$f" "$DEST/$f"
done
```

Post-sync required checks:

1. Confirm preserved files were not changed by sync:
   - `git -C /Users/ivancampos/Code/home/blog diff -- data content images config.js posts.js robots.txt sitemap.xml rss.xml`
2. Regenerate artifacts in destination via `generate.html`.
3. Run destination `verify.html` over `http(s)` and require `publishReady: true`.
4. Smoke test destination `index.html` routes (`#/`, post, tag, search).

Repeatability requirement:

- Running the same migration twice with unchanged source contracts and unchanged destination canonical data must produce zero additional diffs after regeneration.

## Runtime Configuration

Use `config.js` for domain portability and runtime metadata/feature settings.

Domain and metadata keys:

- `siteUrl`: absolute base URL used for canonical URLs and generated artifacts
- `basePath`: base path for hosted subdirectory deployments (default `/`)
- `agentsPath`: relative path to the agent discovery page (default `agents/`)
- `agentRootUrl`: optional absolute override for `ai:agent-root`; if empty, derived from `siteUrl + agentsPath`
- `agentEntryPath`: optional absolute-path override for `codex-agent-entry`; if empty, derived from `basePath + agentsPath`
- `siteTitle`: runtime title override for app shell/meta values
- `siteDescription`: runtime description override for app shell/meta values
- `siteAuthor`: runtime author-name override for footer/byline values
- `siteAuthorUrl`: runtime author URL override for footer author link (must start with `http://` or `https://`)
- `rssLanguage`: RSS channel language tag (default `en-us`)

Feature keys:

- `themePreset`
- `animationsEnabled`
- `tagConstellationEnabled`
- `tagConstellationMotion`

Theme preset options for `themePreset`:

- `xrai-theme` (default)
- `b&w-theme`
- `neon-rain-grid-theme`
- `hologram-alley-theme`
- `ghost-in-the-circuit-theme`
- `cyber-samurai-theme`
- `time-rift-console-theme`
- `dark-matter-ledger-theme`
- `solarpunk-transition-theme`
- `tactical-hud-cleanroom-theme`
- `posthuman-minimal-theme`
- `neon-shrine-theme`
- `warp-drive-blueprint-theme`
- `holo-archive-museum-theme`

Each preset lives in its own file under `themes/`.

Notes:

- Do not skip `data/site.json`; canonical data must remain valid even if runtime overrides exist in `config.js`.
- If URL/path config changes, regenerate `posts.js`, `robots.txt`, `sitemap.xml`, and `rss.xml`, then run `verify.html`.

## Agent Read Order

Start at `/agents/` when available.

1. `agent-manifest.json` (machine-readable contract)
2. `AGENTS.md` (human workflow and constraints)
3. `README.md` (project overview)
4. `schemas/site.schema.json` and `schemas/posts.schema.json` (data contracts)
5. `agent-capabilities.json` and `sanitization-policy.json` (safety and boundary contracts)

## Change Hygiene

- Keep diffs focused and minimal.
- Avoid unrelated edits.
- Preserve behavior unless the task explicitly changes behavior.
- Prefer deterministic outputs to reduce drift in generated files.

## Contract Version Governance

- Breaking contract changes: increment `agent-manifest.json` `contractVersion` major component and update `lastUpdated`.
- Additive non-breaking changes: increment `contractVersion` minor component and update `lastUpdated`.
- Docs-only clarifications: increment `contractVersion` patch component and update `lastUpdated`.
