Skip to content

chore(draft): setup github action for generating editor's draft .html/ .docx#11

Open
awoie wants to merge 13 commits into
mainfrom
awoie/setup-editors-draft
Open

chore(draft): setup github action for generating editor's draft .html/ .docx#11
awoie wants to merge 13 commits into
mainfrom
awoie/setup-editors-draft

Conversation

@awoie

@awoie awoie commented Jul 5, 2026

Copy link
Copy Markdown

This PR does the following:

  • setup github action to build .html/ .docx working draft
  • working draft is currently a skeleton document aligned with the ISO template

Fixes #12

@awoie awoie requested review from andrewhughes3000 and jogu July 5, 2026 15:58

@andrewhughes3000 andrewhughes3000 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@jogu

jogu commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

(feedback from claude/codex, and '1' is missing as it wasn't helpful so I deleted it)

2. HTML draft numbers ISO front matter as clauses; DOCX does not

File: draft/digital-credentials-harmonized-presentation.md:30 ·
Severity: High · Status: Confirmed

{mainmatter} starts before # Foreword, so the HTML output numbers
Foreword = 1, Introduction = 2, Scope = 3. The DOCX filter
(tools/iso-styles.lua) separately makes Foreword/Introduction unnumbered so
that Scope numbers as clause 1 — its stated intent. The two artifacts from the
same source therefore disagree on every clause number (HTML "3. Scope" is DOCX
"1 Scope"). For a document where ISO liaison discussion happens by clause
number, this divergence is already visible and will compound as clauses are
added.

Fix: Make the HTML rendition unnumber the front matter too (e.g. frontmatter
special sections), or number both consistently — a deliberate choice either
way.

3. mmark-to-pandoc line filters are not fenced-code-block aware

File: tools/mmark-to-pandoc.py:70 · Severity: High ·
Status: Confirmed

The filters that drop {:...} IAL lines and {mainmatter}/{backmatter}
markers, and rewrite .# headings, run on every line including lines inside
fenced code blocks. Once the spec gains request/response examples, any example
line matching those patterns is silently deleted or mangled in the Word output
while the HTML stays correct — a silent divergence in a normative example, with
no build error.

Fix: Track fence state (```/~~~) and skip filtering inside
fences. See also the structural recommendation below.

4. Abstract-dropping swallows any lower-level headings after .# Abstract

File: tools/mmark-to-pandoc.py:58 · Severity: High ·
Status: Confirmed

The loop that removes the abstract only stops at part markers or level-1 #
headings, but mmark ends the abstract at the next heading of any level. A
frontmatter subsection added after .# Abstract (e.g. ## Notice) appears in
the HTML draft but is silently missing from the ISO Word document.

Fix: Stop the drop loop at any heading, not only level-1.

5. Reference docx carries the template's section setup through wholesale

File: tools/make-iso-reference.py:139 (with --reference-doc in
Makefile:36) · Severity: Medium · Status: Confirmed (mechanism in
code; observed empirically in a generated DOCX)

transform() only touches [Content_Types].xml, .rels files, styles.xml,
and header/footer parts; word/document.xml — where the template's
multi-section setup (sectPr) lives — passes through untouched. Pandoc emits a
single-section document derived from it: in a generated DOCX the final sectPr
referenced only even/default header/footer parts and used the template's
first-section margins. The template's separate front-matter/body sections
(page-numbering restarts, per-section headers, margins) cannot survive this,
risking wrong page layout/numbering as the draft grows.

Fix: Curate the reference docx's single section deliberately (see
structural recommendation: commit a hand-finished reference docx).

6. TOML title extraction only handles plain double-quoted strings

File: tools/mmark-to-pandoc.py:41 · Severity: Medium ·
Status: Confirmed

Single-quoted TOML literal strings (title = 'Foo') never match, leaving the
Word document with no title block at all; escaped quotes/backslashes are
captured raw and re-escaped by json.dumps, rendering literal \" sequences
on the title page.

Fix: Parse the %%% block with tomllib instead of regexes.

7. Title/subtitle split truncates titles containing " - "

File: tools/iso-styles.lua:70 · Severity: Medium (latent — the
current title has exactly one separator) · Status: Confirmed

The split matches the first " - ". A title like "Digital Credentials -
Harmonized Presentation - Working Group Draft" renders with main title
"Digital Credentials" and the rest demoted to subtitle — a wrong title page
with no error.

Fix: Split on the last " - ", or pass title and status as separate
metadata fields instead of encoding them in one string.

8. Standalone reference-docx output keeps ISO OLE object and dangling image refs

File: tools/make-iso-reference.py:74 · Severity: Medium (standalone
usage only; pandoc consumes only styles) · Status: Confirmed

DROP_PREFIXES omits word/embeddings/, so the template's embedded
oleObject1.bin survives into the output, contradicting the docstring's claim
that no ISO branding travels with the file. The media relationships are
stripped but the r:embed="rId25" references in document.xml remain, so
opening the standalone output in Word shows broken-image placeholders.

Fix: Add word/embeddings/ to DROP_PREFIXES and remove the drawing
elements that reference dropped media (or stop advertising standalone usage).

9. Empty stream in [seriesInfo]; unpinned markdown2rfc image

Files: draft/digital-credentials-harmonized-presentation.md:8,
Makefile:25 · Severity: Low/Medium · Status: Confirmed

make html succeeds but mmark warns Empty 'stream' in [seriesInfo], resulting XML may fail to parse — the block has name/value/status but no stream.
The danielfett/markdown2rfc image is untagged (:latest), so a future
image/toolchain update could turn the warning into a CI break. The
[seriesInfo] block looks carried over from IETF drafts (ipr = "none",
OpenID workgroup); worth deciding what series info this document actually has
rather than just adding a stream value.

Fix: Decide the correct seriesInfo for an OpenID/ISO joint document; pin
the Docker image by tag or digest.

10. No concurrency group on the GitHub Pages deployment

File: .github/workflows/build.yml:68 · Severity: Low/Medium ·
Status: Plausible

Two quick merges to main can run deploy-pages concurrently: one fails with
"a deployment is already in progress" (red CI on main), or the older build
finishes last and the published draft goes stale.

Fix: Add the standard concurrency: { group: "pages", cancel-in-progress: false }
block.

11. Unpinned pandoc install via apt

File: .github/workflows/build.yml:42 · Severity: Low (cleanup) ·
Status: Confirmed

apt-get update && apt-get install pandoc adds 30–60 s to every run (doubled
across push and PR triggers) and pulls whatever version the runner image
resolves, so the ISO .docx rendering can silently change between identical
commits.

Fix: Install a pinned pandoc release .deb — faster and reproducible.

12. "Working Group Draft" label on an automatic per-commit build

Files: README.md:27, Makefile (-wg-draft.html naming), and the
draft's own Foreword text · Severity: Low (process/status question) ·
Status: Plausible

The removed README text distinguished "Editor's Copy" from "Working Group
Drafts" — distinct approval statuses in the OpenID process. The new text and
the output filename label the per-commit build from main as "The current
Working Group Draft", inviting readers to treat unapproved content as an
approved draft. The branch itself is named setup-editors-draft.

Fix: Decide the intended status with the WG and label the artifact
accordingly (e.g. "Editor's Copy" until a draft is approved).

13. Fragile cp glob in the Makefile

File: Makefile:27 · Severity: Low · Status: Plausible

cp $(SRCDIR)/$(DOC)*.html <single file> breaks if the glob ever matches two
files — e.g. after an interrupted run leaves a stale intermediate behind —
failing with "target is not a directory" until manually cleaned up.

Fix: Copy the exact expected filename, or clean before building.


Architecture assessment

The goal — one markdown source producing both an OpenID-style HTML draft and an
ISO-styled Word document — is sound, and single-sourcing is the right call.
The fragility concentrates in three stacked regex transformation layers
(line-filtering mmark syntax, regex surgery on the .dotx zip, string-splitting
the title in Lua), each of which fails silently. Nine of the thirteen
findings live in those layers.

Recommended restructuring, without changing the architecture:

  1. Commit a hand-finished reference docx instead of regenerating it every
    build.
    Run make-iso-reference.py once (or do the cleanup by hand in
    Word), fix the section setup, headers/footers, and margins properly, verify
    no ISO branding remains, and commit template/iso-reference.docx. This
    removes an entire fragile script from the build path and fixes finding 5 in
    a way regex-editing OOXML inside a zip never can. (The .dotx is already
    committed, so redistribution of a derived file is no new concern.)

  2. Parse, don't pattern-match, in the converter. The %%% TOML block is
    cleanly delimited: split it off, parse with tomllib (stdlib since Python
    3.11), and emit real pandoc metadata. Process the body with fence awareness.
    This kills findings 3, 4, and 6 at the root. Add one golden-output test (a
    sample input with fences, IALs, and multi-heading frontmatter, plus its
    expected output) so future silent corruption becomes a test failure.

  3. Pin everything — the Docker image by tag/digest, pandoc by release
    .deb. Reproducible ISO output is the point of the docx path.

The genuinely different alternative is Metanorma (metanorma-iso),
purpose-built for authoring ISO deliverables: clause numbering,
Foreword/Introduction handling, terms-and-definitions structure, and Word
output are native. But it means AsciiDoc instead of mmark and abandons the
xml2rfc-style HTML that OpenID WGs conventionally publish.

Open question to settle with the WG before investing further: what is the
generated docx for? If WG10's project editor will re-flow content into the
official ISO template manually (common JTC1 practice), the docx only needs to
be complete and readable, and most of the styling precision is effort spent on
an intermediate artifact. If the generated file is meant to be the
submission, the pipeline will keep fighting pandoc's single-section model, and
Metanorma deserves a real evaluation before more regexes accumulate.

- mmark-to-pandoc.py: parse TOML with tomllib, fence-aware filtering,
  abstract drop stops at any heading, title/status as separate fields (#3,4,6,7)
- add golden-output test for the converter (tests/)
- commit template/iso-reference.docx; drop generator from build path (#5)
- make-iso-reference.py: drop word/embeddings/, strip dangling drawing refs (#8)
- Makefile: clean before build, PYTHON override, pin markdown2rfc by digest (#9,13)
- build.yml: pages concurrency group, pinned pandoc .deb, pin Python 3.12 (#10,11)
- draft: unnumbered Foreword/Introduction so Scope=clause 1 in both outputs (#2);
  add seriesInfo stream (#9); relabel Working Group Draft -> Editor's Copy (#12)
@awoie

awoie commented Jul 7, 2026

Copy link
Copy Markdown
Author

(feedback from claude/codex, and '1' is missing as it wasn't helpful so I deleted it)

Thanks for the detailed review. Addressed in the latest push (AI-assisted).

Converter (parse, don't pattern-match). mmark-to-pandoc.py now parses the
%%% block with tomllib and processes the body fence-aware:

  • finding 6: single/escaped TOML titles now parse.
  • finding 7: title/status emitted as separate pandoc fields (split on the last " - ").
  • finding 4: abstract drop stops at the next heading of any level.
  • finding 3: %%%/{...}/.# inside code fences pass through verbatim.
  • Added a golden-output test (tests/) that runs in CI.

Reference docx. Generated once and committed as template/iso-reference.docx;
make-iso-reference.py is out of the build path (finding 5). finding 8: drops
word/embeddings/ and strips the drawing/object refs so it opens clean.

Build/CI. finding 13 clean-before-build; finding 9 markdown2rfc pinned by
digest + stream added; finding 11 pandoc from pinned .deb; finding 10
concurrency: pages on deploy; Python pinned to 3.12 (converter needs 3.11+).

Findings 2 + 12. Foreword/Introduction are now unnumbered front matter (.#)
with {mainmatter} before Scope, so HTML and DOCX agree Scope = clause 1;
relabeled "Working Group Draft" to "Editor's Copy" throughout.

Not going the Metanorma route: it would mean AsciiDoc and dropping the
xml2rfc-style HTML that OpenID WGs publish. The committed reference docx would
still benefit from a one-time manual Word pass to finalize section setup
(finding 5). seriesInfo is the mmark/xml2rfc front-matter block
(name/value/status/stream) that labels the document's series in the HTML header;
it is currently carried over from IETF Internet-Drafts, so its final values for
an OpenID/ISO joint document are a WG decision (finding 9). For now I only added
stream to clear the build warning.

- seriesInfo stream independent conflicted with xml2rfc's default
  submissionType (IETF) and failed # Clean stale intermediates first so the copy below is unambiguous even if a
# previous run was interrupted.
rm -f draft/digital-credentials-harmonized-presentation*.html draft/digital-credentials-harmonized-presentation*.xml draft/digital-credentials-harmonized-presentation*.txt
docker run --rm -v "/Users/oliver.terbu/git/openid/dchp/draft:/data" danielfett/markdown2rfc@sha256:7b4412559d6ba5db45a14174a28da5b240512e7c2a886a5e4adb44e5e67f34ca digital-credentials-harmonized-presentation.md
Dockerfile danielfett/markdown2rfc
Using versions:
mmark: 2.2.31
xml2rfc 3.16.0
---------------------
mkdir -p build
# Cleaned above, so this glob now matches exactly the fresh output whatever
# markdown2rfc names it (it may add a draft-version suffix).
cp draft/digital-credentials-harmonized-presentation*.html build/digital-credentials-harmonized-presentation-editors-copy.html
rm -f draft/digital-credentials-harmonized-presentation*.html draft/digital-credentials-harmonized-presentation*.xml draft/digital-credentials-harmonized-presentation*.txt
HTML Editor's Copy -> build/digital-credentials-harmonized-presentation-editors-copy.html; set stream = IETF to clear
  the empty-stream warning without the conflict (finding 9)
- Makefile: auto-detect a tomllib-capable Python (3.11+) so mkdir -p build
python3.13 tools/mmark-to-pandoc.py < draft/digital-credentials-harmonized-presentation.md > build/digital-credentials-harmonized-presentation.pandoc.md
pandoc build/digital-credentials-harmonized-presentation.pandoc.md \
		--reference-doc=template/iso-reference.docx \
		--lua-filter=tools/iso-styles.lua \
		-o build/digital-credentials-harmonized-presentation.docx
rm -f build/digital-credentials-harmonized-presentation.pandoc.md
ISO Word document -> build/digital-credentials-harmonized-presentation.docx works
  where the default python3 is older, with a clear error if none is found
- Makefile: revert the HTML copy to a glob (markdown2rfc may add a draft-version
  suffix); the clean-before-build step keeps it unambiguous (finding 13)
@awoie

awoie commented Jul 7, 2026

Copy link
Copy Markdown
Author

(feedback from claude/codex, and '1' is missing as it wasn't helpful so I deleted it)

Thanks for the detailed review. Addressed in the latest push (AI-assisted).

Converter (parse, don't pattern-match). mmark-to-pandoc.py now parses the %%% block with tomllib and processes the body fence-aware:

  • finding 6: single/escaped TOML titles now parse.
  • finding 7: title/status emitted as separate pandoc fields (split on the last " - ").
  • finding 4: abstract drop stops at the next heading of any level.
  • finding 3: %%%/{...}/.# inside code fences pass through verbatim.
  • Added a golden-output test (tests/) that runs in CI.

Reference docx. Generated once and committed as template/iso-reference.docx; make-iso-reference.py is out of the build path (finding 5). finding 8: drops word/embeddings/ and strips the drawing/object refs so it opens clean.

Build/CI. finding 13 clean-before-build; finding 9 markdown2rfc pinned by digest + stream added; finding 11 pandoc from pinned .deb; finding 10 concurrency: pages on deploy; Python pinned to 3.12 (converter needs 3.11+).

Findings 2 + 12. Foreword/Introduction are now unnumbered front matter (.#) with {mainmatter} before Scope, so HTML and DOCX agree Scope = clause 1; relabeled "Working Group Draft" to "Editor's Copy" throughout.

Not going the Metanorma route: it would mean AsciiDoc and dropping the xml2rfc-style HTML that OpenID WGs publish. The committed reference docx would still benefit from a one-time manual Word pass to finalize section setup (finding 5). seriesInfo is the mmark/xml2rfc front-matter block (name/value/status/stream) that labels the document's series in the HTML header; it is currently carried over from IETF Internet-Drafts, so its final values for an OpenID/ISO joint document are a WG decision (finding 9). For now I only added stream to clear the build warning.

Follow-up: fixed two build issues from the first pass (AI-assisted).

  • make html was failing: seriesInfo stream = "independent" conflicts with
    xml2rfc's default submissionType (IETF). Set stream = "IETF" to clear the
    empty-stream warning without the conflict.
  • make docx failed on Python older than 3.11 (no tomllib). The Makefile now
    auto-picks a tomllib-capable interpreter (override with PYTHON=...), and the
    HTML copy is back to a glob since markdown2rfc may add a draft-version suffix.

@awoie

awoie commented Jul 7, 2026

Copy link
Copy Markdown
Author

It seems there is a build error on github. I will fix and let you know once fixed @jogu .

@awoie awoie changed the title chore(draft): setup github action for generating working draft .html/ .docx chore(draft): setup github action for generating editor's draft .html/ .docx Jul 7, 2026
@awoie

awoie commented Jul 7, 2026

Copy link
Copy Markdown
Author

It seems there is a build error on github. I will fix and let you know once fixed @jogu .

I forgot to push the fixes. Fixes are in and build action succeeded. Please review again @jogu.

mmark hard-codes the rfc submissionType as IETF and won't accept a non-IETF
stream, so the previous stream = IETF was misleading and stream = independent
fails the build. Leave stream unset (benign Empty-stream warning, HTML still
builds) and note that the real publication reference is a WG/SDO decision
(issue 13).
@c2bo

c2bo commented Jul 7, 2026

Copy link
Copy Markdown
Member

Would it make sense to move the tooling to a separate repository in OIDF and provide it ready to use as a container?

jogu and others added 9 commits July 8, 2026 10:14
The build job runs tests/test_mmark_to_pandoc.py, but the push and
pull_request paths filters did not include tests/**, so a PR touching
only the test or its golden fixtures merged with no CI run at all; a
fixture/converter mismatch would only surface on the next unrelated PR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The committed template/iso-reference.docx shipped three things from the
ISO Word template that the generator's docstring promised were stripped:

  * docProps/core.xml with the template author's personal metadata
    (dc:creator / cp:lastModifiedBy) — a third party's personal data in
    a public repo; only app.xml and custom.xml were dropped. Drop the
    whole docProps/ tree (Word and pandoc do not need document
    properties) and strip the package references to it.
  * the entire ISO template body: title page, WD/CD review warning, and
    the full ISO copyright/IPR notice (© ISO, "All rights reserved…",
    the ISO copyright office address). Pandoc ignores the reference
    document's body — it reads the styles and the body-level <w:sectPr>
    only — so replace the body with one empty paragraph plus that
    sectPr, and strip drawing/object elements from the kept
    headers/footers instead (their media relationships were already
    being removed).
  * [trash]/0000.dat and [trash]/0001.dat — zip-housekeeping junk left
    in the .dotx by whatever tool last edited the ISO template.

Add tests/test_iso_reference.py pinning all of this against the
committed file (docProps absence, ISO-boilerplate tripwires, junk
entries, sectPr preservation) and run it in CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fence tracking normalised every fence to three characters and
accepted any indentation, so three distinct kinds of legal fence content
desynced the open/closed state and mmark filtering ran inside verbatim
examples (or, inverted, {backmatter}/{: ...} lines leaked into the Word
document as literal text):

  * a 3-backtick line inside a 4+-backtick fence was taken as the closer
    (CommonMark: a closer must be at least as long as the opener);
  * a '```lang' line inside an open fence was taken as the closer
    (closing fences must be bare — no info string);
  * backticks indented 4+ spaces (indented-code content) toggled fence
    state (fences may be indented at most 3 spaces).

Track the opener's marker verbatim and require closers to match its
character, meet its length, and carry no info string; also reject
backtick openers whose info string contains a backtick. Each rule is
pinned by a new focused test case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three independent ways the %%% ... %%% detection deviated from how
mmark reads the file, each leaking or crashing instead of converting:

  * a UTF-8 BOM (e.g. from Notepad) hid the opening delimiter —
    str.strip() does not remove U+FEFF — so the raw TOML (title,
    seriesInfo, author emails) was emitted verbatim as Word body text;
  * a '%%%' line inside a TOML multi-line string was taken as the
    closing delimiter, so tomllib crashed on the truncated block even
    though mmark parses the same file fine;
  * an unclosed block was silently treated as body, again rendering the
    raw TOML into the Word document.

Strip a leading BOM, find the closing delimiter by parsing (a candidate
that leaves invalid TOML behind is not the closer), and raise a clear
error for unclosed/invalid front matter so `make docx` fails loudly
rather than shipping a garbled deliverable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The abstract-dropping state only terminated on ATX headings ('#'/'.#')
or part markers, so a setext-style heading after .# Abstract

    Foreword
    ========

was swallowed together with its entire section body — whole sections
silently vanished from the Word document. Look one line ahead for a
=/- underline under a non-blank line and end the drop there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ABSTRACT_START and IAL_LINE were anchored at column 0 while the heading
regexes tolerate up to 3 leading spaces (per CommonMark/kramdown). An
abstract heading indented 1-3 spaces was therefore rewritten to a
literal '# Abstract' clause — shipping the abstract into an ISO
deliverable that must not have one — and an indented attribute-list
line (e.g. attached to a list item) rendered as literal '{: ...}' body
text in the Word document.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
convert() used str.splitlines(), which also breaks lines at U+2028,
U+0085, form feed, and friends — characters markdown (and mmark) treat
as ordinary text. A LINE SEPARATOR pasted into prose from Word or a PDF
(a common artifact when copying from ISO documents) inside a heading or
table row therefore split that line in two in the Word rendition only,
silently diverging from the HTML rendition. Normalise CRLF/CR and split
on "\n" alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
template/Word_template_for_ISO_standards.dotx carried everything the
derived reference docx scrubs: the template author's personal metadata
(docProps/core.xml), an "ISO - Internal" classification label
(docProps/custom.xml), the full ISO copyright/title-page/footer
boilerplate, the ISO logo/OLE/customXml parts, and [trash]/ zip junk —
and it is ISO-copyrighted material in a public repo. Sanitizing the
committed iso-reference.docx while publishing its dirty source defeated
the point.

Drop the .dotx; the committed iso-reference.docx remains the build
input. To regenerate it, obtain the template from ISO/IEC JTC 1/SC 17
WG 10 and place it at the documented path (the generator now writes to
the committed location by default — the old default, build/, was read
by nothing).

Extend tests/test_iso_reference.py to guard the committed artifacts:
the hygiene checks scan every committed .docx/.dotx (via git ls-files,
with a new "ISO - Internal" tripwire), and a sync check rebuilds the
reference document in memory and compares it part-for-part
(decompressed, so zlib differences between environments cannot cause
false failures) so a template or generator change cannot silently ship
a stale docx — it runs whenever the ISO template is present locally
and skips otherwise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Makefile: add a `make test` target (globs tests/test_*.py, so a new
  test runs in CI without editing the workflow) and share the
  Python-with-tomllib guard between docx and test via a need-python
  prerequisite; build.yml now runs `make test` like the other steps
  delegate to make.
- mmark-to-pandoc.py: spell the 3-space block-indent tolerance the same
  way in all seven regexes; this also fixes the last members of the
  indented-construct leak class (an indented {mainmatter} passed
  through as literal Word text, tab-indented headings ended the
  abstract drop). Test case added.
- make-iso-reference.py: derive _DANGLING from DROP_PREFIXES so the
  drop list and the reference-stripping list cannot drift (verified
  output-identical against the ISO template); inline the trivial
  _is_dropped wrapper.
- tests: read each zip part once in the boilerplate scan instead of
  once per marker; open the reference docx once in main(); drop the
  redundant name parameter threaded into diff headers; replace
  repeated why-the-template-is-not-committed prose with pointers to
  the generator docstring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prepare editor's draft generation/ rendering

4 participants