chore: initialize EverOS 1.0.0

md-first memory extraction framework for AI agents.

Markdown is the single source of truth; SQLite holds state and LanceDB
provides the rebuildable vector + BM25 + scalar index. The codebase follows
a single-direction DDD layering (entrypoints -> service -> memory -> infra,
with component / core / config cross-cutting) enforced by import-linter.

Engineering surface:
- Coding conventions in .claude/rules/ (path-scoped) and workflows in
  .claude/skills/ (/commit, /new-branch, /pr).
- GitHub Actions CI runs make lint + test + integration; pre-commit mirrors
  the gates locally (ruff, hygiene hooks, gitlint commit-msg).
- Commit messages follow Conventional Commits, enforced by gitlint.
- make lint also enforces datetime two-zone discipline and OpenAPI drift.
This commit is contained in:
Elliot Chen
2026-06-05 22:35:51 +08:00
commit 518b8eca85
636 changed files with 160553 additions and 0 deletions

View File

@ -0,0 +1,106 @@
"""``global_exception_handler`` — uniform error envelope per v1 API §1.
We mount the handler on a minimal FastAPI app with three error-emitting
routes (HTTPException 4xx / 5xx, RequestValidationError, raw exception)
and assert the envelope shape + status code each route produces.
"""
from __future__ import annotations
from collections.abc import AsyncIterator
import pytest
from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from httpx import ASGITransport, AsyncClient
from pydantic import BaseModel
from everos.core.middleware.global_exception import global_exception_handler
class _Body(BaseModel):
name: str
def _build_app() -> FastAPI:
app = FastAPI()
app.add_exception_handler(HTTPException, global_exception_handler)
app.add_exception_handler(RequestValidationError, global_exception_handler)
app.add_exception_handler(Exception, global_exception_handler)
@app.get("/raise-400")
async def raise_400() -> None:
raise HTTPException(status_code=400, detail="bad input")
@app.get("/raise-500-http")
async def raise_500_http() -> None:
raise HTTPException(status_code=503, detail="upstream dead")
@app.get("/boom")
async def boom() -> None:
raise RuntimeError("hidden internals")
@app.post("/validate")
async def validate(_body: _Body) -> dict[str, str]:
return {"ok": "yes"}
return app
@pytest.fixture
async def client() -> AsyncIterator[AsyncClient]:
app = _build_app()
# raise_app_exceptions=False — let the registered handler convert the
# RuntimeError into a 500 response instead of re-raising into the test.
transport = ASGITransport(app=app, raise_app_exceptions=False)
async with AsyncClient(transport=transport, base_url="http://test") as c:
yield c
def _assert_envelope(body: dict[str, object], *, code: str, path: str) -> None:
"""Wiki §1 envelope: ``{request_id, error: {code, message, timestamp, path}}``."""
assert isinstance(body["request_id"], str) and body["request_id"]
error = body["error"]
assert isinstance(error, dict)
assert error["code"] == code
assert isinstance(error["message"], str) and error["message"]
assert isinstance(error["timestamp"], str) and "T" in error["timestamp"]
assert error["path"] == path
async def test_http_exception_4xx(client: AsyncClient) -> None:
resp = await client.get("/raise-400")
assert resp.status_code == 400
body = resp.json()
_assert_envelope(body, code="HTTP_ERROR", path="/raise-400")
assert body["error"]["message"] == "bad input"
async def test_http_exception_5xx_uses_system_error(client: AsyncClient) -> None:
"""5xx routed through HTTPException still produces SYSTEM_ERROR + generic msg."""
resp = await client.get("/raise-500-http")
assert resp.status_code == 503
body = resp.json()
_assert_envelope(body, code="SYSTEM_ERROR", path="/raise-500-http")
# Internal detail "upstream dead" is suppressed in 5xx envelopes.
assert body["error"]["message"] == "Internal server error"
async def test_unhandled_exception_5xx(client: AsyncClient) -> None:
"""RuntimeError → 500 with generic ``SYSTEM_ERROR`` envelope; details hidden."""
resp = await client.get("/boom")
assert resp.status_code == 500
body = resp.json()
_assert_envelope(body, code="SYSTEM_ERROR", path="/boom")
assert body["error"]["message"] == "Internal server error"
# Must not leak the internal exception message.
assert "hidden internals" not in resp.text
async def test_validation_error_returns_422(client: AsyncClient) -> None:
resp = await client.post("/validate", json={}) # missing ``name``
assert resp.status_code == 422
body = resp.json()
_assert_envelope(body, code="HTTP_ERROR", path="/validate")
# First-error message includes the offending field somewhere.
assert "name" in body["error"]["message"].lower()

View File

@ -0,0 +1,148 @@
"""``ProfileMiddleware`` — env gating, query-param gating, pyinstrument output."""
from __future__ import annotations
from collections.abc import AsyncIterator
import pytest
from fastapi import FastAPI
from httpx import ASGITransport, AsyncClient
from everos.core.middleware.profile import ProfileMiddleware, _profiling_enabled
def _build_app() -> FastAPI:
app = FastAPI()
app.add_middleware(ProfileMiddleware)
@app.get("/hello")
async def hello() -> dict[str, str]:
return {"ok": "yes"}
return app
@pytest.fixture
def disable_env(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("PROFILING_ENABLED", raising=False)
monkeypatch.delenv("PROFILING", raising=False)
@pytest.fixture
def enable_env(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("PROFILING_ENABLED", "true")
def test_profiling_enabled_truthy_variants(monkeypatch: pytest.MonkeyPatch) -> None:
for v in ("1", "true", "TRUE", "yes"):
monkeypatch.setenv("PROFILING_ENABLED", v)
assert _profiling_enabled() is True
def test_profiling_enabled_falsy_variants(monkeypatch: pytest.MonkeyPatch) -> None:
for v in ("0", "false", "no", "", "anything-else"):
monkeypatch.setenv("PROFILING_ENABLED", v)
assert _profiling_enabled() is False
def test_profiling_falls_back_to_legacy_env(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("PROFILING_ENABLED", raising=False)
monkeypatch.setenv("PROFILING", "yes")
assert _profiling_enabled() is True
@pytest.fixture
async def disabled_client(disable_env: None) -> AsyncIterator[AsyncClient]:
app = _build_app()
async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://test"
) as c:
yield c
@pytest.fixture
async def enabled_client(enable_env: None) -> AsyncIterator[AsyncClient]:
app = _build_app()
async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://test"
) as c:
yield c
async def test_disabled_passthrough(disabled_client: AsyncClient) -> None:
"""When profiling is disabled, ``?profile=true`` is ignored — JSON returned."""
resp = await disabled_client.get("/hello?profile=true")
assert resp.status_code == 200
assert resp.json() == {"ok": "yes"}
async def test_enabled_without_query_passthrough(enabled_client: AsyncClient) -> None:
"""Enabled middleware but request without ``?profile=true`` → normal response."""
resp = await enabled_client.get("/hello")
assert resp.status_code == 200
assert resp.json() == {"ok": "yes"}
async def test_enabled_with_query_returns_html(enabled_client: AsyncClient) -> None:
"""With ``?profile=true`` and pyinstrument available, response is HTML."""
try:
import pyinstrument # noqa: F401
except ImportError:
pytest.skip("pyinstrument not installed in this env")
resp = await enabled_client.get("/hello?profile=true")
assert resp.status_code == 200
assert "text/html" in resp.headers.get("content-type", "")
# Pyinstrument output contains the word "pyinstrument" in its template.
assert "pyinstrument" in resp.text.lower() or "<html" in resp.text.lower()
async def test_enabled_with_query_returns_html_when_inner_raises(
enabled_client: AsyncClient,
) -> None:
"""An exception inside the wrapped handler is logged but still produces HTML."""
try:
import pyinstrument # noqa: F401
except ImportError:
pytest.skip("pyinstrument not installed in this env")
# Rebuild a tiny app whose route raises so the middleware's except branch
# fires; the profile HTML is still emitted regardless.
app = FastAPI()
app.add_middleware(ProfileMiddleware)
@app.get("/bang")
async def bang() -> None:
raise RuntimeError("inner exception")
async with AsyncClient(
transport=ASGITransport(app=app, raise_app_exceptions=False),
base_url="http://test",
) as c:
resp = await c.get("/bang?profile=true")
assert resp.status_code == 200
assert "text/html" in resp.headers.get("content-type", "")
async def test_enabled_without_pyinstrument(monkeypatch: pytest.MonkeyPatch) -> None:
"""If pyinstrument import fails, middleware degrades to passthrough."""
monkeypatch.setenv("PROFILING_ENABLED", "true")
# Force the import inside ProfileMiddleware.__init__ to fail.
import builtins
real_import = builtins.__import__
def fail_pyinstrument(name: str, *args: object, **kwargs: object) -> object:
if name == "pyinstrument":
raise ImportError("simulated")
return real_import(name, *args, **kwargs)
monkeypatch.setattr(builtins, "__import__", fail_pyinstrument)
app = _build_app() # ProfileMiddleware ctor runs here
async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://test"
) as c:
resp = await c.get("/hello?profile=true")
assert resp.status_code == 200
assert resp.json() == {"ok": "yes"}

View File

@ -0,0 +1,162 @@
"""``PrometheusMiddleware`` — increments counters / histograms, skips /metrics.
We isolate the test from the production registry by overriding it with a
fresh :class:`prometheus_client.CollectorRegistry` for the duration of
the test. The middleware was already imported with module-level Counter /
Histogram bound to whatever the registry was at import time — those
metric objects continue to record to the real registry. The test
therefore reads via ``_http_requests_total`` directly rather than via
``generate_metrics_response()``.
"""
from __future__ import annotations
from collections.abc import AsyncIterator
import pytest
from fastapi import FastAPI
from httpx import ASGITransport, AsyncClient
from everos.core.middleware import prometheus as prom_mod
def _sample_value(metric: object, **labels: str) -> float:
"""Read the current value of a labeled prometheus metric (test helper)."""
labeled = metric.labels(**labels)._labeled # type: ignore[attr-defined]
for sample in labeled.collect()[0].samples:
if sample.name.endswith("_total"):
return float(sample.value)
return float("nan")
def _histogram_count(metric: object, **labels: str) -> float:
labeled = metric.labels(**labels)._labeled # type: ignore[attr-defined]
for sample in labeled.collect()[0].samples:
if sample.name.endswith("_count"):
return float(sample.value)
return float("nan")
def _build_app() -> FastAPI:
app = FastAPI()
app.add_middleware(prom_mod.PrometheusMiddleware)
@app.get("/hello")
async def hello() -> dict[str, str]:
return {"ok": "yes"}
@app.get("/users/{user_id}")
async def get_user(user_id: str) -> dict[str, str]:
return {"user": user_id}
return app
@pytest.fixture
async def client() -> AsyncIterator[AsyncClient]:
app = _build_app()
async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://test"
) as c:
yield c
async def test_increments_counter_on_200(client: AsyncClient) -> None:
before = _sample_value(
prom_mod._http_requests_total, method="GET", path="/hello", status="200"
)
resp = await client.get("/hello")
assert resp.status_code == 200
after = _sample_value(
prom_mod._http_requests_total, method="GET", path="/hello", status="200"
)
assert after == before + 1
async def test_observes_duration_histogram(client: AsyncClient) -> None:
before = _histogram_count(
prom_mod._http_request_duration_seconds, method="GET", path="/hello"
)
await client.get("/hello")
after = _histogram_count(
prom_mod._http_request_duration_seconds, method="GET", path="/hello"
)
assert after == before + 1
def test_skip_paths_constant_contains_known_endpoints() -> None:
"""Skip set is the contract — assert membership directly to avoid
polluting the global registry by ``.labels(path='/metrics')``-ing it
(that creates a zero-valued sample which then leaks into the
exposition format that test_metrics_route inspects).
"""
assert "/metrics" in prom_mod._SKIP_PATHS
assert "/health" in prom_mod._SKIP_PATHS
assert "/healthz" in prom_mod._SKIP_PATHS
assert "/favicon.ico" in prom_mod._SKIP_PATHS
async def test_path_params_normalized(client: AsyncClient) -> None:
"""``/users/abc`` should record against the route template ``/users/{user_id}``."""
before = _sample_value(
prom_mod._http_requests_total,
method="GET",
path="/users/{user_id}",
status="200",
)
resp = await client.get("/users/abc")
assert resp.status_code == 200
after = _sample_value(
prom_mod._http_requests_total,
method="GET",
path="/users/{user_id}",
status="200",
)
assert after == before + 1
# ── _normalize_path direct tests (defensive fallback branches) ─────────
def test_normalize_path_uses_path_params_fallback() -> None:
"""When scope has no ``route`` but ``path_params`` is set, substitute names."""
from types import SimpleNamespace
from everos.core.middleware.prometheus import _normalize_path
fake_req = SimpleNamespace(
scope={},
url=SimpleNamespace(path="/x/abc/y"),
path_params={"id": "abc"},
)
# type: ignore[arg-type] — helper accepts anything duck-typed.
assert _normalize_path(fake_req) == "/x/{id}/y" # type: ignore[arg-type]
def test_normalize_path_unmatched_fallback() -> None:
"""No route, no path_params → ``{unmatched}`` sentinel."""
from types import SimpleNamespace
from everos.core.middleware.prometheus import _normalize_path
fake_req = SimpleNamespace(
scope={},
url=SimpleNamespace(path="/x"),
path_params={},
)
assert _normalize_path(fake_req) == "{unmatched}" # type: ignore[arg-type]
def test_normalize_path_non_dict_scope_falls_through() -> None:
"""Defensive: a non-dict ``scope`` skips the route lookup entirely."""
from types import SimpleNamespace
from everos.core.middleware.prometheus import _normalize_path
fake_req = SimpleNamespace(
scope="not-a-dict",
url=SimpleNamespace(path="/x"),
path_params={},
)
assert _normalize_path(fake_req) == "{unmatched}" # type: ignore[arg-type]