Pick a Shape
Choose an ODS profile from the job the document does, fill the expected headings, and keep execution contracts out of YAML.
Pick a Shape
Overview
A profile is the shape of a document: which H2 or H3 headings a reader should find. It is not a file type and not a layout template.
guide got you through the first document. This page teaches you to pick the next shape without memorizing all thirteen standard profiles.
Prerequisites
- A workspace with
ods.tomland at least one document. - Comfort with the three placement rules from Your first document.
Steps
1. Pick from the job, not from a catalog
Ask what the file is for:
Are you teaching a procedure?
yes → guide
Are you recording a choice you already made?
yes → decision
Are you specifying a product capability?
yes → feature
Are you writing an on-call / ops procedure?
yes → sop
None of those / still exploring?
→ note (default; no required headings)
That covers most engineering repos. The other profiles (api, architecture, policy, meeting, faq, checklist, agent, skill) wait until you have that job. Full templates: specs/profiles.md. Pocket version: Decision cards.
2. Fill the headings the profile promises
| Profile | Expected H2/H3 headings | Why those, not others |
|---|---|---|
guide |
Overview, Prerequisites, Steps, Troubleshooting | A how-to that cannot be followed is decoration. |
decision |
Context, Decision, Alternatives, Consequences | Future you needs the rejected options, not only the winner. |
feature |
Goal, Scope, Requirements, Acceptance Criteria, Risks | A PRD without acceptance criteria cannot be tested. |
sop |
Purpose, Prerequisites, Steps, Validation, Rollback | A runbook without rollback is an incident waiting. |
note |
(none) | Scratchpads should not fail lint. |
Heading names must match the exact canonical section title (e.g. ## Alternatives, ## Non-Scope). Write the exact expected heading.
Missing expected headings are warnings, not errors. The file is still compliant. The warning exists so a decision does not ship without ## Consequences.
3. Grow the running example with a decision
The refunds guide assumes a payment provider. Record that choice as docs/decisions/004-stripe.md:
---
description: Why the billing service uses Stripe as the card processor.
tags:
- billing
- architecture
ods:
profile: decision
status: stable
---
# ADR 004: Stripe for Card Payments
## Context
The billing service must capture and refund cards without storing PAN data.
## Decision
Use Stripe as the card processor.
## Alternatives
- Adyen: stronger international coverage, higher integration cost for this team.
- In-house processor: rejected; PCI scope is not worth the control.
## Consequences
Refunds go through Stripe's refund API. The dashboard must store `charge_id`, not raw card numbers.
Same three placement rules. Different shape. A reader who sees profile: decision can trust those four headings exist.
4. Use status as a lifecycle, not a review board
| Status | Means |
|---|---|
draft |
Changing; do not treat as source of truth. |
stable |
Checked and ready for others to follow. |
deprecated |
Still readable; superseded. Point at the replacement with related (next page). |
archived |
Kept for history; not maintained. |
There is no in-review or needs-approval. If your team wants a review flag, put it in a heading or a top-level key your SSG already understands — not a new ods.status value.
5. Keep execution contracts in headings, not in YAML
This is the mistake that shows up the moment people write agent instructions.
Wrong — operational keys pollute frontmatter:
---
role: Autonomous TypeScript engineer
refusal_guardrails: [Never drop production]
workflow: [Inspect, Code, Test]
ods:
profile: agent
---
Right — the profile already reserved body sections for that:
---
description: Implement the refunds endpoint from the API contract.
ods:
profile: agent
status: draft
---
# Refunds Endpoint Agent
## Goal
Implement POST /api/v1/refunds against the published schema.
## Constraints
Never drop production data.
## Steps
1. Inspect the schema.
2. Write the handler.
3. Run the tests.
YAML is for facts a linter and an indexer should enforce. Prompts, guardrails, and workflows are prose. They belong under H2/H3 headings so any human or model can read them without a special parser.
Troubleshooting
- “Which profile if it is a bit of everything?” Use
noteuntil the job is clear. Do not invent a hybrid. - “Can I add extra headings?” Yes. Expected headings are a minimum, not a maximum.
- “Can I invent
profile: rfc?” Yes, as a custom profile — that is level 7. Until then,featureordecisionis enough. - “Lint says unknown profile.” Typo, or a custom profile not listed in
ods.toml. Unknown profiles warn and behave likenote.
You can stop here if you can pick note / guide / decision / feature / sop and fill the headings.
Next only if one document should require another: 03 · Link documents.