canonical-markdown-authoring
Convert plain markdown contract drafts into OpenAgreements' canonical template.md authoring format. The canonical form is a single lawyer-editable file that compiles to a validated JSON contract spec plus a rendered DOCX via the shared template renderer.
Activation
Use this skill when the user wants to:
- Convert a plain-prose contract draft into a canonical OpenAgreements
template.md - Migrate an existing JSON-source template to canonical authoring
- Author a new template that compiles via
npm run generate:templates - Add or refactor a Defined Terms clause,
oa:clausedirectives, or signer metadata - Bring a template into parity with the Wyoming / Employee IP canonical patterns
This skill assumes:
- You are working inside an OpenAgreements repo checkout. Templates live at
content/templates/<template-id>/template.md.
- The shared canonical compiler (
scripts/template_renderer/canonical-source.mjs)
and the cover-standard-signature-v1 layout are present.
Canonical structure overview
A canonical template.md has these parts in this order:
- YAML frontmatter — template ID, source paths, layout, style, document
metadata, section labels.
# Title— H1 matchingdocument.titlein frontmatter.## Cover Terms— short subtitle paragraph followed by a
Kind | Label | Value | Show When table with {snake_case} field placeholders.
- Optional
recitalssection —<!-- oa:section type=recitals -->
followed by an H2 such as ## Recitals and one or more recital paragraphs.
- Operative section —
<!-- oa:section type=standard_terms -->followed
by an author-chosen H2 such as ## Standard Terms, ## Resolutions, or ## Terms. Clauses live here, each preceded by <!-- oa:clause id=... -->. The first clause should be Defined Terms with type=definitions when a definitions clause is needed.
- Signature section —
<!-- oa:section type=signature -->followed by the
signature H2 and then <!-- oa:signature-mode arrangement=... --> plus the signer blocks.
Step-by-step conversion
Step 1 — Skeleton the frontmatter
---
template_id: openagreements-<slug> # kebab-case, must match the directory slug
layout_id: cover-standard-signature-v1
style_id: openagreements-default-v1
outputs:
docx: content/templates/openagreements-<slug>/template.docx
document:
title: <Document title> # MUST match the H1 below
label: <Catalog label, e.g. "OpenAgreements XYZ">
version: "1.0"
license: Free to use under CC BY 4.0
include_cloud_doc_line: true
defined_term_highlight_mode: definition_site_only # see "Highlight modes"
cover_row_height: 700
sections:
cover_terms:
section_label: Cover Terms
heading_title: Cover Terms
standard_terms:
section_label: Standard Terms
heading_title: Standard Terms
signature:
section_label: Signature Page
heading_title: Signatures
---
Notes:
- Canonical sources do not declare
source_json.npm run generate:templates
auto-discovers any content/templates/<slug>/template.md whose frontmatter declares template_id, layout_id, and style_id, then writes the generated JSON to content/templates/<slug>/.template.generated.json (a hidden, do-not-edit-by-hand artifact).
- Do not add
output_markdown_pathoroutputs.markdown— the canonical
compiler rejects them. The canonical template.md is the source.
- For directive-backed sections, the body H2 that follows
oa:sectionis the
rendered heading source of truth. Keep the frontmatter sections metadata in place, but treat the body heading as authoritative for the visible section title.
Step 2 — Title (H1)
# <Document title>
Keep the H1 text identical to document.title. There is no automatic cross-validation today, but drift between the two is a known footgun.
If the rendered title or section heading differs from the raw markdown, see "Sharp edges and renderer transforms" below for the body-vs.-frontmatter source-of-truth map.
Step 3 — Cover Terms section
Open with one short subtitle paragraph, then the Kind | Label | Value | Show When table:
## Cover Terms
The terms below are incorporated into and form part of this agreement.
| Kind | Label | Value | Show When |
| --- | --- | --- | --- |
| row | Company | {company_name} | always |
| row | Employee | {employee_name} | always |
| row | Effective Date | {effective_date} | always |
| group | Confidentiality | | always |
| subrow | Trade Secrets Duration | {trade_secret_duration} | always |
| subrow | Other Confidential Information Duration | {other_confidentiality_duration} | confidentiality_other_included |
Rules:
- Kind is
row,group, orsubrow. row— single-line cover term.group— section header with no value (leave theValuecolumn blank).subrow— child of the most recentgroup; rendered indented.- Label is the lawyer-facing label.
- Value is either literal text or a
{snake_case}field placeholder. Field
names must match ^[a-z_][a-z0-9_]*$.
- Show When:
always— always rendered.<field_name>— rendered only when the boolean field is truthy. The
field's name must satisfy ^[a-z_][a-z0-9_]*$.
Step 4 — Directive-anchored body sections
Every operative section starts with an oa:section directive. The H2 that follows may be author-chosen. Every clause inside the operative section then gets an oa:clause directive, a ### Heading, and prose paragraphs:
<!-- oa:section type=standard_terms -->
## Standard Terms
<!-- oa:clause id=assignment-of-inventions -->
### Assignment of Inventions
Employee hereby assigns and agrees to assign to Company all right, title, and
interest in Covered Inventions, to the extent permitted by law.
<!-- oa:clause id=non-competition when=noncompete_included omitted="[Intentionally Omitted.]" -->
### Non-Competition
During the Restricted Period, Employee must not engage in any Competitive Business
within the Restricted Territory.
If the document needs standalone WHEREAS-style recitals, author them in a separate recitals section before the operative section:
<!-- oa:section type=recitals -->
## Recitals
**WHEREAS**, Company is considering a financing transaction.
**WHEREAS**, the board has reviewed the proposed terms.
<!-- oa:section type=standard_terms -->
## Resolutions
oa:section types:
standard_terms— required operative clause sectionsignature— required signature sectionrecitals— optional recital-only section
Directive attributes:
id— slug, kebab-case, unique within the document. Used for stable
machine references.
when=<field_name>(optional) — clause is only included when the named
boolean field is truthy.
omitted="<text>"(optional) — text rendered in place of the body when
when evaluates false.
Step 4A — Present-tense IP assignment language
If a clause transfers inventions, work product, patent rights, copyrights, or other IP ownership, use a present-tense operative grant such as hereby assigns.
- Preferred baseline:
Employee hereby assigns to Company all right, title, and interest in ... - If future cooperation is also needed, add it after the present assignment:
... and will sign additional documents reasonably requested to confirm ownership.
- Do not rely on
agrees to assignorwill assignwithout a present-tense
grant. Federal Circuit contract law applied in the Stanford/Roche line of cases (FilmTec, DDB Techs, Rasmussen Instruments, the Federal Circuit decision in Stanford v. Roche, 583 F.3d 832) treats future-tense language as a promise to assign rather than a present transfer of rights — which diligence reviewers flag as a gap.
- This applies to employee invention-assignment agreements, contractor IP
as