Skip to content

deps: PhoenixmlDb.Xslt 2.5.1 -> 2.7.0 - #49

Merged
elvogel merged 3 commits into
mainfrom
deps/engine-2.7.0
Oct 8, 2026
Merged

elvogel merged 3 commits into
mainfrom
deps/engine-2.7.0

Conversation

@elvogel

@elvogel elvogel commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Takes PhoenixmlDb.Xslt 2.7.0 (with XQuery 2.7.0 and Core 2.2.0), and brings two documents back
into line with what is actually on main.

Why 2.7.0 and not 2.6.0

2.7.0 is the first release that answers both published advisories:

Advisory Affected Patched
GHSA-86rg-wxgp-9p5j < 2.5.1 2.5.1
GHSA-h2xc-4m53-6j8r <= 2.5.1 — the version 0.2.5 shipped 2.6.0
GHSA-xxjq-rwpx-m5ww <= 2.6.0 2.7.0

This supersedes #47, which stopped at 2.6.0 and would have left the second one open.

It is not the performance release it was held for. Nothing in the 9 XSLT commits, ~30 XQuery
commits or 2 Core commits between the tags is performance work; the bulk is schema-aware typing,
plus security limits and correctness fixes.

Verification

Protocol fixed in advance on #47, and followed:

Step Result
Pin committed before any measurement ef38dde; nothing measured from a dirty tree
Resolved versions, from docmd.deps.json Xslt 2.7.0, XQuery 2.7.0, Core 2.2.0
Loaded assembly asserted at runtime, per arm 2.7.0+abad2d4…, aborts on mismatch
Release build 0 warnings, 0 errors
Full suite 383 total, 0 failed, 1 skipped (needs DOCMD_CORPUS)
All 13 corpus documents, 2.5.1 vs 2.7.0 byte-identical — diff -r reports nothing, 2,087,892 bytes each side

Byte-identical output makes the coverage oracle redundant here: identical bytes are identical
coverage.

Performance: 3.8% faster than shipped, 5.4% slower than 2.6.0

Transform time only, in-process, 13 corpus documents, minimum of 5 runs each. All three engines
built into separate worktrees with their own benchmark projects, so no arm could borrow
another's assembly.

Engine Corpus total Largest document Allocated Peak working set
2.5.1 212,828 ms 41,874 ms 5,296 MiB 2,416 MiB
2.6.0 194,280 ms 38,356 ms 5,062 MiB 2,860 MiB
2.7.0 204,756 ms 40,716 ms 5,064 MiB 2,481 MiB

The regression against 2.6.0 is real, not noise: 12 of 13 documents are slower, the thirteenth is
18 paragraphs and 80 ms, and the per-run ranges do not overlap (2.6.0 38,356–39,089 ms; 2.7.0
40,716–40,994 ms). Allocations match 2.6.0 to within 0.1%, so the cost is compute, not garbage.
docmd configures no SchemaProvider, so the schema-aware typing is work it pays for and cannot
use. Filed upstream as phoenixmldb-xslt#319.

Peak working set is a single sample, not a minimum — read it as an indication only.

What this does not fix

--stylesheet compiles a caller's stylesheet and sets no RegexMatchTimeout. A catastrophically
backtracking pattern ran 91,227 ms to completion with a cancellation token that fired at
2 s; the same pattern stopped at 2,013 ms with RegexMatchTimeout set. Identical on 2.5.1
and 2.7.0 — a timeout nobody sets does not fire, whatever the engine does. Filed as #48 and
recorded as defect 4 in docs/deferred-work.md.

docmd's own stylesheet is not affected: cancelling a conversion of the largest corpus document
already works on 2.5.1 (requested at 500 ms, OperationCanceledException at 1,624 ms).

Second commit: documentation

160cdc9 is separable and touches no code. The changelog's Unreleased section was empty while
#37, #38 and #39 sat fixed on main, and docs/deferred-work.md still presented all three as
deferred with plans for work already done. It also corrects a count: the inline-wrapper half of
the dropped-text fix shipped unprotected for eight releases, v0.1.0 through v0.2.4, not three.

Not included

No version bump. Releasing is a separate decision, and the 2.6.0-to-2.7.0 trade is worth making
deliberately.

🤖 Generated with Claude Code

https://claude.ai/code/session_018wZEgtuzaZPswykiGEBxbz

Lucas Vogel and others added 2 commits October 7, 2026 19:27
2.7.0 patches GHSA-xxjq-rwpx-m5ww, and 2.6.0 before it patched
GHSA-h2xc-4m53-6j8r, which names 2.5.1 as affected. docmd compiles a
caller-supplied stylesheet when --stylesheet is given, so the limits
those advisories restore are ones docmd can reach.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wZEgtuzaZPswykiGEBxbz
…erifying 2.7.0

The changelog's Unreleased section was empty while three user-visible fixes sat on
main: a guarded integer cast, the four-column indent threshold, and ordered-list
continuation. deferred-work.md still presented all three as deferred, with
"Closes with:" plans for work already done.

Also corrects a count that was wrong: the inline-wrapper half of the dropped-text
fix shipped unprotected for eight releases, v0.1.0 through v0.2.4, not three.

New defect 4 is the one the 2.7.0 verification turned up. --stylesheet compiles a
caller's stylesheet and sets no RegexMatchTimeout, so a backtracking pattern runs
unbounded and cancelling does not stop it. Measured on both 2.5.1 and 2.7.0: the
token alone had no effect over 91 seconds, and a 2-second RegexMatchTimeout
stopped the same pattern at 2,013 ms. No pin bump closes this one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wZEgtuzaZPswykiGEBxbz
CI restores with --locked-mode, so the pin and the lock file have to move together;
without this the build fails NU1004 before compiling anything. An ordinary local
restore rewrites the lock files silently, which is why the first push missed them.

Only the three engine packages changed: Xslt and XQuery 2.5.1 -> 2.7.0, Core
2.0.0 -> 2.2.0. Nothing else drifted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wZEgtuzaZPswykiGEBxbz
@elvogel
elvogel merged commit 0cb5bc3 into main Oct 8, 2026
1 check passed
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.

1 participant