@coordiation/agent 0.1.0 → 1.0.0-rc.1
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/README.md +200 -0
- package/approvals.schema.json +40 -0
- package/artifact.schema.json +28 -0
- package/capability-template.schema.json +49 -0
- package/development-contract.schema.json +72 -0
- package/evidence.schema.json +36 -0
- package/interview.schema.json +45 -0
- package/lifecycle-adapter.schema.json +18 -0
- package/lifecycle.schema.json +46 -0
- package/package.json +35 -3
- package/product-project.schema.json +31 -0
- package/production-record.schema.json +127 -0
- package/prototype-contract.schema.json +115 -0
- package/qa-report.schema.json +87 -0
- package/release-record.schema.json +141 -0
- package/schema-registry.json +29 -0
- package/src/hardening.js +69 -0
- package/src/index.js +46 -1
- package/src/lifecycle.js +1751 -0
- package/traceability.schema.json +42 -0
- package/ux-contract.schema.json +84 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://coordiation.com/schemas/production-record.schema.json",
|
|
4
|
+
"title": "Coordiation Production record",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["schemaVersion", "id", "kind", "stage", "status", "derivedFrom", "acceptanceCriteria", "evidence", "body"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schemaVersion": { "const": "1.0" },
|
|
9
|
+
"id": { "type": "string", "pattern": "^DEPLOY-[0-9]{3}$" },
|
|
10
|
+
"kind": { "const": "production-record" },
|
|
11
|
+
"stage": { "const": "production" },
|
|
12
|
+
"status": { "enum": ["draft", "approved", "superseded"] },
|
|
13
|
+
"derivedFrom": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^RELEASE-[0-9]{3}$" }, "uniqueItems": true },
|
|
14
|
+
"acceptanceCriteria": { "type": "array", "minItems": 4, "items": { "type": "string", "pattern": "^AC-[0-9]{3}$" }, "uniqueItems": true },
|
|
15
|
+
"evidence": { "type": "array", "items": { "type": "string", "pattern": "^EVIDENCE-[0-9]{3}$" }, "uniqueItems": true },
|
|
16
|
+
"body": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": ["capability", "deployment", "authority", "configuration", "rollout", "healthChecks", "healthStatus", "monitoring", "monitoringStatus", "rollback", "requiredEvidence", "incidents", "feedback", "productionBlockers", "openDecisions"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"capability": { "type": "string", "minLength": 1 },
|
|
21
|
+
"deployment": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"required": ["id", "environment", "releaseId", "version", "candidateId", "sourceRevision", "status", "completedAt"],
|
|
24
|
+
"properties": {
|
|
25
|
+
"id": { "type": "string", "minLength": 1 },
|
|
26
|
+
"environment": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
|
27
|
+
"releaseId": { "type": "string", "pattern": "^RELEASE-[0-9]{3}$" },
|
|
28
|
+
"version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z.-]+)?$" },
|
|
29
|
+
"candidateId": { "type": "string", "minLength": 1 },
|
|
30
|
+
"sourceRevision": { "type": "string", "minLength": 7, "maxLength": 128 },
|
|
31
|
+
"status": { "enum": ["planned", "deployed", "failed"] },
|
|
32
|
+
"completedAt": { "type": ["string", "null"], "format": "date-time" }
|
|
33
|
+
},
|
|
34
|
+
"additionalProperties": false
|
|
35
|
+
},
|
|
36
|
+
"authority": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"required": ["releaseApprovalRequired", "releaseId", "rule"],
|
|
39
|
+
"properties": {
|
|
40
|
+
"releaseApprovalRequired": { "const": true },
|
|
41
|
+
"releaseId": { "type": "string", "pattern": "^RELEASE-[0-9]{3}$" },
|
|
42
|
+
"rule": { "type": "string", "minLength": 1 }
|
|
43
|
+
},
|
|
44
|
+
"additionalProperties": false
|
|
45
|
+
},
|
|
46
|
+
"configuration": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"required": ["requiredVariableNames", "secretValuesStored", "validation"],
|
|
49
|
+
"properties": {
|
|
50
|
+
"requiredVariableNames": { "type": "array", "items": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$" }, "uniqueItems": true },
|
|
51
|
+
"secretValuesStored": { "const": false },
|
|
52
|
+
"validation": { "type": "string", "minLength": 1 }
|
|
53
|
+
},
|
|
54
|
+
"additionalProperties": false
|
|
55
|
+
},
|
|
56
|
+
"rollout": {
|
|
57
|
+
"type": "object",
|
|
58
|
+
"required": ["strategy", "batches", "currentBatch", "pauseConditions"],
|
|
59
|
+
"properties": {
|
|
60
|
+
"strategy": { "type": "string", "minLength": 1 },
|
|
61
|
+
"batches": { "type": "array", "minItems": 2 },
|
|
62
|
+
"currentBatch": { "type": "string", "minLength": 1 },
|
|
63
|
+
"pauseConditions": { "type": "array", "minItems": 2, "items": { "type": "string" } }
|
|
64
|
+
},
|
|
65
|
+
"additionalProperties": false
|
|
66
|
+
},
|
|
67
|
+
"healthChecks": {
|
|
68
|
+
"type": "array",
|
|
69
|
+
"minItems": 3,
|
|
70
|
+
"items": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"required": ["id", "signal", "successCondition"],
|
|
73
|
+
"properties": {
|
|
74
|
+
"id": { "type": "string", "pattern": "^RELEASE-[0-9]{3}-HEALTH-[0-9]{3}$" },
|
|
75
|
+
"signal": { "type": "string", "minLength": 1 },
|
|
76
|
+
"successCondition": { "type": "string", "minLength": 1 }
|
|
77
|
+
},
|
|
78
|
+
"additionalProperties": false
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"healthStatus": { "enum": ["pending", "healthy", "unhealthy"] },
|
|
82
|
+
"monitoring": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"required": ["signals", "alerts", "observationWindow"],
|
|
85
|
+
"properties": {
|
|
86
|
+
"signals": { "type": "array", "minItems": 4, "items": { "type": "string" }, "uniqueItems": true },
|
|
87
|
+
"alerts": {
|
|
88
|
+
"type": "array",
|
|
89
|
+
"minItems": 2,
|
|
90
|
+
"items": {
|
|
91
|
+
"type": "object",
|
|
92
|
+
"required": ["signal", "condition", "owner"],
|
|
93
|
+
"properties": {
|
|
94
|
+
"signal": { "type": "string", "minLength": 1 },
|
|
95
|
+
"condition": { "type": "string", "minLength": 1 },
|
|
96
|
+
"owner": { "type": "string", "minLength": 1 }
|
|
97
|
+
},
|
|
98
|
+
"additionalProperties": false
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"observationWindow": { "type": "string", "minLength": 1 }
|
|
102
|
+
},
|
|
103
|
+
"additionalProperties": false
|
|
104
|
+
},
|
|
105
|
+
"monitoringStatus": { "enum": ["pending", "active", "degraded"] },
|
|
106
|
+
"rollback": {
|
|
107
|
+
"type": "object",
|
|
108
|
+
"required": ["candidate", "triggers", "steps", "owner", "readiness"],
|
|
109
|
+
"properties": {
|
|
110
|
+
"candidate": { "type": "string", "minLength": 1 },
|
|
111
|
+
"triggers": { "type": "array", "minItems": 2, "items": { "type": "string" } },
|
|
112
|
+
"steps": { "type": "array", "minItems": 3, "items": { "type": "string" } },
|
|
113
|
+
"owner": { "type": "string", "minLength": 1 },
|
|
114
|
+
"readiness": { "enum": ["pending", "ready", "not-ready"] }
|
|
115
|
+
},
|
|
116
|
+
"additionalProperties": false
|
|
117
|
+
},
|
|
118
|
+
"requiredEvidence": { "type": "array", "const": ["deployment", "health", "monitoring", "rollback-readiness"] },
|
|
119
|
+
"incidents": { "type": "array" },
|
|
120
|
+
"feedback": { "type": "array" },
|
|
121
|
+
"productionBlockers": { "type": "array" },
|
|
122
|
+
"openDecisions": { "type": "array" }
|
|
123
|
+
},
|
|
124
|
+
"additionalProperties": false
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://coordiation.com/schemas/prototype-contract.schema.json",
|
|
4
|
+
"title": "Coordiation interactive prototype contract",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["schemaVersion", "id", "kind", "stage", "status", "revision", "derivedFrom", "acceptanceCriteria", "body"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schemaVersion": { "const": "1.0" },
|
|
9
|
+
"id": { "type": "string", "pattern": "^PROTO-[0-9]{3}$" },
|
|
10
|
+
"kind": { "const": "prototype-contract" },
|
|
11
|
+
"stage": { "const": "prototype" },
|
|
12
|
+
"status": { "enum": ["draft", "approved", "superseded"] },
|
|
13
|
+
"revision": { "type": "integer", "minimum": 1 },
|
|
14
|
+
"derivedFrom": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^UX-[0-9]{3}$" } },
|
|
15
|
+
"acceptanceCriteria": { "type": "array", "minItems": 4, "items": { "type": "string", "pattern": "^AC-[0-9]{3}$" }, "uniqueItems": true },
|
|
16
|
+
"body": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": ["capability", "fidelity", "frameworkContract", "componentPlan", "layoutContract", "statePreviews", "interactionMap", "viewportMatrix", "motionContract", "mockAdapter", "evidenceRequirements", "openDecisions"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"capability": { "type": "string", "minLength": 1 },
|
|
21
|
+
"fidelity": { "type": "string", "minLength": 1 },
|
|
22
|
+
"frameworkContract": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"required": ["css", "components", "icons", "runtime"],
|
|
25
|
+
"properties": {
|
|
26
|
+
"css": { "type": "string", "pattern": "@coordiation/css" },
|
|
27
|
+
"components": { "type": "string", "pattern": "@coordiation/ui" },
|
|
28
|
+
"icons": { "type": "string", "pattern": "@coordiation/icons" },
|
|
29
|
+
"runtime": { "type": "string" }
|
|
30
|
+
},
|
|
31
|
+
"additionalProperties": false
|
|
32
|
+
},
|
|
33
|
+
"componentPlan": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"minItems": 5,
|
|
36
|
+
"items": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"required": ["registryId", "role"],
|
|
39
|
+
"properties": {
|
|
40
|
+
"registryId": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
|
|
41
|
+
"role": { "type": "string", "minLength": 1 }
|
|
42
|
+
},
|
|
43
|
+
"additionalProperties": false
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"layoutContract": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"required": ["shell", "content", "rules"],
|
|
49
|
+
"properties": {
|
|
50
|
+
"shell": { "$ref": "#/$defs/classes" },
|
|
51
|
+
"content": { "$ref": "#/$defs/classes" },
|
|
52
|
+
"rules": { "type": "array", "minItems": 1, "items": { "type": "string" } }
|
|
53
|
+
},
|
|
54
|
+
"additionalProperties": false
|
|
55
|
+
},
|
|
56
|
+
"statePreviews": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"minItems": 5,
|
|
59
|
+
"items": {
|
|
60
|
+
"type": "object",
|
|
61
|
+
"required": ["id", "fixture", "purpose", "visibleContent", "availableActions", "componentIds"],
|
|
62
|
+
"properties": {
|
|
63
|
+
"id": { "type": "string" },
|
|
64
|
+
"fixture": { "type": "string" },
|
|
65
|
+
"purpose": { "type": "string" },
|
|
66
|
+
"visibleContent": { "type": "array", "items": { "type": "string" } },
|
|
67
|
+
"availableActions": { "type": "array", "items": { "type": "string" } },
|
|
68
|
+
"componentIds": { "type": "array", "minItems": 5, "items": { "type": "string" } }
|
|
69
|
+
},
|
|
70
|
+
"additionalProperties": false
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"interactionMap": { "type": "array", "minItems": 4 },
|
|
74
|
+
"viewportMatrix": {
|
|
75
|
+
"type": "array",
|
|
76
|
+
"minItems": 3,
|
|
77
|
+
"items": {
|
|
78
|
+
"type": "object",
|
|
79
|
+
"required": ["width", "label", "requirement"],
|
|
80
|
+
"properties": {
|
|
81
|
+
"width": { "enum": [320, 768, 1280] },
|
|
82
|
+
"label": { "type": "string" },
|
|
83
|
+
"requirement": { "type": "string" }
|
|
84
|
+
},
|
|
85
|
+
"additionalProperties": false
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"motionContract": {
|
|
89
|
+
"type": "object",
|
|
90
|
+
"required": ["classes", "rules"],
|
|
91
|
+
"properties": {
|
|
92
|
+
"classes": { "$ref": "#/$defs/classes" },
|
|
93
|
+
"rules": { "type": "array", "minItems": 1, "items": { "type": "string" } }
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"mockAdapter": { "type": "object", "required": ["policy", "fixtures", "reset"] },
|
|
97
|
+
"evidenceRequirements": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"required": ["screenshots", "keyboardPath", "accessibility", "acceptanceCriteria"],
|
|
100
|
+
"properties": {
|
|
101
|
+
"screenshots": { "type": "array", "minItems": 15 },
|
|
102
|
+
"keyboardPath": { "type": "string", "minLength": 1 },
|
|
103
|
+
"accessibility": { "type": "string", "minLength": 1 },
|
|
104
|
+
"acceptanceCriteria": { "type": "array", "minItems": 4 }
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"openDecisions": { "type": "array" }
|
|
108
|
+
},
|
|
109
|
+
"additionalProperties": false
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"$defs": {
|
|
113
|
+
"classes": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "(^|:)co-" } }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://coordiation.com/schemas/qa-report.schema.json",
|
|
4
|
+
"title": "Coordiation QA report",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["schemaVersion", "id", "kind", "stage", "status", "derivedFrom", "acceptanceCriteria", "evidence", "body"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schemaVersion": { "const": "1.0" },
|
|
9
|
+
"id": { "type": "string", "pattern": "^QA-[0-9]{3}$" },
|
|
10
|
+
"kind": { "const": "qa-report" },
|
|
11
|
+
"stage": { "const": "qa" },
|
|
12
|
+
"status": { "enum": ["draft", "approved", "superseded"] },
|
|
13
|
+
"derivedFrom": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^DEV-[0-9]{3}$" }, "uniqueItems": true },
|
|
14
|
+
"acceptanceCriteria": { "type": "array", "minItems": 4, "items": { "type": "string", "pattern": "^AC-[0-9]{3}$" }, "uniqueItems": true },
|
|
15
|
+
"evidence": { "type": "array", "items": { "type": "string", "pattern": "^EVIDENCE-[0-9]{3}$" }, "uniqueItems": true },
|
|
16
|
+
"body": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": ["capability", "strategy", "testCases", "stateCoverage", "viewportCoverage", "accessibilityChecklist", "securityChecklist", "regressionScope", "requiredEvidence", "releaseBlockers", "openDecisions"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"capability": { "type": "string", "minLength": 1 },
|
|
21
|
+
"strategy": { "type": "string", "minLength": 1 },
|
|
22
|
+
"testCases": {
|
|
23
|
+
"type": "array",
|
|
24
|
+
"minItems": 4,
|
|
25
|
+
"items": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"required": ["id", "criterionId", "statement", "preconditions", "steps", "expected", "evidenceTypes"],
|
|
28
|
+
"properties": {
|
|
29
|
+
"id": { "type": "string", "pattern": "^QA-[0-9]{3}-CASE-[0-9]{3}$" },
|
|
30
|
+
"criterionId": { "type": "string", "pattern": "^AC-[0-9]{3}$" },
|
|
31
|
+
"statement": { "type": "string", "minLength": 1 },
|
|
32
|
+
"preconditions": { "type": "array", "minItems": 1, "items": { "type": "string" } },
|
|
33
|
+
"steps": { "type": "array", "minItems": 1, "items": { "type": "string" } },
|
|
34
|
+
"expected": { "type": "string", "minLength": 1 },
|
|
35
|
+
"evidenceTypes": { "type": "array", "minItems": 1, "items": { "enum": ["functional", "visual", "accessibility", "security", "regression"] }, "uniqueItems": true }
|
|
36
|
+
},
|
|
37
|
+
"additionalProperties": false
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"stateCoverage": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"minItems": 5,
|
|
43
|
+
"items": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"required": ["stateId", "fixture", "checks"],
|
|
46
|
+
"properties": {
|
|
47
|
+
"stateId": { "type": "string", "minLength": 1 },
|
|
48
|
+
"fixture": { "type": "string", "minLength": 1 },
|
|
49
|
+
"checks": { "type": "array", "minItems": 3, "items": { "type": "string" } }
|
|
50
|
+
},
|
|
51
|
+
"additionalProperties": false
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"viewportCoverage": {
|
|
55
|
+
"type": "array",
|
|
56
|
+
"minItems": 3,
|
|
57
|
+
"items": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"required": ["width", "label", "requirement"],
|
|
60
|
+
"properties": {
|
|
61
|
+
"width": { "enum": [320, 768, 1280] },
|
|
62
|
+
"label": { "type": "string", "minLength": 1 },
|
|
63
|
+
"requirement": { "type": "string", "minLength": 1 }
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"accessibilityChecklist": { "type": "array", "minItems": 7, "items": { "type": "string" } },
|
|
68
|
+
"securityChecklist": { "type": "array", "minItems": 5, "items": { "type": "string" } },
|
|
69
|
+
"regressionScope": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"required": ["components", "utilities", "upstreamArtifacts", "requirement"],
|
|
72
|
+
"properties": {
|
|
73
|
+
"components": { "type": "array", "items": { "type": "string" } },
|
|
74
|
+
"utilities": { "type": "array", "items": { "type": "string" } },
|
|
75
|
+
"upstreamArtifacts": { "type": "array", "items": { "type": "string" } },
|
|
76
|
+
"requirement": { "type": "string", "minLength": 1 }
|
|
77
|
+
},
|
|
78
|
+
"additionalProperties": false
|
|
79
|
+
},
|
|
80
|
+
"requiredEvidence": { "type": "array", "const": ["functional", "visual", "accessibility", "security", "regression"] },
|
|
81
|
+
"releaseBlockers": { "type": "array" },
|
|
82
|
+
"openDecisions": { "type": "array" }
|
|
83
|
+
},
|
|
84
|
+
"additionalProperties": false
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://coordiation.com/schemas/release-record.schema.json",
|
|
4
|
+
"title": "Coordiation release record",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["schemaVersion", "id", "kind", "stage", "status", "derivedFrom", "acceptanceCriteria", "evidence", "body"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schemaVersion": { "const": "1.0" },
|
|
9
|
+
"id": { "type": "string", "pattern": "^RELEASE-[0-9]{3}$" },
|
|
10
|
+
"kind": { "const": "release-record" },
|
|
11
|
+
"stage": { "const": "release" },
|
|
12
|
+
"status": { "enum": ["draft", "approved", "superseded"] },
|
|
13
|
+
"derivedFrom": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^QA-[0-9]{3}$" }, "uniqueItems": true },
|
|
14
|
+
"acceptanceCriteria": { "type": "array", "minItems": 4, "items": { "type": "string", "pattern": "^AC-[0-9]{3}$" }, "uniqueItems": true },
|
|
15
|
+
"evidence": { "type": "array", "items": { "type": "string", "pattern": "^EVIDENCE-[0-9]{3}$" }, "uniqueItems": true },
|
|
16
|
+
"body": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": ["capability", "version", "candidate", "changelog", "compatibility", "migration", "environment", "rollout", "healthChecks", "rollback", "requiredEvidence", "releaseBlockers", "openDecisions"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"capability": { "type": "string", "minLength": 1 },
|
|
21
|
+
"version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z.-]+)?$" },
|
|
22
|
+
"candidate": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"required": ["id", "snapshotSha256", "sourceQa", "acceptanceCriteria"],
|
|
25
|
+
"properties": {
|
|
26
|
+
"id": { "type": "string", "minLength": 1 },
|
|
27
|
+
"snapshotSha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
28
|
+
"sourceQa": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": ["id", "revision"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"id": { "type": "string", "pattern": "^QA-[0-9]{3}$" },
|
|
33
|
+
"revision": { "type": "integer", "minimum": 1 }
|
|
34
|
+
},
|
|
35
|
+
"additionalProperties": false
|
|
36
|
+
},
|
|
37
|
+
"acceptanceCriteria": { "type": "array", "minItems": 4, "items": { "type": "string", "pattern": "^AC-[0-9]{3}$" }, "uniqueItems": true }
|
|
38
|
+
},
|
|
39
|
+
"additionalProperties": false
|
|
40
|
+
},
|
|
41
|
+
"changelog": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"minItems": 1,
|
|
44
|
+
"items": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"required": ["type", "summary", "requirementIds"],
|
|
47
|
+
"properties": {
|
|
48
|
+
"type": { "enum": ["feature", "fix", "change", "deprecation", "security"] },
|
|
49
|
+
"summary": { "type": "string", "minLength": 1 },
|
|
50
|
+
"requirementIds": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^AC-[0-9]{3}$" }, "uniqueItems": true }
|
|
51
|
+
},
|
|
52
|
+
"additionalProperties": false
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"compatibility": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"required": ["framework", "coordiation", "breakingChanges", "support"],
|
|
58
|
+
"properties": {
|
|
59
|
+
"framework": { "type": "string", "minLength": 1 },
|
|
60
|
+
"coordiation": { "type": "array", "minItems": 1, "items": { "type": "string" }, "uniqueItems": true },
|
|
61
|
+
"breakingChanges": { "type": "array" },
|
|
62
|
+
"support": { "type": "string", "minLength": 1 }
|
|
63
|
+
},
|
|
64
|
+
"additionalProperties": false
|
|
65
|
+
},
|
|
66
|
+
"migration": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"required": ["required", "steps", "reversibility"],
|
|
69
|
+
"properties": {
|
|
70
|
+
"required": { "type": "boolean" },
|
|
71
|
+
"steps": { "type": "array", "minItems": 1, "items": { "type": "string" } },
|
|
72
|
+
"reversibility": { "type": "string", "minLength": 1 }
|
|
73
|
+
},
|
|
74
|
+
"additionalProperties": false
|
|
75
|
+
},
|
|
76
|
+
"environment": {
|
|
77
|
+
"type": "object",
|
|
78
|
+
"required": ["variableNames", "secretValuesStored", "validation"],
|
|
79
|
+
"properties": {
|
|
80
|
+
"variableNames": { "type": "array", "items": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$" }, "uniqueItems": true },
|
|
81
|
+
"secretValuesStored": { "const": false },
|
|
82
|
+
"validation": { "type": "string", "minLength": 1 }
|
|
83
|
+
},
|
|
84
|
+
"additionalProperties": false
|
|
85
|
+
},
|
|
86
|
+
"rollout": {
|
|
87
|
+
"type": "object",
|
|
88
|
+
"required": ["strategy", "batches", "pauseConditions"],
|
|
89
|
+
"properties": {
|
|
90
|
+
"strategy": { "type": "string", "minLength": 1 },
|
|
91
|
+
"batches": {
|
|
92
|
+
"type": "array",
|
|
93
|
+
"minItems": 2,
|
|
94
|
+
"items": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"required": ["name", "audience", "percentage"],
|
|
97
|
+
"properties": {
|
|
98
|
+
"name": { "type": "string", "minLength": 1 },
|
|
99
|
+
"audience": { "type": "string", "minLength": 1 },
|
|
100
|
+
"percentage": { "type": "number", "minimum": 0, "maximum": 100 }
|
|
101
|
+
},
|
|
102
|
+
"additionalProperties": false
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"pauseConditions": { "type": "array", "minItems": 2, "items": { "type": "string" } }
|
|
106
|
+
},
|
|
107
|
+
"additionalProperties": false
|
|
108
|
+
},
|
|
109
|
+
"healthChecks": {
|
|
110
|
+
"type": "array",
|
|
111
|
+
"minItems": 3,
|
|
112
|
+
"items": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"required": ["id", "signal", "successCondition"],
|
|
115
|
+
"properties": {
|
|
116
|
+
"id": { "type": "string", "pattern": "^RELEASE-[0-9]{3}-HEALTH-[0-9]{3}$" },
|
|
117
|
+
"signal": { "type": "string", "minLength": 1 },
|
|
118
|
+
"successCondition": { "type": "string", "minLength": 1 }
|
|
119
|
+
},
|
|
120
|
+
"additionalProperties": false
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"rollback": {
|
|
124
|
+
"type": "object",
|
|
125
|
+
"required": ["triggers", "steps", "owner", "maximumDecisionTime"],
|
|
126
|
+
"properties": {
|
|
127
|
+
"triggers": { "type": "array", "minItems": 2, "items": { "type": "string" } },
|
|
128
|
+
"steps": { "type": "array", "minItems": 3, "items": { "type": "string" } },
|
|
129
|
+
"owner": { "type": "string", "minLength": 1 },
|
|
130
|
+
"maximumDecisionTime": { "type": "string", "minLength": 1 }
|
|
131
|
+
},
|
|
132
|
+
"additionalProperties": false
|
|
133
|
+
},
|
|
134
|
+
"requiredEvidence": { "type": "array", "const": ["candidate", "release-notes", "rollback-validation"] },
|
|
135
|
+
"releaseBlockers": { "type": "array" },
|
|
136
|
+
"openDecisions": { "type": "array" }
|
|
137
|
+
},
|
|
138
|
+
"additionalProperties": false
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "1.0",
|
|
3
|
+
"kind": "coordiation-schema-registry",
|
|
4
|
+
"currentLifecycleVersion": "1.0",
|
|
5
|
+
"supportedLifecycleVersions": ["1.0"],
|
|
6
|
+
"policy": {
|
|
7
|
+
"major": "Breaking field, identifier, gate, or semantic changes require an explicit migration.",
|
|
8
|
+
"minor": "Additive optional fields and new artifact capabilities remain backward-compatible.",
|
|
9
|
+
"patch": "Clarifications and validation fixes may not change valid artifact meaning.",
|
|
10
|
+
"unknown": "Unknown versions are rejected instead of being guessed or silently rewritten."
|
|
11
|
+
},
|
|
12
|
+
"schemas": [
|
|
13
|
+
"product-project.schema.json",
|
|
14
|
+
"lifecycle.schema.json",
|
|
15
|
+
"artifact.schema.json",
|
|
16
|
+
"traceability.schema.json",
|
|
17
|
+
"approvals.schema.json",
|
|
18
|
+
"evidence.schema.json",
|
|
19
|
+
"interview.schema.json",
|
|
20
|
+
"capability-template.schema.json",
|
|
21
|
+
"ux-contract.schema.json",
|
|
22
|
+
"prototype-contract.schema.json",
|
|
23
|
+
"development-contract.schema.json",
|
|
24
|
+
"qa-report.schema.json",
|
|
25
|
+
"release-record.schema.json",
|
|
26
|
+
"production-record.schema.json",
|
|
27
|
+
"lifecycle-adapter.schema.json"
|
|
28
|
+
]
|
|
29
|
+
}
|
package/src/hardening.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import schemaRegistry from "../schema-registry.json" with { type: "json" };
|
|
2
|
+
|
|
3
|
+
const ALLOWED_ADAPTER_HOOKS = new Set(["artifact.created", "artifact.revised", "evidence.recorded", "gate.checked", "artifact.approved"]);
|
|
4
|
+
const lifecycleAdapters = new Map();
|
|
5
|
+
|
|
6
|
+
function adapterManifest(value) {
|
|
7
|
+
const manifest = value?.manifest ?? value;
|
|
8
|
+
const id = String(manifest?.id ?? "").trim().toLowerCase();
|
|
9
|
+
const version = String(manifest?.version ?? "").trim();
|
|
10
|
+
const capabilities = [...new Set(manifest?.capabilities ?? [])];
|
|
11
|
+
const hooks = [...new Set(manifest?.hooks ?? [])];
|
|
12
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(id)) throw new Error("Lifecycle adapter id must use lowercase letters, numbers, and hyphens.");
|
|
13
|
+
if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version)) throw new Error("Lifecycle adapter version must use semantic versioning.");
|
|
14
|
+
if (!capabilities.every((entry) => typeof entry === "string" && entry.trim())) throw new Error("Lifecycle adapter capabilities must be non-empty strings.");
|
|
15
|
+
if (!hooks.every((hook) => ALLOWED_ADAPTER_HOOKS.has(hook))) throw new Error(`Lifecycle adapter hooks must be one of: ${[...ALLOWED_ADAPTER_HOOKS].join(", ")}.`);
|
|
16
|
+
return { id, version, capabilities, hooks };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getSchemaCompatibility(version = schemaRegistry.currentLifecycleVersion) {
|
|
20
|
+
const requestedVersion = String(version ?? "").trim();
|
|
21
|
+
const compatible = schemaRegistry.supportedLifecycleVersions.includes(requestedVersion);
|
|
22
|
+
return {
|
|
23
|
+
schemaVersion: schemaRegistry.schemaVersion,
|
|
24
|
+
kind: "coordiation-schema-compatibility",
|
|
25
|
+
requestedVersion,
|
|
26
|
+
currentVersion: schemaRegistry.currentLifecycleVersion,
|
|
27
|
+
supportedVersions: schemaRegistry.supportedLifecycleVersions,
|
|
28
|
+
compatible,
|
|
29
|
+
mode: compatible ? (requestedVersion === schemaRegistry.currentLifecycleVersion ? "current" : "compatible") : "migration-required",
|
|
30
|
+
policy: schemaRegistry.policy,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function assertSchemaCompatibility(version) {
|
|
35
|
+
const result = getSchemaCompatibility(version);
|
|
36
|
+
if (!result.compatible) throw new Error(`Unsupported Coordiation lifecycle schema ${result.requestedVersion || "(missing)"}. Current supported version: ${result.currentVersion}. Run an explicit migration before reading or writing artifacts.`);
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function registerLifecycleAdapter(definition, handlers = definition?.handlers ?? {}, { overwrite = false } = {}) {
|
|
41
|
+
const manifest = adapterManifest(definition);
|
|
42
|
+
if (lifecycleAdapters.has(manifest.id) && !overwrite) throw new Error(`Lifecycle adapter already registered: ${manifest.id}.`);
|
|
43
|
+
for (const hook of manifest.hooks) if (typeof handlers[hook] !== "function") throw new Error(`Lifecycle adapter ${manifest.id} requires a function handler for ${hook}.`);
|
|
44
|
+
lifecycleAdapters.set(manifest.id, { manifest, handlers: Object.fromEntries(manifest.hooks.map((hook) => [hook, handlers[hook]])) });
|
|
45
|
+
return manifest;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function listLifecycleAdapters() {
|
|
49
|
+
return [...lifecycleAdapters.values()].map(({ manifest }) => structuredClone(manifest)).sort((left, right) => left.id.localeCompare(right.id));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function unregisterLifecycleAdapter(id) {
|
|
53
|
+
return lifecycleAdapters.delete(String(id ?? "").trim().toLowerCase());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function dispatchLifecycleAdapterHook(hook, payload, { adapterIds } = {}) {
|
|
57
|
+
if (!ALLOWED_ADAPTER_HOOKS.has(hook)) throw new Error(`Unknown lifecycle adapter hook: ${hook}.`);
|
|
58
|
+
const selected = adapterIds ? new Set(adapterIds.map((id) => String(id).trim().toLowerCase())) : null;
|
|
59
|
+
const results = [];
|
|
60
|
+
for (const { manifest, handlers } of lifecycleAdapters.values()) {
|
|
61
|
+
if (selected && !selected.has(manifest.id)) continue;
|
|
62
|
+
if (!manifest.hooks.includes(hook)) continue;
|
|
63
|
+
const output = await handlers[hook](structuredClone(payload), structuredClone(manifest));
|
|
64
|
+
results.push({ adapterId: manifest.id, hook, output: output ?? null });
|
|
65
|
+
}
|
|
66
|
+
return { schemaVersion: schemaRegistry.schemaVersion, kind: "coordiation-adapter-dispatch", hook, results };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { schemaRegistry };
|
package/src/index.js
CHANGED
|
@@ -177,7 +177,7 @@ export function createContextPack(topic, manifest) {
|
|
|
177
177
|
if (!definition) throw new Error(`Unknown context topic: ${topic}. Available: ${Object.keys(contextPacks).join(", ")}`);
|
|
178
178
|
const currentUtilities = manifest?.coordiation?.frequentUtilities ?? [];
|
|
179
179
|
const relevantUtilities = currentUtilities.filter(({ candidate }) => definition.utilityHints.some((hint) => candidate.includes(hint.replace(/^.*:/, "").replace(/^co-/, "")))).slice(0, 15);
|
|
180
|
-
|
|
180
|
+
const pack = {
|
|
181
181
|
schemaVersion: AGENT_SCHEMA_VERSION,
|
|
182
182
|
kind: "coordiation-context-pack",
|
|
183
183
|
topic: normalized,
|
|
@@ -195,6 +195,13 @@ export function createContextPack(topic, manifest) {
|
|
|
195
195
|
checks: definition.checks,
|
|
196
196
|
workflow: ["inspect project", "reuse registered primitives", "generate literal classes", "validate checks", "run project build"],
|
|
197
197
|
};
|
|
198
|
+
pack.contextBudget = { bytes: 0, estimatedTokens: 0, targetTokens: 1200, withinTarget: true };
|
|
199
|
+
for (let iteration = 0; iteration < 3; iteration += 1) {
|
|
200
|
+
const bytes = Buffer.byteLength(JSON.stringify(pack));
|
|
201
|
+
const estimatedTokens = Math.ceil(bytes / 4);
|
|
202
|
+
pack.contextBudget = { bytes, estimatedTokens, targetTokens: 1200, withinTarget: estimatedTokens <= 1200 };
|
|
203
|
+
}
|
|
204
|
+
return pack;
|
|
198
205
|
}
|
|
199
206
|
|
|
200
207
|
export async function writeAgentManifest(manifest, { cwd = process.cwd(), output = AGENT_MANIFEST_PATH } = {}) {
|
|
@@ -205,3 +212,41 @@ export async function writeAgentManifest(manifest, { cwd = process.cwd(), output
|
|
|
205
212
|
await writeFile(destination, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
206
213
|
return compactPath(root, destination);
|
|
207
214
|
}
|
|
215
|
+
|
|
216
|
+
export {
|
|
217
|
+
LIFECYCLE_GATES,
|
|
218
|
+
LIFECYCLE_SCHEMA_VERSION,
|
|
219
|
+
LIFECYCLE_STAGES,
|
|
220
|
+
approveLifecycleArtifact,
|
|
221
|
+
checkLifecycleGate,
|
|
222
|
+
createDevelopmentContract,
|
|
223
|
+
createProductionRecord,
|
|
224
|
+
createPrototypeContract,
|
|
225
|
+
createQaReport,
|
|
226
|
+
createReleaseRecord,
|
|
227
|
+
createUxContract,
|
|
228
|
+
getLifecycleStatus,
|
|
229
|
+
getTraceability,
|
|
230
|
+
initializeLifecycleProject,
|
|
231
|
+
interviewTemplates,
|
|
232
|
+
listCapabilityTemplates,
|
|
233
|
+
registerCapabilityTemplate,
|
|
234
|
+
recordDevelopmentEvidence,
|
|
235
|
+
recordLifecycleEvidence,
|
|
236
|
+
recordProductionEvidence,
|
|
237
|
+
recordQaEvidence,
|
|
238
|
+
recordReleaseEvidence,
|
|
239
|
+
reviseLifecycleArtifact,
|
|
240
|
+
resolveCapabilityTemplate,
|
|
241
|
+
runRequirementInterview,
|
|
242
|
+
} from "./lifecycle.js";
|
|
243
|
+
|
|
244
|
+
export {
|
|
245
|
+
assertSchemaCompatibility,
|
|
246
|
+
dispatchLifecycleAdapterHook,
|
|
247
|
+
getSchemaCompatibility,
|
|
248
|
+
listLifecycleAdapters,
|
|
249
|
+
registerLifecycleAdapter,
|
|
250
|
+
schemaRegistry,
|
|
251
|
+
unregisterLifecycleAdapter,
|
|
252
|
+
} from "./hardening.js";
|