One build constraint quietly shaped the whole app
I wanted everything in one native language. A limitation in how Apple's ML framework builds meant the AI part had to stay Python — so I designed around it.
I would have preferred Jiva to be one clean native app, all in Swift. It is not — the audio and capture core is native, but the language-model work runs in an embedded Python runtime bundled inside the app. That split was not a preference. It was forced by one specific build constraint, and understanding it changed how I structured everything.
The short version: Apple's fast on-device machine-learning framework needs the full Xcode toolchain to compile its GPU code, and the way I build the app from the command line does not have that, so I cannot compile the model layer natively. Rather than fight it, I accepted it: the model work stays in Python, which can load and run those models without that toolchain, and gets bundled into the app so the user never has to install anything. Note that the primary driver of the architecture here was not what I wanted, rather what actually builds — and designing with the real constraint instead of against it saved me from a long, losing fight.
The upside of accepting it is that the boundary is now clean: native Swift for everything that has to be fast and system-level, embedded Python for the model work, and a clear line between them. A constraint I did not choose ended up giving the app a sensible structure.
The general lesson, especially as a non-engineer, is that some walls do not move, and the skill is telling those apart from the ones that do. I could have spent weeks trying to force the native path. The constraint was real and permanent, and the productive response was to design a clean seam around it rather than treat it as a bug to defeat. Good architecture is often just an honest accommodation of what your tools will and will not do.
More soon.