1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 04:18:09 +03:00

docs sync

This commit is contained in:
Anton Afanasyeu
2026-06-23 11:02:33 +02:00
parent 0b41f5f980
commit 2adfb2fe2a
42 changed files with 4333 additions and 691 deletions

View File

@@ -483,7 +483,7 @@ endobj
endobj
81 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174830+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174830+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103621+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103621+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 On-Demand Remote Access \(Reverse Tunnel\) Proposals) /Trapped /False
>>
endobj
@@ -1052,7 +1052,7 @@ xref
trailer
<<
/ID
[<559db9fd7b62d2e91af17ade78c5196e><559db9fd7b62d2e91af17ade78c5196e>]
[<f661f3d31db877cde66dc5c3877f072a><f661f3d31db877cde66dc5c3877f072a>]
% ReportLab generated PDF document -- digest (opensource)
/Info 81 0 R

View File

@@ -265,7 +265,7 @@ endobj
endobj
42 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174830+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174830+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103621+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103621+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 Email agent config & 2FA / mobile auth flow) /Trapped /False
>>
endobj
@@ -537,7 +537,7 @@ xref
trailer
<<
/ID
[<004fa69baafe806860fd5caf900f27cc><004fa69baafe806860fd5caf900f27cc>]
[<0781db1091e119408594de96d3ab2a27><0781db1091e119408594de96d3ab2a27>]
% ReportLab generated PDF document -- digest (opensource)
/Info 42 0 R

View File

@@ -208,7 +208,7 @@ endobj
endobj
33 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174830+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174830+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103621+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103621+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 alpha priorities \(2026-06-08 renumber\)) /Trapped /False
>>
endobj
@@ -418,7 +418,7 @@ xref
trailer
<<
/ID
[<d83210b5b8072cc987bb1c318f31c89f><d83210b5b8072cc987bb1c318f31c89f>]
[<a3cc5b4e2ffe782a6de46cae27a9a929><a3cc5b4e2ffe782a6de46cae27a9a929>]
% ReportLab generated PDF document -- digest (opensource)
/Info 33 0 R

View File

@@ -203,7 +203,7 @@ endobj
endobj
31 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174830+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174830+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (BE services & infrastructure \204 validation map) /Trapped /False
>>
endobj
@@ -385,7 +385,7 @@ xref
trailer
<<
/ID
[<75fe7d8232594dda144e97ffd8f367f5><75fe7d8232594dda144e97ffd8f367f5>]
[<fb9bfca085b4cc71dbd16a6ec3c9802f><fb9bfca085b4cc71dbd16a6ec3c9802f>]
% ReportLab generated PDF document -- digest (opensource)
/Info 31 0 R

View File

@@ -137,7 +137,7 @@ endobj
endobj
22 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Stream dump \204 developer debug recording \(FR 0.1\)) /Trapped /False
>>
endobj
@@ -277,7 +277,7 @@ xref
trailer
<<
/ID
[<20faf14480cf6a5151269a1112e8dd23><20faf14480cf6a5151269a1112e8dd23>]
[<5414717d95a706704816768ef651c305><5414717d95a706704816768ef651c305>]
% ReportLab generated PDF document -- digest (opensource)
/Info 22 0 R

View File

@@ -275,7 +275,7 @@ endobj
endobj
47 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 exposed services catalog) /Trapped /False
>>
endobj
@@ -589,7 +589,7 @@ xref
trailer
<<
/ID
[<ab9efcddb9075779887ee065ecd85d8c><ab9efcddb9075779887ee065ecd85d8c>]
[<821a3e74e00ad5b4b9fe220c5add2f64><821a3e74e00ad5b4b9fe220c5add2f64>]
% ReportLab generated PDF document -- digest (opensource)
/Info 47 0 R

View File

@@ -183,7 +183,7 @@ endobj
endobj
30 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 alpha release & QA) /Trapped /False
>>
endobj
@@ -377,7 +377,7 @@ xref
trailer
<<
/ID
[<22fbb11b27f5f2572e8185d6911a1116><22fbb11b27f5f2572e8185d6911a1116>]
[<9e958e14022981bf5a40e5727c09a87f><9e958e14022981bf5a40e5727c09a87f>]
% ReportLab generated PDF document -- digest (opensource)
/Info 30 0 R

View File

@@ -122,7 +122,7 @@ endobj
endobj
20 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Alpha soak checklist \(LAN demo\)) /Trapped /False
>>
endobj
@@ -240,7 +240,7 @@ xref
trailer
<<
/ID
[<d13b107bc5a7f93c8642ebc1592ff911><d13b107bc5a7f93c8642ebc1592ff911>]
[<da88c70ac5260df544a5bef670fb64c3><da88c70ac5260df544a5bef670fb64c3>]
% ReportLab generated PDF document -- digest (opensource)
/Info 20 0 R

View File

@@ -244,7 +244,7 @@ endobj
endobj
40 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (AV quality enhancement \204 Q&A session notes) /Trapped /False
>>
endobj
@@ -512,7 +512,7 @@ xref
trailer
<<
/ID
[<885b3d86c2d7fc8825759aeb11eaff9c><885b3d86c2d7fc8825759aeb11eaff9c>]
[<d92cdd33b95bf41f24a49cb9e3df4341><d92cdd33b95bf41f24a49cb9e3df4341>]
% ReportLab generated PDF document -- digest (opensource)
/Info 40 0 R

View File

@@ -137,7 +137,7 @@ endobj
endobj
22 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast build ecosystem) /Trapped /False
>>
endobj
@@ -278,7 +278,7 @@ xref
trailer
<<
/ID
[<e642f50f6998474676e62cda30c69ab5><e642f50f6998474676e62cda30c69ab5>]
[<b59c8931b799160e290e481e14299f1f><b59c8931b799160e290e481e14299f1f>]
% ReportLab generated PDF document -- digest (opensource)
/Info 22 0 R

View File

@@ -97,7 +97,7 @@ endobj
endobj
15 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Commercial features \(developer-gated\)) /Trapped /False
>>
endobj
@@ -192,7 +192,7 @@ xref
trailer
<<
/ID
[<550d28e222cb18370f0095c31b168c50><550d28e222cb18370f0095c31b168c50>]
[<fb238f534e35c75275910d5c14862078><fb238f534e35c75275910d5c14862078>]
% ReportLab generated PDF document -- digest (opensource)
/Info 15 0 R

View File

@@ -102,7 +102,7 @@ endobj
endobj
16 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Anonymous crash reporter) /Trapped /False
>>
endobj
@@ -198,7 +198,7 @@ xref
trailer
<<
/ID
[<a6b6c31fc1c3334769ccc6ba2abbc535><a6b6c31fc1c3334769ccc6ba2abbc535>]
[<22d958c84565d9778bc748babddf22d8><22d958c84565d9778bc748babddf22d8>]
% ReportLab generated PDF document -- digest (opensource)
/Info 16 0 R

View File

@@ -279,7 +279,7 @@ endobj
endobj
46 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103622+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103622+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (URL shortener service \204 design review \(DR\)) /Trapped /False
>>
endobj
@@ -553,7 +553,7 @@ xref
trailer
<<
/ID
[<83c7ff4a46a2644aace09ed6f7e081cb><83c7ff4a46a2644aace09ed6f7e081cb>]
[<0c13123401870dc3636a59ca6043fbfa><0c13123401870dc3636a59ca6043fbfa>]
% ReportLab generated PDF document -- digest (opensource)
/Info 46 0 R

View File

@@ -498,7 +498,7 @@ endobj
endobj
79 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174831+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174831+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103623+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103623+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Platform scaling and multi-environment architecture \204 design review \(DR\)) /Trapped /False
>>
endobj
@@ -933,7 +933,7 @@ xref
trailer
<<
/ID
[<7d99cda1a76db27f24dc235d81baf7e5><7d99cda1a76db27f24dc235d81baf7e5>]
[<633c08311ac4fc3baffc5b7f2ceda12e><633c08311ac4fc3baffc5b7f2ceda12e>]
% ReportLab generated PDF document -- digest (opensource)
/Info 79 0 R

View File

@@ -324,7 +324,7 @@ endobj
endobj
51 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174832+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174832+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103623+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103623+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (RSSH routed egress \(dev-only\) \204 design review \(DR\)) /Trapped /False
>>
endobj
@@ -663,7 +663,7 @@ xref
trailer
<<
/ID
[<ed6e2cbfecdbe9d49d63d210ed176bb8><ed6e2cbfecdbe9d49d63d210ed176bb8>]
[<007c0311bfb71c5beb7d2970ce25523e><007c0311bfb71c5beb7d2970ce25523e>]
% ReportLab generated PDF document -- digest (opensource)
/Info 51 0 R

View File

@@ -319,7 +319,7 @@ endobj
endobj
51 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174832+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174832+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103623+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103623+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Codec2 / ultra-low-bandwidth voice \204 design review \(DR\)) /Trapped /False
>>
endobj
@@ -657,7 +657,7 @@ xref
trailer
<<
/ID
[<c52c2dec229f7f4121897008cb63143d><c52c2dec229f7f4121897008cb63143d>]
[<c9beadc7d306c78320e68b037811d0b8><c9beadc7d306c78320e68b037811d0b8>]
% ReportLab generated PDF document -- digest (opensource)
/Info 51 0 R

View File

@@ -4,34 +4,30 @@
| Field | Value |
|---|---|
| Author | Anton Afanasyeu |
| Revision | R0 |
| Revision | R1 |
| Creation date | 2026-06-18 |
| Last modification date | 2026-06-18 |
| Last modification date | 2026-06-22 |
| Co-authored | Cursor Agent (project assistant) |
| Severity | high |
| State | approved for planning |
| State | frozen — superseded by [SPEC R1](../specs/20260618_repos_reorganizing.md) |
| Document type | DR |
| Pre-requisite to | Gitea org `ac` repo creation; post-alpha full MS split (alpha may stay on monolith until Step 8+) |
| Superseded by | [docs/specs/20260618_repos_reorganizing.md](../specs/20260618_repos_reorganizing.md) |
<!-- doc-meta:end -->
\newpage
\newpage
---
**Document type:** DR (Design Review)
**Document type:** DR (Design Review)**FROZEN**
**Specification:** [docs/specs/20260618_repos_reorganizing.md](../specs/20260618_repos_reorganizing.md) (normative implementation doc)
**Source draft:** [docs/drafts/20260618_repos_reorganizing.txt](../drafts/20260618_repos_reorganizing.txt)
**PDF:** [20260618_repos_reorganizing.pdf](20260618_repos_reorganizing.pdf) · Regenerate: `bash scripts/build-all-docs-pdf.sh`
**Status:** PO-approved (2026-06-18) — **implementation phased**; monolith remains deployable until each step completes
**Scope:** Split `git://f0xx.org/android_cast` monolith into Gitea org **`ac`** — full microservice end-state, VM-first cloud path
**Status:** Frozen R1.1 (2026-06-22) — accepted; **do not edit** except typo fixes; implement per SPEC
**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](../INFRA.md) · [BUILD_DEPLOY.md](../BUILD_DEPLOY.md) · [specs/20100612_1_scaling.md](../specs/20100612_1_scaling.md) · [orchestration/sim/cluster0/ARCHITECTURE.md](../../orchestration/sim/cluster0/ARCHITECTURE.md) · [examples/crash_reporter/backend/scripts/gitea/README.md](../../examples/crash_reporter/backend/scripts/gitea/README.md)
**Related:** [INFRA.md](../INFRA.md) · [BUILD_DEPLOY.md](../BUILD_DEPLOY.md) · [specs/20100612_1_scaling.md](../specs/20100612_1_scaling.md) · [orchestration/sim/cluster0/ARCHITECTURE.md](../../orchestration/sim/cluster0/ARCHITECTURE.md)
**Documentation index:** [README.md](../README.md)
---
---
**VCS clarification (R1):** Canonical remotes are **`git://f0xx.org/ac/<repo>`** — repos are **created and owned on the POs git server** (bare repos, hooks, ACLs). **Gitea** at `…/git/` is a **read-only browse UI** over those mirrors, not the system of record and **not** where new repos are provisioned. Ops mirror scripts (`examples/crash_reporter/backend/scripts/gitea/`) sync **server → Gitea** for HTML UI only.
---
@@ -43,7 +39,7 @@
- [3. PO decisions (locked)](#3-po-decisions-locked)
- [4. Current state](#4-current-state)
- [5. Target architecture](#5-target-architecture)
- [6. Gitea repo catalog](#6-gitea-repo-catalog)
- [6. Git repository catalog](#6-git-repository-catalog)
- [7. Public URL map](#7-public-url-map)
- [8. Dependency graphs](#8-dependency-graphs)
- [9. Monolith conversion steps](#9-monolith-conversion-steps)
@@ -52,6 +48,8 @@
- [12. ac-workspace and OTA versioning](#12-ac-workspace-and-ota-versioning)
- [13. Risks and mitigations](#13-risks-and-mitigations)
- [14. Changelog](#14-changelog)
- [Appendix A — Git disk paths and remotes](#appendix-a-git-disk-paths-and-remotes)
- [Appendix B — Optional HTTPS read-only git access](#appendix-b-optional-https-read-only-git-access)
<!-- /toc -->
---
@@ -60,19 +58,21 @@
**Question:** How should the androidcast monolith (`git://f0xx.org/android_cast`) be split into independent repos and deployable microservices?
**Short answer:** Create Gitea org **`ac`** with **platform libraries**, **microservice APIs**, **thin backend UIs**, **client repos**, and **`ac-deploy`** (submodules **`ac-scripts`**). End-state is **full microservice** architecture. Delivery is **strictly ordered****[§9 Monolith conversion steps](#9-monolith-conversion-steps)** — with **`ac-ms-identity` as the gate** before any domain service split.
**Short answer:** Create git org **`ac`** on the **f0xx.org git server** with **platform libraries**, **microservice APIs**, **thin backend UIs**, **client repos**, and **`ac-deploy`** (submodules **`ac-scripts`**). End-state is **full microservice** architecture. Delivery is **strictly ordered****[§9 Monolith conversion steps](#9-monolith-conversion-steps)** — with **`ac-ms-identity` as the gate** before any domain service split.
**DR decision (R0):**
**DR decision (R1):**
| Item | Decision |
|------|----------|
| **Gitea org** | **`ac`** — `git://f0xx.org/ac/<repo>` |
| **Git org** | **`ac`** on f0xx.org git server`git://f0xx.org/ac/<repo>` |
| **Gitea** | Browse-only UI at `…/git/`; **not** repo provisioning; PO creates bare repos on git server |
| **Architecture** | Full microservice end-state; phased migration from monolith |
| **URL prefix** | **`/app/androidcast_project/`** (full path, locked) |
| **Path-per-service** | `/issues/`, `/tickets/`, `/access/`, etc. — replace `/crashes/?view=` |
| **Path-per-microproject** | **One URI root per surface** `/issues/`, `/tickets/`, `/graphs/`, … — **no** `/crashes/` and **no** `?view=` in target URLs |
| **Scripts** | **`ac-scripts`** separate; **`ac-deploy`** consumes it (submodule or PATH) |
| **Workspace** | Optional **`ac-workspace`** — selective clone only; **not** build-all-in-one |
| **Identity gate** | **Step 6** (`ac-ms-identity`) before domain MS extraction |
| **Repo catalog (§6)** | **Approved** — PO minor naming deltas acceptable; structure kept as R1 table |
| **Cloud** | VM lift-and-shift first; K8s optional later |
| **Alpha** | Monolith may run in prod until Step 8+; no forced big-bang |
@@ -85,7 +85,7 @@ The monolith bundles Android app, PHP backend (crashes, tickets, graphs, RBAC, r
- Independent CI/CD and rollback per service
- Clear ownership and OpenAPI contracts
- Mapping repos to VM roles ([scaling SPEC §6.3](../specs/20100612_1_scaling.md))
- Product URLs such as [issues](https://apps.f0xx.org/app/androidcast_project/crashes/?view=reports) vs [tickets](https://apps.f0xx.org/app/androidcast_project/crashes/?view=tickets) under distinct paths
- Product URLs such as [issues](https://apps.f0xx.org/app/androidcast_project/issues/) vs [tickets](https://apps.f0xx.org/app/androidcast_project/tickets/) **distinct path roots**, not `?view=` under a shared `/crashes/` console
Todays coupling: **one MariaDB**, **one session cookie** (`ac_crash_sess`, path `/app/androidcast_project`), **shared Auth.php** across consoles ([BUILD_DEPLOY.md](../BUILD_DEPLOY.md)).
@@ -95,13 +95,16 @@ Todays coupling: **one MariaDB**, **one session cookie** (`ac_crash_sess`, pa
| # | Topic | Decision |
|---|-------|----------|
| 1 | Gitea org | **`ac`** |
| 1 | Git org | **`ac`** on f0xx.org **git server** (bare repos); Gitea = browse UI only |
| 2 | Architecture | **Full microservice** (phased delivery) |
| 3 | ac-scripts | Separate repo; **ac-deploy utilizes ac-scripts** |
| 4 | Public URLs | Path-per-service under **`/app/androidcast_project/`** |
| 4 | Public URLs | **One path root per microproject** under **`/app/androidcast_project/`** |
| 5 | ac-workspace | Optional manifest; **not** unified build; supports multi-repo OTA |
| 6 | Cloud | VM lift-and-shift; no K8s requirement at R0 |
| 6 | Cloud | VM lift-and-shift; no K8s requirement at R1 |
| 7 | Identity gate | **Approved** — identity MS before other MS splits |
| 8 | Legacy `/crashes/` | **301 only** during migration; **removed** from docs, hub, mobile defaults |
| 9 | `?view=` routing | **Forbidden** in target state — each console is its own nginx location + repo |
| 10 | Git submodules | **Only** `third-party/*` and `backend/url-shortener` — no other nested git trees in product repos |
---
@@ -118,14 +121,22 @@ Todays coupling: **one MariaDB**, **one session cookie** (`ac_crash_sess`, pa
| `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 `/crashes/assets/` today |
| `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** (infra on BE; scripts in ac-deploy)
- **Gitea** — read-only web UI over git mirrors on BE (`:3000`); **not** where repos are created
- **MariaDB**, **Janus** (:8089)
- `examples/gentoo-portage-experimental/` (exclude or separate lab repo)
### 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, not monolith legacy).
---
@@ -162,15 +173,26 @@ Backend UI (thin → MS APIs)
| 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 infra |
| ac-ms-vcs | **Not a repo** — Gitea is infra/UI only; git server is source of truth |
---
## 6. Gitea repo catalog
## 6. Git repository catalog
Canonical: **`git://f0xx.org/ac/<repo>`**
HTTPS (Gitea UI): **`https://apps.f0xx.org/app/androidcast_project/git/ac/<repo>.git`**
Legacy: **`git://f0xx.org/android_cast`** → read-only mirror until retired.
**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 |
|----|------|---------|------|
@@ -208,7 +230,21 @@ Legacy: **`git://f0xx.org/android_cast`** → read-only mirror until retired.
| 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); Gitea mirrors under `ac/`.
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.”
```mermaid
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]
```
---
@@ -216,25 +252,56 @@ Third-party codecs remain **submodules of C0** (upstream URLs); Gitea mirrors un
**Base prefix (locked):** `https://apps.f0xx.org/app/androidcast_project`
| Today | Target URL |
|-------|------------|
### 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` |
| `…/graphs/` | `…/graphs/` (unchanged) |
| `…/build/` | `…/build/` (unchanged) |
| `…/` (hub) | `…/` (unchanged) |
| `…/git/` | `…/git/` (Gitea) |
| `/v0/ota/` | `/v0/ota/` (unchanged) |
| `…/crashes/` (any) | **301** → matching row above |
**Cookie path:** remain `/app/androidcast_project` at **ac-platform-edge** until SSO tokens replace shared PHP session.
**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.
**Migration:** 301 redirects from old `?view=` URLs for ≥ one release; update `BackendEndpoints.java`, `CrashSettings.java`.
**Code updates:** `BackendEndpoints.java`, hub `index.php`, all console nav, OpenAPI base paths, deploy nginx fragments.
---
@@ -349,21 +416,13 @@ flowchart TB
| 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 | Gitea infra | ac-be-builder, ac-ms-ota |
| 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 (Gitea)
### 8.5 Repo creation waves
```mermaid
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]
```
See **[§6.2](#62-repo-creation-waves-git-server)** for the ordered wave diagram.
---
@@ -371,14 +430,15 @@ flowchart LR
Ordered steps for converting the monolith. **Do not skip gates.** Each step lists repos created/moved, monolith paths affected, and verification.
### Step 1 — Gitea org and mirrors (no code move)
### Step 1 — Git org `ac` on f0xx.org server (no code move)
**Goal:** Org **`ac`** exists; legacy mirror preserved.
**Goal:** Namespace **`ac`** exists on the **git server**; legacy monolith mirror preserved; Gitea browse UI synced.
| Action | Detail |
|--------|--------|
| Create org | `ac` on f0xx.org Gitea |
| 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.
@@ -536,7 +596,7 @@ Monolith/builder **call identity** for auth (HTTP or shared session bridge durin
|------|--------|
| 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/?view=*` to new paths |
| ac-platform-edge | Enable **301** from `/crashes/` and `?view=*` to §7 path roots |
**Verify:** Hub cards link to `/issues/`, `/tickets/`; no broken CSS.
@@ -567,7 +627,7 @@ Monolith/builder **call identity** for auth (HTTP or shared session bridge durin
|--------|--------|
| ac-workspace | Publish optional `.gitmodules` manifest |
| Retire | Stop commits to `android_cast` monolith; archive mirror |
| Gitea migrate | Update scripts for org `ac` ([gitea README](../../examples/crash_reporter/backend/scripts/gitea/README.md)) |
| Gitea mirror sync | Update mirror scripts for org `ac` (server → Gitea UI; [gitea README](../../examples/crash_reporter/backend/scripts/gitea/README.md)) |
**Verify:** Fresh clone via ac-workspace or individual repos; prod deploy from ac-deploy only.
@@ -592,7 +652,7 @@ Monolith/builder **call identity** for auth (HTTP or shared session bridge durin
| Step | Name | Gate |
|------|------|------|
| 1 | Gitea org `ac` | — |
| 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 | — |
@@ -615,13 +675,13 @@ Monolith/builder **call identity** for auth (HTTP or shared session bridge durin
| Independent deploy | Yes — per MS/UI repo | Single PHP deploy |
| Failure isolation | Stronger | Shared FPM pool |
| Auth complexity | Needs identity MS + edge early | Works today |
| URL clarity | `/issues/`, `/tickets/` | `?view=` parameters |
| URL clarity | `/issues/`, `/tickets/`, … — one URI per microproject | `?view=` under `/crashes/` |
| Ops load | More nginx, repos, logs | One sync path ([INFRA.md](../INFRA.md)) |
| Alpha risk | High if before Step 6 | Lower |
| Cloud mapping | 1:1 to VM roles | Lift entire tree |
| Rollback | Revert one repo SHA | Revert one commit |
PO choice is approved with **Step 6 gate** enforced in [§9](#9-monolith-conversion-steps).
PO choice is approved with **Step 6 gate** enforced in [§9](#9-monolith-conversion-steps). **R1:** URL model is **path-per-microproject** (§7), not query-parameter routing.
---
@@ -674,8 +734,310 @@ PO choice is approved with **Step 6 gate** enforced in [§9](#9-monolith-convers
---
## 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](#appendix-b-optional-https-read-only-git-access) — 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):
```text
git-r.f0xx.org. IN A <GIT_SERVER_PUBLIC_IP>
```
Verify:
```bash
dig +short git-r.f0xx.org
```
---
### 2) Install packages (git server — example: Gentoo/Alpine)
On the machine that holds `/var/git/`:
```bash
# 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`):
```bash
# 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):
```bash
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:
```bash
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):
```nginx
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:
```bash
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:
```bash
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:
```bash
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:
```bash
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:
```nginx
auth_basic "git read-only";
auth_basic_user_file /etc/git-ro/htpasswd/ro-users;
```
Clone with token (password = token):
```bash
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:
```bash
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:
```bash
crontab -e
```
Add:
```cron
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`:
```bash
#!/bin/sh
set -eu
certbot renew --quiet
nginx -t
rc-service nginx reload
```
```bash
chmod 0755 /etc/git-ro/certbot-renew.sh
crontab -e
```
```cron
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
```bash
# 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
```
---
## 14. Changelog
| Rev | Date | Change |
|-----|------|--------|
| R0 | 2026-06-18 | Initial DR from draft; PO locked org `ac`, full MS, URL prefix, identity gate; §9 conversion steps; dependency graphs |
| R1 | 2026-06-20 | **VCS:** git server = SoT; Gitea = browse UI only — not repo provisioning. **§6:** structure rationale; flat `ac-*` catalog approved. **§7:** no `/crashes/` or `?view=` in target; full path-per-microproject catalog. **PDF:** removed spurious `\newpage` blank sheets. PO review before SPEC. |
| R1.1 | 2026-06-22 | **Appendix A:** disk path ↔ `git://` URL index table (§6 catalog + legacy). **Appendix B:** optional HTTPS read-only git (`git-r.f0xx.org`), certbot, nginx smart HTTP, token ACL outside AndroidCast. |
| R1.1-frozen | 2026-06-22 | **Frozen** — superseded by [SPEC R1](../specs/20260618_repos_reorganizing.md) |

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,178 @@
%PDF-1.4
%“Œ‹ž ReportLab Generated PDF document (opensource)
1 0 obj
<<
/F1 2 0 R /F2 3 0 R /F3 8 0 R /F4 9 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
>>
endobj
4 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 10 0 R /Fit ] /Rect [ 45.68504 762.0394 116.381 773.0394 ] /Subtype /Link /Type /Annot
>>
endobj
5 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 10 0 R /Fit ] /Rect [ 45.68504 751.0394 124.813 762.0394 ] /Subtype /Link /Type /Annot
>>
endobj
6 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 10 0 R /Fit ] /Rect [ 45.68504 740.0394 108.381 751.0394 ] /Subtype /Link /Type /Annot
>>
endobj
7 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 10 0 R /Fit ] /Rect [ 45.68504 729.0394 108.373 740.0394 ] /Subtype /Link /Type /Annot
>>
endobj
8 0 obj
<<
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
>>
endobj
9 0 obj
<<
/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font
>>
endobj
10 0 obj
<<
/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
11 0 obj
<<
/Annots [ 4 0 R 5 0 R 6 0 R 7 0 R ] /Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0
/Trans <<
>> /Type /Page
>>
endobj
12 0 obj
<<
/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
13 0 obj
<<
/Outlines 15 0 R /PageMode /UseNone /Pages 20 0 R /Type /Catalog
>>
endobj
14 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260623103624+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103624+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Live Cast Control Plane \(P0-P2 kickoff\)) /Trapped /False
>>
endobj
15 0 obj
<<
/Count 4 /First 16 0 R /Last 19 0 R /Type /Outlines
>>
endobj
16 0 obj
<<
/Dest [ 10 0 R /Fit ] /Next 17 0 R /Parent 15 0 R /Title (Scope implemented)
>>
endobj
17 0 obj
<<
/Dest [ 10 0 R /Fit ] /Next 18 0 R /Parent 15 0 R /Prev 16 0 R /Title (Non-goals \(remaining\))
>>
endobj
18 0 obj
<<
/Dest [ 10 0 R /Fit ] /Next 19 0 R /Parent 15 0 R /Prev 17 0 R /Title (Data model notes)
>>
endobj
19 0 obj
<<
/Dest [ 10 0 R /Fit ] /Parent 15 0 R /Prev 18 0 R /Title (Follow-up phases)
>>
endobj
20 0 obj
<<
/Count 3 /Kids [ 10 0 R 11 0 R 12 0 R ] /Type /Pages
>>
endobj
21 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 350
>>
stream
Gas309kseb&-h(iregH[(*#.+hJ6skH*ASb@?K(l<nD1gqYN?Oqk95ea?YoVH'0kG$pMp1#M^\c-4JHr/_H4TRc6%:mfd&n>":b;AJ%6OAL]3UZ:uf`isa".?A/Xl:03adIjq0?J%#_TS[?aOQWn-o)_`4O;6gqb''466Z,1a*3+C\3Nr+9`fljW)@:%7/E2KmC2k.NukCWf`/(,Gmf*0+i,i^PaB6$4KVmu;VgN[M"g1N9U^:]BH$WE:RIGa#Bq(U5hHf_Z8[mI8;U"@PW?GC&4FiuH(5<'HMa)JoW!u*;-n@4Hj?Im&rWQ8F1kni'A5TJl-Zm3U2:DYDs,FBteMGNHDF+j~>endstream
endobj
22 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 491
>>
stream
Gatn"?#SI?'Sc)J/)JHk;CMj0Z$/3N\XKBio4=_R3]-Aa_)%n_qnl0.D/Co"W]Cb`S-.)a4s9?21p:a,HtdQ/,*5(]#V&r-jr;#mMa%S17i$uIQ/VtSer7e`aS3!0nOc=u_.6hl?%H]9l@L_X(AU[N_%9,cB8/B%KU<%g`]Q5=n;'!tA:9=oBRZ`P1pMOB]>QAu48AB"-WG/A1t-r^@Betl_:_#imIgm5;1B;YHgnMV?sLWr3SN>3^@Su0bnV.-ohcXq9etqMeiNSflo!l@mqMejpaS6>NjjcE_qr>ti5DGR1r1gM&80NR+KJG2lB:X_J"r%'P<K:9lf6I11a(a2[e;K[(F:^<hmi+-DH[_&AfB;V\BWrj\#eIr/VHU#D<c_.lhj]"0oSol4FZ(hnD)]l*@'"h,fISSKJ@%FZD0>g`jbh!7eW\^9G^+.`9[Ad_Fm=5<h=g-5D^hg)-+3t68:o.bt0MkmNDPi@.>&E$M(k~>endstream
endobj
23 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1744
>>
stream
Gatm<D/\-!&H:Nn0d"Lpf\"gn;H9V?Qh7:NHYGgs01aLE*q6W3Y3WLSOS\!Uei&UL&DVet0]66_1G@'1ZWPSLQW:a)$,FLsb\IS;)obg\*5d?t%:"nMr-W#).im4Y%,IKWT'%!)rlCd]FIP0llXs?9N"`F4^"L',bO<pND@a#jFRB7!,4Hk;0gUq3GQQpo0`FFDqEhB&ecrSADR2f/l&N2bp%7pSFC=mni5G1Kpl#Tj\:X>,O&4OdYN`<<?0Cq=qm#tUC(,i*Qn7?2biea40U3SkPh(cYLN^sHJ9C8HTkP%GJM>0,jnQV?=<_Y`3c-L0OCbsu)]B)mdM_Zkr,Y%^H+)nJjPg4'X/E`!Smre0MhZ?pHPY[IMYHs&a'VNEGa\.grDKR.h=q_+eHT783]-K<Kcfo:JgD\\ElQ)ZjK&Zt#.6)tNMo$IM.$uMmIBY@g3bX(0*fMb*Jm$!VGcqhB$2On)p6q^Z0#r;U03$TSk$SR>]s*Y@D^`[M-q?j9P\f9e7hnZo!mAXaf*o(I4uQ[)Y:$0;GMegMAXZI"h+o8/94kU+/Udq9l;$TR:$[mlDN,e]5c;5iPBL*./5</gKdrHGi_lc_0mT8*+COL.!Q,,mNBJbjU%&C#F'ZJ$"&ci:12?bkh=?R!'oe^h.j.1CsE-!"54\8)YWcfr'8DjZ","d$K<6t[Bh]YV67$:[!1R6`\GEUa*>#FXr"4b]HT.aiLu\8L-E.,6e-dB"4oW?k*JfneEMJ6VJP"^3ktn6$5"joT#-5*OCp->_8YaTd[2V#$!dUkA/o(0_@L;"e8h3(CH:;;N8%(:-uoGTP7+5QT2Zk#=%+Z-#VhGnOS8uMcG6&5`p_(PhB@OeqA!.S_G#obrY0OPLaapPP%Qc!:dpS3(-^B'6_f,[jU[@_&6N3I4qiP-3U&B4BY!K'?=nS'H:CL_UGf12_mol'aE\2J:(.L39QSa=J<p'\+0QmH-g>^#obOu^mZFPneZ(8K&PU3R0b_&[q)Pi"F5:M'Q-0l=R7sP1"B!Gih*u]m[M%d>IF0&q7kWng41C%!=:7O!"\io5)9:&K]G`f&lZYdSG;.KN"^bm&/eAO[Xo_090;72qlL$^FlouqIQD-I)N%f&(-&`40^,AZ+SR]$^]CD_CJ,L)p%&khV\k%@.O@DKMc@:m>h709eq\8N8N,eaOTo?N6<!5PMI*1d>3CGH,P`&+'pTnmk$.kN9-7<XQg"rE2qN.sB,Ee-g;F2uiK_gHHb4I5S+;]])f1HufENR'N;7^+q9b>ZKL>HL87k.()/??WW6W]Dhh/^:tXe;]`',f5cf`Im(gqhnH"oT6+#07A#6BoJJ@c;Pnk5X:ZXf*,N0t2AV-[h3.]g+1u#\Jlr_+^lnS-J9><3%*`D&PD;SS.TgdqU4`YBMqt3?UfnoAU]W1pXP]Y2eq0&cA4Vbu;\!Io7!BE+R&1jp9MslMS&1cO;#R4_(f:^0qqdR4A%"1IW[!-;(O9:m@)Xj.<qo9&*bjf;-W2d4J6e,GnWZL=P2!h;3%@=9a-u8n^7.OMmQUU@la@Le-r,am2ujk>VA4#e8="(G=GFU1`p<nI*uc""pT6d7h[hiMkg2RHWqR++;YX:j(t;R//')p$q;d)khU_Fi<^F,O43`e9Y>W>^pG#5!G!(.9riVQ,%+*Wq)C)qP]]Qct$9TY3US$SjP:ra0N>Y1p7X_[IKA6W;d3QKMaZbCZl5DVGY^GL*b\OT/o:<M&gj45>cB;I/~>endstream
endobj
xref
0 24
0000000000 65535 f
0000000061 00000 n
0000000122 00000 n
0000000229 00000 n
0000000341 00000 n
0000000488 00000 n
0000000635 00000 n
0000000782 00000 n
0000000929 00000 n
0000001044 00000 n
0000001149 00000 n
0000001355 00000 n
0000001597 00000 n
0000001803 00000 n
0000001890 00000 n
0000002206 00000 n
0000002280 00000 n
0000002379 00000 n
0000002497 00000 n
0000002608 00000 n
0000002706 00000 n
0000002781 00000 n
0000003222 00000 n
0000003804 00000 n
trailer
<<
/ID
[<dab4f5eab97be7c79d196b8cb2e530e9><dab4f5eab97be7c79d196b8cb2e530e9>]
% ReportLab generated PDF document -- digest (opensource)
/Info 14 0 R
/Root 13 0 R
/Size 24
>>
startxref
5640
%%EOF

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
%“Œ‹ž ReportLab Generated PDF document (opensource)
1 0 obj
<<
/F1 2 0 R /F2 3 0 R
/F1 2 0 R /F2 3 0 R /F3 15 0 R /F4 16 0 R /F5 17 0 R
>>
endobj
2 0 obj
@@ -17,17 +17,77 @@ endobj
endobj
4 0 obj
<<
/Contents 9 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 8 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 45.68504 762.0394 129.725 773.0394 ] /Subtype /Link /Type /Annot
>>
endobj
5 0 obj
<<
/Contents 10 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 8 0 R /Resources <<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 45.68504 751.0394 115.477 762.0394 ] /Subtype /Link /Type /Annot
>>
endobj
6 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 45.68504 740.0394 112.821 751.0394 ] /Subtype /Link /Type /Annot
>>
endobj
7 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 45.68504 729.0394 176.853 740.0394 ] /Subtype /Link /Type /Annot
>>
endobj
8 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 59.68504 718.6019 100.53 728.6019 ] /Subtype /Link /Type /Annot
>>
endobj
9 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 59.68504 708.6019 122.2125 718.6019 ] /Subtype /Link /Type /Annot
>>
endobj
10 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 59.68504 698.6019 135.1275 708.6019 ] /Subtype /Link /Type /Annot
>>
endobj
11 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 45.68504 688.0394 130.157 699.0394 ] /Subtype /Link /Type /Annot
>>
endobj
12 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 45.68504 677.0394 189.741 688.0394 ] /Subtype /Link /Type /Annot
>>
endobj
13 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 45.68504 666.0394 159.501 677.0394 ] /Subtype /Link /Type /Annot
>>
endobj
14 0 obj
<<
/Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /Fit ] /Rect [ 45.68504 655.0394 98.59704 666.0394 ] /Subtype /Link /Type /Annot
>>
endobj
15 0 obj
<<
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
>>
endobj
16 0 obj
<<
/BaseFont /Symbol /Name /F4 /Subtype /Type1 /Type /Font
>>
endobj
17 0 obj
<<
/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font
>>
endobj
18 0 obj
<<
/Contents 39 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 38 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
@@ -35,59 +95,233 @@ endobj
/Type /Page
>>
endobj
6 0 obj
19 0 obj
<<
/PageMode /UseNone /Pages 8 0 R /Type /Catalog
/Annots [ 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R
14 0 R ] /Contents 40 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 38 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0
/Trans <<
>> /Type /Page
>>
endobj
7 0 obj
20 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174842+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174842+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Grafana vs Others GraphVis Pivot) /Trapped /False
/Contents 41 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 38 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
8 0 obj
21 0 obj
<<
/Count 2 /Kids [ 4 0 R 5 0 R ] /Type /Pages
/Contents 42 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 38 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
9 0 obj
22 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2826
/Contents 43 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 38 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
23 0 obj
<<
/Contents 44 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 38 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
24 0 obj
<<
/Outlines 26 0 R /PageMode /UseNone /Pages 38 0 R /Type /Catalog
>>
endobj
25 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 Graph Visualization Pivot) /Trapped /False
>>
endobj
26 0 obj
<<
/Count 12 /First 27 0 R /Last 37 0 R /Type /Outlines
>>
endobj
27 0 obj
<<
/Dest [ 18 0 R /Fit ] /Next 28 0 R /Parent 26 0 R /Title (Context and constraints)
>>
endobj
28 0 obj
<<
/Dest [ 18 0 R /Fit ] /Next 29 0 R /Parent 26 0 R /Prev 27 0 R /Title (Executive summary)
>>
endobj
29 0 obj
<<
/Dest [ 18 0 R /Fit ] /Next 30 0 R /Parent 26 0 R /Prev 28 0 R /Title (Option comparison)
>>
endobj
30 0 obj
<<
/Count 3 /Dest [ 18 0 R /Fit ] /First 31 0 R /Last 33 0 R /Next 34 0 R /Parent 26 0 R
/Prev 29 0 R /Title (Role-based graph packs \(suggested\))
>>
endobj
31 0 obj
<<
/Dest [ 18 0 R /Fit ] /Next 32 0 R /Parent 30 0 R /Title (User graphs)
>>
endobj
32 0 obj
<<
/Dest [ 18 0 R /Fit ] /Next 33 0 R /Parent 30 0 R /Prev 31 0 R /Title (Slug admin graphs)
>>
endobj
33 0 obj
<<
/Dest [ 18 0 R /Fit ] /Parent 30 0 R /Prev 32 0 R /Title (Platform admin graphs)
>>
endobj
34 0 obj
<<
/Dest [ 18 0 R /Fit ] /Next 35 0 R /Parent 26 0 R /Prev 30 0 R /Title (Estimates \(engineering\))
>>
endobj
35 0 obj
<<
/Dest [ 18 0 R /Fit ] /Next 36 0 R /Parent 26 0 R /Prev 34 0 R /Title (Recommendation under your constraints)
>>
endobj
36 0 obj
<<
/Dest [ 18 0 R /Fit ] /Next 37 0 R /Parent 26 0 R /Prev 35 0 R /Title (Implementation slice \(proposed\))
>>
endobj
37 0 obj
<<
/Dest [ 18 0 R /Fit ] /Parent 26 0 R /Prev 36 0 R /Title (Source linkage)
>>
endobj
38 0 obj
<<
/Count 6 /Kids [ 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R ] /Type /Pages
>>
endobj
39 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 867
>>
stream
Gat=-gK3,h'7]2KR)a:TN[8%2Sl26;rOs$qcoq9A3B`8%,[)2B[@@6ofC)7j0?Mqnj\Qk[O_7.)rJaLd`#k`R&!d3fSm_2Y!28m="(E3-4FMpQVmB`CA@'bT%$OjI"jciNa)Z!D%`sIi;p2G]Yf<j1q-\FW*SU_&q&/`KPo+&A6kL,hY=)3e"LuBh4HF_XIgTU<M8LkV+^?ai__\,1I*#L%J3S`mYt4f1Efn:Z0@i_o!M9:FVr-EARg!R)*IleM[dBsCN_.5CJ_eXXXdqdo!oq-M9'O0%OJMe!I%>YsLNA:7,(>.n$XS&t%O"RiA3#9]PsurG1epK^,8'MjA4a]mVG-Ol=NmN6>QiJ'cdJT$jVbMoqb$\H#1kS+D;PA\>1J@6T>^"T4GW=XL@:<\>i9P?@J1Wq<Bls9A#F1%U&!BGqmh!nF8,6J]G('Dra*>6D;Q*LhK7dHqOcD`@6?/9BBjDY_gn&h>;.0\$pG%?Kq5q&e1jY;+fB;YP=7"9_n#Sf*KY,.n]_.=OtD7:/Dl`EEfq(Q;j4d/-N9d2ls6[o8+XDdigddFqfP)R2bR(`bfmOT,K])8i1Fmp&uCu0n2r+^r>a6SH8/'Zpt%Hj$$Q:3q*WI/D0j>*AY(Ug+)o45f\\"eA6>7;T"^5,\\aO'4t>k4Y*Ne?haIJ#F"1oF/bX(IVlKnpF9:cD*XJa&m?0,dO/d3DYen7\6ElVuZ@r,4n$+Xk`AD"+./UZ"Ztt\PQS<]E5piW`3$=EF(D/!F*.<+"I%K+gI]heY,[^%7rg^%g\/+XJWg]ZeCo^)+_r&5T%%hi(MVe;Zpk$a%?E;)MXQufg7e!?JAs6V?I;Ll#2R[]]_T(#si2S&1o4S\S<>)NI1^LT@$.p"3"C.2p>W&@=2ZuIeL&%!SeY6%2HWTf]M.JX\(#!B9eHX&5<u\`@l<!JqY2R]W(i])dK2jPT*9:kFA6F,r<Ust@.Bam!H$^HB'gP1i3`CkcFb7Fcn[p>3KS6a@dtg@(8+.R4+E@`i%)5h*HS8#2KHfGBNZ4Pp8Z&)0Qt_O%^OOdAV[31_&+D(>"^p.!5n4Et-<K;3#"pMI,+^%C$/tFEDBudBaZ@[7La@1M?m*-_C\Yqd,8F&S3Ns7h`EL>;hDM$rE\('mQA')+T&dZu#"6Q`cQEnl78'93&`6IC8i<"]F=T3JLM$pNR:Qe/(^_Q\mV;Hg,VKbp+bWKk^A%t[K6FB*ojI<m::9o+oY@-8ZdY1q6=o.%7W92Y$a'Y_Q$C@r=,'XdMQua4d??QJQY9-[jb80&+Y1gf@8f)IEX57:P[tFf#rSn+*+<3pZh'G]`g:M@I<GVKZn\@^e$V5HhR8ti_f7D,%Cjm@C?K#]aX$;W`[/EsR*E%OI/ql77BbHrd:n24LE;1<M.sF^[1.+in!:X`PdlM,XDPmX=L?P9A'=@)gS?4e^<_u1G"DuMK4?ab.@_-oJIt"PDK\[W>goo.dlU.<UJ>]XE>IoXNl(lTZ$HQeX0#fs.JQ"R$<`Y%]i_O_'^6\Ylo(9(e_D,qY[1_K%j=Xk+W%f."G=+RUTn(.Li<"2'[4H);!ghWbbIQ'D>JYf>#(Q=O%%_DWSXjZchVCCAGKeBPbSuE.g2]KDCr-[@DrHmj//Jh*`7#/_<#6.Yd(-!SukGs+]#,/33[%D1JSs$VtbQN@]q4$^6)`[NcjND'*YhL)#RQG4G:E>K%FelFrdaN#'aIrf&OpP?upXf9=l]m$OD92?$GJ;UK=0ie%tI[l/FZi7EJd;'q#4+5(Ia8*GR$4+`e5\c=9mN4G0&XOGY3c59*ttpiQ=tW7%38;)/VO+^`-&P.^i"fhTP'1?l*c/bnj;)3T+f.N!c9+QqQ>!`b2Mia*VW@f?_f.aH#=Q5fBo6'4.B*9\?lH6(cnnb3sAB^gWqXcUjP's)W!kpR&MOhsd,0b&>+/B>luYc^\<=4tQn>YDNZhE\uL9>jQ;!`KAK.WPisp.*R\p:B?*X$A(D+At?j@s*qO09(9X.M]44T'_T&;mc=SWO0U"($MVn1eQU)@lL!g7`c5EU:3"nWT@Oj@^WIN5\r,P^oU+Jl:FgGY9qAma%F9Qbor3e#emd)7O>3@eD_mMKuXqA>1@Z;YmXneHF50cSKfAuSI2cJTk@!BP("Bq[L@DZYE8GLO!=WkSEGH.c-a4MIqpLloN:Elm_?ZkAuFd?3,Ohu*c.R+>o5LB;?HmAfJ;4V*eC35?8K'b7V1RS)u<OK8$GbJI&1#l!Oklb.iQ@%p.7SghO&%J7CV!9EB*=XHco4N/_(Bb;qEM:S\Y"q?*5=t`(:dF_H)X%99tt*!&Jr7<bsFcf97;Q,XflB3KELZRDMr)=c9Jf-a'.B@hc6C\lm.?L,biFk>:372:(okLW'2=h1XQHE3.SRNs[PH&:r>[o:NgI&k1OPoh-epLBV<f^=[@NX8fW7'q.huKe>kE6d&rR7jse!';d;j?U^p]QkX#Y`[B`d$]!ANA^7$K[_BJ=JlJ[Qqg3.hUV!GGW45*<r\0#[Vu+_U/M^s[Y3q#_5Ts()<VqZU&V'L_.rn14DP%F3aUr):&,"Q],-GluQP\@go-g"N+umVNN<G`.W:*p)nli6G3_#2>$QGF_Z^-W;;3=!djh2hu)>Xc=n'+fK4^S0'c58rD0+t0@^]8`?3W*kK7mb@`b.g&1;?(pM8N"J"L5t4qR^KmT3<I^WD(J#u"$oYhYliK4(od5=Kj7/sn%D0[C4`k4bpo-,mNsCt\Q[M"-maQP25DZ;-+sttppT.lQ<1b/2E[H?c\:3$\o[*0pg_4t[#RV+3#2^\O1_E$3/%&FljjA\@/Df(SG`h+_:fb~>endstream
Gat=*gMWc?&:Ml+b[\+[?'"LZ*ja[>V,aqWVPm9@7Ar2JWrQ9h;K]a'D,S5^'*8aP(A=7SB?&s>!jrQ)n)ji3CC&P$#fn,n!-5q"]SGt7jNdrn/\*"P(R0PMMGPta(2&C/opI0i+C61inpr4*!fiAW9IqRZh'`OBl[f-EkCPGO!%G8J(/5s2iF87qH"LNqM:Mk.Ak^$H*j&c-afIGKdeo(3PGRclCpW+/KPqE._H!)B.XnVJ+k73^W)X4_JOJ_1?.Bu.45K*%YaM2fiuTgjo.5I)g%9IaF#r3]k?7>ToC`%#l.qg$I-!bZ,d)7_#SW(L?^8Ks#1Bt`[`O\kmDjS&SN<,c/9=&n121eS+P3j-[%-Q`C`#<G6V9ZTh6oYte',Wg`9K1_4GT8qk4R"l6pGV#O;Rb([BT[4OmVda;b>08DT/kqSWrd_m#''Ojmbr0JV6sdk:f+hbDkpD2pnetHU=G*!/K3K38G:P=[!so1T8d>mLI]7PXasL]fEgt+;g9>(ACMW7;XuUe&'Gh`ZD*oF;f%;^"XppW9@"D!PRM60ZrGk[6N6;>E2Ir^"`1C/2dn-4=5UKSd#A6a!X'_MTY58"4jJKh>Npt2`d*l^"'YB5#1toc^j:PCm(@uiTL\5(5$4@4Rl%AYt8<h?G&/l]gq\X/:>X42i19;-pCZ6UlX]2*?b;hs)/S11W>']RrmB;S\;bQqu46(lLW)F0&a&TU<N_mlD>$.L<1#OG@,"nZ'rmB$CX>h7KkA?:h*H4U2#?t+_6Sj/Hi6h?45^LFL>[[#io_Z9b+Z4W+(07G!hHAM*rGd'h]62<"ccZkK"'fr&cbS<?OCmd'oJs'1<u>jn80Gi>Q7-&7G&>WpkU7~>endstream
endobj
10 0 obj
40 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1842
/Filter [ /ASCII85Decode /FlateDecode ] /Length 680
>>
stream
Gatm<bBDVu&Dd46B'I5W7?@WocH;2)Bq(\RNgAP;,U=Vn6Nob9lIU4[MA2mXU;Zd#fK.B0G6W8GQocYQi"%PlP8rM($Bs?Q&/V3"+MR6\oJ:l^?Mo4;eiRSZ40BC0&-e7k4mM'KBQf>;c7]`[FJ'4>Es-Rs8cuZ-L:d(ppb82&;?8:G8BOO*YE[+rip_'3Mn(5qQ_Kj3]m0_/mkB0j6hlO'RkOnYP;n@H"<m/d@69V;;%IIr%\,3S4/?c\'-12KisEO4Hom3V$l8h7%^WX#WINK'JnX$WgVEWhqmh0sNsBYfVmcgG4'N-`0#WKgpD;B_#i/uY].MD>!&6T3,ti\,A<=;E7MA:%OFJp:&hJ["B4B!ElC\eaL)i7)2o`re-<"5Y)&u'=I*_LkGLR5%V8<>AFgpD*O/(Tf_eHqj)tlt64F`T3`X2pLO??BZIlj0p&RKi8`:PT(AZKQ*4X1qC.iNTXAS?aLfHPFi6\%AGL;']=<T`f?klJW$QfeuSmBDL$%3mu4.m>0e,91r/E(1a83/C='_bjt(m=YDFHBob/`=&`V78,bl$SP[2m@,l$(l[t>@g*WfcH+38&*6-7ZG9,qb.NW[j_'5ci`P:*X8WA'I_W*32tSPMh9X-&(H.!![QWcB/qp>7^);RPs5)H*g=biYmFVr%]sVLg<GTDLfe_Qd20`>%?L+&iUe/3WGDjb1lc)ZM[(0C_B$Ui([^EYMXNb*r;Uam$^^p</K0#qqON*j;?OB$ScC#8DQT%oEkGCAACZ%D\G+i@TIk`D)r@M!j$dT^'$M=IW`;=8C7.Pu28]@_;T)lp&1L@`s=_8Y[Xr+Ah':Jjn4i/LJSam,.p:Z]+YjRe!`EY1cfKNDrRhI#(!V&m&h7per\ddgo5\e1]:Wbf_7;B\j\k'Ab<EVsoKLM^_'88LF`cNq3TCcUV\OM'tTUe$3)d2Lj&DB,&nqi#Cgm:j%$IG7ndlQIOlglC((R[f4U>Shm(Jkke.Z=irPVZ.A<\N'1`i_Sm+Sb['1Fr]ZXVu3hiPrq,q'+jD<`H_nF!X7QREZURiLu2#'m6^*E2(;W@V4UASjJ.!/!So''[/[9(>7sn5(FV)K\iCpae.GVqR`juL<=g<Q\,I2@r9GC7+I88*9K,Bk_(/t__ZEmFp1lHc`qlE&_:Pl9!),$[-fu%j;)+.XOcsUeM_5ua68P@$,q:deu>loKg&`6*a":9UcB!BfgZCDj2]oD407:mE@gVLN3cIJQ$QO>Yo=dd=$I2,%Hl8W@)IUJ(M/:W(&TGF9:O>+H7Q(_>nOV[=Rj7W!!C+G0bo(`WefnqBdF/lETu=GB`Qc>4$%6;P2h2Ci"QkIc.u^"s%W%&_9D\7m1:2a0u3P.n=spX_i5ZMmWm3Y^ctM27ZSjXF2!YO-><VJ4eL[ihq\F78;ns[.t#[TldB$+FiEH1h`2@9k+XOg%mM8+>%YepeT-Gp/@P+j;;GX^8"e_7.D0UHeMCiQc/U\>eCq;Tj9iFb4q"c3mqHhjYpE_LqY%&]I[;EY3?gT+VPr:4b[ZjQ.F\+<<&;b[#h1rXFd(N#qlWZTR=@ZilEcrECYGSH?mM:r\ef##CO$8HA'Sl;To*q^r"!2&`=]&[+rc[jhLMJsWtdJVibD,jU+.XAS3Y__+C*+e:BTk\@JtkZ3udfb3sN.Iki']*Ph7tb"jMC_nV"LM5?U$q.b$MT2h^GW8TWj&j8Qm!%tm!@B>IS`5crHji2SZ]X]^p,L.lN$aRhAX-J9:m8NUI/r]7H!)Jg4Zi4P..oG`.hB^P2sBSSbp(uF]DVHHDM00"il]6,cP'^%"[T`B269aO+VLoJ%/@0518"YTcX*h\=]~>endstream
Gatn$d;GF-'Sc)J'^)cm1`%*@_sXh4R3kX4f<W"ZOUDZh!]IAZg:mLo8Y`E4"fW%G+L([UF8-1]U9NTb?Sha)F1>C]^]a3c@#?Anhr$PfrL)W^8=CZe-4pF,3JugTL3_`9MGb'70q^L9&PiGtKObdLX_-O[pkZ`uj@s$D"+u],E06(U>(TmE@C2BT]1^4p6iO6$rs[X25)\:5O8!l-ktiNEkb!1bUBdL9?GLh:e2R]%:$$?m.#ZBOSHRP%NNc2'k]&WurC?1=d@p?4'im>i8'o@^hZ$1DXf:FZHf8KAPniZj>#B)V/2(70<RQ.q/h]^#iU_aW"bMnM-f1JuLPuG<?V]=gc^5tGe&(S=Xo_HY8rm"\fsD)F[I@sARr^Gb2VFO<?8]UC4pk1h8kWl`Y/Z-GnRSqIb-3E8WCntIO\V5d(Jgp7kC"itUJi%YD;&.t,JQ0X[45^#;/8mAgpk>?P'AIG]?lGNYEdt%8rc/8Naa'g*dr?"bYWU&&DWESB+2]$j"%V%*65kh.IJi/rBA#`g\G=XID4FGQ15f-h.hc<::XB*G/g;SKI%c]S1KE/p(]T40QmgIs#6PdYZ(*99E`*B5('9_elX$^H"j[b_saAQ)!fPL(*H@,jpYQ;pE^gVR3?bKh>U>T&p&`Tn4lN+&rb;5a9r&N_#EB0ln:a_etW~>endstream
endobj
41 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 137
>>
stream
Gar'`]*cDO&;9"kTAhNS@cJ`sQ<)AT7bBX2'SI1sre63!8eu#Hi*12+:VXOqE!h>Xcq$8qnjH_CLV:rJP%rsj5>UUDD.`Liah"L%cVntog).//WF]OI2_e/&`/?Tki+CUX9Pb^j~>endstream
endobj
42 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 137
>>
stream
Gar'`]*cDO&;9"kTAhN!`Q!btAh.P+,O??T$:5)Js2%0!'c(Chi*12':B,^cE"9mgcpTunnjM9CKRM'[P%nF[hj8K8<cdi[ag.prcc><c[4u7=;Tm#&O;KE.i_Ac@E&[+g9Rn-*~>endstream
endobj
43 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2979
>>
stream
Gatm>8UK2O&&.4.i0[8T=k'VHP\r;UT!jikmO]5EU2;gB8kMkWmlun;XLP\ig%0;WAC:Sdi!!H&-=GgTUAp9PJ2[k'Iiq!-==f"_L'*?0n:#BMl\[M\*S9c^f6"e=4i9#q+5_;8p#(S?2>h((Y:ILJ8a$c=s!^uM.$Sh"fS0cl'Xb0]f1MFqKhl[dNgB#9/CX0%-N:DZ^u?^mr_hHu4f3a@"MRG31c,ZjG+IY4Hlqfj"p5ea_tL_D&O%pSS%-KtG_+h-?9#1*2$2+0"ub+gC&-W$#1F]g2'Bd/%GM?Yiu9PYg[OO>^Bd^)6M8\qo+..9?KtN(I1+YFo;lK;9;#Dr;4bm-:nEqmK_Njb5ps!%YV-uke7tb45k$=.mYUDMpQA",2j!ThV_mA<j:QdNrHniG]Ndh4in86p$,sKC/W1<mqb.0kn(nm+PV^S%#2/7jWm^.?Z\_`N1YSO8OW2YFPmR-OlR[gYQ5&>Y89dNqSnIZhG[A2oQLKhjgRH*aiEj2B&pZB^TT[9=CE[`7ZPDO&$7]_PYQSL)$RY=LN4>W!KU4aX$U[?NT!6n:1I4I:`g\4j$T-P21ZT!EP)8npcMeEAlTN!o[feIc<^:/:m5aVf&m?o/Ok(n=Ylu<s3"H#XJ$Z('q1aI%dZfXV#\f<IBlr_Ge),a0dH\LnCcHi6reMW0"C=D_1\as)Z#-070c)AjPHDhXbKso7K9Be&/*G'[n;p^SN164<8XD!]Nj5Hu*Ob+`pNp+Q@&Iu<cQ.U,Xrh[6@L6!fXcrh0!$t,<D"mCX(BRd*la^P(,/c`#$qYkO"=B2P3mqQ'(C6ilGI+ADIJ8^iH()#i7e"d!&35a$J#%kmp-J1mmlFtN,NMa%^LKp\5<r5YjI&L0pTL23A]eCYjYTYFBXp6`fGKTAd^.SOM13\WM!>h%o=c:J9.ja864#T`\D#`X0sipXr.7e4B*]JF<Xg6<35'u`Df4HA30nA,FA>o!N"SV#A0KP6cHS]U(0VOZ(7#"SoB`D4j<LNG/C(SdB:+6]]/CLLka?l"L@8<>UZl!;D[V!K*uYp"4I?^";$>(Wn4<5Mfb-9X/N.=O)#?2sp4"u=6AYs(o^#hqo54q"ltt./enV^jo`q%q+n1Nh*)EaYhAd)ADqDE[C-Y,4E+m*E:;.D;EFr`if(;Z)*0$)68XRCS/g$.HD`b\lR%\T@q3ksta4Q9l^%;,V.,Z(hKKfIN:+YXfD:*NVh').a`G*)3cB+\;8UHUa:g$,I,DTN6;NB=-Pk#QpWf/7+]PGaFE[seK^&j`W;.@3um7Z%O]X2rLQWmImr^\8MM5@;$Xij_BdZPuFLD0uP\Vtd,GU!:N=,#do?XnOoh:=Da`KH&e<s:dC]Kj>7ZI@3AL,C\aat?\O.P#eeCAs(n\'q;+F24W>*NZ5+e"[7'lQ4u+`)qY94QrUp[,u`Q.Msm3Ne1GpnZ"#Dh+b.b.9?kP`>DT0_d?EiUAL4ECNWk36.+r$RVnG;b5X[ic?3ru%NC_p"d4tQM6,0W0O<h-*&@6;76o'(7=)6FalIuq$(3:++3g')_ShI;NCah:(E1@.MZ%3l'P"&L;0;X\/??&h41HjUp7";9KU9aVJ^0b6oh^X7CkHYuQuu$fP/:r%::L)_]'[MCOKt6`/cd4=Ns?s/&-)U@1'5XC>QXde^\rS7/F0:3)<n<XitF1D]jUP@2kRd"me6<s*'OR`7rJF#g'-O\]`idu(Q`V.(@\;0+N16H84i(f3_>VPet,mbh*\Yf4&0X7[G3o%b?p=86cX<YUp7u'5`TE")^a"RDlSSrk6b=1MD^^6kYWOuA@5Sq/:'[.l4gJ?n<a8Cdi&Cl#,-@:YJLf-.F>q%%$0bj1X&VB=`jX5`j$7ZR1LmC">#>\=)<!l=`H=+;.WhSlZN!tDVS(-p>);HcKd8E/*so&cbrg^q]E7=[J:JGO(2/Yge2LZ<5;b]FG6cRR[gC3lWe1\mo>%4OeAhL@^0Y+AZ8;S7d=k=@6-BgBS8X_e1O/jR.%EuYmM-C:alp7O`$RMknC>lI5_TSN=aRNeGeo:Be.em?7lCZ.QtsJ'QZMD]NQIR0^6V-/ef`T@08$m(q$i8VHrE`JmpRpY=bi2VK.V._1.&5MP9N)ZhTBtj]Vn%(=*RKS,4!mp41)&5DCPW`VIt2Xo+)Cq_:HG,RMQ);FA*KZQ$DIW1NZF1(BV#(Uk;ARNdg?b.AM/?P[j,`VsJ/>*Ym69Ie+Ug<U1\ilW1kFG$hF)a6&I4i]\"hV:8`&WaqsAbhZRC*-Nj=a,M$8E<[oo]mIAT#R.L>R^A9Jn"IY=$e4E_:2`-5"D/0q/M?Gk/B%+\j.\U<%>Z0?J_6jD&/$Lq>Td;7snL7*LS=[$Q_)/,iQ`+f=K5LI"je7_A2Y-7hsKMNdZqh5C;Bf,.CBbr))QLgbC,^OPo+DYfI3N14ak1q@l3lYtL+7gL/%(H/>K_8R2-pd5q*.#^3[+8lJWUC;ZG\<".-pFtad:8nL.E3AHonaN;8o'-,_H@PDN.-dTJJ0^5$)a)DD$:T)t$km)^>5<e?.fb&;-aYNjh!djs@Tip!*Sme$,9AeEd8_ZIR1>0nu:O?Za&81.+p-c1R&Q@`SkI\(Yo_G%VVOnsU&C%*VS=7/$chM[U"^O7Q4(t@-Jd\HJDpQ'&/sq*:0\-Dk-W&(3X]T'fR1\hDEm6A\onOnV0Xae<m@EJT-uVT!$1=36i+4!^=NK4>%?7I8+/fcm7KsGhIZT:qYrB,.Vbr)RDVsD=>43<0WP&I_C)=*lp(m/^X?g#;l0ogt><Y/?CR1"kdZA#DQ8S;W.+b]X%KF7'gMW,^VE/bY%JF,\mpp#("cQ!Waa$T,kIV%UW$4)pY.s!^2j>\Icb5&aLQqe^OeG9\Q;StK:P+pC=Ln:RamN'UVM"8<]cK[D=cB/"MuDGh2nf^X6#:nPs)V8(21J&e2C5o3PAC%"$'=RX8Cn1=@\r"jMfdj'-3p^Q%gJ!-1]~>endstream
endobj
44 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 972
>>
stream
GatUr>BALP&;B$5/']AR#(m>uUi3&#0@R:&>992@KI&mCD7PfPiSSij"&3LX3-77bK.kZ^B?s_ud&2NHT322"N7!!q^d="C@)HB.nMRJh-U1DZp<I(\`+d^C,"^6+)Oq?&3P%lpZMds8&7Jgop&4W-]jg7Cm+7"qTYghYPd8.T`]r[5fNdlI<A&:uX&gX3cuV1QEm*iEgI4/",sH=DpuMZ+SPg-Y2)8HS:oR(LWg&^rTRLMNb-QSoj"^NY%Jn-9LB0#..MmjDI/eMP69:ksMm\^l[[67,)4ij8=N+M_le6<tamhD&!dlDr>SaVeLTK1O3aL\+r=&n=bF.K^4ALaD2H[&jiMD`9J5]C^9*$D53^r$I,;WCnCYKO;,nG[dYs)@E*b8>]B,G#%"Pt"[k9WXDSM\])^4D_?.$"E"`>QBqN8C5c<CN4*U2KI*$+a@!::[3-H"sP,]lG&CN4sAV2XFlEP\D!+`*q;?,-68YCrO+!gaQOGk)(]Rku:,Rg.F([D6^^>iE51iEgLfAl.?qSW6D#UZQ[#pF)/g*[XlgiKp4#^aLWN4A7OAjWo*i[<*e=DVZ`<K)`Nu9e_Sq>2aUESd]#Q.Riue8f/%dqhs:bSlcduA!)#eI\Zf$CD;Sp=TN:a(l1sk4%sCl\A]^c]eFV4bb=+]!CnE[dHm*?*-54'\^ri2"[ILJRDU`"i3'%#B?o>##AW$%bTE-o,;>EoI4sg_XNLC_7T]]9t.ii<chKmn[4*UdCS0"kM'];VaRlB6NJt"E3:cH%K>:71MBFmBcBqGe-pZ@IsKqNUtfI@<%Bbe=5T<*LY&dlL=VHUg\XjD8<fp`UI-eqTd$K_'LpNr.9q76_B@uj^kS)b[=XcX*&.Wf9Ln%Oe<N]rN$CHL&LBC'_KGdUd,40@"9]:]f.^Yj]SaB0)8n@Ofr^\rEhDuZFl^l8Oi^sXJ3NTu>)ZmP7[kTTq8+.W61*_Sub~>endstream
endobj
xref
0 11
0 45
0000000000 65535 f
0000000061 00000 n
0000000102 00000 n
0000000209 00000 n
0000000321 00000 n
0000000524 00000 n
0000000728 00000 n
0000000796 00000 n
0000001102 00000 n
0000001167 00000 n
0000004084 00000 n
0000000135 00000 n
0000000242 00000 n
0000000354 00000 n
0000000501 00000 n
0000000648 00000 n
0000000795 00000 n
0000000942 00000 n
0000001088 00000 n
0000001236 00000 n
0000001385 00000 n
0000001533 00000 n
0000001681 00000 n
0000001829 00000 n
0000001978 00000 n
0000002094 00000 n
0000002172 00000 n
0000002278 00000 n
0000002484 00000 n
0000002776 00000 n
0000002982 00000 n
0000003188 00000 n
0000003394 00000 n
0000003600 00000 n
0000003687 00000 n
0000004005 00000 n
0000004080 00000 n
0000004185 00000 n
0000004297 00000 n
0000004409 00000 n
0000004579 00000 n
0000004672 00000 n
0000004784 00000 n
0000004887 00000 n
0000005007 00000 n
0000005139 00000 n
0000005267 00000 n
0000005363 00000 n
0000005459 00000 n
0000006417 00000 n
0000007188 00000 n
0000007416 00000 n
0000007644 00000 n
0000010715 00000 n
trailer
<<
/ID
[<bc6184b32d1f12a1bd28db177f8e8b1d><bc6184b32d1f12a1bd28db177f8e8b1d>]
[<1220a3b30f173e67e1de9b17fb8764b7><1220a3b30f173e67e1de9b17fb8764b7>]
% ReportLab generated PDF document -- digest (opensource)
/Info 7 0 R
/Root 6 0 R
/Size 11
/Info 25 0 R
/Root 24 0 R
/Size 45
>>
startxref
6018
11778
%%EOF

View File

@@ -183,7 +183,7 @@ endobj
endobj
30 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174833+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174833+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 production infrastructure) /Trapped /False
>>
endobj
@@ -376,7 +376,7 @@ xref
trailer
<<
/ID
[<62e6c98798332c0d70f94c87e8f28c95><62e6c98798332c0d70f94c87e8f28c95>]
[<3987d7e5e7c49c9d6c3d21b5ad2336d3><3987d7e5e7c49c9d6c3d21b5ad2336d3>]
% ReportLab generated PDF document -- digest (opensource)
/Info 30 0 R

View File

@@ -142,7 +142,7 @@ endobj
endobj
23 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174833+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174833+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Crash console \204 open ingest API \(design\)) /Trapped /False
>>
endobj
@@ -289,7 +289,7 @@ xref
trailer
<<
/ID
[<40b0d4915320fbf245576f9c86c8a968><40b0d4915320fbf245576f9c86c8a968>]
[<107f393aba3f78a44c74cf3a4f0feb42><107f393aba3f78a44c74cf3a4f0feb42>]
% ReportLab generated PDF document -- digest (opensource)
/Info 23 0 R

View File

@@ -152,7 +152,7 @@ endobj
endobj
24 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174833+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174833+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Open tasks \204 dependency graph) /Trapped /False
>>
endobj
@@ -294,7 +294,7 @@ xref
trailer
<<
/ID
[<4cca413c1249fe7757d7ab6f2c356e7a><4cca413c1249fe7757d7ab6f2c356e7a>]
[<08187b5269d829047bd7f5065873f151><08187b5269d829047bd7f5065873f151>]
% ReportLab generated PDF document -- digest (opensource)
/Info 24 0 R

View File

@@ -163,7 +163,7 @@ endobj
endobj
27 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Opus / Speex / stream protection \204 validation checklist \(task 3\)) /Trapped /False
>>
endobj
@@ -333,7 +333,7 @@ xref
trailer
<<
/ID
[<57e4e0aca5ee192ac24df0f4d343b97f><57e4e0aca5ee192ac24df0f4d343b97f>]
[<4b48bb56a60d820ab881edafab813382><4b48bb56a60d820ab881edafab813382>]
% ReportLab generated PDF document -- digest (opensource)
/Info 27 0 R

View File

@@ -142,7 +142,7 @@ endobj
endobj
23 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Over-the-air \(OTA\) updates \204 deployment schema **v0**) /Trapped /False
>>
endobj
@@ -290,7 +290,7 @@ xref
trailer
<<
/ID
[<676f27593046572b8cd4c389e7e4f7aa><676f27593046572b8cd4c389e7e4f7aa>]
[<7ee18bc160ebf9dc1046423de38ba744><7ee18bc160ebf9dc1046423de38ba744>]
% ReportLab generated PDF document -- digest (opensource)
/Info 23 0 R

View File

@@ -127,7 +127,7 @@ endobj
endobj
20 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Pro / OSS split \(cast-core + cast-pro AAR\)) /Trapped /False
>>
endobj
@@ -259,7 +259,7 @@ xref
trailer
<<
/ID
[<bf3391a6afce2847368495673b246a93><bf3391a6afce2847368495673b246a93>]
[<ac2722b644e5539ca34adb5d4cb5cbfe><ac2722b644e5539ca34adb5d4cb5cbfe>]
% ReportLab generated PDF document -- digest (opensource)
/Info 20 0 R

View File

@@ -89,7 +89,8 @@ Click a link to open a guide. Section links jump within the document (GitHub, Cu
| [20100612_1_scaling.md](DRs/20100612_1_scaling.md) | |
| [20260616_rssh_routed_egress.md](DRs/20260616_rssh_routed_egress.md) | RSSH routed egress (postponed). |
| [20260617_codec2_ulbw_voice.md](DRs/20260617_codec2_ulbw_voice.md) | Codec2 ULBW voice-only cast + SFU negotiation hooks. |
| [20260618_repos_reorganizing.md](DRs/20260618_repos_reorganizing.md) | Monolith → Gitea org `ac` full microservice split + migration steps. |
| [20260618_repos_reorganizing.md](DRs/20260618_repos_reorganizing.md) | Monolith → git org `ac` **frozen DR** R1.1 |
| [20260618_repos_reorganizing.md](specs/20260618_repos_reorganizing.md) | **SPEC R1** — repo split, path-per-URI, migration plan (normative) |
---

View File

@@ -153,7 +153,7 @@ endobj
endobj
25 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 documentation index) /Trapped /False
>>
endobj
@@ -253,17 +253,17 @@ GarnQ4`>s,'\rL!2j,Y2Gf7VIg8H)\3`Pd>,m?5I#W;ibrdKEq;-TkXak$(>48Fnu%%uk//)XH<EDN5A
endobj
43 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 3497
/Filter [ /ASCII85Decode /FlateDecode ] /Length 3510
>>
stream
Gb!#^>BAN>&q801kbhA$0$'L/Q+Y4@G1`14!@MN\>c!V&!87^8eHO_)lVERP#t0_i3N:`,@PY;I4l&9mp"(ue5f=1)s#OA7b6;-U'-Iu).j2,?_r;HU`OinBOk1sl78S+qPX3bT6'MR/^5$0FOVE3U!fJX,b$VlmVJ1CB8js$;nD<Xs=9_O+AUYVIJAkm"pl0("_p:W4Wal&s!L_@\7=qI:8Wc9"#-+Wd+D;*&a9;BgkMp?@_M:)^.%r-_M$+uSeSj(fs5_KsqHM8OBnnI6IckWHV7pSa>l1,W?r5T6e^Z98CJoT,Wn=.\=f_!oP.U?[lQ\s>/eK@]q?R_I9*C)T+$lWCM'.rH,=nU_&L=/9Jjer<_*NJL[4^uJlbfWBM4W4)q/qR#Fm)`)V4aY]97HqF#p`Zt0J>rA1<NK)Z:,9+hSK)i=&_<jW`5^E.]T%#T-rBq*PS'9IJc:T*>S9EXas)bXHJGH:T?sfRJGC'btVt;s((N6?l)5>(KjTn,%8*"?uUJ['>M:m>MELokdEe$^ig\57I]gGgW]n^jC74s%#jH7i<'dH'$^sja$A^G*mjcUg?@R)>d(mO*`6k5:?"utjTSH)b\s]=jP!uVKMQd$FT")pNdb*B;&n;p)u(4/,'8P+m5?k=P:5j;lof^j;!@tBFEE%N)7S'jL,GN]-F;*/ABp[4SLaV8cQK,5>+(q?m3lQi#1O)K2h$=KBD\[&@USZPCf);cPc=iE)4fb7gIE%Q+F*H[)"f$Caj,o*eaB*AhUrp9\/<HCf?qs8><#&'f3a5T,G0))H>,^a_S,7hf\3qYltt'SVR$8sfT$WPH%(1&5%Ar+4e[5RU&@l!];B\YID2):`n7l6+&B!hoCDmXRGI6f?I&TRNAcO8hSM&$mNC4<Vp[2_G-d*_76m?1dooUU'LX-;Y^"%(rJY^7Q?cRWE9u6NJi2Jff&2BJ_YpFRYmj(d,b\:sq*R4(^8Ua^GSF_Op\^=Mj?[":Ul2pS)`i)40$b9MM9Bs\aOi_Y#BpA?mb7+7X&T[rCh4u#>`%TB;EL:XbpUNoB"#,!0]*"A%(F4mL][H83#h"-pCOYkNh]V/i$aVN`_i_CEF5i[HfK:VpsZfA,L-%32#5SDc<T%*PU<:VD0uNLDf"<>SF=7!WoX,.Z7k5_c>.od.)(`RSfQt]3MO,Ik.*[V%Ou20Most&5J"Np*1G_ZrbQ1aHQ>ZD^7u!%>a#H'CS$M5$_mrfM<f.CS\U9f,U5sjo7E;Y"3I2n%iS3_@rjOJ)7PULl_*3om?ndW=P.!80qsiEN8Ob,`Y@E?^%SHn7eG9]AiMT.8C#HDA@=1)c)bZ``UF!0AK)m#Y+ZkQ+Ml^_9?rrK4![ac2TF6R<i8N`[:W)kUP3i=48IIO/?OpTrNPoH6X4dR`d.&(09T[fd5IgrVe##n:*0#[F+!Q*_hT9c<0,]E,4R"9=7.krE+40te@X-t8o$V31Gc1n08?lqX<?@BB=!](lo'2LZ?GY"LmtrX^"sp\jBr@pZA=.^9k^_Hho9g)\.MN=>;Wh;=Lg;G)1B&e29Vg:3hM/C13$2m&7Yls%-$@ng`RjI!F2+>jH\b,*iPg!_k6l;R$SDViR7)/%^R!-%j-oD-UJMa<n.a([3f1CWVOM"IacLqmJA!&9-/YQ@IciM(h-5nH4Yk7]k2dCNWsB'&n6$-SSIaeCQ=UI[kQs:k8$hdl)/-*G0mR*(jS4>*qA%'PHOAeA.osQ@E_%h,3p@HCs?uIe,-[5T:4nlXfof*Y)GeJWmO8g/r;4C43!j([-t2qGr^C$J'>3tDc60l[An$`Zt<=*jr52hWFm3XmJG*0c[H1`)"qDL$U!<PiM=HG3PJ]KE%NDtB\!C9]nQmKo[^*U3h'6+d4G=+n(kfre9:tip_T%k*s2_G%SJe-NIgQa9[RafF?QFRlRLB5er43QN[G4`158oVc)oB<g5J,$=7j`HfhGq29@sns[lY*JBfui'>*GA[5qQ/DHZcg#T01$\Fp(\%`XIjL[_6']o3Ib6gZ6qEBf7]K`l>BJ.IDI(@8PB%,qGQSjFHJA9"%BGQ)<lZ>`r-Y/.@[@4pBp>lA_RIK34(eT?Y@1C1Cu`/M9rT36KF,*o(/iCc"#0D.f'(pL.RV/%32+QIO9m[bC35Qe&(8n]2Ueo0l"Rf6XH-d=\J-o-83c?pE<f_l=>$_ZBC>`X*r'H/"B>Ml@+p>O>dq?a.ls:TPLF3k&GiNMM<>SL_lOJ)J)Vh?c6nA;.h`p[%%5TYOKGT"7')A+6?#o2HtV$cLK>imEBKO.>HjT>r"2YZZd\;A*EE&.r(Y@5A_i"4\V.D\aO&/W$]7Lbu(V_Iarh97uEP66p=m&N1#Z,aUpO/4?l+<o,Aq@`]S%R>^h@k)kHY$^"cd#&b8$[H%eR/4<+P)n]=0jH;HHZOf\SDt%?^+sh0sAg%d[hVcX`1ak@oE:AQ^EeS]+KN`DLHLQPbEeAE%JlHcBF>P5b'B7(8AI%;i;`_u8'R)mkaQN0Nampsb9?:WdBH#8.MsuK,<+-o?QV4o[b?J;^5jIXE/([AA:]5\L8L=[2Fk85EV+7GC10;M[e+S4im(mE5/4DuO@V-aKA0mp^7=8#NF&^dA.5p&q\t@eFTqaRr8l$)(8/qQ<;%s<enbH;n_Y)#7&?l"oWMe7Ek5;0Q:T-^`aK\[`rsSG\3Ol'6RY0n$q0to:5rE=I&jE7+Q0"D=<'cj]p&"od>Wg@G[]\'W'$-(IlX>]LHDIME\)+iK;SoQFDk#87f%]ppb'1e\KZq##;/_'MaXs0XK?QfMB1L$ZhtPG`B)@2OV]`=Z\h[fn:q8][nGJLnM)RSR]O["ui]?;"gMGQo=uA.F02Xf?UEZ9^r%:FuCDimN@2*R[0M#Z][+IFXP3NjKWO)Eu'4ctC;hXT$M.[Y"XDYMQj0]&b=\c23%^cr<n]BJiQm.#WNB0c+_#<Z^2b<W6"5eGspV>_]oV.)dej8Y7q[o;?pg/@og<j<a$5kl>s'hS/IJ9A2du(Tq+61-I4?)-(4)RU`-32)0H9Pn%Vajji`:IC&3an,6RqrW*GPlG$jqhIYmS,o(B+8M>SP%I04SLaLpc"O6Y@BXe5U[?N"W>BaIR/f;BG*JS:l)7g&%!T)QS88-bB;**fRjg%S5Z.lE)@"jF"ILn_m,XB^UP#t@H+*7;>@SA[X[$sYH/+2Wk,0\acU0[i3QQ^o;0NXi!Y0N)WZ[+=UM_u0.tN/+KmbS92FRZ+s3bbTp&g%%j)^K:st@ddqOI_f.4.X*o2UmY<ZX9.g1i$8%"u^?ZnPq%>l7+m)AlR,o[B@o@XY6"scf2")9iY?8#0OpL/5R^oschCX`SO5'[K`e+2;P_?1%.W=+aS)e=Dr^(m;"\J:e#pFNic.HFP?ReT\uE#2Q;K%ck=2T[b-[][ZF(qDrH#`OtLq^1?$PiHbkN,>GRA&Fl-K.90N$.2^3rB:eSe4.C3=/LA@>epS9FMqUf#RWl)j9'\2@!L1a*dIEDKPUJ>~>endstream
Gb"/)>BAN>&q801kbhA)0$'L/4`<*A*Hk/mJ<R<>Y#<AN!,[D-l@SF%oqt:]JZo`LP-$dCl4atsTr#KKFFQG0"@W0Lm'"#&\=1:r%08e(3X6i:1/./PRXY%t"5,je.tXcOU(!Kf$)1tOp`>Ug78iV!"K!]BPeVTk6aQ;FUP]U7i55,7R"]Fh@R1WVK^#*_rImnTa3S(TW[!"fJ5#3Y+@4MVUduV!L+6q!#b"'hR3:At!PTm0>X_#QKW<BF&k!/j^E?>Off^SEml_n+$tVEthRu@Co:43JbrJ_?36R`TC)bHeFIofg[c&cQk;c1U)p\)'"KC$#K#BVj6)(iF+ApHTO=4ri8EB@S,Z:*;&op0f6u3N&j*Uj72Xs_lLJMUt4fQHlCDFJHct0bRJsN6:qBjT^+N\)ao6-P.S7O-FZ3:Jc1UssOB%<):PtG"P7C<m%8\/(cdH_D5_tSHDW3D%l2+3TpO]99kUl*YC>@4N&`3LbSch9C,f4"%@YoW!G$*.2<K:>LU#2L/$3Pc+k[gEcQNpEu1L<#3j\!O&8jkTGFR%sZ@7jsT7:9&n,&@nVBZnB$H];U\OG?<`:b3_6(ZL#m8n@>.dbsbiA)U-+_fnj<IY^g*.%gt$c+t)oti"@n6=#g2*l+ed.PO?lPYfDfi%M23)#O&UA2u7@EUN(cCmSE`2Un67$JT'We4*[KbdE01\',G"A]eK#?='5>pO9mBN]0N\kJNQi1)SukC,tM*5/F#Lq*3^jZ5jjiDP:Wcj6$9lK40ENW=Q?U`Si*cmMV;AjO.9B;Bd*/lJs\tGcXj>$efEC&^,O5I!Q9hYUhKA\joKnM2BI37pFINOoo/:,db=E:FDR?Iqta_TZELC2LYI,u2j\bF"q3?B(boY,ZZNU0Gg5#9]2[M0/g;&3X_1C=6![>!M($44)&N#TVCORZKf'(d8K9s"!7#<gT%Oc>oK,1E@;+IRnk1]ebZ+"fC6s_];&21TpKSm]9jNo6p3LUi_)tqnF+t?pfAqam^KCg09o-JOcjf10%a<S\8c>G?Ro;mqAX5IsR_RI\Xgs,,15ljU1VZ0p3o@bZ1AADA3Lf2OZt^<s`3I`M.Q'-PX*t"UhY!drf_9'T24=)l?g?=T'6Z-(PN+32IK^K<S\SeVn%a>ujPjPBQh^sNFYL]a^54R-]?K%!N:*g9mffdRW2'nU.OW8lrnTHoU!_]cO*]qHQ[us?4.=O622MW`_5m*FC3JMaomCYT)[:;<?t@:.Ie[)X+>FepT\aWAYf=AjGur2%()!e'LABes7GWZ]?rh;[0jI'&*'k2i(4LDILu'!&oYr3Zag!]ANi1I<SlO%3QpDS%Y/1m:CZNE,823$JN+8aX)SspeK/!gIeRanWN=jWVIqmlr%DUFL903B?hCQ@@#aaA1E?)X17Ih31XYT*^%$iO)kcoZO,Y&A.IdGuZopHJ'-=2GKgj?j_S3$WbH<7[KBoH\Ba6&BW`O%S/*@=FtCc2?\olB*3p=e8S8NkZ_QeOlp*3LCt(A$U/)`_seE,aXE?Hc(.$I,\0<c/=TqHn-[okJ1Kk+a>pV/D"p''t,[6+hYu>>3.I#WL<eo#foAO&T!"iQluYXNR!&iQCH$)QO]!NrUsV:4tT5cDsloe/39:8(JIqnP)0e2!<c>Q96L/L;atj@#-hUkWfc+c@Q(/EAVXVdKln[k>n'B)Io;]]W!peI:D5I++:;)Ad^V7L66]>mkM"/]]]RfCHfQh57CYI:#ri!-T4FS_pQB?Sr>5dhtC,>*7s>[0%=PZCn8S4P;Qi'R'[s<8%WpE>Q0<;;r=>#*bn^.C,AC[=QXB:equ75m0!I]_095'1kCY=_$2R^ju@'pFq3r<;d>7F':Q=^Cp0PL2SCiF)3'E[C"B?"c+1GgNOj"`&H<BKs'rhE`F0/;HO91iSIsQb=.YJWE)C28g)/4rXheskfk(cL\V],aN9XiLk(:<m&\Cc.BEfCWhJ2H<,X%1iQ,[4/Cf&#Lf3I+%(Si_2]B_hSH3ls6nng$^4+(,,au6db@N#d%l[_'rAP.%3I1/a!V<#mBKGZDt7*0Y0Yg`4GO&N?eP=6)Chrc]i?G1@.</G>(pU`;RfM,%V+iQf>S&Dp^U]\(C3sSJS'$"9ikC#<ln;cn>Pbi##>uTtuP:QP%oq66tbfR4=KPN\Mo'!p_V=b/)0Q<VSLgaAAQD"B9KQ086<Se$kNaaKUfMq_!d2-UU#=JC>*)5ee^6)C$[W>k;kr8P7k6F;NR]I&[rZ9sG&/9@Ac;RgA@gkQn@?Qbk6\8G:=Zgrui/n\3pj)3L$&8\@.O>];$PK-Z&e9+2I\;!PikpADX!JAg$^)j%82r.kC.W\7/4d'I,2oaK8TKZ@_h(9LDWScf,aQ*ZLH?,5^cWb0@6r=7hVc;'UmA[0LBU6uH%QV8P$IP^*u6-$j:+:(8>P;U4tK66aW#W;,8he?(jfV'-!+c,:T,R0W-^`W,r[6!01[B:8-^rF4<Y1s:j0Y"IS,TI6#e7dKACph5?`NTFU=HQJu0,s^Bi^ZTF-EqRP*jqNo'9:"[Z;BRsT$RIa6i[OCYX5FRH`ZJ*G?pXif2bjKpr9+$DT#?DXSk7'$g8QL$I!m?hf!@uZ?a'ug#264`*<-tF#>7G1662JKk6)b%"c(LLL%0NoI`"7aYYOa74kcC>uaoEhp^*P5($q#A1AGq.WL=&#I$B`@Y*AQ1$/8\t__]X'`jJ1BcGXIal+P`#bbVQK0#^BF*P`Udf%MT14C1O8<d=&aWDSupP-\'22'H2hQLD;K[?:nDMVY+0.2r&QoE-2_F"9pQfUrH*VhjWa&%HZT"3>]i5IhP.JQW9Tjod\a##p-,Js`UVB:_DG[WRk5iN_u?>fIQX$GL0P;NK$`>d>-5\mS_<"=hFVYQdqgt50pgUns7C,G6EI6f;!Zu]jM8[heMkS1FMknDbr3l*fBdZN^_UA<jdR+10`57jA_lp##LVppTi^b;U&ue4riTP*)oIt-(kfVi/=W2./A)*^[GsV+a*i##Lp,.lO4ud>0os2d=TI(6j+kZC+?p\0r0TEWdq_l"cl80mS\TBhG?m;`Xf*j:l$XEC40\8kq/*G(RM@HR+H0@r"2@D#Nfs&9fZB_j&qCkM],(F1Xf6<;1Spfm.#@Fh@Q95^:6XmU'M(&a4O=Z#?+of=6dInU+nn<6rKIj6UQ/6.^6<$q*tH9^q;o+GM,H:Eo#%s9o0)X_E[=/I;UoV$`"FoYJBrR*K,5a3JS,RhBs9[Lbnn9WFa7O5LS_s-B6N9k$fI/i)EMS*IWlMHCImOhca;-ikR'tckeWgRh)1C$]n0'R4!O^'s7.D=>Ub,8[1RWG<Ok:5(?Id1;90<Z5.^mLE$B-PWap=6eksMl".tpYWB<B58DIF`1Uuqi?=`2MK0(*M\oQfmKjNs)Ktb1Bb'cfhGHIX#%or;LLTQ0>5D[Ai>'W;i'808q7:7/WO1_6STZMk#.NEs,_1!^J'B'_o+"4'YRQtsggf+k"6M*t'$O(sUQK5i:rr@GT2&$~>endstream
endobj
44 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1487
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1496
>>
stream
Gatn&D/\Dn&BE]&;iJ)p'78>c395pEk<dmsV'Si&pK":.V29b.+jSf=\%PReP8$p'9@\,E+UH_\kEgJhHQ]!AMq"B`$K*ammMQ%75VrRPC*l>Yn=l[r7qAsSZo$OFF;#YGeZ<*7`;=LWYG]A;#^=oR`E`nsJnS0Ql.0)(e\E"_\&<9:Nr9?cXYRCD$jUBrZ%!W:70YN>(FOSgKA4\R@6/L5/eX6p0A5a5NtD7!d2s+R288dH3Nf7Z%qKZ>Tq<::0tdY1PPYg<78fG4:aTr)$HY&IOEO0:E1]CO>?UEd):5PkB!CBOc=rHu1\;#XPV#RsqOqmH">mcI"4*SBOV]hq84=^=YV)8)a]`ZUoL#B-n\(ujqP/cf0BPqX^nFI:VDV%)cmfBuJ#I.WdGV>IKlJf?_b98RA1GV:.1(L@H*18tJjo,MlCRTtT$]&,5KK4m"VWY_MkjT?j>&@Z#HeuTH<<KspbnPrh_"3.5[06QloA3a1.+!:h:<%ZTc5Wj]f<rX.KqK99U7H"ld[HsNt%^h/$?,Ie!*G7M/9sK2!Dbuc.i'mksF,mfldlYIp''VFq(#+\kP`NMq;DUb68]>'hgI>dpNU/."o;nfYVuDe2Aama#Pt*LV^T2LI's5ad3Mh!u0>g^9+ZSEaHgfjAp2KU9kLi?gqm&W`nghStWo'(c2bhPelGOdL-7(3c5q$A.lI-U4*IMj'VoXK1Sc$Z`'T?!.SM$/b:m>8Ih&GBm:P'$nk-@J;-q=;2q4fE:QE%8kiKnkQ_J!]nrqjF?GGp`n,IlH=8e%>W#4I#$A-$MNk5FTjDKMgON?)?mU%IX\-io'A%ME`9ZO@5Oej%;q@$?l5>tL:VT.XK/^6sEt9o%M*DGZ<$(M3p]g[VUsZ=I-fnNT_ih:ni#*T3$^TX&F4hb`/D&Akh/k-Rr<k0O=n&0\$)rFa@pAi\n(l(6GnnRccBV@R1:;Ys\XLpug?0j^FZ7^96G6#gA.$;i.m.Vn;oa.!^*,.[Mi<Kg/JnoZ[HDs"f80^,X0^`pf2[&00)>DW7C_8P>OS.l;c)<$q;ggYIl"OdWWP%0.]jCIcdG4]2Yq5%kL\O%BQ-.mij81991++TYSJ#tek=R\XY&Acn^oqJpG@[=H%/__`;(r[5JcT+1`jY(cQ>rs,15qP<p[>Ej)GK$V:sZ7@J9(qpL1j0%Kc5AkdbmPKp<lUSep$,U;4'8k'L:XdE/G#B\K7bnBNf%9TTD7fMk3p)753uC"f#fhq6[@&@/\./7=k^pCc&?<Lr^"qQ;n^$d$AE<0'\,IS$gPW(Jm!U^!=Zc0A0-!PsY(<IK?o1`nooXI/G%97C'N0dfg/ejTr]0N!\8*r*tr%'+E6.)dr+&]lQf6+6$/-g">D<-Ld%nkgu`dDQ!l+to5JcE"r9;=#RgWB=$?e]PoSM"^Dl)Q(-Wbn&&R$#sd+H$s.:*k\]0Rm6U.UfPghM!MQY=IM[7>>o`^oV;?e"s!RHrh&0D~>endstream
GatUt@;hW+&;Iso=,^,7amCCA`>ER/&Xt%HSX9CPY>V/2J[NbAB'J_EfA*REJ_25B*H`=E9!FY9H2Pt3b9R3aI$*Q8[K\]_TR0:]=HLaXfS0jW"G5^j[s)Ape*\08f/IPc4^selJW8:?BtTP7p[X8,,\nN/I<G;6JjI((DpFgp(=;SQeM;icbi-_E!6IHeI&t4jiG2dKa#3^1W81aNa$a>$0kcR82=tLo0S.LYEF&&]iONm.F1AJ+(Zp=Ss&]qA(5qaNcf]8r\ZouF&PQfL@Q,AcaSP<\&`-8Pj/N'h`LHXh+F/:BANEVfl2dna/[^[d]sm1d,gG`oWe(hZ7OU#O1bZbfO3_MSK[V=UU/lh=UiHd2C;nY,K>SZKRY>Gm>Z*d+[ff.1?r@"XD6kp3@-Rod/3!b#:hc*_n8j]01n+99$U8IL<.R&-')mKh6EsLB`UaS)k:H1"rC`d>9?PeJ#tYpWXd8^8UfDE\<=@D095#(uaP>s<]bbA&d=OLrCI;^%Q=DtQKf*rm6ubJ%XJ\\[MT^)fWSFT,WH`+P"C#r$SY'Ieb&(`8G&KVVXr?0BT8s4a/'H5Sm4TuUaf]1fdrYkh4h;4U.[OBg<\i'Cc_:`QWt:'&E!IK'M0;biSO8<U'`BrV-u*mjI!*bU5]\O9gBRPUi2+pImofMq7E<nE_=LBu)S==?Nd>ID,R7PrE-cL97)Q8oBn]-"$!eDFTa$$mY^qJTPktBCWM0lQT<[HXKgp.W#7'#'/3]cjUPgiIqJjr(e12pLSig&TFqY<#mpMp[YNaT]T8\u;oEq5"5obr`QS"DN%BNg3A]E<&<%kpM"403`#p*<OFu/.+VG8_S=l''Mms1&#Q?:cLJ_B,F$T)Mc64H-Ai7=NTZ^@KY"Fnm9e8aOscNTh>)qg3$`kFfJ"ct<=G./rs:7XC.__l;?7bb\O8(nD*R\,Z[fWo\6?[r&`c<SlP]]EBiKhj$)(ucH7)f)'@k3FeuF+o(0U</XWI963JO\?eS!U#33">4^A5%u^<c>2>3f<n?^(gik(:U@4@8)]=Y*mfR5%ScT`.F(W[AXuVgkmb(:gKSf.c:.,cJer]u8u:Rop:tscCmG*7j+O"!VI*Nl>CjJt"L2)a%C`dZr\MNB1ORN!,aESooolnQ(YL/qR>iR=3XWaGoICOpm2<m'oEUF%?n*rh^4b6j]7pou3!cU,nBZ^0,d)j&GZ!IjL^)&0_HTLU29Dn9B\R.2iA]N\,"3.B_4_d1ktib&<o<E?#Q&WS`%7r:$Wn/*SV2u5oqZuL\a9kc6?7&se\d9</nnVoeV2"s1go(PH*`Ak+BY&7lh<'$k5G1D*Rjt4b>3Jni?\99VUTPc)kCZ?^`T7XfTkc%.@,ag87*eVZ7?HU+!.>QAh*(F%r050*r]FqMFu"YU)qNV`K##2a^`:GUO)]dBJ0n11G*rT+,4PEi]?T"prLs6nU]Y8s+g*&[,5p6ijg+<QMZ>[%<]]W*M"9+i8+F`0DQg~>endstream
endobj
xref
0 45
@@ -311,11 +311,11 @@ xref
0000007001 00000 n
0000007229 00000 n
0000007642 00000 n
0000011231 00000 n
0000011244 00000 n
trailer
<<
/ID
[<4606f0426670fb09488d895e0a695b1c><4606f0426670fb09488d895e0a695b1c>]
[<92c26b5f54e3746e1385e7de7d418327><92c26b5f54e3746e1385e7de7d418327>]
% ReportLab generated PDF document -- digest (opensource)
/Info 25 0 R
@@ -323,5 +323,5 @@ trailer
/Size 45
>>
startxref
12810
12832
%%EOF

View File

@@ -183,7 +183,7 @@ endobj
endobj
30 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Remote access \204 implementation notes \(v1 WireGuard\)) /Trapped /False
>>
endobj
@@ -383,7 +383,7 @@ xref
trailer
<<
/ID
[<d904f4741c13412ecfac86be95b5e1e2><d904f4741c13412ecfac86be95b5e1e2>]
[<2e5e258f86156f4a4896ff7a73d11ff3><2e5e258f86156f4a4896ff7a73d11ff3>]
% ReportLab generated PDF document -- digest (opensource)
/Info 30 0 R

View File

@@ -137,7 +137,7 @@ endobj
endobj
22 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Remote access \204 validation \(Linux CLI + mobile parity\)) /Trapped /False
>>
endobj
@@ -277,7 +277,7 @@ xref
trailer
<<
/ID
[<edb858d19a7dc7c6b966c01613958242><edb858d19a7dc7c6b966c01613958242>]
[<273a5779660ef1c3a1fa0fe8ac555dc5><273a5779660ef1c3a1fa0fe8ac555dc5>]
% ReportLab generated PDF document -- digest (opensource)
/Info 22 0 R

View File

@@ -198,7 +198,7 @@ endobj
endobj
32 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Android Cast \204 implementation roadmap) /Trapped /False
>>
endobj
@@ -407,7 +407,7 @@ xref
trailer
<<
/ID
[<8f27e090a4e0d9efbfb958e71fb6f0a8><8f27e090a4e0d9efbfb958e71fb6f0a8>]
[<64cfdfbd492de96b1f420ef3af29dc90><64cfdfbd492de96b1f420ef3af29dc90>]
% ReportLab generated PDF document -- digest (opensource)
/Info 32 0 R

View File

@@ -132,7 +132,7 @@ endobj
endobj
21 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Tickets, Gitea, and alpha smoke delegation) /Trapped /False
>>
endobj
@@ -266,7 +266,7 @@ xref
trailer
<<
/ID
[<933f0253ea9da04f7117c56c29f33651><933f0253ea9da04f7117c56c29f33651>]
[<b7da7c1b75a9d967c8f3f16fe99a3c06><b7da7c1b75a9d967c8f3f16fe99a3c06>]
% ReportLab generated PDF document -- digest (opensource)
/Info 21 0 R

View File

@@ -112,7 +112,7 @@ endobj
endobj
18 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (USB-C / HDMI and USB-tether cast \(roadmap D & E\)) /Trapped /False
>>
endobj
@@ -216,7 +216,7 @@ xref
trailer
<<
/ID
[<04785d34764bfbca56a9a6cb6c28e5e7><04785d34764bfbca56a9a6cb6c28e5e7>]
[<9cd4cb0630e7ead9ac0a5ad348fb7971><9cd4cb0630e7ead9ac0a5ad348fb7971>]
% ReportLab generated PDF document -- digest (opensource)
/Info 18 0 R

View File

@@ -102,7 +102,7 @@ endobj
endobj
16 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (VPN / Remote Access demo \204 gap report \(2026-06-13\)) /Trapped /False
>>
endobj
@@ -204,7 +204,7 @@ xref
trailer
<<
/ID
[<0d0dcfb02c2ef4688845f129827f2125><0d0dcfb02c2ef4688845f129827f2125>]
[<6ac300ed6bdcf096c05d1a9c2cf22e1c><6ac300ed6bdcf096c05d1a9c2cf22e1c>]
% ReportLab generated PDF document -- digest (opensource)
/Info 16 0 R

View File

@@ -30,6 +30,8 @@ SUBTITLE_BY_REL = {
"DRs/20100611_3_url_shortener.md": "URL shortener service — design review",
"specs/20100612_1_scaling.md": "Platform scaling — SPEC (clusters, bandwidth, GEO, cloud path)",
"DRs/20100612_1_scaling.md": "Platform scaling — DR (architecture, bandwidth, GEO policy, task graph)",
"DRs/20260618_repos_reorganizing.md": "Repository & microservice split — frozen DR R1.1",
"specs/20260618_repos_reorganizing.md": "Repository & microservice split — SPEC R1 (normative)",
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

@@ -32,7 +32,7 @@ A. Current codebase map (monolith → draft names)
| ac-ms-vcs (gitea) | `examples/crash_reporter/backend/scripts/gitea/` | **Ops scripts only** — Gitea is external service on BE, not app source |
| ac-ms-tracker / analytics | `Ticket*`, `Graph*` repos in crash_reporter | Same DB + session — **logical modules**, not separate services today |
| SFU stub | `examples/sfu/`, `api/sfu_health.php` | Post-alpha; stay in console until F1 SPEC |
| Experimental | `examples/gentoo-portage-experimental/` (nested `.git`) | **Exclude** from meta umbrella or own repo — do not submodule into product meta |
| Experimental / lab | Nested `.git` under `examples/` (not `third-party/` or `backend/url-shortener`) | **Out of scope** — omit from migration docs and manifests |
| third-party codecs | `third-party/libvpx|opus|speex|wireguard-android` | Stay **submodules of ac-mobile** (upstream URLs unchanged); Gitea mirrors per existing migrate script |
[AI comment]: **Correction for draft “how” section:** `be-console` is **not** `./examples/build_console` — that is **builder**. Primary operator console is **`examples/crash_reporter/backend`** (crashes + tickets + graphs + RBAC + remote access APIs). Builder is separate product surface under `/build/`.

View File

@@ -305,7 +305,7 @@ endobj
endobj
51 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (URL shortener service \204 specification) /Trapped /False
>>
endobj
@@ -647,7 +647,7 @@ xref
trailer
<<
/ID
[<70460d5cbd1dab2ea3f548e883e3e39b><70460d5cbd1dab2ea3f548e883e3e39b>]
[<d16e01c48b634c03f8ff4cf540cab7ad><d16e01c48b634c03f8ff4cf540cab7ad>]
% ReportLab generated PDF document -- digest (opensource)
/Info 51 0 R

View File

@@ -425,7 +425,7 @@ endobj
endobj
67 0 obj
<<
/Author (Android Cast project) /CreationDate (D:20260618174834+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260618174834+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Author (Android Cast project) /CreationDate (D:20260623103625+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260623103625+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (Platform scaling and multi-environment architecture \204 specification) /Trapped /False
>>
endobj
@@ -862,7 +862,7 @@ xref
trailer
<<
/ID
[<09178fbdf1e2842e537b65a31d547b84><09178fbdf1e2842e537b65a31d547b84>]
[<f609b527db1b307c43f0903cc372abaa><f609b527db1b307c43f0903cc372abaa>]
% ReportLab generated PDF document -- digest (opensource)
/Info 67 0 R

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long