Skip to content

feat: add exact qpk-vnext N2 sqlite foundation#260

Closed
Pigbibi wants to merge 1 commit into
mainfrom
codex/qpk-vnext-n2-sqlite-exact
Closed

feat: add exact qpk-vnext N2 sqlite foundation#260
Pigbibi wants to merge 1 commit into
mainfrom
codex/qpk-vnext-n2-sqlite-exact

Conversation

@Pigbibi

@Pigbibi Pigbibi commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Fresh exact put/get foundation

Fresh base: origin/main@a06a99f74566ce60ae91fc39317cdfc16558e325; no code from frozen PR #259 is reused.

This KISS N2 slice intentionally contains only:

  • trusted single-process stdlib sqlite3 exact durable put/get
  • constructor side-effect-free; absolute DB path; ephemeral rejected before open
  • ordinary sqlite3.connect(str(path)), including ?/#/%/space/Unicode paths; no URI interpolation
  • reads never create; writes initialize only missing/empty files; existing non-empty DBs require exact marker/schema
  • minimal store_meta(namespace) + results(key PRIMARY KEY,payload BLOB) schema
  • fixed rollback journal + synchronous=FULL
  • transactional create-once, byte-identical idempotency, conflict/no-overwrite
  • BLOB-like payload validation, N1 decode and exact key verification, sanitized failures

No selector/list/latest, identity columns, legacy/compatibility/migration, network/S3, caller/orchestrator, or live behavior.

Validation

  • focused: 5 passed
  • full suite: 619 passed, 1 skipped
  • ruff, compileall, diff-check: passed

Review mode: preflight then one concentrated closure maximum; remediation_count=0.

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

🤖 Codex PR Review

🚫 Merge blocked: 2 serious issue(s) found in high-risk files

⚖️ Codex Review Arbitration

🚫 block: Prior schema finding is fixed and does not conflict: _validate_schema() now compares (name,type,notnull,pk) for both tables, and the new test suite rejects a forged schema that previously would have passed. But the current reliability findings still stand against the cumulative diff. _configure() in src/quant_platform_kit/strategy_lifecycle/qpk_vnext_n2_store.py executes PRAGMA journal_mode=DELETE and PRAGMA synchronous=FULL and never checks the returned effective values, even though SQLite documents that journal_mode returns the actual mode and returns the original mode if the change could not be made, and that pragma behavior can be ignored/overridden in some environments (https://www.sqlite.org/pragma.html). The public doc for this PR describes the store as a durable foundation, yet the first-create path still returns "created" without any parent-directory sync after creating the database file; there is no directory fsync() anywhere in the implementation, so the newly created file entry is not explicitly made durable before success is reported (https://www.sqlite.org/atomiccommit.html, https://www.sqlite.org/pragma.html).

🚫 Blocking Issues

These issues must be fixed before this PR can be merged:

1. 🔴 [CRITICAL] Reliability in src/quant_platform_kit/strategy_lifecycle/qpk_vnext_n2_store.py

When put() creates a brand-new database file, the code never fsyncs the parent directory after the file is created and committed. On POSIX filesystems, SQLite's FULL sync protects the file contents, but it does not guarantee the directory entry for a newly created file is durable. A power loss after put() returns "created" can therefore lose the entire database file even though the write was acknowledged. (line 88)

Suggestion: Track the first-create path and, after the initial successful commit that creates the database, open the parent directory and fsync() it before reporting success. Fail closed if the directory sync cannot be completed.

2. 🟠 [HIGH] Logic in src/quant_platform_kit/strategy_lifecycle/qpk_vnext_n2_store.py

The store sets PRAGMA journal_mode=DELETE and PRAGMA synchronous=FULL but never verifies the effective values. SQLite pragmas can return a different mode than requested or remain unchanged under some environments/configurations, which means the store can silently run with weaker durability than the PR contract promises while still accepting writes. (line 75)

Suggestion: Capture and validate the pragma results immediately after setting them, and fail closed unless the effective journal mode is exactly delete and the effective synchronous level is exactly FULL.


Review by Codex PR Review bot • PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: af539563aa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +149 to +153
item = decode_wire(data)
if item.key != key:
_fail()
return item
except (sqlite3.Error, StoreError, TypeError, UnicodeError, json.JSONDecodeError):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Catch contract decode failures as StoreError

When a persisted row contains syntactically valid JSON that fails N1 validation, such as b"{}", a bad digest, or a wrong namespace, decode_wire(data) raises ContractError. This handler does not catch that type, so get() leaks the N1 contract exception instead of normalizing corrupted-row reads to StoreError; callers that only handle store failures will see an unexpected exception despite the store's fail-closed/sanitized contract.

Useful? React with 👍 / 👎.

Comment on lines +58 to +60
meta_cols = {row[1] for row in conn.execute("PRAGMA table_info(store_meta)")}
result_cols = {row[1] for row in conn.execute("PRAGMA table_info(results)")}
if meta_cols != {"key", "value"} or result_cols != {"key", "payload"}:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate the actual SQLite schema before accepting a DB

When an existing non-empty database has the expected table and column names but not the constraints this store creates, for example results(key TEXT, payload BLOB) without PRIMARY KEY/NOT NULL, this check still accepts it. put() then relies on the database uniqueness contract to preserve create-once semantics, so preexisting duplicate keys or nullable payloads can be accepted and later make reads fail or return whichever duplicate SQLite happens to fetch, instead of rejecting the non-exact schema up front.

Useful? React with 👍 / 👎.

Comment on lines +149 to +150
item = decode_wire(data)
if item.key != key:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject ephemeral payloads on durable reads

If an existing or corrupted row contains a valid N1 wire payload with persist_mode="ephemeral", decode_wire() succeeds and item.key still matches because N1 keys intentionally exclude persist_mode. get() then returns an ephemeral contract from the durable store even though put() rejects the same contract before opening the DB, so seeded/corrupted databases can bypass the durable-only invariant instead of failing closed.

Useful? React with 👍 / 👎.

Co-Authored-By: Codex <noreply@openai.com>
@Pigbibi Pigbibi force-pushed the codex/qpk-vnext-n2-sqlite-exact branch from af53956 to bd8b9d0 Compare July 14, 2026 21:17
@Pigbibi

Pigbibi commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Concentrated closure (head bd8b9d0) validates exact catalog objects and column constraints (allowing only SQLite internal autoindexes), rejects triggers/views/indexes, normalizes payload/ContractError/ephemeral/key failures to StoreError, and closes connections on schema validation failure. Added forged schema/catalog, corrupt/ephemeral payload, and no-mutation regressions.

@Pigbibi

Pigbibi commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

PERMANENT_FREEZE: exact-store closure exhausted; durability/pragma semantics remain deployment-sensitive and no consumer contract exists. Frozen evidence retained; N2 deferred pending consumer.

@Pigbibi Pigbibi closed this Jul 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bd8b9d0c62

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if item.persist_mode != "durable":
_fail()
return item
except (sqlite3.Error, StoreError, TypeError, UnicodeError, json.JSONDecodeError):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Catch JSON parser failures as StoreError

When a persisted/corrupted BLOB contains syntactically valid JSON that fails inside the stdlib parser before N1 validation runs, such as an integer over Python's digit limit raising plain ValueError or deeply nested arrays raising RecursionError, this handler does not catch it. In those cases get() leaks a raw runtime exception instead of the store's fail-closed StoreError, so callers that handle store failures can still crash on corrupted rows.

Useful? React with 👍 / 👎.

def _validate_schema(conn: sqlite3.Connection) -> None:
try:
objects = {(row[0], row[1]) for row in conn.execute(
"SELECT name,type FROM sqlite_master WHERE name NOT LIKE 'sqlite_%'")}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Escape the SQLite-internal object filter

When validating an existing database, this LIKE 'sqlite_%' treats _ as a single-character wildcard, so user-created objects such as sqliteXextra or sqlitefoo are filtered out along with internal sqlite_ objects. Fresh evidence is the unescaped LIKE pattern on this line: an otherwise exact database with an extra sqliteX... table still passes validation, bypassing the documented invariant that only store_meta and results may exist.

Useful? React with 👍 / 👎.

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