Add secret-free effective-runtime-config/status endpoint (router, slots, guardrails, warnings)
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 152
- Forks
- 16
- Avg merge
- 14h 48m
- Merged PRs (30d)
- 536
Description
Split out from #391 (claim 4).
Claim
A client can know the YAML it supplied, but cannot query what Mecatl actually accepted and resolved. A read-only endpoint should expose at least: whether semantic routing is active; category names and resolved model IDs; classifier slot/model; active model slots; guardrails enabled state and rule summary; warnings/dropped configuration — so clients can display runtime truth rather than configured intent.
Investigation (verified against the codebase)
Verdict: confirmed. The full client surface was enumerated; no endpoint exposes runtime-resolved config state.
Evidence
- HTTP: 44 routes (
internal/adapter/server/http.go:43-86) +/healthz//readyz(health.go:32-48, pure liveness) — session CRUD/run/approve/plan/cancel/fork, MCP discovery (sources = configured names, not resolved state), content discovery,GET /v1/models(the only status-ish endpoint; models-only), teams, schedules. gRPC: HarnessService 30 rpcs (mirrors HTTP) + ScheduleService 10 rpcs. None expose router active state, category→model resolution, classifier slot/model, model-slot bindings, guardrails state/rule summary, or config warnings. Grep foreffective|/v1/status|runtime.?statusacrossinternal/= zero hits. - The truth exists but is diag-log-only at Build:
logModelRouterFacts(internal/app/slots.go:697-716),logGuardrailsPosture/guardrailsPostureLine(internal/app/build.go:3365-3422),narratePosture(internal/app/posture.go:262-271),logSlotConfigFacts; permconfig drop warnings (internal/adapter/permconfig/resolve.go:433-669, ~14 WARN sites) are emitted-and-forgotten. The resolution happens (foldOperatorModelRouterbuild.go:1234,foldOperatorModelSlotsbuild.go:1145,foldOperatorGuardrailsguardrails.go:21) and lives in the process-localapp.Config, reachable only via the daemon log.
Nuance (minor understatement in the claim)
GET /v1/models + ListModelsResponse.provider_status already exposes live provider reachability/model counts, and CreateSessionResponse.resolved_model echoes the effective per-session provider/model/window/effort — but neither covers router/guardrails/slots/warnings, so the verdict stands.
Proposed fix (~1-2 days)
Read-only GET /v1/status in NewHTTPHandler + a Service method projecting a snapshot app.Build computes once and hands to server.NewService via a Config field (the SetProviderStatus precedent, service.go:1003). Contents all derivable from the post-fold Config:
- posture;
- router {active, disabled, categories + resolved selectors, default_category, classifier model/slot};
- slots (post-fold, alias→concrete via the same
resolveSlotModel); - guardrails {enabled, checker + provenance, mode, rule_count, used_defaults, rule summaries};
- warnings.
The warnings collector (a Diagnostics decorator or permconfig recording dropped-block reasons) is the only genuinely new machinery.
Constraints
- HTTP-only needs no proto change (a gRPC mirror would need
task generate+ the same-PR docs/user-docs rule). - Not api-compat-gated (composition layer, outside
engine/api/*.txt). - Mount behind the existing authn middleware — never on the unauthenticated health mux (health.go:15-16).
- Secret-free discipline is binding — never project MCP
ServerConfig.Headers/tokens (AGENTS.md:AgentMCPServer.Headersis secret-shaped, "never logged/projected"), provider keys, or--auth-token; guardrail rule prompts summary-only. - The warnings ring buffer is a new process-lifetime structure → ADR 0027 List 1 row (the static snapshot itself adds none).
- The endpoint is readable by any authenticated client — if multi-tenancy ever lands, consider admin-scoping.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with internal/adapter/server/http.go:43-86, internal/app/build.go, internal/app/slots.go, and service.go:1003; trace how the post-fold app.Config reaches NewHTTPHandler and the SetProviderStatus precedent. Done means an authenticated GET /v1/status reports resolved router, slots, guardrails, posture, and warnings without exposing secrets, while preserving the unauthenticated health mux.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend, security
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100