From c7178b808d00fe3ea2367c80db582b624999fdc7 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 10:54:19 +0000 Subject: [PATCH 1/8] feat: surface ephemeral pgmq-disabled state in status and doctor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pgmq_client is None at runtime, events were silently dropped with only a DEBUG-level log — invisible by default and leaving no trace in the runtime state file. - Upgrade the emitter fallback log from DEBUG to WARNING so drops are immediately visible in normal log output - Record each dropped event in runtime_state.event_send_failures using the sentinel queue "" so the condition survives beyond the live process - Surface pgmq-disabled drops in `netengine status` with a clear WARNING line pointing operators to `netengine doctor` - Add check_pgmq_runtime_state() to db_doctor.py that reads the state file and emits a WARN DoctorCheckResult when drops are present - Wire the new probe into standard_probes() so `netengine doctor` shows the condition under the database group Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AhwicpfSvKesuRxBHs9sQ2 --- netengine/cli/main.py | 20 +++++++++++ netengine/diagnostic/db_doctor.py | 60 +++++++++++++++++++++++++++++++ netengine/diagnostic/preflight.py | 7 ++++ netengine/events/emitter.py | 14 +++++++- 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/netengine/cli/main.py b/netengine/cli/main.py index e0f6363..7c0eb66 100644 --- a/netengine/cli/main.py +++ b/netengine/cli/main.py @@ -1079,6 +1079,26 @@ def _print_status(state: RuntimeState) -> None: if state.step_ca_container_id: click.echo(f"step-ca container: {state.step_ca_container_id}") + failures = state.event_send_failures + if failures: + from netengine.events.emitter import _PGMQ_DISABLED_QUEUE + + disabled_drops = [f for f in failures if f.get("queue") == _PGMQ_DISABLED_QUEUE] + send_failures = [f for f in failures if f.get("queue") != _PGMQ_DISABLED_QUEUE] + click.echo("") + if disabled_drops: + click.echo( + f"WARNING: pgmq client not wired — {len(disabled_drops)} event(s) silently " + "dropped in last run. Run `netengine doctor` for details." + ) + if send_failures: + click.echo(f"Event send failures: {len(send_failures)}") + for failure in send_failures[-3:]: + click.echo( + f" ! [{failure.get('queue', '?')}] {failure.get('event_type', '?')}: " + f"{failure.get('exception', '?')}" + ) + @cli.command() @click.option("--name", default=None, help="World name (pre-fills wizard prompt).") diff --git a/netengine/diagnostic/db_doctor.py b/netengine/diagnostic/db_doctor.py index aab23a2..ca7f04c 100644 --- a/netengine/diagnostic/db_doctor.py +++ b/netengine/diagnostic/db_doctor.py @@ -3,10 +3,13 @@ from __future__ import annotations import asyncio +import json from collections.abc import Iterable +from pathlib import Path from urllib.parse import urlparse from netengine.diagnostic.preflight import DoctorCheckResult, DoctorStatus +from netengine.events.emitter import _PGMQ_DISABLED_QUEUE from netengine.events.queues import PRIMARY_QUEUES, dlq_for DB_URL_HINT = ( @@ -15,6 +18,10 @@ ) PGMQ_HINT = "Run database migrations or install pgmq before normal alpha boot." QUEUE_HINT = "Run `netengine migrate up`; migrations may create missing pgmq queues." +PGMQ_RUNTIME_HINT = ( + "pgmq_client was not wired during the last world run — events were silently dropped. " + "Ensure database migrations ran and pgmq is healthy, then re-run `netengine up`." +) def _parse_db_url(db_url: str | None) -> DoctorCheckResult: @@ -165,3 +172,56 @@ def check_database( if not db_url or parsed.status != DoctorStatus.OK: return checks return checks + asyncio.run(_inspect_database(db_url, timeout=timeout)) + + +def check_pgmq_runtime_state(state_file: Path) -> DoctorCheckResult: + """Check the runtime state file for events dropped because pgmq_client was not wired. + + This surfaces the ephemeral pgmq-disabled condition that is otherwise only + visible at WARNING log level during a live run. + """ + if not state_file.exists(): + return DoctorCheckResult( + "pgmq runtime state", + DoctorStatus.SKIP, + "no runtime state file found (world not yet booted)", + group="database", + required=False, + ) + + try: + data = json.loads(state_file.read_text()) + except Exception as exc: + return DoctorCheckResult( + "pgmq runtime state", + DoctorStatus.WARN, + f"could not read runtime state file: {exc}", + "Inspect the state file manually or re-run `netengine up`.", + group="database", + required=False, + ) + + failures: list[dict] = data.get("event_send_failures") or [] + disabled_drops = [f for f in failures if f.get("queue") == _PGMQ_DISABLED_QUEUE] + if disabled_drops: + return DoctorCheckResult( + "pgmq runtime state", + DoctorStatus.WARN, + ( + f"{len(disabled_drops)} event(s) silently dropped in last run " + f"because pgmq_client was not wired " + f"(most recent: {disabled_drops[-1].get('event_type', 'unknown')} " + f"at {disabled_drops[-1].get('failed_at', 'unknown')})" + ), + PGMQ_RUNTIME_HINT, + group="database", + required=False, + ) + + return DoctorCheckResult( + "pgmq runtime state", + DoctorStatus.OK, + "no pgmq-disabled drops recorded in last run", + group="database", + required=False, + ) diff --git a/netengine/diagnostic/preflight.py b/netengine/diagnostic/preflight.py index 602ddf3..c920d00 100644 --- a/netengine/diagnostic/preflight.py +++ b/netengine/diagnostic/preflight.py @@ -604,6 +604,12 @@ def _check_filesystem(ctx: DoctorContext) -> list[DoctorCheckResult]: ] +def _check_pgmq_runtime_state(ctx: DoctorContext) -> DoctorCheckResult: + from netengine.diagnostic.db_doctor import check_pgmq_runtime_state + + return check_pgmq_runtime_state(ctx.state_file) + + def standard_probes() -> tuple[DoctorProbe, ...]: """Return host-readiness probes; each accepts only ``DoctorContext``.""" return ( @@ -614,6 +620,7 @@ def standard_probes() -> tuple[DoctorProbe, ...]: lambda ctx: _check_docker_daemon(), lambda ctx: _check_compose(), _check_database, + _check_pgmq_runtime_state, _check_ports, _check_filesystem, _check_docker_conflicts, diff --git a/netengine/events/emitter.py b/netengine/events/emitter.py index d38a955..627d3ea 100644 --- a/netengine/events/emitter.py +++ b/netengine/events/emitter.py @@ -10,6 +10,9 @@ from netengine.handlers.context import PhaseContext +_PGMQ_DISABLED_QUEUE = "" + + def _failure_record(event: EventEnvelope, queue: Queue | str, exc: Exception) -> EventSendFailure: """Build the structured runtime-state record for an event send failure.""" return { @@ -105,7 +108,16 @@ async def emit_event( ) if context.pgmq_client is None: - context.logger.debug("pgmq_client not available; event logged only") + context.logger.warning( + "pgmq_client not wired; event dropped " + f"(event_type={event_type}, emitted_by={emitted_by})" + ) + record_event_send_failure( + context, + event, + _PGMQ_DISABLED_QUEUE, + RuntimeError("pgmq_client not wired — event silently dropped"), + ) return event target_queue = queue or queue_for_event_type(event_type) From 3deebfe6599243f582c6904c40c8a53bfa20f55f Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 11:04:13 +0000 Subject: [PATCH 2/8] fix: remove unresolvable redactable dep to unblock CI redactable ^0.1.0 was added to pyproject.toml before the package was published to PyPI, making it impossible to regenerate poetry.lock and breaking all CI jobs. The codebase already imports it via importlib with a documented fallback for when it is unavailable, so removing it from the required deps is safe and matches the actual runtime behaviour. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AhwicpfSvKesuRxBHs9sQ2 --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 408fd50..49e4e53 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,6 @@ fastapi = ">=0.115" omegaconf = "^2.3" prometheus-client = "^0.25.0" cryptography = ">=44,<49" -redactable = "^0.1.0" [tool.poetry.group.dev.dependencies] pytest = "^7.4" From c28166bc24da9f457f7bb3aad8ba07ba85bf19a3 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 11:08:47 +0000 Subject: [PATCH 3/8] fix: resolve mypy errors, missing redaction imports, and Supply Chain action version - db_doctor.py: narrow type-ignore to import-untyped, annotate failures list properly - preflight.py: guard against None before int() in _parse_compose_port - routes.py: import _is_secret_field and _contains_private_pem from redaction module (fallback code referenced them but they were never imported, causing NameError) - ci.yaml: pin trivy-action to @0.29.0 (0.30.0 does not exist) - Reformat emitter.py, db_doctor.py, preflight.py with black Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AhwicpfSvKesuRxBHs9sQ2 --- .github/workflows/ci.yaml | 2 +- netengine/api/routes.py | 7 ++++++- netengine/diagnostic/db_doctor.py | 8 +++----- netengine/diagnostic/preflight.py | 20 ++++++++++---------- netengine/events/emitter.py | 1 - 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 76030e7..e63837e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -223,7 +223,7 @@ jobs: path: sbom.spdx.json - name: Vulnerability scan - uses: aquasecurity/trivy-action@0.30.0 + uses: aquasecurity/trivy-action@0.29.0 with: scan-type: fs scan-ref: . diff --git a/netengine/api/routes.py b/netengine/api/routes.py index 787a79f..7a0648b 100644 --- a/netengine/api/routes.py +++ b/netengine/api/routes.py @@ -23,7 +23,12 @@ from netengine.events.queues import PRIMARY_QUEUES, Queue, dlq_for from netengine.logging import get_logger from netengine.phase_labels import PHASE_LABELS -from netengine.security.redaction import redact_for_api, redact_for_support_bundle +from netengine.security.redaction import ( + _contains_private_pem, + _is_secret_field, + redact_for_api, + redact_for_support_bundle, +) from netengine.spec.loader import SpecLoadError, load_spec from netengine.spec.models import SPEC_SCHEMA_VERSION, NetEngineSpec diff --git a/netengine/diagnostic/db_doctor.py b/netengine/diagnostic/db_doctor.py index ca7f04c..988a928 100644 --- a/netengine/diagnostic/db_doctor.py +++ b/netengine/diagnostic/db_doctor.py @@ -69,7 +69,7 @@ def _queue_name(row: object) -> str | None: async def _inspect_database(db_url: str, *, timeout: float) -> list[DoctorCheckResult]: try: - import asyncpg # type: ignore[import] + import asyncpg # type: ignore[import-untyped] except ImportError: return [ DoctorCheckResult( @@ -164,9 +164,7 @@ async def _inspect_database(db_url: str, *, timeout: float) -> list[DoctorCheckR await conn.close() -def check_database( - db_url: str | None, *, timeout: float = 3.0 -) -> list[DoctorCheckResult]: +def check_database(db_url: str | None, *, timeout: float = 3.0) -> list[DoctorCheckResult]: """Return actionable doctor checks for Postgres, pgmq, and event queues.""" checks = [parsed := _parse_db_url(db_url)] if not db_url or parsed.status != DoctorStatus.OK: @@ -201,7 +199,7 @@ def check_pgmq_runtime_state(state_file: Path) -> DoctorCheckResult: required=False, ) - failures: list[dict] = data.get("event_send_failures") or [] + failures: list[dict[str, object]] = data.get("event_send_failures") or [] disabled_drops = [f for f in failures if f.get("queue") == _PGMQ_DISABLED_QUEUE] if disabled_drops: return DoctorCheckResult( diff --git a/netengine/diagnostic/preflight.py b/netengine/diagnostic/preflight.py index c920d00..31b21d4 100644 --- a/netengine/diagnostic/preflight.py +++ b/netengine/diagnostic/preflight.py @@ -119,6 +119,8 @@ def _parse_compose_port(raw_port: object) -> tuple[int, str] | None: if isinstance(raw_port, dict): published = raw_port.get("published") or raw_port.get("target") proto = str(raw_port.get("protocol") or "tcp").lower() + if published is None: + return None try: return int(published), proto except (TypeError, ValueError): @@ -330,9 +332,7 @@ def _can_bind(port: int, proto: str) -> bool: def _check_port(port: int, proto: str) -> DoctorCheckResult: name = f"port:{port}/{proto}" - label = next( - (p.label for p in KNOWN_LOCAL_PORTS if p.port == port and p.proto == proto), None - ) + label = next((p.label for p in KNOWN_LOCAL_PORTS if p.port == port and p.proto == proto), None) detail_suffix = f" ({label})" if label else "" try: _can_bind(port, proto) @@ -479,20 +479,20 @@ def _check_docker_conflicts(ctx: DoctorContext) -> list[DoctorCheckResult]: ( DoctorStatus.FAIL if kind == "container" and conflicts - else DoctorStatus.WARN - if conflicts - else DoctorStatus.OK + else DoctorStatus.WARN if conflicts else DoctorStatus.OK ), ", ".join(conflicts) if conflicts else "no known name conflicts", ( "Stop/remove conflicting containers before startup." if kind == "container" and conflicts else ( - "Run `netengine down` or remove stale Docker resources if these " - "belong to an old run." + ( + "Run `netengine down` or remove stale Docker resources if these " + "belong to an old run." + ) + if conflicts + else None ) - if conflicts - else None ), "docker", required=kind == "container", diff --git a/netengine/events/emitter.py b/netengine/events/emitter.py index 627d3ea..c823be8 100644 --- a/netengine/events/emitter.py +++ b/netengine/events/emitter.py @@ -9,7 +9,6 @@ from netengine.events.schema import EventEnvelope from netengine.handlers.context import PhaseContext - _PGMQ_DISABLED_QUEUE = "" From 15224ef7be6aeedd7002d19b577f37b78eccf2af Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 11:10:27 +0000 Subject: [PATCH 4/8] fix: add v prefix to trivy-action tag and reformat runner.py - ci.yaml: trivy-action versions use v-prefix tags (v0.29.0, not 0.29.0) - runner.py: reformat with black (pre-existing lint failure) Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AhwicpfSvKesuRxBHs9sQ2 --- .github/workflows/ci.yaml | 2 +- netengine/diagnostic/runner.py | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e63837e..139c22a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -223,7 +223,7 @@ jobs: path: sbom.spdx.json - name: Vulnerability scan - uses: aquasecurity/trivy-action@0.29.0 + uses: aquasecurity/trivy-action@v0.29.0 with: scan-type: fs scan-ref: . diff --git a/netengine/diagnostic/runner.py b/netengine/diagnostic/runner.py index 1aecc33..8e7fcff 100644 --- a/netengine/diagnostic/runner.py +++ b/netengine/diagnostic/runner.py @@ -60,14 +60,10 @@ def __init__( self.elapsed_ms = elapsed_ms self.remediation = remediation or hint self.related_phase = related_phase if related_phase is not None else phase - self.related_resource = ( - related_resource if related_resource is not None else resource - ) + self.related_resource = related_resource if related_resource is not None else resource log_commands = related_logs if related_logs is not None else logs self.related_logs = list(log_commands or []) - self.command_to_retry = ( - command_to_retry if command_to_retry is not None else retry_command - ) + self.command_to_retry = command_to_retry if command_to_retry is not None else retry_command @property def phase(self) -> int | None: From 33590032c8aaa3493bfb18317722ea51a70a9bb4 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 11:10:58 +0000 Subject: [PATCH 5/8] fix: upgrade trivy-action to v0.36.0 (v0.29.0 had broken setup-trivy dep) Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AhwicpfSvKesuRxBHs9sQ2 --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 139c22a..069a834 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -223,7 +223,7 @@ jobs: path: sbom.spdx.json - name: Vulnerability scan - uses: aquasecurity/trivy-action@v0.29.0 + uses: aquasecurity/trivy-action@v0.36.0 with: scan-type: fs scan-ref: . From 31d519bcb866bdeac88b06b5f12b8ed3929cbe8b Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 11:12:06 +0000 Subject: [PATCH 6/8] fix: sort imports with isort (context, and_handler, app_handler, test_doctor) Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AhwicpfSvKesuRxBHs9sQ2 --- netengine/handlers/and_handler.py | 2 +- netengine/handlers/app_handler.py | 2 +- netengine/handlers/context.py | 3 +-- tests/test_doctor.py | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/netengine/handlers/and_handler.py b/netengine/handlers/and_handler.py index 31a2a58..5da65c1 100644 --- a/netengine/handlers/and_handler.py +++ b/netengine/handlers/and_handler.py @@ -7,9 +7,9 @@ from netengine.events.schema import EventEnvelope from netengine.handlers.context import PhaseContext from netengine.handlers.dns import DNSHandler -from netengine.handlers.protocols import DockerAdapterProtocol, PGMQAdapterProtocol from netengine.handlers.domain_registry_handler import DomainRegistryHandler from netengine.handlers.gateway_handler import GatewayHandler +from netengine.handlers.protocols import DockerAdapterProtocol, PGMQAdapterProtocol from netengine.logging import get_logger from netengine.spec.models import NetEngineSpec diff --git a/netengine/handlers/app_handler.py b/netengine/handlers/app_handler.py index d273320..9ebc15e 100644 --- a/netengine/handlers/app_handler.py +++ b/netengine/handlers/app_handler.py @@ -6,9 +6,9 @@ from netengine.handlers._base import BasePhaseHandler from netengine.handlers.context import PhaseContext from netengine.handlers.dns import DNSHandler -from netengine.handlers.protocols import DockerAdapterProtocol, PGMQAdapterProtocol from netengine.handlers.oidc_handler import OIDCHandler from netengine.handlers.pki_handler import PKIHandler +from netengine.handlers.protocols import DockerAdapterProtocol, PGMQAdapterProtocol from netengine.logging import get_logger from netengine.spec.models import NetEngineSpec diff --git a/netengine/handlers/context.py b/netengine/handlers/context.py index be88886..26e70fd 100644 --- a/netengine/handlers/context.py +++ b/netengine/handlers/context.py @@ -5,9 +5,8 @@ from pathlib import Path from typing import TYPE_CHECKING, Any, Optional -from netengine.handlers.protocols import DockerAdapterProtocol, PGMQAdapterProtocol - from netengine.core.state import RuntimeState +from netengine.handlers.protocols import DockerAdapterProtocol, PGMQAdapterProtocol from netengine.spec.models import NetEngineSpec if TYPE_CHECKING: diff --git a/tests/test_doctor.py b/tests/test_doctor.py index 0054e34..d378276 100644 --- a/tests/test_doctor.py +++ b/tests/test_doctor.py @@ -1,7 +1,7 @@ """Doctor command tests.""" -from pathlib import Path import sys +from pathlib import Path from types import SimpleNamespace from click.testing import CliRunner @@ -9,8 +9,8 @@ from netengine.cli import doctor as doctor_mod from netengine.cli import main as cli_main from netengine.cli.doctor import DoctorCheckResult, DoctorStatus -from netengine.events.queues import PRIMARY_QUEUES, dlq_for from netengine.diagnostic.preflight import DoctorContext, run_preflight +from netengine.events.queues import PRIMARY_QUEUES, dlq_for def test_doctor_appears_in_help() -> None: From c9dc81371156b74672b2e152d61e7212b2ca17ef Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 11:15:40 +0000 Subject: [PATCH 7/8] fix: regenerate docs/licenses.md from poetry venv (remove stale global packages) The previous licenses.md was generated from a developer machine with global Poetry tools installed; CI generates from the project venv only. Regenerate with 81 packages. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AhwicpfSvKesuRxBHs9sQ2 --- docs/licenses.md | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/docs/licenses.md b/docs/licenses.md index 17c0b16..603a9d9 100644 --- a/docs/licenses.md +++ b/docs/licenses.md @@ -13,28 +13,20 @@ Generated from installed Python package metadata. Re-run with `python scripts/ge | anyio | 4.14.0 | MIT | UNKNOWN | | asyncpg | 0.30.0 | Apache License, Version 2.0 | UNKNOWN | | attrs | 26.1.0 | MIT | UNKNOWN | -| backports.zstd | 1.6.0 | PSF-2.0 | UNKNOWN | | black | 24.10.0 | MIT | UNKNOWN | -| build | 1.5.0 | MIT | UNKNOWN | -| CacheControl | 0.14.4 | Apache-2.0 | UNKNOWN | | certifi | 2026.6.17 | MPL-2.0 | https://github.com/certifi/python-certifi | | cffi | 2.0.0 | MIT | UNKNOWN | | cfgv | 3.5.0 | MIT | https://github.com/asottile/cfgv | | charset-normalizer | 3.4.7 | MIT | UNKNOWN | -| cleo | 2.1.0 | MIT | https://github.com/python-poetry/cleo | | click | 8.4.1 | BSD-3-Clause | UNKNOWN | | coverage | 7.14.2 | Apache-2.0 | https://github.com/coveragepy/coveragepy | -| crashtest | 0.4.1 | MIT | https://github.com/sdispater/crashtest | | cryptography | 48.0.1 | Apache-2.0 OR BSD-3-Clause | UNKNOWN | | deprecation | 2.1.0 | Apache 2 | http://deprecation.readthedocs.io/ | | distlib | 0.4.3 | PSF-2.0 | https://github.com/pypa/distlib | | dnspython | 2.8.0 | ISC | UNKNOWN | | docker | 7.1.0 | Apache-2.0 | UNKNOWN | -| dulwich | 1.2.6 | Apache-2.0 OR GPL-2.0-or-later | UNKNOWN | | fastapi | 0.138.0 | MIT | UNKNOWN | -| fastjsonschema | 2.21.2 | BSD | https://github.com/horejsek/python-fastjsonschema | | filelock | 3.29.4 | MIT | UNKNOWN | -| findpython | 0.8.0 | MIT | UNKNOWN | | flake8 | 6.1.0 | MIT | https://github.com/pycqa/flake8 | | frozenlist | 1.8.0 | Apache-2.0 | https://github.com/aio-libs/frozenlist | | h11 | 0.16.0 | MIT | https://github.com/python-hyper/h11 | @@ -46,18 +38,10 @@ Generated from installed Python package metadata. Re-run with `python scripts/ge | identify | 2.6.19 | MIT | https://github.com/pre-commit/identify | | idna | 3.18 | BSD-3-Clause | UNKNOWN | | iniconfig | 2.3.0 | MIT | UNKNOWN | -| installer | 1.0.1 | MIT | UNKNOWN | | isort | 5.13.2 | MIT | https://pycqa.github.io/isort/ | -| jaraco.classes | 3.4.0 | UNKNOWN | https://github.com/jaraco/jaraco.classes | -| jaraco.context | 6.1.2 | MIT | UNKNOWN | -| jaraco.functools | 4.5.0 | MIT | UNKNOWN | -| jeepney | 0.9.0 | MIT | UNKNOWN | -| keyring | 25.7.0 | MIT | UNKNOWN | | librt | 0.11.0 | MIT | UNKNOWN | | loguru | 0.7.3 | UNKNOWN | UNKNOWN | | mccabe | 0.7.0 | Expat license | https://github.com/pycqa/mccabe | -| more-itertools | 11.1.0 | MIT | UNKNOWN | -| msgpack | 1.2.1 | Apache-2.0 | UNKNOWN | | multidict | 6.7.1 | Apache License 2.0 | https://github.com/aio-libs/multidict | | mypy | 1.20.2 | MIT | UNKNOWN | | mypy_extensions | 1.1.0 | MIT | UNKNOWN | @@ -66,13 +50,9 @@ Generated from installed Python package metadata. Re-run with `python scripts/ge | omegaconf | 2.3.1 | UNKNOWN | https://github.com/omry/omegaconf | | packaging | 26.2 | Apache-2.0 OR BSD-2-Clause | UNKNOWN | | pathspec | 1.1.1 | UNKNOWN | UNKNOWN | -| pbs-installer | 2026.6.10 | MIT | UNKNOWN | -| pip | 26.1 | MIT | UNKNOWN | -| pkginfo | 1.12.1.2 | MIT | https://code.launchpad.net/~tseaver/pkginfo/trunk | +| pip | 26.0.1 | MIT | UNKNOWN | | platformdirs | 4.10.0 | MIT | UNKNOWN | | pluggy | 1.6.0 | MIT | UNKNOWN | -| poetry | 2.4.1 | MIT | UNKNOWN | -| poetry-core | 2.4.0 | MIT | UNKNOWN | | postgrest | 2.31.0 | MIT | UNKNOWN | | pre-commit | 3.8.0 | MIT | https://github.com/pre-commit/pre-commit | | prometheus_client | 0.25.0 | Apache-2.0 AND BSD-2-Clause | UNKNOWN | @@ -82,24 +62,15 @@ Generated from installed Python package metadata. Re-run with `python scripts/ge | pydantic | 2.13.4 | MIT | UNKNOWN | | pydantic_core | 2.46.4 | MIT | https://github.com/pydantic/pydantic | | pyflakes | 3.1.0 | MIT | https://github.com/PyCQA/pyflakes | -| Pygments | 2.20.0 | BSD-2-Clause | UNKNOWN | | PyJWT | 2.13.0 | MIT | UNKNOWN | -| pyproject_hooks | 1.2.0 | UNKNOWN | UNKNOWN | -| pyright | 1.1.409 | MIT | https://github.com/RobertCraigie/pyright-python | | pytest | 7.4.4 | MIT | https://docs.pytest.org/en/latest/ | | pytest-asyncio | 0.21.2 | Apache 2.0 | https://github.com/pytest-dev/pytest-asyncio | | pytest-cov | 4.1.0 | MIT | https://github.com/pytest-dev/pytest-cov | | python-discovery | 1.4.2 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated document... | UNKNOWN | | python-dotenv | 1.2.2 | BSD-3-Clause | UNKNOWN | -| pytokens | 0.4.1 | MIT License Copyright (c) 2024 Tushar Sadhwani Permission is hereby granted, free of charge, to any person obtaining... | UNKNOWN | | PyYAML | 6.0.3 | MIT | https://pyyaml.org/ | -| RapidFuzz | 3.14.5 | MIT | UNKNOWN | | realtime | 2.31.0 | MIT | UNKNOWN | | requests | 2.34.2 | Apache-2.0 | UNKNOWN | -| requests-toolbelt | 1.0.0 | Apache 2.0 | https://toolbelt.readthedocs.io/ | -| ruff | 0.15.12 | MIT | https://docs.astral.sh/ruff | -| SecretStorage | 3.5.0 | BSD-3-Clause | UNKNOWN | -| shellingham | 1.5.4 | ISC License | https://github.com/sarugaku/shellingham | | starlette | 1.3.1 | BSD-3-Clause | UNKNOWN | | storage3 | 2.31.0 | MIT | UNKNOWN | | StrEnum | 0.4.15 | UNKNOWN | https://github.com/irgeek/StrEnum | @@ -107,8 +78,6 @@ Generated from installed Python package metadata. Re-run with `python scripts/ge | supabase | 2.31.0 | MIT | UNKNOWN | | supabase-auth | 2.31.0 | MIT | UNKNOWN | | supabase-functions | 2.31.0 | MIT | UNKNOWN | -| tomlkit | 0.15.0 | MIT | UNKNOWN | -| trove-classifiers | 2026.6.1.19 | UNKNOWN | https://github.com/pypa/trove-classifiers | | types-PyYAML | 6.0.12.20260518 | Apache-2.0 | UNKNOWN | | typing-inspection | 0.4.2 | MIT | UNKNOWN | | typing_extensions | 4.15.0 | PSF-2.0 | UNKNOWN | From f4110d73bb24f5ff6e9d62f1e5b68b3f07ec664e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 11:16:45 +0000 Subject: [PATCH 8/8] fix: update pip version in licenses.md to 25.1.1 (matches CI venv) Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AhwicpfSvKesuRxBHs9sQ2 --- docs/licenses.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/licenses.md b/docs/licenses.md index 603a9d9..289b92f 100644 --- a/docs/licenses.md +++ b/docs/licenses.md @@ -50,7 +50,7 @@ Generated from installed Python package metadata. Re-run with `python scripts/ge | omegaconf | 2.3.1 | UNKNOWN | https://github.com/omry/omegaconf | | packaging | 26.2 | Apache-2.0 OR BSD-2-Clause | UNKNOWN | | pathspec | 1.1.1 | UNKNOWN | UNKNOWN | -| pip | 26.0.1 | MIT | UNKNOWN | +| pip | 25.1.1 | MIT | UNKNOWN | | platformdirs | 4.10.0 | MIT | UNKNOWN | | pluggy | 1.6.0 | MIT | UNKNOWN | | postgrest | 2.31.0 | MIT | UNKNOWN |