Compare commits
1
Commits
main
..
87a4877596
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87a4877596 |
@@ -18,7 +18,7 @@ on:
|
||||
- .gitea/workflows/deploy.yml
|
||||
|
||||
env:
|
||||
PORTAL_RELEASE: v0.6.20
|
||||
PORTAL_RELEASE: v0.3.33
|
||||
INSTANCE: redoal-portal
|
||||
|
||||
jobs:
|
||||
@@ -57,10 +57,6 @@ jobs:
|
||||
KANIDM_URL=${{ vars.KANIDM_URL }}
|
||||
OAUTH2_CLIENT_ID=${{ vars.OAUTH2_CLIENT_ID }}
|
||||
OAUTH2_CLIENT_SECRET=${{ secrets.OAUTH2_CLIENT_SECRET }}
|
||||
# Onboarding from a desk (portal 0.3.40+, `invite:` alternatives): a
|
||||
# Kanidm service-account token in idm_people_on_boarding. Empty
|
||||
# means invites are not configured on this instance.
|
||||
KANIDM_API_TOKEN=${{ secrets.KANIDM_API_TOKEN }}
|
||||
PUBLIC_URL=${{ vars.PUBLIC_URL }}
|
||||
COOKIE_SECURE=true
|
||||
# This repo is its own instance's content source; branding
|
||||
|
||||
@@ -15,18 +15,13 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# The lint is portal itself (`portal lint`, since portal 0.6.0;
|
||||
# iris is no longer released), at the version this site runs
|
||||
# (PORTAL_RELEASE in deploy.yml).
|
||||
# Same bare-metal runner/host as this repo's own Deploy workflow,
|
||||
# which ships question_lint alongside the portal binary in every
|
||||
# pinned release - so content is validated by the exact portal
|
||||
# version this instance runs, not a hand-maintained yq/jq subset
|
||||
# of the same rules.
|
||||
- name: Lint questions
|
||||
env:
|
||||
PORTAL_RELEASE: v0.6.20
|
||||
run: |
|
||||
# The checkout is on a noexec mount for this runner; the cargo
|
||||
# target dir is where it may run what it fetched.
|
||||
bin="/var/local/cargo-target/portal-lint-$PORTAL_RELEASE"
|
||||
[ -x "$bin" ] || { curl -sfL "${{ github.server_url }}/uhhm/portal/releases/download/$PORTAL_RELEASE/portal-x86_64-linux" -o "$bin" && chmod +x "$bin"; }
|
||||
"$bin" lint --path questions
|
||||
run: /srv/app/redoal-portal/current/question_lint --path questions
|
||||
|
||||
reload:
|
||||
runs-on: bare
|
||||
|
||||
@@ -38,19 +38,3 @@ aggregates:
|
||||
kept: { event: kept }
|
||||
transitions:
|
||||
open: [removed, kept]
|
||||
# TestFlight beta signups (index.yaml's "Test it on your iPhone").
|
||||
# Attended by automation, not a human desk: a new "requested" signup
|
||||
# is handed to the App Store Connect API to invite the Apple ID to the
|
||||
# closed beta; "withdrawn" (the /joined-testers self-transition) drops
|
||||
# them from the invite list.
|
||||
- bucket: redoal_testers
|
||||
attended_by: >
|
||||
n8n TestFlight onboarding workflow — ops/n8n/testflight-onboarding
|
||||
in redoal/redoal. Consumes NATS events.redoal_testers.* and calls
|
||||
App Store Connect POST /v1/betaTesters.
|
||||
initial: open
|
||||
states:
|
||||
open: { event: requested }
|
||||
withdrawn: { event: withdrawn }
|
||||
transitions:
|
||||
open: [withdrawn]
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
/* redoal - the skin over portal's own stylesheet
|
||||
(site.yaml `stylesheet`, loaded after main.css, so these rules win). */
|
||||
|
||||
/* The way in sits beside the wordmark on every page. redoal.com is read
|
||||
and answered without an account, so the invitation is not shown.
|
||||
Whoever edits the site still signs in at /auth/login directly, and
|
||||
once signed in the nav keeps its name and its way out. */
|
||||
.session:has(a[href^="/auth/login"]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Without :has(), the link alone goes and the empty nav stays. */
|
||||
.session a[href^="/auth/login"] {
|
||||
display: none;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 85 KiB |
@@ -0,0 +1,99 @@
|
||||
id: /advantages
|
||||
name: What is it good for?
|
||||
description: >
|
||||
The same one trick — a drawing is an address — answers different
|
||||
needs. Here's what redoal gives you, grouped by what you're trying to
|
||||
do. None of it needs an account, a server that owns your words, or a
|
||||
platform's permission.
|
||||
alternatives:
|
||||
- name: A community keeping its own memory
|
||||
description: >
|
||||
No company holds the recordings. The people who show up are the
|
||||
infrastructure, and the network is built so their memory survives
|
||||
them.
|
||||
features:
|
||||
- name: No server owns the words
|
||||
description: >
|
||||
Recordings live on the phones of the people who visit a
|
||||
place, handed peer to peer. There is no central store to
|
||||
seize, subpoena, or switch off — the memory is only ever
|
||||
where its people are.
|
||||
icon: lucide:server-off
|
||||
- name: Attention is what preserves
|
||||
description: >
|
||||
Every time someone listens, their phone keeps a copy and
|
||||
quietly becomes another place you can get it from. A voice
|
||||
heard by many is, by that fact alone, held by many. The more
|
||||
a thing is cared about, the harder it is to lose.
|
||||
icon: lucide:ear
|
||||
- name: The infrastructure points the right way
|
||||
description: >
|
||||
When a relay helps, it points visitors toward each other — it
|
||||
never becomes the place the words live. The fewer servers it
|
||||
takes to keep a voice reachable, the more the network is
|
||||
doing what it was built to do.
|
||||
icon: lucide:git-fork
|
||||
- name: An artist placing work where it's found
|
||||
description: >
|
||||
Leave something at a shape, and it belongs to that shape — found
|
||||
by feel, answered in kind, and not quietly unsaid later.
|
||||
features:
|
||||
- name: The drawing is the address
|
||||
description: >
|
||||
Your line becomes a twenty-byte fingerprint that reconstructs
|
||||
back into the shape you drew. Similar drawings land at the
|
||||
same place, so work is found by gesture, not by a name in a
|
||||
directory.
|
||||
icon: lucide:pen-tool
|
||||
- name: A place holds voices, and answers
|
||||
description: >
|
||||
Leave a short recording at a shape; anyone who arrives hears
|
||||
it, and can answer — not only with their own voice, but with
|
||||
a drawn gesture that points somewhere, a reply in the same
|
||||
wordless language.
|
||||
icon: lucide:radio
|
||||
- name: What's left is kept
|
||||
description: >
|
||||
A voice left at a place isn't retracted out from under the
|
||||
people who heard it. The record is forward-only — you build
|
||||
on it, you don't erase it.
|
||||
icon: lucide:history
|
||||
- name: Anyone tired of accounts and platforms
|
||||
description: >
|
||||
A network you carry in your hand, that asks nothing of you before
|
||||
you use it.
|
||||
features:
|
||||
- name: Nothing to sign up for
|
||||
description: >
|
||||
No account, no profile, no directory of you. You draw, you
|
||||
arrive, you're part of it — the gesture is the only
|
||||
credential, and it's yours the moment your hand lifts.
|
||||
icon: lucide:user-x
|
||||
- name: Sovereign by construction
|
||||
description: >
|
||||
The parts that keep it running are ones you can run yourself —
|
||||
no dependence on a big platform's servers to find each other
|
||||
or move a recording. The whole design leans toward fewer
|
||||
rented middlemen, not more.
|
||||
icon: lucide:shield-check
|
||||
- name: Leaving costs nothing
|
||||
description: >
|
||||
Your phone reclaims space on its own, and letting go of a
|
||||
recording never deletes it from the world — the network
|
||||
fetches it back the next time someone arrives wanting it. You
|
||||
can travel light and still be a full member.
|
||||
icon: lucide:feather
|
||||
- name: Go deeper on how it remembers
|
||||
description: >
|
||||
The preservation model has a twist worth seeing on its own: your
|
||||
phone protects what's *rare*.
|
||||
action: /advantages/memory
|
||||
consequence: [Show me how the memory works]
|
||||
features:
|
||||
- name: Memory that protects what's rare
|
||||
description: >
|
||||
Your phone can't hold everything, so it keeps the voices few
|
||||
others do — releasing the ones already safe on many devices,
|
||||
holding the ones in danger of vanishing. The network
|
||||
preserves itself without anyone deciding what survives.
|
||||
icon: lucide:gem
|
||||
@@ -0,0 +1,46 @@
|
||||
id: /advantages/memory
|
||||
name: How redoal remembers
|
||||
description: >
|
||||
A place's voices should stay reachable as long as people care about
|
||||
them, and no longer — and no phone should fill up preserving voices
|
||||
nobody returns to. redoal gets there with three forces that need no
|
||||
coordinator: attention spreads a voice, scarcity keeps it, and the
|
||||
person who spoke it is the anchor of last resort.
|
||||
alternatives:
|
||||
- name: The three forces
|
||||
description: >
|
||||
No server decides what survives. The incentives do — and they
|
||||
pull in exactly the right directions.
|
||||
features:
|
||||
- name: Attention replicates
|
||||
description: >
|
||||
Every time someone listens to a recording, their phone keeps
|
||||
a copy and quietly announces itself as another place you can
|
||||
get it from. A voice heard by a hundred people is, by that
|
||||
fact alone, held by a hundred phones. Listening is hosting.
|
||||
icon: lucide:ear
|
||||
- name: Scarcity is kept
|
||||
description: >
|
||||
When a phone runs low on room, it doesn't drop the oldest
|
||||
voice — it drops the safest one. The network already knows
|
||||
how many phones hold each recording, so each device keeps the
|
||||
ones held by almost no one and lets go of the ones held by
|
||||
many. Everyone reaching for the rare voice is exactly what
|
||||
protects it.
|
||||
icon: lucide:gem
|
||||
- name: The speaker anchors
|
||||
description: >
|
||||
Whoever left a recording never forgets their own — a place's
|
||||
origin is always reachable through the person who made it.
|
||||
Below everything else, the author is the backstop, so no
|
||||
voice falls all the way out of the world while its speaker
|
||||
still carries a phone.
|
||||
icon: lucide:anchor
|
||||
- name: Letting go is safe
|
||||
description: >
|
||||
A phone releasing a voice isn't deleting it — the drawing
|
||||
still leads there, and the network fetches it back on demand
|
||||
the next time someone arrives wanting it. Reclaiming space
|
||||
and preserving memory are separate, which is what lets a
|
||||
small phone be a full member without fear.
|
||||
icon: lucide:recycle
|
||||
+14
-21
@@ -1,28 +1,17 @@
|
||||
# «Atelic Antics», the group exhibition at Podium, part of Attac's
|
||||
# «Big Tech må vekk» 2026: opens 23 October 2026 at 19:00 and runs for a month. Announced
|
||||
# The group exhibition at Podium, part of Attac's «Big Tech må vekk»
|
||||
# 2026: opens 23 October 2026 at 19:00 and runs for a month. Announced
|
||||
# in every header while it runs (portal's event: window); afterwards a
|
||||
# followup, and a "post what happened" task lands on /review.
|
||||
name: Where can you see it in person?
|
||||
description: >
|
||||
redoal is part of «Atelic Antics», the group exhibition at Podium,
|
||||
opening 23 October and running for a month — the art strand of the
|
||||
conference «Big Tech må vekk». Draw on the screens, leave a voice at a shape,
|
||||
redoal is part of the group exhibition at Podium, opening 23 October
|
||||
and running for a month — the art strand of the conference
|
||||
«Big Tech må vekk». Draw on the screens, leave a voice at a shape,
|
||||
hear who came before you.
|
||||
event:
|
||||
starts: 2026-10-23T19:00:00+02:00
|
||||
# To 15 November, per the poster — not a month. The header announces
|
||||
# this while it runs, so a duration that overshoots keeps inviting
|
||||
# people to a closed room.
|
||||
duration: 23d
|
||||
duration: 31d
|
||||
place: Podium, Hausmanns gate 34, Oslo
|
||||
slideshow:
|
||||
slides:
|
||||
- image: images/atelic-antics.webp
|
||||
caption: >
|
||||
«Atelic Antics» — suggestions on digital resistance. Podium,
|
||||
Hausmanns gate 34, 24 October to 15 November 2026.
|
||||
width: 989
|
||||
height: 1400
|
||||
alternatives:
|
||||
- name: Come draw on the wall
|
||||
description: >
|
||||
@@ -32,10 +21,9 @@ alternatives:
|
||||
features:
|
||||
- name: Opening 23 October, 19:00
|
||||
description: >
|
||||
«Atelic Antics» opens at [Podium](https://podium.enterprises/),
|
||||
Hausmanns gate 34, and is up until 15 November. Come to the
|
||||
opening, or any Saturday or Sunday after between 13:00 and
|
||||
17:00.
|
||||
At [Podium](https://podium.enterprises/), Hausmanns gate 34,
|
||||
and up for a month. Come to the opening, or any Saturday
|
||||
or Sunday after.
|
||||
icon: lucide:calendar-days
|
||||
- name: Part of «Big Tech må vekk»
|
||||
description: >
|
||||
@@ -50,3 +38,8 @@ alternatives:
|
||||
Listen to the voices left there, add your own, and watch
|
||||
your line find the lines drawn before it.
|
||||
icon: lucide:hand
|
||||
- name: Take the zine with you
|
||||
description: >
|
||||
The printed zine sits in the room — six short pieces on what
|
||||
a network like this could mean. Fold one, hand it on.
|
||||
icon: lucide:book-open
|
||||
|
||||
+25
-37
@@ -40,25 +40,6 @@ alternatives:
|
||||
The one trick, and what it enables — the parts that run today,
|
||||
said plainly.
|
||||
features:
|
||||
- name: The count so far
|
||||
description: >
|
||||
Live from the front-door relay — the running tally of what's
|
||||
been left at places.
|
||||
icon: lucide:activity
|
||||
resource:
|
||||
source:
|
||||
kind: url
|
||||
url: https://relay.redoal.com/pulse
|
||||
public: true
|
||||
# /pulse (redoal ADR-0023) returns { voices_echoed: N }; shape
|
||||
# it into one card — the number as the heading, the phrase
|
||||
# beneath. Emit a bare object, not a wrapped [ … ]: the portal
|
||||
# collects the jq output stream into an array itself, so a
|
||||
# wrapping [ ] nests it ([[{…}]]) and drops to a raw JSON dump.
|
||||
jq: >
|
||||
{ "name": (.voices_echoed | tostring),
|
||||
"description": "voices echoed so far" }
|
||||
empty: The first voice hasn't echoed yet.
|
||||
- name: A drawing is an address
|
||||
description: >
|
||||
The computer measures how your line curves, turns, and keeps
|
||||
@@ -119,8 +100,7 @@ alternatives:
|
||||
- name: Follow the build as it lands
|
||||
description: >
|
||||
The network as it is being built — and we need collaborators on
|
||||
every new surface it grows. Desktop releases run free; the iPhone
|
||||
beta is one tap away below.
|
||||
every new surface it grows.
|
||||
features:
|
||||
- name: Communicate
|
||||
description: >
|
||||
@@ -132,25 +112,34 @@ alternatives:
|
||||
description: Start exploring by running one of our applications.
|
||||
icon: lucide:package
|
||||
resource:
|
||||
# The public manifest redoal's release job writes to
|
||||
# dl.redoal.com (the repo is private; its own release assets
|
||||
# 404 for visitors). Portal renders a manifest of this shape as
|
||||
# one download card: the newest version, this device's file
|
||||
# first, the Arch repo lines and TestFlight folded with the
|
||||
# rest (content-reference, "A releases manifest").
|
||||
source:
|
||||
kind: url
|
||||
url: https://dl.redoal.com/releases.json
|
||||
kind: gitea_releases
|
||||
owner: redoal
|
||||
repo: redoal
|
||||
public: true
|
||||
empty: Nothing released yet — the first cut lands here.
|
||||
- name: Test the iPhone app
|
||||
# url pinned to null while the repo is private - a private
|
||||
# release's html_url 404s for anonymous visitors, and the
|
||||
# card renders an unlinked heading instead (same lesson as
|
||||
# uhhm/questions 9b7162f).
|
||||
jq: >
|
||||
.[] | {name: .name, description: .body, tag: .tag_name,
|
||||
published: .published_at, url: null}
|
||||
|
||||
- name: See what it's good for
|
||||
description: >
|
||||
The same one trick answers different needs — a community keeping
|
||||
its own memory, an artist placing work where it's found, anyone
|
||||
done with accounts and platforms.
|
||||
action: /advantages
|
||||
consequence: [Show me the advantages]
|
||||
features:
|
||||
- name: Grouped by what you're after
|
||||
description: >
|
||||
The desktop releases above run free, no sign-up. The iPhone
|
||||
build rides TestFlight (Apple's beta program) — [join the
|
||||
redoal testers](https://testflight.apple.com/join/eR9dvHkz)
|
||||
with one tap on your iPhone; no invitation, no email, no
|
||||
waiting on us.
|
||||
icon: lucide:smartphone
|
||||
Not a feature list — the advantages sorted by the thing
|
||||
you're trying to do, including the one worth seeing on its
|
||||
own: how your phone protects what's rare.
|
||||
icon: lucide:sparkles
|
||||
|
||||
- name: Hear from us when it matters
|
||||
description: >
|
||||
@@ -173,4 +162,3 @@ alternatives:
|
||||
- name: email
|
||||
label: Email
|
||||
type: email
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
id: /joined-testers
|
||||
route: ^/joined-testers
|
||||
followup: true
|
||||
name: What happens next?
|
||||
description: >
|
||||
You asked for a place in the closed beta — here's the shape of it.
|
||||
alternatives:
|
||||
- name: Your invite is on its way
|
||||
description: ""
|
||||
features:
|
||||
- name: Check your mail
|
||||
description: >
|
||||
A TestFlight invite goes to the Apple ID you left. Tap it on
|
||||
your iPhone, install TestFlight if you don't have it, and
|
||||
redoal lands on your home screen.
|
||||
icon: lucide:mail
|
||||
- name: It's rough on purpose
|
||||
description: >
|
||||
A beta, and an artwork before a product — the networked edges
|
||||
are where the interesting questions live. Tell us what breaks.
|
||||
icon: lucide:hammer
|
||||
|
||||
- name: Withdraw from the beta
|
||||
description: >
|
||||
Changed your mind? Confirm below and we'll drop your Apple ID from
|
||||
the invite list.
|
||||
self_transition:
|
||||
bucket: redoal_testers
|
||||
to: withdrawn
|
||||
label: Remove me from the beta
|
||||
Reference in New Issue
Block a user