Skip to content

Commit ad50f70

Browse files
committed
Merge remote-tracking branch 'origin/main' into develop
# Conflicts: # .claude/commands/review.md # cmd/ckb/setup.go # internal/query/review.go # internal/query/review_coupling.go # internal/query/review_test.go # internal/secrets/scanner.go
2 parents bf28787 + 1cae8fc commit ad50f70

File tree

154 files changed

+19112
-306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+19112
-306
lines changed

.claude/commands/audit.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
Run a CKB-augmented compliance audit optimized for minimal token usage.
2+
3+
## Input
4+
$ARGUMENTS - Optional: framework(s) to audit (default: auto-detect from repo context). Examples: "gdpr", "gdpr,pci-dss,hipaa", "all"
5+
6+
## Philosophy
7+
8+
CKB already ran deterministic checks across 20 regulatory frameworks, mapped every finding
9+
to a specific regulation article, and assigned confidence scores. The LLM's job is ONLY what
10+
CKB can't do: assess whether findings are real compliance risks or false positives given the
11+
repo's actual purpose, and prioritize remediation by business impact.
12+
13+
### Available frameworks (20 total)
14+
15+
**Privacy:** gdpr, ccpa, iso27701
16+
**AI:** eu-ai-act
17+
**Security:** iso27001, nist-800-53, owasp-asvs, soc2, hipaa
18+
**Industry:** pci-dss, dora, nis2, fda-21cfr11, eu-cra
19+
**Supply chain:** sbom-slsa
20+
**Safety:** iec61508, iso26262, do-178c
21+
**Coding:** misra, iec62443
22+
23+
### CKB's blind spots (what the LLM must catch)
24+
25+
CKB maps code patterns to regulation articles using AST + regex + tree-sitter. It is
26+
structurally correct but contextually blind:
27+
28+
- **Business context**: CKB flags PII patterns in a healthcare app and a game engine equally
29+
- **Architecture awareness**: a finding in dead/test code vs production code has different weight
30+
- **Compensating controls**: CKB can't see infrastructure-level encryption, WAFs, or IAM policies
31+
- **Regulatory applicability**: CKB flags HIPAA in a repo that doesn't handle PHI
32+
- **Risk prioritization**: 50 findings need ordering by actual business/legal exposure
33+
- **Cross-reference noise**: the same hardcoded credential maps to 6 frameworks — that's 1 fix, not 6
34+
35+
## Phase 1: Structural scan (~2k tokens into context)
36+
37+
```bash
38+
ckb audit compliance --framework=$ARGUMENTS --format=json --min-confidence=0.7 2>/dev/null
39+
```
40+
41+
For large repos, scope to a specific path to reduce noise:
42+
```bash
43+
ckb audit compliance --framework=$ARGUMENTS --scope=src/api --format=json --min-confidence=0.7 2>/dev/null
44+
```
45+
46+
If no framework specified, pick based on repo context:
47+
- Has health/patient/medical code → `hipaa,gdpr`
48+
- Has payment/billing/card code → `pci-dss,soc2`
49+
- EU company or processes EU data → `gdpr,dora,nis2`
50+
- AI/ML code → `eu-ai-act`
51+
- Safety-critical/embedded → `iec61508,iso26262,misra`
52+
- General SaaS → `iso27001,soc2,owasp-asvs`
53+
- If unsure → `iso27001,owasp-asvs` (broadest applicability)
54+
55+
From the JSON output, extract:
56+
- `score`, `verdict` (pass/warn/fail)
57+
- `coverage[]` — per-framework scores with passed/warned/failed/skipped check counts
58+
- `findings[]` — with check, severity, file, startLine, message, suggestion, confidence, CWE
59+
- `checks[]` — per-check status and summary
60+
- `summary` — total findings by severity, files scanned
61+
62+
Note:
63+
- **Per-framework scores**: which frameworks are clean vs problematic
64+
- **Finding count by severity**: errors are your priority
65+
- **CWE references**: cross-reference with known vulnerability databases
66+
- **Confidence scores**: low confidence (< 0.7) findings are likely false positives
67+
68+
**Early exit**: If verdict=pass and all framework scores ≥ 90, write a one-line summary and stop.
69+
70+
## Phase 2: Triage findings (targeted reads only)
71+
72+
Do NOT read every flagged file. Group findings by root cause first:
73+
74+
1. **Deduplicate cross-framework findings** — a hardcoded secret flagged by GDPR, PCI DSS, HIPAA, and ISO 27001 is one fix
75+
2. **Check for dominant category** — if > 50% of findings are one category (e.g., "sql-injection"), investigate that category systemically (is the pattern matching too broad?) rather than checking each file individually
76+
3. **Check applicability** — does this repo actually fall under the flagged framework? (e.g., HIPAA findings in a non-healthcare repo)
77+
4. **Read only error-severity files** — warnings and info can wait
78+
5. **For each error finding**, read just the flagged lines (not the whole file) and assess:
79+
- Is this a real compliance risk or a pattern false positive?
80+
- Are there compensating controls elsewhere? (check imports, config, middleware)
81+
- What's the remediation effort: one-liner fix vs architectural change?
82+
83+
## Phase 3: Write the audit summary (be terse)
84+
85+
```markdown
86+
## [COMPLIANT|NEEDS REMEDIATION|NON-COMPLIANT] — CKB score: [N]/100
87+
88+
[One sentence: what frameworks were audited and overall posture]
89+
90+
### Critical findings (must remediate)
91+
1. **[framework]** `file:line` Art. [X][issue + remediation in one sentence]
92+
2. ...
93+
94+
### Not applicable (false positives from context)
95+
[List findings CKB flagged but that don't apply to this repo, with one-line reason]
96+
97+
### Cross-framework deduplication
98+
[N findings deduplicated to M root causes]
99+
100+
### Framework scores
101+
| Framework | Score | Status | Checks |
102+
|-----------|-------|--------|--------|
103+
| [name] | [N] | [pass/warn/fail] | [passed]/[total] |
104+
```
105+
106+
If fully compliant: just the header + framework scores. Nothing else.
107+
108+
## Anti-patterns (token waste)
109+
110+
- Reading every flagged file → waste (group by root cause, read only errors)
111+
- Treating cross-framework duplicates as separate issues → waste (1 code fix = 1 issue)
112+
- Explaining what each regulation requires → waste (CKB already mapped articles)
113+
- Re-checking frameworks CKB scored at 100 → waste
114+
- Auditing frameworks that don't apply to this repo → waste
115+
- Reading low-confidence findings (< 0.7) → waste (likely false positives)
116+
- Suggesting infrastructure controls for code-level findings → out of scope
117+
- Using wrong framework IDs (use pci-dss not pcidss, owasp-asvs not owaspasvs) → CKB error

.claude/commands/review.md

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ It is structurally sound but semantically blind:
1919
- **Design fitness**: wrong abstraction, leaky interface, coupling that metrics miss
2020
- **Input validation**: missing bounds checks, nil guards outside AST patterns
2121
- **Race conditions**: concurrency issues, mutex ordering, shared state
22+
- **Resource leaks**: file handles, goroutines, connections not closed on all paths
2223
- **Incomplete refactoring**: callers missed across module boundaries
2324
- **Domain edge cases**: error paths, boundary conditions tests don't cover
2425

@@ -29,19 +30,36 @@ so pre-existing issues interacting with new code won't surface.
2930
## Phase 1: Structural scan (~1k tokens into context)
3031

3132
```bash
32-
ckb review --base=main --format=json --compact 2>/dev/null
33+
ckb review --base=main --format=json 2>/dev/null
3334
```
3435

3536
If a PR number was given:
3637
```bash
3738
BASE=$(gh pr view $ARGUMENTS --json baseRefName -q .baseRefName)
38-
ckb review --base=$BASE --format=json --compact 2>/dev/null
39+
ckb review --base=$BASE --format=json 2>/dev/null
3940
```
4041

41-
From the output, build three lists:
42+
If "staged" was given:
43+
```bash
44+
ckb review --staged --format=json 2>/dev/null
45+
```
46+
47+
Parse the JSON output to extract:
48+
- `score`, `verdict` — overall quality
49+
- `checks[]` — status + summary per check (15 checks: breaking, secrets, tests, complexity,
50+
coupling, hotspots, risk, health, dead-code, test-gaps, blast-radius, comment-drift,
51+
format-consistency, bug-patterns, split)
52+
- `findings[]` — severity + file + message + ruleId (top-level, separate from check details)
53+
- `narrative` — CKB AI-generated summary (if available)
54+
- `prTier` — small/medium/large
55+
- `reviewEffort` — estimated hours + complexity
56+
- `reviewers[]` — suggested reviewers with expertise areas
57+
- `healthReport` — degraded/improved file counts
58+
59+
From checks, build three lists:
4260
- **SKIP**: passed checks — don't touch these files or topics
4361
- **INVESTIGATE**: warned/failed checks — these are your review scope
44-
- **READ**: hotspot files + files with warn/fail findings — the only files you'll read
62+
- **READ**: files with warn/fail findings — the only files you'll read
4563

4664
**Early exit**: Skip LLM ONLY when ALL conditions are met:
4765
1. Score ≥ 90 (not 80 — per-check caps hide warnings at 80)
@@ -56,14 +74,20 @@ the code is semantically correct.
5674

5775
Do NOT read the full diff. Do NOT read every changed file.
5876

59-
Read ONLY:
60-
1. Files that appear in INVESTIGATE findings (just the changed hunks via `git diff main...HEAD -- <file>`)
61-
2. New files (CKB has no history for these) — but only if <500 lines each
62-
3. Skip generated files, test files for existing tests, and config/CI files
77+
**For files CKB flagged (INVESTIGATE list):**
78+
Read only the changed hunks via `git diff main...HEAD -- <file>`.
79+
80+
**For new files** (CKB has no history — these are your biggest blind spot):
81+
- If it's a new package/module: read the entry point and types/interfaces first,
82+
then follow references to understand the architecture before reading individual files
83+
- If < 500 lines: read the file
84+
- If > 500 lines: read the first 100 lines (types/imports) + functions CKB flagged
85+
- Skip generated files, test files for existing tests, and config/CI/docs files
6386

64-
For each file you read, look for exactly:
87+
**For each file you read, look for exactly:**
6588
- Logic errors (wrong condition, off-by-one, nil deref, race condition)
66-
- Security issues (injection, auth bypass, secrets CKB's 26 patterns missed)
89+
- Resource leaks (file handles, connections, goroutines not closed on error paths)
90+
- Security issues (injection, auth bypass, secrets CKB's patterns missed)
6791
- Design problems (wrong abstraction, leaky interface, coupling metrics don't catch)
6892
- Missing edge cases the tests don't cover
6993
- Incomplete refactoring (callers that should have changed but didn't)
@@ -78,6 +102,11 @@ CKB already checked these structurally.
78102

79103
[One sentence: what the PR does]
80104

105+
[If CKB provided narrative, include it here]
106+
107+
**PR tier:** [small/medium/large] | **Review effort:** [N]h ([complexity])
108+
**Health:** [N] degraded, [N] improved
109+
81110
### Issues
82111
1. **[must-fix|should-fix]** `file:line`[issue in one sentence]
83112
2. ...
@@ -87,6 +116,9 @@ CKB already checked these structurally.
87116

88117
### CKB flagged (verified above)
89118
[for each warn/fail finding: confirmed/false-positive + one-line reason]
119+
120+
### Suggested reviewers
121+
[reviewer — expertise area]
90122
```
91123

92124
If no issues found: just the header line + CKB passed list. Nothing else.
@@ -95,10 +127,12 @@ If no issues found: just the header line + CKB passed list. Nothing else.
95127

96128
- Reading files CKB marked as pass → waste
97129
- Reading generated files → waste
98-
- Summarizing what the PR does in detail → waste (git log exists)
130+
- Summarizing what the PR does in detail → waste (git log exists, CKB has narrative)
99131
- Explaining why passed checks passed → waste
100132
- Running MCP drill-down tools when CLI already gave enough signal → waste
101133
- Reading test files to "verify test quality" → waste unless CKB flagged test-gaps
102134
- Reading hotspot-only files with no findings → high churn ≠ needs review right now
103135
- Trusting score >= 80 as "safe to skip" → dangerous (per-check caps hide warnings)
104136
- Skipping new files because CKB didn't flag them → CKB has no SCIP data for new files
137+
- Reading every new file in a large new package → read entry point + types first, then follow refs
138+
- Ignoring reviewEffort/prTier → these tell you how thorough to be

CHANGELOG.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,134 @@
22

33
All notable changes to CKB will be documented in this file.
44

5+
## [8.3.0] - 2026-03-27
6+
7+
### Added
8+
9+
#### Compliance Audit (`ckb audit compliance`)
10+
Full regulatory compliance auditing with 131 checks across 20 frameworks:
11+
12+
```bash
13+
ckb audit compliance --framework=gdpr,iso27001 # Specific frameworks
14+
ckb audit compliance --framework=all # All 20 frameworks
15+
ckb audit compliance --recommend # Auto-detect applicable frameworks
16+
ckb audit compliance --framework=gdpr --ci # CI mode with exit codes
17+
```
18+
19+
**20 frameworks:** GDPR, CCPA, ISO 27701, EU AI Act, ISO 27001, NIST 800-53, OWASP ASVS, SOC 2, PCI DSS, HIPAA, DORA, NIS2, FDA 21 CFR Part 11, EU CRA, SBOM/SLSA, DO-178C, IEC 61508, ISO 26262, MISRA C, IEC 62443.
20+
21+
**Cross-framework mapping:** A single finding (e.g., hardcoded credential) automatically surfaces all applicable regulations with specific clause references and CWE IDs.
22+
23+
**Framework recommendation (`--recommend`):** Scans codebase for indicators (HTTP handlers, PII fields, database imports, payment SDKs) and recommends applicable frameworks with confidence scores.
24+
25+
**Output formats:** human, json, markdown, sarif.
26+
27+
**MCP tool:** `auditCompliance` — runs compliance audit via MCP using the persistent SCIP index.
28+
29+
#### MCP Tools: `listSymbols` and `getSymbolGraph`
30+
31+
**`listSymbols`** — Bulk symbol listing without search query:
32+
```
33+
listSymbols(scope: "src/services/", kinds: ["function"], minLines: 30, sortBy: "complexity")
34+
```
35+
Returns complete symbol inventory with body ranges (`lines`, `endLine`) and complexity metrics (`cyclomatic`, `cognitive`). Replaces exploring 40 files one-by-one.
36+
37+
**`getSymbolGraph`** — Batch call graph for multiple symbols:
38+
```
39+
getSymbolGraph(symbolIds: [...30], depth: 1, direction: "callers")
40+
```
41+
Returns deduplicated nodes and edges with complexity per node. One call replaces 30 serial `getCallGraph` calls.
42+
43+
#### `searchSymbols` Enhancements
44+
45+
- **Complexity metrics:** Results now include `lines`, `cyclomatic`, `cognitive` per symbol via tree-sitter enrichment
46+
- **Server-side filtering:** `minLines`, `minComplexity`, `excludePatterns` params — filter 80% of noise server-side instead of client-side
47+
- **`batchGet` with `includeCounts`:** Returns `referenceCount`, `callerCount`, `calleeCount` per symbol (parallel SCIP lookups)
48+
49+
#### Symbol Body Ranges (`startLine`, `endLine`, `lines`)
50+
51+
`searchSymbols`, `explore` keySymbols, and `getSymbolGraph` now return full body ranges via tree-sitter enrichment. Consumers no longer need to read source files for brace-matching.
52+
53+
#### Explore keySymbols Improvements
54+
55+
- Functions rank above struct fields (behavioral analysis priority)
56+
- Tree-sitter supplement fills in functions when SCIP returns only types
57+
- Per-symbol `cyclomatic` and `cognitive` complexity
58+
59+
#### `getFileComplexity` in Refactor Preset
60+
61+
Previously only available in `full` preset (96 tools). Now in `refactor` (39 tools).
62+
63+
### Fixed
64+
65+
#### Bug-Pattern False Positives (42 → 0)
66+
- **defer-in-loop:** Recognize `func(){}()` closure pattern as correct (defer fires per iteration)
67+
- **discarded-error:** Skip closure bodies in IIFE patterns; add `singleReturnNew` allowlist (NewScanner, NewReader, etc.); add `noErrorMethods` (Scan, WriteHeader, WriteJSON, WriteError, BadRequest, NotFound, InternalError)
68+
- **missing-defer-close:** Remove NewReader/NewWriter from resource-opening functions (bufio wrappers don't need Close)
69+
- **nil-after-deref:** 30-line gap threshold filters cross-scope false matches
70+
- **shadowed-err:** Only flag when outer `err` is standalone function-body-level `:=`; treat if/for/switch initializer `:=` as scoped
71+
72+
All fixes use `FindNodesSkipping` — scope-aware tree-sitter node search that stops recursion at `func_literal` boundaries.
73+
74+
#### Secrets Scanner
75+
- Shell variable interpolation (`${VAR:-default}`, `${VAR:?error}`) in Docker Compose URLs no longer flagged as password_in_url
76+
- Shell environment leak: `env -i` wrapper prevents user profile (.zshrc) from corrupting subprocess output
77+
78+
#### Test-Gap Detection
79+
- `vi.mock`/`jest.mock` module-level mocking recognized — functions covered by module mocks no longer flagged
80+
- Barrel/re-export files (`export * from '...'`) skipped — pure re-exports have no logic to test
81+
82+
#### Coupling Check
83+
- Expanded noise filter: test files, dependency manifests (go.mod, package.json), documentation, generated directories (dist/, build/, l10n/, __generated__/)
84+
- Generated file suffixes: .pb.go, .pb.h, .pb.cc, .pb.ts, _grpc.pb.go, _pb2.py, .g.dart, .freezed.dart, .mocks.dart, _string.go, wire_gen.go, _mock.go, .bundle.js, .arb, .d.ts
85+
- Flutter l10n false positive fixed (#185): .arb files excluded from coupling analysis
86+
87+
#### Compliance Audit FP Reduction (11,356 → ~50 findings)
88+
- Deep-nesting: threshold 4→6, reset at function boundaries, 3-per-file cap
89+
- Dead-code: skip Go files (handled by AST-based bug-patterns)
90+
- Dynamic-memory: skip garbage-collected languages
91+
- Global-state: exclude regexp.MustCompile, errors.New, sync primitives
92+
- Swallowed-errors: remove overly broad `_ = obj.Method()` pattern
93+
- Eval-injection: skip Go and .github/ directories
94+
- Insecure-random: inline import scanning for crypto/rand vs math/rand; skip import lines
95+
- Path-traversal: skip filepath.Join, HasPrefix comparisons, testdata/
96+
- Non-FIPS-crypto: skip strings.Contains pattern matching
97+
- SQL injection (PCI DSS): add parameterized query detection, #nosec support
98+
- TODO detection: case-sensitive TEMP, skip "Stub:/Placeholder:/Note:" comments, require comment context
99+
100+
#### FTS Empty Query Bug
101+
`FTS.Search("")` returned empty results (early return for empty query). Added `listAll()` method that queries `symbols_fts_content` directly. Fixes `listSymbols` and `searchSymbols("")` returning 0 on MCP.
102+
103+
#### MCP Server Warmup
104+
Changed warmup from `SearchSymbols("", 1)` (cached empty results before SCIP loaded) to `RefreshFTS()` (populates FTS from SCIP without caching search results).
105+
106+
#### IEC 61508 Tree-Sitter Crash
107+
`complexityExceededCheck` bypassed thread-safe `AnalyzeFileComplexity()` wrapper, calling `ComplexityAnalyzer.AnalyzeFile()` directly — SIGABRT when concurrent checks hit CGO.
108+
109+
#### Daemon API Endpoints (7 stubs → implementations)
110+
- Schedule list/detail/cancel via scheduler.ListSchedules()
111+
- Repo list/detail via repos.LoadRegistry()
112+
- Federation list/detail via federation.List()/LoadConfig()
113+
- CLI daemon status: HTTP health query with version/uptime display
114+
115+
#### Query Engine Stubs (4 → implementations)
116+
- Ownership refresh: CODEOWNERS parsing + git-blame analysis
117+
- Hotspot refresh: git churn data with 90-day window
118+
- Responsibility refresh: module responsibility extraction
119+
- Ownership history: storage table query
120+
121+
### Changed
122+
- Score calculation: floor is 0 (not 20), per-rule deduction cap of 10 documented
123+
- `LikelyReturnsError`: removed "Scan" from error patterns, added `singleReturnNew` and `noErrorMethods` maps
124+
- Generated file detection: 20+ new patterns (protobuf, Go generators, Dart/Flutter, GraphQL, bundlers)
125+
- Per-check findings cap (50 max) in compliance engine
126+
- Compliance config: `DefaultDaemonPort` constant replaces hardcoded 9120
127+
128+
### Performance
129+
- `batchGet` with `includeCounts`: parallel reference/caller/callee lookups (10-concurrent semaphore)
130+
- FTS multiplier: 2x → 10x when filters active (handles SCIP struct field flooding)
131+
- MCP index warmup: background `RefreshFTS()` on engine init
132+
5133
## [8.2.0] - 2026-03-21
6134

7135
### Added

CLAUDE.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ golangci-lint run
5353
./ckb review --base=develop --format=markdown
5454
./ckb review --checks=breaking,secrets,health --ci
5555

56+
# Run compliance audit (131 checks across 20 regulatory frameworks)
57+
./ckb audit compliance --framework=gdpr
58+
./ckb audit compliance --framework=gdpr,iso27001,owasp-asvs
59+
./ckb audit compliance --framework=all --min-confidence=0.7 --format=sarif
60+
./ckb audit compliance --framework=pci-dss,hipaa --ci --fail-on=error
61+
./ckb audit compliance --framework=iec61508 --sil-level=3
62+
5663
# Auto-configure AI tool integration (interactive)
5764
./ckb setup
5865

@@ -92,7 +99,7 @@ ckb setup --tool=cursor --global
9299
claude mcp add ckb -- npx @tastehub/ckb mcp
93100
```
94101

95-
`ckb setup --tool=claude-code` also installs the `/ckb-review` slash command for Claude Code, which orchestrates CKB's structural analysis with LLM semantic review.
102+
`ckb setup --tool=claude-code` also installs the `/ckb-review` and `/ckb-audit` slash commands for Claude Code, which orchestrate CKB's structural analysis with LLM semantic review.
96103

97104
### Key MCP Tools
98105

@@ -162,6 +169,7 @@ Storage Layer (internal/storage/) - SQLite for caching and symbol mappings
162169
- **internal/coupling/**: Co-change analysis from git history.
163170
- **internal/streaming/**: SSE streaming infrastructure for long-running MCP operations.
164171
- **internal/envelope/**: Response metadata (ConfidenceFactor, CacheInfo) for AI transparency.
172+
- **internal/compliance/**: Regulatory compliance auditing (131 checks, 20 frameworks). Each framework is a subpackage (gdpr/, iso27001/, owaspasvs/, etc.) with checks that map findings to regulation articles.
165173

166174
### Data Flow
167175

0 commit comments

Comments
 (0)