Skip to content

feat: add SOXL/TQQQ clean-cutover snapshots - #199

Closed
Pigbibi wants to merge 2 commits into
mainfrom
codex/soxl-tqqq-clean-cutover-phase1-20260726
Closed

feat: add SOXL/TQQQ clean-cutover snapshots#199
Pigbibi wants to merge 2 commits into
mainfrom
codex/soxl-tqqq-clean-cutover-phase1-20260726

Conversation

@Pigbibi

@Pigbibi Pigbibi commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add offline-only pair-scoped clean-cutover schema, materializer, and verifier
  • require caller-supplied manifest and calendar SHA-256 values for readback
  • cover independent pair identities and fail-closed fixture validation

Validation

  • python3 -m pytest -q tests/test_soxl_tqqq_clean_cutover_snapshot.py
  • python3 -m ruff check src/us_equity_snapshot_pipelines/soxl_tqqq_clean_cutover_snapshot.py tests/test_soxl_tqqq_clean_cutover_snapshot.py
  • python3 -m compileall -q src/us_equity_snapshot_pipelines/soxl_tqqq_clean_cutover_snapshot.py

No provider, real-data, replay, optimization, plugin L2/L3, or live behavior is included; size remains zero.

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

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown

🤖 Codex PR Review

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

🚫 Blocking Issues

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

1. 🟠 [HIGH] Logic in src/us_equity_snapshot_pipelines/soxl_tqqq_clean_cutover_snapshot.py

_validate_rows treats any weekday as a valid trading session, and the verifier only compares calendar_sha256 as an opaque string. A caller can materialize and verify rows for a weekday market holiday such as 2026-11-26 while claiming a real NYSE calendar digest, so the snapshot records non-trading dates as completed sessions and still passes readback. (line 128)

Suggestion: Validate every session against the actual calendar referenced by calendar_sha256 (or another caller-supplied allowed-session set derived from that calendar) instead of using weekday() < 5 as the only trading-session check.

ℹ️ Other Findings

1. 🟡 [MEDIUM] Reliability in src/us_equity_snapshot_pipelines/soxl_tqqq_clean_cutover_snapshot.py

The immutability check is racy: destination.exists() is tested before os.replace(temporary, destination). A concurrent process can create output_dir after the check and, if it is an empty directory, the later rename can replace it, overwriting a path that was supposed to be immutable. (line 359)

Suggestion: Reserve the target path atomically before writing or publishing, for example with an exclusive lock/sentinel (O_CREAT|O_EXCL) or a no-replace rename primitive, so a concurrent creator cannot be overwritten between the existence check and publication.

2. 🟡 [MEDIUM] Logic in src/us_equity_snapshot_pipelines/soxl_tqqq_clean_cutover_snapshot.py

Snapshot identity is derived from the SHA-256 of raw JSON bytes, but the verifier never enforces canonical serialization for manifest.json, payload.json, or publication.json. The same logical snapshot can therefore be reserialized with different key order or whitespace, produce a different snapshot_id, and still verify as valid when the caller supplies the new digest. (line 264)

Suggestion: Reject noncanonical JSON during verification by round-tripping each parsed object through _canonical_json(...) and comparing the bytes, or define the published digests over canonicalized objects instead of raw file bytes.


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

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

"properties": {
"schema": {"const": "soxl_tqqq_clean_cutover_snapshot.v1"},
"pair_id": {"enum": ["QQQ_TQQQ", "SOXX_SOXL"]},
"symbols": {"type": "array", "items": {"type": "string"}, "minItems": 2, "maxItems": 2, "uniqueItems": true},

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 Bind schema symbols to the selected pair

When a downstream consumer validates a manifest only against this new schema, pair_id: "QQQ_TQQQ" can be paired with any two unique strings, including SOXX/SOXL or unrelated symbols, even though the Python verifier requires the exact PAIR_SYMBOLS mapping. This allows a schema-valid manifest to misidentify its dataset; add pair-specific conditional constraints so each pair_id requires its canonical ordered symbol list.

Useful? React with 👍 / 👎.

or manifest["plugin"] != PLUGIN
or manifest["offline_fixture"] is not True
or manifest["compatibility"] != _compatibility()
or manifest["size"] != SIZE

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 Require an exact integer type for the size sentinel

When verifying an externally produced manifest containing "size": false, this comparison accepts it because Python considers False == 0; the same equality behavior also lets one-session per_symbol_counts use booleans and lets the publication's complete field be 1. The verifier then reports a schema-invalid artifact as valid despite promising strict readback, so these contract fields need exact type checks rather than value equality alone.

Useful? React with 👍 / 👎.

_invalid("session must be a canonical ISO date")
if type(symbol) is not str or symbol not in symbols:
_invalid("each session must contain exactly the pair symbols")
if type(adjusted_close) not in (int, float) or isinstance(adjusted_close, bool) or not math.isfinite(adjusted_close) or adjusted_close <= 0:

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 Convert oversized prices into validation failures

If an offline fixture contains an arbitrarily large integer such as 10**1000 for adjusted_close, math.isfinite(adjusted_close) raises OverflowError while converting it to a float. This affects both materialization and authenticated readback and bypasses SnapshotValidationError/INVALID_EVIDENCE, so callers that classify invalid fixtures by that documented exception instead crash; catch the overflow or validate integers without converting them to float.

Useful? React with 👍 / 👎.

Comment on lines +126 to +127
if not _is_iso_date(session):
_invalid("session must be a canonical ISO date")

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 sessions against the bound market calendar

When rows contain a syntactically valid non-trading date such as Saturday 2026-01-03, both materialization and verification accept it as a completed session even when the caller supplies the expected calendar digest, because the date is checked only for ISO syntax and the digest is never related to the rows. This permits impossible market sessions into the price snapshot and can corrupt downstream returns; validate every session against the calendar represented by calendar_sha256 (or at minimum reject weekends).

Useful? React with 👍 / 👎.

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

Pigbibi commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Closing unmerged per the bounded Phase 1 authority: natural review remained FAILURE after the sole consolidated remediation (budget 1/1). Evidence is preserved; no further remediation, rerun, or merge is authorized.

@Pigbibi Pigbibi closed this Jul 26, 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: be4995f537

ℹ️ 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 +373 to +375
(temporary / "payload.json").write_bytes(payload_bytes)
(temporary / "manifest.json").write_bytes(manifest_bytes)
(temporary / "publication.json").write_bytes(_canonical_json(publication))

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 over-limit members before publishing

When valid inputs serialize beyond MAX_MEMBER_BYTES—for example, a source_identity longer than 1 MiB or a sufficiently long row history—the materializer writes the files and returns success, but verify_clean_cutover_snapshot always rejects the resulting snapshot as oversized. Check each serialized member's size before renaming the temporary directory so every successfully materialized snapshot can pass readback.

Useful? React with 👍 / 👎.

Comment on lines +96 to +97
except (UnicodeDecodeError, ValueError, json.JSONDecodeError) as exc:
raise SnapshotValidationError(f"{INVALID_EVIDENCE}: invalid {name}") 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 Normalize deeply nested JSON parse failures

When an externally supplied member contains deeply nested JSON, json.loads can raise RecursionError while the member is still well below the 1 MiB limit; a roughly 200 KB payload with 100,000 nested arrays reproduces this. Because the exception is not caught here, authenticated readback escapes without the documented SnapshotValidationError/INVALID_EVIDENCE classification instead of treating the malformed fixture as invalid.

Useful? React with 👍 / 👎.

@@ -0,0 +1,100 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/format-assertion": true},

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 Activate format assertions through the selected dialect

When a downstream consumer uses an ordinary Draft 2020-12 validator without separately installing and enabling a format checker, format remains annotation-only because $schema selects the standard meta-schema; declaring $vocabulary in this instance schema does not activate assertion behavior. Dates such as 2026-02-30 therefore satisfy the regex and pass schema validation, while the test masks this by explicitly supplying FORMAT_CHECKER; select a meta-schema that declares the assertion vocabulary or otherwise make the validator requirement enforceable.

Useful? React with 👍 / 👎.

"first_available_session": {"type": "string", "format": "date", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"},
"last_available_session": {"type": "string", "format": "date", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"},
"completed_sessions": {"type": "array", "items": {"type": "string", "format": "date", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"}, "minItems": 1, "uniqueItems": true},
"row_count": {"type": "integer", "minimum": 2},

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 Require an even coverage row count

For either supported pair, every completed session contains exactly two symbols, but this schema accepts an odd row_count such as 3 alongside one completed session and one count per symbol. A schema-only consumer can therefore accept impossible coverage that the Python verifier rejects; require at least multipleOf: 2 so the static pair cardinality is represented in the schema.

Useful? React with 👍 / 👎.

if type(value) is not str or not value.endswith("Z"):
return False
try:
return datetime.fromisoformat(value[:-1] + "+00:00").isoformat().replace("+00:00", "Z") == 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 Align accepted timestamps with the manifest schema

When materialized_at contains canonical nonzero six-digit fractional seconds, such as 2026-07-26T00:00:00.123456Z, this equality succeeds, so both materialization and authenticated readback accept the value. The bundled manifest schema's timestamp pattern permits seconds only, however, causing a successfully produced snapshot to fail schema validation; either reject fractional seconds here or allow the same canonical form in the schema.

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