commit 45c8b72d8e3cdf44e35b02aa00cc45e7d32da1fe Author: 1b-agent Date: Thu Oct 8 08:48:30 2026 +0000 Initial commit: Greenfield vs MIT comparison document with strong recommendation diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4d5081d --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Python +__pycache__/ +*.pyc +*.pyo +.venv/ +venv/ + +# OS +.DS_Store +Thumbs.db + +# Editor +.vscode/ +.idea/ +*.swp + +# Logs +*.log + +# Build +node_modules/ +dist/ +build/ +*.egg-info/ diff --git a/Greenfield-vs-MIT-Comparison.md b/Greenfield-vs-MIT-Comparison.md new file mode 100644 index 0000000..9f24e32 --- /dev/null +++ b/Greenfield-vs-MIT-Comparison.md @@ -0,0 +1,525 @@ +# Greenfield (AGPL) vs MIT-Licensed Custom Compositor — Final Comparison & Recommendation + +> **Executive summary.** This document compares two approaches to building +> a Wayland-to-HTML5 compositor for the Odoo 20 fork: +> +> 1. **Option A — Use Greenfield as-is** (AGPL-3.0): faster time-to-market, +> battle-tested codebase, but **AGPL contamination forces the entire +> Odoo fork to be open-sourced** under AGPL-3.0. **NOT COMPATIBLE with +> the user's proprietary goal.** +> +> 2. **Option B — Build a fully MIT-licensed custom compositor** (this +> bundle): reuse Greenfield's 7 MIT libs as building blocks, replace +> the 4 AGPL packages with clean-room reimplementations in TypeScript +> (browser) and Python (host). **Fully proprietary, but ~6-9 months +> of engineering effort.** +> +> **Final recommendation: Option B (MIT-licensed custom compositor)**. +> The user's #1 priority is license purity for a proprietary Odoo fork — +> this rules out Option A. With 2 senior engineers in parallel, Option B +> is achievable in ~5-6 months to MVP, ~8-9 months to production. + +## TL;DR — Decision matrix + +| Dimension | Option A: Greenfield (AGPL) | Option B: MIT Custom Compositor | +|---|---|---| +| **License purity** | ❌ **AGPL-3.0 contamination** — entire Odoo fork must be open-sourced | ✅ **Fully proprietary** — MIT/Apache/BSD/LGPL only, with 3 substitutions | +| **Time to MVP** | ✅ 1-2 weeks (run as-is in dev) | ❌ ~32 weeks (with 2 engineers in parallel) | +| **Time to production** | ⚠️ Never (AGPL blocks shipping) | ❌ ~38 weeks (with 2 engineers) | +| **Performance** | ✅ Battle-tested, optimised | ✅ Modern stack (WebGL2 + WebCodecs HW + OffscreenCanvas), should match or exceed Greenfield | +| **Maintainability** | ⚠️ Forked from rc1, must track upstream | ✅ Full control, no upstream dependency | +| **Sandboxing** | ❌ Zero (apps have full host access) | ✅ bubblewrap + seccomp + systemd-run from day 1 | +| **Multi-tenancy** | ❌ Single-user single-session | ✅ Per-Odoo-DB isolation, JWT-scoped sessions | +| **Odoo integration** | ⚠️ Custom shell needed (Preact → Odoo OWL) | ✅ Native Odoo 20 OWL shell + backend addon | +| **Vendor lock-in** | ❌ Locked to Greenfield's architecture + upstream churn | ✅ Swap any component (e.g. replace pywayland with Smithay Rust) | +| **Clean-room legal risk** | N/A (using AGPL code directly) | ⚠️ Must maintain SPEC.md + CLEAN_ROOM_LOG.md as legal defense | +| **Total effort** | ~1-2 weeks to dev MVP, **never shippable** | ~32-38 weeks to production MVP | +| **Recommendation** | ❌ **REJECT** (license incompatible) | ✅ **ADOPT** (the only viable path) | + +## Detailed comparison + +### 1. License purity (user's #1 priority) + +#### Option A — Greenfield (AGPL) + +**Critical problem**: The 4 user-facing packages are AGPL-3.0: +- `@gfld/compositor` (browser compositor library) +- `@gfld/compositor-proxy` (native proxy) +- `@gfld/compositor-proxy-cli` (proxy CLI) +- `@gfld/compositor-shell` (Preact shell — out of scope, user replaces with Odoo) + +**AGPL §13 network-use clause**: "If you modify the Program, your modified +version must prominently offer all users interacting with it remotely +through a computer network, an opportunity to obtain the source code of +your modified version." + +**Impact on Odoo fork**: The Odoo fork is a network service (users access +it via browser). If the compositor is AGPL-derivative, the entire Odoo +fork must be open-sourced to all users. This **destroys the proprietary +value** of the Odoo fork. + +**Additional GPL contaminants found in Greenfield** (Agent T audit): +- `@gfld/compositor-ffmpeg-h264` — declared Apache-2.0 but actually + GPL-3.0 (FFmpeg built with `--enable-gpl --enable-version3 --enable-nonfree`) +- `x264enc` GStreamer plugin — GPL-2.0+ (no dynamic-linking exception) +- `gstreamer1.0-libav` on Debian — LGPL source but GPL binary (libavcodec + built with `--enable-gpl` and links `libx264.so.164` + `libx265.so.215`) + +**Verdict**: ❌ **NOT VIABLE** for a proprietary product. + +#### Option B — MIT Custom Compositor + +**License stack** (verified clean by Agent T): + +| Component | License | Compatible? | +|---|---|---| +| @gfld/common, @gfld/client-protocol, @gfld/compositor-protocol | MIT | ✅ | +| @gfld/compositor-wasm (pixman + xkbcommon) | MIT | ✅ | +| @gfld/xtsb (optional, XWayland) | MIT | ✅ | +| @gfld/client-generator, @gfld/compositor-generator | MIT | ✅ | +| pywayland | Apache-2.0 | ✅ | +| python-xkbcommon | MIT | ✅ | +| PyGObject + GStreamer | LGPL-2.1+ (dynamic linking) | ✅ | +| gst-vaapi (vaapih264enc) | LGPL + MIT (libva) | ✅ | +| gst-plugins-bad (nvh264enc, openh264enc) | BSD subset | ✅ | +| libwayland, libdrm, mesa | MIT | ✅ | +| aiohttp | Apache-2.0 | ✅ | +| kcp (PyPI) | MIT | ✅ | +| PyJWT | MIT | ✅ | +| bubblewrap | LGPL-2.0+ (dynamic linking) | ✅ | +| libseccomp | LGPL-2.1 | ✅ | +| Odoo 20 Community | LGPL-3.0 (separate process) | ✅ | +| WebCodecs, WebGL2, OffscreenCanvas | W3C standards | ✅ | +| OpenH264 (BSD fallback decoder) | BSD-2-Clause | ✅ | +| Custom browser compositor (your code) | PROPRIETARY (clean-room) | ✅ | +| Custom Python proxy (your code) | PROPRIETARY | ✅ | +| Custom Odoo 20 addon (your code) | PROPRIETARY | ✅ | + +**3 mandatory substitutions** (to avoid GPL contamination): +1. **WebCodecs API** replaces `@gfld/compositor-ffmpeg-h264` (GPL) +2. **vaapih264enc / nvh264enc / openh264enc** replaces `x264enc` (GPL) +3. **Don't install `gstreamer1.0-libav`** (GPL binary on Debian) + +**Clean-room requirement**: The custom browser compositor MUST be +written clean-room — Person A writes spec (may read AGPL), Person B +implements (must NOT read AGPL). Maintain `SPEC.md` + +`CLEAN_ROOM_LOG.md` as legal-defensibility artifacts. + +**Verdict**: ✅ **FULLY PROPRIETARY VIABLE** with 3 substitutions + clean-room discipline. + +### 2. Time to MVP + +#### Option A — Greenfield (AGPL) + +- **Week 1-2**: Run Greenfield's compositor-proxy-cli in Docker, embed + the compositor-shell in an Odoo iframe, launch `gtk4-demo`, see it + render. +- **Week 3-4**: Replace compositor-shell with minimal Odoo OWL component. +- **Week 5-6**: Integrate with Odoo auth, add app launcher. + +**Total to dev MVP**: ~4-6 weeks. + +**But**: This is dev-only. You cannot ship this without open-sourcing +your Odoo fork. So time-to-MVP is irrelevant — the option is non-viable. + +#### Option B — MIT Custom Compositor + +| Phase | Weeks (1 dev) | Weeks (2 devs parallel) | +|---|---|---| +| Phase 0: Spike (validate libwayland ↔ asyncio) | 1 | 1 | +| Phase 1: Browser compositor MVP (clean-room TS) | 25 | 15 (one on compositor, one on transport+input) | +| Phase 2: Python proxy MVP (aiohttp + pywayland + GStreamer) | 3.5 | 3.5 (parallel with Phase 1) | +| Phase 3: Odoo integration (OWL shell + backend addon + JWT) | 3.5 | 3.5 (parallel with Phase 1) | +| Phase 4: Sandboxing v1 (bubblewrap + seccomp) | 1.5 | 1.5 | +| Phase 5: Polish & testing | 3 | 3 | +| **TOTAL to MVP** | **~37.5 weeks (~9 months)** | **~24 weeks (~6 months)** | +| Phase 6 (optional): XWayland + multi-tenant + portal | +9 | +6 | + +**Critical path**: Browser compositor (Phase 1) is the bottleneck. +With 2 senior engineers (one on compositor core + roles, one on +transport + input + Python proxy + Odoo integration), MVP in ~6 months. + +### 3. Performance + +#### Option A — Greenfield (AGPL) + +- WebGL1 (no OffscreenCanvas, no WebGL2) +- Main-thread WebGL (jank on heavy frames) +- WebCodecs with hardware decode **disabled** (FIXME: "frame offset is wrong") +- FFmpeg Wasm fallback (GPL — can't ship anyway) +- H.264 encoding: x264 software (GPL — can't ship anyway) +- No adaptive bitrate (EncoderFeedback data produced but not consumed) +- Single-threaded JS compositor + +#### Option B — MIT Custom Compositor + +- **WebGL2** (uniform buffer objects, simplified shaders) +- **OffscreenCanvas + Web Workers** (render in worker, never block main thread) +- **WebCodecs with hardware decode enabled** (fix Greenfield's FIXME) +- **OpenH264 BSD Wasm fallback** (replaces Greenfield's GPL FFmpeg Wasm) +- **Hardware-accelerated encoding by default** (vaapih264 on Intel/AMD, nvh264 on NVIDIA) +- **Adaptive bitrate** (consumes EncoderFeedback data Greenfield ignores) +- Multi-threaded (render worker + decode worker) + +**Expected performance**: Should match or exceed Greenfield. Hardware +decode + hardware encoding + worker offload should give 2-3× improvement +on heavy content. + +### 4. Maintainability + +#### Option A — Greenfield (AGPL) + +- Forked from `1.0.0-rc1` — must track upstream commits manually +- 3 native Node addons (`.node` files, Linux-x64 only, ABI-locked to Node major) +- Heavy build toolchain (Yarn 4 + CMake + Ninja + Meson + pkg-config + 2 Emscripten versions) +- Solo maintainer (Erik De Rijcke) — single point of failure +- No CHANGELOG, no SECURITY.md, no CONTRIBUTING.md + +#### Option B — MIT Custom Compositor + +- Full control over the codebase +- No native Node addons (pure Python + TypeScript) +- Standard build toolchain (npm/pnpm + pip + standard tsc/aiohttp) +- Python team can maintain Python parts; TS team can maintain browser parts +- No upstream churn to track + +### 5. Sandboxing & security + +#### Option A — Greenfield (AGPL) + +**Zero sandboxing** (Agent S analysis, pitfall M): +- Plain `child_process.spawn()` with no isolation +- Apps have full host filesystem access +- Apps share the proxy's env (could leak DB passwords, Odoo session cookies) +- No network isolation +- No resource limits +- Basic Auth (single replayable credential) +- Client-generated `compositorSessionId` (spoofable) + +**Verdict**: ❌ **Cannot ship in production** without major security work. + +#### Option B — MIT Custom Compositor + +**Sandboxing from day 1** (Agent S analysis): +- `bubblewrap --unshare-all --clearenv --seccomp ` +- `--ro-bind /usr /usr`, minimal `/etc` whitelist, `$HOME` overlay +- `--dev-bind /dev/dri/renderD128` (single GPU render node) +- `--ro-bind $HOST_XDG/wayland-N /run/user//wayland-N` (single socket only) +- `--uid 100000-165535` per-app (UID remap via `/etc/subuid`) +- `--unshare-net` by default (most apps don't need network) +- `systemd-run --scope -p MemoryMax=1G -p CPUQuota=200% -p TasksMax=256` +- JWT auth (HS256, 15-min expiry, signed by Odoo backend) +- Server-generated `compositor_session_id` (UUID, not client-generated) + +**Effort**: ~7-9 dev-days for v1 (shippable), +4-9 days for v2 (XWayland sandbox + veth networking). + +**Verdict**: ✅ **Production-grade sandboxing** out of the box. + +### 6. Multi-tenancy + +#### Option A — Greenfield (AGPL) + +Single-user single-session. No multi-tenant isolation. Each Odoo +database would need its own proxy instance, manually configured. + +#### Option B — MIT Custom Compositor + +- One compositor proxy per Odoo database (Docker container per tenant) +- JWT `db` claim scopes every WS to one Odoo database +- Per-session wayland socket (`$XDG_RUNTIME_DIR/wayland-N`) +- Per-session forked worker process +- Per-app UID remap (100000-165535) +- Per-app cgroup limits (MemoryMax, CPUQuota, TasksMax) +- Optional: per-tenant Docker container with `--cpus` and `--memory` limits + +### 7. Odoo integration depth + +#### Option A — Greenfield (AGPL) + +- Custom shell needed: replace Preact compositor-shell with Odoo OWL component +- Auth bridging: Greenfield's Basic Auth → Odoo session (fragile) +- No audit log integration +- No multi-tenancy + +#### Option B — MIT Custom Compositor + +- **Native Odoo 20 OWL shell** (ir.actions.client with target=fullscreen) +- **JWT auth** issued by Odoo backend (HS256, 15-min expiry) +- **Audit log** model (`compositor.audit.log`, append-only) — every app + launch/terminate/crash logged with user, timestamp, app, duration +- **App catalog** model (`compositor.app`) — per-user allowed apps list, + filtered by `res.groups` +- **Session model** (`compositor.session`) — mail.thread mixin for + tracking +- **Nginx reverse proxy** for single-origin HTTPS (eliminates CORS) +- **Docker Compose** with GPU passthrough + +### 8. Vendor lock-in + +#### Option A — Greenfield (AGPL) + +- Locked to Greenfield's architecture (browser compositor + Node proxy) +- Locked to Node.js (N-API addons ABI-locked to Node major) +- Locked to Linux-x64 (no ARM64) +- Locked to Greenfield's wire protocol (no schema versioning) +- Must track upstream rc1 → 1.0 transitions + +#### Option B — MIT Custom Compositor + +- Swap any component: + - Replace pywayland with Smithay (Rust) if Python doesn't work out + - Replace aiohttp with FastAPI if needed + - Replace GStreamer with PyAV (FFmpeg Python bindings) if needed + - Replace WebGL2 with WebGPU when browser support is widespread +- No Node.js dependency (pure Python + TypeScript) +- Linux-x64 + ARM64 (pywayland ships ARM64 wheels) +- Can version your own wire protocol from commit #1 + +## Effort estimates (detailed, person-weeks) + +### Option A — Greenfield (AGPL) + +| Phase | Person-weeks | Notes | +|---|---|---| +| Dev MVP (run as-is in Docker) | 1-2 | Cannot ship — AGPL | +| Replace shell with Odoo OWL | 2 | Cannot ship — AGPL | +| Auth integration | 1 | Cannot ship — AGPL | +| Sandboxing (NEW, not in Greenfield) | 1.5 | Cannot ship — AGPL | +| Multi-tenancy | 1.5 | Cannot ship — AGPL | +| **TOTAL** | **~7-8 weeks** | **All wasted — cannot ship** | + +### Option B — MIT Custom Compositor + +#### Single engineer, sequential + +| Phase | Weeks | Deliverable | +|---|---|---| +| Phase 0: Spike | 1 | Validate libwayland ↔ asyncio integration (5-line cffi shim) | +| Phase 1: Browser compositor MVP | 25 | Clean-room TypeScript, ~13,400 LOC | +| Phase 1a: Surface state stack | 3 | Surface.ts, SurfaceRole.ts, Subsurface.ts (1,200 LOC) | +| Phase 1b: Rendering pipeline | 3 | Renderer.ts, Scene.ts, View.ts, Output.ts, shaders (1,800 LOC, WebGL2) | +| Phase 1c: Buffers | 1.5 | Shm.ts, BufferContents.ts, ImageBitmapBuffer.ts (600 LOC) | +| Phase 1d: Transport + decoders | 4 | Channel.ts, kcp.ts, ReconnectingWebSocket.ts, WebCodecsFrameDecoder.ts, OpenH264FrameDecoder.ts (3,500 LOC + 500 LOC) | +| Phase 1e: Input | 3 | Seat.ts, Keyboard.ts, Pointer.ts, Touch.ts, Xkb.ts (2,500 LOC) | +| Phase 1f: Roles (xdg-shell) | 3 | XdgWmBase.ts, XdgSurface.ts, XdgToplevel.ts, XdgPopup.ts, XdgPositioner.ts (1,800 LOC, HIGH RISK) | +| Phase 1g: Data device + clipboard + DnD | 1.5 | DataDeviceManager.ts, DataSource.ts, DataOffer.ts, PrimarySelectionDeviceManager.ts (NEW) (600 LOC) | +| Phase 1h: Desktop policy | 1.5 | Desktop.ts, FloatingDesktopSurface.ts (800 LOC) | +| Phase 1i: Math | 0.5 | Mat4.ts, Vec4.ts, Point.ts, Size.ts, Rect.ts (500 LOC) | +| Phase 1j: UserShellApi | 0.5 | UserShellApi.ts (120 LOC) | +| Phase 1k: Browser glue | 2 | input.ts, pointer.ts, touch.ts (NEW), dnd.ts, selection.ts (750 LOC) | +| Phase 1l: Core | 0.5 | Session.ts, Globals.ts (200 LOC) | +| Phase 2: Python proxy MVP | 3.5 (~17 dev-days) | aiohttp + pywayland + GStreamer, ~2,880 LOC Python | +| Phase 2a: aiohttp WS server (9 endpoints) | 3 days | /signal, /channel, /mkfifo, /mkstemp-mmap, /read-fd, etc. | +| Phase 2b: Channel/ARQChannel/SimpleChannel port | 1.5 days | Clean-room from spec | +| Phase 2c: kcp PyPI package integration | 0.5 days | RealistikDash/kcp.py | +| Phase 2d: NativeAppContext (signaling, escalation) | 2 days | 10-min SIGHUP grace, SIGTERM escalation | +| Phase 2e: ProxyInputOutput (FD workaround) | 2 days | os.pipe(), os.memfd_create(), asyncio streams | +| Phase 2f: libwayland event-loop integration | 1 day | 5-line cffi shim for wl_event_loop_get_fd | +| Phase 2g: Multiprocessing + FD passing | 1.5 days | multiprocessing.reduction.send_handle | +| Phase 2h: GStreamer encoder thread + marshalling | 2 days | GLib MainLoop in separate thread, asyncio.run_coroutine_threadsafe | +| Phase 2i: Reconnection & lifecycle | 1 day | | +| Phase 2j: Tests | 3 days | pytest + pytest-asyncio | +| Phase 3: Odoo integration | 3.5 (~18 dev-days) | OWL shell + backend addon + JWT + Nginx + Docker | +| Phase 3a: Odoo addon skeleton | 2 days | Models + controllers + views + security | +| Phase 3b: JWT issuance + audit log | 1.5 days | HS256, 15-min expiry, pyjwt | +| Phase 3c: OWL 3 fullscreen client action | 2.5 days | ir.actions.client, target=fullscreen, **must use proxy() not useState()** | +| Phase 3d: Browser compositor integration | 2 days | userShell.actions.initScene | +| Phase 3e: JWT middleware + WS handshake | 1.5 days | | +| Phase 3f: Audit POSTback + Nginx + Docker + GPU | 2 days | | +| Phase 3g: Multi-tenant | 1.5 days | Per-DB proxy spawning + db claim | +| Phase 3h: Tests | 2 days | HttpCase + TransactionCase | +| Phase 3i: Documentation + buffer | 3 days | | +| Phase 4: Sandboxing v1 | 1.5 (~7-9 dev-days) | bubblewrap + seccomp + systemd-run | +| Phase 4a: bwrap integration | 2-3 days | | +| Phase 4b: seccomp profile + compile | 1-2 days | Docker default profile + CLONE_NEWUSER allow | +| Phase 4c: systemd-run cgroup wrapper | 1 day | MemoryMax=1G, CPUQuota=200%, TasksMax=256 | +| Phase 4d: Wayland socket ownership fix | 0.5 days | chmod 0660 + sandbox group | +| Phase 4e: GPU passthrough testing | 1 day | /dev/dri/renderD128 only | +| Phase 4f: Schema + docs | 1 day | | +| Phase 5: Polish & testing | 3 | Tests, hardening, docs | +| **MVP TOTAL** | **~37.5 weeks** | Single-tenant, single-app, fully proprietary, sandboxed | +| Phase 6 (optional): XWayland | +8 | ~5,000 LOC TS, uses @gfld/xtsb (MIT) | +| Phase 6 (optional): Multi-tenant portal | +2 | XDG Desktop Portal (FileChooser/Secret) | +| Phase 6 (optional): Per-tenant veth networking | +2 | nftables filter | +| **GRAND TOTAL (with Phase 6)** | **~49.5 weeks** | Production-ready | + +#### Two engineers in parallel + +| Phase | Weeks | Notes | +|---|---|---| +| Phase 0: Spike | 1 | Both engineers validate together | +| Phase 1 (Eng A: compositor core + roles) + Phase 2+3 (Eng B: transport + Python + Odoo) | 25 (Eng A is critical path) | Parallel | +| Phase 4 (Eng B: sandboxing) + Phase 5 (Eng A: tests) | 3 | Parallel | +| **MVP TOTAL** | **~29 weeks (~7 months)** | | +| Phase 6 (optional): XWayland (Eng A) + multi-tenant (Eng B) | +6 | Parallel | +| **GRAND TOTAL (with Phase 6)** | **~35 weeks (~9 months)** | | + +#### Three engineers in parallel (aggressive) + +| Phase | Weeks | Notes | +|---|---|---| +| Phase 0: Spike | 1 | All three validate together | +| Phase 1 (Eng A: compositor + roles) + Phase 2 (Eng B: Python proxy) + Phase 3 (Eng C: Odoo integration) | 25 (Eng A is critical path) | Fully parallel | +| Phase 4 (Eng B: sandboxing) + Phase 5 (Eng A + C: tests) | 2 | Parallel | +| **MVP TOTAL** | **~28 weeks (~7 months)** | | +| Phase 6 (optional): XWayland (Eng A) + portal (Eng B) + veth (Eng C) | +5 | Parallel | +| **GRAND TOTAL (with Phase 6)** | **~33 weeks (~8 months)** | | + +## Final recommendation + +### Strong recommendation: Option B (MIT Custom Compositor) + +**The user's #1 priority is license purity for a proprietary Odoo +fork.** This single requirement rules out Option A entirely — AGPL §13 +would force the entire Odoo fork to be open-sourced, destroying the +proprietary value. + +**Option B is the only viable path.** With 3 mandatory substitutions +(no GPL x264, no GPL FFmpeg Wasm, no Debian gst-libav) + clean-room +discipline for the browser compositor, the entire stack is +MIT/Apache/BSD/LGPL — fully proprietary-compatible. + +### Effort justification + +The user is essentially building a Wayland compositor from scratch. +This is a significant engineering effort (~25-30 dev-weeks for the +browser compositor alone), but: + +1. **It's a one-time cost.** Once built, the compositor is yours to + maintain and extend indefinitely. +2. **The browser compositor is the bulk of the work** (~60% of total + effort). The Python proxy + Odoo integration + sandboxing are + relatively quick (~8.5 weeks total). +3. **The clean-room approach is legally defensible.** With proper + SPEC.md + CLEAN_ROOM_LOG.md artifacts, the user can demonstrate + non-infringement even if Greenfield's maintainer alleges + derivative-work infringement. +4. **The modernized stack is better than Greenfield** — WebGL2, + WebCodecs HW decode, OffscreenCanvas + Workers, adaptive bitrate, + sandboxing, multi-tenancy, Odoo integration. The user gets a + better product, not just a license-clean one. + +### Phased rollout recommendation + +To minimize risk and validate assumptions early: + +**Phase 0 (Week 1): Spike** +- Validate libwayland ↔ asyncio integration (5-line cffi shim) +- Validate `kcp` PyPI package works with aiohttp WebSocket +- Validate WebCodecs `prefer-hardware` decode works on target hardware +- If any of these fail, reassess before committing to the full plan + +**Phase 1 (Weeks 2-15, 2 engineers): Browser compositor MVP** +- Eng A: Surface + Roles (xdg-shell state machine) +- Eng B: Transport + Input + Decoders +- Target: A single Linux app renders in a `` via the custom compositor + +**Phase 2 (Weeks 2-6, parallel with Phase 1): Python proxy MVP** +- Eng C: aiohttp + pywayland + GStreamer + bubblewrap sandboxing +- Target: Python proxy can spawn a sandboxed Linux app and stream its + surface to the browser compositor + +**Phase 3 (Weeks 7-10, after Phase 2): Odoo integration** +- Eng C: OWL shell + backend addon + JWT + Nginx + Docker +- Target: End-to-end: user clicks app in Odoo, app launches sandboxed, + renders in Odoo canvas + +**Phase 4 (Weeks 11-13): Polish & testing** +- All engineers: tests, hardening, docs +- Target: Production-ready MVP + +**Phase 5 (Weeks 14+, optional): XWayland + multi-tenant + portal** +- Add X11 app support, per-tenant isolation, XDG Desktop Portal + +### Critical success factors + +1. **Hire 2-3 senior engineers** with Wayland + WebGL + TypeScript + + Python expertise. The browser compositor is the critical path — + don't understaff it. + +2. **Set up clean-room discipline from day 1.** Designate Person A + (spec author, may read AGPL) and Person B (implementer, must NOT + read AGPL). Maintain `SPEC.md` + `CLEAN_ROOM_LOG.md`. + +3. **Add CI/CD license hygiene gates from day 1.** Docker image audit, + npm license-checker, pip-licenses, gst-inspect check. Catch GPL + contamination early. + +4. **Engage legal counsel** before starting the clean-room process. + This bundle is engineering analysis, not legal advice. + +5. **Test with real Linux apps early.** Don't wait until Phase 4 to + test with GTK4/Qt6 apps. Bugs in the xdg-shell state machine are + subtle and need real apps to surface. + +6. **Skip XWayland in MVP.** Most modern GTK4/Qt6 apps are + Wayland-native. Add XWayland only if a specific X11-only app is + needed. + +7. **Use the kcp PyPI package.** Don't port Greenfield's TS KCP to + Python — the Cython wrapper is faster and battle-tested. + +8. **Reuse Greenfield's MIT C files** (westfield-egl.c, wlr_drm.c, + wlr_linux_dmabuf_v1.c, etc.) via cffi. ~3,374 lines of MIT C + reused verbatim — significant effort savings. + +9. **Use vendored ReconnectingWebSocket** (Pedro Ladaria, MIT, 514 + lines TS). Don't reinvent. + +10. **Plan for 6-9 months**, not 3. The browser compositor is a + significant piece of engineering. Underestimating it is the most + common failure mode for Wayland compositor projects. + +## What's at stake + +**If the user chooses Option A (AGPL)**: +- They cannot ship a proprietary product. +- They must open-source their entire Odoo fork. +- Their investment in Odoo customizations becomes a gift to competitors. +- The product is non-viable as a commercial offering. + +**If the user chooses Option B (MIT)**: +- They invest ~6-9 months of engineering effort. +- They get a fully proprietary Wayland-to-HTML5 compositor. +- They get a modernized stack (WebGL2, WebCodecs HW, OffscreenCanvas, + sandboxing, multi-tenancy, Odoo integration). +- They have full control over their IP and roadmap. +- The product is viable as a commercial offering. + +**The choice is clear: Option B.** + +--- + +## Appendix: Quick reference cards + +### Option A — Greenfield (AGPL) quick reference + +| Aspect | Detail | +|---|---| +| Repo | https://github.com/udevbe/greenfield | +| Version | 1.0.0-rc1 | +| License | AGPL-3.0 (4 packages) + MIT (7 libs) + GPL (compositor-ffmpeg-h264, hidden) | +| Browser stack | WebGL1, main-thread, FFmpeg Wasm (GPL), WebCodecs HW disabled | +| Backend | Node.js + 3 C N-API addons (Linux-x64 only) | +| Sandboxing | None | +| Multi-tenancy | None | +| Odoo integration | Custom shell needed, Basic Auth | +| Time to dev MVP | 4-6 weeks | +| Time to production | **Never** (AGPL blocks shipping) | +| Verdict | ❌ **REJECT** | + +### Option B — MIT Custom Compositor quick reference + +| Aspect | Detail | +|---|---| +| Browser stack | WebGL2 + OffscreenCanvas + Web Workers + WebCodecs (HW enabled) + OpenH264 BSD Wasm fallback | +| Backend | Python (aiohttp + pywayland + PyGObject/GStreamer + bubblewrap + seccomp) | +| License | MIT/Apache/BSD/LGPL only, fully proprietary-compatible | +| Sandboxing | bubblewrap + seccomp + systemd-run + cgroups v2, from day 1 | +| Multi-tenancy | Per-Odoo-DB Docker container, JWT-scoped sessions | +| Odoo integration | Native OWL shell + backend addon + JWT (HS256) + Nginx + Docker Compose | +| Effort (2 engineers) | ~6 months to MVP, ~9 months to production | +| Effort (3 engineers) | ~7 months to MVP, ~8 months to production | +| Clean-room requirement | Mandatory (SPEC.md + CLEAN_ROOM_LOG.md) | +| GPL contaminants to avoid | 3 (FFmpeg Wasm, x264enc, gst-libav) | +| Verdict | ✅ **ADOPT** | diff --git a/README.md b/README.md new file mode 100644 index 0000000..646646d --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Greenfield (AGPL) vs MIT-Licensed Custom Compositor — Comparison + +This repo holds the head-to-head decision matrix comparing: +1. **Option A — Use Greenfield as-is** (AGPL-3.0): faster time-to-market, but AGPL contamination forces the entire Odoo fork to be open-sourced. +2. **Option B — Build a fully MIT-licensed custom compositor** (this bundle's recommended path). + +**Final recommendation: Option B**. See `Greenfield-vs-MIT-Comparison.md` for the full analysis with person-week estimates per phase. + +## Related repos +- `one-os-dev-wayland-html5-compositor-greenfield-analysis` — deep analysis of Greenfield (the reference implementation) +- `one-os-dev-wayland-html5-compositor-mit-compositor-analysis` — architecture & build plan for our MIT-licensed alternative