fix: close proof-integrity gaps between claims and implementation - #1
Merged
Conversation
The product's claim is that forecasts are cryptographically committed before settlement and scored honestly afterwards. Several surfaces asserted more than the code delivered. Each fix below closes one of those gaps. Anchor the pre-settlement commitment digest Receipts now carry commitmentHash: a SHA-256 over the frozen forecast (probability, direction, confidence, thesis, counter-thesis, signer) bound to the market evidence it was formed against. It is computed at commit time, so anchoring it proves what was believed before the outcome was known. Previously the client anchored the post-resolution evidence hash, falling back to a hash synthesized from the receipt id when unresolved -- which could not prove a pre-settlement commitment at all. That fallback is gone. Verify anchors on-chain instead of trusting the client A reported transaction hash was stored unverified. anchorDecisionReceipt now re-reads the mined transaction from Somnia and requires that it succeeded, targeted the anchor contract, was sent by the claiming address, and carries calldata containing exactly this receipt's commitment digest. Make staking real The UI offered a stake selector and the contract exposed a payable anchorReceiptWithStake, but it was never called: the amount was self-reported and stored as STAKED. The payable entrypoint is now used, and the recorded stake is the value observed on-chain. A commit-time selection is an intention (NONE) until confirmed; the resolver settles only confirmed stakes. Fail closed on the oracle webhook POST /api/oracle/resolve skipped authentication entirely when ORACLE_WEBHOOK_SECRET was unset, letting anyone settle any market. It now returns 503 rather than accepting anonymous settlement. Stop fabricating outcomes The resolver mapped any inconclusive settlement price to YES, feeding invented outcomes into Brier scores and leaderboard tiers. Extracted as mapSettlementOutcome, which returns VOID and is excluded from scoring. Label the AI Model Arena as a fixture Its rankings come from five hand-authored scenarios, but the UI presented them as LIVE, VERIFIED and "across resolved DreamDEX contracts". The tab remains -- it demonstrates a real mechanism -- and now says so. Repair the drifted migration chain 0003_eventforge_execution_anchoring.sql was absent from _journal.json and never applied, and the stake, signer and oracleSource columns appeared in no migration at all, so a freshly migrated database lacked columns the code writes. Regenerated as 0003_cool_ghost_rider.sql, which absorbs the orphan (verified a strict subset) and adds commitmentHash. Also: regenerate pnpm-lock.yaml, which failed --frozen-lockfile against package.json and was breaking CI at the install step; pin the npm registry in .npmrc, as the inherited mirror stalls installs; correct README contract signatures that did not match ProofCastAnchor.sol; rename $SOM to STT, the actual Shannon native currency. Adds server/integrity.test.ts (18 tests) covering the VOID rule, every anchor rejection path, and digest determinism. Suite: 60 passing, typecheck clean, production build succeeds. The new migration has not been executed against a database locally -- no MySQL or Docker daemon available -- so CI is its first run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The product's claim is that forecasts are cryptographically committed before settlement and scored honestly afterwards. Several surfaces asserted more than the code delivered. Each fix below closes one of those gaps.
Anchor the pre-settlement commitment digest
Receipts now carry commitmentHash: a SHA-256 over the frozen forecast
(probability, direction, confidence, thesis, counter-thesis, signer) bound to
the market evidence it was formed against. It is computed at commit time, so
anchoring it proves what was believed before the outcome was known.
Previously the client anchored the post-resolution evidence hash, falling back
to a hash synthesized from the receipt id when unresolved -- which could not
prove a pre-settlement commitment at all. That fallback is gone.
Verify anchors on-chain instead of trusting the client
A reported transaction hash was stored unverified. anchorDecisionReceipt now
re-reads the mined transaction from Somnia and requires that it succeeded,
targeted the anchor contract, was sent by the claiming address, and carries
calldata containing exactly this receipt's commitment digest.
Make staking real
The UI offered a stake selector and the contract exposed a payable
anchorReceiptWithStake, but it was never called: the amount was self-reported
and stored as STAKED. The payable entrypoint is now used, and the recorded
stake is the value observed on-chain. A commit-time selection is an intention
(NONE) until confirmed; the resolver settles only confirmed stakes.
Fail closed on the oracle webhook
POST /api/oracle/resolve skipped authentication entirely when
ORACLE_WEBHOOK_SECRET was unset, letting anyone settle any market. It now
returns 503 rather than accepting anonymous settlement.
Stop fabricating outcomes
The resolver mapped any inconclusive settlement price to YES, feeding invented
outcomes into Brier scores and leaderboard tiers. Extracted as
mapSettlementOutcome, which returns VOID and is excluded from scoring.
Label the AI Model Arena as a fixture
Its rankings come from five hand-authored scenarios, but the UI presented them
as LIVE, VERIFIED and "across resolved DreamDEX contracts". The tab remains --
it demonstrates a real mechanism -- and now says so.
Repair the drifted migration chain
0003_eventforge_execution_anchoring.sql was absent from _journal.json and never
applied, and the stake, signer and oracleSource columns appeared in no
migration at all, so a freshly migrated database lacked columns the code
writes. Regenerated as 0003_cool_ghost_rider.sql, which absorbs the orphan
(verified a strict subset) and adds commitmentHash.
Also: regenerate pnpm-lock.yaml, which failed --frozen-lockfile against package.json and was breaking CI at the install step; pin the npm registry in .npmrc, as the inherited mirror stalls installs; correct README contract signatures that did not match ProofCastAnchor.sol; rename $SOM to STT, the actual Shannon native currency.
Adds server/integrity.test.ts (18 tests) covering the VOID rule, every anchor rejection path, and digest determinism. Suite: 60 passing, typecheck clean, production build succeeds. The new migration has not been executed against a database locally -- no MySQL or Docker daemon available -- so CI is its first run.