Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4775df3
Add load(path) for opening a document; parse replaces parse_document …
claude Oct 2, 2026
39752c1
load: name the file as given (no symlink following), decode BOM in on…
claude Oct 2, 2026
a287d8e
load: read the path as given; Document.path after source_map
claude Oct 2, 2026
735af1e
Simplify the validation API: validate(), resolve=, a result that is o…
claude Oct 2, 2026
782a6a0
validate: one resolver helper, a documented no-read opt-out, stricter…
claude Oct 2, 2026
47b642d
validate: a document does not read itself; a legacy importer reads no…
claude Oct 2, 2026
da6f7de
validate: ask a resolver for a normalized in-directory path; CLI repo…
claude Oct 2, 2026
7987785
validate: the self-reference guard applies to every resolver
claude Oct 2, 2026
4916a0c
Group what validation resolved under result.index (DocumentIndex, Inl…
claude Oct 2, 2026
7785cb8
DocumentIndex: say values are as written; ValidationResult is built b…
claude Oct 2, 2026
10bf372
DocumentIndex: describe the inline values as the checks met them; sim…
claude Oct 2, 2026
a8624e1
Template and Form: read a template once, ask what is reached, check a…
claude Oct 2, 2026
326b4c8
Template: review fixes (defaults round-trip, rules, includes included…
claude Oct 2, 2026
0cdca37
Template: placeholder rules checked outside drafting notes, fragments…
claude Oct 2, 2026
bee875a
Form: the answer copy keeps its originals alive
claude Oct 2, 2026
cc548ef
Question.from_text and Question.hint: read what a person types
claude Oct 2, 2026
01ea6d3
from_text: review fixes (hand-built questions agree with their hint, …
claude Oct 2, 2026
390d0ba
coerce, load_answers, Form.as_dict, Question.accepts/to_text, legaldo…
claude Oct 2, 2026
fd7819d
Stage 3 review fixes: strict JSON, UTF-8 stdout for questions, bounde…
claude Oct 2, 2026
4805ef8
as_dict: a set or map holding an integer too long to write is still data
claude Oct 2, 2026
e44a40d
to_text: a set or map holding an integer too long to write describes …
claude Oct 2, 2026
17d3045
legaldown assemble -i and --save-answers
claude Oct 2, 2026
2766e39
assemble -i: review fixes (non-UTF-8 input, problems before asking, i…
claude Oct 2, 2026
b46ee37
Text answers: no control characters; _ask reads a plain line (no clai…
claude Oct 2, 2026
8fced7d
Version 0.4.0
claude Oct 2, 2026
777b355
PR review fixes: answers checked as the spec words them, Question as …
claude Oct 2, 2026
2f49559
README: the deprecated assemble no longer hands a loader a path outsi…
claude Oct 2, 2026
6de56b0
save-answers never replaces a file with nothing; assemble's refusal o…
claude Oct 2, 2026
c525342
save-answers: a symbolic link loop as the file to save to is an error…
claude Oct 2, 2026
729d783
tests: a symbolic link loop to save to is an error before Python 3.13…
claude Oct 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions CONFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,21 @@ files other than the document itself.
| Other | `frontmatter-invalid-yaml` (reported by the CLI and assembly, not the validator), `definition-circular`, `definition-used-before-declaration`, `language-code-invalid`, `authoritative-not-declared` |

In practice this means validating a set of files is out of scope: the validator does not resolve
or cross-check includes, attachment file contents, or bilingual document sets. Single-document
or cross-check includes, attachment file contents, or bilingual document sets. The one thing it
reads from another file is the definitions the amended original (§7.5) and the LegalDown
attachment files (§12.4) declare, from beside a document that has a path (`legaldown.load`; the
CLI) or through `validate(resolve=)`; an unreadable file is as if it were not asked for. Single-document
authoring, editing, and CI validation are fully covered. Assembly is the exception: it reads a
template's include fragments and LegalDown attachment files, and reports the checks on them that
its output depends on (see [Assembly](#assembly-157-176)); the validator still does not.

The template constructs of specification 0.2 (§15) are validated within the document: questions,
conditions and alternatives, reference safety, `{{choose:}}`, drafting notes, insertion
boundaries, and the final option (§15.9, `validate_document(final=True)` or
boundaries, and the final option (§15.9, `validate(final=True)` or
`legaldown validate --final`); assembly is described below. Two limits apply:

- A template's include fragments and LegalDown attachment files are not read (Full, §17.4), so
- A template's include fragments and LegalDown attachment files are not read (Full, §17.4) — the
attachment files only for the definitions they declare — so
`question-unused` is not reported for a template that has either: a question may be used there.
- A LegalDown attachment file or include fragment validated on its own is checked as a
standalone document: conditions, placeholders, and terms that refer to its template's
Expand Down Expand Up @@ -162,7 +166,7 @@ failed to resolve. From assembly, which reads the file, it means the file could
and for one whose `---` block holds YAML that is a scalar or a list rather than a mapping of
fields: that block is not frontmatter, its `---` lines are thematic breaks, and the whole document
is validated as body. A block that cannot be read at all — YAML that is malformed, nested too
deep, or a mapping of another kind (`!!set`) — is `frontmatter-invalid-yaml`: `parse_document`
deep, or a mapping of another kind (`!!set`) — is `frontmatter-invalid-yaml`: `parse` (and `load`)
raises `FrontmatterError` for it, which the CLI reports and assembly returns as a diagnostic, for
the template or for a fragment or attachment file it reads. Any other exception while parsing is
a fault of this implementation: the CLI reports it as an internal error (exit status 2), never as
Expand Down Expand Up @@ -201,18 +205,21 @@ CI runs this on every push and pull request.

## Assembly (§15.7, §17.6)

`assemble(template, answers)` and `legaldown assemble` perform §15.7.2 byte for byte and report
`Template.form(answers).assemble()` and `legaldown assemble` perform §15.7.2 byte for byte and report
the answer rules of §16.12 (`answer-invalid`, `answer-missing`, `answer-unknown`). The block
structure assembly edits is recorded by the parser's own walk, so assembly and validation read a
template the same way. `template_questions` and `needed_questions` list the questions a template
asks, all of them or those an answers set still leaves open.
template the same way. `Template.questions` lists the questions a template asks; `Form.questions`
those it reaches given an answers set, and `Form.unanswered` those still left open. §15.7.2 gives assembly a template that
validates without Errors, which assembly itself does not check; a `Template` refuses one with Errors
in the validator's template rules (`Template.problems`), and the deprecated `assemble` function does
not.

- A single-file template is assembled at Core, as §17.6 permits ("Core + Assembly").
- A template with include fragments or LegalDown attachment files is assembled when the caller
passes `load_file`, which reads them; the CLI reads them relative to the template and refuses a
passes `resolve` (`load_file` of the deprecated function), which reads them; the CLI reads them relative to the template and refuses a
path that leads out of its directory. Reading them is a Full capability (§17.4) that this
implementation provides for assembly without claiming Full, as §17.1 allows. Without
`load_file`, such a template is refused with `include-file-missing` or
`resolve`, such a template is refused with `include-file-missing` or
`attachment-file-missing`, never assembled partially (§17.6).
- A file assembly reads is checked as the Full level checks it (§16.10–§16.12), and the template
is refused if it fails: frontmatter (`include-has-frontmatter`, `attachment-has-frontmatter`), a
Expand Down
Loading
Loading