feat: parliament seat collaboration loop (0.9.19)

Seats publish via parliament_note, sync pushes on write, member join without
stealing the chair, and worker tools are hard-gated when parliament is active.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-10-29 11:29:38 +08:00
co-authored by Cursor
parent 1605d74f17
commit 812e3ee265
15 changed files with 532 additions and 83 deletions
+7 -15
View File
@@ -17,6 +17,7 @@
#include "cJSON.h"
#include "cst_agent.h"
#include "cst_parliament.h"
#include "cst_skills.h"
#include "cst_tools.h"
#include "cst_runtime.h"
@@ -775,14 +776,9 @@ static int task_run(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *c,
(void)ud;
if (!ctx->agent)
return out_text(r, 1, "error: task needs a running agent");
{
cst_settings_t s; cst_settings_load(&s);
const char *mode = getenv("CST_COLLABORATION");
if ((!mode || !mode[0]) && s.collaboration[0]) mode = s.collaboration;
if (mode && !strcmp(mode, "parliament"))
return out_text(r, 1, "error: collaboration=parliament replaces in-process "
"workers; use Realm peer seats");
}
if (cst_parliament_is_active())
return out_text(r, 1, "error: parliament mode replaces in-process workers; "
"publish parliament_note and coordinate via peer seats");
const cst_agent_config_t *pcfg = cst_agent_config(ctx->agent);
if (pcfg->depth > 0)
return out_text(r, 1, "error: a sub-agent cannot start sub-agents; do "
@@ -1197,13 +1193,9 @@ static int async_worker_tool(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *c
if (!ctx->agent) return out_text(out, 1, "error: no agent");
const cst_agent_config_t *cfg = cst_agent_config(ctx->agent);
if (cfg->depth || !cfg->runtime) return out_text(out, 1, "error: only the main agent can schedule workers");
{
cst_settings_t s; cst_settings_load(&s);
const char *mode = getenv("CST_COLLABORATION");
if ((!mode || !mode[0]) && s.collaboration[0]) mode = s.collaboration;
if (mode && !strcmp(mode, "parliament"))
return out_text(out, 1, "error: collaboration=parliament replaces in-process workers; use Realm peer seats");
}
if (cst_parliament_is_active())
return out_text(out, 1, "error: parliament mode replaces in-process workers; "
"use parliament_note and Realm peer seats");
if (strcmp(c->name, "worker_start")) {
const char *wt = arg(c, "worktree"); int code;
if (wt && cst_runtime_resource_busy(cfg->runtime, wt)) return out_text(out, 1, "error: worker is still using this worktree; wait before review/integration");