traverse-framework / traverse-framework/registry

Publish capability: core.idempotency-guard (business duplicate-submit / idempotency guard)

Open
#502 0 comments 0 reactions 0 assignees View on GitHub
enhancement good first issue help wanted no-spec-needed
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.