traverse-framework / traverse-framework/registry
Publish capability: core.idempotency-guard (business duplicate-submit / idempotency guard)
- Dominant language
- Rust
- Stars
- 1
- Forks
- 1
- Avg merge
- 1h 17m
- Merged PRs (30d)
- 217
Description
## Why
Agents and clients retry. Business transactions (payments, refunds, ticket creates) need an **idempotency / duplicate-submit guard** that is a decision helper — not a generic string hash util. The capability compares a business idempotency key + request fingerprint against caller-supplied prior records and returns accept/reject/replay.
## One-PR ask
Publish **`core.idempotency-guard@1.0.0`**:
**Inputs:**
- `key`: string (minLength ≥ 1; business idempotency key)
- `request_fingerprint`: string (caller-computed hash of canonical business fields — capability does **not** invent hashing of arbitrary JSON trees beyond a documented fingerprint compare)
- `prior`: `null` | `{ "key": string, "request_fingerprint": string, "outcome": "accepted"|"rejected", "resource_ref"?: string }`
- `policy_version`: string
**Outputs:**
- `decision`: `accept_new` | `replay_prior` | `reject_conflict` | `reject_invalid`
- `reason_code`: e.g. `first_submit` | `same_fingerprint_replay` | `fingerprint_conflict` | `invalid_key`
- `resource_ref`: string | null (echo from prior on replay)
- `policy_version`: string
**Behavior:**
- No prior → `accept_new`
- Prior same key + same fingerprint → `replay_prior`
- Prior same key + different fingerprint → `reject_conflict`
- Empty key → `reject_invalid`
Deterministic; no silent coerce.
Follow [`CONTRIBUTING.md`](https://github.com/traverse-framework/registry/blob/main/CONTRIBUTING.md) and [`capabilities/README.md`](https://github.com/traverse-framework/registry/blob/main/capabilities/README.md) publish checklist.
- Include `capability-src/` with real Rust tests meeting registry coverage gates (`functions` 100%, lines/regions ≥ 95%)
- Use `traverse-cli capability publish` (or the documented scaffold) so `artifact.digest` / `artifact.url` survive
- Declare `authoring.method` (`human` or `llm-assisted`)
- Ensure every `use_cases[].persona_ref` resolves (scaffold personas if needed)
- Run `bash scripts/ci/pre_pr_check.sh ` before opening
- One capability per PR; branch from `origin/main`, not another `publish/*` branch
**Apps are not ready — publish the capability only.** No app wiring, no demo product surface.
## Out of scope
- Generic string/json utilities (hashing helpers as the product)
- Implementing the durable idempotency store inside WASM with ambient network
- Payment provider APIs
## Done when
- CI green; published in next index
- Tests for all four decisions above
- Contract makes clear durable storage is **host/app responsibility**; this cap is the pure guard
## Host / deps notes
**Pure WASM by default** — caller supplies `prior` (fetched from host state / DB). Do **not** require ambient network. Optional note: apps may later wrap with `traverse_host` state like `commerce.pricing-config`, but v1 stays pure so it is first-contributor friendly.
## Labels
`help wanted` · `good first issue` · `enhancement` · `no-spec-needed`
Contributor guide
Research direction
Read CONTRIBUTING.md and capabilities/README.md first, then use the documented scaffold or traverse-cli capability publish to create the capability and its capability-src/ Rust tests. Run bash scripts/ci/pre_pr_check.sh with the draft PR body; done means all four decisions are covered, registry requirements pass, and the pure host-supplied prior contract is published with CI green.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, wasm
- Domain
- backend-api-design, release
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100