@fulmenhq/tsfulmen 0.2.7 → 0.2.8

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 (48) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/config/crucible-ts/agentic/roles/cicd.yaml +3 -0
  3. package/config/crucible-ts/agentic/roles/cxotech.yaml +152 -0
  4. package/config/crucible-ts/agentic/roles/dataeng.yaml +3 -0
  5. package/config/crucible-ts/agentic/roles/deliverylead.yaml +159 -0
  6. package/config/crucible-ts/agentic/roles/devlead.yaml +3 -0
  7. package/config/crucible-ts/agentic/roles/devrev.yaml +3 -0
  8. package/config/crucible-ts/agentic/roles/entarch.yaml +4 -0
  9. package/config/crucible-ts/agentic/roles/infoarch.yaml +3 -0
  10. package/config/crucible-ts/agentic/roles/infraeng.yaml +193 -0
  11. package/config/crucible-ts/agentic/roles/prodmktg.yaml +3 -0
  12. package/config/crucible-ts/agentic/roles/qa.yaml +3 -0
  13. package/config/crucible-ts/agentic/roles/releng.yaml +129 -0
  14. package/config/crucible-ts/agentic/roles/secrev.yaml +3 -0
  15. package/config/crucible-ts/agentic/roles/uxdev.yaml +3 -0
  16. package/config/crucible-ts/taxonomy/metrics.yaml +1 -1
  17. package/dist/appidentity/index.js.map +1 -1
  18. package/dist/config/index.js.map +1 -1
  19. package/dist/crucible/index.d.ts +61 -1
  20. package/dist/crucible/index.js +47 -1
  21. package/dist/crucible/index.js.map +1 -1
  22. package/dist/errors/index.js.map +1 -1
  23. package/dist/foundry/index.js.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/pathfinder/index.js.map +1 -1
  28. package/dist/reports/license-inventory.csv +19 -27
  29. package/dist/schema/index.js.map +1 -1
  30. package/dist/signals/index.js.map +1 -1
  31. package/dist/telemetry/http/index.js.map +1 -1
  32. package/dist/telemetry/index.js.map +1 -1
  33. package/dist/telemetry/prometheus/index.js +2 -2
  34. package/dist/telemetry/prometheus/index.js.map +1 -1
  35. package/package.json +14 -14
  36. package/schemas/crucible-ts/upstream/3leaps/crucible/PROVENANCE.md +21 -20
  37. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/access-tier.dimension.json +24 -6
  38. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/retention-lifecycle.dimension.json +24 -6
  39. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/schema-stability.dimension.json +20 -5
  40. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/sensitivity.dimension.json +20 -5
  41. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/velocity-mode.dimension.json +20 -5
  42. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/volatility.dimension.json +24 -6
  43. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/volume-tier.dimension.json +24 -6
  44. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/agentic/v0/README.md +87 -0
  45. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/agentic/v0/role-prompt.schema.json +60 -1
  46. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/classifiers/v0/dimension-definition.schema.json +18 -6
  47. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/classifiers/v0/sensitivity-level.schema.json +64 -21
  48. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/types.schema.json +15 -5
package/package.json CHANGED
@@ -2,36 +2,36 @@
2
2
  "author": "3 Leaps, LLC",
3
3
  "dependencies": {
4
4
  "@3leaps/string-metrics-wasm": "0.3.8",
5
- "ajv": "^8.17.1",
5
+ "ajv": "^8.18.0",
6
6
  "ajv-draft-04": "^1.0.0",
7
7
  "ajv-formats": "^3.0.1",
8
8
  "archiver": "^7.0.1",
9
- "commander": "^14.0.1",
9
+ "commander": "^14.0.3",
10
10
  "fast-glob": "^3.3.3",
11
11
  "hash-wasm": "^4.12.0",
12
12
  "picomatch": "^4.0.3",
13
13
  "pino": "^9.5.0",
14
14
  "tar-stream": "^3.1.7",
15
15
  "unzipper": "^0.12.3",
16
- "yaml": "^2.6.1"
16
+ "yaml": "^2.8.2"
17
17
  },
18
18
  "description": "TypeScript Fulmen helper library - ergonomic access to Crucible SSOT and core utilities",
19
19
  "devDependencies": {
20
- "@biomejs/biome": "^2.2.5",
21
- "@types/archiver": "^6.0.2",
22
- "@types/bun": "^1.1.12",
23
- "@types/express": "^5.0.0",
24
- "@types/node": "^22.9.0",
20
+ "@biomejs/biome": "^2.4.3",
21
+ "@types/archiver": "^7.0.0",
22
+ "@types/bun": "^1.3.9",
23
+ "@types/express": "^5.0.6",
24
+ "@types/node": "^25.3.0",
25
25
  "@types/picomatch": "^4.0.2",
26
26
  "@types/unzipper": "^0.10.11",
27
27
  "@vitest/coverage-v8": "^4.0.18",
28
28
  "@vitest/ui": "^4.0.18",
29
- "fastify": "^5.2.0",
30
- "prettier": "^3.6.2",
29
+ "fastify": "^5.7.4",
30
+ "prettier": "^3.8.1",
31
31
  "prom-client": "^15.1.3",
32
- "tsup": "^8.3.5",
33
- "tsx": "^4.19.2",
34
- "typescript": "^5.7.2",
32
+ "tsup": "^8.5.1",
33
+ "tsx": "^4.21.0",
34
+ "typescript": "^5.9.3",
35
35
  "vitest": "^4.0.18"
36
36
  },
37
37
  "engines": {
@@ -184,5 +184,5 @@
184
184
  },
185
185
  "type": "module",
186
186
  "types": "./dist/index.d.ts",
187
- "version": "0.2.7"
187
+ "version": "0.2.8"
188
188
  }
@@ -7,32 +7,31 @@
7
7
  | Field | Value |
8
8
  | ---------- | ------------------------------------------ |
9
9
  | Repository | https://github.com/3leaps/crucible |
10
- | Tag | v0.1.4 |
11
- | Commit | 415cec1e5931d091252f91209f6e0456838c6a22 |
12
- | Date | 2026-01-22 |
10
+ | Tag | v0.1.12 |
11
+ | Commit | 96a17853ee48446f7740d61a518fcfcba20ae444 |
12
+ | Date | 2026-02-18 |
13
13
  | Synced By | devlead (Claude Opus 4.5 via Claude Code) |
14
14
 
15
15
  ## Structure
16
16
 
17
17
  ```
18
18
  schemas/upstream/3leaps/crucible/
19
- ├── schemas/
20
- │ ├── agentic/v0/ # Role prompt schema (MANUAL)
21
- │ ├── ailink/v0/ # Prompt/response schemas
22
- │ ├── classifiers/v0/ # Dimension meta-schemas
23
- │ └── foundation/v0/ # Type primitives, error response
24
- ├── config/
25
- │ └── classifiers/ # Dimension definitions
26
- ├── docs/
27
- │ ├── standards/ # Classification standards
28
- │ └── catalog/ # Classifier catalog
29
- └── PROVENANCE.md
19
+ ├── schemas/
20
+ │ ├── classifiers/v0/ # Dimension meta-schemas
21
+ │ ├── foundation/v0/ # Type primitives, error response
22
+ │ ├── ailink/v0/ # Prompt/response schemas
23
+ │ └── agentic/v0/ # Role prompt schemas
24
+ ├── config/
25
+ │ └── classifiers/ # Dimension definitions
26
+ ├── docs/
27
+ │ ├── standards/ # Classification standards
28
+ │ └── catalog/ # Classifier catalog
29
+ └── PROVENANCE.md
30
30
  ```
31
31
 
32
32
  ## Files Synced
33
33
 
34
- - **26 files** auto-synced via `3leaps-crucible-upstream-pull.ts`
35
- - **1 file** manually synced: `schemas/agentic/v0/role-prompt.schema.json`
34
+ 28 files from 3leaps/crucible
36
35
 
37
36
  ## Canonical URLs
38
37
 
@@ -41,13 +40,15 @@ These schemas are canonically hosted at:
41
40
  - `https://schemas.3leaps.dev/classifiers/v0/*.json`
42
41
  - `https://schemas.3leaps.dev/foundation/v0/*.json`
43
42
  - `https://schemas.3leaps.dev/ailink/v0/*.json`
43
+ - `https://schemas.3leaps.dev/agentic/v0/*.json`
44
44
 
45
- ## Manual Sync Items
45
+ ## Excluded (Manual Sync)
46
46
 
47
- The following are NOT auto-synced - they require manual review for fulmenhq-specific customization:
47
+ The following are NOT synced by this script:
48
48
 
49
- - `schemas/agentic/v0/role-prompt.schema.json` - Present, manually synced
50
- - `config/agentic/` - Not vendored (fulmenhq maintains its own role definitions)
49
+ - `config/agentic/` - Role definitions
50
+
51
+ These are synced manually as they require review for fulmenhq-specific customization.
51
52
 
52
53
  ## Refresh
53
54
 
@@ -93,11 +93,29 @@
93
93
  "last_updated": "2026-01-22"
94
94
  },
95
95
  "examples": [
96
- { "dataset": "unreviewed-upload", "value": "unknown" },
97
- { "dataset": "public-api-docs", "value": "public" },
98
- { "dataset": "internal-runbooks", "value": "internal" },
99
- { "dataset": "project-roadmap", "value": "restricted" },
100
- { "dataset": "security-audit-findings", "value": "privileged" },
101
- { "dataset": "legal-discovery-materials", "value": "eyes-only" }
96
+ {
97
+ "dataset": "unreviewed-upload",
98
+ "value": "unknown"
99
+ },
100
+ {
101
+ "dataset": "public-api-docs",
102
+ "value": "public"
103
+ },
104
+ {
105
+ "dataset": "internal-runbooks",
106
+ "value": "internal"
107
+ },
108
+ {
109
+ "dataset": "project-roadmap",
110
+ "value": "restricted"
111
+ },
112
+ {
113
+ "dataset": "security-audit-findings",
114
+ "value": "privileged"
115
+ },
116
+ {
117
+ "dataset": "legal-discovery-materials",
118
+ "value": "eyes-only"
119
+ }
102
120
  ]
103
121
  }
@@ -93,11 +93,29 @@
93
93
  "last_updated": "2026-01-22"
94
94
  },
95
95
  "examples": [
96
- { "dataset": "new-data-source", "value": "unknown" },
97
- { "dataset": "session-cache", "value": "transient" },
98
- { "dataset": "debug-logs", "value": "short" },
99
- { "dataset": "transaction-history", "value": "standard" },
100
- { "dataset": "audit-records", "value": "long" },
101
- { "dataset": "litigation-evidence", "value": "legal-hold" }
96
+ {
97
+ "dataset": "new-data-source",
98
+ "value": "unknown"
99
+ },
100
+ {
101
+ "dataset": "session-cache",
102
+ "value": "transient"
103
+ },
104
+ {
105
+ "dataset": "debug-logs",
106
+ "value": "short"
107
+ },
108
+ {
109
+ "dataset": "transaction-history",
110
+ "value": "standard"
111
+ },
112
+ {
113
+ "dataset": "audit-records",
114
+ "value": "long"
115
+ },
116
+ {
117
+ "dataset": "litigation-evidence",
118
+ "value": "legal-hold"
119
+ }
102
120
  ]
103
121
  }
@@ -91,10 +91,25 @@
91
91
  "last_updated": "2026-01-22"
92
92
  },
93
93
  "examples": [
94
- { "path": "schemas/new-feature/", "value": "unknown" },
95
- { "path": "schemas/agentic/v0/", "value": "experimental" },
96
- { "path": "schemas/foundation/v1/", "value": "stable" },
97
- { "dataset": "api-v2-endpoints", "value": "evolving" },
98
- { "dataset": "api-v1-endpoints", "value": "deprecated" }
94
+ {
95
+ "path": "schemas/new-feature/",
96
+ "value": "unknown"
97
+ },
98
+ {
99
+ "path": "schemas/agentic/v0/",
100
+ "value": "experimental"
101
+ },
102
+ {
103
+ "path": "schemas/foundation/v1/",
104
+ "value": "stable"
105
+ },
106
+ {
107
+ "dataset": "api-v2-endpoints",
108
+ "value": "evolving"
109
+ },
110
+ {
111
+ "dataset": "api-v1-endpoints",
112
+ "value": "deprecated"
113
+ }
99
114
  ]
100
115
  }
@@ -121,10 +121,25 @@
121
121
  "last_updated": "2026-01-22"
122
122
  },
123
123
  "examples": [
124
- { "dataset": "retail-pos-transactions", "value": "0-public" },
125
- { "dataset": "proxy-session-logs", "value": "2-blinded" },
126
- { "dataset": "api-keys-inventory", "value": "4-personal" },
127
- { "dataset": "credential-dumps", "value": "5-privileged" },
128
- { "dataset": "security-breach-evidence", "value": "6-eyes-only" }
124
+ {
125
+ "dataset": "retail-pos-transactions",
126
+ "value": "0-public"
127
+ },
128
+ {
129
+ "dataset": "proxy-session-logs",
130
+ "value": "2-blinded"
131
+ },
132
+ {
133
+ "dataset": "api-keys-inventory",
134
+ "value": "4-personal"
135
+ },
136
+ {
137
+ "dataset": "credential-dumps",
138
+ "value": "5-privileged"
139
+ },
140
+ {
141
+ "dataset": "security-breach-evidence",
142
+ "value": "6-eyes-only"
143
+ }
129
144
  ]
130
145
  }
@@ -70,10 +70,25 @@
70
70
  "last_updated": "2026-01-22"
71
71
  },
72
72
  "examples": [
73
- { "dataset": "new-pipeline", "value": "unknown" },
74
- { "dataset": "daily-etl-jobs", "value": "batch" },
75
- { "dataset": "dashboard-metrics", "value": "micro-batch" },
76
- { "dataset": "fraud-detection", "value": "streaming" },
77
- { "dataset": "analytics-platform", "value": "hybrid" }
73
+ {
74
+ "dataset": "new-pipeline",
75
+ "value": "unknown"
76
+ },
77
+ {
78
+ "dataset": "daily-etl-jobs",
79
+ "value": "batch"
80
+ },
81
+ {
82
+ "dataset": "dashboard-metrics",
83
+ "value": "micro-batch"
84
+ },
85
+ {
86
+ "dataset": "fraud-detection",
87
+ "value": "streaming"
88
+ },
89
+ {
90
+ "dataset": "analytics-platform",
91
+ "value": "hybrid"
92
+ }
78
93
  ]
79
94
  }
@@ -62,11 +62,29 @@
62
62
  "last_updated": "2026-01-22"
63
63
  },
64
64
  "examples": [
65
- { "dataset": "newly-ingested-feed", "value": "unknown" },
66
- { "dataset": "retail-pos-transactions", "value": "daily" },
67
- { "dataset": "network-telemetry", "value": "streaming" },
68
- { "dataset": "product-catalog", "value": "weekly" },
69
- { "dataset": "agentic-role-definitions", "value": "static" },
70
- { "dataset": "api-rate-limits", "value": "hourly" }
65
+ {
66
+ "dataset": "newly-ingested-feed",
67
+ "value": "unknown"
68
+ },
69
+ {
70
+ "dataset": "retail-pos-transactions",
71
+ "value": "daily"
72
+ },
73
+ {
74
+ "dataset": "network-telemetry",
75
+ "value": "streaming"
76
+ },
77
+ {
78
+ "dataset": "product-catalog",
79
+ "value": "weekly"
80
+ },
81
+ {
82
+ "dataset": "agentic-role-definitions",
83
+ "value": "static"
84
+ },
85
+ {
86
+ "dataset": "api-rate-limits",
87
+ "value": "hourly"
88
+ }
71
89
  ]
72
90
  }
@@ -56,11 +56,29 @@
56
56
  "last_updated": "2026-01-22"
57
57
  },
58
58
  "examples": [
59
- { "dataset": "new-data-feed", "value": "unknown" },
60
- { "dataset": "test-fixtures", "value": "tiny" },
61
- { "dataset": "product-catalog", "value": "small" },
62
- { "dataset": "transaction-history", "value": "medium" },
63
- { "dataset": "event-telemetry", "value": "large" },
64
- { "dataset": "global-clickstream", "value": "massive" }
59
+ {
60
+ "dataset": "new-data-feed",
61
+ "value": "unknown"
62
+ },
63
+ {
64
+ "dataset": "test-fixtures",
65
+ "value": "tiny"
66
+ },
67
+ {
68
+ "dataset": "product-catalog",
69
+ "value": "small"
70
+ },
71
+ {
72
+ "dataset": "transaction-history",
73
+ "value": "medium"
74
+ },
75
+ {
76
+ "dataset": "event-telemetry",
77
+ "value": "large"
78
+ },
79
+ {
80
+ "dataset": "global-clickstream",
81
+ "value": "massive"
82
+ }
65
83
  ]
66
84
  }
@@ -0,0 +1,87 @@
1
+ # Agentic Schemas v0
2
+
3
+ Schemas for AI coding agent collaboration.
4
+
5
+ **Status**: Unstable (v0) - breaking changes may occur without notice.
6
+
7
+ ## Schemas
8
+
9
+ | Schema | Purpose |
10
+ | ------------------------- | ---------------------------------- |
11
+ | `role-prompt.schema.json` | Role prompt frontmatter validation |
12
+
13
+ ## Usage
14
+
15
+ ### Role Prompts
16
+
17
+ Role prompts define how AI coding assistants operate within repositories. They use YAML frontmatter validated against `role-prompt.schema.json`:
18
+
19
+ ```yaml
20
+ ---
21
+ slug: devlead
22
+ name: Development Lead
23
+ description: Architecture, implementation, and code review
24
+ version: 1.0.0
25
+ author: entarch
26
+ status: approved
27
+ category: agentic
28
+ tags: [role, implementation, architecture]
29
+ ---
30
+
31
+ # Role: devlead
32
+
33
+ One-line description.
34
+
35
+ ## Context
36
+ When to use this role...
37
+
38
+ ## Scope
39
+ - What this role covers
40
+ - Boundaries of responsibility
41
+
42
+ ## Mindset
43
+ Focus on:
44
+ - Key questions to ask
45
+ - Perspective to maintain
46
+
47
+ ## Responsibilities
48
+ - Specific duties
49
+ - Quality expectations
50
+
51
+ ## Escalates To
52
+ - When to escalate
53
+ - Who to escalate to
54
+
55
+ ## Does Not
56
+ - Explicit exclusions
57
+ - Out-of-scope items
58
+
59
+ ## Examples
60
+ Commit examples, checklists...
61
+ ```
62
+
63
+ ### Required Body Sections
64
+
65
+ By convention (not schema-enforced), role prompts should include:
66
+
67
+ | Section | Required | Purpose |
68
+ | ---------------- | ----------- | ---------------------------------------- |
69
+ | Context | Recommended | When to use this role |
70
+ | Scope | Yes | What this role covers |
71
+ | Mindset | Recommended | Context engineering for AI effectiveness |
72
+ | Responsibilities | Yes | Specific duties and expectations |
73
+ | Escalates To | Yes | When and who to hand off to |
74
+ | Does Not | Yes | Explicit boundaries and exclusions |
75
+ | Examples | Recommended | Commit patterns, checklists |
76
+
77
+ ## Schema URL
78
+
79
+ ```
80
+ https://schemas.3leaps.dev/agentic/v0/role-prompt.schema.json
81
+ ```
82
+
83
+ ## Related
84
+
85
+ - [docs/catalog/roles/](../../docs/catalog/roles/) - Baseline role definitions
86
+ - [docs/repository/agent-identity.md](../../docs/repository/agent-identity.md) - Identity scheme
87
+ - [FulmenHQ Crucible](https://github.com/fulmenhq/crucible) - Enterprise role catalog
@@ -52,7 +52,15 @@
52
52
  },
53
53
  "category": {
54
54
  "type": "string",
55
- "enum": ["agentic", "automation", "review", "governance", "marketing"],
55
+ "enum": [
56
+ "agentic",
57
+ "analytics",
58
+ "automation",
59
+ "consulting",
60
+ "governance",
61
+ "marketing",
62
+ "review"
63
+ ],
56
64
  "description": "Role category for organization"
57
65
  },
58
66
  "tags": {
@@ -63,6 +71,32 @@
63
71
  },
64
72
  "description": "Searchable tags for the role"
65
73
  },
74
+ "domains": {
75
+ "type": "array",
76
+ "items": {
77
+ "type": "string",
78
+ "enum": [
79
+ "analytics",
80
+ "architecture",
81
+ "automation",
82
+ "consulting",
83
+ "coordination",
84
+ "delivery",
85
+ "development",
86
+ "documentation",
87
+ "governance",
88
+ "implementation",
89
+ "marketing",
90
+ "product",
91
+ "quality",
92
+ "security",
93
+ "strategy"
94
+ ]
95
+ },
96
+ "minItems": 1,
97
+ "maxItems": 3,
98
+ "description": "Process domains this role operates in (1-3). Used for organizational categorization beyond technical functions."
99
+ },
66
100
  "extends": {
67
101
  "type": "string",
68
102
  "format": "uri",
@@ -140,6 +174,31 @@
140
174
  }
141
175
  },
142
176
  "description": "Named checklists for common tasks"
177
+ },
178
+ "pre_push_checklist": {
179
+ "type": "array",
180
+ "items": {
181
+ "type": "string"
182
+ },
183
+ "description": "Checklist of validations to perform before pushing changes"
184
+ },
185
+ "required_reading": {
186
+ "type": "object",
187
+ "properties": {
188
+ "description": {
189
+ "type": "string",
190
+ "description": "Explanation of what should be read and why"
191
+ },
192
+ "pattern": {
193
+ "type": "string",
194
+ "description": "Guidance on where to find required reading (project-specific)"
195
+ }
196
+ },
197
+ "description": "Documents that must be read before starting work in this role"
198
+ },
199
+ "cross_role_note": {
200
+ "type": "string",
201
+ "description": "Guidance on coordination with other roles"
143
202
  }
144
203
  },
145
204
  "additionalProperties": false,
@@ -125,7 +125,9 @@
125
125
  },
126
126
  "synonyms": {
127
127
  "type": "array",
128
- "items": { "type": "string" },
128
+ "items": {
129
+ "type": "string"
130
+ },
129
131
  "description": "Alternative names that map to this value"
130
132
  }
131
133
  },
@@ -162,12 +164,16 @@
162
164
  "properties": {
163
165
  "default_order": {
164
166
  "type": "array",
165
- "items": { "type": "string" },
167
+ "items": {
168
+ "type": "string"
169
+ },
166
170
  "description": "Default sort order of value keys"
167
171
  },
168
172
  "ordinal_mapping": {
169
173
  "type": "object",
170
- "additionalProperties": { "type": "integer" },
174
+ "additionalProperties": {
175
+ "type": "integer"
176
+ },
171
177
  "description": "Numeric ordinal for each value key"
172
178
  },
173
179
  "missing_handling": {
@@ -188,12 +194,16 @@
188
194
  "properties": {
189
195
  "downgrade": {
190
196
  "type": "array",
191
- "items": { "type": "string" },
197
+ "items": {
198
+ "type": "string"
199
+ },
192
200
  "description": "Valid downgrade paths (e.g., '4-personal->2-blinded')"
193
201
  },
194
202
  "upgrade": {
195
203
  "type": "array",
196
- "items": { "type": "string" },
204
+ "items": {
205
+ "type": "string"
206
+ },
197
207
  "description": "Valid upgrade paths"
198
208
  }
199
209
  },
@@ -208,7 +218,9 @@
208
218
  },
209
219
  "reviewers": {
210
220
  "type": "array",
211
- "items": { "type": "string" },
221
+ "items": {
222
+ "type": "string"
223
+ },
212
224
  "description": "Required reviewers for changes"
213
225
  },
214
226
  "review_cycle": {