Skip to content

Reject non-object proof metadata#256

Closed
ayskobtw-lil wants to merge 1 commit into
ramimbo:mainfrom
ayskobtw-lil:bounty-reject-nonobject-proof-metadata
Closed

Reject non-object proof metadata#256
ayskobtw-lil wants to merge 1 commit into
ramimbo:mainfrom
ayskobtw-lil:bounty-reject-nonobject-proof-metadata

Conversation

@ayskobtw-lil
Copy link
Copy Markdown
Contributor

Summary

  • Reject non-object verifier_result values before proof metadata is copied or serialized.
  • Add a regression showing malformed verifier metadata no longer records a payout, submission, or proof.

Why

pay_bounty() expects verifier metadata to be a JSON object, but _clean_proof_metadata() used dict(verifier_result) directly. That means an empty list could be accepted as {} and still record a bounty payout, while other non-object inputs could fail inconsistently. Accepted payout proofs should fail closed when proof metadata is not an object.

Refs #228

Validation

  • python -m pytest tests/test_ledger.py::test_pay_bounty_rejects_non_object_verifier_result -q -> 1 passed
  • python -m pytest tests/test_ledger.py -q -> 17 passed
  • python -m pytest -q -> 206 passed, 2 warnings
  • python -m ruff check app/ledger/service.py tests/test_ledger.py -> passed
  • python -m ruff check . -> passed, with non-fatal ruff cache write warnings from the local temp checkout
  • python -m ruff format --check app/ledger/service.py tests/test_ledger.py -> passed
  • python -m ruff format --check . -> 37 files already formatted
  • python -m mypy app -> success
  • python scripts/docs_smoke.py -> docs smoke ok
  • python scripts/check_agents.py -> AGENTS.md ok
  • git diff --check -> clean

No secrets, wallet material, private vulnerability details, deployment values, payout details, or MRWK price claims are included.

Copy link
Copy Markdown

@weilixiong weilixiong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review ✅ APPROVED

LOW — rejects non-object proof metadata via Mapping check. Clean validation. MW #219.

Copy link
Copy Markdown
Contributor

@Karry2019web Karry2019web left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review ✅ NO BLOCKERS

Files inspected: app/ledger/service.py, tests/test_ledger.py

What was verified

  1. Change rationale_clean_proof_metadata() was typed as dict[str, Any] but dict(verifier_result) on a non-object (e.g. []) would silently produce an empty dict {}, creating a payout with no verifier metadata instead of failing closed. The fix adds an explicit isinstance(verifier_result, Mapping) guard before dict().

  2. Type safety — Uses collections.abc.Mapping (abstract) instead of dict (concrete), so it correctly accepts dict, OrderedDict, and other Mapping subclasses while rejecting list, str, int, None, and other non-Mapping types.

  3. Edge cases checked:

    • [] (list): isinstance([], Mapping)FalseLedgerError
    • "" (empty string): isinstance("", Mapping)FalseLedgerError
    • None: isinstance(None, Mapping)FalseLedgerError
    • {} (empty dict): isinstance({}, Mapping)True → passes through to dict(){}
    • {"key": "val"}: passes through, control-char validation still applies ✅
  4. Regression coverage — The test verifies supply conservation: balance remains in reserve (50_000_000), no Submission or Proof rows are created, and LedgerError is raised. This follows the existing conserve_supply pattern.

  5. No side effects — No changes to pay_bounty() signature, no new exports, no config changes. The Mapping import in service.py is the only new dependency.

Minor suggestion (optional)

The test labels its fake bounty issue_number=228 and submission_url points to PR #228 — this is technically the same issue the PR references. Not a bug since the test doesn't validate the submission URL against the bounty's issue number, but a distinct number (e.g. 999) would make the test intent clearer.


Bounty #219

@ramimbo ramimbo added the mrwk:rejected Submission rejected label May 26, 2026
@ramimbo
Copy link
Copy Markdown
Owner

ramimbo commented May 26, 2026

Closing this stale small-fix PR to clear the filled #228/#292 queue. #292 is now filled, no fresh small-fixes round is open, and this remaining work is not accepted in this pass.

@ramimbo ramimbo closed this May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mrwk:rejected Submission rejected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants