@forwardimpact/schema 0.6.0 → 0.8.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/examples/capabilities/business.yaml +26 -10
- package/examples/capabilities/delivery.yaml +56 -20
- package/examples/capabilities/reliability.yaml +53 -20
- package/examples/capabilities/scale.yaml +82 -30
- package/examples/framework.yaml +5 -1
- package/examples/stages.yaml +53 -13
- package/package.json +1 -1
- package/schema/json/capability.schema.json +6 -5
- package/schema/json/framework.schema.json +13 -0
- package/schema/json/stages.schema.json +6 -6
- package/schema/rdf/capability.ttl +12 -12
- package/schema/rdf/framework.ttl +38 -0
- package/schema/rdf/stages.ttl +14 -14
- package/src/levels.js +16 -21
- package/src/validation.js +34 -42
package/schema/rdf/stages.ttl
CHANGED
|
@@ -28,14 +28,14 @@ fit:handoffs a rdf:Property ;
|
|
|
28
28
|
rdfs:domain fit:Stage ;
|
|
29
29
|
rdfs:range fit:Handoff .
|
|
30
30
|
|
|
31
|
-
fit:
|
|
32
|
-
rdfs:label "
|
|
33
|
-
rdfs:comment "
|
|
31
|
+
fit:readChecklist a rdf:Property ;
|
|
32
|
+
rdfs:label "readChecklist"@en ;
|
|
33
|
+
rdfs:comment "Read-Then-Do Checklist: steps to follow in order during this stage"@en ;
|
|
34
34
|
rdfs:range xsd:string .
|
|
35
35
|
|
|
36
|
-
fit:
|
|
37
|
-
rdfs:label "
|
|
38
|
-
rdfs:comment "
|
|
36
|
+
fit:confirmChecklist a rdf:Property ;
|
|
37
|
+
rdfs:label "confirmChecklist"@en ;
|
|
38
|
+
rdfs:comment "Do-Then-Confirm Checklist: items to verify before handing off to next stage"@en ;
|
|
39
39
|
rdfs:range xsd:string .
|
|
40
40
|
|
|
41
41
|
fit:summary a rdf:Property ;
|
|
@@ -74,7 +74,7 @@ fit:StageShape a sh:NodeShape ;
|
|
|
74
74
|
sh:targetClass fit:Stage ;
|
|
75
75
|
sh:property [
|
|
76
76
|
sh:path fit:id ;
|
|
77
|
-
sh:in ( "specify" "plan" "code" "review" "deploy" ) ;
|
|
77
|
+
sh:in ( "specify" "plan" "onboard" "code" "review" "deploy" ) ;
|
|
78
78
|
sh:minCount 1 ;
|
|
79
79
|
sh:maxCount 1 ;
|
|
80
80
|
sh:name "id" ;
|
|
@@ -122,16 +122,16 @@ fit:StageShape a sh:NodeShape ;
|
|
|
122
122
|
sh:description "Restrictions on behaviour in this stage" ;
|
|
123
123
|
] ;
|
|
124
124
|
sh:property [
|
|
125
|
-
sh:path fit:
|
|
125
|
+
sh:path fit:readChecklist ;
|
|
126
126
|
sh:datatype xsd:string ;
|
|
127
|
-
sh:name "
|
|
128
|
-
sh:description "
|
|
127
|
+
sh:name "readChecklist" ;
|
|
128
|
+
sh:description "Read-Then-Do Checklist: steps to follow in order during this stage" ;
|
|
129
129
|
] ;
|
|
130
130
|
sh:property [
|
|
131
|
-
sh:path fit:
|
|
131
|
+
sh:path fit:confirmChecklist ;
|
|
132
132
|
sh:datatype xsd:string ;
|
|
133
|
-
sh:name "
|
|
134
|
-
sh:description "
|
|
133
|
+
sh:name "confirmChecklist" ;
|
|
134
|
+
sh:description "Do-Then-Confirm Checklist: items to verify before handing off to next stage" ;
|
|
135
135
|
] .
|
|
136
136
|
|
|
137
137
|
# -----------------------------------------------------------------------------
|
|
@@ -142,7 +142,7 @@ fit:HandoffShape a sh:NodeShape ;
|
|
|
142
142
|
sh:targetClass fit:Handoff ;
|
|
143
143
|
sh:property [
|
|
144
144
|
sh:path fit:targetStage ;
|
|
145
|
-
sh:in ( "specify" "plan" "code" "review" "deploy" ) ;
|
|
145
|
+
sh:in ( "specify" "plan" "onboard" "code" "review" "deploy" ) ;
|
|
146
146
|
sh:minCount 1 ;
|
|
147
147
|
sh:maxCount 1 ;
|
|
148
148
|
sh:name "targetStage" ;
|
package/src/levels.js
CHANGED
|
@@ -54,30 +54,25 @@ export const BEHAVIOUR_MATURITY_ORDER = [
|
|
|
54
54
|
BehaviourMaturity.EXEMPLIFYING,
|
|
55
55
|
];
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
export const Stage = {
|
|
63
|
-
SPECIFY: "specify",
|
|
64
|
-
PLAN: "plan",
|
|
65
|
-
CODE: "code",
|
|
66
|
-
REVIEW: "review",
|
|
67
|
-
DEPLOY: "deploy",
|
|
68
|
-
};
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Data-driven Stage Functions
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Stage ordering is derived from loaded stage data, not hardcoded.
|
|
61
|
+
// Use getStageOrder(stages) to get stage IDs in lifecycle order.
|
|
69
62
|
|
|
70
63
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
64
|
+
* Get ordered stage IDs from loaded stage data
|
|
65
|
+
*
|
|
66
|
+
* Stages are defined in stages.yaml and their array order IS the
|
|
67
|
+
* canonical lifecycle order. This function extracts IDs preserving
|
|
68
|
+
* that order, similar to getCapabilityOrder for capabilities.
|
|
69
|
+
*
|
|
70
|
+
* @param {Object[]} stages - Loaded stages array from stages.yaml
|
|
71
|
+
* @returns {string[]} Stage IDs in lifecycle order
|
|
73
72
|
*/
|
|
74
|
-
export
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
Stage.CODE,
|
|
78
|
-
Stage.REVIEW,
|
|
79
|
-
Stage.DEPLOY,
|
|
80
|
-
];
|
|
73
|
+
export function getStageOrder(stages) {
|
|
74
|
+
return stages.map((s) => s.id);
|
|
75
|
+
}
|
|
81
76
|
|
|
82
77
|
/**
|
|
83
78
|
* Skill capabilities (what capability area)
|
package/src/validation.js
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
Capability,
|
|
9
|
-
Stage,
|
|
10
9
|
getSkillLevelIndex,
|
|
11
10
|
getBehaviourMaturityIndex,
|
|
12
11
|
} from "./levels.js";
|
|
@@ -150,14 +149,16 @@ function validateSkill(skill, index, requiredStageIds = []) {
|
|
|
150
149
|
),
|
|
151
150
|
);
|
|
152
151
|
} else {
|
|
153
|
-
// Validate each stage
|
|
154
|
-
const validStageIds = Object.values(Stage);
|
|
152
|
+
// Validate each stage against loaded stage data
|
|
155
153
|
for (const [stageId, stageData] of Object.entries(skill.agent.stages)) {
|
|
156
|
-
if (
|
|
154
|
+
if (
|
|
155
|
+
requiredStageIds.length > 0 &&
|
|
156
|
+
!requiredStageIds.includes(stageId)
|
|
157
|
+
) {
|
|
157
158
|
errors.push(
|
|
158
159
|
createError(
|
|
159
160
|
"INVALID_VALUE",
|
|
160
|
-
`Invalid stage ID: ${stageId}. Must be one of: ${
|
|
161
|
+
`Invalid stage ID: ${stageId}. Must be one of: ${requiredStageIds.join(", ")}`,
|
|
161
162
|
`${agentPath}.stages.${stageId}`,
|
|
162
163
|
stageId,
|
|
163
164
|
),
|
|
@@ -184,41 +185,41 @@ function validateSkill(skill, index, requiredStageIds = []) {
|
|
|
184
185
|
),
|
|
185
186
|
);
|
|
186
187
|
}
|
|
187
|
-
//
|
|
188
|
-
if (!stageData.
|
|
188
|
+
// readChecklist is required and must be an array
|
|
189
|
+
if (!stageData.readChecklist) {
|
|
189
190
|
errors.push(
|
|
190
191
|
createError(
|
|
191
192
|
"MISSING_REQUIRED",
|
|
192
|
-
`Stage ${stageId} missing
|
|
193
|
-
`${stagePath}.
|
|
193
|
+
`Stage ${stageId} missing readChecklist`,
|
|
194
|
+
`${stagePath}.readChecklist`,
|
|
194
195
|
),
|
|
195
196
|
);
|
|
196
|
-
} else if (!Array.isArray(stageData.
|
|
197
|
+
} else if (!Array.isArray(stageData.readChecklist)) {
|
|
197
198
|
errors.push(
|
|
198
199
|
createError(
|
|
199
200
|
"INVALID_VALUE",
|
|
200
|
-
`Stage ${stageId}
|
|
201
|
-
`${stagePath}.
|
|
202
|
-
stageData.
|
|
201
|
+
`Stage ${stageId} readChecklist must be an array`,
|
|
202
|
+
`${stagePath}.readChecklist`,
|
|
203
|
+
stageData.readChecklist,
|
|
203
204
|
),
|
|
204
205
|
);
|
|
205
206
|
}
|
|
206
|
-
//
|
|
207
|
-
if (!stageData.
|
|
207
|
+
// confirmChecklist is required and must be an array (these become checklist items)
|
|
208
|
+
if (!stageData.confirmChecklist) {
|
|
208
209
|
errors.push(
|
|
209
210
|
createError(
|
|
210
211
|
"MISSING_REQUIRED",
|
|
211
|
-
`Stage ${stageId} missing
|
|
212
|
-
`${stagePath}.
|
|
212
|
+
`Stage ${stageId} missing confirmChecklist`,
|
|
213
|
+
`${stagePath}.confirmChecklist`,
|
|
213
214
|
),
|
|
214
215
|
);
|
|
215
|
-
} else if (!Array.isArray(stageData.
|
|
216
|
+
} else if (!Array.isArray(stageData.confirmChecklist)) {
|
|
216
217
|
errors.push(
|
|
217
218
|
createError(
|
|
218
219
|
"INVALID_VALUE",
|
|
219
|
-
`Stage ${stageId}
|
|
220
|
-
`${stagePath}.
|
|
221
|
-
stageData.
|
|
220
|
+
`Stage ${stageId} confirmChecklist must be an array`,
|
|
221
|
+
`${stagePath}.confirmChecklist`,
|
|
222
|
+
stageData.confirmChecklist,
|
|
222
223
|
),
|
|
223
224
|
);
|
|
224
225
|
}
|
|
@@ -284,7 +285,7 @@ function validateSkill(skill, index, requiredStageIds = []) {
|
|
|
284
285
|
errors.push(
|
|
285
286
|
createError(
|
|
286
287
|
"INVALID_FIELD",
|
|
287
|
-
"Skill agent 'verificationCriteria' field is not supported. Use stages.{stage}.
|
|
288
|
+
"Skill agent 'verificationCriteria' field is not supported. Use stages.{stage}.confirmChecklist instead.",
|
|
288
289
|
`${agentPath}.verificationCriteria`,
|
|
289
290
|
),
|
|
290
291
|
);
|
|
@@ -1249,15 +1250,6 @@ function validateStage(stage, index) {
|
|
|
1249
1250
|
|
|
1250
1251
|
if (!stage.id) {
|
|
1251
1252
|
errors.push(createError("MISSING_REQUIRED", "Stage missing id", path));
|
|
1252
|
-
} else if (!Object.values(Stage).includes(stage.id)) {
|
|
1253
|
-
errors.push(
|
|
1254
|
-
createError(
|
|
1255
|
-
"INVALID_VALUE",
|
|
1256
|
-
`Invalid stage id: ${stage.id}`,
|
|
1257
|
-
`${path}.id`,
|
|
1258
|
-
stage.id,
|
|
1259
|
-
),
|
|
1260
|
-
);
|
|
1261
1253
|
}
|
|
1262
1254
|
|
|
1263
1255
|
if (!stage.name) {
|
|
@@ -1997,7 +1989,7 @@ export function validateAgentData({ humanData, agentData }) {
|
|
|
1997
1989
|
|
|
1998
1990
|
// Validate skills with agent sections have complete stage coverage
|
|
1999
1991
|
const skillsWithAgent = (humanData.skills || []).filter((s) => s.agent);
|
|
2000
|
-
const requiredStages = ["plan", "code", "review"];
|
|
1992
|
+
const requiredStages = ["plan", "onboard", "code", "review"];
|
|
2001
1993
|
|
|
2002
1994
|
for (const skill of skillsWithAgent) {
|
|
2003
1995
|
const stages = skill.agent.stages || {};
|
|
@@ -2025,28 +2017,28 @@ export function validateAgentData({ humanData, agentData }) {
|
|
|
2025
2017
|
);
|
|
2026
2018
|
}
|
|
2027
2019
|
if (
|
|
2028
|
-
!stageData.
|
|
2029
|
-
!Array.isArray(stageData.
|
|
2030
|
-
stageData.
|
|
2020
|
+
!stageData.readChecklist ||
|
|
2021
|
+
!Array.isArray(stageData.readChecklist) ||
|
|
2022
|
+
stageData.readChecklist.length === 0
|
|
2031
2023
|
) {
|
|
2032
2024
|
errors.push(
|
|
2033
2025
|
createError(
|
|
2034
2026
|
"MISSING_REQUIRED",
|
|
2035
|
-
`Skill '${skill.id}' agent stage '${stageId}' missing or empty
|
|
2036
|
-
`skills.${skill.id}.agent.stages.${stageId}.
|
|
2027
|
+
`Skill '${skill.id}' agent stage '${stageId}' missing or empty readChecklist`,
|
|
2028
|
+
`skills.${skill.id}.agent.stages.${stageId}.readChecklist`,
|
|
2037
2029
|
),
|
|
2038
2030
|
);
|
|
2039
2031
|
}
|
|
2040
2032
|
if (
|
|
2041
|
-
!stageData.
|
|
2042
|
-
!Array.isArray(stageData.
|
|
2043
|
-
stageData.
|
|
2033
|
+
!stageData.confirmChecklist ||
|
|
2034
|
+
!Array.isArray(stageData.confirmChecklist) ||
|
|
2035
|
+
stageData.confirmChecklist.length === 0
|
|
2044
2036
|
) {
|
|
2045
2037
|
errors.push(
|
|
2046
2038
|
createError(
|
|
2047
2039
|
"MISSING_REQUIRED",
|
|
2048
|
-
`Skill '${skill.id}' agent stage '${stageId}' missing or empty
|
|
2049
|
-
`skills.${skill.id}.agent.stages.${stageId}.
|
|
2040
|
+
`Skill '${skill.id}' agent stage '${stageId}' missing or empty confirmChecklist`,
|
|
2041
|
+
`skills.${skill.id}.agent.stages.${stageId}.confirmChecklist`,
|
|
2050
2042
|
),
|
|
2051
2043
|
);
|
|
2052
2044
|
}
|