Skip to content

security: v0.1 hardening — locked writes, append-only grants, quarantine flags, live-Postgres CI#2

Merged
jp-cruz merged 1 commit into
mainfrom
fix/v0.1-hardening
Jul 2, 2026
Merged

security: v0.1 hardening — locked writes, append-only grants, quarantine flags, live-Postgres CI#2
jp-cruz merged 1 commit into
mainfrom
fix/v0.1-hardening

Conversation

@jp-cruz

@jp-cruz jp-cruz commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Implements the post-merge hardening list, with every claim live-verified against a real pgvector/pg17 container before pushing:

Item Verification
Migration 001 DESC index bug (first real-PG parse failure, as predicted) all 3 migrations apply clean
Chain-fork concurrency bug: prev-hash read + insert now atomic under pg_advisory_xact_lock 10 parallel writers → 1 genesis, all prev_hashes unique, chain verifies
Append-only by grants: jeli_app role = INSERT+SELECT only (scripts/setup_db_roles.sql) UPDATE/DELETE denied, SELECT/INSERT allowed, live
Read-time quarantine: injection_flagged in search results live roundtrip
Config honesty: API key required only for future http transport
docs/THREAT-MODEL.md: explicit guarantees vs gaps (temporal fields unprotected; poison-auditable, not poison-proof)
SECURITY.md, CHANGELOG.md (v0.1.0-alpha), dependabot.yml
CI integration job: pgvector service container + alembic + live tests this PR's checks

Post-merge: tag v0.1.0-alpha + GitHub release.

🤖 Generated with Claude Code

…nts, read-time quarantine, live-Postgres CI

Everything below was verified against a real pgvector/pg17 instance
(migrations, full roundtrip, tamper detection, 10 concurrent writers,
role grants):

- fix(migrations): 001 used postgresql_using="DESC" (index METHOD slot,
  not sort order) — first bug found the moment real Postgres parsed the
  DDL; rewritten as a DESC column expression. No deployed DB had applied
  001 yet.
- fix(concurrency): capture_memory's prev-hash read + insert now run in
  one transaction under pg_advisory_xact_lock — two concurrent writers
  previously forked the chain, making legit data fail verification.
  Live test: 10 parallel writers, one genesis, all prev_hashes unique.
- feat(least-privilege): scripts/setup_db_roles.sql creates jeli_app
  with INSERT+SELECT only — append-only enforced by grants, not code.
  Live-verified: UPDATE/DELETE denied, SELECT/INSERT allowed.
- feat(read-time quarantine): search_memory results now carry
  injection_flagged so consumers can treat flagged content as data,
  never instructions.
- fix(config honesty): SCOPED_MCP_API_KEY now required only for the
  (future) http transport — stdio's boundary is process spawn, and
  requiring an unchecked secret was security theater.
- docs: THREAT-MODEL.md — explicit guarantees vs known gaps (temporal
  fields not integrity-protected; poison-auditable, not poison-proof;
  chain-key custody). SECURITY.md, CHANGELOG.md, dependabot.yml.
- ci: integration job with pgvector service container running alembic +
  live tests (skipped locally unless JELI_TEST_DB_URL is set).

133 tests locally (129 unit + 4 live integration).

Co-Authored-By: Claude Fable 5 <[email protected]>
@jp-cruz jp-cruz merged commit 8b28278 into main Jul 2, 2026
13 checks passed
@jp-cruz jp-cruz deleted the fix/v0.1-hardening branch July 2, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant