2026-08-25 17:18:22 +02:00
|
|
|
|
# Taken - Umbrelapp
|
|
|
|
|
|
|
2026-09-09 15:58:22 +02:00
|
|
|
|
> **App: Evolu Relay.** Prioriteit: **A** | Afhankelijk van: –
|
|
|
|
|
|
>
|
|
|
|
|
|
> **Van B naar A op 09-09-2026.** Er staat een 0.7.0 klaar die niet gebouwd is, en zolang die niet op het
|
|
|
|
|
|
> apparaat draait komt het plan **Testclient** ook niet verder: de proeven daar vragen een relay die
|
|
|
|
|
|
> eigenaars toelaat. Eén stap bij de gebruiker blokkeert dus twee plannen. Het plan houdt zijn nummer 008.
|
2026-08-28 13:59:15 +02:00
|
|
|
|
>
|
|
|
|
|
|
> Van A naar B op 28-08-2026: het doel van dit plan is gehaald en het restwerk wacht nergens op.
|
2026-08-25 17:18:22 +02:00
|
|
|
|
>
|
|
|
|
|
|
> Actief sinds 25-08-2026. Gepromoveerd uit `Masterplannen/` omdat de gebruiker besloot het pakket meteen te
|
|
|
|
|
|
> maken. De afhankelijkheid op **Proefopstelling** is daarmee geen blokkade meer maar een parallelle bron:
|
|
|
|
|
|
> fase 1 daarvan is af en leverde de feiten waarop dit pakket rust. Wat er nog uit moet komen zijn twee
|
|
|
|
|
|
> vragen die pas bij het installeren pijn doen, en die staan hieronder als eigen taak.
|
2026-08-27 16:47:29 +02:00
|
|
|
|
>
|
|
|
|
|
|
> **Dit is de focus vanaf 27-08-2026, op verzoek van de gebruiker.** Het werk aan Electrum Gate is die dag
|
|
|
|
|
|
> afgerond tot en met de tweede indeling; het plan **Eigenimage** staat klaar maar ligt bewust stil. Twee
|
|
|
|
|
|
> feiten om mee te beginnen: **de app staat op dit moment uit** op de Umbrel, en hij is nog nooit met
|
|
|
|
|
|
> Trezor Suite verbonden geweest. "Gebouwd" is hier dus nog verder van "werkend" dan bij Gate.
|
2026-08-25 17:18:22 +02:00
|
|
|
|
|
|
|
|
|
|
## Volgende stap
|
|
|
|
|
|
|
2026-09-10 10:14:01 +02:00
|
|
|
|
- [ ] **0.7.1 nakijken op het apparaat.** De vier punten van de gebruiker zijn alleen in `voorbeeld/`
|
|
|
|
|
|
gezien: de lege plek bovenaan, de kop met het aantal, de gelijke rijhoogte (ook tijdens labelen) en
|
|
|
|
|
|
de tekst in "About this app"
|
|
|
|
|
|
- [x] **0.7.1 gebouwd, geduwd en gepind (10-09-2026, gebruiker).** De digest staat drie keer in de compose
|
2026-09-10 09:54:22 +02:00
|
|
|
|
- [x] **0.7.1 klaargezet (10-09-2026): de twee eigenaarskaders opgeruimd.** Vier punten van de gebruiker
|
|
|
|
|
|
na een dag met 0.7.0, en één ervan is meer dan een woordkeuze: **elke rij is nu even hoog**. Een rij
|
|
|
|
|
|
werd hoger op het moment dat je hem een naam gaf, want het label duwde het id naar een derde regel;
|
|
|
|
|
|
het id staat nu bij de tijden op de onderregel, afgekapt met een puntje en volledig in de tooltip.
|
|
|
|
|
|
Verder: "Accepted owners" en "Waiting list" heten "Accepted" en "Waiting", de badge "Waiting" is weg
|
2026-09-10 10:01:15 +02:00
|
|
|
|
(een geblokkeerde eigenaar is nu precies de regel mét badge), de regel onder het adres is weg, en de
|
|
|
|
|
|
teller met wachtenden staat in de kop van dat kader in plaats van in een widget bovenaan; die plek
|
|
|
|
|
|
blijft leeg zodat "Status" de rechterkolom houdt. Ook eruit: **de eis in "About this app" dat het
|
|
|
|
|
|
adres met `http` moet beginnen**, die het kader onderaan tegensprak. Beide waren waar, dus wat eruit
|
|
|
|
|
|
moest was de eis. Nagekeken in `voorbeeld/`: alle vijf de rijen zijn 68px, ook tijdens het labelen.
|
|
|
|
|
|
**Op het apparaat nog ongezien**, want er is geen image
|
2026-09-10 09:54:22 +02:00
|
|
|
|
- [x] **0.7.0 gebouwd, geduwd en gepind (10-09-2026, gebruiker).** De digest staat drie keer in de
|
|
|
|
|
|
compose. Bij het duwen liep de gebruiker eerst op `unauthorized: reqPackageAccess`; dat is de
|
|
|
|
|
|
packages-rechtencontrole van Gitea en geen fout in dit pakket
|
2026-09-09 15:45:55 +02:00
|
|
|
|
- [x] **0.7.0 klaargezet (09-09-2026): één weg naar binnen, en de melding bij elke klik weg.** Vier punten
|
|
|
|
|
|
van de gebruiker, opgekomen tijdens het beproeven met de testcliënt:
|
|
|
|
|
|
- de getimede leerstand is eruit; de **wachtlijst** is de enige weg naar binnen. Zijn redenering:
|
|
|
|
|
|
dubbelop, en het venster liet iederéén toe die er toevallig in verbond. Daarmee verdween ook de
|
|
|
|
|
|
bug dat een geleerde eigenaar in de weigerlijst bleef staan terwijl hij al kon schrijven
|
|
|
|
|
|
- "Refused owners" heet "Waiting list", met de badge "Waiting" en een teller waar het tijdvenster
|
|
|
|
|
|
stond. Het veld op schijf blijft `rejected`
|
|
|
|
|
|
- het adres onderaan zei `http://` en zegt nu `ws://`, met een regel over `wss://<domein>` zonder
|
|
|
|
|
|
poort achter een reverse proxy
|
|
|
|
|
|
- de melding bij elke klik is weg; de knoppen in de lijsten gaan even op slot. Foutmeldingen blijven
|
|
|
|
|
|
|
|
|
|
|
|
`STATE_VERSION` blijft 1, dus een `owners.json` van 0.6.0 leest door. **Alles nog ongezien op het
|
|
|
|
|
|
apparaat**, want er is geen image
|
2026-09-07 19:24:40 +02:00
|
|
|
|
- [x] **De eigenaars gesorteerd op laatst gezien, meest recent bovenaan (07-09-2026, 0.5.6).** Op verzoek
|
|
|
|
|
|
van de gebruiker; in beide kaders en over de groepen heen. Alleen de pagina, dus geen nieuwe image.
|
|
|
|
|
|
**Nog nakijken op het apparaat.**
|
|
|
|
|
|
- [ ] **"Laatst gezien" ook bijwerken bij een sync, niet alleen bij de verbinding.** Het relay-proces
|
|
|
|
|
|
zet `lastSeen` in `decideOwner`, en dat wordt alleen bij de WebSocket-upgrade gesteld. Een client die
|
|
|
|
|
|
dagen verbonden blijft, zakt dus in de lijst terwijl hij druk bezig is. De haak die per schrijfactie
|
|
|
|
|
|
loopt is `isOwnerWithinQuota`; daar kan een pure functie in `policy.js` het tijdstip bijwerken, met
|
|
|
|
|
|
een test in `test_limiter.mjs`. Leesacties zijn niet te zien: daar heeft de relay geen haak voor.
|
|
|
|
|
|
Kost een nieuwe image, dus alleen als de gebruiker dat wil.
|
2026-09-04 09:55:11 +02:00
|
|
|
|
- [x] **De accentgloed uitgezet, als schakelaar (04-09-2026, 0.5.5).** Op verzoek van de gebruiker, en in
|
|
|
|
|
|
dezelfde stap in Electrum Gate (0.0.29). `data-glow="on"` op het html-element zet hem terug, en
|
|
|
|
|
|
alleen samen met `data-depth="deep"`. De blur gaat met de gloed mee, waardoor het mobiele
|
|
|
|
|
|
terugvalblok uit 0.5.3 verviel. Alleen de pagina, dus geen nieuwe image.
|
2026-08-30 13:05:58 +02:00
|
|
|
|
- [x] **De image 0.5.0 gebouwd en geduwd op de Umbrel (30-08-2026), en gepind.** Digest
|
|
|
|
|
|
`sha256:1e4dafdc…acea49a`, en de suite meldt hem nu als `gepind`. Bouwen kan alleen daar: umbreld kan
|
|
|
|
|
|
niet bij een image die alleen lokaal bestaat, en `docker` vraagt op dat apparaat `sudo`.
|
2026-08-30 12:26:56 +02:00
|
|
|
|
|
2026-08-30 13:05:58 +02:00
|
|
|
|
**Twee dingen om te bewaren voor de volgende verhoging.** De digest stond hier bewust even níet, want
|
|
|
|
|
|
een oude digest onder een nieuwe tag levert stilzwijgend de oude image; ongepind faalt hard en
|
|
|
|
|
|
zichtbaar. Doe dat dus weer zo: digest weg, bouwen, duwen, nieuwe erin. En doe **beide** pushes naar
|
|
|
|
|
|
de repo vóórdat de app in umbrelOS geüpdatet wordt, anders is het toevoegen van de digest een tweede
|
|
|
|
|
|
compose-wijziging en kost het een extra versienummer.
|
2026-08-30 12:26:56 +02:00
|
|
|
|
|
2026-08-30 13:05:58 +02:00
|
|
|
|
`docker buildx imagetools inspect` gaf `MediaType: application/vnd.docker.distribution.manifest.v2+json`,
|
|
|
|
|
|
dus **één architectuur en geen multi-arch index**. Dat is bij bouwen op het apparaat zelf te
|
|
|
|
|
|
verwachten en het klopt per constructie met de host; voor de officiele store hoort er arm64 bij, en
|
|
|
|
|
|
dat staat bij **Publicatie-Relay**
|
2026-08-31 11:28:11 +02:00
|
|
|
|
- [x] **0.5.2: de opfrisbeurt uit het gedeelde designsysteem (31-08-2026).** Dezelfde drie dingen als in
|
|
|
|
|
|
Electrum Gate: accentgloed, doorschijnende kaarten met randlicht en schaduw, en één hoek voor elk
|
|
|
|
|
|
buitenste kader. Alleen de pagina, dus `VERSION` in `build.sh` blijft staan en het manifest gaat
|
|
|
|
|
|
alleen omhoog. Dat is de regel uit de kop van de changelog, en dit is het tweede geval op rij.
|
2026-08-30 13:17:26 +02:00
|
|
|
|
- [x] **0.5.1: de melding bovenaan ging nooit weg (30-08-2026).** Gemeld door de gebruiker binnen een uur
|
|
|
|
|
|
na 0.5.0, op de pagina op zijn eigen Umbrel. Eén ontbrekende tak: de ronde zette de melding wel áán
|
|
|
|
|
|
maar nooit uit, dus "Sent." bleef staan tot je herlaadde. Nu is de melding van de ronde en niet van de
|
|
|
|
|
|
klik. Een weigering is de uitzondering, blijft staan tot de volgende opdracht, en is rood geworden.
|
|
|
|
|
|
|
|
|
|
|
|
**Alleen een `*.template` geraakt, dus geen nieuwe image**: `build.sh` blijft op 0.5.0 en het manifest
|
|
|
|
|
|
gaat naar 0.5.1. Dat is de normale gang van zaken en niet een slordigheid; de regel staat in
|
|
|
|
|
|
[CHANGELOG-evolu-relay.md](../../../CHANGELOG-evolu-relay.md), waar hij bij 0.5.0 nog verkeerd stond
|
|
|
|
|
|
- [ ] **De app store verversen in umbrelOS en de app updaten naar 0.5.1. Eigenaar: gebruiker.**
|
2026-08-30 12:26:56 +02:00
|
|
|
|
- [ ] **Daarna op het apparaat nakijken wat een browser moet bewijzen (30-08-2026).** De pagina is met
|
|
|
|
|
|
nagemaakte gegevens bekeken en dat vond twee echte fouten, maar drie dingen kan alleen de app zelf
|
|
|
|
|
|
zeggen: loopt de teller écht af en gaat de deur dan dicht, blijft een label na een herstart staan, en
|
|
|
|
|
|
klopt het adres in het kader "Relay address" (dat gebruikt `window.location.hostname`, en achter de
|
|
|
|
|
|
app-proxy is dat een ander adres dan op een laptop)
|
2026-08-28 10:44:31 +02:00
|
|
|
|
- [x] **De kále Evolu-relay geprobeerd, en hij werkt (28-08-2026).** Trezor Suite op de desktop stuurde
|
|
|
|
|
|
elf labels naar `docker.io/evoluhq/relay:latest` en die kwamen aan: de database in het volume groeide
|
|
|
|
|
|
van 40960 naar 49152 bytes. **De protocolversie klopt**, en daarmee is de richting uit
|
|
|
|
|
|
[OPEN.md](OPEN.md) punt 6 gemeten in plaats van verwacht. Het protocol en alle metingen staan in
|
|
|
|
|
|
[PLAN.md](PLAN.md) §6a
|
2026-08-28 13:38:18 +02:00
|
|
|
|
- [x] **Uitgezocht waarom iOS niets doet (28-08-2026): het ligt aan het apparaat en niet aan dit pakket.**
|
|
|
|
|
|
De `OwnerId` wordt op de Trezor afgeleid, en het model van de gebruiker kan nog niet aan een iPhone
|
|
|
|
|
|
gekoppeld worden. Zonder apparaat kent de app geen `deviceStaticSessionId`, en dan slaat Suite een
|
|
|
|
|
|
label lokaal op en doet verder niets, zonder melding. De hele redenering met bronregels staat in
|
|
|
|
|
|
[OPEN.md](OPEN.md) punt 9
|
2026-08-28 13:59:15 +02:00
|
|
|
|
- [x] **De leeskant gemeten en in orde (28-08-2026).** Getest met een tweede gebruikersaccount op dezelfde
|
|
|
|
|
|
Mac, en dat is schoner dan een tweede apparaat: die installatie heeft een **lege** lokale
|
|
|
|
|
|
Evolu-database, dus alles wat daar verschijnt kan alleen van de relay komen. Dezelfde Trezor en
|
|
|
|
|
|
dezelfde wallet, dus dezelfde `OwnerId` en geen nieuwe eigenaar. De labels kwamen door. Daarmee zijn
|
|
|
|
|
|
beide richtingen bewezen
|
2026-08-28 11:02:51 +02:00
|
|
|
|
- [x] **Besloten wat er met het huidige pakket gebeurt (28-08-2026): het gaat eruit.** De relay van Trezor,
|
|
|
|
|
|
de quota-manager en de Postgres vervallen. Wat ervoor in de plaats komt staat in [PLAN.md](PLAN.md)
|
|
|
|
|
|
§4g en §4h
|
|
|
|
|
|
- [x] **De limiter gekozen (28-08-2026): weg 1, uitbreiden via `createRelay`.** Dat bleek veel kleiner dan
|
|
|
|
|
|
**Bereikbaarheid** §4b aannam: het zijn twee terugroepfuncties, `isOwnerAllowed` en
|
|
|
|
|
|
`isOwnerWithinQuota`, en Trezor doet zelf niets anders. De gebruiker breidde het ontwerp uit met een
|
|
|
|
|
|
schakelaar voor nieuwe eigenaars en met wissen per eigenaar. Zie [OPEN.md](OPEN.md) punt 8
|
|
|
|
|
|
- [x] **De vraag of het databaseschema zichzelf aanmaakt is vervallen.** Hij ging over het pakket dat eruit
|
|
|
|
|
|
gaat, en de kale relay maakt zijn database bij de start zelf aan; dat is op 28-08-2026 gezien
|
2026-08-27 16:56:06 +02:00
|
|
|
|
|
2026-08-28 11:02:51 +02:00
|
|
|
|
## Fase 5 - De verbouwing naar de kale relay
|
2026-08-27 16:56:06 +02:00
|
|
|
|
|
2026-08-28 13:08:31 +02:00
|
|
|
|
**Op 28-08-2026 in één sessie gedaan en op het apparaat draaiend, versie 0.3.0.** Wat er staat: het eigen
|
|
|
|
|
|
relay-programma met de allowlist, het bouwrecept, de compose met de omgedraaide poorten, de statuspagina, en
|
|
|
|
|
|
TLS via Zoraxy op een eigen subdomein. De Mac synchroniseert eroverheen, met een geleerde eigenaar en een
|
|
|
|
|
|
gesloten deur erna.
|
|
|
|
|
|
|
|
|
|
|
|
Wat er niet staat: iOS doet niets mee, en daardoor is de leeskant nooit gemeten. Beide staan hierboven bij
|
|
|
|
|
|
"Volgende stap".
|
2026-08-27 16:56:06 +02:00
|
|
|
|
|
2026-08-28 11:12:41 +02:00
|
|
|
|
- [x] **Het eigen relay-programma geschreven (28-08-2026).** `tools/evolu-relay/src/`: `policy.js` met het
|
|
|
|
|
|
beleid als pure functies, `store.js` voor de staat op schijf, en `index.js` dat `createRelay`
|
|
|
|
|
|
aanroept met de opstartvolgorde van Evolu zelf. Met test: `node tests/test_limiter.mjs`, 60 toetsen,
|
|
|
|
|
|
en de beslissende regel is muteertest gedaan
|
|
|
|
|
|
- [x] **Een getal gekozen voor `isOwnerWithinQuota`: 1 MB per schrijfactie**, instelbaar met
|
|
|
|
|
|
`RELAY_MAX_WRITE_BYTES`. Onderweg bleek de aanname hieronder fout: die 1 MB van de gepubliceerde image
|
|
|
|
|
|
is **per schrijfactie** en geen totaal per eigenaar. Er valt dus geen labelgeschiedenis tegenaan te
|
|
|
|
|
|
lopen. Een totaal per eigenaar zou vragen dat we in de opslag van de relay kijken, en dat doen we niet
|
|
|
|
|
|
- [x] **De allowlist als staat onder `${APP_DATA_DIR}/data/`**, naast de relay-database en niet erin:
|
|
|
|
|
|
`owners.json`, atomair geschreven, en `command.json` als postbus voor de pagina
|
|
|
|
|
|
- [ ] **Data per eigenaar wissen.** Nog niet gebouwd, en bewust niet gegokt: het beleid kan een eigenaar
|
|
|
|
|
|
vergeten en blokkeren, maar zijn berichten staan in de SQLite van de relay
|
|
|
|
|
|
(`evolu_message`, `evolu_history`, met `ownerId` als systeemkolom). Dat is schrijven in andermans
|
|
|
|
|
|
schema, dus dat wil eerst nagekeken worden in `createRelaySqliteStorage` van Evolu
|
|
|
|
|
|
- [ ] **Een `package-lock.json` maken en `npm install` in de Dockerfile omzetten naar `npm ci`.** De twee
|
|
|
|
|
|
pakketten van Evolu staan exact vast, maar wat eronder hangt beweegt nu nog mee. `build.sh` waarschuwt
|
|
|
|
|
|
hiervoor. Kan pas op een machine met netwerk en npm
|
2026-08-28 11:02:51 +02:00
|
|
|
|
- [ ] **Wissen per eigenaar laten doen door het relay-proces zelf**, aangestuurd met een vlagbestand vanaf
|
|
|
|
|
|
de pagina. Geen tweede container die langszij in de SQLite schrijft, en geen Docker-socket
|
2026-08-28 11:12:41 +02:00
|
|
|
|
- [x] **`tools/evolu-relay/build.sh` omgeschreven (28-08-2026):** bouwt de eigen `Dockerfile` in plaats van
|
|
|
|
|
|
de repo van Trezor te klonen. Git is niet meer nodig, de pin zit nu in `package.json`, en `VERSION`
|
|
|
|
|
|
in het script hoort gelijk te zijn aan `version` in het manifest
|
2026-08-28 11:22:32 +02:00
|
|
|
|
- [x] **De compose omgezet (28-08-2026):** pagina achter `app_proxy` mét de inlog, relay op host-poort
|
|
|
|
|
|
3852. Postgres, wachtwoord en quota-manager eruit; drie containers werden relay, agent en nginx. De
|
|
|
|
|
|
image is gepind op tag plus digest
|
|
|
|
|
|
- [x] **De statuspagina gebouwd (28-08-2026):** `index.html.template`, `nginx.conf.template` en
|
|
|
|
|
|
`agent.py.template`, met het ontwerpsysteem van Electrum Gate en zonder de Google Fonts-verwijzing.
|
|
|
|
|
|
Toont of de relay draait, de omvang en het laatste schrijfmoment van de database, het adres dat je in
|
|
|
|
|
|
Suite invult, en de eigenaars in drie lijsten met knoppen om te blokkeren, alsnog toe te laten of te
|
|
|
|
|
|
vergeten. **Nog nooit in een browser gezien**
|
2026-08-28 11:28:42 +02:00
|
|
|
|
- [x] **Het relay-programma op het apparaat geverifieerd (28-08-2026).** Losgedraaid uit het register,
|
|
|
|
|
|
buiten de app om. Het log meldde `learned a new owner`, en in `/app/data` stonden daarna
|
|
|
|
|
|
`evolu-relay.db` van 49152 bytes (dezelfde omvang als bij de proef van vanochtend, dus de labels zijn
|
|
|
|
|
|
geland) en `owners.json` van 241 bytes. Daarmee is de hele keten gemeten: `isOwnerAllowed` wordt
|
|
|
|
|
|
aangeroepen met iets wat het beleid begrijpt, de leerstand werkt, en de allowlist gaat naar schijf
|
2026-08-28 11:51:41 +02:00
|
|
|
|
- [x] **De pagina en de agent op het apparaat geverifieerd (28-08-2026).** De pagina rendert, toont de
|
|
|
|
|
|
gegevens van de relay, en de knop **Close** werkt: de leerstand ging naar `closed` en de geleerde
|
|
|
|
|
|
eigenaar staat in de lijst met eerste en laatste verschijning. Daarmee is de hele keten gemeten,
|
|
|
|
|
|
pagina → agent → postbus → relay-proces → schijf → pagina
|
|
|
|
|
|
- [x] **De fout die dat opleverde is gerepareerd:** de korte containernaam `agent` is op het gedeelde
|
|
|
|
|
|
Docker-netwerk niet uniek, dus de helft van de verzoeken kwam bij Electrum Gate uit. Beide apps
|
|
|
|
|
|
wijzen nu naar `<app-id>_agent_1`, en `test_appstore_vorm.py` toetst dat voortaan
|
2026-08-28 13:59:15 +02:00
|
|
|
|
- [x] **De app opnieuw geïnstalleerd in plaats van geüpdatet (28-08-2026).** De oude installatie was er
|
|
|
|
|
|
eerst afgehaald, en dat was ook de nette weg: niet elk bestand bereikt een bestaande installatie via
|
|
|
|
|
|
een update
|
|
|
|
|
|
- [x] **Zoraxy ingericht (28-08-2026)** op een eigen subdomein met TLS, doorverwijzend naar de relay-poort,
|
|
|
|
|
|
met de WebSocket-upgrade aan. De handshake-curl uit [PLAN.md](PLAN.md) §6a stap 3 geeft daar
|
|
|
|
|
|
`101 Switching Protocols`, en de desktop synchroniseert eroverheen
|
2026-08-25 17:18:22 +02:00
|
|
|
|
|
2026-08-30 12:26:56 +02:00
|
|
|
|
## Fase 6 - De statuspagina op de lijst van de gebruiker (0.5.0)
|
|
|
|
|
|
|
|
|
|
|
|
**De lijst kwam op 30-08-2026, nadat de gebruiker met 0.4.0 gewerkt had.** Negen punten, en alle negen
|
|
|
|
|
|
gedaan. Twee ervan waren onderzoeksvragen; die staan onderaan.
|
|
|
|
|
|
|
|
|
|
|
|
Waarom dit in één ronde kon: de pagina is een `*.template` en zit dus in de update-whitelist. Zodra hij in
|
|
|
|
|
|
een eigen image zit (het plan **Eigenimage**) kost elke tweak een bouw plus een digest, en dán is dit
|
|
|
|
|
|
duurder. Die volgorde stond als reden bij de vorige taak en is daarmee ingelost.
|
|
|
|
|
|
|
|
|
|
|
|
- [x] **Gelijkgetrokken met Electrum Gate.** Dezelfde `max-width: 1760px`, hetzelfde raster van twaalf
|
|
|
|
|
|
kolommen, hetzelfde icoon van 64 pixels met terugval, dezelfde `t-h1` van 2rem, hetzelfde menu met
|
|
|
|
|
|
drie punten, en het versienummer achter de tagline. De pagina leende dat ontwerp al maar op eigen maten
|
|
|
|
|
|
- [x] **Een tijdvenster van twee minuten voor nieuwe eigenaars, met een stopknop.** **De teller zit in het
|
|
|
|
|
|
relay-proces en niet in de pagina**, en dat is de kern van deze taak: een teller in een tabblad dat je
|
|
|
|
|
|
sluit, sluit de deur niet. `policy.js` heeft er een veld `learningUntil` voor gekregen, plus
|
|
|
|
|
|
`isLearningOpen` en `expireLearning`
|
|
|
|
|
|
- [x] **`decideOwner` kijkt naar `isLearningOpen` en niet naar het veld `learning`.** Dat is geen
|
|
|
|
|
|
netheid: de lus die het bestand opruimt loopt elke twee seconden, en in dat gat zou een onbekende
|
|
|
|
|
|
alsnog binnenkomen. Muteertest gedaan: de juiste drie toetsen vielen om
|
|
|
|
|
|
- [x] **Zonder `STATE_VERSION` te verhogen**, en met een toets die dat verdedigt. Een verhoging zou
|
|
|
|
|
|
`normalizeState` het bestand van de draaiende installatie laten afwijzen, en dan schuift `store.js` de
|
|
|
|
|
|
allowlist opzij en gaat de deur dicht voor eigenaars die er al in stonden
|
|
|
|
|
|
- [x] **Geweigerde en geblokkeerde eigenaars in één kader.** Wat je ermee doet is hetzelfde: toelaten of
|
|
|
|
|
|
vergeten. Welke van de twee een regel is, staat als badge op de regel, en die badge staat **buiten**
|
|
|
|
|
|
het hover-blok. Dat was de eerste van de twee fouten die de voorbeeldweergave vond: erbinnen was het
|
|
|
|
|
|
onderscheid onzichtbaar tenzij je over de regel ging, en dat is juist de informatie waarvoor de twee
|
|
|
|
|
|
kaders zijn samengevoegd
|
|
|
|
|
|
- [x] **De uitleggende regels eruit.** De koppen zeggen genoeg; wat er te weten valt staat in de nieuwe
|
|
|
|
|
|
dialoog. Wat níet weggegooid is maar verplaatst: dat het adres met `http` moet beginnen en niet met
|
|
|
|
|
|
`ws`, en wat de relay wel en niet kan zien
|
|
|
|
|
|
- [x] **Knoppen alleen bij hover, per regel.** Met opacity en niet met `display: none`, zodat ze met de
|
|
|
|
|
|
tab-toets bereikbaar blijven; `focus-within` maakt ze dan zichtbaar, en op een aanraakscherm staan ze
|
|
|
|
|
|
altijd aan. Dit had één gevolg dat je niet ziet aankomen: onzichtbare knoppen houden hun ruimte, dus
|
|
|
|
|
|
de kop "New owners" brak over twee regels en de waarde stond lager dan in de drie kaders ernaast.
|
|
|
|
|
|
Opgelost met kortere knoptekst plus hetzelfde afbreekpunt van 1400px dat Gate gebruikt
|
|
|
|
|
|
- [x] **Geen voetregel, en een menu-item "About this app" in plaats daarvan.** In **beide** apps, op verzoek
|
|
|
|
|
|
van de gebruiker. Bij Gate staat daar bovendien wat de statuswidget wél en niet bewijst
|
|
|
|
|
|
- [x] **Labels op een eigenaar-id, te onderhouden.** Hover een regel en klik **Label**: het veld komt in de
|
|
|
|
|
|
plaats van de titel, Enter bewaart, Escape breekt af. **De labels staan in een eigen bestand
|
|
|
|
|
|
`labels.json` met de agent als enige schrijver**, en niet in `owners.json`. Drie redenen: één schrijver
|
|
|
|
|
|
per bestand blijft de afspraak, een label is meteen opgeslagen in plaats van na de volgende ronde van
|
|
|
|
|
|
de relay, en labelen blijft werken als de relay omgevallen is. De relay hoeft dit niet te weten, want
|
|
|
|
|
|
een label zegt niets over wie er binnen mag
|
|
|
|
|
|
- [x] **De statuswidget van Electrum Gate verduidelijkt**, op de opmerking van de gebruiker dat die van
|
|
|
|
|
|
Evolu Relay veel duidelijker is. Er stond "Answering" met "answered in 7 ms, from inside the app"; nu
|
|
|
|
|
|
"Running" met de meting eronder, en de nuance staat onder een eigen kopje in de nieuwe dialoog
|
|
|
|
|
|
|
|
|
|
|
|
### Wat er aan toetsen bij kwam
|
|
|
|
|
|
|
|
|
|
|
|
De pagina's zijn samen bijna drieduizend regels en er stond geen enkele toets op. Dat blijft zo voor wat ze
|
|
|
|
|
|
tonen, maar drie klassen fouten hoeven niet op het apparaat gevonden te worden:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] **`tests/test_relay_agent.py`** (nieuw, 65 toetsen): de labels en het tijdvenster in de agent. Twee
|
|
|
|
|
|
muteertests gedaan
|
|
|
|
|
|
- [x] **`tests/test_paginas_parsen.mjs`** (nieuw): loopt de JavaScript van elke pagina, en loopt hij ook nog
|
|
|
|
|
|
ná de invulling door umbreld. Muteertest gedaan met een echte syntaxfout
|
|
|
|
|
|
- [x] **Een dollarteken-toets in `test_appstore_vorm.py`.** Dit is de valstrik van dit hele project, en het
|
|
|
|
|
|
commentaar in drie bestanden beweerde al dat déze test hem dichthield terwijl dat niet zo was. Nu
|
|
|
|
|
|
wel. Hij vond meteen twee valse positieven in de eigen opzet (een kaal dollarteken in een
|
|
|
|
|
|
commentaarregel, en de exports van een afhankelijkheid), en die zijn in de toets opgelost en niet in
|
|
|
|
|
|
de bestanden
|
|
|
|
|
|
- [x] **Een toets dat er geen werkbestanden in een app-map staan.** umbreld kopieert de héle app-map naar
|
|
|
|
|
|
het apparaat, dus een bewerkbestand van een icoon van 175 kB gaat mee in elke back-up. Die stond er
|
|
|
|
|
|
op 30-08-2026
|
|
|
|
|
|
- [x] **`tools/voorbeeldpagina.mjs`** (nieuw): maakt van een `*.template` een pagina die je in een browser
|
|
|
|
|
|
kunt openen, met de variabelen ingevuld en nagemaakte gegevens erin. Geen toets en geen bewijs, maar
|
|
|
|
|
|
het vond in één keer de twee fouten hierboven. Uitvoer komt in `voorbeeld/` en die map is gitignored
|
|
|
|
|
|
|
|
|
|
|
|
### De twee onderzoeksvragen
|
|
|
|
|
|
|
|
|
|
|
|
- [x] **"Komen geweigerde eigenaars toch met de hele blow aan instellingen in de database?" Nee.**
|
|
|
|
|
|
`isOwnerAllowed` wordt in de WebSocket-**upgrade** aangeroepen; een weigering is een HTTP 401 en een
|
|
|
|
|
|
gesloten socket, dus er wordt niets opgeslagen. **Maar het gewenste gevolg treedt wel op**: Evolu is
|
|
|
|
|
|
local-first, de cliënt houdt alles zelf en probeert opnieuw, dus alsnog toelaten brengt de hele
|
|
|
|
|
|
geschiedenis binnen. De redenering met bronregels staat in
|
|
|
|
|
|
[Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md) §10, en daar staat ook de
|
|
|
|
|
|
scherpe kant: **blokkeren werkt pas bij de volgende verbinding**, want voor een lopende verbinding
|
|
|
|
|
|
wordt de vraag nooit opnieuw gesteld. Dat staat als open punt 10 in [OPEN.md](OPEN.md)
|
|
|
|
|
|
- [x] **"Kunnen we de blobs ontcijferen met de xpub?" Nee, en de premisse klopt niet.** Een `OwnerId` wordt
|
|
|
|
|
|
niet uit een xpub gemaakt: `OwnerId`, `OwnerEncryptionKey` en `OwnerWriteKey` komen alle drie met
|
|
|
|
|
|
SLIP-21 uit één 32-byte node die het apparaat aflevert. Dat spoor loopt langs de seed en niet langs
|
|
|
|
|
|
BIP32, dus uit een xpub is er niets te halen. **Met die node zelf kan het wél**, en `trezorlib` heeft
|
|
|
|
|
|
er een functie voor. Waarom dat níet in deze app hoort, en waar het wél hoort, staat in §11 van
|
|
|
|
|
|
hetzelfde document; het plan-punt staat in de repo `HomeGit/Trezor` bij **AdvancedUI**
|
|
|
|
|
|
|
2026-08-25 17:18:22 +02:00
|
|
|
|
## Fase 1 - De app-map
|
|
|
|
|
|
|
|
|
|
|
|
- [x] **`whatsnext-evolu-relay/` aangemaakt met `umbrel-app.yml` en `docker-compose.yml` (25-08-2026).**
|
|
|
|
|
|
Mapnaam gelijk aan het `id`, met het store-voorvoegsel `whatsnext-`, en de manifestvelden in de
|
|
|
|
|
|
voorgeschreven volgorde
|
|
|
|
|
|
- [x] `data/postgres/.gitkeep` erin, zodat de mount bij de eerste start niet als root wordt aangemaakt
|
|
|
|
|
|
- [x] **`dependencies` weggelaten en niet leeg gezet.** Deze app hangt van geen enkele andere app af; een
|
|
|
|
|
|
leeg veld zou suggereren dat er iets te kiezen valt
|
2026-08-28 11:13:37 +02:00
|
|
|
|
- [x] **Een eigen icoon (28-08-2026).** `icon.png` aangeleverd door de gebruiker, met de `icon`-regel in
|
|
|
|
|
|
het manifest die naar de rauwe versie in deze repo wijst. Als laatste regel, want bij inlevering in
|
|
|
|
|
|
de officiële store hoort hij weg
|
2026-08-25 17:18:22 +02:00
|
|
|
|
|
|
|
|
|
|
## Fase 2 - De compose
|
|
|
|
|
|
|
|
|
|
|
|
- [x] **`app_proxy` met `PROXY_AUTH_ADD: "false"`, en geen eigen `ports:`.** Trezor Suite is geen browser
|
|
|
|
|
|
met een sessiecookie. Dit is het patroon van de eigen `nostr-relay`-app van Umbrel, dus een precedent
|
|
|
|
|
|
en geen omweg; zie [PLAN.md](PLAN.md) §4c
|
|
|
|
|
|
- [x] **Relay en quota-manager uit één image met een ander `command`.** Expliciet en niet leunend op de
|
|
|
|
|
|
`CMD` van de Dockerfile, want daar staat `yarn start` met bovenstrooms zelf een twijfel erbij
|
|
|
|
|
|
- [x] **De quota-manager gaat mee.** Niet omdat de relay hem aanroept, maar omdat de relay elke eigenaar
|
|
|
|
|
|
zonder limietenrij weigert en dit is wat die rijen maakt
|
|
|
|
|
|
- [x] **Postgres onder `${APP_DATA_DIR}/data/postgres`**, wachtwoord uit `${APP_PASSWORD}`, `PGDATA` op een
|
|
|
|
|
|
submap, en `postgres:17-alpine` in plaats van `postgres` kaal
|
|
|
|
|
|
- [x] **Healthcheck op de eigen database en gebruiker**, niet op `-d postgres` zoals bovenstrooms: die
|
|
|
|
|
|
database bestaat hier niet, en dan is de controle groen op het verkeerde antwoord
|
2026-08-25 18:37:18 +02:00
|
|
|
|
- [x] **De eigen image gepind op tag plus digest (25-08-2026).**
|
|
|
|
|
|
`sc.kamenier-hamer.nl/sysop/evolu-relay:c03a204@sha256:2fe1e9e9…`, op beide services. Dat moest wel:
|
|
|
|
|
|
zie fase 4. **Let op dat dit één architectuur is** (amd64), want er is alleen amd64 geduwd. Voor de
|
|
|
|
|
|
officiele store hoort er een multi-arch index-digest met arm64 in; dat staat bij **Publicatie-Relay**
|
2026-08-28 13:59:15 +02:00
|
|
|
|
- [x] **De Postgres-pin is vervallen (28-08-2026):** die database zit niet meer in de app
|
2026-08-30 12:26:56 +02:00
|
|
|
|
- [x] **De statuspagina verbeteren, op een lijst van de gebruiker.** De lijst kwam op 30-08-2026 en is in
|
|
|
|
|
|
één ronde uitgevoerd; zie fase 6 hieronder
|
2026-09-08 16:36:30 +02:00
|
|
|
|
- [x] **`python:3-alpine` en `nginx:alpine` pinnen: vervallen (08-09-2026).** Sinds 0.6.0 zitten de agent
|
|
|
|
|
|
en de pagina in de eigen relay-image (plan **Eigenimage**, fase 5), en die twee images staan niet
|
|
|
|
|
|
meer in de compose. Wat er te pinnen is, is de eigen image, en dat gebeurt bij elke verhoging. De
|
|
|
|
|
|
oude tekst hieronder blijft staan als uitleg waarom er tot dan bewust níet gepind is.
|
|
|
|
|
|
|
|
|
|
|
|
Op aanwijzing van de gebruiker (30-08-2026): die twee images waren
|
|
|
|
|
|
de plek waar de agent en de pagina van deze app uitgevoerd werden, en dat is precies wat **Eigenimage**
|
|
|
|
|
|
naar een eigen image verhuisde. Pin je ze dan, dan pin je iets dat verdwijnt.
|
2026-08-30 13:42:14 +02:00
|
|
|
|
|
|
|
|
|
|
De eis komt uit **Publicatie-Relay** en die is nog ver weg, dus er is geen haast. De regel en de hele
|
|
|
|
|
|
keten erachter staan in [KNOWLEDGE.md](../../../KNOWLEDGE.md); de commando's in
|
|
|
|
|
|
[Images-pinnen.md](../../../Referenties/Images-pinnen.md).
|
|
|
|
|
|
|
|
|
|
|
|
**De eigen relay-image is een ander geval en die is wél gepind**, bij elke verhoging. Verwar die twee
|
|
|
|
|
|
niet: de suite drukt beide af in dezelfde lijst
|
2026-08-25 17:18:22 +02:00
|
|
|
|
|
|
|
|
|
|
## Fase 3 - Het bouwrecept
|
|
|
|
|
|
|
|
|
|
|
|
- [x] **`tools/evolu-relay/build.sh` (25-08-2026).** Haalt de broncode op een vastgezette commit en bouwt
|
|
|
|
|
|
de Dockerfile van Trezor. Niet hun bouwstappen nabouwen; wat wij toevoegen is de pin
|
|
|
|
|
|
- [x] **Niet in de app-map gezet, en dat is geen netheid.** Een `Dockerfile` staat niet in de
|
|
|
|
|
|
update-whitelist, dus bouwen-in-de-app zou elke nieuwe versie een herinstallatie kosten. Zie
|
|
|
|
|
|
[PLAN.md](PLAN.md) §4f
|
|
|
|
|
|
- [x] **Onder `tools/` en niet onder `build/`:** dat laatste staat in `.gitignore` als bouwselmap, dus het
|
|
|
|
|
|
recept zou stilzwijgend buiten de repo blijven. Gevonden bij het stagen, niet bij het schrijven
|
|
|
|
|
|
- [x] Het script controleert na het ophalen dat de commit is wat hij verwachtte, en faalt hard als dat niet
|
|
|
|
|
|
zo is. Zonder die regel bouwt het stil de verkeerde toestand
|
|
|
|
|
|
|
|
|
|
|
|
## Fase 4 - Installeren en verifiëren op de Umbrel
|
|
|
|
|
|
|
|
|
|
|
|
Niets hiervan is op een laptop te doen. Eigenaar van deze hele fase: **gebruiker**.
|
|
|
|
|
|
|
2026-08-25 18:37:18 +02:00
|
|
|
|
- [x] **De image gebouwd op de Umbrel (25-08-2026), in 50 seconden.** Twee dingen die het opleverde: de
|
|
|
|
|
|
gebruiker `umbrel` zit hier níet in de groep `docker`, dus het moet met `sudo`; en de Dockerfile van
|
|
|
|
|
|
Trezor bouwt zonder aanpassing
|
|
|
|
|
|
- [x] **In een register gezet, want anders kan umbreld er niet bij (25-08-2026).** Dit was de grote
|
|
|
|
|
|
verrassing van de dag en het staat met bron in
|
|
|
|
|
|
[Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md): umbreld haalt élke image via
|
|
|
|
|
|
de Docker Engine API op, niet via compose. Een lokaal gebouwde tag is dus onbereikbaar en
|
|
|
|
|
|
`pull_policy: never` doet niets, want de compose wordt niet gelezen om te pullen. Het Gitea-register op
|
|
|
|
|
|
dezelfde server als de store bleek de kortste weg, en anoniem halen werkt daar
|
|
|
|
|
|
- [x] **De app geïnstalleerd en alle drie de containers blijven draaien (25-08-2026).** `relay`,
|
|
|
|
|
|
`quota-manager` en `db`, met `db` op healthy en de app-proxy op 3851. De lokale images waren vooraf
|
|
|
|
|
|
weggehaald, dus de pull uit het register is echt gedaan en het hele pad is bewezen: broncode →
|
|
|
|
|
|
bouwrecept → register → gepinde digest → installatie
|
2026-08-28 13:59:15 +02:00
|
|
|
|
- [x] **De schemavraag is vervallen (28-08-2026):** de kale relay maakt zijn SQLite bij de start zelf aan,
|
|
|
|
|
|
en de Postgres waar deze vraag over ging zit niet meer in de app
|
|
|
|
|
|
- [x] **Trezor Suite synchroniseert (28-08-2026), heen én terug.** Niet naar 3851 zoals hier stond maar naar
|
|
|
|
|
|
3852: de poorten zijn omgedraaid, want 3851 draagt nu de statuspagina. Zie de "Volgende stap"
|
|
|
|
|
|
hierboven
|
|
|
|
|
|
- [ ] De app gestopt en gestart, en de data heeft het overleefd. **Nog niet gedaan**, en het is de laatste
|
|
|
|
|
|
controle van dit plan die er echt toe doet: de allowlist en de labels staan onder
|
|
|
|
|
|
`${APP_DATA_DIR}/data/relay`, dus een herstart hoort niets te kosten. **Eigenaar: gebruiker**
|
|
|
|
|
|
- [x] **Gecontroleerd of het toevoegen van deze app Electrum Gate raakt (28-08-2026), en dat deed het.**
|
|
|
|
|
|
Niet zoals verwacht via poorten of geheugen, maar via een naam: beide apps hadden een service `agent`
|
|
|
|
|
|
op hetzelfde Docker-netwerk, en Docker verdeelde de naam over allebei. De pagina van Gate ging daardoor
|
|
|
|
|
|
stuk. Gerepareerd in beide apps, met een toets in `test_appstore_vorm.py` zodat het niet stil
|
|
|
|
|
|
terugkomt
|
2026-08-25 17:18:22 +02:00
|
|
|
|
|
|
|
|
|
|
## Geblokkeerd / wacht op
|
|
|
|
|
|
|
2026-08-28 13:59:15 +02:00
|
|
|
|
**Leeg sinds 28-08-2026.** Beide blokkades zijn opgeheven en ze staan hier voor de geschiedenis.
|
|
|
|
|
|
|
|
|
|
|
|
- [x] **"Hoe registreer je een eigenaar bij de quota-manager?"** is vervallen: de quota-manager zit niet
|
|
|
|
|
|
meer in de app, en de kale relay kent geen limietentabel. De vraag bestond alleen bij het pakket van
|
|
|
|
|
|
Trezor
|
|
|
|
|
|
- [x] **"Accepteert Trezor Suite dit adres, en in welke vorm?"** is beantwoord: ja, met `http(s)://` en
|
|
|
|
|
|
desgewenst een pad, zowel via het dev-utils-veld als via de gewone "Custom server"-instelling. Gemeten
|
|
|
|
|
|
op de desktop, heen en terug
|