feat(sidecar): protocol 3 — the first route on this bridge that is not a GET #3

Merged
whitlocktech merged 1 commits from feat/phase-6-identity into edge 2026-09-21 22:25:29 +00:00
Member

POST /link/confirm forwards a one-time link code to the plugin and hands back what it says. Everything before it was the website reading what the game had already told us; this is the website asking the game a question only the game can answer.

It is still a forwarder and holds no authority of its own

It does not mint codes, does not store them, does not know what a website user is, and cannot tell a good code from a bad one. Putting the code table here would give the sidecar a credential and an opinion, and D2 and the bridge principles say it has neither.

A refused code is a 200

link.ok and link.error are both answers, and the website has to tell "that code is wrong" from "the game never replied" to say the right thing to a player. The two transport failures keep the codes respond already gives them: 503 when the game is down, 504 when it is up and silent.

That distinction was walked from the other end this phase: with the sidecar up and no plugin connected, POST /link/confirm answers {"error":"no plugin connected"} with a 503, and the module turns that into "The game servers are unreachable right now — try again in a minute" rather than "that code is wrong".

usable_code

Split out and tested because its two rejections are easy to get subtly wrong. It trims before it measures: a player pasting a code out of game chat brings whitespace with it, a field of nothing but spaces is empty rather than four characters long, and the length bound belongs on the trimmed value.

Checks

cargo test --release — 46 green. cargo clippy --release --all-targets -- -D warnings — clean. Built and run against the phase-6 module for the whole browser walk.

AI disclosure

  • This contribution was AI-assisted (Claude Code).

🤖 Generated with Claude Code

https://claude.ai/code/session_01PMH6bw1jXMgbyF3ZWGEzSM

`POST /link/confirm` forwards a one-time link code to the plugin and hands back what it says. Everything before it was the website reading what the game had already told us; this is the website asking the game a question only the game can answer. ## It is still a forwarder and holds no authority of its own It does not mint codes, does not store them, does not know what a website user is, and cannot tell a good code from a bad one. Putting the code table here would give the sidecar a credential and an opinion, and D2 and the bridge principles say it has neither. ## A refused code is a 200 `link.ok` and `link.error` are both answers, and the website has to tell *"that code is wrong"* from *"the game never replied"* to say the right thing to a player. The two transport failures keep the codes `respond` already gives them: **503** when the game is down, **504** when it is up and silent. That distinction was walked from the other end this phase: with the sidecar up and no plugin connected, `POST /link/confirm` answers `{"error":"no plugin connected"}` with a 503, and the module turns that into *"The game servers are unreachable right now — try again in a minute"* rather than *"that code is wrong"*. ## `usable_code` Split out and tested because its two rejections are easy to get subtly wrong. It **trims before it measures**: a player pasting a code out of game chat brings whitespace with it, a field of nothing but spaces is empty rather than four characters long, and the length bound belongs on the trimmed value. ## Checks `cargo test --release` — 46 green. `cargo clippy --release --all-targets -- -D warnings` — clean. Built and run against the phase-6 module for the whole browser walk. ## AI disclosure - [x] This contribution was AI-assisted (Claude Code). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01PMH6bw1jXMgbyF3ZWGEzSM
wtclaude added 1 commit 2026-09-21 14:12:04 +00:00
feat(sidecar): protocol 3 — the first route on this bridge that is not a GET
All checks were successful
PR Checks / rust-gates (pull_request) Successful in 2m30s
fd6efd9a2c
`POST /link/confirm` forwards a one-time link code to the plugin and hands back
what it says. Everything before it was the website reading what the game had
already told us; this is the website asking the game a question only the game can
answer.

**It is still a forwarder and holds no authority of its own.** It does not mint
codes, does not store them, does not know what a website user is, and cannot tell
a good code from a bad one. Putting the code table here would give the sidecar a
credential and an opinion, and D2 and the bridge principles say it has neither.

**A refused code is a 200.** `link.ok` and `link.error` are both answers, and the
website has to tell "that code is wrong" from "the game never replied" to say the
right thing to a player. The two transport failures keep the codes `respond`
already gives them: 503 when the game is down, 504 when it is up and silent.

`usable_code` is split out and tested because its two rejections are easy to get
subtly wrong. It trims BEFORE it measures: a player pasting a code out of game
chat brings whitespace with it, a field of nothing but spaces is empty rather
than four characters long, and the length bound belongs on the trimmed value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
whitlocktech merged commit 47ffc9a78c into edge 2026-09-21 22:25:29 +00:00
whitlocktech deleted branch feat/phase-6-identity 2026-09-21 22:25:29 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Rust-Link#3
No description provided.