scratch matrix approval notifier, add chat-native MCP approval tools
Some checks failed
Desktop App / Build Linux (amd64) (push) Waiting to run
Desktop App / Attach to Release (push) Blocked by required conditions
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled

Removes the entire Matrix-based notifier (internal/notifier/) that polled
for pending approvals, sent Matrix alerts, and checked for reaction-based
approve/deny. Approval decisions now work on any chat platform (Hermes
desktop, Telegram, Discord, WhatsApp, CLI) via two new MCP tools:

- list_approvals — query pending/recent approvals by status or entity
- decide_approval — approve/deny via same API endpoint as UI + nomos

Config fields removed: MatrixHomeserver, MatrixUserID, MatrixToken,
MatrixRoomID, ApprovalHMACSecret. Docker notifier: service removed.
Approval HMAC token generation removed (unused by code).

The existing chat-assent path in nomos (cmd/nomos/assent.go) and the
control-room Approve button keep working unchanged — both call the
shared POST /api/v1/approvals/{id}/decision endpoint.
This commit is contained in:
2026-08-15 20:56:28 +02:00
parent 809c16f6fd
commit ec119566fd
15 changed files with 115 additions and 587 deletions

View File

@@ -15,7 +15,6 @@ import (
"github.com/dtoro/oikos/internal/execworker"
"github.com/dtoro/oikos/internal/httpapi"
"github.com/dtoro/oikos/internal/knowledge"
"github.com/dtoro/oikos/internal/notifier"
"github.com/dtoro/oikos/internal/observability"
"github.com/dtoro/oikos/internal/scheduler"
"github.com/dtoro/oikos/internal/secrets"
@@ -23,7 +22,6 @@ import (
)
var schedulerRunner = scheduler.RunnerForMain()
var notifierRunner = notifier.RunnerForMain()
var execWorkerRunner = execworker.RunnerForMain()
func main() {
@@ -55,8 +53,6 @@ func main() {
)
if sec != nil {
overlays := secrets.ConfigOverlays(map[string]func(string){
"matrix_token": func(v string) { cfg.MatrixToken = v },
"approval_hmac-secret": func(v string) { cfg.ApprovalHMACSecret = v },
"mcp_bearer-token": func(v string) { cfg.MCPBearerToken = v },
"api_token": func(v string) { cfg.APIToken = v },
"oidc_client-secret": func(v string) { cfg.OIDCClientSecret = v },
@@ -65,7 +61,7 @@ func main() {
slog.Info("secrets resolved from Infisical", "count", n)
secrets.VerifyExpectedSecrets(ctx, sec, []string{
"matrix_token", "approval_hmac-secret", "mcp_bearer-token",
"approval_hmac-secret", "mcp_bearer-token",
"api_token", "openrouter_api-key", "webhook_hmac-secret",
})
}
@@ -95,8 +91,6 @@ func main() {
}
case "scheduler":
runWithPool(ctx, cfg, "scheduler", schedulerRunner)
case "notifier":
runWithPool(ctx, cfg, "notifier", notifierRunner)
case "execution-worker":
runWithPool(ctx, cfg, "execution-worker", execWorkerRunner)
case "all":
@@ -113,10 +107,9 @@ func main() {
}
go schedulerRunner(ctx, pool, cfg)
go notifierRunner(ctx, pool, cfg)
go execWorkerRunner(ctx, pool, cfg)
slog.Info("all: starting api with scheduler + notifier + execution-worker in background")
slog.Info("all: starting api with scheduler + execution-worker in background")
if err := httpapi.ListenAndServe(ctx, pool, cfg); err != nil {
slog.Error("api failed", "error", err)
os.Exit(1)
@@ -145,7 +138,6 @@ Roles:
export Export DB state back to seed YAMLs (DR / version control)
api Run the REST + MCP API server
scheduler Run the observe loop
notifier Run the notification service (Matrix alerts)
all Run all roles in one process (dev mode)
secret Secret management (Infisical: get, set, list, verify, audit, migrate, export-sops)
knowledge Convert wiki to knowledge seed (one-shot)
@@ -386,8 +378,6 @@ func runSecret(ctx context.Context, cfg config.Config) {
// expectedSecrets is the set of keys that should exist in Infisical
// for a fully-migrated deployment.
var expectedSecrets = []string{
"matrix_token",
"approval_hmac-secret",
"mcp_bearer-token",
"api_token",
"openrouter_api-key",
@@ -429,8 +419,6 @@ func runSecretAudit(ctx context.Context, cfg config.Config) {
backend := newInfisicalBackendOrFail(cfg)
envValues := map[string]string{
"matrix_token": cfg.MatrixToken,
"approval_hmac-secret": cfg.ApprovalHMACSecret,
"mcp_bearer-token": cfg.MCPBearerToken,
"api_token": cfg.APIToken,
"oidc_client-secret": cfg.OIDCClientSecret,