feat: channel-to-workspace routing control plane (epic #30)#39
feat: channel-to-workspace routing control plane (epic #30)#39drpedapati wants to merge 6 commits intodevelopmentfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 86563ecc38
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if err != nil { | ||
| return nil, err | ||
| } | ||
| return agent.NewAgentLoop(cloned, msgBus, provider), nil |
There was a problem hiding this comment.
Register cron tooling on routed workspace loops
This pool factory creates routed handlers with agent.NewAgentLoop(...) only, but the cron tool is wired separately on the singleton gateway loop via setupCronTool. In routing mode, user traffic is handled by these pooled loops, so mapped chats lose the cron tool and reminder/scheduling requests that work in non-routing mode will fail for routed workspaces.
Useful? React with 👍 / 👎.
| if cfg.Routing.Enabled { | ||
| resolver, err := routing.NewResolver(cfg) |
There was a problem hiding this comment.
Initialize routing dispatcher even when startup flag is off
Routing dispatch/reload is only started when cfg.Routing.Enabled is already true at gateway boot. If operators start from the default disabled state and then run sciclaw routing enable plus sciclaw routing reload, there is no running watcher/dispatcher to apply it, so messages keep flowing through the non-routing path and ACL/mapping enforcement does not take effect until a full restart.
Useful? React with 👍 / 👎.
| if strings.TrimSpace(out.UnmappedBehavior) == "" { | ||
| out.UnmappedBehavior = config.RoutingUnmappedBehaviorBlock |
There was a problem hiding this comment.
Preserve unmapped behavior on partial routing imports
mergeRouting is written to keep the current unmapped_behavior when the import omits it, but decodeRoutingPayload force-fills empty values with block first. That means a mapping-only import silently changes an existing default policy back to block, altering routing behavior even though the input did not specify a policy change.
Useful? React with 👍 / 👎.
Summary
Implements collaborative routing so each chat room/thread can map to a dedicated workspace with per-mapping sender ACLs, plus operations CLI and runtime reload support.
Included
routing.enabled,unmapped_behavior,mappings[])(channel, chat_id)matchingAgentLooppool (lazy create + reuse)<channel>:<chat_id>@<workspace_hash>routing status/list/add/remove/set-users/validate/explain/enable/disable/import/export/reload)sciclaw routing reload) via resolver replacement in running gatewayroute_match,route_unmapped,route_deny,route_invalid, reload success/failure logs)Commits
f7f9effconfig schema + validationfe119d9resolver + dispatcher + loop pool8451582routing CLI14d77c6doctor diagnosticsbdba7caruntime hot reload trigger86563ecdocs/runbookVerification
go test ./pkg/config ./pkg/routing ./pkg/agent ./cmd/picoclawCloses #30