Skip to content

feat: complete four-store commerce example - #1

Draft
hyochan wants to merge 3 commits into
mainfrom
codex/commerce-protocol-review
Draft

hyochan wants to merge 3 commits into
mainfrom
codex/commerce-protocol-review

Conversation

@hyochan

@hyochan hyochan commented Sep 8, 2026

Copy link
Copy Markdown
Member

The runnable Commerce Protocol example now completes account deletion and provides Apple, Google, Amazon, and Horizon evidence bridges. Each bridge is checked against the published contract; the fictional fixture keeps real HTTP, SQLite, signed delivery, retries, and restart behavior visible in the dashboard.

The same app backend and event receiver work with SQLite, memory, and IAPKit provider configurations. Account-erasure tombstones reject late grants and replay after restart. Amazon/Horizon ownership answers remain point-in-time checks and do not inherit the subscription fixture's expiry.

Seven milestones and 22 immutable source checkpoints can be installed and replayed. The source export refuses stale recordings, and documentation follows the recorded predecessor chain.

Companion IAPKit and documentation: hyodotdev/openiap#445.

Checks: 229 runtime assertions, 3 composition tests, 5 tooling tests, all 22 checkpoint installations and replays, and 75 composition assertions with an extracted-archive replay and negative control passed.

Scope: local fixture and integration evidence only; no real store checkout or production-conformance claim. No merge requested.

Preview

commerce-example.webm

Complete account erasure, store evidence bridges and provider composition while preserving the app backend and receiver. Record executable checkpoints and reject stale documentation exports.
@hyochan hyochan added 🎯 feature New feature 👀 example 💨 ci Cloud integration 📖 documentation Improvements or additions to documentation labels Sep 8, 2026
hyochan added a commit to hyodotdev/openiap that referenced this pull request Sep 9, 2026
Commerce Protocol now walks readers through purchase, verification,
ownership, access, events, and account deletion, with IAPKit and the
runnable example alongside each step. The architecture opens
explanations in place; navigation, nested accordions, and transitions
follow the same documentation layout.

IAPKit binds Amazon and Horizon purchases to authenticated app accounts
and rechecks ownership before returning access. Only entitled evidence
binds, at most 20 purchases per app account; the 21st binding answers
`bound: false` (SPEC §4.4) and is logged, and the read keeps the same
bound as a backstop. Rechecks draw on their own admission bucket (300
tokens, 5/s, one per bound purchase) before any store call and do not
write back an unchanged verdict. Erasure refuses the erased app user id
while its job is retained; another app account may bind the same Amazon
or Horizon evidence afterwards as a first binding. Apple and Google
subscription rows keep their permanent erasure marker.

The example → IAPKit → example check keeps one app backend and receiver
unchanged: 170 assertions, recorded at the committed sources. The docs
build verifies that the report, snapshots, hashes, and `#L<n>` anchors
agree with each other; freshness against the current IAPKit sources is
the advisory `bun run audit:commerce-evidence`, run with
`continue-on-error` in the web E2E job, and a recording from an
uncommitted tree is marked `-dirty`. Static HTML, canonical metadata,
sitemap generation, and readable AI entry points make the same guides
available without JavaScript.

Companion example:
hyodotdev/openiap-commerce-protocol-example#1.

Checks: IAPKit lint and the full IAPKit test suite (one existing skip),
compiled-server smoke, the protocol suite, 170 provider-replacement
assertions, the composition and source-provenance checks, 144
prerendered pages, and the SDK parity, docs, layout, CI-path, and
agent-surface audits pass locally.

Review: CodeRabbit skips this diff (over its 100-file limit) and Codex
is over its usage limit until Sep 15, so this head was reviewed by three
independent read-only review-self lenses (kit correctness, tests and
tooling, docs and protocol) and by Grok on the pasted diff. Every
finding that did not need a product decision was fixed in `3bf91680` and
the follow-up commit; the Grok notes left as they are, with reasons, are
in the PR comments.

Merge gate: device regression remains pending for the `packages/kit`
Martie live-receipt rows on iOS and Android/Play. The local four-store
checks use synthetic evidence and mocked store responses; no real
Amazon, Horizon, Apple, or Google checkout is claimed. Cross-company
adoption and production migration are not established by this run.

Preview


[commerce-docs.webm](https://github.com/user-attachments/assets/853d1473-14bd-4c04-82bb-d9278f4eeb9f)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…mber

The unscoped `openiap-commerce-protocol` is retired: every version on npm
carries a deprecation notice, its latest is 0.1.0, and nothing publishes it
any more. The specification ships as `@hyodotdev/openiap-commerce-protocol`,
now at 0.3.0.

That release renames the capability descriptor's `specVersion` to
`commerceProtocolVersion`, because OpenIAP governs two protocols and a member
named for "the spec" said nothing about which one. The two changes have to
land together: on 0.3.0 with the old name, the published schema rejects the
descriptor with "Capabilities use the published response schema"; on 0.1.0
with the new name, the schema still requires `specVersion` and
`composition/run.mjs` reads undefined.

`verify.mjs` passes 229 checks and the composition tests pass. The 23 recorded
checkpoints are untouched and still verify: each installs from its own
lockfile, so they stay pinned to the package version they were built against.
The seven-step walkthrough taught `specVersion`, which 0.3.0 renamed to
`commerceProtocolVersion`. A reader following step 4 would have written a
member the published schema rejects, so the lesson had to move with the
protocol rather than stay pinned to a retired name.

Each step is re-recorded from its own milestone source with the dependency
moved to the scoped package at 0.3.0 and the member renamed. The recorded
runs are real: 6, 10, 15, 18, 22, 138 and 229 checks, and
`verify:checkpoints` applies the whole patch chain from an empty directory
and installs and tests every archive independently.

One tooling fix was needed to make the chain reproducible. Early recorders
normalised patch paths with a blind string replace, which also rewrote those
strings where they appear as file content — `capture.mjs`'s own source — so
the patch could not reproduce its archive. Each milestone's recorder now
scopes that replace to the `diff --git` / `--- a/` / `+++ b/` headers, which
is what the current `checkpoint-tools.mjs` already does.

The superseded records are retired rather than overwritten: they recorded a
build against the deprecated unscoped package and cannot be kept true beside
a chain that teaches the current one.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💨 ci Cloud integration 📖 documentation Improvements or additions to documentation 👀 example 🎯 feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant