mirror of
https://github.com/himanshudongre/smriti.git
synced 2026-08-28 05:14:59 +00:00
Add capabilities manifest to /health for stale-backend detection
The health endpoint now returns git_sha and a capabilities list so agents can detect when the running backend is missing features they need (e.g., claims, structured_tasks). Skill pack v1.8 teaches the capabilities probe: check /health when a 404 or missing section suggests the backend is stale, tell the human to restart. Diagnosed from the autonomy validation where Codex hit a backend without /api/v5/claims — the backend process was running old code.
This commit is contained in:
parent
bd257c3393
commit
6da93ae856
4 changed files with 102 additions and 14 deletions
|
|
@ -1,10 +1,29 @@
|
|||
import logging
|
||||
import pathlib
|
||||
import re
|
||||
import subprocess
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
from app.config import settings
|
||||
|
||||
|
||||
def _resolve_git_sha() -> str:
|
||||
"""Return the short git SHA of the backend directory, or 'unknown'."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", "--short", "HEAD"],
|
||||
cwd=pathlib.Path(__file__).resolve().parent.parent,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return result.stdout.strip()
|
||||
except Exception:
|
||||
pass
|
||||
return "unknown"
|
||||
|
||||
class SecretGuardFilter(logging.Filter):
|
||||
def filter(self, record):
|
||||
if isinstance(record.msg, str) and re.search(r'sk-[a-zA-Z0-9_\-]+', record.msg):
|
||||
|
|
@ -48,9 +67,29 @@ def create_app() -> FastAPI:
|
|||
app.include_router(lineage.router, prefix="/api/v5", tags=["lineage-v5"])
|
||||
app.include_router(claims.router, prefix="/api/v5", tags=["claims-v5"])
|
||||
|
||||
# ── Capabilities manifest ────────────────────────────────────────
|
||||
# Computed once at startup so /health is zero-cost at request time.
|
||||
_git_sha = _resolve_git_sha()
|
||||
|
||||
# Hardcoded feature flags matching the route modules included above.
|
||||
# When a new feature ships (new route module, new query param, new
|
||||
# schema shape), add it here so agents can detect stale backends.
|
||||
_capabilities = [
|
||||
"claims", # /api/v5/claims
|
||||
"structured_tasks", # task objects with intent_hint/blocked_by/status
|
||||
"checkpoint_notes", # /api/v5/checkpoint/{id}/notes
|
||||
"branch_disposition", # PATCH /api/v5/lineage/branches/disposition
|
||||
"freshness", # since_commit_id on state endpoint
|
||||
"compact_state", # --compact mode on state brief
|
||||
]
|
||||
|
||||
@app.get("/health")
|
||||
async def health_check():
|
||||
return {"status": "ok"}
|
||||
return {
|
||||
"status": "ok",
|
||||
"git_sha": _git_sha,
|
||||
"capabilities": _capabilities,
|
||||
}
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
|
|
|
|||
38
backend/tests/integration/test_health.py
Normal file
38
backend/tests/integration/test_health.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
"""Integration tests for GET /health capabilities manifest.
|
||||
|
||||
Validates that the health endpoint returns the capabilities list and
|
||||
git_sha that agents use to detect stale backends.
|
||||
"""
|
||||
|
||||
|
||||
def test_health_returns_capabilities(client):
|
||||
"""Health endpoint includes status, git_sha, and capabilities."""
|
||||
r = client.get("/health")
|
||||
assert r.status_code == 200
|
||||
data = r.json()
|
||||
|
||||
assert data["status"] == "ok"
|
||||
assert "git_sha" in data
|
||||
assert isinstance(data["git_sha"], str)
|
||||
assert len(data["git_sha"]) > 0
|
||||
|
||||
assert "capabilities" in data
|
||||
assert isinstance(data["capabilities"], list)
|
||||
|
||||
|
||||
def test_health_includes_required_capabilities(client):
|
||||
"""All shipped features are listed in capabilities."""
|
||||
r = client.get("/health")
|
||||
data = r.json()
|
||||
caps = data["capabilities"]
|
||||
|
||||
required = [
|
||||
"claims",
|
||||
"structured_tasks",
|
||||
"checkpoint_notes",
|
||||
"branch_disposition",
|
||||
"freshness",
|
||||
"compact_state",
|
||||
]
|
||||
for cap in required:
|
||||
assert cap in caps, f"Missing capability: {cap}"
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
smriti_skill_pack_version: 1.7
|
||||
smriti_skill_pack_version: 1.8
|
||||
title: Smriti — how to use it well
|
||||
target: {{display_name}}
|
||||
---
|
||||
|
|
@ -214,7 +214,7 @@ Say out loud: **"Session complete. Branch pushed, checkpoint
|
|||
written, working tree clean."** or **"Stopping — checkpointed
|
||||
findings, branch is [disposition]."**
|
||||
|
||||
### 3.5 Backend reachability
|
||||
### 3.5 Backend reachability and capabilities
|
||||
|
||||
The Smriti backend is a shared service started by the human. You
|
||||
are a client of it. You do not own it.
|
||||
|
|
@ -231,14 +231,22 @@ are a client of it. You do not own it.
|
|||
tool loop creates environment-variable inheritance issues that
|
||||
cause silent mock fallback on all LLM-backed endpoints. The
|
||||
human starts the backend; you use it.
|
||||
- **Runtime freshness after code changes.** If backend code has
|
||||
been merged to main since the backend was last started (e.g.,
|
||||
new API routes, schema changes, config fixes), the backend
|
||||
must be restarted before agents can rely on the new endpoints.
|
||||
Check `git log --oneline -5` against the running server's
|
||||
behavior. If a new endpoint returns 404 or the behavior does
|
||||
not match the merged code, tell the human: "The backend may
|
||||
need a restart to pick up recent changes on main."
|
||||
- **Check capabilities before using advanced features.** After
|
||||
reading state, before creating claims or using features like
|
||||
structured tasks, probe the backend:
|
||||
{{mcp:`curl -s http://localhost:8000/health`}}{{cli:`curl -s http://localhost:8000/health`}}
|
||||
The response includes `git_sha` and a `capabilities` list. If
|
||||
you need `claims` but the capabilities list does not include it,
|
||||
the backend is running stale code. Tell the human: "The backend
|
||||
at localhost:8000 does not support [feature]. Its git_sha is
|
||||
[sha] but the current repo is at [repo sha]. Please restart
|
||||
the backend with `make dev` to pick up recent changes."
|
||||
- **When to check capabilities:** You do NOT need to check on every
|
||||
session. Check when:
|
||||
- A Smriti API call returns 404 on a route you expect to exist
|
||||
- The state brief is missing sections you expect (e.g., no
|
||||
`## Active work` when you know claims were recently merged)
|
||||
- You are about to use a feature for the first time in a session
|
||||
|
||||
### 3.6 Work claims: declare intent before working
|
||||
|
||||
|
|
@ -825,7 +833,7 @@ tell you. Do not guess.
|
|||
|
||||
---
|
||||
|
||||
*Smriti skill pack version {{primary_mode}}-1.7 — this file is
|
||||
*Smriti skill pack version {{primary_mode}}-1.8 — this file is
|
||||
authoritative for agent behaviour on this project. If you catch it
|
||||
contradicting itself or your observed behaviour of the tools, tell
|
||||
the human; the skill pack is versioned and meant to be updated.*
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ def test_load_template_nonempty():
|
|||
|
||||
def test_get_version_parses_frontmatter():
|
||||
version = get_version()
|
||||
assert version == "1.7"
|
||||
assert version == "1.8"
|
||||
|
||||
|
||||
def test_get_version_raises_when_frontmatter_missing():
|
||||
|
|
@ -142,8 +142,11 @@ _REQUIRED_PHRASES = [
|
|||
"clean finish",
|
||||
"branch disposition",
|
||||
"push your branch",
|
||||
# Section 3.5 — backend reachability
|
||||
# Section 3.5 — backend reachability and capabilities
|
||||
"backend reachability",
|
||||
"capabilities",
|
||||
"git_sha",
|
||||
"stale code",
|
||||
"do not attempt to start",
|
||||
# Section 3.6 — work claims
|
||||
"work claims",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue