@olegkoval/agent-skills 1.43.0 → 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.
- package/adapters/claude/olko-github-pr/skills/lekker-review/SKILL.md +85 -2
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/pricing.json +9 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-conventions.md +158 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-implementation.md +76 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-quality.md +87 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-simplification.md +63 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-test-quality.md +172 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/phase4-comparison.md +42 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/profile.md +347 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/profiles/lekker-deep.md +82 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/revmux/profiles/lekker-medium.md +81 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/fixtures/context.json +3 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/fixtures/house-rules.md +11 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/fixtures/revmux-report.json +179 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/install-revmux-prompts.sh +66 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/revmux-adapter.mjs +261 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/revmux-engine.sh +156 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/selftest.mjs +76 -0
- package/package.json +1 -1
- package/plugins/olko-apple-kit/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-creative/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-garmin-kit/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-git-tools/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-github-pr/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-github-pr/skills/lekker-review/SKILL.md +85 -2
- package/plugins/olko-github-pr/skills/lekker-review/references/pricing.json +9 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-conventions.md +158 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-implementation.md +76 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-quality.md +87 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-simplification.md +63 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/lenses/lekker-test-quality.md +172 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/phase4-comparison.md +42 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/profile.md +347 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/profiles/lekker-deep.md +82 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/revmux/profiles/lekker-medium.md +81 -0
- package/plugins/olko-github-pr/skills/lekker-review/scripts/fixtures/context.json +3 -0
- package/plugins/olko-github-pr/skills/lekker-review/scripts/fixtures/house-rules.md +11 -0
- package/plugins/olko-github-pr/skills/lekker-review/scripts/fixtures/revmux-report.json +179 -0
- package/plugins/olko-github-pr/skills/lekker-review/scripts/install-revmux-prompts.sh +66 -0
- package/plugins/olko-github-pr/skills/lekker-review/scripts/revmux-adapter.mjs +261 -0
- package/plugins/olko-github-pr/skills/lekker-review/scripts/revmux-engine.sh +156 -0
- package/plugins/olko-github-pr/skills/lekker-review/scripts/selftest.mjs +76 -0
- package/plugins/olko-github-pr/skills/lekker-review/workflow.js +43 -6
- package/plugins/olko-obsidian/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-product/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-reflection/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-release/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-skill-meta/.claude-plugin/plugin.json +1 -1
- 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 -
|
|
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.
|