feat(outline): the wiki workload #1

Merged
binjovi-bot merged 3 commits from feat/outline-app-manifests into trunk 2026-09-14 13:35:54 +00:00
Owner

Everything Outline needs is already live in the cluster — namespace, Postgres
database, Valkey, RustFS bucket and key, OIDC client, certificate, gateway
listener, portal card. This is the workload that uses them.

It is also what finally gives outline.sean.farm a DNS record: external-dns runs
with --source=gateway-httproute, so the listener alone resolves nothing. Today
the hostname answers DNS_PROBE_POSSIBLE.

Layout

Follows sean/zot: apps/outline.yaml is the child ArgoCD Application, syncing
manifests/outline beside it. The app-of-apps root in sean/seanfarm syncs
apps/.

Four things checked against the source, not assumed

SECRET_KEY is 64 characters of which 64 are digits. server/env.ts at
v1.10.1 carries @IsHexadecimal() and @Length(64, 64), and External Secrets
cannot emit hex — digits are a subset of hex, so this satisfies both exactly.
Allowing letters would produce g-z and Outline would refuse to boot. Frozen
(refreshInterval: "0"): it encrypts stored data, and "Do not change this value
once set or your users will be unable to login."

DATABASE_URL is assembled here, because Outline reads no other database
variable, and the rotating password is urlquery-encoded. OpenBao rotates it
hourly under a policy this repository does not control; one @ or / in a
generated value would re-point the connection at another host.

OIDC discovery uses the PUBLIC issuer. The document carries the authorization
endpoint the browser is sent to, and a browser cannot reach
hydra-public.ory.svc. Verified: https://auth.sean.farm answers
/.well-known/openid-configuration with issuer: https://auth.sean.farm.

The S3 endpoint is the stable ClusterIP with an explicit :9000, never the
headless name. RustFS has no port-80 listener.

arm64

The image is pinned to the multi-arch index digest, verified against the registry
to carry a linux/arm64 child, and the pod carries the arm-canary toleration.
Every node in this fleet is arm64.

kubectl kustomize manifests/outline builds 10 objects.

https://claude.ai/code/session_01JGe4pyhQ36AhgDfPJry4d3

Everything Outline needs is already live in the cluster — namespace, Postgres database, Valkey, RustFS bucket and key, OIDC client, certificate, gateway listener, portal card. **This is the workload that uses them.** It is also what finally gives `outline.sean.farm` a DNS record: external-dns runs with `--source=gateway-httproute`, so the listener alone resolves nothing. Today the hostname answers `DNS_PROBE_POSSIBLE`. ## Layout Follows `sean/zot`: `apps/outline.yaml` is the child ArgoCD Application, syncing `manifests/outline` beside it. The app-of-apps root in `sean/seanfarm` syncs `apps/`. ## Four things checked against the source, not assumed **`SECRET_KEY` is 64 characters of which 64 are digits.** `server/env.ts` at v1.10.1 carries `@IsHexadecimal()` and `@Length(64, 64)`, and External Secrets cannot emit hex — digits are a subset of hex, so this satisfies both exactly. Allowing letters would produce `g-z` and Outline would refuse to boot. Frozen (`refreshInterval: "0"`): it encrypts stored data, and *"Do not change this value once set or your users will be unable to login."* **`DATABASE_URL` is assembled here**, because Outline reads no other database variable, and the rotating password is `urlquery`-encoded. OpenBao rotates it hourly under a policy this repository does not control; one `@` or `/` in a generated value would re-point the connection at another host. **OIDC discovery uses the PUBLIC issuer.** The document carries the authorization endpoint the *browser* is sent to, and a browser cannot reach `hydra-public.ory.svc`. Verified: `https://auth.sean.farm` answers `/.well-known/openid-configuration` with `issuer: https://auth.sean.farm`. **The S3 endpoint is the stable ClusterIP with an explicit `:9000`**, never the headless name. RustFS has no port-80 listener. ## arm64 The image is pinned to the multi-arch index digest, verified against the registry to carry a `linux/arm64` child, and the pod carries the `arm-canary` toleration. Every node in this fleet is arm64. `kubectl kustomize manifests/outline` builds 10 objects. https://claude.ai/code/session_01JGe4pyhQ36AhgDfPJry4d3
Everything Outline needs exists in the cluster already -- namespace,
Postgres database, Valkey, RustFS bucket and key, OIDC client,
certificate, gateway listener, portal card. This is the workload that
uses them, and the HTTPRoute that finally gives outline.sean.farm a DNS
record: external-dns runs with --source=gateway-httproute, so the
listener alone resolves nothing.

Four settings carry more weight than they look:

  SECRET_KEY is 64 characters of which 64 are digits. server/env.ts
  carries @IsHexadecimal() and @Length(64, 64), and External Secrets
  cannot emit hex -- digits are a subset of hex, so this satisfies both.
  Allowing letters would produce g-z and Outline would refuse to boot.
  It is frozen: it encrypts stored data, and changing it locks every
  user out.

  DATABASE_URL is assembled here because Outline reads no other database
  variable, and the rotating password is urlquery-encoded. OpenBao
  rotates it hourly under a policy this repository does not control, and
  one '@' would re-point the connection at another host.

  OIDC discovery uses the PUBLIC issuer. The document carries the
  authorization endpoint the BROWSER is sent to, and a browser cannot
  reach hydra-public.ory.svc.

  The S3 endpoint is the stable ClusterIP with an explicit :9000. RustFS
  has no port-80 listener.

The image is the multi-arch index digest, verified against the registry
to carry a linux/arm64 child; the pod carries the arm-canary toleration.
Every node in this fleet is arm64.

Claude-Session: https://claude.ai/code/session_01JGe4pyhQ36AhgDfPJry4d3
sean force-pushed feat/outline-app-manifests from 608e59e845 to 54878c2756 2026-09-14 10:14:19 +00:00 Compare
sean force-pushed feat/outline-app-manifests from 54878c2756 to e1dfa77a8b
Some checks failed
binjovi/ci Binjovi failed the frozen plan
2026-09-14 12:13:53 +00:00
Compare
sean force-pushed feat/outline-app-manifests from e1dfa77a8b
Some checks failed
binjovi/ci Binjovi failed the frozen plan
to 195b639be6
Some checks failed
binjovi/ci Binjovi failed the frozen plan
2026-09-14 12:26:42 +00:00
Compare
chore(outline): re-run the build on binjovi v0.1.736
All checks were successful
binjovi/ci Binjovi completed the frozen plan
868727143d
The first build of this pull request failed in gitops_validate.v1 with
:invalid_task. The agent refused the source: sean/outline ->
manifests/outline was not in its @native_argocd_sources allow-list.
sean/binjovi #1778 added it to BOTH lists (Agent.Command and
ExecutionPlan) and shipped as v0.1.736, verified on binjovi-staging and
binjovi-production at 2026-09-14T12:59Z.

Binjovi builds on push, and there is no rebuild command, so this empty
commit is the re-run. No manifest changed.

Claude-Session: https://claude.ai/code/session_01JGe4pyhQ36AhgDfPJry4d3
docs(outline): record why a wiki carries a tag protection
Some checks failed
binjovi/ci Binjovi will not build this: its base branch must be trunk. Retarget the pull request.
a609798426
Onboarding declared branch protections for main and trunk and left the
`**` tag rule out, because Outline publishes no Git tags. That reading is
about the wrong thing: Forgejo.Authority.check/2 requires all three of
every provider-guarded project, to prove that nobody but binjovi-bot can
move a ref. `binjovictl authority outline` answered `blocked ·
invalid_tag_protection_response` and every release died 503.

The next person to read this repository should not have to rediscover
that from a reason code naming the shape of Forgejo's reply.

Claude-Session: https://claude.ai/code/session_01JGe4pyhQ36AhgDfPJry4d3
binjovi-bot deleted branch feat/outline-app-manifests 2026-09-14 13:35:54 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
sean/outline!1
No description provided.