gaia-framework 1.65.1 → 1.83.2

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.
Files changed (57) hide show
  1. package/.claude/commands/gaia-create-stakeholder.md +20 -0
  2. package/.claude/commands/gaia-test-gap-analysis.md +17 -0
  3. package/CLAUDE.md +102 -1
  4. package/README.md +2 -2
  5. package/_gaia/_config/global.yaml +5 -1
  6. package/_gaia/_config/lifecycle-sequence.yaml +20 -0
  7. package/_gaia/_config/skill-manifest.csv +2 -0
  8. package/_gaia/_config/workflow-manifest.csv +3 -1
  9. package/_gaia/core/engine/workflow.xml +11 -1
  10. package/_gaia/core/protocols/review-gate-check.xml +29 -1
  11. package/_gaia/core/workflows/party-mode/steps/step-01-agent-loading.md +60 -9
  12. package/_gaia/creative/workflows/problem-solving/checklist.md +64 -14
  13. package/_gaia/creative/workflows/problem-solving/instructions.xml +367 -22
  14. package/_gaia/creative/workflows/problem-solving/workflow.yaml +31 -1
  15. package/_gaia/dev/agents/_base-dev.md +7 -1
  16. package/_gaia/dev/skills/_skill-index.yaml +9 -0
  17. package/_gaia/dev/skills/figma-integration.md +296 -0
  18. package/_gaia/lifecycle/knowledge/brownfield/config-contradiction-scan.md +137 -0
  19. package/_gaia/lifecycle/knowledge/brownfield/dead-code-scan.md +179 -0
  20. package/_gaia/lifecycle/knowledge/brownfield/test-execution-scan.md +209 -0
  21. package/_gaia/lifecycle/skills/document-rulesets.md +91 -6
  22. package/_gaia/lifecycle/templates/brownfield-scan-doc-code-prompt.md +219 -0
  23. package/_gaia/lifecycle/templates/brownfield-scan-hardcoded-prompt.md +169 -0
  24. package/_gaia/lifecycle/templates/brownfield-scan-integration-seam-prompt.md +127 -0
  25. package/_gaia/lifecycle/templates/brownfield-scan-runtime-behavior-prompt.md +141 -0
  26. package/_gaia/lifecycle/templates/brownfield-scan-security-prompt.md +440 -0
  27. package/_gaia/lifecycle/templates/gap-entry-schema.md +282 -0
  28. package/_gaia/lifecycle/templates/infra-prd-template.md +356 -0
  29. package/_gaia/lifecycle/templates/platform-prd-template.md +431 -0
  30. package/_gaia/lifecycle/templates/prd-template.md +70 -0
  31. package/_gaia/lifecycle/templates/story-template.md +22 -1
  32. package/_gaia/lifecycle/workflows/2-planning/create-ux-design/instructions.xml +52 -3
  33. package/_gaia/lifecycle/workflows/4-implementation/add-feature/checklist.md +1 -1
  34. package/_gaia/lifecycle/workflows/4-implementation/add-feature/instructions.xml +2 -3
  35. package/_gaia/lifecycle/workflows/4-implementation/add-stories/checklist.md +5 -0
  36. package/_gaia/lifecycle/workflows/4-implementation/add-stories/instructions.xml +73 -1
  37. package/_gaia/lifecycle/workflows/4-implementation/create-stakeholder/checklist.md +25 -0
  38. package/_gaia/lifecycle/workflows/4-implementation/create-stakeholder/instructions.xml +79 -0
  39. package/_gaia/lifecycle/workflows/4-implementation/create-stakeholder/workflow.yaml +22 -0
  40. package/_gaia/lifecycle/workflows/4-implementation/create-story/instructions.xml +11 -1
  41. package/_gaia/lifecycle/workflows/4-implementation/retrospective/instructions.xml +21 -1
  42. package/_gaia/lifecycle/workflows/4-implementation/retrospective/workflow.yaml +1 -1
  43. package/_gaia/lifecycle/workflows/4-implementation/validate-story/instructions.xml +11 -0
  44. package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/checklist.md +12 -0
  45. package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/instructions.xml +248 -4
  46. package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/workflow.yaml +1 -0
  47. package/_gaia/testing/workflows/test-gap-analysis/checklist.md +8 -0
  48. package/_gaia/testing/workflows/test-gap-analysis/instructions.xml +53 -0
  49. package/_gaia/testing/workflows/test-gap-analysis/workflow.yaml +38 -0
  50. package/bin/gaia-framework.js +44 -8
  51. package/bin/helpers/derive-bump-label.js +41 -0
  52. package/bin/helpers/validate-bump-labels.js +38 -0
  53. package/gaia-install.sh +96 -21
  54. package/package.json +1 -1
  55. package/_gaia/_memory/tier2-results/.gitkeep +0 -0
  56. package/_gaia/_memory/tier2-results/checkpoint-resume-2026-03-24.yaml +0 -6
  57. package/_gaia/_memory/tier2-results/engine-scenarios-2026-03-22.yaml +0 -14
@@ -0,0 +1,440 @@
1
+ # Security Endpoint Audit Scanner — Subagent Prompt
2
+
3
+ > Brownfield deep analysis scan subagent. Detects security gaps in API endpoints and infrastructure security configurations.
4
+ > Reference: Architecture ADR-021, Section 10.15.2, Section 10.15.5, ADR-022 §10.16.5
5
+ > Infra-awareness: E12-S6 — applies infra-specific patterns when project_type is infrastructure or platform.
6
+ > Non-REST protocols: E11-S17 — GraphQL and gRPC endpoint detection and security gap scanning.
7
+
8
+ ## Objective
9
+
10
+ Scan the codebase at `{project-path}` to catalog all API endpoints and infrastructure security configurations, and identify security gaps.
11
+
12
+ **Input variables:**
13
+ - `{tech_stack}` — Detected technology stack from Step 1 discovery
14
+ - `{project-path}` — Absolute path to the project source code directory
15
+ - `{project_type}` — Project type: `application`, `infrastructure`, or `platform`
16
+
17
+ **Output format:** Follow the gap entry schema at `{project-root}/_gaia/lifecycle/templates/gap-entry-schema.md` exactly.
18
+
19
+ ## Phase 1: Endpoint Discovery (Application Patterns)
20
+
21
+ Catalog all API endpoints. For each endpoint, record: route path, HTTP method, authentication, authorization, handler function.
22
+
23
+ ### Stack-Aware Endpoint Discovery Patterns
24
+
25
+ Apply framework-specific patterns based on {tech_stack}:
26
+
27
+ #### Java/Spring
28
+ - `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `@PatchMapping`
29
+ - `@RequestMapping(method = RequestMethod.GET)`
30
+ - `RouterFunction<ServerResponse>` (Spring WebFlux)
31
+ - `@RestController` class-level `@RequestMapping`
32
+
33
+ #### Node/Express
34
+ - `app.get()`, `app.post()`, `app.put()`, `app.delete()`, `app.patch()`
35
+ - `router.get()`, `router.post()`, `router.put()`, `router.delete()`
36
+ - `app.route().get().post()`
37
+ - `app.all()`
38
+
39
+ #### Python/Django
40
+ - `path()`, `re_path()` in `urls.py`
41
+ - `@api_view(['GET', 'POST'])`
42
+ - `class XxxViewSet(viewsets.ModelViewSet)`
43
+ - `class XxxView(APIView)`
44
+
45
+ #### Go/Gin
46
+ - `r.GET()`, `r.POST()`, `r.PUT()`, `r.DELETE()`, `r.PATCH()`
47
+ - `group.GET()`, `group.POST()`
48
+ - `http.HandleFunc()`, `http.Handle()`
49
+ - `mux.HandleFunc()`, `mux.Handle()`
50
+
51
+ ### Graceful Exit — No API Endpoints
52
+
53
+ If no API endpoints are detected, output a summary note and zero gap entries for the application phase.
54
+
55
+ ## Phase 1b: GraphQL Endpoint Discovery
56
+
57
+ Catalog all GraphQL endpoints. For each endpoint, record: operation type (query/mutation/subscription), resolver function, authentication directives, authorization checks.
58
+
59
+ ### Schema-First Detection Patterns
60
+
61
+ - `.graphql` and `.gql` schema files
62
+ - `type Query { ... }` and `type Mutation { ... }` blocks in schema files
63
+ - `typeDefs` variable definitions in JS/TS files (template literals with SDL)
64
+
65
+ ### Code-First Detection Patterns
66
+
67
+ - `@Resolver()` decorators (NestJS, TypeGraphQL)
68
+ - `@Query()` and `@Mutation()` decorators
69
+ - `resolvers` objects exported from modules
70
+ - Python class-based resolvers (Strawberry `@strawberry.type`, Ariadne `@query_type.field`)
71
+ - Go resolver structs (gqlgen `resolver.go` files)
72
+
73
+ ### GraphQL Framework Variants
74
+
75
+ Apply framework-specific patterns based on detected GraphQL library:
76
+
77
+ | Framework | Language | Detection Pattern |
78
+ |---|---|---|
79
+ | Apollo Server | Node/TS | `ApolloServer`, `@apollo/server`, Apollo plugins |
80
+ | GraphQL Yoga | Node/TS | `createYoga`, `@graphql-yoga/node` |
81
+ | Mercurius | Node/TS (Fastify) | `mercurius`, `app.graphql` |
82
+ | Strawberry | Python | `strawberry.Schema`, `@strawberry.type` |
83
+ | gqlgen | Go | `gqlgen.yml`, `generated.go`, resolver structs |
84
+ | Ariadne | Python | `ariadne`, `make_executable_schema` |
85
+ | NestJS GraphQL | Node/TS | `@nestjs/graphql`, `@Resolver()`, `@Query()`, `@Mutation()` |
86
+
87
+ ### GraphQL Middleware Chain Detection
88
+
89
+ - `graphql-shield` rule trees (`const permissions = shield({ ... })`)
90
+ - `@UseGuards(AuthGuard)` decorators (NestJS)
91
+ - Apollo Server plugins (`ApolloServerPlugin` implementing `requestDidStart`)
92
+ - Yoga plugins (`useAuth`, custom `envelop` plugins)
93
+ - Custom context resolvers setting `context.user` from auth headers
94
+
95
+ ### Graceful Exit — No GraphQL Endpoints
96
+
97
+ If no GraphQL schema files, resolver definitions, or GraphQL framework imports are detected, skip Phase 1b and Phase 2b entirely. Output a summary note and zero gap entries for GraphQL.
98
+
99
+ ## Phase 1c: gRPC Endpoint Discovery
100
+
101
+ Catalog all gRPC endpoints. For each endpoint, record: service name, RPC method name, request/response message types, streaming type (unary/server/client/bidirectional), interceptor chain.
102
+
103
+ ### Proto Service Parsing
104
+
105
+ - `.proto` files with `service` blocks defining `rpc` methods
106
+ - `stream` annotations on request or response types (server streaming, client streaming, bidirectional streaming)
107
+ - `package` declarations for service namespace
108
+
109
+ ### Server Interceptor Detection
110
+
111
+ | Language | Interceptor Pattern |
112
+ |---|---|
113
+ | Java | `ServerInterceptor` interface, `@GrpcService` (Spring gRPC), interceptor registry |
114
+ | Go | `grpc.UnaryInterceptor()`, `grpc.StreamInterceptor()`, `grpc.ChainUnaryInterceptor()` |
115
+ | Python | `grpc.server_interceptor`, `intercept_service()` |
116
+ | Node/TS | `addService()` calls, `@GrpcMethod` decorators (NestJS), `grpc-js` server options |
117
+
118
+ ### gRPC Middleware Chain Detection
119
+
120
+ - Interceptor chains in server setup (ordered middleware)
121
+ - `@GrpcMethod` decorators with guard annotations (NestJS)
122
+ - Metadata extractors for authentication tokens
123
+ - Health check service registration (`grpc.health.v1`)
124
+
125
+ ### Graceful Exit — No gRPC Endpoints
126
+
127
+ If no `.proto` files, gRPC server setup, or gRPC framework imports are detected, skip Phase 1c and Phase 2c entirely. Output a summary note and zero gap entries for gRPC.
128
+
129
+ ## Phase 1d: Mixed-Protocol Detection
130
+
131
+ A single codebase may expose REST + GraphQL + gRPC endpoints simultaneously. When multiple protocols are detected:
132
+
133
+ 1. Scan all three protocols independently
134
+ 2. Identify shared authentication middleware (e.g., a JWT validator used by both Express routes and Apollo context)
135
+ 3. Do not double-count shared middleware as separate gaps — if auth middleware covers both REST and GraphQL, count it once
136
+ 4. Note in findings when multiple protocols share infrastructure
137
+
138
+ ## Phase 2: Security Gap Detection — Application Rules
139
+
140
+ ### 1. Missing Authentication Middleware (AC3a)
141
+
142
+ Detect endpoints with no authentication middleware. Mutating endpoints (POST, PUT, PATCH, DELETE) missing auth are `critical`. Read endpoints (GET) missing auth that return non-public data are `high`.
143
+
144
+ ### 2. IDOR Vulnerability Detection (AC3b)
145
+
146
+ Detect endpoints where path parameters reference resources without ownership validation. IDOR vulnerabilities are `critical` severity.
147
+
148
+ ### 3. Rate Limiting Gap Detection (AC3c)
149
+
150
+ Detect endpoints without rate limiting at the application level. Missing rate limiting is `high` severity.
151
+
152
+ **Note:** Reverse proxy or API gateway rate limiting is not visible to static code analysis. Verify infrastructure-level rate limiting separately.
153
+
154
+ ### 4. Sensitive Data Exposure Detection (AC3d)
155
+
156
+ Detect endpoints whose response objects contain fields that should be filtered:
157
+ - `password`, `password_hash`, `hashed_password`
158
+ - `token`, `access_token`, `refresh_token`, `api_key`, `secret`
159
+ - `ssn`, `social_security`, `national_id`
160
+ - `credit_card`, `card_number`, `cvv`, `expiry`
161
+ - Any field matching patterns: `*_secret`, `*_key`, `*_token`
162
+
163
+ Sensitive data exposure is `high` severity.
164
+
165
+ ### 5. Missing Input Validation on Mutating Endpoints (AC3e)
166
+
167
+ Detect POST/PUT/PATCH/DELETE endpoints that accept a request body but have no input validation. Missing input validation is `high` severity.
168
+
169
+ ## Phase 2b: GraphQL Security Gap Detection
170
+
171
+ ### 1. Queries/Mutations Missing Auth Directives
172
+
173
+ Detect GraphQL operations missing authentication. Look for:
174
+ - Resolvers without `@auth`, `@authenticated`, `@HasPermission`, or `@UseGuards(AuthGuard)` directives
175
+ - Schema types without `@auth` directive when other types have it (inconsistent protection)
176
+ - Mutation resolvers with no authorization checks are `critical` severity
177
+ - Query resolvers returning non-public data without auth are `high` severity
178
+
179
+ ### 2. Introspection Enabled in Production
180
+
181
+ Detect GraphQL introspection configuration that may leak schema in production:
182
+ - `introspection: true` in Apollo Server config without `NODE_ENV` conditional
183
+ - Missing introspection disable in production configuration
184
+ - Yoga/Mercurius default introspection without explicit disable
185
+
186
+ Introspection in production is `medium` severity.
187
+
188
+ ### 3. Mutations Without Authorization Checks
189
+
190
+ Detect mutation resolvers that lack authorization logic:
191
+ - Mutation handlers with no permission checks, guard decorators, or authorization middleware
192
+ - `graphql-shield` rules that allow mutations without role checks
193
+ - NestJS mutations without `@UseGuards()` when other mutations have guards
194
+
195
+ Missing mutation authorization is `critical` severity.
196
+
197
+ ### 4. Field-Level Authorization Gaps
198
+
199
+ Detect sensitive fields exposed without field-level auth controls:
200
+ - Fields named `email`, `password`, `ssn`, `token`, `secret`, `creditCard` without `@Authorized` or field-level resolvers
201
+ - Resolver types exposing sensitive nested objects without per-field permission checks
202
+ - User types exposing admin-only fields to all authenticated users
203
+
204
+ Field-level authorization gaps are `high` severity.
205
+
206
+ ### 5. GraphQL Federation and Schema Stitching
207
+
208
+ When Apollo Federation or schema stitching is detected:
209
+ - Note gateway-level auth that may mask per-service gaps
210
+ - Flag subgraph services that rely solely on gateway auth without their own validation
211
+ - Detect `@external` fields without authorization in the owning subgraph
212
+
213
+ Federation auth gaps are `medium` severity with a note about gateway-level coverage.
214
+
215
+ ## Phase 2c: gRPC Security Gap Detection
216
+
217
+ ### 1. Services Missing Auth Interceptors
218
+
219
+ Detect gRPC server setup without authentication interceptors:
220
+ - Server initialization without `AuthInterceptor` or equivalent in the interceptor chain
221
+ - Services registered via `addService` with no auth middleware applied
222
+ - Spring gRPC services without `@GrpcService` security configuration
223
+
224
+ Missing auth interceptor is `critical` severity.
225
+
226
+ ### 2. Unary RPCs Without Authorization Metadata
227
+
228
+ Detect unary RPC methods that do not validate authorization metadata:
229
+ - `rpc` method handlers that do not extract or validate `metadata` authorization headers
230
+ - Handler functions that skip token/credential validation from gRPC metadata
231
+ - Methods that do not check caller identity or roles from request context
232
+
233
+ Missing unary authorization is `high` severity.
234
+
235
+ ### 3. Streaming RPCs Without Per-Message Auth
236
+
237
+ Detect bidirectional and server streaming RPCs without per-message authentication:
238
+ - Stream handlers that authenticate only at connection start but not per-message
239
+ - Bidirectional streams without per-message auth validation
240
+ - Server streaming RPCs that do not re-validate authorization on long-lived connections
241
+
242
+ Missing stream auth is `high` severity.
243
+
244
+ ### 4. TLS Configuration Gaps
245
+
246
+ Detect insecure gRPC transport configuration:
247
+ - `grpc.insecure_port` usage in non-development configuration
248
+ - `ServerCredentials.createInsecure()` in production server setup
249
+ - Missing TLS certificate configuration in production gRPC servers
250
+ - Plaintext gRPC channels in production client configuration
251
+
252
+ Insecure TLS is `critical` severity.
253
+
254
+ ### 5. gRPC Reflection Enabled in Production
255
+
256
+ Detect gRPC reflection service that may expose service definitions:
257
+ - `grpc.reflection.v1alpha` or `grpc.reflection.v1` service registered without environment guard
258
+ - Reflection service enabled unconditionally (similar risk to GraphQL introspection)
259
+
260
+ Reflection in production is `medium` severity.
261
+
262
+ ## Phase 3: False-Positive Mitigation — Inherited Auth
263
+
264
+ Before flagging an endpoint as "missing authentication middleware," trace the middleware chain upward:
265
+
266
+ #### Java/Spring Security
267
+ - `HttpSecurity.authorizeRequests().anyRequest().authenticated()` — app-level
268
+ - `@PreAuthorize` on controller class — class-level
269
+ - `SecurityFilterChain` bean — app-level
270
+ - `.antMatchers("/api/**").authenticated()` — path-level
271
+
272
+ #### Node/Express Middleware
273
+ - `app.use(authMiddleware)` — app-level
274
+ - `router.use(passport.authenticate('jwt'))` — router-level
275
+ - `app.use('/api', authMiddleware, apiRouter)` — path-level
276
+
277
+ #### Django Permissions
278
+ - `REST_FRAMEWORK.DEFAULT_PERMISSION_CLASSES: [IsAuthenticated]` — app-level
279
+ - `LoginRequiredMixin` — class-level
280
+ - `@login_required` — function-level
281
+
282
+ #### Go/Gin Middleware
283
+ - `r.Use(JWTAuth())` — app-level
284
+ - `group := r.Group("/api"); group.Use(AuthMiddleware())` — group-level
285
+
286
+ #### GraphQL Inherited Auth
287
+ - Apollo Server `context` function that validates JWT and sets `context.user` — app-level
288
+ - `graphql-shield` rule tree applied via `applyMiddleware` — schema-level
289
+ - NestJS `@UseGuards(AuthGuard)` on resolver class — class-level
290
+ - Apollo Federation gateway-level auth that validates before routing to subgraphs — gateway-level
291
+
292
+ #### gRPC Inherited Auth
293
+ - Global auth interceptor registered via `grpc.UnaryInterceptor(authInterceptor)` — server-level
294
+ - `ServerInterceptor` added to server builder interceptor chain — server-level
295
+ - Per-service interceptor applied at `addService` — service-level
296
+ - TLS mutual authentication (mTLS) at transport level — transport-level
297
+
298
+ ## Phase 4: Infrastructure Security Patterns (E12-S6)
299
+
300
+ **Apply ONLY when {project_type} is `infrastructure` or `platform`.**
301
+
302
+ ### 4a. Exposed Ports in Kubernetes Manifests
303
+
304
+ Detect Kubernetes Services and Pods that expose ports unnecessarily or without documentation.
305
+
306
+ **Flag these:**
307
+ - `NodePort` services exposing ports to external traffic without documented justification
308
+ - `hostPort` usage in Pod specs (exposes container port on the node's IP)
309
+ - Services with `type: LoadBalancer` without IP whitelisting or security group restrictions
310
+ - Pods with `hostNetwork: true` (shares the node's network namespace)
311
+ - Containers listening on privileged ports (< 1024) without documented need
312
+
313
+ **Severity:** `high` for NodePort/LoadBalancer exposure, `critical` for hostNetwork/hostPort
314
+
315
+ ### 4b. Permissive Ingress Rules
316
+
317
+ Detect overly permissive network ingress rules in Kubernetes Ingress resources, cloud security groups, and firewall rules.
318
+
319
+ **Flag these:**
320
+ - Kubernetes Ingress resources without TLS configuration
321
+ - Ingress rules with wildcard hosts: `host: "*"` or missing host field
322
+ - AWS Security Groups with `0.0.0.0/0` ingress on non-standard ports
323
+ - Terraform `aws_security_group_rule` with `cidr_blocks = ["0.0.0.0/0"]` on ports other than 80/443
324
+ - GCP firewall rules with `source_ranges = ["0.0.0.0/0"]` without service account filtering
325
+ - Azure NSG rules with `source_address_prefix = "*"` on sensitive ports
326
+
327
+ **Severity:** `critical` for `0.0.0.0/0` on sensitive ports (SSH/22, DB/3306/5432, admin ports), `high` for permissive ingress on standard ports
328
+
329
+ ### 4c. Overly Broad RBAC Bindings
330
+
331
+ Detect Kubernetes RBAC configurations that grant excessive permissions.
332
+
333
+ **Flag these:**
334
+ - `ClusterRoleBinding` bound to `cluster-admin` for non-system service accounts
335
+ - `RoleBinding` or `ClusterRoleBinding` with `resources: ["*"]` and `verbs: ["*"]`
336
+ - Service accounts with `automountServiceAccountToken: true` when not needed
337
+ - `ClusterRole` with `apiGroups: ["*"]` granting access to all API groups
338
+ - Roles that grant `create`, `delete`, or `patch` on `secrets` without namespace scoping
339
+ - Default service account with non-default permissions
340
+
341
+ **Severity:** `critical` for cluster-admin bindings and wildcard permissions, `high` for broad secret access
342
+
343
+ ### 4d. Missing NetworkPolicy
344
+
345
+ Detect Kubernetes namespaces and workloads without NetworkPolicy enforcement.
346
+
347
+ **Flag these:**
348
+ - Namespaces with no NetworkPolicy resources defined (all traffic allowed by default)
349
+ - Pods in namespaces where NetworkPolicy exists but does not select them (via label selectors)
350
+ - NetworkPolicy with empty `ingress` or `egress` rules (allows all traffic of that type)
351
+ - Workloads in production namespaces without both ingress AND egress NetworkPolicy
352
+ - Multi-tenant clusters without namespace-level network isolation
353
+
354
+ **Severity:** `high` for missing NetworkPolicy in production, `medium` for missing in non-production
355
+
356
+ ## Output Format
357
+
358
+ ### Gap Entry Structure
359
+
360
+ Each finding MUST use the standardized gap schema from `gap-entry-schema.md`:
361
+
362
+ ```yaml
363
+ gap:
364
+ id: "GAP-SECURITY-{seq}"
365
+ category: "security-endpoint"
366
+ severity: "{critical|high}"
367
+ title: "Short description (max 80 chars)"
368
+ description: "What was found, why it matters, what security implication it has"
369
+ evidence:
370
+ file: "relative/path/to/file"
371
+ line: 42
372
+ protocol: "rest"
373
+ recommendation: "Actionable fix — add middleware, validate input, filter response"
374
+ verified_by: "machine-detected"
375
+ confidence: "{high|medium|low}"
376
+ ```
377
+
378
+ **Protocol field:** Every gap entry MUST include a `protocol` field in the evidence section indicating which API protocol the finding applies to: `rest`, `graphql`, or `grpc`. This enables downstream consumers to filter and route findings by protocol.
379
+
380
+ #### GraphQL Gap Example
381
+
382
+ ```yaml
383
+ gap:
384
+ id: "GAP-SECURITY-015"
385
+ category: "security-endpoint"
386
+ severity: "critical"
387
+ title: "Mutation resolver missing authorization checks"
388
+ description: "createUser mutation has no @auth directive or guard. Any authenticated user can create accounts."
389
+ evidence:
390
+ file: "src/graphql/resolvers/user.resolver.ts"
391
+ line: 42
392
+ protocol: "graphql"
393
+ recommendation: "Add @UseGuards(AuthGuard, RolesGuard) or @auth directive to the createUser mutation."
394
+ verified_by: "machine-detected"
395
+ confidence: "high"
396
+ ```
397
+
398
+ #### gRPC Gap Example
399
+
400
+ ```yaml
401
+ gap:
402
+ id: "GAP-SECURITY-022"
403
+ category: "security-endpoint"
404
+ severity: "critical"
405
+ title: "gRPC server missing auth interceptor in production config"
406
+ description: "Server setup uses grpc.insecure_port without TLS. No auth interceptor in interceptor chain."
407
+ evidence:
408
+ file: "cmd/server/main.go"
409
+ line: 58
410
+ protocol: "grpc"
411
+ recommendation: "Add TLS credentials and an auth interceptor to the gRPC server configuration."
412
+ verified_by: "machine-detected"
413
+ confidence: "high"
414
+ ```
415
+
416
+ ### Confidence Classification
417
+
418
+ - **high** — exact pattern match (e.g., no auth decorator/annotation on a `@PostMapping` handler)
419
+ - **medium** — heuristic match (e.g., handler accesses path parameter without obvious ownership check)
420
+ - **low** — ambiguous case (e.g., custom auth mechanism not recognized by pattern table)
421
+
422
+ ### Budget Enforcement
423
+
424
+ Each gap entry should average approximately 100 tokens in structured YAML format.
425
+ Maximum output: 70 gap entries per scan.
426
+
427
+ If more than 70 gaps are detected:
428
+ 1. Sort all findings by severity (critical > high)
429
+ 2. Within same severity, sort by confidence (high > medium > low)
430
+ 3. Keep the top 70 entries
431
+ 4. Append a budget summary section:
432
+
433
+ ```markdown
434
+ ## Budget Summary
435
+ Total gaps detected: {N}. Showing top 70 by severity. Omitted: {N-70} entries.
436
+ ```
437
+
438
+ ## Output File
439
+
440
+ Write all findings to: `{planning_artifacts}/brownfield-scan-security.md`