Eén app store, twee apps
umbrelOS leest per store één repo, dus twee apps in twee repo's kan niet. Deze repo is de store en bevat vanaf nu Electrum Gate en het werk aan Evolu Relay. Opgezet als verse repo op verzoek van de gebruiker: de historie van ElectrumTLS en van EvoluRelay komt niet mee. Dat heeft één gevolg dat verder gaat dan opruimen. In de historie van ElectrumTLS staat het domein van de gebruiker en het certificaatpad, van vóór de opschoning van 19-08. Die komt hier niet in. Zolang die repo op de Git-server blijft staan verandert dat niets, dus het weghalen ervan is het laatste stuk van open punt 3 van het plan Appstore, en geen bijzaak. De store zelf hoefde niet te veranderen: store-id whatsnext, en dus blijft het app-id whatsnext-electrum-gate. Dat hangt aan het store-id en niet aan de URL, dus voor umbrelOS is dit dezelfde app in een andere store. Dat de store op 19-08 naar de maker genoemd werd in plaats van naar deze ene app, betaalt zich hier uit. Wat de documentatie betreft is dit één wortel voor beide apps, en dat was de reden om samen te voegen en niet de prijs ervan: de appstore-spec, het pinnen van images en de werkwijze golden al voor allebei en stonden in twee repo's naast elkaar. De kruisverwijzing die daarvoor nodig was (Referenties/Umbrel-appstore.md in de oude EvoluRelay-repo) is verdwenen; wat daarin stond over de plekken waar de relay een ander geval is, staat nu als ontwerp in het masterplan Umbrelapp §4. Botsende namen kregen een achtervoegsel met de app, en alleen die: Publicatie werd Publicatie-Gate en Publicatie-Relay, CHANGELOG.md werd CHANGELOG-electrum-gate.md. Proefopstelling kreeg 007, tussen de twee bestaande nummers, zodat de bovenkant van de reeks op tier-orde blijft staan. CONTINUE_HERE.md heeft een kolom App, maar de tiers lopen over beide apps heen: er is één volgorde van werken. Electrum Gate gaat naar 0.0.15, want website, repo, support, submission en icon wijzen nu naar UmbrelApps en zonder versieverhoging rolt dat niet uit. De release notes leggen aan de gebruiker uit dat hij de store opnieuw moet toevoegen. Of een geïnstalleerde app een wisseling van store-URL overleeft is nog steeds niet uitgezocht; dat blijkt bij het omzetten. Twee dingen in de plannen van Electrum Gate waren door deze verhuizing niet meer waar en zijn bijgewerkt: de taak "de repo hernoemen" in fase 7 is afgevinkt, en de repo-vorm in PLAN.md §4a toonde nog de store-id electrumtls, die al sinds fase 7 achterhaald was. Tests: 39 goed 0 fout en 54 goed 0 fout, niets overgeslagen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# Open punten - Webinterface
|
||||
|
||||
> Beslissingen die nog een **eigenaar** of een **moment** nodig hebben. Wordt een punt een taak, dan
|
||||
> verhuist het naar [TAKEN.md](TAKEN.md).
|
||||
>
|
||||
> **Nummers blijven staan**, ook als een punt beslist is: er kan elders naar verwezen worden. Beslissen
|
||||
> betekent verplaatsen naar de kop hieronder, niet hernummeren.
|
||||
|
||||
## Nog te beslissen
|
||||
|
||||
3. **Komt het activiteitenlog er?**
|
||||
Toegevoegd 19-08-2026, nadat de gebruiker vroeg of er iets over live client-aanroepen te tonen is, en
|
||||
bijgesteld naar logregels onder elkaar. Het ontwerp staat in [PLAN.md](PLAN.md) §4e en de kaart staat
|
||||
al op de pagina in de `no data`-toestand, dus de vorm is te beoordelen zonder dat er iets gebouwd is.
|
||||
|
||||
Wat er beslist moet worden is niet "kan het" maar "is dit het waard, nu het niet is wat er gevraagd
|
||||
werd". Er was gevraagd om **elk verzoek** te loggen, en dat kan niet zonder het Electrum-verkeer van de
|
||||
gebruiker uit te lezen. Wat overblijft is een regel per verbinding en per verkeerspiek. Het vraagt een
|
||||
`log_format` die langs de template-invulling moet, plus een tweede weg naar de bytetellers van een
|
||||
lopende verbinding, want nginx logt een stream-sessie pas bij het sluiten en een wallet houdt hem
|
||||
twaalf uur open.
|
||||
**Moment:** na fase 2, want dan draait de schrijflus toch al · **Eigenaar:** gebruiker
|
||||
|
||||
5. **Wordt er gecontroleerd of de TLS-poort zelf antwoordt?**
|
||||
Toegevoegd 19-08-2026, nadat de badge "Serving this page" eruit ging. De gebruiker wees erop dat die
|
||||
badge niets zei: de pagina wordt nooit getoond aan een wallet die op 50022 verbindt. Mijn gedachte
|
||||
erachter was dat de pagina en de TLS-terminatie in dezelfde container zitten, dus dat de een de ander
|
||||
bewijst, maar dat stond er niet en niemand leest het zo.
|
||||
|
||||
Wat daarbij opvalt en het eigenlijke punt is: **de app controleert wel of de Electrum-server antwoordt,
|
||||
maar niet of hij zelf antwoordt.** Dat is precies zijn enige taak. De agent zou een TLS-verbinding naar
|
||||
de eigen poort kunnen opzetten en de handdruk kunnen afmaken; dat bewijst het luisteren, het certificaat
|
||||
en de doorverbinding in één keer, en het is dezelfde truc waarmee de einddatum van het actieve
|
||||
certificaat te lezen valt.
|
||||
|
||||
Waarom het nog geen taak is: het raakt de agent, en die heeft nog nooit gedraaid. Er is weinig aan om
|
||||
een tweede ongeteste controle op een eerste ongeteste controle te bouwen. Zodra de agent op de Umbrel
|
||||
loopt, is dit de eerstvolgende zinvolle toevoeging aan het dashboard.
|
||||
**Moment:** nadat de agent draait · **Eigenaar:** gebruiker
|
||||
|
||||
7. **Kan Zoraxy of Nginx Proxy Manager verplicht gesteld worden bij de installatie?** Gevraagd door de
|
||||
gebruiker op 20-08-2026, die erbij opmerkte dat sommige apps bij de installatie twee dropdowns tonen.
|
||||
**Technisch antwoord: nee, niet als "de een of de ander".** Nagetrokken in de bron, zie
|
||||
[Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md) §4, met bronlinks.
|
||||
|
||||
Kort: dat dialoog toont één dropdown **per afhankelijkheid** en niet per keuze. In het schema van
|
||||
umbreld is `dependencies` een platte lijst van app-id's, en wat er in een dropdown staat komt van de
|
||||
andere kant, namelijk elke app die `implements: [<dat id>]` declareert. Het voorbeeld dat de gebruiker
|
||||
zag is `mempool` met `dependencies: [bitcoin, electrs]`. Zoraxy en NPM declareren geen `implements`,
|
||||
dus er is geen gedeelde rol om naar te wijzen, en dat staat in hún manifest en niet in het onze.
|
||||
|
||||
Wat overblijft is Zoraxy hard eisen, en dat is een dropdown met één optie. Wat er nog over te beslissen
|
||||
is, is of dat wenselijk is: het sluit de bron `Own folder` uit, en Zoraxy deïnstalleren zou deze app
|
||||
meesleuren.
|
||||
**Moment:** vrij · **Eigenaar:** gebruiker beslist
|
||||
|
||||
## Beslist
|
||||
|
||||
8. **Welke tagline, en waar?** - **Overal die van de appstore** (20-08-2026, gebruiker).
|
||||
"Your own node from anywhere, without waiting for Tor" staat nu ook op de pagina; daar stond "TLS in
|
||||
front of your own Electrum server".
|
||||
|
||||
De afweging was dat de twee lezers op een ander moment zitten: in de winkel moet de regel iemand
|
||||
overtuigen die de app niet kent, op het dashboard staat iemand die hem al draait. Dat pleit voor twee
|
||||
regels. Wat de doorslag gaf is dat deze afweging al eerder gemaakt is: bij het hernoemen naar Electrum
|
||||
Gate was de reden dat de oude naam het **middel** beschreef en niet de opbrengst. Met die maatstaf was
|
||||
de dashboardregel de achterblijver, niet de winkelregel.
|
||||
|
||||
Een toets houdt de twee plekken nu gelijk. Niet omdat het kan, maar omdat ze ver uit elkaar staan:
|
||||
niemand die het manifest aanpast, opent daarna de pagina.
|
||||
|
||||
6. **Kan een certificaat via de pagina geupload worden?** - **Ja, en gebouwd** (20-08-2026, op verzoek van
|
||||
de gebruiker). Zie [CHANGELOG-electrum-gate.md](../../../CHANGELOG-electrum-gate.md) 0.0.7 voor de vier
|
||||
stukken die het vroeg.
|
||||
|
||||
Twee besluiten die eruit voortkwamen en die het waard zijn om terug te lezen:
|
||||
|
||||
- **de bestandsnaam komt uit het certificaat en niet uit het verzoek.** Daarmee is de hele klasse
|
||||
padtrucs weg zonder dat er iets gefilterd hoeft te worden op invoer die je niet vertrouwt. Wat er
|
||||
niet in het alfabet zit gaat eruit, dus een jokerteken-certificaat voor `*.example.org` wordt
|
||||
`example.org`;
|
||||
- **uploaden kiest niet.** De nieuwe komt voorgeselecteerd in de lijst en de gebruiker drukt op de
|
||||
bestaande knop. Zo blijft er precies één plek waar TLS van certificaat wisselt, en dat is dezelfde
|
||||
reden waarom de app bij twijfel niets kiest.
|
||||
|
||||
Het geheim door een formulier: te verantwoorden omdat het pad achter de inlog van umbrelOS zit en de
|
||||
sleutel in de app-data van de gebruiker zelf landt, met rechten 0600. De agent kapt af op 96k en nginx
|
||||
ook, dus een verzoek dat te groot is komt niet eens bij de validatie.
|
||||
|
||||
|
||||
4. **Wat gebeurt er met de blokken-per-uur-grafiek in het eerste etmaal?** - **Vervallen** (19-08-2026).
|
||||
De vraag ging over een grafiek die er niet meer is: de gebruiker heeft blokken per uur diezelfde dag
|
||||
geschrapt, als grafiek én als tegel. Zie [PLAN.md](PLAN.md) §3.
|
||||
|
||||
1. **Wat toont de pagina als `status.json` ontbreekt?** - **Een neutrale melding, geen fout**
|
||||
(19-08-2026).
|
||||
"No readings yet", met de uitleg dat dit normaal is in de eerste minuten na een installatie of een
|
||||
herstart. Bewust neutraal opgemaakt en niet rood: het bestand ontbreekt in de normale gang van zaken
|
||||
even, en een foutkleur op een normale toestand leert mensen foutkleuren negeren.
|
||||
|
||||
Daarnaast blijft elk afzonderlijk veld op `unknown` staan in plaats van leeg. Een leeg veld leest als
|
||||
"in orde", en dit is de pagina die juist geraadpleegd wordt wanneer er iets mis lijkt.
|
||||
|
||||
2. **Nederlands of Engels?** - **Engels, en alles** (19-08-2026, gebruiker).
|
||||
Dat betekent de pagina én de teksten in `umbrel-app.yml`, want een Engelse pagina onder een
|
||||
Nederlandse winkelbeschrijving is een halve keuze. Codecommentaar blijft Nederlands: de
|
||||
projectafspraak koppelt zichtbare UI-tekst aan de taal van de app, en commentaar niet.
|
||||
@@ -0,0 +1,288 @@
|
||||
# Webinterface - plan
|
||||
|
||||
> Gepromoveerd op 19-08-2026 vanuit `Plannen/Masterplannen/`, omdat het werk begonnen is: de pagina is
|
||||
> herbouwd. Taken staan in [TAKEN.md](TAKEN.md), open punten in [OPEN.md](OPEN.md), de geschiedenis in
|
||||
> [PROGRESS.md](PROGRESS.md).
|
||||
>
|
||||
> **De afhankelijkheid van Configuratie is vervallen.** Die stond er omdat de pagina de ingestelde
|
||||
> waarden moet tonen. In het ontwerp dat er nu ligt haalt de pagina álles uit `status.json` en uit de
|
||||
> umbrel-variabelen, en staat er geen enkele installatiespecifieke waarde meer in het bestand. Daarmee
|
||||
> hoefde Configuratie er niet vóór, en is dit deel van Configuratie fase 2 meteen af.
|
||||
|
||||
## 1. Doel
|
||||
|
||||
De statuspagina toont verzonnen gegevens. De statuswaarden staan als de tekst `Online` in de HTML, het
|
||||
domein staat er hardgecodeerd in en er wordt niets uitgelezen. De pagina meldt dus ook "Online" als
|
||||
stunnel omgevallen is, en dat is erger dan geen pagina: hij wordt geraadpleegd juist wanneer er iets mis
|
||||
lijkt, en geeft dan het verkeerde antwoord.
|
||||
|
||||
Als dit af is, toont de pagina alleen dingen die waar zijn, of hij zegt dat hij het niet weet.
|
||||
|
||||
## 2. Afbakening
|
||||
|
||||
Vastgesteld op 18-08-2026, na het zien van de pagina in bedrijf.
|
||||
|
||||
- De verzonnen status en het verzonnen logvenster eruit.
|
||||
- **Blokhoogte en backend-status.** De hoogte via het Electrum-protocol, plus welke implementatie actief
|
||||
is en of hij antwoordt. Dit is meteen de echte gezondheidscontrole.
|
||||
- **Certificaat:** geldig tot, resterende dagen, een zichtbare waarschuwing onder de dertig dagen, en het
|
||||
tijdstip van de laatste herlading.
|
||||
- **Reactietijd van de backend**, en de geschiedenis daarvan als sparkline.
|
||||
- Aansluiten op het design-systeem in `HomeGit/Docs/website-design-system.html`: donker-eerst met een
|
||||
lichte variant, tokens voor kleur en radius, en de bestaande componenten `card`, `card-stat`, `badge`,
|
||||
`alert` en `list-item`.
|
||||
- **Verbindingsregels per client**, met kopieerknop. Toegevoegd 19-08-2026 op verzoek van de gebruiker.
|
||||
De ene wallet wil `domein:poort:s` op één regel, de andere wil host en poort in aparte velden met SSL
|
||||
aangevinkt, en juist die kleine verschillen kosten mensen tijd. De rijen komen uit
|
||||
[Referenties/Clients.md](../../Referenties/Clients.md) §4; wie er een bijzet, zet hem daar ook bij.
|
||||
- **Een activiteitenlog**, zie §4e. Herziening van een eerder niet-doel.
|
||||
|
||||
## 3. Niet-doelen
|
||||
|
||||
- **Een backend of API.** Zodra de pagina iets moet opvragen, is er een proces nodig dat luistert, en dan
|
||||
is dit geen configuratie-app meer. De weg eromheen staat in §4.
|
||||
- **Live logs, in de zin van een logvenster.** Ruwe logregels in de browser vragen precies de backend uit
|
||||
het vorige punt, en bij een TLS-proxy staan er verbindingsgegevens in. `docker logs` blijft de plek
|
||||
voor de echte logs. Wat er **wel** komt is een uitgedunde samenvatting per sessie; zie §4e. Dat is
|
||||
op 19-08-2026 herzien op verzoek van de gebruiker, en het is een andere zaak dan een logvenster.
|
||||
- **Instellingen bewerken in de pagina.** Uitdrukkelijk zo besloten in het plan **Configuratie**.
|
||||
- **Koersgegevens en koersgrafieken.** Besloten op 18-08-2026, na afweging. Het vraagt een externe API,
|
||||
en dan haalt de browser van iedereen die dit dashboard opent data op bij een derde partij. Bij een
|
||||
zelfgehoste Bitcoin-opstelling is dat precies het soort lek dat deze app juist dichtzet, en umbrelOS
|
||||
heeft er bovendien al widgets voor. **Alles op het dashboard komt uit lokale bronnen.**
|
||||
- **Verbindingen per uur als grafiek.** Kan wel, maar bij één of twee wallets is die grafiek vrijwel
|
||||
leeg. Het activiteitenlog uit §4e dekt dezelfde vraag beter.
|
||||
- **De blokhoogte zelf als grafiek.** Die loopt met ongeveer één per tien minuten omhoog, dus het is
|
||||
altijd dezelfde schuine lijn.
|
||||
- **Blokken per uur, in welke vorm dan ook.** Geschrapt op 19-08-2026 door de gebruiker, nadat het als
|
||||
grafiek én als tegel op de pagina had gestaan. Het antwoordt op een vraag die de gebruiker niet heeft:
|
||||
of de node meekomt met het netwerk is de zorg van de Electrum-server en niet van deze proxy, en de
|
||||
blokhoogte zelf zegt dat al. Gevolg voor het ontwerp: `history` in `status.json` hoeft alleen nog de
|
||||
reactietijd te bewaren, want de sparkline is de enige afnemer.
|
||||
- **De afweging Tor tegenover TLS op het dashboard.** Ook 19-08-2026, door de gebruiker. Die uitleg is
|
||||
positionering en hoort in de winkelbeschrijving in `umbrel-app.yml`, waar iemand staat te kiezen. Wie
|
||||
het dashboard opent, heeft al gekozen en komt iets nakijken. De onderbouwing blijft in
|
||||
[Referenties/Clients.md](../../../Referenties/Clients.md) §1 staan; die voedt nu alleen de marketing.
|
||||
|
||||
## 4. Ontwerp
|
||||
|
||||
### 4a0. Wél een backend, en waarom die er alsnog is
|
||||
|
||||
Herzien op 19-08-2026, nadat de gebruiker vroeg of de WebDAV-truc uit §4f van
|
||||
**Configuratie** eigenlijk de gebruikelijke manier is om een backend in een Umbrel-app te bouwen. Het
|
||||
antwoord was nee, en het onderzoek eromheen veranderde deze paragraaf.
|
||||
|
||||
**Wat umbrelOS zelf aanbiedt is één instelling per app: de afhankelijkheidskeuze.** In
|
||||
`AppSettingsSchema` staat `dependencies: z.record(z.string())` en verder niets. Daarom kostte het wisselen
|
||||
tussen Electrs, Fulcrum en ElectrumX twee regels: dát mechanisme bestaat. Er is géén generiek
|
||||
instellingenformulier dat een community-app kan declareren, en de andere umbrel-haken (`hooks/`,
|
||||
`exports.sh`, `*.template`) zijn er voor het opstarten en voor andere apps, niet voor de gebruiker.
|
||||
|
||||
**Apps die wél instelbare configuratie hebben, zijn zelf een backend.** Nginx Proxy Manager, Home
|
||||
Assistant en Jellyfin brengen hun eigen server en hun eigen instellingenscherm mee, in hun eigen image.
|
||||
umbrelOS levert dat scherm niet; de app doet het. De juiste conclusie is dus niet "umbrelOS heeft er iets
|
||||
voor" maar "die apps hebben een backend".
|
||||
|
||||
**Besluit van de gebruiker: een tweede container met een klein programma.** Een officiële
|
||||
`python:3-alpine`, met het script uit `agent.py.template` zodat het bij een update meekomt. Geen eigen
|
||||
image, dus geen bouwstap, geen registry en geen multi-arch-gedoe. Dat laatste is de reden dat een eigen
|
||||
image afvalt, niet de complexiteit van het programma.
|
||||
|
||||
Wat die keuze onderweg oploste, en dat was de eigenlijke aanleiding:
|
||||
|
||||
- **de shell-lus was aan zijn plafond.** Een certificaatdatum lezen, een JSON-RPC-verzoek doen, een
|
||||
geschiedenis bijhouden en een keuze valideren zijn geen dingen die je met `openssl` en `nc` aan elkaar
|
||||
knoopt zonder dat het stil verkeerde antwoorden gaat geven;
|
||||
- **de controles op `openssl`, `nc` en de WebDAV-module vervallen alle drie.** De agent doet dat werk zelf
|
||||
met de standaardbibliotheek, dus de app hangt niet meer af van wat er toevallig in de nginx-image zit;
|
||||
- **het hardgecodeerde domein is weg uit `docker-compose.yml` en `nginx.conf.template`.** De agent
|
||||
schrijft `cert.conf` met de paden die hij gevonden heeft, en nginx doet daar een `include` op. Daarmee
|
||||
is dat deel van **Configuratie** fase 2 af.
|
||||
|
||||
**Wat het kost.** Een tweede container, en een echt API-oppervlak in plaats van geen. Klein, maar niet
|
||||
nul, en daarom staat de verantwoording bij de `location /api/` in `nginx.conf.template` en niet alleen
|
||||
hier.
|
||||
|
||||
**nginx herladen kan de agent niet zelf**, want dat vraagt de Docker-socket en die is er bewust uit. De
|
||||
agent zet een vlagbestand neer en de nginx-container herlaadt zichzelf zodra hij dat ziet. Die lus
|
||||
verplaatst wat eerst de certificaatbewaking was, en doet nu alleen nog dit ene ding.
|
||||
|
||||
### 4a. Statusgegevens uit status.json
|
||||
|
||||
De pagina vraagt nooit iets aan een dienst die kan omvallen: de agent schrijft elke ronde een
|
||||
`status.json`, en de pagina haalt dat op met `fetch` en vult zichzelf. Dat blijft de kern, ook nu er een
|
||||
agent is; het alternatief, een pagina die live naar de backend vraagt, zou de pagina zelf laten hangen
|
||||
als de backend hangt.
|
||||
|
||||
Wat er in staat: het domein en de poort waar de wallet heen moet, het adres en de naam van de backend, de
|
||||
blokhoogte en de reactietijd, de einddatum van het actieve certificaat, de lijst met gevonden
|
||||
certificaten, een geschiedenis van reactietijden over 24 uur, en de logregels. Plus het tijdstip van
|
||||
schrijven, en dat is het belangrijkste veld van allemaal.
|
||||
|
||||
Wat de vorm oplevert:
|
||||
|
||||
- **de pagina kan niet meer liegen over "draait het".** Elk veld heeft een zichtbare onbekend-toestand en
|
||||
nooit een lege waarde, want een leeg veld leest als "in orde". Dit is de pagina die juist geraadpleegd
|
||||
wordt wanneer er iets mis lijkt;
|
||||
- **oude gegevens zijn herkenbaar, en wel bij de waarde zelf.** Onder de blokhoogte staat "as of ... ago",
|
||||
de badge bij de backend gaat van groen naar grijs met "last answered", en de voettekst noemt het
|
||||
tijdstip. Dat is de enige manier waarop de pagina een gestopte agent kan opmerken.
|
||||
|
||||
**Bewust geen melding bovenaan daarvoor.** Die heeft er even gestaan en is er op 19-08-2026 op verzoek
|
||||
van de gebruiker uit. De afweging is het opschrijven waard, want hij geldt voor elke volgende melding
|
||||
die iemand wil toevoegen: een banner die hetzelfde zegt als wat er drie regels lager bij het getal
|
||||
staat, voegt geen informatie toe maar wel gewicht, en dat gewicht gaat ten koste van de meldingen die
|
||||
wél iets nieuws zeggen. Een melding bovenaan is er voor iets wat je nergens anders ziet, zoals een
|
||||
ontbrekend certificaat;
|
||||
- **de lus valt nooit stil.** Een mislukte ronde wordt gelogd en overgeslagen; stoppen zou de pagina op
|
||||
oude gegevens bevriezen zonder dat iemand het ziet.
|
||||
|
||||
### 4a1. De indeling van de pagina
|
||||
|
||||
Vastgesteld door de gebruiker op 19-08-2026, na het bekijken van de eerste versie.
|
||||
|
||||
**De volgorde, van boven naar beneden:** Electrum-server, de drie statustegels, de certificaatkeuze, het
|
||||
activiteitenlog, en onderaan het instellen van je wallet. De regel erachter: **eerst waar je naar kijkt
|
||||
als je iets nakomt, onderaan waar je naar kijkt als je iets instelt.** Dat laatste doe je één keer.
|
||||
|
||||
De laatste twee zijn op verzoek van de gebruiker omgedraaid ten opzichte van de eerste opzet. Dat pakte
|
||||
beter uit dan alleen als voorkeur: het certificaatkader is nu het smalle kader links en het log het brede
|
||||
rechts, waardoor de kolomgrens samenvalt met die van de rij erboven in plaats van ertegenin te lopen. En
|
||||
logregels zijn monospace, dus die hebben de breedte beter nodig dan een lijst met keuzerondjes.
|
||||
|
||||
**Twee kaders zijn er één geworden.** "Point your wallet here" en "Setting up your wallet" stelden dezelfde
|
||||
vraag, dus het verbindingsadres met de kopieerknop staat nu bovenaan het instelkader in plaats van in een
|
||||
eigen kader erboven.
|
||||
|
||||
**Breed, met kaders naast elkaar.** Twaalf kolommen, en de rijen wisselen 5/7 en 7/5 af: de
|
||||
Electrum-server naast de statustegels, het log naast de certificaatkeuze, en het instelkader vol breed.
|
||||
Afgekapt op 1760px, want op een ultrawide monitor levert een kader van 2500px regels op die niemand leest.
|
||||
|
||||
**Elk kader is hetzelfde opgebouwd.** Een `card-head` met een titel in `t-h3`, dan de inhoud. Bijgesteld op
|
||||
19-08-2026 door de gebruiker: de drie statustegels hadden een eigen kleine grijze kop in kapitalen, en dat
|
||||
maakte ze een apart soort ding zonder dat daar een reden voor was. De titel gebruikt de token
|
||||
`--text-primary` en niet letterlijk wit, want in de lichte variant is wit onzichtbaar.
|
||||
|
||||
Wat daarbij vastligt en niet per ongeluk mag verschuiven:
|
||||
|
||||
- **de leesvolgorde in de HTML ís de bedoelde volgorde.** Er staat nergens een `order` of een `row-start`
|
||||
die de opmaak laat afwijken van de bron, dus bij een smal scherm stapelt alles precies zoals het gelezen
|
||||
hoort te worden. Wie hier een kader bijzet, zet het op de goede plek in de HTML en niet op de goede plek
|
||||
in het raster;
|
||||
- **de statustegels rekken mee met hun buur**, met de titel boven en het getal onder, want van zichzelf
|
||||
zijn ze lager dan het kader ernaast en dan staat er een gat rechtsboven. De onderregel van een tegel
|
||||
heeft daarvoor dezelfde hoogte als de sparkline, anders staat het getal van "Backend response" hoger dan
|
||||
de andere twee;
|
||||
- **het logblok scrollt zelf horizontaal in plaats van af te kappen.** Met puntjes zou een smal scherm de
|
||||
bytes stil verbergen, en dat is dezelfde soort onwaarheid als een verzonnen statuswaarde;
|
||||
- **twee kaders naast elkaar zijn even hoog**, en het langste bepaalt de rij. Wat mag meegroeien zegt dat
|
||||
zelf: het logblok en de certificaatlijst. Daardoor is de certificaatlijst een scrollend vak in plaats van
|
||||
een lijst die de pagina oprekt, en dat was nodig: een gedeelde certificatenmap kan er tientallen bevatten.
|
||||
Het aantal staat in de kop, want zodra er een scrollbalk is, is niet meer te zien hoeveel er onder de rand
|
||||
staan.
|
||||
|
||||
**Bewust een lijst en geen dropdown.** De gebruiker vroeg op 19-08-2026 of een dropdown niet netter was,
|
||||
en dat is het visueel ook, maar het botst met wat dit besturingselement moet doen: je kiest hier op de
|
||||
hostnaam waarop je wallet verbindt, en dan wil je bron, naam en resterende dagen naast elkaar kunnen
|
||||
vergelijken. In een dropdown zie je er één per keer, en een verlopen certificaat kan er niet rood in
|
||||
omdat `option`-opmaak per browser verschilt. De hoogtewinst die de dropdown zou opleveren komt er met een
|
||||
scrollend vak ook, dus er hoefde niets ingeleverd te worden;
|
||||
|
||||
- **er is geen voetregel.** Er heeft er een gestaan met "Last reading ... ago" en het versienummer; die is
|
||||
er op verzoek van de gebruiker uit. De leeftijd stond al bij de waarden zelf, dus dat was een derde keer
|
||||
hetzelfde.
|
||||
|
||||
Het **versienummer** is wel gebleven, klein achter de tagline als `v0.0.3`. Dat is een aparte afweging en
|
||||
hij viel andersom uit dan de rest van de voetregel: dit project verloor een keer een dag aan een wijziging
|
||||
die niet uitrolde door een niet-verhoogde `version`, en dan is "welke versie zie ik nu eigenlijk" precies
|
||||
de vraag die je stelt. Het staat in `--text-sec` en niet in `--text-ter`, want die laatste is in de lichte
|
||||
variant `#bbbbbb` op wit en op deze grootte niet te lezen.
|
||||
|
||||
### 4b. Waarschuwen op een aflopend certificaat
|
||||
|
||||
Met de einddatum in `status.json` is dit een vergelijking in de pagina zelf: onder de dertig dagen een
|
||||
opvallende melding, verlopen een duidelijke fout. Dat is de enige echte toevoeging ten opzichte van nu,
|
||||
en hij is goedkoop omdat de datum er toch al is.
|
||||
|
||||
### 4c. Welke backend er gekozen is
|
||||
|
||||
Die volgt uit `${APP_ELECTRS_NODE_IP}` en `${APP_ELECTRS_NODE_PORT}`, maar dat is een IP-adres en geen
|
||||
naam. De adressen liggen per app vast (Electrs op `10.21.21.10`, Fulcrum op `10.21.21.200`, ElectrumX op
|
||||
`10.21.21.199`), dus een vertaaltabel kan er een naam van maken. Dat is aardig, maar het is een tabel die
|
||||
stilzwijgend veroudert als Umbrel de adressen wijzigt. Voorstel: het adres tonen, en de naam alleen als
|
||||
extra wanneer hij in de tabel staat. Dan is de pagina bij veroudering minder informatief in plaats van
|
||||
onwaar.
|
||||
|
||||
### 4e. Het activiteitenlog
|
||||
|
||||
Toegevoegd 19-08-2026, nadat de gebruiker vroeg of er iets over live client-aanroepen te tonen is, en
|
||||
diezelfde dag bijgesteld naar logregels onder elkaar in plaats van een lijst met sessiekaarten.
|
||||
|
||||
**Eerst de grens, want die bepaalt de rest. Een regel per protocolaanroep kan niet.** De wallet doet zijn
|
||||
verzoeken *binnen* één TLS-verbinding die hier getermineerd wordt en daarna als bytestroom naar de backend
|
||||
gaat. nginx `stream` kent geen verzoeken, alleen verbindingen. Ze wél tellen zou betekenen dat de app de
|
||||
Electrum-berichten van de gebruiker uitleest, en dat is precies het verkeer waarvoor deze app bestaat. Dat
|
||||
is geen implementatiedrempel maar een ontwerpgrens, en hij hoort ook op de pagina te staan zodat niemand
|
||||
denkt dat het log iets verzwijgt.
|
||||
|
||||
Wat er wél per regel in kan:
|
||||
|
||||
| Gebeurtenis | Waar het vandaan komt |
|
||||
|-|-|
|
||||
| `connect` | de verbindingsteller is opgelopen sinds de vorige ronde |
|
||||
| ~~`traffic`~~ | vervallen op 20-08-2026, zie punt 2 onderaan deze paragraaf |
|
||||
| `disconnect` | de `access_log`-regel van nginx, met duur en bytes |
|
||||
| `probe` | een sessie die eindigde zonder één byte in beide richtingen. Toegevoegd 20-08-2026: een doorgestuurde poort wordt gescand, en zonder dit onderscheid gaf elke scan een rode `refused`-regel terwijl er niets geweigerd is. Bewust op de bytes en niet op de duur of de status: een scan die tien seconden open blijft is nog steeds een scan, en een echte sessie die na een halve seconde omvalt is nog steeds een storing |
|
||||
| `refused` | de verbinding gaf wél verkeer door en liep daarna stuk. Dit is het geval dat rood mag zijn |
|
||||
| `reload` | het certificaat is gewijzigd en nginx is herladen |
|
||||
| `start` | de container is gestart en luistert |
|
||||
|
||||
Die regels komen als `log` in `status.json`, afgekapt op 24 uur. De pagina toont ze nieuwste bovenaan, in
|
||||
een monospace-blok dat scrollt.
|
||||
|
||||
**Bewust niet gelogd: het IP-adres van de client en de bronpoort.** Dat is precies het soort gegeven dat
|
||||
deze app van het netwerk af houdt, en om te zien dát het werkt is het niet nodig.
|
||||
|
||||
Twee dingen die eerst uitgezocht moeten worden, en die het bouwen kunnen blokkeren:
|
||||
|
||||
1. **Een `log_format` bevat nginx-variabelen met een dollarteken, en dit bestand is een template.** De
|
||||
invulling bij het starten vervangt die en zou ze leegmaken; dat is dezelfde valkuil die nu bovenaan
|
||||
`nginx.conf.template` beschreven staat. De uitweg is de `log_format` niet in het template te zetten
|
||||
maar door het `command`-blok in `docker-compose.yml` te laten wegschrijven als een `include`-bestand,
|
||||
want daar wordt een dollarteken al als `$$` ontsnapt. Te verifiëren.
|
||||
2. **nginx `stream` schrijft zijn regel pas bij het sluiten van de sessie.** Een verbinding die twaalf uur
|
||||
openstaat, verschijnt dus pas na afloop, en dat is de normale toestand van een wallet. Daarom komen
|
||||
`connect` en `traffic` niet uit de log maar uit de lopende verbinding; anders lijkt een actieve wallet
|
||||
afwezig. **Uitgezocht en gebouwd op 20-08-2026, nadat de gebruiker meldde dat hij van zijn verbonden
|
||||
wallet niets terugzag:**
|
||||
|
||||
- **`connect` komt uit `/proc/net/tcp`.** Kolom 2 is het lokale adres met de poort in hex, kolom 4 de
|
||||
toestand; tellen wat op `:C366` staat met toestand `01` geeft het aantal open wallet-verbindingen.
|
||||
Dat bestand geldt **per netwerk-namespace**, en daar zit de bevinding: de agent kan het niet lezen,
|
||||
want hij zit in een andere container. De teller staat daarom in de achtergrondlus van de
|
||||
nginx-container, die het aantal naar een bestand schrijft dat de agent oppikt. Zelfde patroon als de
|
||||
herlaadvlag, en om dezelfde reden: geen Docker-socket. Geteld wordt alleen het aantal;
|
||||
- **`traffic` vervalt.** Bytes van een lopende sessie zijn er niet af te lezen: `/proc/net/tcp` heeft
|
||||
geen tellers, en de interfacetellers van de container bevatten ook het dashboard- en backendverkeer.
|
||||
Wat er dan overblijft is een schatting die als meting leest, en dat is precies wat §4c verbiedt. De
|
||||
sessieregel bij het sluiten geeft de echte aantallen;
|
||||
- **de pagina toont de teller in de badge van het activiteitenlog** en niet als logregel alleen. De
|
||||
vraag is "is mijn wallet nu verbonden", en die hoort niet uit een lijst afgeleid te worden.
|
||||
|
||||
## 5. Het werk
|
||||
|
||||
Staat in [TAKEN.md](TAKEN.md), met de fase-indeling en wat er af is.
|
||||
|
||||
## 6. Open punten
|
||||
|
||||
Staan in [OPEN.md](OPEN.md).
|
||||
|
||||
## 7. Verificatie
|
||||
|
||||
Handmatig, want het gaat om wat er in een browser staat:
|
||||
|
||||
- de pagina toont het werkelijk ingestelde domein en de werkelijke poorten, niet die uit de HTML;
|
||||
- na een certificaatvernieuwing verandert de einddatum op de pagina;
|
||||
- **stunnel of de proxy stoppen laat de pagina niet "Online" tonen.** Dit is de controle die de aanleiding
|
||||
van dit plan afdekt en de enige die per se gedaan moet worden;
|
||||
- een certificaat dat binnen dertig dagen verloopt, geeft een zichtbare waarschuwing.
|
||||
@@ -0,0 +1,339 @@
|
||||
# Voortgang - Webinterface
|
||||
|
||||
## 20-08-2026 - scans zijn geen weigeringen, en meer lucht tussen de kaders
|
||||
|
||||
De gebruiker vroeg wat een logregel `refused ... status 500` met nul bytes betekende. Antwoord: een
|
||||
TLS-handdruk die niet is afgemaakt, en op een doorgestuurde poort vrijwel altijd een scanner. Dat is geen
|
||||
storing, maar het log liep er wel vol met rode regels die suggereerden dat de app iets geweigerd had.
|
||||
|
||||
**Nu een eigen soort `probe`, en de grens ligt bij de bytes.** Niet bij de duur en niet bij de status: een
|
||||
scan die tien seconden open blijft is nog steeds een scan, en een sessie die na een halve seconde omvalt
|
||||
maar wél verkeer had is nog steeds een storing. Dat de bytetellers niets over de handdruk zeggen, bleek uit
|
||||
de sessies van de gebruiker zelf: een mislukte verbinding kwam op 0 en 0 uit terwijl er wél een handdruk
|
||||
geprobeerd is. Rood is nu voorbehouden aan het geval waar je iets aan moet doen.
|
||||
|
||||
Verder de ruimte tussen de kaders van 1 naar 1,5rem. De kaders hebben 1,8rem binnenin, dus de ruimte ertussen
|
||||
was kleiner dan die erbinnen; dat is de reden dat het krap aanvoelde.
|
||||
|
||||
**Geraakt:** `agent.py.template`, `index.html.template`, `umbrel-app.yml` (0.0.14), `PLAN.md` §4e-tabel,
|
||||
`tests/test_agent_certificates.py`. **Tests:** 54 goed 0 fout en 39 goed 0 fout, niets overgeslagen; de
|
||||
indeling van de sessieregels is mutatie-getest met een grens op de duur in plaats van de bytes, en dat viel
|
||||
om zoals het moest.
|
||||
|
||||
## 20-08-2026 - de mobiele opmaak, en een tegel minder
|
||||
|
||||
De pagina liep op een telefoon buiten beeld. **De oorzaak was één regel CSS:** de clientlijst stond op
|
||||
`minmax(420px, 1fr)`, en dat eist een track van minstens 420 pixels ook op een smaller scherm. Nu met
|
||||
`min(420px, 100%)` eromheen. Daarbij vouwen de lijstregels en de logregels onder de 700 pixels om, met de
|
||||
waarde onder de titel in plaats van ernaast.
|
||||
|
||||
Voor de logregels is dat een **herziening** van een eerdere keuze: die scrollen liever dan dat ze afkappen,
|
||||
omdat de kolomvorm dan blijft staan. Dat argument geldt op een breed scherm en daar blijft het zo, maar op
|
||||
een telefoon betekende het dat je de bytes nooit zag.
|
||||
|
||||
Verder is de tegel met het aantal dagen tot het certificaat verloopt eruit, op verzoek van de gebruiker.
|
||||
Dezelfde redenering als bij de badges: de kaart eronder zegt het al, en met een datum erbij. Backend
|
||||
response is nu twee kolommen breed, want de sparkline is het enige op die rij dat met breedte iets doet.
|
||||
|
||||
**Diezelfde dag nagekeken op een telefoon en het ziet er goed uit.** Eén regressie kwam eruit: door het
|
||||
omvouwen volgde de kopieerknop de tekst, en het ene adres is langer dan het andere, dus stonden de knoppen
|
||||
niet op één lijn. Verholpen in **0.0.11** met `margin-left: auto` op de knop, en niet met `space-between` op
|
||||
de rij: bij de gesplitste weergave staat er ook een notitie naast de waarde die daar tegenaan hoort te
|
||||
blijven staan.
|
||||
|
||||
Bijvangst die geen opmaak is: **`0.0.10` na `0.0.9` leverde gewoon een update op.** Daarmee is de aanname
|
||||
uit die release bevestigd en is een tekstvergelijking met groter-dan uitgesloten. Staat in de naslag, want
|
||||
het scheelt de volgende keer een omweg via `0.1.0`.
|
||||
|
||||
**Geraakt:** `index.html.template`, `umbrel-app.yml` (0.0.10 en 0.0.11), `CHANGELOG.md`,
|
||||
`Referenties/Umbrel-appstore-spec.md`. **Tests:** 39 goed 0 fout op de manifest- en configuratietoetsen; aan
|
||||
de agent is niets geraakt.
|
||||
|
||||
## 20-08-2026 - nagekeken in de browser, en dit plan is nu tier A
|
||||
|
||||
Na de verse installatie van 0.0.9 heeft de gebruiker alles nagekeken wat alleen met de hand kan.
|
||||
**Uploaden werkt, kiezen werkt, ook met de certificaten uit Zoraxy**, de keuzelijst bij het installeren zag
|
||||
er goed uit en het versienummer op de pagina klopt. Daarmee is het uploadpad uit 0.0.7 bewezen op het
|
||||
gelukkige pad; alleen de weigering bij een sleutel die niet bij het certificaat hoort is nog niet in een
|
||||
browser gezien.
|
||||
|
||||
**Dit plan is naar tier A gegaan** en van nummer 020 naar 005. Niet omdat er meer werk bij kwam, maar omdat
|
||||
het het enige plan is met werk dat nu te doen is: **Appstore** is in de kern af en wacht op een herstart die
|
||||
niet te plannen is, en **Publicatie** wacht op een publieke repo.
|
||||
|
||||
Eén nieuwe bevinding van de gebruiker om mee te beginnen: in mobiele weergave lopen de verbindingsregels
|
||||
met hun kopieerknoppen en de logregels buiten beeld. Dat laatste is een bewuste keuze geweest (de logregels
|
||||
scrollen liever dan dat ze afgekapt worden), maar op een telefoon is dat het verkeerde antwoord.
|
||||
|
||||
**Geraakt:** alleen documentatie. **Tests:** niet van toepassing.
|
||||
|
||||
## 20-08-2026 - uploaden gebouwd, en de pagina verder uitgekleed
|
||||
|
||||
**Een certificaat uploaden kan nu via de pagina**, open punt 6. Het echte werk zat niet in het formulier
|
||||
maar in de validatie: het paar gaat onder een `.tmp`-naam naar de doelmap en wordt daar door
|
||||
`ssl.SSLContext.load_cert_chain` geopend, dezelfde OpenSSL die nginx straks gebruikt. Zonder die controle
|
||||
levert een verkeerde sleutel een nginx die niet meer herlaadt, en dat is dezelfde klasse storing als
|
||||
waardoor 0.0.3 niet startte. **De bestandsnaam komt uit het certificaat zelf**, dus de hele klasse padtrucs
|
||||
is weg zonder invoerfiltering. Uploaden kiest niet: de nieuwe komt voorgeselecteerd in de lijst.
|
||||
|
||||
Twee dingen die bij het bouwen bijna fout gingen en het opschrijven waard zijn: `os.replace` uit `/tmp`
|
||||
naar `/certs/own` faalt met EXDEV omdat dat een bind-mount is, en `-subj "/CN=../.."` in openssl leest de
|
||||
schuine streep als scheidingsteken, waardoor de padtruc-toets zichzelf stil oversloeg.
|
||||
|
||||
Verder op verzoek van de gebruiker: het app-icoon in de kop in plaats van het schildje, de badges uit de
|
||||
hoek van álle kaders, "your choice" weg achter het actieve certificaat, en Trezor Suite is niet
|
||||
desktop-only. Die laatste is de tweede keer dat leveranciersdocumentatie het aflegt tegen één keer kijken.
|
||||
Bijgevangen: de teller zweeg over een wallet die al verbonden was voordat de agent begon, en dat is precies
|
||||
het geval waarin iemand komt kijken.
|
||||
|
||||
Aan het eind van de dag nog één tekstbesluit: de pagina had een andere tagline dan de appstore, en die van
|
||||
de appstore wint (0.0.8). Zie [OPEN.md](OPEN.md) punt 8; de reden is dezelfde maatstaf als bij het
|
||||
hernoemen van de app, namelijk de opbrengst en niet het middel.
|
||||
|
||||
**Geraakt:** `agent.py.template`, `index.html.template`, `nginx.conf.template`, `docker-compose.yml`,
|
||||
`umbrel-app.yml` (0.0.7 en 0.0.8), `OPEN.md` punt 6 en 8, `Referenties/Clients.md`, beide testbestanden.
|
||||
**Tests:** 48 goed 0 fout en 24 goed 0 fout, niets overgeslagen; de sleutelcontrole en de beschrijfbare
|
||||
mount zijn mutatie-getest. **Niet geverifieerd:** het uploaden in een echte browser.
|
||||
|
||||
## 20-08-2026 - de pagina naast een werkende app, en §4e afgemaakt
|
||||
|
||||
Eerste sessie met een app die echt draait, en dat leverde meteen de bevinding op waar §4e om vroeg: de
|
||||
gebruiker zag van zijn verbonden wallet niets terug. Oorzaak is bekend en staat in het plan, namelijk dat
|
||||
nginx `stream` pas bij het sluiten van een sessie logt. Het open punt was hoe je de lopende verbinding dan
|
||||
wél afleest. **Antwoord: `/proc/net/tcp`, geteld in de nginx-container**, want dat bestand geldt per
|
||||
netwerk-namespace en de agent zit in een andere. Het aantal gaat via een bestand naar de agent, net als de
|
||||
herlaadvlag. **`traffic` is daarbij vervallen:** bytes van een lopende sessie zijn er niet af te lezen, en
|
||||
een schatting die als meting leest is precies wat §4c verbiedt.
|
||||
|
||||
Daarnaast een reeks verzoeken van de gebruiker, alle om dezelfde reden: de pagina was te druk. De
|
||||
certificaatkeuze is een dropdown geworden (met veertien certificaten was die lijst het drukste onderdeel
|
||||
van de pagina, voor iets wat je één keer doet), `disconnected` heet `session ended` met leesbare details
|
||||
erachter, en er zijn vijf stukken tekst geschrapt: de voetnoot onder het log, de regel bij Certificate, de
|
||||
stip in de badges, de zin over apps op de Umbrel zelf en de uitleg over één regel versus twee velden.
|
||||
Bijgevangen bij de dropdown: de oude keuzelijst zette zichzelf elke ronde terug, dus een keuze verdween
|
||||
binnen tien seconden weer. Verder heet Blockstream Green nu Blockstream; die app is omgedoopt.
|
||||
|
||||
**Geraakt:** `index.html.template`, `agent.py.template`, `docker-compose.yml`, `umbrel-app.yml` (0.0.6),
|
||||
`PLAN.md` §4e, `OPEN.md` punt 6 en 7, `Referenties/Clients.md`, `tests/`. **Tests:** 29 goed 0 fout en 19
|
||||
goed 0 fout, niets overgeslagen; de teller en de logregel zijn mutatie-getest. **Niet geverifieerd:** alles
|
||||
in de browser, dus de dropdown, de hoogtes en de badge. Dat is handwerk van de gebruiker.
|
||||
|
||||
## 19-08-2026 - sessie afgesloten; plan zakt naar tier C
|
||||
|
||||
Laatste twee wijzigingen van de dag: certificaat en activiteitenlog omgedraaid, en het losse
|
||||
verbindingsadres met kopieerknop eruit samen met het label "tested clients". Het omdraaien pakte beter uit
|
||||
dan als voorkeur alleen, want de kolomgrens valt nu samen met die van de rij erboven (x=738 in beide rijen)
|
||||
en logregels hebben de breedte beter nodig dan keuzerondjes. Het adres verdween zonder verlies: het staat
|
||||
bij elke clientregel in de vorm die díe client wil, met kopieerknop.
|
||||
|
||||
**Het plan zakt van A naar C**, wachtend op de installatie. De pagina is af voor zover dat zonder de Umbrel
|
||||
kan; al het resterende werk hier begint met kijken of de agent doet wat hij zou moeten doen.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template`, de plannen, `CONTINUE_HERE.md`.
|
||||
**Tests:** 21 goed, 0 fout. Die raken de pagina niet.
|
||||
**Niet geverifieerd:** de agent heeft nooit gedraaid, en ik heb de pagina zelf nooit gezien; het
|
||||
browserpaneel bleef dicht, dus alles is gemeten in plaats van bekeken.
|
||||
|
||||
## 19-08-2026 - voetregel weg, certificaatlijst scrollt, kaders gelijk
|
||||
|
||||
De voetregel met "Last reading ... ago" en het versienummer is eruit; de gebruiker houdt van een rustige
|
||||
interface en de leeftijd stond al bij de waarden zelf. Het **versienummer** is op verzoek dezelfde dag
|
||||
teruggezet, klein achter de tagline als `v0.0.3`: dit project verloor een keer een dag aan een wijziging
|
||||
die niet uitrolde door een niet-verhoogde `version`, en dan is dat precies de vraag die je stelt. Het
|
||||
staat in `--text-sec`, want `--text-ter` is in de lichte variant `#bbbbbb` op wit en op die grootte niet
|
||||
te lezen.
|
||||
|
||||
De gebruiker vroeg of de certificaatlijst een scrollbalk moest krijgen of beter een dropdown werd, en of
|
||||
het logblok en het certificaatkader dan even hoog konden. Het is een scrollende lijst geworden en geen
|
||||
dropdown, want je kiest hier op de hostnaam waarop je wallet verbindt en dan wil je bron, naam en
|
||||
resterende dagen kunnen vergelijken; in een dropdown zie je er één per keer en kan een verlopen
|
||||
certificaat er niet rood in. De hoogtewinst kwam er met een scrollend vak toch, dus er hoefde niets
|
||||
ingeleverd te worden. Het aantal staat nu in de kop, want met een scrollbalk is niet meer te zien hoeveel
|
||||
er onder de rand staan.
|
||||
|
||||
Gemeten met negentien certificaten: 1062px inhoud in een vak van 360px, en de knop blijft eronder staan.
|
||||
Met vier: geen scrollbalk, dus geen leeg vak. In beide gevallen zijn de twee kaders exact even hoog, 773px
|
||||
respectievelijk 636px. Eerst stond het vak op 460px, maar dan werd de rij 873px en vulde die op een
|
||||
1080p-scherm het hele beeld.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** 21 goed, 0 fout; die raken de pagina niet. Nagemeten op 1760px en op mobiel, in beide gevallen
|
||||
zonder horizontale schuifbalk en zonder console-fouten.
|
||||
|
||||
## 19-08-2026 - kaders gelijkgetrokken, en een badge die niets zei
|
||||
|
||||
De drie statustegels hadden een eigen kleine grijze kop in kapitalen en de andere kaders een witte titel.
|
||||
Op verzoek is dat nu overal hetzelfde: een `card-head` met een titel in `t-h3`. Wel met de token
|
||||
`--text-primary` en niet met letterlijk wit, want in de lichte variant is wit onzichtbaar. Bij het
|
||||
nameten bleek het getal van "Backend response" 21px hoger te staan dan de andere twee, omdat daar een
|
||||
sparkline onder hangt in plaats van een tekstregel; de onderregel van een tegel heeft nu dezelfde hoogte
|
||||
als die sparkline.
|
||||
|
||||
De badge "Serving this page" is eruit. De gebruiker wees erop dat die niets zegt: de pagina wordt nooit
|
||||
getoond aan een wallet die op 50022 verbindt. Mijn gedachte erachter was dat de pagina en de
|
||||
TLS-terminatie in dezelfde container zitten en dat de een de ander dus bewijst, maar dat stond er niet en
|
||||
zo leest niemand het. Een badge waarvan de betekenis niet in één zin op te schrijven is, hoort er niet te
|
||||
staan.
|
||||
|
||||
Wat dat wel opleverde, en dat is als open punt 5 vastgelegd: **de app controleert of de Electrum-server
|
||||
antwoordt, maar niet of hij zelf antwoordt**, en dat is zijn enige taak. Een TLS-verbinding naar de eigen
|
||||
poort zou het luisteren, het certificaat en de doorverbinding in één keer bewijzen. Nog geen taak, want
|
||||
het raakt de agent en die heeft nog nooit gedraaid.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** 21 goed, 0 fout; die raken de pagina niet. Gemeten in beide thema's en op 1760px: zeven
|
||||
identieke koppen, drie getallen op één lijn, geen horizontale schuifbalk, geen console-fouten.
|
||||
|
||||
## 19-08-2026 - de vervallen-melding eruit
|
||||
|
||||
De gebruiker vond de melding "Readings are out of date" niet nuttig, en dat klopt: dezelfde mededeling
|
||||
staat al onder de blokhoogte ("as of ... ago"), in de badge bij de Electrum-server die grijs wordt met
|
||||
"last answered", en in de voettekst met het tijdstip. De banner was een vierde keer hetzelfde en wel de
|
||||
hardste.
|
||||
|
||||
De berekening blijft staan, want die stuurt de badge; alleen de melding is weg. Gecontroleerd met een
|
||||
`status.json` van een uur oud: geen enkele melding zichtbaar, badge grijs met "last answered 2 hours ago",
|
||||
"as of 2 hours ago" onder de blokhoogte, en de voettekst met datum en tijd. Er gaat dus geen informatie
|
||||
verloren.
|
||||
|
||||
De afweging staat nu in [PLAN.md](PLAN.md) §4a, omdat hij geldt voor elke volgende melding die iemand wil
|
||||
toevoegen: een banner is er voor iets wat je nergens anders ziet.
|
||||
|
||||
Wat de gebruiker zag was trouwens de preview en niet de app: die `status.json` is een vast bestand dat
|
||||
niets ververst, dus die verloopt altijd als je het tabblad open laat staan.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** 21 goed, 0 fout; die raken de pagina niet.
|
||||
|
||||
## 19-08-2026 - de pagina opnieuw ingedeeld, breed en met kaders naast elkaar
|
||||
|
||||
De gebruiker zag dat "Point your wallet here" en "Setting up your wallet" dezelfde vraag stelden. Die zijn
|
||||
er één geworden, en dat kader is naar onderen verhuisd. De volgorde is nu: Electrum-server, de drie
|
||||
statustegels, het activiteitenlog, de certificaatkeuze, en onderaan het instellen. De regel erachter is de
|
||||
moeite van het opschrijven waard, want hij beslist waar een volgend kader komt: eerst waar je naar kijkt
|
||||
als je iets nakomt, onderaan waar je naar kijkt als je iets instelt.
|
||||
|
||||
Op verzoek ook breed, met kaders naast elkaar: twaalf kolommen, rijen die 5/7 en 7/5 afwisselen, afgekapt
|
||||
op 1760px omdat een kader van 2500px regels oplevert die niemand leest. Belangrijk detail dat bewust zo is
|
||||
gebouwd: er staat geen `order` in de CSS, dus de leesvolgorde in de HTML is de bedoelde volgorde en
|
||||
stapelen op een smal scherm geeft exact dezelfde reeks.
|
||||
|
||||
Twee dingen die het meten opleverde en die anders waren blijven staan. De statustegels waren 146px naast een
|
||||
kader van 293px, dus stond er een gat rechtsboven; ze rekken nu mee en zetten hun inhoud onderaan. En het
|
||||
logblok kapte op een smal scherm de bytes af met puntjes; het scrollt nu zelf horizontaal, want stil
|
||||
verbergen is dezelfde soort onwaarheid als een verzonnen statuswaarde.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** de suite raakt de pagina niet; wel gedraaid en groen (21). Gecontroleerd via de afmetingen van
|
||||
de kaders op 1760px en op mobiel: volgorde gelijk, geen horizontale schuifbalk op de pagina, logblok
|
||||
scrollt zelf, geen console-fouten.
|
||||
**Niet geverifieerd:** ik heb de pagina niet met eigen ogen gezien; het browserpaneel stond dicht, dus dit
|
||||
is gemeten en niet bekeken.
|
||||
|
||||
## 19-08-2026 - een tweede container, en de eerste tests in dit project
|
||||
|
||||
De gebruiker vroeg of de WebDAV-truc de gebruikelijke manier is om een backend in een Umbrel-app te
|
||||
bouwen. Dat was hij niet, en het uitzoeken veranderde het ontwerp. umbrelOS biedt precies één instelling
|
||||
per app, de afhankelijkheidskeuze in `AppSettingsSchema`; apps met instelbare configuratie zijn zelf een
|
||||
backend, in hun eigen image. De gebruiker koos daarop een tweede container met een klein python-programma,
|
||||
uit een `*.template` zodat het bij een update meekomt, zonder eigen image.
|
||||
|
||||
Dat loste meer op dan de keuzelijst. De controles op `openssl`, `nc` en de WebDAV-module zijn alle drie
|
||||
vervallen, want de agent doet dat werk met de standaardbibliotheek. En het hardgecodeerde domein is weg uit
|
||||
`docker-compose.yml` en `nginx.conf.template`: de agent schrijft `cert.conf` en nginx doet daar een
|
||||
`include` op. Daarmee is dat deel van **Configuratie** fase 2 af.
|
||||
|
||||
Twee dingen die het bouwen opleverde. De standaardbibliotheek heeft geen X.509-parser, dus die is er nu:
|
||||
een DER-lezer voor de einddatum en de domeinnamen. Dat is precies het soort code dat niet faalt met een
|
||||
fout maar met een verkeerd antwoord, en een certificaatdatum die er een jaar naast zit valt nooit op.
|
||||
Daarom is hij getoetst tegen `ssl` op 74 echte CA-certificaten, op een levend servercertificaat voor de
|
||||
subjectAltName, en op beide tijdvormen met zelfgebouwde certificaten, want het CA-materiaal gebruikt
|
||||
uitsluitend UTCTime na 2000. Dit project had nog geen suite; die staat nu in `tests/` en `CLAUDE.md`
|
||||
vertelt hoe je hem draait.
|
||||
|
||||
Het tweede: bij het schrijven van de compose bleek mijn eigen `choose` het plan **Configuratie** §4c tegen
|
||||
te spreken. Die koos bij meerdere certificaten "de langst geldige", terwijl daar uitdrukkelijk staat dat er
|
||||
niet gegokt mag worden. Nu weigert de app en noemt de kandidaten, en de pagina zet er een foutmelding
|
||||
boven, want geen certificaat betekent geen TLS.
|
||||
|
||||
**Geraakt:** nieuw `whatsnext-electrum-gate/agent.py.template`, nieuw `tests/`, nieuw `CLAUDE.md`,
|
||||
gewijzigd `docker-compose.yml`, `nginx.conf.template`, `index.html.template`, en de plannen.
|
||||
**Tests:** 21 goed, 0 fout. Mutatietest gedaan op de twee guards: de keuze-validatie en de verloopfilter,
|
||||
allebei met de juiste enkele test die omvalt.
|
||||
**Niet geverifieerd:** de agent heeft nog nooit op de Umbrel gedraaid. Alles over de echte werking, dus de
|
||||
certificaatscan op de Zoraxy-map, de Electrum-vraag, het herladen via de vlag en de keuze via de API, staat
|
||||
nog open.
|
||||
|
||||
## 19-08-2026 - certificaatkeuze op het dashboard
|
||||
|
||||
De gebruiker vroeg hoe je aanwijst welk certificaat van welke app je wilt gebruiken, en koos daarbij voor
|
||||
een keuzelijst op het dashboard boven een sleutel in een configuratiebestand. Dat draait het niet-doel
|
||||
"geen instellingenscherm in de web-UI" terug, en dat is opgeschreven als uitzondering met de reden erbij:
|
||||
dit is de enige instelling waarvan de app de mogelijke waarden zelf al kent, want hij kijkt in de
|
||||
gemounte mappen.
|
||||
|
||||
Terugschrijven kan zonder backend met de WebDAV-module van nginx: één `location` die een `PUT` van
|
||||
hooguit een kilobyte aanneemt, naar `${APP_DATA_DIR}/config/` zodat de keuze een herstart overleeft.
|
||||
Of die module in de image zit, is de eerste van drie controles die nu op de Umbrel moeten gebeuren.
|
||||
|
||||
Twee dingen bewust níet gedaan. De mount voor Nginx Proxy Manager staat uitgecommentarieerd, want het pad
|
||||
is een gok en Docker maakt een ontbrekend bind-mountpad aan; dat zou een lege maphierarchie neerzetten in
|
||||
de app-data van een app die er misschien niet is. En de pagina meldt geen succes na het opslaan: nginx
|
||||
moet het certificaat nog herladen, en dat blijkt pas uit de volgende `status.json`.
|
||||
|
||||
**Geraakt:** `index.html.template`, `nginx.conf.template`, `docker-compose.yml`, en de plannen
|
||||
Webinterface en Configuratie.
|
||||
**Tests:** geen suite. In de lokale render gecontroleerd dat de lijst vier certificaten toont met het
|
||||
verlopen exemplaar als zodanig, dat het actieve aangevinkt staat, en dat de knop pas aangaat bij een
|
||||
andere keuze. **Het wegschrijven zelf is niet geprobeerd**, want daar is de Umbrel voor nodig.
|
||||
|
||||
## 19-08-2026 - dashboard uitgedund na de eerste blik
|
||||
|
||||
De gebruiker heeft de pagina bekeken en er drie dingen af gehaald: de grafiek blokken per uur, de tegel
|
||||
blokken laatste uur, en het kader over Tor tegenover TLS. De eerste twee beantwoorden een vraag over de
|
||||
Electrum-server en niet over deze proxy; de derde is positionering en hoort in de winkelbeschrijving,
|
||||
waar iemand nog staat te kiezen. Er blijven drie tegels over. `history` in `status.json` hoeft daardoor
|
||||
alleen nog de reactietijd te bewaren.
|
||||
|
||||
De badge bij de Electrum-server zei `answering`, en op de vraag wat dat betekende was er geen goed
|
||||
antwoord: het liet in het midden of dat nú gold of ooit. Hij noemt nu de meting en het moment, dus
|
||||
`answered 2 minutes ago`, `no answer 2 minutes ago` of `not checked yet`.
|
||||
|
||||
De activiteitenkaart is omgebouwd tot logregels onder elkaar in monospace, nieuwste bovenaan. Daarbij
|
||||
hoort een grens die op de pagina zelf staat: een regel per protocolaanroep kan niet, want die verzoeken
|
||||
zitten in de versleutelde verbinding en ze tellen zou betekenen dat de app het verkeer van de gebruiker
|
||||
uitleest.
|
||||
|
||||
Kopieerknoppen in een lijstregel verschijnen nu bij hover. Met `opacity` en niet met `display`, zodat ze
|
||||
met de tab-toets bereikbaar blijven; op aanraakschermen staan ze altijd aan.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** geen suite. In de lokale render gecontroleerd: drie tegels, zestien logregels, geen
|
||||
console-fouten, blokkengrafiek en Tor-kader weg.
|
||||
|
||||
## 19-08-2026 - plan werd actief, en de pagina is herbouwd
|
||||
|
||||
Gepromoveerd vanuit `Plannen/Masterplannen/` omdat het werk begon. De oude pagina beweerde `Online` als
|
||||
platte tekst in de HTML, had een verzonnen logvenster en noemde een hardgecodeerd domein. Die is
|
||||
vervangen door een pagina die alles uit `status.json` haalt en elk veld dat hij niet kent zichtbaar op
|
||||
`unknown` laat staan.
|
||||
|
||||
Twee dingen die het ontwerp veranderd hebben ten opzichte van het masterplan. De pagina is verhuisd van
|
||||
`web/index.html` naar `index.html.template` in de app-root: umbreld ververst bij een update alleen een
|
||||
whitelist, dus onder `web/` zou elke latere wijziging stilzwijgend niet aankomen en een herinstallatie
|
||||
kosten. En doordat de pagina niets meer hardgecodeerd heeft, is de afhankelijkheid van **Configuratie**
|
||||
vervallen; dat deel van Configuratie fase 2 is hiermee meteen af.
|
||||
|
||||
Op verzoek van de gebruiker zijn er drie dingen bijgekomen: verbindingsregels per client met een
|
||||
kopieerknop (uit `Referenties/Clients.md` §4), een korte eerlijke uitleg over Tor tegenover TLS, en een
|
||||
kaart voor wallet-activiteit die nu op `no data` staat zodat de vorm beoordeeld kan worden voordat er
|
||||
iets voor gebouwd wordt. Dat laatste is een herziening van het niet-doel "live logs", en de grens ligt
|
||||
bij een samenvatting per sessie zonder client-IP.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` (was `web/index.html`),
|
||||
`nginx.conf.template`, `docker-compose.yml`, `umbrel-app.yml`.
|
||||
**Tests:** dit project heeft geen suite. Handmatig gecontroleerd in een lokale render met een
|
||||
voorbeeld-`status.json`: beide thema's, alle kaarten, geen console-fouten.
|
||||
**Nog niet geverifieerd:** alles wat een echte `status.json` vraagt, want die wordt nog niet geschreven
|
||||
(fase 2). De kopieerknop is niet achter de app-proxy van umbrelOS geprobeerd, en dat is juist het pad
|
||||
waar de terugval voor http gebruikt wordt.
|
||||
@@ -0,0 +1,210 @@
|
||||
# Taken - Webinterface
|
||||
|
||||
> Prioriteit: **A** | Wacht op: –
|
||||
>
|
||||
> **Van C naar B naar A op 20-08-2026, op één dag.** Eerst verviel de blokkade "de app geïnstalleerd en de
|
||||
> agent draaiend". Aan het eind van die dag is dit het enige plan met werk dat nú te doen is: **Appstore**
|
||||
> heeft alleen nog een herstart nodig die niet te plannen is, en **Publicatie** wacht op een publieke repo.
|
||||
> Het nummer is daarom van 020 naar 005 gegaan; alleen dit plan kreeg een nieuw nummer, Appstore houdt 010.
|
||||
>
|
||||
> Afgezakt van A naar C op 19-08-2026 bij het afsluiten van de sessie. De pagina is af voor zover dat
|
||||
> zonder de Umbrel kan; al het resterende werk in dit plan begint met kijken of de agent doet wat hij zou
|
||||
> moeten doen, en dat kan niet vóór de installatie.
|
||||
|
||||
## Volgende stap
|
||||
|
||||
- [x] **0.0.10 op een telefoon nagekeken. In orde (20-08-2026).** De gebruiker meldt dat het er goed uitziet
|
||||
op mobiel. Eén ding kwam eruit: de kopieerknoppen stonden niet op één lijn, omdat de knop door het
|
||||
omvouwen de lengte van het adres volgde. Verholpen in 0.0.11 met `margin-left: auto` op de knop.
|
||||
Bijvangst: `0.0.10` na `0.0.9` levert wél een update op, dus tweecijferige versiedelen zijn veilig
|
||||
|
||||
- [x] **De agent zien draaien. Gelukt op 20-08-2026, over drie versies.** De agent start en luistert, de
|
||||
pagina laadt, hij vond veertien certificaten in `/certs/zoraxy` en weigerde daarom te kiezen, een
|
||||
keuze op de pagina werd aangenomen, en daarna verbindt een wallet over 50022. De keten waar dit plan
|
||||
op wachtte is dus rond.
|
||||
|
||||
- [ ] **Het uploaden op het niet-gelukkige pad proberen**, het enige stuk van 0.0.7 dat nog niet in een
|
||||
browser gezien is: een sleutel die niet bij het certificaat hoort. Verwacht: een weigering met een
|
||||
leesbare reden, en niets dat achterblijft in `data/certs`. De guard is met echte sleutelparen getoetst
|
||||
en mutatie-getest, dus dit gaat over de weg van de melding naar de pagina en niet over de controle
|
||||
zelf. **Eigenaar: gebruiker**
|
||||
|
||||
- [x] **0.0.7 en 0.0.9 in de browser nagekeken. Gelukt (20-08-2026):** uploaden werkt, kiezen werkt, ook
|
||||
met de certificaten uit Zoraxy, de keuzelijst bij het installeren zag er goed uit en het
|
||||
versienummer op de pagina klopt. Daarmee is het uploadpad uit 0.0.7 bewezen op het gelukkige pad
|
||||
|
||||
- [x] **0.0.6 in de browser nagekeken (20-08-2026).** Ziet er goed uit volgens de gebruiker. Wat eruit
|
||||
kwam: de badges konden weg, "your choice" zei niets, Trezor Suite is niet desktop-only, en
|
||||
Blockstream Green heet Blockstream
|
||||
|
||||
- [x] **De pagina naast een werkende app gelegd (20-08-2026).** Blokhoogte en backend-reactietijd komen
|
||||
binnen. Wat eruit kwam: van een verbonden wallet was niets te zien, de keuzelijst was te druk, en
|
||||
een reeks uitleg-teksten kon weg. Alles verwerkt in 0.0.6
|
||||
|
||||
- [ ] **Het activiteitenlog een etmaal laten lopen** en dan kijken of het klopt: komt er een
|
||||
`connected`-regel bij een nieuwe wallet, en wat staat er na een nacht in. De teller is nieuw en is
|
||||
alleen tegen tijdelijke bestanden getoetst, niet tegen een echte wallet
|
||||
|
||||
Daarna, en niet eerder:
|
||||
|
||||
- [ ] Uitzoeken waar Nginx Proxy Manager op umbrelOS zijn certificaten neerzet. De mount staat
|
||||
uitgecommentarieerd in `docker-compose.yml`: een gok invullen zou Docker een lege maphierarchie
|
||||
laten aanmaken in de app-data van een app die er misschien niet eens is
|
||||
- [ ] Open punt 5: laten controleren of de TLS-poort zélf antwoordt. Dat is nu het enige wat de app niet
|
||||
over zichzelf weet, en het is zijn enige taak
|
||||
- [x] **Open punt 6: een certificaat uploaden via de pagina. Gebouwd in 0.0.7** (20-08-2026). Beschrijfbare
|
||||
mount voor de agent, een eigen nginx-locatie met een grotere limiet, en validatie met
|
||||
`load_cert_chain` voordat er iets geplaatst wordt. De bestandsnaam komt uit het certificaat zelf,
|
||||
dus padtrucs kunnen niet. **Nog niet in een browser geprobeerd**
|
||||
- [ ] Open punt 7: beslissen of Zoraxy een harde afhankelijkheid wordt. "Zoraxy of NPM" kan niet, en dat
|
||||
is op 20-08-2026 in de bron nagetrokken; alleen de wens staat nog open. Zie [OPEN.md](OPEN.md)
|
||||
punt 7
|
||||
- [ ] Fase 5, het activiteitenlog, als de gebruiker het wil
|
||||
|
||||
De drie controles op `openssl`, `nc` en de WebDAV-module zijn **vervallen** met de komst van de agent: die
|
||||
doet dat werk zelf met de standaardbibliotheek. Zie [PLAN.md](PLAN.md) §4a0.
|
||||
|
||||
Daarna, in deze volgorde:
|
||||
|
||||
- [ ] Fase 2 bouwen op de uitkomst van die controle
|
||||
- [ ] Fase 5, als de gebruiker de wallet-activiteit wil
|
||||
|
||||
## Fase 1 - Het liegen eruit
|
||||
|
||||
- [x] De verzonnen statusblokken (`Online`, `Online`) en het verzonnen logvenster weg
|
||||
- [x] Het hardgecodeerde domein weg. De pagina bevat geen enkele installatiespecifieke waarde meer
|
||||
- [x] Taal naar Engels, zie [OPEN.md](OPEN.md) punt 2
|
||||
- [x] Opnieuw opgebouwd op het design-systeem: tokens, `card`, `badge`, `alert`, `list-item`, `btn`,
|
||||
donker met een lichte variant en een schakelaar
|
||||
- [x] **De pagina verhuisd naar `index.html.template` in de app-root.** Onder `web/` zou elke latere
|
||||
wijziging een herinstallatie kosten: umbreld ververst bij een update alleen een whitelist en die
|
||||
kijkt niet in submappen. Als template zit hij in de whitelist én wordt hij bij elke start ingevuld
|
||||
|
||||
## Fase 2 - De agent schrijft `status.json`
|
||||
|
||||
Herzien 19-08-2026: dit is een tweede container met een python-programma geworden in plaats van een
|
||||
shell-lus in de compose. Onderbouwing in [PLAN.md](PLAN.md) §4a0.
|
||||
|
||||
- [x] `agent.py.template`, met de instellingen uit de omgeving in plaats van uit template-invulling.
|
||||
Daardoor staat er geen accolade-variabele in en blijft het geldige Python, dus is het te importeren
|
||||
in een test. De eerste toets in `tests/` controleert precies die aanname
|
||||
- [x] Schrijft `status.json` atomair via een tijdelijk bestand en `os.replace`, want de pagina leest het
|
||||
elke minuut en een half geschreven bestand geeft een lege pagina
|
||||
- [x] Einddatum van het certificaat met een eigen DER-lezer. Getoetst tegen `ssl` op 74 echte
|
||||
CA-certificaten, op een levend servercertificaat, en op beide tijdvormen
|
||||
- [x] Blokhoogte en reactietijd via `blockchain.headers.subscribe` over een verse socket
|
||||
- [x] Een `history`-reeks bijhouden, afgekapt op 24 uur, met alléén de reactietijd. De sparkline is sinds
|
||||
19-08-2026 de enige afnemer
|
||||
- [x] Herkennen welke backend het is aan de hand van het adres, en `unknown` als hij niet in de tabel
|
||||
staat. Zie [PLAN.md](PLAN.md) §4c: liever minder informatief dan onwaar
|
||||
- [x] De lus valt nooit stil: een mislukte ronde wordt gelogd en overgeslagen. Stoppen zou de pagina op
|
||||
oude gegevens bevriezen, en dat is precies het liegen dat dit plan moest afschaffen
|
||||
- [ ] Draaien op de Umbrel. Niets hiervan is buiten de tests uitgevoerd
|
||||
|
||||
## Fase 3 - De pagina vult zichzelf
|
||||
|
||||
- [x] `fetch` op `status.json`, elke minuut
|
||||
- [x] Elk veld heeft een zichtbare onbekend-toestand; nooit een leeg veld, want dat leest als "in orde"
|
||||
- [x] "Laatst bijgewerkt" tonen, en oude gegevens als zodanig laten zien zodra ze ouder zijn dan twee
|
||||
schrijfronden. **Bijgesteld 19-08-2026 op verzoek van de gebruiker:** dat gebeurt niet meer met een
|
||||
melding bovenaan de pagina maar alleen bij de waarden zelf, want die melding zei voor de vierde keer
|
||||
wat er al onder de blokhoogte, in de badge bij de Electrum-server en in de voettekst stond
|
||||
- [x] Leesbare melding als het bestand ontbreekt, zonder dat het op een fout lijkt.
|
||||
Zie [OPEN.md](OPEN.md) punt 1
|
||||
- [ ] Verifiëren tegen een échte `status.json` in plaats van tegen de voorbeeldversie uit de preview
|
||||
|
||||
## Fase 4a - De indeling
|
||||
|
||||
Vastgesteld door de gebruiker op 19-08-2026 na het bekijken van de eerste versie. Ontwerp in
|
||||
[PLAN.md](PLAN.md) §4a1.
|
||||
|
||||
- [x] Volgorde: Electrum-server, drie statustegels, activiteitenlog, certificaatkeuze, instellen van je
|
||||
wallet
|
||||
- [x] "Point your wallet here" opgegaan in "Setting up your wallet"; het waren dezelfde kaders
|
||||
- [x] Breed met een raster van twaalf kolommen, rijen die 5/7 en 7/5 afwisselen, afgekapt op 1760px
|
||||
- [x] De leesvolgorde in de HTML is de bedoelde volgorde, zonder `order` in de CSS, zodat stapelen op een
|
||||
smal scherm dezelfde volgorde geeft. Gecontroleerd op 1760px en op mobiel
|
||||
- [x] Statustegels rekken mee met de hoogte van hun buur, anders staat er een gat rechtsboven
|
||||
- [x] Het logblok scrollt zelf horizontaal in plaats van de regel met puntjes af te kappen
|
||||
- [x] **Alle kaders hetzelfde opgebouwd** (19-08-2026): een `card-head` met een titel in `t-h3`, dan de
|
||||
inhoud. De drie statustegels hadden een eigen kleine grijze kop in kapitalen. De titel gebruikt de
|
||||
token `--text-primary`, niet letterlijk wit, anders is hij onzichtbaar in de lichte variant
|
||||
- [x] De onderregel van een statustegel is even hoog als de sparkline, zodat de drie getallen op één lijn
|
||||
staan. Gecontroleerd: koppen op y=153, getallen op y=311
|
||||
- [x] **De badge "Serving this page" verwijderd** (19-08-2026, op aanwijzing van de gebruiker). Zie
|
||||
[OPEN.md](OPEN.md) punt 5 voor wat er wél op die plek zou horen
|
||||
- [x] **De voetregel verwijderd** (19-08-2026). Daarin stond "Last reading ... ago" plus het versienummer;
|
||||
het eerste stond al bij de waarden zelf
|
||||
- [x] **Het versienummer teruggezet**, klein achter de tagline als `v0.0.3`. Dezelfde dag op verzoek van de
|
||||
gebruiker. In `--text-sec` en niet in `--text-ter`, want die laatste is in de lichte variant `#bbbbbb`
|
||||
op wit en op deze grootte onleesbaar
|
||||
- [x] **De certificaatlijst scrollt**, met het aantal in de kop. Een gedeelde certificatenmap kan er
|
||||
tientallen bevatten. Gecontroleerd met 19 certificaten: 1062px inhoud in een vak van 360px, knop
|
||||
blijft eronder staan
|
||||
- [x] **Het logblok en het certificaatkader zijn even hoog.** Het langste kader van de rij bepaalt de
|
||||
hoogte, en wat mag meegroeien zegt dat zelf met flex. Gemeten: 636px bij vier certificaten, 773px bij
|
||||
negentien, in beide gevallen allebei gelijk
|
||||
- [x] **Certificaat en activiteitenlog omgedraaid** (19-08-2026, op verzoek). Certificaat links en smal,
|
||||
log rechts en breed. Dat pakt twee kanten goed uit: de kolomgrens valt nu samen met die van de rij
|
||||
erboven (gemeten: x=738 in beide rijen), en monospace logregels hebben de breedte beter nodig
|
||||
- [x] **Het losse verbindingsadres met kopieerknop eruit**, plus het label "tested clients". Zonder
|
||||
verlies: hetzelfde adres staat bij elke clientregel, in de vorm die díe client wil, met een
|
||||
kopieerknop erbij. Het instelkader werd daarmee 533px in plaats van 610px
|
||||
- [ ] Nog niet met eigen ogen gezien op een echt breed scherm; gecontroleerd via de afmetingen van de
|
||||
kaders, niet visueel, want het browserpaneel stond dicht
|
||||
|
||||
## Fase 4 - Bruikbaar in plaats van alleen eerlijk
|
||||
|
||||
- [x] Verloopwaarschuwing onder de dertig dagen, en een foutmelding als het certificaat verlopen is
|
||||
- [x] Kopieerknop op het verbindingsadres, met terugval voor http zonder de clipboard-API
|
||||
- [x] Verbindingsregels per client, met kopieerknop per regel. Bron: `Referenties/Clients.md` §4
|
||||
- [x] Kopieerknoppen verschijnen bij hover over de regel. Met `opacity` en niet met `display`, zodat ze
|
||||
met de tab-toets bereikbaar blijven, plus `focus-within` en altijd zichtbaar op aanraakschermen
|
||||
- [ ] De kopieerknop echt uitproberen achter de app-proxy van umbrelOS. Die draait over http, dus de
|
||||
terugval met `execCommand` is daar het pad dat gebruikt wordt en niet de uitzondering. Wat op
|
||||
19-08-2026 lokaal wél bewezen is: de **faalroute** meldt "Press Ctrl+C" in plaats van stil niets te
|
||||
doen. De geslaagde route vraagt een echte muisklik, want de clipboard-API weigert een klik die uit
|
||||
een script komt
|
||||
|
||||
## Fase 4b - De certificaatkeuze
|
||||
|
||||
Besloten 19-08-2026 door de gebruiker: een keuzelijst op het dashboard in plaats van een sleutel in het
|
||||
configuratiebestand. Het ontwerp hoort bij het plan **Configuratie** §4e en §4f; hier staat alleen wat de
|
||||
pagina en de compose ervoor doen.
|
||||
|
||||
- [x] Keuzelijst op de pagina, met per certificaat de bron, de bestandsnaam, het domein en het aantal
|
||||
resterende dagen. Een verlopen certificaat staat er rood bij en wordt niet verborgen: het bestaat,
|
||||
en het kiezen ervan moet een zichtbare vergissing zijn en geen onvindbare
|
||||
- [x] `PUT` naar `api/certificate`, doorgestuurd naar de agent. De WebDAV-truc is vervallen: de agent
|
||||
neemt de keuze aan en kan hem ook controleren, wat WebDAV niet kon
|
||||
- [x] De pagina meldt níet zelf dat het gelukt is. Nginx moet het certificaat nog herladen, en dat blijkt
|
||||
pas uit de volgende `status.json`
|
||||
- [x] De Zoraxy-mount van `/certs` naar `/certs/zoraxy`, en `/certs/own` erbij, zodat er per bron een map
|
||||
is. Beide containers hebben ze nodig: de agent om te kiezen, nginx om het bestand te openen
|
||||
- [x] `certificates` in `status.json`, met per certificaat de bron, de naam, het domein uit het
|
||||
certificaat en de einddatum
|
||||
- [x] **De guard: een id die de agent niet zelf gevonden heeft, wordt geweigerd.** Zowel bij de `PUT` als
|
||||
bij het kiezen. Getest, inclusief de mutatietest
|
||||
- [x] **Bij meerdere kandidaten kiest de app niet.** Bijgesteld nadat bleek dat mijn eerste versie "de
|
||||
langst geldige" pakte, wat het plan **Configuratie** §4c uitdrukkelijk verbiedt: een verkeerd
|
||||
certificaat geeft een verbinding die het lijkt te doen en bij de wallet stukloopt op
|
||||
naamverificatie. De pagina toont dan een foutmelding met de kandidaten erin
|
||||
- [x] De pagina toont bovenaan een foutmelding als er geen certificaat actief is, want dan is er geen TLS
|
||||
en dat is het ergste wat deze app kan overkomen
|
||||
|
||||
## Fase 5 - Het activiteitenlog
|
||||
|
||||
Voorstel, nog niet besloten. Ontwerp in [PLAN.md](PLAN.md) §4e. De kaart staat al op de pagina en toont
|
||||
`no data`, zodat de vorm te beoordelen is voordat er iets voor gebouwd wordt.
|
||||
|
||||
- [x] Vorm: logregels onder elkaar, monospace, nieuwste bovenaan, met de grens erbij vermeld dat een
|
||||
regel per protocolaanroep niet kan zonder het verkeer van de gebruiker uit te lezen
|
||||
- [ ] Uitzoeken of een `log_format` met dollartekens langs de template-invulling te krijgen is, via een
|
||||
`include` die het `command`-blok wegschrijft
|
||||
- [ ] Uitzoeken hoe de bytetellers van een lopende verbinding in de container af te lezen zijn; nginx
|
||||
logt een stream-sessie pas bij het sluiten
|
||||
- [ ] `log` in `status.json`, zonder client-IP en zonder bronpoort
|
||||
|
||||
## Geblokkeerd / wacht op
|
||||
|
||||
- [ ] Niets. De afhankelijkheid van **Configuratie** is vervallen, zie [PLAN.md](PLAN.md)
|
||||
@@ -0,0 +1,50 @@
|
||||
# Open punten - Proefopstelling
|
||||
|
||||
> Beslissingen die nog een **eigenaar** of een **moment** nodig hebben. Staat een punt hier zonder
|
||||
> allebei, dan is dat de eerste fout om op te lossen. Wordt een punt een taak, dan verhuist het naar
|
||||
> [TAKEN.md](TAKEN.md).
|
||||
>
|
||||
> **Nummers blijven staan**, ook als een punt beslist is: er kan elders naar verwezen worden, ook vanuit
|
||||
> codecommentaar. Beslissen betekent verplaatsen naar de kop hieronder, niet hernummeren.
|
||||
|
||||
## Nog te beslissen
|
||||
|
||||
1. **Waar draait de proefopstelling?**
|
||||
Er zijn twee plekken en ze meten niet hetzelfde. Een machine met Docker onder handbereik is het
|
||||
snelst en het makkelijkst opruimen. De Umbrel zelf lijkt dichter bij het doel, maar dat is
|
||||
schijnnauwkeurigheid: je draait dan nog steeds niet als umbrelOS-app, je hebt wel meteen last van
|
||||
poortbotsingen met wat er al draait, en een mislukte poging laat rommel achter op een
|
||||
productiemachine.
|
||||
Voorstel: de losse machine, tenzij er een reden is dat het daar niet kan. De echte controle op de
|
||||
Umbrel hoort bij het masterplan **Umbrelapp**.
|
||||
**Moment:** voor fase 2 · **Eigenaar:** gebruiker
|
||||
|
||||
2. **Welke Trezor Suite telt?**
|
||||
Desktop, web en mobiel zijn drie verschillende programma's, en het is niet gegeven dat ze alle drie
|
||||
een eigen sync-server accepteren. Het antwoord bepaalt wat "het werkt" betekent, en het bepaalt ook
|
||||
het masterplan **Bereikbaarheid**: alleen desktop op het thuisnetwerk vraagt veel minder dan een
|
||||
telefoon onderweg.
|
||||
**Moment:** valt samen met de "Volgende stap" van fase 1 · **Eigenaar:** gebruiker
|
||||
|
||||
3. **Is er een tweede apparaat om mee te synchroniseren?**
|
||||
Fase 3 heeft er een nodig, want dat is de enige controle die bewijst dat de relay doet waarvoor hij
|
||||
bestaat. Een tweede installatie van Suite op dezelfde machine kan misschien ook, maar dat is niet
|
||||
uitgezocht en het is zwakker bewijs: dezelfde machine, hetzelfde netwerk.
|
||||
**Moment:** voor fase 3 · **Eigenaar:** gebruiker
|
||||
|
||||
4. **Wat als de quota-manager verplicht blijkt én zelf een externe dienst nodig heeft?**
|
||||
Dan is dit geen pakketteerprobleem meer. Denkrichtingen, niet in volgorde: de quota-manager mee
|
||||
pakketteren met een minimale configuratie die niets betaalt; uitzoeken of er een schakelaar is die de
|
||||
controle uitzet; of concluderen dat zelf hosten niet bedoeld is en het project hier stoppen. Dat
|
||||
laatste is een geldige uitkomst en zou de goedkoopste zijn die dit plan kan opleveren.
|
||||
**Moment:** zodra fase 1 of fase 2 het antwoord geeft · **Eigenaar:** gebruiker beslist, op basis van
|
||||
wat er dan bekend is
|
||||
|
||||
5. **Wordt de proefopstelling zelf vastgelegd in deze repo?**
|
||||
Een `compose/`-map met de gebruikte compose en een `.env.sample` maakt het herhaalbaar, en dat is
|
||||
veel waard als er over twee weken pas verder gewerkt wordt. Er zit een prijs aan: deze repo wordt
|
||||
publiek, dus er mag geen enkel echt geheim in, en een tweede compose naast die van het pakket kan
|
||||
later verwarren welke de echte is.
|
||||
Voorstel: wel, in een map die duidelijk `proefopstelling/` heet, met uitsluitend een `.env.sample`
|
||||
en nooit een `.env`.
|
||||
**Moment:** bij de eerste geslaagde start in fase 2 · **Eigenaar:** gebruiker
|
||||
@@ -0,0 +1,89 @@
|
||||
# Proefopstelling - plan
|
||||
|
||||
> Ontwerp en afbakening. **Dit bestand lees je zelden**, alleen bij twijfel over scope of architectuur.
|
||||
> Status staat in [TAKEN.md](TAKEN.md), geschiedenis in [PROGRESS.md](PROGRESS.md), onbesliste punten in
|
||||
> [OPEN.md](OPEN.md).
|
||||
|
||||
## 1. Doel
|
||||
|
||||
Uitzoeken of Evolu Relay zelf gehost bruikbaar is voor Trezor Suite, en met welke **minimale** set
|
||||
containers en omgevingsvariabelen. Dat gebeurt lokaal, buiten Umbrel om, want een pakket bouwen voor iets
|
||||
waarvan je niet weet of het draait is de dure volgorde.
|
||||
|
||||
Als dit plan af is, is er één zin die het volgende plan kan aannemen: "de relay draait met deze containers
|
||||
en deze variabelen, en Trezor Suite synchroniseert ermee." Zonder die zin is elk manifest een gok.
|
||||
|
||||
## 2. Afbakening
|
||||
|
||||
Alles tot en met een label dat op apparaat A gezet wordt en op apparaat B verschijnt, via een relay die op
|
||||
het thuisnetwerk draait en die niets van Trezor nodig heeft.
|
||||
|
||||
Binnen dit plan valt ook het opschrijven van wat er nodig bleek: welke variabelen, welke poorten, welke
|
||||
volumes, en waar de images vandaan komen. Dat is niet de bijvangst maar het eigenlijke product; het
|
||||
volgende plan leest het.
|
||||
|
||||
## 3. Niet-doelen
|
||||
|
||||
- **Geen `umbrel-app.yml` en geen `docker-compose.yml` in Umbrel-vorm.** Dat is het masterplan
|
||||
**Umbrelapp**, en het heeft de uitkomst van dit plan nodig.
|
||||
- **Geen bereikbaarheid van buiten, geen TLS, geen Tailscale.** Masterplan **Bereikbaarheid**. Hier
|
||||
volstaat een IP op het eigen netwerk.
|
||||
- **Geen eigen image bouwen of publiceren.** Blijkt dat nodig, dan is dat een bevinding van dit plan en
|
||||
werk van het volgende.
|
||||
- **Niets met quota's of betalen.** De quota-manager is hier een obstakel dat je wegwerkt of moet
|
||||
meenemen, geen functionaliteit die we willen.
|
||||
- **Geen bijdrage aan `trezor/trezor-suite-sync`.** Ook niet als er onderweg iets stuk blijkt.
|
||||
|
||||
## 4. Ontwerp
|
||||
|
||||
### 4a. De volgorde is: eerst wat het project kan doden
|
||||
|
||||
Het vooronderzoek zet "clone en draai" als eerste stap. Dat is niet de goedkoopste weerlegging. Er zijn
|
||||
twee aannames waarop dit project stukloopt, en de eerste kost een minuut:
|
||||
|
||||
1. **Kan Trezor Suite überhaupt naar een eigen relay wijzen?** Het vooronderzoek gaat uit van een
|
||||
"Custom server"-veld. Bestaat dat niet in de Suite-versie van de gebruiker, of alleen op een platform
|
||||
dat hij niet gebruikt, dan is er niets te pakketteren. Dit is te controleren in de interface, zonder
|
||||
iets te installeren.
|
||||
2. **Is de quota-manager verplicht?** Zie [Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md)
|
||||
§3. Dit is te lézen in `.env.sample`, de compose en de broncode, en pas daarna te bewijzen door hem weg
|
||||
te laten.
|
||||
|
||||
Pas als die twee goed staan, is "clone en draai" de moeite waard.
|
||||
|
||||
### 4b. Wat er gedraaid wordt
|
||||
|
||||
De compose van Trezor zelf, ongewijzigd waar het kan, met de quota-manager uitgeschakeld. Ongewijzigd is
|
||||
hier een doel op zich: elke aanpassing die je maakt, is een aanpassing waarvan je later niet meer weet of
|
||||
hij nodig was. Werkt het niet zonder wijziging, dan is de wijziging zelf een bevinding.
|
||||
|
||||
### 4c. Wat er opgeschreven wordt
|
||||
|
||||
Per container: image en herkomst, poorten, volumes, en de omgevingsvariabelen die **echt** nodig bleken,
|
||||
niet de hele `.env.sample`. Dat onderscheid is het verschil tussen een manifest van tien regels en een van
|
||||
veertig, en het is achteraf niet meer te maken.
|
||||
|
||||
Daarbij twee dingen die het volgende plan hard nodig heeft en die je alleen hier tegenkomt: **komt de
|
||||
image uit een registry of alleen uit een Dockerfile**, en **hoe authenticeert Suite zich tegen de relay**.
|
||||
Die tweede bepaalt of de app achter de inlog van umbrelOS kan staan; zie het masterplan **Umbrelapp**,
|
||||
§4b.
|
||||
|
||||
## 5. Raakvlakken
|
||||
|
||||
- **Umbrelapp** is hard afhankelijk van dit plan: het aantal containers, de variabelen en de
|
||||
authenticatievraag komen hier vandaan.
|
||||
- **Bereikbaarheid** leunt op één bevinding hier: accepteert Suite een `http://`-adres, of eist het TLS?
|
||||
- **Publicatie** leunt op de herkomst van de image. Zonder een gepinde multi-arch image uit een registry
|
||||
komt dat plan niet van de grond.
|
||||
|
||||
## 6. Verificatie
|
||||
|
||||
Wat als bewijs telt, in oplopende sterkte:
|
||||
|
||||
1. de relay start en blijft draaien zonder quota-manager;
|
||||
2. Trezor Suite accepteert het adres en meldt geen fout;
|
||||
3. een label dat op apparaat A gezet wordt, verschijnt op apparaat B na een synchronisatie. **Dit is de
|
||||
enige die telt.** De eerste twee kunnen slagen terwijl er niets gesynchroniseerd wordt.
|
||||
|
||||
Wat hier per se **niet** bewezen wordt, en wat dus niet als "werkt" gemeld mag worden: gedrag op arm64,
|
||||
overleven van een herstart, gedrag onder umbrelOS, en bereikbaarheid van buiten het thuisnetwerk.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Voortgang - Proefopstelling
|
||||
|
||||
> Chronologisch sessielog, nieuwste bovenaan. Kort: 3 tot 6 regels per entry. Wat er is gebeurd en
|
||||
> waarom, niet wat er nog moet: dat staat in [TAKEN.md](TAKEN.md).
|
||||
|
||||
## 25-08-2026 - plan werd actief
|
||||
|
||||
Dit project bestond uit één document, `trezor-suite-sync-umbrel-app-plan.md`, met het vooronderzoek van
|
||||
dezelfde dag erin. Dat is bij het inrichten van de repo over vier plannen verdeeld; dit is het enige dat
|
||||
meteen actief werd, omdat het als enige nu al iets te doen heeft en omdat de andere drie er hard van
|
||||
afhangen. Het origineel staat ongewijzigd in `Plannen/Masterplannen/Archief/Vooronderzoek.PLAN.md`, want
|
||||
het is de bron onder elke regel die met "onderzocht 25-08-2026" gemerkt is.
|
||||
|
||||
**Eén ding is bij het verdelen omgedraaid.** Het vooronderzoek zet "clone en draai" als eerste stap. Er
|
||||
zit een goedkopere weerlegging vóór: of Trezor Suite überhaupt naar een eigen sync-server kan wijzen. Dat
|
||||
kost een minuut in de interface, en is het antwoord nee, dan is er niets te pakketteren. Dat staat nu als
|
||||
"Volgende stap"; de clone is fase 2.
|
||||
|
||||
**De remote is anoniem bereikbaar, en dat is hier een eis en geen hygiëne.** Getest met de
|
||||
credential-helper leeg gezet, want een gewone `ls-remote` slaagt op deze machine ook als de repo dicht
|
||||
staat. De repo is nog leeg, dus dit bewijst bereikbaarheid en nog niet dat umbreld de store-inhoud kan
|
||||
ophalen; die controle hoort bij het masterplan **Umbrelapp**.
|
||||
|
||||
**Geraakt:** de hele `Docs/`-boom, `.gitignore`, `.gitattributes`, `CLAUDE.md`, `README.md`.
|
||||
**Tests:** niet van toepassing, er is nog geen bron. Zie `Docs/README.md`, "Projectspecifiek".
|
||||
@@ -0,0 +1,58 @@
|
||||
# Taken - Proefopstelling
|
||||
|
||||
> Prioriteit: **A** | Afhankelijk van: -
|
||||
>
|
||||
> Actief sinds 25-08-2026, bij het inrichten van dit project. Dit is het enige plan met een tier: de drie
|
||||
> masterplannen wachten allemaal op de uitkomst hiervan.
|
||||
|
||||
## Volgende stap
|
||||
|
||||
- [ ] **Controleren of Trezor Suite een eigen sync-server accepteert, en op welk platform.** Dit is de
|
||||
goedkoopste weerlegging van het hele project en het kost een minuut in de interface. Noteer waar het
|
||||
veld staat, hoe het adres eruit moet zien (met of zonder schema, met of zonder poort), en of het
|
||||
alleen op desktop bestaat. **Eigenaar: gebruiker**
|
||||
|
||||
## Fase 1 - Kan dit überhaupt
|
||||
|
||||
- [ ] Het veld voor een eigen sync-server in Trezor Suite gevonden, met de vorm die het verwacht
|
||||
- [ ] `.env.sample`, `docker-compose.yaml` en de relay-broncode van `trezor/trezor-suite-sync` gelezen op
|
||||
de vraag of de quota-manager verplicht is. **Lezen, nog niet draaien:** als het antwoord in de
|
||||
broncode staat, scheelt dat een halve middag proberen
|
||||
- [ ] Vastgesteld of Trezor een image publiceert of alleen een Dockerfile levert. Zie
|
||||
[Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md) §4 punt 1; dit bepaalt of
|
||||
het masterplan **Publicatie** haalbaar is
|
||||
|
||||
## Fase 2 - De stack lokaal draaien
|
||||
|
||||
- [ ] `trezor/trezor-suite-sync` gekloond
|
||||
- [ ] `docker compose up` met **alleen** Postgres en `evolu-relay`, de quota-manager weggelaten
|
||||
- [ ] De relay antwoordt op poort 4000 en blijft draaien. Blijft hij niet draaien, dan is de foutmelding
|
||||
de bevinding: schrijf hem letterlijk op in [PROGRESS.md](PROGRESS.md)
|
||||
- [ ] **Blocker-check:** is de relay hard afhankelijk van de quota-manager? Zo ja, die erbij en
|
||||
uitzoeken wat hij zelf nodig heeft. Vraagt hij een externe dienst, dan is dat geen taak meer maar
|
||||
open punt 4 in [OPEN.md](OPEN.md)
|
||||
|
||||
## Fase 3 - Echt synchroniseren
|
||||
|
||||
- [ ] Trezor Suite op apparaat A naar `http://<ip-van-de-machine>:4000` laten wijzen
|
||||
- [ ] Een label toevoegen op apparaat A
|
||||
- [ ] Datzelfde label zien verschijnen op apparaat B. **Dit is de enige controle die telt**; de twee
|
||||
hierboven kunnen slagen terwijl er niets gesynchroniseerd wordt
|
||||
- [ ] Geprobeerd wat er gebeurt als de relay even weg is en terugkomt. Niet omdat het nu moet werken,
|
||||
maar omdat het gedrag straks op een Umbrel bij elke update voorkomt
|
||||
|
||||
## Fase 4 - Vastleggen wat het pakket moet worden
|
||||
|
||||
- [ ] Per container opgeschreven: image en herkomst, poorten, volumes, en de variabelen die **echt** nodig
|
||||
bleken. Niet de hele `.env.sample` overnemen
|
||||
- [ ] Opgeschreven hoe Trezor Suite zich tegen de relay authenticeert, of dat het helemaal niet doet. Dit
|
||||
bepaalt of de app achter de inlog van umbrelOS kan staan; zie het masterplan **Umbrelapp**, §4b
|
||||
- [ ] Opgeschreven of Suite een `http://`-adres accepteert of TLS eist. Hier hangt het masterplan
|
||||
**Bereikbaarheid** aan
|
||||
- [ ] [Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md) bijgewerkt: alles wat daar
|
||||
als "onderzocht 25-08-2026" staat en nu bevestigd of weerlegd is, met de nieuwe datum erbij
|
||||
- [ ] Het masterplan **Umbrelapp** herzien met wat hier uitkwam, en pas daarna promoveren
|
||||
|
||||
## Geblokkeerd / wacht op
|
||||
|
||||
- [ ] Fase 3 wacht op een tweede apparaat met Trezor Suite. Zie [OPEN.md](OPEN.md) punt 3
|
||||
@@ -0,0 +1,144 @@
|
||||
# Open punten - Appstore
|
||||
|
||||
> Beslissingen die nog een **eigenaar** of een **moment** nodig hebben. Staat een punt hier zonder
|
||||
> allebei, dan is dat de eerste fout om op te lossen. Wordt een punt een taak, dan verhuist het naar
|
||||
> [TAKEN.md](TAKEN.md).
|
||||
>
|
||||
> **Nummers blijven staan**, ook als een punt beslist is: er kan elders naar verwezen worden, ook vanuit
|
||||
> codecommentaar. Beslissen betekent verplaatsen naar de kop hieronder, niet hernummeren.
|
||||
|
||||
## Nog te beslissen
|
||||
|
||||
2. **Wat gebeurt er met de bestaande handmatige installatie?** - **In twee stappen, en de eerste is niet
|
||||
meer uit te stellen** (bijgewerkt 20-08-2026).
|
||||
|
||||
De container is gestopt maar de compose staat er nog: een `alpine:latest` met een `apk add stunnel` bij
|
||||
elke start, met `restart: unless-stopped` en een mount op de certificaten van Zoraxy. Wat er nu aan de
|
||||
orde is:
|
||||
|
||||
- **de container weghalen, nu.** Hij bindt poort **50002**, en dat is precies de poort die Fulcrum op de
|
||||
host wil. Zolang hij bestaat kan het omschakelen naar Fulcrum niet slagen, en dat staat in fase 6 als
|
||||
taak. `restart: unless-stopped` betekent bovendien dat hij een herstart van de Umbrel overleeft;
|
||||
- **de map laten staan tot de herstart-controle gedaan is.** Dat is een compose plus een
|
||||
`entrypoint.sh` en het kost niets. Het is de gedocumenteerde weg terug, en die vervalt pas als
|
||||
bewezen is dat de app na een herstart vanzelf terugkomt. Let op de volgorde: de container mount zijn
|
||||
`entrypoint.sh` uit die map, dus eerst de container weg en dan de map.
|
||||
|
||||
**Moment:** stap 1 nu, stap 2 na de herstart-controle · **Eigenaar:** gebruiker
|
||||
|
||||
4. **Eigen icoon en gallery.**
|
||||
Het manifest wijst nu naar het Electrs-icoon en een screenshot van Electrs in `getumbrel/umbrel-apps`,
|
||||
dus naar andermans bestanden en naar plaatjes van een andere app. Er moet een eigen SVG komen. De
|
||||
gallery is minder dringend: die is er voor een winkelpagina die hier niemand bezoekt, zie
|
||||
[KNOWLEDGE.md](../../../KNOWLEDGE.md). Vraag is wie het icoon maakt en of het in de repo komt of extern
|
||||
gehost wordt.
|
||||
**Moment:** fase 5 · **Eigenaar:** gebruiker
|
||||
|
||||
7. **Hoe wordt de herstart-controle alsnog gedaan?**
|
||||
Dit is de controle waar het hele plan om begon: komt de app na een herstart van de Umbrel vanzelf
|
||||
terug. Hij is op 18-08-2026 uitgesteld omdat de Umbrel een productiemachine is en niet op verzoek
|
||||
herstart wordt. Dat is een geldige reden, maar het betekent wel dat het plan **niet afgerond kan
|
||||
worden**: alles wat er nu ligt is een sterke aanwijzing en geen bewijs.
|
||||
|
||||
Wat er specifiek niet mee getest is, en waar de enige echte twijfel zit: de **volgorde bij het
|
||||
opstarten**. Zoraxy kan later klaar zijn dan deze app, en dan bestaat het certificaat nog niet.
|
||||
|
||||
Bijgewerkt op 20-08-2026: hier stond dat de compose daarvoor een wachtlus heeft. Die is er niet meer,
|
||||
want juist die lus was de klem van 0.0.3. De opvolger is de vangnettak in de herlaadlus, die TLS
|
||||
aanzet zodra `cert.conf` verschijnt zonder dat er een vlag bij hoort. Dat is precies het
|
||||
Zoraxy-is-later-klaar-geval, en het is nog nooit echt voorgekomen; alleen getoetst tegen tijdelijke
|
||||
bestanden.
|
||||
|
||||
**Moment:** bij de eerstvolgende herstart die er toch komt, bijvoorbeeld een umbrelOS-update of een
|
||||
stroomonderbreking. Noteer de uitkomst dan in `PROGRESS.md`. · **Eigenaar:** gebruiker
|
||||
|
||||
9. **Volgt de app-map de conventie van andere apps?** Gevraagd door de gebruiker op 20-08-2026, die
|
||||
opmerkte dat hij bij andere apps geen app-code in `app-data` ziet. Uitgezocht en vastgelegd in
|
||||
[Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md); de korte versie is dat
|
||||
config-in-app-data een bestaand patroon is (`electrs` mount zijn `torrc` zo) en dat code-in-app-data
|
||||
het gevolg is van geen eigen image bouwen, wat een besluit is en geen ongeluk.
|
||||
|
||||
**Beide vervolgpunten zijn diezelfde dag gedaan in 0.0.9**, nadat de gebruiker zei dat hij de app wil
|
||||
publiceren als standaard-app: de data staat onder `data/` met een `.gitkeep` per map, en `backupIgnore`
|
||||
noemt de sessielog en `status.json`. Niet `data/runtime/config`, want daar zit de certificaatkeuze.
|
||||
|
||||
Wat het uitzoeken daarna opleverde is groter dan dit punt en staat daarom in een eigen masterplan
|
||||
**Publicatie**: de eisen van de officiële store, wat er al aan voldoet, en het risico dat niet in een
|
||||
checklist staat, namelijk de leesmount op de certificaten van Zoraxy.
|
||||
**Moment:** afgerond · **Eigenaar:** –
|
||||
|
||||
## Beslist
|
||||
|
||||
8. **Wordt de repo hernoemd, en wat wordt dan het store-id?** - **Store-id `whatsnext`, app-id
|
||||
`whatsnext-electrum-gate`, repo-naam nog niet** (19-08-2026, gebruiker).
|
||||
|
||||
Het app-id **moet** met het store-id beginnen en de mapnaam moet gelijk zijn aan het app-id (zie
|
||||
[Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md)). De aanname bij het stellen
|
||||
van deze vraag was dat de repo-naam daar ook in zat, want de store-URL ís de repo-URL. **Dat klopte
|
||||
niet:** het store-id is gewoon een veld in `umbrel-app-store.yml` en staat los van de naam van de
|
||||
repo. Daardoor kon het store-id meteen goed gezet worden en kan de repo-naam wachten.
|
||||
|
||||
De store heet nu naar de maker en niet naar deze ene app. Dat is de variant die later een tweede app
|
||||
toelaat zonder opnieuw te hernoemen, en dat weegt hier zwaarder dan de kosten, want die zijn nul: de
|
||||
gebruiker gaf aan de app zonder bezwaar opnieuw te kunnen installeren.
|
||||
|
||||
**Afgerond op 25-08-2026, en eerder dan gedacht.** Hier stond dat de repo nog `ElectrumTLS` heette en
|
||||
dat het hernoemen zou meeliften op een publieke versie op GitHub. Wat het versnelde was Evolu Relay:
|
||||
umbrelOS leest per store één repo, dus een tweede app dwong de vraag af. De repo is
|
||||
`UmbrelApps` geworden, met `website`, `repo`, `support`, `submission` en `icon` mee, in 0.0.15.
|
||||
|
||||
**Het app-id is niet meegegaan** en dat is de reden dat dit goedkoop was: `whatsnext-electrum-gate`
|
||||
hangt aan het store-id en niet aan de URL. Voor umbrelOS is het dus dezelfde app in een andere store.
|
||||
|
||||
**Wat er wél open blijft, en nu voor het eerst echt aan de orde is:** of een geïnstalleerde app een
|
||||
wisseling van **store-URL** overleeft, of dat de store verwijderd en opnieuw toegevoegd moet worden en
|
||||
de app daarna opnieuw geïnstalleerd. Niet uitgezocht, en niet aannemen dat het meevalt. **Eigenaar:**
|
||||
gebruiker, bij het omzetten van de store in umbrelOS.
|
||||
|
||||
|
||||
1. **Draait `nginx:alpine` met de `stream`- en `stream_ssl`-module?** - **Ja** (18-08-2026).
|
||||
Op de Umbrel gecontroleerd met `docker run --rm nginx:alpine nginx -V`. Aanwezig zijn
|
||||
`--with-stream`, `--with-stream_realip_module`, `--with-stream_ssl_module` en
|
||||
`--with-stream_ssl_preread_module`, alle vier statisch meegebouwd, dus zonder `load_module`.
|
||||
|
||||
Daarmee gaat het ontwerp uit [PLAN.md](PLAN.md) §4c door in de kleine variant: één container die de
|
||||
web-UI serveert én TLS termineert, geen stunnel-installatie bij het starten, geen losse
|
||||
`cert-monitor`, en de Docker-socket-mount vervalt.
|
||||
|
||||
Twee dingen die deze uitkomst meebracht en die het opschrijven waard zijn. nginx wil de **volledige
|
||||
keten** in `ssl_certificate`, terwijl stunnel het gesplitst wilde; de `awk`-splitsing uit
|
||||
`entrypoint.sh` is daarmee overbodig in plaats van overgenomen. En dit antwoord geldt voor de tag
|
||||
`nginx:alpine` van vandaag: bij het pinnen op een digest wordt dezelfde controle op díe digest
|
||||
herhaald, anders is er iets anders bewezen dan er uitgeleverd wordt.
|
||||
|
||||
6. **Hoe komen `entrypoint.sh` en `web/` in `${APP_DATA_DIR}`?** - **Bij installatie automatisch, bij
|
||||
een update niet** (18-08-2026).
|
||||
umbreld doet bij installatie `rsync --archive` van de hele app-map naar `${APP_DATA_DIR}`, dus de
|
||||
mounts in de compose kloppen. Bij een **update** wordt alleen een whitelist ververst:
|
||||
`docker-compose.yml`, `*.template`, `exports.sh`, `torrc`, `hooks` en `umbrel-app.yml`.
|
||||
|
||||
Gevolg dat het ontwerp stuurt: een gewijzigde `entrypoint.sh` bereikt een bestaande installatie nooit,
|
||||
zonder foutmelding. Logica die later nog moet kunnen wijzigen hoort daarom in de compose, in de image,
|
||||
of in een `*.template`-bestand; dat laatste staat in de whitelist én wordt bij elke start met de
|
||||
omgevingsvariabelen ingevuld. Zie de naslag
|
||||
[Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md).
|
||||
|
||||
3. **Wanneer wordt er voor het eerst gepusht?** - **Meteen, vóór de opschoning** (18-08-2026).
|
||||
De repo staat sindsdien publiek op `https://sc.kamenier-hamer.nl/sysop/ElectrumTLS.git`, met het
|
||||
domein en het certificaatpad er nog in. Publiek zijn was geen keuze (umbreld kloont anoniem), alleen
|
||||
de volgorde was dat. Afweging van de gebruiker: de repo is voor eigen gebruik en wordt niet
|
||||
aangekondigd, dus vindbaarheid is laag.
|
||||
Gevolg dat vastligt: die waarden staan nu in de **historie**. Het plan **Configuratie** haalt ze uit de
|
||||
bestanden, niet uit de historie; dat laatste zou een herschrijving vragen. Behandel het domein dus als
|
||||
bekend, en laat het geen reden zijn om Configuratie uit te stellen of juist te haasten.
|
||||
|
||||
**Bijgewerkt 25-08-2026: die historie is bij de verhuizing achtergebleven.** `UmbrelApps` is als lege
|
||||
repo begonnen met alleen de huidige toestand erin, op verzoek van de gebruiker die de historie niet
|
||||
nodig had. Daarmee vervalt de vaststelling hierboven, maar **pas als de oude repo weg is**: zolang
|
||||
`ElectrumTLS` op de Git-server staat, staat het domein daar nog in de historie. Dat weghalen is dus
|
||||
geen opruimwerk maar het laatste stuk van deze beslissing. **Eigenaar:** gebruiker
|
||||
|
||||
5. **Mag de app-id later nog wijzigen?** - **Ja** (18-08-2026).
|
||||
Er zijn geen andere installaties, dus achterwaartse compatibiliteit is geen eis. Een wijziging kost
|
||||
één keer opnieuw installeren. Genoteerd omdat de prefix-regel anders zwaarder lijkt dan hij is: de
|
||||
keuze `electrumtls-electrum-tls` mag herzien worden zolang dat vóór fase 6 gebeurt.
|
||||
@@ -0,0 +1,193 @@
|
||||
# Appstore - plan
|
||||
|
||||
> Ontwerp en afbakening. **Dit bestand lees je zelden**, alleen bij twijfel over scope of architectuur.
|
||||
> Status staat in [TAKEN.md](TAKEN.md), geschiedenis in [PROGRESS.md](PROGRESS.md), onbesliste punten in
|
||||
> [OPEN.md](OPEN.md).
|
||||
|
||||
## 1. Doel
|
||||
|
||||
De app draait nu als een met de hand neergezette docker-compose die umbrelOS niet kent. Gevolg: na een
|
||||
herstart van de Umbrel, of als een app waar deze van afhangt omvalt, moet er met de hand
|
||||
`docker compose down` en `up` gedaan worden. Dit plan maakt er een echte Umbrel-app van in een eigen
|
||||
community app store: een tegel met icoon, die umbrelOS zelf installeert, start en na een herstart weer
|
||||
opbrengt.
|
||||
|
||||
Als dit af is, is de repo tegelijk de app store: de URL erin plakken in umbrelOS is genoeg om de app te
|
||||
installeren, en een `git push` is genoeg om een update uit te leveren.
|
||||
|
||||
## 2. Afbakening
|
||||
|
||||
- De repo omzetten naar de vorm die umbrelOS voor een community app store verwacht.
|
||||
- `docker-compose.yml` omzetten naar de moderne vorm: `app_proxy`, geen zelfgebouwd netwerk, geen
|
||||
handmatige host-poorten waar dat niet hoeft.
|
||||
- De Electrum-backend via de afhankelijkheid aanspreken in plaats van via een hardgecodeerde
|
||||
containernaam, zodat Electrs, Fulcrum en ElectrumX alle drie werken.
|
||||
- Een image die gepind kan worden, in plaats van `alpine:latest` met `apk add` bij elke start.
|
||||
- Het manifest compleet en eerlijk maken: eigen icoon, eigen gallery, kloppende velden.
|
||||
- De oude `install.sh` en `uninstall.sh` weghalen.
|
||||
|
||||
De volledige spec waar dit tegenaan moet, met bronvermelding per feit, staat in
|
||||
[Referenties/Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md). Die is bij het
|
||||
schrijven van dit plan uitgezocht en hoeft niet opnieuw opgezocht te worden.
|
||||
|
||||
## 3. Niet-doelen
|
||||
|
||||
- **De hardgecodeerde waarden eruit halen.** Het domein `sync.kamenier-hamer.nl` en het Zoraxy-pad blijven
|
||||
in dit plan staan zoals ze zijn. Dat is het plan **Configuratie**, en het apart houden is bewust: een
|
||||
commit die tegelijk de structuur omgooit en de configuratie herontwerpt is niet meer na te lezen.
|
||||
- **De web-UI eerlijk maken.** De pagina toont verzonnen status. Dat is het plan **Webinterface**. Hier
|
||||
wordt de pagina alleen verhuisd en aan `app_proxy` gehangen, niet herschreven.
|
||||
- **Meerdere apps in de store.** De store krijgt de vorm die meer apps toelaat, maar er komt er één in.
|
||||
- **Indienen bij de officiële Umbrel App Store.** Een community store is er juist om dat niet te hoeven.
|
||||
Als het later toch aantrekkelijk wordt, is de spec-eis grotendeels dezelfde, dus dit sluit niets af.
|
||||
|
||||
## 4. Ontwerp
|
||||
|
||||
### 4a. De repo-vorm
|
||||
|
||||
```
|
||||
UmbrelApps/
|
||||
├── umbrel-app-store.yml id: whatsnext
|
||||
├── whatsnext-electrum-gate/
|
||||
│ ├── umbrel-app.yml id: whatsnext-electrum-gate
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── *.template
|
||||
│ └── data/{certs,runtime}/.gitkeep
|
||||
├── whatsnext-evolu-relay/ komt er bij het masterplan Umbrelapp
|
||||
├── Docs/
|
||||
├── tests/
|
||||
└── README.md
|
||||
```
|
||||
|
||||
De store-id is `whatsnext`. De prefix-eis is hard: mapnaam en manifest-`id` moeten gelijk zijn en allebei
|
||||
met de store-id beginnen.
|
||||
|
||||
**Bijgewerkt op 25-08-2026**, toen de repo een store met meer dan één app werd. Hier stond nog de vorm van
|
||||
18-08-2026 met store-id `electrumtls`; die was al achterhaald door fase 7. Wat de tweede app bewijst is dat
|
||||
de keuze van 19-08 om de store naar de maker te noemen in plaats van naar deze ene app, klopte: er hoefde
|
||||
niets voor te hernoemen.
|
||||
|
||||
### 4b. Backend-onafhankelijk, en waarom dat bijna niets kost
|
||||
|
||||
umbrelOS 1.3 heeft swappable dependencies. Fulcrum en ElectrumX declareren allebei `implements: [electrs]`
|
||||
en hun `exports.sh` aliast `APP_ELECTRS_IP`, `APP_ELECTRS_NODE_IP` en `APP_ELECTRS_NODE_PORT` naar hun
|
||||
eigen waarden. De gebruiker kiest de implementatie in de umbrelOS-instellingen; umbrelOS laadt de
|
||||
`exports.sh` van de gekozen app.
|
||||
|
||||
Deze app hoeft daarvoor dus **geen keuzemechanisme te bouwen**. Het is dit:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
- electrs
|
||||
```
|
||||
|
||||
en in de compose `${APP_ELECTRS_NODE_IP}:${APP_ELECTRS_NODE_PORT}` gebruiken.
|
||||
|
||||
Twee vallen om te vermijden. De eerste: de huidige compose zet `ELECTRS_HOST=${APP_ELECTRS_IP}`, en dat
|
||||
is de **web-UI-container** van Electrs, niet de Electrum-server; dat moet `APP_ELECTRS_NODE_IP` worden.
|
||||
De tweede: alleen `IP`, `NODE_IP` en `NODE_PORT` worden gealiast, dus alles wat Electrs-specifiek is
|
||||
(zoals `APP_ELECTRS_RPC_HIDDEN_SERVICE`) mag hier niet gebruikt worden.
|
||||
|
||||
### 4c. De image: nginx `stream` in plaats van stunnel
|
||||
|
||||
Het huidige `alpine:latest` plus `apk add stunnel` bij elke start is op drie manieren fout: het is niet
|
||||
te pinnen, het faalt zonder internet, en het maakt de starttijd afhankelijk van een Alpine-mirror. De
|
||||
app-store-eis is een image gepind op de multi-arch index-digest.
|
||||
|
||||
Er zijn drie wegen, en de aanbeveling is de derde:
|
||||
|
||||
1. **Eigen image bouwen** met een `Dockerfile` en een workflow die multi-arch naar een registry duwt.
|
||||
Correct, maar het voegt CI, een registry en een tweede uitleverstroom toe aan een app die verder uit
|
||||
twee shellscripts bestaat.
|
||||
2. **Een bestaande stunnel-image pinnen.** Er is geen onderhouden multi-arch stunnel-image die het
|
||||
vertrouwen waard is. Afgevallen.
|
||||
3. **De officiële `nginx`-image gebruiken en de `stream`-module de TLS-terminatie laten doen.** Die image
|
||||
is multi-arch, wordt onderhouden en is gewoon te pinnen. Dan valt er meer weg dan alleen het
|
||||
bouwprobleem:
|
||||
- dezelfde container serveert de web-UI én termineert TLS, dus van drie containers blijft er één over.
|
||||
**Bijgesteld 19-08-2026:** het zijn er weer twee, want er is een agent bijgekomen. De winst die hier
|
||||
bedoeld werd blijft wel staan: geen Docker-socket, geen installatie bij het starten, en de
|
||||
certificaatwissel is een reload. Zie het plan **Webinterface**, `PLAN.md` §4a0;
|
||||
- een certificaatwissel wordt `nginx -s reload` **binnen** de container, dus de `cert-monitor` heeft de
|
||||
Docker-socket niet meer nodig. Die socket is nu read-only gemonteerd, maar read-only op de
|
||||
Docker-socket beschermt niets: wie de socket kan lezen kan containers starten en is daarmee root op
|
||||
de host. Dat weghalen is de grootste beveiligingswinst in dit plan;
|
||||
- een reload verbreekt bestaande verbindingen niet, een containerherstart wel.
|
||||
|
||||
**Te verifiëren voordat hierop gebouwd wordt:** dat de officiële `nginx:alpine` daadwerkelijk met
|
||||
`--with-stream` en `--with-stream_ssl_module` gebouwd is. Dat is de aanname waar deze hele keuze op
|
||||
rust en hij is in één commando te controleren (`nginx -V`). Klopt hij niet, dan valt dit terug op weg 1.
|
||||
|
||||
De `awk`-splitsing van de certificaat-chain uit `entrypoint.sh` blijft bruikbaar en wordt overgenomen.
|
||||
|
||||
### 4d. Poorten
|
||||
|
||||
`port:` in het manifest is de **web-UI-poort** van de tegel, niet de TLS-poort. Dat staat nu op 50002 en
|
||||
is daarmee fout.
|
||||
|
||||
De TLS-poort blijft een gepubliceerde host-poort; daar helpt `app_proxy` niet, want dat is voor HTTP.
|
||||
Welke poort dat wordt is een open punt in **Configuratie**: Fulcrum bezet host-poort 50002 en botst dus
|
||||
met de huidige keuze.
|
||||
|
||||
### 4e. De eigen Git-server als app store
|
||||
|
||||
De repo staat op `https://sc.kamenier-hamer.nl/sysop/UmbrelApps.git` (tot 25-08-2026:
|
||||
`.../ElectrumTLS.git`). umbreld valideert de URL alleen
|
||||
met de `URL`-constructor en kloont met isomorphic-git; er is geen GitHub-eis. Wat er wél uit die aanroep
|
||||
volgt, en op 18-08-2026 in orde is bevonden:
|
||||
|
||||
- **HTTPS, niet SSH.** In orde.
|
||||
- **Anoniem kloonbaar.** In orde sinds 18-08-2026, maar het kostte moeite en de oorzaak was niet de
|
||||
voor de hand liggende.
|
||||
|
||||
umbrelOS gaf `HTTP Error: 401 Unauthorized` bij het toevoegen van de store. De repo stond op public en
|
||||
`REQUIRE_SIGNIN_VIEW` stond op `false`, en toch weigerde Gitea. De oorzaak was de zichtbaarheid van het
|
||||
**account** `sysop`, die op "limited" stond. **Gitea staat niet toe dat een repo zichtbaarder is dan
|
||||
zijn eigenaar**, dus de repo werd stilzwijgend teruggezet naar "intern", wat voor een niet-ingelogde
|
||||
bezoeker hetzelfde is als privé. De knop "make public" leek te werken maar het label bleef op
|
||||
"intern" staan, en dat is het enige zichtbare spoor.
|
||||
|
||||
Dit is eerst verkeerd beoordeeld, en de manier waaróp is het onthouden waard. Een `git ls-remote` vanaf
|
||||
de werkmachine slaagde, ook met `GIT_TERMINAL_PROMPT=0`, en dat leek bewijs van anonieme toegang. Het
|
||||
was het niet: Git Credential Manager stuurde de bij de push opgeslagen inloggegevens stilzwijgend mee.
|
||||
`GIT_TERMINAL_PROMPT=0` onderdrukt alleen de **vraag** om een wachtwoord, niet het **aanleveren** ervan.
|
||||
De test die het wel aantoont, zet de credential-helper leeg:
|
||||
|
||||
```
|
||||
GIT_TERMINAL_PROMPT=0 git -c credential.helper= ls-remote <url>
|
||||
```
|
||||
|
||||
Die faalt met `could not read Username`, en dat is de toestand die umbreld ziet.
|
||||
- **SHA-1 als objectformaat.** In orde, na het opnieuw aanmaken van de repo. isomorphic-git kan geen
|
||||
SHA-256; zie de naslag.
|
||||
- **Geldig certificaat op `sc.kamenier-hamer.nl`.** Nog niet expliciet gecontroleerd vanaf de Umbrel.
|
||||
- **Alles op de standaardbranch.** In orde: `main`, zowel lokaal als op de remote.
|
||||
- **De URL is de identiteit van de store.** Wijzigt hij, dan ziet umbrelOS een andere store en moet hij
|
||||
opnieuw toegevoegd worden.
|
||||
|
||||
## 5. Raakvlakken
|
||||
|
||||
**Configuratie** herschrijft dezelfde bestanden en wacht op dit plan. Twee dingen komen daarvandaan
|
||||
terug: de TLS-poort (open punt daar, want Fulcrum bezet 50002) en het feit dat het domein na dit plan nog
|
||||
steeds vast in de code staat.
|
||||
|
||||
**Webinterface** wacht op Configuratie en raakt hier alleen de verhuizing van `web/index.html`. Het
|
||||
containerontwerp uit §4c is wel de reden dat dat plan zonder backend kan: de proxy en de webserver worden
|
||||
één container, dus als de pagina geserveerd wordt, draait de proxy ook.
|
||||
|
||||
## 6. Verificatie
|
||||
|
||||
Er zijn geen tests in dit project en die zijn hier ook niet zinvol: de app is configuratie, geen code.
|
||||
Wat er wél moet, en wat per se handmatig op het apparaat gebeurt:
|
||||
|
||||
- de store laat zich in umbrelOS toevoegen en de app verschijnt met icoon en tegel;
|
||||
- installeren via de umbrelOS-interface werkt zonder SSH;
|
||||
- **na `sudo reboot` komt de app vanzelf terug.** Dit is de aanleiding voor het hele plan en dus de
|
||||
belangrijkste controle;
|
||||
- de app komt ook terug nadat Electrs handmatig gestopt en gestart is;
|
||||
- een Electrum-wallet verbindt over TLS en verifieert het certificaat;
|
||||
- omschakelen naar Fulcrum in de umbrelOS-instellingen laat de app werken zonder aanpassing.
|
||||
|
||||
Wat automatisch gecontroleerd kan worden, en de moeite waard is omdat het de fouten vangt die je niet
|
||||
ziet: dat de YAML geldig is, dat het `id` in het manifest gelijk is aan de mapnaam, en dat elke `image:`
|
||||
een `@sha256:`-digest heeft.
|
||||
@@ -0,0 +1,222 @@
|
||||
# Voortgang - Appstore
|
||||
|
||||
> Chronologisch sessielog, nieuwste bovenaan. Kort: 3 tot 6 regels per entry. Wat er is gebeurd en
|
||||
> waarom, niet wat er nog moet: dat staat in [TAKEN.md](TAKEN.md).
|
||||
|
||||
## 20-08-2026 - alles van de verse installatie nagekeken; dit plan zakt naar B
|
||||
|
||||
De hele checklist van de herinstallatie is bevestigd door de gebruiker: `data/` met `certs/` en `runtime/`
|
||||
eronder, de pagina komt op zonder gekozen certificaat, `v0.0.9` staat achter de tagline, de keuzelijst voor
|
||||
de Electrum-server verscheen bij het installeren, en daarna werkten kiezen én uploaden.
|
||||
|
||||
**Daarmee is dit plan in de kern af en gaat het van A naar B.** Alles waar het om begon is bewezen: de app
|
||||
is een echte umbrelOS-app, hij komt op uit een schone installatie, en een wallet van buiten verbindt over
|
||||
TLS. Wat er nog staat is niet te plannen (de herstartcontrole) of hoort bij het masterplan **Publicatie**.
|
||||
**Webinterface** is daarmee tier A geworden en van 020 naar 005 hernummerd; dit plan houdt 010.
|
||||
|
||||
**Geraakt:** alleen documentatie. **Tests:** niet van toepassing.
|
||||
|
||||
## 20-08-2026 - verse installatie van 0.0.9, en die werkte
|
||||
|
||||
De gebruiker heeft de app gedeïnstalleerd en opnieuw geïnstalleerd in plaats van geüpdatet, zodat de
|
||||
app-data schoon is. **Dat werkte, en het bewijst iets wat op een bestaande installatie niet te bewijzen
|
||||
was:** de pagina komt omhoog op een installatie waar nog nooit een certificaat gekozen is. Dat is precies
|
||||
de situatie waarin 0.0.3 stukliep, en de reparatie uit 0.0.4 was tot nu toe alleen getoetst op een
|
||||
installatie die die keuze al had.
|
||||
|
||||
Wat er nog níet uit volgt: of de twee `.gitkeep`-bestanden hun werk deden. Een werkende app bewijst dat
|
||||
niet, want Docker maakt een ontbrekende bind-mount-map zelf aan; het verschil zit alleen op schijf. Staat
|
||||
als losse taak, want het is een eis voor het masterplan **Publicatie**.
|
||||
|
||||
**Geraakt:** alleen documentatie. **Tests:** niet van toepassing.
|
||||
|
||||
## 20-08-2026 - data onder data/, en een doel dat de maatstaf verandert
|
||||
|
||||
De gebruiker vroeg of het klopt dat alle runtime-bestanden in de installatiemap staan, want bij andere apps
|
||||
ziet hij daar geen app-code. **Dat klopt, en het verschil zit niet in umbrelOS:** voor elke app wordt de
|
||||
hele app-map naar `app-data` gekopieerd, maar andere apps hebben hun code in een image. Config uit
|
||||
`app-data` mounten is wél een bestaand patroon; `electrs` doet zijn `torrc` precies zo, en `torrc` en
|
||||
`*.template` staan met naam in de update-whitelist. Bijvangst: de invulling gebeurt met `envsubst`, en dat
|
||||
is de onderbouwing van de architectuurregel over accolade-variabelen.
|
||||
|
||||
Waar deze app echt afweek was de plaats van de data, en dat is in **0.0.9** verholpen: `runtime/` en
|
||||
`certs/` staan nu onder `data/`, met een `.gitkeep` per map. Aanleiding was het antwoord op de vervolgvraag:
|
||||
**de gebruiker wil de app publiceren als standaard-app voor Umbrel.** De packaging-documentatie van umbrel
|
||||
zegt woordelijk dat gebruikersstaat onder `${APP_DATA_DIR}/data/...` hoort, dus dit was geen smaak.
|
||||
|
||||
Dat doel verandert de maatstaf van "hij werkt hier" naar "iemand anders keurt het pakket goed", en dat is
|
||||
een eigen plan geworden: **Publicatie**, als masterplan. Het meeste blijkt al goed; wat er nog moet is de
|
||||
images pinnen, het app-id kaal maken en de manifestvelden op orde brengen. Het risico staat niet in die
|
||||
lijst: deze app leest de certificaatmap van een andere app, en dat is precies waar een review over valt.
|
||||
|
||||
**Geraakt:** `docker-compose.yml`, `umbrel-app.yml` (0.0.9 en `backupIgnore`), twee `.gitkeep`-bestanden,
|
||||
`Referenties/Umbrel-appstore-spec.md`, `OPEN.md` punt 7 en 9, nieuw
|
||||
`Plannen/Masterplannen/Publicatie.PLAN.md`, `tests/test_server_start_zonder_certificaat.py`.
|
||||
**Tests:** 48 goed 0 fout en 33 goed 0 fout, niets overgeslagen; de data-conventie is mutatie-getest.
|
||||
|
||||
## 20-08-2026 - de app werkt: pagina, keuze, TLS en een wallet van buiten
|
||||
|
||||
**De reparatie werkt.** Na de uitrol van 0.0.4 laadt het dashboard, met de melding "No certificate in use"
|
||||
en de reden van de agent erbij. De agent vond **veertien certificaten in Zoraxy** en koos daarom niets; dat
|
||||
is de weigering die zo bedoeld is, en het antwoord op de vraag die de log van 0.0.3 openliet.
|
||||
|
||||
Wat de gebruiker er meteen van zei: die reden somde alle veertien domeinnamen op, en dat is een muur tekst
|
||||
die zegt wat de keuzelijst eronder al toont. **0.0.5** geeft alleen het aantal. De weigering zelf blijft.
|
||||
|
||||
**En daarna liep het hele pad.** Een certificaat kiezen op de pagina werkt: de agent nam de keuze aan, nginx
|
||||
kwam met poort 50022 door, en na het aanpassen van de doorstuurregel in de router verbindt een wallet van
|
||||
buiten. **Daarmee is fase 6 in de kern klaar** en is de app voor het eerst als umbrelOS-app af.
|
||||
|
||||
**Geraakt:** `agent.py.template` (`choose`), `umbrel-app.yml` (0.0.5), `tests/test_agent_certificates.py`,
|
||||
`CHANGELOG.md`. **Tests:** 21 goed 0 fout en 15 goed 0 fout, niets overgeslagen; de ingekorte reden is
|
||||
mutatie-getest. Nog open op de Umbrel: de herstartcontrole en het omschakelen naar Fulcrum.
|
||||
|
||||
## 20-08-2026 - 0.0.3 geinstalleerd, geen UI, en de oorzaak was het ontwerp
|
||||
|
||||
**De app is geinstalleerd en er kwam geen pagina.** De log van `app_proxy` meldde alleen dat de server niet
|
||||
te bereiken was, en die van `server` herhaalde "Wachten tot de agent een certificaat gekozen heeft". Dat is
|
||||
geen storing maar een klem in het ontwerp: het stream-blok met `listen 50022 ssl` includeerde de `cert.conf`
|
||||
van de agent, nginx weigert te starten zonder dat certificaat, dus ook de pagina kwam niet omhoog. En de
|
||||
pagina is precies waar je dat certificaat kiest.
|
||||
|
||||
**Verholpen in 0.0.4** door het TLS-deel naar `stream.conf.template` te verplaatsen; het `command`-blok legt
|
||||
dat pas in `/var/lib/gate/tls/` als `cert.conf` bestaat, en `nginx.conf` haalt die map met een jokerteken op.
|
||||
Meegenomen: een mislukte `nginx -s reload` brak de herlaadlus af, want die draait onder `set -e`.
|
||||
|
||||
Wat de log wél bewees: de agent start en luistert (`[gate] api listening on port 8000`), en Tor bootstrapt.
|
||||
Wat de agent in de certificaatmappen vond, is nog onbekend; dat leest de pagina van 0.0.4 straks voor.
|
||||
|
||||
**Geraakt:** `nginx.conf.template`, `docker-compose.yml`, nieuw `stream.conf.template`, `umbrel-app.yml`
|
||||
(0.0.4 en release notes), `CLAUDE.md`, `CHANGELOG.md`, nieuw
|
||||
`tests/test_server_start_zonder_certificaat.py`. **Tests:** 21 goed 0 fout en 15 goed 0 fout, niets
|
||||
overgeslagen. De reparatie zelf is **niet** geverifieerd: dat vraagt de uitrol op de Umbrel.
|
||||
|
||||
## 19-08-2026 - sessie afgesloten; dit plan is de enige tier A
|
||||
|
||||
Bij de prioriteitsherziening blijft **Appstore de enige tier A**, en de reden is dat er precies één
|
||||
handeling openstaat waar al het andere achter wacht: de app installeren. **Webinterface is naar C gezakt**;
|
||||
dat plan is af voor zover het zonder de Umbrel kan.
|
||||
|
||||
Wat er van de gebruiker moet, in deze volgorde: de doorstuurregel in de router naar 50022, dan de oude app
|
||||
verwijderen, de store-URL opnieuw laten ophalen en `whatsnext-electrum-gate` installeren. Versie staat op
|
||||
0.0.3 en de release notes kloppen, dus daar hoeft niets meer aan.
|
||||
|
||||
Ook opgemerkt en als taak vastgelegd: het plan **Configuratie** is grotendeels ingehaald door het werk van
|
||||
vandaag. De agent doet de certificaatbronnen en de keuze al, en het hardgecodeerde domein is uit de compose
|
||||
en uit `nginx.conf.template` verdwenen. Dat plan moet dus eerst opgeschoond worden voordat promotie nog
|
||||
zin heeft, anders lijkt het groter dan het is.
|
||||
|
||||
**Geraakt:** alleen documentatie in deze entry.
|
||||
**Tests:** 21 goed, 0 fout.
|
||||
|
||||
## 19-08-2026 - hernoemd naar Electrum Gate, fase 7 grotendeels af
|
||||
|
||||
De wallet-verbinding had de nacht doorstaan, dus de `proxy_timeout`-fix is bewezen en de storing waar de
|
||||
sessie van gisteren mee begon is verklaard en verholpen.
|
||||
|
||||
De app heet nu **Electrum Gate**, met store-id `whatsnext` en app-id `whatsnext-electrum-gate`. Bij het
|
||||
voorleggen van die keuze zat een fout in mijn eigen redenering: ik nam aan dat de repo-naam het store-id
|
||||
bepaalt, omdat de store-URL de repo-URL is. Dat is niet zo, het store-id is gewoon een veld. Daardoor kon
|
||||
het meteen goed en kan de repo-naam wachten tot er een publieke versie op GitHub komt.
|
||||
|
||||
Twee dingen die er vooruitlopend op andere plannen bij konden, omdat er tóch opnieuw geïnstalleerd wordt:
|
||||
de TLS-poort is 50022 in plaats van 50002, wat de botsing met Fulcrum wegneemt, en de web-UI is
|
||||
herbouwd. **Dat vraagt eenmalig een aanpassing van de doorstuurregel in de router**, anders komt een
|
||||
wallet van buiten niet meer binnen.
|
||||
|
||||
De tagline en de beschrijving zijn Engels geworden en gaan nu over de afweging Tor tegenover snelheid, in
|
||||
plaats van over TLS als middel.
|
||||
|
||||
**Geraakt:** `umbrel-app-store.yml`, de app-map (hernoemd), `umbrel-app.yml`, `docker-compose.yml`,
|
||||
`nginx.conf.template`, `README.md` en de plannen.
|
||||
**Tests:** dit project heeft geen suite. **Niets hiervan is op de Umbrel gedraaid**: de nieuwe app is nog
|
||||
niet geïnstalleerd, en `version` staat nog op 2.0.1 omdat de gebruiker de UI eerst wilde zien.
|
||||
|
||||
## 18-08-2026 - storing na tien minuten, en de besluiten over naam en dashboard
|
||||
|
||||
Kort na de installatie viel de wallet-verbinding weg. De container bleef onafgebroken draaien
|
||||
(`status=running`, `restarts=0`, schone nginx-log), wat de container als oorzaak uitsloot en één
|
||||
verdachte overliet: `proxy_timeout` in een `stream`-blok staat standaard op tien minuten, en een
|
||||
Electrum-wallet houdt een langlopende, grotendeels stille verbinding open. **Dit was een regressie van
|
||||
diezelfde dag:** stunnel hanteerde twaalf uur, en dat verschil is bij de vertaling naar nginx niet
|
||||
opgemerkt. Nu op twaalf uur, met `proxy_socket_keepalive`.
|
||||
|
||||
Meegenomen omdat ze bij het uitzoeken bovenkwamen: nginx draaide als achtergrondproces onder een shell,
|
||||
die daardoor PID 1 was en signalen niet doorgaf, en het script eindigde met exitcode 0 als nginx omviel,
|
||||
waardoor `restart: on-failure` niet zou ingrijpen. Nginx is nu met `exec` het hoofdproces.
|
||||
|
||||
De gebruiker vroeg of umbrelOS een update wel zou zien, en dat was de goede vraag: het `version`-veld
|
||||
stond nog op 2.0.0, dus de fix was nooit uitgerold. Zonder melding en zonder fout. Na 2.0.1 kwam de
|
||||
update binnen en werkte hij, wat meteen de hele uitleverketen aantoont.
|
||||
|
||||
Aan het eind besloten: de app gaat **Electrum Gateway** heten, want de oude naam beschreef het middel en
|
||||
niet de waarde. En het dashboard krijgt alleen lokale gegevens; koersdata valt af omdat de browser van
|
||||
elke bezoeker dan bij een derde partij aanklopt.
|
||||
|
||||
**Geraakt:** `docker-compose.yml`, `nginx.conf.template`, `umbrel-app.yml`, en de plannen.
|
||||
**Tests:** niet van toepassing. **De `proxy_timeout`-fix is nog niet bewezen**: die brak pas na tien
|
||||
minuten stilte, dus dat vraagt een langere observatie. Ook de herstart-controle staat nog open.
|
||||
|
||||
## 18-08-2026 - geinstalleerd op de Umbrel, wallet verbindt
|
||||
|
||||
De app is als Umbrel-app geïnstalleerd en een Electrum-wallet krijgt over TLS direct data terug. Dat
|
||||
bewijst het hele pad in één keer: het `stream`-blok, het certificaat, en de verbinding naar de
|
||||
Electrum-server via `APP_ELECTRS_NODE_IP`.
|
||||
|
||||
De weg erheen kostte drie omwegen die allemaal buiten de app zelf lagen. De Gitea-repo was als SHA-256
|
||||
aangemaakt terwijl isomorphic-git alleen SHA-1 kan. Daarna weigerde Gitea anonieme toegang, en de oorzaak
|
||||
bleek niet de repo maar de zichtbaarheid van het **account**: Gitea staat niet toe dat een repo
|
||||
zichtbaarder is dan zijn eigenaar en zet hem dan zwijgend terug naar "intern". En de installatie faalde
|
||||
drie keer op `Bind for 0.0.0.0:50002 failed: port is already allocated`, omdat de oude handmatige
|
||||
container nog draaide. Dat laatste was de voorspelde en gewenste faalrichting: de bestaande dienst bleef
|
||||
gewoon werken.
|
||||
|
||||
Eén les die het onthouden waard is: een `git ls-remote` vanaf de eigen machine bewees niets over anonieme
|
||||
toegang, want de credential-helper stuurde de opgeslagen inloggegevens stilzwijgend mee. Dat leidde tot
|
||||
een verkeerde diagnose die pas onderuitging met `-c credential.helper=`.
|
||||
|
||||
**Geraakt:** niets in de app; alleen documentatie en de configuratie van de Gitea-server.
|
||||
**Tests:** niet van toepassing. Wallet-verbinding handmatig geverifieerd. **De herstart-controle staat
|
||||
nog open**, en dat is de aanleiding van het hele plan.
|
||||
|
||||
## 18-08-2026 - fases 1 tot en met 5 gebouwd
|
||||
|
||||
De repo heeft de vorm van een community app store, de compose is omgezet naar
|
||||
`app_proxy`, de backend loopt via de afhankelijkheid, en het manifest klopt met een eigen icoon.
|
||||
|
||||
Twee dingen die het uitzoekwerk opleverde en die het ontwerp veranderd hebben. De controle op de Umbrel
|
||||
bevestigde dat `nginx:alpine` alle vier de stream-modules meebrengt, waardoor drie containers er één
|
||||
werden en de Docker-socket kon vervallen; dat was de grootste beveiligingswinst en hij was gratis. En
|
||||
umbreld blijkt bij een **update** alleen een whitelist te verversen (`docker-compose.yml`, `*.template`,
|
||||
`exports.sh`, `torrc`, `hooks`, `umbrel-app.yml`), terwijl bij installatie de hele map wordt gekopieerd.
|
||||
Daarom staat de nginx-configuratie in een `*.template` en niet in een los script: anders had een `git
|
||||
push` stilzwijgend niets gedaan bij een bestaande installatie.
|
||||
|
||||
Ook bleek de `awk`-splitsing van de certificaatketen niet overgenomen te hoeven worden maar juist fout
|
||||
te zijn: nginx wil de volledige keten in `ssl_certificate`, waar stunnel hem gesplitst wilde.
|
||||
|
||||
**Geraakt:** `umbrel-app-store.yml`, `electrumtls-electrum-tls/` (compose, manifest, `nginx.conf.template`,
|
||||
`icon.png`), verwijderd zijn `entrypoint.sh`, `cert-watch.sh`, `install.sh` en `uninstall.sh`.
|
||||
**Tests:** niet van toepassing, dit project heeft er geen. **Niets is op de Umbrel geïnstalleerd of
|
||||
gedraaid**; dat is fase 6.
|
||||
|
||||
## 18-08-2026 - plan werd actief
|
||||
|
||||
Dit plan is als eerste actief geworden omdat het de aanleiding van de hele sessie oplost: de app draait
|
||||
als een handmatig neergezette docker-compose die umbrelOS niet kent, en moet na elke herstart of na een
|
||||
storing in een afhankelijkheid met de hand opgestart worden.
|
||||
|
||||
De repo is dezelfde dag onder versiebeheer gebracht en gepusht naar
|
||||
`https://sc.kamenier-hamer.nl/sysop/ElectrumTLS.git`. Dat kostte één omweg: de Gitea-repo was als SHA-256
|
||||
aangemaakt, en de push faalde met een melding die de oorzaak niet noemt. Bij het uitzoeken bleek het
|
||||
probleem groter dan de push, want umbreld kloont met isomorphic-git en die kan uitsluitend SHA-1. De repo
|
||||
is opnieuw aangemaakt als SHA-1.
|
||||
|
||||
Twee dingen die het uitzoekwerk opleverde en die het werk kleiner maken dan gedacht. umbrelOS doet géén
|
||||
hostnaamcontrole op de store-URL, dus een eigen Gitea kan de app store zijn. En wisselen tussen Electrs,
|
||||
Fulcrum en ElectrumX vraagt geen eigen mechanisme: die declareren `implements: [electrs]` en aliassen
|
||||
zichzelf naar `APP_ELECTRS_*`, dus twee regels volstaan. Dat was oorspronkelijk een apart plan waard en
|
||||
is nu fase 3.
|
||||
|
||||
**Geraakt:** promotie vanuit `Plannen/Masterplannen/Appstore.PLAN.md`; nog geen app-bestanden.
|
||||
**Tests:** niet van toepassing, dit project heeft er geen. Er is nog niets op de Umbrel geverifieerd.
|
||||
@@ -0,0 +1,174 @@
|
||||
# Taken - Appstore
|
||||
|
||||
> Prioriteit: **B** | Afhankelijk van: –
|
||||
>
|
||||
> **Van A naar B op 20-08-2026**, bij de prioriteitsherziening na de verse installatie van 0.0.9. Alles
|
||||
> waar dit plan om begon is af: de app is een echte umbrelOS-app, hij komt op uit een schone installatie,
|
||||
> en een wallet van buiten verbindt over TLS. Wat er nog staat is niet te plannen (de herstartcontrole
|
||||
> wacht op een herstart die er toch komt) of hoort bij het masterplan **Publicatie**. Het plan houdt zijn
|
||||
> nummer 010; alleen **Webinterface** kreeg een nieuw nummer bij de promotie naar A.
|
||||
|
||||
## Volgende stap
|
||||
|
||||
- [x] **De maphiërarchie na een verse installatie nagekeken. In orde (20-08-2026):** in
|
||||
`~/umbrel/app-data/whatsnext-electrum-gate/` staat `data/` met `certs/` en `runtime/` eronder. Dat is
|
||||
de vorm die de appstore-eis vraagt, en samen met de twee `.gitkeep`-bestanden in de repo is dat punt
|
||||
van het masterplan **Publicatie** dus af. Wat deze controle niet onderscheidt is wie de mappen
|
||||
aanmaakte, `rsync` of Docker; voor de eis maakt dat niet uit, want die gaat over wat er in de repo
|
||||
staat
|
||||
|
||||
- [x] **0.0.9 opnieuw geïnstalleerd in plaats van geüpdatet. Gelukt (20-08-2026).** De gebruiker koos een
|
||||
deïnstallatie plus verse installatie omdat de app-data dan schoon is, en dat werkte. Daarmee is
|
||||
bewezen wat op een bestaande installatie niet te bewijzen was: **de pagina komt omhoog op een
|
||||
installatie waar nog nooit een certificaat gekozen is.** Dat is precies de situatie waarin 0.0.3
|
||||
stukliep
|
||||
- [ ] **Na `sudo reboot` controleren dat de app vanzelf terugkomt.** Dit is de aanleiding voor het hele
|
||||
plan en nu het enige wat er in de kern nog openstaat; zie fase 6. **Eigenaar: gebruiker, op een
|
||||
moment dat het kan**
|
||||
|
||||
- [x] **De doorstuurregel in de router naar poort 50022 gezet (20-08-2026).** Nodig omdat de app niet meer
|
||||
op 50002 luistert; zonder deze regel komt een wallet van buiten niet binnen
|
||||
- [x] **Een certificaat kiezen op de pagina, en daarmee het hele pad. Gelukt (20-08-2026):** de keuze werd
|
||||
aangenomen, nginx kwam met poort 50022 door, en een wallet van buiten verbindt. De app doet waarvoor
|
||||
hij bestaat
|
||||
|
||||
- [x] **0.0.4 uitrollen en kijken of de pagina nu komt. Gelukt (20-08-2026).** De pagina laadt, de
|
||||
melding "No certificate in use" staat er met de reden van de agent, en de veertien certificaten uit
|
||||
Zoraxy staan als keuzelijst. Daarmee is de klem uit 0.0.3 bewezen verholpen
|
||||
|
||||
- [x] De oude app `electrumtls-electrum-tls` verwijderen in umbrelOS, de store-URL opnieuw laten ophalen,
|
||||
en `whatsnext-electrum-gate` installeren. **Gedaan (20-08-2026), en het leverde meteen een fout op:**
|
||||
er kwam geen UI. Oorzaak was geen installatiefout maar een ontwerpfout, verholpen in 0.0.4, zie
|
||||
[PROGRESS.md](PROGRESS.md) en [CHANGELOG-electrum-gate.md](../../../CHANGELOG-electrum-gate.md)
|
||||
|
||||
Daarna, in deze volgorde:
|
||||
|
||||
- [x] `version` op **0.0.3** en de release notes herschreven (19-08-2026). Niet 3.0.0: de gebruiker heeft
|
||||
de nummering opnieuw onder 1.0 gezet, omdat 1.0.0 en 2.0.x een rijpheid beweerden die er niet was.
|
||||
De stap terug in het nummer kan omdat de oude app gedeïnstalleerd wordt en dit een nieuwe app-id is,
|
||||
dus er is geen geïnstalleerd manifest om tegen te vergelijken. **Vanaf hier moet het nummer altijd
|
||||
omhoog**; zie [CHANGELOG-electrum-gate.md](../../../CHANGELOG-electrum-gate.md)
|
||||
- [x] Controleren of de wallet-verbinding de nacht heeft doorstaan. **Gelukt (19-08-2026):** de
|
||||
verbinding stond er 's ochtends nog. Daarmee is de `proxy_timeout`-fix bewezen en de storing
|
||||
verklaard en verholpen
|
||||
- [x] Het plan **Webinterface** promoveren naar `Actief/`; het werk daaraan is begonnen
|
||||
- [ ] Het plan **Configuratie** herzien vóórdat het gepromoveerd wordt. Bij het afsluiten van de sessie op
|
||||
19-08-2026 bleek het grotendeels ingehaald: de agent doet §4e en §4f al, en het hardgecodeerde
|
||||
domein is uit `docker-compose.yml` én uit `nginx.conf.template` verdwenen, dus fase 2 is op de
|
||||
README na klaar. Wat er nog echt in zit, is kleiner dan het plan suggereert. Eerst opschonen, dan
|
||||
beslissen of promotie nog nodig is
|
||||
|
||||
## Fase 1 - De repo-vorm
|
||||
|
||||
- [x] `umbrel-app-store.yml` aanmaken met `id: electrumtls` en een `name`
|
||||
- [x] Map `electrumtls-electrum-tls/` aanmaken en de app-bestanden erheen verplaatsen
|
||||
- [x] `id` in `umbrel-app.yml` op `electrumtls-electrum-tls` zetten, gelijk aan de mapnaam
|
||||
- [x] `install.sh` en `uninstall.sh` verwijderen; umbreld beheert dit onder umbrelOS 1.x
|
||||
- [x] Verplaatsen en inhoudelijk wijzigen in **twee** commits houden, anders is de verhuizing niet als
|
||||
"alleen verplaatst" na te lezen
|
||||
|
||||
## Fase 2 - De compose
|
||||
|
||||
- [x] `app_proxy`-service toevoegen met `APP_HOST: electrumtls-electrum-tls_server_1`
|
||||
- [x] Het externe `umbrel_main_network` en het top-level `networks:`-blok verwijderen
|
||||
- [x] `version: "3.7"` weghalen; die sleutel is verouderd
|
||||
- [x] Certificaatmount op `${UMBREL_ROOT}/app-data/zoraxy/...` in plaats van een absoluut pad
|
||||
- [x] De handmatige `${APP_ELECTRUM_TLS_WEB_PORT}`-plaatshouder eruit; de web-UI loopt via `app_proxy`
|
||||
- [x] **Uitzoeken hoe `entrypoint.sh`, `cert-watch.sh` en `web/` in `${APP_DATA_DIR}` terechtkomen.**
|
||||
Bij installatie kopieert umbreld de hele app-map met `rsync --archive`, dus de mounts kloppen. Bij
|
||||
een **update** wordt alleen een whitelist ververst; zie [OPEN.md](OPEN.md) punt 6
|
||||
- [ ] Logica die later nog moet kunnen wijzigen uit `entrypoint.sh` halen en in de compose of in een
|
||||
`*.template` zetten, anders levert een `git push` geen update op bij een bestaande installatie
|
||||
|
||||
## Fase 3 - Backend-onafhankelijk
|
||||
|
||||
- [x] `dependencies: [electrs]` in het manifest laten staan en controleren
|
||||
- [x] `ELECTRS_HOST` van `${APP_ELECTRS_IP}` naar `${APP_ELECTRS_NODE_IP}` (nu wijst hij naar de
|
||||
web-UI-container van Electrs, niet naar de Electrum-server)
|
||||
- [x] `ELECTRS_PORT` van de vaste 50001 naar `${APP_ELECTRS_NODE_PORT}`
|
||||
- [x] Controleren dat er nergens een Electrs-specifieke variabele gebruikt wordt; alleen `IP`, `NODE_IP`
|
||||
en `NODE_PORT` worden door Fulcrum en ElectrumX gealiast
|
||||
- [x] De terugval `electrs_electrs_1` in `entrypoint.sh` vervangen door hard stoppen met een melding;
|
||||
een oude containernaam als standaard laat de app draaien terwijl hij naar niets wijst
|
||||
- [ ] Op de Umbrel verifiëren: omschakelen naar Fulcrum en controleren dat het zonder aanpassing werkt
|
||||
(staat ook in fase 6)
|
||||
|
||||
## Fase 4 - De image
|
||||
|
||||
- [x] Uitkomst van de "Volgende stap" verwerken: nginx `stream`, of terugvallen op een eigen image
|
||||
- [ ] Image pinnen op de multi-arch index-digest, geverifieerd met `docker buildx imagetools inspect`
|
||||
(kan alleen op de Umbrel; staat als TODO in de compose). **Sinds 20-08-2026 ook de grootste
|
||||
openstaande eis voor het masterplan Publicatie**, want de officiële store eist
|
||||
`repo:versie@sha256:<digest>` met beide architecturen erin. Blijft hier staan tot dat plan actief
|
||||
wordt; een taak op twee plekken loopt uit elkaar
|
||||
- [x] `apk add` bij het starten verwijderen
|
||||
- [x] De `cert-monitor`-service samenvoegen met de proxy en de Docker-socket-mount schrappen
|
||||
- [x] Certificaatwissel omzetten naar een reload binnen de container in plaats van een containerherstart
|
||||
- [x] `entrypoint.sh` en `cert-watch.sh` verwijderen; de logica staat nu in de compose en in
|
||||
`nginx.conf.template`, die allebei bij een update wél ververst worden
|
||||
|
||||
## Fase 5 - Het manifest
|
||||
|
||||
- [x] `port` op de web-UI-poort zetten in plaats van 50002
|
||||
- [x] Eigen icoon toevoegen; verwijst nu naar het Electrs-icoon in andermans repo
|
||||
- [x] `gallery` invullen of tot het minimum beperken; het wijst nu naar een screenshot van Electrs
|
||||
- [x] `developer`, `website`, `repo`, `support`, `submitter` en `submission` kloppend maken
|
||||
- [x] `releaseNotes` en `version` bijwerken
|
||||
- [x] `tagline` en `description` bijwerken; die noemden stunnel, dat er niet meer is
|
||||
- [x] Controleren dat Gitea `icon.png` als afbeelding serveert. **Ja**, na het omzetten van de
|
||||
accountzichtbaarheid: 33,9 kB als `image/png`. De eerdere 401 en 404 kwamen van dezelfde oorzaak
|
||||
als de mislukte kloon, dus er is geen `data:`-URI nodig
|
||||
|
||||
## Fase 6 - Installeren en verifiëren
|
||||
|
||||
- [x] De bestaande handmatige installatie stoppen; die hield poort 50002 vast en liet de installatie drie
|
||||
keer falen. Stond in `~/umbrel/home/Containers/ElectrumTLS`
|
||||
- [x] Store-URL toevoegen in umbrelOS en de app installeren
|
||||
- [x] Verbinden met een Electrum-wallet over TLS. Werkt: de wallet krijgt direct data terug, wat het hele
|
||||
pad bewijst, dus TLS-terminatie, certificaat en de verbinding naar de Electrum-server
|
||||
- [ ] **Na `sudo reboot` controleren dat de app vanzelf terugkomt.** Dit is de aanleiding voor het plan
|
||||
en de enige controle die er nog echt toe doet. **Uitgesteld op 18-08-2026:** de Umbrel is een
|
||||
productiemachine en wordt niet op verzoek herstart. Zie [OPEN.md](OPEN.md) punt 7
|
||||
- [ ] Vervanger die nu wél kan: de app stoppen en starten via umbrelOS. Dat gebruikt hetzelfde
|
||||
`app-script start`-pad als het opstarten na een herstart, maar bewijst niet de volgorde ten
|
||||
opzichte van Zoraxy
|
||||
- [ ] Controleren dat de app terugkomt nadat Electrs gestopt en gestart is
|
||||
- [ ] **De oude stunnel-container weghalen, vóór de Fulcrum-test.** Hij bindt poort 50002 en dat is de
|
||||
poort die Fulcrum op de host wil, dus die test kan niet slagen zolang hij bestaat. Met
|
||||
`docker compose -f ~/umbrel/home/Containers/ElectrumTLS/docker-compose.yml down`. Het externe
|
||||
`umbrel_main_network` blijft daarbij staan; dat verwijdert compose nooit. **Eigenaar: gebruiker**
|
||||
- [ ] Omschakelen naar Fulcrum in de umbrelOS-instellingen en controleren dat het zonder aanpassing werkt
|
||||
- [ ] Pas ná een geslaagde herstart de oude map `~/umbrel/home/Containers/ElectrumTLS` opruimen; tot dan
|
||||
is dat de terugweg. Let op de volgorde: de container mount zijn `entrypoint.sh` uit die map, dus
|
||||
eerst de container weg en dan de map
|
||||
|
||||
## Fase 7 - Naam en identiteit
|
||||
|
||||
Toegevoegd 18-08-2026. De naam beschreef het middel (TLS) en niet wat je ermee kunt.
|
||||
|
||||
- [x] Naam wordt **Electrum Gate**. Bijgesteld op 19-08-2026; op 18-08-2026 stond hier nog Electrum
|
||||
Gateway. TLS is uit de naam en uit de tagline verdwenen; die gaat nu over de afweging Tor tegenover
|
||||
snelheid
|
||||
- [x] Store-id `whatsnext`, app-id en mapnaam `whatsnext-electrum-gate`. Zie [OPEN.md](OPEN.md) punt 8
|
||||
- [x] `developer` en `submitter` op `WhatsNext?` (19-08-2026)
|
||||
- [x] `tagline` en `description` herschreven, in het Engels, met de Tor-afweging en de lijst met clients
|
||||
waarvoor de app nuttig is
|
||||
- [ ] Eigen icoon van de gebruiker inbouwen, in de kleuren van het design-systeem. Het huidige
|
||||
`icon.png` staat er nog en is niet het definitieve
|
||||
- [x] **De repo hernoemd naar `UmbrelApps`, met `icon`, `website`, `repo`, `support` en `submission` mee
|
||||
(25-08-2026, in 0.0.15).** Niet uitgesteld tot GitHub, zoals hier stond, maar afgedwongen door Evolu
|
||||
Relay: umbrelOS leest per store één repo, dus een tweede app maakte een naam naar deze ene app
|
||||
onhoudbaar. Het **app-id** ging niet mee en dat hoefde ook niet; dat hangt aan het store-id en niet
|
||||
aan de URL
|
||||
- [ ] **In umbrelOS de oude store verwijderen en de nieuwe URL toevoegen.** Hier valt te zien of een
|
||||
geïnstalleerde app een wisseling van store-URL overleeft, en dat is **niet uitgezocht**; ga er niet
|
||||
van uit. Zie [OPEN.md](OPEN.md) punt 8. **Eigenaar: gebruiker**
|
||||
- [ ] Pas daarna de repo `ElectrumTLS` op de Git-server weghalen. Dat is niet alleen opruimen: zolang hij
|
||||
bestaat, staat het domein nog in een publieke historie. Zie [OPEN.md](OPEN.md) punt 3.
|
||||
**Eigenaar: gebruiker**
|
||||
|
||||
## Geblokkeerd / wacht op
|
||||
|
||||
- [x] Keuze van de TLS-poort - **vervallen 19-08-2026**. Open punt 1 van het plan **Configuratie** is
|
||||
beslist op 50022 en meteen doorgevoerd, omdat de app toch opnieuw geïnstalleerd wordt. Daarmee is
|
||||
ook de botsing met Fulcrum weg en kan de omschakelcontrole in fase 3 en fase 6 echt gedaan worden
|
||||
Reference in New Issue
Block a user