How do I create a new doc?
Table of Contents
For the contract every generated document follows (frontmatter, sections, TODO vocabulary), see document types. For background on the generator itself, see ores.codegen.
Question
Answer
For all standard document types, use compass add instead of calling
generate_doc.sh directly. It supports: story, task, sprint,
version, recipe, knowledge, component, capture, memory,
investigation, product_identity, skill, diagram, entity_org,
field_group, dataset_overview, facet, facet_group. It defaults
--parent-dir from context (current sprint for stories/tasks, current version
for sprints, doc/llm/skills for skills) so you rarely need to type a path.
This recipe remains the authoritative reference for edge cases (explicit --id,
non-current parents, cross-sprint predecessors, etc.).
Memories support a one-shot body — no placeholder fill-in step:
compass add memory --slug prefer_x_over_y --title "Prefer X over Y" \ --description "One-line summary." --memory-subtype feedback \ --statement "The rule itself." \ --why "The correction or incident behind it." \ --how-to-apply "When X applies, do Y."
Codegen field-group models scaffold into the component's modeling
directory (the _field_group.org suffix drives loader dispatch):
compass add field_group --component trading --slug instrument_identity \ --description "Codegen field-group model for instrument_identity." \ --brief "Common identity fields shared by all instrument types."
Literate template-library docs scaffold into
projects/ores.codegen/library/templates/ (the default parent dir
for both types). A facet doc holds one template family's literate
source and requires --facet-group; a facet_group doc is the
namespace page indexing its facets (filename gets a _group.org
suffix to avoid colliding with a same-named facet):
compass add facet --slug cpp_domain_type --facet-group cpp \ --title "C++ domain type templates" --description "…" compass add facet_group --slug cpp \ --title "C++ template group" --description "…"
Call projects/ores.codegen/generate_doc.sh with the type, slug, parent
directory, and the document's title and description. The script fills in a fresh
UUID, today's dates, the required frontmatter (including the
glossary-linked blurb), a * Status table at the type's default state where
applicable, and the skeleton sections — leaving only the content for you to fill
in.
For task and story, the codegen automatically prepends Task: = / =Story: =
to the title you supply (idempotent: passing =--title "Task: Foo" won't
double-prefix). Sprints and versions keep the title as-given.
For task / story / sprint, parent :ID:, title and slug are auto-detected from
<parent-dir>/<parent-type>.org so you usually don't need to pass them. Run the
script from a terminal and it prompts for any missing required field.
New task
projects/ores.codegen/generate_doc.sh \ --type task --slug fix_broken_link \ --parent-dir doc/agile/versions/v0/sprint_17/audit_tooling \ --title "Fix broken id-links surfaced by audit" \ --description "Audit reports two unresolved id-links; fix them." \ --tags "audit,bug_fix"
Parent story info is auto-detected from
doc/agile/versions/v0/sprint_17/audit_tooling/story.org.
New story
projects/ores.codegen/generate_doc.sh \ --type story --slug audit_tooling \ --parent-dir doc/agile/versions/v0/sprint_17 \ --title "Audit tooling" \ --description "Scripts that enforce the information-architecture invariants." \ --tags "audit,scripts"
New story continuing from a previous sprint
Add --predecessor-id and --predecessor-title. The script renders
#+predecessor: in the frontmatter and a Continued from: line in
the body:
projects/ores.codegen/generate_doc.sh \ --type story --slug currencies_temporal_continued \ --parent-dir doc/agile/versions/v0/sprint_17 \ --title "Currencies temporal (continued)" \ --description "Pick up where sprint 02 left off." \ --tags "currencies,temporal,reference_data" \ --predecessor-id ed5bc735-fb54-4ce0-9a08-6dab88c242d0 \ --predecessor-title "Currencies temporal and export"
After the script runs, manually update the predecessor story: add
#+successor: <new-uuid> to its frontmatter and a
Continued in: [[id:<new-uuid>][...]] note in its * Decisions
section.
New sprint
projects/ores.codegen/generate_doc.sh \ --type sprint --slug sprint_17 \ --parent-dir doc/agile/versions/v0 \ --title "Sprint 17" \ --description "Sprint 17 — describe its mission in one sentence." \ --tags "v0"
New version
projects/ores.codegen/generate_doc.sh \ --type version --slug v1 \ --parent-dir doc/agile/versions \ --title "Version 1" \ --description "First production release." \ --tags "v1"
New component model
Component overview files are always named component_overview.org.
Use --slug component_overview (not the component name):
./projects/ores.compass/compass.sh add component \ --slug component_overview \ --parent-dir projects/ores.example/modeling \ --title "ores.example" \ --description "One-line summary of what the component does." \ --tags "example,component"
Output: projects/ores.example/modeling/component_overview.org.
See How do I create a component overview? for how to fill in each section.
New recipe
Use the how_do_i_<thing> slug convention. The output is
<parent-dir>/how_do_i_<thing>.org:
./projects/ores.compass/compass.sh add recipe \ --slug how_do_i_clear_the_cache \ --parent-dir doc/recipes/cmake \ --title "How do I clear the cache?" \ --description "Remove the CMake binary cache to force a clean re-configure." \ --tags "cmake,build,recipe"
Scaffold with content — the body sections can be supplied as
arguments (verbatim org markup; multi-line via $(printf ...) or
shell $'...' quoting) so the recipe is born complete instead of
with placeholder text:
--intro— lead paragraph before* Question;--question— the* Questionbody;--answer— the* Answerbody (include the#+begin_srcblock);--script— the* Scriptbody;--tested-by— the* Tested bybody;--see-also— one* See alsobullet (repeatable).
Sections not supplied fall back to the fill-in placeholders.
When the recipe's * Answer involves a shell command, write it in
an #+begin_src sh :results verbatim block so the recipe is
executable in emacs (C-c C-c) — see How do I list available presets?
for an example that also captures a #+RESULTS: snapshot.
New manual chapter
Use compass add manual. The slug should follow the chapter_<N>_<topic> convention.
--parent-dir defaults to doc/manual/user_guide and can be omitted.
Headings inside the chapter start at ** (level 2); they become \section in the PDF.
After creating, add a #+include line in user_manual.org and an entry in user_manual_site.org.
./projects/ores.compass/compass.sh add manual \ --slug chapter_4_reference_data \ --title "Reference Data" \ --description "Reference data management in ORE Studio: currencies, countries, and other slowly-changing financial master data." \ --tags "manual,reference_data,user_guide"
New knowledge document
./projects/ores.compass/compass.sh add knowledge \ --slug build_system_decisions \ --parent-dir doc/knowledge/architecture \ --title "Build system decisions" \ --description "Why we picked Ninja over Make as the default generator." \ --tags "build,architecture,knowledge"
New Claude Code skill
Use compass add skill. The slug must be snake_case; it becomes the
folder name and the name: field in the skill's markdown frontmatter.
--parent-dir defaults to doc/llm/skills and can be omitted:
./projects/ores.compass/compass.sh add skill \ --slug my_new_skill \ --title "My New Skill" \ --description "When and how to use the new skill."
Output: doc/llm/skills/my_new_skill/SKILL.org.
After filling in the skill body, rebuild the shipped bundle so Claude Code picks up the change — see How do I deploy the skills?:
./compass.sh build --direct skills
New product identity
There is one product identity document per product (product_identity.org
under doc/identity/). The codegen scaffolds a fresh one — useful
mostly when bootstrapping a new product or migrating an existing
identity from scratch.
projects/ores.codegen/generate_doc.sh \ --type product_identity --slug product_identity \ --parent-dir doc/identity \ --title "ORE Studio product identity" \ --description "The durable statement of what ORE Studio is and is not." \ --tags "identity,vision"
New investigation report
Investigation reports live in doc/investigations/. They are formal records
of technical research or debugging sessions.
projects/ores.codegen/generate_doc.sh \ --type investigation --slug msvc_c1202_rfl_complexity \ --parent-dir doc/investigations \ --title "MSVC C1202 and rfl complexity" \ --description "Root cause analysis of recursive template depth limits in reflect-cpp." \ --tags "msvc,cpp,reflect_cpp,investigation"
New capture
Captures live in doc/agile/product_backlog/ across four buckets:
inbox/ (untriaged), next/ (upcoming candidate), deferred/
(long-horizon), discarded/ (explicitly rejected).
The preferred way to file a new capture is compass capture, which
lands the file in inbox/ automatically:
projects/ores.compass/compass.sh capture --note "Add an uptime screen"
To create directly in a specific bucket via codegen:
projects/ores.codegen/generate_doc.sh \ --type capture --slug add_uptime_screen \ --parent-dir doc/agile/product_backlog/next \ --title "Add an uptime screen" \ --description "Surface live service health in the Qt UI." \ --tags "ui,observability"
The bucket name is derived from --parent-dir basename and appears in
the generated blurb automatically.
New memory
Memories live under doc/llm/memory/. Pass --memory-subtype to pick
the kind of memory (feedback / user / project / reference
— default feedback). The memory filetag is auto-injected so
the catalogue is greppable.
projects/ores.codegen/generate_doc.sh \ --type memory --slug do_not_re_export_env_vars \ --parent-dir doc/llm/memory \ --title "Do not re-export ORES_* env vars in Bash tool calls" \ --description "The user already exports them; prepending is noise." \ --memory-subtype feedback
For the LLM-side decision flow (when to write vs push back), see the doc-add-memory skill; for the standalone recipe with body conventions, see How do I create a memory?.
Creating a set of inter-linked documents
When creating multiple documents that will link to each other (e.g. a knowledge doc and several component overviews that reference it), the correct order is:
Generate all skeleton files first. Each call mints a fresh UUID. Do not pre-assign or guess UUIDs before running the script — they will not match.
projects/ores.codegen/generate_doc.sh --type knowledge ... projects/ores.codegen/generate_doc.sh --type component --slug component_overview ... projects/ores.codegen/generate_doc.sh --type component --slug component_overview ...
Collect the generated IDs.
grep "^:ID:" projects/ores.foo/modeling/component_overview.org \ doc/knowledge/topic/my_knowledge.org
- Fill in the content of each file, using the actual IDs in
[[id:UUID][label]]links.
The --id flag is for migration only — preserving an existing UUID
when reformatting a document that already has one. Never use it to
pre-assign an ID to a brand-new document.
What the script does
- Generates a fresh UUID (always uppercase hex) and puts it in
:ID:. Every:ID:property and[[id:UUID]]link in the documentation graph must use uppercase hex — see Lock down uppercase UUID invariant. - Sets
#+createdand#+updatedto today. - Adds
--parent-slugas a filetag, so the parent-tag invariant holds. - Auto-detects parent
:ID:and#+title:from<parent-dir>/<parent-type>.orgfor task/story/sprint. - Renders the type's Mustache template from
projects/ores.codegen/library/templates/. - Writes the file (path varies by type — see the table in
projects/ores.codegen/docs/doc_generator.md). - Refuses to overwrite an existing file unless
--forceis passed.
Tested by
Manual smoke tests during initial development. No automated test yet — ores.codegen does not currently exercise the doc generator in CI.
See also
- How do I create a component overview? — component-specific workflow with section-by-section guidance.
- Component Documentation Guide — what makes a good component doc.
- How do I run codegen? — the C++ model-driven generator on the same infrastructure.
- document types — the contract every generated document follows.
- lifecycle — cross-sprint stories use
#+predecessor=/=#+successor. projects/ores.codegen/docs/doc_generator.md— full CLI reference.