From 692aaf33dc09080c501908ea9bca3867bc3cf697 Mon Sep 17 00:00:00 2001 From: Justin Hernandez Date: Tue, 24 Mar 2026 13:42:19 -0700 Subject: [PATCH] update spec workflow to use repo-canonical two-layer model (#1865) * update skills * fixes and formatting --- .claude/skills/spec-from-audit/SKILL.md | 12 ++- CLAUDE.md | 30 +++--- app/AGENTS.md | 2 +- packages/mobile-sdk-alpha/AGENTS.md | 2 +- .../projects/sdk/workstreams/sdk-core/SPEC.md | 4 +- .../SC-03-selfclient-adapter-assembly.md | 34 +++---- .../projects/sdk/workstreams/webview/SPEC.md | 2 +- .../WV-07-selfclient-proving-assembly.md | 96 ++++++++++++------- .../plans/WV-08-tunnel-proving-flow.md | 69 ++++++------- 9 files changed, 140 insertions(+), 111 deletions(-) diff --git a/.claude/skills/spec-from-audit/SKILL.md b/.claude/skills/spec-from-audit/SKILL.md index ab0a600f0..67dca55d9 100644 --- a/.claude/skills/spec-from-audit/SKILL.md +++ b/.claude/skills/spec-from-audit/SKILL.md @@ -1,6 +1,6 @@ --- name: spec-from-audit -description: Generate one Linear spec document per issue — agent-executable implementation plans with file paths, validation commands, and acceptance criteria. +description: Generate one spec per issue — repo file (canonical) + Linear document (mirror). Agent-executable implementation plans with file paths, validation commands, and acceptance criteria. disable-model-invocation: false user-invocable: true argument-hint: '[issue IDs or path-to-audit-doc]' @@ -8,7 +8,7 @@ argument-hint: '[issue IDs or path-to-audit-doc]' # Spec from Audit -You take Linear issues (created by `/gaps-to-issues`) and generate one spec per issue as a Linear document. Each spec is an agent-executable implementation plan — a new Claude Code session with no prior context should be able to pick up the spec and produce a correct PR. +You take Linear issues (created by `/gaps-to-issues`) and generate one spec per issue. Each spec is written to the repo (`specs/`) as the canonical version, then mirrored to a Linear document for cross-tool access. A new Claude Code session with no prior context should be able to pick up the repo spec and produce a correct PR. ## Input @@ -35,9 +35,10 @@ Do not guess file contents — read them. Specs with wrong line numbers or stale ### Step 3: Generate Specs -For each issue, create a spec as a Linear document using `mcp__linear-server__create_document`. +For each issue, write the spec to **both** locations: -Link the document to the **issue** (not the project). +1. **Repo file** — Write to `specs/projects/sdk/workstreams//plans/-.md` using the Write tool. Determine `` from the workstream the issue belongs to (e.g., `webview`, `sdk-core`, `build-pipeline`). Always create or update the backlog row in the workstream's `SPEC.md` — if `SPEC.md` doesn't exist yet, create it. +2. **Linear document** — Create using `mcp__linear-server__create_document`, linked to the **issue** (not the project). This is the cross-tool access copy. **Title format:** `SPEC: ` @@ -133,4 +134,5 @@ Show the user: - If you discover the issue description is wrong (e.g., the code was already fixed), note this and ask the user whether to still create the spec or update the issue. - Specs are for agents, not humans. Write them as precise instructions, not explanatory documents. - The spec is the source of truth, not the issue body. Issue bodies are lightweight pointers — the spec must be fully self-contained. Do not assume the agent has read the issue description. -- Link specs to issues (not projects). Use `mcp__linear-server__create_document` with the `issue` parameter. +- The repo file (`specs/`) is the canonical version. The Linear document is a copy for cross-tool access. Both should have identical content. +- Link Linear documents to issues (not projects). Use `mcp__linear-server__create_document` with the `issue` parameter. diff --git a/CLAUDE.md b/CLAUDE.md index 6145b4e00..99006af34 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,22 +46,24 @@ nvm use && corepack enable && yarn install ## Specs & Planning -**Every feature — even minor ones — needs a spec.** Specs live in **Linear** as documents attached to issues. Do not create spec files in the `specs/` folder — that folder is deprecated and being migrated to Linear. +**Every feature — even minor ones — needs a spec.** For SDK work (`packages/`, `webview-app`, `webview-bridge`), specs live in **both** the repo (`specs/`) and Linear. The repo spec is the canonical, version-controlled execution plan. The Linear issue is the tracking and discovery layer. For app-only or non-SDK work, a Linear issue with inline scope is sufficient — no repo spec required. ### Where Specs Live -- **Specs → Linear documents**, attached to the relevant Linear issue (not the project) -- **Architecture context → `specs/projects/sdk/OVERVIEW.md`** (read-only reference, still in repo) -- **Audit docs → `docs/reviews/`** (PR audit findings, kept in repo for git history) -- **`specs/` folder** — deprecated. Existing specs are being migrated to Linear. Do not create new files here. +- **Execution specs → `specs/projects/sdk/workstreams//plans/-.md`** — version-controlled, agent-executable plans +- **Backlog → `specs/projects/sdk/workstreams//SPEC.md`** — durable context plus backlog table per workstream +- **Architecture context → `specs/projects/sdk/OVERVIEW.md`** — system architecture, bridge protocol, decision matrix +- **Audit docs → `docs/reviews/`** — PR audit findings, kept in repo for git history +- **Linear issues** — tracking, discovery, status. Link to the repo spec. Attach a Linear document copy for cross-tool access. ### Planning Protocol -1. **Read** this file's Key Rules and any relevant Linear issue/spec — understand the current state and constraints +1. **Read** this file's Key Rules and any relevant specs — understand the current state and constraints 2. **Create a Linear issue** if one doesn't exist — include scope, files modified, acceptance criteria -3. **Create a spec as a Linear document** attached to the issue — this is the execution plan -4. **Then implement** — one spec = one PR ≤2k LOC -5. **After completion:** Update the Linear issue status. Close when done. +3. **Write the spec** in `specs/` following the two-layer model (backlog row in `SPEC.md`, execution plan in `plans/`) +4. **Create a Linear document** attached to the issue with the spec content (so non-GitHub users can review) +5. **Then implement** — one spec = one PR (see PR size target in Key Rules) +6. **After completion:** Update the Linear issue status. Close when done. ### Spec-Writing Guidelines @@ -72,7 +74,7 @@ Specs are agent-executable prompts. A new Claude Code session with no prior cont - **Be explicit about constraints.** "You will NOT modify..." not just "Focus on..." - **Provide exact file paths with line numbers.** `src/utils/sumsubProvider.ts:118` not "the provider file." - **State the validation command.** Agents will run it. If it's not there, they'll skip validation. -- **One spec = one PR ≤2k LOC.** If a spec would produce >2k LOC, split it. +- **One spec = one PR.** Target the PR size from Key Rules (1k–3k LOC). If a spec would exceed that, split it. - **Mark items as required vs optional.** Don't let agents infer priority. - **Include out-of-scope sections.** These are as important as in-scope sections for preventing drift. - **Use `--remote` for medium+ work.** Medium and large specs benefit from `claude --remote` so work continues in the background. @@ -83,17 +85,17 @@ Three Claude Code skills automate the review-to-implementation pipeline: 1. **`/pr-audit`** — Multi-agent review (component + integration + routing), produces audit doc in `docs/reviews/` 2. **`/gaps-to-issues`** — Creates Linear issues from audit PR buckets -3. **`/spec-from-audit`** — Generates agent-executable specs as Linear documents, one per issue +3. **`/spec-from-audit`** — Generates agent-executable specs (repo file + Linear document), one per issue Run them in sequence with review pauses between each step. ### Why Specs - Prevents scope creep — writing "files NOT modified" forces focus -- Survives session loss — specs live in Linear, not session memory +- Survives session loss — specs live in the repo and Linear, not session memory - Enables parallel work — multiple agents can pick up specs from the same project -- Creates audit trail — what was planned vs what was built -- Enables cross-tool review — anyone with Linear access can review specs, not just GitHub users +- Creates audit trail — what was planned vs what was built (version-controlled in git) +- Enables cross-tool review — Linear documents let non-GitHub users review specs ## Validation Commands diff --git a/app/AGENTS.md b/app/AGENTS.md index 059fad1a4..96590eab9 100644 --- a/app/AGENTS.md +++ b/app/AGENTS.md @@ -291,4 +291,4 @@ See `.cursor/rules/test-memory-optimization.mdc` for comprehensive guidelines, e The Self Wallet app serves as a **test environment** for the SDK refactor. For SDK architecture context: - **[SDK Overview](../specs/projects/sdk/OVERVIEW.md)** — System architecture, bridge protocol, decision matrix (read-only reference) -- **Implementation specs** — Live in Linear as documents attached to issues. Check the relevant Linear issue for the current spec. Do not create spec files in `specs/` — that folder is deprecated. +- **Implementation specs** — Canonical source is `specs/projects/sdk/workstreams//plans/` (version-controlled). Linear documents attached to issues are mirrored copies for tracking/discovery. When in doubt, trust the repo spec. diff --git a/packages/mobile-sdk-alpha/AGENTS.md b/packages/mobile-sdk-alpha/AGENTS.md index 0305f1fc0..41511caa7 100644 --- a/packages/mobile-sdk-alpha/AGENTS.md +++ b/packages/mobile-sdk-alpha/AGENTS.md @@ -147,7 +147,7 @@ yarn build # Confirm build still works For architecture context: - **[SDK Overview](../../specs/projects/sdk/OVERVIEW.md)** — System architecture, bridge protocol, decision matrix (read-only reference) -- **Implementation specs** — Live in Linear as documents attached to issues. Check the relevant Linear issue for the current spec. Do not create spec files in `specs/` — that folder is deprecated. +- **Implementation specs** — Canonical source is `specs/projects/sdk/workstreams//plans/` (version-controlled). Linear documents attached to issues are mirrored copies for tracking/discovery. When in doubt, trust the repo spec. Before implementing SDK work, read `CLAUDE.md` Key Rules for constraints and validation commands. diff --git a/specs/projects/sdk/workstreams/sdk-core/SPEC.md b/specs/projects/sdk/workstreams/sdk-core/SPEC.md index e38d27e7f..b88cd109b 100644 --- a/specs/projects/sdk/workstreams/sdk-core/SPEC.md +++ b/specs/projects/sdk/workstreams/sdk-core/SPEC.md @@ -74,7 +74,7 @@ | ----- | ---------------------------------------------------------------------------- | ------ | -------- | ---------- | ------------------------------------------------------------------------------------------ | --- | | SC-01 | Consolidate bridge-layer fallback duplicates with engine-owned adapters | Done | High | - | [plans/SC-01-fallback-adapter-dedup.md](./plans/SC-01-fallback-adapter-dedup.md) | - | | SC-02 | Expose `generateKey()` and `getPublicKey()` in bridge crypto adapter surface | Done | Medium | SC-01 | [plans/SC-02-crypto-bridge-surface.md](./plans/SC-02-crypto-bridge-surface.md) | - | -| SC-03 | Extract reusable app adapter factories for SelfClient assembly | Done | Medium | SC-02 | [plans/SC-03-selfclient-adapter-assembly.md](./plans/SC-03-selfclient-adapter-assembly.md) | - | +| SC-03 | Extract reusable app adapter factories for SelfClient assembly | Done | Medium | SC-02 | [plans/SC-03-selfclient-adapter-assembly.md](./plans/SC-03-selfclient-adapter-assembly.md) | - | Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done` @@ -84,7 +84,7 @@ Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done` | ------------------------------------------------------------------------------------------ | ----- | ------ | | [plans/SC-01-fallback-adapter-dedup.md](./plans/SC-01-fallback-adapter-dedup.md) | SC-01 | Done | | [plans/SC-02-crypto-bridge-surface.md](./plans/SC-02-crypto-bridge-surface.md) | SC-02 | Done | -| [plans/SC-03-selfclient-adapter-assembly.md](./plans/SC-03-selfclient-adapter-assembly.md) | SC-03 | Done | +| [plans/SC-03-selfclient-adapter-assembly.md](./plans/SC-03-selfclient-adapter-assembly.md) | SC-03 | Done | ## Completion Checklist diff --git a/specs/projects/sdk/workstreams/sdk-core/plans/SC-03-selfclient-adapter-assembly.md b/specs/projects/sdk/workstreams/sdk-core/plans/SC-03-selfclient-adapter-assembly.md index 5be236583..61f2abb96 100644 --- a/specs/projects/sdk/workstreams/sdk-core/plans/SC-03-selfclient-adapter-assembly.md +++ b/specs/projects/sdk/workstreams/sdk-core/plans/SC-03-selfclient-adapter-assembly.md @@ -20,13 +20,13 @@ from the browser entry point. ### What the SDK provides -| Adapter | Factory | Location | Consumer | -| ------------------ | ----------------------------- | ------------------------------------------------------ | ------------- | -| Crypto (browser) | `createWebCryptoAdapter()` | `mobile-sdk-alpha/src/adapters/browser/crypto.ts` | webview-app | -| Crypto (RN) | `createCryptoAdapter()` | `mobile-sdk-alpha/src/adapters/react-native/crypto.ts` | RN app | -| Network (browser) | `createWebNetworkAdapter()` | `mobile-sdk-alpha/src/adapters/browser/network.ts` | webview-app | -| Network (RN) | `createNetworkAdapter()` | `mobile-sdk-alpha/src/adapters/react-native/network.ts`| RN app | -| Analytics | `createWebAnalyticsAdapter()` | `mobile-sdk-alpha/src/adapters/browser/analytics.ts` | webview-app | +| Adapter | Factory | Location | Consumer | +| ----------------- | ----------------------------- | ------------------------------------------------------- | ----------- | +| Crypto (browser) | `createWebCryptoAdapter()` | `mobile-sdk-alpha/src/adapters/browser/crypto.ts` | webview-app | +| Crypto (RN) | `createCryptoAdapter()` | `mobile-sdk-alpha/src/adapters/react-native/crypto.ts` | RN app | +| Network (browser) | `createWebNetworkAdapter()` | `mobile-sdk-alpha/src/adapters/browser/network.ts` | webview-app | +| Network (RN) | `createNetworkAdapter()` | `mobile-sdk-alpha/src/adapters/react-native/network.ts` | RN app | +| Analytics | `createWebAnalyticsAdapter()` | `mobile-sdk-alpha/src/adapters/browser/analytics.ts` | webview-app | ## What Was Done @@ -52,20 +52,20 @@ consumers can import it. ## Files Modified -| File | Change | Risk | -| ----------------------------------------------------------- | ---------------------------------------- | -------- | -| `packages/mobile-sdk-alpha/src/adapters/browser/network.ts` | **Created** — browser network factory | **Low** | -| `packages/mobile-sdk-alpha/src/adapters/browser/index.ts` | Added barrel export | **Low** | -| `packages/mobile-sdk-alpha/src/browser.ts` | Added re-export | **Low** | +| File | Change | Risk | +| ----------------------------------------------------------- | ------------------------------------- | ------- | +| `packages/mobile-sdk-alpha/src/adapters/browser/network.ts` | **Created** — browser network factory | **Low** | +| `packages/mobile-sdk-alpha/src/adapters/browser/index.ts` | Added barrel export | **Low** | +| `packages/mobile-sdk-alpha/src/browser.ts` | Added re-export | **Low** | ## Files NOT Modified -| File | Why | -| ----------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| File | Why | +| ----------------------------------------------------------- | ----------------------------------------------------------------------------------- | | `app/src/providers/selfClientProvider.tsx` | RN app keeps its own inline adapters — avoids accidental breakage in production app | -| `packages/webview-app/src/providers/SelfClientProvider.tsx` | webview-app wiring is WV-07 scope | -| `packages/mobile-sdk-alpha/src/client.ts` | `createSelfClient()` factory is correct as-is | -| `packages/webview-bridge/**` | Bridge adapters are a separate assembly path | +| `packages/webview-app/src/providers/SelfClientProvider.tsx` | webview-app wiring is WV-07 scope | +| `packages/mobile-sdk-alpha/src/client.ts` | `createSelfClient()` factory is correct as-is | +| `packages/webview-bridge/**` | Bridge adapters are a separate assembly path | ## Design Decision: Separate RN and Browser Adapter Paths diff --git a/specs/projects/sdk/workstreams/webview/SPEC.md b/specs/projects/sdk/workstreams/webview/SPEC.md index 7e780d46b..4dc6c303c 100644 --- a/specs/projects/sdk/workstreams/webview/SPEC.md +++ b/specs/projects/sdk/workstreams/webview/SPEC.md @@ -52,7 +52,7 @@ On **March 11, 2026**, the active SDK scope changed to **WebView only, with no c | WV-04 | Define the host callback contract for launch, dismiss, and final result without native modules | Done | Medium | WV-02 | [plans/WV-04-host-callback-contract.md](./plans/WV-04-host-callback-contract.md) | Browser host fallback now uses `postMessage` for iframe/popup embedding while native transports keep their current behavior | | WV-05 | Integrate KYC provider Web SDK into ProviderLaunchScreen (Sumsub as default) | In Progress | High | WV-02 | [plans/WV-05-sumsub-web-sdk.md](./plans/WV-05-sumsub-web-sdk.md) | Code complete on `feat/webview-sdk`, needs testing | | WV-06 | Wire KYC result through verification pipeline to host lifecycle callback | Ready | High | WV-05 | [plans/WV-06-kyc-result-flow.md](./plans/WV-06-kyc-result-flow.md) | Sumsub result → kycResultStore → ConfirmIdentificationScreen → lifecycle.setResult() | -| WV-07 | SelfClient assembly and proving machine export for WebView | Ready | High | SC-03 | [plans/WV-07-selfclient-proving-assembly.md](./plans/WV-07-selfclient-proving-assembly.md) | Export useProvingStore, map bridge→SDK adapters, keychain-backed documents, create real SelfClient | +| WV-07 | SelfClient assembly and proving machine export for WebView | Ready | High | SC-03 | [plans/WV-07-selfclient-proving-assembly.md](./plans/WV-07-selfclient-proving-assembly.md) | Export useProvingStore, map bridge→SDK adapters, keychain-backed documents, create real SelfClient | | WV-08 | Wire tunnel flow with real proving machine (register → disclose) | Ready | High | WV-07 | [plans/WV-08-tunnel-proving-flow.md](./plans/WV-08-tunnel-proving-flow.md) | Replace mock tunnel proving with real provingMachine: Sumsub → store doc → prove → disclose → result | Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done` diff --git a/specs/projects/sdk/workstreams/webview/plans/WV-07-selfclient-proving-assembly.md b/specs/projects/sdk/workstreams/webview/plans/WV-07-selfclient-proving-assembly.md index d80866502..73deb80d8 100644 --- a/specs/projects/sdk/workstreams/webview/plans/WV-07-selfclient-proving-assembly.md +++ b/specs/projects/sdk/workstreams/webview/plans/WV-07-selfclient-proving-assembly.md @@ -34,11 +34,17 @@ exports alongside the existing type-only exports: ```typescript // Existing (keep): -export type { ProvingStateType, provingMachineCircuitType } from './proving/provingMachine'; +export type { + ProvingStateType, + provingMachineCircuitType, +} from './proving/provingMachine'; // Add: export type { ProvingState } from './proving/provingMachine'; -export { useProvingStore, getPostVerificationRoute } from './proving/provingMachine'; +export { + useProvingStore, + getPostVerificationRoute, +} from './proving/provingMachine'; ``` Additive-only — no RN regression risk. @@ -53,15 +59,23 @@ boundary), not IndexedDB. Use the existing `secureStorage` bridge domain. ```typescript import type { WebViewBridge } from '../bridge'; -import type { DocumentsAdapter, DocumentCatalog, IDDocument } from '@selfxyz/mobile-sdk-alpha'; +import type { + DocumentsAdapter, + DocumentCatalog, + IDDocument, +} from '@selfxyz/mobile-sdk-alpha'; const CATALOG_KEY = 'self_document_catalog'; const DOC_PREFIX = 'self_doc_'; -export function createKeychainDocumentsAdapter(bridge: WebViewBridge): DocumentsAdapter { +export function createKeychainDocumentsAdapter( + bridge: WebViewBridge, +): DocumentsAdapter { async function storageGet(key: string): Promise { const result = await bridge.request<{ value: string | null }>( - 'secureStorage', 'get', { key }, + 'secureStorage', + 'get', + { key }, ); return result?.value ?? null; } @@ -121,7 +135,7 @@ import { bridgeAuthAdapter } from './auth'; import { createKeychainDocumentsAdapter } from './keychain-documents'; import { createWebAnalyticsAdapter, - createWebNetworkAdapter, // from SC-03 + createWebNetworkAdapter, // from SC-03 webNFCScannerShim, } from '@selfxyz/mobile-sdk-alpha/browser'; @@ -150,7 +164,9 @@ export function createSdkAdapters(opts: CreateSdkAdaptersOpts): Adapters { const navigation: NavigationAdapter = { goBack, goTo: (routeName, params) => { - const query = params ? `?${new URLSearchParams(params as Record)}` : ''; + const query = params + ? `?${new URLSearchParams(params as Record)}` + : ''; navigate(`/${routeName}${query}`); }, }; @@ -177,7 +193,10 @@ Replace the current `SelfClientAdapters` bag-of-adapters with a real `SelfClient` instance created via `createSelfClient()`. ```typescript -import { createSelfClient, createListenersMap } from '@selfxyz/mobile-sdk-alpha/browser'; +import { + createSelfClient, + createListenersMap, +} from '@selfxyz/mobile-sdk-alpha/browser'; import { createSdkAdapters } from '@selfxyz/webview-bridge/adapters'; // Replace SelfClientAdapters type with SelfClient from SDK @@ -185,7 +204,7 @@ import { createSdkAdapters } from '@selfxyz/webview-bridge/adapters'; // (they are WebView-specific and not part of SDK Adapters interface) export interface WebViewAdapters { - client: SelfClient; // real SDK client with provingMachine access + client: SelfClient; // real SDK client with provingMachine access lifecycle: BridgeLifecycleAdapter; haptic: BridgeHapticAdapter; biometrics: BridgeBiometricsAdapter; @@ -193,6 +212,7 @@ export interface WebViewAdapters { ``` The `SelfClient` instance gives webview-app access to: + - `client.useProvingStore` — Zustand hook for proving state - `client.getProvingState()` — snapshot accessor - `client.emit()` / `client.on()` — event system @@ -204,13 +224,13 @@ The `SelfClient` instance gives webview-app access to: Add packages externalized by the SDK's tsup build: -| Package | Version | Why | -|--------------------|---------|----------------------------------| -| `socket.io-client` | ^4.8.3 | TEE status WebSocket listener | -| `xstate` | ^5.20.2 | Internal state machine | -| `node-forge` | ^1.3.3 | AES-256-GCM encryption | -| `buffer` | ^6.0.3 | Node.js Buffer polyfill | -| `elliptic` | ^6.5.4 | Crypto ops via @selfxyz/common | +| Package | Version | Why | +| ------------------ | ------- | ------------------------------ | +| `socket.io-client` | ^4.8.3 | TEE status WebSocket listener | +| `xstate` | ^5.20.2 | Internal state machine | +| `node-forge` | ^1.3.3 | AES-256-GCM encryption | +| `buffer` | ^6.0.3 | Node.js Buffer polyfill | +| `elliptic` | ^6.5.4 | Crypto ops via @selfxyz/common | `zustand` and `@selfxyz/common` are already deps. @@ -233,7 +253,11 @@ Pass required config fields to `createSelfClient()`: ```typescript const client = useMemo(() => { - const adapters = createSdkAdapters({ bridge, navigate, goBack: () => navigate(-1) }); + const adapters = createSdkAdapters({ + bridge, + navigate, + goBack: () => navigate(-1), + }); const listeners = createListenersMap(); return createSelfClient({ config: { @@ -249,31 +273,31 @@ const client = useMemo(() => { ## Files You Will Create -| File | What | Risk | -|-----------------------------------------------------------|---------------------------------------------------|----------| -| `packages/webview-bridge/src/adapters/keychain-documents.ts` | Keychain-backed DocumentsAdapter via secureStorage | **Low** | -| `packages/webview-bridge/src/adapters/sdk-adapter-map.ts` | Bridge→SDK adapter mapping + factory | **Low** | +| File | What | Risk | +| ------------------------------------------------------------ | -------------------------------------------------- | ------- | +| `packages/webview-bridge/src/adapters/keychain-documents.ts` | Keychain-backed DocumentsAdapter via secureStorage | **Low** | +| `packages/webview-bridge/src/adapters/sdk-adapter-map.ts` | Bridge→SDK adapter mapping + factory | **Low** | ## Files You Will Modify -| File | Change | Risk | -|--------------------------------------------------------------|------------------------------------------------------|------------| -| `packages/mobile-sdk-alpha/src/browser.ts` | Add `useProvingStore`, `ProvingState` exports | **Low** | -| `packages/webview-bridge/src/adapters/index.ts` | Add barrel exports for new adapters | **Low** | -| `packages/webview-app/src/providers/SelfClientProvider.tsx` | Replace adapter bag with real SelfClient | **Medium** | -| `packages/webview-app/package.json` | Add 5 dependencies | **Low** | -| `packages/webview-app/src/main.tsx` | Add Buffer polyfill (2 lines) | **Low** | -| `specs/projects/sdk/workstreams/webview/SPEC.md` | Add WV-07 to backlog | **None** | +| File | Change | Risk | +| ----------------------------------------------------------- | --------------------------------------------- | ---------- | +| `packages/mobile-sdk-alpha/src/browser.ts` | Add `useProvingStore`, `ProvingState` exports | **Low** | +| `packages/webview-bridge/src/adapters/index.ts` | Add barrel exports for new adapters | **Low** | +| `packages/webview-app/src/providers/SelfClientProvider.tsx` | Replace adapter bag with real SelfClient | **Medium** | +| `packages/webview-app/package.json` | Add 5 dependencies | **Low** | +| `packages/webview-app/src/main.tsx` | Add Buffer polyfill (2 lines) | **Low** | +| `specs/projects/sdk/workstreams/webview/SPEC.md` | Add WV-07 to backlog | **None** | ## Files You Will NOT Modify -| File | Why | -|---------------------------------------------------------------|--------------------------------------------------------------| -| `packages/mobile-sdk-alpha/src/proving/provingMachine.ts` | Engine is already browser-compatible; no changes needed | -| `packages/mobile-sdk-alpha/src/client.ts` | `createSelfClient()` factory is correct as-is | -| `packages/native-shell-android/**` | secureStorage handler already exists and handles JSON values | -| `packages/native-shell-ios/**` | secureStorage handler already exists and handles JSON values | -| `packages/webview-app/src/screens/**` | Screen wiring is WV-08 scope | +| File | Why | +| --------------------------------------------------------- | ------------------------------------------------------------ | +| `packages/mobile-sdk-alpha/src/proving/provingMachine.ts` | Engine is already browser-compatible; no changes needed | +| `packages/mobile-sdk-alpha/src/client.ts` | `createSelfClient()` factory is correct as-is | +| `packages/native-shell-android/**` | secureStorage handler already exists and handles JSON values | +| `packages/native-shell-ios/**` | secureStorage handler already exists and handles JSON values | +| `packages/webview-app/src/screens/**` | Screen wiring is WV-08 scope | ## Constraints diff --git a/specs/projects/sdk/workstreams/webview/plans/WV-08-tunnel-proving-flow.md b/specs/projects/sdk/workstreams/webview/plans/WV-08-tunnel-proving-flow.md index 5f9e6e025..996cfeccb 100644 --- a/specs/projects/sdk/workstreams/webview/plans/WV-08-tunnel-proving-flow.md +++ b/specs/projects/sdk/workstreams/webview/plans/WV-08-tunnel-proving-flow.md @@ -76,20 +76,20 @@ export const TunnelProvingScreen: React.FC = () => { **State → UI mapping:** -| provingMachine state | UI shown | -|--------------------------|--------------------------------------------------| -| `idle` | Loading spinner | -| `parsing_id_document` | "Preparing document..." | -| `fetching_data` | "Fetching verification data..." | -| `validating_document` | "Validating document..." | -| `init_tee_connexion` | "Connecting to prover..." | -| `ready_to_prove` | "Ready" (auto-confirm or user confirms) | -| `proving` | "Generating proof..." (with Euclid animation) | -| `post_proving` | "Finalizing..." | -| `completed` | Navigate to result screen (success) | -| `error` / `failure` | Navigate to result screen (error with code) | -| `passport_not_supported` | Show unsupported document error | -| `passport_data_not_found`| Show missing document error | +| provingMachine state | UI shown | +| ------------------------- | --------------------------------------------- | +| `idle` | Loading spinner | +| `parsing_id_document` | "Preparing document..." | +| `fetching_data` | "Fetching verification data..." | +| `validating_document` | "Validating document..." | +| `init_tee_connexion` | "Connecting to prover..." | +| `ready_to_prove` | "Ready" (auto-confirm or user confirms) | +| `proving` | "Generating proof..." (with Euclid animation) | +| `post_proving` | "Finalizing..." | +| `completed` | Navigate to result screen (success) | +| `error` / `failure` | Navigate to result screen (error with code) | +| `passport_not_supported` | Show unsupported document error | +| `passport_data_not_found` | Show missing document error | ### 3. Wire disclose flow after register @@ -163,31 +163,31 @@ tunnel flow. ## Files You Will Modify -| File | Change | Risk | -|----------------------------------------------------------------------------|-------------------------------------------------|------------| -| `packages/webview-app/src/screens/tunnel/TunnelProvingScreen.tsx` | Replace mock with real provingMachine | **Medium** | -| `packages/webview-app/src/screens/tunnel/TunnelResultScreen.tsx` | Wire real result from proving state | **Low** | -| `packages/webview-app/src/screens/tunnel/TunnelProofReceiptScreen.tsx` | Wire user confirmation to provingMachine | **Low** | -| `packages/webview-app/src/App.tsx` | Update tunnel routes if needed | **Low** | -| `specs/projects/sdk/workstreams/webview/SPEC.md` | Add WV-08 to backlog | **None** | +| File | Change | Risk | +| ---------------------------------------------------------------------- | ---------------------------------------- | ---------- | +| `packages/webview-app/src/screens/tunnel/TunnelProvingScreen.tsx` | Replace mock with real provingMachine | **Medium** | +| `packages/webview-app/src/screens/tunnel/TunnelResultScreen.tsx` | Wire real result from proving state | **Low** | +| `packages/webview-app/src/screens/tunnel/TunnelProofReceiptScreen.tsx` | Wire user confirmation to provingMachine | **Low** | +| `packages/webview-app/src/App.tsx` | Update tunnel routes if needed | **Low** | +| `specs/projects/sdk/workstreams/webview/SPEC.md` | Add WV-08 to backlog | **None** | ## Files You Will NOT Modify -| File | Why | -|---------------------------------------------------------------|--------------------------------------------------------| -| `packages/mobile-sdk-alpha/src/proving/provingMachine.ts` | Engine unchanged — consumed as-is | -| `packages/webview-bridge/**` | Bridge layer unchanged — WV-07 already handled mapping | -| `packages/native-shell-android/**` | No new native handlers needed | -| `packages/native-shell-ios/**` | No new native handlers needed | -| `packages/webview-app/src/screens/proving/ProvingScreen.tsx` | Non-tunnel proving screen — separate concern | -| `packages/webview-app/src/providers/SelfClientProvider.tsx` | Already wired in WV-07 | +| File | Why | +| ------------------------------------------------------------ | ------------------------------------------------------ | +| `packages/mobile-sdk-alpha/src/proving/provingMachine.ts` | Engine unchanged — consumed as-is | +| `packages/webview-bridge/**` | Bridge layer unchanged — WV-07 already handled mapping | +| `packages/native-shell-android/**` | No new native handlers needed | +| `packages/native-shell-ios/**` | No new native handlers needed | +| `packages/webview-app/src/screens/proving/ProvingScreen.tsx` | Non-tunnel proving screen — separate concern | +| `packages/webview-app/src/providers/SelfClientProvider.tsx` | Already wired in WV-07 | ## Files You May Create -| File | What | -|-----------------------------------------------------------------------|---------------------------------------------------| -| `packages/webview-app/src/hooks/useProvingFlow.ts` | Optional: shared hook for register→disclose chain | -| `packages/webview-app/src/screens/tunnel/TunnelProviderScreen.tsx` | If tunnel needs its own Sumsub launch screen | +| File | What | +| ------------------------------------------------------------------ | ------------------------------------------------- | +| `packages/webview-app/src/hooks/useProvingFlow.ts` | Optional: shared hook for register→disclose chain | +| `packages/webview-app/src/screens/tunnel/TunnelProviderScreen.tsx` | If tunnel needs its own Sumsub launch screen | ## Constraints @@ -211,7 +211,8 @@ tunnel flow. Construct it directly from Sumsub's attestation: ```typescript const kycData: KycData = { - documentType: deserializeApplicantInfo(attestation.serializedApplicantInfo).idType, + documentType: deserializeApplicantInfo(attestation.serializedApplicantInfo) + .idType, documentCategory: 'kyc', mock: false, signature: attestation.signature,