* #3719: run the file commands through the hostile-parameter test hostile_params_never_panic skips file.*, insert.picture and insert.textFromFile, the commands that take a path and parse what is there. hostile_file_params_never_panic runs them with the same junk params, and with paths to an empty file, a folder, a missing name and noise under each extension they open or save. Automation roots hold them to a temporary folder. It found no panic, so this adds only the test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * #5688: check the whole working directory, on the sample document The working-directory check looked only for hostile-relative names, but an empty path comes out as .pdf or .dotx there. It now compares the whole folder before and after the runs. The runs now use the sample document, like hostile_params_never_panic: on an empty document the export commands had almost nothing to write. The docs and comments name the three groups of commands, because other commands also read files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * #5688: a failing file check names the files, not their bytes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
8.3 KiB
WordCraft architecture
Last reviewed: 2026-10-28 · Last updated: 2026-11-05 · Change: trivial (the hostile-parameter test now has a sibling for
file.*,insert.pictureandinsert.textFromFile; previously trivial: craft-proof's row says what a build without the Language data keeps: English spelling from an installed Hunspell English or the built-in list, rule hyphenation for Bulgarian, Turkish and Russian; previously minor: proofing moved out:wordcraft-proofis craft-libs'craft-proof, its Language data craft-i18n'slanguage-data/embedded fromCRAFT_I18N_DIR; previously major: crate and layer inventory, source counts, proofing languages and module boundaries re-measured from this checkout; previously minor:proofis per language: English and Polish; previously major: first committed version;plan/architecture.mdis local-only) · Target: Microsoft Word (Microsoft 365) for Mac 16.113.4
How WordCraft is built today. The longer design notes in
plan/architecture.md are gitignored and local to the original author's machine; this file is the
committed, current summary. Rules for working in the code are in AGENTS.md.
Layers
On 2026-10-28, find crates apps xtask -type f -name '*.rs' -print0 | xargs -0 wc -l counted
333,448 Rust source lines across 16 crates, 3 apps and xtask. Cargo.toml declares workspace
members with crates/*, apps/* and xtask; cargo xtask layers verified 20 workspace packages
(16 crates, 3 apps and xtask) and no layering violations. The layer and line counts below are
from that command and per-directory find ... -name '*.rs' ... | wc -l counts on that date. Each
crate name links to its source tree.
| Layer | Crate | Lines | Job |
|---|---|---|---|
| L0 standalone | control-key |
87 | Per-window control-port key files shared by the app and MCP bridge |
| L0 | geom |
1,271 | Units (points, twips, EMU, inches, cm), rectangles and measurement parsing |
| L1 | doc |
23,719 | Document model: stories, paragraphs, runs, tables, sections, styles, numbering, fields, notes, comments, revisions and equations; edit primitives and bidi |
| L1 | fonts |
7,088 | Font database, metrics, outlines, HarfRust shaping, Word font substitution and OpenType MATH |
| L1 | metafile |
3,614 | Shared Windows Metafile parsing and drawing primitives used by format readers and renderers |
| L1 (external) | craft-proof (package alias wordcraft-proof) |
— | Proofing moved to craft-libs (CP1, 2026-11): fifteen spelling dictionaries: English (US, GB, CA), Polish, Portuguese, Italian, Croatian, Turkish, Russian, Czech, Indonesian and Spanish (Spain, Mexico, Latin America, Uruguay); language modules provide spelling, suggestions and grammar, while Bulgarian and German have hyphenation only. Its word lists and patterns are craft-i18n's language-data/, embedded from CRAFT_I18N_DIR at the commit in craft-i18n.rev (CI and releases set CRAFT_I18N_REQUIRED=1); without them English spelling falls back to an installed Hunspell English or craft-proof's built-in Moby list, and pattern hyphenation is off (Bulgarian, Turkish and Russian hyphenate by rule) |
| L2 | docbin |
8,815 | Word 97–2003 .doc reader (FIB, piece table, FKPs, SPRMs, stylesheet, lists, tables, notes, pictures) over a CFB container |
| L2 | docx |
37,376 | OOXML WordprocessingML reader/writer (Transitional and Strict), OMML, custom properties and preserved VBA parts |
| L2 | formats |
23,058 | TXT, Markdown, HTML, RTF, ODT and LaTeX import/export through the shared document model |
| L2 | layout |
35,990 | Paragraph line layout (para), page/section flow and table layout, then display-list generation (display); hit testing maps points to document positions. para owns shaping, breaks, tabs and line geometry; page flow composes paragraphs, tables, headers/footers, notes and floats. |
| L3 | pdf |
4,513 | krilla PDF export: font subsets, selectable text, links, outline and tagging |
| L3 | render |
4,499 | vello_cpu rasterizer: pages and thumbnails from the display list; PNG/JPEG |
| L4 | engine |
72,851 | Session and editing state; command registry in cmd/; file dispatch in io; catalog, keymap, recovery, ribbon model, speech and view state |
| L5 | mcp |
1,822 | MCP server exposing commands as tools; headless or bridged to the running app |
| L5 | zotero |
2,372 | Zotero word-processor integration protocol answered against a Session |
| L6 | ui-egui |
81,759 | Front end: ribbon, keytips, mini-toolbar, Backstage, canvas, rulers, panes, dialogs, i18n, themes, control channel and headless ui_shot example |
| apps | wordcraft |
3,740 | Desktop app (eframe + wgpu; logging, window geometry and file associations) |
| apps | wordcraft-cli |
1,901 | convert, text, inspect, run, commands, parity, mcp and zotero |
| apps | wordcraft-web |
1,159 | Browser build (eframe web runner, WebGPU with WebGL2 fallback) |
| tooling | xtask |
1,488 | Workspace maintenance and quality-gate commands, including layers |
Data flow
- Open:
engine::iopicks a reader by extension (docx,docbin,formats, JSON) and produces adoc::Document. - Edit: every user-visible action is a command id run through
Session::run(ribbon, shortcuts, command search, CLI, control channel and MCP all dispatch by id).Session::runsnapshots for undo (blocks areArc-shared, so snapshots are cheap) and catches an escaped panic, restoring the document (never-crash standard). - Layout:
layoutturns the document into pages of positioned glyphs, boxes and images (display list), incrementally: an edit relayouts only what changed (1.4 ms on a 188-page document, measured 2026-10-06). - Draw: the UI paints pages through
render(CPU raster, cached per page, pixel-aligned) on an egui/wgpu canvas; PDF export walks the same display list throughpdf. - Save:
engine::iopicks a writer by extension.
Testing and gates
- 821
#[test]functions and 10 property-test blocks: model, layout, DOCX round-trip and hostile input,.doc, formats, typing parity (engine/src/tests/typing.rs), bidi, i18n catalogs, UI interaction (egui_kittest), MCP acceptance;hostile_file_params_never_panicrunsfile.*,insert.pictureandinsert.textFromFilewith junk params and unusable paths, held to a temporary folder, andhostile_params_never_panicevery other command with junk params. cargo xtask ci: fmt, clippy-D warnings, tests, asset attribution, layering, wasm build.cargo xtask parityregeneratesparity-checklist.md; a test keeps the catalog percentage above a floor that only rises.- GitHub Actions on PRs: packaging lint, and FreeBSD / Windows ARM64 when build files change;
release builds on pushes to
release.
Revision history
| Date | Change | Summary |
|---|---|---|
| 2026-11-05 | trivial | hostile_file_params_never_panic runs file.*, insert.picture and insert.textFromFile with junk params and unusable paths (#3719) |
| 2026-11-02 | trivial | craft-proof's row: without the Language data English spelling falls back to an installed Hunspell English or the built-in Moby list, and only pattern hyphenation is off (#5202 review) |
| 2026-11-01 | minor | proof left the workspace: it is craft-proof in storytold/craft-libs (with its history), and the spelling and hyphenation data is craft-i18n's language-data/ (CRAFT_I18N_DIR); assets/spelling and assets/hyphenation are gone |
| 2026-10-28 | major | Recounted workspace crates, layers and Rust source lines; refreshed proofing languages and documented current engine/layout module boundaries and source links |
| 2026-10-10 | minor | proof: proofing languages (English, Polish), affix engine, Polish patterns; layout and engine route each run by its language |
| 2026-10-10 | major | First committed architecture doc, from the crates' sources and AGENTS.md |