Repository navigation
mcpp-language-server 0.0.12: the maintained mcppls-clangd engine, mcpp formatting, crash recovery, linux-arm64 again - #46
Draft
Sunrisepeak wants to merge 17 commits into
Draft
Sunrisepeak wants to merge 17 commits into
Sunrisepeak wants to merge 17 commits into
Conversation
This was referenced Oct 6, 2026
…h recovery, save planning The product side of the 0.0.12 joint work with mcppls-clangd, without the raw evidence it produced (that is in the evidence-0.0.12 archive): - a payload binds its engine's immutable identity (payload version 4, engine.json: version, LLVM base and commit, fork commit, patch-series digest, platform, binary SHA-256, features), verified at assembly and at startup; a maintained engine selects the kit of its LLVM base, and workarounds retire only for a capability the verified identity declares - format.fallbackStyle: without a project .clang-format, an mcpp project gets the pinned mcpp style when the bundled engine declares it - VS Code: a server exiting during initialize, or a failed protocol write, settles the client before a fresh one starts (WA-VSCODE-003/004); recovery shares the manual lifecycle queue and the crash budget; the log path is learned from stderr before a report can be interrupted - a body save whose disk and draft module structure the plan already covers does not schedule another whole-project plan - the model gateway's initialize has its own bounded deadline - Darwin pipes to children are protected from SIGPIPE per descriptor - CI keeps bounded timing and stability diagnostics for native runs
…taken as built, save planning holds on aliased paths - linux-arm64 returns to the lock, the release manifest, the extension and every CI matrix: its removal was a scope decision with no technical failure behind it, and the maintained engine is built for it at the Ubuntu 20.04 floor (glibc 2.31 instead of LLVM's own build's 2.34). - mcppls.pack.clangd takes a maintained engine part (mcppls-clangd's clangd-<version>-<platform>.tar.gz, whose clangd/ holds engine.json) byte for byte: no strip, no thinning, no re-signing, so the identity the payload verifies names the bytes it ships. - test_save_plan failed on macOS and Windows only: its hand-built model named files under the raw temporary directory while the workspace resolves a document's URI canonically, as a loaded model does (/var is /private/var, Windows may hand out a short name). Reproduced on Linux with a symlinked TMPDIR (the same four assertions), fixed by giving the fixture the canonical root a loaded model has. - the default background-index priority applies on macOS only, the one host with evidence for it (Linux maps both priorities to SCHED_IDLE; Windows' background mode also lowers I/O priority, unmeasured for indexing). - format.fallbackStyle compares `auto` case-insensitively, like `mcpp`. - payload version 4 is a named constant shared by assembly and verification. - Intel macOS build scaffolding goes (its cross target, the __bzero stub, the Neovim bootstrap, the x86_64 SIGPIPE path); 0.0.11 never shipped it. - mcppls-devtools check tree: no tracked file above 1 MiB, none generated. - the xlings descriptors depend on the LLVM base of a maintained engine. - CHANGELOG 0.0.12, install floors (glibc 2.31, macOS 12), the part 3 plan and its record; the earlier status documents point at the evidence archive.
Sunrisepeak
force-pushed
the
release/0.0.12-joint
branch
from
October 9, 2026 07:03
0592ccd to
39a2b23
Compare
… not won in a polling race The server answers initialize within milliseconds, so finding it between its spawn and the client's start by polling the process table was a race; under PRoot on linux-x64 the poll lost it for a full minute. MCPPLS_SERVER, read at every start, now names a stand-in that waits three seconds before becoming the real server, so the test kills a process whose initialize is certainly unanswered, and the recovery it checks is unchanged. The format fallback line of the initialization options moves below the engine.workers comment it had split.
…fixes retire their workarounds Running the conformance fixtures against the maintained engine, which product CI had never done, showed where it speaks differently from stock clangd: - A failed prerequisite is reported per importing file, "Failed to build module prerequisites for <file>; due to module worker failed: <source>:...", naming the unit that failed rather than the module. The parser took "prerequisites for <file>" for a module name, so no module-failed diagnostic, closure containment or std kit fallback happened (module-faults). It now reads the importer and the failed unit, and the module is the one the plan gave that unit. - An import with no unit in the project is kept textual: "Keeping import of third-party module <name> textual; no module unit for it in this project". It is an unresolved module, as stock clangd's "Don't get the module unit" is, so it gets its stand-in (partial-scan-standins). - WA-CLANGD-001 and WA-CLANGD-010 retire for an engine whose verified identity declares module-directive-recovery and const-correctness-views, as WA-006 already did for module-directive-diagnostic-ranges. Conformance checks take "retired-by": a check watching a defect the payload's engine is proved free of holds and says why (workaround-canaries' 001 and 010, typing-import-spin's T2); against any other clangd it runs. Both log formats keep working for an external stock clangd.
packaging/payload.lock.json names mcppls-clangd v0.0.12's clangd-23.1.0-mcppls.0-<platform>.tar.gz for linux-x64, linux-arm64, darwin-arm64 and win32-x64 (each sha256 from two downloads and the digest the release publishes beside the asset); the stock clangd archives no platform names go, the kit sources stay. clangd-version and CLANGD_VERSION are 23.1.0-mcppls.0; the kit keeps the LLVM base, 23.1.0. The engine's identity declares module-directive-recovery, so the checks that watch WA-CLANGD-001 itself being on (typing-import T6) or its disk-side set-aside (typing-autosave T3) are retired-by it, as the canaries are.
…nd the scenario tests read its owned cache The first product CI run with mcppls-clangd bundled showed three more places where the product assumed stock clangd: - Under PRoot every process is traced call by call, and mcppls-clangd's supervised compiler worker is a process per module; with PROOT_NO_SECCOMP clangd was still preparing after 20 s. For a verified maintained engine under a detected sandbox the server passes --modules-builder-worker-policy=in-process (with the owned cache's payload bounds off, which need a worker), the upstream way. - mcppls-clangd's owned cache publishes every module file as .owned-payload-v1/generation-<slot>-<n>/payload.pcm. The scenario tests took a module file's unit from its directory and its module from its file name, so a warm start that reused all 111 xlings BMIs counted 135 rebuilds, SC4 found no std file and U11 nothing to truncate. An owned payload's unit is now the source its control block names, its module the one that source declares, and a new generation holding the bytes of a payload there was is a read copy, not a build. - In a module importer that was just opened, mcppls-clangd waits for the file's first preamble before it answers a completion (issue #50), where stock clangd answers at once without imported declarations. Typing checks with "firstOpenSeconds" now measure that wait on its own, with its own budget, and hold the typing after it to the unchanged budgets: ux-xlings U5 locally, first answer 6.1 s after opening, then p95 0.14 s (stock: 0.21 s).
… directive recovery too typing-import-spin's T2-crash-restarted is the Windows face of the defect T2 watches on Linux and macOS (clangd 23.1 crashes there instead of spinning); an engine that declares module-directive-recovery has neither.
…y when the engine says so again mcppls-clangd reports "Keeping import of third-party module <name> textual; no module unit for it in this project" both for a unit whose scan keeps failing (partial-scan-standins, reported at every attempt) and once while its provider index catches up with a database whose provider moved. Under PRoot the second came 7 s after the move, past DATABASE_REREAD, and typing-import's hello.greet got a stand-in that pushed greet.cppm out of the database and restarted clangd. For a module the plan gives a unit, a report is now taken only when repeated at least 2 s after the first (and the count starts again when its provider changes); a module the plan has no unit for is taken at once, as before.
…f is not primed again module_already_built_ found a BMI only in stock clangd's layout, <source>-<hash>/<command>/<module>.pcm, so with mcppls-clangd bundled every warm start primed all of a project's modules again: on four cores, xlings' first ready took 14.1 s against stock clangd's 7.2 s, and every importer's prerequisites queued behind the 111 prime units (completion p95 at the 1 s budget, recovery after a kill over 25 s on CI). An owned payload's unit is the first source path its control block names; the units the owned cache keeps are read once per plan, as the stock listing is, and the command check from module-builds.json is unchanged. On four cores the warm start is now ready in 3.0 s and typing completion p95 is 0.23 s (stock clangd: 7.2 s, 0.19 s).
…23.1 workarounds follow its features
…o stand-ins for importers and sets no file aside for one (WA-CLANGD-013)
…ested before the engine is released
…ound and how each gap closed
…, for answers, latency while typing, crashes and stalls
…ack, and a probe's syntax error outside the workspace is no project issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
mcpp-language-server 0.0.12 bundles the maintained engine, mcppls-clangd 0.0.12 (LLVM 23.1.0 + 25 patches for C++ modules), on linux-x64, linux-arm64, darwin-arm64 and win32-x64.
What changed
Engine and payload
engine.json). Both assembly and the server verify it before trusting the engine's declared capabilities.mcppls.pack.clangdtakes a maintained engine part byte for byte: no strip, no thinning, no re-signing.23.1.0-mcppls.0.Editing
mcppls.format.fallbackStyle: without a project.clang-format, an mcpp project formats in the pinned mcpp style.VS Code
Save planning
test_save_planfailed only on macOS and Windows. Root cause: the hand-built test model used the raw temporary directory, while the workspace resolves documents canonically, as a loaded model does (/var→/private/var). Reproduced on Linux with a symlinkedTMPDIR(the same four assertions failed) and fixed.Platforms
Smaller changes
format.fallbackStylematchesautocase-insensitively.mcppls-devtools check treekeeps raw evidence and caches out of the tree.Evidence
Raw evidence from the joint work (Part 2 performance, VS Code, crash and resource runs) is in
mcpp-language-server-0.0.12-evidence.tar.zston theevidence-0.0.12release. The full incremental history is kept in thearchive/0.0.12-jointbranch. The plan and its record are in.agents/docs/2026-10-09-0.0.12-part3-convergence-plan.md.Companion engine PR: Sunrisepeak/mcppls-clangd#2