- Deterministic scoring.py (quant 60 / qual 40 / flags -15, profitability heaviest) - Per-company JSON ledger with forecast-target chaining deck N-1 -> N - Single-shot sandbox agent with guided-JSON fallback ladder (no tool loop) - Portfolio dashboard with sparklines, KPI hit rates, BDEF category bars - 48 unit tests green; endpoints smoke-tested; npm check+build green Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import { sdk } from './sdk'
|
|
import { WEB_UI_PORT } from './interfaces'
|
|
|
|
export const main = sdk.setupMain(async ({ effects }) => {
|
|
// Mount the persistent volume at /data: config.json, ssh key, optional HF
|
|
// token, the per-company deck inbox, job run state, and saved scorecards /
|
|
// ledgers all live here.
|
|
const mounts = sdk.Mounts.of().mountVolume({
|
|
volumeId: 'main',
|
|
mountpoint: '/data',
|
|
subpath: null,
|
|
readonly: false,
|
|
})
|
|
|
|
const sub = await sdk.SubContainer.of(
|
|
effects,
|
|
{ imageId: 'main' },
|
|
mounts,
|
|
'boardroom-webui',
|
|
)
|
|
|
|
// The web UI runs the FastAPI app AND, in a background thread, the Boardroom
|
|
// Map job runner (which extracts dropped decks, serves the chosen models on
|
|
// the Sparks in waves, runs the grading panel + adjudicator, computes the
|
|
// deterministic composite, and updates each company's scorecard ledger).
|
|
return sdk.Daemons.of(effects).addDaemon('webui', {
|
|
subcontainer: sub,
|
|
exec: {
|
|
command: [
|
|
'uvicorn',
|
|
'app:app',
|
|
'--host',
|
|
'0.0.0.0',
|
|
'--port',
|
|
String(WEB_UI_PORT),
|
|
],
|
|
cwd: '/app',
|
|
env: { BM_DATA_DIR: '/data' },
|
|
},
|
|
ready: {
|
|
display: 'Web Interface',
|
|
fn: () =>
|
|
sdk.healthCheck.checkPortListening(effects, WEB_UI_PORT, {
|
|
successMessage: 'The control panel is ready',
|
|
errorMessage: 'The control panel is not yet listening',
|
|
}),
|
|
},
|
|
requires: [],
|
|
})
|
|
})
|