ADR 0045, D12, step 1: project-halkyon was renamed halkyon-days, its
repositories keeping their names. Every URL naming it moves along: the
servers' source-code links, which the AGPL requires, and their tests;
the forks in the pubspecs and the lock (appflowy-editor, pure-zstd,
serverpod-offline-sync); the snaps, the F-Droid listings and the
release configurations; the docs. The curator's credit for the
alphabets names the repository by its name since ADR 0015, halkyon,
rather than halkyon_learn. Forgejo redirects the old addresses until
the name is taken again.
ADRs 0015 and 0039 keep the name they were written with, and the local
folders theirs.
halkyon_editor's gen-l10n caches under build/, committed before its
.gitignore named the folder, are no longer tracked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
F-Droid's Time is for clocks and timers; a to-do list with a calendar
belongs under Task and Calendar & Agenda, the developer's choice of
both. No other app used Time, so the repository no longer lists it. The
release test now checks every category the listing names. ADR 0033 gets
D26 (the review's fixes so far) and D27.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The certificate of the key Todo's releases are signed with (alias
halkyon-todo), made in memory and kept in Proton Pass alone; the release
tool releases no APK signed otherwise.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
deploy/compose.todo.yaml adds Todo's server at todo.halkyon.eu, a member
of Learn's register, its database halkyon_todo in the instance's
PostgreSQL, its image built as Train's. redeploy.sh and backup.sh go over
every app server .env switches on (train, todo). Each compose file names
its server to the register in a variable of its own
(INSTANCE_MEMBER_TRAIN, INSTANCE_MEMBER_TODO), which halkyon_base adds to
INSTANCE_MEMBERS, each address once, as a second compose file's default
would have replaced Train's.
apps/todo/release.dart configures the release tool for Todo's APK and
snap: a key of its own (pinned once made; until then nothing is
released), the F-Droid listing (Time, NonFreeNet), and the snap from
apps/todo/snap/, which the tool builds in a clone of the repository at the
tag with that folder in place of snap/, as snapcraft builds one recipe a
folder and the root's is Learn's. What's new for 0.1.0 in English and
German, now shown. Android's backup and transfer are off, as Train's
(D53): the reminders scheduled keep their tasks' titles unsealed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
tool/with_signing_keys.sh downloads the app's Android keystore and the
F-Droid index's from the vault Infra · Signing into a folder under
$XDG_RUNTIME_DIR, runs tool/release.dart with their paths, and removes
the folder however the run ends. The passwords are asked for as ever.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
apps/train/release.dart configures the release tool for Train's APK on
train.halkyon.eu; its release builds sign with its own key when the tool
hands it over. Its F-Droid listing declares NonFreeDep for Polar's SDK and
NonFreeNet; the repository's script copies each app's icon. The key's
certificate is pinned once the key is made.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The repository is all of Halkyon's apps', so its icon stays Halkyon's
emblem (ADR 0031, D3), kept in tool/release/fdroid/ now that the snap's
icon is Learn's graduation cap. Learn's listing keeps the snap's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The server's half of D25: every account has a way in, and the anonymous
accounts left from before go with the daily pruning.
- The module signs nobody in anonymously: `anonymousIdp` and
`gitHubUpgrade` are gone, and so is linking GitHub at the register.
- A password is set only by someone whose address is theirs (a
`firstPassword` code) or who signs in with GitHub alone (a fresh
sign-in and a `signUp` code); an anonymous account is refused
`wrongCredentials` before any code is used.
- SimpleLogin refuses to link onto a caller without `identified`
(`wrongCaller`), the member's endpoint too, so nothing turns an
anonymous account into one with a way in.
- `pruneAnonymousPeople` deletes every anonymous account left, however
new, never one identified. Learn and Todo schedule it as
`prune-accounts` and cancel the old `prune-abandoned-anonymous-people`
entry once.
- Learn: someone without `identified` keeps no files;
`FILE_LIMIT_ANONYMOUS_MB` is gone. `minimumAppBuild` is 23, as builds
up to 22 start with an anonymous account.
- Learn's sync tests make their person and session by SQL in the
development database, as Serverpod stores sessions.
- Docs, store listings and ADRs 0010, 0014, 0016, 0017 and 0019 amended.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Build 21 (v0.18.0) was the release tool/release.sh was kept for, the one
going with ADR 0014's breaking deploy; every release since is
`dart run tool/release.dart learn`. The comments that named the script
(the F-Droid script, the certificate pin, the Gradle signing) now name
the Dart tool.
Learn's release uploads the snap to the Snap Store's edge channel last,
where v0.18.0 went by hand; the release refuses to start unless
`snapcraft whoami` shows a login.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
- Melos 8.9 as the root's dev dependency, with scripts across the
workspace (analyze, test:dart, test:flutter, generate, check) and its
filters (--diff, --include-dependents); cli_util overridden to 0.5.2
for it, since Learn's flutter_launcher_icons asks for 0.4 and uses only
its logger, unchanged in 0.5.
- tool/check.dart in place of tool/check.sh: packages, formatting of our
own files, analysis, the tools' tests, then every package's tests
through Melos (--changed-since=<commit> for only what changed and what
depends on it). tool/pre-push is the hook: the signature check, then
the checks. CI generates every server's code and runs the same check.
- The images build from the root with a workspace narrowed to what they
need (tool/workspace_only.sh); compose, the deploy's migration test,
the snap, the release script, the editor's launch files and Learn's
asset tools (run from apps/learn) follow the new layout.
- The project's source is named as project-halkyon/halkyon (source link,
snap, F-Droid listing, release uploads); the AGPL packages carry the
licence's own text.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The Snap Store and F-Droid listings now say what the demo video says:
every studyset is made by its learners (build one for any subject, or
copy one someone published), the app connects to any instance, the
repository holds everything to run one, and all the code is public
(app AGPL-3.0, server SSPL-1.0). Signing in later keeps everything with
GitHub or an email address, now that both are ways in.
The F-Droid listing takes the snap's description again, as its header
says; it had kept the text from before v0.17.0. AGENTS.md no longer
says it declares TetheredNet, which it dropped once the app could
choose its instance.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A new install asks first which instance to keep the person's studysets
on, as Mastodon's apps do: an address, checked to answer as an instance
of Halkyon Learn, or the build's own (learn.halkyon.eu) in one tap.
Nothing is made anywhere before that, not even an anonymous account. An
install from before goes on with the build's instance without asking.
As Moshidon does, the device keeps an account on each instance it was
used with, each signed in with its own folder and session, one in use at
a time. Settings › Switch account lists them: another one switches at
once, anonymous accounts included; Add account chooses another instance;
removing one not in use deletes what the device holds of it. Signing out
ends only the account in use.
The build's own instance keeps its data where installs kept it before
(`people/`, Serverpod's own session key), so they keep everything; other
instances get folders and keys of their own. What the device shares
across instances (its settings, sounds, the Pomodoro timer's place in the
system) is made once and outlives every switch.
The F-Droid listing drops TetheredNet: the app is no longer tied to the
project's instance.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Halkyon's website is one site for all its apps, as Proton's is, so
Halkyon Learn's page is halkyon.app/learn rather than a site of its own
at learn.halkyon.app, which redirects there. The snap's and the F-Droid
repository's listings point to it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The repository is Halkyon's, for all of its apps, so its address is the
brand's: https://halkyon.app/fdroid/repo. learn.halkyon.app stays Halkyon
Learn's own address, for its website later. Moved before anyone but the
maintainer had added it; the address is permanent once people have.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Releases also publish the APK in the project's own F-Droid repository,
https://learn.halkyon.app/fdroid/repo. tool/fdroid_repo.sh adds the APK,
signs the indexes with the repository's own key and uploads them to
ramiel as the user fdroid, whose key can only write into the folder
Caddy serves (rrsync), the APKs first and the indexes last.
tool/release.sh checks that key and its password before building and
publishes after the Forgejo release.
- tool/release/fdroid/ holds the repository's settings (Halkyon, the
snap's icon) and the app's listing (the snap's text), with the
anti-features TetheredNet (learn.halkyon.eu only, for now) and
NonFreeNet (YouTube, the server's SSPL) declared with their reasons,
in F-Droid's own definitions and with its icons (fdroiddata, AGPL v3).
- The index key's certificate is pinned: a new key would make the F-Droid
app refuse the repository.
- fdroidserver v2.4.5, since Ubuntu's v2.2.1 knows neither TetheredNet
nor reasons.
README and AGENTS.md describe it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
tool/release.sh builds a release on the maintainer's laptop: one APK for
every phone, from a checkout of the signed tag and signed with the app's
own key, and the snap, both connecting to learn.halkyon.eu, the project's
instance; their checksums signed with GPG; the release on code.halkyon.app
through Forgejo's API, and the snap in the Store's edge channel.
Before building it checks that main is clean and pushed, that the tag is
signed by a key deploys accept, the version and a raised build number,
the pinned Flutter, and that the keystore holds the key whose certificate
tool/release/android-certificate.sha256 names. After building it checks
the APK's signer, package, version, that it isn't debuggable and that it
names the server, and the snap's version. The key's password and the
Forgejo token are asked for at each run and never stored.
Release builds take the app's key from the environment and otherwise fall
back to the debug key, so `flutter run --release` works anywhere. The
native libraries go into the APK compressed: an APK for three
architectures was 110 MB with them stored as they are, 48 MB now. The
list of dependencies Gradle adds for Google Play is left out.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>