Skip to content

0.23.0: a file that ends clangd costs the session that file, the session keeps a reserve of engine starts (#86), and code actions reach the editor (#89) - #88

Merged
Sunrisepeak merged 12 commits into
mainfrom
fix/issue-86-engine-exits
Nov 13, 2026
Merged

Sunrisepeak merged 12 commits into
mainfrom
fix/issue-86-engine-exits

Conversation

@Sunrisepeak

@Sunrisepeak Sunrisepeak commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Server side of #86 after 0.22.0 — implements .agents/docs/2026-11-12-issue-86-engine-trap-and-start-budget-design.md; the split, the order across repositories and what changed while implementing are in .agents/docs/2026-11-12-issue-86-implementation-plan.md.

Companions: Sunrisepeak/mcppls-clangd#22 (the engine: the trap itself, 23.1.0-mcppls.11) and #23 (issue 89: the image links clangd's refactorings), tested here as the candidate and released as v0.0.23 (23.1.0-mcppls.12), which the lock now pins (the candidate file is gone); mcpplibs/openkal-windows#47 (merged, 0.22.0: one identity for a file, grant slots returned).

What the reports showed, and what changes

0.22.0 this PR
the exit exitCode: -1, "clangd exited unexpectedly" clangd ended by an illegal instruction (0xC000001D) while building src/ui/monitor_view.cppm; exitCode, exitCondition, endedByEnvironment; the runner's fault block (Linux, macOS) as exception + stack
who is set aside files of unanswered requests and edits of the last 10 s (main.cpp) the file whose AST build was in flight; the only one → at the first exit; several or none → a strike each; ended from outside → nobody
how it comes back on an edit, on "modules built again" (by the restart), in every new session a crash ledger in the workspace cache: one retry per term (2, 4, 8, 16 min, 1 h, 1 d); unchanged is not eligible after the second exit; Restart clangd tries again; a build that survives clears it
the grant table restarts until the start is refused, "33 engine starts" (17), nothing in the log counted; automatic restarts stop at a reserve of 3 starts (engine-paused); the refusal is logged, says the true count and offers Restart Server

Also: Workspace::serve_kept finished its job after detaching the engines' requests — a clangd between an exit and its restart answered the detachment at once as cancelled, the editor got cancelled instead of the kept answer and the job was written to after it was erased (SIGSEGV under gdb; found by the new fixture). build.dirty no longer counts mcpp.lock; the kit line says when its target is the host's default.

Tests

  • tests/unit/test_exits.cpp: conditions (NTSTATUS, signals), builds in flight, suspects, the ledger's rules and its file, the budget's arithmetic (the report's 16×4 and CI's 21×3), the runner's fault lines.
  • tests/unit/test_server.cpp: the engine with a process that ends by a signal while one file's build is in flight — set aside at the first exit, across an edit and a new session, Restart clangd tries again and the term doubles; and the reserve — an automatic restart above it, paused inside it, the person's restart made.
  • conformance engine-trap (Linux, macOS): the payload's clangd ended by SIGTRAP whenever it builds src/trap.cppm; clangd-crash-closure under the ledger's rule.
  • conformance on windows-2025 (build 26100), where [engine-start-failed] clangd could not be started: granting C:/Program Files: out of memory #86's fault occurs and no row ran before: 74 of the 75 Windows cases. cmake-msvc-std stays on windows-2022 alone -- its own project does not build with that image's CMake 4.4.5 (plan §2.14).

Found while getting CI green (plan §2.13–2.19)

  • The engine candidate was named and not tested. Since the engine's run has one artifact (mcppls-clangd 0.0.21) the payload job looked for the part a directory deeper than download-artifact put it and assembled the payload from the lock's engine, silently; three runs here were green on 23.1.0-mcppls.10. The job now finds the part, prints the engine of every platform and fails when the payload does not carry the candidate's image; mcppls-devtools payload --candidate refuses to run without an engine. The runs since tested the candidates, and the last the released 23.1.0-mcppls.12.
  • Failures that were re-run, as this repository re-runs them: VS Code downloads timing out (proot, clean machine), macOS runners not assigned, and one failure each of mcpp-polling-watch-inputs@polling (windows-2025), mcpp-target-live (windows-2022) and verify-changes V5 in a stability round (darwin), each passing when run again.
  • macOS keeps the fewest engine starts under the reserve (its grant set is the widest); follow-up.

Local: mcpp test 625 cases green; engine-trap green against the 0.22.0 payload; mcppls-devtools check all green.

Not in this PR (plan §2, §5)

The platform pin (openkal-platform with openkal-windows ≥ 0.22.0), the runner's trap report on Windows (E2 layer 1), WA-CLANGD-015 (the stopgap; the engine ships with this release), windows-2025 rows for vscode-e2e / clean-machine / bench.

Sunrisepeak and others added 12 commits November 12, 2026 19:02
…session keeps a reserve of engine starts (#86)

The reports of #86 after 0.22.0: clangd.okb ended by 0xC000001D on Windows 11
24H2 on every module unit that includes a library header (fixed in the engine,
mcppls-clangd 0.0.22, tested here as a candidate), and the server turned that
into a loop that spent the sandbox's grant table.

- the exit keeps its number and its name (ExitCondition; no more -1);
- the suspect is the file whose build was in flight (ast-build events), set
  aside at the first exit when it is the only one; an end from outside names
  nobody;
- a crash ledger in the workspace's cache: one retry per term, whatever the
  reason; unchanged is not eligible after the second exit; a new session reads
  it; Restart clangd tries again;
- a start budget: automatic restarts stop at a reserve of three starts
  (paused); the refused start is logged, counted truly and offers Restart
  Server;
- the runner's fault report (okrun on Linux and macOS) is read into the exit;
- Workspace::serve_kept finishes the job before detaching engine requests (a
  use after free the engine-trap fixture found);
- D: lastExit.reproduce, fileIdentity, the payload's dirty stamp, the kit line;
- tests: exits unit cases, two engine cases with a process that ends by a
  signal, conformance engine-trap, clangd-crash-closure under the ledger's
  rule, a windows-2025 conformance row;
- series 0.23; packaging/engine-candidate.json names the engine PR's run.

Design: .agents/docs/2026-11-12-issue-86-engine-trap-and-start-budget-design.md
Plan:   .agents/docs/2026-11-12-issue-86-implementation-plan.md

Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
…ap's second session says so in its status

A file set aside on the guess (asked about or edited lately, and clangd ended
twice with nothing in flight) keeps the short term and the way back on an edit
it had before: the ledger's long terms across sessions are for a file clangd
named or was building.

A new session with a ledger-held file open is degraded at once, with
file-ended-engine: the fixture asserts that instead of ready.

Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
…sks its CMake for its import std gate; the candidate is the engine PR's head

- tests/unit: the engine trap case expected SIGILL on every host; on Windows the same fault is 0xC000001D.
- ci: windows-2025 ships CMake 4.4 where windows-2022 has 3.31.6, and cmake-msvc-std pins the gate of the
  latter's experimental import std. The row asks the image's CMake which known gate is its own.
- engine: a build is over when its diagnostics come, whoever they are for (a prime unit too).
- packaging/engine-candidate.json: mcppls-clangd run 43198727766, commit 9c5b935 (the PR's head).
- plan: the budget counts a workspace's own starts; windows-2025's CMake.
… is another toolchain

windows-2025 has CMake 4.4.5 and MSVC 14.51. The fixture's own project is written for CMake 3.31.6's
experimental import std: the gate is another UUID there, and with the right one CMake 4.4.5 builds the
standard module's library and leaves it off the program's link line (LNK2001). That is the fixture's
prepare, before any server runs. The probe of the gate goes again; 74 of the row's 75 cases run.
… is red

The engine's run has one artifact since mcppls-clangd 0.0.21 (clangd-openkal), and download-artifact puts one
match straight into its path: the payload job looked for the archive in candidate/clangd-openkal, found no
part, and assembled the payload from the lock's engine under --candidate, without a word. This pull request's
runs so far tested 23.1.0-mcppls.10 (the status of a conformance case said so: 15 features).

- the archive is looked for wherever the artifact put it; no part with a candidate named stops the job;
  the job prints the engine of every platform and checks the payload carries the candidate's image;
- mcppls-devtools payload --candidate refuses to run with no --clangd;
- the candidate is the engine pull request's head (run 43213696250, c3669bd);
- the changelog says which conformance case the 26100 row leaves out.
…release doc in Chinese says what the payload job checks
…ppls-clangd's PR 23, whose image links clangd's refactorings; conformance code-actions carries each one out; mtest 0.6.3

The bundled engine's image was linked from clangd's libraries alone and offered no refactoring; the server
passed on the empty list. The runner answers workspace/applyEdit and its check code-action does what an
editor does with an action (the literal's edit, or its command and the edit the server then asks for). The
fixture asks on a class's name, a selected expression and auto, in a source file and a module unit.
…gine candidate is PR 23's present head

stability (linux-x64, 1 of 2) failed twice at the first round of mcpp-split: query symbol hello::count answered
in about 3 s without the definition, where the two later rounds and the run before answered in 4.5 s with it.
The check reported the expectation alone. It now reports the command's output (provenance, snapshot, the
symbol) and what it wrote to standard error, so a run that fails there says which answer was short.

packaging/engine-candidate.json names mcppls-clangd run 43288717890 (e6b4756): the same engine inputs, with
the code-actions case that finds a refactoring by its identifier.

Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
…n progress report

query symbol answered without the definition, and query refs with "no symbol named", when the query's
own start was slow enough for the workspace to report it ($/progress, token mcppls/<root>): the kernel's
sink counted every progress report as the engine's, so settle_index took the server's "loading" for the
index begun and ended, skipped opening a unit, and asked workspace/symbol of a clangd that had not read its
database. The answer was the module index's alone: the declaration.

Reproduced here by a first query beside a session that had just begun (3 of 3 without the definition in
2.7 s; 4 of 4 with it in 6 s after the change), and it is what stability's first round on a fresh runner
showed twice (3 s instead of 4.5 s, no definition).

- orchestrator.client: status_progress_token / is_status_progress_token, the one definition the workspace
  writes its token by and the kernel tells it by; unit test in test_server.
- kernel: the sink counts an engine's reports only.

Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
@Sunrisepeak Sunrisepeak changed the title 0.23.0: a file that ends clangd costs the session that file, and the session keeps a reserve of engine starts (#86) 0.23.0: a file that ends clangd costs the session that file, the session keeps a reserve of engine starts (#86), and code actions reach the editor (#89) Nov 13, 2026
@Sunrisepeak
Sunrisepeak merged commit 3eeea44 into main Nov 13, 2026
168 of 170 checks 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