diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 9df0200..7e2a5ec 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -40,6 +40,9 @@ on: - "frontend/**" - "tests/**" - "pyproject.toml" + # The lock now determines what gets installed, so a lock-only change has + # to trigger a run — otherwise a dependency bump lands untested. + - "uv.lock" - "alembic/**" - "alembic.ini" - "Dockerfile" @@ -140,19 +143,16 @@ jobs: # red with no repo change (issue #2194). Green CI has to mean "these exact # versions passed", or it isn't evidence of anything. # - # `--frozen`, not `--locked`, and that difference is a known gap: --locked - # additionally fails when the lock is STALE against pyproject, which is the - # guard that would catch someone editing a dependency without re-locking. - # It can't be turned on until uv.lock is regenerated with `uv lock` — the - # mcp cap edited pyproject, so the lock no longer matches, and this - # workstation has no uv (or pip) to regenerate it with. --frozen still - # delivers the reproducibility this fix is for; a forgotten re-lock shows - # up as a loud ImportError rather than a silent version drift. Flip to - # --locked in the same change that regenerates the lock. + # `--locked` also FAILS when uv.lock is stale against pyproject, so a + # dependency edit has to go through a deliberate `uv lock` — it can't + # arrive on its own. That check earned its place immediately: it caught + # that the lock had been missing `pgvector` entirely (added to pyproject, + # never re-locked), which the old install path had been silently papering + # over by resolving from pyproject instead. - name: Install locked dependencies env: UV_PROJECT_ENVIRONMENT: /opt/venv - run: uv sync --frozen --extra dev + run: uv sync --locked --extra dev - name: Run tests # Integration tests (real Postgres) run in the `integration` job below. @@ -197,7 +197,7 @@ jobs: - name: Install locked dependencies env: UV_PROJECT_ENVIRONMENT: /opt/venv - run: uv sync --frozen --extra dev + run: uv sync --locked --extra dev - name: Integration suite (resolve service IP, migrate, test) run: | set -eux diff --git a/uv.lock b/uv.lock index fdcb59c..67bed32 100644 --- a/uv.lock +++ b/uv.lock @@ -354,54 +354,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, ] -[[package]] -name = "scribe" -version = "0.1.0" -source = { editable = "." } -dependencies = [ - { name = "aiosmtplib" }, - { name = "alembic" }, - { name = "apscheduler" }, - { name = "asyncpg" }, - { name = "bcrypt" }, - { name = "caldav" }, - { name = "fastembed" }, - { name = "httpx" }, - { name = "hypercorn" }, - { name = "icalendar" }, - { name = "mcp", extra = ["cli"] }, - { name = "quart" }, - { name = "sqlalchemy", extra = ["asyncio"] }, -] - -[package.optional-dependencies] -dev = [ - { name = "pytest" }, - { name = "pytest-asyncio" }, - { name = "ruff" }, -] - -[package.metadata] -requires-dist = [ - { name = "aiosmtplib", specifier = ">=3.0" }, - { name = "alembic", specifier = ">=1.13" }, - { name = "apscheduler", specifier = ">=3.10,<4.0" }, - { name = "asyncpg", specifier = ">=0.29" }, - { name = "bcrypt", specifier = ">=4.0" }, - { name = "caldav", specifier = ">=1.3" }, - { name = "fastembed", specifier = ">=0.4" }, - { name = "httpx", specifier = ">=0.27" }, - { name = "hypercorn", specifier = ">=0.17" }, - { name = "icalendar", specifier = ">=5.0" }, - { name = "mcp", extras = ["cli"], specifier = ">=1.0,<2" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" }, - { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.23" }, - { name = "quart", specifier = ">=0.19" }, - { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.6" }, - { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0" }, -] -provides-extras = ["dev"] - [[package]] name = "fastembed" version = "0.8.0" @@ -1038,6 +990,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, ] +[[package]] +name = "pgvector" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/ec/6eb80aebc728200f95229219882994c1b0585b956ca47da5edb9d062627a/pgvector-0.5.0.tar.gz", hash = "sha256:07a9dcf735696879406983afc6eba9a787cef7c0cf6c367ca1a5779f036dee74", size = 35170, upload-time = "2026-07-06T18:27:27.767Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/e4/a5573f2c579ca9ad133293bfb624148ba0893674ca4a6eeec85ced9a6a09/pgvector-0.5.0-py3-none-any.whl", hash = "sha256:fedc9800894e6da2be51358d7b7c574bf34f247ca741a5a09513622135f5964f", size = 30958, upload-time = "2026-07-06T18:27:26.797Z" }, +] + [[package]] name = "pillow" version = "12.2.0" @@ -1496,6 +1457,56 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/58/ed/dea90a65b7d9e69888890fb14c90d7f51bf0c1e82ad800aeb0160e4bacfd/ruff-0.15.10-py3-none-win_arm64.whl", hash = "sha256:601d1610a9e1f1c2165a4f561eeaa2e2ea1e97f3287c5aa258d3dab8b57c6188", size = 11035607, upload-time = "2026-04-09T14:05:47.593Z" }, ] +[[package]] +name = "scribe" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "aiosmtplib" }, + { name = "alembic" }, + { name = "apscheduler" }, + { name = "asyncpg" }, + { name = "bcrypt" }, + { name = "caldav" }, + { name = "fastembed" }, + { name = "httpx" }, + { name = "hypercorn" }, + { name = "icalendar" }, + { name = "mcp", extra = ["cli"] }, + { name = "pgvector" }, + { name = "quart" }, + { name = "sqlalchemy", extra = ["asyncio"] }, +] + +[package.optional-dependencies] +dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiosmtplib", specifier = ">=3.0" }, + { name = "alembic", specifier = ">=1.13" }, + { name = "apscheduler", specifier = ">=3.10,<4.0" }, + { name = "asyncpg", specifier = ">=0.29" }, + { name = "bcrypt", specifier = ">=4.0" }, + { name = "caldav", specifier = ">=1.3" }, + { name = "fastembed", specifier = ">=0.4" }, + { name = "httpx", specifier = ">=0.27" }, + { name = "hypercorn", specifier = ">=0.17" }, + { name = "icalendar", specifier = ">=5.0" }, + { name = "mcp", extras = ["cli"], specifier = ">=1.0,<2" }, + { name = "pgvector", specifier = ">=0.3" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" }, + { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.23" }, + { name = "quart", specifier = ">=0.19" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.6" }, + { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0" }, +] +provides-extras = ["dev"] + [[package]] name = "shellingham" version = "1.5.4"