Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,102 @@ jobs:
env:
BORG_TEST_CODEX_BIN: ${{ github.workspace }}/installer/npm/node_modules/.bin/codex
run: node --test --test-concurrency=1 tests/*.test.mjs providers/*.test.mjs

python-tests:
name: Python tests (${{ matrix.suite }})
runs-on: ${{ matrix.os }}
timeout-minutes: 30
env:
PYTHONDONTWRITEBYTECODE: '1'
strategy:
fail-fast: false
matrix:
include:
- suite: connector
os: macos-14
requirements: installer/requirements.lock
- suite: coordination
os: ubuntu-24.04
requirements: coordination/requirements-core.lock
- suite: installer
os: macos-14
requirements: installer/requirements.lock
- suite: memory
os: ubuntu-24.04
requirements: memory/requirements.txt
- suite: graph
os: ubuntu-24.04
requirements: graph/requirements.txt
- suite: training
os: ubuntu-24.04
requirements: training/requirements.txt
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.12'
cache: pip
cache-dependency-path: ${{ matrix.requirements }}
- name: Install pinned suite dependencies
shell: bash
run: |
if [[ "${{ matrix.requirements }}" == "installer/requirements.lock" ]]; then
python -m pip install --require-hashes -r "${{ matrix.requirements }}"
else
python -m pip install -r "${{ matrix.requirements }}"
fi
- name: Install pinned coordination test runtime
if: matrix.suite == 'coordination'
env:
BORG_CI_RUNTIME_HOME: ${{ runner.temp }}/borg-coordination-runtime
run: |
python -B - <<'PY'
import os
from pathlib import Path
from installer.downloads import executable, unpack

root = Path(os.environ["BORG_CI_RUNTIME_HOME"])
unpack(root, "beads")
print(executable(root, "beads", "bd"))
PY
- name: Prepare portable graph test fixture
if: matrix.suite == 'graph'
env:
BORG_CI_GRAPH_HOME: ${{ runner.temp }}/borg-graph-fixture
run: |
PYTHONPATH=graph/tests python -B - <<'PY'
import os
from pathlib import Path
from test_portable_graph import install_fixture

install_fixture(Path(os.environ["BORG_CI_GRAPH_HOME"]))
PY
- name: Run ${{ matrix.suite }} suite
shell: bash
run: |
case "${{ matrix.suite }}" in
connector)
PYTHONPATH=connector python -B -m unittest discover -s connector -p 'test_*.py'
;;
coordination)
PATH="$RUNNER_TEMP/borg-coordination-runtime/runtime/beads:$PATH" \
PYTHONPATH=coordination python -B -m unittest discover -s coordination/tests -p 'test_*.py'
PATH="$RUNNER_TEMP/borg-coordination-runtime/runtime/beads:$PATH" \
PYTHONPATH=coordination python -B -m unittest discover -s coordination/comms/hub/tests -p 'test_*.py'
;;
installer)
python -B -m unittest discover -s installer -p 'test_*.py'
;;
memory)
python -B -m unittest discover -s memory/tests -p 'test_*.py'
;;
graph)
BORG_HOME="$RUNNER_TEMP/borg-graph-fixture" GRAPH_FEED_LIVE=1 \
python -B -m unittest discover -s graph/tests -p 'test_*.py'
;;
training)
python -B -m unittest discover -s training/tests -p 'test_*.py'
;;
esac
94 changes: 57 additions & 37 deletions RELEASE-INVENTORY.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"excluded_self": "RELEASE-INVENTORY.json",
"file_count": 396,
"file_count": 400,
"files": [
{
"bytes": 1914,
"path": ".github/workflows/site.yml",
"sha256": "6bfdccbe0a3994dba7c402c2f7a2e0713de367e92476c68f680bc87439e7d1cf"
},
{
"bytes": 1756,
"bytes": 5498,
"path": ".github/workflows/verify.yml",
"sha256": "d97bb88a2b4944ebdaa16b70322c11f1ac568c35d9321cdb9ed133fa4573e38b"
"sha256": "cb97b2990c3af1b3831c9a940df64e7f6def1287ae73e0e718c5a2d2e380a902"
},
{
"bytes": 29,
Expand Down Expand Up @@ -128,14 +128,14 @@
"sha256": "da78048f938980354dc1572d7c7b74693a5f672979f2453ab71ddd70eb41ae0f"
},
{
"bytes": 5952,
"bytes": 6343,
"path": "conductor/INTEGRATION.md",
"sha256": "e80f558ee37bbaa1fa62f1cf7a3a3831e0c00d1265c09734e800e6e74a0bce81"
"sha256": "696bd18dcc8961ebcad6bc32ba4d539465683004761a7766c1de9eb11fc0eaf1"
},
{
"bytes": 5446,
"bytes": 6147,
"path": "conductor/README.md",
"sha256": "851a3a2f15704bd767d5652d5290f4a14067ee54fcc6f4acac5fa84c6132a37e"
"sha256": "40137a28aba61cf7e3e07fe436a9705b19826888227175669ed321368dcbfb28"
},
{
"bytes": 1007,
Expand All @@ -148,29 +148,29 @@
"sha256": "16bfcbc021204e2086955c420d65b7e384cabaa74f9a032438bcf62467771f9d"
},
{
"bytes": 26418,
"bytes": 30170,
"path": "conductor/conductor.mjs",
"sha256": "7e01bd436fe0c1242ff0128290ed43f05a4123c688b06b6b4d721e56ebbc06c0"
"sha256": "188db1b61294f411ef87bdbf54596585469776c281b7f3ddde98aacdefe29870"
},
{
"bytes": 1794,
"bytes": 1827,
"path": "conductor/config.example.json",
"sha256": "7c448cc4badca7720cedc54cd5f7fc4e39b28fcdc70d835a46a075e13f3bc3d9"
"sha256": "86e3459fd8ecf7f619323e549d4a910638698c47d0ef4e15eae7a27d6462802a"
},
{
"bytes": 12451,
"bytes": 12901,
"path": "conductor/config.mjs",
"sha256": "70dd4729fc315ac92566cc9c07b99221e402bad73d43e06a9f02b24e11461db6"
"sha256": "f65fdc54b8ef4d8e153299ab478e87e36a8b7e2813bd5ac77eceb7086baaeacb"
},
{
"bytes": 730,
"path": "conductor/docs/EVENTS-PAGINATION.md",
"sha256": "b90a21d7341dbfd3f8279eaedbb0367c2eed019e9eca3906ecb27f339d3d7b04"
},
{
"bytes": 7276,
"bytes": 8448,
"path": "conductor/docs/LAUNCH-RELIABILITY.md",
"sha256": "88e58e20a4817726a851a902193f3700c0c93bcffb471e664c0abb99c156dac8"
"sha256": "c6944b0ff09d2951a502d2bf151c1f58b2a73525f97e8b3f0fec29329789425f"
},
{
"bytes": 2673,
Expand All @@ -182,6 +182,11 @@
"path": "conductor/docs/protocol-notes.md",
"sha256": "b9cb66dc771323af67a9080c30385ccae63faf209b03a2a3832c719527f857bc"
},
{
"bytes": 3398,
"path": "conductor/http-auth.mjs",
"sha256": "fd0b2eec1968b5d9aa9dbbc39d38f6f88c310d7dc7bfdf372e81cbb8ea5068f6"
},
{
"bytes": 506,
"path": "conductor/package.json",
Expand All @@ -208,19 +213,19 @@
"sha256": "dc2f397239ace8ad8f31375c1c9c064148ec7956396be9408b32df15d0a35a4f"
},
{
"bytes": 3139,
"bytes": 4169,
"path": "conductor/router/receipt-reader-worker.mjs",
"sha256": "5810e5fbcf95a09c089f74befde10bf691dfad3ebee79c476a2c193cc9dc23a9"
"sha256": "87692446392c7454a68d1b9d6d9bef123a1a948d434fd1439305b6ae72d0810f"
},
{
"bytes": 2740,
"bytes": 3163,
"path": "conductor/router/receipt-reader.mjs",
"sha256": "529a8ddfc636174029dbc45b92f62edc6ce21362ec0c7081ac337ce4f412066d"
"sha256": "6a6e00355c1635f9057d5744553ad9adf562134f43ddc15e97d694d4888053e8"
},
{
"bytes": 30846,
"bytes": 47501,
"path": "conductor/router/router.mjs",
"sha256": "21dae5b306a32828eaa467dbd906d04229bb93d13997b6709c1298464ac12296"
"sha256": "a162d59f963a63a6d16b87466eeb6e477851ea8042fa321d4cc4484e9862109b"
},
{
"bytes": 7600,
Expand All @@ -233,30 +238,40 @@
"sha256": "e88a460e968cd42453b691fade79e97f5ef62af081362bd506fde0b1134742a2"
},
{
"bytes": 4707,
"bytes": 5403,
"path": "conductor/tests/config.test.mjs",
"sha256": "de4869238830787b4a97e439d6a692b44e3a04c56ab553f8f8cd3c7e090380cf"
"sha256": "031e06a8af00143db161eb4cf9fee785dd274d6e7b18f9c121999bdad1bba8b7"
},
{
"bytes": 8281,
"path": "conductor/tests/http-auth.test.mjs",
"sha256": "d1363c04e8adcc92b9ce85eb874602aa0ded863bedd7606a08e81ff32178ed70"
},
{
"bytes": 3761,
"bytes": 4013,
"path": "conductor/tests/native-app-server.test.mjs",
"sha256": "8e0491bf9e3665e971707d995ed52e0f59d4883d5b03450c57d535178b5b6340"
"sha256": "8ba0f91c04a709178958e651568ff07e480a3ad66e8e7bae0c8c28e97840174e"
},
{
"bytes": 3201,
"bytes": 4129,
"path": "conductor/tests/receipt-reader.test.mjs",
"sha256": "9ee874660a8b68c2138ffe79a00dc004ae5a1046d1eb5faf5ca3faf37dc008be"
"sha256": "aaa5d2f4e69da5b517e917b5b9ee10d284f1cacf8f15acef9592c7ea725d9a76"
},
{
"bytes": 5927,
"bytes": 6190,
"path": "conductor/tests/resume-bookkeeping.test.mjs",
"sha256": "da0d0fdb77326135e7a59805d566788872bec30f54562f793894835ec29228ec"
"sha256": "6314d14eb14f2e39365a3a1cc124787deccb42da834c7c736da4de634f43fde9"
},
{
"bytes": 19262,
"path": "conductor/tests/router-collision-review.test.mjs",
"sha256": "887b542efcd87b1ee7fab0eff8f0f2c453d4dd90f531bbe1fff9d2618bd27996"
},
{
"bytes": 17062,
"path": "conductor/tests/router-lifecycle.test.mjs",
"sha256": "269042e90c330435720b4c6e49aa78d95bce78631a287b3ca793bb6323a45b90"
},
{
"bytes": 11193,
"path": "conductor/tests/router-ownership.test.mjs",
Expand Down Expand Up @@ -923,19 +938,19 @@
"sha256": "364603a5328293467b00765f5aa989d294a5ebd8414d1d9b307997b531b3bc00"
},
{
"bytes": 2957,
"bytes": 3280,
"path": "graph/tests/test_legacy_graphiti_scope_guard.py",
"sha256": "de7da0bf2baae31ab74e1f3afb0f978353fd436834b4be68d0c8c398599007e2"
"sha256": "a107021fef8b8c8d64a465dd5612aa756a037b8bb3f0191747413269aac058a9"
},
{
"bytes": 7624,
"path": "graph/tests/test_parallel_feed.py",
"sha256": "fd62acdc688193d2b0d42c6582882132e735bca9f7384521c47e107809b2dd3f"
},
{
"bytes": 18441,
"bytes": 19636,
"path": "graph/tests/test_portable_graph.py",
"sha256": "6773dfde9b2187a5e67b261382910e586ad9c8282d8937c13797ec81413a823d"
"sha256": "7233df41ebc3d84167e3de1444fbcb6403ec4d24ca4cc31be45c1ac6b36f15d3"
},
{
"bytes": 1308,
Expand Down Expand Up @@ -1033,9 +1048,9 @@
"sha256": "b8573095ab48abf8bede9582452e598afd7118078f6a571d5ee86832f58a7826"
},
{
"bytes": 17826,
"bytes": 19270,
"path": "installer/health.py",
"sha256": "561d1c1c2864a6709189b975e116760fa50342e9b266a6ab7522eb512dba4fb0"
"sha256": "88b70d35ff8e029a90c0ad70a80871a8aa51aff2098e56acdea7213ca9670c2e"
},
{
"bytes": 14377,
Expand Down Expand Up @@ -1122,6 +1137,11 @@
"path": "installer/test_browser.py",
"sha256": "5153cd2ec6e58ee83bf1bf43c4f0e1f22a4ef2cdef6ac7285eed1ea6b9188a57"
},
{
"bytes": 1463,
"path": "installer/test_conductor_auth.py",
"sha256": "44d3aaa890404ef1c6d2a4d4796b84cca10b755d71ba1c9e21d5a85a7860f655"
},
{
"bytes": 2884,
"path": "installer/test_config.py",
Expand Down Expand Up @@ -1983,7 +2003,7 @@
"sha256": "cd4bdb4529012e0cfcd38e059215f9ea433b8ee1fa636276b36c6515e7949e28"
}
],
"inventory_sha256": "23769a5f267e127828ca7376832656052cd92035ab9af3b2537bd13d00cce849",
"inventory_sha256": "927bc4b7fc93fcc354eea91f24337b98d289d616292f38fab72c87a95eb85cac",
"schema": "borg-public-inventory/v1",
"total_bytes": 87983389
"total_bytes": 88047043
}
15 changes: 10 additions & 5 deletions conductor/INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ $BORG_HOME/
runtime/npm/node_modules/.bin/codex
conductors/config.json # conductor-owned schema
conductors/primary/profile/
.conductor/http-token # generated bearer credential, mode 0600
conductors/primary/logs/
policies/SEAT-RULES.md
policies/LEAD-RULES.md
Expand Down Expand Up @@ -92,7 +93,10 @@ CONDUCTOR_LOGS=/absolute/path/to/borg/conductors/primary/logs \

The root installer owns service management. Readiness is the interaction-backed
`GET /status` response with `ok: true`, the configured port and the exact
configured `codexHome`; a listening process alone is not readiness proof.
configured `codexHome`; a listening process alone is not readiness proof. The
shipped CLI reads the profile-local bearer token automatically. External local
supervisors may use token-free `GET /healthz` only for process liveness; it is
not conductor initialization or provider readiness proof.

## 3. Status and native authentication

Expand Down Expand Up @@ -136,10 +140,11 @@ BORG_HOME=/absolute/path/to/borg \
--effort high
```

`rank` is read-only. `route` is the only dispatch entrypoint; it writes private
intent/receipt evidence and then uses the existing conductor thread and turn
protocol. Root should never dispatch directly to a port when fleet admission
or duplicate protection is required.
`rank` never dispatches work, but it reconciles and may archive private receipt
evidence before scanning claims. `route` is the only dispatch entrypoint; it
writes private intent/receipt evidence and then uses the existing conductor
thread and turn protocol. Root should never dispatch directly to a port when
fleet admission or duplicate protection is required.

## Multi-machine or multi-account extension

Expand Down
14 changes: 12 additions & 2 deletions conductor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ or external queue. A one-machine, one-lane configuration is valid.
- Node at the root-provided executable inside `$BORG_HOME/runtime/`
- Codex at `$BORG_HOME/runtime/npm/node_modules/.bin/codex`
- HTTP bound only to `127.0.0.1:$PORT`
- Per-profile bearer token at `$CODEX_HOME/.conductor/http-token`, mode `0600`

The conductor creates a 32-byte random token on first start and defaults to
`CONDUCTOR_AUTH=enforce`. All shipped router and installer health calls read
that profile-local token and send it as a bearer credential. `GET /healthz` is
the only token-free endpoint; it returns only `{ "ok": true }`. Host and browser
origin checks apply to every endpoint in both `report` and `enforce` modes.
`POST /rpc` accepts only `account/read`, `account/rateLimits/read`, `model/list`,
`thread/read`, `hooks/list`, and `config/read`.

Fresh installs contain no provider authentication. The owner authenticates the
dedicated profile with native `codex login`, then pins the observed account
Expand All @@ -57,8 +66,9 @@ remaining usable native allowance; earliest reset is only the tie break.
Actual provider exhaustion and provider spend controls have separate evidence
codes. No discretionary reservation or allowance floor is created.

Dispatch holds a private lock, persists an intent before admission scans,
rechecks the configured fleet before selection, and refuses duplicate
Dispatch holds a private lock, reconciles active receipts from exact native
`thread/read` evidence, archives aged terminal receipts, persists an intent
before admission scans, rechecks the configured fleet before selection, and refuses duplicate
`{workId,cwd}` intents across process restarts. Workspaces are compared by
filesystem-canonical identity, so aliases and parent/child paths overlap. Active
workspace and work-ID claims, including this router's own receipts under any
Expand Down
Loading
Loading