Stained Glass OS

0016. Our own office suite: an editable engine, based on ONLYOFFICE

Decision confirmed (2026-09-29). David approved Option A (an attributed AGPL derivative of ONLYOFFICE's open engine, built natively on Linux); the suite is AGPL-3.0 with ONLYOFFICE attribution; named "SG Office, based on ONLYOFFICE", distinct from the LibreOffice-based sg-office; Phase 1 proceeds -- a buildable native engine + minimal SG-themed shell that opens/round-trips one .docx/.xlsx/.pptx, plus the fidelity harness as a make test-* gate, before any parity feature work.

Context

ADR 0015 chose, for the shipping suite, LibreOffice for Windows run under wine-sg and installed on request from The Document Foundation's MSI. That decision's own recorded weakness is decisive here:

A from-source Windows build is not feasible with an open toolchain, so engine patches (LAMBDA and friends, Excel's error values, spilling, the financial function bugs) cannot be carried [...] the rest is recorded in office/parity/REPORT.md as the honest list of gaps.

We ship an engine we cannot edit. LibreOffice's Windows build needs MSVC with Microsoft's SDK/CRT; its MinGW cross-build was removed upstream years ago (25.2's configure knows only MSC for Windows). Every engine-level Excel gap in 0015 (dynamic-array spilling, the LAMBDA/MAP/REDUCE/SCAN family, Excel's error values and date/ordering quirks) is therefore frozen until TDF fixes it.

David's mandate (2026-09-29), verbatim in intent: build our own office suite for SG OS, an editable, buildable-from-source Documents / Spreadsheets / Presentations that renders and round-trips .docx/.xlsx/.pptx (and ODF) neck-and-neck with Microsoft Office, using ONLYOFFICE as the key reference. 0015's own consequences already point here:

ONLYOFFICE's JavaScript engine is the one route to engine patches without a Windows toolchain. If its Wine problems are solved [...] this decision is worth revisiting with the same corpora.

0015 rejected ONLYOFFICE for shipping because it could not run VBA at all and, run as a Windows build under Wine, gave a credentials prompt and an empty sheet. Neither objection binds the new mandate: we are not shipping ONLYOFFICE's Windows binary under Wine, we are building its open engine from source, natively on Linux, editing it, and theming our own shell over it. The Wine wall was a property of running someone else's Windows build, not of the engine.

The governing licensing rule ([[licensing-reimplementation-rule]], ADR 0004) stands: our code is never Microsoft's; the core OS stays open source; we never ship third-party or Microsoft binaries in the image. ONLYOFFICE is AGPL-3.0 -- more copyleft than SG OS's usual LGPL/MPL, not less open -- so building on it keeps us open source. It is a third party's code, so any derivative must be a properly attributed AGPL derivative, and the ONLYOFFICE binary we install as a QA oracle stays in a dev/QA area, never in the OS or ISO.

Options

A. An attributed AGPL derivative of ONLYOFFICE's open engine

Fork ONLYOFFICE's core (C++ conversion + calc-adjacent code, x2t, DocumentBuilder) and sdkjs (the JavaScript Word/Cell/Slide document engines), build them from source on Linux with gcc + node, put our own native shell and SG Office theming over the top, and patch the engine where Excel fidelity demands it. Our suite becomes AGPL-3.0, which is consistent with an open-source core and is what David proposed ("SG Office, based on ONLYOFFICE").

B. A clean-room reimplementation, ONLYOFFICE only as reference

Read ONLYOFFICE (and the public OOXML/ODF specs) to learn how a feature should behave, then write every line ourselves -- our own OOXML/ODF model, our own layout/render, our own formula engine -- shipping under a licence of our choosing, unencumbered by AGPL.

C. (status quo, for reference) keep shipping LibreOffice-under-Wine only

Do nothing new. Rejected by the mandate: the engine stays uneditable and the 0015 gaps stay frozen. Retained as the interim shipping suite until ours is proven -- this ADR does not touch office/ (sg-office).

Option A: an attributed AGPL derivative of ONLYOFFICE's open engine, built from source natively on Linux, with our own SG-Office-themed shell.

Rationale, honestly weighed:

Option A does not mean shipping ONLYOFFICE. It means our own repository, our own build, our own shell and theme, our own patches, correctly attributed.

Evidence (what actually ran, 2026-09-29)

Toolchain on the dev box: gcc (Debian 14.2.0-19) 14.2.0, node v20.19.2, python3 3.11.10. ONLYOFFICE build_tools, core, sdkjs, web-apps and DesktopEditors are AGPL-3.0; build_tools orchestrates the Linux build with Python + node/grunt + gcc/qmake (no MSVC on Linux) -- confirmed from the repos. This is the editable/open-toolchain property the mandate requires.

Oracle installed and proven headless (no root, no X): downloaded onlyoffice-documentbuilder_amd64.deb 8.2.0-143 (81 MB) from download.onlyoffice.com, extracted with dpkg-deb -x into the dev/QA area office-qa/oracle/ (never installed system-wide, never in the image). The tree contains docbuilder, x2t (the OOXML/ODF converter), sdkjs (the JS engine, present as source-shipped script), libdoctrenderer.so, and the ICU data. A smoke script:

builder.CreateFile("docx");
Api.GetDocument().GetElement(0).AddText("Hello from the SG Office oracle");
builder.SaveFile("docx", "out.docx");  builder.CloseFile();

run as LD_LIBRARY_PATH=. ./docbuilder smoke.docbuilder produced a valid 25 KB .docx, exit 0, on a headless host with no display. Creating an .xlsx with a =TEXTJOIN(...) formula and saving it also succeeded. Known quirk: reading a cell back with GetRange("A3").GetValue() after OpenFile on an .xlsx throws TypeError: Cannot read property 'Vd' in this build -- so the fidelity harness reads values via conversion (x2t / rendered output), not the live GetValue API. Noted so it is not re-litigated.

Formula baseline already high: 0015 measured ONLYOFFICE's engine (DocumentBuilder, the same sdkjs used by the editors) at 720/775 cases matching Excel on our corpus -- ahead of LibreOffice 26.8's 714, and it has Excel's error values, 1900-leap-year dates and TRUE>100 ordering, and it spills dynamic arrays (LibreOffice does not). LAMBDA/MAP/REDUCE/SCAN/LET are still missing upstream -- but now they are ours to add.

Proposed architecture

  sg-office2  (new package, AGPL-3.0, "SG Office, based on ONLYOFFICE")
  =========================================================================
  Shell (native Linux; SG Office theming; our code)
    - three entry programs: Documents / Spreadsheets / Presentations
    - hosts the JS editors offline (CEF, as ONLYOFFICE's desktop does) OR a
      thinner host if we can avoid a full Chromium -- to be settled in Phase 1
    - Start-menu entries, window class, icons, ribbon = SG Office look
  Engine (our fork of ONLYOFFICE core + sdkjs; built with gcc + node)
    - sdkjs: Word/Cell/Slide document + layout + calc engines (JavaScript)
    - core: x2t converter (OOXML/ODF/PDF <-> internal "bin"), DocumentBuilder
    - OUR PATCHES land here: LAMBDA family, Excel error names, extra functions
  SG Office compatibility layer (carried/adapted from office/)
    - Excel-syntax + MS-format defaults: default to .docx/.xlsx/.pptx, Excel
      error-name display, number formats, ribbon arrangement
    - SG Office Functions: the add-in's 16-20 functions become native sdkjs
      functions (JS -> JS, no UNO bridge), so they move *into* the engine
    - VBA: later phase; native gives us room for a real VBA path vs the
      LibreOffice-under-Wine bridge that 0015 used
  sg-shell integration
    - file associations + Default apps: reuse office/defaults/*.reg pattern,
      but pointed at native launchers (a wine-side .exe shim exec'ing the
      native binary, matching how the shell launches things, OR native desktop
      entries -- Phase 1 decides which fits sg-shell's launcher model)
    - Open/Save go through the normal dialogs; mapped drives / UNC as today

Why native, not under Wine: 0015's ONLYOFFICE failure (credentials prompt + empty sheet) was its Windows build under Wine. Building the Linux engine natively removes that entire failure mode and gives us gcc/node editability. The cost is that our shell is a native Linux app in a Windows-like shell; the launcher-shim question (wine .exe stub vs native entry) is the one integration detail Phase 1 must resolve, and sg-shell already launches a mix.

How the office/ work carries over: the parity corpus (775 cases), the VBA corpus, and the fidelity set are engine-independent and move verbatim into the new harness. SG Office Functions' logic is already written and tested (office/functions/); reimplementing those functions as native sdkjs functions is a port, not a rewrite. The MS-format defaults and ribbon arrangement are configuration we re-express against the new shell.

QA rendering-fidelity oracle and harness (Phase 0 deliverable)

Consequences

The go/no-go this ADR asks for

  1. Base choice: approve Option A (AGPL ONLYOFFICE derivative) over Option B (clean-room)? Recommended: A.
  2. Licence: accept that our suite is AGPL-3.0 with ONLYOFFICE attribution (kept notices, "based on ONLYOFFICE", original developer named)?
  3. Naming: "SG Office, based on ONLYOFFICE" (as David proposed in 0015 for the ONLYOFFICE path), distinct from the interim LibreOffice-based sg-office?
  4. Scope of Phase 1: stand up a buildable native engine + minimal themed shell that opens and round-trips one .docx/.xlsx/.pptx, plus the fidelity harness as a make test-* gate -- before any parity feature work?

Addendum (2026-09-30): how the engine is built (M2)

Measured while building it; each point is a decision the build now depends on.

Addendum (2026-09-30): the program around the editors (M3)