T-HUB/infra/occupymedia/element/apply-auth-branding.py
glass beadian b89dea5c93 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.
2026-10-14 08:04:56 +00:00

46 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Merge the auth-only patch into an existing, file-bind-mounted Element config."""
import argparse
import copy
import json
from pathlib import Path
def merge(current, patch):
for key, value in patch.items():
if isinstance(value, dict):
if not isinstance(current.get(key), dict):
current[key] = {}
merge(current[key], value)
else:
current[key] = value
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("config", type=Path)
parser.add_argument("--write", action="store_true", help="write in place; otherwise print a preview")
args = parser.parse_args()
patch = json.loads(Path(__file__).with_name("auth-branding.patch.json").read_text())
# r+ intentionally retains the inode: replacing this file would leave an
# existing Docker single-file bind mount serving the old config.
with args.config.open("r+" if args.write else "r", encoding="utf-8") as config_file:
current = json.load(config_file)
if not isinstance(current, dict):
raise ValueError("Element config must be a JSON object")
original = copy.deepcopy(current)
merge(current, patch)
for key in ("setting_defaults", "default_theme", "default_server_config", "default_server_name"):
assert current.get(key) == original.get(key), f"Auth patch must preserve {key}"
output = json.dumps(current, indent=2, ensure_ascii=False) + "\n"
if args.write:
config_file.seek(0)
config_file.write(output)
config_file.truncate()
else:
print(output, end="")
if __name__ == "__main__":
main()