mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-18 15:50:25 +02:00
feat(control-pane): live control-plane view with 2D projection and static-threshold advisories
Wire scripts/lib/agent-proximity/ and the #3028 coordination inventory into the control pane as one read-only live view, ecc.control-plane.view.v1, shaped as tasks, lanes and events. - agent-proximity/projection.js: rolling z-score per channel, tails clipped at the 2.5th and 97.5th percentile, mapped back to [0, 1], static channel weights, PCA (Jacobi on the 3x3 covariance) over x_tree, x_overlap, x_dep. Raw mode until the window holds 8 samples. No runtime dependencies. - agent-proximity/index.js: airspace links now carry the per-channel values. - agent-proximity/distance.js: rightOfWay(a, b) extracted from advise(). - control-pane/proximity.js: snapshot includes agent summaries (files, progress, startedAt) so the view can join sessions to working sets. - control-pane/control-plane-view.js: builds the view from the snapshot; advisory events derived from every pair link against the view's static thresholds (ta 0.35, ra 0.7), deterministic ids, steer/hold from rightOfWay; lease conflicts from the inventory as events; inventory manifest built from live sessions with sanitized ids, declared-only. - control-pane/server.js: GET /control-plane (self-contained page with the 2D canvas), GET /api/control-plane, GET /api/control-plane/events; one projection window per server so z-scores roll across polls. - docs/control-plane/VIEW-CONTRACT.md: the task/lane/event contract for reuse by the Ito ops control plane. - docs/control-plane/TCAS-HOOK.md: design for slice (b), not implemented. The view does not acquire leases, steer or pause agents, and claims no conflict-reduction number.
This commit is contained in:
@@ -269,6 +269,65 @@ async function runTests() {
|
||||
passed++;
|
||||
else failed++;
|
||||
|
||||
if (
|
||||
await test('serves the control-plane live view page, the view JSON and the event feed', async () => {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-control-plane-view-'));
|
||||
const dbPath = path.join(tempDir, 'ecc2.db');
|
||||
|
||||
try {
|
||||
await writeMinimalDatabase(dbPath);
|
||||
const app = await createControlPaneServer({
|
||||
host: '127.0.0.1',
|
||||
port: 0,
|
||||
dbPath,
|
||||
repoRoot: REPO_ROOT,
|
||||
allowActions: false
|
||||
});
|
||||
|
||||
await app.listen();
|
||||
try {
|
||||
const page = await fetchLocal(`${app.url}/control-plane`);
|
||||
assert.strictEqual(page.status, 200);
|
||||
assert.ok((page.headers.get('content-type') || '').includes('text/html'));
|
||||
const html = await page.text();
|
||||
assert.ok(html.includes('ECC Control Plane'), 'page is titled ECC Control Plane');
|
||||
assert.ok(html.includes('<canvas'), 'page renders the 2D projection canvas');
|
||||
assert.ok(html.includes('/api/control-plane'), 'page polls the view feed');
|
||||
assert.ok(!html.includes('<script src='), 'page loads no external scripts');
|
||||
|
||||
const view = await fetchLocal(`${app.url}/api/control-plane`).then(r => r.json());
|
||||
assert.strictEqual(view.schemaVersion, 'ecc.control-plane.view.v1');
|
||||
assert.deepStrictEqual(view.thresholds, { ta: 0.35, ra: 0.7, source: 'static' });
|
||||
assert.ok(Array.isArray(view.tasks) && view.tasks.length === 1, 'one session becomes one task');
|
||||
assert.strictEqual(view.tasks[0].id, 'session-a');
|
||||
assert.strictEqual(view.tasks[0].lane, 'harness:codex');
|
||||
assert.ok(Array.isArray(view.lanes) && view.lanes.length === 1);
|
||||
assert.ok(Array.isArray(view.events) && Array.isArray(view.pairs));
|
||||
assert.strictEqual(view.projection.method, 'pca');
|
||||
assert.deepStrictEqual(view.projection.channels, ['x_tree', 'x_overlap', 'x_dep']);
|
||||
assert.strictEqual(view.inventory.status, 'ok');
|
||||
assert.strictEqual(view.inventory.mode, 'read-only');
|
||||
assert.strictEqual(view.counts.tasks, 1);
|
||||
|
||||
const events = await fetchLocal(`${app.url}/api/control-plane/events`).then(r => r.json());
|
||||
assert.strictEqual(events.schemaVersion, 'ecc.control-plane.view.v1');
|
||||
assert.deepStrictEqual(events.events, []);
|
||||
assert.deepStrictEqual(events.counts, { events: 0, advisories: 0, resolutions: 0 });
|
||||
|
||||
// The airspace page links to the new view.
|
||||
const airspace = await fetchLocal(`${app.url}/proximity`).then(r => r.text());
|
||||
assert.ok(airspace.includes('href="/control-plane"'));
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
} finally {
|
||||
fs.rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
})
|
||||
)
|
||||
passed++;
|
||||
else failed++;
|
||||
|
||||
if (
|
||||
await test('serves health, asset, not-found, invalid body, and read-only action responses', async () => {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-control-pane-routes-'));
|
||||
|
||||
Reference in New Issue
Block a user