AI writing contract
Cursor · Claude · Codex · any agent
Agent digest — not sole source of truth. Human voice: Writing Style. Capabilities: Site Authoring Capabilities. Constitution: AGENTS.md. If this page disagrees with code (app/astro.config.mjs, app/content.config.ts, app/package.json), code wins — then update this page and authoring-capabilities.md. See starlight-content-author skill → system_docs freshness check.
Read order (every content task)
Section titled “Read order (every content task)”| Step | Document | Why |
|---|---|---|
| 0 | content-intake skill (inbox / enrich only) | Per-file classify → write → ledger; multi-extract |
| 1 | AGENTS.md | Constitution — warrant test, visuals, editorial color rules, inbox policy |
| 2 | Writing style | Voice, structure, full QC gate |
| 3 | Authoring capabilities | What is wired today (keep aligned with code) |
| 4 | Doc components | When to use which diagram |
| 5 | Component library | Starlight + Zaj MDX components |
| 6 | This page (optional digest) | Agent checklist — verify freshness vs rows 1–3 |
Repo skills (keep identical): starlight-content-author — .cursor/skills/, .claude/skills/, .agents/skills/, .codex/skills/. Rule mirror: .cursor/rules/content-authoring.mdc.
Editorial color (agent rules)
Section titled “Editorial color (agent rules)”Color is semantic and automatic: set structure + frontmatter; theme.css renders it. Never hand-pick hex or tint a heading/paragraph. The agent rules:
- Headings are the color system —
#coral ·##teal ·###gold ·####amber (plain). Sequential levels only; one#per page;####rare = split the page. - Eyebrow — one
<p class="eyebrow">…</p>kicker near the top of hub/long pages (lists doc types or topic family). - Status —
status:frontmatter (current/target/future/draft) → heading badge;sidebar.badgefor nav hints. - Inline status —
<Badge>(.mdx) orzaj-badge--*spans — not manual styling. - Callouts —
:::note/tip/caution/danger,> [!NOTE]alerts, or:::idea/:::decision/:::start/:::next/:::summary. Never colored headings or raw HTML divs.
Full tables (heading levels, badge variants, callout→plugin map, evidence badges) live in Writing style → Editorial color & badges and Authoring capabilities — don’t duplicate them here.
Plugins that affect writing
Section titled “Plugins that affect writing”Use the wired plugins; never reference unwired ones — starlight-changelogs is blocked (no /changelog/* routes), and starlight-videos is parked until a real video page needs it. Agent-critical: local zaj-mermaid wiring (diagrams when the warrant test passes), starlight-heading-badges (status: + sidebar.badge), starlight-package-managers (<PackageManagers> for installs — never four hand-copied blocks), starlight-tags (accurate tags:), starlight-links-validator (build fails on broken links), starlight-auto-drafts (draft: true until ready). Full per-plugin usage + inventory: Authoring capabilities + Starlight plugins in use.
Visual warrant test (mandatory)
Section titled “Visual warrant test (mandatory)”Before marking a section done, ask:
| Trigger | Section conveys… | Required visual |
|---|---|---|
| Process | ≥2 ordered steps | Mermaid flow / sequence or <Steps> + diagram for complex flows |
| Relationship | Parts that own, use, or reference each other | Mermaid graph or diagrams/*.astro component |
| Change over time | Phases, roadmap, before↔after | Mermaid timeline or Timeline.astro / StageFlow.astro |
Prose-only is allowed only for: a single definition, one fact, a flat list, or linear narrative with no parts-and-relationships.
Pick the lightest tool (see doc-components trigger table):
- Mermaid fence (works in
.md) - Reusable
~/components/diagrams/*.astro(.mdxonly) - Raster photo via
astro:assets— never for diagrams
Custom SVG rules: token colors only, viewBox, role="img", <title>/<desc>, light + dark verified. Connectors: 90° orthogonal elbows only — horizontal + vertical path segments; no diagonal lines or C bezier curves on flow arrows (see doc-components → Orthogonal connectors). Lane discipline: routes in gutters outside nodes, stagger parallel lanes, edges-before-nodes z-order (see doc-components → Lane discipline). Mermaid inherits stepAfter from astro.config.mjs.
MDX vs Markdown
Section titled “MDX vs Markdown”| Need | Format |
|---|---|
Prose, mermaid, :::directives, github alerts | .md |
<CardGrid>, <Steps>, <Badge>, <PackageManagers>, diagram components | .mdx + imports |
Rename .md → .mdx without changing the URL slug.
Page structure callouts
Section titled “Page structure callouts”Bookend long guides / playbooks / hubs: :::start (entry — audience, prerequisites, first action) and :::next / :::summary (exit / recap) — token-colored blocks, not fake headings. Demos: Component library → Custom blocks.
Copy as prompt (every doc page)
Section titled “Copy as prompt (every doc page)”The Copy as prompt control appears in the title bar and at the page footer (PageCopyPrompt.astro → CopyPageButton.astro) and copies a structured LLM payload built by app/src/lib/page-prompt.ts:
- Persona + mission — the assistant’s role and what to do with this page
- Autonomy contract — do agent-owned work, update ledgers when guide state changes, and ask only at true human gates
- Metadata — title, URL, shelf,
status,kind,description,tags - Assistant instructions — cite headings, honor callouts, respect
target/future/draft - Document body — cleaned markdown (imports/exports/HTML comments stripped)
Authors: write pages so they copy well — clear ## sections, use :::start/:::next for navigation context, set accurate frontmatter, and make human gates explicit. Agents are expected to choose the safer/professional default and complete routine progress/customization/feedback updates without asking; only mark a Step 👤 when credentials, provider dashboards, production/DNS, destructive operations, or real business/product decisions require the human. The hard auth boundary is universal: an AI agent never types passwords, logs in, or creates accounts; the human performs that one credential/auth/account moment, then the agent resumes post-session clicks, navigation, screenshots, and checks. The Open in ChatGPT / Claude menu passes the live URL for fetch-based reading.
Playbook Part contract (partNumber in frontmatter)
Section titled “Playbook Part contract (partNumber in frontmatter)”Playbooks use the tree Playbook → Phase → Part → Step → sub-step. A Part is the .mdx document-level unit inside a Phase. A Step is a numbered action inside that Part’s ## Steps section. New Parts use partNumber; existing stepNumber frontmatter is a legacy alias during migration.
Part / procedural pages under build/playbooks/ must use one consistent heading spine so humans and agents skim, execute, and gate consistently:
## TL;DR{Goal/objective first — the outcome this Part achieves — then who it's for and what done looks like.}
:::note[For beginners and agents]Read the **TL;DR** first, follow the Steps in order, then check **every** box in the checklist before advancing. Agents: treat unchecked items as blockers — log command output as evidence (`# Expected:` in code blocks).:::
## Background
{optional — context / prerequisites / concepts; omit when not needed → the spine is just TL;DR → Steps}
## Steps
### 1. Set up the first thing ← Step heading; action-oriented; 🤖 agent-doable → NO callout{1–2 sentences: what it does and why.}{command block — include a `# Expected:` comment for the result}- Expected: {what you should see — exit 0, a "ready" line, a new file/row}
### 2. Paste your license key ← 👤 User step → callout AFTER the intro{1–2 sentences.}:::note[Who does this]👤 **User** — paste it in the vendor dashboard (browser).:::
## Checklist
Do not mark this Part done until **every** box below is checked.
- [ ] …- [ ] …
:::next[Next Part][Label](/path/to/next-part/):::Agent rules for playbook Parts:
- Do not advance to the next Part while any checklist box is unchecked.
- Do not ask whether routine progress/customization/feedback ledgers should be updated. If the Part changes project state, update the relevant state file as part of the work; ask only for true human gates or genuinely equal choices.
- Name Steps action-first (verb): “Set up…”, “Configure…”, “Verify…” — never a bare noun like “GitHub CLI”.
- Give each Step a 1–2 sentence intro, then the action. Every command block states its expected result — a
# Expected:comment and/or a- Expected:bullet beneath it. - Who does this — Steps are 🤖 agent-doable by default (no marker). Add a
:::note[Who does this]callout only for 👤 User (authentication, account creation, password/secret entry, paid/provider dashboard, OAuth) or 🔀 mix Steps, after the intro sentence; the 🤖/👤/🔀 legend appears once near the top, not per Step. Write tool-agnostic — the callout flags where a human must act, while the agent resumes after the session or non-secret state exists. - No back-to-back callouts — never place two
:::blocks directly adjacent; separate them with prose or a heading. - Convert legacy shapes when editing old Parts:
:::summary[TL;DR]→## TL;DRheading,## Completion checklist→## Checklist,## Gate/✅lines →- [ ]checklist items. - Prefer plain words over jargon; define acronyms on first use.
- Batch maintenance script (repo root):
python3 scripts/playbook-step-contract.py(legacy filename; idempotent skip if contract already present).
Template: Playbook Part template. Human voice details: Writing style → Playbook Parts.
Playbook phase hubs vs Parts
Section titled “Playbook phase hubs vs Parts”Phase hubs are orientation pages: purpose, flow, diagram, Stepper, kit shortcut, and links to Parts. They do not own required work. If a reader or agent must do something before advancing, create or update a numbered Part document with partNumber, ## Steps, and ## Checklist, then link it from the phase hub.
When converting source material, translate source phase labels and task numbers into the current ZajLibrary playbook names before publishing. Source labels such as Phase 0, Phase 1A, Phase 1B, or Task 62 belong in intake ledgers/source notes, not reader-facing playbooks.
Agent pre-publish checklist
Section titled “Agent pre-publish checklist”Run every item before declaring a page done:
- Inbox/enrich (when applicable):
content-intakeloop — classified shelf+type, COVERAGE.md row, multi-extract peels, file-by-file (not bulk dump) - Read writing-style QC — all items pass
- Part pages (
partNumber, legacystepNumberaccepted): spine## TL;DR→## Background(optional) →## Steps(numbered###Steps) →## Checklist;:::noteaudience note under TL;DR,- [ ]items +:::nextat bottom - Playbook phase hubs: required work is linked to Part pages/checklist gates; no source phase/task labels leak into reader-facing naming
- Warrant test run per major section — diagrams present where triggered
- Orthogonal connectors — flow lines use 90° elbows (no diagonal/bezier arrows)
- Heading hierarchy — one
#, no skipped levels,####rare; no inline heading colors - Eyebrow on hub/long guide pages where appropriate
-
status:set;draft: trueuntil ready for production - Callouts use
:::/ github alerts /idea/decision/start/next/summary— not colored HTML - Long pages bookended with
:::start(entry) and:::nextor:::summary(exit/recap) where helpful - Badges via frontmatter,
<Badge>, orzaj-badge--*— not manual styling - Tags accurate for
starlight-tags - No secrets; no hardcoded hex
-
cd app && npm run buildexits 0
Anti-patterns (agents fail the gate if these ship)
Section titled “Anti-patterns (agents fail the gate if these ship)”- Relationship or process section with no diagram
- Screenshot of a diagram instead of Mermaid/SVG
- Skipped heading levels or multiple
# - Inline
color:/background:on headings or paragraphs - Emoji-per-bullet decoration
- Referencing unwired plugins (e.g.
starlight-changelogspages) - Custom component when Mermaid or an admonition suffices
Related
Section titled “Related”- Writing Style & Quality Bar — human-facing voice + full checklist
- Site Authoring Capabilities — plugins, components, shelves
- Starlight plugins in use — installed package inventory