Skip to content

fix(setup): the wizard was asking the poller gate a question it does not answer - #22

Merged
emooreatx merged 1 commit into
mainfrom
fix/21-wizard-shape-on-provisional-mode
Aug 29, 2026
Merged

fix(setup): the wizard was asking the poller gate a question it does not answer#22
emooreatx merged 1 commit into
mainfrom
fix/21-wizard-shape-on-provisional-mode

Conversation

@emooreatx

Copy link
Copy Markdown
Contributor

Closes #21.

The diagnosis is slightly different from the issue's

The issue reads the 80-line gap between clientMode=NODE and clientMode=AGENT as the wizard finalising on a provisional value, and suggests waiting for the probe.

Waiting alone wouldn't have fixed it. At the first gate line the mode was NODE correctly, and it would have stayed NODE however long we waited — the brain reports setup_required: true, and clientModeFrom demotes an unconfigured brain to NODE (CIRISAgent#1075).

The circularity is named in that arm's own comment

addLlmProvider  503   <- so the user could not configure an escape

This gate exists precisely to stop AGENT-only pollers firing at a
server that cannot answer them

The demotion exists because an unconfigured brain 503s addLlmProvider. And the wizard used that demotion to skip the step that calls addLlmProvider.

brain unconfigured → gate says NODE → wizard drops the AI step → brain stays unconfigured

The fix that stopped the 503s became the reason configuration never happens.

Two different questions

question unconfigured brain
clientMode should agent surfaces and pollers run? demote — correct, they'd 503
the wizard is there a brain that needs configuring? offer the step — that's the point

ModeProbe.brainPresent = folded && reachable, independent of readiness, because readiness must not gate the step that produces readiness. The poller gate is unchanged.

The provisional-value half is real too

setupHasAgent was clientMode?.isAgent ?: false — "not probed yet" became "no brain". SetupViewModel is keyed on it and isFinalSetupStep reads it, so the step list is fixed at composition. Screen.Setup now holds on StartupScreen until the probe answers.

Same distinct-zeroes rule as CapabilityWire's null-versus-empty: could-not-determine must not become a definite answer.

Tested against the log

The exact first gate line from the issue — SETUP / 0 services / folded / reachable / unconfigured / fabric-node. The poller gate still returns NODE there; brainPresent is true at the same instant.

Mutation: let readiness back into brainPresent and the two decisive cases fail.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EGE52kPzjGFiPzGcs63ZC1

…not answer

CIRISClient#21. On a folded agent's first run the wizard drops the AI step, so
setup completes with no LLM and the user reaches chat to silence.

NOT A RACE — OR NOT ONLY ONE. The issue reads the 80-line gap between
`clientMode=NODE` and `clientMode=AGENT` as the wizard finalising on a
provisional value, and suggests waiting for the probe. Waiting alone would not
have fixed it: at the first gate line the mode was NODE **correctly**, and it
would still be NODE however long we waited, because the brain reports
`setup_required: true` and `clientModeFrom` demotes an unconfigured brain to
NODE (CIRISAgent#1075).

THE CIRCULARITY IS NAMED IN THE ARM'S OWN COMMENT. That demotion was added
because an unconfigured brain 503s every AGENT poller, and the list of victims
includes:

    addLlmProvider  503   <- so the user could not configure an escape

So: the brain is unconfigured, therefore the gate says NODE, therefore the
wizard drops the AI step, therefore the brain stays unconfigured. The fix that
stopped the 503s became the reason configuration never happens.

`clientMode` answers "should the agent surfaces and AGENT-only pollers run",
and demoting there is right. The wizard asks "is there a brain here that needs
configuring", where being unconfigured is the REASON TO OFFER THE STEP. Using
one for the other is a category error, not a timing bug.

`ModeProbe.brainPresent` = `folded && reachable`, independent of readiness —
because readiness must not gate the step that produces readiness. The poller
gate is unchanged.

AND THE PROVISIONAL-VALUE HALF IS REAL TOO. `setupHasAgent` was
`clientMode?.isAgent ?: false`, so "not probed yet" became "no brain", and
`SetupViewModel` is keyed on it while `isFinalSetupStep` reads it — the step
list is FIXED at composition. `Screen.Setup` now holds on StartupScreen until
the probe answers rather than composing the shape on a default. Same
distinct-zeroes rule as CapabilityWire's null-versus-empty: could-not-determine
must not become a definite answer.

Tested against the exact gate line from the issue's log — SETUP / 0 services /
folded / reachable / unconfigured / fabric-node. The poller gate still returns
NODE there, and `brainPresent` is true at the same instant. Mutation: let
readiness back into `brainPresent` and the two decisive cases fail.

Closes #21.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGE52kPzjGFiPzGcs63ZC1
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@emooreatx
emooreatx merged commit b7e480c into main Aug 29, 2026
3 checks passed
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.

Setup wizard finalises on provisional clientMode=NODE — folded agents finish first run with no LLM configured

1 participant