miscsubjectsAI governance

Skill · the loop · site

article-editing

Use when creating, editing, sourcing, illustrating, exporting, or deleting any article on miscsubjects.com — from the admin studio, curl, a coding agent, a Cloudflare Gateway model, or Google Sheets. One REST contract for all of them.

The failure this skill exists to stop

2026-07-29: Models asked to write or edit one article burned most of their turn discovering tools, repairing formats, and choosing between competing write paths; the owner ordered one documented REST contract for every client — studio, curl, agents, Gateway models, Sheets.

Source
this build
License
site
Canonical file
.claude/skills/article-editing/SKILL.md synced to .agents/skills/article-editing/SKILL.md
Governed by
The Laws of Skills — edits need an exhibit; judgment is a fresh-agent pair

Article editing — the one contract

Every article on miscsubjects.com is one row in one table, reachable through one REST API. The admin studio (/admin/articles), the public page's admin bar, curl, coding agents, Gateway models, and the Google Sheets poller are all clients of the same verbs. There is no second write path. If you are about to write an article any other way, stop and use this.

The verbs

ActionCall
List + filterGET /api/articles?q=&tag=&category=&status=&model=&has_hero=1&register=all&limit=250
ReadGET /api/articles/<slug> — full object; ?format=post = the exact re-postable body; ?rev=N = an old revision
Create / replacePUT /api/articles/<slug> body {"title","body","tags":[],"category","register","status","hero","claims":[],"sources":[],"replace":true,"prov":{"model":"<you>","action":"write"}}
Surgical editPATCH /api/articles/<slug> body {"find":"<exact>","replace":"<new>","expected_hash":"<sha256 of the body you read>"} — 409 on concurrent edit, 422 on 0 or ambiguous matches
Append a sourcePOST /api/articles/<slug>/webhook body {"kind":"source","data":{"url","title","quote","claim_ids":[]}} (also kinds: claim, widget, provenance, contribution, review)
Model rewritePOST /api/articles/<slug>/rewrite body {"find","instruction","model":"workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast"} — returns the proposal + the exact PATCH that applies it; nothing is applied until you send that PATCH
DeleteDELETE /api/articles/<slug> (immutable slugs refuse; retract via status)
Download oneGET /api/articles/export?slug=<slug> (.md attachment)
Download a setGET /api/articles/export?tag=<tag> or ?category=<cat> or ?all=1
Object folderGET /api/articles/<slug>/bundle?format=zip (markdown + json + skill + manifest)
RevisionsGET /api/articles/<slug>/revisions; restore = GET ?rev=N then PUT its fields back

Auth — one token, every transport

There is ONE token format. Present it any of three ways — they are interchangeable by design, so a browser-based model and its curl fallback never diverge:

Validate any token, either transport: GET /api/token/validate?share=<token> or curl /api/token/validate -H 'Authorization: Bearer <token>' — returns scope, expiry, exactly what it permits, and its revoke + ledger links.

Scopes: act = read + write (search the directory, read any article, PUT/PATCH/DELETE it, append sources, invoke any capability — the write gate is satisfied). row:/rows:/pfx: = the same token format attenuated to named capabilities. Owner mints: GET /api/dispatch?mint_share=1&scope=act (with the owner key or admin cookie).

Other lanes that still work: the owner's /admin/login cookie (studio + admin bar); x-terminal-key for the owner's own terminal; and a model holding NOTHING can still earn a prose write by reading the live law — GET /api/write-gate/challenge → answer → token.

Writing a new article — the short path

  1. GET /api/articles/writing-law/skill — the live writing law. Follow it.
  2. Draft first: PUT /api/articles/<slug> with "draft": true — invisible everywhere public until you publish.
  3. Sources as you go: one POST /webhook {"kind":"source"} per source. Embed any of them inline in the body with [[embed:source:sN]] — the page renders a full source card at that spot. Other inline shortcodes: [[embed:<other-article-slug>]] embeds an article card.
  4. Claims: include claims:[{id,text,section,tier,source_ids}] in the PUT — claims are the atomized, checkable objects; tiers and source links render on the page.
  5. Hero image: generate through the build's image pipeline (/admin/generate, or the image-to-R2 capability in the directory), take the returned https://miscsubjects.com/img/gen/... URL, set it as hero.
  6. Publish: PUT again with "draft": false (or just without draft). Sign your provenance: prov.model is never omitted.
  7. Verify: open https://miscsubjects.com/a/<slug> and GET /api/articles/<slug>/health.

Guardrails you will hit (they are features)

Why some articles have DIVs and some don't

DIV/voxel structure (GET /api/articles/<slug>/voxels) is generated from claims in meta. An article with atomized claims has addressable DIVs, hashes, and a challengeable surface; an article that is only prose does not. To give a prose article DIVs, add claims (POST /webhook {"kind":"claim"} or claims:[] on PUT) — never a parallel format.

Interfaces over this contract

Update this skill whenever the API changes: edit .claude/skills/article-editing/SKILL.md and its sibling in .agents/skills/, then run node scripts/sync_skill_pages.mjs — the live page at /skills/article-editing regenerates from these files.

Folder contents · 1 files