@olegkoval/agent-skills 1.43.1 → 1.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/adapters/claude/olko-github-pr/skills/lekker-review/SKILL.md +85 -2
  2. package/adapters/claude/olko-github-pr/skills/lekker-review/references/pricing.json +9 -0
  3. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-conventions.md +158 -0
  4. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-implementation.md +76 -0
  5. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-quality.md +87 -0
  6. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-simplification.md +63 -0
  7. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-test-quality.md +172 -0
  8. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/phase4-comparison.md +42 -0
  9. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/profile.md +347 -0
  10. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/profiles/lekker-deep.md +82 -0
  11. package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/profiles/lekker-medium.md +81 -0
  12. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/fixtures/context.json +3 -0
  13. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/fixtures/house-rules.md +11 -0
  14. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/fixtures/revmux-report.json +179 -0
  15. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/install-revmux-prompts.sh +66 -0
  16. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/revmux-adapter.mjs +261 -0
  17. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/revmux-engine.sh +156 -0
  18. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/selftest.mjs +76 -0
  19. package/package.json +1 -1
  20. package/plugins/olko-apple-kit/.claude-plugin/plugin.json +1 -1
  21. package/plugins/olko-creative/.claude-plugin/plugin.json +1 -1
  22. package/plugins/olko-garmin-kit/.claude-plugin/plugin.json +1 -1
  23. package/plugins/olko-git-tools/.claude-plugin/plugin.json +1 -1
  24. package/plugins/olko-github-pr/.claude-plugin/plugin.json +1 -1
  25. package/plugins/olko-github-pr/skills/lekker-review/SKILL.md +85 -2
  26. package/plugins/olko-github-pr/skills/lekker-review/references/pricing.json +9 -0
  27. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-conventions.md +158 -0
  28. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-implementation.md +76 -0
  29. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-quality.md +87 -0
  30. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-simplification.md +63 -0
  31. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-test-quality.md +172 -0
  32. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/phase4-comparison.md +42 -0
  33. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/profile.md +347 -0
  34. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/profiles/lekker-deep.md +82 -0
  35. package/plugins/olko-github-pr/skills/lekker-review/references/revmux/profiles/lekker-medium.md +81 -0
  36. package/plugins/olko-github-pr/skills/lekker-review/scripts/fixtures/context.json +3 -0
  37. package/plugins/olko-github-pr/skills/lekker-review/scripts/fixtures/house-rules.md +11 -0
  38. package/plugins/olko-github-pr/skills/lekker-review/scripts/fixtures/revmux-report.json +179 -0
  39. package/plugins/olko-github-pr/skills/lekker-review/scripts/install-revmux-prompts.sh +66 -0
  40. package/plugins/olko-github-pr/skills/lekker-review/scripts/revmux-adapter.mjs +261 -0
  41. package/plugins/olko-github-pr/skills/lekker-review/scripts/revmux-engine.sh +156 -0
  42. package/plugins/olko-github-pr/skills/lekker-review/scripts/selftest.mjs +76 -0
  43. package/plugins/olko-github-pr/skills/lekker-review/workflow.js +43 -6
  44. package/plugins/olko-obsidian/.claude-plugin/plugin.json +1 -1
  45. package/plugins/olko-product/.claude-plugin/plugin.json +1 -1
  46. package/plugins/olko-reflection/.claude-plugin/plugin.json +1 -1
  47. package/plugins/olko-release/.claude-plugin/plugin.json +1 -1
  48. package/plugins/olko-skill-meta/.claude-plugin/plugin.json +1 -1
  49. package/plugins/olko-web-ops/.claude-plugin/plugin.json +1 -1
@@ -56,6 +56,10 @@ FAANG-grade code review. Isolated worktree checkout, full context gathering
56
56
  you have MCP tools configured for), then 5 parallel specialized review
57
57
  agents, a finding-verification pass, and one unified markdown output.
58
58
 
59
+ An optional `--engine revmux` flag can replace the Step 2 Workflow-tool pipeline
60
+ with revmux (profiles and lenses under `references/revmux/`); default stays
61
+ `workflow`, and both engines feed the same Step 3 synthesis.
62
+
59
63
  Two modes, same review engine:
60
64
 
61
65
  | Mode | Target | Entry |
@@ -233,6 +237,12 @@ in Step 4. Use it for a read-only pre-push look.
233
237
  **`--no-artifact` flag:** parse and store as `ARTIFACT=false` (default true).
234
238
  Skips Step 3.5 (living review artifact) silently.
235
239
 
240
+ **`--engine revmux|workflow` flag:** parse and store as `ENGINE`, default
241
+ `workflow`. `revmux` is allowed only at depth `medium` or `deep` - revmux's
242
+ scripts reject `scan` (see Depth gate). If depth resolves to `scan` (explicit
243
+ or auto), force `ENGINE=workflow` regardless of the flag and note `engine
244
+ forced to workflow - revmux needs medium/deep` in the review header.
245
+
236
246
  **Re-review detection:** run
237
247
  `ls ~/code-reviews/*-<TARGET_SLUG>-<repo-short-name>.md 2>/dev/null | sort | tail -1`
238
248
  (`TARGET_SLUG` = `pr-<PR_NUMBER>` in pr mode, `branch-<LOCAL_BRANCH sanitized to
@@ -421,7 +431,9 @@ their prompts wholesale - the workflow script delivers it by path.
421
431
 
422
432
  ---
423
433
 
424
- ## Step 2 - Workflow (review + verify + critic)
434
+ ## Step 2 - Review engine (review + verify + critic)
435
+
436
+ ### ENGINE=workflow (default)
425
437
 
426
438
  Invoke the Workflow tool:
427
439
 
@@ -500,12 +512,61 @@ provers on `sonnet`, housekeeping on `haiku`. Only the synthesis in Step 3 runs
500
512
  on the session model.
501
513
 
502
514
  Return value from the workflow:
503
- `{findings, droppedCount, downgradedCount, hardRuleCount, proveAttemptCount, provenCount, acCoverage, coverageVerdict, mutationSlip, mockSmells, agentCount, outputTokens, turnTokensTotal}`
515
+ `{engine, findings, droppedCount, downgradedCount, hardRuleCount, proveAttemptCount, provenCount, acCoverage, coverageVerdict, mutationSlip, mockSmells, agentCount, outputTokens, turnTokensTotal}`
504
516
  `outputTokens` is this workflow's own output spend; `turnTokensTotal` is the
505
517
  whole turn's shared pool (main loop included).
506
518
 
507
519
  Wait for the workflow to complete before proceeding to Step 3.
508
520
 
521
+ ### ENGINE=revmux
522
+
523
+ revmux replaces Review, Dedup, Verify, and Critic with its own multi-agent
524
+ round; Prove still runs inside `workflow.js`. Steps:
525
+
526
+ 1. `TASK_SLUG` = `<repo-short-name>-<TARGET_SLUG>`, `RUN` = `01-review`.
527
+ 2. Run the engine:
528
+
529
+ ```bash
530
+ ${CLAUDE_PLUGIN_ROOT}/scripts/revmux-engine.sh \
531
+ --task <TASK_SLUG> --run <RUN> --depth <depth> \
532
+ --workdir <worktreePath> \
533
+ --diff-file <scratchpad>/pr.diff \
534
+ --context-file <scratchpad>/context.json \
535
+ --profile-file ${CLAUDE_PLUGIN_ROOT}/references/revmux/profile.md \
536
+ --config-dir ~/.config/revmux \
537
+ --out <scratchpad>/revmux.json
538
+ ```
539
+
540
+ 3. Adapt the report:
541
+
542
+ ```bash
543
+ node ${CLAUDE_PLUGIN_ROOT}/scripts/revmux-adapter.mjs \
544
+ <scratchpad>/revmux.json --pricing \
545
+ ${CLAUDE_PLUGIN_ROOT}/references/pricing.json \
546
+ --context <scratchpad>/context.json \
547
+ > <scratchpad>/findings.json
548
+ ```
549
+
550
+ 4. Invoke Workflow(`workflow.js`) with the same args as the `ENGINE=workflow`
551
+ path above, plus `engine: "revmux"` and
552
+ `findingsFile: "<scratchpad>/findings.json"`. It skips Review/Dedup/
553
+ Verify/Critic, runs Prove only, and its return adds `engine, questions,
554
+ agents, degraded, totalTokens, totalUsd` on top of the usual keys.
555
+ 5. **Fallback to `ENGINE=workflow` for this run** when either holds: the
556
+ engine script exits `2` (tool error - also raised for a missing profile
557
+ file, the codex guard, or an unsupported depth), or every row in the
558
+ adapter's `agents` array has `degraded: true`. State the fallback in the
559
+ review header (`**Note:** revmux unavailable - fell back to workflow
560
+ engine`) and re-run the `ENGINE=workflow` path from the top of Step 2.
561
+
562
+ **Trust boundary:** always pass `--config-dir ~/.config/revmux` explicitly.
563
+ Without it revmux also reads the reviewed repo's checked-in `.revmux/`, which
564
+ is executed as prompts. `~/.config/revmux` is where
565
+ `scripts/install-revmux-prompts.sh` puts the lekker profiles and lenses; run it
566
+ with `--check` when the engine exits 2 complaining about a missing profile. The task archive lives under the tasks dir
567
+ (`LEKKER_REVMUX_TASKS_DIR`, default `~/code-reviews/revmux-tasks`) and is not
568
+ committed anywhere.
569
+
509
570
  ---
510
571
 
511
572
  ## Step 3 - Synthesize and output
@@ -601,6 +662,17 @@ requirements:
601
662
  cost. Input tokens are estimated (diff tokens x agent passes + context
602
663
  + prompt files). Use the pricing table in `references/output-format.md`.
603
664
  Real numbers only - no `<N>` placeholders.
665
+ When `ENGINE=revmux`: build the rows from the adapter's `agents` array
666
+ (`name`, `model`, `tokens`, `usd` per row) and report `totalUsd` as the
667
+ total. Read `pricingMissing`; when it is non-empty, explicitly mark `totalUsd`
668
+ as incomplete and name the unpriced models. State plainly that the USD figures are an API list-price estimate
669
+ computed from `references/pricing.json`'s placeholder prices
670
+ (`verified: false`) until that file is verified against real invoices.
671
+ Prove-phase tokens still come from the workflow return's `outputTokens`,
672
+ same as the workflow engine. When `questions` (from the adapter) is
673
+ non-empty, render them under a `## Questions for the author` section. When
674
+ `degraded` is non-empty, add one banner line in the review header naming
675
+ the degraded agents, e.g. `⚠️ degraded: implementation, test-quality`.
604
676
 
605
677
  **Save the review:**
606
678
 
@@ -858,6 +930,17 @@ do verification inline per `references/agents/verifier.md`, and state this
858
930
  fallback in the review output under a
859
931
  `**Note:** Workflow tool unavailable - ran agents directly` line in the header.
860
932
 
933
+ - `ENGINE=revmux` specific: on an exit-2 from `revmux-engine.sh`, or an
934
+ adapter report where every agent came back `degraded`, fall back to
935
+ `ENGINE=workflow` for that run (Step 2) rather than retrying revmux - this
936
+ is a fallback, not a retry loop, so it does not count against the
937
+ two-identical-failures rule above.
938
+ - Never delete or rename anything under the revmux tasks dir
939
+ (`LEKKER_REVMUX_TASKS_DIR`, default `~/code-reviews/revmux-tasks`). A
940
+ duplicate run name (same `TASK_SLUG`/`RUN` pair) is revmux's own hard
941
+ error, by design - pick the next `NN-...` name (e.g. `03-...`) rather than
942
+ clearing the old one.
943
+
861
944
  Fix-mode specific:
862
945
  - Never claim a fix landed without a `git log` / `git status` receipt from the
863
946
  worktree. The review's proposed `fix` text is not an applied fix.
@@ -0,0 +1,9 @@
1
+ {
2
+ "note": "USD per million tokens, keyed by revmux's actual_model. revmux runs `claude --print` under subscription (Max plan) auth, so nothing here is a real API bill; this is an API-list-price ESTIMATE for the cost block only. Where a model exposes separate input/output prices, usd = tokens/1e6 * output price (output-only, not blended), because revmux reports a single combined `tokens` figure per agent with no input/output split to weight a blend. verified:false entries are not confirmed against a current price sheet (no local claude-api pricing doc found on this machine as of 2026-09-09) and must be checked before this cost block is trusted for a real decision.",
3
+ "claude-opus-5": { "input": 15, "output": 75, "blended": 45, "verified": false },
4
+ "claude-sonnet-5": { "input": 3, "output": 15, "blended": 9, "verified": false },
5
+ "claude-haiku-4-5-20251001": { "input": 1, "output": 5, "blended": 3, "verified": false },
6
+ "opus": { "input": 15, "output": 75, "blended": 45, "verified": false },
7
+ "sonnet": { "input": 3, "output": 15, "blended": 9, "verified": false },
8
+ "haiku": { "input": 1, "output": 5, "blended": 3, "verified": false }
9
+ }
@@ -0,0 +1,158 @@
1
+ ---
2
+ description: deviations from Teifi's own codebase conventions — the "strong teammate" non-blocking lens
3
+ ---
4
+ ## Lens: lekker-conventions
5
+
6
+ Review the change for deviations from Teifi's established codebase
7
+ conventions and idioms. This is the "strong teammate" lens: the suggestions a
8
+ senior Teifi engineer leaves — non-blocking, but they make the code match how
9
+ the rest of the codebase is written. Look beyond the diff only for
10
+ convention-specific precedent and reuse searches. Other lenses may inspect the
11
+ runtime context they need for their own cross-file checks.
12
+
13
+ Read `{{PROFILE}}` now, before forming any opinion — it carries the Teifi
14
+ conventions text. Its §1 (naming matrix), §2 (comment policy), §5 (commit
15
+ hygiene) and §6 (generated code) are yours — they are the house style, so a
16
+ deviation needs NO codebase precedent beyond that file (the file IS the
17
+ precedent; cite the section, e.g. "teifi-conventions §1 verbs").
18
+ Everything else in this lens still requires a cited precedent from the code.
19
+
20
+ Axes to cover:
21
+ - Naming (teifi-conventions §1): every symbol the diff INTRODUCES against the
22
+ matrix — boolean without `is`/`has`, async I/O named `get`, a row lock or a
23
+ throw-on-miss or a cache read absent from the name (`…ForUpdate`,
24
+ `…OrThrow`, `…Cached`), a collidable component without its domain prefix, a
25
+ bare generic noun (`line`, `node`, `row`) where the domain has two variants in
26
+ scope. NEVER flag a boundary name (DB column, GraphQL/oRPC field, enum value,
27
+ route string, wire key) — renaming it breaks callers outside the diff.
28
+ - Comments (teifi-conventions §2): one finding per over-commenting offender the
29
+ diff ADDED, with the deletion as the fix. Never a vague "too many comments",
30
+ never a pre-existing comment, never a lint/type pragma or a genuine
31
+ non-obvious "why".
32
+ - Generated code (teifi-conventions §6): a changed `.sql` / `.graphql` /
33
+ `.json` schema / `prisma/schema.prisma` whose generated artifact is absent
34
+ from the diff (or the reverse) — major. Raise NO naming, comment, or
35
+ complexity finding inside a `generated/` directory. A hand-rolled `fetch` to
36
+ the Shopify Admin GraphQL endpoint instead of the genql client — major.
37
+ - Commits (teifi-conventions §5): non-conventional or vague commit subjects, and
38
+ any Claude Code / assistant mention in the commit or PR text.
39
+ - Type-system idioms:
40
+ * A hand-written interface/type that duplicates an existing Zod schema —
41
+ should be `z.infer<typeof zSchema>` so the schema stays the single source
42
+ of truth. (Grep for a matching z-schema in the same feature folder.)
43
+ * Raw `string` used for a Shopify GID or an entity id where a branded
44
+ `ID<'Customer'>` (or similar) type exists and is used elsewhere.
45
+ * A union typed as `as readonly string[]` / a hand-rolled `is...` guard where
46
+ a `z.enum([...])` + `z.infer` would give validation, narrowing, and the
47
+ options array in one declaration.
48
+ * An unnecessary `satisfies` / redundant type annotation the compiler already
49
+ infers.
50
+ * A GID validated/parsed inline where a shared helper exists (e.g.
51
+ `zNamespacedGid`). Grep the shared libs and the repo before asserting.
52
+ - Reuse (search the worktree AND sibling Teifi repos before flagging):
53
+ * Inline fetch/client logic that should reuse — or be promoted into — a
54
+ shared client (e.g. a company-switcher client) that already exists or that
55
+ the codebase clearly wants.
56
+ * A util/helper that already exists elsewhere being re-implemented inline.
57
+ * A symbol defined locally that is (or should be) exported from a shared
58
+ module — "are we not exporting this somewhere?"
59
+ - Consistency:
60
+ * Cache-key / composite-key separators that disagree with the repo's
61
+ prevailing choice (e.g. `:` vs `::`). Grep existing key-building code to
62
+ find the prevailing pattern, then flag the deviation.
63
+ * Ad-hoc error throwing where the repo has an idiom (e.g. `throw new
64
+ HttpError('...', 403)` instead of a bare string / generic Error).
65
+ * Naming/casing that breaks the convention used by sibling files.
66
+
67
+ MANDATORY SWEEP — do this FIRST, before forming any opinion:
68
+
69
+ The axes above are symptom-driven: they only fire once you already suspect a
70
+ duplication. That is how a re-implemented helper slips through — nobody thinks to
71
+ look. So run these enumerations mechanically, whether or not anything looks wrong.
72
+
73
+ 1. **Sibling sweep for every file the diff ADDS.** For each added file, list its
74
+ directory and read the exports of its neighbours. A helper that solves the same
75
+ problem is usually sitting in the same folder.
76
+
77
+ ```bash
78
+ REVIEW_CONFIG="{{CONTEXT}}/worktree.json"
79
+ WORKTREE="$(jq -er '.worktreePath | select(type == "string" and length > 0)' "$REVIEW_CONFIG")"
80
+ BASE_REV="$(jq -er '(.mergeBase // .baseRef) | select(type == "string" and length > 0)' "$REVIEW_CONFIG")"
81
+ REPO_ROOT="$(jq -er '.repoRoot | select(type == "string" and length > 0)' "$REVIEW_CONFIG")"
82
+ SIBLING_ROOT="$(dirname "$REPO_ROOT")"
83
+
84
+ git -C "$WORKTREE" diff --name-status "$BASE_REV"...HEAD | awk '$1=="A"{print $2}' |
85
+ while IFS= read -r added_file; do
86
+ added_dir="$WORKTREE/$(dirname "$added_file")"
87
+ ls -la "$added_dir" # what already lives beside it
88
+ grep -rn "^export " "$added_dir"/*.ts "$added_dir"/*.tsx 2>/dev/null |
89
+ grep -v -F -- "$added_file"
90
+ done
91
+ grep -rn "^export " "$SIBLING_ROOT" --include='*.ts' --include='*.tsx' \
92
+ --exclude-dir=node_modules 2>/dev/null
93
+ ```
94
+
95
+ A new `foo/bar-thing.ts` next to an existing `foo/thing.ts` is a finding waiting
96
+ to happen. Read the neighbour, do not just note its name.
97
+
98
+ 2. **New-symbol sweep.** For every function/const the diff exports, search the repo
99
+ for something that already does that job, by BEHAVIOUR not just by name. Names
100
+ rarely match; behaviour does.
101
+
102
+ ```bash
103
+ git -C "$WORKTREE" diff --unified=0 "$BASE_REV"...HEAD | \
104
+ grep '^+' | grep -E 'export (function|const) ' # collect new symbols
105
+ # then for each, search by what it does, e.g. a locale normaliser:
106
+ grep -rln "toLowerCase()\|normalize\|isoCode\|split('-')" "$WORKTREE" \
107
+ --include='*.ts' --include='*.tsx'
108
+ ```
109
+
110
+ Pick 2 or 3 behavioural keywords from the new function's body and grep those.
111
+ Reviewing the diff alone cannot catch this.
112
+
113
+ 3. **State what you swept.** In your output, name the directories you listed and the
114
+ behavioural greps you ran, even when they found nothing. A sweep that is not
115
+ reported did not happen, and the next reviewer cannot tell "no duplication exists"
116
+ from "nobody looked".
117
+
118
+ HARD RULES:
119
+ - Only raise a finding when the better pattern PROVABLY ALREADY EXISTS. Cite it:
120
+ the file:line where the helper/type/convention lives, or the sibling file that
121
+ does it the idiomatic way. If you cannot find a concrete precedent, DROP the
122
+ finding — "this would be nicer as X" on taste alone is not allowed.
123
+ - Every finding must still trace to a `+` line in the diff (the deviation must
124
+ be code this change added/changed). The supporting precedent may live outside the
125
+ diff; the deviation may not.
126
+ - These are suggestions, not blockers. Do not inflate severity. Report each as
127
+ `file:line — <deviation> (precedent: <file:line of the existing pattern>)`.
128
+ - ONE EXCEPTION to non-blocking: if the re-implementation DIVERGES in behaviour
129
+ from the helper it duplicates, that is not a style nit, it is two spellings of
130
+ the same value that disagree, and it belongs on lekker-quality's severity
131
+ scale rather than this lens's. Diff the two implementations before deciding:
132
+ same inputs, same outputs? If a real input produces different results, say so
133
+ explicitly and give the input.
134
+
135
+ To find precedents, you may run:
136
+
137
+ ```bash
138
+ grep -rn "<symbol or pattern>" "$WORKTREE" --include='*.ts' --include='*.tsx'
139
+ find "$SIBLING_ROOT" \( -name "*.ts" -o -name "*.tsx" \) ! -path "*/node_modules/*" \
140
+ | xargs grep -l "<symbol>" 2>/dev/null | head
141
+ ```
142
+
143
+ Always include *.tsx. Extension and frontend code lives in .tsx, so a search that
144
+ omits it silently reports "no precedent exists" for whole directories.
145
+
146
+ A mined record of what other bots (Greptile / Gemini / CodeRabbit) have
147
+ commented on in this repo may be present under `{{CONTEXT}}`. Use it as a prior,
148
+ not as a checklist: a high count means "frequently raised here", not "correct" —
149
+ never raise a finding because a bot once said it, only because it is true here.
150
+
151
+ Rules:
152
+ - Report file:line — description with a precedent citation. No positive
153
+ observations. No taste-only suggestions.
154
+ - Quote the verbatim offending line(s) — never paraphrased, never reconstructed
155
+ from memory — and give a concrete drop-in fix, or when the fix is
156
+ architectural, a minimal skeleton plus one sentence on what else must change.
157
+ - A finding you cannot quote and cannot fix is a finding you have not proven —
158
+ drop it instead.
@@ -0,0 +1,76 @@
1
+ ---
2
+ description: correctness, scalability and integration issues — Teifi's GQL-1 hard rule included
3
+ ---
4
+ ## Lens: lekker-implementation
5
+
6
+ Review the change for correctness, scalability, and integration issues.
7
+
8
+ Axes to cover:
9
+ - Business Logic / AC coverage: for each acceptance criterion available in
10
+ `{{CONTEXT}}` (a ticket's AC list, when present), mark met / partial / missing.
11
+ Scope creep is also worth flagging.
12
+ Decide each AC against the code that RUNS, not against the diff. Use the
13
+ worktree (`{{WORKDIR}}`) to follow the AC through its runtime path into files
14
+ the diff never touched, and specifically:
15
+ (a) Find what invokes the new code and on what trigger. New code that nothing
16
+ calls satisfies nothing, however correct its body is.
17
+ (b) For an AC with a timing, cadence or SLA component, name the trigger's real
18
+ frequency (the cron expression, the poll interval, the webhook) and compare
19
+ that number against the AC. A reaper on a daily cron cannot meet a two-hour
20
+ SLA.
21
+ (c) For an AC about a failure mode (crash, OOM, timeout, network loss), confirm
22
+ the handling is reachable under that failure. A killed process never reaches
23
+ a `finally` block, a shutdown hook, or the tail of a long-running function.
24
+ An AC can fail with every added line correct, because the defect is what the
25
+ diff left alone. That is a finding, not an absence of one.
26
+ - Binding scoping decisions: when `{{CONTEXT}}` names a resolved flag from the
27
+ ticket's Dev Scoping Session, a diff that contradicts it is major (critical
28
+ when it changes external behaviour or data shape); quote the decision text.
29
+ - Scalability: N+1 queries, missing pagination, unbounded in-memory
30
+ collections, missing rate-limit handling, cron jobs without overlap guard,
31
+ missing DB indexes for new query patterns.
32
+ - Time/Space Complexity: O(n²) where linear exists, large payloads in memory,
33
+ sort/dedup on large arrays that could be done at DB level.
34
+ - Integration Contracts: Shopify API misuse, BC API assumptions, webhook
35
+ idempotency, external API pagination not handled.
36
+ - GraphQL pagination (GQL-1): for every GraphQL query in the diff that uses a
37
+ nodes connection (`nodes { ... }`):
38
+ (a) Check that `pageInfo { hasNextPage endCursor }` is present alongside nodes — if missing, critical.
39
+ (b) Check that all pages are fetched (a loop or recursion using endCursor) — a single-page fetch is a bug, critical.
40
+ (c) Check the page size: must be 250 (Shopify max). If any other size is used without a code comment explaining why, flag as major.
41
+ Title any critical finding under this axis `[GQL-1] ...`.
42
+ - Feature-flag rollout (Reflag repos ONLY): first check the repo actually uses
43
+ Reflag — a `package.json` (any depth, excluding node_modules) depending on
44
+ `@reflag/node-sdk` or `@teifi-digital/reflag-client`. If it does not, SKIP this
45
+ axis entirely and raise nothing; a repo with no flag client cannot act on the
46
+ finding. Where it does apply, ask whether the change should ship behind a flag:
47
+ (a) a client should validate it before everyone sees it; (b) it changes data
48
+ shape or what gets written; (c) it touches orders, money, or fulfilment; (d) it
49
+ cannot be verified without real client data or volume. Do NOT raise it for pure
50
+ UI/copy with no data change, a bug fix that is strictly better and obviously
51
+ correct, internal/admin-only surfaces, or work fully covered by tests and
52
+ verifiable in staging. Tie-breaker: if you would not be comfortable fixing it
53
+ forward at 2am, it needs a flag. Name which of (a)-(d) applies.
54
+ Severity: major at most, usually minor — this is a rollout judgement call, not
55
+ a defect. NEVER title this with a bracketed hard-rule tag (that would force
56
+ critical and imply a policy violation). Never invent a concrete flag key as
57
+ though it exists: flag keys must be confirmed against Reflag, so say a flag is
58
+ needed without naming one.
59
+ Also raise as a structural concern (severity major) when a diff BOTH adds a
60
+ column/table AND changes what is read or written — the SOP requires splitting
61
+ that into expand / migrate / read-switch / contract PRs. Name the split.
62
+
63
+ GQL-1's full rule text lives in `{{PROFILE}}` — read it there before applying it.
64
+
65
+ Rules:
66
+ - Every finding must trace to a `+` line in the diff, with one exception: an
67
+ unmet AC whose defect lives in code the diff did not touch. Anchor that one to
68
+ the unchanged file:line that had to change, and say in the description why the
69
+ unchanged line is the defect. That line may be an unchanged one — do not drop
70
+ an unmet AC for lack of a quotable added line.
71
+ - Report file:line — description. No positive observations.
72
+ - Quote the verbatim offending line(s) — never paraphrased, never reconstructed
73
+ from memory — and give a concrete drop-in fix, or when the fix is
74
+ architectural, a minimal skeleton plus one sentence on what else must change.
75
+ - A finding you cannot quote and cannot fix is a finding you have not proven —
76
+ drop it instead.
@@ -0,0 +1,87 @@
1
+ ---
2
+ description: quality, security and data-integrity issues — Teifi's TS-1/TS-2 hard rules included
3
+ ---
4
+ ## Lens: lekker-quality
5
+
6
+ Review the change for quality, security, and data-integrity issues.
7
+
8
+ Axes to cover:
9
+ - Data Integrity: missing transactions on multi-step writes, optimistic
10
+ concurrency without locking, partial-failure with no rollback, silent data
11
+ loss in batch loops.
12
+ - Security: SQL/command injection, auth bypass, missing permission checks,
13
+ IDOR, secrets in logs, webhook signature not verified.
14
+ When the diff touches a controller, a route, or an auth decorator, do NOT hand-roll the
15
+ decorator grep. Use the `route-auth-map` skill, which already does exactly this and prints
16
+ method/path/controller/guards plus an explicit unguarded-endpoint section. If the Skill tool
17
+ is unavailable to you, read `~/.claude/skills/route-auth-map/SKILL.md` and follow its steps.
18
+ Compare the map before and after the diff: a route that gains a handler but no guard, or
19
+ loses `@Authenticated`/`@Permission`, is critical.
20
+ - Error Handling: unhandled promise rejections, empty catch blocks, missing
21
+ retries on transient failures, no dead-letter for failed jobs.
22
+ - Catch-block exit paths: when the diff adds or edits a branch inside a `catch`,
23
+ enumerate EVERY way control leaves that block - each early return, each
24
+ rethrow, and the fall-through - and say what the client sees on each. A new
25
+ branch that changes what gets logged or reported, while leaving a rethrow or
26
+ fall-through reachable for the same condition, is a finding: the error is now
27
+ silent AND still escapes. Do not accept "it reports correctly" as covering the
28
+ block; the report and the control flow are separate claims.
29
+ - Schema/Migration: NOT NULL without default, rename without two-step,
30
+ pgtyped queries invalidated, Prisma client out of sync.
31
+ - Naming/Typos: wrong casing convention, mixed conventions in same scope,
32
+ misspelled identifiers (these are bugs-in-waiting).
33
+ - Derived-value consistency: when the diff introduces a transform of some input
34
+ (normalise, trim, lowercase, parse, clamp, default), grep EVERY other use of
35
+ that raw input in the same scope and check they all go through the transform.
36
+ Half-applied transforms are a classic near-miss: the value is normalised at the
37
+ call site but the raw one is still used in a React dependency array, a cache
38
+ key, a log line, an equality check, or a second call site. Two spellings of the
39
+ "same" value then disagree. Enumerate the uses; do not eyeball the hunk.
40
+
41
+ ```bash
42
+ grep -n "<rawIdentifier>" <file> # every use, then confirm each is intended
43
+ ```
44
+
45
+ - Env vars: dead vars, renamed without migration, wrong fallback operator
46
+ (?? vs ||), type mismatch, leaked in logs.
47
+ - TypeScript type safety (TS-1): flag every type cast (`as X`, `<X>expr`)
48
+ and every use of `any`. Test files: only flag blatantly omitted types
49
+ (e.g. `any[]` on a clearly-typed list). All others: critical. Quote the
50
+ cast, explain the correct type, show the fix. Ask if they're Harry Potter.
51
+ Title the finding `[TS-1] ...`.
52
+ - No JavaScript files (TS-2): if the diff adds any `.js` file to a non-Liquid
53
+ theme repo, flag as critical — must be `.ts`. Title the finding `[TS-2] ...`.
54
+ - Dependency changes. Skip this axis entirely unless the diff touches
55
+ `package.json`, a lockfile, or a vendored dependency. Where it applies:
56
+ (a) A version bump is a behaviour change nobody in this PR wrote. If neither
57
+ the PR body nor a commit message cites the changelog or migration notes,
58
+ that is major: semver is a promise the maintainer may not have kept,
59
+ and a "patch" can carry a behavioural change.
60
+ (b) A bulk bump of several unrelated packages in one PR is major. When
61
+ it breaks the build you have lost which package did it. The fix is to
62
+ split it per package, or per genuinely related group.
63
+ (c) A `package.json` dependency change with no matching lockfile change in the
64
+ same diff, or a lockfile change with no `package.json` change and no
65
+ explanation, is critical: the lockfile is what actually ships.
66
+ (d) A new direct dependency that duplicates something already in the stack is
67
+ major. Name the existing thing that already solves it.
68
+ Raise NO naming, comment, complexity, or TS-1 finding inside a lockfile or a
69
+ `node_modules` path.
70
+
71
+ TS-1 and TS-2 are Teifi hard rules: their text is defined in full in `{{PROFILE}}`
72
+ (read it there before applying either). A finding for one of them MUST have its
73
+ title start with the bracketed tag, e.g. `[TS-1] ...` or `[TS-2] ...`, so the
74
+ caller can recognize it as a policy violation rather than an ordinary finding.
75
+
76
+ CI status, Sentry signals, and existing reviews may be present in `{{CONTEXT}}` —
77
+ read what is there before forming an opinion, and skip anything that is absent
78
+ rather than treating its absence as a finding.
79
+
80
+ Rules:
81
+ - Every finding must trace to a `+` line in the diff.
82
+ - Report file:line — description. No positive observations.
83
+ - Quote the verbatim offending line(s) from the diff — never paraphrased, never
84
+ reconstructed from memory — and give a concrete drop-in fix, or when the fix
85
+ is architectural, a minimal skeleton plus one sentence on what else must change.
86
+ - A finding you cannot quote and cannot fix is a finding you have not proven —
87
+ drop it instead of reporting it as a minor observation with no evidence.
@@ -0,0 +1,63 @@
1
+ ---
2
+ description: over-engineering and DRY violations, plus Teifi's debug-artifact hygiene table
3
+ ---
4
+ ## Lens: lekker-simplification
5
+
6
+ Review the change for over-engineering and DRY violations.
7
+
8
+ Look for:
9
+ - Copy-paste logic: identical blocks that differ only in a constant — flag
10
+ for extraction.
11
+ - Parallel implementations: two functions doing the same thing — one should
12
+ call the other.
13
+ - Unnecessary abstraction inversion: private helper called exactly once, adds
14
+ no reuse — should be inlined.
15
+ - Over-engineered control flow: nested ternaries / promise chains that could
16
+ be plain if/else or async/await.
17
+ - Config spread: same magic constant defined in multiple files.
18
+ - Debug artifacts and hygiene: apply the fixed severity table in §3 of
19
+ `{{PROFILE}}` (the Teifi conventions section) — `debugger` and
20
+ `.only`/`fit`/`fdescribe` are critical, an added `console.log`/`console.debug`
21
+ in production code and a hardcoded URL are major, an unreferenced
22
+ TODO/FIXME and a >3-line commented-out block are minor. Those severities
23
+ are fixed: do not soften them, and only flag occurrences the diff ADDED.
24
+ - Wrapper that adds nothing, factory for single implementation, layer-cake
25
+ anti-pattern (handler → service → repo with no logic in any layer).
26
+ - Feature flags always on/off, fallback that can never trigger, dual
27
+ implementations where old has no callers.
28
+ - Relocated complexity: a refactor that moves code without reducing the number
29
+ of concepts a reader must hold to follow it. Count them before and after. If
30
+ the count is unchanged, the restructuring did not simplify anything, and the
31
+ finding is that a cheaper move was available (deleting a branch, a mode, or a
32
+ layer outright, rather than re-centralising the same logic). Major when
33
+ the change is sold as a cleanup or refactor, minor otherwise.
34
+ - Feature logic in a shared module: feature-specific behaviour added to a
35
+ general-purpose util, a shared client, or a base class. The branch belongs in
36
+ the package that owns the concept. Name the owning layer in the fix.
37
+ - Dead code this diff orphans: when the diff replaces or reroutes something,
38
+ grep the worktree for remaining callers of what it superseded (the old helper,
39
+ the old component, a now-unreferenced constant, a flag that can no longer be
40
+ false). Enumerate what is now unreachable. NEVER propose a silent deletion:
41
+ the fix lists the orphans and asks the author to confirm removal.
42
+ Minor, or major when the dead path is still reachable from production code.
43
+
44
+ Only flag where duplication or complexity creates a real maintenance risk or
45
+ bug surface — not aesthetic preference.
46
+
47
+ When you flag a structural problem, name the move, not just the smell: replace a
48
+ chain of conditionals with a typed model or an explicit dispatcher, collapse
49
+ duplicate branches into one flow, separate orchestration from business logic,
50
+ move feature logic into the package that owns it, reuse the canonical helper
51
+ instead of a near-duplicate, delete a pass-through wrapper. Prefer the remedy
52
+ that removes moving pieces over one that spreads the same complexity around. A
53
+ finding that says "this is complex" without naming the restructuring is not
54
+ actionable: name the move or drop the finding.
55
+
56
+ Rules:
57
+ - Every finding must trace to a `+` line in the diff.
58
+ - Report file:line — description. No positive observations.
59
+ - Quote the verbatim offending line(s) — never paraphrased, never reconstructed
60
+ from memory — and give a concrete drop-in fix, or when the fix is
61
+ architectural, a minimal skeleton plus one sentence on what else must change.
62
+ - A finding you cannot quote and cannot fix is a finding you have not proven —
63
+ drop it instead.