Rename design r2, "Selector scopes and parser matrix", case2-install row. --org/--business
and --org-file/--business-file are two families, each its own scope: each spelling once, and
a second spelling must carry the same text (file paths compared as given). Missing values
are usage; a flag-shaped or invalid id keeps the business-id refusal; a flag-shaped file, a
repeated spelling and a conflict say why. All exit 4 before anything is read or written.
The persona-import call it spawns still passes --business.
Rename design r2, "Selector scopes and parser matrix". case2-persona-import.mjs takes --org
through selectorScope and case2-precheck.sh through scripts/selector.sh, one scope each. Both
keep their exit codes and their old business-id wording; a repeated or conflicting selector
says why. persona-import now checks the id while parsing, so stage refuses an invalid
selector before it reads anything.
The case2-install fake stack copy carries packages/business/src/selector.mjs, which the real
copy already does (COPY_PATHS takes packages/business/src).
Rename design r2, "Selector scopes and parser matrix". packages/business/src/selector.mjs
and scripts/selector.sh carry one rule set: in a parser's scope each spelling appears once,
and a second spelling must carry exactly the same value; a repeated spelling, a missing or
flag-shaped value, an invalid id and unequal values refuse. The file family
(--business-file/--org-file) compares paths as given.
Every CLI parser that took --business now takes --org through orgSelector, and the old
global --org rewrite in main() is gone, so a value another option consumes is never read as
a selector. The id is checked while parsing (OrgError org-invalid, exit 3), so grants admin
set no longer reads the token and proxy init no longer prompts for the key before an
invalid id refuses. access gains the same local id check.
mosaic console start --dev-local-owner --dev-insecure-bind ADDR
--dev-allow-host NAME[,NAME...] binds 0.0.0.0 or an IPv4 address and
answers only NAME:<bound port> plus the loopback names. Both flags are
refused without the dev owner, the bind without an allowed name, and a
specific ADDR that is not itself a name. Start and console status print
the no-sign-in warning; the state file records bind and allowHosts.
serve.mjs takes devAllowHosts only with the dev owner; SSO, preview and
tester listeners stay loopback. Writes need Origin http://<same Host>.
Chromium sends no Fetch Metadata from a LAN http origin, so for an
allowed name a write with that exact Origin and no Sec-Fetch-Site counts
as same-origin; an explicit header is still judged by the routes.
chat.js builds its operation keys without crypto.randomUUID, which an
insecure context lacks.
The endpoint ended after MOSAIC_FIXTURE_TTL_S, but init passed it only PATH, so
the lifetime was always the 14400 s default. Its record stayed after it ended,
and init refused fixture-exists until `dev fixture stop`.
init now takes --ttl SECONDS (0 = no expiry; otherwise 60 to 2147483, the
longest delay a Node timer holds; the default stays 14400), passes it to the
endpoint, and records ttlSeconds and expiresAt. /health and status report them.
A record whose pid is no longer the endpoint is stale: init removes it and says
which pid it replaced. A live endpoint still refuses fixture-exists.
A running bus keeps the endpoint it read at start, so after a replacement
the bus needs a restart; --ttl 0 avoids the expiry in the first place.
On a deploy tree node_modules is a symlink. .gitignore's node_modules/
matches only a directory, so git ls-files -co --exclude-standard lists
the link as an untracked file and the fixtures' cpSync throws EISDIR
on it (8 failures in pinned-copy.test.mjs). stack-copy.sh never takes
node_modules from git (it archives COPY_PATHS and runs npm ci), so the
fixtures now exclude **/node_modules from the listing. The copy code is
unchanged.
- A Console is stale only when its pid is gone or its start time differs. A live Console
started from another entry path is never quarantined; stop refuses to signal it and
names the path it was started from.
- The lock-clear fence records the clearer's pid and start time. A fence left by a dead
clearer is moved aside and recovery continues; a live or unreadable fence refuses.
lock show reports a fence.
- Console state is moved aside with one atomic rename after an inode re-check.
console start and stop move a console.json whose recorded process is gone
aside instead of refusing (P19 #857). mosaic org lock show|clear reports a
lifecycle lock holder and clears it only when the holder is dead.
mosaic bus recover marks a bus host stopped when its process is gone and its
socket does not answer, and writes a recovery receipt (P19 #862).
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.
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.
Read-only: finds a thread's launch and end records in the organization launch log and checks each run's session.json, bundle manifest digests and turn stderr files.
Starts the fixture provider's loopback endpoint for a named dev instance and records it under the data root. Refuses the default instance, a configured proxy, provider credentials in the environment, a non-loopback bind and a second fixture. fixtureLauncherOptions hands the endpoint to the launcher as its session proxy context.
A click on the test Console's Resume button opened window.confirm and the
browser daemon hung: the mouse release, screenshots and the frame tree all
block until the dialog is answered, and ui-browser had no way to answer it.
A click that opens a dialog now returns {dialog:{type,message}}. The new
command `dialog accept|dismiss` answers it and records the type, message
and answer in the receipt. While a dialog is open other commands except
stop refuse (journaled), and no screenshot or URL check is attempted.
A real-Chromium confirm test covers accept, dismiss and the refusals.