Files
one-os-dev-wayland-html5-co…/Greenfield-vs-MIT-Comparison.md

25 KiB
Raw Permalink Blame History

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 <memfd>
  • --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/<UID>/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 <canvas> 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