learning_ai_notes/docs/PLATFORM_SMOKE_CHECKS.md

213 lines
6.9 KiB
Markdown

# NoteLett Platform Smoke Checks
Status: active production-readiness smoke reference
Last updated: May 5, 2026
Use these checks to prove NoteLett is running against the shared ByteLyst platform services, not only compiling against `@bytelyst/*` packages. The common-platform source of truth is `../learning_ai/learning_ai_common_plat`; prefer its compose files and scripts when bringing up shared services.
## 1. Bring Up Shared Services
From `../learning_ai/learning_ai_common_plat`:
```bash
docker compose up -d platform-service extraction-service mcp-server
docker compose ps platform-service extraction-service mcp-server
```
Expected local ports:
| Service | Port | Purpose |
| --- | ---: | --- |
| `platform-service` | 4003 | Auth, telemetry, diagnostics, flags, kill switch, blob, billing |
| `extraction-service` | 4005 | Extraction, task extraction, URL/content processing, transcription |
| `mcp-server` | 4007 | Shared MCP tool registry and tool execution |
| `notelett-backend` | 4016 | Product backend |
| `notelett-web` | 3000 | Product web app |
## 2. Environment
Use these defaults for local smoke runs:
```bash
export PLATFORM_URL="${PLATFORM_URL:-http://localhost:4003}"
export PLATFORM_API_URL="${PLATFORM_API_URL:-http://localhost:4003/api}"
export EXTRACTION_URL="${EXTRACTION_URL:-http://localhost:4005}"
export MCP_ORIGIN="${MCP_ORIGIN:-http://localhost:4007}"
export MCP_URL="${MCP_URL:-http://localhost:4007/api}"
export NOTELETT_URL="${NOTELETT_URL:-http://localhost:4016}"
export NOTELETT_API_URL="${NOTELETT_API_URL:-http://localhost:4016/api}"
export PRODUCT_ID=notelett
```
Authenticated platform, blob, and MCP calls require a platform bearer token:
```bash
export TOKEN="<platform-service JWT for a NoteLett viewer/admin test user>"
```
When using common-platform compose locally, generate test tokens with the same mechanism used by `../learning_ai/learning_ai_common_plat/scripts/prototype-self-test.sh`: execute inside `platform-service` and call the built `createAccessToken()` helper with `productId: "notelett"`.
## 3. Unauthenticated Health
These should pass before authenticated smoke checks:
```bash
curl -sf "$PLATFORM_URL/health"
curl -sf "$EXTRACTION_URL/health"
curl -sf "$MCP_ORIGIN/health"
curl -sf "$NOTELETT_URL/health"
curl -sf "$NOTELETT_API_URL/bootstrap"
```
Expected:
- all health endpoints return 2xx
- `GET /api/bootstrap` returns `productId: "notelett"` and backend port `4016`
- if extraction sidecar is not enabled, service health can still pass while sidecar-specific checks below report degraded/unavailable
## 4. Platform-Service Checks
Telemetry:
```bash
curl -sf "$PLATFORM_API_URL/telemetry/config?productId=$PRODUCT_ID" \
-H "Authorization: Bearer $TOKEN"
curl -sf "$PLATFORM_API_URL/telemetry/events" \
-H "Authorization: Bearer $TOKEN" \
-H "content-type: application/json" \
-d '{"productId":"notelett","eventName":"notelett.smoke","timestamp":"2026-05-05T00:00:00.000Z","properties":{"source":"platform-smoke"}}'
```
Diagnostics:
```bash
curl -sf "$PLATFORM_API_URL/diagnostics/config?productId=$PRODUCT_ID" \
-H "Authorization: Bearer $TOKEN"
curl -sf "$PLATFORM_API_URL/diagnostics/sessions?productId=$PRODUCT_ID&limit=1" \
-H "Authorization: Bearer $TOKEN"
```
Feature flags and kill switch:
```bash
curl -sf "$PLATFORM_API_URL/flags?productId=$PRODUCT_ID" \
-H "Authorization: Bearer $TOKEN"
curl -sf "$PLATFORM_API_URL/flags/evaluate" \
-H "Authorization: Bearer $TOKEN" \
-H "content-type: application/json" \
-d '{"productId":"notelett","flagKey":"notelett.enabled","context":{"userId":"smoke-user"}}'
```
Blob:
```bash
curl -sf "$PLATFORM_API_URL/blob/containers" \
-H "Authorization: Bearer $TOKEN"
curl -sf "$PLATFORM_API_URL/blob/sas" \
-H "Authorization: Bearer $TOKEN" \
-H "content-type: application/json" \
-d '{"container":"attachments","blobName":"notelett/smoke/hello.txt","permissions":"rw","expiresInMinutes":10}'
```
For an end-to-end local blob upload/delete cycle, prefer the common-platform pattern in `scripts/prototype-self-test.sh` and substitute `productId: "notelett"` plus a `notelett/smoke/` blob prefix.
## 5. Extraction-Service Checks
```bash
curl -sf "$EXTRACTION_URL/api/extract/models"
curl -sf "$EXTRACTION_URL/api/extract/sidecar-health"
curl -sf "$EXTRACTION_URL/api/extract/cache-stats"
```
For a minimal extraction task:
```bash
curl -sf "$EXTRACTION_URL/api/extract" \
-H "content-type: application/json" \
-d '{"productId":"notelett","taskType":"task_extraction","text":"Ship the production smoke checks and update the roadmap.","options":{"maxTasks":5}}'
```
Expected:
- models/cache endpoints return 2xx
- sidecar health may be `degraded` in local dev if the Python sidecar is intentionally disabled; record that explicitly rather than treating it as an unknown
- extraction responses should include structured output or a stable error body
## 6. MCP-Server Checks
```bash
curl -sf "$MCP_URL/tools" \
-H "Authorization: Bearer $TOKEN"
```
Confirm NoteLett tools are present in the returned registry, especially:
- `notes.notes.list`
- `notes.notes.get`
- `notes.notes.search`
- `notes.notes.create_draft`
- `notes.notes.update`
- `notes.relationships.link`
- `notes.tasks.extract`
- `notes.artifacts.attach`
Call a read-only tool:
```bash
curl -sf "$MCP_URL/tools/call" \
-H "Authorization: Bearer $TOKEN" \
-H "content-type: application/json" \
-d '{"name":"notes.notes.search","arguments":{"workspaceId":"<workspace-id>","query":"smoke","limit":5}}'
```
Expected:
- MCP server returns 2xx and wraps tool output in MCP `content`
- auth, role, product scope, request ID, and product backend errors are visible in logs
- write tools should be tested with dry-run/idempotency in P2.3/P3.5 before release
## 7. NoteLett Backend Checks
Start backend in memory mode for local product smoke:
```bash
DB_PROVIDER=memory \
JWT_SECRET="${JWT_SECRET:-dev-secret-do-not-use-in-prod}" \
PLATFORM_SERVICE_URL="$PLATFORM_URL" \
EXTRACTION_SERVICE_URL="$EXTRACTION_URL" \
MCP_SERVER_URL="${MCP_URL%/api}" \
pnpm --filter @notelett/backend run dev
```
Then check:
```bash
curl -sf "$NOTELETT_URL/health"
curl -sf "$NOTELETT_API_URL/bootstrap"
curl -sf "$NOTELETT_API_URL/diagnostics/config"
curl -sf "$NOTELETT_API_URL/diagnostics/flags"
curl -sf "$NOTELETT_API_URL/diagnostics/telemetry"
```
Expected:
- bootstrap identifies NoteLett
- diagnostics report `productId: "notelett"` and the configured shared service URLs
- production should not expose unauthenticated diagnostics without the P3.3 decision applied
## 8. Recording Results
For every smoke run, record:
- date/time and git commit
- which services were running locally or remotely
- exact commands run
- pass/fail for health, bootstrap, telemetry, diagnostics, flags, kill switch, blob, extraction, MCP, and product backend
- any intentional local-dev degradation, such as extraction sidecar unavailable
Production-readiness completion requires these checks to be automated or repeated through the final P10 gate.