#ifndef CST_PARLIAMENT_H #define CST_PARLIAMENT_H #include "cst_realm.h" #include #ifdef __cplusplus extern "C" { #endif /* Parliament is one shared whole across agents. Password unlock claims the * single chair on the logging-in device; peers sync the same context. A new * project replaces all parliament context. */ typedef struct { char parliament_id[64]; char project_id[64]; char chair_instance[64]; char chair_device[128]; unsigned long revision; char status[32]; /* idle | open | dissolved */ } cst_parliament_meta_t; int cst_parliament_path(char *out, size_t n); int cst_parliament_load(cst_parliament_meta_t *m); int cst_parliament_save(const cst_parliament_meta_t *m); /* Login: unlock Realm with password, enroll/ensure instance, claim chair, * return handover summary (malloc'd) or NULL. */ char *cst_parliament_login(const char *password, const char *instance_id, const char *device_label, char *err, size_t err_sz); /* Join as a peer seat without stealing the chair (claims only if vacant). * Returns JOIN_OK summary (malloc'd) or NULL. */ char *cst_parliament_seat_join(const char *password, const char *instance_id, const char *device_label, char *err, size_t err_sz); /* Only one chair: previous chair is demoted; handover notes left in meta. */ int cst_parliament_claim_chair(const char *instance_id, const char *device_label); /* Probe local environment as device-private context (malloc'd text). */ char *cst_parliament_device_context(void); /* Prefer CST_INSTANCE_ID, else sanitized hostname (never empty). */ int cst_parliament_default_instance(char *out, size_t n); /* New project: wipe shared parliament context; keep Realm keys. */ int cst_parliament_new_project(const char *project_id); /* Resolve collaboration mode: env CST_COLLABORATION, then settings, * then password-Realm with an open parliament → "parliament". */ int cst_parliament_is_active(void); /* 1 when the local seat ticket matches the current chair. */ int cst_parliament_is_chair(void); /* Short status lines for TUI/CLI (malloc'd; caller frees). */ char *cst_parliament_status_text(void); /* Append/replace synchronized context blob (all agents share this file). */ int cst_parliament_context_put(const char *text); char *cst_parliament_context_get(void); /* Append a structured seat note and bump revision (triggers peer sync). * kind: status | agenda | result | handover | note */ int cst_parliament_context_append(const char *seat_id, const char *kind, const char *body); /* Ask the local parliament service to dial peers soon (best-effort). */ void cst_parliament_sync_request(void); int cst_parliament_sync_pending(void); void cst_parliament_sync_ack(void); /* Local login ticket: opens require a fresh seat session (or password env). * Any enrolled seat may hold a ticket; chair is tracked separately in meta. */ int cst_parliament_session_write(const char *instance_id); int cst_parliament_session_ok(char *instance_id_out, size_t n); void cst_parliament_session_clear(void); /* Apply a peer sync bundle (higher revision already selected by caller). */ int cst_parliament_apply_sync(unsigned long revision, const char *parliament_id, const char *project_id, const char *chair, const char *context); /* Background parliament service: discover + peer listen + context sync. */ int cst_parliament_daemon_pidfile(char *out, size_t n); int cst_parliament_daemon_running(void); /* Read pidfile metadata. Returns 0 when a live service is recorded. */ int cst_parliament_daemon_info(int *pid_out, char *instance_out, size_t in_sz, int *port_out); /* Start in background (Unix fork). password unlocks Realm in the child. * Returns 0 and writes pid. Restarts if a different instance/port is running. */ int cst_parliament_daemon_start(const char *password, const char *instance_id, int peer_port, char *err, size_t err_sz); int cst_parliament_daemon_stop(void); /* Foreground service loop (used by --service and the forked child). */ int cst_parliament_daemon_run(const char *password, const char *instance_id, int peer_port, char *err, size_t err_sz); #ifdef __cplusplus } #endif #endif