Local distribution
One workstation.
Two clean packages.
Forge Local separates the governed Python server from the static browser
client. They install together on one Mac, bind on loopback, and need no remote worker,
shared control plane, Docker host or source checkout.
1Package shape
Server and client have different jobs
⚙Local server
Compiled Python runtime,
Forge APIs, governance, integrations, workspace templates and native-tool orchestration.
It contains no browser frontend in the split build and reads no credential from the
package.
server/forge-local-server · forge.backend-package.v1
▣Browser client
Static HTML, JavaScript,
CSS and images only. Inline code is split into fingerprinted assets; Settings is
lazy-loaded; immutable assets can be cached independently from the HTML shell.
client/forge-local-client · forge.frontend-package.v1
The binding is explicit.The local launcher sets
FORGE_FRONTEND_DIR to the verified client directory. The server remains the
security and data boundary; the client contains no Python, configuration, credentials,
tests or repository history.
Measured current client.The verified v3.1 package serves a
105,970-byte HTML shell. The complete compressed client archive is 5.7 MB;
roughly 5.3 MB is optional image content, principally the Forge Pet atlas. The shell
is light; the visual asset pack remains the next meaningful client-size target.
2Build
Create the local package set
venv/bin/python tools/build_local_packages.py \
--output dist/local/forge-local-<release> \
--runtime-root /path/to/self-contained/python-3.12 \
--site-packages venv/lib/python3.12/site-packages \
--signing-key /private/path/to/forge-release-key.pem
Development builds may replace --signing-key with the explicit
--unsigned-development flag. Never put a signing key, connector token, runtime
state or generated evidence inside either artifact.
3Verify and run
Prove the bytes before startup
1Verify both manifests
Run
./scripts/verify-local.sh. It checks the package-set archive checksums and
every server/client file digest. A signed server package also verifies its signature.
2Run without installing
Use
./scripts/run-local.sh, then open http://127.0.0.1:8787/.
Unsigned development builds additionally require
FORGE_ALLOW_UNSIGNED_PACKAGE=1.
3Install for the current user
Run
./scripts/install-macos.sh. Add --service to install the
launchd user service. The installer writes a private environment file that joins the
server to the client.
4State and upgrades
Packages are replaceable; evidence is durable
Installed packages
Versioned server and client folders live under
~/Library/Application Support/Forge/releases. A current symlink
selects the active pair, making an upgrade or rollback explicit.
Durable local state
Configuration stays under
~/.config/forge; run and evidence state stays under
~/.local/share/forge/state. Upgrading or removing binaries does not silently
delete either location.
Uninstall is recoverable.
uninstall-macos.sh removes the launcher and service while preserving packages
and state. --remove-packages moves release binaries to Trash; it still does not
remove credentials or runtime evidence.
5Readiness
What green means locally
A release is ready when package verification passes, the UI and
/api/health return HTTP 200 on loopback, and the automated suite is green.
Optional connectors may remain warnings. A capability that depends on an unavailable
connector remains blocked honestly; that warning does not prevent unrelated local
capabilities from running.
Source-level instructions:
packages/local/SETUP.md. Architecture decision:
ADR-0002.