“the cross-repo trap.”

Late-night fire drill that turned into a deploy-hygiene fix.

The symptom

POST /api/chats returning 500 immediately after a SR8 redeploy. Stack trace pointed straight at Agent.__init__() rejecting a kwarg one_call_per_iteration that werbos was passing on every session construction.

The trap underneath: werbos/session/chat.py had been bumped to pass that kwarg, but pyproject.toml was still pinned at an older pitts SHA (107adb2) that didn’t accept it. The local editable checkout of pitts had the matching code, but uncommitted — so local tests passed, the live SR8 build broke. Cross-repo half- finished change.

Fix in two layers

  • Layer 1 — pitts upstream. Commit + push the one_call_per_iteration safety belt (pitts c8e1867), then bump the werbos pin (7c07747) to consume it. 2 regression tests for the dispatch behavior: with the flag, only the FIRST tool_call from a multi-call AssistantMessage fires; the model re-decides on iteration N+1.
  • Layer 2 — the deploy trap that produced the bug. The bigger realization was why I’d missed the version mismatch: deploy/sr8/redeploy.sh only git pulled the werbos repo, but the docker build context on SR8 copies nine sibling repos (pitts, pfm, mcculloch, partyparrot-py, observe, watchtower, warden, beacon, werbos-suite-ui) directly into the build context. Pulling only werbos silently shipped stale sibling code. Re-bake the script (1a4f369) to pull every expected sibling, --ff-only so divergence surfaces loudly, skip any repo with uncommitted work. Trap closed permanently.

Phase 17 / Sprint NP.1 — npm install -g werbos

Captured the npm-wrapper plan as a sprint on the roadmap (d8f48f5). Architecture: thin JS shim over system Python, child_process.spawn('python3', ['-m', 'werbos', ...]) — no bundled Python (~40 MB × 3 platforms is the wrong trade for Phase 1), no Node-Python bridge dependency. Lockstep version with the PyPI wheel; mac + linux only for Phase 1; Tauri explicitly deferred.

The acceptance criterion locked early: a clean machine with only python3 + node installed must run npm install -g werbos and end up with a working werbos binary that pulls in every needed file, sets up data directories, and launches both werbos chat and werbos serve end-to-end. Real test, not “the install succeeded.”

Aphorism worth keeping

“Pulling only werbos silently shipped stale sibling code.”

Cross-repo changes need cross-repo deploys. The lesson the trap taught: redeploy.sh is part of the codebase, not just an operator note. If the script lies about what it pulls, the build will eventually disagree with the source.