docs(init): validate specification

Parse CoreCI Chat v0.1 Engineering Spec v1.1 (Sarah Chen, locked 2026-08-24).
Rewrite placeholder .ciagent/ files with spec-derived content:
- PROJECT.md: vision, M1 scope (17 REQs), constraints, key decisions
- REQUIREMENTS.md: M1 REQs 001-014+038/039/040 with verbatim acceptance
  criteria, M2/M3 deferrals, traceability matrix, out-of-scope
- ARCHITECTURE.md: components, data flow, M1 build-order waves A-E
- steer-v0.1-spec.md: authoritative spec persisted
- CHECKPOINT.json: stage=specify

---ci---
phase: 0
milestone: v0.1
status: specify
---/ci---
This commit is contained in:
CIAgent
2026-08-24 22:33:46 +00:00
parent 2cf16ed091
commit 6146e9bc76
5 changed files with 592 additions and 97 deletions
+91 -34
View File
@@ -2,50 +2,107 @@
## Overview
Architecture is intentionally unspecified at init. The system architecture will be drafted during the research stage of phase 0 once the full project specification is supplied, then refined by the architecture-drift guard across execution phases. This placeholder records the init-time invariants so the drift guard has a baseline to compare against.
CoreCI Chat v0.1 is a multi-tenant SaaS with a TypeScript control plane, a Go Relay Agent distributed to customer Linux hosts, and an OpenAI-compatible BYOM routing layer. The control plane runs in a single AWS region (us-east-1) and enforces tenant isolation via Postgres Row-Level Security. Every request flows through an API gateway that authenticates the session, resolves the tenant, enforces RBAC, and writes an immutable audit entry. The Relay Agent is an outbound-only WebSocket client that registers as a target and heartbeats to the control plane; in M2 it will receive MCP tool calls (SSH) and enforce a fixed command whitelist. All credentials live in AWS Secrets Manager (prod) or a local-encrypted fallback (dev) behind a `SecretProvider` interface — never env vars, config files, or DB columns.
Init-time invariants:
- Single git repository at `~/coreci-chat` with branch hierarchy `main → milestone/v0.1-bootstrap → phase/00-pre-execution`
- CIAgent reference files live in `.ciagent/` (single-project mode; no `projects[]` subdirectories)
- Release target: Gitea `coreci/coreci-chat` at `https://git.cloudinit.dev`
- Autonomy: `full` (no HITL after clarify; decision threshold 0.6)
The v0.1 wedge is read-only diagnostic: no write actions, no hosted inference, no remediation. Async durable execution is provided by Trigger.dev (instrumented in M3 for chat workflows; the runtime bootstrap lands in M1 Wave A so M3 plugs in cleanly).
### Init-time invariants (preserved by the architecture-drift guard)
- Single git repository at `~/coreci-chat`, branch hierarchy `main → milestone/v0.1-bootstrap → phase/NN-*`.
- `.ciagent/` reference files at repo root (single-project mode).
- Release target: Gitea `coreci/coreci-chat` at `https://git.cloudinit.dev`.
- Autonomy: `full` (no HITL after clarify; decision threshold 0.6).
### Architecture invariants (M1 → v0.1)
- Every HTTP request hits the API gateway first: auth → tenant resolve → RBAC → audit.
- Every DB query runs under `SET app.tenant_id = ?` via a session-scoped transaction; RLS policies enforce scoping. Cross-tenant queries return empty.
- Every credential is resolved via `SecretProvider.get(tenantId, key)`; the provider abstracts AWS Secrets Manager (prod) and local-encrypted (dev/test).
- Every auditable event (prompt, tool call, SSH command, response) is appended to `audit_log` with a `prev_hash → curr_hash` chain; `UPDATE`/`DELETE` are REVOKE'd from the app role; a write failure halts the enclosing operation (REQ-038 Edge 7).
- Every LLM inference call is routed to the tenant's configured BYOM endpoint via an OpenAI-compatible `/v1/chat/completions` contract; unconfigured/unreachable → reject with actionable error (REQ-009).
- The Relay Agent makes only outbound connections (WebSocket to SaaS). No inbound firewall rules on customer hosts.
## Components
### .ciagent/config.json
- **Description**: Registry and runtime configuration — autonomy, release, secrets, backend, verification, security, ship settings
- **Boundaries**: Written only during init and config-mutation commands; never hand-edited outside the harness
- **Depends on**: None
### apps/control-plane (TypeScript, Next.js App Router API routes + standalone services)
- **Description**: API gateway, tenant resolution, RBAC enforcement, BYOM registry/validation/routing, Relay Agent WebSocket server, audit writer, secret provider bootstrap, dashboard (Next.js). Hosts the admin dashboard in M1; the chat UI lands here in M3.
- **Boundaries**: All inbound HTTP/WebSocket enters here. Owns the Postgres connection and the `SET app.tenant_id` discipline. Owns the Trigger.dev runtime bootstrap.
- **Depends on**: `packages/db`, `packages/auth`, `packages/audit`, `packages/secrets`, `packages/config`, Trigger.dev, WorkOS, AWS Secrets Manager.
### .ciagent/PROJECT.md
- **Description**: Vision, requirements, constraints, key decisions
- **Boundaries**: Updated during specify/clarify stages; read by all downstream stages
- **Depends on**: .ciagent/config.json
### apps/relay-agent (Go)
- **Description**: Single static binary. Outbound WebSocket client to the control plane; registration (tenant/target/hostname/OS/IP/version); heartbeat + exponential-backoff reconnect (max 5 → alert); systemd service; SSH whitelist file format + enforcement hook (the SSH adapter plugs into the hook in M2 — no SSH execution in M1).
- **Boundaries**: No inbound ports. Reads its tenant registration token from a local config written by the install script (token resolves to a secret-manager reference, never the raw secret). All state is in-memory or on the control plane.
- **Depends on**: control-plane WebSocket endpoint; systemd; the fixed SSH whitelist file shipped alongside the binary.
### .ciagent/ROADMAP.md
- **Description**: Phase breakdown with success criteria and dependencies
- **Boundaries**: Authored by the roadmapper during phase 0; status updated as phases complete
- **Depends on**: .ciagent/PROJECT.md, .ciagent/REQUIREMENTS.md
### apps/dashboard (Next.js, part of apps/control-plane in M1)
- **Description**: Tenant admin dashboard surfaced in the same Next.js app. M1 surfaces Relay Agent status (green/yellow/red), target hostname, last 100 log lines, BYOM config + validation, RBAC user/role management. Per-tenant view under RLS.
- **Boundaries**: Server components read via the same API gateway (no DB access bypassing RLS). Client components subscribe to a status WebSocket fan-out.
- **Depends on**: `apps/control-plane` API, `packages/auth`.
### .ciagent/REQUIREMENTS.md
- **Description**: Formal requirements with REQ-IDs, v1/v2 split, out-of-scope, and traceability matrix
- **Boundaries**: Authored during specify/clarify; traceability updated each phase
- **Depends on**: .ciagent/PROJECT.md
### packages/db (TypeScript)
- **Description**: Postgres schema, migrations, RLS policies, the `withTenant(tenantId, fn)` helper that sets `app.tenant_id` and runs `fn` in a transaction. Tables: `tenants`, `users`, `tenant_memberships` (user × tenant × role), `targets`, `byom_endpoints` (URL in DB, key ref to secret manager), `audit_log` (append-only, hash-chain), `invitations`. All tenant-scoped tables carry `tenant_id` and an RLS policy.
- **Boundaries**: The ONLY module that opens a Postgres connection. App role has INSERT/SELECT on `audit_log` only; UPDATE/DELETE REVOKE'd. Schema migrations run via a gated migrator.
- **Depends on**: Postgres 16.
### .ciagent/ARCHITECTURE.md
- **Description**: System architecture (this file) — components, data flow, build order
- **Boundaries**: Authored during research/plan; enforced by architecture-drift guard across execution phases
- **Depends on**: .ciagent/ROADMAP.md, .ciagent/REQUIREMENTS.md
### packages/auth (TypeScript)
- **Description**: WorkOS SSO/SAML integration, session management, tenant resolution middleware, RBAC role → route permission map (Admin/Operator/Viewer). Enforces RBAC at the API gateway from the first endpoint (REQ-005 pattern).
- **Boundaries**: Sessions are httpOnly cookies; tokens never logged. WorkOS is the only IdP in v0.1.
- **Depends on**: WorkOS SDK, `packages/db`.
### packages/audit (TypeScript)
- **Description**: Append-only audit writer. Computes `curr_hash = sha256(prev_hash || canonical_payload)`. Payload includes tenant_id, user_id, target_id (for SSH), timestamp, correlation_id, event_type, event_body. On write failure: throws `AuditWriteHaltError` → enclosing operation halts + admin alert (REQ-038 Edge 7).
- **Boundaries**: Never exposes UPDATE/DELETE. Read path is admin-export only (no query UI in MVP — spec §2.2).
- **Depends on**: `packages/db`.
### packages/secrets (TypeScript)
- **Description**: `SecretProvider` interface with two impls: `AwsSecretsManagerProvider` (prod, us-east-1, KMS-backed) and `LocalEncryptedProvider` (dev/test, AES-256-GCM with a key from an env var only for the master key — the master key is the ONE allowed env var, everything else is provider-resolved). Every tenant credential (BYOM key, Proxmox token, SSH key, Git token) is stored/retrieved via `provider.put(tenantId, name, value)` / `provider.get(tenantId, name)`.
- **Boundaries**: Secrets never logged, never written to DB columns, never in config files. The DB stores only a reference (e.g. `aws-sm:coreci/<tenantId>/byom`).
- **Depends on**: AWS SDK (prod), Node crypto (dev).
### packages/config (TypeScript)
- **Description**: Typed config loading (env-aware: prod/staging/dev/test). Loads non-secret config only. The only env vars consumed here are infra-level (DATABASE_URL, WORKOS_API_KEY, AWS_REGION, SECRET_MASTER_KEY_DEV, TRIGGER_API_KEY). All tenant/customer secrets go through `packages/secrets`.
- **Boundaries**: Never reads tenant secrets directly.
- **Depends on**: nothing.
## Data Flow
Init only — no runtime data flow. The future data flow will be described once the specification is parsed and the research stage drafts the real architecture.
### M1 happy path — Relay Agent registration (J2 steps 34)
```
Platform Lead ──install script──▶ customer Linux host
detect-OS → install-binary → write-systemd-unit → register-target (writes tenant reg token to local config)
systemd ──start──▶ relay-agent (Go binary)
relay-agent ──outbound WebSocket (wss, tenant reg token)──▶ control-plane WS server
control-plane: auth token → resolve tenant (RLS) → INSERT target (hostname/OS/IP/version) → audit append
control-plane ──ack + target_id──▶ relay-agent
relay-agent ──heartbeat every Ns──▶ control-plane (updates last_seen → green status)
control-plane ──status fan-out──▶ dashboard (server-sent events / WS)
```
## Build Order
### M1 happy path — BYOM configure + validate (J2 step 2)
```
Admin ──POST /api/byom (url, key)──▶ API gateway
auth → tenant resolve (RLS) → RBAC (Admin only) → audit append (config event)
secrets.put(tenantId, "byom", key) → returns ref
INSERT byom_endpoints (tenant_id, url, secret_ref) — under RLS
BYOM validator: fetch OpenAI-compatible /v1/chat/completions with a trivial test prompt
on success → mark validated=true, audit append (validation ok), return green
on failure → rollback insert, audit append (validation fail), return error details (Edge 11)
```
1. Establish git-native branch hierarchy (DONE — branch gate)
2. Write `.ciagent/config.json` with autonomy + release + secrets (DONE)
3. Seed placeholder PROJECT.md, ROADMAP.md, REQUIREMENTS.md, ARCHITECTURE.md (DONE)
4. Persist `GITEA_TOKEN` to `.ciagent/.env.secrets` and seed `.gitignore` (DONE)
5. Land the init commit on `phase/00-pre-execution` with a `---ci---` block (next)
6. (future) Parse the full specification and replace placeholders via the specify → clarify → research → plan stages
### M3 (forward reference) — chat diagnostic (J1)
```
Operator ──prompt──▶ API gateway → auth → tenant → RBAC (Operator) → audit append (prompt)
orchestrator (Trigger.dev task) → BYOM routing shim → POST tenant's BYOM /v1/chat/completions
if unconfigured/unreachable → reject (REQ-009, Edge 1), audit append, halt
LLM returns tool selection → MCP gateway → route to adapter (M2) → Relay Agent (SSH, M2)
read-only enforced at gateway (403 on write) and Relay Agent (whitelist)
tool output streams via SSE → UI trace panel → audit append (tool call + SSH command + output)
LLM synthesizes cited answer → stream to UI → audit append (response)
conversation persisted (tenant-scoped) → audit append
```
## Build Order (M1 waves — each a vertical slice, testable + shippable)
1. **Wave A — Foundations.** Monorepo (pnpm): `apps/control-plane`, `apps/relay-agent` (Go module), `apps/dashboard`, `packages/{db,auth,audit,secrets,config}`. Postgres schema + RLS + `withTenant`. `audit_log` hash-chain + REVOKE UPDATE/DELETE. `SecretProvider` interface + AWS SM impl + local-encrypted impl. Trigger.dev bootstrap (runtime wired, no tasks yet). Covers REQ-038, REQ-039, REQ-040.
2. **Wave B — Identity & RBAC.** WorkOS SSO; session; tenant resolution middleware (`SET app.tenant_id`); RBAC at API gateway (Admin/Operator/Viewer → route permission map). First endpoint protected on day one. Covers REQ-001, REQ-002, REQ-003, REQ-004, REQ-005.
3. **Wave C — BYOM.** Tenant-scoped BYOM endpoint registry (URL in DB, key in secret manager); validate-on-save test inference call (OpenAI-compatible); routing shim (no inference in M1 — proxy contract + REQ-009 reject path). Covers REQ-006, REQ-007, REQ-008, REQ-009.
4. **Wave D — Relay Agent.** Modular install script (detect-OS/install-binary/write-systemd-unit/register-target; clean abort on unsupported OS). Go binary: outbound wss + tenant reg token, registration (tenant/target/hostname/OS/IP/version), heartbeat + exp-backoff (max 5 → alert), auto-reconnect, systemd unit w/ auto-restart. SSH whitelist file format + enforcement hook (no adapter yet — M2 plugs in). Covers REQ-010, REQ-011, REQ-012, REQ-013, (REQ-026 whitelist hook).
5. **Wave E — Dashboard surfacing.** WebSocket fan-out of agent status to dashboard; green/yellow/red; target hostname; last 100 log lines; per-tenant view under RLS. M1 gate demo: SSO → BYOM green → install → register → green dashboard. Covers REQ-014.
+1 -1
View File
@@ -4,5 +4,5 @@
"milestone": "v0.1",
"phase_role": "pre_execution",
"attempts": 1,
"updated_at": "2026-08-24T22:20:00Z"
"updated_at": "2026-08-24T22:40:00Z"
}
+62 -34
View File
@@ -2,48 +2,76 @@
## What This Is
A placeholder CIAgent project scaffold initialized at `~/coreci-chat`. The full project specification will be supplied in a subsequent session; this init establishes the git-native branch hierarchy, `.ciagent/` reference files, autonomy configuration, and release target so subsequent pipeline stages (specify → clarify → research → plan) can proceed without re-running setup gates.
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.1 — Read-Only Diagnostic MVP.** Milestone branch: `milestone/v0.1-bootstrap`. Tags run on the v0.0.x patch line (no prior minor exists); phase 0 seeds `v0.0.1`, each execution phase ships a progressive patch, and the final phase's patch (`v0.0.(N+1)`) IS the milestone release. Milestone type: **Feature** (at least one `feat:` phase).
## Authoritative Spec
`/home/opencode/coreci-chat/.ciagent/steer-v0.1-spec.md` — CoreCI Chat v0.1 Engineering Specification v1.1 (FINAL), authored by Sarah Chen (Product Owner), locked 2026-08-24. Anchor docs: CoreCI Chat Vision v1.0, locked Phase 2 scope decisions. All 44 REQs locked; Section 7 decisions locked.
## M1 Scope (current milestone)
REQ-001 → REQ-014, REQ-038, REQ-039, REQ-040 (17 REQs total). M1 acceptance gate (spec §2.3): Platform Lead can sign up via SSO, configure a BYOM endpoint with green validation, deploy Relay Agent via install script on at least one target Linux host, register the target, and see green status in the admin dashboard. Audit logging, RLS, and secret manager are operational.
## Requirements
### Validated
### Validated (Phase 0 init)
- ✓ Initialize a git repository at `~/coreci-chat` with branch hierarchy `main → milestone/v0.1-bootstrap → phase/00-pre-execution`
- ✓ Write `.ciagent/config.json` with autonomy `full`, release target Gitea `coreci/coreci-chat`, secrets hygiene
- ✓ Persist `GITEA_TOKEN` to `.ciagent/.env.secrets` (mode 0600); `.env*` in `.gitignore`
- ✓ Initialize a git repository at `~/coreci-chat` with a `main` branch
- ✓ Create the CIAgent branch hierarchy: `main → milestone/v0.1-bootstrap → phase/00-pre-execution`
- ✓ Write `.ciagent/config.json` with autonomy, release, and secrets configuration
- ✓ Persist release target: Gitea `coreci/coreci-chat` at `https://git.cloudinit.dev`
- ✓ Seed `.gitignore` to prevent committing `.env*` secrets
- ✓ Record initial commit on `phase/00-pre-execution` with a `---ci---` block
### Active (Phase 0 — this run)
- [ ] SPECIFY: parse spec, rewrite PROJECT.md / REQUIREMENTS.md / ARCHITECTURE.md with real content
- [ ] CLARIFY: resolve 5 architectural decisions (approved by PO during kickoff)
- [ ] RESEARCH: produce research artifacts + PERSONAS.md under `.ciagent/`
- [ ] PLAN: vertical-slice wave plans referencing REQ IDs, MVP/UX sections
- [ ] GRILL: adversarial plan review, binding verdicts
### Active
- [ ] Provide the full project specification (objective, requirements, constraints, out-of-scope) in a follow-up session
- [ ] Refine PROJECT.md, ROADMAP.md, REQUIREMENTS.md, ARCHITECTURE.md once the specification is parsed
- [ ] Run the clarify stage against the full specification
### Out of Scope
- Implementation work — no source code is written during init
- Remote git push — no `origin` remote is configured; the Gitea release target is configured for future ship phases
- Milestone release tag — phase 0 ships as a patch (`v0.0.1`-line) only after the full pipeline runs
## Context
Init was invoked with the literal argument "Create a folder in ~/coreci-chat". Per the user, the full specification will arrive in a separate session; the goal of this init is solely to land the scaffold so the next `ciagent-run` can pick up from phase 0 (specify → clarify → research → plan) without re-running the setup gates.
### Out of Scope (v0.1 — do not build)
See `.ciagent/REQUIREMENTS.md` § Out of Scope and spec §2.2. Highlights: write actions, hosted LLM inference, Kubernetes/ArgoCD/Helm, Slack/Teams/CLI/mobile, approval-gated remediation, RAG, SOC 2 Type 1 final cert, custom RBAC roles, BYOK, multi-region, Windows. Anything not in the spec is a spec-time scope question — never silently added.
## Constraints
- All `.ciagent/` file writes occurred only after the mandatory branch gate completed (HEAD on `phase/00-pre-execution`, never `main`)
- `GITEA_TOKEN` is stored only in `.ciagent/.env.secrets` (mode 0600), never in `config.json`, never echoed, never committed
- Autonomy level `full` — preset applied verbatim (threshold 0.6, clarify_budget 10, escalation_hooks `[deploy, delete_data, merge_to_main]`)
- Single-project mode — `projects[]` is empty; files live directly in `.ciagent/`
- **Branch discipline:** all writes on `phase/NN-*` branches, never `main`. `---ci---` blocks in every commit.
- **Read-only by default:** 100% of write-action requests rejected at MCP gateway (HTTP 403) and at Relay Agent (SSH whitelist). No state mutation is possible in v0.1.
- **BYOM mandatory:** 100% of LLM inference outbound to the customer-configured endpoint; zero inference from CoreCI Chat infra.
- **Multi-tenancy isolation:** Postgres RLS on all tenant-scoped tables; cross-tenant queries return empty. Quarterly pen test, zero leakage.
- **Audit immutability:** write-once store, 100% capture, zero deletes; write failure halts the operation (no silent drops).
- **Secret handling:** every credential via the centralized secret manager from the first secret. No env vars, no config files, no DB columns. Never logged in plaintext.
- **RBAC enforcement:** at the API gateway from the first endpoint. No "auth later" stubs.
- **SSH whitelist:** fixed whitelist shipped with the Relay Agent in M1; M2 plugs the SSH adapter into the existing enforcement hook. Customer extension deferred to v1.1 (signed config).
- **Supported targets:** Ubuntu 24.04 LTS, Debian 12+ (install script aborts cleanly on unsupported OS with actionable error). Proxmox VE 7.x and 8.x.
- **Relay Agent distribution:** install script (`curl|bash`) primary, apt package fallback. systemd service, outbound-only WebSocket, per-target registration.
- **Async durable execution:** Trigger.dev.
- **Identity:** WorkOS (SSO/SAML + SCIM).
- **GRC:** Vanta (instrumentation in M3, not M1).
- **Single region:** us-east-1 MVP. TLS 1.2+ in transit, AES-256 at rest.
- **Performance NFRs:** <3s p95 time-to-first-token; <5 min p95 diagnostic completion (≤10 tool calls); ≥5 concurrent workflows per tenant; ≤20 tool calls per workflow; 60 req/min per user, 300 req/min per tenant (token bucket).
- **Autonomy:** `full` — no HITL after clarify. Decision threshold 0.6. Escalation hooks: `[deploy, delete_data, merge_to_main]`.
## Key Decisions
| Decision | Rationale | Outcome |
|----------|-----------|---------|
| Autonomy level = `full` | User-selected; CI/CD automation without HITL after clarify | Preset persisted to config.json |
| Release forge = `gitea` | No git origin detected; user chose self-hosted Gitea | `config.release.gitea` populated with base_url/owner/repo |
| Milestone version = `v0.1` | No existing tags; `computeMilestoneTag()` returns `v0.1.0` | Branch `milestone/v0.1-bootstrap` created from `main` |
| Phase 0 slug = `pre-execution` | Canonical phase-0 name per branch-strategy reference | Branch `phase/00-pre-execution` created from milestone |
| Specification deferred | User will supply full spec in a follow-up session | PROJECT.md/ROADMAP.md/REQUIREMENTS.md seeded as placeholders |
| Decision | Rationale | Source |
|----------|-----------|--------|
| Spec v1.1 locked, 44 REQs | Sarah Chen (PO) locked 2026-08-24 | spec §8 |
| M1 = REQ-001..014 + 038/039/040 | spec §2.3 | spec §2.3 |
| Trigger.dev durable runtime | Best TS DX, long-running workflows, MVP cost | spec §7 Q1 |
| WorkOS IdP | Enterprise SAML/SSO/SCIM at mid-market price | spec §7 Q2 |
| Vanta GRC | AWS-native ecosystem, M3 instrumentation | spec §7 Q3 |
| Install script primary, apt fallback | Fastest to ship, flexible | spec §7 Q4 |
| Fixed SSH whitelist, no customer extension in v0.1 | Security; signed-config extension in v1.1 | spec §7 Q5 |
| PVEAuditor built-in role for Proxmox | Simpler setup, well-understood | spec §7 Q6 |
| Gitea via SaaS-to-API exposure | Customer opens firewall; Relay-Agent variant deferred | spec §7 Q7 |
| pgvector for v1.1 RAG | Co-located with primary DB (not v0.1) | spec §7 Q8 |
| OpenAI-compatible BYOM contract for M1 | Most customer endpoints speak it; pluggable provider iface for Anthropic-native in M3 | CLARIFY (PO-approved default) |
| Relay Agent in Go | Single static binary, ideal for curl\|bash + systemd + zero-runtime on Ubuntu/Debian | CLARIFY (PO-approved default) |
| AWS Secrets Manager (prod) + local-encrypted (dev) behind `SecretProvider` interface | Spec §5 default us-east-1; interface enables CI/local without AWS | CLARIFY (PO-approved default) |
| 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 | CLARIFY (PO-approved default) |
| Next.js (App Router) + TypeScript single SPA | Dashboard in M1, chat UI in M3, same app | CLARIFY (PO-approved default) |
+100 -28
View File
@@ -1,44 +1,116 @@
# Requirements
Milestone type: nfr (placeholder — re-evaluated by `getMilestoneType()` once phases are defined)
Tags run on: v0.0.x patch line (no prior tags exist; phase 0 seeds v0.0.1)
Source: CoreCI Chat v0.1 Engineering Specification v1.1 (`.ciagent/steer-v0.1-spec.md`), Sarah Chen (PO), locked 2026-08-24.
Milestone type: **Feature** (at least one `feat:` phase). Tags run on the v0.0.x patch line (no prior minor exists; phase 0 seeds `v0.0.1`).
## v1 Requirements
## M1 Requirements (this milestone — REQ-001..014, 038, 039, 040)
### Init
All acceptance criteria verbatim from spec §4. Every REQ maps to Journey J1 and/or J2 (spec §3.2) and to at least one failure/edge path (spec §3.3).
- [ ] **REQ-001**: Full project specification supplied and parsed (objective, requirements, constraints, out-of-scope) in a follow-up session
- [ ] **REQ-002**: Clarify stage run against the full specification; all ambiguities resolved (defaults accepted under `full` autonomy)
- [ ] **REQ-003**: Research artifacts committed under `.ciagent/`
- [ ] **REQ-004**: Plan committed and ready for execution-phase decomposition
- [ ] **REQ-005**: Project scaffold initialized at `~/coreci-chat` with git-native branch hierarchy (main → milestone/v0.1-bootstrap → phase/00-pre-execution)
### Identity & Access
### Release
- [ ] **REQ-001** (J2, High) Establish SSO session via identity provider — **Given** an unauthenticated user navigates to CoreCI Chat, **when** they complete SSO flow via the configured IdP, **then** a session is established and they are redirected to the dashboard. _(Edge 10: SSO provider down → error w/ retry, tenant creation blocked)_
- [ ] **REQ-002** (J2, High) Provision tenant on first signup — **Given** a user completes signup for the first time, **when** tenant creation runs, **then** a new tenant is created, the user is assigned Admin role, and the admin dashboard loads.
- [ ] **REQ-003** (J2, High) Invite users to tenant via email — **Given** an Admin submits an invitation, **when** the system processes the invite, **then** an email is sent to the invitee containing a single-use acceptance link. _(Edge 15: bounce → admin notified, invite invalidated)_
- [ ] **REQ-004** (J2, High) Apply RBAC role to user — **Given** an Admin assigns a role (Admin/Operator/Viewer), **when** the assignment is saved, **then** the user's role is updated and enforced on the next API call.
- [ ] **REQ-005** (J1, J2, High) Enforce RBAC at API gateway — **Given** a user with role X calls endpoint Y, **when** the role check runs, **then** the request is allowed iff X has permission for Y. _(Critical-path pattern: set at API gateway from first endpoint, no auth-later stubs.)_
- [ ] **REQ-006**: Release target configured for Gitea `coreci/coreci-chat` at `https://git.cloudinit.dev`
- [ ] **REQ-007**: `GITEA_TOKEN` persisted to `.ciagent/.env.secrets` (mode 0600); `.env*` added to `.gitignore`
### BYOM (Bring Your Own Model)
## v2 Requirements
- [ ] **REQ-006** (J2, High) Configure BYOM endpoint (URL + API key) — **Given** an Admin submits endpoint URL and API key, **when** the form is saved, **then** the API key is stored in the secret manager and the URL is validated.
- [ ] **REQ-007** (J2, High) Validate BYOM endpoint connectivity on save — **Given** an Admin submits a BYOM endpoint, **when** validation runs, **then** a test inference call is sent and the result is displayed as success or failure with error details. _(Edge 11: test fails → save blocked, errors surfaced)_
- [ ] **REQ-008** (J1, J2, High) Route all LLM inference to configured BYOM endpoint — **Given** a user submits a prompt, **when** orchestration runs, **then** 100% of LLM inference calls are sent to the configured BYOM endpoint (verified via outbound traffic log).
- [ ] **REQ-009** (J1, J2, High) Reject LLM request when BYOM is unconfigured or unreachable — **Given** no BYOM endpoint is configured or it is unreachable, **when** an Operator submits a prompt, **then** the request is rejected with a clear actionable error and no inference is attempted. _(Edge 1: unreachable mid-workflow → actionable error, halt.)_
_(none — reserved for future minor requirements after milestone v0.1 ships)_
### Relay Agent
## Out of Scope
- [ ] **REQ-010** (J2, High) Distribute Relay Agent as systemd service via install script — **Given** a Platform Lead runs the install script on a supported host (Ubuntu 24.04 LTS or Debian 12+), **when** execution completes, **then** a systemd service is installed, started, and configured for auto-start on boot; install aborts with clear error on unsupported OS. _(Edge 16: unsupported OS → clean abort, list supported versions. Critical-path: modular install — separate functions detect-OS/install-binary/write-systemd-unit/register-target.)_
- [ ] **REQ-011** (J2, High) Establish outbound WebSocket from Relay Agent to SaaS — **Given** the Relay Agent systemd service is running with valid tenant credentials, **when** the service starts, **then** it establishes an outbound WebSocket to CoreCI Chat SaaS within 60 seconds.
- [ ] **REQ-012** (J2, High) Register Relay Agent with tenant + target metadata — **Given** a Relay Agent connects, **when** registration completes, **then** tenant ID, target ID, hostname, OS name and version, IP address, and agent version are recorded. _(Edge 12: registration fails → error + troubleshooting link, dashboard red.)_
- [ ] **REQ-013** (J2, High) Maintain heartbeat and auto-reconnect on WebSocket drop — **Given** the WebSocket drops, **when** 30 seconds elapse without reconnect, **then** the Relay Agent initiates reconnection with exponential backoff (max 5 attempts before alerting); systemd auto-restarts on hard failure. _(Edge 4: drops mid-investigation → auto-reconnect, resume from durable state.)_
- [ ] **REQ-014** (J2, Med) Surface Relay Agent health and logs in admin dashboard — **Given** a Relay Agent is registered, **when** an Admin views the dashboard, **then** health status (green/yellow/red), target hostname, and the last 100 log lines are visible.
### Security & Compliance (M1)
- [ ] **REQ-038** (J1, J2, High) Log every prompt, tool call, SSH command, and response to immutable audit store — **Given** any of these events occur, **when** the audit log write runs, **then** the entry is written to a write-once store with tenant ID, user ID, target ID (for SSH), timestamp, and correlation ID; write failures halt the operation. _(Edge 7: write fails → halt + alert, no silent drops. Critical-path: append-only from day one; hash-chain pattern propagates to M2/M3.)_
- [ ] **REQ-039** (J1, J2, High) Implement Row-Level Security on all tenant-scoped data — **Given** any database query is executed, **when** the query runs, **then** RLS policies enforce tenant scoping and cross-tenant queries return empty results. _(Critical-path: zero leakage verified by pen test.)_
- [ ] **REQ-040** (J2, High) Store tenant credentials in centralized secret manager — **Given** any tenant credential (BYOM API key, Proxmox token, SSH key, Git token) is stored, **when** stored, **then** it resides in the centralized secret manager and never in plaintext in application logs or DB rows. _(Critical-path: every credential via secret manager from the first secret. No env vars, no config files, no DB columns. Ever.)_
## Deferred to M2 (REQ-015 → REQ-027 — MCP Layer & Day 1 Adapters)
Listed for traceability; NOT in M1 scope. M2 acceptance gate: all four Day 1 integrations respond to a test call, multi-target scoping functional, read-only enforcement verified at both gateway and Relay Agent layers (including SSH whitelist). See spec §2.3.
REQ-015 (abstract MCP tool schema), REQ-016 (route to adapter), REQ-017 (SSE stream), REQ-018 (read-only at gateway), REQ-019 (rate limit), REQ-020 (Proxmox adapter), REQ-021 (SSH/Linux adapter), REQ-022 (GitHub adapter), REQ-023 (Gitea adapter), REQ-024 (multi-target scope), REQ-025 (Proxmox auth PVEAuditor), REQ-026 (SSH key + whitelist enforcement at Relay Agent — **whitelist file format + enforcement hook ship in M1, adapter plugs in M2**), REQ-027 (Git scoped tokens).
## Deferred to M3 (REQ-028 → REQ-037, REQ-041 → REQ-044 — Chat, Orchestration, Hardening)
Listed for traceability; NOT in M1 scope. M3 acceptance gate: Operator asks a diagnostic question, sees streamed tool execution, receives a cited evidence-backed answer within 5 min p95; async workflows persist/rejoin; usage metered; SOC 2 controls instrumented; all v0.1 release gates pass.
REQ-028 (chat UI), REQ-029 (NL input), REQ-030 (streaming response + citations), REQ-031 (tool traces), REQ-032 (conversation history), REQ-033 (reason about tools), REQ-034 (multi-step workflows), REQ-035 (≤20 step limit), REQ-036 (durable execution), REQ-037 (rejoin workflow), REQ-041 (SOC2 posture page), REQ-042 (Vanta instrumentation), REQ-043 (usage metering), REQ-044 (usage dashboard).
## Out of Scope (v0.1 — do not build)
| Feature | Reason |
|---------|--------|
| Implementation source code | Init only — no implementation work during phase 0 |
| Remote git push | No `origin` remote configured; Gitea target is for future ship phases |
| Milestone release tag (v0.1.0) | Phase 0 ships a patch (v0.0.x line); milestone tag is created only when the final phase ships |
| Full specification parsing | Deferred to a follow-up session per user instruction |
| Write actions (apply/delete/scale/restart/VM start-stop) | v1.1 (spec §2.2) |
| Hosted LLM inference | Never — BYOM permanent (spec §2.2) |
| Kubernetes / ArgoCD / Helm | Not planned (spec §2.2) |
| Slack / Teams / Discord / CLI / mobile chat surfaces | v1.1+ / not planned (spec §2.2) |
| Approval-gated remediation, Senior Approver persona | v1.1 (spec §2.2) |
| RAG over historical incidents | v1.1 (spec §2.2) |
| SOC 2 Type 1 final certification | Audit-in-progress posture only (spec §2.2) |
| Custom RBAC roles beyond Admin/Operator/Viewer | v1.2+ (spec §2.2) |
| BYOK / customer-managed encryption keys | v1.2+ (spec §2.2) |
| Multi-region deployment | Single region MVP (spec §5) |
| Windows server management | Not planned v1.x (spec §2.2) |
| Fine-tuning, custom model deployments | Not planned (spec §2.2) |
| Anything not in the spec | Flag as spec-time scope question; never silently add |
## Traceability
| Requirement | Phase | Status |
|-------------|-------|--------|
| REQ-001 | Phase 0 | pending |
| REQ-002 | Phase 0 | pending |
| REQ-003 | Phase 0 | pending |
| REQ-004 | Phase 0 | pending |
| REQ-005 | Phase 0 | complete |
| REQ-006 | Phase 0 | complete |
| REQ-007 | Phase 0 | complete |
| Requirement | Milestone | Phase | Status |
|-------------|-----------|-------|--------|
| REQ-001 | M1 | Wave B | pending |
| REQ-002 | M1 | Wave B | pending |
| REQ-003 | M1 | Wave B | pending |
| REQ-004 | M1 | Wave B | pending |
| REQ-005 | M1 | Wave B | pending |
| REQ-006 | M1 | Wave C | pending |
| REQ-007 | M1 | Wave C | pending |
| REQ-008 | M1 | Wave C | pending |
| REQ-009 | M1 | Wave C | pending |
| REQ-010 | M1 | Wave D | pending |
| REQ-011 | M1 | Wave D | pending |
| REQ-012 | M1 | Wave D | pending |
| REQ-013 | M1 | Wave D | pending |
| REQ-014 | M1 | Wave E | pending |
| REQ-015 | M2 | — | deferred |
| REQ-016 | M2 | — | deferred |
| REQ-017 | M2 | — | deferred |
| REQ-018 | M2 | — | deferred |
| REQ-019 | M2 | — | deferred |
| REQ-020 | M2 | — | deferred |
| REQ-021 | M2 | — | deferred (whitelist hook ships M1 Wave D) |
| REQ-022 | M2 | — | deferred |
| REQ-023 | M2 | — | deferred |
| REQ-024 | M2 | — | deferred |
| REQ-025 | M2 | — | deferred |
| REQ-026 | M2 | — | deferred (whitelist format + hook ships M1 Wave D) |
| REQ-027 | M2 | — | deferred |
| REQ-028 | M3 | — | deferred |
| REQ-029 | M3 | — | deferred |
| REQ-030 | M3 | — | deferred |
| REQ-031 | M3 | — | deferred |
| REQ-032 | M3 | — | deferred |
| REQ-033 | M3 | — | deferred |
| REQ-034 | M3 | — | deferred |
| REQ-035 | M3 | — | deferred |
| REQ-036 | M3 | — | deferred |
| REQ-037 | M3 | — | deferred |
| REQ-038 | M1 | Wave A | pending |
| REQ-039 | M1 | Wave A | pending |
| REQ-040 | M1 | Wave A | pending |
| REQ-041 | M3 | — | deferred |
| REQ-042 | M3 | — | deferred |
| REQ-043 | M3 | — | deferred |
| REQ-044 | M3 | — | deferred |
+338
View File
@@ -0,0 +1,338 @@
# CoreCI Chat v0.1 — Engineering Specification v1.1 (FINAL)
**Owner:** Sarah Chen
**Status:** Locked (v1.1)
**Type:** Feature (MVP)
**Target Milestone:** CoreCI Chat v0.1 — Read-Only Diagnostic MVP
**Companion Product:** CoreCI (existing CI/CD platform by owner)
**Locked Date:** 2026-08-24
> **Operating Principles for this Spec:**
> 1. **Incremental Delivery:** Defines net-new work for CoreCI Chat v0.1. Pre-existing systems and locked architectures are referenced, not restated.
> 2. **Zero Ambiguity:** Any requirement not translatable to a pass/fail QA test is rejected by Engineering.
> 3. **No Scope Expansion:** Any requirement discovered during spec build that is not authorized by CoreCI Chat Vision v1.0 / Phase 2 scope will be flagged as a spec-time scope question and escalated — never silently added.
---
## 1. Objective
CoreCI Chat v0.1 delivers a browser-based chat interface where mid-market enterprise IT operators ask natural-language questions about their infrastructure and receive coherent, evidence-backed diagnostic answers within five minutes. CoreCI Chat speaks MCP to a Relay Agent installed as a systemd service on the customer's Linux servers (Ubuntu 24.04 or Debian), and directly to Proxmox and GitHub/Gitea APIs. All AI inference is routed through a customer-provided model endpoint (BYOM). Every prompt, tool call, and command execution is immutably audited. The wedge is deliberately conservative: CoreCI Chat investigates in v0.1 and proposes remediation in v1.1. CoreCI Chat is a companion product to CoreCI (the owner's existing CI/CD platform).
*Acceptance Gate:* A developer reading this can state the goal of the feature in a single sentence.
---
## 2. Scope & Target Milestones
### 2.1 In Scope (Explicit Additions)
**Core Application**
- Browser-based chat UI (no mobile, no native apps, no CLI)
- Streaming tool execution traces with inline citations
- Conversation history persistence per user/tenant
- Tenant admin dashboard
**AI Orchestration**
- LLM orchestration engine (BYOM endpoint routing only — no hosted inference)
- Async durable execution for long-running tool calls
- Conversation memory within session
- Rejoin-in-progress async workflow
- LLM step limit (≤20 tool calls per workflow)
**MCP Layer**
- Abstract generic MCP tool schema
- MCP gateway with read-only enforcement at proxy layer
- Adapter implementations (Day 1): Proxmox, SSH/Linux Server, GitHub, Gitea
- Multi-tenancy isolation at gateway
- SSE streaming from MCP to UI
- Token-bucket rate limiting (per user, per tenant)
**Relay Agent**
- Lightweight systemd service running on Linux hosts (Ubuntu 24.04, Debian 12+)
- Distribution via install script (curl|bash or apt package)
- Outbound WebSocket to CoreCI Chat SaaS (no inbound firewall rules required)
- Read-only enforcement at Relay Agent layer for SSH command execution
- Heartbeat, health check, and auto-reconnect
- Per-target registration (each Relay Agent = one target)
**Identity & Access**
- SSO/SAML via WorkOS (or equivalent)
- RBAC: Admin, Operator, Viewer roles
- Per-tenant credential storage in centralized secret manager
**Security & Compliance**
- Immutable audit logging (prompts, tool calls, SSH commands, responses)
- Row-Level Security on all tenant-scoped data
- "SOC 2 Type 1 Audit in Progress" posture published
- GRC platform (Vanta or Drata) instrumentation
**Pricing Infrastructure**
- Usage metering layer (tool calls, LLM tokens, workflow executions)
- Per-tenant usage dashboard for Admin
**Out-of-Box Setup**
- Install script for Relay Agent
- Configuration templates for Day 1 integrations
- Pre-built smoke-test investigation scenarios
### 2.2 Out of Scope (Explicit Exclusions)
- Write actions of any kind (apply, delete, scale, rollback, restart, container start/stop, VM start/stop) — deferred to v1.1
- Approval-gated remediation workflows and Senior Approver persona — v1.1
- Remediation diff preview UI — v1.1
- Hosted LLM inference from CoreCI Chat — never (BYOM is permanent)
- Fine-tuning on customer data
- Custom model deployments managed by CoreCI Chat
- MCP integrations beyond Proxmox, SSH/Linux Server, GitHub, Gitea — v1.2+
- Custom MCP server authoring tools for customers — v1.2+
- Inbound webhook ingestion from alerting tools (manual chat launch only in MVP)
- Visual drag-and-drop workflow builder (LLM-driven dynamic only in MVP)
- Workflow templates, sharing, versioning — v1.2+
- Slack / Teams / Discord chat interfaces — v1.1+
- Mobile apps — not planned for v1.x
- CLI for power users — v1.1
- Email notifications — v1.1
- Multi-region deployment (single region MVP)
- White-label / multi-brand tenants
- Custom RBAC roles beyond Admin / Operator / Viewer — v1.2+
- Audit log query UI (logs captured and exportable, not searchable in MVP) — v1.2+
- RAG over historical incidents, post-mortems, Slack threads — v1.1
- SOC 2 Type 1 final certification — controls in place, audit running, cert post-MVP
- HIPAA, FedRAMP, PCI, ISO 27001 — not planned for v1.x
- Customer-managed encryption keys (BYOK) — v1.2+
- Data residency controls beyond BYOM (single region MVP)
- **Kubernetes integration** of any kind — not planned
- **ArgoCD integration** of any kind — not planned
- **Helm-based distribution** of any kind — not planned
- Container orchestration surfaces (Kubernetes, Nomad, Docker Swarm, etc.) — not planned for v1.x
- Windows server management — not planned for v1.x (Linux only)
### 2.3 Milestone Breakdown
* **Milestone 1 — Foundation (Weeks 13):** Ships REQ-001 through REQ-014, REQ-038, REQ-039, REQ-040.
* _Acceptance Gate:_ Platform Lead can sign up via SSO, configure a BYOM endpoint with green validation, deploy Relay Agent via install script on at least one target Linux host, register the target, and see green status in admin dashboard. Audit logging, RLS, and secret manager are operational.
* **Milestone 2 — MCP Layer & Day 1 Adapters (Weeks 45):** Ships REQ-015 through REQ-027.
* _Acceptance Gate:_ Platform Lead can configure all four Day 1 integrations (Proxmox, SSH target, GitHub or Gitea) and verify each adapter responds to a test call from the admin dashboard. Multi-target scoping is functional. Read-only enforcement is verified at both gateway and Relay Agent layers (including SSH command whitelist).
* **Milestone 3 — Chat, Orchestration, Hardening (Weeks 68):** Ships REQ-028 through REQ-037, REQ-041 through REQ-044.
* _Acceptance Gate:_ Operator can ask a natural-language diagnostic question, see streamed tool execution, and receive a cited, evidence-backed answer within 5 minutes (p95). Async workflows persist and rejoin correctly. Usage is metered. SOC 2 controls are instrumented. All v0.1 release gates pass.
---
## 3. Personas & User Journeys
### 3.1 Personas
* **Persona A — The Operator (Primary User):** SRE, Sysadmin, or Platform Engineer who owns infrastructure reliability across on-prem Proxmox environments, Linux servers (Ubuntu/Debian), and Git-based CI/CD workflows. Day is SSH sessions, Proxmox UI, GitHub/Gitea, observability tools, Slack, Jira. Pain is real-time cognitive load during incidents across heterogeneous infrastructure. MVP authority: read-only across all integrated systems.
* **Persona B — The Platform Lead / Tenant Admin (Secondary User):** Senior platform engineer or IT lead who owns the CoreCI Chat tenant. Connects MCP integrations, deploys Relay Agents, configures BYOM endpoint, manages RBAC, reviews audit logs. Pain is setup time for a small team.
### 3.2 Happy Paths
**Journey 1 — Operator performs diagnostic investigation to achieve evidence-backed root cause in under 5 minutes**
1. **Step 1:** Operator opens CoreCI Chat in browser → Chat UI loads with input field, history, and streaming area. _(Maps to REQ-028)_
2. **Step 2:** Operator types natural-language question and submits → Submission accepted, orchestration begins. _(Maps to REQ-029)_
3. **Step 3:** LLM (via BYOM) reasons about which abstract MCP tools to invoke → Tool selection recorded. _(Maps to REQ-033)_
4. **Step 4:** Orchestrator invokes abstract tools; gateway routes to tenant-specific adapters → Routing confirmed with tenant context. _(Maps to REQ-015, REQ-016)_
5. **Step 5:** Adapter executes read-only query (Proxmox, SSH, GitHub, or Gitea); read-only enforced at both layers → Query results returned, write attempts blocked. SSH commands go through whitelist enforcement. _(Maps to REQ-018, REQ-020, REQ-021, REQ-022, REQ-023, REQ-024, REQ-025, REQ-026, REQ-027)_
6. **Step 6:** Tool execution output streams to UI in real-time → Trace panel updates as each tool returns. _(Maps to REQ-017, REQ-031)_
7. **Step 7:** LLM synthesizes cited answer from tool evidence → Response rendered inline with citations. _(Maps to REQ-030)_
8. **Step 8:** If workflow exceeds 30s, state persists; user can rejoin → Resume works seamlessly. _(Maps to REQ-036, REQ-037)_
9. **Step 9:** Audit log captures prompt, all tool calls (including SSH commands), all responses → Immutable entries written. _(Maps to REQ-038)_
10. **Step 10:** Conversation history persisted per user/tenant → Available next session. _(Maps to REQ-032)_
* **Testable Acceptance (BDD Format):**
* [x] **Given** an Operator is authenticated and on the chat page, **when** they submit "why is `web-server-01` throwing 503s in production", **then** within 5 minutes (p95) the response includes a cited root-cause hypothesis referencing at least one tool execution (Proxmox VM state, SSH service status, or recent deploy commit).
* [x] **Given** the LLM invokes a tool, **when** the tool returns, **then** a tool trace entry is rendered in the UI within 1 second of the return.
* [x] **Given** the workflow completes, **when** the Operator refreshes or returns later, **then** the conversation is fully retrievable with prompts, tool calls, SSH command outputs, and responses.
**Journey 2 — Platform Lead onboards a CoreCI Chat tenant to achieve working integration in under 2 hours**
1. **Step 1:** Platform Lead signs up via SSO → Session established, tenant created, user assigned Admin. _(Maps to REQ-001, REQ-002)_
2. **Step 2:** Platform Lead configures BYOM endpoint (URL + API key) → Endpoint validated with green test call. _(Maps to REQ-006, REQ-007)_
3. **Step 3:** Platform Lead runs Relay Agent install script on target Linux host(s) → systemd service installed and started. _(Maps to REQ-010, REQ-011)_
4. **Step 4:** Relay Agent establishes outbound WebSocket → Registered with tenant + target metadata (hostname, OS, IP). _(Maps to REQ-012)_
5. **Step 5:** Platform Lead configures Day 1 integrations (Proxmox, SSH targets, GitHub or Gitea) → Adapters activated with credentials. _(Maps to REQ-020, REQ-021, REQ-022, REQ-023, REQ-025, REQ-026, REQ-027)_
6. **Step 6:** Platform Lead verifies multi-target scope where applicable → Target selector functions correctly. _(Maps to REQ-024)_
7. **Step 7:** Platform Lead assigns RBAC roles (Operator, Viewer) to team members → Roles enforced on next API call. _(Maps to REQ-003, REQ-004, REQ-005)_
8. **Step 8:** Platform Lead runs smoke-test investigation → End-to-end diagnostic returns expected result. _(Maps to REQ-033, REQ-034, REQ-035)_
9. **Step 9:** Relay Agent health and logs visible in admin dashboard → Status green, logs accessible. _(Maps to REQ-014)_
10. **Step 10:** Usage metering is active → Counters increment for tool calls, LLM tokens, workflow executions. _(Maps to REQ-043, REQ-044)_
* **Testable Acceptance (BDD Format):**
* [x] **Given** a Platform Lead completes signup via SSO, **when** the dashboard loads, **then** a new tenant exists with the user as Admin and all onboarding steps are visible.
* [x] **Given** the Relay Agent install script is executed with valid tenant credentials, **when** the systemd service starts, **then** an outbound WebSocket to CoreCI Chat SaaS is established within 60 seconds and health status turns green.
* [x] **Given** all onboarding steps complete, **when** the Platform Lead runs the smoke-test scenario, **then** the diagnostic returns a result, audit log entries are written (including SSH commands if invoked), and usage counters increment.
### 3.3 Failure & Edge Paths
* **Edge 1 (J1):** BYOM endpoint unreachable mid-workflow → System displays actionable error, suggests reconfiguration, halts workflow. Handled via REQ-009.
* **Edge 2 (J1):** LLM step limit hit (>20 tool calls) → Workflow halts with clear error to user; partial results preserved. Handled via REQ-035.
* **Edge 3 (J1):** MCP adapter times out → Surface timeout with retry option; tool trace shows failure. Handled via REQ-016, REQ-017.
* **Edge 4 (J1):** Relay Agent WebSocket drops mid-investigation → Auto-reconnect via exponential backoff; workflow resumes from durable state. Handled via REQ-013, REQ-036.
* **Edge 5 (J1):** Rate limit hit → HTTP 429 surfaced with retry-after window. Handled via REQ-019.
* **Edge 6 (J1):** Multi-target scope ambiguous (multiple targets registered, no selection) → Prompt user to select target before tool execution. Handled via REQ-024.
* **Edge 7 (J1):** Audit log write fails → Operation halts; admin alerted; no silent drops. Handled via REQ-038.
* **Edge 8 (J1):** Write-action request submitted to MCP gateway → Rejected with HTTP 403 and audited. Handled via REQ-018.
* **Edge 9 (J1):** SSH command not on whitelist → Command rejected at Relay Agent, error returned to LLM, audit log records attempt. Handled via REQ-026.
* **Edge 10 (J2):** SSO provider down → Error displayed with retry; tenant creation blocked. Handled via REQ-001.
* **Edge 11 (J2):** BYOM endpoint test fails on save → Save blocked; error details surfaced. Handled via REQ-007.
* **Edge 12 (J2):** Relay Agent fails to register → Registration error with troubleshooting link; dashboard shows red status. Handled via REQ-012.
* **Edge 13 (J2):** MCP adapter auth fails (Proxmox token, SSH key, Git token) → Credential validation error; integration not activated. Handled via REQ-025, REQ-026, REQ-027.
* **Edge 14 (J2):** Smoke-test investigation fails → Specific failure point surfaced (LLM, adapter, network, auth). Handled via REQ-033, REQ-034.
* **Edge 15 (J2):** Email invitation bounces → Admin notified; invitation marked invalid. Handled via REQ-003.
* **Edge 16 (J2):** Unsupported OS detected during Relay Agent install → Install aborted with clear message listing supported OS versions. Handled via REQ-010.
---
## 4. Functional Requirements
_Every REQ must map to at least one journey and possess testable criteria._
| ID | Title | Journeys | Priority | Acceptance Criteria (Given/When/Then or explicit rules) |
| :--- | :--- | :--- | :--- | :--- |
| **REQ-001** | Establish SSO session via identity provider | J2 | High | **Given** an unauthenticated user navigates to CoreCI Chat, **when** they complete SSO flow via the configured IdP, **then** a session is established and they are redirected to the dashboard. |
| **REQ-002** | Provision tenant on first signup | J2 | High | **Given** a user completes signup for the first time, **when** tenant creation runs, **then** a new tenant is created, the user is assigned Admin role, and the admin dashboard loads. |
| **REQ-003** | Invite users to tenant via email | J2 | High | **Given** an Admin submits an invitation, **when** the system processes the invite, **then** an email is sent to the invitee containing a single-use acceptance link. |
| **REQ-004** | Apply RBAC role to user | J2 | High | **Given** an Admin assigns a role (Admin/Operator/Viewer), **when** the assignment is saved, **then** the user's role is updated and enforced on the next API call. |
| **REQ-005** | Enforce RBAC at API gateway | J1, J2 | High | **Given** a user with role X calls endpoint Y, **when** the role check runs, **then** the request is allowed iff X has permission for Y. |
| **REQ-006** | Configure BYOM endpoint (URL + API key) | J2 | High | **Given** an Admin submits endpoint URL and API key, **when** the form is saved, **then** the API key is stored in the secret manager and the URL is validated. |
| **REQ-007** | Validate BYOM endpoint connectivity on save | J2 | High | **Given** an Admin submits a BYOM endpoint, **when** validation runs, **then** a test inference call is sent and the result is displayed as success or failure with error details. |
| **REQ-008** | Route all LLM inference to configured BYOM endpoint | J1, J2 | High | **Given** a user submits a prompt, **when** orchestration runs, **then** 100% of LLM inference calls are sent to the configured BYOM endpoint (verified via outbound traffic log). |
| **REQ-009** | Reject LLM request when BYOM is unconfigured or unreachable | J1, J2 | High | **Given** no BYOM endpoint is configured or it is unreachable, **when** an Operator submits a prompt, **then** the request is rejected with a clear actionable error and no inference is attempted. |
| **REQ-010** | Distribute Relay Agent as systemd service via install script | J2 | High | **Given** a Platform Lead runs the install script on a supported host (Ubuntu 24.04 LTS or Debian 12+), **when** execution completes, **then** a systemd service is installed, started, and configured for auto-start on boot; install aborts with clear error on unsupported OS. |
| **REQ-011** | Establish outbound WebSocket from Relay Agent to SaaS | J2 | High | **Given** the Relay Agent systemd service is running with valid tenant credentials, **when** the service starts, **then** it establishes an outbound WebSocket to CoreCI Chat SaaS within 60 seconds. |
| **REQ-012** | Register Relay Agent with tenant + target metadata | J2 | High | **Given** a Relay Agent connects, **when** registration completes, **then** tenant ID, target ID, hostname, OS name and version, IP address, and agent version are recorded. |
| **REQ-013** | Maintain heartbeat and auto-reconnect on WebSocket drop | J2 | High | **Given** the WebSocket drops, **when** 30 seconds elapse without reconnect, **then** the Relay Agent initiates reconnection with exponential backoff (max 5 attempts before alerting); systemd auto-restarts on hard failure. |
| **REQ-014** | Surface Relay Agent health and logs in admin dashboard | J2 | Med | **Given** a Relay Agent is registered, **when** an Admin views the dashboard, **then** health status (green/yellow/red), target hostname, and the last 100 log lines are visible. |
| **REQ-015** | Define abstract MCP tool schema | J1, J2 | High | **Given** the MCP gateway receives a call, **when** it routes, **then** calls match one of the approved abstract tools: `get_logs`, `list_resources`, `describe_topology`, `get_recent_deploys`, `list_events`, `get_metrics`, `list_ci_runs`, `get_ci_run`. |
| **REQ-016** | Route abstract MCP calls to tenant-specific adapter | J1, J2 | High | **Given** an Operator submits a prompt, **when** the LLM requests an abstract tool, **then** the gateway routes to the tenant's specific adapter (Proxmox, SSH, GitHub, or Gitea) based on tool type and tenant config. |
| **REQ-017** | Stream tool execution output to chat UI via SSE | J1 | High | **Given** an Operator submits a prompt, **when** tool calls execute, **then** partial results are streamed to the UI within 1 second of each tool return. |
| **REQ-018** | Enforce read-only at MCP gateway proxy layer | J1, J2 | High | **Given** any write-action request (POST, PUT, DELETE, PATCH) is submitted to MCP, **when** the gateway processes it, **then** the request is rejected with HTTP 403 and audited. |
| **REQ-019** | Apply token-bucket rate limit per user and per tenant | J1 | Med | **Given** a user exceeds 60 req/min or a tenant exceeds 300 req/min, **when** the next request arrives, **then** the request is rejected with HTTP 429 and the limit window is communicated. |
| **REQ-020** | Implement read-only Proxmox MCP adapter | J1, J2 | High | **Given** an Operator requests VM list or VM status, **when** the adapter executes, **then** a list of VMs (ID, name, status, node, resource allocation) is returned, no state mutation is possible, and the audit log records the call. Supports Proxmox VE 7.x and 8.x. |
| **REQ-021** | Implement read-only SSH/Linux Server MCP adapter | J1, J2 | High | **Given** an Operator requests system state (e.g., service status, disk usage, recent logs), **when** the adapter executes, **then** a whitelisted read-only command runs via SSH and the output is returned; commands not on the whitelist are rejected at the Relay Agent layer; audit log records the full command and output. |
| **REQ-022** | Implement read-only GitHub MCP adapter | J1, J2 | High | **Given** an Operator requests recent commits, PRs, or Actions workflow runs, **when** the adapter executes, **then** the requested data is returned, no state mutation is possible, and the audit log records the call. |
| **REQ-023** | Implement read-only Gitea MCP adapter | J1, J2 | High | **Given** an Operator requests repositories, commits, PRs, or Gitea Actions runs, **when** the adapter executes, **then** the requested data is returned, no state mutation is possible, and the audit log records the call. |
| **REQ-024** | Scope MCP queries to explicitly selected target in multi-target tenants | J1, J2 | High | **Given** a tenant has ≥2 registered targets and the Operator selects target X, **when** any MCP call executes, **then** only target X is queried and results are labeled with target identifier. |
| **REQ-025** | Authenticate to Proxmox via scoped API token + read-only role | J2 | High | **Given** a customer creates a Proxmox user with `PVEAuditor` role and generates an API token, **when** the adapter authenticates, **then** API calls succeed only for read-only operations; the token is stored in the secret manager. |
| **REQ-026** | Authenticate to Linux servers via SSH key with command whitelist enforcement at Relay Agent | J2 | High | **Given** a customer generates an SSH keypair for the Relay Agent and authorizes it on the target host, **when** the Relay Agent receives a tool call, **then** only commands on the approved whitelist (`cat`, `ls`, `systemctl status`, `journalctl`, `df`, `du`, `ps`, `top`, `ss`, `netstat`, `ip`, `uptime`, `uname`, etc.) are executed; non-whitelisted commands are rejected and audited. |
| **REQ-027** | Authenticate to GitHub and Gitea via scoped API tokens | J2 | High | **Given** a customer provides a GitHub or Gitea API token with read-only scope, **when** the adapter authenticates, **then** API calls succeed only for permitted resources; the token is stored in the secret manager. |
| **REQ-028** | Render chat interface in browser | J1 | High | **Given** an Operator navigates to CoreCI Chat, **when** the page loads, **then** a chat interface renders with input field, message history, and streaming output area. |
| **REQ-029** | Accept natural language input and submit for orchestration | J1 | High | **Given** an Operator types a question and submits, **when** the submission is processed, **then** the prompt is sent to the LLM orchestrator and streaming response begins within 3 seconds (p95). |
| **REQ-030** | Display streaming LLM response with inline citations | J1 | High | **Given** the LLM returns a response, **when** the response streams to the UI, **then** citations referencing specific tool calls or evidence are rendered inline and clickable to expand the underlying evidence (including raw SSH command output where applicable). |
| **REQ-031** | Display streaming tool execution traces | J1 | High | **Given** the orchestrator invokes tools, **when** each tool returns, **then** the UI displays the tool name, target, and a snippet of the result in a collapsible trace panel (SSH commands show full command + output snippet). |
| **REQ-032** | Persist conversation history per user/tenant | J1 | High | **Given** an Operator completes a conversation, **when** they reload or return later, **then** the conversation is retrievable in full (prompts, tool calls, responses). |
| **REQ-033** | Reason about which MCP tools to invoke from user prompt | J1 | High | **Given** an Operator asks a diagnostic question, **when** orchestration runs, **then** the LLM invokes at least one relevant abstract MCP tool (e.g., `get_logs`, `list_resources`, `get_recent_deploys`). |
| **REQ-034** | Execute multi-step tool sequences (LLM-driven dynamic workflows) | J1 | High | **Given** a complex question, **when** orchestration runs, **then** the LLM can chain multiple tool calls in sequence, with each result informing the next call. |
| **REQ-035** | Apply LLM step limit to prevent infinite loops | J1 | Med | **Given** an LLM attempts >20 tool calls in a single workflow, **when** the limit is reached, **then** the workflow halts with a clear error to the user and partial results are preserved. |
| **REQ-036** | Persist workflow state across async boundaries via durable execution | J1 | High | **Given** a workflow exceeds 30 seconds (e.g., long log query, slow SSH execution), **when** orchestration suspends, **then** state is persisted to durable execution store and the workflow can resume. |
| **REQ-037** | Allow user to rejoin in-progress async workflow | J1 | High | **Given** a workflow is in progress, **when** the Operator refreshes or returns, **then** they see current workflow state and can resume interaction. |
| **REQ-038** | Log every prompt, tool call, SSH command, and response to immutable audit store | J1, J2 | High | **Given** any of these events occur, **when** the audit log write runs, **then** the entry is written to a write-once store with tenant ID, user ID, target ID (for SSH), timestamp, and correlation ID; write failures halt the operation. |
| **REQ-039** | Implement Row-Level Security on all tenant-scoped data | J1, J2 | High | **Given** any database query is executed, **when** the query runs, **then** RLS policies enforce tenant scoping and cross-tenant queries return empty results. |
| **REQ-040** | Store tenant credentials in centralized secret manager | J2 | High | **Given** any tenant credential (BYOM API key, Proxmox token, SSH key, Git token) is stored, **when** stored, **then** it resides in the centralized secret manager and never in plaintext in application logs or DB rows. |
| **REQ-041** | Publish "SOC 2 Type 1 Audit in Progress" posture | J2 | Med | **Given** a prospect visits the security page, **when** they read, **then** the "Audit in Progress" posture is clearly stated with target completion timeline and current control coverage. |
| **REQ-042** | Instrument GRC platform with control evidence | J2 | Med | **Given** CoreCI Chat runs in production, **when** the GRC platform syncs, **then** evidence of controls (access logs, change management, vendor risk, incident response) is automatically collected. |
| **REQ-043** | Meter tool calls, LLM tokens, and workflow executions per tenant | J1, J2 | High | **Given** a tenant uses CoreCI Chat, **when** usage events occur, **then** counters increment for tool calls, LLM tokens, and workflow executions, and values are queryable per tenant per day. |
| **REQ-044** | Display per-tenant usage dashboard to Admin | J2 | Med | **Given** an Admin opens the usage dashboard, **when** the page loads, **then** current period tool calls, LLM tokens, workflow executions, and projected cost are displayed. |
---
## 5. Technical Constraints & NFRs (Non-Functional Requirements)
* **Read-Only by Default:** No write actions permitted at MCP gateway or Relay Agent layers. Threshold: 100% of write-action requests rejected at both layers with HTTP 403 (REQ-018). SSH write commands rejected at Relay Agent (REQ-026).
* **BYOM Mandatory:** All LLM inference routed to customer-configured endpoint. Threshold: 100% of inference calls outbound to customer endpoint; zero inference calls originate from CoreCI Chat infrastructure (REQ-008, REQ-009).
* **Multi-Tenancy Isolation:** All tenant-scoped data protected by Row-Level Security. Threshold: Zero cross-tenant data exposure verified via quarterly pen tests (REQ-039).
* **Audit Log Immutability:** All prompts, tool calls, SSH commands, and responses logged to write-once store. Threshold: 100% capture rate, zero deletes permitted (REQ-038).
* **SSH Command Whitelist Enforcement:** Relay Agent enforces command whitelist for all SSH-issued commands. Threshold: 100% of SSH commands checked against whitelist before execution; non-whitelisted commands rejected and audited (REQ-026).
* **Supported Target Operating Systems:** Ubuntu 24.04 LTS and Debian 12 (Bookworm) or later. Install script aborts on unsupported OS (REQ-010).
* **Supported Proxmox Versions:** Proxmox VE 7.x and 8.x. Older versions explicitly unsupported (REQ-020).
* **Time to First Streamed Token:** <3 seconds (p95) from user submission to first visible token.
* **Diagnostic Completion Time:** <5 minutes (p95) for typical investigation (≤10 tool calls).
* **Concurrent Workflows per Tenant:** ≥5 concurrent investigations per tenant.
* **LLM Step Limit:** ≤20 tool calls per workflow.
* **Conversation History Retention:** 90 days minimum, 1 year target.
* **SaaS Availability Target:** 99.5% uptime MVP, 99.9% target post-MVP.
* **Relay Agent Reconnection:** Auto-reconnect within 30 seconds of drop, exponential backoff, max 5 attempts before alerting; systemd auto-restarts on hard failure (REQ-013).
* **Browser Support:** Latest 2 versions of Chrome, Firefox, Safari, Edge.
* **Rate Limiting:** Token-bucket, 60 req/min per user, 300 req/min per tenant (REQ-019).
* **Encryption:** TLS 1.2+ in transit, AES-256 at rest.
* **Secret Handling:** All credentials stored in centralized secret manager (AWS Secrets Manager or equivalent); never logged in plaintext (REQ-040).
* **Single-Region Deployment:** MVP deploys to one region (us-east-1 default).
* **Browser-Only Chat UI:** No mobile apps, no native apps, no CLI, no Slack/Teams in MVP.
* **Systemd-Only Relay Agent Distribution:** Distributed exclusively as a systemd service via install script (REQ-010).
* **Per-Target Relay Agent Model:** Each Relay Agent registers as one target and queries only its own host. Multi-target environments deploy multiple agents (REQ-012, REQ-026).
* **Outbound-Only Network Model:** Relay Agent establishes outbound WebSocket to CoreCI Chat SaaS. No inbound firewall rules required from customer (REQ-011).
* **Self-Hosted Gitea Limitation:** CoreCI Chat SaaS requires network access to customer's self-hosted Gitea instance for read-only API calls. Customers must expose the Gitea API endpoint or run a Relay Agent locally.
* **Async Durable Execution Runtime:** **Trigger.dev** — best DX for TypeScript-first team, supports long-running workflows, cost-effective at MVP scale.
* **Identity Provider:** **WorkOS** — best enterprise SAML/SSO/SCIM coverage at mid-market price point; clean separation from product user model.
* **GRC Platform:** **Vanta** — best ecosystem integrations for AWS-native stacks; mature control monitoring.
---
## 6. Milestone Plan & Release Gates
**Test evidence required for Production Release:**
* [ ] Code coverage ≥ 80% on new modules
* [ ] CI/CD pipeline builds successfully (GREEN)
* [ ] QA sign-off: 100% of Journey 1 and Journey 2 integration tests pass
* [ ] Security/Compliance review approved (audit logging, RLS, secret handling, read-only enforcement, SSH whitelist enforcement verified)
* [ ] All Milestone 1, 2, and 3 acceptance gates passed (Section 2.3)
* [ ] All 16 Failure & Edge Paths have passing test cases (Section 3.3)
* [ ] Load test: ≥5 concurrent workflows per tenant sustained for 1 hour with no degradation
* [ ] Pen test: Cross-tenant data leakage test passed (zero leakage)
* [ ] SSH whitelist test: Attempt to execute non-whitelisted command (e.g., `rm -rf /tmp/test`) and verify rejection at Relay Agent with audit log entry
* [ ] Documentation: Admin onboarding guide, Operator quick-start, security & compliance page, public status page, Relay Agent install guide
**Pre-Production Design Partner Gate (recommended before GA):**
* [ ] At least 1 mid-market design partner (ideally existing CoreCI customer) completes full onboarding via Journey 2
* [ ] At least 3 distinct Operators across 2 design partners complete ≥10 diagnostic investigations via Journey 1
* [ ] Audit logs (including SSH command capture), usage metering, and Relay Agent health verified end-to-end in production-like environment
---
## 7. Open Questions & Assumptions
_Unresolved product or architectural questions. All questions below were resolved and approved by Product Owner on 2026-08-24._
1. **Async Durable Execution Runtime** — Trigger.dev vs Inngest vs Temporal.
* _Decision:_ **Trigger.dev** — best DX for TypeScript-first team, supports long-running workflows, cost-effective at MVP scale.
2. **Identity Provider** — WorkOS vs Clerk vs Auth0.
* _Decision:_ **WorkOS** — best enterprise SAML/SSO/SCIM coverage at mid-market price point; clean separation from product user model.
3. **GRC Platform** — Vanta vs Drata vs Secureframe.
* _Decision:_ **Vanta** — best ecosystem integrations for AWS-native stacks; mature control monitoring.
4. **Relay Agent Distribution Mechanism** — Install script (curl|bash) vs apt package vs Docker container.
* _Decision:_ **Install script (curl|bash) with apt package as fallback** — install script is fastest to ship and most flexible; apt package for design partners that prefer managed distribution. Docker container deferred to v1.1+.
5. **SSH Command Whitelist Maintenance** — Ship fixed whitelist with Relay Agent vs allow customer extension via config file.
* _Decision:_ **Ship fixed whitelist initially; allow customer extension via signed config in v1.1** — fixed whitelist is more secure for v0.1; extension mechanism requires careful design (signed configs, audit logging on whitelist changes).
6. **Proxmox Permission Model** — Built-in `PVEAuditor` role vs custom role with finer-grained permissions.
* _Decision:_ **Built-in `PVEAuditor` for v0.1** — simpler setup, well-understood scope. Custom role support in v1.1 if design partners request specific restrictions.
7. **Self-Hosted Gitea Access Pattern** — Customer exposes API to SaaS vs Relay Agent on Gitea host.
* _Decision:_ **Customer exposes API to SaaS for v0.1** (with documented firewall rules); Relay Agent variant deferred until demand justifies the engineering.
8. **Vector Store for v1.1 RAG (future-facing, not v0.1)** — PostgreSQL+pgvector vs dedicated (Pinecone, Weaviate).
* _Decision:_ **pgvector** — avoids new infrastructure; co-located with primary database.
---
## 8. Changelog
| Version | Date | Author | What Changed | REQs Affected |
| :--- | :--- | :--- | :--- | :--- |
| v1.0 | 2026-08-24 | Sarah Chen | Initial Draft generated from Steer Vision v1.0 and locked Phase 2 scope (superseded by v1.1) | REQ-001 REQ-043 (original) |
| v1.1 | 2026-08-24 | Sarah Chen | **Major revision per product owner pivot:** Product renamed CoreCI Chat (companion to existing CoreCI CI/CD platform). Removed all Kubernetes, ArgoCD, and Helm dependencies. Replaced Kubernetes MCP adapter with Proxmox MCP adapter. Removed ArgoCD MCP adapter. Added SSH/Linux Server MCP adapter with command whitelist enforcement at Relay Agent. Replaced ServiceAccount auth with SSH key auth; replaced Helm distribution with systemd service via install script. Renamed "multi-cluster" to "multi-target" scoping. Added supported OS constraint (Ubuntu 24.04, Debian 12+). Added Proxmox version support constraint (7.x, 8.x). Added 16th failure path (unsupported OS). Added 8th open question (self-hosted Gitea access pattern). Total REQs now 44 (was 43). Product Owner set to Sarah Chen. | REQ-010, REQ-011, REQ-012 (Relay Agent deployment), REQ-020 (Proxmox), REQ-021 (SSH/Linux — new), REQ-022/023 (GitHub/Gitea expanded for Actions), REQ-024 (multi-target), REQ-025 (Proxmox auth), REQ-026 (SSH auth + whitelist), REQ-027 (Git auth — new split), REQ-038 (audit log expanded for SSH commands) |
---
*End of CoreCI Chat v0.1 Engineering Specification v1.1*
*Product Owner: Sarah Chen — Locked 2026-08-24 — Ready for ciagent Milestone 1 implementation.*