Skip to content
ODS
Home/Docs/extend ods

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 — reusable SKILL.md packages

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 in ods.toml, or make ods.profile match the loaded definition name.
  • “Invalid custom profile placement.” ods.custom_profile is only valid in a file selected by custom_profiles or a registered pack. Move it to that file and use ods.profile in the ordinary document.
  • “Two packs define rfc.” First match wins; you should get a warning. Rename one.
  • “I want implements / replaces edges.” Out of scope on purpose. Use depends or related, and explain the nuance in prose. See specs/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.