gaia-framework 1.65.0 → 1.66.0

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 (92) hide show
  1. package/.claude/commands/gaia-add-feature.md +2 -2
  2. package/.claude/commands/gaia-change-request.md +16 -4
  3. package/.claude/commands/gaia-edit-ux.md +17 -0
  4. package/.claude/commands/gaia-resume.md +1 -1
  5. package/.claude/commands/gaia-validate-prd.md +9 -3
  6. package/CLAUDE.md +16 -1
  7. package/README.md +3 -3
  8. package/_gaia/_config/adversarial-triggers.yaml +91 -0
  9. package/_gaia/_config/files-manifest.csv +1 -0
  10. package/_gaia/_config/gaia-help.csv +10 -6
  11. package/_gaia/_config/global.yaml +2 -1
  12. package/_gaia/_config/lifecycle-sequence.yaml +26 -4
  13. package/_gaia/_config/manifest.yaml +3 -3
  14. package/_gaia/_config/skill-manifest.csv +3 -1
  15. package/_gaia/_config/workflow-manifest.csv +5 -3
  16. package/_gaia/core/config.yaml +1 -1
  17. package/_gaia/core/engine/workflow.xml +31 -5
  18. package/_gaia/core/protocols/review-gate-check.xml +29 -1
  19. package/_gaia/core/workflows/brainstorming/template.md +6 -0
  20. package/_gaia/lifecycle/agents/pm.md +9 -10
  21. package/_gaia/lifecycle/agents/ux-designer.md +1 -0
  22. package/_gaia/lifecycle/agents/validator.md +2 -1
  23. package/_gaia/lifecycle/config.yaml +1 -1
  24. package/_gaia/lifecycle/knowledge/brownfield/config-contradiction-scan.md +137 -0
  25. package/_gaia/lifecycle/knowledge/brownfield/dead-code-scan.md +179 -0
  26. package/_gaia/lifecycle/knowledge/brownfield/test-execution-scan.md +209 -0
  27. package/_gaia/lifecycle/module-help.csv +1 -1
  28. package/_gaia/lifecycle/skills/document-rulesets.md +251 -0
  29. package/_gaia/lifecycle/skills/memory-management-cross-agent.md +218 -0
  30. package/_gaia/lifecycle/skills/memory-management.md +32 -122
  31. package/_gaia/lifecycle/templates/brownfield-scan-doc-code-prompt.md +219 -0
  32. package/_gaia/lifecycle/templates/brownfield-scan-hardcoded-prompt.md +169 -0
  33. package/_gaia/lifecycle/templates/brownfield-scan-integration-seam-prompt.md +127 -0
  34. package/_gaia/lifecycle/templates/brownfield-scan-runtime-behavior-prompt.md +141 -0
  35. package/_gaia/lifecycle/templates/brownfield-scan-security-prompt.md +212 -0
  36. package/_gaia/lifecycle/templates/gap-entry-schema.md +247 -0
  37. package/_gaia/lifecycle/templates/infra-prd-template.md +356 -0
  38. package/_gaia/lifecycle/templates/platform-prd-template.md +431 -0
  39. package/_gaia/lifecycle/templates/prd-template.md +70 -0
  40. package/_gaia/lifecycle/templates/story-template.md +1 -0
  41. package/_gaia/lifecycle/workflows/1-analysis/create-product-brief/workflow.yaml +1 -0
  42. package/_gaia/lifecycle/workflows/2-planning/create-prd/instructions.xml +4 -2
  43. package/_gaia/lifecycle/workflows/2-planning/create-prd/workflow.yaml +1 -0
  44. package/_gaia/lifecycle/workflows/2-planning/create-ux-design/workflow.yaml +1 -0
  45. package/_gaia/lifecycle/workflows/2-planning/edit-prd/instructions.xml +4 -4
  46. package/_gaia/lifecycle/workflows/2-planning/edit-prd/workflow.yaml +1 -0
  47. package/_gaia/lifecycle/workflows/2-planning/edit-ux-design/checklist.md +18 -0
  48. package/_gaia/lifecycle/workflows/2-planning/edit-ux-design/instructions.xml +66 -0
  49. package/_gaia/lifecycle/workflows/2-planning/edit-ux-design/workflow.yaml +27 -0
  50. package/_gaia/lifecycle/workflows/3-solutioning/create-architecture/instructions.xml +3 -1
  51. package/_gaia/lifecycle/workflows/3-solutioning/create-architecture/workflow.yaml +1 -0
  52. package/_gaia/lifecycle/workflows/3-solutioning/create-epics-stories/workflow.yaml +1 -0
  53. package/_gaia/lifecycle/workflows/3-solutioning/edit-architecture/instructions.xml +4 -7
  54. package/_gaia/lifecycle/workflows/3-solutioning/edit-architecture/workflow.yaml +1 -0
  55. package/_gaia/lifecycle/workflows/3-solutioning/security-threat-model/workflow.yaml +1 -0
  56. package/_gaia/lifecycle/workflows/4-implementation/add-feature/checklist.md +42 -0
  57. package/_gaia/lifecycle/workflows/4-implementation/add-feature/instructions.xml +196 -0
  58. package/_gaia/lifecycle/workflows/{cross-phase → 4-implementation}/add-feature/workflow.yaml +20 -9
  59. package/_gaia/lifecycle/workflows/4-implementation/add-stories/checklist.md +5 -0
  60. package/_gaia/lifecycle/workflows/4-implementation/add-stories/instructions.xml +73 -1
  61. package/_gaia/lifecycle/workflows/4-implementation/add-stories/workflow.yaml +1 -0
  62. package/_gaia/lifecycle/workflows/4-implementation/code-review/workflow.yaml +1 -0
  63. package/_gaia/lifecycle/workflows/4-implementation/correct-course/workflow.yaml +1 -0
  64. package/_gaia/lifecycle/workflows/4-implementation/create-story/checklist.md +1 -1
  65. package/_gaia/lifecycle/workflows/4-implementation/create-story/instructions.xml +5 -4
  66. package/_gaia/lifecycle/workflows/4-implementation/dev-story/workflow.yaml +1 -1
  67. package/_gaia/lifecycle/workflows/4-implementation/retrospective/instructions.xml +21 -1
  68. package/_gaia/lifecycle/workflows/4-implementation/retrospective/workflow.yaml +2 -1
  69. package/_gaia/lifecycle/workflows/4-implementation/sprint-planning/instructions.xml +3 -0
  70. package/_gaia/lifecycle/workflows/4-implementation/sprint-planning/workflow.yaml +2 -0
  71. package/_gaia/lifecycle/workflows/4-implementation/triage-findings/workflow.yaml +1 -0
  72. package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/checklist.md +15 -0
  73. package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/instructions.xml +153 -57
  74. package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/workflow.yaml +5 -0
  75. package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/instructions.xml +23 -12
  76. package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/workflow.yaml +11 -0
  77. package/_gaia/lifecycle/workflows/4-implementation/val-validate-plan/instructions.xml +0 -2
  78. package/_gaia/lifecycle/workflows/5-deployment/deployment-checklist/workflow.yaml +1 -0
  79. package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/checklist.md +12 -0
  80. package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/instructions.xml +313 -5
  81. package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/workflow.yaml +1 -0
  82. package/_gaia/lifecycle/workflows/anytime/memory-hygiene/instructions.xml +8 -18
  83. package/_gaia/testing/config.yaml +1 -1
  84. package/_gaia/testing/workflows/edit-test-plan/workflow.yaml +1 -0
  85. package/_gaia/testing/workflows/test-design/workflow.yaml +2 -0
  86. package/_gaia/testing/workflows/traceability/workflow.yaml +1 -0
  87. package/bin/gaia-framework.js +25 -9
  88. package/bin/generate-checksums.js +124 -0
  89. package/gaia-install.sh +74 -28
  90. package/package.json +5 -2
  91. package/_gaia/lifecycle/workflows/cross-phase/add-feature/checklist.md +0 -30
  92. package/_gaia/lifecycle/workflows/cross-phase/add-feature/instructions.xml +0 -85
@@ -0,0 +1,212 @@
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
+
7
+ ## Objective
8
+
9
+ Scan the codebase at `{project-path}` to catalog all API endpoints and infrastructure security configurations, and identify security gaps.
10
+
11
+ **Input variables:**
12
+ - `{tech_stack}` — Detected technology stack from Step 1 discovery
13
+ - `{project-path}` — Absolute path to the project source code directory
14
+ - `{project_type}` — Project type: `application`, `infrastructure`, or `platform`
15
+
16
+ **Output format:** Follow the gap entry schema at `{project-root}/_gaia/lifecycle/templates/gap-entry-schema.md` exactly.
17
+
18
+ ## Phase 1: Endpoint Discovery (Application Patterns)
19
+
20
+ Catalog all API endpoints. For each endpoint, record: route path, HTTP method, authentication, authorization, handler function.
21
+
22
+ ### Stack-Aware Endpoint Discovery Patterns
23
+
24
+ Apply framework-specific patterns based on {tech_stack}:
25
+
26
+ #### Java/Spring
27
+ - `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `@PatchMapping`
28
+ - `@RequestMapping(method = RequestMethod.GET)`
29
+ - `RouterFunction<ServerResponse>` (Spring WebFlux)
30
+ - `@RestController` class-level `@RequestMapping`
31
+
32
+ #### Node/Express
33
+ - `app.get()`, `app.post()`, `app.put()`, `app.delete()`, `app.patch()`
34
+ - `router.get()`, `router.post()`, `router.put()`, `router.delete()`
35
+ - `app.route().get().post()`
36
+ - `app.all()`
37
+
38
+ #### Python/Django
39
+ - `path()`, `re_path()` in `urls.py`
40
+ - `@api_view(['GET', 'POST'])`
41
+ - `class XxxViewSet(viewsets.ModelViewSet)`
42
+ - `class XxxView(APIView)`
43
+
44
+ #### Go/Gin
45
+ - `r.GET()`, `r.POST()`, `r.PUT()`, `r.DELETE()`, `r.PATCH()`
46
+ - `group.GET()`, `group.POST()`
47
+ - `http.HandleFunc()`, `http.Handle()`
48
+ - `mux.HandleFunc()`, `mux.Handle()`
49
+
50
+ ### Graceful Exit — No API Endpoints
51
+
52
+ If no API endpoints are detected, output a summary note and zero gap entries for the application phase.
53
+
54
+ ## Phase 2: Security Gap Detection — Application Rules
55
+
56
+ ### 1. Missing Authentication Middleware (AC3a)
57
+
58
+ 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`.
59
+
60
+ ### 2. IDOR Vulnerability Detection (AC3b)
61
+
62
+ Detect endpoints where path parameters reference resources without ownership validation. IDOR vulnerabilities are `critical` severity.
63
+
64
+ ### 3. Rate Limiting Gap Detection (AC3c)
65
+
66
+ Detect endpoints without rate limiting at the application level. Missing rate limiting is `high` severity.
67
+
68
+ **Note:** Reverse proxy or API gateway rate limiting is not visible to static code analysis. Verify infrastructure-level rate limiting separately.
69
+
70
+ ### 4. Sensitive Data Exposure Detection (AC3d)
71
+
72
+ Detect endpoints whose response objects contain fields that should be filtered:
73
+ - `password`, `password_hash`, `hashed_password`
74
+ - `token`, `access_token`, `refresh_token`, `api_key`, `secret`
75
+ - `ssn`, `social_security`, `national_id`
76
+ - `credit_card`, `card_number`, `cvv`, `expiry`
77
+ - Any field matching patterns: `*_secret`, `*_key`, `*_token`
78
+
79
+ Sensitive data exposure is `high` severity.
80
+
81
+ ### 5. Missing Input Validation on Mutating Endpoints (AC3e)
82
+
83
+ Detect POST/PUT/PATCH/DELETE endpoints that accept a request body but have no input validation. Missing input validation is `high` severity.
84
+
85
+ ## Phase 3: False-Positive Mitigation — Inherited Auth
86
+
87
+ Before flagging an endpoint as "missing authentication middleware," trace the middleware chain upward:
88
+
89
+ #### Java/Spring Security
90
+ - `HttpSecurity.authorizeRequests().anyRequest().authenticated()` — app-level
91
+ - `@PreAuthorize` on controller class — class-level
92
+ - `SecurityFilterChain` bean — app-level
93
+ - `.antMatchers("/api/**").authenticated()` — path-level
94
+
95
+ #### Node/Express Middleware
96
+ - `app.use(authMiddleware)` — app-level
97
+ - `router.use(passport.authenticate('jwt'))` — router-level
98
+ - `app.use('/api', authMiddleware, apiRouter)` — path-level
99
+
100
+ #### Django Permissions
101
+ - `REST_FRAMEWORK.DEFAULT_PERMISSION_CLASSES: [IsAuthenticated]` — app-level
102
+ - `LoginRequiredMixin` — class-level
103
+ - `@login_required` — function-level
104
+
105
+ #### Go/Gin Middleware
106
+ - `r.Use(JWTAuth())` — app-level
107
+ - `group := r.Group("/api"); group.Use(AuthMiddleware())` — group-level
108
+
109
+ ## Phase 4: Infrastructure Security Patterns (E12-S6)
110
+
111
+ **Apply ONLY when {project_type} is `infrastructure` or `platform`.**
112
+
113
+ ### 4a. Exposed Ports in Kubernetes Manifests
114
+
115
+ Detect Kubernetes Services and Pods that expose ports unnecessarily or without documentation.
116
+
117
+ **Flag these:**
118
+ - `NodePort` services exposing ports to external traffic without documented justification
119
+ - `hostPort` usage in Pod specs (exposes container port on the node's IP)
120
+ - Services with `type: LoadBalancer` without IP whitelisting or security group restrictions
121
+ - Pods with `hostNetwork: true` (shares the node's network namespace)
122
+ - Containers listening on privileged ports (< 1024) without documented need
123
+
124
+ **Severity:** `high` for NodePort/LoadBalancer exposure, `critical` for hostNetwork/hostPort
125
+
126
+ ### 4b. Permissive Ingress Rules
127
+
128
+ Detect overly permissive network ingress rules in Kubernetes Ingress resources, cloud security groups, and firewall rules.
129
+
130
+ **Flag these:**
131
+ - Kubernetes Ingress resources without TLS configuration
132
+ - Ingress rules with wildcard hosts: `host: "*"` or missing host field
133
+ - AWS Security Groups with `0.0.0.0/0` ingress on non-standard ports
134
+ - Terraform `aws_security_group_rule` with `cidr_blocks = ["0.0.0.0/0"]` on ports other than 80/443
135
+ - GCP firewall rules with `source_ranges = ["0.0.0.0/0"]` without service account filtering
136
+ - Azure NSG rules with `source_address_prefix = "*"` on sensitive ports
137
+
138
+ **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
139
+
140
+ ### 4c. Overly Broad RBAC Bindings
141
+
142
+ Detect Kubernetes RBAC configurations that grant excessive permissions.
143
+
144
+ **Flag these:**
145
+ - `ClusterRoleBinding` bound to `cluster-admin` for non-system service accounts
146
+ - `RoleBinding` or `ClusterRoleBinding` with `resources: ["*"]` and `verbs: ["*"]`
147
+ - Service accounts with `automountServiceAccountToken: true` when not needed
148
+ - `ClusterRole` with `apiGroups: ["*"]` granting access to all API groups
149
+ - Roles that grant `create`, `delete`, or `patch` on `secrets` without namespace scoping
150
+ - Default service account with non-default permissions
151
+
152
+ **Severity:** `critical` for cluster-admin bindings and wildcard permissions, `high` for broad secret access
153
+
154
+ ### 4d. Missing NetworkPolicy
155
+
156
+ Detect Kubernetes namespaces and workloads without NetworkPolicy enforcement.
157
+
158
+ **Flag these:**
159
+ - Namespaces with no NetworkPolicy resources defined (all traffic allowed by default)
160
+ - Pods in namespaces where NetworkPolicy exists but does not select them (via label selectors)
161
+ - NetworkPolicy with empty `ingress` or `egress` rules (allows all traffic of that type)
162
+ - Workloads in production namespaces without both ingress AND egress NetworkPolicy
163
+ - Multi-tenant clusters without namespace-level network isolation
164
+
165
+ **Severity:** `high` for missing NetworkPolicy in production, `medium` for missing in non-production
166
+
167
+ ## Output Format
168
+
169
+ ### Gap Entry Structure
170
+
171
+ Each finding MUST use the standardized gap schema from `gap-entry-schema.md`:
172
+
173
+ ```yaml
174
+ gap:
175
+ id: "GAP-SECURITY-{seq}"
176
+ category: "security-endpoint"
177
+ severity: "{critical|high}"
178
+ title: "Short description (max 80 chars)"
179
+ description: "What was found, why it matters, what security implication it has"
180
+ evidence:
181
+ file: "relative/path/to/file"
182
+ line: 42
183
+ recommendation: "Actionable fix — add middleware, validate input, filter response"
184
+ verified_by: "machine-detected"
185
+ confidence: "{high|medium|low}"
186
+ ```
187
+
188
+ ### Confidence Classification
189
+
190
+ - **high** — exact pattern match (e.g., no auth decorator/annotation on a `@PostMapping` handler)
191
+ - **medium** — heuristic match (e.g., handler accesses path parameter without obvious ownership check)
192
+ - **low** — ambiguous case (e.g., custom auth mechanism not recognized by pattern table)
193
+
194
+ ### Budget Enforcement
195
+
196
+ Each gap entry should average approximately 100 tokens in structured YAML format.
197
+ Maximum output: 70 gap entries per scan.
198
+
199
+ If more than 70 gaps are detected:
200
+ 1. Sort all findings by severity (critical > high)
201
+ 2. Within same severity, sort by confidence (high > medium > low)
202
+ 3. Keep the top 70 entries
203
+ 4. Append a budget summary section:
204
+
205
+ ```markdown
206
+ ## Budget Summary
207
+ Total gaps detected: {N}. Showing top 70 by severity. Omitted: {N-70} entries.
208
+ ```
209
+
210
+ ## Output File
211
+
212
+ Write all findings to: `{planning_artifacts}/brownfield-scan-security.md`
@@ -0,0 +1,247 @@
1
+ # Gap Entry Schema
2
+
3
+ > **Version:** 1.1.0
4
+ > **Story:** E11-S1, E12-S5
5
+ > **Traces to:** FR-111, FR-123, US-38, ADR-021, ADR-022
6
+ >
7
+ > Standardized output schema for brownfield scan subagents (E11).
8
+ > All scan agents MUST format gap entries using this schema.
9
+ > Infra-specific categories added for infrastructure/platform project support (E12-S5).
10
+ > Location: `_gaia/lifecycle/templates/gap-entry-schema.md`
11
+
12
+ ## Schema Definition
13
+
14
+ Each gap entry is a YAML object with the following fields:
15
+
16
+ ```yaml
17
+ id: "GAP-{scan_type}-{seq}"
18
+ category: "<enum>"
19
+ severity: "<enum>"
20
+ title: "<string>"
21
+ description: "<string>"
22
+ evidence:
23
+ file: "<relative-path>"
24
+ line: <number-or-range>
25
+ recommendation: "<string>"
26
+ verified_by: "<agent-id>"
27
+ confidence: "<enum>"
28
+ ```
29
+
30
+ ## Field Reference
31
+
32
+ | Field | Type | Required | Description |
33
+ |-------|------|----------|-------------|
34
+ | `id` | string | yes | Unique identifier. Format: `GAP-{scan_type}-{seq}` where `scan_type` maps to the category and `seq` is a zero-padded 3-digit sequence (e.g., `GAP-dead-code-001`) |
35
+ | `category` | enum | yes | Gap classification — must be one of the 12 allowed values (see Category Enum) |
36
+ | `severity` | enum | yes | Impact level — must be one of the 5 allowed values (see Severity Enum) |
37
+ | `title` | string | yes | Short summary of the gap (max 80 characters) |
38
+ | `description` | string | yes | Detailed explanation of the gap, what it means, and why it matters |
39
+ | `evidence` | object | yes | Source code evidence (see Evidence Object) |
40
+ | `recommendation` | string | yes | Actionable fix or remediation guidance |
41
+ | `verified_by` | string | yes | ID of the scan agent that produced this finding (e.g., `dead-code-analyzer`, `config-scanner`) |
42
+ | `confidence` | enum | yes | Agent's confidence in the finding accuracy (see Confidence Enum) |
43
+
44
+ ## Enums
45
+
46
+ ### Severity Enum
47
+
48
+ | Value | Description |
49
+ |-------|-------------|
50
+ | `critical` | Blocks deployment or causes data loss |
51
+ | `high` | Significant risk requiring prompt attention |
52
+ | `medium` | Moderate risk, should be addressed in current sprint |
53
+ | `low` | Minor issue, can be deferred |
54
+ | `info` | Informational finding, no immediate action needed |
55
+
56
+ ### Category Enum
57
+
58
+ 12 categories total — 7 application categories (E11-S1) plus 5 infrastructure categories (E12-S5):
59
+
60
+ #### Application Categories (7)
61
+
62
+ | Value | Scan Agent | Description |
63
+ |-------|------------|-------------|
64
+ | `config-contradiction` | E11-S2 | Configuration files contradict each other or runtime behavior |
65
+ | `dead-code` | E11-S3 | Unreachable code, unused exports, orphaned files |
66
+ | `hard-coded-logic` | E11-S4 | Magic numbers, embedded URLs, environment-specific constants |
67
+ | `security-endpoint` | E11-S5 | Unprotected routes, missing auth, exposed secrets |
68
+ | `runtime-behavior` | E11-S6 | Behavior that only manifests at runtime (race conditions, memory leaks) |
69
+ | `doc-code-drift` | E11-S7 | Documentation does not match actual code behavior |
70
+ | `integration-seam` | E11-S8 | Fragile integration points, tight coupling, missing contracts |
71
+
72
+ #### Infrastructure Categories (5) — ADR-022 §10.16.5
73
+
74
+ | Value | Infra PRD Section | Description |
75
+ |-------|-------------------|-------------|
76
+ | `resource-drift` | Resource Specifications | Declared infrastructure state differs from actual deployed state (e.g., Terraform state mismatch, orphaned cloud resources) |
77
+ | `config-sprawl` | Environment Strategy & DX | Configuration values duplicated across multiple files without a single source of truth (e.g., same port in Dockerfile, Helm values, and Terraform variables) |
78
+ | `secret-exposure` | Security Posture | Secrets, credentials, or sensitive values present in source files, environment configs, or IaC definitions without proper secrets management |
79
+ | `missing-policy` | Verification Strategy | Infrastructure lacks policy-as-code enforcement (e.g., no OPA/Rego, no Checkov rules, no tfsec scans for security/compliance) |
80
+ | `environment-skew` | Environment Strategy & DX | Environment definitions (dev/staging/prod) have inconsistent resource specifications, missing parity, or undocumented differences |
81
+
82
+ ### Confidence Enum
83
+
84
+ | Value | Description |
85
+ |-------|-------------|
86
+ | `high` | Strong evidence, verified through multiple signals |
87
+ | `medium` | Reasonable evidence, single signal source |
88
+ | `low` | Weak evidence, needs human verification |
89
+
90
+ ## Evidence Object
91
+
92
+ The `evidence` field is a composite object grouping source location data:
93
+
94
+ ```yaml
95
+ evidence:
96
+ file: "src/services/auth.ts" # Relative path from project root (non-empty string)
97
+ line: 42 # Single line number
98
+ ```
99
+
100
+ Or with a line range:
101
+
102
+ ```yaml
103
+ evidence:
104
+ file: "config/database.yml"
105
+ line: "15-28" # Line range (start-end)
106
+ ```
107
+
108
+ | Sub-field | Type | Required | Constraints |
109
+ |-----------|------|----------|-------------|
110
+ | `file` | string | yes | Relative path from project root. Must be non-empty. |
111
+ | `line` | number or string | yes | Single line number (integer) or range as `"start-end"` string |
112
+
113
+ ## ID Format
114
+
115
+ Pattern: `GAP-{scan_type}-{seq}`
116
+
117
+ - `scan_type` is the category value (e.g., `dead-code`, `config-contradiction`)
118
+ - `seq` is a zero-padded 3-digit sequence number starting at 001
119
+ - Regex: `^GAP-(config-contradiction|dead-code|hard-coded-logic|security-endpoint|runtime-behavior|doc-code-drift|integration-seam|resource-drift|config-sprawl|secret-exposure|missing-policy|environment-skew)-\d{3}$`
120
+
121
+ The `scan_type` component in the ID maps directly to the `category` value. See the Category Enum tables (Application + Infrastructure) for the full list of valid scan types.
122
+
123
+ ## Validation Rules
124
+
125
+ All fields listed in the Field Reference are **required** — a gap entry with any missing field is invalid.
126
+
127
+ ### Enum Validation
128
+
129
+ - `severity` must be exactly one of: `critical`, `high`, `medium`, `low`, `info`
130
+ - `category` must be exactly one of: `config-contradiction`, `dead-code`, `hard-coded-logic`, `security-endpoint`, `runtime-behavior`, `doc-code-drift`, `integration-seam`, `resource-drift`, `config-sprawl`, `secret-exposure`, `missing-policy`, `environment-skew`
131
+ - `confidence` must be exactly one of: `high`, `medium`, `low`
132
+ - Any value not in the enum set must be rejected
133
+
134
+ ### Format Validation
135
+
136
+ - `id` must match the regex `^GAP-(config-contradiction|dead-code|hard-coded-logic|security-endpoint|runtime-behavior|doc-code-drift|integration-seam|resource-drift|config-sprawl|secret-exposure|missing-policy|environment-skew)-\d{3}$`
137
+ - `evidence.file` must be a non-empty string containing a relative path (no leading `/`)
138
+ - `evidence.line` must be a positive integer or a range string matching `^\d+-\d+$`
139
+ - `title` should not exceed 80 characters
140
+ - `verified_by` must be a non-empty string identifying the scan agent
141
+
142
+ ### Required vs Optional
143
+
144
+ All 9 fields (`id`, `category`, `severity`, `title`, `description`, `evidence`, `recommendation`, `verified_by`, `confidence`) are **required**. There are no optional fields in the base schema.
145
+
146
+ ## Budget Control
147
+
148
+ Each gap entry should average approximately **100 tokens** in structured YAML format (per NFR-024).
149
+
150
+ Guidelines:
151
+ - Use structured YAML, not prose paragraphs
152
+ - Keep `title` under 80 characters
153
+ - Keep `description` to 1-2 sentences
154
+ - Keep `recommendation` to 1-2 sentences
155
+ - Avoid embedding full code snippets in descriptions — reference via `evidence` instead
156
+
157
+ With 12 categories across application and infrastructure scans, total token usage varies by project type. After consolidation and deduplication (E11-S10), the single `consolidated-gaps.md` must stay within the 40K framework context budget.
158
+
159
+ ## Examples
160
+
161
+ ### Application Category Example
162
+
163
+ ```yaml
164
+ id: "GAP-config-contradiction-001"
165
+ category: "config-contradiction"
166
+ severity: "high"
167
+ title: "Database timeout mismatch between config files"
168
+ description: "production.yaml sets db.timeout to 30s while docker-compose.yml sets POSTGRES_TIMEOUT to 10s."
169
+ evidence:
170
+ file: "config/production.yaml"
171
+ line: 18
172
+ recommendation: "Align timeout values. Set both to 30s or extract to a shared environment variable."
173
+ verified_by: "config-scanner"
174
+ confidence: "high"
175
+ ```
176
+
177
+ ### Infrastructure Category Examples
178
+
179
+ ```yaml
180
+ id: "GAP-resource-drift-001"
181
+ category: "resource-drift"
182
+ severity: "high"
183
+ title: "Terraform state shows orphaned S3 bucket"
184
+ description: "S3 bucket 'app-logs-legacy' exists in AWS but is not declared in any Terraform configuration."
185
+ evidence:
186
+ file: "infra/terraform/storage.tf"
187
+ line: "1-45"
188
+ recommendation: "Import the bucket into Terraform state or delete it if no longer needed."
189
+ verified_by: "infra-drift-scanner"
190
+ confidence: "high"
191
+ ```
192
+
193
+ ```yaml
194
+ id: "GAP-config-sprawl-001"
195
+ category: "config-sprawl"
196
+ severity: "medium"
197
+ title: "Database port duplicated across 4 config files"
198
+ description: "Port 5432 is hardcoded in Dockerfile, docker-compose.yml, Helm values.yaml, and Terraform variables.tf."
199
+ evidence:
200
+ file: "docker-compose.yml"
201
+ line: 14
202
+ recommendation: "Extract database port to a single environment variable, reference it from all 4 files."
203
+ verified_by: "config-sprawl-scanner"
204
+ confidence: "high"
205
+ ```
206
+
207
+ ```yaml
208
+ id: "GAP-secret-exposure-001"
209
+ category: "secret-exposure"
210
+ severity: "critical"
211
+ title: "AWS access key embedded in Terraform variables"
212
+ description: "AWS_ACCESS_KEY_ID is set as a default value in variables.tf instead of using a secrets manager."
213
+ evidence:
214
+ file: "infra/terraform/variables.tf"
215
+ line: 23
216
+ recommendation: "Remove the default value, use AWS SSM Parameter Store or HashiCorp Vault."
217
+ verified_by: "secret-scanner"
218
+ confidence: "high"
219
+ ```
220
+
221
+ ```yaml
222
+ id: "GAP-missing-policy-001"
223
+ category: "missing-policy"
224
+ severity: "medium"
225
+ title: "No policy-as-code enforcement for Kubernetes manifests"
226
+ description: "Kubernetes deployments lack OPA/Gatekeeper or Kyverno policies for security constraints."
227
+ evidence:
228
+ file: "k8s/deployments/api-server.yaml"
229
+ line: "1-30"
230
+ recommendation: "Add OPA Gatekeeper constraints or Kyverno policies to enforce pod security standards."
231
+ verified_by: "policy-scanner"
232
+ confidence: "medium"
233
+ ```
234
+
235
+ ```yaml
236
+ id: "GAP-environment-skew-001"
237
+ category: "environment-skew"
238
+ severity: "high"
239
+ title: "Staging uses 2 replicas while production uses 5"
240
+ description: "Replica counts differ between staging and production with no documented justification."
241
+ evidence:
242
+ file: "k8s/overlays/staging/deployment-patch.yaml"
243
+ line: 8
244
+ recommendation: "Document the replica difference rationale or align staging proportionally."
245
+ verified_by: "env-skew-scanner"
246
+ confidence: "high"
247
+ ```