feat: per-connection publish governance — auto, 1-admin, majority, consensus

Per the owner's spec: each social connection gets publishGovernance in its
fields — unset = manual publish (today), auto = dispatch on approval,
admin1/admin_majority/admin_consensus = a publish-phase chatgov poll
(subject draft_publish, its own open-poll slot, no collision with review
gates). Dispatch holds until the publish poll passes (E3 pre-dispatch
check); auto dispatches on approval. Includes migration 033, the PATCH
/connections/:id/publish-governance route (chatgov.manage), and 19+31 new
tests. Implementation by the branding-panel process (claude/opus), lint
and integration fixes here.
This commit is contained in:
glass beadian 2026-10-14 08:04:56 +00:00
parent f2eb14956e
commit b89dea5c93
26 changed files with 1637 additions and 31 deletions

View file

@ -103,6 +103,19 @@ http {
listen [::]:80;
server_name chat.occupymedia.cc;
# Tunnel origin path: the branded client on this host, Matrix API to the homeserver.
# Element redirects first-time phone visitors here before loading config.
# Send them to the form rather than the separate Element app-download hero.
location = /mobile_guide/ {
# Preserve the browser's HTTPS origin even on the tunnel's HTTP hop.
absolute_redirect off;
return 302 /#/login;
}
location = /hub-chat-auth.css {
alias /opt/occ-chat-brand/hub-chat-auth.css;
default_type text/css;
add_header X-Served-By occ-edge always;
add_header Cache-Control "no-cache" always;
}
location ^~ /_matrix {
proxy_pass http://100.117.210.52:6167;
proxy_http_version 1.1;
@ -131,6 +144,12 @@ http {
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Hash routes never reach nginx. Inject into the SPA HTML shell; the
# stylesheet only targets mx_AuthPage and leaves signed-in rooms alone.
proxy_set_header Accept-Encoding "";
sub_filter '</head>' '<link rel="stylesheet" href="/hub-chat-auth.css?v=1"></head>';
sub_filter_once on;
# text/html is sub_filter's default type; JSON/JS/CSS are not rewritten.
proxy_read_timeout 60s;
}
}
@ -143,6 +162,17 @@ http {
ssl_certificate /etc/letsencrypt/live/occupymedia.cc/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/occupymedia.cc/privkey.pem;
location = /mobile_guide/ {
absolute_redirect off;
return 302 /#/login;
}
location = /hub-chat-auth.css {
alias /opt/occ-chat-brand/hub-chat-auth.css;
default_type text/css;
add_header X-Served-By occ-edge always;
add_header Cache-Control "no-cache" always;
}
location ^~ /_matrix {
proxy_pass http://100.117.210.52:6167;
proxy_http_version 1.1;
@ -176,6 +206,9 @@ http {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Accept-Encoding "";
sub_filter '</head>' '<link rel="stylesheet" href="/hub-chat-auth.css?v=1"></head>';
sub_filter_once on;
proxy_read_timeout 60s;
}
}