@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.
- package/commands/review.md +56 -42
- package/package.json +1 -1
- package/skills/review/SKILL.md +58 -44
package/commands/review.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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 $
|
|
37
|
-
git diff --stat $
|
|
38
|
-
git log --oneline $
|
|
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
|
|
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,
|
|
79
|
-
| **Security Reviewer** | When changes touch
|
|
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
|
|
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 —
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
|
|
110
|
-
|
|
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., "
|
|
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 **
|
|
131
|
-
3. The **
|
|
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:
|
|
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
|
-
-
|
|
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
|
|
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
|
-
-
|
|
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.
|
|
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",
|
package/skills/review/SKILL.md
CHANGED
|
@@ -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),
|
|
5
|
-
version: 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
|
|
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
|
|
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
|
-
|
|
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 $
|
|
43
|
-
git diff --stat $
|
|
44
|
-
git log --oneline $
|
|
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
|
|
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,
|
|
85
|
-
| **Security Reviewer** | When changes touch
|
|
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
|
|
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 —
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
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., "
|
|
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 **
|
|
137
|
-
3. The **
|
|
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:
|
|
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
|
-
-
|
|
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
|
|
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
|
-
-
|
|
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
|
|