小程序 / Taro / 微信小程序 / 支付宝小程序 / 抖音小程序 / 小程序上线审核 → implement, debug, test, and ship mini-program client features: pages, state, API integration, auth, sharing, platform capabilities, review, and device verification. Triggers also include \"重构这个小程序页面/组件(局部)\", \"refactor a mini-program page/component\".
Scanned 9/2/2026
Install to Claude Code
npx -y skills add ccoalm/ccl-skills --skill miniapp-product-dev --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Miniapp Product Dev?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ccoalm-miniapp-product-dev)More formats (shields.io, HTML) on the badges page.
---
name: miniapp-product-dev
description: "小程序 / Taro / 微信小程序 / 支付宝小程序 / 抖音小程序 / 小程序上线审核 → implement, debug, test, and ship mini-program client features: pages, state, API integration, auth, sharing, platform capabilities, review, and device verification. Triggers also include \"重构这个小程序页面/组件(局部)\", \"refactor a mini-program page/component\"."
---
# Miniapp Product Dev
Use this skill for mini-program client engineering and platform delivery. It covers product-facing miniapp work across WeChat, Alipay, Douyin/TikTok, Baidu, and similar host platforms. It does not own general product strategy, backend service architecture, or visual design rules.
## Framework Scope
Primary framework target: **Taro** (React-based multi-platform mini-program framework). Apply this skill's recipes assuming Taro unless the task states otherwise.
Adjacent frameworks recognized but not the default target:
- **uni-app / Remax / kbone / mpvue**: recipes here usually apply with framework-equivalent substitutions; verify before assuming behavior.
- **Native WeChat / Alipay / Douyin / Baidu mini-program**: host-platform contracts (config, capabilities, review, release) carry over; framework-specific code mechanics (JSX/hooks vs WXML/WXSS, lifecycle hooks, runtime APIs) require native-platform substitution.
- **Embedded H5 inside a mini-program webview**: this skill owns the mini-program shell, bridge contract, host capabilities, and review/release evidence; the H5 React/Vue page belongs to `web-react-dev` (or the relevant web skill).
If the team adopts a non-Taro framework as a new primary, the skill scope must be re-declared rather than letting Taro recipes silently apply to mismatched runtimes.
For evaluating whether Taro is the right choice for a given project (vs native, uni-app, Remax/kbone, or splitting per-platform), read `references/framework-choice.md`. Taro is the current default but not a permanent decision — re-evaluate when the project's target-platform set, design-system divergence, or maintenance signals change materially.
## Maturity Baseline
The current baseline is **vendor-spec + framework-canonical**, not `mature confirmed`: host-platform guidelines, Taro documentation/examples, and canonical Taro UI libraries (taroify, NutUI-Taro, tdesign React mapping). No production-quality miniapp portfolio has been observed end-to-end. Apply positive rules as defaults and anti-patterns as guardrails, and mark them `confirmed` only after a correction-free real feature delivery.
**Existing team codebases** do not automatically supply positive rules: production use proves distribution, not quality. Until audited end-to-end against this skill or piloted through one real feature with a `skill-extraction-workflow` retrospective, label them `quality-unverified` per `references/source-evidence-map.md`. Use this skill from the start and feed lessons back through extraction, not silently copy patterns.
## Runtime Compatibility
This skill is shared by OpenCode, Codex, and Claude Code. Keep instructions tool-agnostic: prefer repository-local scripts, platform developer tools, CLI commands, simulator evidence, screenshots, and explicit manual checks over host-specific features. When a tool is unavailable, record the missing evidence and use the closest deterministic check instead of pretending the platform was verified.
## Routing
- Use `product-rd-workflow` first when the work spans product intent, design, service contracts, implementation, test, review, release, and follow-up.
- Use `product-ui-ux-design` before or alongside coding for visible page structure, interaction model, density, empty/error/loading states, trust copy, accessibility, and launch acceptance.
- Use `../product-ui-ux-design/references/multi-stack-strategy.md` and `../product-ui-ux-design/references/multi-project-token-consistency.md` when the mini-program is one of several client stacks under one brand (web desktop + H5 + native app + mini-program). Cross-end brand alignment (color tokens, typography, voice/tone, terminology, navigation labels, trust copy) is owned there, not here. This skill enforces the host-platform constraints on top of those tokens. For the **scope** of what must align across web + app + mini-program (beyond just theme and logo — including auth/onboarding copy, error vocabulary, payment confirmations, privacy disclosures, share/QR payload schema, deep-link routes), read `references/cross-stack-alignment.md`.
- Use `web-react-dev` for the React layer when Taro shares code with a React web project (see Sibling Boundary below).
- Use backend architecture/dev skills for API contracts, auth services, payment callbacks, subscriptions, persistence, async jobs, and admin/ops surfaces.
- For backend HTTP integrations, preserve current client wire behavior unless an explicit consumer-migration decision exists. Classify JSON vs protobuf-backed HTTP using `../platform-service-connectivity/references/protobuf-http-contract-signals.md`.
- First decide whether the client diff touches the HTTP contract or wire behavior. Wire-unchanged page/component/state work does not need a backend owner round-trip and must not claim backend contract conformance.
- For unrelated client work, classify the diff with the canonical gate. If the surface is out of scope, client work may continue without claiming backend contract conformance.
- If the canonical gate classifies the diff as in scope, confirm the backend's recorded wire format or route back to the backend contract owner.
- Routine JSON/OpenAPI changes use the existing API contract record and do not require backend wire-format confirmation when the canonical reference classifies the surface as out of the protobuf wire-format gate.
- Mini-program request wrappers must consume the backend contract's recorded response envelope per `../platform-service-connectivity/references/http-response-envelope-contract.md`: for surfaces on the canonical `code`/`message`/`data` envelope, page/component state reads typed business data from `data`; other shipped or non-JSON envelopes are consumed per their recorded contract. Read only fields present in the recorded contract — do not infer business fields from unrecorded top-level or fallback shapes — and scatter no duplicate envelope parsing across the client.
- If backend wire-format evidence is unreachable for an in-scope surface, stop at `pending-contract-owner`, name the backend owner or owning repo, record the attempted lookup, and set the next escalation path. An assumed-wire-format note never unblocks merge. The blocker clears only when a checkable owner record, quoted prior backend record, or explicit migration decision is available; if no owner responds within the team's review SLA, keep the client change blocked or downscope the touched wire-format surface and record the dropped surface as an open owner-routed gap. Do not claim backend contract conformance or completion for the removed slice.
- Do not fork IDL or hand-maintain duplicated DTOs in the mini-program repo.
- Use `testing-strategy` to choose unit, component, integration, miniprogram automation, E2E, manual device, and release verification layers.
- Use `test-artifact-management` when the ask is about generating structured test cases from a Feishu requirements doc or codebase and tracking them in Feishu Bitable before implementation begins.
- Use `defect-diagnosis` first for crashes, failed builds, platform review rejection, flaky device behavior, auth/payment/share failures, or production symptoms.
- Use `feature-risk-router` when the slice touches money, login/identity, user data, permissions, generated/AI content, write finality, platform review policy, or release risk.
- Use `skill-extraction-workflow` to feed learnings from real mini-program work back into this skill (or a sibling) — corrections, repeated defects, online-practice uptake, pilot retrospectives. New mini-program work runs through this skill from the start. Recorded extraction passes are necessary evidence for upgrading the maturity baseline, but the full upgrade-path criteria (real feature delivery cycle, host-platform review pass, cross-stack alignment confirmation, correction RCA per defect — see `references/source-evidence-map.md` → "Upgrade Path to `mature confirmed`") all apply; implementation hours alone do not move the baseline. Do not silently mine an older, quality-unverified team codebase for positive rules; route observations through the extraction workflow with the right evidence label (see `references/source-evidence-map.md` → "Team-owned mini-program portfolio").
## Lifecycle and Neighboring Skills
How this skill sits inside the broader delivery loop for a mini-program feature. Each stage names its **owning skill** and what this skill receives from / hands off to it.
| Stage | Owner | What flows into this skill | What this skill hands back |
|---|---|---|---|
| Risk classification | `feature-risk-router` | Risk tags (money / identity / privacy / write finality / generated content / host capability), required gates | Confirmation that the gate set covers mini-program-specific risks (review policy, host capability, finality across host pay) |
| Product / cross-stage delivery | `product-rd-workflow` | Product intent, scope, service contract, release plan | Mini-program-specific delivery considerations (multi-target shipping set, host review timeline, gray release lever choice) |
| Design (visual, interaction, copy, states) | `product-ui-ux-design` | Design source (Figma), tokens, state enumeration, copy / voice, accessibility criteria; cross-stack alignment is owned in `../product-ui-ux-design/references/multi-stack-strategy.md` + `../product-ui-ux-design/references/multi-project-token-consistency.md` | Mini-program platform constraints on top of the design (safe-area, host gesture, capability denial states, host-native affordance), screenshot acceptance per shipped host |
| Implementation — React layer + pure shared | `web-react-dev` | Component decomposition, hooks, state ownership, effect discipline, pure shared DTOs / validators / mapping | Mini-program contract on co-owned runtime adapters (auth epoch tuple, request cancellation, storage manifest, finality / idempotency, kill-switch, trace propagation) — enforced via the named co-owned-adapter owner + miniapp-contract tests (see "Sibling Boundary With web-react-dev" → shared-runtime-adapter row for the full gate) |
| Implementation — mini-program runtime | **This skill** | Taro lifecycle, host APIs, platform branching, subpackage, capability adapters, multi-target build, review-safe copy | — |
| Implementation — backend services | Go / Python service skills + `llm-inference-integration` | API contracts, server idempotency by `(principal, tenant, action, business-key, fingerprint)`, payment reconciliation, share-token issuance, signed capability grants, server-side feature flags | This skill consumes those contracts. If the backend cannot supply a contract that a **specific** mini-program flow needs (server-business-key idempotency / bounded reconciliation / signed grants / fail-closed flag), route the **block-or-downscope** decision through `feature-risk-router` + `product-rd-workflow` with backend owner evidence — the legitimate exits are remove the risky capability, ship a read-only or non-finality subset, record a deferred-gate row with a tracking ticket, or block. Do not strand the work without an owner. |
| Implementation — native / cross-platform app | `app-cross-platform-dev` | App-side equivalent surfaces (when the same product also ships native); used for cross-stack alignment cross-checks | — (mini-program is a separate host) |
| Test strategy | `testing-strategy` | Layer choice (unit / component / API contract / mini-program automation / E2E / manual device / release smoke), scenario matrix | Mini-program-specific evidence requirements (one host compile is not multi-host pass; developer-tool compile is structural only; per-shipped-target real-device evidence is blocking) |
| Debugging / production symptom | `defect-diagnosis` | Reproduction discipline, 5-Why root cause, regression closure | Mini-program-specific repro paths (developer tool, real device, host version matrix, share/scene param) |
| Release / review submission / rollback | **This skill** (`references/qa-release.md`) | Per-host evidence matrix, server-flag kill-switch runbook, current platform-policy doc URL + date | — |
| Post-ship learning capture | `skill-extraction-workflow` | RCA framing, source-evidence labels, dual-track review/challenge gates, sibling-skill mini-map | Updates to this skill's rules, `Do Not` list, references; upgrade-path progress toward `mature confirmed`; recurring anti-pattern entries |
Treat the loop as: **risk-route → product/design → develop (this skill + web/backend) → test → release → debug → extract back**. Skipping the extract-back step is how a team accumulates implementation hours without the skill ever maturing.
Repo-local agent contracts (`AGENTS.md` at the repo root and in source directories) are part of the delivery contract: when a change moves a stable boundary, generated surface, workflow, or directory-local rule, update the nearest contract in the same MR and keep coverage in sync per `product-rd-workflow`'s spec / repo-contract sync gate.
When checking a mini-program project against team standards, split conformance into deterministic and agent review evidence. Deterministic checks cover project config, target/platform build commands, subpackage config, generated API/IDL client usage, environment/lane config, TC traceability, CI gates, and required request/trace identifiers in central request wrappers. Agent review checks cover page/component boundaries, host capability contracts, shared adapter safety, finite-value mapping, multi-target release risk, and whether tests/device evidence cover the shipped targets. For the deterministic executor list and the mini-program ESLint config enforcing the two host-boundary invariants (the `react-dom`/DOM-global ban and `TARO_ENV` adapter-layer confinement — ESLint config, not a regex source-scan), see `testing-strategy/references/fitness-functions.md` §4.1.3 (spec 006).
## Sibling Boundary With web-react-dev
Taro is React syntax compiled to mini-program runtime; a Taro project typically shares a substantial portion of code with a React web project in the same monorepo. Without an explicit boundary, ownership of state hooks, API clients, and shared components drifts.
| Layer | Owner | Notes |
| --- | --- | --- |
| React component structure, hooks, JSX, TSX types | `web-react-dev` | Component decomposition, state lifting, effect discipline are the same rules. |
| Pure shared layer (DTOs, types, validators, pure mapping) | `web-react-dev` (monorepo pkg-shared) | No platform branches; no I/O. |
| Shared runtime adapters consumed by mini-program targets (request client, auth state machine, storage namespace, finality/idempotency wrapper, observability transport) | **Co-owned with a named final-decision owner** (one engineer per adapter, recorded in repo). `web-react-dev` sets browser semantics; this skill's contract — full session-epoch tuple fencing, request cancellation across route switch, storage namespacing + manifest + historical-prefix purge, sensitive-field handling, late-callback fencing, server-business-key idempotency, pending-reconciliation with bounded timeout on cold start / page-show / re-login, support-id propagation, kill-switch dimensions, trace propagation — is a **blocking acceptance gate** before mini-program targets import the adapter. Web may not merge an adapter change that is browser-safe but mini-program-unsafe; the gate's miniapp-contract tests must pass first — the merge record must carry the fixed token `gate: miniapp-product-dev SKILL.md Sibling Boundary → shared runtime adapters row` plus a passing miniapp-contract run recorded on the change under merge. |
| Shared design tokens / theme | `product-ui-ux-design` + per-stack injection | Tokens flow from the design source; injection mechanics per `multi-project-token-consistency.md`. |
| Component library choice (Taroify, NutUI-Taro, tdesign-miniprogram) | **Co-owned** with `product-ui-ux-design`: design owns UX / token / accessibility / brand-fit criteria; this skill owns runtime fit (package size, host-platform compatibility, framework version compatibility, build pipeline integration). Both signoffs required. See `references/framework-choice.md` → "What this skill does NOT decide" and `../product-ui-ux-design/references/multi-stack-strategy.md` for the design source of truth check. |
| Taro lifecycle (`useReady`, `useLoad`, `useDidShow`, `useDidHide`) | This skill | Page lifecycle differs from React DOM lifecycle. |
| `Taro.*` runtime APIs (`Taro.request`, `Taro.login`, `Taro.navigateTo`, `Taro.getStorage`, etc.) | This skill | Use the repo's existing adapter when one exists; introduce an adapter for shared or high-risk surfaces (request, auth, payment, storage, host capability). Do not call host APIs ad hoc from arbitrary components. |
| Platform branching (`process.env.TARO_ENV`, conditional compilation, platform-specific files) | This skill | Branching at the adapter/wrapper layer, not sprinkled in render code. |
| Subpackage config, preloading, package size budget | This skill | Mini-program-only concept. |
| Host capabilities (login, pay, share, subscribe message, scan, location, file, scope) | This skill | Capability detection, denial/cancel/timeout/recovery states. |
| Mini-program app/page config files (`app.config.ts`, `page.config.ts`, platform-specific `project.config.json`) | This skill | Versioning, route registration, tab/subpackage layout, permissions declaration. |
| Build target, `taro build --type weapp/alipay/tt/swan`, CI matrix | This skill | One target compiling does not prove other targets pass. |
| Host-platform review submission, gray release, real-device evidence | This skill | Not a web concern. |
| H5 build target inside a Taro multi-target project | `web-react-dev` for the H5 output's React/browser concerns; this skill stays out unless the H5 is embedded back inside a mini-program webview. |
Cross-checking rule: when editing code shared with a React web project, also check the relevant React rule in `web-react-dev` (state ownership, effects, accessibility, observability). When the code is mini-program-only (config, host API, platform branch), this skill is authoritative.
## Core Workflow
Before editing Taro/native mini-program code, page config, host capability adapters, platform project files, styles, assets, or tests, complete enough analysis and planning for the change to be reviewable. Scale the plan to risk: a simple low-risk single-page change can use a short inline plan; multi-target, API-visible, host-capability, platform-review/release, bug-fix, branch/MR, unclear-risk, or high-risk work needs explicit task split, host/target verification matrix, acceptance checks, verification commands, rollback or stop conditions, and named handoffs to testing, web/app, backend, release, or diagnosis skills before edits. Runtime-visible work consumes the canonical Design brief and Test Phase 0 before implementation.
1. Resolve the miniapp platform and delivery shape.
- Host platform target(s): WeChat, Alipay, Douyin/TikTok, Baidu, or several at once. Multi-target = a separate verification matrix; one target compiling is not proof another target passes.
- Framework: confirm Taro as the project's framework (default for this skill). If the repo is native, uni-app, Remax, kbone, or mpvue, apply this skill's recipes with framework-equivalent substitutions and call out the substitution in the change description.
- For Taro: confirm Taro major version, React version, build target list (`taro build --type weapp/alipay/tt/swan/h5/rn`), and which targets are actually shipped vs. listed-but-unverified.
- Target: new page, tab, component, package/subpackage, plugin, webview bridge, or platform capability.
- Release channel: developer tools preview, experience build, gray release, full release, or platform review submission.
2. Analyze the existing client surface before editing.
- Locate page ownership, route registration, tab/subpackage config, app/global state, API client, storage wrapper, auth/session owner, analytics wrapper, and tests.
- For Taro: locate `app.config.ts` / `app.config.js` (route + tab + subpackage + permission registration), per-page `*.config.ts`, `config/index.ts` (build config), `project.config.json` / `project.private.config.json` (WeChat target), `project.alipay.json` (Alipay target), `project.tt.json` (Douyin target) and similar per-target project config files, and the Taro plugin pipeline. `mini.project.json` is the native-Alipay project config, not the Taro Alipay project config.
- For native miniapp: WeChat uses `app.json` + `project.config.json` + `sitemap.json` + `ext.json` (plugin/extension); Alipay uses `app.json` + `mini.project.json`; Douyin/Baidu use their own platform project files. `manifest.json` + `pages.json` is uni-app shape, not native; only include it when the repo is uni-app. Also inspect package config, build scripts, and CI jobs as applicable.
- Identify platform-branching code paths: `process.env.TARO_ENV` checks in Taro, conditional compilation blocks, or platform-specific files (`*.weapp.tsx`, `*.alipay.tsx`). Confirm branching lives at the adapter/wrapper layer, not in render code.
- Identify whether the change must be shared, forked, or guarded by capability detection.
- For every visible UI change, load `../product-ui-ux-design/references/delivery-contract.md` and consume either its full Design brief + Phase 0 or its valid low-risk copy-only record + lightweight Phase 0 before coding. The lightweight path checks semantics, accessible name, localization, rendered extent, and target-host render without inventing unrelated matrices; risk-bearing copy uses the full path. For full slices, map structure, state/adaptation matrices, behavior and criteria to pages/host adapters; record route/back/share entry, hosts, capabilities, recovery geometry, and preserved behavior. A mini-program `web-view` has a host member here and a separate web-content owner member; browser/H5-only preview satisfies neither the shipped-host bridge nor the complete owner set.
- Before the first implementation edit, add the canonical `client_entry` defined there: local rule identifier or short quote and implementation decision, target surface/runtime, planned run/capture command, and behavior that must remain unchanged.
3. Define the miniapp contract before coding.
- Pages, route params, tab ownership, back behavior, deep links, scene/query entry, and share/open-from-chat behavior. Treat every scene/share/QR param as untrusted input: schema-parse it, server-authorize the referenced target against the current identity, and require backend-issued, TTL-bounded, replay-protected share tokens for attribution or unlock flows. Client-side attribution is never the final source of truth.
- API request contract, auth/session renewal, request cancellation or de-dupe, error envelope mapping, retry policy, and trace/request id propagation. Auth must run through a single state machine with single-flight token refresh, a session/user-identity epoch, and stale-callback fencing — concurrent pages must not both silently re-login and overwrite each other's session.
- Finite-value boundary: generated API enums, backend string codes, scene/share/QR params, storage values, analytics dimensions, and host bridge payload codes should flow through one typed client/domain mapping module. Pages/components should use mapped symbols and label tables instead of scattering raw values such as `"US"`, `"CN"`, `"active"`, or `"default"` across render, storage, routing, or tracking code. If shared client-domain ownership is unclear, keep a local mapper for the slice, mark temporary duplicate/raw uses with `finite-value-debt: <task-ref> <owner> <deadline> <reason>`, and record the consolidation owner. Architecture owns the cross-stack semantic decision when the same value must align across mini-program, web, app, backend, storage, and analytics.
- Storage scope: local storage keys, TTL, sensitive data handling, migration, logout/account-delete cleanup, and stale-cache recovery.
- Capability contracts: login, user profile, phone number, location, camera, album, file, scan, payment, subscribe message, share, webview, Bluetooth/NFC, clipboard, and open settings.
- Analytics: page exposure, entry scene, click/submit, funnel, error, performance, and release version dimensions.
- High-risk finality: **server-enforced** idempotency (business-key dedupe on the backend) is the primary defense; UI duplicate-submit lock is secondary, never the only line. Persist pending order/request id **before** invoking the host-platform action (pay, scan, submit). On cold start / page show / re-login, reconcile pending state against the backend **before** enabling a new attempt. Treat local `cancel` as non-final until the backend reconciliation confirms it — async callbacks can flip cancel → success after the user moved on.
4. Implement with platform constraints visible.
- Keep page render code thin; isolate data loading, command handling, mapping, validation, and platform adapters.
- Keep platform APIs behind local wrappers when the repo already has them. Do not call host APIs (`Taro.request`, `Taro.login`, `Taro.requestPayment`, `wx.*`, `my.*`, etc.) ad hoc from arbitrary components.
- For Taro: confine `process.env.TARO_ENV` and conditional-compilation branches to adapter/wrapper modules. Render components should consume capability-flags or platform-specific files (`*.weapp.tsx`, `*.alipay.tsx`), not branch on `TARO_ENV` inline.
- For Taro: do not import `react-dom` or call real browser-only APIs (`document.*` mutation, `window.*` mutation, `requestAnimationFrame`, `IntersectionObserver`/`ResizeObserver`/`MutationObserver`, browser layout APIs) into code that compiles to a mini-program target. Use Taro's cross-platform equivalents (`Taro.createSelectorQuery`, `Taro.nextTick`, lifecycle hooks). Taro 3 ships an emulated DOM that tolerates some neutral usage, but treat real-browser-only APIs as H5-only and isolate them behind the `h5` target (`*.h5.tsx`, capability adapter, or `process.env.TARO_ENV === 'h5'` in adapter code).
- For Taro: own durable page/component state in the repo's chosen state owner (Zustand, Jotai, MobX, Redux Toolkit, React Context, TanStack Query, or an existing custom store as appropriate) rather than `Taro.eventCenter`. `eventCenter` is fine for navigation handoff payloads and simple lifecycle events between sibling pages; do not use it as the canonical store for durable, multi-page state. Always register listeners with cleanup in `useDidHide` / `useUnload` / effect teardown.
- Respect miniapp package limits, subpackage loading, preloading, image/font budgets, cold-start performance, and first-screen loading. For Taro, every subpackage page must be declared in `app.config.ts` `subPackages`; otherwise `Taro.navigateTo` / `Taro.switchTab` to it fails at runtime. Subpackage preload (`preloadRule` / `Taro.preloadSubpackage`) is a performance optimization, not a navigation prerequisite — verify routing works without preload and that the loading/transition state is acceptable, then add preload as needed.
- Route-API correctness is a static rule, not a runtime hope: `tabBar.list` pages must live in the main package and only `Taro.switchTab` may target them; subpackage pages are reached via `Taro.navigateTo` / `redirectTo` / `reLaunch`; `switchTab` to a non-tab page or `navigateTo` to a tab page fails silently or at runtime. Wrap routing in a typed helper that knows each page's route class. Model the cold subpackage-download path (network slow / failed): show loading, handle `fail` callback, allow retry and back fallback — do not let the user stare at a frozen tap.
- Model permission denial, permanent denial, settings handoff (`Taro.openSetting` / native equivalent), capability unavailable, offline/weak network, background/foreground restore, and host-version incompatibility.
- Keep copy and UI states review-safe for platform policy: privacy prompts, user authorization, payments, ads, medical/financial/legal-sensitive wording, generated content, and UGC moderation where relevant.
- Treat webview bridges and plugin APIs as security boundaries, not just contracts.
- **Initial allowlist is not enough** — once a webview navigates or executes redirect/XSS, an allowed page can still try to invoke capabilities.
- The contract: strict HTTPS origin + path allowlist (an allowed domain with an open redirect is not safe — pin path or use signed routes), nonce/handshake **bound to `(webview-instance, current-route, session-epoch)`** and re-issued on every navigation, **origin/path revalidated on every message** (not only at handshake), **per-message capability invocation requires a server-signed capability grant scoped to the full identity + session tuple `(route, action, session-incarnation, user, tenant, bound-account, permission-scope-hash, webview-instance, short-expiry)`** — route-level opt-in alone lets a compromised allowed page reuse the opt-in across actions, and an incomplete identity binding lets a grant survive a permission downgrade or bound-account switch; the signing dependency has an **offline contract** (pre-mint a short-lived bundle for the route's first interaction; on outage additional capabilities fail closed with explicit unavailable UX — never bypass signing because the backend is slow), schema validation on every payload, timeout, and cleanup on `useDidHide` / `useUnload`.
- Treat the embedded page as adversarial input even when it is "your own" H5.
- Per-page command/async-work ownership: every long-running operation (request, upload, scan, polling, subpackage download, host capability call) is owned by a per-page controller with abort/cancel, a lifecycle epoch (incremented on page unload, route switch, logout/account-switch), and a late-result-ignore rule — callbacks arriving after the epoch advances are dropped, not applied to a destroyed page or the next user's state. For operations that cannot be canceled (server-side payment, irrevocable upload), reconcile final state via backend on next entry instead of mutating UI from a stale callback.
5. Verify in the right environment.
- Run repo formatter, typecheck/build, focused tests, and platform compile commands. For Taro, run `taro build --type <target>` for every target the change touches; one target's success is not the others' success.
- Test-code authoring: pick the matching § from the decision table in `testing-strategy/references/test-code-authoring-patterns.md`; smell lint: `testing-strategy/references/fitness-functions.md` §4.1.4.
- **TC traceability**: link tests via the `createTcSuite(test, describe)` factory wrapper. Registers at collection time so `.skip` / `.skipIf` / `.todo` still map to Bitable status. Full overloads supported: `.concurrent` / `.each` / `(name, options, fn)`. Helper from `test-artifact-management/references/tc_helpers/tc.ts`, installed under `test/tc.ts`. See `test-artifact-management/references/tc-marker-conventions.md`. Before adding tests, `grep -rn 'tcTest\|tcDescribe' src/ __tests__/` plus the sidecar `test/results/tc-map.jsonl` to check for existing coverage — extend rather than duplicate. When a TC is marked 废弃, grep both source and sidecar; follow deprecation cascade in `testing-strategy`. Tests without any TC link: prompt user only when the underlying code is also removed.
- **废弃级联:业务代码是否仍在用** — 小程序栈混合多种引用机制,单一 grep 不够:
1. TS/JS 模块:`npx madge --dependents src/<path>` 或 `grep -rEn "from ['\"][./]*<path>"`
2. 页面注册:检查 `app.json` / `app.config.ts` 的 `pages` 数组;若页面 path 不在数组里,整个页面文件可删
3. 组件/模板:`grep -rn "<custom-tag>" src/`(usingComponents 在父 json 里声明 + wxml 里使用);`grep -rn "<wxs.*src=\"<wxs-file>" src/`
4. 静态资源:图片/字体被 wxml/wxss 引用 → `grep -rn "<filename>" src/`;分包资源 → 查每个分包 `pages` 列表
5. 平台条件编译(Taro 多端):`#ifdef WEAPP / ALIPAY` 内的 import 在另一端不存在;按目标平台跑 build 看 warning
- For visible changes, inspect the rendered page in the relevant developer tool (WeChat DevTools, Alipay IDE, Douyin DevTools, Baidu DevTools), simulator, preview build, or real device and capture evidence where feasible.
- For systemic UI/UX redesign slices, diff the declared host target list against repo-configured build targets; every configured target must be classified as shipped (needs rendered evidence), product-level permanently excluded (can complete) — valid only when the authoritative build/release target source already stopped shipping that target before this slice; removing or disabling a target within the slice is a separate product/release scope change that routes through its product/risk/release owners and cannot satisfy this gate's evidence for the same slice; explanatory docs or an MR comment alone are temporary-skip authority, never permanent exclusion — or temporary slice-skip for a shipped target (leaves that host `pre-runtime-test-ready` / `blocked`), and any unclassified target blocks completion.
- For UI/UX redesign evidence, include declared host targets, host developer-tool or real-device channel, loading/empty/error/final states, long text or text-scale behavior where supported, permission/capability prompts, route/share/scene entry when relevant, and screenshot or equivalent host-rendered artifact. Mark each dimension covered or `N/A` with a one-line reason; `N/A` is valid only when the reason names a verifiable structural fact, explains why that fact makes the dimension unreachable or unchanged for this slice, and includes a checkable pointer such as a file path, config key, or commit that resolves at review time. Persist evidence artifacts where reviewers can access them using sanitized/test accounts and redacting tokens, PII, credentials, private paths, and raw personal data; remove temporary smoke files or generated preview helpers before commit unless the repo intentionally owns them.
- Return the complete canonical client-record member defined in `../product-ui-ux-design/references/delivery-contract.md` for testing Phase 1 and the design verdict. The member includes its applied rule/decision, affected files/components, preserved behavior, exact command, immutable candidate binding, producer member/version actually exercised, artifacts, tested host/tool/device targets, states/dimensions/capabilities, criterion-mapped observations, coverage boundary, and gaps. A host render proves only the captured host/member states; it cannot close an unbound producer member. `testing-strategy` records aggregate sufficiency before the design owner records the candidate-bound verdict.
- For mini-program runtime changes, developer-tool or real-device smoke is a completion gate, not optional evidence. This includes changes to `Taro.*` or host APIs, `wx.*`/`my.*` calls, chunked/streaming transport, foreground/background recovery, route/share/scene behavior, storage/session restore, permissions/capabilities, and host-rendered loading/error/final states. If the tool or device is missing, first attempt discovery and normal setup; if still unavailable, stop at `pre-runtime-test-ready` or `blocked` and name the owner, attempted commands, residual risk, and next unblock action. `pre-runtime-test-ready` is a handoff-only label; it is not merge-ready, release-ready, or complete.
- If an automation, remote-control, or screenshot channel reports a blank or stale mini-program surface while a human operator can see the real host page rendering, treat it as an observation-channel conflict before treating it as an app defect. Re-check focus/window/permission state, capture the human-visible state through another channel when possible, label which evidence came from the automation channel versus the human-visible host, and only mark "blank screen" as a product defect after at least one host-visible channel reproduces it.
- When a human operator's already-authenticated host client or device is used as the runtime test surface, treat it as a human-assisted host test: record observer role/source class, sanitized account class, host client/device, entry path, actions performed, redacted artifacts, state changes such as login/logout or permission prompts, and restoration outcome in the project evidence. Label it as manual, scenario-scoped evidence; it does not replace required automated assertions or other host checks. If requested logout/account-switch/storage/permission restoration is not confirmed, mark the host test blocked or incomplete until restored or handed off to a named owner. Do not record personal phone numbers, personal operator names, chat/contact handles, tokens, private account names, or reviewer credentials in shared artifacts.
- Treat appid, dev-tool login, plugin authorization, service-port availability, and host identity/configuration as part of the runtime verification surface, not as background noise. A generated preview QR or a backend login success does not prove the mini-program runtime path until the correct host/app identity and permissions are exercised in the tool or on device.
- Verify route entry, share/deep-link scene params, auth state, storage restore, network error, permission denial, and primary recovery path for affected flows.
- For detail pages and deep-link/share/QR entry points, test missing or stale route params, missing local storage/cache payloads, expired auth, and direct cold entry. These states must resolve to an explicit empty/error/recovery state or safe redirect; a permanent loading spinner or blank screen under cold entry or missing-param entry is a blocking defect that must be fixed or explicitly marked `blocked` with a real owner, resolution path, and target follow-up point before the flow can be called complete. For stale storage/cache, include at least one real-device or emulator state test with a prior-version or manually seeded cache payload. Developer-tool-only stale-cache evidence is fallback evidence and must be labeled as a `device-state gap`; a flow with an open `device-state gap` is `blocked` or `pre-runtime-test-ready`, not complete.
- For payment, subscription, login, phone, camera/media, or write-finality changes, verify sandbox/mock plus one platform-specific happy path. If platform evidence is unavailable after remediation, stop at `pre-runtime-test-ready` or `blocked`; do not complete the work by only recording the gap.
- For release work, verify app id/env, version, build output, platform review checklist, gray release/rollback path, analytics version tag, and owner handoff. For every **shipped** host platform, compile + developer-tool/real-device evidence is blocking — "recorded as unverified" is only acceptable for targets the release is not actually shipping. Mini-program rollback through host-platform re-review is slow; risky flows must therefore have a **server-side feature flag with safe default + tested kill-switch runbook** in place before submission. Capture the current official platform-policy doc URL + date for every review-sensitive area touched (payment, privacy, AI/generated content, minors, financial/medical/legal copy) — policy text changes faster than skill rules.
## Non-Negotiable Rules
- Do not treat a browser or H5-only preview as proof that a miniapp platform passes. For Taro, `taro build --type h5` passing is not evidence that `weapp`/`alipay`/`tt`/`swan` targets pass.
- Do not push large or high-frequency `setData` payloads across the logic↔render bridge. `setData` serializes its payload from the logic thread to the render thread on every call, so a multi-hundred-KB payload or a per-scroll-tick / per-keystroke call janks rendering, and the host drops an oversized call (WeChat documents a per-`setData` size limit on the order of 1 MB — confirm the exact current value in the platform docs). Send only the changed fields via data-path keys (e.g. `this.setData({'list[3].done': true})`), not the whole list; throttle/debounce high-frequency updates; and page or virtualize long lists rather than re-pushing the full array. (WeChat 小程序平台性能优化指南:`setData` 数据量与调用频率,以当前官方文档为准;Taro `setState` compiles to `setData`, so the same limit applies.)
- Do not call multi-platform miniapp work complete because one host platform compiled.
- Do not add direct platform API calls when the repo has wrappers or adapters.
- Do not import `react-dom` or use real browser-only APIs (DOM mutation, browser observers, RAF/layout APIs, browser globals) in Taro code that compiles to a mini-program target; isolate that code behind the H5 build target.
- Do not sprinkle `process.env.TARO_ENV` branches inside render code as a project convention; confine platform branching to adapter/wrapper modules or platform-specific files. (Taro permits inline branching; the guardrail is a maintainability rule, not a framework limitation.)
- Do not use `Taro.eventCenter` as the canonical owner of durable cross-page state; reserve it for navigation handoff and simple lifecycle events, and clean up listeners on `useDidHide` / `useUnload`.
- Do not ship a page without verifying route registration, entry scene/share params, tab vs. `navigateTo` vs. `switchTab` vs. `redirectTo` vs. `reLaunch` semantics, and page-stack depth budget. Routing defects are a leading cause of host-platform review rejection.
- Do not leave async work running across page hide/unload or route switch: every long-running operation lives under a per-page controller with cancel + lifecycle epoch + late-callback ignore. Callbacks arriving after the epoch advances are dropped.
- Do not let any money / quota / publishing / account-finality mutation rely on a client-side UI lock alone — server-enforced idempotency by business key is the primary defense. Persist pending state before invoking the action; reconcile against backend on cold start / page show / re-login before enabling a retry. Treat local `cancel` as non-final until backend confirms.
- Do not let logout / account-switch leave in-flight work alive: increment the auth epoch, abort pending requests / uploads / pollers, clear query caches and storage namespaces, and drop any callback whose epoch is stale.
- Do not store sensitive durable fields (phone, profile, tenant flag, identity proof, payment metadata) in raw mini-program storage by default. If durable storage is required by product, namespace by user + tenant + platform + app-version, bound by TTL, prefer encrypted or server-backed storage, and add a purge test that runs on logout/account-delete.
- Do not trust scene / share / QR / webview-bridge payloads: schema-parse, server-authorize against current identity, require backend-issued and TTL-bounded share tokens with replay protection, and gate webview bridge by HTTPS origin + path allowlist + per-message capability allowlist + nonce.
- Do not scatter backend enum/string literals through mini-program pages, scene/share/QR parsing, host bridge payload handling, storage, analytics, or tests. Centralize finite-value parsing, display labels, defaults, and unknown-value behavior at the API/client-domain boundary, and keep raw literals only in clearly named boundary conversion tests that cover every known external value plus unknown/default behavior. Migrate existing non-boundary test raw literals for that value in the same pull request or mark each remaining use with `finite-value-debt: <task-ref> <owner> <deadline> <reason>`, even when the current slice does not introduce a new mapper.
- Do not ship auth, payment, phone, location, camera, share, subscription, or generated-content flows without explicit denial/error/retry states.
- Do not ship a host platform without compile + developer-tool/real-device evidence for that platform — "recorded as unverified" is only acceptable for non-shipped targets.
- Do not claim a mini-program runtime fix is complete when developer-tool or real-device smoke did not run. Build output, unit tests, source-regex checks, and independent code review can make the branch `pre-runtime-test-ready`; they cannot make host-runtime behavior complete.
- Do not submit a risky flow for platform review without a server-side feature flag (safe default + kill-switch runbook); platform-review rollback is too slow to be the only lever. The flag does not stop client-only effects (permission prompts triggered at startup, SDK auto-collection on load, host-platform config already submitted) — the flow's **client-side code path itself must no-op when the flag is off**, the SDK must not load until the flag is on, and any host-config change submitted at review time must be reviewed for "what if we need to disable this without a new submission" before approval.
- Do not ship review-sensitive surfaces (payment, privacy disclosure, AI/generated content, minors, financial/medical/legal copy, account deletion, SDK data collection) without naming the current platform-policy doc URL + date you read.
- Do not claim platform review or real-device readiness without current evidence.
- Do not put private app ids, secrets, tokens, reviewer accounts, or internal product names into this skill or shared references.
## Reference Loading
- For source provenance, current extraction boundary, and keep/merge/discard decisions, read `references/source-evidence-map.md` when auditing or re-extracting this skill.
- For platform-specific capability and config checks, read `references/platform-capabilities.md`.
- For product/page acceptance and UI state checklist, read `references/product-page-checklist.md`.
- For API, auth, storage, analytics, and high-risk finality contracts, read `references/contracts-and-state.md`.
- For QA, developer-tool, real-device, review submission, release, and rollback checks, read `references/qa-release.md`.
- For framework choice (Taro vs native vs uni-app vs Remax/kbone vs per-platform split) and decision factors, read `references/framework-choice.md`.
- For cross-stack alignment scope (what must align across web + app + mini-program beyond theme/logo — auth copy, error vocabulary, payment confirmation, privacy disclosure, share payload schema, deep-link routes), read `references/cross-stack-alignment.md`.
- For incorporating online best practices (canonical Taro / WeChat / Alipay / Douyin examples, top-tier mini-programs as UX idiom library, vetting weak vs strong online sources) without overclaiming what observation can prove, read `references/online-practice-uptake.md`.
- For cross-stack brand alignment (web desktop + H5 + native app + mini-program sharing one brand), read `../product-ui-ux-design/references/multi-stack-strategy.md` and `../product-ui-ux-design/references/multi-project-token-consistency.md`.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!