Skip to content

Rotate the capability path when the port moves - #47

Merged
takashi-matsuyama merged 1 commit into
mainfrom
fix/rotate-path-on-port-move
Aug 16, 2026
Merged

takashi-matsuyama merged 1 commit into
mainfrom
fix/rotate-path-on-port-move

Conversation

@takashi-matsuyama

Copy link
Copy Markdown
Member

Recovering from an "address in use" start failure kept the profile's capability
path so that a configuration the user had pasted would need only its port
updated. Reading the two config shapes we actually produce shows that property
does not exist:

  • a pasted URL names the port, so the move alone stops it naming this app's
    server, and the panel copies whole snippets — the same one line is re-copied
    either way;
  • a bridge entry names only the locator id, and the bridge reads port and
    path from the locator when it connects, so it keeps resolving across both.

So the path was being kept for nobody, while "address in use" is the one moment
the app knows another process held the port — and a client still configured with
the old URL goes on offering the path to whoever holds it now. Keeping it made
that disclosure a key that finds the new port; rotating makes it a dead path.
What is reachable through the path is schema metadata either way, never row data
(EGRESS.md item 10), so this is a metadata-confidentiality change, not an
integrity one.

The locator id is kept for the same reason the path is not: it is the profile's
identity in another application's config file, and the only thing here whose
survival a pasted configuration depends on.

Two statements the app makes about itself are corrected with the behaviour:

  • README said moving the port keeps the path "so a config you pasted stays
    valid" — false for a URL config, and misattributed for a bridge entry;
  • README described the note on an already-open config panel as saying the server
    is not running, when that panel names the port conflict instead.

Filed as #23, where the trade was left open as a product decision. Two of the
three options there are settled by this: the UI leg (option c) is already on
main, and rotating only on an observed foreign bind (option b) is not adopted
— EADDRINUSE carries no identity of the holder, and probing for one either
hands the real path to whoever is listening or is defeated by a squatter that
answers only paths it has already harvested.

Checks

test:unit 347/347, typecheck (tsc + svelte-check, 0 errors), lint,
build, check:treeshake, check:egress — all pass locally.

Negative controls for the new test: reverting to a kept path fails it, and
rotating the bridge id fails it.

An adversarial read of the diff found one false sentence in the README text
added here (a pasted URL described as having "stopped resolving anyway" — it
resolves, to whatever now holds the old port); that is fixed in this commit.

`move port` is the recovery from an "address in use" start failure, and it kept
the profile's capability path so that a configuration the user had pasted would
need only its port updated. That property does not exist. A pasted URL names
the port, so the move had already invalidated it, and the panel copies whole
snippets - the user re-copies the same one line either way. A bridge entry names
only the locator id and reads port and path from this app when it connects, so
it is unaffected by either change. Keeping the path was protecting nobody.

What it did cost is reach. "Address in use" is the one moment this app knows
another process held the port, and a client still configured with the old URL
goes on offering the path to whoever holds it now. With the path kept, what that
discloses is a key that finds the new port; rotated, it is a dead path. What is
reachable through it is schema metadata either way, never row data (EGRESS.md
item 10), so this is a metadata-confidentiality change and not an integrity one.

The locator id is kept for the same reason the path is not: it is the profile's
identity in another application's config file, and the only thing here whose
survival a pasted configuration depends on.

Two statements the app makes about itself went with the behaviour. README said
moving the port keeps the path "so a config you pasted stays valid", which was
false for a URL config and misattributed for a bridge entry, and it described
the note on an already-open config panel as saying the server is not running,
when that panel names the port conflict instead.

Refs #23.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@takashi-matsuyama
takashi-matsuyama merged commit 5058ddc into main Aug 16, 2026
2 checks passed
@takashi-matsuyama
takashi-matsuyama deleted the fix/rotate-path-on-port-move branch August 16, 2026 05:09
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