forge v0.3.0 — command sandbox and structured logs
forge v0.3.0 — command sandbox and structured logs
M5 is complete. This release closes the last two modules — the tool sandbox (#4) and full logging (#7) — and brings the offline test suite to 247 cases with CI now covering every module.
Highlights
- Command sandbox (#4) —
run_commandno longer executes straight on your machine:sandbox.mode: auto(default) runs inside Docker when it is available and otherwise falls back to hardened local execution;dockerrefuses to run at all without a daemon (use it in production);local/offfor explicit control- container runs are locked down:
--rm --network=none(no network by default), memory/CPU/PID caps, read-only rootfs with a writable/tmp, non-root user, working directory mounted read-only, and the container is force-removed on timeout - the local fallback still buys real protection: host-env allowlist, dangerous-command patterns (
rm -rf /,mkfs,ddto raw devices,shutdown…), timeout kill, output clipping - security fix: the old
run_commandhanded the wholeos.environto the child process — any command could readDEEPSEEK_API_KEY. The environment is now allowlisted - try it:
/sandbox(status) ·/sandbox mode docker(hot-reloaded) ·/sandbox test echo hi
- Structured logs (#7) — one JSON line per event in
data/logs/forge-YYYYMMDD.jsonl: daily files with size rotation, retention pruning, level filtering, per-run correlation ids (role / model / steps / tools / tokens / latency) and an HTTP request log- secret redaction: values under
key/token/secret/authorizationfields and anything shaped likesk-…/Bearer …/gho_…are written as*** - inspect with
/logs,/logs tail 20,/logs errors
- secret redaction: values under
- CI coverage —
test_device.pyandtest_voice.pyexisted but were never wired into CI; they are now, together with the new sandbox/logging suite
Fixes
- sandbox: a truthy default on
Sandbox.__init__(mode="auto")silently overrodesandbox.modefrom config, sodocker/offpolicies behaved asauto— caught by the new tests tools.run_command(): no longer leaks host environment variables to the commands it executes
Tests & CI
247 passed + 1 skipped on Python 3.9 / 3.11 / 3.13. 16 offline test files — no API keys, no network, no container runtime required. The single skip is the networked Edge-TTS case, by design.
Install
pip install "git+https://github.com/musokean/forge.git"
pip install "handcraft-agent[server] @ git+https://github.com/musokean/forge.git" # + HTTP APIforge # interactive chat — try /sandbox and /logs
forge --serve # HTTP API (Swagger at /docs)Notes
- The Docker isolation path is asserted parameter-by-parameter in the suite and needs no container runtime in CI; verifying it against a real container requires Docker installed on the host.
- Still open: hardware Phase 1 (real device link), voice Phase 2/3 (barge-in / streaming), client executor module.