Skip to content

feat: add strict vNext result/store contract - #254

Closed
Pigbibi wants to merge 4 commits into
mainfrom
codex/qpk-vnext-result-store-n1
Closed

feat: add strict vNext result/store contract#254
Pigbibi wants to merge 4 commits into
mainfrom
codex/qpk-vnext-result-store-n1

Conversation

@Pigbibi

@Pigbibi Pigbibi commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Scope

QPK-N1 clean-slate vNext strict result/store contract foundation only.

  • Independent namespace/schema qpk-vnext/result/v1; no legacy key reuse or fallback.
  • Explicit canonical profile, execution timing, result identity version, persist mode, strategy/run/parameter/source metadata.
  • Deterministic wire serialization, identity digest, and key generation.
  • Strict JSON-safe immutable parameter values, safe segments, unknown-field rejection, sanitized errors.
  • Durable/ephemeral are contract semantics only; no store/cache/publish I/O.

Source of truth: /Users/lisiyi/Documents/Codex/2026-07-14/ba-2/outputs/quant_system_clean_slate_vnext_decision_2026-07-15.md
Commit: 7e8624d07df00d9385293a50cf5dfca36f310782

Non-goals

No legacy reads/migration/index, PerformanceStore integration, caller/orchestrator/runner, real artifacts, broker/live/account, or new dependencies.

Validation

6 focused tests; full 613 passed, 1 skipped; ruff, compileall, diff-check passed.

Co-Authored-By: Codex <noreply@openai.com>
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

🤖 Codex PR Review

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

⚖️ Codex Review Arbitration

🚫 block: VNextResultContract.__post_init__ validates result_identity_version and param_version only as non-bool positive ints, with no MAX_SAFE_JSON_INTEGER cap, while _identity_payload() serializes both fields as JSON numbers and key also embeds their numeric values. The same module explicitly treats MAX_SAFE_JSON_INTEGER as part of the wire contract for params, so the current source of truth supports the reviewer's claim that oversized version numbers are accepted into identity-bearing wire data without the repository's existing JSON-safety guardrail. Nothing in the diff, tests, or docs proves those oversized values are intentionally supported or encoded in an alternate safe form. The prior blocking finding was about removing a hardcoded canonical_profile allowlist; the current finding is a separate issue and does not reverse or contradict that earlier required behavior.

🚫 Blocking Issues

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

1. 🟠 [HIGH] Logic in src/quant_platform_kit/strategy_lifecycle/vnext_result_store_contract.py

result_identity_version and param_version are only checked for positivity, not for JSON-safe range. Both fields are serialized into the wire payload and participate in identity/key generation, so values above 2**53 - 1 will round differently in JavaScript/double-based consumers and produce mismatched digests, keys, or decode failures even though the producer accepted them. (line 149)

Suggestion: Apply the same MAX_SAFE_JSON_INTEGER bound used for parameter values to result_identity_version and param_version during construction (and therefore decode), or encode oversized values in an explicitly tagged string form.

ℹ️ Other Findings

1. 🟡 [MEDIUM] Logic in src/quant_platform_kit/strategy_lifecycle/vnext_result_store_contract.py

_computed_at() validates the timestamp format but returns the original string unchanged, so multiple lexical forms for the same instant (for example 2026-07-15T00:00:00Z and 2026-07-15T00:00:00.000000Z) are both accepted and emitted as distinct wire payloads. That breaks the PR's stated goal of deterministic/canonical wire serialization and can create false mismatches in systems that compare or hash the full wire document. (line 103)

Suggestion: Parse computed_at and re-emit it in one canonical UTC form before storing it on the contract, then compare against that normalized value during decode.


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: 7e8624d07d

ℹ️ 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 isinstance(value, float) and math.isfinite(value):
return value
if isinstance(value, tuple):
return [_param_value(item) for item in value]

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 Preserve array-valued params through decode

When any parameter is array-valued by passing a tuple, this branch serializes it into a JSON list in to_wire(), but decode_vnext_wire() feeds that list back through _param_value(), which rejects lists. As a result, the contract can emit wire data that its own decoder rejects; the stored list is also reachable via contract.params and can be mutated after construction, changing the digest/key of a supposedly frozen result contract.

Useful? React with 👍 / 👎.

Co-Authored-By: Codex <noreply@openai.com>

@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: e63ead352f

ℹ️ 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".

def _param_value(value: Any) -> Any:
if value is None:
raise VNextContractError()
if isinstance(value, (str, bool, int)):

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 non-encodable parameter strings

When a parameter value is a Python string containing a lone surrogate, this branch accepts it even though _canonical_json(..., ensure_ascii=False).encode() later raises UnicodeEncodeError while computing key or to_wire(). That lets callers construct a supposedly strict JSON-safe contract that cannot generate its deterministic wire/key and fails with an unsanitized low-level exception; validate parameter strings for UTF-8/JSON encodability before accepting them.

Useful? React with 👍 / 👎.

object.__setattr__(self, "execution_timing", ExecutionTiming(self.execution_timing))
object.__setattr__(self, "persist_mode", PersistMode(self.persist_mode))
except Exception as exc:
raise VNextContractError() from exc

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 Suppress enum exception causes in sanitized errors

When an invalid execution_timing or persist_mode comes from untrusted wire data, this from exc preserves the underlying ValueError as __cause__; any traceback or structured error log will still include the raw rejected value even though the contract documents sanitized validation errors. Treat these enum coercion failures as expected validation failures and raise without chaining (or from None) so secrets embedded in malformed payloads are not echoed.

Useful? React with 👍 / 👎.

Co-Authored-By: Codex <noreply@openai.com>

@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: c1a76ae279

ℹ️ 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".

def _text(value: Any) -> str:
if not isinstance(value, str) or not value or len(value) > _MAX_SEGMENT:
raise VNextContractError()
if any(ord(char) < 32 or char in "/\\" for char in value):

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 computed_at is UTF-8 encodable

When untrusted wire data contains an escaped lone surrogate in computed_at, this check accepts it because it only rejects control characters and slashes. Since computed_at is excluded from _identity_payload(), the digest path never exercises _canonical_json(...).encode(), so decode_vnext_wire() can return a contract whose to_wire() payload cannot be UTF-8 JSON-encoded despite the strict JSON-safe wire contract; validate/sanitize these metadata strings before accepting them.

Useful? React with 👍 / 👎.

Comment on lines +65 to +66
if isinstance(value, float) and math.isfinite(value):
return value

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 Normalize negative-zero params before hashing

When a parameter value is -0.0, this branch accepts it unchanged. Python mapping/dataclass equality treats a contract with -0.0 params as equal to the same contract with 0.0, but _canonical_json emits different tokens (-0.0 vs 0.0), so equal contracts produce different identity_digest/key values and can create duplicate result-store entries for the same logical parameters; normalize or reject negative zero before hashing.

Useful? React with 👍 / 👎.

Comment on lines +59 to +64
if isinstance(value, (str, bool)):
return value
if isinstance(value, int):
if abs(value) > MAX_SAFE_JSON_INTEGER:
raise VNextContractError()
return value

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 Avoid bool/int parameter equality collisions

When the same parameter is provided as True versus 1 (or False versus 0), these branches preserve different JSON wire types, but Python mapping/dataclass equality still considers the resulting contracts equal. That leaves equal contracts with different identity_digest/key values, so any caller comparing decoded contracts, de-duplicating contract lists, or using equality in tests can treat two distinct result-store identities as interchangeable; make equality type-aware or reject/normalize these ambiguous numeric cases.

Useful? React with 👍 / 👎.

Co-Authored-By: Codex <noreply@openai.com>

@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: 92e7cbf3e4

ℹ️ 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 +165 to +168
if not isinstance(self.result_identity_version, int) or isinstance(self.result_identity_version, bool) or self.result_identity_version < 1:
raise VNextContractError()
if not isinstance(self.param_version, int) or isinstance(self.param_version, bool) or self.param_version < 1:
raise VNextContractError()

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 Cap version integers to JSON-safe range

When untrusted wire data or direct construction supplies result_identity_version or param_version above MAX_SAFE_JSON_INTEGER, these checks still accept it even though oversized parameter ints are rejected for JSON safety. The resulting wire payload and identity digest then contain JSON numbers that double-based clients can round before recomputing or verifying the contract, so apply the same safe-integer upper bound to both version fields.

Useful? React with 👍 / 👎.


@property
def key(self) -> str:
return f"{VNEXT_NAMESPACE}/{self.domain}/{self.canonical_profile}/{self.strategy_id}/{self.run_id}/{self.execution_timing.value}/i{self.result_identity_version}/p{self.param_version}/{_digest(self._identity_payload())}.json"

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 Coerce segment strings before building keys

When callers pass a str enum or other str subclass with a custom __str__ for domain, canonical_profile, strategy_id, etc., _segment() accepts it and __post_init__ stores it unchanged. This interpolation then uses the subclass string form for the key (for example Profile.SOXL), while to_wire() and identity_digest JSON-encode the underlying string value (SOXL), so serializing and decoding the same contract changes key and can orphan stored results. Reject non-exact strings or coerce to plain strings before building the key.

Useful? React with 👍 / 👎.

@Pigbibi

Pigbibi commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

PERMANENT_FREEZE: remaining vNext contract redesign evidence requires safe-range validation for all identity-bearing integers and one canonical UTC timestamp serialization. No further code, rerun, reslice, merge, bypass, or thread resolution. Preserve this PR as frozen evidence.

@Pigbibi Pigbibi closed this Jul 14, 2026
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