Nightly narrative queue
Nightly narrative queue
Mechanical narrative work queue, drained by narrative-ops (Sonnet sidekick to narrative-designer). Each entry is a bounded task whose creative decisions have already been made elsewhere — by a narrative-designer decision log, a tech-architect rename map, or an existing canon page.
This page is the task queue specification plus the live queue itself. It is status:canon because the schema is canonical even when the queue is empty.
Purpose
The naming-discipline pipeline (ratified 2026-05-20) splits narrative work into two tiers:
- Creative tier —
narrative-designer(Opus). Four-phase writing schema, tonal calibration, canon authorship, naming picks. Expensive, slow, irreplaceable. - Mechanical tier —
narrative-ops(Sonnet). Glossary backfill, EN body cleanup, rename propagation, wiki expansion from existing canon, items/materials/recipes flavour text. Cheap, fast, traceable.
The queue is the contract between the two tiers: narrative-designer (or any lead with the right context) posts a queue entry; narrative-ops drains it on nightly cron. The queue makes the boundary auditable — every mechanical edit traces back to a queue entry with explicit acceptance criteria and a source pointer.
Entry schema
Queue entries are YAML-fenced inside this Markdown page. Humans write them; agents read them. Do not migrate to TypeScript — the queue is editing-prone and reviewable-in-diff in YAML.
- handle: <short-kebab-case-task-handle> kind: glossary-entry | en-body-cleanup | cross-file-propagation | wiki-expansion | flavour-text scope: <one-paragraph description of what files / what range> acceptance: <verifiable criterion — REQUIRED, e.g. "lint:naming passes; npcs/X.ts handle field == 'X'; transcreationNote >= 10 chars"> source: <pointer to canon evidence — decision log path, data file path, or canon wiki path — REQUIRED for kinds glossary-entry, wiki-expansion, flavour-text> status: pending | in-flight | done | blocked blocked-reason: <only present if status == blocked>Field semantics
- handle — short, kebab-case, unique within the queue. Names the task, not the entity being worked on. Example:
glossary-backfill-cech-faction,propagate-rename-pan-kepka. - kind — one of the five allowed
narrative-opstask types. Any other value is a malformed entry;narrative-opswill refuse and FLAG_LEAD. See.claude/agents/narrative-ops.mdfor the canonical definitions. - scope — one paragraph. What files, what range, what subset. Specific enough that two agents reading it would touch the same files.
- acceptance — REQUIRED for every entry. A verifiable criterion the executor can check after the work. Vague acceptance is not acceptance — the criterion must name a lint command, a typecheck result, a field value, or a measurable property. Examples:
lint:naming passes; all npcs/*.ts files have non-empty handle fieldwiki/src/content/docs/lore/npcs/pan-kepka.mdx ≥ 300 PL words; every paragraph carries source trace commentdata/src/content/factions/cech-niedokonczonych-wypraw.ts en.description field contains zero PL characters
- source — pointer to canon evidence. Required for kinds that touch creative-adjacent content (
glossary-entry,wiki-expansion,flavour-text); optional for purely mechanical kinds (en-body-cleanup,cross-file-propagation) where the glossary itself or the rename map is the source. - status — lifecycle.
pending→ posted, waiting.in-flight→narrative-opsis working it.done→ committed.blocked→ executor hit a FLAG_LEAD condition;narrative-designermust triage. - blocked-reason — only present when
status == blocked. One sentence naming the FLAG condition (e.g.grammar collapse on word-level swap line 47,kind=flavour-text but no style precedent exists for this material category).
Required-fields-by-kind matrix
| kind | handle | kind | scope | acceptance | source | status |
|---|---|---|---|---|---|---|
| glossary-entry | yes | yes | yes | yes | yes | yes |
| en-body-cleanup | yes | yes | yes | yes | optional | yes |
| cross-file-propagation | yes | yes | yes | yes | optional | yes |
| wiki-expansion | yes | yes | yes | yes | yes | yes |
| flavour-text | yes | yes | yes | yes | yes | yes |
A glossary-entry, wiki-expansion, or flavour-text entry posted without a source is malformed. narrative-ops will refuse and FLAG_LEAD: narrative-designer. No source = no canon evidence = no autonomous work.
Queue
# Queue (empty — Phase A bootstrap; first entries land in Phase C)tasks: []How nightly runs work (DRAFT — Phase D decision required before activation)
This section is the operational shape of the nightly run. It is DRAFT — autonomous nightly execution is NOT enabled in Phase A. Activation requires a D-level decision in Phase D after Phase C populates the queue with real entries and the dry-run cycle has been observed manually for at least one iteration.
- Trigger. A
/schedulecron entry (Phase D) runsnarrative-opsagainst this page once per night. The agent picks allstatus: pendingentries in queue order, executes them sequentially, and updatesstatusin-place toin-flight→done(orblocked). - Boundaries.
narrative-opswill refuse any entry whosekindis unknown, whose required fields for the kind are missing, or whose work would require creative invention. Refused entries flip tostatus: blockedwith a populatedblocked-reason. - Morning review discipline. First action of the working day:
narrative-designer(or CEO when narrative-designer is offline) reviews the overnight diff.doneentries are spot-checked against theiracceptancecriterion.blockedentries are triaged: either reformulated with the missing context, escalated, or closed as out-of-scope. - Commit discipline. Each completed entry is its own commit with the entry
handlein the message (e.g.chore(narrative-ops): drain glossary-backfill-cech-faction). Pre-existing uncommitted work in the tree at run start is not touched. - Rollback. Every commit is reversible by
git reset --soft HEAD~Nper the repo’s destructive-ops policy (CEO consent required for force-push or hard reset).
Until the Phase D ratification, this page exists as the specification + empty queue. Entries can be added to the queue (status: pending) during Phase C for manual dry-run dispatch — but no cron, no autonomous drain.