# Business Logic Audit

> Dùng khi user nói 'business audit', 'logic check', 'kiểm tra business logic', 'code đúng rules chưa', hoặc trước GA release. Verify code implement đúng rules.md + use-cases.md. 5 categories /100.

- Skill: `victoraurelius/business-logic-audit` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add victoraurelius/business-logic-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/victoraurelius/business-logic-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: VictorAurelius (https://skillmd.com/u/victoraurelius)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/victoraurelius/business-logic-audit

---


# /business-logic-audit — Verify Code ↔ Business Rules

Score /100. Walk through every domain in `documents/01-business/`, verify code implements rules correctly. Adapt `<modules>` / `<core-module>` placeholders to your project layout.

## Process

### 1. Collect Domains

```bash
ls documents/01-business/*/ | grep -v README
```

### 2. Primacy: bug-finding > scoring (BLOCKING)

> **An audit's purpose is to surface code-rules drift BEFORE production violates documented business policy (wrong pricing, wrong retention, wrong consent flow). A `/100` score is less actionable than the same score + list of unimplemented BR-xxx + config-key drifts with file:line evidence.** Per `.claude/rules/audit-skill-rubric-business-logic-audit.md` §4 (mirror of the security-audit bug-finding-primacy pattern).

Rules for every audit run:
1. Enumerate ALL §3 sub-checks per category. NEVER skip.
2. Each sub-check returns: PASS / FAIL / N/A-with-reason / `❓ UNCHECKED`. No partial credit.
3. Final output starts with **bug list** (every BR/config FAIL with `rules.md:line` + `*.java:line` evidence) BEFORE the score.
4. Score is descriptive only; audit-level verdict = FAIL if ANY P0 sub-check FAILS.
5. Cat 5 Stakeholder rules require human review — Claude flags FAIL, human decides closure.

### 3. Per-Domain: 5 Categories with per-check rubric

Every category binds to a per-check pass/fail rule. For EACH domain folder, read `rules.md`, `use-cases.md`, `api-contract.md`, then verify in code:

| # | Category (20pts) | Per-check rubric file |
|---|-----------------|-----------------------|
| 1 | **Rule Coverage** | **`.claude/rules/audit-skill-rubric-business-logic-audit.md` §2.1 (6 sub-checks)** |
| 2 | **Config Accuracy** | **`.claude/rules/audit-skill-rubric-business-logic-audit.md` §2.2 (5 sub-checks)** |
| 3 | **Edge Case Tests** | **`.claude/rules/audit-skill-rubric-business-logic-audit.md` §2.3 (5 sub-checks)** |
| 4 | **Cross-Domain Consistency** | **`.claude/rules/audit-skill-rubric-business-logic-audit.md` §2.4 (5 sub-checks)** |
| 5 | **Stakeholder Alignment** | **`.claude/rules/audit-skill-rubric-business-logic-audit.md` §2.5 (5 sub-checks)** |

#### Per-check scoring (all 5 categories)

For each Category N:
1. Walk through every §2 sub-check in the bound rule.
2. Mark each sub-check PASS / FAIL / N/A-with-reason / `❓ UNCHECKED`.
3. Score = `20 - (failed_P0_count * 6) - (failed_P1_count * 3) - (failed_P2_count * 1)`, floor 0; cap 20 if all PASS.
4. If ANY P0 sub-check fails → category total CAPPED at 16/20 AND audit-level verdict = FAIL.
5. Each FAIL surfaces in bug list per §2 primacy.

Legacy scoring narrative: `reference/scoring-guide.md` retained for backward-compat only.

### 4. Output

Save to `documents/audits/business-logic-audit-[date].md`

### 5. Scripts

```bash
# Existing — checks 3-layer structure exists
scripts/verify-business-docs.sh

# Manual — verify each BR-xxx has code path
# Grep for config keys in application.yml
```

## Grep Scope — CRITICAL

**NEVER** scope greps to only top-level module dirs — multi-module Maven/Gradle projects put classes/config in submodules (`<core-module>/`, `<service-module>/`). Narrow scope = silent false-positive ("class doesn't exist" when it does).

**Safe patterns** (use one):

```bash
# Option 1 (broad, preferred) — project root, filter by extension
grep -rnE "ClassName|BR-ID" --include="*.java"
grep -rn "config.key.name" --include="*.yml"

# Option 2 (explicit submodules) — glob all module src dirs
grep -rn "ClassName" <modules>/*/src/ --include="*.java"
grep -rn "config.key" <modules>/*/src/main/resources/ --include="*.yml"
```

**Sanity check before filing "X doesn't exist" gap:**

```bash
# If narrow grep returns 0 hits, re-run with broad scope before claiming absence
grep -rn "SuspectedMissingClass" --include="*.java" | head -5
```

Ref: `.claude/rules/audit-to-gap-pipeline.md`.

## Context Management

Audit này có thể tốn 30-50K tokens nếu không kiểm soát. Tuân thủ:

1. **Output limiting** — LUÔN pipe grep results qua `| head -N`:
   - BR-xxx grep: `| head -30` (chỉ cần biết có/không, không cần xem hết)
   - Config key grep: `| head -20`
   - Test file count: dùng `wc -l` thay vì list full
2. **Per-domain staging** — Nếu >5 domains, score 2 domains đầy đủ rồi apply pattern cho còn lại. Chỉ individually score domains có cấu trúc ĐẶC BIỆT.
3. **Subagent delegation** — Nếu >8 domains hoặc codebase >500 source files:
   - Agent 1: nhóm domain A
   - Agent 2: nhóm domain B
   - Parent: aggregate scores
4. **Skip known-good** — Domains không thay đổi từ audit trước → carry forward score, chỉ verify version match

## Gotchas

- Config keys are in `application.yml` AND `application-test.yml` — check both
- Some BR-xxx implemented in gateway (rate-limit rules) not core — search all modules
- Category 5 (Stakeholder) always requires human review — Claude flags, human decides
- Grep output cho large codebase có thể 1000+ lines — LUÔN giới hạn
- **Multi-module scope trap** — `grep -r "X" <top-level-dirs>` may silently miss submodule hits (e.g. `<core-module>/`). Follow "Grep Scope" section above.

## Skill Contents

- `reference/scoring-guide.md` — Detailed rubric per category with examples
- `data/eval-fixtures/` — 3 synthetic scenarios for self-test

## Eval Fixtures

3 synthetic fixtures live under `data/eval-fixtures/` to keep this skill
honest when its body is edited (per eval-first guidance — keep a regression
contract). Each fixture has a `# Expected: PASS|FAIL` header and a
`Which check fires` annotation.

- `good.md` — synthetic `attendance` domain where every BR-* maps to code +
  config aligns; expected output `100/100 Grade A`.
- `bad-rule-not-implemented.md` — `BR-ATT-005` declared in rules.md but no
  `@PreAuthorize` / service guard exists; Category 1 must report `-4`.
- `edge-config-key-renamed.md` — config key `late-threshold-minutes`
  renamed to `late-grace-minutes` in code, rules.md not updated; Category 2
  must catch the silent drift.

**Run:** open the fixture and walk through the audit process steps mentally
against the synthetic content; the `Expected audit-report excerpt` section
in each fixture is the regression contract. When extending this skill,
re-walk all 3 fixtures and confirm the expected outputs still hold.

