Coordination server for the Burnout Paradise decompilation workflow.
This service prevents multiple agents from claiming the same translation unit at the same time. It stores live work status, owners, leases, goals, dependencies, and an event log. It does not store reconstructed code, IDA exports, leaked references, dossiers, or other decompilation evidence.
This repo contains an MVP server:
- FastAPI HTTP API.
- Live web dashboard at
/. - SQLite-backed store for local/dev deployment.
- Atomic TU claims.
- Lease expiry for abandoned work.
- Dependency-ranked
nextcompatible with the existingwork nextbehavior. - Import from
BP-Decomp_Workflow/progress. - Append-only event log.
- Server-sent events stream for real-time dashboard refresh.
- GitHub repo overview (info, recent commits, file tree) on the dashboard.
- Explorer panel to search/filter/sort every TU and function, with a detail drawer showing the data handed to agents (deps, dependents, funcs, goals).
- Git-derived contribution attribution per agent: "contributed to" (any
surviving-line author) and "primary on" (dominant author).
class:TUs are attributed viaprogress/class_homes.json; the dashboard shows only GitHub-verifiable data (git-reconstructed events are hidden by default,BP_HIDE_RECONSTRUCTED=0to reveal). - File-tree entries and TU destinations link straight to the file on GitHub.
- Burnout Paradise themed dashboard (drop a
logo.pnginto the static folder). - Small stdlib HTTP client for
work.pyintegration.
PostgreSQL is the right production database once more people are using it, but the public protocol should not need to change.
From the repo root, launch.ps1 sets up a local .venv, refreshes the database
from the workflow checkout, and serves. It resolves every path relative to
itself, so the repo can live anywhere.
.\launch.ps1 # serve on 127.0.0.1:8765
.\launch.ps1 -HostName 0.0.0.0 -Port 8765 # bind for LAN access
.\launch.ps1 -NoImport # serve existing db, skip importBy default the workflow checkout is expected as a sibling folder
(..\BP-Decomp_Workflow). Override with -WorkflowRoot <path> or the
BP_WORKFLOW_ROOT environment variable; override the database with -Db or
BP_WORK_DB.
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e .[dev]bp-work-server --db data\bp-work.sqlite3 import ..\BP-Decomp_Workflow --resetExpected scale for the current workflow snapshot:
4319 TUs
27549 funcs
21548 dependency edges
3 goals
bp-work-server --db data\bp-work.sqlite3 serve --host 0.0.0.0 --port 8765Health check:
Invoke-RestMethod http://localhost:8765/healthDashboard:
http://localhost:8765/
Ask for the next ranked work item:
Invoke-RestMethod "http://localhost:8765/next?n=5"Claim work:
Invoke-RestMethod http://localhost:8765/claims `
-Method Post `
-ContentType "application/json" `
-Body '{"tu":"GameSource/Foo/Bar.cpp","agent":"adrian-codex-1","lease_seconds":7200}'The dashboard mirrors a GitHub repository (default BurnoutDecomp/b5-decomp on the
dev branch): description, stars/forks/issues, recent commits, and the file
tree. The browser only talks to this server's /github/overview endpoint; the
server proxies and caches GitHub so every viewer shares one upstream request.
Rate limits are handled in two layers: a per-resource TTL plus conditional
ETag requests (GitHub does not count 304 Not Modified responses against
the limit). Unauthenticated access allows 60 requests/hour; set a token to raise
it to 5000/hour.
$env:GITHUB_TOKEN = "ghp_xxx" # optional, raises the rate limit
$env:BP_GITHUB_OWNER = "BurnoutDecomp" # optional overrides
$env:BP_GITHUB_REPO = "b5-decomp"
$env:BP_GITHUB_REF = "dev"The dashboard's Explorer is backed by read-only JSON endpoints:
GET /api/facets # filter options: sources, statuses, goals
GET /api/tus # search/filter/sort TUs (q, status, source, goal, owner, sort, order, limit, offset)
GET /api/tu?id=<tu> # full detail for one TU (funcs, deps, dependents, goals)
GET /api/funcs # search functions (q, status, tu, limit, offset)
sort accepts id, funcs, updated, status, or queue (dependency-ranked,
matching next).
When commits reach b5-decomp (or the workflow's progress/ files) outside the
server's normal claim/submit flow, refresh the server's derived state: re-resolve
class homes, re-import the progress files, then re-warm Git attribution.
The easy way — one command.
-
Local server (this repo's dev DB) — from the server repo:
.\sync.ps1 # backup -> resolve class homes -> import (no reset) -> warm .\sync.ps1 -Reconcile # also reconcile status.json from committed files (promote-only)
-
Remote server (over HTTP) — from the workflow repo:
work server-update # refresh class homes, push, re-import on the server work server-update --reconcile # also reconcile status.json (promote-only)
Both preserve live claims + the event log (no --reset), and sync.ps1 backs up the
DB first (timestamped, never clobbered). The remote path re-warms attribution lazily on
the next dashboard view.
The manual steps (what those commands wrap):
# 1) Workflow repo: refresh the derived inputs from the new commits
cd ..\BP-Decomp_Workflow
git pull # new commits + reconciled status.json
git -C b5-decomp fetch origin dev # local clone needs them for git-blame
python tools\work\resolve_class_homes.py --apply # refresh class TU -> real home-file map
# If the new commits also changed which TUs are done and status.json is not
# already reconciled, regenerate it from the committed files first:
python tools\work\reconcile_from_files.py --apply --no-demote
# 2) Server repo: re-import progress, then re-warm attribution
cd ..\BP-work-server
bp-work-server --db data\bp-work.sqlite3 import ..\BP-Decomp_Workflow
bp-work-server --db data\bp-work.sqlite3 warm-attribution-cache `
--decomp-root ..\BP-Decomp_Workflow\b5-decomp --branch devimport(without--reset) updates TU status/metadata and readsprogress/class_homes.json, preserving existing data.warm-attribution-cacherecomputes Git surviving-line attribution for the new revision. The dashboard also auto-warms when it sees a new repo revision, so the explicit warm is optional.resolve_class_homes.pymaps eachclass:TU to the committed file that holds its code, so class work attributes to its authors instead of a syntheticsrc/classes/<Class>.cpppath; ambiguous classes are left unmapped, never guessed.
There is intentionally no event-reconstruction command. Synthesizing
review_passevents from git history (a removedreconcile-eventstool) produced fabricated events stamped with commit dates; per-person credit is now derived purely from Git attribution. Any reconstructed events left from that era are hidden by default (BP_HIDE_RECONSTRUCTED=0to reveal them).
The header shows /static/logo.png if present and falls back to a B5 mark
otherwise. Drop a Burnout Paradise logo at
bp_work_server/static/logo.png to brand the dashboard; the rest of the theme
adapts around it.
python -m pytest -q
python -m compileall bp_work_serverSee docs/protocol.md.
The BP-Decomp_Workflow integration is opt-in:
$env:WORK_SERVER = "http://your-server:8765"
$env:WORK_AGENT = "adrian-codex-1"
work next
work start "GameSource/Foo/Bar.cpp"When WORK_SERVER is unset, the original local-only work behavior is unchanged.