Skip to content

Latest commit

 

History

History
145 lines (111 loc) · 7.86 KB

File metadata and controls

145 lines (111 loc) · 7.86 KB

Contributing to LegalDown

LegalDown is an open specification. Contributions are welcome — from typo fixes to new language features.

The specification is currently v0.2 DRAFT: breaking changes are still possible between draft revisions, and are recorded in CHANGELOG.md.


Where to start

You want to… Go to
Ask a question, float an idea, or discuss a design Discussions
Report an error, ambiguity, or contradiction in the spec Issues
Propose a concrete change Discussion first, then a pull request

Design changes start in Discussions. A pull request that changes the language itself is much more likely to land if the design was agreed first — the specification's job is to be unambiguous, and that is easier to settle in prose than in a diff.

Small corrections — typos, broken links, a validation row that contradicts its own section — can go straight to a pull request.


What makes a good specification change

LegalDown has a few standing commitments. A change that conflicts with one of these needs a strong argument:

  • No hardcoded numbers in source. Section numbers, list markers, and cross-reference text are generated at render time (§1.2). Anything that puts them back into the document is a regression.
  • Content and presentation stay separate. How something looks belongs to the style template (§13.7), not the document.
  • Determinism. Two conformant implementations must produce the same result for the same input. If a rule leaves room for interpretation, it is not finished — the identifier algorithm (§5.3) and the directive grammar (§11.2) are the reference standard for the level of precision expected.
  • Minimal extensions. LegalDown extends CommonMark only where legal drafting genuinely needs it. Prefer reusing an existing mechanism over adding a new directive.
  • Every rule needs a severity. A new requirement belongs in the §16 validation tables as an Error, Warning, or Info — otherwise implementations will disagree about what to do with it.
  • Every rule needs a conformance level. Decide whether the check is Core, Rendering, or Full (§17). Roughly: a check needing only the document file is Core; one needing the active style template or rendered output is Rendering; one needing another file is Full; one needing an answers set belongs to the Assembly capability (§17.6). Where a rule sits in a §16 table whose level differs, §17.2 carves it out by name — as it does for the style-template-dependent §16.3 row and the supersedes.file existence row.

Pull request checklist

A specification change usually touches more than the specification. Before opening a PR:

  • spec/legaldown-spec.md — the normative change, including any §16 validation rows and §17 conformance placement
  • llm/legaldown-spec-llm.md — the condensed reference, if the change is authoring-facing (skip for implementation-only changes, and say so in the PR)
  • README.md — if the change affects the introductory material or examples
  • examples/ — if the change adds a feature, add or extend an example, and update the feature-coverage table in examples/README.md
  • §18 ↔ examples/simple/ stay byte-identical — three documents claim the specification's §18 fenced blocks and the files in examples/simple/ are the same text. If you edit either, edit both
  • CHANGELOG.md — a dated entry under [Unreleased] (format below)
  • The spec's Revision: date — bump it when spec/legaldown-spec.md changes
  • fixtures/ — a fixture per new or changed rule (see below); if the change touches template assembly (§15.7), add or update a byte-exact case in fixtures/assembly/
  • Cross-references still resolve — section numbers shift when sections are added

If you deliberately skip one of these, say why in the PR description. Reviewers check for this.

Changelog entries

Entries follow Keep a Changelog with a few local conventions. Look at existing entries for the shape:

  • A short paragraph explaining why — what was broken, ambiguous, or missing
  • #### Added / #### Changed / #### Removed sections as needed
  • A #### Validation changes table with Rule | Before | After whenever severities move
  • A #### Files touched list
  • Breaking changes get a blockquote at the top of the entry and a migration note

Examples

Every document in examples/ must be valid under the current specification — no Errors. Warnings and Info notes may be configuration-dependent (see the notes in examples/README.md), so "no Errors" is the bar a contributor can actually verify. When you add a feature, add or extend an example that exercises it, and update the feature-coverage table in examples/README.md so the claim and the file agree.

Fixtures

fixtures/ is the conformance corpus: one directory per §16 rule id, holding a document that trips that rule and the diagnostic a validator must produce. It is what lets independent implementations verify they agree.

When you add or change a validation rule:

  • Give it a rule id in the §16 table (§16.1) — stable, lowercase, never renamed or reused
  • Add fixtures/invalid/<rule-id>/ with a case that trips it, and an expectation file recording rule id, level, and line — never message text, which §16.9 leaves to implementations
  • If the rule cannot be exercised by a document — because it depends on a style template or on the implementation rather than the input — record it in fixtures/coverage.json under not_mechanically_testable with a reason, rather than writing a fixture that does not test it
  • If the rule is checked only when assembling a template, or only under the final option (§15.9), say so in the expectation with requires_capability: "assembly" and requires_config ({"answers": "answers.yaml"} or {"final": true})
  • Run python fixtures/verify.py, which checks the corpus is self-consistent and that every rule id in §16 is accounted for

When you change how assembly works (§15.7), add or update a case in fixtures/assembly/ — a template, an answers set, and the exact output a conforming assembler must produce. Assembly is specified to be byte-identical across implementations, so these cases are compared byte for byte.


Style

  • Conformance keywords — MUST / MUST NOT / SHOULD / SHOULD NOT / MAY, per §1.5. Use them deliberately; prose that sounds normative but uses none of them will be read inconsistently.
  • Say who is bound. "Renderers MUST…", "Validators SHOULD…", "Authors MAY…" — a requirement without a subject is ambiguous.
  • Reference sections as §5.3, and keep a link to the section where the reader may need it.
  • Match the surrounding file's line-wrapping. spec/legaldown-spec.md and llm/legaldown-spec-llm.md keep each prose paragraph on a single line, so that an edit produces a one-line diff instead of a reflow; CHANGELOG.md, CONTRIBUTING.md, and the example documents wrap at roughly 100 characters. Do not reflow a paragraph you did not otherwise change.
  • Examples should look like real legal documents, not foo/bar.

Licensing

The specification is licensed under CC BY 4.0. By contributing, you agree that your contribution is licensed under the same terms.

The license covers the specification document and this repository's contents. It does not cover software that implements LegalDown — parsers, validators, renderers, and editors may be released under any license their authors choose.