@dogfood-lab/schemas 1.2.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.
- package/LICENSE +21 -0
- package/README.md +76 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/validate.d.ts +67 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +87 -0
- package/dist/validate.js.map +1 -0
- package/package.json +57 -0
- package/src/json/dogfood-doctrine.schema.json +86 -0
- package/src/json/dogfood-finding.schema.json +414 -0
- package/src/json/dogfood-pattern.schema.json +124 -0
- package/src/json/dogfood-recommendation.schema.json +107 -0
- package/src/json/dogfood-record-submission.schema.json +226 -0
- package/src/json/dogfood-record.schema.json +303 -0
- package/src/json/policy.schema.json +182 -0
- package/src/json/scenario.schema.json +143 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/dogfood-lab/testing-os/packages/schemas/src/json/policy.schema.json",
|
|
4
|
+
"title": "Dogfood Policy",
|
|
5
|
+
"description": "Per-repo or global policy defining verification rules. Global policy provides defaults and non-overridable rules. Repo policies define surface-specific requirements.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["policy_version"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
|
|
11
|
+
"repo": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"pattern": "^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$",
|
|
14
|
+
"description": "Full org/repo. Absent in global policy."
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
"policy_version": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$"
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
"enforcement": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"description": "How Gate F treats this repo. Defaults to required if omitted.",
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"properties": {
|
|
27
|
+
"mode": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"enum": ["required", "warn-only", "exempt"],
|
|
30
|
+
"description": "required: Gate F fails on missing/stale/non-pass. warn-only: emits warning, exits 0. exempt: reports exempt status, exits 0."
|
|
31
|
+
},
|
|
32
|
+
"reason": {
|
|
33
|
+
"type": ["string", "null"],
|
|
34
|
+
"description": "Why this repo is warn-only or exempt. Required if mode is not 'required'."
|
|
35
|
+
},
|
|
36
|
+
"review_after": {
|
|
37
|
+
"type": ["string", "null"],
|
|
38
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
|
|
39
|
+
"description": "Date (YYYY-MM-DD) to review enforcement mode. Required if mode is 'exempt'."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
"surfaces": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"description": "Per-surface policy. Keys are product_surface values.",
|
|
47
|
+
"propertyNames": {
|
|
48
|
+
"enum": ["cli", "desktop", "web", "api", "mcp-server", "npm-package", "plugin", "library"]
|
|
49
|
+
},
|
|
50
|
+
"additionalProperties": {
|
|
51
|
+
"$ref": "#/$defs/surface_policy"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
"defaults": {
|
|
56
|
+
"$ref": "#/$defs/surface_policy",
|
|
57
|
+
"description": "Default surface policy. Used when a surface has no explicit policy."
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
"global_rules": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"description": "Non-overridable rules. Only meaningful in global policy. Repo policies cannot weaken these.",
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"required": ["id", "severity"],
|
|
66
|
+
"additionalProperties": false,
|
|
67
|
+
"properties": {
|
|
68
|
+
"id": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"description": "Stable rule ID for reporting and diagnostics."
|
|
71
|
+
},
|
|
72
|
+
"description": { "type": "string" },
|
|
73
|
+
"severity": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"enum": ["reject", "warn", "info"],
|
|
76
|
+
"description": "reject: fails verification. warn: accepted with warning. info: logged only."
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
"stale_thresholds": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"description": "Days since last accepted dogfood record. Used by CLI and indexes.",
|
|
85
|
+
"additionalProperties": false,
|
|
86
|
+
"properties": {
|
|
87
|
+
"critical": {
|
|
88
|
+
"type": "integer",
|
|
89
|
+
"minimum": 1,
|
|
90
|
+
"description": "Days until flagged critical (red)."
|
|
91
|
+
},
|
|
92
|
+
"warning": {
|
|
93
|
+
"type": "integer",
|
|
94
|
+
"minimum": 1,
|
|
95
|
+
"description": "Days until flagged warning (yellow)."
|
|
96
|
+
},
|
|
97
|
+
"healthy": {
|
|
98
|
+
"type": "integer",
|
|
99
|
+
"minimum": 1,
|
|
100
|
+
"description": "Days within which the repo is considered healthy (green)."
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
"$defs": {
|
|
107
|
+
"surface_policy": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"additionalProperties": false,
|
|
110
|
+
"properties": {
|
|
111
|
+
"required_scenarios": {
|
|
112
|
+
"type": "array",
|
|
113
|
+
"items": { "type": "string" },
|
|
114
|
+
"description": "Scenario IDs that must have a recent accepted record."
|
|
115
|
+
},
|
|
116
|
+
"freshness": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"additionalProperties": false,
|
|
119
|
+
"properties": {
|
|
120
|
+
"max_age_days": {
|
|
121
|
+
"type": "integer",
|
|
122
|
+
"minimum": 1,
|
|
123
|
+
"description": "Maximum days since last accepted run before the surface is stale."
|
|
124
|
+
},
|
|
125
|
+
"warn_age_days": {
|
|
126
|
+
"type": "integer",
|
|
127
|
+
"minimum": 1,
|
|
128
|
+
"description": "Days since last accepted run before warning."
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
"execution_mode_policy": {
|
|
133
|
+
"type": "object",
|
|
134
|
+
"additionalProperties": false,
|
|
135
|
+
"properties": {
|
|
136
|
+
"allowed": {
|
|
137
|
+
"type": "array",
|
|
138
|
+
"items": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"enum": ["bot", "human", "mixed"]
|
|
141
|
+
},
|
|
142
|
+
"description": "Which execution modes are accepted for this surface."
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"ci_requirements": {
|
|
147
|
+
"type": "object",
|
|
148
|
+
"additionalProperties": false,
|
|
149
|
+
"properties": {
|
|
150
|
+
"coverage_min": {
|
|
151
|
+
"type": ["number", "null"],
|
|
152
|
+
"description": "Minimum coverage percentage. Null means no coverage gate."
|
|
153
|
+
},
|
|
154
|
+
"tests_must_pass": {
|
|
155
|
+
"type": "boolean",
|
|
156
|
+
"description": "Whether all CI test checks must pass."
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"evidence_requirements": {
|
|
161
|
+
"type": "object",
|
|
162
|
+
"additionalProperties": false,
|
|
163
|
+
"properties": {
|
|
164
|
+
"required_kinds": {
|
|
165
|
+
"type": "array",
|
|
166
|
+
"items": {
|
|
167
|
+
"type": "string",
|
|
168
|
+
"enum": ["log", "screenshot", "recording", "transcript", "artifact", "other"]
|
|
169
|
+
},
|
|
170
|
+
"description": "Evidence kinds that must be present."
|
|
171
|
+
},
|
|
172
|
+
"min_evidence_count": {
|
|
173
|
+
"type": "integer",
|
|
174
|
+
"minimum": 0,
|
|
175
|
+
"description": "Minimum number of evidence items across all scenarios."
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/dogfood-lab/testing-os/packages/schemas/src/json/scenario.schema.json",
|
|
4
|
+
"title": "Dogfood Scenario Definition",
|
|
5
|
+
"description": "Authored in source repos under dogfood/scenarios/. Defines what constitutes a real dogfood exercise for a specific product surface. Steps are descriptive (what to verify), not executable (how to automate).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"scenario_id",
|
|
9
|
+
"scenario_name",
|
|
10
|
+
"scenario_version",
|
|
11
|
+
"product_surface",
|
|
12
|
+
"execution_mode",
|
|
13
|
+
"description",
|
|
14
|
+
"steps",
|
|
15
|
+
"success_criteria"
|
|
16
|
+
],
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"properties": {
|
|
19
|
+
|
|
20
|
+
"scenario_id": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
23
|
+
"description": "Stable kebab-case ID. Referenced by policy and records. Must be unique within the repo."
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
"scenario_name": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "Human-readable name for display."
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
"scenario_version": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
34
|
+
"description": "Semver. Bump when steps or success criteria change."
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"product_surface": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"enum": ["cli", "desktop", "web", "api", "mcp-server", "npm-package", "plugin", "library"],
|
|
40
|
+
"description": "The product surface this scenario exercises."
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
"execution_mode": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"enum": ["bot", "human", "mixed"],
|
|
46
|
+
"description": "bot: fully automated. human: manual exercise. mixed: automation + human attestation."
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
"description": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "What this scenario proves about the product."
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
"preconditions": {
|
|
55
|
+
"type": "array",
|
|
56
|
+
"items": { "type": "string" },
|
|
57
|
+
"description": "Conditions that must be true before the scenario can run."
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
"steps": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"minItems": 1,
|
|
63
|
+
"description": "Ordered steps describing the dogfood exercise.",
|
|
64
|
+
"items": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"required": ["id", "action"],
|
|
67
|
+
"additionalProperties": false,
|
|
68
|
+
"properties": {
|
|
69
|
+
"id": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
72
|
+
"description": "Stable step ID. Referenced by success_criteria.required_steps and record step_results."
|
|
73
|
+
},
|
|
74
|
+
"action": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"description": "What the operator does in this step."
|
|
77
|
+
},
|
|
78
|
+
"verifiable": {
|
|
79
|
+
"type": "boolean",
|
|
80
|
+
"default": false,
|
|
81
|
+
"description": "Whether this step produces a checkable outcome."
|
|
82
|
+
},
|
|
83
|
+
"expected": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "What a passing result looks like. Required if verifiable is true."
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
"success_criteria": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"required": ["required_steps"],
|
|
94
|
+
"additionalProperties": false,
|
|
95
|
+
"properties": {
|
|
96
|
+
"required_steps": {
|
|
97
|
+
"type": "array",
|
|
98
|
+
"items": { "type": "string" },
|
|
99
|
+
"description": "Step IDs that must pass for the scenario to pass. Must reference valid step IDs."
|
|
100
|
+
},
|
|
101
|
+
"minimum_evidence": {
|
|
102
|
+
"type": "array",
|
|
103
|
+
"description": "Evidence types the verifier will require for this scenario.",
|
|
104
|
+
"items": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"required": ["kind"],
|
|
107
|
+
"additionalProperties": false,
|
|
108
|
+
"properties": {
|
|
109
|
+
"kind": {
|
|
110
|
+
"type": "string",
|
|
111
|
+
"enum": ["log", "screenshot", "recording", "transcript", "artifact", "other"]
|
|
112
|
+
},
|
|
113
|
+
"description": { "type": "string" }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
"tags": {
|
|
121
|
+
"type": "array",
|
|
122
|
+
"items": { "type": "string" },
|
|
123
|
+
"description": "Freeform tags for filtering and grouping."
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
"automation": {
|
|
127
|
+
"type": ["object", "null"],
|
|
128
|
+
"description": "Automation hints. Null means human-only scenario.",
|
|
129
|
+
"additionalProperties": false,
|
|
130
|
+
"properties": {
|
|
131
|
+
"script": {
|
|
132
|
+
"type": "string",
|
|
133
|
+
"description": "Path to automation script, relative to repo root."
|
|
134
|
+
},
|
|
135
|
+
"timeout_ms": {
|
|
136
|
+
"type": "integer",
|
|
137
|
+
"minimum": 1000,
|
|
138
|
+
"default": 120000
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|