Skip to content

Releases: yanlingLabs/norma

vendor-libreoffice-20260822-r4 (headless LibreOffice, macOS arm64, r4)

Choose a tag to compare

Prebuilt, privacy-scrubbed headless LibreOffice engine for macOS arm64 — vendored dependency for
the Norma app, not an app release itself (--latest=false; does not affect the app's release
lineage or its Sparkle appcast).

What this is

A native macOS arm64 build of LibreOffice/core @ 11482c8f71bc76ed6260bc03b1576a52a788ab4f
with --enable-headless (the svp/headless VCL backend — the same shape LibreOffice's own iOS
port uses). Same commit, same configure flags, same build as -r2/-r3 — this asset changes
exactly one thing. Zero source patches anywhere in this build.

Why -r4

One disclosed change on top of -r3, from the same already-built core/instdir/ (no rebuild):
product-set/Frameworks/libmswordlo.dylib is added (68th dylib).

-r3 fixed .xlsx export and left .docx export failing with
SfxBaseModel::impl_store ... failed: 0xc10(Error Area:Io Class:Write Code:16), honestly disclosed
there as "a different, still-open Writer/OOXML-export defect." It was neither Writer's nor a defect —
it was the same omission class as -r3's own, one library over:

  • registry/writer.xcd routes the MS Word 2007 XML filter to
    com.sun.star.comp.Writer.WriterFilter. On an export descriptor that implementation does
    exactly one thing: createInstance("com.sun.star.comp.Writer.DocxExport")
    (sw/source/writerfilter/filter/WriterFilter.cxx).
  • services/services.rdb places com.sun.star.comp.Writer.DocxExport (and
    com.sun.star.comp.Writer.RtfExport) in $LO_LIB_DIR/libmswordlo.dylibabsent from -r2/
    -r3's Frameworks/
    , because the UNO service manager dlopens it by name at export time.
    It is not a link-time dependency of anything, so neither the closure recipe's
    DYLD_PRINT_LIBRARIES trace (an import + tile-paint workload) nor its one-level otool -L
    safety net could ever have seen it.
  • 0xc10 was never evidence of a failed write: SfxBaseModel::impl_store synthesises
    ERRCODE_IO_CANTWRITE whenever storing returns false having set no error of its own
    (sfx2/source/doc/sfxbasemodel.cxx, "Storing has failed, no error is set!"), which is exactly
    how a missing export service presents.

Verified before packaging (a standalone LOK harness against product-set + this one dylib, nothing
else changed): gate.docx.docx and gate.odt.docx both now save real, complete
WordprocessingML packages whose text survives the round trip (the two directions together rule out
a fixture-specific effect); gate.xlsx, gate.pptx and gate.ods are unaffected. Also verified
with the same harness that the legacy-binary import behaviour is unchangedlibmswordlo also
carries Writer's WW8 (.doc) importer, and it makes no difference here, because the four
FormatDetector service libraries remain intentionally out of this trim, so content detection never
selects a binary filter.

This file was NOT rebuilt: it is a verbatim cp -pP from the identical core/instdir/ every other
dylib already came from, re-scanned for privacy independently rather than assumed clean by
inheritance. Its install-name/link shape was verified rather than patched — the same fixed-width
@__…OOO/<name> LC_ID placeholder its siblings carry, @loader_path/-relative dependencies that
are all already inside the kept set, and the same adhoc, linker-signed / TeamIdentifier=not set
posture. No install_name_tool run was needed or performed.

Engine-wise, nothing else changed, and this was re-measured rather than inherited: all six format
fixtures were re-rendered against this asset's own product-set (raw SHA-256 of the paintTile
output at the pinned tile geometry) and every hash matches -r3/-r2/the original build exactly.
Adding one dylib changes zero pixels — a filter library only ever dlopen'd on the export path
cannot affect what paintTile draws.

Contents

  • product-set/ — the runtime closure: Frameworks/ (68 of 248 possible dylibs — -r3's set plus
    this release's one added file) + Resources/ (LibreOffice's config/UI-resource tree, shipped
    whole, unchanged).
  • LICENSES/ — per-upstream-project license texts, plus MANIFEST.md (updated: 68 dylibs; the new
    file is the same already-covered libreoffice-core module/license, no new upstream project).
  • VERSION-PIN — the exact configure flags, commit, build facts an embedder needs, the R4 ADDENDUM
    documenting the change above in full, and the six-fixture pixel-hash pins (values unchanged,
    and re-verified against this asset before upload).

Using this

Ships adhoc/linker-signed, as LibreOffice's own build produces it — this tarball does not sign
or notarize anything. An embedding application is responsible for re-signing these dylibs with its
own Developer ID identity (and hardened runtime, if applicable) at its own build time — Norma's own
embed phase does this, counting Mach-Os dynamically rather than assuming a fixed number, so the 68th
dylib needs no build-script change.

See VERSION-PIN inside the archive for the dlopen entry point, the required _Exit(0) teardown
pattern, and the fontconfig caveat — all unchanged.

Privacy scan — exact command and full result

Reused this repo's own local-only identity guard (the same mechanism scripts/release.ts's §11b
publish gate uses for app releases) — ~/norma-private/git-hooks/name-guard.sh artifacts <path>,
patterns not reproduced here since this file ships inside a public release (the guard is deliberately
local-only, outside every repository, for exactly that reason).

Scanned separately, before compression:

  • The added dylib alone (libmswordlo.dylib): clean.
  • product-set/Frameworks/ whole (all 68 dylibs): clean.
  • product-set/Resources/ minus one already-known, byte-verified-unchanged file
    (liblangtag/language-subtag-registry.xml — IANA's language-subtag registry, whose one match is a
    real registered language name, a natural-language collision and not an identity leak; this exact
    file is already a standing exclusion in this repo's own release-lib.ts NAME_SCAN_EXCLUSIONS
    for the identical reason): clean.
  • LICENSES/: clean.
  • VERSION-PIN: clean.
  • The final, uncompressed .tar (owner-suppressed, tar --uid 0 --gid 0 --uname '' --gname '',
    verified with tar tvf): exactly one hit, independently verified byte-for-byte to be the same
    IANA registry collision above — not a new leak, not identity-bearing.
  • The .tar.zst was verified by decompression round-trip (SHA-256-identical to the already-scanned
    .tar), not re-scanned directly — compression would hide any string from a byte scan the same way
    it would for a .zip/.dmg, so the meaningful gate is the uncompressed archive.

Zero identity hits anywhere in this asset.

vendor-libreoffice-20260822 (headless LibreOffice, macOS arm64, r3)

Choose a tag to compare

Prebuilt, privacy-scrubbed headless LibreOffice engine for macOS arm64 — vendored dependency for
the Norma app, not an app release itself (--latest=false; does not affect the app's release
lineage or its Sparkle appcast).

What this is

A native macOS arm64 build of LibreOffice/core @ 11482c8f71bc76ed6260bc03b1576a52a788ab4f
with --enable-headless (the svp/headless VCL backend — the same shape LibreOffice's own iOS
port uses). Same commit, same configure flags, same build as -r2 — this asset changes only the
two items below. Zero source patches anywhere in this build.

Why -r3

Two disclosed changes on top of -r2, both from the same already-built core/instdir/ (no
rebuild):

  1. The OOXML export fix. -r2's saveAs to .xlsx crashed the whole helper process —
    libuno_sal.dylib.3's text-encoding subsystem lazily dlopens libsal_textenclo.dylib by
    name the first time a full charset lookup is needed (e.g. an Excel font record's Windows
    charset ID), and abort()s when the load fails. That dylib is absent from -r2's 66-dylib
    Frameworks/ because it is reached only through a runtime dlopen, never a link-time
    dependency — -r2's closure recipe (a DYLD_PRINT_LIBRARIES trace of an import+paint-only
    workload, plus a one-level otool -L safety net) had no way to see it. -r3 adds this one
    file — a verbatim cp -pP from the identical instdir every other dylib already came from,
    re-scanned for privacy independently, not assumed clean by inheritance. Verified before
    packaging (a standalone LOK harness, product-set + this one dylib, nothing else changed):
    gate.xlsx now saves successfully (real output file, clean exit); gate.pptx is unaffected
    (already worked, still works). gate.docx still does not save — the missing-dylib abort is
    gone (no crash, reproduced on two independent fresh profiles), but a different, still-open
    Writer/OOXML-export defect surfaces instead: a clean, caught SVSTREAM_WRITE_ERROR
    (ERRCODE_IO_CANTWRITE) inside SfxBaseModel::impl_store. Unrelated to the charset-table gap
    this asset fixes; disclosed, not chased further here.

  2. A tar-container privacy fix -r2 didn't have. Measured directly against the live,
    currently-published -r2 asset (cold-downloaded, SHA-256-matched to its pin): the tarball's own
    per-entry headers record the packaging account's macOS username and primary group, via
    bsdtar's default owner-name recording — independent of, and not caught by, -r2's own
    file-content byte-scan (which read extracted file bytes, never the tar's own header bytes).
    -r3's tar is built with explicit owner/group suppression (tar --uid 0 --gid 0 --uname '' --gname ''); see the Privacy scan section below for the verification. The live -r2 asset was
    not modified or re-uploaded — a GitHub release asset is maintainer-replaceable at the same
    URL, and re-publishing scrubbed bytes under the same name is exactly the silent-swap hazard this
    repo's own fetch-libreoffice.ts header warns against. Flagged here as an open item for whoever
    owns this asset's lifecycle to consider once -r3 is the pinned, fetched asset.

Engine-wise, nothing else changed: all six format fixtures render pixel-identical (raw SHA-256 of
the paintTile output) to -r2/the original build. Adding one dylib and fixing tar metadata
changes zero pixels.

Contents

  • product-set/ — the runtime closure: Frameworks/ (67 of 248 possible dylibs — -r2's trim
    plus this release's one added file) + Resources/ (LibreOffice's config/UI-resource tree,
    shipped whole, unchanged from -r2).
  • LICENSES/ — per-upstream-project license texts, plus MANIFEST.md (updated: 67 dylibs, the
    new file is the same already-covered libreoffice-core module/license, no new upstream
    project).
  • VERSION-PIN — the exact configure flags, commit, build facts an embedder needs, the R3
    ADDENDUM documenting both changes above in full (including the verified install-name/link shape
    of the added dylib — matches its siblings, no patching needed), and the six-fixture pixel-hash
    pins (unchanged from -r2).

Using this

Ships adhoc/linker-signed, as LibreOffice's own build produces it — this tarball does not sign
or notarize anything. An embedding application is responsible for re-signing these dylibs with its
own Developer ID identity (and hardened runtime, if applicable) at its own build time — Norma's own
embed phase does this, counting Mach-Os dynamically rather than assuming a fixed number, so the
67th dylib needs no build-script change.

See VERSION-PIN inside the archive for the dlopen entry point, the required _Exit(0) teardown
pattern, and the fontconfig caveat — all unchanged from -r2.

Privacy scan — exact command and full result

Reused this repo's own local-only identity guard (the same mechanism scripts/release.ts's §11b
publish gate uses for app releases) — ~/norma-private/git-hooks/name-guard.sh artifacts <path>,
patterns not reproduced here since this file ships inside a public release (the guard is deliberately
local-only, outside every repository, for exactly that reason).

Scanned separately, before compression:

  • The added dylib alone (libsal_textenclo.dylib): clean.
  • product-set/Frameworks/ whole (all 67 dylibs): clean.
  • product-set/Resources/ minus one already-known, byte-verified-unchanged-from--r2 file
    (liblangtag/language-subtag-registry.xml, IANA's language-subtag registry — a natural-language
    collision, <description>Como Karim</description>, a real registered language name (ISO 639-3
    cfg), not an identity leak; this exact file is already a standing exclusion in this repo's own
    release-lib.ts NAME_SCAN_EXCLUSIONS for the identical reason): clean.
  • LICENSES/: clean.
  • VERSION-PIN: clean.
  • The final, uncompressed .tar (owner-suppressed): exactly one hit, independently verified
    byte-for-byte to be the same IANA registry collision above (single match, same description
    string, same file) — not a new leak, not identity-bearing.
  • The .tar.zst was verified by decompression round-trip (SHA-256-identical to the already-scanned
    .tar), not re-scanned directly — compression would hide any string from a byte scan the same
    way it would for a .zip/.dmg, so the meaningful gate is the uncompressed archive.

Zero identity hits anywhere in this asset.

Norma 0.2.013

Choose a tag to compare

@HeavenllyDemon HeavenllyDemon released this 18 Aug 10:22

Norma 0.2.013

Signed Sparkle appcast entry: releases/appcast.xml.

vendor-libreoffice-20260819 (headless LibreOffice, macOS arm64, r2)

Choose a tag to compare

RETIRED — superseded by r3 (vendor-libreoffice-20260822).

The r2 asset has been removed from this release. Its tarball container metadata
recorded the packaging account's identity (the file contents were clean; the
container was the gap). r3 is a straight re-cut from the same pinned upstream
commit with that gap closed, plus one dylib restored so OOXML export works.

Nothing depends on this asset: the vendor fetch pins r3, and no shipped release
of the app ever embedded the office engine.

This release is kept as a provenance record only.

Norma 0.2.012

Choose a tag to compare

@HeavenllyDemon HeavenllyDemon released this 15 Aug 10:19

Norma 0.2.012

Signed Sparkle appcast entry: releases/appcast.xml.

Norma 0.2.011

Choose a tag to compare

@HeavenllyDemon HeavenllyDemon released this 13 Aug 20:55

Norma 0.2.011

Signed Sparkle appcast entry: releases/appcast.xml.

Norma 0.2.010

Choose a tag to compare

@HeavenllyDemon HeavenllyDemon released this 06 Aug 15:32

Norma 0.2.010

Signed Sparkle appcast entry: releases/appcast.xml.

Norma 0.2.009

Choose a tag to compare

@HeavenllyDemon HeavenllyDemon released this 06 Aug 14:29

Norma 0.2.009

Signed Sparkle appcast entry: releases/appcast.xml.

Norma 0.2.008

Choose a tag to compare

@HeavenllyDemon HeavenllyDemon released this 29 Jul 04:33

Norma 0.2.008

Signed Sparkle appcast entry: releases/appcast.xml.

Norma 0.2.007

Choose a tag to compare

@HeavenllyDemon HeavenllyDemon released this 25 Jul 23:43

Norma 0.2.007

Signed Sparkle appcast entry: releases/appcast.xml.