Files
agent-platform/docs/RELEASE_NOTES.md
T
2026-07-06 07:17:40 +02:00

9.5 KiB
Raw Blame History

Release Notes — agent-platform v0

Version: v0 (api.py declares 0.3.0; first public release) Date: 2026-07-06 Release auditor: 3rd call this project (per 3-block cadence rule) Decision: HOLD for production — see §6 and §8 Repo: https://forgejo.media-on.de/Leopoldadmin/agent-platform Commit: 347ccb0 on main


1. What ships in v0

Architecture (matches PLAN.md §2)

  • Two-container deployment on Coolify:
    • agent-platform (FastAPI + LiteLLM + Pydantic-AI, HTMX UI, SQLite, audit)
    • mcp-tools (FastMCP server, 6 generic tools: echo, get_time, calculate, http_get, list_env, json_format)
  • MCP transport: http://mcp-tools:8501/mcp (FastMCP streamable-http).
  • SQLite at /data/agent-platform.db (named volume agent-data).
  • Traefik labels via env interpolation — durable fix for the Coolify-v4 build_pack stripping loadbalancer.server.port on expose.

Features

  • Agents — code-defined (agents/ Python modules) and DB-defined. CRUD: list / create / get / update / delete. enabled toggle (admin).
  • Chat/api/chat/<agent_id> (and /<conv_id>). LiteLLM provider abstraction via LLM_PROVIDER env (e.g. openrouter, anthropic, openai). Tool-call loop with per-agent allowed_tools whitelist.
  • Audit — every write action logged in audit table.
  • UI — server-rendered HTML (HTMX + Jinja2). Pages: dashboard, agents list, agent detail, chat, audit (admin).
  • Health/health (no auth) returns status, agent count, MCP reachability, current model.
  • Auth — Bearer token (static master + per-session token via sessions table).

Operational

  • .gitea/workflows/test.yml runs pytest on push/PR.
  • Coolify resource UUID n27nquozfhcgbph182ivbht3 runs both containers with healthchecks + depends_on: service_healthy.

2. Known issues (release-blocking? see §6)

Tag legend — 🟥 = production-blocker · 🟧 = risk to accept in writing · 🟨 = quality nit · 🟩 = mitigated

Security

  • 🟧 S2mcp_tools/server.py::http_get: SSRF protection blocks private/loopback/reserved IPv4, but follow_redirects=True plus un-pinned DNS allows DNS-rebinding bypass to internal targets. Effort: S (drop follow_redirects or resolve once + re-check).
  • 🟧 S3agents/example.py includes list_env in allowed_tools. Tool masks KEY/SECRET/TOKEN/PASSWORD, but any other env name (custom names like AGENT_PLATFORM_DB_PATH, MCP_*) leaks raw. Effort: S (narrow allowed_tools per agent or add explicit whitelist to list_env).
  • 🟧 S5 — Master AUTH_TOKEN logins are not recorded in audit. No way to detect token compromise from logs. Effort: S (add log_audit(..., action="token_auth") in auth.get_current_user).

Correctness

  • 🟨 C2DELETE /api/agents/<id> is annotated status_code=204 but the handler also returns a JSON body. FastAPI emits 204 + body — non-conformant; some clients may reject. Effort: XS (drop the return, or remove status_code=204 and return 200).
  • 🟨 C4llm.py does not capture LiteLLM cached_tokens (prompt-cache billing). Budget tracking will be off for cached calls. Effort: XS.
  • 🟨 C5db.py uses datetime.utcnow() (deprecated in 3.12). Will start emitting DeprecationWarning under Python ≥ 3.12. Effort: XS (datetime.now(timezone.utc)).
  • 🟨 C6discover_agents() is called on every FastAPI boot (sync_code_agents in lifespan). Once per process is already the case — partially mitigated by commit history; ongoing cost is just the import-time scan of agents/. Effort: XS.

Data

  • 🟧 D1 — No automated SQLite backup. The agent-data volume has no cron snapshotting. A volume loss = audit + agent-config loss. Effort: S (daily sqlite3 .backup cron on host + offsite).
  • 🟧 D3 — No alembic. Schema changes rely on CREATE TABLE IF NOT EXISTS. Adding a column = hand-edited SQL. Effort: M (init alembic on next schema change).

Missing

  • 🟧 M2 — UI auth flow (login page → token submit → cookie) not verified end-to-end in a real browser. Effort: S (manual click-through).
  • 🟧 M4 — No users table. Session user_id is a free-text column populated only via token-issuance (no UI). Multi-user identity is not enforceable. Effort: M.

Quality / DX (X1X7)

  • 🟨 Various developer-experience nits — docstrings, type hints, README polish. Not release-relevant. Effort: combined < M.

Mitigated (closed) — quality review v1

  • 🟩 B1B5 staging blockers (boot guard, MCP path, Dockerfile user, healthchecks/depends_on, Traefik labels).
  • 🟩 C3 — case-insensitive Bearer prefix (auth.py).
  • 🟩 S1MCPClient.health() CancelledError + asyncio.Lock (mcp_client.py).
  • 🟩 S6, X5 and the other 7 critical quality-review issues.
  • 🟩 21 pytest collected, 19 passed + 2 xpassed (347ccb0).

3. Upgrade path

There is no prior version of agent-platform on this repo — this is the first deploy. Future versions will follow the existing 6-phase lifecycle:

  1. Tag vN on the merge commit to main.
  2. Re-run release_auditor (this audit template).
  3. Promote to production via the checklist in §6.

Because agent-data is a Docker volume, schema-changing releases need:

  • Read-only backup of /data/agent-platform.db before upgrade.
  • Alembic migration (once D3 lands).

4. Production checklist (PROMOTE runbook)

Apply exactly these changes when promoting from staging → production. No environment-level "magic" beyond what is listed.

  1. Clone Coolify resource from staging (n27nquozfhcgbph182ivbht3) into a new production resource. Do not reuse the staging UUID.
  2. Bind production domain — replace the Traefik host label via the FQDN env var (compose already interpolates ${FQDN:-…}).
  3. Generate & paste a fresh AUTH_TOKEN (python -c "import secrets;print(secrets.token_urlsafe(48))"). Paste into Coolify env, not into .env in the repo. ≥ 32 chars, never the default literal.
  4. Rotate AUTH_TOKEN even on a feature-identical deploy — the staging token leaked to humans in chat logs.
  5. Paste LLM_API_KEY (provider-specific). Until then, /api/chat/* returns 500 (deliberate, surfaced by Gate-3 smoke test).
  6. Decide on residual security risk — sign off in writing on S2/S3/S5 or land the S-effort patches first (see §2).
  7. Enable SQLite backup cron0 3 * * * /usr/local/bin/sqlite3 /data/agent-platform.db ".backup /backups/agent-$(date +%F).db" (closes D1). Offsite-copy to Backblaze / S3 / Nextcloud.
  8. Verify post-deploycurl -fsS https://<prod-fqdn>/health → 200
    • mcp_server: "reachable"; curl -fsS -H "Authorization: Bearer $NEW_TOKEN" https://<prod-fqdn>/api/agents → 200 array.
  9. Tag the release commit: git tag -a v0.0.0 <sha> -m "agent-platform v0" && git push origin v0.0.0.
  10. Update current_status.md §2 to reflect production URL.

5. Rollback plan

Trigger: post-deploy health check fails, OR 5xx-rate > 1% in first 10 min.

  1. In Coolify UI: select the production resource → Stop (does not delete the volume). < 30 s.
  2. Re-deploy last known-good image tag4847d3eb05ab324273d80c4594956b1a79483fe9 (audit-verified, post-C3+S1 staging image). To do this, pin the image tag: in Coolify's compose editor to that digest and redeploy.
  3. Verify: curl -fsS https://<prod-fqdn>/health → 200.
  4. Inform user: post-mortem template lives in docs/postmortem_template.md (TODO; not yet generated). For v0 the minimum is a 5-line summary to #platform-status.
  5. Volume rollback — if the rollback needs pre-upgrade SQLite, docker cp agent-platform-prod-1:/data /tmp/db-before-rollback before any redeploy. Coolify UI exposes per-container console for this.

Recovery time objective (RTO): ~ 5 minutes (Coolify stop + redeploy). Recovery point objective (RPO): 024 h depending on backup cron.

6. Promote decision

Verdict: HOLD (with the option to escalate to PROMOTE).

Reasoning:

  • Staging is fully green (health, CRUD, UI, MCP reachability).
  • 21/21 effective tests pass; CI workflow present.
  • Three issues remain open that the promoter (human) should sign off on in writing before production, because they are policy / threat- model decisions, not pure engineering tasks:
    • S2 / SSRF — accept as-is for v0 internal-only deployment, or land the fix (S-effort).
    • S3 / list_env — narrow example agent's allowed_tools, or harden list_env (S-effort).
    • S5 / master-token audit — at minimum, leave the audit trail off for the master token in v0 to avoid log volume; revisit at v0.1.
  • All other residual items are quality / DX nits that do not block production.

If the promoter signs off on S2/S3/S5 in writing, this verdict flips to PROMOTE without further code changes — proceed to §4 step 1.

Effort to flip HOLD → PROMOTE without signing off on residuals:

  • ≤ 1 day for an engineering pass that closes C2, C4, C5, D1, M2.
  • That is not requested in this audit window.

7. Artefacts produced by this audit

  • docs/current_status.md — phase, deploy state, single next action.
  • docs/test_report.md — pytest 21/21, xfail/xpass log, smoke-test evidence.
  • docs/RELEASE_NOTES.md — this file.

All three are committed in a single change as docs: release audit + current_status + test_report + release notes (T010).