1
0
mirror of git://f0xx.org/ac/ac-docs synced 2026-07-29 03:38:22 +03:00
Files
ac-docs/specs/20260618_repos_reorganizing.md
Anton Afanasyeu 69a448f156 initial
2026-06-23 12:20:43 +02:00

41 KiB
Raw Blame History

Repository and microservice reorganization — specification

Field Value
Author Anton Afanasyeu
Revision R1
Creation date 2026-06-18
Last modification date 2026-06-22
Co-authored Cursor Agent (project assistant)
Severity high
State accepted
Document type spec
Supersedes
Design review docs/DRs/20260618_repos_reorganizing.md (frozen R1.1)

Document type: SPEC
Source draft: docs/drafts/20260618_repos_reorganizing.txt
Design review: docs/DRs/20260618_repos_reorganizing.md (frozen)
PDF: 20260618_repos_reorganizing.pdf · Regenerate: bash scripts/build-all-docs-pdf.sh
Status: Accepted — implementation phased per §9; monolith remains deployable until each migration step completes
Scope: Split git://f0xx.org/android_cast monolith into git org ac on the f0xx.org git server — full microservice end-state, VM-first cloud path

Related: INFRA.md · BUILD_DEPLOY.md · specs/20100612_1_scaling.md · orchestration/sim/cluster0/ARCHITECTURE.md

Documentation index: README.md

VCS (normative): Canonical remotes are git://f0xx.org/ac/<repo> — repos are created on the PO git server (bare repos, hooks, ACLs). Gitea at …/git/ is a browse UI over mirrors only. Optional HTTPS read-only: Appendix B.


Table of contents


1. Purpose

Define the normative end-state and ordered migration for splitting the AndroidCast monolith (git://f0xx.org/android_cast) into:

  • Independent git repositories under org ac on the f0xx.org git server
  • Microservice APIs (OpenAPI) and thin backend UIs
  • One public URI root per microproject under https://apps.f0xx.org/app/androidcast_project/
  • Phased delivery without a forced big-bang during alpha

Identity gate: ac-ms-identity (migration Step 6) MUST complete before any other domain microservice split.


2. Scope

In scope Out of scope (this SPEC)
Repo catalog, disk paths, git remotes (Appendix A) K8s / service mesh (optional later)
Path-per-microproject URL map (§7) SFU/media transcode runtime (F1/F2 repos listed only)
13-step migration plan (§9) Rewriting mobile codec stack
Platform libs (Composer) before MS split Gitea as repo provisioning UI
Optional HTTPS read-only git (Appendix B) Merging AndroidCast with unrelated git hosting products
ac-workspace manifest + OTA multi-repo SHAs Unified monorepo build in ac-workspace
VM lift-and-shift mapping to scaling SPEC
Unrelated nested git trees under examples/ (not product submodules)

Git submodules (monolith → split): only third-party/* (mobile deps) and backend/url-shortener.

Alpha: Production MAY continue on the monolith until migration Step 8+ per service; each step MUST leave prior steps deployable.


3. Requirements

3.1 Must

ID Requirement
R-VCS-1 Canonical remote: git://f0xx.org/ac/<repo>; PO creates bare repos on git server
R-VCS-2 Gitea at …/git/ is browse-only mirror; agents MUST NOT provision repos in Gitea
R-URL-1 Public base prefix: /app/androidcast_project/
R-URL-2 Target URLs MUST NOT use /crashes/ or ?view= (legacy 301 only, ≥ one release)
R-URL-3 One path root per microproject (§7.2)
R-URL-4 Auth at project root: /login, /logout, /register, /two-factor, /verify-email
R-ARCH-1 Full microservice end-state per §5§6
R-ARCH-2 ac-ms-identity gate before domain MS extraction (Step 6)
R-ARCH-3 ac-scripts separate; ac-deploy consumes it
R-MIG-1 Migration steps §9 executed in order; gates MUST NOT be skipped
R-SUB-1 Monolith submodules: only third-party/* and backend/url-shortener
R-SUB-2 No other nested git submodules in product repos or ac-workspace manifests
R-TEST-1 Each step verification in §9 and §12 MUST pass before the next step starts

3.2 Should

ID Requirement
R-VCS-3 Optional HTTPS read-only clones via git-r.f0xx.org (Appendix B)
R-VCS-4 Disk layout ac/<repo> under configurable GIT_ROOT (default /var/git/)
R-URL-5 Cookie path /app/androidcast_project until SSO replaces shared PHP session
R-DOC-1 OpenAPI stubs per MS in ac-docs/openapi/ after Step 4

3.3 Non-goals

  • Big-bang cutover before identity MS and edge shell exist
  • ac-ms-vcs application repo (VCS is infrastructure)
  • https://f0xx.org/... as git smart HTTP endpoint
  • AndroidCast code reading /etc/git-ro/ token ACL files (Appendix B is ops-only)

4. Baseline (current monolith)

4.1 Monolith map

Monolith path Future repo(s) Notes
app/, ndk/, gradle/ ac-mobile-android third-party submodules
desktop/session-studio/ ac-session-studio Low coupling
docs/ ac-docs
scripts/ ac-scripts
orchestration/ ac-deploy cluster0, docker
examples/crash_reporter/backend/ ac-ms-* + ac-be-* 32 PHP classes, 24 APIs
examples/build_console/ ac-ms-build, ac-be-builder Same DB users
examples/app_hub/ ac-be-hub Loads shared platform-web assets (not /crashes/assets/)
backend/url-shortener/ ac-ms-url-shortener Existing submodule

4.2 What is not a git repo

  • Gitea — read-only web UI over git mirrors on BE (:3000); not where repos are created
  • MariaDB, Janus (:8089)

4.3 Git submodules (monolith — only these)

Path Role after split
third-party/* Native/codec deps (submodules of ac-mobile-android)
backend/url-shortener/ URL shortener → ac-ms-url-shortener

No other directories in the monolith carry git submodules. Post-split, ac-deploy may submodule ac-scripts (repo-to-repo pin).


5. Target architecture

Platform (Composer / static — not runtime MS)
  ac-platform-php, ac-platform-db, ac-platform-web, ac-scripts, ac-docs

Infrastructure
  ac-deploy          submodules ac-scripts; docker, cluster0, nginx
  ac-platform-edge   nginx BFF: routes + session cookie domain
  ac-workspace       optional clone manifest (no unified build)

Clients
  ac-mobile-android, ac-mobile-ios (future), ac-session-studio

Microservices (OpenAPI)
  ac-ms-identity → ac-ms-rbac → ac-ms-devices
  ac-ms-issues, ac-ms-tickets, ac-ms-graphs, ac-ms-remote-access
  ac-ms-url-shortener, ac-ms-build, ac-ms-ota, ac-ms-notifications (later)

Backend UI (thin → MS APIs)
  ac-be-hub, ac-be-issues, ac-be-tickets, ac-be-graphs,
  ac-be-remote-access, ac-be-access, ac-be-builder, ac-be-auth

Consolidations vs initial PO sketch:

Initial name R0 decision
ac-be-console (monolith) Dissolved into ac-be-issues … ac-be-access
ac-ms-tracker ac-ms-issues + ac-ms-tickets
ac-ms-vpn-rssh + ac-ms-vpn-wireguard ac-ms-remote-access (single control plane)
ac-ms-analytics ac-ms-graphs (+ BI later)
ac-ms-orchestration ac-ms-build + ac-deploy
ac-ms-vcs Not a repo — Gitea is infra/UI only; git server is source of truth

6. Git repository catalog

Canonical remote: git://f0xx.org/ac/<repo> — PO provisions bare repos on the git server (org namespace ac).
Browse UI (optional): https://apps.f0xx.org/app/androidcast_project/git/ac/<repo> — Gitea mirror for humans; push/fetch use git server.
Legacy: git://f0xx.org/android_cast → read-only mirror until retired.

6.1 Structure rationale (R1)

The catalog below is the recommended end-state for this project:

  • Platform libs (P*) before microservices — avoids auth/DB duplication across 10+ PHP trees.
  • Thin BE UI (B*) separate from MS APIs (S*) — matches POs one public URI per microproject (§7).
  • ac-deploy + ac-scripts as the only deploy orchestration entry — fits VM roles in scaling SPEC.
  • No ac-ms-vcs repo — VCS is infrastructure, not application code.

POs initial sketch used deeper folder names (ac-backend/*, ac-microservice/*). R1 keeps the flatter ac-<name> list — easier permissions, clone URLs, and OTA manifest entries. Minor renames are acceptable; dependency order and URI split are locked.

ID Repo Git URL Role
W0 ac-workspace git://f0xx.org/ac/ac-workspace Optional submodule manifest
P0 ac-platform-php git://f0xx.org/ac/ac-platform-php Composer: auth client, PDO, HTTP
P1 ac-platform-db git://f0xx.org/ac/ac-platform-db SQL migrations
P2 ac-platform-web git://f0xx.org/ac/ac-platform-web Shared CSS/JS/theme
P3 ac-platform-edge git://f0xx.org/ac/ac-platform-edge nginx routes + proxy
P4 ac-scripts git://f0xx.org/ac/ac-scripts CI, OTA, native codecs, PDF
P5 ac-docs git://f0xx.org/ac/ac-docs Documentation
D0 ac-deploy git://f0xx.org/ac/ac-deploy docker, cluster0; uses P4
C0 ac-mobile-android git://f0xx.org/ac/ac-mobile-android Android + ndk + third-party
C1 ac-mobile-ios git://f0xx.org/ac/ac-mobile-ios Future iOS
C2 ac-session-studio git://f0xx.org/ac/ac-session-studio Desktop analyzer
S0 ac-ms-template git://f0xx.org/ac/ac-ms-template New MS cookiecutter
S1 ac-ms-identity git://f0xx.org/ac/ac-ms-identity Users, login, 2FA, sessions
S2 ac-ms-rbac git://f0xx.org/ac/ac-ms-rbac Companies, privileges
S3 ac-ms-devices git://f0xx.org/ac/ac-ms-devices Device registry
S4 ac-ms-issues git://f0xx.org/ac/ac-ms-issues Crash/report ingest
S5 ac-ms-tickets git://f0xx.org/ac/ac-ms-tickets Ticket workflow
S6 ac-ms-graphs git://f0xx.org/ac/ac-ms-graphs Graph ingest/query
S7 ac-ms-remote-access git://f0xx.org/ac/ac-ms-remote-access WG + RSSH API
S8 ac-ms-url-shortener git://f0xx.org/ac/ac-ms-url-shortener Short links API
S9 ac-ms-build git://f0xx.org/ac/ac-ms-build Build worker API
S10 ac-ms-ota git://f0xx.org/ac/ac-ms-ota Channel manifests
S11 ac-ms-notifications git://f0xx.org/ac/ac-ms-notifications SMTP (post-alpha)
B0 ac-be-hub git://f0xx.org/ac/ac-be-hub Landing
B1 ac-be-issues git://f0xx.org/ac/ac-be-issues Issues UI
B2 ac-be-tickets git://f0xx.org/ac/ac-be-tickets Tickets UI
B3 ac-be-graphs git://f0xx.org/ac/ac-be-graphs Graphs UI
B4 ac-be-remote-access git://f0xx.org/ac/ac-be-remote-access RA admin UI
B5 ac-be-access git://f0xx.org/ac/ac-be-access RBAC admin UI
B6 ac-be-builder git://f0xx.org/ac/ac-be-builder Builder UI
B7 ac-be-auth git://f0xx.org/ac/ac-be-auth Login/register shell
F1 ac-ms-sfu-signaling git://f0xx.org/ac/ac-ms-sfu-signaling Future F1
F2 ac-ms-media-transcode git://f0xx.org/ac/ac-ms-media-transcode Future VOD

Third-party codecs remain submodules of C0 (upstream URLs); optional git-server mirrors under ac/ for backup (sync scripts, not Gitea-as-SoT).

6.2 Repo creation waves (git server)

PO creates bare repos on the git server in waves (Gitea mirror sync follows). Agent/docs do not “create repos in Gitea.”

flowchart LR
    W1[Wave 1: docs scripts deploy session-studio url-shortener] --> W2[Wave 2: platform-php platform-db platform-web]
    W2 --> W3[Wave 3: ms-identity]
    W3 --> W4[Wave 4: ms-rbac ms-devices]
    W4 --> W5[Wave 5: ms-issues ms-tickets + be UI]
    W5 --> W6[Wave 6: ms-graphs ms-remote-access ms-build + UI]
    W6 --> W7[Wave 7: platform-edge mobile-android ms-ota]

7. Public URL specification

Base prefix (locked): https://apps.f0xx.org/app/androidcast_project

7.1 Rules (R1 — PO locked)

  1. No /crashes/ in target URLs — legacy path 301 → correct microproject root for ≥ one release, then drop from nginx/docs/mobile.
  2. No ?view= routing — each product surface has its own path root and (eventually) its own BE UI repo + nginx location.
  3. Auth at project root/login, /logout, /register, /two-factor, /verify-email (not under /issues/).
  4. Shared cookie path/app/androidcast_project at ac-platform-edge until SSO tokens replace shared PHP session.

7.2 Target path catalog (one URI per microproject)

Microproject Target URL root Repo (UI / API) Notes
Hub / landing …/ ac-be-hub Entry cards link to path roots only
Auth …/login, …/logout, … ac-be-auth → ac-ms-identity Project-root paths
Issues (reports) …/issues/ ac-be-issues / ac-ms-issues Was ?view=reports
Issue detail …/issues/{id} ac-be-issues Was ?view=report&id=
Tickets …/tickets/ ac-be-tickets / ac-ms-tickets Was ?view=tickets
Ticket detail …/tickets/{id} ac-be-tickets Was ?view=ticket&id=
Analytics / graphs …/graphs/ ac-be-graphs / ac-ms-graphs Already separate
RBAC / access …/access/ ac-be-access / ac-ms-rbac Was ?view=rbac
Remote access …/remote-access/ ac-be-remote-access / ac-ms-remote-access Was ?view=remote_access
Short links …/short-links/ ac-be-hub or thin UI / ac-ms-url-shortener Was ?view=short_links
Live sessions …/live-sessions/ ac-be-issues (or ac-be-live) / live_cast API Was ?view=live_sessions
Live join / education …/live/join, …/live/education shared live pages Under issues until split
Builder …/build/ ac-be-builder / ac-ms-build Unchanged
Git browse …/git/ Gitea UI (mirror) Not a microservice repo
OTA /v0/ota/ ac-ms-ota Top-level on apps host

API examples: …/issues/api/upload (not …/crashes/api/upload.php).

7.3 Migration table (legacy → target)

Legacy (forbidden in target) Target URL
…/crashes/?view=reports …/issues/
…/crashes/?view=report&id=N …/issues/N
…/crashes/?view=tickets …/tickets/
…/crashes/?view=ticket&id=N …/tickets/N
…/crashes/?view=home …/issues/ or …/ (hub)
…/crashes/?view=rbac …/access/
…/crashes/?view=remote_access …/remote-access/
…/crashes/?view=short_links …/short-links/
…/crashes/?view=live_sessions …/live-sessions/
…/crashes/?view=graphs …/graphs/
…/crashes/login …/login
…/crashes/api/upload.php …/issues/api/upload
…/crashes/ (any) 301 → matching row above

Monolith shim (Step 5 only): nginx may internally rewrite /issues/ → legacy PHP ?view=reports until ac-ms-issues exists — not exposed in links, docs, or mobile defaults.

Code updates: BackendEndpoints.java, hub index.php, all console nav, OpenAPI base paths, deploy nginx fragments.


8. Dependency graphs

8.1 End-to-end — clients, edge, services

flowchart TB
    subgraph clients [Clients]
        AND[ac-mobile-android]
        IOS[ac-mobile-ios]
        HUB[ac-be-hub]
        SS[ac-session-studio]
    end

    subgraph edge [Edge]
        EDGE[ac-platform-edge]
    end

    subgraph core [Core MS — order matters]
        ID[ac-ms-identity]
        RB[ac-ms-rbac]
        DV[ac-ms-devices]
    end

    subgraph domain [Domain MS]
        IS[ac-ms-issues]
        TK[ac-ms-tickets]
        GR[ac-ms-graphs]
        RA[ac-ms-remote-access]
        UL[ac-ms-url-shortener]
        BL[ac-ms-build]
        OT[ac-ms-ota]
    end

    AND --> EDGE
    IOS --> EDGE
    HUB --> EDGE
    SS -.->|offline files| AND
    EDGE --> ID
    EDGE --> IS & TK & GR & RA & UL & BL & OT & RB

    ID --> RB
    RB --> DV
    IS --> DV & RB
    TK --> RB
    TK -.-> IS
    GR --> ID
    RA --> RB & DV
    RA -.-> IS
    UL --> RB
    BL --> ID
    OT --> BL
    OT --> AND & IOS

8.2 Backend UI → microservice (requires)

flowchart LR
    B7[ac-be-auth] --> S1[ac-ms-identity]
    B5[ac-be-access] --> S2[ac-ms-rbac]
    B1[ac-be-issues] --> S4[ac-ms-issues]
    B2[ac-be-tickets] --> S5[ac-ms-tickets]
    B3[ac-be-graphs] --> S6[ac-ms-graphs]
    B4[ac-be-remote-access] --> S7[ac-ms-remote-access]
    B6[ac-be-builder] --> S9[ac-ms-build]
    B0[ac-be-hub] --> S1
    B0 --> P2[ac-platform-web]

    S4 --> S3[ac-ms-devices]
    S4 --> S2
    S5 --> S2
    S7 --> S2 & S3

Every B* and S* also requires P0 (ac-platform-php) and P1 (ac-platform-db) via Composer — omitted from diagram for clarity.

8.3 Platform and deploy layer

flowchart TB
    D0[ac-deploy] --> P4[ac-scripts]
    D0 --> P3[ac-platform-edge]
    D0 --> P1[ac-platform-db]

    P3 -->|routes| S1 & S4 & S5 & S6 & S7 & S8 & S9 & S10
    P2[ac-platform-web] -->|static| B0 & B1 & B2

    S1 & S2 & S3 & S4 & S5 --> P0[ac-platform-php]
    S6 & S7 & S8 & S9 & S10 --> P0
    B0 & B1 & B2 & B3 & B4 & B5 & B6 & B7 --> P0

    P1 --> DB[(MariaDB / managed DB)]
    S11[ac-ms-notifications] -.->|mail| S1

8.4 Service dependency matrix

Service Requires (hard) Requires (soft) Required by
ac-platform-db All MS, migration jobs
ac-platform-php ac-platform-db All MS, all BE UI
ac-platform-web ac-be-hub, all BE UI
ac-platform-edge ac-deploy nginx templates all MS upstream addrs All public HTTP
ac-ms-identity platform-db, platform-php ac-ms-notifications All MS, all BE UI, ac-ms-build
ac-ms-rbac ac-ms-identity devices, issues, tickets, RA, url-shortener
ac-ms-devices ac-ms-rbac ac-ms-identity ac-ms-issues, ac-ms-remote-access
ac-ms-issues ac-ms-rbac, ac-ms-devices ac-be-issues, mobile upload
ac-ms-tickets ac-ms-rbac ac-ms-issues ac-be-tickets
ac-ms-graphs ac-ms-identity ac-be-graphs, mobile
ac-ms-remote-access ac-ms-rbac, ac-ms-devices ac-ms-issues ac-be-remote-access, mobile
ac-ms-url-shortener ac-ms-rbac hub/admin UI
ac-ms-build ac-ms-identity git server mirrors ac-be-builder, ac-ms-ota
ac-ms-ota ac-ms-build C0, C1 SHAs mobile OTA clients
ac-mobile-android ac-ms-issues, ac-ms-graphs, ac-ms-remote-access APIs ac-ms-ota

8.5 Repo creation waves

See §6.2 for the ordered wave diagram.


9. Migration plan

Ordered steps for converting the monolith. Do not skip gates. Each step lists repos created/moved, monolith paths affected, and verification (see also §12).

Step 1 — Git org ac on f0xx.org server (no code move)

Goal: Namespace ac exists on the git server; legacy monolith mirror preserved; Gitea browse UI synced.

Action Detail
Create org / paths PO: bare repos under git://f0xx.org/ac/<repo> on git server
Mirror android_cast → read-only; plan ac-workspace or retire later
Gitea (optional) Sync mirrors for …/git/ browse UI only — not repo creation
Update docs Pointer in INFRA.md, AGENTS.md

Verify: git ls-remote git://f0xx.org/ac/ac-docs (after Step 2) ; legacy push still works.

Requires: nothing
Enables: all following steps


Step 2 — Extract zero-coupling repos

Goal: Repos with no runtime dependency on PHP monolith.

Repo From monolith CI
ac-docs docs/ PDF build
ac-scripts scripts/ lint/smoke
ac-session-studio desktop/session-studio/ unit tests
ac-ms-url-shortener backend/url-shortener/ PHPUnit (change remote URL only if already split)
ac-deploy orchestration/ + nginx seeds docker compose smoke

ac-deploy submodules ac-scripts at pinned SHA.

Verify: Each repo builds independently; monolith submodule paths updated OR mirror dual-push during transition.

Requires: Step 1
Enables: Steps 34


Step 3 — Platform libraries (foundation)

Goal: Shared code leaves monolith as Composer packages — no MS split yet.

Repo Extract from
ac-platform-db sql/, migrations from crash_reporter + url-shortener
ac-platform-php Auth*, Database, Rbac helpers, bootstrap patterns, shared_session.php
ac-platform-web crashes/assets/, shared theme referenced by hub

Monolith requires packages via Composer; behavior unchanged.

Verify: Monolith tests green; single login still works across hub/crashes/build.

Requires: Step 2
Enables: Step 4 (identity)


Step 4 — Microservice template and OpenAPI baseline

Goal: Cookiecutter + contract layout for all MS.

Repo Action
ac-ms-template Copy url-shortener + platform-php wiring
ac-docs Add openapi/ stubs per service

Verify: Scaffold new empty MS from template; deploy locally via ac-deploy.

Requires: Step 3
Enables: Step 5


Step 5 — Edge proxy (routing shell)

Goal: ac-platform-edge nginx config routes paths; still proxies to monolith PHP until MS exist.

Action Detail
Deploy edge config Map /issues/ → monolith ?view=reports internally (temporary)
Cookie Single path /app/androidcast_project

Verify: curl -I new paths return 200 via rewrite; old URLs still work.

Requires: Step 2 (ac-deploy)
Enables: Step 10 URL cutover


Step 6 — Identity microservice (GATE)

Goal: ac-ms-identity owns users, login, register, 2FA, session issuance.

Repo From monolith
ac-ms-identity Auth*, UserRepository, AuthTotp*, AuthRegistration*, …
ac-be-auth login/register views (thin)

Monolith/builder call identity for auth (HTTP or shared session bridge during transition).

Verify: Login at /app/androidcast_project/ + builder; sessions valid; ./scripts/test_rbac_api.sh still passes against bridged auth.

Requires: Steps 3, 4
Enables: Steps 7, 9, 11 — nothing else splits before this


Step 7 — RBAC and devices microservices

Goal: Company scope and device registry are independent APIs.

Repo From monolith
ac-ms-rbac Rbac*, RbacAdmin*, companies API
ac-ms-devices DeviceRepository

Verify: Upload still registers device; RBAC panel works via APIs.

Requires: Step 6
Enables: Steps 8, 9


Step 8 — Issues and tickets (domain core)

Goal: Split POs primary URL surfaces.

Repo From monolith
ac-ms-issues upload, Report*, Tag*, reports API
ac-ms-tickets Ticket*, attachments
ac-be-issues reports views + JS
ac-be-tickets tickets views + JS

Edge routes /issues/ → S4/B1, /tickets/ → S5/B2.

Verify: Mobile upload to new URL; web issue/ticket lists; E2E ticket workflow.

Requires: Step 7
Enables: Step 9 (RA links to issues)


Step 9 — Graphs and remote access

Repo From monolith
ac-ms-graphs GraphRepository, graph_* API
ac-ms-remote-access RemoteAccess*, WireGuard*, Rssh*
ac-be-graphs graphs UI
ac-be-remote-access remote_access view

Verify: BackendEndpoints graph URL; RA E2E (ra_e2e_cli.sh); mobile RA API.

Requires: Steps 7, 8 (RA → devices, issue links)
Enables: Step 11


Step 10 — Hub, access UI, URL migration

Repo Action
ac-be-hub Extract app_hub; use ac-platform-web assets
ac-be-access RBAC UI → calls ac-ms-rbac
ac-platform-edge Enable 301 from /crashes/ and ?view=* to §7 path roots

Verify: Hub cards link to /issues/, /tickets/; no broken CSS.

Requires: Steps 5, 8, 9
Enables: Step 11


Step 11 — Build and OTA pipeline

Repo From monolith
ac-ms-build BuildRunner, build APIs
ac-be-builder build_console UI
ac-ms-ota OTA manifest assembly
ac-mobile-android app/, ndk/, gradle (extract from monolith)

Verify: Builder triggers APK; OTA channel publishes; manifest lists android (+ ios when C1 exists).

Requires: Step 6 (identity for builder users)
Enables: Step 12


Step 12 — Optional workspace and monolith retirement

Action Detail
ac-workspace Publish optional .gitmodules manifest
Retire Stop commits to android_cast monolith; archive mirror
Gitea mirror sync Update mirror scripts for org ac (server → Gitea UI; gitea README)

Verify: Fresh clone via ac-workspace or individual repos; prod deploy from ac-deploy only.

Requires: Steps 111 complete for services in scope
Enables: cloud VM scaling, future F1/F2 MS


Step 13 — Notifications and cloud hardening (post-alpha)

Repo Action
ac-ms-notifications Extract AuthMailer; wire 2.x mail when unblocked
ac-deploy Managed DB DSN templates; cluster0 → cloud VM roles

Requires: Step 6; mail infra (developer)
Enables: full 2FA mail E2E


Conversion step summary (quick reference)

Step Name Gate
1 Git org ac on server
2 docs, scripts, deploy, session-studio, url-shortener
3 platform-php, platform-db, platform-web
4 ms-template, OpenAPI
5 platform-edge (shell)
6 ms-identity, be-auth GATE
7 ms-rbac, ms-devices after 6
8 ms-issues, ms-tickets, be-issues, be-tickets after 7
9 ms-graphs, ms-remote-access, be UI after 78
10 be-hub, be-access, URL 301 after 89
11 ms-build, ms-ota, mobile-android after 6
12 ac-workspace, retire monolith after 111
13 notifications, cloud post-alpha

10. Infrastructure and cloud

Stage Pattern
Prod today FE TLS → BE :80 nginx + PHP-FPM + MariaDB
cluster0 lab cast0103; NFS config only; GTID DB (ARCHITECTURE.md)
Cloud phase A 46 VMs: be-web, be-data, be-ops, be-build (scaling §6.3)
Cloud phase B Managed DB; DSN in secrets (not in git)
Cloud phase C K8s optional — not required at R0

Inter-service calls: HTTP on private VLAN / localhost initially; OpenAPI in ac-docs. No service mesh at R0.

ac-deploy ships Ansible/docker-compose per VM role; submodules ac-scripts.


11. ac-workspace and OTA versioning

ac-workspace — optional; lists repo SHAs for a release train. Not a unified Gradle/PHP build.

ac-ms-ota manifest (same product version, per-platform SHAs):

{
  "channel": "staging",
  "version": "00.02.00.00",
  "artifacts": {
    "android": { "repo": "ac-mobile-android", "git_sha": "abc123" },
    "ios": { "repo": "ac-mobile-ios", "git_sha": "def456" }
  }
}

12. Verification and acceptance

Per-step gates from §9 — all MUST pass before the next step begins.

Step Acceptance criteria
1 git ls-remote git://f0xx.org/ac/ac-docs succeeds (after Step 2 repo exists); legacy android_cast push still works
2 Each extracted repo builds/CI green independently
3 Monolith tests green; single login across hub/issues/build
4 Empty MS scaffold deploys locally via ac-deploy
5 curl -I on /issues/, /tickets/, … return 200 via edge rewrite
6 Login + ./scripts/test_rbac_api.sh pass (identity gate)
7 Device upload + RBAC API via new services
8 Mobile upload to …/issues/api/upload; ticket E2E
9 Graph + RA E2E (ra_e2e_cli.sh)
10 Hub links use path roots only; 301 from /crashes/
11 Builder APK + OTA channel publish
12 Fresh clone via ac-workspace or per-repo remotes
13 Mail E2E when infra unblocked

URL regression (ongoing): hub, mobile BackendEndpoints, nginx fragments, and docs MUST NOT introduce new /crashes/ or ?view= links after Step 5.

Repo index: Appendix A disk paths MUST match live git server layout before Step 2 mass extract.


13. Risks and mitigations

Risk Mitigation
Auth split breaks all consoles Step 6 gate; session bridge during transition
Hub broken CSS ac-platform-web before ac-be-hub (Step 3 before 10)
Mobile upload URL change Parallel endpoints + BackendEndpoints normalization
DB schema drift ac-platform-db single migration stream
Too many repos to bump Composer semver for P0; not @common submodule diamond
Alpha blocked Monolith stays prod until Step 8+ complete per service
PO BE learning curve ac-ms-template, ac-deploy, OpenAPI, localhost HTTP

Appendix A — Git disk paths and remotes

Convention: disk paths are relative to the git server root (example: /var/git/). PO may choose another root; keep the ac/<repo> layout.
Canonical clone/fetch (write + read): git://f0xx.org/ac/<repo>
HTTPS read-only (optional): see Appendix B — separate vhost; not https://f0xx.org/... app URLs.

# Disk path (relative) Git repo URL
1 ac/ac-workspace git://f0xx.org/ac/ac-workspace
2 ac/ac-platform-php git://f0xx.org/ac/ac-platform-php
3 ac/ac-platform-db git://f0xx.org/ac/ac-platform-db
4 ac/ac-platform-web git://f0xx.org/ac/ac-platform-web
5 ac/ac-platform-edge git://f0xx.org/ac/ac-platform-edge
6 ac/ac-scripts git://f0xx.org/ac/ac-scripts
7 ac/ac-docs git://f0xx.org/ac/ac-docs
8 ac/ac-deploy git://f0xx.org/ac/ac-deploy
9 ac/ac-mobile-android git://f0xx.org/ac/ac-mobile-android
10 ac/ac-mobile-ios git://f0xx.org/ac/ac-mobile-ios
11 ac/ac-session-studio git://f0xx.org/ac/ac-session-studio
12 ac/ac-ms-template git://f0xx.org/ac/ac-ms-template
13 ac/ac-ms-identity git://f0xx.org/ac/ac-ms-identity
14 ac/ac-ms-rbac git://f0xx.org/ac/ac-ms-rbac
15 ac/ac-ms-devices git://f0xx.org/ac/ac-ms-devices
16 ac/ac-ms-issues git://f0xx.org/ac/ac-ms-issues
17 ac/ac-ms-tickets git://f0xx.org/ac/ac-ms-tickets
18 ac/ac-ms-graphs git://f0xx.org/ac/ac-ms-graphs
19 ac/ac-ms-remote-access git://f0xx.org/ac/ac-ms-remote-access
20 ac/ac-ms-url-shortener git://f0xx.org/ac/ac-ms-url-shortener
21 ac/ac-ms-build git://f0xx.org/ac/ac-ms-build
22 ac/ac-ms-ota git://f0xx.org/ac/ac-ms-ota
23 ac/ac-ms-notifications git://f0xx.org/ac/ac-ms-notifications
24 ac/ac-be-hub git://f0xx.org/ac/ac-be-hub
25 ac/ac-be-issues git://f0xx.org/ac/ac-be-issues
26 ac/ac-be-tickets git://f0xx.org/ac/ac-be-tickets
27 ac/ac-be-graphs git://f0xx.org/ac/ac-be-graphs
28 ac/ac-be-remote-access git://f0xx.org/ac/ac-be-remote-access
29 ac/ac-be-access git://f0xx.org/ac/ac-be-access
30 ac/ac-be-builder git://f0xx.org/ac/ac-be-builder
31 ac/ac-be-auth git://f0xx.org/ac/ac-be-auth
32 ac/ac-ms-sfu-signaling git://f0xx.org/ac/ac-ms-sfu-signaling
33 ac/ac-ms-media-transcode git://f0xx.org/ac/ac-ms-media-transcode
34 android_cast git://f0xx.org/android_cast

Bare repo on server (PO): git init --bare /var/git/ac/ac-workspace (repeat per row; path = {GIT_ROOT}/ + disk path).


Appendix B — Optional HTTPS read-only git access

Scope: Standalone git infrastructure on the PO git host. Not part of the AndroidCast monorepo, BE PHP tree, Gitea product UI, or apps.f0xx.org consoles.
Goal: Keep git://f0xx.org/... for normal push/fetch; add https:// for read-only clones (anonymous and/or token), with TLS certs and ACL files outside the AndroidCast project.

Suggested hostname: git-r.f0xx.org (read-only smart HTTP). Do not reuse https://f0xx.org/ landing or https://apps.f0xx.org/ app paths for git smart HTTP.

Suggested paths on git server:

Path Purpose
/var/git/ Bare repos (Appendix A disk layout)
/etc/git-ro/ nginx snippets, token maps, install scripts — not in android_cast repo
/etc/git-ro/tokens/ Per-token permission files (see step 8)
/etc/letsencrypt/live/git-r.f0xx.org/ Certbot certificates

1) DNS

Add an A (or AAAA) record for the read-only git vhost pointing at the git server public or edge IP (same host that serves git:// today, or FE DNAT to it):

git-r.f0xx.org.  IN  A  <GIT_SERVER_PUBLIC_IP>

Verify:

dig +short git-r.f0xx.org

2) Install packages (git server — example: Gentoo/Alpine)

On the machine that holds /var/git/:

# Gentoo (example)
emerge -av nginx git fcgiwrap certbot

# Alpine (example)
apk add nginx git git-daemon fcgiwrap certbot certbot-nginx openssl

Enable fcgiwrap (smart HTTP via git http-backend):

# systemd example
systemctl enable --now fcgiwrap

3) Issue free TLS certificates (Certbot)

Run on the git server (or on FE if it terminates TLS and proxies to git — adjust plugin):

certbot certonly --standalone -d git-r.f0xx.org \
  --agree-tos -m admin@f0xx.org --non-interactive

If nginx is already bound to :80/:443, use the nginx plugin instead:

certbot certonly --nginx -d git-r.f0xx.org \
  --agree-tos -m admin@f0xx.org --non-interactive

Certificates land under /etc/letsencrypt/live/git-r.f0xx.org/fullchain.pem and privkey.pem.


4) nginx — HTTPS smart HTTP, read-only

Create /etc/git-ro/nginx-git-ro.conf (outside AndroidCast):

server {
    listen 443 ssl;
    server_name git-r.f0xx.org;

    ssl_certificate     /etc/letsencrypt/live/git-r.f0xx.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/git-r.f0xx.org/privkey.pem;

    root /var/git;

    location ~ ^/ac/(.+?)(\.git)?/(HEAD|info/refs|objects/info/.*|objects/([0-9a-f]{2}/[0-9a-f]{38}|pack/pack-.*))$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend;
        fastcgi_param GIT_HTTP_EXPORT_ALL "";
        fastcgi_param GIT_PROJECT_ROOT /var/git;
        fastcgi_param PATH_INFO /$1.git/$2;
        fastcgi_pass unix:/run/fcgiwrap.socket;
    }

    location ~ ^/ac/(.+?)\.git$ {
        return 301 /ac/$1.git/info/refs?service=git-upload-pack;
    }
}

Include it from the main nginx config:

ln -s /etc/git-ro/nginx-git-ro.conf /etc/nginx/conf.d/git-ro.conf
nginx -t && rc-service nginx reload    # Gentoo
# nginx -t && systemctl reload nginx   # other

Read-only guarantee: do not enable receive-pack; only git-upload-pack (clone/fetch) is exposed. Push stays on git://f0xx.org (SSH or authenticated path), not this vhost.

Test anonymous clone:

git clone https://git-r.f0xx.org/ac/ac-docs.git /tmp/ac-docs-ro-test

5) Mark public repos for anonymous HTTPS read

For each bare repo that may be cloned without a token:

GIT_ROOT=/var/git
repo=ac/ac-docs
touch "${GIT_ROOT}/${repo}.git/git-daemon-export-ok"
git -C "${GIT_ROOT}/${repo}.git" config http.receivepack false
git -C "${GIT_ROOT}/${repo}.git" config http.uploadpack true

Repeat for every Appendix A row you want world-readable over HTTPS.


6) Optional — require token for private HTTPS read

Add HTTP basic auth for selected locations. Store credentials outside AndroidCast:

install -d -m 0750 /etc/git-ro/htpasswd
htpasswd -c /etc/git-ro/htpasswd/ro-ci-user

In /etc/git-ro/nginx-git-ro.conf, inside the location block for smart HTTP:

    auth_basic "git read-only";
    auth_basic_user_file /etc/git-ro/htpasswd/ro-users;

Clone with token (password = token):

git clone https://ro-ci-user:<TOKEN>@git-r.f0xx.org/ac/ac-ms-identity.git

7) Token-wise permissions (outside AndroidCast)

Keep a simple ACL file per token under /etc/git-ro/tokens/not referenced by android_cast code:

install -d -m 0700 /etc/git-ro/tokens
cat > /etc/git-ro/tokens/ci-read-issues.env <<'EOF'
# token name: ci-read-issues
# htpasswd user: ro-ci-issues
# allowed repo prefixes (one per line, relative to /var/git)
ac/ac-ms-issues
ac/ac-be-issues
ac/ac-platform-php
EOF
chmod 0600 /etc/git-ro/tokens/*.env

Enforcement options (pick one on the git server):

  • Simple: separate htpasswd users per token + nginx location blocks per repo prefix.
  • Scalable: small git-ro-auth script (not in AndroidCast repo) consulted by nginx auth_request.

AndroidCast never reads /etc/git-ro/; CI machines hold tokens in their own secret stores.


8) Certbot renewal (crontab)

Edit root crontab on the git server:

crontab -e

Add:

17 3 * * * certbot renew --quiet --deploy-hook "nginx -t && rc-service nginx reload"

Or install a one-shot renew script /etc/git-ro/certbot-renew.sh:

#!/bin/sh
set -eu
certbot renew --quiet
nginx -t
rc-service nginx reload
chmod 0755 /etc/git-ro/certbot-renew.sh
crontab -e
17 3 * * * /etc/git-ro/certbot-renew.sh >> /var/log/git-ro-certbot.log 2>&1

9) Client remote examples

Use case Remote URL
Developer push/fetch (canonical) git://f0xx.org/ac/ac-mobile-android
Anonymous read (HTTPS) https://git-r.f0xx.org/ac/ac-docs.git
Token read (HTTPS) https://<user>:<token>@git-r.f0xx.org/ac/ac-ms-issues.git
Browse HTML (optional) https://apps.f0xx.org/app/androidcast_project/git/ (Gitea mirror only)

Do not document https://f0xx.org/... as a git smart HTTP endpoint; landing stays human/PDF only.


10) Verification checklist

# TLS
curl -sSI https://git-r.f0xx.org/ac/ac-docs.git/info/refs?service=git-upload-pack | head

# git:// still works (unchanged)
git ls-remote git://f0xx.org/ac/ac-docs

# HTTPS read-only (no push)
git clone https://git-r.f0xx.org/ac/ac-docs.git /tmp/ro-clone-test
cd /tmp/ro-clone-test && git push origin HEAD  # must fail on this vhost

Document Role
DRs/20260618_repos_reorganizing.md Frozen design review R1.1 (source of this SPEC)
INFRA.md FE/BE topology, ports
BUILD_DEPLOY.md Session cookie, deploy paths
specs/20100612_1_scaling.md VM roles, cluster layout
orchestration/sim/cluster0/ARCHITECTURE.md Lab cluster
OPEN_TASKS_GRAPH.md Task dependencies

15. Changelog

Rev Date Change
R1 2026-06-22 SPEC converted from frozen DR R1.1; normative requirements §3; migration §9; verification §12
R1.1 2026-06-22 Submodule policy §4.3: only third-party/* + backend/url-shortener