Make AMPB a bundled browser runtime

This commit is contained in:
jwinterm
2026-07-07 17:05:58 -04:00
parent 8a96957f62
commit e059b134b3
16 changed files with 141 additions and 69 deletions
+4 -3
View File
@@ -6,9 +6,9 @@ Adaptive Multi-Protocol Browser, or AMPB, is a transport-aware browser shell. It
URLs to the right network, adopts transports that are already healthy, and manages missing
transports when configured to do so.
AMPB is Firefox-first for normal web browsing. The initial product should control a
hardened Firefox runtime, transport-specific profiles, and AMPB-owned transport setup
before graduating into a deeper Firefox or Tor Browser fork.
AMPB should ship its own browser runtime. Desktop targets a bundled Firefox/Gecko-lineage
app, Android targets bundled GeckoView/Fenix/Tor Browser Android-lineage code, and iOS
uses an AMPB-owned shell with platform browser-engine constraints.
The first fixture is Wownero across clearnet, Tor, I2P, Gemini, and Reticulum-oriented
targets generated by AMPG. Interactive fixtures include `ai-gen-bot` and the Medusa
@@ -52,6 +52,7 @@ python3 -m unittest discover -s tests
## Documentation
- [Architecture](docs/architecture.md)
- [Browser builds](docs/browser-builds.md)
- [Candidate transports](docs/candidate-transports.md)
- [Configuration](docs/configuration.md)
- [Fixture manifests](docs/fixture-manifests.md)
+2 -2
View File
@@ -23,7 +23,7 @@ class ConfigError(ValueError):
@dataclass(frozen=True)
class AppConfig:
state_dir: str = ".ampb"
default_engine: str = "hardened-firefox"
default_engine: str = "ampb-gecko"
isolate_by_transport: bool = True
transport_modes: dict[str, str] | None = None
@@ -68,7 +68,7 @@ def _parse_config(data: dict[str, Any], path: Path) -> AppConfig:
transports = _table(data, "transports", path)
state_dir = _string(browser, "state_dir", ".ampb", path)
default_engine = _string(browser, "default_engine", "hardened-firefox", path)
default_engine = _string(browser, "default_engine", "ampb-gecko", path)
isolate_by_transport = _bool(profiles, "isolate_by_transport", True, path)
transport_modes = _transport_modes(transports, path)
+24 -24
View File
@@ -80,31 +80,40 @@ TRANSPORT_DEFINITIONS = (
BROWSER_BACKENDS = (
BrowserBackend(
"hardened-firefox",
"primary web runtime",
"ampb-gecko-desktop",
"primary desktop runtime",
"planned",
"desktop, android",
"managed profile, policy, and native transport launcher",
"strong baseline; track Firefox ESR and Tor Browser hardening choices",
"Default AMPB web runtime before a full browser fork.",
"desktop",
"bundled Firefox/Gecko-lineage app with AMPB-owned profiles and transports",
"no system browser dependency; track Firefox ESR, Tor Browser, and Mullvad hardening choices",
"Default desktop runtime; users should not need Firefox installed.",
),
BrowserBackend(
"tor-browser-compatible",
"tor-hardened target",
"ampb-geckoview-android",
"primary android runtime",
"planned",
"desktop, android",
"adopt, launch, or fork after transport contracts are stable",
"highest Tor web target; do not claim equivalence until Tor Browser patches are tracked",
"Path toward real Tor Browser-grade behavior for .onion browsing.",
"android",
"bundled GeckoView/Fenix/Tor Browser Android-lineage app with foreground transports",
"no system browser dependency; app owns profile, proxy policy, and transport lifecycle",
"Default Android runtime for real mobile AMPB.",
),
BrowserBackend(
"webkit-ios-shell",
"ampb-webkit-ios",
"ios runtime",
"planned",
"ios",
"native shell with embedded transports and isolated web views",
"bundled iOS app shell with WebKit views and embedded transport runtimes",
"platform constrained; avoid clearnet fallback and isolate transport state",
"Required for App Store-style iOS builds outside special browser-engine entitlements.",
"Default iOS path unless alternate browser-engine entitlements become practical.",
),
BrowserBackend(
"tor-browser-lineage",
"tor-hardened target",
"planned",
"desktop, android",
"reuse or track Tor Browser patches after AMPB transport contracts are stable",
"highest Tor web target; do not claim equivalence until Tor Browser patches are tracked",
"Path toward real Tor Browser-grade behavior for .onion browsing.",
),
BrowserBackend(
"gemini-native-viewer",
@@ -115,13 +124,4 @@ BROWSER_BACKENDS = (
"no web engine or shared browser storage required",
"Used for Gemini and similar lightweight document transports.",
),
BrowserBackend(
"chromium-cef",
"prototype fallback",
"fallback",
"desktop",
"profile launcher only when Firefox path is blocked",
"not a Tor Browser privacy baseline",
"Allowed for experiments, but not the main privacy-browser strategy.",
),
)
+3 -3
View File
@@ -24,9 +24,9 @@ class PlatformCapability:
PLATFORM_CAPABILITIES = (
PlatformCapability("clearnet", "desktop", "ready", "ready", "unsupported", "unsupported", "Use system browser or isolated desktop profile."),
PlatformCapability("clearnet", "android", "ready", "ready", "unsupported", "unsupported", "Use Android browser shell, WebView, or Custom Tabs."),
PlatformCapability("clearnet", "ios", "ready", "ready", "unsupported", "unsupported", "Use iOS browser shell with platform web constraints."),
PlatformCapability("clearnet", "desktop", "ready", "ready", "unsupported", "unsupported", "Use bundled AMPB Gecko desktop runtime with isolated profile."),
PlatformCapability("clearnet", "android", "ready", "ready", "unsupported", "unsupported", "Use bundled AMPB GeckoView Android runtime with isolated profile."),
PlatformCapability("clearnet", "ios", "ready", "ready", "unsupported", "unsupported", "Use bundled AMPB iOS shell with platform WebKit constraints."),
PlatformCapability("tor", "desktop", "ready", "ready", "planned", "planned", "Adopt local Tor or prompt before managed Arti SOCKS setup."),
PlatformCapability("tor", "android", "planned", "planned", "planned", "planned", "Use an app-owned foreground service; prefer Arti/Tor runtime integration where available."),
PlatformCapability("tor", "ios", "foreground-only", "planned", "foreground-only", "bundled", "Use foreground embedded Arti sessions; do not assume background service or global proxy."),
+10 -9
View File
@@ -29,19 +29,20 @@ isolation decisions outside the browser engine until those contracts are stable.
## Browser Strategy
The first implementation should be Firefox-first without becoming a browser-engine fork
immediately. AMPB should control a hardened Firefox runtime, AMPB-owned profiles,
transport proxy policy, native transport setup, and health checks while the orchestration
contracts become stable.
The first implementation should ship an AMPB-owned browser runtime, not attach to the
host system browser. Desktop AMPB should be a bundled Firefox/Gecko-lineage app with
AMPB-owned profiles, transport proxy policy, native transport setup, and health checks.
Android AMPB should use a bundled GeckoView/Fenix/Tor Browser Android-lineage runtime
with visible foreground transport services.
Tor Browser compatibility is the high bar for `.onion` browsing. AMPB must not claim Tor
Browser equivalence until it tracks the relevant Tor Browser hardening, fingerprinting,
proxy, and update behavior. Chromium or CEF can remain a prototype fallback, but it is not
the main privacy-browser strategy.
proxy, and update behavior. AMPB should not depend on system Firefox, system Chrome, or
the user's default browser.
The long-term browser can become a deeper Firefox or Tor Browser fork once the
orchestration surface is reliable: profile isolation is predictable, transport adoption is
boring, and generated fixtures from AMPG open without manual proxy setup.
The long-term browser can become a deeper Firefox, GeckoView, or Tor Browser fork once
the orchestration surface is reliable: profile isolation is predictable, transport adoption
is boring, and generated fixtures from AMPG open without manual proxy setup.
Generated backend metadata lives in
[generated browser strategy](generated/browser-strategy.md).
+3 -1
View File
@@ -21,7 +21,9 @@ python3 -m ampbrowser docs generate --check
Generated files live under `docs/generated/` and must not be edited by hand. They cover
route rules, active transports, browser backend strategy, adapter contracts, candidate
transports, and platform capabilities.
transports, and platform capabilities. Browser source trees, object directories, caches,
and artifacts belong under `/tmp/ampb-browser-build` or another explicit external build
workspace, not this repo.
## Manual Docs
+48
View File
@@ -0,0 +1,48 @@
# Browser Builds
> Status: draft | Updated 2026-07-07 | Applies to: AMPB desktop and mobile builders
AMPB browser builds must keep source checkouts, object directories, toolchain caches, and
temporary artifacts outside this repository. The default local workspace is
`/tmp/ampb-browser-build`.
## Runtime Targets
- Desktop: bundled Firefox/Gecko-lineage AMPB app.
- Android: bundled GeckoView/Fenix/Tor Browser Android-lineage AMPB app.
- iOS: AMPB-owned iOS shell with platform WebKit constraints and embedded transports.
- Tor hardening: track Tor Browser behavior before claiming Tor Browser equivalence.
## Workspace
Create a local build workspace:
```sh
sh tools/browser-build-workspace.sh
```
Override the root when needed:
```sh
AMPB_BROWSER_BUILD_ROOT=/tmp/ampb-browser-build sh tools/browser-build-workspace.sh
```
The script creates:
- `/tmp/ampb-browser-build/src`
- `/tmp/ampb-browser-build/obj`
- `/tmp/ampb-browser-build/cache`
- `/tmp/ampb-browser-build/artifacts`
- `/tmp/ampb-browser-build/logs`
## Repo Rule
Keep only repeatable scripts, clean docs, and small AMPB source changes in this repo.
Do not commit Firefox source trees, GeckoView checkouts, Tor Browser build trees, browser
object directories, SDK downloads, signing material, generated profiles, release artifacts,
or machine-local notes.
## Rebuild Notes
Public rebuild docs should be general and credential-free. Private signing, release,
account, and machine inventory notes belong outside public docs.
+1 -1
View File
@@ -27,7 +27,7 @@ Example configs live under `examples/`.
```toml
[browser]
default_engine = "hardened-firefox"
default_engine = "ampb-gecko"
state_dir = ".ampb"
[transports.tor]
+4 -4
View File
@@ -6,8 +6,8 @@ This file is generated from code. Do not edit it by hand.
| Backend | Role | Status | Platforms | Launch Mode | Privacy Posture | Note |
| --- | --- | --- | --- | --- | --- | --- |
| `hardened-firefox` | primary web runtime | `planned` | desktop, android | managed profile, policy, and native transport launcher | strong baseline; track Firefox ESR and Tor Browser hardening choices | Default AMPB web runtime before a full browser fork. |
| `tor-browser-compatible` | tor-hardened target | `planned` | desktop, android | adopt, launch, or fork after transport contracts are stable | highest Tor web target; do not claim equivalence until Tor Browser patches are tracked | Path toward real Tor Browser-grade behavior for .onion browsing. |
| `webkit-ios-shell` | ios runtime | `planned` | ios | native shell with embedded transports and isolated web views | platform constrained; avoid clearnet fallback and isolate transport state | Required for App Store-style iOS builds outside special browser-engine entitlements. |
| `ampb-gecko-desktop` | primary desktop runtime | `planned` | desktop | bundled Firefox/Gecko-lineage app with AMPB-owned profiles and transports | no system browser dependency; track Firefox ESR, Tor Browser, and Mullvad hardening choices | Default desktop runtime; users should not need Firefox installed. |
| `ampb-geckoview-android` | primary android runtime | `planned` | android | bundled GeckoView/Fenix/Tor Browser Android-lineage app with foreground transports | no system browser dependency; app owns profile, proxy policy, and transport lifecycle | Default Android runtime for real mobile AMPB. |
| `ampb-webkit-ios` | ios runtime | `planned` | ios | bundled iOS app shell with WebKit views and embedded transport runtimes | platform constrained; avoid clearnet fallback and isolate transport state | Default iOS path unless alternate browser-engine entitlements become practical. |
| `tor-browser-lineage` | tor-hardened target | `planned` | desktop, android | reuse or track Tor Browser patches after AMPB transport contracts are stable | highest Tor web target; do not claim equivalence until Tor Browser patches are tracked | Path toward real Tor Browser-grade behavior for .onion browsing. |
| `gemini-native-viewer` | alternate-web viewer | `planned` | desktop, android, ios | built-in fetch and render path | no web engine or shared browser storage required | Used for Gemini and similar lightweight document transports. |
| `chromium-cef` | prototype fallback | `fallback` | desktop | profile launcher only when Firefox path is blocked | not a Tor Browser privacy baseline | Allowed for experiments, but not the main privacy-browser strategy. |
+3 -3
View File
@@ -6,9 +6,9 @@ This file is generated from code. Do not edit it by hand.
| Transport | Platform | Browse | Adopt | Manage | Install | Note |
| --- | --- | --- | --- | --- | --- | --- |
| `clearnet` | `desktop` | `ready` | `ready` | `unsupported` | `unsupported` | Use system browser or isolated desktop profile. |
| `clearnet` | `android` | `ready` | `ready` | `unsupported` | `unsupported` | Use Android browser shell, WebView, or Custom Tabs. |
| `clearnet` | `ios` | `ready` | `ready` | `unsupported` | `unsupported` | Use iOS browser shell with platform web constraints. |
| `clearnet` | `desktop` | `ready` | `ready` | `unsupported` | `unsupported` | Use bundled AMPB Gecko desktop runtime with isolated profile. |
| `clearnet` | `android` | `ready` | `ready` | `unsupported` | `unsupported` | Use bundled AMPB GeckoView Android runtime with isolated profile. |
| `clearnet` | `ios` | `ready` | `ready` | `unsupported` | `unsupported` | Use bundled AMPB iOS shell with platform WebKit constraints. |
| `tor` | `desktop` | `ready` | `ready` | `planned` | `planned` | Adopt local Tor or prompt before managed Arti SOCKS setup. |
| `tor` | `android` | `planned` | `planned` | `planned` | `planned` | Use an app-owned foreground service; prefer Arti/Tor runtime integration where available. |
| `tor` | `ios` | `foreground-only` | `planned` | `foreground-only` | `bundled` | Use foreground embedded Arti sessions; do not assume background service or global proxy. |
+10 -8
View File
@@ -8,18 +8,20 @@ mobile shells should implement only the platform-specific browser and transport
## Android
Android is the primary mobile target for full AMPB browsing. Tor, I2P, IPFS, and
Reticulum adapters should run only after a URL selects that transport and the user
approves setup. Managed adapters must use visible, stoppable foreground services and
app-owned state. Tor should prefer an Arti/Tor runtime path when the native shell can
Android is the primary mobile target for full AMPB browsing. It should ship a bundled
GeckoView/Fenix/Tor Browser Android-lineage runtime, not depend on a system browser. Tor,
I2P, IPFS, and Reticulum adapters should run only after a URL selects that transport and
the user approves setup. Managed adapters must use visible, stoppable foreground services
and app-owned state. Tor should prefer an Arti/Tor runtime path when the native shell can
support it cleanly.
## iOS
iOS is a supported design target, but transport management is constrained. AMPB should
assume foreground-only sessions for managed transports unless a reviewed platform
capability proves otherwise. The iOS shell should still share routing, policy, consent,
fixture, Gemini, IPFS gateway, and clearnet behavior with the rest of AMPB.
iOS is a supported design target, but transport management and browser engines are
constrained. AMPB should ship its own iOS app shell, use platform WebKit views where
required, and assume foreground-only sessions for managed transports unless a reviewed
platform capability proves otherwise. The iOS shell should still share routing, policy,
consent, fixture, Gemini, IPFS gateway, and clearnet behavior with the rest of AMPB.
Tor on iOS should be modeled as an embedded Arti session, not a global daemon install.
The first vertical should prove foreground `.onion` browsing through an app-owned Arti
+1 -1
View File
@@ -1,5 +1,5 @@
[browser]
default_engine = "hardened-firefox"
default_engine = "ampb-gecko"
state_dir = ".ampb"
[transports.tor]
+1 -1
View File
@@ -1,5 +1,5 @@
[browser]
default_engine = "hardened-firefox"
default_engine = "ampb-gecko"
state_dir = ".ampb"
[transports.i2p]
+9 -8
View File
@@ -6,18 +6,19 @@ from ampbrowser.metadata import BROWSER_BACKENDS
class BrowserStrategyTest(unittest.TestCase):
def test_primary_backend_is_hardened_firefox(self) -> None:
primary = [backend for backend in BROWSER_BACKENDS if backend.role == "primary web runtime"]
def test_primary_desktop_backend_is_bundled_gecko(self) -> None:
primary = [backend for backend in BROWSER_BACKENDS if backend.role == "primary desktop runtime"]
self.assertEqual(1, len(primary))
self.assertEqual("hardened-firefox", primary[0].name)
self.assertIn("Firefox", primary[0].privacy_posture)
self.assertEqual("ampb-gecko-desktop", primary[0].name)
self.assertIn("no system browser dependency", primary[0].privacy_posture)
def test_chromium_is_fallback_not_privacy_baseline(self) -> None:
chromium = next(backend for backend in BROWSER_BACKENDS if backend.name == "chromium-cef")
def test_primary_android_backend_is_bundled_geckoview(self) -> None:
primary = [backend for backend in BROWSER_BACKENDS if backend.role == "primary android runtime"]
self.assertEqual("fallback", chromium.status)
self.assertIn("not a Tor Browser", chromium.privacy_posture)
self.assertEqual(1, len(primary))
self.assertEqual("ampb-geckoview-android", primary[0].name)
self.assertIn("no system browser dependency", primary[0].privacy_posture)
if __name__ == "__main__":
+1 -1
View File
@@ -13,7 +13,7 @@ class ConfigTest(unittest.TestCase):
config = load_config(Path(tmp))
self.assertEqual(".ampb", config.state_dir)
self.assertEqual("hardened-firefox", config.default_engine)
self.assertEqual("ampb-gecko", config.default_engine)
self.assertEqual("adopt-or-prompt-manage", config.transport_mode("tor"))
self.assertEqual(".ampb/profiles/tor", config.profile_path("tor"))
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
set -eu
root="${AMPB_BROWSER_BUILD_ROOT:-/tmp/ampb-browser-build}"
mkdir -p "$root/src"
mkdir -p "$root/obj"
mkdir -p "$root/cache"
mkdir -p "$root/artifacts"
mkdir -p "$root/logs"
printf 'AMPB_BROWSER_BUILD_ROOT=%s\n' "$root"
printf 'AMPB_BROWSER_SRC=%s\n' "$root/src"
printf 'AMPB_BROWSER_OBJ=%s\n' "$root/obj"
printf 'AMPB_BROWSER_CACHE=%s\n' "$root/cache"
printf 'AMPB_BROWSER_ARTIFACTS=%s\n' "$root/artifacts"
printf 'AMPB_BROWSER_LOGS=%s\n' "$root/logs"