microsoft/hve-core

Public

mirrored from https://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/docs-update-scripts-linting-readme

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/linting/schemas/accessibility-state.schema.json

503lines · modecode

1{
2 "$schema": "https://json-schema.org/draft/2020-12/schema",
3 "$id": "https://github.com/microsoft/hve-core/schemas/accessibility-state.schema.json",
4 "title": "Accessibility Planner State Schema",
5 "description": "Schema for Accessibility Planner state.json files under .copilot-tracking/accessibility/{project-slug}/",
6 "type": "object",
7 "required": [
8 "project",
9 "phase",
10 "frameworkSelections",
11 "controlMappings",
12 "riskClassification",
13 "evidenceRegister",
14 "gates",
15 "planRiskAssessment",
16 "noticeLog"
17 ],
18 "properties": {
19 "project": {
20 "$ref": "#/$defs/project"
21 },
22 "phase": {
23 "type": "string",
24 "enum": [
25 "discovery",
26 "framework-selection",
27 "standards-mapping",
28 "plan-risk-assessment",
29 "impact-evidence",
30 "backlog-handoff"
31 ],
32 "description": "Current planner phase"
33 },
34 "frameworkSelections": {
35 "type": "object",
36 "description": "Map of framework id to selection state. Default framework ids: wcag-22, aria-apg, coga, section-508, en-301-549. User-imported skills supply their own ids; selection is always explicit (no auto-include).",
37 "patternProperties": {
38 "^[a-z0-9]+(-[a-z0-9]+)*$": {
39 "$ref": "#/$defs/frameworkSelectionEntry"
40 }
41 },
42 "additionalProperties": false
43 },
44 "controlMappings": {
45 "type": "array",
46 "description": "Per-framework control coverage records",
47 "items": {
48 "$ref": "#/$defs/controlMapping"
49 }
50 },
51 "riskClassification": {
52 "$ref": "#/$defs/riskClassification"
53 },
54 "evidenceRegister": {
55 "type": "array",
56 "description": "Evidence inventory; shape is compatible with security planner evidence records so SSSC and RAI can cross-reference entries by stable id and sourceUri",
57 "items": {
58 "$ref": "#/$defs/evidenceEntry"
59 }
60 },
61 "gates": {
62 "type": "object",
63 "description": "Per-phase gate state; one key per value of the phase enum",
64 "required": [
65 "discovery",
66 "framework-selection",
67 "standards-mapping",
68 "plan-risk-assessment",
69 "impact-evidence",
70 "backlog-handoff"
71 ],
72 "properties": {
73 "discovery": { "$ref": "#/$defs/gateEntry" },
74 "framework-selection": { "$ref": "#/$defs/gateEntry" },
75 "standards-mapping": { "$ref": "#/$defs/gateEntry" },
76 "plan-risk-assessment": { "$ref": "#/$defs/gateEntry" },
77 "impact-evidence": { "$ref": "#/$defs/gateEntry" },
78 "backlog-handoff": { "$ref": "#/$defs/gateEntry" }
79 },
80 "additionalProperties": false
81 },
82 "planRiskAssessment": {
83 "$ref": "#/$defs/planRiskAssessment"
84 },
85 "disclaimerShownAt": {
86 "type": ["string", "null"],
87 "format": "date-time",
88 "description": "ISO 8601 timestamp when planner disclaimer was displayed"
89 },
90 "noticeLog": {
91 "type": "array",
92 "items": { "$ref": "#/$defs/noticeLogEntry" },
93 "description": "Timestamped audit log of user-facing disclaimers, framework attributions, and professional-review reminders"
94 },
95 "raiPlanRef": {
96 "type": ["string", "null"],
97 "description": "URI of related RAI plan when AI-generated UI surfaces are present"
98 },
99 "securityPlanRef": {
100 "type": ["string", "null"],
101 "description": "URI of related security plan when paired"
102 },
103 "ssscPlanRef": {
104 "type": ["string", "null"],
105 "description": "URI of related SSSC plan when paired"
106 }
107 },
108 "additionalProperties": false,
109 "$defs": {
110 "noticeLogEntry": {
111 "type": "object",
112 "required": ["noticeType", "shownAt", "source"],
113 "properties": {
114 "noticeType": {
115 "type": "string",
116 "enum": [
117 "session-start-disclaimer",
118 "framework-attribution",
119 "exit-reminder",
120 "handoff-disclaimer",
121 "professional-review-reminder"
122 ],
123 "description": "Category of notice shown to the user"
124 },
125 "shownAt": {
126 "type": "string",
127 "format": "date-time",
128 "description": "ISO 8601 timestamp when the notice was shown"
129 },
130 "source": {
131 "type": "string",
132 "minLength": 1,
133 "description": "Instruction file or canonical text source for the notice"
134 },
135 "details": {
136 "type": "object",
137 "additionalProperties": true,
138 "description": "Planner-specific metadata such as phase, framework id, or output artifact path"
139 }
140 },
141 "additionalProperties": false
142 },
143 "phaseName": {
144 "type": "string",
145 "enum": [
146 "discovery",
147 "framework-selection",
148 "standards-mapping",
149 "plan-risk-assessment",
150 "impact-evidence",
151 "backlog-handoff"
152 ]
153 },
154 "surface": {
155 "type": "string",
156 "enum": ["web", "mobile", "desktop", "document", "voice"]
157 },
158 "regulatoryScope": {
159 "type": "string",
160 "enum": ["us-section-508", "eu-eaa", "uk-eqa", "ca-aoda", "other"]
161 },
162 "project": {
163 "type": "object",
164 "required": ["slug", "name", "entryMode"],
165 "properties": {
166 "slug": {
167 "type": "string",
168 "minLength": 1,
169 "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
170 "description": "Kebab-case project identifier used as the directory name"
171 },
172 "name": {
173 "type": "string",
174 "minLength": 1,
175 "description": "Human-readable project name"
176 },
177 "repo": {
178 "type": ["string", "null"],
179 "description": "Repository identifier (owner/name or remote URI)"
180 },
181 "entryMode": {
182 "type": "string",
183 "enum": ["capture", "from-prd", "from-brd", "from-security-plan", "from-rai-plan"],
184 "description": "How the assessment was initiated"
185 },
186 "surfaces": {
187 "type": "array",
188 "items": { "$ref": "#/$defs/surface" },
189 "description": "Delivery surfaces in scope"
190 },
191 "audiences": {
192 "type": "array",
193 "items": { "type": "string" },
194 "description": "Audience or persona identifiers in scope"
195 },
196 "regulatoryScope": {
197 "type": "array",
198 "items": { "$ref": "#/$defs/regulatoryScope" },
199 "description": "Applicable regulatory regimes"
200 },
201 "aiGeneratedSurfaces": {
202 "type": "boolean",
203 "default": false,
204 "description": "Whether the project includes AI-generated UI, alt text, or captions"
205 }
206 },
207 "additionalProperties": false
208 },
209 "frameworkSelectionEntry": {
210 "type": "object",
211 "required": ["enabled"],
212 "properties": {
213 "enabled": {
214 "type": "boolean",
215 "description": "Whether the framework is active in this assessment"
216 },
217 "skillPath": {
218 "type": "string",
219 "description": "Relative path to SKILL.md under .github/skills/accessibility/<id>/"
220 },
221 "level": {
222 "type": ["string", "null"],
223 "enum": [null, "A", "AA", "AAA"],
224 "description": "Conformance level (applies to wcag-22 and similar W3C frameworks; null otherwise)"
225 },
226 "version": {
227 "type": ["string", "null"],
228 "description": "Framework version pinned for this assessment"
229 },
230 "disabled": {
231 "type": "boolean",
232 "default": false,
233 "description": "Whether the framework has been explicitly excluded"
234 },
235 "disabledReason": {
236 "type": ["string", "null"],
237 "description": "Required when disabled=true: rationale for exclusion"
238 },
239 "disabledAtPhase": {
240 "anyOf": [
241 { "$ref": "#/$defs/phaseName" },
242 { "type": "null" }
243 ],
244 "description": "Required when disabled=true: phase in which the framework was excluded"
245 }
246 },
247 "additionalProperties": false,
248 "allOf": [
249 {
250 "if": {
251 "type": "object",
252 "properties": { "disabled": { "const": true } },
253 "required": ["disabled"]
254 },
255 "then": {
256 "required": ["disabledReason", "disabledAtPhase"],
257 "properties": {
258 "disabledReason": { "type": "string", "minLength": 1 },
259 "disabledAtPhase": { "$ref": "#/$defs/phaseName" }
260 }
261 }
262 }
263 ]
264 },
265 "controlMapping": {
266 "type": "object",
267 "required": ["frameworkId", "controlId", "surfaces", "status"],
268 "properties": {
269 "frameworkId": {
270 "type": "string",
271 "description": "Framework id matching a key in frameworkSelections"
272 },
273 "controlId": {
274 "type": "string",
275 "description": "Stable control identifier within the framework (e.g., SC 1.1.1, 508 E207.2)"
276 },
277 "surfaces": {
278 "type": "array",
279 "items": { "$ref": "#/$defs/surface" },
280 "description": "Surfaces this control applies to in the current scope"
281 },
282 "status": {
283 "type": "string",
284 "enum": ["pending", "covered", "partial", "gap", "not-applicable"],
285 "description": "Coverage status for the control"
286 },
287 "evidence": {
288 "type": "array",
289 "items": { "type": "string" },
290 "description": "Stable evidence ids from evidenceRegister supporting this mapping"
291 },
292 "notes": {
293 "type": ["string", "null"],
294 "description": "Free-form analyst notes"
295 }
296 },
297 "additionalProperties": false
298 },
299 "riskClassification": {
300 "type": "object",
301 "required": ["screeningSignals"],
302 "properties": {
303 "tier": {
304 "type": "string",
305 "enum": ["basic", "standard", "comprehensive"],
306 "description": "Assessment depth tier"
307 },
308 "screeningSignals": {
309 "type": "array",
310 "items": { "type": "string" },
311 "description": "Signals captured during discovery that informed tier selection"
312 },
313 "escalations": {
314 "type": "array",
315 "items": { "$ref": "#/$defs/escalation" },
316 "description": "Phase or control escalations triggered by classification"
317 }
318 },
319 "additionalProperties": false
320 },
321 "escalation": {
322 "type": "object",
323 "required": ["target", "reason"],
324 "properties": {
325 "target": {
326 "type": "string",
327 "description": "Planner or control surface being escalated to (e.g., rai-planner, coga-blocking-controls)"
328 },
329 "reason": {
330 "type": "string",
331 "description": "Why the escalation was raised"
332 },
333 "raisedAtPhase": {
334 "$ref": "#/$defs/phaseName"
335 }
336 },
337 "additionalProperties": false
338 },
339 "evidenceEntry": {
340 "type": "object",
341 "required": ["id", "type", "sourceUri", "status"],
342 "properties": {
343 "id": {
344 "type": "string",
345 "minLength": 1,
346 "description": "Stable evidence id referenced from controlMappings.evidence and cross-planner reports"
347 },
348 "type": {
349 "type": "string",
350 "enum": [
351 "control-implementation",
352 "audit-result",
353 "test-result",
354 "attestation",
355 "screenshot",
356 "document",
357 "external"
358 ],
359 "description": "Evidence record category"
360 },
361 "frameworkId": {
362 "type": ["string", "null"],
363 "description": "Owning framework id when evidence is framework-specific"
364 },
365 "controlId": {
366 "type": ["string", "null"],
367 "description": "Owning control id when evidence is control-specific"
368 },
369 "sourceUri": {
370 "type": "string",
371 "description": "Stable URI for the evidence (file path, URL, or system identifier)"
372 },
373 "collectedAt": {
374 "type": ["string", "null"],
375 "format": "date-time",
376 "description": "ISO 8601 timestamp when evidence was collected"
377 },
378 "status": {
379 "type": "string",
380 "enum": ["pending", "verified", "expired", "superseded"],
381 "description": "Verification lifecycle status"
382 },
383 "notes": {
384 "type": ["string", "null"],
385 "description": "Free-form analyst notes"
386 }
387 },
388 "additionalProperties": false
389 },
390 "gateEntry": {
391 "type": "object",
392 "required": ["confirmed"],
393 "properties": {
394 "confirmed": {
395 "type": "boolean",
396 "description": "Whether the gate has been confirmed for the phase"
397 },
398 "confirmedAt": {
399 "type": ["string", "null"],
400 "format": "date-time",
401 "description": "ISO 8601 timestamp when the gate was confirmed"
402 },
403 "confirmedBy": {
404 "type": ["string", "null"],
405 "description": "Identifier of the user or agent that confirmed the gate"
406 },
407 "notes": {
408 "type": ["string", "null"],
409 "description": "Free-form gate notes"
410 }
411 },
412 "additionalProperties": false,
413 "allOf": [
414 {
415 "if": {
416 "type": "object",
417 "properties": { "confirmed": { "const": true } },
418 "required": ["confirmed"]
419 },
420 "then": {
421 "required": ["confirmedAt", "confirmedBy"],
422 "properties": {
423 "confirmedAt": { "type": "string", "format": "date-time" },
424 "confirmedBy": { "type": "string", "minLength": 1 }
425 }
426 }
427 }
428 ]
429 },
430 "planRiskAssessment": {
431 "type": "object",
432 "required": ["tradeoffs", "watchlist", "deferredMitigations"],
433 "properties": {
434 "tradeoffs": {
435 "type": "array",
436 "items": { "$ref": "#/$defs/tradeoffEntry" },
437 "description": "Recorded tradeoffs between accessibility and competing concerns"
438 },
439 "watchlist": {
440 "type": "array",
441 "items": { "$ref": "#/$defs/watchlistEntry" },
442 "description": "Items requiring ongoing monitoring after handoff"
443 },
444 "deferredMitigations": {
445 "type": "array",
446 "items": { "$ref": "#/$defs/deferredMitigationEntry" },
447 "description": "Mitigations explicitly deferred with rationale and revisit plan"
448 }
449 },
450 "additionalProperties": false
451 },
452 "tradeoffEntry": {
453 "type": "object",
454 "required": ["id", "description", "decision"],
455 "properties": {
456 "id": { "type": "string", "minLength": 1 },
457 "description": { "type": "string", "minLength": 1 },
458 "dimensions": {
459 "type": "array",
460 "items": { "type": "string" },
461 "description": "Dimensions in tension (e.g., performance, security, privacy)"
462 },
463 "decision": {
464 "type": "string",
465 "enum": ["accept", "mitigate", "transfer", "reject"]
466 },
467 "rationale": { "type": ["string", "null"] }
468 },
469 "additionalProperties": false
470 },
471 "watchlistEntry": {
472 "type": "object",
473 "required": ["id", "description", "trigger"],
474 "properties": {
475 "id": { "type": "string", "minLength": 1 },
476 "description": { "type": "string", "minLength": 1 },
477 "trigger": {
478 "type": "string",
479 "description": "Condition that reopens this item"
480 },
481 "owner": { "type": ["string", "null"] }
482 },
483 "additionalProperties": false
484 },
485 "deferredMitigationEntry": {
486 "type": "object",
487 "required": ["id", "description", "deferredReason"],
488 "properties": {
489 "id": { "type": "string", "minLength": 1 },
490 "description": { "type": "string", "minLength": 1 },
491 "deferredReason": { "type": "string", "minLength": 1 },
492 "revisitPhase": {
493 "anyOf": [
494 { "$ref": "#/$defs/phaseName" },
495 { "type": "null" }
496 ]
497 },
498 "controlId": { "type": ["string", "null"] }
499 },
500 "additionalProperties": false
501 }
502 }
503}
504