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 thecover-standard-signature-v1layout 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 aKind | Label | Value | Show Whentable with{snake_case}field placeholders.- Optional
recitalssection —<!-- oa:section type=recitals -->followed by an H2 such as## Recitalsand 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 beDefined Termswithtype=definitionswhen 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:templatesauto-discovers anycontent/templates/<slug>/template.mdwhose frontmatter declarestemplate_id,layout_id, andstyle_id, then writes the generated JSON tocontent/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 canonicaltemplate.mdis the source. - For directive-backed sections, the body H2 that follows
oa:sectionis the rendered heading source of truth. Keep the frontmattersectionsmetadata 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 whenwhenevaluates 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