Skip to content

Release 0.1.0: security review remediation - #49

Merged
eldonm merged 11 commits into
mainfrom
codex/security-review-remediation
Sep 27, 2026
Merged

eldonm merged 11 commits into
mainfrom
codex/security-review-remediation

Conversation

@eldonm

@eldonm eldonm commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Summary

Remediates the 37 findings in the combined gap review and security audit. The high severity auth failures are addressed first in the implementation: database lookup errors deny JWTs, current database roles govern authorization, revocation uses the active session store, logout invalidates the bound refresh token, and public registration cannot grant admin.

The remaining changes harden webhook HMAC and API key scope, path containment, file access and production defaults, graph deletion and traversal, database writes and index inputs, scheduler and retry behavior, and other confirmed findings. The in-process asynchronous webhook mode was removed; handlers and idempotency storage now finish within the request. Durable asynchronous processing should use an external queue.

SPEC.md, CHANGELOG.md, operational docs, and the numbered review ledger were updated alongside code. ROADMAP §2 product decisions remain separate as requested.

Review guide

  1. Auth and secret handling: findings 1–7, 10–11, 17, 19–22, 25, 31–32.
  2. Webhooks and API key scopes: findings 7, 10, 20, 26, 32.
  3. Storage and API defaults: findings 8–9, 12–13, 18–19, 21, 24–25.
  4. Graph and query integrity: findings 14–16, 23, 28, 35–37.
  5. Runtime reliability: findings 27, 29–30, 33–34.
  6. Contract and migration notes: SPEC.md, CHANGELOG.md, docs/md/security-review.md.

Verification

  • Full pytest --cov=jvspatial --cov-report=term-missing -q --disable-warnings passed; total coverage 64%. Optional external-service tests were skipped where Redis, Postgres, MongoDB, or OTel dependencies were unavailable.
  • pre-commit run --all-files passed, including Black, isort, flake8, mypy, and Detect Secrets.
  • The new focused regression module passed (22 tests).
  • git diff --check passed.
  • Standalone mypy with the local Python 3.11 environment reports 86 baseline diagnostics on both origin/main and this PR; after normalizing line numbers, there are no new diagnostics. The configured pre-commit mypy and PR CI checks pass.

Agent guide migration

Root AGENTS.md now holds the complete agent guide; CLAUDE.md is removed. SPEC, PRD, documentation index, audit citations, and source comments point to AGENTS.md. Historical changelog text remains intact.

Release 0.1.0 notes

Security

  • JWT validation now rejects user lookup failures and uses current database roles and permissions. Logout invalidates the access token and its bound refresh token; token revocation failures are surfaced. Public registration never grants admin access. Auth entry points have per-IP rate limits, generic account-state errors, and a 12-character password minimum.
  • Signed GET webhooks require HMAC. Webhook routes default to POST, API-key scopes match path segments, expired cached keys are rejected, and idempotency lookup errors fail closed. Webhook handlers finish within the request; durable asynchronous work must use an external queue.
  • JsonDB record paths and local storage version IDs are confined to their roots. SQL index field paths are validated and raw where= predicates are rejected. Graph deletion, walker errors, DynamoDB bulk writes, and deferred operations now report failures instead of success.
  • BREAKING: Direct file reads require authentication by default when auth is enabled. Set JVSPATIAL_FILES_PUBLIC_READ=true only when intentional.
  • BREAKING: JVSPATIAL_ENVIRONMENT=production unpublishes /docs, /redoc, and /openapi.json by default. Set JVSPATIAL_DOCS_DISABLED=false for an explicit override.
  • BREAKING: Deferred invoke requires a secret even on loopback. Set JVSPATIAL_DEFERRED_INVOKE_ALLOW_LOOPBACK=true only for Lambda Web Adapter self-invoke.
  • BREAKING: The in-process scheduler requires a running server event loop and runs coroutine jobs on that loop. Jobs started outside an event loop must use a configured external scheduler.
  • Hosts with their own trusted auth limiter or test suites can explicitly set rate_limit.auth_entrypoint_rate_limit_enabled=False; the 5/60s cap remains on by default. Declared private helper methods can be replaced on entity instances, while undeclared underscore attributes remain rejected.
  • Authenticated mounted ASGI apps and raw FastAPI routes without jvspatial endpoint metadata remain reachable. Metadata lookup errors still deny access, and /status, /logs, and /graph retain enforced admin roles.

Changed

  • AGENTS.md is now the canonical agent guide. Its former CLAUDE.md content has been consolidated there; CLAUDE.md is removed.

Pre-merge 0.1.0 review addendum (e281236)

  • Reproduced a short catastrophic-backtracking pattern that stalled the in-memory query matcher; added a bounded-time regex engine and regression coverage.
  • Removed name-based FastAPI auth bypasses. Raw routes may defer to an enforcing FastAPI security dependency; jvspatial-managed and admin routes retain framework auth and RBAC.
  • Rebuilt webhook idempotency around an atomic durable claim before handler execution, response replay, and fail-closed persistence. Pending outcomes remain held for operator reconciliation. Added concurrent, replay, malformed-payload, and expiry regressions.
  • Cached declared private fields to avoid a full class-hierarchy scan on every entity assignment. Corrected auth, file-read, webhook, release, and agent documentation; updated the SPEC contract and 0.1.0 changelog.
  • pre-commit run --all-files, focused regressions, and wheel build passed. The full local pytest run reached 100% with no failures; its Python process hung during interpreter shutdown. jvagent's suite reached 100% with no failures on the editable tree. Integral Core PR #65 passed its CI-faithful smoke run in an isolated worktree.
  • PR checks are green: Python 3.10/3.11/3.12 tests, benchmark suite and baseline comparison, pre-commit, and pip-audit. External Postgres and MongoDB integration tests remain skipped locally because those services are unavailable. Required review is still outstanding.

OAuth key custody addendum (ad5817f)

The OAuth signing-key store now encrypts private PEM before persistence when JVSPATIAL_OAUTH_KEY_ENCRYPTION_KEY is configured. A legacy plaintext row is rewrapped on first use. Missing or incorrect keys fail closed for encrypted rows. OAuthSigningKey.save() also encrypts a plaintext signing copy if a caller persists it again. The SPEC, security review, environment reference, operations guidance, agent guide, changelog, and targeted tests were updated. A production host must provision the same Fernet key across workers; key rotation, backup recovery, and managed KMS/HSM custody remain operational release work.

Verification on this addendum: OAuth suite and pre-commit run --all-files passed. A local full pytest run had two walker test failures outside the changed OAuth paths (test_execute_direct_execution_walker and test_walker_endpoint_with_auth_false_allows_access). CI for this exact head must pass before merge; treat these local failures as unresolved until reconciled. Integral Core PR #65 is a draft dependency migration and remains blocked by seven PostgreSQL failures and unpublished distribution wheels.

dd3702f makes the keystore reject missing encryption keys in JVSPATIAL_ENVIRONMENT=production; the focused OAuth suite and all pre-commit checks pass. Core's exact source pin has been advanced to this commit.

Final consumer repair pass (fe54330)

PostgreSQL $exists now matches the in-memory null semantics; graph transactions isolate their identity map and evict touched parent cache entries; index setup is scoped to each database instance. File-backed SQLite closes its prior aiosqlite connection when rebinding across event loops. Regression tests cover these paths, including a real PostgreSQL round trip. Test fixtures now bind their own graph contexts and restore mocked metadata so the full suite is order independent.

The full local jvspatial suite and all pre-commit hooks pass. Integral Core's full JSON and PostgreSQL suites pass with this source code; its focused PostgreSQL tests and CI smoke pass after a frozen sync of the exact Git candidate. jvagent's full local suite passes against the same package code. PR CI is rerunning after a version-portable SQLite test assertion replaced Connection.is_alive().

Publication remains gated on PR CI and required review. The dependent registry-install and release-artifact gates remain pending until jvspatial 0.1.0 and the compatible jvagent package are published.

Review status: All required CI checks on fe54330 are green (Python 3.10, 3.11, 3.12, benchmarks, pre-commit, and pip-audit). This PR is ready for the required human review; it has not been merged or published.

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.029259 +42.3% REGRESSION (+42.3%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.028073 +52.0% REGRESSION (+52.0%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.475105 -76.3% IMPROVED (-76.3%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.025550 -74.3% IMPROVED (-74.3%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.185189 -1.4% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.909028 -39.0% IMPROVED (-39.0%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001642 -53.7% IMPROVED (-53.7%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.360919 +52.5% REGRESSION (+52.5%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.401431 +48.9% REGRESSION (+48.9%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.413416 +81.6% REGRESSION (+81.6%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.391542 +52.6% REGRESSION (+52.6%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.343785 +41.3% REGRESSION (+41.3%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.399657 +57.0% REGRESSION (+57.0%)

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.032980 +60.4% REGRESSION (+60.4%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.033630 +82.1% REGRESSION (+82.1%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.479335 -76.1% IMPROVED (-76.1%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.049086 -73.7% IMPROVED (-73.7%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.138503 -5.2% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.869689 -41.6% IMPROVED (-41.6%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001651 -53.4% IMPROVED (-53.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.349014 +47.5% REGRESSION (+47.5%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.394787 +46.4% REGRESSION (+46.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.350106 +53.8% REGRESSION (+53.8%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.386489 +50.7% REGRESSION (+50.7%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.345447 +42.0% REGRESSION (+42.0%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.381360 +49.8% REGRESSION (+49.8%)

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.036116 +75.7% REGRESSION (+75.7%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.033694 +82.5% REGRESSION (+82.5%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.486568 -75.7% IMPROVED (-75.7%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.030388 -74.1% IMPROVED (-74.1%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.221598 +1.7% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.919451 -38.3% IMPROVED (-38.3%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001681 -52.6% IMPROVED (-52.6%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.350125 +48.0% REGRESSION (+48.0%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.408770 +51.6% REGRESSION (+51.6%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.381877 +67.7% REGRESSION (+67.7%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.425769 +66.0% REGRESSION (+66.0%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.363344 +49.3% REGRESSION (+49.3%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.410012 +61.1% REGRESSION (+61.1%)

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.034556 +68.1% REGRESSION (+68.1%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.033580 +81.8% REGRESSION (+81.8%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.492058 -75.5% IMPROVED (-75.5%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.006918 -74.7% IMPROVED (-74.7%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.200909 -0.0% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.917000 -38.5% IMPROVED (-38.5%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001653 -53.4% IMPROVED (-53.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.337742 +42.7% REGRESSION (+42.7%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.405417 +50.4% REGRESSION (+50.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.393939 +73.0% REGRESSION (+73.0%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.374078 +45.8% REGRESSION (+45.8%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.371770 +52.8% REGRESSION (+52.8%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.389749 +53.1% REGRESSION (+53.1%)

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.033850 +64.6% REGRESSION (+64.6%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.034456 +86.6% REGRESSION (+86.6%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.484972 -75.8% IMPROVED (-75.8%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.031524 -74.1% IMPROVED (-74.1%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.206909 +0.5% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.899095 -39.7% IMPROVED (-39.7%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001616 -54.4% IMPROVED (-54.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.354464 +49.8% REGRESSION (+49.8%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.394527 +46.3% REGRESSION (+46.3%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.384890 +69.1% REGRESSION (+69.1%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.403608 +57.3% REGRESSION (+57.3%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.350878 +44.2% REGRESSION (+44.2%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.414615 +62.9% REGRESSION (+62.9%)

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.033943 +65.1% REGRESSION (+65.1%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.032455 +75.8% REGRESSION (+75.8%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.517814 -74.2% IMPROVED (-74.2%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.107190 -72.2% IMPROVED (-72.2%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.251227 +4.1% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.946751 -36.5% IMPROVED (-36.5%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001686 -52.4% IMPROVED (-52.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.368498 +55.7% REGRESSION (+55.7%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.396551 +47.1% REGRESSION (+47.1%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.389496 +71.1% REGRESSION (+71.1%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.408042 +59.1% REGRESSION (+59.1%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.366186 +50.5% REGRESSION (+50.5%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.421302 +65.5% REGRESSION (+65.5%)

@eldonm
eldonm requested a review from barnwell September 27, 2026 15:30
@eldonm eldonm changed the title Remediate combined security review findings Release 0.1.0: security review remediation Sep 27, 2026
@eldonm eldonm added the release Release preparation and publication label Sep 27, 2026
@eldonm eldonm self-assigned this Sep 27, 2026
@eldonm
eldonm removed the request for review from barnwell September 27, 2026 15:49
@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.026955 +31.1% REGRESSION (+31.1%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.026570 +43.9% REGRESSION (+43.9%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.510792 -74.5% IMPROVED (-74.5%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.105550 -72.3% IMPROVED (-72.3%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.201970 +0.0% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.929425 -37.6% IMPROVED (-37.6%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001709 -51.8% IMPROVED (-51.8%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.371280 +56.9% REGRESSION (+56.9%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.481513 +78.6% REGRESSION (+78.6%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.376626 +65.4% REGRESSION (+65.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.467542 +82.3% REGRESSION (+82.3%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.335530 +37.9% REGRESSION (+37.9%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.405536 +59.3% REGRESSION (+59.3%)

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.015597 -24.1% OK
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.014975 -18.9% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.819981 -59.1% IMPROVED (-59.1%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.167637 -70.7% IMPROVED (-70.7%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.250147 +4.1% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.938816 -37.0% IMPROVED (-37.0%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.002042 -42.4% IMPROVED (-42.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.188483 -20.3% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.284817 +5.6% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.197587 -13.2% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.280960 +9.5% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.202399 -16.8% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.224855 -11.6% OK

@eldonm
eldonm force-pushed the codex/security-review-remediation branch from c6c953e to ad5817f Compare September 27, 2026 18:16
@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.010636 -48.3% IMPROVED (-48.3%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.010732 -41.9% IMPROVED (-41.9%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.398405 -80.1% IMPROVED (-80.1%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 0.941753 -76.4% IMPROVED (-76.4%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 0.812639 -32.4% IMPROVED (-32.4%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.648467 -56.5% IMPROVED (-56.5%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001222 -65.5% IMPROVED (-65.5%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.129671 -45.2% IMPROVED (-45.2%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.202029 -25.1% IMPROVED (-25.1%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.142312 -37.5% IMPROVED (-37.5%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.194478 -24.2% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.131902 -45.8% IMPROVED (-45.8%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.154340 -39.4% IMPROVED (-39.4%)

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.027035 +31.5% REGRESSION (+31.5%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.026419 +43.1% REGRESSION (+43.1%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.481092 -76.0% IMPROVED (-76.0%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.045738 -73.8% IMPROVED (-73.8%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.187500 -1.2% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.919734 -38.3% IMPROVED (-38.3%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001696 -52.2% IMPROVED (-52.2%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.330072 +39.5% REGRESSION (+39.5%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.475998 +76.6% REGRESSION (+76.6%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.382029 +67.8% REGRESSION (+67.8%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.482769 +88.2% REGRESSION (+88.2%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.345906 +42.2% REGRESSION (+42.2%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.389720 +53.1% REGRESSION (+53.1%)

@eldonm
eldonm marked this pull request as draft September 27, 2026 18:24
@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.018275 -11.1% OK
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.018341 -0.7% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.888700 -55.7% IMPROVED (-55.7%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.074812 -73.0% IMPROVED (-73.0%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 0.878715 -26.9% IMPROVED (-26.9%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.695293 -53.3% IMPROVED (-53.3%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.002111 -40.4% IMPROVED (-40.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.218786 -7.5% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.303356 +12.5% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.236620 +3.9% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.298918 +16.5% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.220604 -9.3% OK
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.254929 +0.2% OK

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Threshold: ±25% (informational, does not block merge)

benchmark baseline (s) current (s) delta status
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_deferred_save_batched_100 0.020560 0.027778 +35.1% REGRESSION (+35.1%)
tests/benchmarks/test_deferred_save_benchmarks.py::test_bench_immediate_save_100 0.018466 0.027341 +48.1% REGRESSION (+48.1%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_batched_saves_500 2.005611 0.502965 -74.9% IMPROVED (-74.9%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_empty_query 3.984905 1.062933 -73.3% IMPROVED (-73.3%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_count_filtered 1.201411 1.163127 -3.2% OK
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_find_filtered 1.489928 0.900287 -39.6% IMPROVED (-39.6%)
tests/benchmarks/test_jsondb_benchmarks.py::test_bench_jsondb_save_throughput 0.003544 0.001651 -53.4% IMPROVED (-53.4%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_empty 0.236600 0.335236 +41.7% REGRESSION (+41.7%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_fallback_via_regex 0.269595 0.483392 +79.3% REGRESSION (+79.3%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_count_pushdown 0.227659 0.388983 +70.9% REGRESSION (+70.9%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_fallback_via_regex 0.256533 0.445671 +73.7% REGRESSION (+73.7%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_find_pushdown 0.243315 0.342184 +40.6% REGRESSION (+40.6%)
tests/benchmarks/test_sqlite_benchmarks.py::test_bench_sqlite_sort_limit_pushdown 0.254495 0.382410 +50.3% REGRESSION (+50.3%)

@eldonm
eldonm marked this pull request as ready for review September 27, 2026 19:47
@eldonm
eldonm merged commit 87dd0c7 into main Sep 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release Release preparation and publication

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant