Extend ODS
Extend ODS with custom profiles and packs, and know which spec chapter to open for expert or implementer work.
Extend ODS
Overview
Everything before this page is standard ODS. You extend the standard when the thirteen built-in profiles are not the shape you actually write, or when you are implementing a parser.
This is the off-ramp into the spec, not a second spec.
Prerequisites
- A workspace you already lint (Run the workspace).
- A clear gap: a recurring document kind or an engine you are building.
- Willingness to stay inside what ODS refuses to add (no new file extension, no
title:, no custom code roles, no profile inheritance trees).
Steps
1. Add a custom profile only when a kind repeats
If you write RFCs every month, define the shape once.
docs/profiles/rfc.md:
---
ods:
custom_profile:
name: rfc
required_keys:
- github-issue
optional_keys: []
forbidden_keys: []
---
# Profile: RFC
## Summary
## Motivation
## Proposed Design
## Drawbacks
## Unresolved Questions
Register the file in ods.toml:
# ods.toml
spec = "0.1"
custom_profiles = ["docs/profiles/rfc.md"]
Then documents may say ods.profile: rfc. Resolution order is: built-in profiles, then custom_profiles, then packs. First match wins.
The required_keys list makes profile-specific metadata explicit. Each listed key must appear at the top level of documents using the profile:
github-issue: 123
ods:
profile: rfc
status: draft
These keys are profile-scoped metadata, not new ods: engine keys. Missing keys produce a PROF-003 warning; forbidden keys produce a PROF-004 warning. They do not change the standard engine-key placement rules. If the configured profile path is missing, the definition is invalid, or ods.profile cannot be resolved, ODS returns an error and does not fall back to another path or to the note profile.
Do not build inheritance (rfc extends feature extends base). Flat shapes stay debuggable. Full rules: specs/profiles.md.
2. Import a pack when several workspaces share shapes
packs = [
"vendor/engineering-pack"
]
A pack is a versioned folder of profiles (and, optionally, templates or skills). Treat it as shared configuration, not as a plugin marketplace inside the spec.
3. Open the spec by job, not by chapter number
| You need… | Open |
|---|---|
| Every frontmatter key, types, placement | specs/keys.md |
| All 13 profiles and templates | specs/profiles.md |
| ID rules, DAG, purity | specs/graph.md |
| Context algorithm | specs/context.md |
| Code roles, no line numbers | specs/assets.md |
Full ods.toml |
specs/indexes.md |
| Lint rule IDs, exit codes | specs/validation.md |
| What ODS will not add | specs/scope.md |
| Formal definitions | specs/glossary.md |
| Rules for coding agents editing this repo | AGENTS.md |
Authors who finished Your first document should not read those linearly. Implementers should start at specs/core.md then keys.md then validation.md.
5. Ignore sibling dialects until you have that problem
The ods engine also speaks:
--okf— Google OKF knowledge bundles (provenance, trust, freshness)--skills— reusableSKILL.mdpackages
Bare ods lint is ODS. You do not need those flags to use this specification.
Troubleshooting
- “Profile not found.” ODS checks the exact paths in
custom_profiles. Create the definition at the configured path, correct the path inods.toml, or makeods.profilematch the loaded definition name. - “Invalid custom profile placement.”
ods.custom_profileis only valid in a file selected bycustom_profilesor a registered pack. Move it to that file and useods.profilein the ordinary document. - “Two packs define
rfc.” First match wins; you should get a warning. Rename one. - “I want
implements/replacesedges.” Out of scope on purpose. Usedependsorrelated, and explain the nuance in prose. Seespecs/scope.md. - “I want to put
role:in frontmatter for agents.” Do not. Use##headings. Re-read Pick a shape §5.
You are at the end of the learning track. Carry Decision cards and Common mistakes. Use the spec as a dictionary.