serve.mjs keeps the bound address as well as the port, so the settings,
queue and business routes answer a request that arrives after close().
browser.mjs keeps an exited leader's group tracked until it is killed at
exit, and close() signals the group only while the leader is alive. The
late-request test is event-based with one owned timeout. New test: the
chromium group dies when the main process dies and close() never runs.
Webui browser and server files (92, pinned-copy excluded): 741 pass, 0 fail.
- serve.mjs read server.address().port in the Host checks. Once close() starts that is
null, so a request on a kept-alive connection threw and was never answered, and the test
file waited forever. The bound port is now stored on 'listening'.
- Killing only chromium's main process left its renderer and GPU children writing into the
profile, so the profile rm failed with ENOTEMPTY. Chromium now runs in its own process
group; close() and the exit hook kill the group, and the rm retries.
- teardown.test.mjs: a request sent after close() starts gets a 200.
Combined node --test runs hung in the org browser files. Two causes:
- org-quick: a page's GET /api/config reached the server on a
kept-alive connection after close(server) had stopped the listener.
The handler threw on server.address().port, the request was never
answered, and server.close() waited for it forever. close() in
fixture.mjs now cuts every connection and fails the hook after 5 s
with a message.
- org-delete: t.after hooks run in registration order, so the data
directory was removed while the server still wrote there. The rm
failed with ENOTEMPTY, node:test skipped the later hooks, and the
open server and chromium kept the file running. The three org files
and project-archive-style now register the removal last.
browser.mjs: close() kills a browser that does not answer
Browser.close within 5 s, a call to an exited browser fails at once,
and an unclosed chromium no longer holds the event loop and is killed
when the test process exits.
teardown.test.mjs reproduces each case: 0/4 pass on the old helpers,
4/4 on the new ones.
mosaic org delete ID --confirm ID --if-revision N, and POST /api/orgs/:id/delete,
mark the organization as deleting, stop its bus, move its files into
<dataRoot>/deleted/<ID>-<stamp>/ with a receipt, then drop it from the registry
and append deleted.log. A failure stops at its step and a rerun resumes. Bus
start refuses an organization that is being deleted. The settings page asks
twice: a panel that lists the effects, then typing the ID before Delete
permanently is enabled. Purge and remote revocation are follow-ups.
Quick Setup made organization code import the plug-in loader, which loads
packages/plugins/<kind>/<name>/index.mjs by a computed path. The scanner now
allows exactly that form in the loader file and still refuses it anywhere else.
A 200 or 201 with a body that does not name the expected step as done now
stops at that step as an unknown outcome, with no further writes. Starting a
new draft re-enables the preset, thinking and run controls and clears the
risk checkbox. Browser regression covers both (Sol review P1, P2).
The dev fixture guard was instance-wide: once a fixture record existed,
every organization's bus start refused when a provider credential was in
the environment. One instance could not hold a fixture organization and a
real-model organization side by side.
Bus start now reads the organization file. An organization that does not
route a launch to the fixture launches as configured. A fixture
organization's launch environment drops provider credentials before the
guard runs.
Settings marked every page except appearance and business read only when
send was off. Organization mode always turns send off, so the read-only
style hid New organization and Save organization. Organizations now stays
writable when the server allows org setup. The browser test asserts both
buttons are visible, not only clickable.