Skip to content

fix: close proof-integrity gaps between claims and implementation - #1

Merged
0xaje merged 1 commit into
mainfrom
fix/proof-integrity
Sep 3, 2026
Merged

fix: close proof-integrity gaps between claims and implementation#1
0xaje merged 1 commit into
mainfrom
fix/proof-integrity

Conversation

@successaje

Copy link
Copy Markdown
Collaborator

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.

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>
@0xaje
0xaje merged commit 67ebf87 into main Sep 3, 2026
1 of 2 checks passed
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.

2 participants