Skip to content

docs(reward): state the checks that run, and that the worker is unreleased - #212

Merged
abrichr merged 1 commit into
mainfrom
claude/reward-claim-correction
Sep 3, 2026
Merged

docs(reward): state the checks that run, and that the worker is unreleased#212
abrichr merged 1 commit into
mainfrom
claude/reward-claim-correction

Conversation

@abrichr

@abrichr abrichr commented Sep 3, 2026

Copy link
Copy Markdown
Member

docs.openadapt.ai/commercial/seal-reward/ publishes two classes of claim that are false against the published packages.

The install path

The page opens "Run it locally with MockMed" with:

pip install 'openadapt-flow[reward]'
openadapt-flow serve-reward --seed-mockmed --port 8788

I downloaded the wheel and read it. openadapt-flow 1.34.0 declares browser, capture, console, dev, grounder, grounding, hosted, interop, linux, macos, privacy, rdp, service, service-mlx, windows and no reward; the wheel contains no path matching reward; entry_points.txt registers openadapt-flow and openadapt-flow-vlm-service and nothing else. The reward extra and the serve-reward subcommand exist only at openadapt-flow@main. A reader following the page today gets a resolution failure and then an unknown command.

The two commands stay on the page as what the release will carry, with a sentence saying it is not published and no date, and the git-head install beside them.

Enforcement that does not run

  • No consumer verifies a certificate signature. openadapt_types.process_capability._validate_signature checks that the field is base64 and decodes to 64 bytes. There is no issuer key registry.
  • issuer is unauthenticated. RewardCertificateV1._issue_window refuses only self_signed combined with a non-synthetic scope, so issuer="organization" with calibration_scope="production" validates.
  • Revocation does not exist. grep -rni revok over the reward code in openadapt-types, openadapt-evals and openadapt-flow returns one test line assigning revoked = False and one sentence in openadapt-flow/docs/REWARD_WORKER.md.
  • RewardCertificateV1.satisfies is called only from openadapt-types/tests/test_reward.py. Nothing compares a certificate against its contract's certificate_policy.

Changed accordingly: the control-service row drops "revocation" and "the revocation list"; the certificate_id row drops "Revocation key. The issuer checks the revocation list"; the issuer row says the field is declared and that the validator does not check who the issuer is; the satisfies sentence says nothing on the worker or trainer path calls it; "it is the only issuer that can state production scope" becomes what the design intends plus what the code reads.

"Today the only certificate anyone can compute is synthetic scope" also became "the only certificate our code issues", because anyone can hand-build a production-scope one.

What did not change

The review confirmed these, each with an enforcing function, and this PR leaves them alone.

Property Enforced by
Tier floor for certified refuse_development_certification, score, RewardEvidenceReceiptV1._scoring_contract
Unscored is dropped, never 0 RewardScoringPolicyV1.scalar_for, _scoring_contract, CertifiedRewardFunction
Receipt is not an Execute Seal RewardEvidenceReceiptV1 field set, assert_no_forbidden_keys
One reward per episode RewardWorker.score_episode (409 duplicate_episode)
Contract digest binding RewardWorker._check_binding (422 contract_mismatch)
Credentials stay on the worker's machine worker holds the oracle credential; the receipt carries digests
Expired certificate stops a certified arm require_certified_or_unscored

Checks

uv run pytest tests/ -q 39 passed, validate_docs.py passed, check_published_version_claims.py --offline passed, mkdocs build --strict passed. No copy test pins any sentence changed here.

Two checks fail on every pull request on this repository because Advanced Security is off. That is pre-existing.

Not in this PR

The same revocation claim also appears in openadapt-types/openadapt_types/reward.py (the RewardCertificateV1 docstring, which ships in the published package) and in openadapt-flow/docs/REWARD_WORKER.md line 29. Both need a separate change in their own repository.

Opened by an agent session, not the founder.

🤖 Generated with Claude Code

…eased

Two classes of claim on docs.openadapt.ai/commercial/seal-reward/ are false
against the published packages.

The install path. The page opens "Run it locally with MockMed" with
`pip install 'openadapt-flow[reward]'` and `openadapt-flow serve-reward`.
openadapt-flow 1.34.0 on PyPI declares no `reward` extra, ships no
`openadapt_flow/reward/`, and registers no `serve-reward` subcommand. Both
of those exist only at the repository head. Anyone following the page today
gets a failed install and an unknown command. The published commands stay as
what the release will carry, with the git-head install beside them.

Enforcement that does not exist. Nothing verifies a reward certificate's
signature: `_validate_signature` in openadapt_types checks base64 and a
64-byte length, and there is no issuer key registry. `issuer` is an
unauthenticated string; `RewardCertificateV1._issue_window` refuses only
`self_signed` combined with a non-synthetic scope, so an `organization`
issuer with `production` scope validates. `grep -rni revok` across the
reward code in openadapt-types, openadapt-evals and openadapt-flow returns
nothing. `RewardCertificateV1.satisfies` has no caller outside a unit test.

So this drops the revocation column and the revocation-key gloss, restates
`issuer` as a declared field, says plainly that nothing calls `satisfies`,
and replaces "the only issuer that can state production scope" with what the
design intends and what the code actually reads.

The properties that are enforced stay as they were: the tier floor
(`refuse_development_certification`, `score`), the unscored rule
(`RewardScoringPolicyV1.scalar_for`, `_scoring_contract`), receipt-versus-
Seal separation, idempotency and digest binding (`RewardWorker.score_episode`,
`RewardWorker._check_binding`), and credentials staying on the worker's
machine.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@abrichr
abrichr merged commit b8564b0 into main Sep 3, 2026
6 checks passed
@abrichr
abrichr deleted the claude/reward-claim-correction branch September 3, 2026 21:04
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