@telelabsai/ship 1.1.2 → 1.1.4

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.
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: reviewer
3
+ description: "Use this agent for code review, test analysis, and security scanning. Handles large diffs and verbose output in isolated context. Spawns for ship-review, ship-test, and ship-secure skills."
4
+ model: sonnet
5
+ tools: Bash, Read, Glob, Grep, Edit
6
+ ---
7
+
8
+ You are a senior code reviewer, test analyst, and security auditor. You analyze codebases with precision and report findings concisely.
9
+
10
+ Activate the relevant skill by reading its SKILL.md and references:
11
+ - Code review: `.claude/skills/ship-review/SKILL.md`
12
+ - Test analysis: `.claude/skills/ship-test/SKILL.md`
13
+ - Security scan: `.claude/skills/ship-secure/SKILL.md`
14
+
15
+ ## Core Principles
16
+
17
+ - Never report false positives. If unsure, mark as "Needs verification"
18
+ - Always include file path and line number for every finding
19
+ - Prioritize findings by impact, not alphabetically
20
+ - Explain WHY something is a problem, not just WHAT
21
+ - Suggest a fix for every finding
22
+ - Respect the codebase's existing patterns before suggesting changes
23
+
24
+ ## Severity Levels
25
+
26
+ | Level | Meaning | CI behavior |
27
+ |-------|---------|-------------|
28
+ | Critical | Must fix. Security holes, data loss, broken logic | Blocks merge |
29
+ | Warning | Should fix. Performance, error handling, testing gaps | Warns |
30
+ | Suggestion | Nice to have. Naming, style, minor improvements | Info only |
31
+
32
+ ## Output Format
33
+
34
+ Always end with a structured summary:
35
+
36
+ ```
37
+ Files reviewed: N
38
+ Critical: N | Warning: N | Suggestion: N
39
+ Verdict: PASS or FAIL (FAIL if any critical)
40
+ ```
41
+
42
+ ## CI Mode
43
+
44
+ When `--ci` flag is present:
45
+ - Output only the structured report (no conversational text)
46
+ - Exit with status in verdict (PASS/FAIL)
47
+ - Format output as markdown suitable for PR comments
@@ -1,20 +1,25 @@
1
1
  /**
2
2
  * PreToolUse hook — blocks dangerous git operations before they execute.
3
+ * Reads secret patterns from shared/secret-patterns.json (single source of truth).
3
4
  *
4
5
  * Exit 0 = allow the tool call
5
6
  * Exit 2 = block the tool call (stdout = reason shown to Claude)
6
7
  */
7
8
 
8
9
  const fs = require('fs');
10
+ const path = require('path');
9
11
 
10
12
  let input;
11
13
  try {
12
14
  input = JSON.parse(fs.readFileSync('/dev/stdin', 'utf8'));
13
15
  } catch {
14
- process.exit(0); // can't parse → allow
16
+ process.exit(0);
15
17
  }
16
18
 
17
19
  const cmd = (input.tool_input && input.tool_input.command) || '';
20
+ const patterns = JSON.parse(
21
+ fs.readFileSync(path.join(__dirname, '..', 'shared', 'secret-patterns.json'), 'utf8')
22
+ );
18
23
 
19
24
  // --- Block force push ---
20
25
  if (/push\s+.*(-f|--force)(?!\S)/.test(cmd) && !cmd.includes('--force-with-lease')) {
@@ -22,36 +27,23 @@ if (/push\s+.*(-f|--force)(?!\S)/.test(cmd) && !cmd.includes('--force-with-lease
22
27
  process.exit(2);
23
28
  }
24
29
 
25
- // --- Block push to protected branches without confirmation ---
26
- const protectedPush = /push\s+.*\b(main|master|production|prod)\b/.test(cmd);
27
- if (protectedPush && !cmd.includes('--force-with-lease')) {
28
- // Allow regular push to main, but block force variants
29
- // The rule file handles the "ask user" part for regular pushes
30
- }
31
-
32
30
  // --- Block staging sensitive files ---
33
- const sensitivePatterns = [
34
- /git\s+add\s+.*\.env(?!\.\w*example)/,
35
- /git\s+add\s+.*credentials/,
36
- /git\s+add\s+.*\.pem/,
37
- /git\s+add\s+.*\.key/,
38
- /git\s+add\s+.*secrets?\./,
39
- ];
40
-
41
- for (const pattern of sensitivePatterns) {
42
- if (pattern.test(cmd)) {
43
- console.log('BLOCKED: Cannot stage sensitive files (.env, credentials, keys). Add to .gitignore instead.');
31
+ for (const file of patterns.dangerousFiles) {
32
+ const escaped = file.replace(/\./g, '\\.').replace(/\*/g, '[^\\s]*');
33
+ const regex = new RegExp(`git\\s+add\\s+.*${escaped}`);
34
+ if (regex.test(cmd)) {
35
+ console.log(`BLOCKED: Cannot stage sensitive file matching "${file}". Add to .gitignore instead.`);
44
36
  process.exit(2);
45
37
  }
46
38
  }
47
39
 
48
- // --- Block git add -A / git add . (encourage specific staging) ---
40
+ // --- Block git add -A / git add . ---
49
41
  if (/git\s+add\s+(-A|--all|\.)(\s|$)/.test(cmd)) {
50
- console.log('BLOCKED: Use specific file names instead of "git add ." or "git add -A" to avoid staging secrets or unwanted files.');
42
+ console.log('BLOCKED: Use specific file names instead of "git add ." or "git add -A" to avoid staging secrets.');
51
43
  process.exit(2);
52
44
  }
53
45
 
54
- // --- Block destructive resets without warning ---
46
+ // --- Block destructive resets ---
55
47
  if (/git\s+reset\s+--hard/.test(cmd)) {
56
48
  console.log('BLOCKED: "git reset --hard" discards all uncommitted changes. Ask the user to confirm first.');
57
49
  process.exit(2);
@@ -0,0 +1,15 @@
1
+ # Code Quality
2
+
3
+ Quick reminders (detailed checks in `.claude/skills/ship-review/references/review-categories.md`):
4
+
5
+ - No N+1 queries, missing indexes, or unbounded queries
6
+ - No race conditions in async code
7
+ - No memory leaks (uncleaned listeners, intervals, subscriptions)
8
+ - Validate error handling on all external calls (APIs, DB, file I/O)
9
+ - Consistent API response format across endpoints
10
+ - No nested loops over large datasets without justification
11
+ - Use caching on repeated expensive operations
12
+ - Validate input at system boundaries
13
+ - Use idempotency keys on payment operations
14
+ - Validate webhook signatures on incoming webhooks
15
+ - Use circuit breakers and timeouts on third-party API calls
@@ -0,0 +1,10 @@
1
+ # Security
2
+
3
+ - Never hardcode secrets, API keys, passwords, or tokens in source code
4
+ - Never use string concatenation in SQL/NoSQL queries (use parameterized queries)
5
+ - Never trust user input (validate and sanitize at all entry points)
6
+ - Ensure all endpoints have authentication and authorization checks
7
+ - Ensure sensitive data is not logged (passwords, tokens, PII)
8
+ - Ensure cookies use httpOnly, secure, and sameSite flags
9
+ - Ensure JWT tokens have expiration
10
+ - Secret patterns defined in .claude/shared/secret-patterns.json
@@ -0,0 +1,62 @@
1
+ {
2
+ "description": "Single source of truth for secret detection. Used by hooks, skills, and git hooks.",
3
+
4
+ "apiKeys": [
5
+ { "name": "AWS Access Key", "pattern": "AKIA[0-9A-Z]{16}", "severity": "critical" },
6
+ { "name": "OpenAI API Key", "pattern": "sk-[a-zA-Z0-9]{48}", "severity": "critical" },
7
+ { "name": "Anthropic API Key", "pattern": "sk-ant-[a-zA-Z0-9-]{90,}", "severity": "critical" },
8
+ { "name": "GitHub Token (PAT)", "pattern": "ghp_[a-zA-Z0-9]{36}", "severity": "critical" },
9
+ { "name": "GitHub OAuth Token", "pattern": "gho_[a-zA-Z0-9]{36}", "severity": "critical" },
10
+ { "name": "GitLab Token", "pattern": "glpat-[a-zA-Z0-9-]{20}", "severity": "critical" },
11
+ { "name": "Slack Bot Token", "pattern": "xoxb-[0-9]{10,}-[a-zA-Z0-9]{24}", "severity": "critical" },
12
+ { "name": "Slack User Token", "pattern": "xoxp-[0-9]{10,}-[a-zA-Z0-9]{24}", "severity": "critical" },
13
+ { "name": "SendGrid API Key", "pattern": "SG\\.[a-zA-Z0-9_-]{22}\\.[a-zA-Z0-9_-]{43}", "severity": "critical" },
14
+ { "name": "Stripe Secret Key", "pattern": "sk_live_[a-zA-Z0-9]{24,}", "severity": "critical" },
15
+ { "name": "Stripe Restricted Key", "pattern": "rk_live_[a-zA-Z0-9]{24,}", "severity": "critical" },
16
+ { "name": "Square Access Token", "pattern": "sq0atp-[a-zA-Z0-9_-]{22}", "severity": "critical" },
17
+ { "name": "Google API Key", "pattern": "AIza[0-9A-Za-z_-]{35}", "severity": "critical" },
18
+ { "name": "Twilio API Key", "pattern": "SK[a-f0-9]{32}", "severity": "critical" },
19
+ { "name": "Mailgun API Key", "pattern": "key-[a-zA-Z0-9]{32}", "severity": "critical" }
20
+ ],
21
+
22
+ "credentials": [
23
+ { "name": "Hardcoded password", "pattern": "password\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" },
24
+ { "name": "Hardcoded secret", "pattern": "secret\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" },
25
+ { "name": "Hardcoded API key", "pattern": "api[_-]?key\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" },
26
+ { "name": "Hardcoded token", "pattern": "auth[_-]?token\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" },
27
+ { "name": "OAuth client secret", "pattern": "client[_-]?secret\\s*[:=]\\s*['\"][^'\"]{4,}['\"]", "severity": "critical" }
28
+ ],
29
+
30
+ "databaseUrls": [
31
+ { "name": "MongoDB connection string", "pattern": "mongodb(\\+srv)?://[^/\\s]{8,}", "severity": "critical" },
32
+ { "name": "PostgreSQL connection string", "pattern": "postgres(ql)?://[^/\\s]{8,}", "severity": "critical" },
33
+ { "name": "MySQL connection string", "pattern": "mysql://[^/\\s]{8,}", "severity": "critical" },
34
+ { "name": "Redis connection string", "pattern": "redis://[^/\\s]{8,}", "severity": "critical" },
35
+ { "name": "RabbitMQ connection string", "pattern": "amqp://[^/\\s]{8,}", "severity": "critical" }
36
+ ],
37
+
38
+ "privateKeys": [
39
+ { "name": "RSA/EC/DSA Private Key", "pattern": "-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----", "severity": "critical" },
40
+ { "name": "PGP Private Key", "pattern": "-----BEGIN PGP PRIVATE KEY BLOCK-----", "severity": "critical" }
41
+ ],
42
+
43
+ "dangerousFiles": [
44
+ ".env", ".env.local", ".env.production", ".env.staging", ".env.development",
45
+ "*.pem", "*.key", "*.p12", "*.pfx",
46
+ "credentials.json", "secrets.json", "service-account.json",
47
+ "id_rsa", "id_ed25519", "id_ecdsa",
48
+ ".npmrc", ".netrc", ".htpasswd"
49
+ ],
50
+
51
+ "falsePositives": [
52
+ "process.env.",
53
+ "os.environ",
54
+ "ENV[",
55
+ "<PLACEHOLDER>",
56
+ "YOUR_KEY_HERE",
57
+ "xxx",
58
+ "changeme",
59
+ ".env.example",
60
+ ".env.template"
61
+ ]
62
+ }
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: ship-review
3
+ description: "AI code review. Analyzes code changes for logic errors, performance issues, database problems, security flaws, API contract violations, and more. Works on PRs, uncommitted changes, or full codebase."
4
+ argument-hint: "[--pr] [--full] [--focus CATEGORY] [--ci]"
5
+ ---
6
+
7
+ # ship-review — AI Code Review
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ ship review # review uncommitted changes
13
+ ship review --pr # review current PR diff against main
14
+ ship review --full # review entire codebase
15
+ ship review --focus security # focus on one category
16
+ ship review --focus perf # focus on performance
17
+ ship review --ci # CI mode (structured output, exit code)
18
+ ```
19
+
20
+ ## Modes
21
+
22
+ | Flag | Scope | Use when |
23
+ |------|-------|----------|
24
+ | (none) | Uncommitted changes | Before committing |
25
+ | `--pr` | PR diff (main..HEAD) | Before merging |
26
+ | `--full` | Entire codebase | Periodic audit |
27
+ | `--focus X` | Single category | Deep dive |
28
+ | `--ci` | Same as --pr, structured output | GitHub Actions |
29
+
30
+ ## Workflow
31
+
32
+ ### Step 1: Gather Changes
33
+
34
+ Based on mode, collect the code to review:
35
+
36
+ **Default (uncommitted):**
37
+ ```bash
38
+ git diff --name-only
39
+ git diff
40
+ ```
41
+
42
+ **PR mode:**
43
+ ```bash
44
+ git log main..HEAD --oneline
45
+ git diff main..HEAD --name-only
46
+ git diff main..HEAD
47
+ ```
48
+
49
+ **Full mode:**
50
+ ```bash
51
+ # Read all source files (exclude node_modules, .git, dist, build)
52
+ ```
53
+
54
+ ### Step 2: Analyze
55
+
56
+ Read each changed file. For every file, check all categories from `references/review-categories.md`.
57
+
58
+ Use the `reviewer` agent for large diffs to keep main context clean.
59
+
60
+ ### Step 3: Classify Findings
61
+
62
+ Assign severity per `references/severity-levels.md`.
63
+
64
+ ### Step 4: Report
65
+
66
+ Output per `references/output-format.md`.
67
+
68
+ ## Quick Reference
69
+
70
+ | Reference | Content |
71
+ |-----------|---------|
72
+ | `references/review-categories.md` | All review categories and what to check |
73
+ | `references/severity-levels.md` | How to classify findings |
74
+ | `references/output-format.md` | Report structure |
@@ -0,0 +1,62 @@
1
+ # Output Format
2
+
3
+ ## Standard Report
4
+
5
+ ```markdown
6
+ ## Ship Review
7
+
8
+ ### Critical
9
+ - [category] file/path.ts:LINE — Description of the issue
10
+ Fix: How to fix it
11
+
12
+ ### Warning
13
+ - [category] file/path.ts:LINE — Description of the issue
14
+ Fix: How to fix it
15
+
16
+ ### Suggestion
17
+ - [category] file/path.ts:LINE — Description of the issue
18
+ Fix: How to fix it
19
+
20
+ ### Summary
21
+ Files reviewed: N
22
+ Critical: N | Warning: N | Suggestion: N
23
+ Verdict: PASS or FAIL
24
+ ```
25
+
26
+ ## Rules
27
+
28
+ - Group findings by severity (Critical first, then Warning, then Suggestion)
29
+ - Within each severity, order by impact (most impactful first)
30
+ - Include file path and line number for every finding
31
+ - Include category tag in brackets: [logic], [security], [performance], [database], [api], [error], [types], [payments], [webhooks], [integrations], [naming]
32
+ - Include a one-line fix suggestion for every finding
33
+ - If no findings at a severity level, omit that section
34
+ - Verdict is FAIL if any critical findings exist, PASS otherwise
35
+ - Keep descriptions concise (one line per finding, fix on next line)
36
+ - If same pattern appears in multiple files, group: "[performance] N+1 query pattern in 4 files: list..."
37
+
38
+ ## CI Mode
39
+
40
+ Same format but:
41
+ - No conversational text before or after the report
42
+ - Just the markdown report
43
+ - Suitable for posting as a PR comment via `gh pr comment`
44
+
45
+ ## Focus Mode
46
+
47
+ When `--focus CATEGORY` is used:
48
+ - Only report findings in that category
49
+ - Still use same format and severity levels
50
+ - Add a note at top: "Focused review: [category] only"
51
+
52
+ ## No Issues Found
53
+
54
+ ```markdown
55
+ ## Ship Review
56
+
57
+ No issues found.
58
+
59
+ Files reviewed: N
60
+ Critical: 0 | Warning: 0 | Suggestion: 0
61
+ Verdict: PASS
62
+ ```
@@ -0,0 +1,169 @@
1
+ # Review Categories
2
+
3
+ ## Logic
4
+
5
+ Check for:
6
+ - Off-by-one errors in loops and array access
7
+ - Null/undefined paths not handled
8
+ - Race conditions in async code (parallel mutations, shared state)
9
+ - Infinite loops or unbounded recursion
10
+ - Wrong comparison operators (== vs ===, > vs >=)
11
+ - Inverted boolean logic (! in wrong place)
12
+ - Dead code paths that can never execute
13
+ - Missing return statements in branching logic
14
+ - Incorrect type coercion
15
+ - Switch/case without break or default
16
+
17
+ ## Performance
18
+
19
+ Check for:
20
+ - N+1 database queries (loop with individual queries)
21
+ - Nested loops creating O(n^2) or worse complexity
22
+ - Unnecessary re-renders in React/frontend frameworks
23
+ - Memory leaks (event listeners not cleaned, intervals not cleared)
24
+ - Blocking calls in async contexts (sync file I/O, CPU-heavy in event loop)
25
+ - Missing pagination on large dataset queries
26
+ - Large payloads without streaming or compression
27
+ - Redundant computations that should be memoized or cached
28
+ - Missing cache headers on API responses
29
+ - No caching strategy for repeated expensive operations
30
+ - Stale cache without invalidation
31
+ - Loading entire collections when filtering would suffice
32
+ - Missing debounce/throttle on frequent events
33
+ - Unnecessary deep cloning of large objects
34
+
35
+ ## Database
36
+
37
+ Check for:
38
+ - Missing indexes on columns used in WHERE, JOIN, ORDER BY
39
+ - SELECT * instead of specific columns
40
+ - No LIMIT on queries that could return large result sets
41
+ - Missing transactions on multi-step operations
42
+ - Unsafe migrations (dropping columns with data, renaming without backfill)
43
+ - No rollback/down migration defined
44
+ - Raw SQL with string concatenation (SQL injection risk)
45
+ - Missing connection pooling configuration
46
+ - No timeout on database queries
47
+ - Deadlock potential (acquiring locks in inconsistent order)
48
+ - Missing unique constraints where data should be unique
49
+ - No foreign key constraints on relationships
50
+ - Schema changes without data migration plan
51
+ - Missing created_at/updated_at timestamps
52
+ - No soft delete strategy when data retention matters
53
+
54
+ ## Security
55
+
56
+ Check for:
57
+ - SQL injection (string interpolation in queries)
58
+ - XSS (unescaped user input in HTML/templates)
59
+ - Command injection (user input in shell commands)
60
+ - Hardcoded secrets, API keys, passwords
61
+ - Missing authentication on endpoints
62
+ - Missing authorization checks (user can access others' data)
63
+ - CSRF vulnerability (no token on state-changing requests)
64
+ - Insecure direct object references (sequential IDs in URLs)
65
+ - Path traversal (user input in file paths)
66
+ - Missing input validation and sanitization
67
+ - Passwords stored in plain text
68
+ - Sensitive data in logs
69
+ - Missing rate limiting on authentication endpoints
70
+ - JWT without expiration
71
+ - Insecure cookie settings (missing httpOnly, secure, sameSite)
72
+
73
+ ## API Contracts
74
+
75
+ Check for:
76
+ - Inconsistent response format across endpoints
77
+ - Breaking changes to existing API (removed/renamed fields)
78
+ - Missing input validation on request body/params
79
+ - No error response standardization
80
+ - Missing HTTP status codes (always 200, even on error)
81
+ - Undocumented endpoints or parameters
82
+ - Missing Content-Type headers
83
+ - No request size limits
84
+ - Exposing internal errors/stack traces to clients
85
+ - Missing versioning strategy on breaking changes
86
+ - Inconsistent naming (camelCase vs snake_case in responses)
87
+
88
+ ## Error Handling
89
+
90
+ Check for:
91
+ - Empty catch blocks (swallowed errors)
92
+ - Catch-all without specific error handling
93
+ - Unhandled promise rejections
94
+ - Missing error boundaries in UI frameworks
95
+ - Silent failures with no logging or user feedback
96
+ - Rethrowing errors without context
97
+ - Missing try/catch around external service calls
98
+ - No fallback for failed network requests
99
+ - Missing timeout handling on HTTP calls
100
+ - Error messages exposing implementation details
101
+
102
+ ## Types
103
+
104
+ Check for:
105
+ - Type mismatches (string where number expected)
106
+ - Unsafe type casting (as any, type assertions)
107
+ - Missing null/undefined checks before property access
108
+ - Implicit any in TypeScript
109
+ - Wrong generic types
110
+ - Missing discriminated union checks
111
+ - Optional chaining hiding real bugs (?. masking null that shouldn't be null)
112
+
113
+ ## Payments and Financial Operations
114
+
115
+ Check for:
116
+ - Missing idempotency key on payment/charge operations (double charge risk)
117
+ - Race condition on balance operations (concurrent debits can overdraw)
118
+ - No transaction wrapping on money operations (partial updates corrupt state)
119
+ - Trusting client-sent prices or amounts (price manipulation attack)
120
+ - Negative amounts not blocked (reverse charge exploit)
121
+ - Currency rounding errors (use integer cents, not floating point dollars)
122
+ - Missing reconciliation between payment provider and local DB
123
+ - No audit trail on financial operations (who charged what, when)
124
+ - Missing refund limits or cooldown period
125
+ - Balance check and debit not atomic (check-then-act race condition)
126
+ - No queue/lock for sequential financial operations on same account
127
+ - Missing retry handling with idempotency for failed payment calls
128
+
129
+ ## Webhooks
130
+
131
+ Check for:
132
+ - No signature validation on incoming webhooks (Stripe, PayPal, etc.)
133
+ - Webhook secret hardcoded instead of environment variable
134
+ - No replay protection (same event processed multiple times)
135
+ - No idempotency on webhook handlers (duplicate events cause duplicate actions)
136
+ - Missing event type validation (processing unknown event types)
137
+ - No timeout on webhook processing (blocking the webhook provider)
138
+ - Webhook endpoint exposed without IP allowlisting or signature check
139
+ - Missing error handling that could lose webhook events
140
+ - No dead letter queue for failed webhook processing
141
+ - Returning 200 before processing completes (losing events on crash)
142
+
143
+ ## Integrations (Third-Party APIs)
144
+
145
+ Check for:
146
+ - No timeout on external HTTP calls (hangs indefinitely)
147
+ - No circuit breaker (one failing service cascades to entire app)
148
+ - No retry with exponential backoff on transient failures
149
+ - Trusting external API response data without validation
150
+ - Missing error handling when integration is down
151
+ - No fallback or graceful degradation when dependency fails
152
+ - Sensitive data sent to third parties unnecessarily
153
+ - API keys for integrations hardcoded (use env vars)
154
+ - No request/response logging for debugging integration issues
155
+ - Missing rate limit handling on outbound API calls (429 responses)
156
+ - No health check for critical integration dependencies
157
+
158
+ ## Naming and Readability
159
+
160
+ Check for:
161
+ - Single-letter variables outside loop counters
162
+ - Misleading function/variable names
163
+ - Inconsistent naming conventions within the file
164
+ - Functions doing more than one thing (god functions)
165
+ - Deep nesting (>3 levels)
166
+ - Files over 300 lines
167
+ - Magic numbers without named constants
168
+ - Boolean parameters without named arguments
169
+ - Commented-out code blocks
@@ -0,0 +1,49 @@
1
+ # Severity Levels
2
+
3
+ ## Critical
4
+
5
+ Blocks merge in CI. Must fix before shipping.
6
+
7
+ Assign critical when:
8
+ - Security vulnerability exploitable in production
9
+ - Data loss or corruption possible
10
+ - Logic error that produces wrong results
11
+ - Breaking change to public API without migration
12
+ - Authentication/authorization bypass
13
+ - Race condition that causes data inconsistency
14
+ - Migration that destroys existing data
15
+
16
+ ## Warning
17
+
18
+ Should fix. Flagged but doesn't block merge.
19
+
20
+ Assign warning when:
21
+ - Performance issue that degrades user experience
22
+ - Missing error handling that could cause silent failures
23
+ - Database query without index on large table
24
+ - Missing test coverage on critical path
25
+ - N+1 query pattern
26
+ - Missing input validation (non-security context)
27
+ - Cache strategy missing on hot path
28
+ - Inconsistent API response format
29
+
30
+ ## Suggestion
31
+
32
+ Nice to have. Informational.
33
+
34
+ Assign suggestion when:
35
+ - Naming could be clearer
36
+ - Code could be simplified
37
+ - Minor style inconsistency
38
+ - Opportunity to extract reusable function
39
+ - Comment would help future readers
40
+ - Test could cover additional edge case
41
+
42
+ ## Rules
43
+
44
+ - When in doubt between two levels, pick the higher one
45
+ - Never mark a security issue below Warning
46
+ - Never mark data loss risk below Critical
47
+ - If a finding is in dead/unreachable code, downgrade by one level
48
+ - If a finding is in test code only, downgrade by one level
49
+ - Group related findings (don't report same pattern 10 times)
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: ship-secure
3
+ description: "AI security scanner. Scans entire codebase for vulnerabilities, dependency CVEs, hardcoded secrets, exposed endpoints, webhook/payment security, and infrastructure misconfigurations."
4
+ argument-hint: "[--deps] [--vulns] [--secrets] [--ci]"
5
+ ---
6
+
7
+ # ship-secure — AI Security Scanner
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ ship secure # full security scan
13
+ ship secure --deps # dependency vulnerabilities only
14
+ ship secure --vulns # vulnerability analysis only (OWASP, endpoints, webhooks, payments)
15
+ ship secure --secrets # secret detection only
16
+ ship secure --ci # CI mode (structured output, exit code)
17
+ ```
18
+
19
+ ## Difference from ship-review
20
+
21
+ - **ship-review** checks your code CHANGES (PR diff) for security issues
22
+ - **ship-secure** scans the ENTIRE CODEBASE regardless of what changed
23
+
24
+ Run `ship-review` on every PR. Run `ship-secure` weekly or before releases.
25
+
26
+ ## Workflow
27
+
28
+ ### Step 1: Dependency Audit
29
+
30
+ ```bash
31
+ npm audit 2>/dev/null || true
32
+ ```
33
+
34
+ Also read `package.json` / `package-lock.json` / `requirements.txt` / `go.mod` and check for known vulnerable versions.
35
+
36
+ Reference: `references/dependency-audit.md`
37
+
38
+ ### Step 2: Secret Detection
39
+
40
+ Scan all source files for hardcoded secrets.
41
+
42
+ Reference: `references/secret-patterns.md`
43
+
44
+ ### Step 3: Vulnerability Analysis
45
+
46
+ Read source code and check for OWASP categories, exposed endpoints, webhook/payment security, and infrastructure misconfigurations.
47
+
48
+ Reference: `references/owasp-checks.md`
49
+
50
+ ### Step 4: Report
51
+
52
+ Output structured report with severity levels.
53
+
54
+ ## Quick Reference
55
+
56
+ | Reference | Content |
57
+ |-----------|---------|
58
+ | `references/owasp-checks.md` | Vulnerability checks with code patterns |
59
+ | `references/dependency-audit.md` | Dependency vulnerability detection |
60
+ | `references/secret-patterns.md` | Secret and credential detection patterns |