fix: bind Binance execution authority to QPK 9618 - #148
Conversation
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e551868b5
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 98a3697cd9
ℹ️ 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 has_execution_authority(allocation.get("execution_decision")): | ||
| market_snapshot = capture_market_snapshot( |
There was a problem hiding this comment.
Recompute allocation after recapturing the market snapshot
Whenever execution authority is approved, this second capture replaces prices, balances, and u_total, but allocation, total_equity, and trend_val_equity still come from the first snapshot. If prices move while the two snapshots and strategy evaluation run—or the BNB top-up changes balances—the portfolio report, daily PnL, state rebasing, and circuit-breaker decision use the old valuation while subsequent execution uses the new market data. Recompute the allocation from the replacement snapshot, or isolate the fuel top-up without replacing the inputs used downstream.
Useful? React with 👍 / 👎.
| member["candidate_identity_sha256"] | ||
| == account["candidate_identity_sha256"] | ||
| == candidate_identity.candidate_sha256 | ||
| and member["decision_digest_sha256"] | ||
| == account["decision_digest_sha256"] | ||
| == decision_digest |
There was a problem hiding this comment.
Require scoped approvals to reference the same portfolio snapshot
When MEMBER and ACCOUNT approvals were produced from different portfolio snapshots within the five-minute freshness window, this comparison still grants authority as long as the candidate and decision digests match. Because portfolio_snapshot_digest_sha256 is only shape-checked and never compared, approvals that were never jointly issued for one account state can be combined to authorize live orders; require the two scoped assessments to carry the same portfolio snapshot digest before accepting them.
Useful? React with 👍 / 👎.
| for field in ( | ||
| "mandate_authority_receipt_sha256", | ||
| "candidate_identity_sha256", | ||
| "decision_digest_sha256", | ||
| "portfolio_snapshot_digest_sha256", | ||
| "assessment_sha256", | ||
| ): | ||
| if not isinstance(value.get(field), str) or not _SHA256_PATTERN.fullmatch(value[field]): |
There was a problem hiding this comment.
Verify each serialized assessment digest before granting authority
When serialized assessment evidence is altered after QPK produced it, this check accepts any 64-character assessment_sha256 without verifying that it is the canonical digest of the assessment. For example, changing a rejected assessment's outcome to APPROVE and clearing reason_codes leaves its candidate and decision digests valid, so has_execution_authority can authorize live orders even though the supplied assessment hash no longer authenticates those fields. Recompute and compare the QPK assessment digest, or use QPK's typed assessment verifier, before trusting the evidence.
Useful? React with 👍 / 👎.
|
Closing unmerged under the anti-review-loop boundary: this execution-authority safety slice consumed its one remediation batch, and the final exact head still has material snapshot, digest-binding, and assessment-integrity P1 blockers. Retain this branch and evidence; runtime authority remains MISSING/no_order. No replacement PR is created. |
Summary
pyproject.toml,qsl.toml, anduv.lockto QPK9618b4bd8e179760ac174914713598762cab15d7Local acceptance
uv lock --check: passed76a60f7b454d467fa68c0c4166530488b5e8528fBoundary