Plan product path: app shell and Forgejo markdown spaces

Mark CSOC-WP-0002 identity done on app.coulomb.social. Defer bulk Bubble
migration until product foundation exists. Open CSOC-WP-0004 for post-login
entry and space content as markdown bound to Forgejo.
This commit is contained in:
tegwick 2026-08-10 09:40:25 +02:00
parent f5537d8365
commit d36795faa6
7 changed files with 288 additions and 84 deletions

View file

@ -1,7 +1,7 @@
--- ---
repo: coulomb-social repo: coulomb-social
updated: "2026-08-09" updated: "2026-08-10"
status: bootstrap status: active
--- ---
# INTENT — coulomb-social # INTENT — coulomb-social
@ -39,8 +39,10 @@ The rebuild is deliberately **product-faithful first**: UI and content parity ma
|---------|----------| |---------|----------|
| Shape | Standalone service — own repo, own DB, own release values (DR-2 B) | | Shape | Standalone service — own repo, own DB, own release values (DR-2 B) |
| Tenancy | Instance-per-client deployment; tenant-keyed data model from migration one (DR-1 C) | | Tenancy | Instance-per-client deployment; tenant-keyed data model from migration one (DR-1 C) |
| Identity | App-local member accounts in v1; auth behind a single module for later OIDC (DR-3 A) | | Identity | NetKingdom OIDC (KeyCape) + user-engine (ADR-0001); proven on app host |
| Delivery lane | commit-SHA images → `gitea.coulomb.social/coulomb/coulomb-social` → `railiance-apps` values → railiance01 | | Public hosts | **`app.coulomb.social`** = rebuild; **`coulomb.social`** = Bubble until cutover |
| Delivery lane | commit-SHA images → `forgejo.coulomb.social/coulomb/coulomb-social` → `railiance-apps` → railiance01 |
| Content direction | Space content as **markdown**, versioned with **Forgejo** (CSOC-WP-0004); bulk Bubble migration later |
| Contract | `the-custodian` `canon/standards/business-app-service-contract_v0.1.md` §§1–6 | | Contract | `the-custodian` `canon/standards/business-app-service-contract_v0.1.md` §§1–6 |
## What Success Looks Like ## What Success Looks Like
@ -69,9 +71,11 @@ The rebuild is deliberately **product-faithful first**: UI and content parity ma
- `GOAL.md` — operator bootstrap note for this repo - `GOAL.md` — operator bootstrap note for this repo
- `SCOPE.md` — in/out boundaries and orientation - `SCOPE.md` — in/out boundaries and orientation
- `workplans/CSOC-WP-0002-netkingdom-user-management-reestablish.md` — **current path**: NetKingdom user management first; content later - `workplans/CSOC-WP-0002-netkingdom-user-management-reestablish.md` — **done**: identity shell on app.coulomb.social
- `workplans/CSOC-WP-0004-app-shell-and-space-content.md` — **current path**: leave login shell; spaces + Forgejo markdown
- `docs/adr/ADR-0001-netkingdom-identity.md` — accepted identity decision - `docs/adr/ADR-0001-netkingdom-identity.md` — accepted identity decision
- `workplans/CSOC-WP-0001-bubble-io-exit-assessment.md` — Bubble assessment; content claim deferred - `workplans/CSOC-WP-0001-bubble-io-exit-assessment.md` — Bubble inventory/migration **after** product foundation
- `workplans/CSOC-WP-0003-self-registration-and-assurance.md` — public registration when NetKingdom mail path lands
- `the-custodian/docs/coulomb-social-rebuild-seed.md` — original workplan seed (CUST-WP-0058-T08) - `the-custodian/docs/coulomb-social-rebuild-seed.md` — original workplan seed (CUST-WP-0058-T08)
- `the-custodian/canon/standards/business-app-service-contract_v0.1.md` - `the-custodian/canon/standards/business-app-service-contract_v0.1.md`
- NetKingdom: IAM Profile, user-engine boundary, KeyCape/Keycloak modes - NetKingdom: IAM Profile, user-engine boundary, KeyCape/Keycloak modes

View file

@ -3,8 +3,12 @@
Reimplementation of **coulomb.social** on Railiance / NetKingdom / HelixForge — Reimplementation of **coulomb.social** on Railiance / NetKingdom / HelixForge —
exiting the stalled bubble.io product. exiting the stalled bubble.io product.
**Current focus:** NetKingdom user management and authenticated shell **Hosts:** rebuild at [`app.coulomb.social`](https://app.coulomb.social);
(`CSOC-WP-0002`). Bubble content claim is deferred. apex [`coulomb.social`](https://coulomb.social) remains Bubble until cutover.
**Current focus:** app shell + spaces with Forgejo-backed markdown content
(`CSOC-WP-0004`). Identity shell is done (`CSOC-WP-0002`). Bulk Bubble
migration is deferred (`CSOC-WP-0001`).
## Quick start ## Quick start

View file

@ -65,12 +65,12 @@ coulomb.social connects people around shared projects and complementary capabili
## Current State ## Current State
- Status: bootstrap / greenfield — identity-first reestablish in progress - Status: **parallel hosts** — identity live; product content under construction
- Implementation: orientation docs + design extract; application scaffold pending (`CSOC-WP-0002`) - **`https://app.coulomb.social`**: Railiance rebuild (OIDC, shell); spaces/content next
- Stability: evolving - **`https://coulomb.social`**: Bubble.io full product until cutover decision
- Usage: internal — product rebuild not yet serving members from this stack - Active path: **`CSOC-WP-0004`** (app shell + Forgejo markdown spaces)
- Prior art: rebuild seed from CUST-WP-0058-T08; topic `coulomb-social` already exists in State Hub under domain `communication` - Deferred: bulk Bubble migration (`CSOC-WP-0001`); public self-registration (`CSOC-WP-0003` / NK)
- Active path: **NetKingdom user management** (`CSOC-WP-0002`); Bubble content claim deferred - Prior art: design extract; CSOC-WP-0002 identity acceptance (2026-08-10)
--- ---

View file

@ -8,7 +8,7 @@ status: active
owner: bernd owner: bernd
topic_slug: coulomb-social topic_slug: coulomb-social
created: "2026-08-09" created: "2026-08-09"
updated: "2026-08-09" updated: "2026-08-10"
origin: residual origin: residual
origin_ref: the-custodian/docs/coulomb-social-rebuild-seed.md origin_ref: the-custodian/docs/coulomb-social-rebuild-seed.md
state_hub_workstream_id: "ecefaeef-908a-4072-ae34-6406862d4cad" state_hub_workstream_id: "ecefaeef-908a-4072-ae34-6406862d4cad"
@ -17,45 +17,56 @@ state_hub_workstream_id: "ecefaeef-908a-4072-ae34-6406862d4cad"
# bubble.io exit assessment # bubble.io exit assessment
Assess the live coulomb.social bubble.io product, export its data model, decide Assess the live coulomb.social bubble.io product, export its data model, decide
the v1 feature cut, and rehearse migration into a tenant-keyed relational the v1 feature cut, and rehearse migration into the code-owned stack.
schema. This plan originates from the CUST-WP-0058-T08 seed in
`the-custodian/docs/coulomb-social-rebuild-seed.md`.
Repo bootstrap (INTENT, SCOPE, TRSL LICENSE, State Hub registration, agent ## Operating posture (2026-08-10)
files) was completed as part of opening this workplan.
**Priority note (2026-08-09):** product **reestablish** proceeds first via | Host | Role |
`CSOC-WP-0002` (NetKingdom user management + authenticated shell). **Content |------|------|
claim / migration** from Bubble remains in this workplan’s scope but is | **`https://coulomb.social`** | **Bubble.io** — full product, production members/content |
**deferred** until after the identity shell lands — do not block WP-0002 on | **`https://app.coulomb.social`** | **Railiance rebuild** — identity live; product surfaces under construction |
inventory completion.
**Strategy:** perfect the rebuild on `app.coulomb.social` **before** migrating all
spaces/data from Bubble. Do **not** repoint apex DNS until product + content
persistence + self-registration are ready and a migration rehearsal has passed.
Identity shell is done (`CSOC-WP-0002`). Product/content foundation is
`CSOC-WP-0004`. This workplan stays the home for **inventory, mapping, feature
cut, and migration rehearsal** — executed when the target schema/content model
exists, not as the immediate next build step.
## Inventory bubble.io app ## Inventory bubble.io app
```task ```task
id: CSOC-WP-0001-T01 id: CSOC-WP-0001-T01
status: todo status: todo
priority: high priority: medium
state_hub_task_id: "240a97c5-1f57-4da6-a75b-d7b3416afdd1" state_hub_task_id: "240a97c5-1f57-4da6-a75b-d7b3416afdd1"
``` ```
Inventory the current bubble.io app: pages, workflows, data types, Inventory the current bubble.io app: pages, workflows, data types,
integrations, external services, and content surfaces that must be preserved integrations, external services, and content surfaces that must be preserved
or deliberately dropped. Record findings under `docs/bubble-inventory/` (create or deliberately dropped. Record findings under `docs/bubble-inventory/` (create
as needed). as needed). Prefer **spaces / pages / markdown-shaped content** first so
`CSOC-WP-0004` Forgejo persistence can map cleanly.
## Data export and schema mapping ## Data export and schema mapping
```task ```task
id: CSOC-WP-0001-T02 id: CSOC-WP-0001-T02
status: todo status: todo
priority: high priority: medium
state_hub_task_id: "0bc6eea3-030d-4987-b203-15ccd4f94fcb" state_hub_task_id: "0bc6eea3-030d-4987-b203-15ccd4f94fcb"
``` ```
Produce a full data dump from bubble.io and map it to a relational model that Produce a full data dump from bubble.io and map it to:
is tenant-keyed from migration one (business-app service contract §1.3).
Document the mapping and export procedure under `docs/migration/`. 1. tenant-keyed application tables (members, space metadata, …), and
2. **space content as markdown trees** bound to Forgejo repositories
(see CSOC-WP-0004 content model).
Document mapping and export under `docs/migration/`. Depends on CSOC-WP-0004
content layout decisions for lossless mapping of pages/artefacts.
## Feature cut decision (human gate) ## Feature cut decision (human gate)
@ -66,34 +77,33 @@ priority: high
state_hub_task_id: "35a0af87-2f22-4fae-8c82-e3cc4f77f074" state_hub_task_id: "35a0af87-2f22-4fae-8c82-e3cc4f77f074"
``` ```
Decide rebuild-as-is vs reduced v1 scope. **Human gate — Bernd.** Capture the Decide rebuild-as-is vs reduced v1 scope. **Human gate — Bernd.** Capture under
decision as a decision record under `docs/decisions/` (or State Hub decision) `docs/decisions/`. Gate **apex cutover / bulk migration**, not day-to-day
before CSOC-WP-0002 implementation scoping proceeds. rebuild work on `app.coulomb.social`.
## Migration rehearsal ## Migration rehearsal
```task ```task
id: CSOC-WP-0001-T04 id: CSOC-WP-0001-T04
status: todo status: todo
priority: medium priority: low
state_hub_task_id: "2e5be321-3d76-4d7a-86b1-cbe4eb554bd7" state_hub_task_id: "2e5be321-3d76-4d7a-86b1-cbe4eb554bd7"
``` ```
Import the exported data into the v1 schema on a dev instance. Record what Import one or more Bubble spaces into the v1 model on a non-production path
failed, what was lossy, and what must change before cutover. Depends on T02 (app host or staging). Record lossiness and residuals. **Blocked until**
and a scaffolded schema (may start as a schema-only dry run). CSOC-WP-0004 persistence exists and T02 mapping is written. Explicitly **not**
a prerequisite for building product UX on the empty/new content store.
## Acceptance ## Acceptance
- Inventory and mapping docs are committed and reviewable. - Inventory and mapping docs are committed and reviewable.
- Feature-cut decision is recorded with owner and date. - Feature-cut decision is recorded with owner and date.
- At least one migration rehearsal has been run and residual gaps listed. - At least one migration rehearsal has been run and residual gaps listed.
- Follow-on implementation workplan `CSOC-WP-0002` can be scoped from T03. - Apex Bubble retirement is only planned after rehearsal + product parity gate.
## Notes ## Notes
- Parallel hosts: `docs/deploy.md`
- Next product build: `workplans/CSOC-WP-0004-app-shell-and-space-content.md`
- Service contract: `the-custodian/canon/standards/business-app-service-contract_v0.1.md` - Service contract: `the-custodian/canon/standards/business-app-service-contract_v0.1.md`
- Delivery lane reference: `vergabe-teilnahme`
- Preconditions before serving members (ops backup, ops-hub registration,
fin-hub cost key) remain platform-side; track against the contract, do not
block inventory/export work here.

View file

@ -4,11 +4,11 @@ type: workplan
title: "Reestablish coulomb.social with NetKingdom user management" title: "Reestablish coulomb.social with NetKingdom user management"
domain: communication domain: communication
repo: coulomb-social repo: coulomb-social
status: active status: done
owner: bernd owner: bernd
topic_slug: coulomb-social topic_slug: coulomb-social
created: "2026-08-09" created: "2026-08-09"
updated: "2026-08-09" updated: "2026-08-10"
depends_on: depends_on:
- CSOC-WP-0001 - CSOC-WP-0001
related: related:
@ -270,6 +270,17 @@ Align with business-app delivery lane without full production cutover:
2026-08-09 (smoke continuation): Offline checklist + `make test` (15) passed. Port-forward with `Host: coulomb.social`: healthz/landing OK; `/auth/login/` 302 to KeyCape with prod redirect + PKCE. KeyCape authorize accepts local and prod redirect URIs (→ Authelia). Full browser MFA login still human step (`docs/identity/smoke.md`); cutover steps in `docs/deploy.md`. 2026-08-09 (smoke continuation): Offline checklist + `make test` (15) passed. Port-forward with `Host: coulomb.social`: healthz/landing OK; `/auth/login/` 302 to KeyCape with prod redirect + PKCE. KeyCape authorize accepts local and prod redirect URIs (→ Authelia). Full browser MFA login still human step (`docs/identity/smoke.md`); cutover steps in `docs/deploy.md`.
2026-08-10 (acceptance complete on parallel host):
- Public rebuild host **`https://app.coulomb.social`** (apex `coulomb.social` remains Bubble).
- KeyCape client `mfaRequired: false`; id_token claim path deployed (`:f5537d8`).
- Operator **tegwick** signed in end-to-end; authenticated shell shows principal
(display name, subject, user-engine id, tenant).
- Workplan acceptance criteria 1–7 satisfied for identity/membership shell.
- Content, spaces, and Bubble migration are **out of scope** here — see
`CSOC-WP-0004` (product shell + markdown/Forgejo content) and deferred
`CSOC-WP-0001` migration.
--- ---
## Sequencing ## Sequencing
@ -292,10 +303,11 @@ are known.
| Residual | Future home | | Residual | Future home |
|----------|-------------| |----------|-------------|
| Bubble content claim & migration | New workplan after CSOC-WP-0001 T03 cut | | Post-login product entry + spaces UI | **CSOC-WP-0004** (next) |
| Full product UI (Research, Pages, …) | Post-shell product workplans | | Space content as markdown + Forgejo | **CSOC-WP-0004** |
| Public self-registration | CSOC-WP-0003 + NK-WP-0025 (platform) |
| Bubble content claim & full migration | CSOC-WP-0001 — **after** product parity on app.* |
| Production Keycloak expanded mode | NetKingdom (NK-WP-0011 triggers) if demand | | Production Keycloak expanded mode | NetKingdom (NK-WP-0011 triggers) if demand |
| Member invitation email at scale | email-connect / NK-WP-0024 lanes |
## Related ## Related

View file

@ -5,10 +5,10 @@ title: "Add NetKingdom self-registration and profile-aware assurance"
domain: communication domain: communication
repo: coulomb-social repo: coulomb-social
status: active status: active
owner: codex owner: bernd
topic_slug: coulomb-social topic_slug: coulomb-social
created: "2026-08-09" created: "2026-08-09"
updated: "2026-08-09" updated: "2026-08-10"
depends_on: depends_on:
- CSOC-WP-0002 - CSOC-WP-0002
- NK-WP-0025 - NK-WP-0025
@ -22,6 +22,11 @@ state_hub_workstream_id: "7cd7d6b8-e01d-4b34-8680-3c0cac68d80e"
Extend the working CSOC-WP-0002 OIDC/JIT shell with a NetKingdom account Extend the working CSOC-WP-0002 OIDC/JIT shell with a NetKingdom account
creation entry point and optional profile/action step-up. creation entry point and optional profile/action step-up.
**2026-08-10 posture:** existing-user login on **`app.coulomb.social`** is proven
(tegwick, AAL1, no MFA). Public **Create account** remains blocked on NetKingdom
mailbox verification (NK-WP-0025 / USER-WP-0022). Product work proceeds via
`CSOC-WP-0004` without waiting on public registration.
## T01 - Preserve and prove first-login JIT profile creation ## T01 - Preserve and prove first-login JIT profile creation
```task ```task
@ -31,35 +36,24 @@ priority: high
state_hub_task_id: "dde13170-7203-4fcd-b0ce-5874fccc4632" state_hub_task_id: "dde13170-7203-4fcd-b0ce-5874fccc4632"
``` ```
Harden the existing issuer/subject keyed Member creation, concurrent callback Harden issuer/subject keyed Member creation, concurrent callback behavior,
behavior, verified ID-token processing, and user-engine link. Preserve the verified ID-token processing, and user-engine link.
current uncommitted CSOC-WP-0002 claim-verification work.
Done when an existing LLDAP identity gets exactly one ordinary Member and **2026-08-10 evidence:** live login on app.coulomb.social shows principal +
repeat login updates safe display fields without changing identity ownership. user-engine id; image `:f5537d8` uses id_token when `/userinfo` 401s.
Covered by the issuer/subject uniqueness constraint, unusable local passwords,
idempotent session establishment tests, and verified ID-token claim handling.
## T02 - Add Create NetKingdom account ## T02 - Add Create NetKingdom account
```task ```task
id: CSOC-WP-0003-T02 id: CSOC-WP-0003-T02
status: progress status: progress
priority: high priority: medium
state_hub_task_id: "aaf2d2cb-6ba9-42cb-9271-aacc414e947a" state_hub_task_id: "aaf2d2cb-6ba9-42cb-9271-aacc414e947a"
``` ```
Add a landing-page registration choice using the configured NetKingdom public Landing-page **Create account** using configured `NETKINGDOM_REGISTRATION_URL`.
registration URL. The configured URL owns any signed return context. Completion must App entry is implemented; remains disabled until NetKingdom public registration
start a fresh OIDC flow before creating an application session. URL + verified-mail flow ship.
Done when a new user can leave coulomb.social, register, and return through
the same callback/JIT path without open redirects.
The application entry point is implemented and ignores browser-supplied
redirect parameters. It remains disabled until the NetKingdom public
registration URL and verified-mail flow are deployed.
## T03 - Support profile/action step-up ## T03 - Support profile/action step-up
@ -70,27 +64,22 @@ priority: high
state_hub_task_id: "6636a746-02ca-4a70-ac3c-0219c89cd6a7" state_hub_task_id: "6636a746-02ca-4a70-ac3c-0219c89cd6a7"
``` ```
Use AAL1 for ordinary member sessions. When profile policy or a protected AAL1 ordinary sessions; AAL2 via `acr_values` when required. Live coulomb-social
action requires MFA, restart authorization with AAL2 acr_values and verify the client uses `mfaRequired: false`.
returned assurance claim before completing the action.
Done when tegwick can use ordinary login without MFA and opt into or encounter
MFA step-up without affecting another member.
Implemented explicit `?assurance=aal2`, OIDC `acr_values`, and callback-side
assurance validation. Ordinary login sends no ACR request.
## T04 - Deploy and run Case A / Case B matrix ## T04 - Deploy and run Case A / Case B matrix
```task ```task
id: CSOC-WP-0003-T04 id: CSOC-WP-0003-T04
status: todo status: progress
priority: high priority: medium
state_hub_task_id: "57bac5f4-fd5d-46ba-92a3-a7bbeb15aa08" state_hub_task_id: "57bac5f4-fd5d-46ba-92a3-a7bbeb15aa08"
``` ```
Test known LLDAP user, new registration, repeated/concurrent callback, | Case | Status |
email collision, state replay, disabled identity, local-account coexistence, |------|--------|
password-only login, AAL2 step-up, logout, and rollback on railiance01. | A — known LLDAP user, first/repeat login on app.* | **done** (tegwick) |
| B — brand-new public registration → OIDC → Member | **blocked** on NK mailbox verification |
Done when both requested cases pass with non-secret evidence. Record remaining negatives (state replay, collision, step-up) when Case B unblocks
or in a short follow-up smoke note under `docs/identity/smoke.md`.

View file

@ -0,0 +1,185 @@
---
id: CSOC-WP-0004
type: workplan
title: "App shell entry and Forgejo-backed space content"
domain: communication
repo: coulomb-social
status: active
owner: bernd
topic_slug: coulomb-social
created: "2026-08-10"
updated: "2026-08-10"
depends_on:
- CSOC-WP-0002
related:
- CSOC-WP-0001
- CSOC-WP-0003
origin: operator
origin_ref: session-2026-08-10-parallel-host-product-path
---
# CSOC-WP-0004 — App shell entry and Forgejo-backed space content
## Context
Identity is live on **`https://app.coulomb.social`**. After Sign in, members
land on an identity **confirmation shell** (“Signed in” + principal dump) with
no product surface. Bubble on apex remains the full product until we choose
cutover.
**Goal for this phase:** build the new implementation toward product usefulness
**before** bulk Bubble data migration. Immediate product foundation:
1. Leave the login confirmation shell into a real **app home**.
2. Establish **space** persistence whose **content is markdown**, stored and
versioned in close connection with **Forgejo** repositories.
Migration of all Bubble spaces is **explicitly later** (`CSOC-WP-0001`).
## Out of scope (this plan)
- Apex DNS cutover / Bubble retirement
- Full Bubble inventory or bulk import
- Public self-registration (CSOC-WP-0003 / NetKingdom)
- Full UI parity (Research, marketplace matching, …) beyond space content MVP
---
## T01 — Post-login product entry (leave confirmation shell)
```task
id: CSOC-WP-0004-T01
status: todo
priority: high
```
Replace the dead-end “Signed in / Principal” page as the primary post-login
destination with an **app home** that a member can use:
- Clear primary navigation: Spaces (and placeholders for later surfaces).
- Principal summary available but secondary (account menu or `/account/`).
- Empty state when the member has no spaces yet (“Create space” or “No spaces”).
- `LOGIN_REDIRECT_URL` and templates updated; design-extract tokens only as needed.
**Done when:** after OIDC login on app.coulomb.social, tegwick lands on app home
(not a debug-only principal card) and can navigate without guessing URLs.
## T02 — Space domain model (metadata, tenant-keyed)
```task
id: CSOC-WP-0004-T02
status: todo
priority: high
```
Introduce `Space` (name pending Bubble vocabulary alignment) as application
metadata in the app DB:
- `tenant_id`, stable slug, display title, owner/membership linkage to Member
- **no** long-form page bodies in Postgres as the system of record
- optional pointer fields for content binding (repo, default branch, root path)
Migrations + admin + minimal list/detail routes behind auth.
**Done when:** authenticated user can list zero-or-more spaces from DB; tests cover
tenant isolation basics.
## T03 — Content model ADR: markdown + Forgejo
```task
id: CSOC-WP-0004-T03
status: todo
priority: high
```
Write `docs/adr/ADR-0002-space-content-forgejo-markdown.md` deciding:
- Markdown (and assets) as the **canonical content form** for space pages
- Forgejo repo layout (one repo per space vs monorepo paths; branch policy)
- How the app **reads** content (clone/cache, raw API, webhook invalidation)
- How the app **writes** (direct git push as service account vs user OAuth to Forgejo)
- Relationship to Bubble page/chunk model for later CSOC-WP-0001 mapping
- Secrets: Forgejo tokens via OpenBao / env secret names only
**Done when:** ADR accepted (or explicitly provisional with open questions listed)
and linked from INTENT/SCOPE.
## T04 — Read path: render space markdown from bound repo
```task
id: CSOC-WP-0004-T04
status: todo
priority: high
```
Implement a vertical slice:
- Operator or seed binds one space to a Forgejo repo path
- App fetches/renders a markdown page (e.g. `README.md` or `pages/index.md`)
- Authz: member of tenant/space only (flex-auth or coarse membership check)
- Fail closed on missing binding or fetch errors
**Done when:** tegwick can open a space on app.coulomb.social and see rendered
markdown sourced from Forgejo (not Bubble).
## T05 — Write / sync path (minimal)
```task
id: CSOC-WP-0004-T05
status: todo
priority: medium
```
Minimal authoring or sync so content is not read-only forever:
- either in-app edit → commit to Forgejo, or
- documented “edit in Forgejo / pull request” workflow + refresh webhook
Prefer the smaller path that keeps git as source of truth.
**Done when:** a content change in Forgejo appears in the app without redeploy,
and (if in-app write exists) a save produces a commit without secrets in git.
## T06 — Seed and runbook for app.coulomb.social
```task
id: CSOC-WP-0004-T06
status: todo
priority: medium
```
Document operator steps: create Forgejo org/repo, bind space, credentials env
names, smoke checklist on app.coulomb.social. Update `docs/deploy.md` and
`docs/identity/smoke.md` pointers as needed.
---
## Sequencing
```text
T01 app home entry
└─► T02 Space metadata
└─► T03 content ADR
└─► T04 read path (MVP value)
├─► T05 write/sync
└─► T06 runbook
```
T01 can ship alone to fix the “stuck on login confirmation” UX immediately.
T03 should land before large T04 investment if write-model choices are unclear;
a **provisional** ADR is enough to start T04 against a single seed repo.
## Acceptance (workplan)
1. Post-login journey is product-shaped (app home + spaces), not identity-debug-only.
2. Spaces exist as tenant-keyed app records.
3. Space page content is markdown backed by Forgejo with a working read path.
4. Bubble migration is still not required for demos on app.coulomb.social.
5. CSOC-WP-0001 can map Bubble pages onto the ADR layout when migration starts.
## Related
- Live host: `docs/deploy.md` (app.coulomb.social parallel to Bubble)
- Identity: CSOC-WP-0002 (done), CSOC-WP-0003 (registration later)
- Migration later: CSOC-WP-0001
- Design tokens: `docs/design-extract/`