publish(role=...) has recorded provenance since the namespace split; this
wires the enforcement the role was reserved for. SGLANG_ROLE_NAMESPACES
selects the mode:
- off (default): no bookkeeping; the mode gate in config_bag stays a
dead-branch-prunable check under dynamo (bag reads run inside compiled
forwards — pinned by a fullgraph test).
- record: audit mode — collect (role, namespace) pairs per process and
persist each new pair immediately to SGLANG_ROLE_NAMESPACES_OUT (worker
teardown skips atexit), plus a per-process stderr summary at exit.
- enforce: a bag read outside the role's ROLE_NAMESPACE_SETS entry fails
closed with an actionable error; None entries mean full tree.
Sets are filled only where audits back them: dp_controller reads only
exec (record-mode plain + DP-attention smokes agree with the module's
static read set — the elastic-EP gate). tokenizer observed zero bag
reads (per-instance managers read self.server_args by design) but keeps
the full tree until the multi-tokenizer disagg shape (TokenizerWorker's
get_disagg read) is audited; encoder / expert_backup /
weight_cache_daemon likewise await their deployment shapes.
Verified end-to-end: DP-attention smoke under enforce boots and serves
with zero violations.