• v0.6.3 3604683df3

    v0.6.3
    Test / test (push) Successful in 1m8s
    Publish release / publish (push) Successful in 1m55s
    Stable

    gitea-actions released this 2026-09-30 17:33:11 +00:00 | 82 commits to main since this release

    • Pages move the way their addresses do. Deeper in the address comes in from the right, back up comes in from the left, and a page at the same depth comes from below or above, with the index on top. The cards on screen leave as layers of their own, one after another, and the next page's cards arrive the same way. The old page stays on screen until the new one has loaded, where it used to go blank in between. Only transforms and opacity are animated, through the browser's View Transitions (public/page-motion.js, before the router). Browsers without them, and anyone who asks for reduced motion, navigate as before.
    • A record that carries a picture, in a list with no buttons, is shown as a card: the picture, the first field as the heading, the rest under it, with no field names, state or time. Cards are shown in the order they were put up. On a desk, the same picture is a thumbnail.
    • Trainer: values in a plan and presents: true on a need make a "who we are" card on the front door. The business's own statements are carried word for word, beside every record the need presents: the people who work there, entered from inside, each with a picture field (a file that only takes JPEG, PNG or WebP) that shows as their portrait. A public list keeps the form's field order, so the first field heads each row.
    Downloads
  • v0.6.2 827a75be3d

    v0.6.2
    docs / deploy (push) Successful in 3s
    Test / test (push) Successful in 1m14s
    Publish release / publish (push) Successful in 2m3s
    Stable

    gitea-actions released this 2026-09-30 15:39:57 +00:00 | 88 commits to main since this release

    • The header knows who is here: on a site with sign-in, a link top right to sign in, or the person's name and the way out. A page with a slideshow gets the wordmark as a bar of its own, the strip full width under it, and the question after.
    • "My cases": where: { field: email, equals: "{user.email}" } lists the records that carry the signed-in person's own address, filled from the session and never from the caller; nobody signed in matches nothing. An attachment is fetched only through a list that shows its record, so a list of my cases opens my files and nobody else's.
    • A stored file on a listed record shows as the name it was sent with and opens from the row, for whoever the list shows the record to. It used to show as its storage key, a string nobody could open.
    • Form controls scale with the text around them (em, not rem): fields, pills, buttons and labels follow a site's body size. The date picker's calendar icon is the size of the text beside it, and the file picker's button takes the field's colours instead of the browser's.
    • KANIDM_GROUP_PREFIX: a site on a Kanidm it shares with others keeps plain group names in its content; the prefix is put on when portal adds or removes a member, and the client's claim map takes it off.
    • Fixed: maps never reached the browser (serde(skip)), so a page with a map drew it on the server and dropped it on hydration.
    Downloads
  • v0.6.1 9a96386444

    v0.6.1
    docs / deploy (push) Successful in 3s
    Test / test (push) Successful in 1m7s
    Publish release / publish (push) Successful in 1m46s
    Stable

    gitea-actions released this 2026-09-30 15:19:37 +00:00 | 95 commits to main since this release

    • Trainer: documents in a plan. A text the site carries word for word (bylaws, terms) becomes a page of its own where every section is one alternative: its heading the card's, its paragraphs the card's words, from a markdown file beside the plan. No model touches it.

    • slideshow on a page: a strip of pictures the full width of the screen under the question, max_height in svh, each picture with its caption laid over it. Swiper when the bundle has loaded, a sideways-scrolling row before. /site/ serves jpeg, and lets a browser keep photographs for an hour.

    • The release's bare binary is named portal-x86_64-linux (it was portal in 0.6.0 only). Gitea lists assets by name, and deploy scripts that take the first asset got the binary instead of the tarball.

    Downloads
  • v0.6.0 3cb0733955

    v0.6.0
    docs / deploy (push) Successful in 3s
    Publish release / publish (push) Successful in 1m53s
    Test / test (push) Successful in 1m5s
    Stable

    gitea-actions released this 2026-09-30 13:33:17 +00:00 | 104 commits to main since this release

    • One binary. The lint (uhhm/iris) and the trainer (uhhm/portal-trainer) are commands of portal: portal serve (the default), portal lint, and portal plan, build, answer, rate, prefer, score, simulate, compare, report, generate. Same source, same version, so the site, the lint and the trainer never disagree about what content means; both histories are merged in. The release attaches the bare portal binary beside the tarball, so a content repo's CI downloads it and runs portal lint. No more iris releases; the pins that exist keep working. The trainer's plans/, intakes/, engines/, sectors/ and its reference prompt live here now; its runs/ stay in uhhm/portal-trainer. Docs gained "Training a site" and "The lint".
    Downloads
  • v0.5.10
    docs / deploy (push) Successful in 4s
    Test / test (push) Failing after 45s
    Publish release / publish (push) Successful in 3m35s
    Stable

    gitea-actions released this 2026-09-30 12:10:06 +00:00 | 223 commits to main since this release

    • The lint lets an invite form collect a required phone in place of a required email: memberships know a person by number first.
    Downloads
  • v0.5.9 89d419ff7b

    v0.5.9
    docs / deploy (push) Successful in 3s
    Test / test (push) Successful in 58s
    Publish release / publish (push) Successful in 3m36s
    Stable

    gitea-actions released this 2026-09-30 12:06:58 +00:00 | 225 commits to main since this release

    • With memberships as the people backend and a Kanidm token still set, an invite makes the Kanidm account as well (no group, the one-time link in the mail): Kanidm makes people, portal makes members, and a site can switch to memberships before its sign-in provider is one everyone already has.
    Downloads
  • v0.5.8 f4ed98322f

    v0.5.8
    docs / deploy (push) Failing after 3s
    Test / test (push) Failing after 59s
    Publish release / publish (push) Successful in 3m22s
    Stable

    gitea-actions released this 2026-09-30 11:40:13 +00:00 | 229 commits to main since this release

    • Fixed: 0.5.7 asked every provider for the phoneNumber scope, and Kanidm denies a sign-in that asks for a scope the person does not hold, so nobody could sign in. The scope is asked for only with OIDC_EXTRA_SCOPES=phoneNumber (Vipps). 0.5.7 must not be deployed on a Kanidm site.
    Downloads
  • v0.5.7 cc26a232ec

    v0.5.7
    docs / deploy (push) Failing after 3s
    Test / test (push) Successful in 58s
    Publish release / publish (push) Successful in 3m21s
    Stable

    gitea-actions released this 2026-09-30 11:33:15 +00:00 | 232 commits to main since this release

    • Memberships: groups kept by portal itself (src/memberships.rs, docs/memberships.md). A membership is a case in the built-in portal_memberships bucket - invited by a desk, a grants, the seed or the responsible pass; active from the person's first sign-in, when the provider's subject, phone number or address matches; removed by a desk. A person is their phone number first (+4791234567, PHONE_COUNTRY for bare numbers), their address second, the provider's subject third, and one record per group and person however it was keyed. At sign-in the active memberships join the groups claim, so Cedar sees the same parents as before. PEOPLE_BACKEND=memberships switches a site; unset, a KANIDM_API_TOKEN means Kanidm and no token means memberships. SEED_ADMIN_PHONE seeds by number. The sign-in asks for the phoneNumber scope and reads phone_number from userinfo.
    • The NATS access service answers for a person named by sub, phone or email with no groups listed: their memberships are looked up first.
    • who_for (the person a grants is about) takes navn as well as name, and a phone number in place of an address.
    • The invite mail for someone who needs no link says where to sign in.
    Downloads
  • v0.5.6 b9327a170f

    v0.5.6
    Test / test (push) Successful in 55s
    Publish release / publish (push) Successful in 3m9s
    Stable

    gitea-actions released this 2026-09-30 06:18:41 +00:00 | 238 commits to main since this release

    • A group may hold a page's responsibility: responsible: { name, contact, group: styret }. No account or mail for the inbox, and any signed-in member of the group gets the suggest-a-change card. Before this, a board's shared address was onboarded as a person.
    Downloads
  • v0.5.5 77867090ed

    v0.5.5
    Test / test (push) Successful in 55s
    Publish release / publish (push) Successful in 3m29s
    Stable

    gitea-actions released this 2026-09-30 05:51:07 +00:00 | 243 commits to main since this release

    • One record answers another, from a list. link on a resource puts a link on every listed record to a page about it ({id}, {field}), a state mail's to may be a field of the record this one belongs to ({notice.email}, and {notice.field} in the text), and value: "{user.email}" fills a field from the session and hides it, so a signed-in person is not asked who they are. Together they make a board: a notice is listed with "answer this", the answer page's form carries the notice's id, and the mail goes to whoever posted it. The lint requires the record field the mail reaches through.
    • The way down the tree is the line at the foot of the page and nothing else. The arrow fixed at the left edge, which 0.5.3 added beside it, is gone: it followed the reader down every page to offer something the foot already does.
    Downloads