@pharaoh-so/mcp 0.3.43 → 0.3.45

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.
@@ -4,7 +4,7 @@ description: Architecture-aware code review with Pharaoh
4
4
 
5
5
  # Review with Pharaoh
6
6
 
7
- The definitive code review. Architecture-aware, branch-aware, multi-agent, adversarial. Five phases that combine Pharaoh's knowledge graph with parallel specialized reviewers and an independent cross-model second opinion.
7
+ The definitive code review, for any codebase. Architecture-aware, branch-aware, multi-agent, adversarial. Five phases that combine Pharaoh's knowledge graph with parallel specialized reviewers and an independent second opinion. Every phase works without Pharaoh too; Pharaoh makes the architecture picture exact and cheap where it maps the repo.
8
8
 
9
9
  Final verdict: **SHIP** / **SHIP WITH CHANGES** / **BLOCK**
10
10
 
@@ -26,16 +26,22 @@ Before merging any branch. Before opening any PR. When reviewing changes that to
26
26
  git log --oneline -1 # latest commit
27
27
  ```
28
28
 
29
- 2. Determine the base branch (what this branch diverged from):
29
+ 2. Determine the base (where this branch diverged from the branch it merges into). The target is the first of these that resolves:
30
30
  ```bash
31
- git merge-base HEAD main # or master, or whatever the default is
31
+ TARGET=$(gh pr view --json baseRefName --jq '"origin/" + .baseRefName' 2>/dev/null) # the open PR's target branch
32
+ [ -n "$TARGET" ] || TARGET=$(git symbolic-ref -q --short refs/remotes/origin/HEAD) # the default branch, set by git clone
33
+ [ -n "$TARGET" ] || for b in origin/main origin/master main master; do
34
+ git rev-parse -q --verify "$b" >/dev/null && TARGET=$b && break
35
+ done
36
+ git merge-base HEAD "$TARGET" # prints the base commit: $BASE below
32
37
  ```
38
+ If no base comes out, stop and ask which branch this merges into. An empty base makes every diff below come out empty, and the review would report no changes.
33
39
 
34
40
  3. Collect the full changeset from the base:
35
41
  ```bash
36
- git diff --name-only $(git merge-base HEAD main)...HEAD # all changed files
37
- git diff --stat $(git merge-base HEAD main)...HEAD # summary stats
38
- git log --oneline $(git merge-base HEAD main)..HEAD # all commits on this branch
42
+ git diff --name-only "$BASE"...HEAD # all changed files
43
+ git diff --stat "$BASE"...HEAD # summary stats
44
+ git log --oneline "$BASE"..HEAD # all commits on this branch
39
45
  ```
40
46
 
41
47
  4. Also check for uncommitted work:
@@ -52,18 +58,34 @@ Before merging any branch. Before opening any PR. When reviewing changes that to
52
58
 
53
59
  ## Phase 1 — Pharaoh Recon
54
60
 
55
- **Goal:** Get the full architectural picture in one call. Do NOT skip this phase — it is what makes this review architecture-aware instead of just a code diff review.
61
+ **Goal:** Get the full architectural picture, and the project's own rules, before reading the diff in depth. Do NOT skip this phase: it is what makes this review architecture-aware instead of just a code diff review.
62
+
63
+ ### With Pharaoh
56
64
 
57
65
  Call `pharaoh_recon` with:
58
- - **repo:** The repository name
66
+ - **repo:** The repository name (if the name is wrong, Pharaoh replies with the repos it maps)
59
67
  - **include_map:** `true`
60
68
  - **modules:** The touched modules from Phase 0 (up to 5)
61
69
  - **blast_radius:** The most critical changed files/functions as blast radius targets (up to 3). Pick the files with the most downstream risk — entry points, shared utilities, exported APIs.
62
70
  - **dependencies:** Pairs of touched modules to trace coupling between (up to 3)
63
71
 
72
+ Pharaoh's graph maps the default branch, so it shows what the change lands on: callers, blast radius, module boundaries, endpoints. Code that is new on this branch isn't in it yet; read the diff for that.
73
+
74
+ ### Without Pharaoh (graceful fallback)
75
+
76
+ If Pharaoh isn't connected, or doesn't map this repo, build the same picture by hand. When Pharaoh is connected but doesn't map the repo, tell the user once that mapping it makes this review architecture-aware, with the install link from `pharaoh_account`, then carry on:
77
+ 1. Read the top-level layout and the manifest files (package.json, pyproject.toml, go.mod, Cargo.toml) to find the module boundaries
78
+ 2. For each changed exported function or file, search for its callers to estimate the blast radius
79
+ 3. Read the entry points the change can reach: routes, CLI commands, jobs, event handlers
80
+ 4. Say in the review that the architecture context came from search, not the graph
81
+
82
+ ### The project's own rules
83
+
84
+ Read the rules the project states for itself: `CLAUDE.md` or `AGENTS.md` (including nested ones in touched directories), `CONTRIBUTING.md` and `SECURITY.md`, whichever exist. Note every rule stated as non-negotiable: testing requirements, security invariants, code style. They are what Phase 2's reviewers check the change against.
85
+
64
86
  Then read `docs/VISION.md` if the repo has one — the repo's architectural contract. For every touched module, find its relevant assertions. Any change touching code governed by a MUST-bullet must be checked against that assertion — if the change would violate the MUST, the verdict tips toward BLOCK unless VISION.md is updated in the same PR with user approval.
65
87
 
66
- **Output of Phase 1:** Architecture map, module profiles for every touched module, blast radius for high-risk changes, dependency paths between coupled modules, and spec alignment.
88
+ **Output of Phase 1:** Architecture map, module profiles for every touched module, blast radius for high-risk changes, dependency paths between coupled modules, the project's rules, and spec alignment.
67
89
 
68
90
  ---
69
91
 
@@ -75,8 +97,8 @@ Then read `docs/VISION.md` if the repo has one — the repo's architectural cont
75
97
 
76
98
  | Agent | When to dispatch | Focus |
77
99
  |-------|-----------------|-------|
78
- | **Code Reviewer** | Always | Bugs, logic errors, CLAUDE.md compliance, code quality. Confidence-filtered (only issues >= 80/100). |
79
- | **Security Reviewer** | When changes touch auth, encryption, tokens, tenant isolation, data access, billing, webhooks, Cypher queries, or any security-sensitive surface. Also dispatch when the Phase 1 blast radius marks the change as HIGH risk. | OWASP Top 10, injection vectors, access control bypasses, tenant isolation violations, cryptographic misuse, secret exposure, plus project-specific security rules. See checklist below. |
100
+ | **Code Reviewer** | Always | Bugs, logic errors, compliance with the project's rules, code quality. Confidence-filtered (only issues >= 80/100). |
101
+ | **Security Reviewer** | When changes touch any security-sensitive surface (see the detection triggers below). Also dispatch when the Phase 1 blast radius marks the change as HIGH risk. | OWASP Top 10, injection vectors, access control bypasses, tenant isolation in multi-tenant systems, cryptographic misuse, secret exposure, plus the project's own security rules. See checklist below. |
80
102
  | **Silent Failure Hunter** | When changes touch error handling, catch blocks, fallback logic, API calls, or any code that could suppress errors | Silent failures, broad catches, swallowed errors, missing user feedback, unjustified fallbacks. |
81
103
  | **Test Analyzer** | When test files are changed, or when new functionality lacks corresponding tests | Behavioral coverage gaps, brittle tests, missing edge cases, tests that prove nothing. |
82
104
  | **Type Design Analyzer** | When new types/interfaces are introduced or existing types are modified | Encapsulation, invariant expression, invariant enforcement. Rates each type 1-10 on four axes. |
@@ -86,7 +108,7 @@ Then read `docs/VISION.md` if the repo has one — the repo's architectural cont
86
108
  The Security Reviewer agent runs a systematic audit against two layers: universal web security (OWASP) and project-specific invariants.
87
109
 
88
110
  **Layer 1 — OWASP Top 10 + Common Vulnerabilities:**
89
- - **Injection:** SQL/Cypher injection, command injection, XSS (reflected/stored/DOM), template injection
111
+ - **Injection:** SQL, NoSQL and graph query injection, command injection, XSS (reflected/stored/DOM), template injection
90
112
  - **Broken auth:** Hardcoded credentials, weak token generation, missing expiry, session fixation
91
113
  - **Broken access control:** Missing authorization checks, IDOR, privilege escalation, path traversal
92
114
  - **Cryptographic failures:** Weak algorithms, plaintext secrets, missing encryption at rest/transit, key exposure
@@ -95,29 +117,22 @@ The Security Reviewer agent runs a systematic audit against two layers: universa
95
117
  - **SSRF:** Unvalidated URLs in fetch/request calls, redirect chains
96
118
  - **Logging & monitoring:** Sensitive data in logs, missing audit trails for privileged operations
97
119
 
98
- **Layer 2 — Project-Specific Security Rules (from CLAUDE.md):**
99
- - Every Cypher query takes `repo` as first parameter — no unanchored MATCH clauses
100
- - `validateRepoOwnership()` runs before every tool handler
101
- - No default/fallback repo values — repo always from tenant's Postgres `tenant_repos`
102
- - Tokens stored as SHA-256 hashes, never plaintext
103
- - GitHub tokens encrypted at rest (AES-256-GCM with per-tenant HKDF-derived keys)
104
- - Webhook signatures verified on every request (`PHARAOH_GITHUB_WEBHOOK_SECRET`)
105
- - Org membership re-checked on every token refresh
106
- - Tenant Neo4j users get `reader` role only — graph writes use admin connection
107
- - Rate limiting enforced per tenant, not per user
108
- - Neo4j admin credentials never leave server-side env vars
109
-
110
- **Detection triggers (auto-dispatch when changed files match):**
111
- - `src/auth/**`, `src/crypto/**` — authentication, encryption
112
- - `src/mcp/server.ts`, `src/mcp/tenant-resolver.ts` — session management, tenant isolation
113
- - `src/mcp/neo4j-queries.ts` — Cypher query construction
114
- - `src/stripe/**`, `src/web/routes/billing.ts` — payment flows
115
- - `src/github/webhooks.ts`, `src/web/routes/webhooks.ts` — webhook verification
116
- - `src/db/**` — database access, schema changes
117
- - Any file containing `validateRepoOwnership`, `runQuery`, `encryptProperty`, `verifyWebhookSignature`
120
+ **Layer 2 — The project's own security rules:**
121
+ Take them from the project's rules collected in Phase 1 and check each one against the diff by name. Rules like "every query is scoped to the caller's tenant", "tokens are stored hashed" and "webhooks verify their signature" are what this layer exists for. If the project states none, work out its threat model from the code: who the users and tenants are, where secrets live, which inputs are untrusted.
122
+
123
+ **Detection triggers (dispatch when the change touches any of these):**
124
+ - Authentication, sessions, tokens, permissions, and the middleware that guards routes
125
+ - Cryptography, secrets, key handling, and environment variables that hold credentials
126
+ - Query construction and data access (SQL, raw ORM queries, NoSQL, graph queries), schema migrations
127
+ - Payments, billing, subscriptions
128
+ - Webhooks, signature verification, third-party callbacks
129
+ - File paths, uploads, shell commands or URLs built from user input
130
+ - Anything the project's rules call security-sensitive
131
+
132
+ Always match on file paths and names (auth, session, token, crypto, middleware, webhook, billing, payment, migration), and classify files that are new on this branch from the diff itself. With Pharaoh, also find these structurally: `get_module_context` on a touched module lists its endpoints, database tables and environment variables, and `get_blast_radius` shows the endpoints, jobs and database operations a changed function reaches. A change that reaches an endpoint, a table or a secret is security-sensitive. Pharaoh's graph is the default branch, so it sees what existing code a change reaches, never the files the branch adds.
118
133
 
119
134
  **Output format:** Each finding must include:
120
- 1. Vulnerability class (e.g., "Cypher Injection", "Missing Ownership Check")
135
+ 1. Vulnerability class (e.g., "SQL Injection", "Missing Authorization Check")
121
136
  2. Severity: CRITICAL / HIGH / MEDIUM
122
137
  3. Affected file:line
123
138
  4. Attack scenario: how an attacker would exploit this
@@ -127,10 +142,10 @@ The Security Reviewer agent runs a systematic audit against two layers: universa
127
142
 
128
143
  For each agent, launch a subagent (via the Agent tool) with:
129
144
  1. The **git diff** of the relevant changed files (not the full session history)
130
- 2. The **Pharaoh context** from Phase 1 (architecture map, blast radius, module profiles) — this is what makes these agents architecture-aware
131
- 3. The **CLAUDE.md rules** relevant to the review (testing requirements, security non-negotiables, code style)
145
+ 2. The **architecture context** from Phase 1 (architecture map, blast radius, module profiles, from Pharaoh or the fallback) — this is what makes these agents architecture-aware
146
+ 3. The **project's rules** from Phase 1 that bear on the review (testing requirements, security rules, code style)
132
147
  4. A clear instruction to focus ONLY on changed code, not pre-existing issues
133
- 5. For the **Security Reviewer** specifically: include the full Layer 2 checklist above and the list of security-sensitive file paths so it knows the project's threat model
148
+ 5. For the **Security Reviewer** specifically: the project's security rules (Layer 2) and the security-sensitive files you found, so it knows the project's threat model
134
149
 
135
150
  Each agent returns a structured report with findings categorized by severity:
136
151
  - **CRITICAL** (90-100): Must fix before merge
@@ -152,7 +167,7 @@ Each agent returns a structured report with findings categorized by severity:
152
167
 
153
168
  Trigger Phase 3 when ANY of these are true:
154
169
  - Changes touch **auth, encryption, access control, token handling, or session management**
155
- - Changes touch **tenant isolation, query construction, or data access patterns**
170
+ - Changes touch **multi-tenant isolation, query construction, or data access patterns**
156
171
  - Changes touch **billing, subscription management, or payment flows**
157
172
  - Changes modify **webhook verification or signature checking**
158
173
  - The Phase 1 blast radius marks the change as **HIGH** risk
@@ -165,7 +180,7 @@ If none of these triggers are met, **skip Phase 3** and proceed to Phase 4.
165
180
  1. **Prepare a review package** — do NOT send your session history:
166
181
  - The changed files (full diff or complete file contents)
167
182
  - What the code does and why it was changed (1-2 sentences)
168
- - Security constraints from CLAUDE.md (tenant isolation rules, encryption requirements, etc.)
183
+ - The project's security rules from Phase 1 (tenant isolation, encryption requirements, etc.)
169
184
  - Specific concerns you want the reviewer to focus on
170
185
 
171
186
  2. **Dispatch to an independent subagent** with instructions to evaluate the code fresh and assign verdicts:
@@ -241,15 +256,14 @@ If none of these triggers are met, **skip Phase 3** and proceed to Phase 4.
241
256
  ### Auto-block triggers (any of these = BLOCK)
242
257
 
243
258
  - Any CRITICAL security finding (injection, broken access control, tenant isolation violation, secret exposure)
244
- - Unreachable exports (new public code with zero callers)
259
+ - Unreachable exports in an application (new public code that nothing calls). In a library, exports are the public API: check each new one is documented or tested instead. Without reachability data (no Pharaoh, no PR Guard), raise it under SHIP WITH CHANGES, not BLOCK
245
260
  - New circular dependencies between modules
246
261
  - HIGH regression risk without corresponding test coverage
247
262
  - **A MUST-bullet in `docs/VISION.md` is violated by this change** (without VISION.md being updated in the same PR with user approval)
248
263
  - Vision spec drift: new complex function has no matching assertion AND the domain it lives in has existing assertions (implies invariants are expected here)
249
264
  - Any CRITICAL finding from Phase 2 or Phase 3 that is confirmed and unfixed
250
265
  - DISAGREE verdict from adversarial review on security-sensitive code, confirmed after verification
251
- - Unanchored Cypher query (MATCH without traversing through `Repo {name: $repo}`)
252
- - Missing `validateRepoOwnership()` on a new tool handler
266
+ - A violation of a security rule the project states as non-negotiable (Phase 1), such as a query that skips the project's tenant scoping or a handler that skips its authorization check
253
267
 
254
268
  ### SHIP WITH CHANGES triggers
255
269
 
@@ -261,7 +275,7 @@ If none of these triggers are met, **skip Phase 3** and proceed to Phase 4.
261
275
  ### SHIP triggers
262
276
 
263
277
  - No CRITICAL or confirmed IMPORTANT findings
264
- - All new exports are reachable
278
+ - All new exports are reachable (applications) or documented and tested (libraries)
265
279
  - Regression risk is LOW or MEDIUM with adequate test coverage
266
280
  - Spec alignment is clean or intentionally divergent with documentation
267
281
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pharaoh-so/mcp",
3
3
  "mcpName": "so.pharaoh/pharaoh",
4
- "version": "0.3.43",
4
+ "version": "0.3.45",
5
5
  "description": "MCP proxy for Pharaoh — maps codebases into queryable knowledge graphs for AI agents. Enables Claude Code in headless environments (VPS, SSH, CI) via device flow auth.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: review
3
3
  prompt-name: review-with-pharaoh
4
- description: "The definitive code review. Five-phase workflow: git context detection (worktree, branch, base, changed files), Pharaoh recon (architecture map, module context, blast radius in one call), parallel specialized agent dispatch (code quality, error handling, test coverage, type design), cross-model adversarial review for security-sensitive changes, and a final synthesized verdict of SHIP / SHIP WITH CHANGES / BLOCK. Always architecture-aware, always branch-aware."
5
- version: 0.3.0
4
+ description: "The definitive code review, for any codebase. Five-phase workflow: git context detection (worktree, branch, base, changed files), Pharaoh recon (architecture map, module context, blast radius in one call, with a fallback when the repo isn't mapped), parallel specialized agent dispatch (code quality, security against the project's own rules, error handling, test coverage, type design), adversarial review for security-sensitive changes, and a final synthesized verdict of SHIP / SHIP WITH CHANGES / BLOCK. Architecture-aware wherever Pharaoh maps the repo, always branch-aware."
5
+ version: 0.4.1
6
6
  homepage: https://pharaoh.so
7
7
  user-invocable: true
8
8
  metadata: {"emoji": "☥", "tags": ["code-review", "pull-request", "architecture", "pharaoh", "multi-agent", "adversarial-review", "regression-risk", "spec-alignment"]}
@@ -10,7 +10,7 @@ metadata: {"emoji": "☥", "tags": ["code-review", "pull-request", "architecture
10
10
 
11
11
  # Review with Pharaoh
12
12
 
13
- The definitive code review. Architecture-aware, branch-aware, multi-agent, adversarial. Five phases that combine Pharaoh's knowledge graph with parallel specialized reviewers and an independent cross-model second opinion.
13
+ The definitive code review, for any codebase. Architecture-aware, branch-aware, multi-agent, adversarial. Five phases that combine Pharaoh's knowledge graph with parallel specialized reviewers and an independent second opinion. Every phase works without Pharaoh too; Pharaoh makes the architecture picture exact and cheap where it maps the repo.
14
14
 
15
15
  Final verdict: **SHIP** / **SHIP WITH CHANGES** / **BLOCK**
16
16
 
@@ -32,16 +32,22 @@ Before merging any branch. Before opening any PR. When reviewing changes that to
32
32
  git log --oneline -1 # latest commit
33
33
  ```
34
34
 
35
- 2. Determine the base branch (what this branch diverged from):
35
+ 2. Determine the base (where this branch diverged from the branch it merges into). The target is the first of these that resolves:
36
36
  ```bash
37
- git merge-base HEAD main # or master, or whatever the default is
37
+ TARGET=$(gh pr view --json baseRefName --jq '"origin/" + .baseRefName' 2>/dev/null) # the open PR's target branch
38
+ [ -n "$TARGET" ] || TARGET=$(git symbolic-ref -q --short refs/remotes/origin/HEAD) # the default branch, set by git clone
39
+ [ -n "$TARGET" ] || for b in origin/main origin/master main master; do
40
+ git rev-parse -q --verify "$b" >/dev/null && TARGET=$b && break
41
+ done
42
+ git merge-base HEAD "$TARGET" # prints the base commit: $BASE below
38
43
  ```
44
+ If no base comes out, stop and ask which branch this merges into. An empty base makes every diff below come out empty, and the review would report no changes.
39
45
 
40
46
  3. Collect the full changeset from the base:
41
47
  ```bash
42
- git diff --name-only $(git merge-base HEAD main)...HEAD # all changed files
43
- git diff --stat $(git merge-base HEAD main)...HEAD # summary stats
44
- git log --oneline $(git merge-base HEAD main)..HEAD # all commits on this branch
48
+ git diff --name-only "$BASE"...HEAD # all changed files
49
+ git diff --stat "$BASE"...HEAD # summary stats
50
+ git log --oneline "$BASE"..HEAD # all commits on this branch
45
51
  ```
46
52
 
47
53
  4. Also check for uncommitted work:
@@ -58,18 +64,34 @@ Before merging any branch. Before opening any PR. When reviewing changes that to
58
64
 
59
65
  ## Phase 1 — Pharaoh Recon
60
66
 
61
- **Goal:** Get the full architectural picture in one call. Do NOT skip this phase — it is what makes this review architecture-aware instead of just a code diff review.
67
+ **Goal:** Get the full architectural picture, and the project's own rules, before reading the diff in depth. Do NOT skip this phase: it is what makes this review architecture-aware instead of just a code diff review.
68
+
69
+ ### With Pharaoh
62
70
 
63
71
  Call `pharaoh_recon` with:
64
- - **repo:** The repository name
72
+ - **repo:** The repository name (if the name is wrong, Pharaoh replies with the repos it maps)
65
73
  - **include_map:** `true`
66
74
  - **modules:** The touched modules from Phase 0 (up to 5)
67
75
  - **blast_radius:** The most critical changed files/functions as blast radius targets (up to 3). Pick the files with the most downstream risk — entry points, shared utilities, exported APIs.
68
76
  - **dependencies:** Pairs of touched modules to trace coupling between (up to 3)
69
77
 
78
+ Pharaoh's graph maps the default branch, so it shows what the change lands on: callers, blast radius, module boundaries, endpoints. Code that is new on this branch isn't in it yet; read the diff for that.
79
+
80
+ ### Without Pharaoh (graceful fallback)
81
+
82
+ If Pharaoh isn't connected, or doesn't map this repo, build the same picture by hand. When Pharaoh is connected but doesn't map the repo, tell the user once that mapping it makes this review architecture-aware, with the install link from `pharaoh_account`, then carry on:
83
+ 1. Read the top-level layout and the manifest files (package.json, pyproject.toml, go.mod, Cargo.toml) to find the module boundaries
84
+ 2. For each changed exported function or file, search for its callers to estimate the blast radius
85
+ 3. Read the entry points the change can reach: routes, CLI commands, jobs, event handlers
86
+ 4. Say in the review that the architecture context came from search, not the graph
87
+
88
+ ### The project's own rules
89
+
90
+ Read the rules the project states for itself: `CLAUDE.md` or `AGENTS.md` (including nested ones in touched directories), `CONTRIBUTING.md` and `SECURITY.md`, whichever exist. Note every rule stated as non-negotiable: testing requirements, security invariants, code style. They are what Phase 2's reviewers check the change against.
91
+
70
92
  Then read `docs/VISION.md` if the repo has one — the repo's architectural contract. For every touched module, find its relevant assertions. Any change touching code governed by a MUST-bullet must be checked against that assertion — if the change would violate the MUST, the verdict tips toward BLOCK unless VISION.md is updated in the same PR with user approval.
71
93
 
72
- **Output of Phase 1:** Architecture map, module profiles for every touched module, blast radius for high-risk changes, dependency paths between coupled modules, and spec alignment.
94
+ **Output of Phase 1:** Architecture map, module profiles for every touched module, blast radius for high-risk changes, dependency paths between coupled modules, the project's rules, and spec alignment.
73
95
 
74
96
  ---
75
97
 
@@ -81,8 +103,8 @@ Then read `docs/VISION.md` if the repo has one — the repo's architectural cont
81
103
 
82
104
  | Agent | When to dispatch | Focus |
83
105
  |-------|-----------------|-------|
84
- | **Code Reviewer** | Always | Bugs, logic errors, CLAUDE.md compliance, code quality. Confidence-filtered (only issues >= 80/100). |
85
- | **Security Reviewer** | When changes touch auth, encryption, tokens, tenant isolation, data access, billing, webhooks, Cypher queries, or any security-sensitive surface. Also dispatch when the Phase 1 blast radius marks the change as HIGH risk. | OWASP Top 10, injection vectors, access control bypasses, tenant isolation violations, cryptographic misuse, secret exposure, plus project-specific security rules. See checklist below. |
106
+ | **Code Reviewer** | Always | Bugs, logic errors, compliance with the project's rules, code quality. Confidence-filtered (only issues >= 80/100). |
107
+ | **Security Reviewer** | When changes touch any security-sensitive surface (see the detection triggers below). Also dispatch when the Phase 1 blast radius marks the change as HIGH risk. | OWASP Top 10, injection vectors, access control bypasses, tenant isolation in multi-tenant systems, cryptographic misuse, secret exposure, plus the project's own security rules. See checklist below. |
86
108
  | **Silent Failure Hunter** | When changes touch error handling, catch blocks, fallback logic, API calls, or any code that could suppress errors | Silent failures, broad catches, swallowed errors, missing user feedback, unjustified fallbacks. |
87
109
  | **Test Analyzer** | When test files are changed, or when new functionality lacks corresponding tests | Behavioral coverage gaps, brittle tests, missing edge cases, tests that prove nothing. |
88
110
  | **Type Design Analyzer** | When new types/interfaces are introduced or existing types are modified | Encapsulation, invariant expression, invariant enforcement. Rates each type 1-10 on four axes. |
@@ -92,7 +114,7 @@ Then read `docs/VISION.md` if the repo has one — the repo's architectural cont
92
114
  The Security Reviewer agent runs a systematic audit against two layers: universal web security (OWASP) and project-specific invariants.
93
115
 
94
116
  **Layer 1 — OWASP Top 10 + Common Vulnerabilities:**
95
- - **Injection:** SQL/Cypher injection, command injection, XSS (reflected/stored/DOM), template injection
117
+ - **Injection:** SQL, NoSQL and graph query injection, command injection, XSS (reflected/stored/DOM), template injection
96
118
  - **Broken auth:** Hardcoded credentials, weak token generation, missing expiry, session fixation
97
119
  - **Broken access control:** Missing authorization checks, IDOR, privilege escalation, path traversal
98
120
  - **Cryptographic failures:** Weak algorithms, plaintext secrets, missing encryption at rest/transit, key exposure
@@ -101,29 +123,22 @@ The Security Reviewer agent runs a systematic audit against two layers: universa
101
123
  - **SSRF:** Unvalidated URLs in fetch/request calls, redirect chains
102
124
  - **Logging & monitoring:** Sensitive data in logs, missing audit trails for privileged operations
103
125
 
104
- **Layer 2 — Project-Specific Security Rules (from CLAUDE.md):**
105
- - Every Cypher query takes `repo` as first parameter — no unanchored MATCH clauses
106
- - `validateRepoOwnership()` runs before every tool handler
107
- - No default/fallback repo values — repo always from tenant's Postgres `tenant_repos`
108
- - Tokens stored as SHA-256 hashes, never plaintext
109
- - GitHub tokens encrypted at rest (AES-256-GCM with per-tenant HKDF-derived keys)
110
- - Webhook signatures verified on every request (`PHARAOH_GITHUB_WEBHOOK_SECRET`)
111
- - Org membership re-checked on every token refresh
112
- - Tenant Neo4j users get `reader` role only — graph writes use admin connection
113
- - Rate limiting enforced per tenant, not per user
114
- - Neo4j admin credentials never leave server-side env vars
115
-
116
- **Detection triggers (auto-dispatch when changed files match):**
117
- - `src/auth/**`, `src/crypto/**` — authentication, encryption
118
- - `src/mcp/server.ts`, `src/mcp/tenant-resolver.ts` — session management, tenant isolation
119
- - `src/mcp/neo4j-queries.ts` — Cypher query construction
120
- - `src/stripe/**`, `src/web/routes/billing.ts` — payment flows
121
- - `src/github/webhooks.ts`, `src/web/routes/webhooks.ts` — webhook verification
122
- - `src/db/**` — database access, schema changes
123
- - Any file containing `validateRepoOwnership`, `runQuery`, `encryptProperty`, `verifyWebhookSignature`
126
+ **Layer 2 — The project's own security rules:**
127
+ Take them from the project's rules collected in Phase 1 and check each one against the diff by name. Rules like "every query is scoped to the caller's tenant", "tokens are stored hashed" and "webhooks verify their signature" are what this layer exists for. If the project states none, work out its threat model from the code: who the users and tenants are, where secrets live, which inputs are untrusted.
128
+
129
+ **Detection triggers (dispatch when the change touches any of these):**
130
+ - Authentication, sessions, tokens, permissions, and the middleware that guards routes
131
+ - Cryptography, secrets, key handling, and environment variables that hold credentials
132
+ - Query construction and data access (SQL, raw ORM queries, NoSQL, graph queries), schema migrations
133
+ - Payments, billing, subscriptions
134
+ - Webhooks, signature verification, third-party callbacks
135
+ - File paths, uploads, shell commands or URLs built from user input
136
+ - Anything the project's rules call security-sensitive
137
+
138
+ Always match on file paths and names (auth, session, token, crypto, middleware, webhook, billing, payment, migration), and classify files that are new on this branch from the diff itself. With Pharaoh, also find these structurally: `get_module_context` on a touched module lists its endpoints, database tables and environment variables, and `get_blast_radius` shows the endpoints, jobs and database operations a changed function reaches. A change that reaches an endpoint, a table or a secret is security-sensitive. Pharaoh's graph is the default branch, so it sees what existing code a change reaches, never the files the branch adds.
124
139
 
125
140
  **Output format:** Each finding must include:
126
- 1. Vulnerability class (e.g., "Cypher Injection", "Missing Ownership Check")
141
+ 1. Vulnerability class (e.g., "SQL Injection", "Missing Authorization Check")
127
142
  2. Severity: CRITICAL / HIGH / MEDIUM
128
143
  3. Affected file:line
129
144
  4. Attack scenario: how an attacker would exploit this
@@ -133,10 +148,10 @@ The Security Reviewer agent runs a systematic audit against two layers: universa
133
148
 
134
149
  For each agent, launch a subagent (via the Agent tool) with:
135
150
  1. The **git diff** of the relevant changed files (not the full session history)
136
- 2. The **Pharaoh context** from Phase 1 (architecture map, blast radius, module profiles) — this is what makes these agents architecture-aware
137
- 3. The **CLAUDE.md rules** relevant to the review (testing requirements, security non-negotiables, code style)
151
+ 2. The **architecture context** from Phase 1 (architecture map, blast radius, module profiles, from Pharaoh or the fallback) — this is what makes these agents architecture-aware
152
+ 3. The **project's rules** from Phase 1 that bear on the review (testing requirements, security rules, code style)
138
153
  4. A clear instruction to focus ONLY on changed code, not pre-existing issues
139
- 5. For the **Security Reviewer** specifically: include the full Layer 2 checklist above and the list of security-sensitive file paths so it knows the project's threat model
154
+ 5. For the **Security Reviewer** specifically: the project's security rules (Layer 2) and the security-sensitive files you found, so it knows the project's threat model
140
155
 
141
156
  Each agent returns a structured report with findings categorized by severity:
142
157
  - **CRITICAL** (90-100): Must fix before merge
@@ -158,7 +173,7 @@ Each agent returns a structured report with findings categorized by severity:
158
173
 
159
174
  Trigger Phase 3 when ANY of these are true:
160
175
  - Changes touch **auth, encryption, access control, token handling, or session management**
161
- - Changes touch **tenant isolation, query construction, or data access patterns**
176
+ - Changes touch **multi-tenant isolation, query construction, or data access patterns**
162
177
  - Changes touch **billing, subscription management, or payment flows**
163
178
  - Changes modify **webhook verification or signature checking**
164
179
  - The Phase 1 blast radius marks the change as **HIGH** risk
@@ -171,7 +186,7 @@ If none of these triggers are met, **skip Phase 3** and proceed to Phase 4.
171
186
  1. **Prepare a review package** — do NOT send your session history:
172
187
  - The changed files (full diff or complete file contents)
173
188
  - What the code does and why it was changed (1-2 sentences)
174
- - Security constraints from CLAUDE.md (tenant isolation rules, encryption requirements, etc.)
189
+ - The project's security rules from Phase 1 (tenant isolation, encryption requirements, etc.)
175
190
  - Specific concerns you want the reviewer to focus on
176
191
 
177
192
  2. **Dispatch to an independent subagent** with instructions to evaluate the code fresh and assign verdicts:
@@ -247,15 +262,14 @@ If none of these triggers are met, **skip Phase 3** and proceed to Phase 4.
247
262
  ### Auto-block triggers (any of these = BLOCK)
248
263
 
249
264
  - Any CRITICAL security finding (injection, broken access control, tenant isolation violation, secret exposure)
250
- - Unreachable exports (new public code with zero callers)
265
+ - Unreachable exports in an application (new public code that nothing calls). In a library, exports are the public API: check each new one is documented or tested instead. Without reachability data (no Pharaoh, no PR Guard), raise it under SHIP WITH CHANGES, not BLOCK
251
266
  - New circular dependencies between modules
252
267
  - HIGH regression risk without corresponding test coverage
253
268
  - **A MUST-bullet in `docs/VISION.md` is violated by this change** (without VISION.md being updated in the same PR with user approval)
254
269
  - Vision spec drift: new complex function has no matching assertion AND the domain it lives in has existing assertions (implies invariants are expected here)
255
270
  - Any CRITICAL finding from Phase 2 or Phase 3 that is confirmed and unfixed
256
271
  - DISAGREE verdict from adversarial review on security-sensitive code, confirmed after verification
257
- - Unanchored Cypher query (MATCH without traversing through `Repo {name: $repo}`)
258
- - Missing `validateRepoOwnership()` on a new tool handler
272
+ - A violation of a security rule the project states as non-negotiable (Phase 1), such as a query that skips the project's tenant scoping or a handler that skips its authorization check
259
273
 
260
274
  ### SHIP WITH CHANGES triggers
261
275
 
@@ -267,7 +281,7 @@ If none of these triggers are met, **skip Phase 3** and proceed to Phase 4.
267
281
  ### SHIP triggers
268
282
 
269
283
  - No CRITICAL or confirmed IMPORTANT findings
270
- - All new exports are reachable
284
+ - All new exports are reachable (applications) or documented and tested (libraries)
271
285
  - Regression risk is LOW or MEDIUM with adequate test coverage
272
286
  - Spec alignment is clean or intentionally divergent with documentation
273
287