Public: anyone can read this; the crew can change it.
A test pins unlinking a parent-forge sign-in: refused when it is the account's last way in #7141
Check · Review · Land · Live done — Landed and live in production.
I added `test/federation-last-way-in.test.ts`. It pins `last_way_in` on unlinking a parent-forge sign-in. The new test passes and `bun x tsc --noEmit` is clean. The test found nothing wrong, so no source module changed. I did not run the rest of the suite.
shipped production is serving it deploy 9e5d84b
Test-only pull, one new file. It pins the refusal in the core module (no password and no passkey, so unlinking returns last_way_in and the link stays). It pins both ways out (passkey, password). It also drives POST /settings/parent/unlink with a real session and a same-origin header, and checks the flash wording and the unlinked case. The names it imports (LAST_WAY_IN, linkParent, linkedParent, unlinkParent) exist in src/core/federation.ts, and the route is registered in src/http/server.ts. It touches no source, adds no dependency, and keeps its state in a temp dir that afterAll removes.
Two things I would do next:
- Add the same refusal assertion for the MCP parent_unlink tool (last_way_in) and the TUI can screen, since both doors already use LAST_WAY_IN.
- Add a cross-origin POST case to the Settings unlink, to show the same-origin check refuses it and the link stays.
I added
test/federation-last-way-in.test.ts. It pinslast_way_inon unlinking a parent-forge sign-in. The new test passes andbun x tsc --noEmitis clean. The test found nothing wrong, so no source module changed. I did not run the rest of the suite.last_way_infromunlinkParent. The link stays.changePassword, the same unlink succeeds and the link is gone.POST /settings/parent/unlinkfor a parent-only account redirects to Settings, which shows theLAST_WAY_INsentence and still shows the link. With a passkey, it shows "Unlinked." and no refusal.Left out: I did not touch
test/parent-link.test.ts, which already has a refusal case that checks the link stays. It does not check the words, and it needs two servers. The new file uses one app, withparentUrlset to a fake https issuer, so no round trip to a parent forge happens.To try it:
bun test test/federation-last-way-in.test.ts.Closes #7130