[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M72TMVRFGJAE5FQ2RYVTY4Q2":3,"skill-same:01M72TMVRFGJAE5FQ2RYVTY4Q2":86},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":26,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":29,"ownerDescription":6,"updatedAt":30,"install":31,"resources":44},"01M72TMVRFGJAE5FQ2RYVTY4Q2","ywc-review-learnings",null,"(ywc) Use when capturing or curating durable repo-specific code-review preferences. Triggers: \"리뷰 학습 누적\", \"리뷰 피드백 축적\", \"review learnings\", \"review memory\", \"remember this review preference\", \"レビュー学習\". Do not use for implementation review (use ywc-impl-review), PR comment handling (use ywc-handle-pr-reviews), in-the-moment review replies (use ywc-receive-review), domain vocabulary (use ywc-ubiquitous-language), or spec review (use ywc-spec-validate).","yongwoon\u002Fywc-agent-toolkit","yongwoon","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F9317029?v=4","01M72SZSF6VKANKG5QTMV4V95S","01M72SZSG8HHC3W2CV5P7EJ5AH",8,"MIT","https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002FSKILL.md",[],[],"2026-11-10 22:39:42",false,"---\nname: ywc-review-learnings\ndescription: >-\n  (ywc) Use when capturing or curating durable repo-specific code-review\n  preferences. Triggers: \"리뷰 학습 누적\", \"리뷰 피드백 축적\", \"review\n  learnings\", \"review memory\", \"remember this review preference\",\n  \"レビュー学習\". Do not use for implementation review (use ywc-impl-review),\n  PR comment handling (use ywc-handle-pr-reviews), in-the-moment review replies\n  (use ywc-receive-review), domain vocabulary (use\n  ywc-ubiquitous-language), or spec review (use ywc-spec-validate).\n---\n\n# ywc-review-learnings\n\n**Announce at start:** \"I'm using the ywc-review-learnings skill to read or update the project's accumulated review learnings.\"\n\nThis skill produces or maintains `docs\u002Freview-learnings.md` — a per-project, accumulating memory of code-review preferences that makes every future review sharper. It is the runtime-agnostic version of the CodeRabbit \"learnings\" idea: instead of relying on a hosted bot's internal database, the learnings live as a committed, human-editable Markdown file that `ywc-impl-review` loads before reviewing. Each learning records not just *what* to do but *why*, so it generalizes to similar-but-not-identical situations rather than degrading into a brittle keyword match.\n\nIt operates in four modes: **read** (load learnings applicable to a review target), **update** (capture new learnings from feedback, recurring findings, or harvested bot comments), **list** (display current learnings), and **curate** (deprecate stale or contradictory learnings).\n\n## Rationalization Defense\n\nWhen tempted to bypass a rule, check this table first:\n\n| Excuse | Reality |\n|---|---|\n| \"Record the rule, the WHY is obvious — skip it\" | The *why* is the whole value. Without it the learning cannot be applied to a similar-but-different case, and a future reader (or LLM) cannot tell a real rule from an overfit one. A learning with no rationale is a keyword match waiting to misfire. |\n| \"This finding was rejected as a false positive — just delete the learning\" | Deleting loses the lesson; the reviewer will re-flag it next PR. Record it as a `FALSE-POSITIVE` polarity learning **with the reason it was wrong**, so the reviewer stops raising it. CodeRabbit's precision comes from remembering *why* a comment was rejected, not just that it was. |\n| \"Append the new learning without reading the file\" | Appending blind creates duplicate and contradictory entries. Always read the full `docs\u002Freview-learnings.md` before any write, and check whether the pattern is already captured. |\n| \"One learning per individual finding is most precise\" | One-per-finding overfits to a single line and floods the file. Generalize to the *class* of issue (the pattern + the why), scoped to the narrowest glob that captures it. |\n| \"This contradicts an old learning — keep both, let the reviewer decide\" | Two contradictory learnings make the reviewer's behavior non-deterministic. Newest-wins: deprecate the old entry with a pointer to the new one (`~~strikethrough~~` + note), never silently delete. |\n| \"Write the learnings without user confirmation, I inferred the intent\" | An unconfirmed learning pollutes *every* future review on the matching glob. Always present the proposed ADD \u002F MODIFY \u002F DEPRECATE set for one confirmation round before writing. |\n| \"Scope it `repo`-wide so it always applies\" | Over-broad scope is the main source of review noise — a TypeScript naming rule applied to `*.sql` is pure friction. Scope to the narrowest file glob that captures the real pattern; reserve `repo` for genuinely universal conventions. |\n\n**Violating the letter of these rules is violating the spirit.** A learnings file full of unconfirmed, why-less, or over-scoped entries degrades review quality on every PR that touches a matching path — the opposite of its purpose.\n\n## Arguments\n\n| Parameter | Format | Default | Description |\n|-----------|--------|---------|-------------|\n| `--mode` | `--mode read\\|update\\|list\\|curate` | auto-detect | Force a specific mode (see Mode Detection below) |\n| `--target` | `--target \u003Cglob\\|path...>` | changed files | Review-target paths\u002Fglobs whose applicable learnings should be loaded (`read`) or attributed (`update`) |\n| `--source` | `--source feedback\\|review\\|pr\\|mining` | `feedback` | Where a new learning comes from in `update` mode (see Capture Sources) |\n| `--pr` | `--pr \u003Cnumber>` | — | With `--source pr`, harvest bot (CodeRabbit \u002F Codex) review comments from this PR via `gh` and distill them into learnings. Optional convenience — never required |\n| `--output` | `--output \u003Cpath>` | `docs\u002Freview-learnings.md` | Learnings file path |\n| `--dry-run` | flag | off | Show the proposed CHANGESET without writing to disk |\n\n### Mode Detection (when `--mode` is omitted)\n\n| Condition | Auto-selected mode |\n|---|---|\n| Invoked by a review skill with a target, file exists | `read` |\n| User is describing feedback on a finding (\"this was wrong because…\", \"always flag…\") | `update` |\n| File absent, user wants to start accumulating | `update` (creates the file with the first learning) |\n| User asks \"what review learnings exist?\" | `list` |\n\n## Workflow\n\n### Mode: read — Load Applicable Learnings\n\nInvoked before a review (typically by `ywc-impl-review` Step 0).\n\n1. **Read the file.** If `docs\u002Freview-learnings.md` is absent, return an empty applicable set and say so — never block a review on a missing learnings file.\n2. **Match by scope.** For each learning, include it if its `Scope` glob matches at least one path in `--target` (or any changed file when `--target` is omitted). `repo`-scoped learnings always match. Skip `deprecated` entries.\n3. **Emit a compact applicable block** in the [Applicable Learnings format](#output-format) — grouped by category, each line carrying the rule, the why, and the polarity (`DO` \u002F `DO-NOT` \u002F `FALSE-POSITIVE`). This block is what the caller injects into each reviewer subagent prompt. Keep it tight; a reviewer that drowns in learnings reviews worse, not better.\n\n### Mode: update — Capture a New Learning\n\n1. **Read the existing file** in full (or note its absence to create it). Parse all current learnings.\n2. **Gather the candidate** from the declared `--source` (see Capture Sources below). Every candidate must yield three things before it can be written: the **rule** (imperative), the **why** (rationale that lets it generalize), and the **polarity** (`DO` adds a check, `DO-NOT` forbids a pattern, `FALSE-POSITIVE` suppresses a known wrong flag).\n3. **Generalize, then scope.** Lift the candidate from the specific line to the issue *class*. Assign the narrowest `Scope` glob that captures the class. If a similar learning already exists, treat this as a `MODIFY`, not a duplicate `ADD`.\n4. **Build the CHANGESET** for user confirmation: `ADD` \u002F `MODIFY` \u002F `DEPRECATE` lists. Show the why for each. Do not write any entry the user has not confirmed.\n5. **Apply and echo.** Write confirmed changes, update the `\u003C!-- updated: DATE -->` header, and print a `Learnings added` confirmation block listing exactly what changed — making the behavioral change explicit (the CodeRabbit pattern). Append a one-line entry to the file's change log.\n\n6. **Codex project-instructions prompt.** The *first* time the file is created (it did not exist before this run), print the activation reminder so the learnings actually reach future reviews:\n   ```text\n   To activate these learnings for future Codex sessions, add a short instruction\n   to AGENTS.md or CODEX.md telling agents to read docs\u002Freview-learnings.md before\n   implementation reviews.\n   ```\n   Print it only on first creation, not on every incremental update — repeating it each run is noise.\n\n### Mode: list — Display Current Learnings\n\nPrint the active learnings (optionally filtered by `--target` glob or category). Show deprecated entries only when explicitly asked. Useful before a review to sanity-check what the reviewer will apply.\n\n### Mode: curate — Deprecate Stale \u002F Contradictory Learnings\n\n1. Read the file. Identify candidates: contradictory pairs, learnings whose `Scope` glob no longer matches any file, or entries the user reports as no longer wanted.\n2. Present a `DEPRECATE` list with the reason for each. On confirmation, mark with `~~strikethrough~~` and a `> deprecated YYYY-MM-DD: \u003Creason \u002F superseded-by #ID>` note. Never hard-delete — the history of *why* a rule was abandoned is itself a learning.\n\n## Capture Sources (`--source` in update mode)\n\n| Source | What it harvests | How |\n|---|---|---|\n| `feedback` (default) | A correction the user gave on a review finding — \"that was a false positive because X\" \u002F \"always flag Y because Z\" | Take the user's reason verbatim as the *why*; classify polarity; confirm scope |\n| `review` | Confirmed recurring findings from a just-completed `ywc-impl-review` | Promote a finding the reviewer is confident about (especially one that recurs) into a `DO`\u002F`DO-NOT` learning so it is caught earlier next time |\n| `pr` | Bot review comments (CodeRabbit \u002F Codex) on a specific PR | `--pr \u003Cn>`; fetch via `gh`, keep only **accepted \u002F resolved-by-fix** comments as `DO` learnings and **explicitly dismissed** ones (with the dismissal reason) as `FALSE-POSITIVE` learnings. A comment that was neither accepted nor dismissed is not yet a learning |\n\nThe detailed harvest procedure for `--source pr` (the `gh` query and the accept-vs-dismiss classification) is in [references\u002Fcapture-sources.md](references\u002Fcapture-sources.md).\n\nThe `--source mining` handoff accepts only a complete, user-confirmed changeset\nfrom `ywc-mine-review-history`: each cluster must include its generalized rule,\nwhy, polarity, target scope, representative evidence, and a list of distinct PR\nnumbers supporting the recurrence. The miner is a producer and has no durable\nwrite authority; this skill remains the sole owner of project-local writes.\n\n## Output Format\n\nThe full learnings-file specification is in [references\u002Flearning-format.md](references\u002Flearning-format.md).\n\n**`docs\u002Freview-learnings.md` (file) summary:**\n\n```markdown\n# Review Learnings — [Project Name]\n\n\u003C!-- updated: YYYY-MM-DD -->\n\n## How this file is used\nLoaded by ywc-impl-review before review; each entry records what + WHY + polarity.\n\n## Learnings\n| ID | Scope | Category | Polarity | Rule | Why | Provenance |\n|----|-------|----------|----------|------|-----|-----------|\n| L001 | `**\u002F*.sql` | Security | DO | Every query on an ownership-scoped table includes the owner-key predicate | App-layer filtering fails open the moment one query forgets WHERE owner_id=? | PR#42 finding, 2026-06-13 |\n| L002 | `**\u002F*.test.ts` | Test | FALSE-POSITIVE | Do not flag a top-level `await` in test setup as a missing-await bug | Vitest supports top-level await in setup files; flagging it is noise | dismissed PR#51, 2026-06-13 |\n```\n\n**Applicable Learnings block (read-mode emission, injected into reviewers):**\n\n```text\n## Applicable Review Learnings (3)\n[Security] DO — Every query on an ownership-scoped table includes the owner-key predicate.\n   why: app-layer filtering fails open if one query forgets the WHERE clause. (L001, **\u002F*.sql)\n[Test] FALSE-POSITIVE — Do NOT flag top-level await in test setup files.\n   why: the runtime supports it; flagging is noise. (L002, **\u002F*.test.ts)\n```\n\n**`Learnings added` confirmation (update-mode emission):**\n\n```text\n✦ Learnings added (1 ADD, 0 MODIFY, 1 DEPRECATE)\n  + L007 [Performance\u002FDO, src\u002Fapi\u002F**] — Batch N+1 ORM reads behind a single query.\n        why: per-row queries in a request loop dominate p95 latency under load.\n  ~ L003 deprecated — superseded by L007 (was scoped too narrowly to src\u002Fapi\u002Fusers.ts).\n```\n\n## Validation\n\nBefore declaring complete:\n\n- [ ] Every active learning has a non-empty `Why` (rationale, not a restatement of the rule)\n- [ ] Every learning has a `Polarity` of exactly `DO`, `DO-NOT`, or `FALSE-POSITIVE`\n- [ ] Every `Scope` is the narrowest glob that captures the class (no gratuitous `repo`-wide scope)\n- [ ] No two **active** learnings contradict each other (the older was deprecated, not left to coexist)\n- [ ] The user confirmed the CHANGESET before any write (no inferred-and-written entries)\n- [ ] `docs\u002Freview-learnings.md` is parseable Markdown with no broken table rows\n- [ ] `\u003C!-- updated: DATE -->` header reflects today's date\n- [ ] A `Learnings added` confirmation was printed for update mode\n- [ ] On first file creation, the AGENTS.md \u002F CODEX.md integration prompt was printed\n\n## Common Mistakes\n\n- **Recording the rule without the why** — the single most common failure. A why-less learning cannot generalize and is indistinguishable from an overfit nitpick; the reviewer either ignores it or misapplies it.\n- **Deleting a dismissed finding instead of recording it as `FALSE-POSITIVE`** — the reviewer has no memory of the dismissal and re-raises the same noise every PR. Capture the dismissal *with its reason*.\n- **One learning per finding** — produces an unscannable file and overfits. Generalize to the class.\n- **Over-broad scope** — `repo`-wide learnings that only apply to one language create cross-language review noise. Scope tightly.\n- **Writing without confirmation** — an unconfirmed learning silently changes every future review on the matching glob.\n\n## Integration\n\n- **Upstream**: `ywc-impl-review` (Step 0 calls this skill in `read` mode; a post-review step calls it in `update --source review`), `ywc-handle-pr-reviews` (a dismissed bot comment can feed `update --source pr`)\n- **Downstream**: `ywc-impl-review` consumes the read-mode Applicable Learnings block; project instructions can also tell Codex sessions to read `docs\u002Freview-learnings.md` before implementation reviews\n- **Pairs with**: `ywc-ubiquitous-language` — same per-project-knowledge-file architecture (read\u002Fupdate modes, user-confirmed writes), different content domain (review preferences vs domain vocabulary)\n- **Do not confuse with**: `ywc-receive-review` (discipline for *responding* to review feedback) — this skill *stores* the durable lesson that feedback produced\n","# ywc-review-learnings\n\n**Announce at start:** \"I'm using the ywc-review-learnings skill to read or update the project's accumulated review learnings.\"\n\nThis skill produces or maintains `docs\u002Freview-learnings.md` — a per-project, accumulating memory of code-review preferences that makes every future review sharper. It is the runtime-agnostic version of the CodeRabbit \"learnings\" idea: instead of relying on a hosted bot's internal database, the learnings live as a committed, human-editable Markdown file that `ywc-impl-review` loads before reviewing. Each learning records not just *what* to do but *why*, so it generalizes to similar-but-not-identical situations rather than degrading into a brittle keyword match.\n\nIt operates in four modes: **read** (load learnings applicable to a review target), **update** (capture new learnings from feedback, recurring findings, or harvested bot comments), **list** (display current learnings), and **curate** (deprecate stale or contradictory learnings).\n\n## Rationalization Defense\n\nWhen tempted to bypass a rule, check this table first:\n\n| Excuse | Reality |\n|---|---|\n| \"Record the rule, the WHY is obvious — skip it\" | The *why* is the whole value. Without it the learning cannot be applied to a similar-but-different case, and a future reader (or LLM) cannot tell a real rule from an overfit one. A learning with no rationale is a keyword match waiting to misfire. |\n| \"This finding was rejected as a false positive — just delete the learning\" | Deleting loses the lesson; the reviewer will re-flag it next PR. Record it as a `FALSE-POSITIVE` polarity learning **with the reason it was wrong**, so the reviewer stops raising it. CodeRabbit's precision comes from remembering *why* a comment was rejected, not just that it was. |\n| \"Append the new learning without reading the file\" | Appending blind creates duplicate and contradictory entries. Always read the full `docs\u002Freview-learnings.md` before any write, and check whether the pattern is already captured. |\n| \"One learning per individual finding is most precise\" | One-per-finding overfits to a single line and floods the file. Generalize to the *class* of issue (the pattern + the why), scoped to the narrowest glob that captures it. |\n| \"This contradicts an old learning — keep both, let the reviewer decide\" | Two contradictory learnings make the reviewer's behavior non-deterministic. Newest-wins: deprecate the old entry with a pointer to the new one (`~~strikethrough~~` + note), never silently delete. |\n| \"Write the learnings without user confirmation, I inferred the intent\" | An unconfirmed learning pollutes *every* future review on the matching glob. Always present the proposed ADD \u002F MODIFY \u002F DEPRECATE set for one confirmation round before writing. |\n| \"Scope it `repo`-wide so it always applies\" | Over-broad scope is the main source of review noise — a TypeScript naming rule applied to `*.sql` is pure friction. Scope to the narrowest file glob that captures the real pattern; reserve `repo` for genuinely universal conventions. |\n\n**Violating the letter of these rules is violating the spirit.** A learnings file full of unconfirmed, why-less, or over-scoped entries degrades review quality on every PR that touches a matching path — the opposite of its purpose.\n\n## Arguments\n\n| Parameter | Format | Default | Description |\n|-----------|--------|---------|-------------|\n| `--mode` | `--mode read\\|update\\|list\\|curate` | auto-detect | Force a specific mode (see Mode Detection below) |\n| `--target` | `--target \u003Cglob\\|path...>` | changed files | Review-target paths\u002Fglobs whose applicable learnings should be loaded (`read`) or attributed (`update`) |\n| `--source` | `--source feedback\\|review\\|pr\\|mining` | `feedback` | Where a new learning comes from in `update` mode (see Capture Sources) |\n| `--pr` | `--pr \u003Cnumber>` | — | With `--source pr`, harvest bot (CodeRabbit \u002F Codex) review comments from this PR via `gh` and distill them into learnings. Optional convenience — never required |\n| `--output` | `--output \u003Cpath>` | `docs\u002Freview-learnings.md` | Learnings file path |\n| `--dry-run` | flag | off | Show the proposed CHANGESET without writing to disk |\n\n### Mode Detection (when `--mode` is omitted)\n\n| Condition | Auto-selected mode |\n|---|---|\n| Invoked by a review skill with a target, file exists | `read` |\n| User is describing feedback on a finding (\"this was wrong because…\", \"always flag…\") | `update` |\n| File absent, user wants to start accumulating | `update` (creates the file with the first learning) |\n| User asks \"what review learnings exist?\" | `list` |\n\n## Workflow\n\n### Mode: read — Load Applicable Learnings\n\nInvoked before a review (typically by `ywc-impl-review` Step 0).\n\n1. **Read the file.** If `docs\u002Freview-learnings.md` is absent, return an empty applicable set and say so — never block a review on a missing learnings file.\n2. **Match by scope.** For each learning, include it if its `Scope` glob matches at least one path in `--target` (or any changed file when `--target` is omitted). `repo`-scoped learnings always match. Skip `deprecated` entries.\n3. **Emit a compact applicable block** in the [Applicable Learnings format](#output-format) — grouped by category, each line carrying the rule, the why, and the polarity (`DO` \u002F `DO-NOT` \u002F `FALSE-POSITIVE`). This block is what the caller injects into each reviewer subagent prompt. Keep it tight; a reviewer that drowns in learnings reviews worse, not better.\n\n### Mode: update — Capture a New Learning\n\n1. **Read the existing file** in full (or note its absence to create it). Parse all current learnings.\n2. **Gather the candidate** from the declared `--source` (see Capture Sources below). Every candidate must yield three things before it can be written: the **rule** (imperative), the **why** (rationale that lets it generalize), and the **polarity** (`DO` adds a check, `DO-NOT` forbids a pattern, `FALSE-POSITIVE` suppresses a known wrong flag).\n3. **Generalize, then scope.** Lift the candidate from the specific line to the issue *class*. Assign the narrowest `Scope` glob that captures the class. If a similar learning already exists, treat this as a `MODIFY`, not a duplicate `ADD`.\n4. **Build the CHANGESET** for user confirmation: `ADD` \u002F `MODIFY` \u002F `DEPRECATE` lists. Show the why for each. Do not write any entry the user has not confirmed.\n5. **Apply and echo.** Write confirmed changes, update the `\u003C!-- updated: DATE -->` header, and print a `Learnings added` confirmation block listing exactly what changed — making the behavioral change explicit (the CodeRabbit pattern). Append a one-line entry to the file's change log.\n\n6. **Codex project-instructions prompt.** The *first* time the file is created (it did not exist before this run), print the activation reminder so the learnings actually reach future reviews:\n   ```text\n   To activate these learnings for future Codex sessions, add a short instruction\n   to AGENTS.md or CODEX.md telling agents to read docs\u002Freview-learnings.md before\n   implementation reviews.\n   ```\n   Print it only on first creation, not on every incremental update — repeating it each run is noise.\n\n### Mode: list — Display Current Learnings\n\nPrint the active learnings (optionally filtered by `--target` glob or category). Show deprecated entries only when explicitly asked. Useful before a review to sanity-check what the reviewer will apply.\n\n### Mode: curate — Deprecate Stale \u002F Contradictory Learnings\n\n1. Read the file. Identify candidates: contradictory pairs, learnings whose `Scope` glob no longer matches any file, or entries the user reports as no longer wanted.\n2. Present a `DEPRECATE` list with the reason for each. On confirmation, mark with `~~strikethrough~~` and a `> deprecated YYYY-MM-DD: \u003Creason \u002F superseded-by #ID>` note. Never hard-delete — the history of *why* a rule was abandoned is itself a learning.\n\n## Capture Sources (`--source` in update mode)\n\n| Source | What it harvests | How |\n|---|---|---|\n| `feedback` (default) | A correction the user gave on a review finding — \"that was a false positive because X\" \u002F \"always flag Y because Z\" | Take the user's reason verbatim as the *why*; classify polarity; confirm scope |\n| `review` | Confirmed recurring findings from a just-completed `ywc-impl-review` | Promote a finding the reviewer is confident about (especially one that recurs) into a `DO`\u002F`DO-NOT` learning so it is caught earlier next time |\n| `pr` | Bot review comments (CodeRabbit \u002F Codex) on a specific PR | `--pr \u003Cn>`; fetch via `gh`, keep only **accepted \u002F resolved-by-fix** comments as `DO` learnings and **explicitly dismissed** ones (with the dismissal reason) as `FALSE-POSITIVE` learnings. A comment that was neither accepted nor dismissed is not yet a learning |\n\nThe detailed harvest procedure for `--source pr` (the `gh` query and the accept-vs-dismiss classification) is in [references\u002Fcapture-sources.md](references\u002Fcapture-sources.md).\n\nThe `--source mining` handoff accepts only a complete, user-confirmed changeset\nfrom `ywc-mine-review-history`: each cluster must include its generalized rule,\nwhy, polarity, target scope, representative evidence, and a list of distinct PR\nnumbers supporting the recurrence. The miner is a producer and has no durable\nwrite authority; this skill remains the sole owner of project-local writes.\n\n## Output Format\n\nThe full learnings-file specification is in [references\u002Flearning-format.md](references\u002Flearning-format.md).\n\n**`docs\u002Freview-learnings.md` (file) summary:**\n\n```markdown\n# Review Learnings — [Project Name]\n\n\u003C!-- updated: YYYY-MM-DD -->\n\n## How this file is used\nLoaded by ywc-impl-review before review; each entry records what + WHY + polarity.\n\n## Learnings\n| ID | Scope | Category | Polarity | Rule | Why | Provenance |\n|----|-------|----------|----------|------|-----|-----------|\n| L001 | `**\u002F*.sql` | Security | DO | Every query on an ownership-scoped table includes the owner-key predicate | App-layer filtering fails open the moment one query forgets WHERE owner_id=? | PR#42 finding, 2026-06-13 |\n| L002 | `**\u002F*.test.ts` | Test | FALSE-POSITIVE | Do not flag a top-level `await` in test setup as a missing-await bug | Vitest supports top-level await in setup files; flagging it is noise | dismissed PR#51, 2026-06-13 |\n```\n\n**Applicable Learnings block (read-mode emission, injected into reviewers):**\n\n```text\n## Applicable Review Learnings (3)\n[Security] DO — Every query on an ownership-scoped table includes the owner-key predicate.\n   why: app-layer filtering fails open if one query forgets the WHERE clause. (L001, **\u002F*.sql)\n[Test] FALSE-POSITIVE — Do NOT flag top-level await in test setup files.\n   why: the runtime supports it; flagging is noise. (L002, **\u002F*.test.ts)\n```\n\n**`Learnings added` confirmation (update-mode emission):**\n\n```text\n✦ Learnings added (1 ADD, 0 MODIFY, 1 DEPRECATE)\n  + L007 [Performance\u002FDO, src\u002Fapi\u002F**] — Batch N+1 ORM reads behind a single query.\n        why: per-row queries in a request loop dominate p95 latency under load.\n  ~ L003 deprecated — superseded by L007 (was scoped too narrowly to src\u002Fapi\u002Fusers.ts).\n```\n\n## Validation\n\nBefore declaring complete:\n\n- [ ] Every active learning has a non-empty `Why` (rationale, not a restatement of the rule)\n- [ ] Every learning has a `Polarity` of exactly `DO`, `DO-NOT`, or `FALSE-POSITIVE`\n- [ ] Every `Scope` is the narrowest glob that captures the class (no gratuitous `repo`-wide scope)\n- [ ] No two **active** learnings contradict each other (the older was deprecated, not left to coexist)\n- [ ] The user confirmed the CHANGESET before any write (no inferred-and-written entries)\n- [ ] `docs\u002Freview-learnings.md` is parseable Markdown with no broken table rows\n- [ ] `\u003C!-- updated: DATE -->` header reflects today's date\n- [ ] A `Learnings added` confirmation was printed for update mode\n- [ ] On first file creation, the AGENTS.md \u002F CODEX.md integration prompt was printed\n\n## Common Mistakes\n\n- **Recording the rule without the why** — the single most common failure. A why-less learning cannot generalize and is indistinguishable from an overfit nitpick; the reviewer either ignores it or misapplies it.\n- **Deleting a dismissed finding instead of recording it as `FALSE-POSITIVE`** — the reviewer has no memory of the dismissal and re-raises the same noise every PR. Capture the dismissal *with its reason*.\n- **One learning per finding** — produces an unscannable file and overfits. Generalize to the class.\n- **Over-broad scope** — `repo`-wide learnings that only apply to one language create cross-language review noise. Scope tightly.\n- **Writing without confirmation** — an unconfirmed learning silently changes every future review on the matching glob.\n\n## Integration\n\n- **Upstream**: `ywc-impl-review` (Step 0 calls this skill in `read` mode; a post-review step calls it in `update --source review`), `ywc-handle-pr-reviews` (a dismissed bot comment can feed `update --source pr`)\n- **Downstream**: `ywc-impl-review` consumes the read-mode Applicable Learnings block; project instructions can also tell Codex sessions to read `docs\u002Freview-learnings.md` before implementation reviews\n- **Pairs with**: `ywc-ubiquitous-language` — same per-project-knowledge-file architecture (read\u002Fupdate modes, user-confirmed writes), different content domain (review preferences vs domain vocabulary)\n- **Do not confuse with**: `ywc-receive-review` (discipline for *responding* to review feedback) — this skill *stores* the durable lesson that feedback produced\n",{"name":5,"description":7},"main","7e8ac872e53df8c89d75663e031626281a2a2f5c","plugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings",1,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit","https:\u002F\u002Fgithub.com\u002Fyongwoon","https:\u002F\u002Fwww.webhani.com","2026-11-08 17:14:59",{"source":8,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add yongwoon\u002Fywc-agent-toolkit --skill ywc-review-learnings",{"tool":37,"command":38},"bunx","bunx skills add yongwoon\u002Fywc-agent-toolkit --skill ywc-review-learnings",{"tool":40,"command":41},"pnpm","pnpm dlx skills add yongwoon\u002Fywc-agent-toolkit --skill ywc-review-learnings","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002FSKILL.md",true,[45,51,55,59,63,67,71,74,78,82],{"path":46,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":49,"sourceHtmlUrl":50},"agents\u002Fopenai.yaml","REFERENCE","参考文档",300,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002Fagents\u002Fopenai.yaml",{"path":52,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":53,"sourceHtmlUrl":54},"evals\u002Fevals.json",4096,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002Fevals\u002Fevals.json",{"path":56,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":57,"sourceHtmlUrl":58},"README.en.md",3681,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002FREADME.en.md",{"path":60,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":61,"sourceHtmlUrl":62},"README.es.md",3368,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002FREADME.es.md",{"path":64,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":65,"sourceHtmlUrl":66},"README.ja.md",4181,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002FREADME.ja.md",{"path":68,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":69,"sourceHtmlUrl":70},"README.ko.md",4139,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002FREADME.ko.md",{"path":72,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":69,"sourceHtmlUrl":73},"README.md","https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002FREADME.md",{"path":75,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":76,"sourceHtmlUrl":77},"README.zh.md",3088,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002FREADME.zh.md",{"path":79,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002Fcapture-sources.md",4404,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002Freferences\u002Fcapture-sources.md",{"path":83,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":84,"sourceHtmlUrl":85},"references\u002Flearning-format.md",4871,"https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-review-learnings\u002Freferences\u002Flearning-format.md",[87,93,99,106,113,120],{"skillNo":88,"name":89,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":92,"publishedAt":18},"01M72TQ84GTCPCV2VJ778V17TW","missing-frontmatter","https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fcodex-description-limit\u002Fmissing-frontmatter\u002FSKILL.md",[],[],{"skillNo":94,"name":95,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":98,"publishedAt":18},"01M72TQ6M4BFWE7P9EPW0GZDCM","malformed-frontmatter","https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fcodex-description-limit\u002Fmalformed-frontmatter\u002FSKILL.md",[],[],{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":18},"01M72TQ3ESGKXZ4QRWGTX92BKJ","fixture-501-fail","(ywc) Use when aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Do not use for x.","https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fcodex-description-limit\u002F501-fail\u002FSKILL.md",[],[],{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":18},"01M72TQ0HJ8H3R37J9WPWGKJZR","fixture-500-pass","(ywc) Use when aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Do not use for x.","https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fcodex-description-limit\u002F500-pass\u002FSKILL.md",[],[],{"skillNo":114,"name":115,"nameZh":6,"description":116,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":18},"01M72TPWNCC7NEYD0D9N12KSQS","ywc-worktrees","(ywc) Use when creating, auditing, pruning, or resolving git worktrees for isolated task workspaces, whether delegated from an executor or used standalone. Triggers: \"worktree 생성\", \"worktree audit\", \"worktree 정리\", \"worktree prune\", \"ywc-worktrees\", \"create worktree\". Do not use for branch creation\u002Fdeletion alone, PR creation (use ywc-create-pr), CI or merge delivery (use ywc-finish-branch), task orchestration (use ywc-sequential-executor or ywc-parallel-executor), or non-git isolation.","https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-worktrees\u002FSKILL.md",[],[],{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":18},"01M72TPRNR3E6QWB91GM98ABBV","ywc-wayfinder","(ywc) Use when a large or uncertain change needs multi-session discovery with a deterministic local map and exactly one active ticket before planning or implementation. Triggers: \"wayfinder\", \"길찾기\", \"discovery map\", \"multi-session discovery\", \"탐색 ticket\", \"経路整理\", \"探索マップ\", \"ywc-wayfinder\". Do not use for ordinary planning (use ywc-plan), idea clarification (use ywc-brainstorm), direct implementation, or tracker\u002Fdatabase writes outside the local Markdown map.","https:\u002F\u002Fgithub.com\u002Fyongwoon\u002Fywc-agent-toolkit\u002Fblob\u002Fmain\u002Fplugins\u002Fywc-agent-toolkit\u002Fskills\u002Fywc-wayfinder\u002FSKILL.md",[],[]]