@forwardimpact/schema 0.6.0 → 0.7.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 +52 -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 +31 -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,13 @@ 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 (requiredStageIds.length > 0 && !requiredStageIds.includes(stageId)) {
|
|
157
155
|
errors.push(
|
|
158
156
|
createError(
|
|
159
157
|
"INVALID_VALUE",
|
|
160
|
-
`Invalid stage ID: ${stageId}. Must be one of: ${
|
|
158
|
+
`Invalid stage ID: ${stageId}. Must be one of: ${requiredStageIds.join(", ")}`,
|
|
161
159
|
`${agentPath}.stages.${stageId}`,
|
|
162
160
|
stageId,
|
|
163
161
|
),
|
|
@@ -184,41 +182,41 @@ function validateSkill(skill, index, requiredStageIds = []) {
|
|
|
184
182
|
),
|
|
185
183
|
);
|
|
186
184
|
}
|
|
187
|
-
//
|
|
188
|
-
if (!stageData.
|
|
185
|
+
// readChecklist is required and must be an array
|
|
186
|
+
if (!stageData.readChecklist) {
|
|
189
187
|
errors.push(
|
|
190
188
|
createError(
|
|
191
189
|
"MISSING_REQUIRED",
|
|
192
|
-
`Stage ${stageId} missing
|
|
193
|
-
`${stagePath}.
|
|
190
|
+
`Stage ${stageId} missing readChecklist`,
|
|
191
|
+
`${stagePath}.readChecklist`,
|
|
194
192
|
),
|
|
195
193
|
);
|
|
196
|
-
} else if (!Array.isArray(stageData.
|
|
194
|
+
} else if (!Array.isArray(stageData.readChecklist)) {
|
|
197
195
|
errors.push(
|
|
198
196
|
createError(
|
|
199
197
|
"INVALID_VALUE",
|
|
200
|
-
`Stage ${stageId}
|
|
201
|
-
`${stagePath}.
|
|
202
|
-
stageData.
|
|
198
|
+
`Stage ${stageId} readChecklist must be an array`,
|
|
199
|
+
`${stagePath}.readChecklist`,
|
|
200
|
+
stageData.readChecklist,
|
|
203
201
|
),
|
|
204
202
|
);
|
|
205
203
|
}
|
|
206
|
-
//
|
|
207
|
-
if (!stageData.
|
|
204
|
+
// confirmChecklist is required and must be an array (these become checklist items)
|
|
205
|
+
if (!stageData.confirmChecklist) {
|
|
208
206
|
errors.push(
|
|
209
207
|
createError(
|
|
210
208
|
"MISSING_REQUIRED",
|
|
211
|
-
`Stage ${stageId} missing
|
|
212
|
-
`${stagePath}.
|
|
209
|
+
`Stage ${stageId} missing confirmChecklist`,
|
|
210
|
+
`${stagePath}.confirmChecklist`,
|
|
213
211
|
),
|
|
214
212
|
);
|
|
215
|
-
} else if (!Array.isArray(stageData.
|
|
213
|
+
} else if (!Array.isArray(stageData.confirmChecklist)) {
|
|
216
214
|
errors.push(
|
|
217
215
|
createError(
|
|
218
216
|
"INVALID_VALUE",
|
|
219
|
-
`Stage ${stageId}
|
|
220
|
-
`${stagePath}.
|
|
221
|
-
stageData.
|
|
217
|
+
`Stage ${stageId} confirmChecklist must be an array`,
|
|
218
|
+
`${stagePath}.confirmChecklist`,
|
|
219
|
+
stageData.confirmChecklist,
|
|
222
220
|
),
|
|
223
221
|
);
|
|
224
222
|
}
|
|
@@ -284,7 +282,7 @@ function validateSkill(skill, index, requiredStageIds = []) {
|
|
|
284
282
|
errors.push(
|
|
285
283
|
createError(
|
|
286
284
|
"INVALID_FIELD",
|
|
287
|
-
"Skill agent 'verificationCriteria' field is not supported. Use stages.{stage}.
|
|
285
|
+
"Skill agent 'verificationCriteria' field is not supported. Use stages.{stage}.confirmChecklist instead.",
|
|
288
286
|
`${agentPath}.verificationCriteria`,
|
|
289
287
|
),
|
|
290
288
|
);
|
|
@@ -1249,15 +1247,6 @@ function validateStage(stage, index) {
|
|
|
1249
1247
|
|
|
1250
1248
|
if (!stage.id) {
|
|
1251
1249
|
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
1250
|
}
|
|
1262
1251
|
|
|
1263
1252
|
if (!stage.name) {
|
|
@@ -1997,7 +1986,7 @@ export function validateAgentData({ humanData, agentData }) {
|
|
|
1997
1986
|
|
|
1998
1987
|
// Validate skills with agent sections have complete stage coverage
|
|
1999
1988
|
const skillsWithAgent = (humanData.skills || []).filter((s) => s.agent);
|
|
2000
|
-
const requiredStages = ["plan", "code", "review"];
|
|
1989
|
+
const requiredStages = ["plan", "onboard", "code", "review"];
|
|
2001
1990
|
|
|
2002
1991
|
for (const skill of skillsWithAgent) {
|
|
2003
1992
|
const stages = skill.agent.stages || {};
|
|
@@ -2025,28 +2014,28 @@ export function validateAgentData({ humanData, agentData }) {
|
|
|
2025
2014
|
);
|
|
2026
2015
|
}
|
|
2027
2016
|
if (
|
|
2028
|
-
!stageData.
|
|
2029
|
-
!Array.isArray(stageData.
|
|
2030
|
-
stageData.
|
|
2017
|
+
!stageData.readChecklist ||
|
|
2018
|
+
!Array.isArray(stageData.readChecklist) ||
|
|
2019
|
+
stageData.readChecklist.length === 0
|
|
2031
2020
|
) {
|
|
2032
2021
|
errors.push(
|
|
2033
2022
|
createError(
|
|
2034
2023
|
"MISSING_REQUIRED",
|
|
2035
|
-
`Skill '${skill.id}' agent stage '${stageId}' missing or empty
|
|
2036
|
-
`skills.${skill.id}.agent.stages.${stageId}.
|
|
2024
|
+
`Skill '${skill.id}' agent stage '${stageId}' missing or empty readChecklist`,
|
|
2025
|
+
`skills.${skill.id}.agent.stages.${stageId}.readChecklist`,
|
|
2037
2026
|
),
|
|
2038
2027
|
);
|
|
2039
2028
|
}
|
|
2040
2029
|
if (
|
|
2041
|
-
!stageData.
|
|
2042
|
-
!Array.isArray(stageData.
|
|
2043
|
-
stageData.
|
|
2030
|
+
!stageData.confirmChecklist ||
|
|
2031
|
+
!Array.isArray(stageData.confirmChecklist) ||
|
|
2032
|
+
stageData.confirmChecklist.length === 0
|
|
2044
2033
|
) {
|
|
2045
2034
|
errors.push(
|
|
2046
2035
|
createError(
|
|
2047
2036
|
"MISSING_REQUIRED",
|
|
2048
|
-
`Skill '${skill.id}' agent stage '${stageId}' missing or empty
|
|
2049
|
-
`skills.${skill.id}.agent.stages.${stageId}.
|
|
2037
|
+
`Skill '${skill.id}' agent stage '${stageId}' missing or empty confirmChecklist`,
|
|
2038
|
+
`skills.${skill.id}.agent.stages.${stageId}.confirmChecklist`,
|
|
2050
2039
|
),
|
|
2051
2040
|
);
|
|
2052
2041
|
}
|