Step 4 of the connection wizard build (ADR-0005): the wizard's frame and its first step, Server. View models only; the window does not use them yet, so nothing an operator sees changes.
What it adds (presentation assembly)
ConnectionWizard: the five steps, Enter and Escape, Back, the result announcement, focus targets, cancel and dispose.
The Server step: address and name, one check that returns all five stages together, the refused certificate with its reasons, and the development-only certificate exception with its warning and review.
Announcement (a sentence raised once, after it is final) and OperationGate (one command at a time per key; a second is refused out loud, never queued). The tree and shell view models use both.
Two contract functions made callable by a client, and nothing else: ManagementText.Bounded (the printable form of service text) and SignInProviderOrigin.TryRead (the one rule for what counts as a sign-in provider's address).
Rules the review pressed on
Next is enabled only while the check on screen passed, and the check the next step hands to servers.add is exactly that one.
An accepted certificate exception belongs to one check. An edit, a decline or a refusal forgets it.
A provider address is judged by the contract's rule only; a text the contract refuses is "not known yet" in the warning and "cannot be used" for a pass.
Installing a root certificate is advised only when the issuer is untrusted; other refusals say what they mean.
Nothing claims the server is reachable, trusted or added; "nothing was checked" is said only when the request certainly did not leave.
Verification
Head 1483636 on release/2.0 at b86a971.
build/Verify.ps1 passed on that head: 1,174 Core, 2,337 Windows runtime and command line, 1,023 presentation tests, none failed; presentation 100% of 2,236 lines, Core and command line 100%, Windows 96.13% (minimum 95).
Review (independent reviewer, two passes, and a replay check)
02d94a0: 0 blockers, 6 should-fix, 16 nits.
05491b4: Verdict on 05491b4: 0 blockers, 0 should-fix, 5 nits. 23 new attempts could not get Next enabled while the screen showed another provider than the check held.
05491b4 was replayed onto b86a971 as 1483636 after pull request 55 merged. Git stopped nowhere. git range-diff shows ten of eleven patches identical; the eleventh differs in one context line of ADR-0005. A second reviewer checked the replay: Verdict on 1483636: 0 blockers, 0 should-fix, 0 nits.
Left open, for the next wizard step
An answer that arrives after the wizard has moved to another step is still shown; no public path reaches it today, and the Sign in step must close it before it waits for a request that stores something.
After a pass that named a name problem, correcting the name leaves the old sentence.
A name mismatch on the sign-in provider's certificate tells the operator to enter another address.
Two lines no test holds, and three document sentences about what a warning remembers.
Not proven here
No view exists yet, so what a screen reader says and whether WinUI moves focus as asked is unshown. Nothing ran against a service that speaks version 2.
Step 4 of the connection wizard build ([ADR-0005](docs/adr/0005-connection-wizard-and-server-tree.md)): the wizard's frame and its first step, Server. View models only; the window does not use them yet, so nothing an operator sees changes.
**What it adds (presentation assembly)**
- `ConnectionWizard`: the five steps, Enter and Escape, Back, the result announcement, focus targets, cancel and dispose.
- The Server step: address and name, one check that returns all five stages together, the refused certificate with its reasons, and the development-only certificate exception with its warning and review.
- `Announcement` (a sentence raised once, after it is final) and `OperationGate` (one command at a time per key; a second is refused out loud, never queued). The tree and shell view models use both.
- Two contract functions made callable by a client, and nothing else: `ManagementText.Bounded` (the printable form of service text) and `SignInProviderOrigin.TryRead` (the one rule for what counts as a sign-in provider's address).
**Rules the review pressed on**
- Next is enabled only while the check on screen passed, and the check the next step hands to `servers.add` is exactly that one.
- An accepted certificate exception belongs to one check. An edit, a decline or a refusal forgets it.
- A provider address is judged by the contract's rule only; a text the contract refuses is "not known yet" in the warning and "cannot be used" for a pass.
- Installing a root certificate is advised only when the issuer is untrusted; other refusals say what they mean.
- Nothing claims the server is reachable, trusted or added; "nothing was checked" is said only when the request certainly did not leave.
**Verification**
- Head `1483636` on `release/2.0` at `b86a971`.
- `build/Verify.ps1` passed on that head: 1,174 Core, 2,337 Windows runtime and command line, 1,023 presentation tests, none failed; presentation 100% of 2,236 lines, Core and command line 100%, Windows 96.13% (minimum 95).
**Review (independent reviewer, two passes, and a replay check)**
- `02d94a0`: `0 blockers, 6 should-fix, 16 nits`.
- `05491b4`: `Verdict on 05491b4: 0 blockers, 0 should-fix, 5 nits.` 23 new attempts could not get Next enabled while the screen showed another provider than the check held.
- `05491b4` was replayed onto `b86a971` as `1483636` after pull request 55 merged. Git stopped nowhere. `git range-diff` shows ten of eleven patches identical; the eleventh differs in one context line of ADR-0005. A second reviewer checked the replay: `Verdict on 1483636: 0 blockers, 0 should-fix, 0 nits.`
**Left open, for the next wizard step**
- An answer that arrives after the wizard has moved to another step is still shown; no public path reaches it today, and the Sign in step must close it before it waits for a request that stores something.
- After a pass that named a name problem, correcting the name leaves the old sentence.
- A name mismatch on the sign-in provider's certificate tells the operator to enter another address.
- Two lines no test holds, and three document sentences about what a warning remembers.
**Not proven here**
No view exists yet, so what a screen reader says and whether WinUI moves focus as asked is unshown. Nothing ran against a service that speaks version 2.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Two small types the connection wizard and the shell's view models both stand
on (ADR-0005). Nothing uses them yet, so nothing an operator sees changes.
Announcement is a text and an event. Announce stores the finished sentence
and then raises Raised once, on the calling thread, so a view tells a screen
reader about a result once and whole. The same sentence announced again is
raised again; Clear removes the text and raises nothing; an announcement of
nothing is refused.
OperationGate holds one key per thing the operator can change: a server's
identifier, the computer, the wizard. A command enters under its key with
the sentence any other command on that key is refused with while it runs.
A second command on a busy key gets that sentence and no hold: it is never
dropped without a word and never queued. Other keys are not affected.
Changed says which key became busy or free. Reads repeated on a timer do
not enter the gate.
Both are at 100% line coverage.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
ManagementText.Bounded is public. The contract says the reader of a reply
applies the rule again, so that a client holds printable, bounded text even
from a service that did not send it so (ADR-0004, "Text on the wire"), and
the presentation assembly, which reads the replies, could not call it. The
records that apply the rule when they are built (an error's message, an
identity value) need nothing from a client; the members that are plain text
on the wire (a check stage's reasons, a refused certificate's subject and
issuer, a server's status) are given this form by the client that shows
them. Message and Identity are the service's own forms and stay internal.
As a public method it refuses a missing text and a negative limit by name.
Nothing else changes: the rule, the cut and every caller are as they were.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
ConnectionWizard is the wizard of ADR-0005 without its window. Nothing uses
it yet, so nothing an operator sees changes. Steps 2 to 5 (sign in, pair,
printers, done) are not built: the frame knows them, can show them and
offers no primary action there.
The frame: the steps of a run and the step indicator, the primary action
and Cancel (Enter and Escape), Back from signing in to the server and from
the summary to the printers and nowhere else, the focus target, one result
announcement, and how a run ends (cancelled, on the Computer page, on a
server). A run that adds a server is not started without a snapshot, while
the stored data is not ready, or at eight servers counting one that is
being removed; WhyAddServerCannotStart is the one rule, for the tree too.
Disposing only cancels, and nothing is announced afterwards.
The Server step:
- The address is read by ServerAddress.TryRead, and what is sent, shown and
logged is the origin it returned. The name is ServerName.Propose of that
origin until the operator types one; a name that breaks ServerName.Check
disables Next and says which part of the rule it breaks.
- A check is one servers.check. Its result is shown as five rows in the
contract's order, each passed, failed with its reasons, not reached or
not known. Next is enabled only for a result the service answered as
passed, in which the contract's own FailureCode finds no failure, whose
provider is an origin or absent, and which offers a sign-in method this
version knows. That result is kept as the client returned it, for adding
the server.
- An address that is already a server says so and offers to open it.
- A refused certificate is shown with its presenter, subject, issuer,
validity, fingerprint and the reasons in words. The development-only
exception is offered only when the reasons include untrustedAuthority.
The warning names the server and says the provider follows after the
check, or names both when the failed check already reported the
provider; the re-check shows what the exception covers before Next is
enabled, and that review is skipped only for the provider the warning
named. An acceptance is for one check: a check under it that does not
pass, an edit of the address and declining all forget it.
- Editing the address removes the result and stops the wait for a check
that is running; a late answer is not shown. A second check while one
runs is refused out loud through the window's gate. Cancel during a
check stops waiting; the only request ever sent is the check.
- No answer: the result's own word decides whether the check may have run.
Only a result that says nothing was carried out is said to have checked
nothing.
WizardReactions is the one table from a refusal's code to what the wizard
does, with a common part, the check's own part and the codes a check is
not answered with. A test walks ManagementErrorCode.All, so a code added
to the contract fails until it has an entry.
WizardMessages holds every sentence. Text the service passed on (a stage's
reasons, a certificate's subject, issuer and fingerprint) is given the
contract's printable form where it is shown; a refusal's message already
has it and is not changed again. Log entries are templates; the only thing
typed that reaches one is the server's origin.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The changelog says what was added and that the window does not use it yet.
ADR-0005 gains "Resolved while building the wizard, 2026-11-11": the
choices the text left open, each taken the way that is safest for the
operator (an acceptance is for one check, when the review of the
exception's addresses is skipped, what counts as passed, what is kept for
adding the server, what Enter says where Next cannot be used).
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
A check reports the server's sign-in provider as text, and servers.add and
trust.set then state it. Their arguments refuse text that names no origin,
an IPv6 literal with a zone among it, because the form origins are compared
in has no place for the zone. A client could not ask the same question, so
the wizard asked one of its own: it showed such an address with the zone
dropped, let the operator accept it, and kept a provider that no request
can be built with (review of step 4, S1).
SignInProviderOrigin.TryRead is that question, made public: true exactly
for text Require accepts, with the origin in the form it is compared in.
Agrees and Require stay internal; a test holds that nothing else of the
class is public, and that reading agrees with the argument records for
every form of text, with a zone and without.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Announcement.Raised was an EventHandler with no arguments, so a listener
read Announcement.Text. When a listener announced something more from
inside the event, the listeners after it read the later sentence twice and
never heard the first (review of step 4, N4).
Raised is now EventHandler<AnnouncementEventArgs>, and the arguments carry
the sentence that was announced. Every listener hears each sentence once
whatever another listener does; Text still ends as what was announced
last. A listener that throws is not caught, as before, and a test now says
so.
This changes the public shape of a shared type: a subscriber takes
(object? sender, AnnouncementEventArgs e) and reads e.Text.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
OperationGate had no test with a second thread: raising Changed inside the
lock, entering without the lock and a release that is not atomic all
passed the suite (review of step 4, S6: R46, R47, R48). One test now asks
the gate from another thread inside the event, for a key that becomes busy
and for one that comes free, and then has sixteen threads fight for one
key, each releasing its hold twice and a third of them from three threads
at once: one holder at a time, every refusal the holder's sentence, as
many busy and free events as entries, and the key free at the end.
The documentation of the gate and of its event arguments now says what a
listener can rely on (N5): Changed is raised on the thread that entered or
released, outside the lock, and Busy in the arguments can be out of date
by the time it is read, so a listener takes the event as "this key
changed", goes to its own thread and reads IsBusy. A test shows the stale
event. The shape of the gate is unchanged.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
What the wizard's Server step says and shows, corrected after the
independent review of step 4. How the frame and the step behave follows in
the next commit.
- One judge for a sign-in provider's address (S1). CertificateView.Origin
asks SignInProviderOrigin.TryRead, the rule the arguments of servers.add
and trust.set are held to, and no rule of its own. An IPv6 literal with
a zone is no origin: in the warning the provider is then "not known
yet", a check that says "passed" and names one is an answer that cannot
be used, and the address that presented a refused certificate is left
out. Nothing is shown with the zone dropped.
- The root certificate only where it can help (S3). CertificateRefused
takes the reasons and says, for each, what it means and what can be
done. Installing the issuing authority's root certificate is named only
for an authority Windows does not trust; a certificate issued for
another name, no certificate, a reason this version does not know and no
reason at all send the operator to the address or to the server's
administrator. When no certificate was presented the sentence no longer
speaks of "the certificate presented by".
- Rows (N8, N9). A row shows at most five reasons and then says how many
more there are. A stage reported twice is shown with the worst of its
outcomes and the reasons of every entry, and a check that says "passed"
and reports a stage twice is an answer that cannot be used.
- Wording (N6, N7, N16). The button that drops the exception is "Drop the
exception": it does not check. update_in_progress says that the service
is prepared for an update, which may be running or may have stopped;
busy does not say who asked for the other change. A service of another
version is told as "the check could not be made", not as "nothing was
checked".
- The two sentences for a pass can end with what is wrong with the name
instead of "Choose Next" (S5); the step uses that in the next commit.
Tests (S6, N13): the sentences for busy, update in progress, no known
sign-in method and the step's introduction are compared with literals;
the test of what the sentences claim now refuses any sentence that says a
check ran, that something was stored or stopped, or names a time, outside
the sentences for a result; and the test that no member is typed as or
named for a secret leaves out what the compiler writes and says what it
shows and what it does not.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
- No state of the exception outlives the result it belongs to (S2). The
two fields that remembered what a warning had named are gone. What an
accepted warning said goes with the one check that runs under it and is
kept only with that check's pass; a warning that is open says what the
check on screen reported. A warning for an earlier address, a declined
one and one left open can no longer skip a review or make a check run
under the exception.
- Uniform guards (S4). GoTo does nothing once the run has ended or the
wizard was disposed. Asking for the exception, accepting, declining and
opening the existing server do nothing off the Server step, and Escape
there cancels the wizard.
- A pass while the typed name breaks the name rule (S5) ends with what is
wrong with the name, points the focus at the name and is shown as a
warning. It no longer says "Choose Next" or points at a button that
cannot be used.
- Close returns when the wizard is no longer active, so a view that
disposes the wizard on hearing a result does not make the check throw
(N1). Close and Dispose free the wizard's gate themselves, not when the
abandoned check has ended (N2).
- A check is sent only for the address in the box (N3). The wait exists
before the gate is entered, so a listener of the gate that edits the
address, cancels or disposes ends the check that was being started, and
nothing is sent.
- Back to the Server step says its result again, the exception and the
addresses it covers among it, with the focus on Next (N10).
- Waiting for the service belongs to the frame (N14): TryBeginWait,
EndWait, StopWaiting and AbandonWait hold the gate, the wait, the rule
for an answer that comes too late and IsBusy, for the later steps to use.
- A second check while one runs is logged as information (N15).
Tests for each of these, for Enter after a check that did not pass (S6),
and for the two notifications that had none: nothing is announced as about
to change after disposal, and the buttons are told when the run ends
(N12).
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The changelog no longer says that "the lasting fix is named" for every
refused certificate, and names what changed: the ways forward by reason,
the bound on a row's reasons, the provider judged by the contract's rule,
Back, and a pass while the name breaks the rule.
ADR-0005, "Resolved while building the wizard": four sentences said
something the code does not do (a stage this version does not know is not
shown; the result is kept also while the name disables Next; when a result
is about the address in the box; the root certificate as the fix for every
certificate failure). They are corrected, and the decisions of the fix
round are recorded: no state of the exception outlives its result, who
says what a provider's address is, what a row shows, a pass while the name
breaks the rule, update and busy, what happens once the run has ended, and
that waiting belongs to the frame.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
"Resolved while planning the build" was written when neither the wizard
nor a caller of the contract's rules existed in the presentation assembly.
With the wizard's frame and Server step that is no longer so for five of
its entries, and one of them said that the contract's printable form
cannot be called from the presentation assembly, which it now can.
- G3: the Server step calls ServerAddress.TryRead, ServerName.Propose and
ServerName.Check and has no rule of its own; the provider a check
reports is read by SignInProviderOrigin.TryRead.
- G5: when a run that adds a server may start is built
(ConnectionWizard.WhyAddServerCannotStart); what the window shows with
no servers is not.
- G8: Back from Sign in and from Done, and from no other step, is built in
the frame.
- G12: when the exception is offered is built in the Server step.
- G20: ManagementText.Bounded is public, and the Server step applies it to
a stage's reasons and a refused certificate's text. The rows and the
nodes are still not built.
The window uses none of this yet; the entries and the paragraph above them
say so.
Signed-off-by: James Maes <james@kof22.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Step 4 of the connection wizard build (ADR-0005): the wizard's frame and its first step, Server. View models only; the window does not use them yet, so nothing an operator sees changes.
What it adds (presentation assembly)
ConnectionWizard: the five steps, Enter and Escape, Back, the result announcement, focus targets, cancel and dispose.Announcement(a sentence raised once, after it is final) andOperationGate(one command at a time per key; a second is refused out loud, never queued). The tree and shell view models use both.ManagementText.Bounded(the printable form of service text) andSignInProviderOrigin.TryRead(the one rule for what counts as a sign-in provider's address).Rules the review pressed on
servers.addis exactly that one.Verification
1483636onrelease/2.0atb86a971.build/Verify.ps1passed on that head: 1,174 Core, 2,337 Windows runtime and command line, 1,023 presentation tests, none failed; presentation 100% of 2,236 lines, Core and command line 100%, Windows 96.13% (minimum 95).Review (independent reviewer, two passes, and a replay check)
02d94a0:0 blockers, 6 should-fix, 16 nits.05491b4:Verdict on 05491b4: 0 blockers, 0 should-fix, 5 nits.23 new attempts could not get Next enabled while the screen showed another provider than the check held.05491b4was replayed ontob86a971as1483636after pull request 55 merged. Git stopped nowhere.git range-diffshows ten of eleven patches identical; the eleventh differs in one context line of ADR-0005. A second reviewer checked the replay:Verdict on 1483636: 0 blockers, 0 should-fix, 0 nits.Left open, for the next wizard step
Not proven here
No view exists yet, so what a screen reader says and whether WinUI moves focus as asked is unshown. Nothing ran against a service that speaks version 2.
🤖 Generated with Claude Code