@openora/create 0.4.1-canary.34 → 0.4.1-canary.35

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 (29) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/generated/core-version.d.ts +1 -1
  3. package/dist/generated/core-version.js +1 -1
  4. package/package.json +3 -3
  5. package/template/__dot__gitignore +1 -1
  6. package/template/__dot__rulesync/commands/adr.md +32 -0
  7. package/template/__dot__rulesync/commands/check.md +3 -3
  8. package/template/__dot__rulesync/commands/doctor.md +16 -0
  9. package/template/__dot__rulesync/hooks/guard-generated.mjs +3 -3
  10. package/template/__dot__rulesync/rules/conventions.md +134 -0
  11. package/template/__dot__rulesync/rules/e2e-conventions.md +26 -0
  12. package/template/__dot__rulesync/rules/oss-boundaries.md +31 -0
  13. package/template/__dot__rulesync/rules/overview.md +10 -1
  14. package/template/__dot__rulesync/skills/add-feature/SKILL.md +3 -3
  15. package/template/__dot__rulesync/skills/create-plugin/SKILL.md +2 -2
  16. package/template/__dot__rulesync/skills/create-pr/SKILL.md +1 -1
  17. package/template/__dot__rulesync/skills/create-ui-module/SKILL.md +58 -0
  18. package/template/__dot__rulesync/skills/review/SKILL.md +110 -0
  19. package/template/__dot__rulesync/subagents/debugger.md +1 -2
  20. package/template/__dot__rulesync/subagents/qa.md +1 -1
  21. package/template/__dot__rulesync/subagents/quality-reviewer.md +67 -0
  22. package/template/__dot__rulesync/subagents/security-reviewer.md +54 -0
  23. package/template/apps/api/package.json.tpl +1 -2
  24. package/template/package.json.tpl +4 -4
  25. package/template/rulesync.jsonc +1 -1
  26. package/template/turbo/generators/config.ts +1 -1
  27. package/template/turbo.json +14 -2
  28. package/template/__dot__rulesync/skills/code-review/SKILL.md +0 -111
  29. package/template/apps/api/src/migrate.ts.tpl +0 -46
@@ -0,0 +1,31 @@
1
+ ---
2
+ root: false
3
+ targets:
4
+ - '*'
5
+ globs:
6
+ - '**/*'
7
+ description: OSS core is read-only; enforced import/module boundaries.
8
+ ---
9
+
10
+ # OSS core + import boundaries
11
+
12
+ ## Never modify OSS core
13
+
14
+ `@openora/*` is a third-party dependency - read it for reference, never write to it.
15
+
16
+ - Do NOT edit `node_modules/**` or a linked OSS checkout. Those paths are write-denied in `.claude/settings.json`; don't route around it with `sed`, redirection, or scripts. A patched dependency is lost on reinstall and diverges from the published package.
17
+ - Extend from the OUTSIDE only: overlay plugins, adapter rebindings, UI plugins, config.
18
+ - If something can only be fixed in core, STOP and report it upstream (problem, expected behavior, likely location).
19
+
20
+ ## Import boundaries (enforced)
21
+
22
+ Enforced by `pnpm check:lint` (oxlint, per-edit), `pnpm check:boundaries` (dependency-cruiser, whole graph), the pre-commit hook, CI, and the agent PostToolUse hook. Fix the import, never work around a violation.
23
+
24
+ - No deep OSS imports: `@openora/*/src/*` or `/dist/*` - import only the published entrypoint or subpath export.
25
+ - No deep imports into your own shared packages - only the barrel/index entrypoint.
26
+ - No app-to-app imports (`apps/api` <-> `apps/web` <-> `apps/backoffice`) - extract shared code to `packages/*`.
27
+ - No cross-module imports inside an app - go through the module barrel, a query invalidation, or a domain event.
28
+ - No overlay-to-overlay imports - couple via a command port, a domain event, or a shared contract.
29
+ - No import cycles.
30
+
31
+ `pnpm check:boundaries:graph` renders the graph (needs Graphviz).
@@ -14,10 +14,17 @@ this repo. Every per-tool instruction file (`AGENTS.md` - shared, also Codex's b
14
14
  subagent and command mirrors are generated by
15
15
  [rulesync](https://github.com/dyoshikawa/rulesync) from the single source in `.rulesync/`
16
16
  (`rules/`, `subagents/`, `commands/`, `mcp.json`). Edit the source under `.rulesync/`, then
17
- run `pnpm sync:agents`. Do not hand-edit the generated files.
17
+ run `pnpm gen:agents`. Do not hand-edit the generated files.
18
18
 
19
19
  This repo is a downstream igaming operator built on the OSS platform (`@openora/*`).
20
20
 
21
+ Apply every rule file in `.rulesync/rules/`:
22
+
23
+ - `conventions` - the code standard (naming, types, functions, frontend, module + package structure, errors, testing, git).
24
+ - `oss-boundaries` - OSS core is read-only; enforced import/module boundaries.
25
+ - `db-conventions` - SQL / Drizzle rules for tables an overlay owns.
26
+ - `e2e-conventions` - dual-mode Playwright specs, fixtures, mocks, page objects.
27
+
21
28
  ## HARD RULE: never modify OSS core
22
29
 
23
30
  `@openora/*` is a third-party dependency - treat it like any published npm package. You may READ it for reference, never write to it.
@@ -72,6 +79,8 @@ Delegate work to these scoped agents - the `start` / `enhance-intent` playbooks
72
79
  - `builder` - senior fullstack engineer. Implements overlays, swaps adapters, mounts UI pages.
73
80
  - `qa` - writes/runs Playwright E2E tests; triages whether a bug is in OSS core (upstream) or your overlay (local fix).
74
81
  - `debugger` - root-causes failures, build-time (Next/Turbopack, tsc, module resolution) and runtime (Chrome DevTools: console/network/DOM). Spawn it whenever something errors or behaves wrong; it finds the cause and routes the fix.
82
+ - `quality-reviewer` - reviews a diff: boundaries, conventions, frontend rules, perf, duplication. Findings only.
83
+ - `security-reviewer` - reviews a diff: authz, secrets/PII, money paths, input validation. Findings only.
75
84
 
76
85
  This repo consumes OSS core as linked packages - never edit `@openora/*` source. If a bug is in core, report it upstream; extend from the outside via plugins.
77
86
 
@@ -4,7 +4,7 @@ name: add-feature
4
4
  description: >
5
5
  Deliver a feature end-to-end in this consumer repo. Aggregates context (Jira + Confluence + Slack +
6
6
  Google Drive + Notion + local docs + past sessions + codebase), produces an approved plan, then drives
7
- delivery by calling sibling skills - create-plugin (build), code-review (review), create-pr (MR) -
7
+ delivery by calling sibling skills - create-plugin (build), review, create-pr (MR) -
8
8
  and create-task for ticket hygiene. Transitions Jira (no comments) and drafts a one-line Slack
9
9
  notice. Use on "add feature", "plan <KEY>-XXX", "deliver <KEY>-XXX", or /add-feature [<KEY>-XXX].
10
10
  Read-only until the plan is approved; never pushes, transitions Jira, or sends Slack without OK.
@@ -33,7 +33,7 @@ re-implement their work. The platform-core twin is the `/add-feature` skill in t
33
33
  - **Read-only until the Step 3 plan is approved.** No edits, commits, pushes, Jira writes, or Slack
34
34
  sends before sign-off.
35
35
  - Reuse sibling skills, don't reinvent: **create-task** (ticket format), **create-plugin** (build an
36
- overlay), **code-review** (review), **create-pr** (MR). Delegate code to subagents.
36
+ overlay), **review** (review), **create-pr** (MR). Delegate code to subagents.
37
37
 
38
38
  ## Steps
39
39
 
@@ -82,7 +82,7 @@ When implementation starts, transition Jira to In Progress (Step 7 - confirm fir
82
82
 
83
83
  ### 5. Review + tests
84
84
 
85
- - Run **code-review** on the change set; loop `[BLOCK]`/`[WARN]` fixes back through `builder`.
85
+ - Run **review** on the change set; loop `[BLOCK]`/`[WARN]` fixes back through `builder`.
86
86
  - Run `/check` (typecheck + lint). Don't proceed on red.
87
87
  - Derive an e2e checklist from the AC (happy path, edge cases, authz negatives, error states), then
88
88
  `qa`: write/run the E2E specs, drive `chrome-devtools` on failure.
@@ -13,7 +13,7 @@ description: >
13
13
 
14
14
  The platform is extended from the **outside only** (overlay plugin / adapter rebind / UI page /
15
15
  config) - never by editing `@openora/*`. This skill picks the correct seam and scaffolds it.
16
- Domain questions go to `expert` first; review the result with `code-review`.
16
+ Domain questions go to `expert` first; review the result with `review`.
17
17
 
18
18
  ## 1. Classify the seam (ask if unclear)
19
19
 
@@ -64,7 +64,7 @@ plugins: [myCustomPspAdapter, walletModule];
64
64
 
65
65
  - `/check` (typecheck + lint) green.
66
66
  - Plugin boots (API health check / `pnpm dev`).
67
- - Hand to `code-review` before opening an MR.
67
+ - Hand to `review` before opening an MR.
68
68
 
69
69
  ## Rules
70
70
 
@@ -31,7 +31,7 @@ If the current branch isn't in the table, target `dev`.
31
31
  3. **Commit.** Conventional-commit message (`feat:`, `fix:`, `docs:`, `refactor:`,
32
32
  `chore:`); for ticket work prefix the ticket key (e.g. `feat(<KEY>-123): ...`).
33
33
  4. **Verify before pushing** (cheap insurance): run the repo's check (e.g.
34
- `pnpm typecheck && pnpm lint`). Don't push a red tree.
34
+ `pnpm check:types && pnpm check:lint`). Don't push a red tree.
35
35
  5. **Push** the current branch - but STOP and get an explicit per-action "yes push"
36
36
  from the user FIRST. Report the commit SHA, then ask. Invoking this skill is NOT
37
37
  push authorization. Pushing to a shared/env branch (`dev`, `stage`, `prod`)
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: create-ui-module
3
+ targets: ['*']
4
+ description: >
5
+ Create a frontend feature module in apps/backoffice or apps/web following ADR-0001's
6
+ modular architecture: standard folder shape, co-located locales, DI hooks, pure
7
+ components, barrel entry, route wiring. Use on "create module", "new feature module",
8
+ "add a backoffice/web module", "/create-ui-module <app> <name>".
9
+ ---
10
+
11
+ # create-ui-module (consumer)
12
+
13
+ Scaffold a feature module under `src/modules/<name>/` per ADR-0001 (`docs/adr/0001-modular-architecture.md`). The shape is lint-enforced (`tools/oxlint-module-structure.mjs`: folder structure, `use-` hook naming, kebab-case files, client-component naming). Copy an existing module as the reference - `apps/backoffice/src/modules/roles/` is canonical.
14
+
15
+ ## 1. Resolve input
16
+
17
+ `<app> <name>` from `$ARGUMENTS` (`backoffice` | `web`, kebab-case name). Ask if missing. Confirm the module doesn't exist and the concern isn't already owned by another module.
18
+
19
+ ## 2. Create the shape
20
+
21
+ ```
22
+ src/modules/<name>/
23
+ pages/<name>-page.tsx page entrypoint(s)
24
+ components/ presentational only - props in, JSX out
25
+ hooks/use-<x>.ts ALL logic/queries/mutations; deps passed as parameters
26
+ utils/ local helpers (only if needed)
27
+ locales/en.json translation keys
28
+ locales/index.ts registration (below)
29
+ index.ts public barrel - the ONLY entry other code may import
30
+ ```
31
+
32
+ `locales/index.ts` pattern (exact):
33
+
34
+ ```ts
35
+ import { registerTranslations } from '@<scope>/ui';
36
+ import en from './en.json';
37
+
38
+ export const locales = { en };
39
+ export const ns = registerTranslations('<name>', locales);
40
+ ```
41
+
42
+ Components use `useTranslation(ns)`; no hardcoded copy. Non-`en` files mirror `en.json` keys exactly.
43
+
44
+ ## 3. Wire the route
45
+
46
+ - backoffice: `src/routes/_authed/<name>.tsx` -> `createFileRoute` with `component` imported from `@/modules/<name>` (see `src/routes/_authed/roles.tsx`).
47
+ - web: the App Router page under `app/(shell)/<name>/` imports from `@/modules/<name>`; client components get `'use client'` line 1 + `.client.tsx` suffix.
48
+
49
+ ## 4. Non-negotiables
50
+
51
+ - No cross-module imports - cross-module effects go through query cache invalidation, never a direct import.
52
+ - Outside code imports ONLY the barrel via `@/modules/<name>`; inside the module use relative paths.
53
+ - Hooks take their clients (oRPC/API) as parameters (see `roles/hooks/use-iam-client-deps.ts`) so they're testable without global mocks.
54
+ - Follow the conventions rule's Frontend + Modular architecture sections (daisyUI, theme tokens, hoisted `styles` const, React Compiler - no manual memo).
55
+
56
+ ## 5. Verify
57
+
58
+ `/check` green (the structure lint runs inside `pnpm check:lint`); route renders (`pnpm dev`). Hand to `review` before an MR.
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: review
3
+ targets: ['*']
4
+ description: Multi-agent code review of the working branch against this repo's conventions, OSS-core boundaries, frontend rules, security, and operator-domain fit. Fans out a configurable number of parallel reviewers, each grounded in the rule docs, then synthesizes one verdict. Use on "review this", "code review", "/review", optionally "--agents N", "--base <ref>", "--fix", "--post" (publish findings to the MR as inline comments + a summary verdict), "--yes" (post without confirming), a GitLab MR number, or paths.
5
+ ---
6
+
7
+ # review
8
+
9
+ You are the orchestrator: scope the diff, fan out N reviewers across dimensions, dedup findings, report ONE verdict. Report-only unless `--fix`.
10
+
11
+ Checklist - tick as you go:
12
+
13
+ ```
14
+ - [ ] 1. Parse args (--agents / --base / MR# / paths / --fix / --post / --yes)
15
+ - [ ] 2. Scope the diff; if empty, ask
16
+ - [ ] 3. Collect task context (ticket AC + MR discussion)
17
+ - [ ] 4. Pick applicable dimensions; small diff -> review inline, else spawn reviewers in ONE message
18
+ - [ ] 5. Dedup + apply the evidence gate
19
+ - [ ] 6. Report one verdict (+ apply fixes only if --fix)
20
+ - [ ] 7. Post to the MR as inline comments + summary (only if --post)
21
+ ```
22
+
23
+ ## 1. Parse `$ARGUMENTS`
24
+
25
+ - `--agents N` - parallel reviewers (1-5); default one per applicable dimension.
26
+ - `--base <ref>` - diff base; default `dev`.
27
+ - `<number>` - a GitLab MR: `glab mr diff <n>` for the patch, `glab mr view <n>` for intent.
28
+ - paths - restrict review to those files/dirs.
29
+ - `--fix` - apply BLOCK/WARN fixes after the review; default report-only.
30
+ - `--post` - publish findings to the GitLab MR as inline diff-line comments + a one-line summary verdict (§8). Requires an MR number. Draft-and-confirm by default.
31
+ - `--yes` - with `--post`, skip the confirmation and publish straight away.
32
+
33
+ ## 2. Scope the diff
34
+
35
+ `git diff <base>...HEAD --name-only`; if empty, fall back to `git status -s`; if still empty, ask. Group changed files by app/package so reviewers and any file-split share the same map. Note the total changed-line count - it picks the mode in §4.
36
+
37
+ ## 2b. Collect task context
38
+
39
+ Distill everything here into ONE context block of at most ~30 lines; it is the only task context reviewers receive.
40
+
41
+ - **Ticket.** Extract the BF key from the branch name / MR title. Fetch it (Atlassian MCP or REST) and distill: goal in one line + acceptance criteria as bullets. No key or no access: skip silently.
42
+ - **MR discussion.** If reviewing an MR: `glab mr view <n>` + unresolved discussion threads. Distill to stated intent + open reviewer asks, so the review doesn't repeat or contradict them. No MR: use branch commit subjects as intent.
43
+ - The AC bullets feed the verdict (§7) - a finding "AC not met" needs a specific bullet.
44
+
45
+ ## 3. Ground every reviewer (mandatory)
46
+
47
+ Each reviewer MUST read the changed code AND the rule docs owning its dimension before judging - never infer behavior from a diff hunk; if a finding depends on a called function, open it. Cite the docs in findings:
48
+
49
+ - `.claude/rules/conventions.md` - the code standard, incl. the Frontend and Modular-architecture sections (React Compiler, daisyUI, module isolation).
50
+ - `.claude/rules/oss-boundaries.md` - OSS core read-only; enforced import boundaries.
51
+ - `.claude/rules/db-conventions.md` - SQL/Drizzle rules for overlay tables.
52
+ - `.claude/rules/workflow.md` + `.claude/rules/overview.md` - how this repo operates.
53
+
54
+ ## 4. Dimensions
55
+
56
+ Dimensions and the roster agent that owns each - never `general-purpose`:
57
+
58
+ 1. **Boundaries, conventions, frontend, perf, duplication** - `quality-reviewer` (its prompt carries the full lens checklists; always applicable).
59
+ 2. **Security & secrets** - `security-reviewer`; only if overlay routes, adapters, auth/session, env/config, or money-adjacent code changed.
60
+ 3. **Operator/domain fit** - `expert`; only if business logic changed AND AC exists to judge against.
61
+
62
+ **Small-diff fast path (<= 150 changed lines): no subagents.** Read the changed files in the main thread and apply the applicable agents' checklists yourself (they live in `.claude/agents/<name>.md` - skim, don't spawn). This is the common case and costs a fraction of a fan-out.
63
+
64
+ ## 5. Allocate to `--agents N` (large diffs only)
65
+
66
+ - N unset: one reviewer per applicable dimension.
67
+ - N > dimensions: extras are additional `quality-reviewer` instances split by file group (state the split; never silently drop files).
68
+ - N < dimensions: drop `expert` first, then merge security into quality (say so in the report).
69
+
70
+ Spawn all reviewers in a SINGLE message (parallel). Pass each: the changed-file list for its dimension (pre-grouped - reviewers never re-scope), the base ref, the §2b context block, and hard caps: read only changed files + immediate callees; max 10 findings; compact `[SEV] file:line - finding - evidence - fix` lines, no prose; do NOT run `/check`/tests.
71
+
72
+ ## 6. Evidence gate (cut false positives)
73
+
74
+ Every reviewer applies this before returning; re-apply it yourself when synthesizing:
75
+
76
+ - Every `[BLOCK]`/`[WARN]` cites a concrete `file:line` AND the rule doc violated - otherwise downgrade to `[INFO]` or drop.
77
+ - High-confidence findings only; unsure = downgrade or omit. Few actionable findings beat flooding.
78
+ - No invented runtime failures - state the trigger path or don't raise it.
79
+ - Don't duplicate what tooling enforces (oxlint, the `/check` gate); for a suspected lint/boundary issue say "confirm with `pnpm check:lint`" - flag only what the gates miss.
80
+
81
+ ## 7. Synthesize
82
+
83
+ Dedup by `file:line`, group by dimension, order BLOCK -> WARN -> INFO. Each line: `[SEV] file:line - finding - evidence - rule cited - fix`. Lead with a one-line summary (counts per severity + verdict); end with **APPROVED** / **CHANGES REQUESTED** + the single most critical finding.
84
+
85
+ Severities: `[BLOCK]` must fix before merge (core edit, boundary break, authz/secret/PII risk, broken extension wiring); `[WARN]` should fix (convention violation, missing test, weak validation); `[INFO]` FYI / hardening.
86
+
87
+ If `--fix`: apply BLOCK + WARN fixes in the working tree (smallest diff satisfying the cited rule), run `/check`, report green/red. Leave INFO untouched. Never commit or push.
88
+
89
+ ## 8. Post to the MR (`--post`)
90
+
91
+ Only when `--post` is set and the target is an MR number. Turns findings into terse review comments: one line each, brief why, backtick every identifier.
92
+
93
+ Post BLOCK + WARN as inline threads; include INFO only if it maps to a concrete `file:line`. One comment per finding, one line each.
94
+
95
+ 1. **Draft.** Rewrite each finding as a terse comment keyed to its `file:line`. Compose the summary as ONE sentence stating whether the changes block prod/push, e.g. `Not a blocker for push - a few cleanups worth doing.` or `Blocker: BLOCK finding in `x.ts` must be fixed before we push.`
96
+ 2. **Confirm.** Show all drafted comments + the summary and stop for approval - UNLESS `--yes`, then skip straight to posting.
97
+ 3. **Post inline comments** as positional discussions on the diff. Mechanics + gotchas are in the Notion memory `glab MR inline diff-line comments (positional discussions)` (query the Memories DB) - the short of it:
98
+ - Diff SHAs from `glab api "projects/consumer%2Fconsumer/merge_requests/<n>" | jq .diff_refs`.
99
+ - Anchor on the NEW-file line of an added (`+`) line (`git show <src-branch>:<file> | grep -n`).
100
+ - POST JSON (build with Python `json.dumps` to dodge quoting) to `.../merge_requests/<n>/discussions` with a `position` object; `glab api -H "Content-Type: application/json" ... --input -`. Do NOT use `-f "position[...]"` - nested params silently drop the position.
101
+ - Verify each response's `.notes[0].position.new_line`; if null it fell back to a general note - delete (`glab api -X DELETE .../notes/<id>`) and retry.
102
+ 4. **Post the summary** as one general MR note (`glab mr note <n> -m "<one sentence>"`).
103
+ 5. Report back the count posted + the summary verdict. Never resolve threads; never push.
104
+
105
+ ## Constraints
106
+
107
+ - Reviewers report; only the orchestrator edits, and only under `--fix` (working tree only - no commit, no push).
108
+ - NEVER edit `@openora/*` core or `node_modules`.
109
+ - Every finding cites a rule doc - no ungrounded opinions.
110
+ - Cap at 5 parallel reviewers.
@@ -26,7 +26,7 @@ Reproduce deterministically with a build, not the dev server (dev caches aggress
26
26
 
27
27
  ```bash
28
28
  pnpm -C apps/web exec next build # or apps/backoffice
29
- pnpm typecheck
29
+ pnpm check:types
30
30
  ```
31
31
 
32
32
  Common consumer-side causes (this stack links `@openora/*` from a sibling checkout):
@@ -35,7 +35,6 @@ Common consumer-side causes (this stack links `@openora/*` from a sibling checko
35
35
  | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
36
36
  | `Module not found: Can't resolve '@openora/...'` but `node -e "require.resolve(...)"` works | A bundler won't compile across the link: boundary (packages live outside the project root) | point the bundler's project root at the common ancestor of your frontend repo and the OSS checkout, and allow imports from outside the root (eg Next.js `turbopack.root` + `experimental.externalDir: true`). |
37
37
  | `extends "@openora/tsconfig/..." doesn't resolve` | An `extends` chain through a symlinked tsconfig | the `@openora/tsconfig` configs must be self-contained (no `extends`) |
38
- | Resolves but won't import | `@openora/*` not built | run `pnpm build:oss` |
39
38
  | Stale error after a fix | Turbopack cache | `rm -rf apps/*/.next` and rebuild |
40
39
 
41
40
  To confirm a resolution issue is the bundler (not a missing dep):
@@ -23,7 +23,7 @@ The OSS platform is headless (API + modules only) - the player app and backoffic
23
23
  | Player app | http://localhost:3000 | operator |
24
24
  | Backoffice | http://localhost:3002 | operator |
25
25
 
26
- Seed credentials (after `pnpm seed`): `admin@oss.dev` / `password123`
26
+ Seed credentials (after `pnpm db:seed`): `admin@oss.dev` / `password123`
27
27
 
28
28
  Confirm actual ports and which UIs exist with the operator - they may have only an API, or a single combined app.
29
29
 
@@ -0,0 +1,67 @@
1
+ ---
2
+ targets:
3
+ - '*'
4
+ name: quality-reviewer
5
+ description: >-
6
+ Code-quality review of changed files: OSS-core boundaries, conventions,
7
+ frontend rules, performance, duplication, and simplification in a single
8
+ pass. Findings only, no edits.
9
+ claudecode:
10
+ model: sonnet
11
+ ---
12
+
13
+ You are a senior code-quality reviewer for this consumer igaming repo (built on `@openora/*` OSS core). One pass over the changed files, several lenses. You are NOT the implementer - findings only, no changes.
14
+
15
+ ## Grounding
16
+
17
+ - Read `.claude/rules/conventions.md` IN FULL (including the Frontend and Modular-architecture sections) and enforce all of it - the lenses below are high-signal reminders, not the boundary of the review.
18
+ - For import/extension questions, `.claude/rules/oss-boundaries.md`; for overlay tables, `.claude/rules/db-conventions.md`.
19
+ - Where no repo rule covers a problem, judge by established industry practice (algorithmic complexity, DB query patterns, transaction scope, React render behavior, error-handling hygiene) and name the principle in the finding.
20
+ - Library API in doubt (Next, React, Drizzle, Zod, `@openora/*`)? Check current docs via context7/web search - never claim from memory.
21
+
22
+ ## Scope
23
+
24
+ The orchestrator passes you the base ref and changed-file list - do not re-scope the diff. Read only the changed files plus the immediate callees a finding depends on. If no file list was passed: `git diff origin/dev...HEAD --name-only`.
25
+
26
+ ## Lenses
27
+
28
+ ### OSS boundaries & extension
29
+
30
+ - [ ] No edits to `@openora/*` core or `node_modules`; extension only via `extensions.config.ts`, overlay plugins, adapters.
31
+ - [ ] No deep imports into core internals - package/subpath entries only.
32
+ - [ ] Overlay talks to platform data via the typed client, events, or read-only `/schema` - never another module's internals.
33
+
34
+ ### Conventions
35
+
36
+ - [ ] Types inferred from schemas/contracts (`z.infer`, `$inferSelect`) - no hand-written duplicates; derive with `.pick/.omit/.extend`.
37
+ - [ ] Single source of truth for enums (values + schema + type triple); `timestamptz` for datetimes; named-object params over 3+ positionals.
38
+ - [ ] Zero-value comments flagged; missing WHY comments on genuinely surprising code flagged.
39
+
40
+ ### Frontend (`apps/web`, `apps/backoffice`, `packages/ui`)
41
+
42
+ - [ ] Module isolation per the Modular-architecture rules; no cross-module reach-ins.
43
+ - [ ] React Compiler assumptions hold (Rules of React); server state via the query lib, not raw `useEffect(fetch)`.
44
+ - [ ] daisyUI/styling conventions followed; no one-off design systems.
45
+
46
+ ### Performance
47
+
48
+ - [ ] No N+1 queries or `await` in a loop that could batch; lists paginate.
49
+ - [ ] No repeated hot-path work computable once; no unbounded reads filtered in JS.
50
+
51
+ ### Duplication & simplification
52
+
53
+ - [ ] No copy-pasted logic a helper a few files over provides - name the existing helper.
54
+ - [ ] No speculative abstraction (interface-with-one-impl, config for a constant); nested ifs flattenable with early returns; dead code introduced by the change.
55
+
56
+ ## Do NOT flag (false-positive guard)
57
+
58
+ - Anything lint/CI (`/check`, oxlint) already enforces.
59
+ - Style taste with no rule behind it (import order, naming preference, blank lines).
60
+ - Theoretical performance issues on cold/admin paths with no evidence they matter.
61
+ - Pre-existing code outside the diff, unless the change actively makes it worse.
62
+ - Missing features or scope expansion - review the change, not the roadmap.
63
+ - Speculative hardening or "might need later" abstractions.
64
+
65
+ ## Output
66
+
67
+ Max 10 findings, highest impact first. Each: `[WARN]`/`[INFO]` `file:line - finding - evidence - rule cited - fix`. Use `[BLOCK]` only for a core edit or boundary break. No prose around the list. End with **PASS** / **CHANGES REQUESTED** + one line on the most impactful finding.
@@ -0,0 +1,54 @@
1
+ ---
2
+ targets:
3
+ - '*'
4
+ name: security-reviewer
5
+ description: >-
6
+ Security review of changed overlay/frontend files for authz, secret/PII,
7
+ money-path, and input-validation risks in a real-money igaming consumer repo.
8
+ Findings only, no edits.
9
+ claudecode:
10
+ model: opus
11
+ ---
12
+
13
+ You are a security reviewer for a real-money igaming consumer repo built on `@openora/*`. Core money/auth logic lives upstream in the platform; you review what the OVERLAY adds: custom routes, adapter swaps, config, and the frontend. Findings only, no changes.
14
+
15
+ ## Grounding
16
+
17
+ If the orchestrator passed a base ref + changed-file list, use them - do not re-scope the diff. Otherwise: `git diff origin/dev...HEAD --name-only`. Read each changed file plus the immediate callees a finding depends on. Prioritize overlay plugins/routes, adapter implementations (KYC, PSP, notifications), auth/session touchpoints, and anything reading env/secrets.
18
+
19
+ ## Checklist
20
+
21
+ ### Authorization
22
+
23
+ - [ ] Overlay admin/backoffice routes enforce the platform guard - never a re-implemented role check.
24
+ - [ ] No client-supplied user id trusted for ownership decisions; caller resolved server-side.
25
+ - [ ] Frontend hides UI by role but the API is the enforcement point - flag authz that exists only client-side.
26
+
27
+ ### Money paths
28
+
29
+ - [ ] Overlay code never mutates balances directly - money flows through platform commands/ports.
30
+ - [ ] Any overlay money-adjacent mutation is idempotent at the data layer (DB guard, not just a key).
31
+ - [ ] Amounts are integer minor units; no float arithmetic on money.
32
+
33
+ ### Secrets & PII
34
+
35
+ - [ ] Vendor adapter credentials from env/config - never in source, templates, or client bundles.
36
+ - [ ] No PII (email, KYC docs, DOB, payment details) in logs, analytics events, error messages, or client-visible payloads.
37
+ - [ ] Nothing secret leaks into `NEXT_PUBLIC_*` or the browser bundle.
38
+
39
+ ### Input & injection
40
+
41
+ - [ ] All external input Zod-validated at the boundary (no `z.any()`/`z.unknown()` on a security edge).
42
+ - [ ] No raw SQL string interpolation; no inline `fetch` to vendors - adapters only (auditable egress).
43
+ - [ ] Webhooks from PSP/KYC vendors verify signatures before trusting payloads.
44
+
45
+ ## Do NOT flag (false-positive guard)
46
+
47
+ - Attack paths you have not traced through the actual code - state the concrete trigger or don't raise it.
48
+ - Platform-core internals (upstream's responsibility) - flag only how the overlay USES them.
49
+ - Code outside the diff, unless the change makes it newly exploitable.
50
+ - Generic hardening wishlists (rate limits everywhere, CSP) with no tie to the changed surface.
51
+
52
+ ## Output
53
+
54
+ Max 10 findings, most severe first. Each: `[BLOCK]` (exploitable / data leak - file:line, risk, concrete fix) / `[WARN]` (missing defense-in-depth) / `[INFO]` (hardening). End with **PASS** / **CHANGES REQUESTED** + one line on the most severe finding.
@@ -7,9 +7,8 @@
7
7
  "build": "tsc",
8
8
  "dev": "node --import tsx --watch --env-file-if-exists=../../.env src/main.ts",
9
9
  "start": "node --import tsx --env-file-if-exists=../../.env src/main.ts",
10
- "db:migrate": "node --import tsx --env-file-if-exists=../../.env src/migrate.ts",
11
10
  "db:seed": "node --import tsx --env-file-if-exists=../../.env src/seed.ts",
12
- "typecheck": "tsc --noEmit"
11
+ "check:types": "tsc --noEmit"
13
12
  },
14
13
  "dependencies": {
15
14
  "@openora/core": "{{coreVersion}}"
@@ -6,11 +6,11 @@
6
6
  "scripts": {
7
7
  "dev": "turbo run dev",
8
8
  "build": "turbo run build",
9
- "typecheck": "turbo run typecheck",
10
- "lint": "oxlint .",
11
- "sync:agents": "rulesync generate",
9
+ "check:types": "turbo run check:types",
10
+ "check:lint": "oxlint .",
11
+ "gen:agents": "rulesync generate",
12
12
  "prepare": "rulesync generate",
13
- "db:migrate": "pnpm -F @{{name}}/api db:migrate",
13
+ "db:migrate": "pnpm -F @{{name}}/api exec openora-migrate",
14
14
  "db:seed": "pnpm -F @{{name}}/api db:seed",
15
15
  "gen": "turbo gen"
16
16
  },
@@ -1,6 +1,6 @@
1
1
  // rulesync config - single source of truth for all AI-agent instruction files.
2
2
  // Source lives in .rulesync/ (rules, subagents, commands, mcp.json).
3
- // Regenerate with `pnpm sync:agents`; CI checks with `pnpm sync:agents:check`.
3
+ // Regenerate with `pnpm gen:agents`.
4
4
  {
5
5
  "$schema": "https://github.com/dyoshikawa/rulesync/releases/latest/download/config-schema.json",
6
6
 
@@ -1,2 +1,2 @@
1
1
  // To customize, replace this re-export with your own plop config.
2
- export { default } from '@openora/turbo-generators';
2
+ export { default } from '@openora/core/generators';
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "$schema": "https://turbo.build/schema.json",
3
3
  "ui": "tui",
4
+ "globalDependencies": [".oxlintrc.json"],
4
5
  "tasks": {
5
6
  "build": {
6
7
  "dependsOn": ["^build"],
@@ -10,8 +11,19 @@
10
11
  "cache": false,
11
12
  "persistent": true
12
13
  },
13
- "typecheck": {
14
- "dependsOn": ["^build"]
14
+ "check:types": {
15
+ "dependsOn": ["^build"],
16
+ "outputs": []
17
+ },
18
+ "//#check:lint": {
19
+ "inputs": [
20
+ "**/*.{ts,tsx,mts,cts,js,mjs,cjs,jsx}",
21
+ "!.turbo/**",
22
+ "!**/node_modules/**",
23
+ "!**/dist/**",
24
+ "!**/.next/**"
25
+ ],
26
+ "outputs": []
15
27
  }
16
28
  }
17
29
  }
@@ -1,111 +0,0 @@
1
- ---
2
- name: code-review
3
- description: Multi-agent code review of the working branch against this repo's conventions, OSS-core boundaries, security, and operator-domain fit. Fans out a configurable number of parallel reviewers, each grounded in the rule docs, then synthesizes one verdict. Use on "review this", "code review", "/code-review", optionally "--agents N", "--base <ref>", "--fix", a GitLab MR number, or paths.
4
- ---
5
-
6
- # code-review
7
-
8
- Orchestrate a parallel, convention-grounded code review of the current change set in this downstream
9
- igaming operator repo. You are the orchestrator: scope the diff, fan out N reviewers across review
10
- dimensions, dedup their findings, and report ONE verdict. Report-only by default - never edit unless
11
- `--fix` is passed.
12
-
13
- Copy this checklist and tick it off as you go:
14
-
15
- ```
16
- code-review:
17
- - [ ] 1. Parse args (--agents / --base / MR# / paths / --fix)
18
- - [ ] 2. Scope the diff; if empty, ask
19
- - [ ] 3. Pick applicable dimensions (only those with touched files)
20
- - [ ] 4. Spawn reviewers in ONE message (parallel)
21
- - [ ] 5. Dedup + apply the evidence/confidence gate
22
- - [ ] 6. Report one verdict (+ apply fixes only if --fix)
23
- ```
24
-
25
- ## 1. Parse `$ARGUMENTS`
26
-
27
- | Token | Meaning | Default |
28
- | ------------------- | --------------------------------------------------------------- | ------------------------------- |
29
- | `--agents N` | how many parallel reviewers to spawn (1-5) | one per applicable dimension |
30
- | `--base <ref>` | branch to diff against | `dev` (this repo's integration) |
31
- | `<number>` (e.g. 8) | a GitLab MR number - review that MR's diff (`glab mr diff <n>`) | - |
32
- | paths | restrict review to these files/dirs | whole diff |
33
- | `--fix` | apply fixes for `[BLOCK]`/`[WARN]` findings after the review | off (report only) |
34
-
35
- ## 2. Scope the diff (do this first)
36
-
37
- - Branch: `git diff <base>...HEAD --name-only` (default base `dev`). If empty, fall back to
38
- unstaged/staged via `git status -s`; if still empty, ask what to review.
39
- - MR number given: `glab mr diff <n>` for the patch + `glab mr view <n>` for intent.
40
- - Group changed files by app/package so reviewers and any file-split share the same map.
41
-
42
- ## 3. Ground every reviewer (mandatory)
43
-
44
- Each spawned reviewer MUST read the actual changed code AND the rule docs that own its dimension
45
- before judging - do not infer behavior from a diff hunk. If a finding depends on what a called
46
- function does, open it; if you can't cite it, fetch it. These docs are the single source of truth -
47
- cite them in findings:
48
-
49
- - `.claude/rules/overview.md` - what this repo is (a downstream operator on `@openora/*` consumed as linked packages), the HARD RULE that OSS core is read-only, how you work here, and the enforced import/module boundaries (extend only from the outside).
50
- - `.claude/rules/db-conventions.md` - SQL / Drizzle rules for tables an overlay owns.
51
- - Any other `.claude/rules/*.md` the consumer has added (e.g. `conventions`, `oss-boundaries`, `frontend`) - cite whichever own the touched files.
52
-
53
- ## 4. Review dimensions
54
-
55
- Each dimension maps to a rule doc and, where one fits, a pre-scoped subagent. Spawn only the
56
- dimensions whose files actually changed.
57
-
58
- | # | Dimension | Covers | Use subagent |
59
- | --- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
60
- | 1 | OSS boundaries & extension | never edits `@openora/*` core; extends only via `extensions.config.ts` / overlay plugins / vendor adapters; no deep `dist/` imports | general (overview) |
61
- | 2 | Conventions & quality | naming, functional/immutable, no `any`/`interface`/default-export, types inferred not hand-written, comments WHY, tests | general (overview) |
62
- | 3 | Frontend | React/styling rules - only if a frontend app or shared UI package was added and changed | general (frontend) |
63
- | 4 | Security & secrets | authz on overlay routes, vendor-adapter creds from env (KYC/PSP/notify), no secret/PII leaks, Zod-validated input | general (overview) |
64
- | 5 | Operator/domain fit | does the change make igaming sense for this operator; launch-blockers (only if business logic changed) | `expert` |
65
-
66
- ## 5. Allocate reviewers to `--agents N`
67
-
68
- - `N` unset: one reviewer per applicable dimension (skip dimensions with no touched files).
69
- - `N` >= applicable dimensions: extra agents split the largest dimension by file group (state the split; never silently drop files).
70
- - `N` < applicable dimensions: merge adjacent dimensions into `N` buckets, preferring to keep 1 (OSS boundaries) and 4 (security) standalone.
71
-
72
- Spawn all reviewers in a SINGLE message (parallel `Task` calls). Use `general-purpose` for general
73
- dimensions with an explicit instruction to read the §3 docs first; use `expert` for the
74
- domain-fit dimension. Pass each reviewer: the changed-file list, the base ref, its dimension
75
- checklist, and the report-only constraint.
76
-
77
- ## 6. Evidence & confidence gate (cut false positives)
78
-
79
- Tell every reviewer to apply this before returning, and re-apply it yourself when synthesizing:
80
-
81
- - Every `[BLOCK]` and `[WARN]` MUST cite a concrete `file:line` AND the rule doc it violates. No location or no rule = downgrade to `[INFO]` or drop it.
82
- - Report only high-confidence findings. If unsure whether something is a real defect vs a theoretical nit, downgrade or omit - prefer few actionable findings over flooding.
83
- - Don't invent runtime failures you haven't traced through the code. State the trigger path or don't raise it.
84
- - Don't bikeshed and don't duplicate what tooling already enforces: oxlint and the `/check` gate (`pnpm typecheck`, `pnpm lint`). For a suspected lint/boundary issue, say "confirm with `pnpm lint`" rather than guessing - flag only what those gates miss.
85
- - Each reviewer self-checks before returning: every finding has evidence + a cited rule, uncertain claims downgraded, no style nitpicks lint already catches, no unverified runtime claims.
86
-
87
- ## 7. Synthesize
88
-
89
- Collect all findings, dedup by `file:line`, and merge into one report. Each finding:
90
-
91
- - `[BLOCK]` - must fix before merge (edits OSS core, boundary break, authz/secret/PII risk, broken extension wiring).
92
- - `[WARN]` - should fix (convention violation, missing test, weak input validation).
93
- - `[INFO]` - FYI / hardening.
94
-
95
- Group by dimension, ordered BLOCK -> WARN -> INFO. Each line:
96
- `[SEV] file:line - finding - evidence - rule cited - fix`. BLOCK/WARN without a `file:line` and a
97
- cited rule do not ship - they were already dropped by the gate in §6. Lead with a one-line summary:
98
- counts per severity + verdict. End with **APPROVED** / **CHANGES REQUESTED** and the single most
99
- critical finding.
100
-
101
- If `--fix`: after the report, apply BLOCK + WARN fixes in the working tree (smallest diff that
102
- satisfies the cited rule), then run the `/check` gate (`pnpm typecheck && pnpm lint`)
103
- and report green/red. Leave INFO items untouched. Never commit or push.
104
-
105
- ## Constraints
106
-
107
- - Read-only by default; `--fix` edits the working tree only - no commit, no push.
108
- - NEVER edit `@openora/*` core or `node_modules` - this repo extends the platform from the outside only.
109
- - Reviewers report findings; they do not edit. Only the orchestrator edits, and only under `--fix`.
110
- - Always cite the rule doc a finding rests on - no opinions ungrounded in the conventions.
111
- - Cap at 5 parallel reviewers.