The developer's decisions of 25 Oct, reviewing ADR 0021 whole: - What an assistant may see and do (D7–D12): the scope of each question (the parts ticked, the studyset, its tree, the library), looked up through read-only tools the app answers on the device; private studysets out of a wider scope unless switched on, and a warning whenever one's content would go to a remote model, Lumo included, as no provider keeps a question confidential while its model answers; changes only as drafts; progress never; text first, an image when ticked or asked for. - What it keeps, does and where it lives (D13–D18): conversations kept sealed with the person's own key; four features (questions about what is open, cards from text, explaining a miss, checking a written answer); grants and limits in halkyon_base, the adapters in a package of their own (halkyon_llm, BSD-3-Clause); the proposal's points 4–8 and 10 as written; the warning once per studyset and assistant; built for v0.21.0. - Sign-ups and operators (D19–D26): SIGN_UP open, approval or closed; the first operator by SQL, others named in the app; suspending an approved account; a wait screen with a matching code the operator checks with the person; 14 days, 10 waiting. - What people are told and what never goes (D27–D30): the app and a privacy page of each instance's own; others' posts only with their author's switch, a copy's licence being its agreement; an opaque ID per person for the provider. ADR 0022 and Learn's AGENTS.md now point to it as accepted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
77 lines
4.8 KiB
Markdown
77 lines
4.8 KiB
Markdown
# ADR 0022: No hand-off and no connector
|
||
|
||
- **Status:** decided 23 Oct 2026, by the developer (D1–D3 below); built for v0.19.0
|
||
(build 22).
|
||
- **Supersedes:** ADR 0006 (Claude reads studysets through a connector on the instance),
|
||
and the hand-off to an AI assistant outside the app (decided 10 and 14 Oct 2026, Learn's
|
||
`AGENTS.md`).
|
||
- **Followed by:** ADR 0021 (an assistant on the instance, on its operator's keys),
|
||
accepted 25 Oct 2026.
|
||
|
||
## Context
|
||
|
||
Since 10 Oct a question asked from the app could leave it in two ways, both through the
|
||
person's own subscription, as Halkyon called no language model with an API key: the
|
||
hand-off opened the chosen assistant's new conversation (Lumo by default, ChatGPT,
|
||
Claude, …) with the question and the chosen parts written in, for the person to send; and
|
||
Claude's apps read the person's studysets through the instance's connector (ADR 0006: MCP
|
||
at `/mcp` with its own OAuth, connected with a code from Settings › Assistant › Connect
|
||
Claude). Beside them, the same field searched the web.
|
||
|
||
ADR 0021 proposes an assistant inside the app on an instance whose operator pays for it:
|
||
several providers on the operator's keys, granted per person, with limits and statistics,
|
||
and personal keys where the operator allows them. The developer asked on 23 Oct to "drop
|
||
the Assistant part that just opens the assistant outside of the app, but let's keep the
|
||
web open part", or else decide how the instance's own assistant and opening one's own
|
||
outside the app go together.
|
||
|
||
## Decisions (23 Oct 2026, the developer's)
|
||
|
||
- **D1 The hand-off goes now** (over keeping it until the instance's assistant comes,
|
||
which was recommended): until then the field searches the web only.
|
||
- **D2 The connector goes too** (over keeping it, which was recommended): an instance has
|
||
one way to an assistant, its operator's (ADR 0021), and nothing else on it reads
|
||
people's content for a language model.
|
||
- **D3 In v0.19.0, the app and the server together** (over releasing v0.19.0 first and
|
||
taking the server's part out with the next raise of `minimumAppBuild`, which was
|
||
recommended): build 22 raises `minimumAppBuild` to 22 anyway, so no app that calls the
|
||
connector's endpoints can use the instance after it, and nothing needs to stay for
|
||
older apps.
|
||
|
||
## What goes, and what stays
|
||
|
||
1. **In the app:** the assistants a question opened in (`AiAssistant`, `AssistantHandOff`),
|
||
the switch at the field's start between them and the web (`assistantTarget`), Settings'
|
||
choice of assistant, Connect Claude with its route, cubit, repository and gateway, and
|
||
their texts. A device's settings file from before keeps the old keys (`aiAssistant`,
|
||
`customAssistantUrl`, `assistantTarget`) until the next change of a setting writes it
|
||
anew without them; nothing reads them.
|
||
2. **On the server:** `lib/src/assistant/` (the MCP endpoint, its OAuth pages and metadata,
|
||
the five tools, connect codes, tokens), `AssistantEndpoint`, the daily forgetting of
|
||
the connector's codes and tokens, their lines in Learn's deletion hook,
|
||
`instance.info().assistantConnectorUrl` (nullable, so an older app reads it as none),
|
||
and Caddy's forwarding of `/mcp`, `/oauth/*` and `/.well-known/oauth-*`. A migration
|
||
drops the five tables (`assistant_client`, `assistant_connect_code`,
|
||
`assistant_connection`, `assistant_grant`, `assistant_token`) with every connection,
|
||
code and token in them: from the deploy on, a connected Claude gets no answer, and
|
||
people remove the connector in Claude's settings.
|
||
3. **Stays:** the field (`AssistantBar` on Home, `AssistantButton` in the Library, on a
|
||
studyset and while studying), off unless the person turns it on in Settings, its chips
|
||
of what the question is about (those a web search takes: a card's front, back, hints
|
||
and explanation, never a studyset's name or description), and the web search through
|
||
the engine chosen in Settings, or Android's own search.
|
||
|
||
## Consequences
|
||
|
||
- Until an instance offers ADR 0021's assistant, its people ask no language model from the
|
||
app. learn.halkyon.eu, a public instance, offers none (ADR 0021: public instances leave
|
||
the assistant unset).
|
||
- The instance reads payloads in one place fewer (ADR 0019's context named four).
|
||
- **The deploy breaks the rule that migrations keep the old server working until the
|
||
switch**, for the minute between the maintenance run and the new server: the old one
|
||
then answers the connector's calls with errors, and an account deleted meanwhile (by
|
||
its owner, or the pruning) fails and is deleted when asked again, as the old server's
|
||
deletion hook still deletes from the connector's tables. Keeping the tables a release
|
||
longer would keep the rule, for codes and tokens nothing reads; since build 22 raises
|
||
`minimumAppBuild` (D3), no released app syncs with that server by then.
|
||
- The privacy page (website repository) drops the connector and the hand-off to Lumo.
|