Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@
- [Workflow and state architecture](./docs/workflow-state-architecture.md):
Effection workflows, service boundaries, Redux slices, and where new KERIA
behavior belongs.
- [W3C VRD issuance and presentation](./docs/w3c-vrd-issuance-and-presentation.md):
QVI-side W3C issuance, holder import/admit prerequisites, verifier
presentation approval, edge signing, and failure triage.
- [Smoke tests](./docs/smoke-tests.md): how the CLI and browser smoke checks
work, how to run them, required local services, configuration, outputs, and
failure triage.
- [Scenario tests](./docs/scenario-runners.md): direct Vitest KERIA flows and
optional fixture requirements.
- [CI](./docs/ci.md): GitHub Actions setup for installing pinned KERIpy/KERIA,
starting local services, caching dependencies, and running smoke tests.
- [Container build](./docs/container-build.md): Docker build contract,
`SIGNIFY_TS_PACKAGE`, and the source-owned dependency override helper.

### Run locally

Expand Down
19 changes: 18 additions & 1 deletion docs/background-operations-and-notifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,14 @@ Current keys:
- Contact mutation: `contact:<contactId>`
- Challenge response/request/verify:
`challenge:<action>:<counterpartyAid>:<localIdentifier-or-challengeId>`
- W3C issuance: `credential:<said>:w3c-issue`
- W3C presentation: `credential:<said>:w3c-present`

Expected future keys:

- Schema resolution: `schema:<said>`
- Registry creation: `registry:issuer:<aid>`
- Credential flows: `credential:<said>`
- Additional credential flows: `credential:<said>:<action>`

The UI should disable only the conflicting action, not the whole app. For
example, rotating one identifier should disable only that identifier's rotate
Expand Down Expand Up @@ -133,6 +135,21 @@ The global `LoadingOverlay` is for foreground work only: connect, passcode
generation, route navigation, and loader/fetcher pending state. Background
operations must not trigger the blocking overlay.

## W3C Issuance And Presentation Notes

W3C VRD issuance and presentation use the same operation records and
notifications as other credential work, but the browser edge owns W3C artifact
assembly and signing.

QVI-side W3C issuance calls `signify-w3c` to build/sign the VC-JWT, submits it
to KERIA for validation, then signs and submits the issuer grant EXN. Holder
presentation resolves the held W3C credential, builds/signs the VP-JWT, and
submits it to KERIA in one foreground action.

KERIA validates the edge-provided VC-JWT or VP-JWT before forwarding. There are
no W3C signing queues, local holder approval records, or background W3C
automators in this workflow.

## Adding A Background Flow

1. Add a typed `OperationKind`.
Expand Down
12 changes: 6 additions & 6 deletions docs/container-build.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Container build

The Docker image runs the wallet against a KERIA+Signify stack. It builds from
this repository plus package/image inputs.
The Docker image runs the wallet used by a KERIA+Signify W3C crosswalk stack.
It builds from this repository plus package/image inputs.

Default stack builds should consume published packages, immutable Git SHAs, or
OCI images. Do not make the portable stack depend on a sibling `signify-ts`
source checkout. Local tree overrides are acceptable only as explicit developer
experiments outside the default build contract.
OCI images. Do not make the portable W3C stack depend on a sibling
`signify-ts` source checkout. Local tree overrides are acceptable only as
explicit developer experiments outside the default build contract.

## Build and publish

Expand Down Expand Up @@ -49,6 +49,6 @@ context. It does not modify the working tree and does not regenerate
the checked-in lockfile must already be compatible with the requested
`SIGNIFY_TS_PACKAGE`.

For cross-repo validation, prefer a pushed GitHub SHA from the intended
For cross-repo W3C validation, prefer a pushed GitHub SHA from the intended
`signify-ts` branch over a `file:` dependency. That keeps browser, Docker, and
headless runs reproducible across machines.
54 changes: 51 additions & 3 deletions docs/smoke-tests.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Smoke Tests

The smoke tests are fast confidence checks for the Signify client boundary and
the React connection/contact paths. They are not full issuer/holder/verifier
tests and they intentionally do not depend on a schema server.
Most smoke tests are fast confidence checks for the Signify client boundary and
the React connection/contact paths. The W3C holder presentation smoke is the
exception: it attaches to a pre-seeded live issuer/holder/verifier stack and
validates the browser path against live services.

Use them before and after changes that touch:

Expand All @@ -29,6 +30,12 @@ pnpm contact:ui-smoke
pnpm contact:challenge-smoke
```

Holder W3C presentation smoke against a live pre-seeded stack:

```bash
pnpm w3c:holder-presentation:smoke
```

Run `pnpm keria:smoke -- --mode connect` first when debugging. It proves the
admin and boot APIs work without involving witnesses or browser automation.

Expand Down Expand Up @@ -61,6 +68,7 @@ The smoke-test stack has one shared smoke module and two executable wrappers.
| Browser wrapper | `tests/browser-smoke.ts` | Starts or reuses Vite, drives the React UI with Puppeteer, and verifies the client summary. |
| Contact OOBI smoke | `tests/contact-oobi-smoke.ts` | Resolves harness and witness OOBIs through the React Contacts UI and verifies operation/notification payload links. |
| Contact challenge smoke | `tests/contact-challenge-smoke.ts` | Exercises browser challenge generation, harness response, synthetic challenge notifications, detail response, and bell response. |
| W3C holder presentation smoke | `tests/w3c-holder-presentation-smoke.mjs` | Attaches Puppeteer to the React app, drives holder VRD presentation, and waits for live KERIA plus verifier-service evidence. |
| App runtime | `src/app/runtime.ts` | Shares connected Signify state between React Router loaders/actions and shell UI. |
| Boundary | `src/signify/client.ts` | Owns `ready()`, `randomPasscode()`, `SignifyClient` construction, boot/connect, state reads, and operation waiting. |
| Config | `src/config.ts` | Supplies shared defaults and environment overrides for browser and Node execution. |
Expand Down Expand Up @@ -230,6 +238,45 @@ This is intentionally longer than the basic browser smoke because it depends on
OOBI exchange, EXN indexing, contact inventory polling, and KERIA challenge
operation completion.

## W3C Holder Presentation Smoke

```bash
pnpm w3c:holder-presentation:smoke
```

This check attaches to an already-running W3C stack. It does not create or mock
the issuer/holder/verifier services. The stack must provide:

1. live KERIA with W3C enabled,
2. a seeded holder wallet passcode and alias,
3. a seeded native VRD credential that can be issued as an edge-built W3C
credential and materialized as an admitted holder credential,
4. live Python, Node, and Go verifier services exposing `/verify/vp` and
`/operations`,
5. a React app build using the intended `signify-ts` package or pinned Git SHA.

Common environment variables:

| Variable | Purpose |
| --- | --- |
| `W3C_HOLDER_SMOKE_URL` | Running React app URL. |
| `W3C_HOLDER_SMOKE_MANIFEST` | Seed/headless manifest with wallet and credential facts. |
| `W3C_HOLDER_PASSCODE` | Holder wallet passcode for the browser flow. |
| `W3C_HOLDER_ALIAS` | Holder identifier alias. |
| `W3C_CREDENTIAL_SAID` | Native VRD credential SAID selected for presentation. |
| `W3C_VERIFIER_REQUEST_JSON` | Single verifier request descriptor JSON. |
| `W3C_VERIFIER_REQUESTS_JSON` | Multiple verifier request descriptors keyed by service. |
| `W3C_PYTHON_VERIFIER_URL` | Python verifier host URL for evidence polling. |
| `W3C_NODE_VERIFIER_URL` | Node verifier host URL for evidence polling. |
| `W3C_GO_VERIFIER_URL` | Go verifier host URL for evidence polling. |

The smoke succeeds only when the issuer browser action builds and submits the
VC-JWT, KERIA validates and forwards the W3C credential to the holder, the
holder browser action builds and submits the VP-JWT, KERIA validates and
forwards the presentation to live verifier services, and verifier operations
reach terminal accepted state. Verifier test doubles, direct library calls, or
CLI-only commands are not acceptance evidence for this browser path.

## Configuration

The smoke tests use the same config as the app:
Expand All @@ -246,6 +293,7 @@ The smoke tests use the same config as the app:
| `BROWSER_SMOKE_URL` | `http://127.0.0.1:5173` | Browser smoke only. |
| `CONTACT_OOBI_SMOKE_URL` | `http://127.0.0.1:5176` | Contact OOBI browser smoke. |
| `CONTACT_CHALLENGE_SMOKE_URL` | `http://127.0.0.1:5177` | Contact challenge browser smoke. |
| `W3C_HOLDER_SMOKE_URL` | unset | W3C holder presentation smoke. |

Browser smoke calls local KERIA directly and requires KERIA CORS support to be
enabled, for example `KERI_AGENT_CORS=true`. Without that, browser preflight for
Expand Down
64 changes: 64 additions & 0 deletions docs/w3c-vrd-issuance-and-presentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# W3C VRD Issuance And Presentation

This guide covers the React app's holder-based W3C VRD path. It is for
maintainers debugging the UI, Effection workflows, and Signify/KERIA boundary.

## Ownership Model

- QVI issuer wallet starts W3C issuance from the native issuer-side VRD ACDC.
- The browser edge assembles and signs VC-JWT and VP-JWT artifacts through
`signify-w3c`.
- KERIA validates edge-provided artifacts, records durable state, forwards issuer
grants, and submits holder presentations to verifier endpoints.
- LE holder wallet presents only after it receives a W3C grant and KERIA
materializes exactly one eligible held W3C credential for the clicked source
credential.

## Issuance Flow

The `Start W3C issuance` control appears only for issuer-side VRD records that
the local wallet can issue as W3C VC-JWTs. It is a QVI-side manual fallback,
not an LE holder action.

The button is enabled only when:

- the credential schema is the supported VRD schema,
- the native credential state is issuer-active,
- the connected wallet controls the issuer AID,
- no conflicting credential command is already running.

`startW3CIssuanceService` calls `signify-did-webs` to ensure issuer did:webs
setup, then calls `signify-w3c` to create an issuance context, build and sign
the VC-JWT at the edge, submit the VC-JWT to KERIA for validation, and sign and
submit the issuer grant EXN. The workflow uses
`/identifiers/{issuer}/w3c/issuances`.

## Holder Presentation Flow

`presentCredentialService` calls `signify-did-webs` to ensure holder did:webs
setup, resolves the clicked source credential SAID to a held W3C credential,
builds and signs the VP-JWT through `signify-w3c`, then submits one request to
`/identifiers/{holder}/w3c/presentations`. KERIA validates the VP-JWT binding
to holder DID, selected credential, audience, nonce, response endpoint, and
wallet state before forwarding it to the verifier.

If presentation cannot resolve a held W3C credential, issue from the QVI first
and wait for the holder wallet to receive the W3C grant. Duplicate or missing
held W3C records are wallet state failures, not signing-request failures.

## Foreground Setup Behavior

W3C issuance and presentation are foreground user-driven credential operations.
They ensure did:webs setup at action time and do not use a session did:webs
SSE/polling worker, background W3C signing/import queues, or local holder
approval records.

## Validation

The holder-presentation smoke script uses Puppeteer against a running app and
live services. It is not a mock or fixture-only test. The script expects live
KERIA, a seeded holder wallet, a W3C credential path, and live Python, Node,
and Go verifier services.

Do not use a CLI verifier command or verifier test double as acceptance
evidence for this path.
21 changes: 21 additions & 0 deletions docs/workflow-state-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,27 @@ Current workflow groups:
multisig have dedicated workflow modules. Avoid placeholder workflow files:
add a real entry point when a domain operation has a caller and lifecycle.

## W3C Credential Flow

The W3C VRD path lives in the credential workflow:

- Domain helpers identify issuer-side and holder-side VRD credentials and choose
the local issuer or holder AID for the foreground action.
- `credentials.service.ts` uses `signify-did-webs` to ensure did:webs setup,
delegates VC-JWT and VP-JWT artifact assembly to `signify-w3c`, then submits
those edge-signed artifacts to KERIA.
- `credentials.op.ts` and runtime command wiring expose those service calls
through normal Effection operation tracking.
- `didwebs.op.ts` only refreshes projected did:webs DID state for display; it
does not own a session signing-request worker or service W3C queues.
- Redux stores only serializable summaries and operation results. It does not
store raw clients, private keys, verifier service objects, or W3C signing
approvals.

KERIA is the durable workflow source of truth and validator/forwarder. The
React app is the edge policy and signing runtime. If a W3C change makes KERIA
assemble or sign token material, it breaks the architecture.

## Redux State

Redux state is a serializable projection of workflow progress and domain
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"contact:challenge-smoke": "tsx tests/contact-challenge-smoke.ts",
"identifier-agent-oobi:smoke": "tsx tests/identifier-agent-oobi-smoke.ts",
"browser:smoke": "tsx tests/browser-smoke.ts",
"w3c:holder-presentation:smoke": "node tests/w3c-holder-presentation-smoke.mjs",
"responsive:smoke": "tsx tests/responsive-smoke.ts",
"unit:test": "vitest run tests/unit",
"multisig:test": "vitest run tests/scenarios/multisig.test.ts tests/scenarios/multisig-interaction.test.ts",
Expand Down
Loading
Loading