[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6D25BTJPMFGP3AM7TBVT25M":3,"skill-same:01M6D25BTJPMFGP3AM7TBVT25M":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":54,"commitSha":55,"skillDirectory":56,"forksCount":57,"repositoryHtmlUrl":58,"repositoryHomepageUrl":59,"ownerHtmlUrl":60,"ownerBlogUrl":59,"ownerDescription":61,"updatedAt":62,"install":63,"resources":76},"01M6D25BTJPMFGP3AM7TBVT25M","review-checklists",null,"Review checklists by kind of change: interface work, API endpoints, database migrations and queries, background jobs, authentication and permissions, infrastructure and CI, dependencies, tests, documentation, mobile apps and animation, each listing the defects most often missed, to use with the `review` method. Read when reviewing a change of that kind.","enowdev\u002Fenowxcli","enowdev","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F179420349?v=4","01M6D1MVX2KC0X3Z9NESE7P22K","Enow Dev.","01M6D1MW1FMZGBDKWAJY4GQX81",67,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli\u002Fblob\u002Fmain\u002Fcrates\u002Fenowx-core\u002Fskills\u002Freview-checklists\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"review checklists","review","work","tests","background jobs","missed","queries","mobile","database migrations","use","read","Animation","api","ci","database","permissions","authentication","infrastructure","documentation","change","2026-11-10 10:12:30",false,"---\nname: review-checklists\ndescription: \"Review checklists by kind of change: interface work, API endpoints, database migrations and queries, background jobs, authentication and permissions, infrastructure and CI, dependencies, tests, documentation, mobile apps and animation, each listing the defects most often missed, to use with the `review` method. Read when reviewing a change of that kind.\"\n---\n\n# Review checklists by kind of change\n\nEach kind of change hides the same defects because the diff looks fine: the\nmigration that locks the table, the endpoint that checks the role but not the\nowner, the job that runs twice, the workflow that pastes a pull request's title\ninto a shell. Settle each item on the lists for what the change touches, with\nthe method in `review`. An item is a question, not a finding: report only what\nthe change gets wrong. The skill in brackets holds the rule and the fix.\n\n## 1. Which lists apply\n\nTake them from `git diff --name-only`: pages and styles (2, and 3 when\nanything animates), routes and handlers (4, and 7 for sign-in or permissions),\nmigrations and queries (5), workers and schedulers (6), workflows, Dockerfiles\nand infrastructure (8), manifests and lockfiles (9), tests (10), docs (11),\nmobile code (12), claims of speed (13). Most changes need two or three.\n\n## 2. Interface (`ui`, `ui-audit`, `frontend-*`)\n\n- Every state of each view that loads data: empty, loading, error, one item\n  and hundreds; errors shown where they happen (`frontend-errors`).\n- Keyboard: Tab reaches every control, Enter or Space works it, Escape closes\n  overlays, focus is visible and returns to the trigger; icon buttons have a\n  name, inputs a label (`frontend-accessibility`).\n- 360, 768 and 1440px: nothing past the right edge, the primary action in view\n  on a phone, wide tables scrolling in their own box (`ui-layout`).\n- Tokens, not raw colours or spacing (`ui_check` flags colours outside them);\n  both themes checked (`ui-themes`); the direction in `DESIGN.md` kept (`ui`).\n- Placeholders marked; no invented figures, testimonials or logos (`ui-audit`).\n- Text through the translation layer, no sentences glued from pieces, dates,\n  numbers and money through `Intl` (`i18n`).\n- No user data in `dangerouslySetInnerHTML`, `v-html`, `{@html}` or `innerHTML`\n  unsanitised; user URLs only `http`, `https` or `mailto` (`frontend-security`).\n- Forms keep input after a failed submit, block double submits and map server\n  errors to fields (`frontend-forms`); filters, sort and page live in the URL\n  when a reload should keep them (`frontend-state`).\n- Images sized (width, height, `srcset`, `sizes`), lazy below the fold but never\n  the largest; no heavy library for a small widget (`frontend-performance`).\n\n## 3. Animation (`motion-audit`)\n\n- With reduced motion, nothing moves beyond fades and nothing stays hidden\n  (`motion-comfort`).\n- No content hidden in the base CSS: without JavaScript or in print the page is\n  complete (`motion-reveal`).\n- Loops stop off screen and in a hidden tab (`motion-performance`).\n- Only `transform` and `opacity` animate; no `transition: all`, no animated\n  size, position or blur (`motion-performance`).\n- One IntersectionObserver for reveals, each block unobserved once shown; no\n  scroll listeners or scroll hijacking (`motion-reveal`).\n- Feedback 80 to 160ms, nothing blocking the user past 400ms (`motion-timing`).\n- No parallax on text, no zoom or spin tied to scroll (`motion-comfort`).\n- `preview` with `motion: true`: the timeline matches the intent, nothing is\n  hidden after scrolling, the reduced-motion pass is still.\n\n## 4. API endpoints (`backend-api`, `backend-security`, `backend-errors`)\n\n- Every input validated at the boundary (body, query, path, headers read), with\n  lengths, ranges, array sizes and a body size limit.\n- The parsed body never saved as it is: nobody sets `role`, `ownerId` or\n  `price` by adding it to the JSON.\n- Authorisation per object: the record loaded scoped to the caller or tenant\n  (`WHERE id = $1 AND owner_id = $2`), not by id and then a role check\n  (`backend-auth`).\n- `201` for a create, `404` where `403` would reveal the record exists, `409`\n  for conflicts, never `200` with an error inside.\n- One error format; the unexpected becomes a generic `500` with a request id;\n  no stack trace or SQL in responses, no token or personal record in logs\n  (`backend-observability`).\n- Lists paginated in the query (default 25, maximum 100); sort and filter\n  fields from an allow-list, never pasted into SQL.\n- A create that must not repeat takes an `Idempotency-Key`; concurrent edits\n  carry a version and get `409` when stale.\n- Rate limits on sign-in, sign-up, reset and whatever sends email or costs\n  money; a timeout on every query and outbound call.\n- Server-side fetches of user URLs refuse private and metadata addresses.\n- No field renamed or removed without a transition; OpenAPI or the shared\n  types changed with it.\n- Tests for another user's id, bad input and the main path (`backend-testing`).\n\n## 5. Database (`database-migrations`, `database-queries`, `database-indexes`, `database-transactions`)\n\n- A new migration, never an edit of one already run anywhere shared; one\n  concern; a down migration or a stated reason for none.\n- Big Postgres tables: most `ALTER TABLE` forms take an `ACCESS EXCLUSIVE`\n  lock, a type change rewrites the table, `SET NOT NULL` scans it;\n  `lock_timeout` set.\n- Live tables: indexes built `CONCURRENTLY` (outside a transaction, so that\n  migration opts out of one), foreign keys and checks added `NOT VALID`, then\n  validated separately.\n- Renames and drops split across releases (expand, then contract); backfills in\n  batches, outside the schema migration, safe to run twice.\n- `NOT NULL` by default, `ON DELETE` chosen per foreign key, unique constraints\n  where the business needs them; money in integer minor units, `timestamptz`\n  for time (`database-schema`, `backend-data`).\n- Parameterised queries; no query per item in a loop or lazy relation in a\n  template; only the columns needed.\n- Large or live lists paged by keyset, ordered by the sort column then the id.\n- An index for each new filter and sort; foreign key columns indexed, which\n  Postgres does not do by itself.\n- No read, decide, write: a conditional update or `SELECT ... FOR UPDATE`, with\n  unique constraints deciding races.\n- Writes that belong together in one transaction, no network call inside it,\n  jobs queued after the commit.\n\n## 6. Background jobs (`backend-jobs`)\n\n- Idempotent: two runs have the effect of one (a unique key, a conditional\n  update, the provider's idempotency key).\n- Carries ids and loads the current state, not a copy taken when queued.\n- Queued after the transaction commits (an outbox or an after-commit hook).\n- Retried with backoff and jitter only for what can succeed later (timeouts,\n  `429`, `5xx`), up to a set number of attempts.\n- A time limit per job; one small job per item, not one for a thousand.\n- Out of attempts: a dead-letter list with the error, visible to someone.\n- Scheduled work runs once across instances, catches up on missed runs, and\n  keeps times of day in the business's time zone, stored in UTC.\n- On `SIGTERM` a worker finishes its job or hands it back.\n\n## 7. Authentication and permissions (`backend-auth`, `security-auth`)\n\n- Passwords hashed with argon2id, or bcrypt at cost 12 or more, by a library;\n  no length cap below 64 characters.\n- A new session id at sign-in; sessions ended by sign-out and by a password\n  change; cookies `HttpOnly`, `Secure`, `SameSite`.\n- JWTs with the algorithm pinned (never `none`), `exp`, `iss` and `aud`\n  checked; no token in `localStorage` in a browser app.\n- The same answer for known and unknown accounts on sign-in, sign-up and reset;\n  rate limits per account and per IP there and on second factors.\n- Reset and verification tokens: 32 random bytes, stored hashed, used once,\n  expiring (30 to 60 minutes for a reset); a reset ends other sessions.\n- Deny by default, checked on the server on every request, owner and tenant in\n  the query rather than a role alone.\n- OAuth and OpenID Connect: PKCE, `state`, `nonce`, the redirect URI matched\n  exactly; accounts linked by verified email only.\n- `next` or `returnTo` after sign-in limited to paths on the same site.\n- Tests for what must fail: another user's record, a lower role, an expired\n  token.\n\n## 8. Infrastructure and CI (`devops-ci`, `devops-containers`, `devops-deploy`, `security-infra`)\n\n- No secret in files, images, logs or `run:` lines; secrets from the platform's\n  store; cloud access by OIDC, not long-lived keys.\n- `permissions:` at the minimum (`contents: read`); IAM without wildcards.\n- Actions pinned to a full commit SHA, base images to a version (and digest),\n  tools to a version; no `latest`.\n- `pull_request_target` never runs the pull request's code; untrusted text\n  (`github.event.pull_request.title`) reaches scripts through `env:`, never\n  inside `run:` (`security-supply-chain`).\n- Images multi-stage and non-root, a `.dockerignore` keeping out `.git`, `.env`\n  and `node_modules`, an exec-form `CMD` so `SIGTERM` reaches the app.\n- Liveness and readiness checks, rollouts that wait for readiness, memory and\n  CPU limits, a restart policy.\n- A rollback path: the previous image kept, a schema the previous version still\n  runs against.\n- Only the app's port public; databases, caches and admin panels private.\n- Validated with the tool (`actionlint`, `hadolint`, `docker build`,\n  `terraform plan`, `kubectl apply --dry-run=server`); the report says which\n  ran.\n\n## 9. Dependencies (`security-supply-chain`, `research-libraries`)\n\n- Needed at all: the standard library, the platform or an installed package may\n  already do it.\n- Maintained: the last release and its date, issues answered, more than one\n  active maintainer for anything critical.\n- A licence the project can use; GPL or AGPL in closed software is the owner's\n  decision, never a default.\n- Size: the gzipped cost in a frontend bundle; transitive dependencies and\n  native builds elsewhere.\n- The lockfile changed in the same commit and matching the manifest; one\n  package manager's lockfile, not two.\n- No new `preinstall` or `postinstall` script without a reason; no look-alike\n  of a popular package's name.\n- The audit clean or triaged (`npm audit`, `pip-audit`, `cargo audit`,\n  `govulncheck`, `osv-scanner`).\n- A major bump with its migration guide read and breaking changes handled at\n  every call site.\n\n## 10. Tests (`testing`)\n\n- They fail without the change: read each assertion against the old code with\n  `git show main:\u003Cpath>`, or run it on the base.\n- They cover the case the change is about, its failure path included.\n- Assertions on outcomes, not on which mock was called; none in a callback that\n  never runs; async ones awaited.\n- Deterministic: no real clock, unseeded randomness, network, order dependence\n  or sleeps (`testing-flaky`).\n- Nothing deleted, skipped (`.skip`, `xit`, `@Ignore`, `#[ignore]`, `t.Skip`)\n  or loosened to pass; snapshots updated for a stated reason.\n- Mocks only at boundaries; never the unit under test (`testing-unit`).\n- Each test makes its own data, unique enough to run in parallel\n  (`testing-data`).\n- Names state the behaviour: \"refund is refused after 30 days\".\n\n## 11. Documentation (`docs`)\n\n- Every flag, default, environment variable, endpoint and command the text\n  names exists in the code (grep each one).\n- Examples run: the commands exist in the scripts or the Makefile; the code\n  compiles against the current API.\n- A changelog entry under Unreleased for what users notice; breaking changes\n  first, with migration steps (`docs-changelog`).\n- New environment variables in `.env.example` and the README (`docs-readme`).\n- The API reference or OpenAPI changed with the endpoints (`docs-api`).\n- Comments changed with the code; none describes the old behaviour\n  (`docs-comments`).\n- No invented numbers, no marketing words (`writing`).\n- Links resolve; screenshots show the current interface.\n\n## 12. Mobile apps (`mobile`, `mobile-ux`, `mobile-data`, `mobile-release`)\n\n- State survives backgrounding and, on Android, the process being killed; data\n  refreshed on resume.\n- Offline and slow networks: timeouts, retries, writes queued with idempotency\n  keys, no endless spinner (`mobile-data`).\n- Permissions asked in context, with a path for a refusal; Android back, safe\n  areas and navigation conventions kept (`mobile-ux`).\n- Icon buttons labelled, text that grows to the largest size, targets of 44pt\n  or 48dp, a sensible screen reader order.\n- Tokens in the Keychain or Keystore, not AsyncStorage or SharedPreferences.\n- Long lists virtualised (FlashList, `LazyColumn`, `ListView.builder`), images\n  sized for their slot (`mobile-performance`).\n- Deep links validated before they act; no personal data in logs.\n- A new permission or SDK reflected in the privacy manifest and the store forms\n  (`mobile-release`).\n\n## 13. Performance claims (`performance`)\n\n- Measured before and after, same machine and workload, both stated.\n- Several runs, median and spread, percentiles for latency; not one run or an\n  average (`performance-benchmarks`).\n- A realistic workload: production-like sizes and concurrency.\n- A profile showing the changed code was the hot path (`performance-profiling`).\n- Correctness kept: tests pass; a cache has an invalidation rule\n  (`backend-caching`).\n- The trade named: memory for speed, one input shape against another.\n- Micro-benchmarks keep the compiler from removing the work (`black_box`).\n- No speed-up claimed in a commit or changelog without its numbers.\n\n## Check it\n\nLists chosen from every path in the diff, config and CI included; each item\nsettled against the code; findings in the `review` format (consequence, line,\ninput, evidence, fix, severity); what could not be checked listed as such.\n\n## Avoid\n\nPasting a checklist into the report; an item raised as a finding because the\ncode does not mention it (a job that cannot fail needs no retries); findings\nwithout a line; the interface list alone on a change that ships a migration.\n","# Review checklists by kind of change\n\nEach kind of change hides the same defects because the diff looks fine: the\nmigration that locks the table, the endpoint that checks the role but not the\nowner, the job that runs twice, the workflow that pastes a pull request's title\ninto a shell. Settle each item on the lists for what the change touches, with\nthe method in `review`. An item is a question, not a finding: report only what\nthe change gets wrong. The skill in brackets holds the rule and the fix.\n\n## 1. Which lists apply\n\nTake them from `git diff --name-only`: pages and styles (2, and 3 when\nanything animates), routes and handlers (4, and 7 for sign-in or permissions),\nmigrations and queries (5), workers and schedulers (6), workflows, Dockerfiles\nand infrastructure (8), manifests and lockfiles (9), tests (10), docs (11),\nmobile code (12), claims of speed (13). Most changes need two or three.\n\n## 2. Interface (`ui`, `ui-audit`, `frontend-*`)\n\n- Every state of each view that loads data: empty, loading, error, one item\n  and hundreds; errors shown where they happen (`frontend-errors`).\n- Keyboard: Tab reaches every control, Enter or Space works it, Escape closes\n  overlays, focus is visible and returns to the trigger; icon buttons have a\n  name, inputs a label (`frontend-accessibility`).\n- 360, 768 and 1440px: nothing past the right edge, the primary action in view\n  on a phone, wide tables scrolling in their own box (`ui-layout`).\n- Tokens, not raw colours or spacing (`ui_check` flags colours outside them);\n  both themes checked (`ui-themes`); the direction in `DESIGN.md` kept (`ui`).\n- Placeholders marked; no invented figures, testimonials or logos (`ui-audit`).\n- Text through the translation layer, no sentences glued from pieces, dates,\n  numbers and money through `Intl` (`i18n`).\n- No user data in `dangerouslySetInnerHTML`, `v-html`, `{@html}` or `innerHTML`\n  unsanitised; user URLs only `http`, `https` or `mailto` (`frontend-security`).\n- Forms keep input after a failed submit, block double submits and map server\n  errors to fields (`frontend-forms`); filters, sort and page live in the URL\n  when a reload should keep them (`frontend-state`).\n- Images sized (width, height, `srcset`, `sizes`), lazy below the fold but never\n  the largest; no heavy library for a small widget (`frontend-performance`).\n\n## 3. Animation (`motion-audit`)\n\n- With reduced motion, nothing moves beyond fades and nothing stays hidden\n  (`motion-comfort`).\n- No content hidden in the base CSS: without JavaScript or in print the page is\n  complete (`motion-reveal`).\n- Loops stop off screen and in a hidden tab (`motion-performance`).\n- Only `transform` and `opacity` animate; no `transition: all`, no animated\n  size, position or blur (`motion-performance`).\n- One IntersectionObserver for reveals, each block unobserved once shown; no\n  scroll listeners or scroll hijacking (`motion-reveal`).\n- Feedback 80 to 160ms, nothing blocking the user past 400ms (`motion-timing`).\n- No parallax on text, no zoom or spin tied to scroll (`motion-comfort`).\n- `preview` with `motion: true`: the timeline matches the intent, nothing is\n  hidden after scrolling, the reduced-motion pass is still.\n\n## 4. API endpoints (`backend-api`, `backend-security`, `backend-errors`)\n\n- Every input validated at the boundary (body, query, path, headers read), with\n  lengths, ranges, array sizes and a body size limit.\n- The parsed body never saved as it is: nobody sets `role`, `ownerId` or\n  `price` by adding it to the JSON.\n- Authorisation per object: the record loaded scoped to the caller or tenant\n  (`WHERE id = $1 AND owner_id = $2`), not by id and then a role check\n  (`backend-auth`).\n- `201` for a create, `404` where `403` would reveal the record exists, `409`\n  for conflicts, never `200` with an error inside.\n- One error format; the unexpected becomes a generic `500` with a request id;\n  no stack trace or SQL in responses, no token or personal record in logs\n  (`backend-observability`).\n- Lists paginated in the query (default 25, maximum 100); sort and filter\n  fields from an allow-list, never pasted into SQL.\n- A create that must not repeat takes an `Idempotency-Key`; concurrent edits\n  carry a version and get `409` when stale.\n- Rate limits on sign-in, sign-up, reset and whatever sends email or costs\n  money; a timeout on every query and outbound call.\n- Server-side fetches of user URLs refuse private and metadata addresses.\n- No field renamed or removed without a transition; OpenAPI or the shared\n  types changed with it.\n- Tests for another user's id, bad input and the main path (`backend-testing`).\n\n## 5. Database (`database-migrations`, `database-queries`, `database-indexes`, `database-transactions`)\n\n- A new migration, never an edit of one already run anywhere shared; one\n  concern; a down migration or a stated reason for none.\n- Big Postgres tables: most `ALTER TABLE` forms take an `ACCESS EXCLUSIVE`\n  lock, a type change rewrites the table, `SET NOT NULL` scans it;\n  `lock_timeout` set.\n- Live tables: indexes built `CONCURRENTLY` (outside a transaction, so that\n  migration opts out of one), foreign keys and checks added `NOT VALID`, then\n  validated separately.\n- Renames and drops split across releases (expand, then contract); backfills in\n  batches, outside the schema migration, safe to run twice.\n- `NOT NULL` by default, `ON DELETE` chosen per foreign key, unique constraints\n  where the business needs them; money in integer minor units, `timestamptz`\n  for time (`database-schema`, `backend-data`).\n- Parameterised queries; no query per item in a loop or lazy relation in a\n  template; only the columns needed.\n- Large or live lists paged by keyset, ordered by the sort column then the id.\n- An index for each new filter and sort; foreign key columns indexed, which\n  Postgres does not do by itself.\n- No read, decide, write: a conditional update or `SELECT ... FOR UPDATE`, with\n  unique constraints deciding races.\n- Writes that belong together in one transaction, no network call inside it,\n  jobs queued after the commit.\n\n## 6. Background jobs (`backend-jobs`)\n\n- Idempotent: two runs have the effect of one (a unique key, a conditional\n  update, the provider's idempotency key).\n- Carries ids and loads the current state, not a copy taken when queued.\n- Queued after the transaction commits (an outbox or an after-commit hook).\n- Retried with backoff and jitter only for what can succeed later (timeouts,\n  `429`, `5xx`), up to a set number of attempts.\n- A time limit per job; one small job per item, not one for a thousand.\n- Out of attempts: a dead-letter list with the error, visible to someone.\n- Scheduled work runs once across instances, catches up on missed runs, and\n  keeps times of day in the business's time zone, stored in UTC.\n- On `SIGTERM` a worker finishes its job or hands it back.\n\n## 7. Authentication and permissions (`backend-auth`, `security-auth`)\n\n- Passwords hashed with argon2id, or bcrypt at cost 12 or more, by a library;\n  no length cap below 64 characters.\n- A new session id at sign-in; sessions ended by sign-out and by a password\n  change; cookies `HttpOnly`, `Secure`, `SameSite`.\n- JWTs with the algorithm pinned (never `none`), `exp`, `iss` and `aud`\n  checked; no token in `localStorage` in a browser app.\n- The same answer for known and unknown accounts on sign-in, sign-up and reset;\n  rate limits per account and per IP there and on second factors.\n- Reset and verification tokens: 32 random bytes, stored hashed, used once,\n  expiring (30 to 60 minutes for a reset); a reset ends other sessions.\n- Deny by default, checked on the server on every request, owner and tenant in\n  the query rather than a role alone.\n- OAuth and OpenID Connect: PKCE, `state`, `nonce`, the redirect URI matched\n  exactly; accounts linked by verified email only.\n- `next` or `returnTo` after sign-in limited to paths on the same site.\n- Tests for what must fail: another user's record, a lower role, an expired\n  token.\n\n## 8. Infrastructure and CI (`devops-ci`, `devops-containers`, `devops-deploy`, `security-infra`)\n\n- No secret in files, images, logs or `run:` lines; secrets from the platform's\n  store; cloud access by OIDC, not long-lived keys.\n- `permissions:` at the minimum (`contents: read`); IAM without wildcards.\n- Actions pinned to a full commit SHA, base images to a version (and digest),\n  tools to a version; no `latest`.\n- `pull_request_target` never runs the pull request's code; untrusted text\n  (`github.event.pull_request.title`) reaches scripts through `env:`, never\n  inside `run:` (`security-supply-chain`).\n- Images multi-stage and non-root, a `.dockerignore` keeping out `.git`, `.env`\n  and `node_modules`, an exec-form `CMD` so `SIGTERM` reaches the app.\n- Liveness and readiness checks, rollouts that wait for readiness, memory and\n  CPU limits, a restart policy.\n- A rollback path: the previous image kept, a schema the previous version still\n  runs against.\n- Only the app's port public; databases, caches and admin panels private.\n- Validated with the tool (`actionlint`, `hadolint`, `docker build`,\n  `terraform plan`, `kubectl apply --dry-run=server`); the report says which\n  ran.\n\n## 9. Dependencies (`security-supply-chain`, `research-libraries`)\n\n- Needed at all: the standard library, the platform or an installed package may\n  already do it.\n- Maintained: the last release and its date, issues answered, more than one\n  active maintainer for anything critical.\n- A licence the project can use; GPL or AGPL in closed software is the owner's\n  decision, never a default.\n- Size: the gzipped cost in a frontend bundle; transitive dependencies and\n  native builds elsewhere.\n- The lockfile changed in the same commit and matching the manifest; one\n  package manager's lockfile, not two.\n- No new `preinstall` or `postinstall` script without a reason; no look-alike\n  of a popular package's name.\n- The audit clean or triaged (`npm audit`, `pip-audit`, `cargo audit`,\n  `govulncheck`, `osv-scanner`).\n- A major bump with its migration guide read and breaking changes handled at\n  every call site.\n\n## 10. Tests (`testing`)\n\n- They fail without the change: read each assertion against the old code with\n  `git show main:\u003Cpath>`, or run it on the base.\n- They cover the case the change is about, its failure path included.\n- Assertions on outcomes, not on which mock was called; none in a callback that\n  never runs; async ones awaited.\n- Deterministic: no real clock, unseeded randomness, network, order dependence\n  or sleeps (`testing-flaky`).\n- Nothing deleted, skipped (`.skip`, `xit`, `@Ignore`, `#[ignore]`, `t.Skip`)\n  or loosened to pass; snapshots updated for a stated reason.\n- Mocks only at boundaries; never the unit under test (`testing-unit`).\n- Each test makes its own data, unique enough to run in parallel\n  (`testing-data`).\n- Names state the behaviour: \"refund is refused after 30 days\".\n\n## 11. Documentation (`docs`)\n\n- Every flag, default, environment variable, endpoint and command the text\n  names exists in the code (grep each one).\n- Examples run: the commands exist in the scripts or the Makefile; the code\n  compiles against the current API.\n- A changelog entry under Unreleased for what users notice; breaking changes\n  first, with migration steps (`docs-changelog`).\n- New environment variables in `.env.example` and the README (`docs-readme`).\n- The API reference or OpenAPI changed with the endpoints (`docs-api`).\n- Comments changed with the code; none describes the old behaviour\n  (`docs-comments`).\n- No invented numbers, no marketing words (`writing`).\n- Links resolve; screenshots show the current interface.\n\n## 12. Mobile apps (`mobile`, `mobile-ux`, `mobile-data`, `mobile-release`)\n\n- State survives backgrounding and, on Android, the process being killed; data\n  refreshed on resume.\n- Offline and slow networks: timeouts, retries, writes queued with idempotency\n  keys, no endless spinner (`mobile-data`).\n- Permissions asked in context, with a path for a refusal; Android back, safe\n  areas and navigation conventions kept (`mobile-ux`).\n- Icon buttons labelled, text that grows to the largest size, targets of 44pt\n  or 48dp, a sensible screen reader order.\n- Tokens in the Keychain or Keystore, not AsyncStorage or SharedPreferences.\n- Long lists virtualised (FlashList, `LazyColumn`, `ListView.builder`), images\n  sized for their slot (`mobile-performance`).\n- Deep links validated before they act; no personal data in logs.\n- A new permission or SDK reflected in the privacy manifest and the store forms\n  (`mobile-release`).\n\n## 13. Performance claims (`performance`)\n\n- Measured before and after, same machine and workload, both stated.\n- Several runs, median and spread, percentiles for latency; not one run or an\n  average (`performance-benchmarks`).\n- A realistic workload: production-like sizes and concurrency.\n- A profile showing the changed code was the hot path (`performance-profiling`).\n- Correctness kept: tests pass; a cache has an invalidation rule\n  (`backend-caching`).\n- The trade named: memory for speed, one input shape against another.\n- Micro-benchmarks keep the compiler from removing the work (`black_box`).\n- No speed-up claimed in a commit or changelog without its numbers.\n\n## Check it\n\nLists chosen from every path in the diff, config and CI included; each item\nsettled against the code; findings in the `review` format (consequence, line,\ninput, evidence, fix, severity); what could not be checked listed as such.\n\n## Avoid\n\nPasting a checklist into the report; an item raised as a finding because the\ncode does not mention it (a job that cannot fail needs no retries); findings\nwithout a line; the interface list alone on a change that ships a migration.\n",{"name":5,"description":7},"main","38293fe1b096e6bf3646c7344c38786ed688f464","crates\u002Fenowx-core\u002Fskills\u002Freview-checklists",21,"https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli","https:\u002F\u002Fenowx.ai","https:\u002F\u002Fgithub.com\u002Fenowdev","Pretending to be a Developer","2026-10-06 02:05:35",{"source":8,"skillName":5,"commands":64,"prompt":74,"zipAvailable":75},[65,68,71],{"tool":66,"command":67},"npx","npx skills add enowdev\u002Fenowxcli --skill review-checklists",{"tool":69,"command":70},"bunx","bunx skills add enowdev\u002Fenowxcli --skill review-checklists",{"tool":72,"command":73},"pnpm","pnpm dlx skills add enowdev\u002Fenowxcli --skill review-checklists","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli\u002Fblob\u002Fmain\u002Fcrates\u002Fenowx-core\u002Fskills\u002Freview-checklists\u002FSKILL.md",true,[],[78,91,113,129,154,176],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":87,"publishedAt":49},"01M6D2HQYSQD9N7MTNDT4A7CBM","demo-skill","Project-scope demo skill for tests.","https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli\u002Fblob\u002Fmain\u002Fworkspace\u002F.agents\u002Fskills\u002Fdemo-skill\u002FSKILL.md",[84],{"categoryNo":85,"categoryName":86,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[88,89,32,90,39],"demo skill","demo","project",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":103,"publishedAt":49},"01M6D2HM0GCPM0TM2HPG9HHR2R","writing","Writing words people read: the specific thing instead of claims, words to drop, sentences, interface copy (buttons, labels, errors, empty states, confirmations), page copy, notifications and emails, alt text and link text, numbers and dates, words that translate well, documentation and voice. Read before writing a page's copy, an interface's text or a document.","https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli\u002Fblob\u002Fmain\u002Fcrates\u002Fenowx-core\u002Fskills\u002Fwriting\u002FSKILL.md",[97,100],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":101,"categoryName":102,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000036","内容创作者",[93,104,105,106,107,108,39,109,110,111,47,112],"text","emails","empty","drop","document","page","voice","notifications","translate",{"skillNo":114,"name":115,"nameZh":6,"description":116,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":122,"publishedAt":49},"01M6D2HG07YS49NM196Q0R3AZ8","ui","Designing or restyling an interface: direction, layout, type, colour, icons, components, states, responsive behaviour. Read before building a page, a screen or a set of components.","https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli\u002Fblob\u002Fmain\u002Fcrates\u002Fenowx-core\u002Fskills\u002Fui\u002FSKILL.md",[119],{"categoryNo":120,"categoryName":121,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000032","设计师",[115,123,124,125,126,109,127,39,128],"icons","components","SET","responsive","layout","before building",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":139,"publishedAt":49},"01M6D2HB59HZHWG1RYZDV4SJ91","ui-themes","Light and dark themes, and colour that holds in both: tokens with a value per theme, and what each kind of content needs to stay visible (icons, SVG drawings and line art, logos, photos, screenshots, charts, code, maps, borders, shadows, focus, form controls), switching without a flash, and checking both. Read before building a second theme or a theme toggle, and before any drawing, logo or chart on a page that has two themes.","https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli\u002Fblob\u002Fmain\u002Fcrates\u002Fenowx-core\u002Fskills\u002Fui-themes\u002FSKILL.md",[135,138],{"categoryNo":136,"categoryName":137,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},[115,140,141,142,143,144,145,146,147,39,128,148,109,149,150,151,123,152,153],"ui themes","switching","photos","tokens","drawing","focus","maps","Art","flash","code","Charts","content","screenshots","logo",{"skillNo":155,"name":156,"nameZh":6,"description":157,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":158,"categories":159,"keywords":163,"publishedAt":49},"01M6D2H5R5KRAE524C8QX0T7Q0","ui-structure","Structure before styling: the blueprint written before any interface code (the screen's job, the regions its kind of page needs, their order and why, the layout skeleton in numbers, the components and their states), the anatomy and order of a homepage, a dashboard, a list, a detail page, settings, a form, sign-in, pricing, docs, an article and a checkout, and how to turn the blueprint into code (tokens, layout primitives, components, sections, page). Read first, before building or rebuilding any page or screen.","https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli\u002Fblob\u002Fmain\u002Fcrates\u002Fenowx-core\u002Fskills\u002Fui-structure\u002FSKILL.md",[160,161,162],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},{"categoryNo":101,"categoryName":102,"taxonomyType":26,"taxonomyTypeDesc":27},[164,115,165,124,166,167,149,168,169,170,127,143,171,172,173,39,128,109,174,175],"structure","ui structure","pricing","dashboard","Blueprint","article","anatomy","styling","primitives","list","why","how",{"skillNo":177,"name":178,"nameZh":6,"description":179,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":180,"categories":181,"keywords":189,"publishedAt":49},"01M6D2H0ZZBJG77MBGPZHA6MWD","ui-stack-vue","Building interfaces in Vue 3 and Nuxt: project layout, script setup with typed defineProps, defineEmits and defineModel, attribute fallthrough, slots and scoped slots, template refs, ref, reactive and computed, watch versus watchEffect, composables and VueUse, provide and inject, Pinia, keyed v-for, transitions, Nuxt 4 (app directory, pages, layouts, useFetch and useAsyncData keys, $fetch in handlers, server routes, runtime config, useSeoMeta, NuxtImg, middleware), VeeValidate forms, Reka UI and Nuxt UI, testing, vue-tsc, and the traps. Read when the project uses Vue or Nuxt.","https:\u002F\u002Fgithub.com\u002Fenowdev\u002Fenowxcli\u002Fblob\u002Fmain\u002Fcrates\u002Fenowx-core\u002Fskills\u002Fui-stack-vue\u002FSKILL.md",[182,185,188],{"categoryNo":183,"categoryName":184,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":186,"categoryName":187,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":120,"categoryName":121,"taxonomyType":26,"taxonomyTypeDesc":27},[115,190,191,192,193,194,195,196,127,90,197,198,39,199,200,201,202,203,204,205],"vue","stack","ui stack vue","forms","pages","watch","runtime","transitions","fetch","pinia","nuxt","template","server","config","directory","testing"]