M2 delivers the read-only MCP capability broker gateway and four Day-1 infrastructure adapters (Proxmox, SSH/Linux, GitHub, Gitea). 13 REQs (015-027) all pass. 656 tests green. M1 non-regression verified. MCP spec 2025-06-18 conformance verified (PROTOCOL.md + 7 tests). Defense-in-depth SSH (broker layer 1 + Relay Agent layer 2 + no-shell exec). Two-track LLM smoke (Track A mock-path P0 gate passes). CI: Gitea Actions (.gitea/workflows/ci.yml) with Postgres 16 + RLS verification. Phases shipped: P0 pre-execution v0.1.0 P1 Wave F — MCP gateway v0.1.1 P2 Wave G — Proxmox v0.1.2 P3 Wave H — SSH/Linux v0.1.3 P4 Wave I — Git adapters v0.1.4 P5 Wave J — SSE+smoke+UI v0.1.5 P6 Final — review+ship v0.1.6 ← milestone release ---ci--- phase: 6 milestone: v0.2 status: complete phase_role: final milestone_complete: true requirements: covered: [REQ-015, REQ-016, REQ-017, REQ-018, REQ-019, REQ-020, REQ-021, REQ-022, REQ-023, REQ-024, REQ-025, REQ-026, REQ-027] partial: [] ---/ci---
11 KiB
coreci-chat
What This Is
A browser-based chat interface where mid-market enterprise IT operators ask natural-language questions about their infrastructure (Proxmox VE 7.x/8.x, SSH/Linux servers on Ubuntu 24.04 LTS / Debian 12+, GitHub, self-hosted Gitea) and receive coherent, evidence-backed diagnostic answers within 5 minutes (p95). All LLM inference is routed through a customer-provided model endpoint (BYOM) — CoreCI Chat never hosts inference. CoreCI Chat is a companion product to CoreCI (the owner's existing CI/CD platform). The v0.1 wedge is deliberately conservative: investigate and diagnose; remediation is deferred to v1.1.
The Relay Agent is a lightweight systemd service installed on customer Linux hosts, communicating to the CoreCI Chat SaaS over an outbound-only WebSocket. Read-only enforcement is applied at both the MCP gateway (control plane) and the Relay Agent (SSH command whitelist). Every prompt, tool call, SSH command, and response is written to an immutable audit log. All tenant-scoped data is protected by Postgres Row-Level Security. All credentials live in a centralized secret manager (AWS Secrets Manager in prod, encrypted-local fallback in dev).
One-sentence goal: A browser-based chat interface where mid-market enterprise IT operators ask natural-language questions about their infrastructure (Proxmox, SSH/Linux servers, GitHub, Gitea) and receive evidence-backed diagnostic answers in under 5 minutes — with all LLM inference routed through customer-provided model endpoints (BYOM).
Milestone
v0.2 — MCP Layer & Day 1 Adapters. Milestone branch: milestone/v0.2-mcp-layer-day1-adapters. Tags run on the v0.1.x patch line (M1's previous minor): phase 0 seeds v0.1.0, each execution phase ships a progressive patch, and the final phase's patch (v0.1.(N+1)) IS the milestone release. Milestone type: Feature (new MCP adapters are feat: phases).
Predecessor: v0.1 — Read-Only Diagnostic MVP (COMPLETE, shipped v0.0.1..v0.0.7; all 17 M1 REQs PASS, 189 tests green, 98% DB coverage).
Authoritative Specs
- M1 (predecessor, shipped):
/home/opencode/coreci-chat/.ciagent/steer-v0.1-spec.md— CoreCI Chat v0.1 Engineering Specification v1.1 (FINAL), Sarah Chen, locked 2026-08-24. - M2 (current):
/home/opencode/coreci-chat/.ciagent/steer-m2-spec.md— CoreCI Chat v0.1 M2 Engineering Specification v1.0 (Locked), Sarah Chen, locked 2026-08-25. All 9 open questions resolved. D-006 (GitHub scopes) and D-007 (MCP transport) recorded as deviations.
M2 Scope (current milestone)
REQ-015 → REQ-027 (13 REQs total). M2 acceptance gate (spec §6): MCP capability broker gateway with closed read-only tool registry, four Day-1 adapters (Proxmox, SSH/Linux via Relay Agent, GitHub, Gitea), SSE streaming to Test-Call UI, token-bucket rate limiting, multi-target scoping, read-only enforcement at the broker (INV-7). Real GitHub smoke + mock validation for other three adapters + LLM-driven tool-calling smoke (packages/llm-mock). CI Postgres 16 with RLS verification (Wave 0 prerequisite). M1 non-regression.
M2 customer-facing surface: Settings → Adapters configuration UI + Test-Call UI (in the existing M1 dashboard). M3 (next milestone) consumes M2's gateway to deliver the chat orchestration surface.
Requirements
Validated (Phase 0 init — M2)
- ✓ M1 milestone complete (checkpoint cleared; v0.0.1..v0.0.7 shipped)
- ✓ Branch hierarchy created:
main → milestone/v0.2-mcp-layer-day1-adapters → phase/00-pre-execution - ✓ M2 spec saved and locked at
.ciagent/steer-m2-spec.md(v1.0, all 9 open questions resolved) - ✓ GITEA_TOKEN available in
.ciagent/.env.secretsfor release shipping
Active (Phase 0 — this run)
- SPECIFY: apply spec delta to PROJECT.md / REQUIREMENTS.md / ARCHITECTURE.md, establish milestone v0.2
- CLARIFY: carry D-001..D-005 from M1; add D-006 (GitHub scopes) + D-007 (MCP transport)
- RESEARCH: MCP
2025-06-18conformance verification, Proxmox API + PVEAuditor, SSH adapter patterns, GitHub/Gitea APIs, SSE, token-bucket,packages/llm-mock - PLAN: vertical-slice waves F/G/H/I/J + final, REQ traceability, wave ordering + parallelism
- GRILL: adversarial review — closed tool set completeness, defense-in-depth, INV-7 at broker, MCP conformance evidence
- MVP/UX: 3 mandatory sections (User-Facing Surface = Settings→Adapters + Test-Call; Happy Path = J1+J2; UX Acceptance Criteria)
Out of Scope (M2 — do not build)
See .ciagent/steer-m2-spec.md §2.2 and M1 spec §2.2. Highlights: LLM chat UI/orchestration (M3), Trigger.dev task execution (M3), write actions (v1.1), hosted LLM inference (never), Kubernetes/ArgoCD/Helm (not planned), Slack/Teams/CLI/mobile (v1.1+), approval-gated remediation (v1.1), RAG (v1.1), SOC 2 final cert (post-MVP), custom RBAC roles (v1.2+), BYOK (v1.2+), multi-region (MVP single-region), Windows (not planned v1.x), fine-tuning (not planned). M2-specific exclusions: 5+ adapters (only 4), MCP result persistence tables, cross-tenant adapter sharing, custom tool endpoints.
Constraints
- Branch discipline: all writes on
phase/NN-*branches, nevermain.---ci---blocks in every commit. - Read-only by default (INV-7): the MCP broker is the load-bearing safety boundary. 100% of write-action requests rejected at the broker (HTTP 403) before adapter invocation. For SSH, defense-in-depth: broker validates
commandagainst whitelist subset (layer 1) AND Relay AgentCheckCommandvalidates at execution (layer 2). - Closed tool registry (REQ-015): 9-tool starter set locked across 4 adapters. Per-tenant policy may disable tools but never add new ones. Additions require spec amendment (v1.2+).
- MCP conformance: broker implements MCP spec version
2025-06-18. Conformance verification artifact required at M2 gate. - BYOM mandatory: 100% of LLM inference outbound to the customer-configured endpoint; zero inference from CoreCI Chat infra.
- Multi-tenancy isolation (INV-2): every MCP capability invocation runs under
withTenant+ RLS. Adapters are per-tenant; cross-tenant adapter sharing prohibited. - Audit immutability (INV-4): every MCP capability invocation, adapter config change, write rejection, and test connection appends to M1's
audit_log. New event types:adapter.configured,adapter.test_connection.{succeeded,failed},adapter.capability_invoked,adapter.write_rejected. - Secret handling (INV-3): all adapter credentials via
SecretProvider. No env vars, config files, or DB columns for tenant secrets. Credentials never logged; secret identifiers hashed in audit events. - RBAC enforcement (INV-1): at the API gateway from the first endpoint. Auth → tenant resolve → RBAC → audit ordering preserved.
- Rate limiting (REQ-019): token-bucket per user (60 req/min) and per tenant (300 req/min). In-memory, process-local in M2. Capacity = rate; refill 1/sec (user) / 5/sec (tenant).
- SSE streaming (REQ-017): per-call streams, ULID correlation IDs. Client disconnect cancels in-flight adapter call; no audit event for client-side cancellation.
- RLS verification: all M2 schema additions verified against real Postgres 16 in CI (not PGlite). PGlite only for unit tests with documented RLS gap.
- M1 non-regression: all M1 REQs (001-014, 038-040) remain passing. No breaking changes to M1 systems except additive (new tables, new audit event types).
- Performance NFRs: MCP capability invocation P95 < 2s (live); SSE chunk delivery < 100ms; rate limiter check < 5ms; adapter upstream timeout 10s (504); SecretProvider.get timeout 5s (503).
- Autonomy:
full— no HITL after clarify. Decision threshold 0.6. Escalation hooks:[deploy, delete_data, merge_to_main].
Key Decisions
| Decision | Rationale | Source |
|---|---|---|
| Spec v1.1 locked, 44 REQs | Sarah Chen (PO) locked 2026-08-24 | M1 spec §8 |
| M2 = REQ-015..027 (13 REQs) | M2 spec §2.3 | M2 spec §2.3 |
MCP spec version 2025-06-18 |
Latest stable with complete published documentation | M2 spec §7 Q1 |
| In-process custom MCP transport for TS adapters | MCP 2025-06-18 allows custom transports; subprocess spawning unnecessary for same-process TS modules |
M2 spec §7 Q1, D-007 |
| SSH adapter MCP layer in-process, downstream WebSocket to M1 Relay | M1 Relay Agent architecture inherited; MCP tools/call JSON-RPC sits between broker and TS SSH module |
M2 spec §7 Q1, D-007 |
| 9-tool closed starter set across 4 adapters | Conservative MVP scope; additions require spec amendment (v1.2+) | M2 spec §7 Q2 |
| SSH 6-command whitelist subset (broker + Relay defense-in-depth) | Conservative subset of M1's whitelist; broker validates before dispatch, Relay CheckCommand validates at execution |
M2 spec §7 Q3 |
| In-memory token-bucket rate limiting | M2 single-instance; Redis migration path for M3 | M2 spec §7 Q4 |
GitHub fine-grained PAT: metadata:read + actions:read minimum (no contents:read) |
M2 GitHub tools don't read repo contents; D-006 deviation | M2 spec §7 Q5, D-006 |
| Gitea version-aware scope validation | ≥1.22 fine-grained read:repository; <1.22 any token with broker-side write blocklist |
M2 spec §7 Q6 |
| Per-call SSE streams with ULID correlation IDs | Simpler correlation, easier rate limiting; session-based considered for M3 | M2 spec §7 Q7 |
packages/llm-mock as devDependency with import guard |
Clean separation; CI-only; build-time guard prevents prod leak | M2 spec §7 Q8 |
| M2→M3 contract freeze at M2 acceptance gate | 5-endpoint REST+SSE contract frozen; M3 treats as stable API | M2 spec §7 Q9, §9 |
| Trigger.dev durable runtime | Best TS DX, long-running workflows, MVP cost | M1 spec §7 Q1 |
| WorkOS IdP | Enterprise SAML/SSO/SCIM at mid-market price | M1 spec §7 Q2 |
| Vanta GRC | AWS-native ecosystem, M3 instrumentation | M1 spec §7 Q3 |
| Install script primary, apt fallback | Fastest to ship, flexible | M1 spec §7 Q4 |
| Fixed SSH whitelist, no customer extension in v0.1 | Security; signed-config extension in v1.1 | M1 spec §7 Q5 |
| PVEAuditor built-in role for Proxmox | Simpler setup, well-understood | M1 spec §7 Q6 |
| Gitea via SaaS-to-API exposure | Customer opens firewall; Relay-Agent variant deferred | M1 spec §7 Q7 |
| pgvector for v1.1 RAG | Co-located with primary DB (not v0.1) | M1 spec §7 Q8 |
| OpenAI-compatible BYOM contract for M1 | Most customer endpoints speak it; pluggable provider iface for Anthropic-native in M3 | M1 CLARIFY D-001 |
| Relay Agent in Go | Single static binary, ideal for curl|bash + systemd + zero-runtime on Ubuntu/Debian | M1 CLARIFY D-002 |
AWS Secrets Manager (prod) + local-encrypted (dev) behind SecretProvider interface |
Spec §5 default us-east-1; interface enables CI/local without AWS | M1 CLARIFY D-003 |
| Postgres append-only table + hash-chain + REVOKE UPDATE/DELETE for audit (M1); S3 Object Lock WORM in M3 | Append-only from day one; cheap refactor to WORM later | M1 CLARIFY D-004 |
| Next.js (App Router) + TypeScript single SPA | Dashboard in M1, chat UI in M3, same app | M1 CLARIFY D-005 |