@forwardimpact/model 0.7.1 → 0.8.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/package.json +2 -2
- package/src/agent.js +15 -15
- package/src/checklist.js +9 -12
- package/src/index.js +2 -3
- package/src/job.js +6 -3
- package/src/policies/index.js +3 -3
- package/src/policies/orderings.js +21 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forwardimpact/model",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Derivation engine for roles, skills, and AI agent profiles",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"./toolkit": "./src/toolkit.js"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@forwardimpact/schema": "^0.
|
|
33
|
+
"@forwardimpact/schema": "^0.7.0"
|
|
34
34
|
},
|
|
35
35
|
"engines": {
|
|
36
36
|
"node": ">=18.0.0"
|
package/src/agent.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
sortAgentBehaviours,
|
|
27
27
|
focusAgentSkills,
|
|
28
28
|
} from "./policies/composed.js";
|
|
29
|
-
import {
|
|
29
|
+
import { compareByStageOrder } from "./policies/orderings.js";
|
|
30
30
|
import { LIMIT_AGENT_WORKING_STYLES } from "./policies/thresholds.js";
|
|
31
31
|
import { SkillLevel } from "@forwardimpact/schema/levels";
|
|
32
32
|
|
|
@@ -269,18 +269,15 @@ export function generateSkillMarkdown(skillData, stages) {
|
|
|
269
269
|
stageName,
|
|
270
270
|
nextStageName,
|
|
271
271
|
focus: stageData.focus,
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
readChecklist: stageData.readChecklist || [],
|
|
273
|
+
confirmChecklist: stageData.confirmChecklist || [],
|
|
274
274
|
};
|
|
275
275
|
},
|
|
276
276
|
);
|
|
277
277
|
|
|
278
|
-
// Sort stages using canonical ordering from
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
ORDER_AGENT_STAGE.indexOf(a.stageId) -
|
|
282
|
-
ORDER_AGENT_STAGE.indexOf(b.stageId),
|
|
283
|
-
);
|
|
278
|
+
// Sort stages using canonical ordering from loaded stage data
|
|
279
|
+
const stageComparator = compareByStageOrder(stages);
|
|
280
|
+
stagesArray.sort(stageComparator);
|
|
284
281
|
|
|
285
282
|
return {
|
|
286
283
|
frontmatter: {
|
|
@@ -433,9 +430,9 @@ export function deriveHandoffs({ stage, discipline, track, stages }) {
|
|
|
433
430
|
const baseName = `${abbrev}-${toKebabCase(track.id)}`;
|
|
434
431
|
|
|
435
432
|
return stage.handoffs.map((handoff) => {
|
|
436
|
-
// Find the target stage to get its
|
|
433
|
+
// Find the target stage to get its confirmChecklist
|
|
437
434
|
const targetStage = stages.find((s) => s.id === handoff.targetStage);
|
|
438
|
-
const
|
|
435
|
+
const confirmChecklist = targetStage?.confirmChecklist || [];
|
|
439
436
|
|
|
440
437
|
// Build rich prompt - formatted for single-line display
|
|
441
438
|
const promptParts = [handoff.prompt];
|
|
@@ -445,9 +442,9 @@ export function deriveHandoffs({ stage, discipline, track, stages }) {
|
|
|
445
442
|
`Summarize what was completed in the ${stage.name} stage.`,
|
|
446
443
|
);
|
|
447
444
|
|
|
448
|
-
// Add
|
|
449
|
-
if (
|
|
450
|
-
const formattedCriteria =
|
|
445
|
+
// Add confirm checklist from target stage with inline numbered list
|
|
446
|
+
if (confirmChecklist.length > 0) {
|
|
447
|
+
const formattedCriteria = confirmChecklist
|
|
451
448
|
.map((item, index) => `(${index + 1}) ${item}`)
|
|
452
449
|
.join(", ");
|
|
453
450
|
promptParts.push(
|
|
@@ -560,12 +557,15 @@ function buildStageProfileBodyData({
|
|
|
560
557
|
return {
|
|
561
558
|
title: `${name} - ${stageName} Agent`,
|
|
562
559
|
stageDescription: stage.description,
|
|
560
|
+
stageId: stage.id,
|
|
561
|
+
stageName,
|
|
562
|
+
isOnboard: stage.id === "onboard",
|
|
563
563
|
identity: identity.trim(),
|
|
564
564
|
priority: priority ? priority.trim() : null,
|
|
565
565
|
skillIndex,
|
|
566
566
|
roleContext,
|
|
567
567
|
workingStyles,
|
|
568
|
-
|
|
568
|
+
confirmChecklist: checklist || [],
|
|
569
569
|
constraints,
|
|
570
570
|
agentIndex: filteredAgentIndex,
|
|
571
571
|
hasAgentIndex: filteredAgentIndex.length > 0,
|
package/src/checklist.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Checklist Derivation
|
|
3
3
|
*
|
|
4
|
-
* Checklists are derived from skills with agent.stages.{stage}.
|
|
4
|
+
* Checklists are derived from skills with agent.stages.{stage}.confirmChecklist criteria.
|
|
5
5
|
* Each skill defines its own readiness criteria for stage transitions.
|
|
6
6
|
*
|
|
7
|
-
* Checklist = Stage × Skill Matrix × Skill
|
|
7
|
+
* Checklist = Stage × Skill Matrix × Skill Confirm Checklist
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { CHECKLIST_STAGE_MAP } from "./policies/orderings.js";
|
|
11
|
-
|
|
12
10
|
/**
|
|
13
11
|
* Derive checklist items for a specific stage
|
|
14
12
|
* Returns skills grouped by capability with their ready criteria
|
|
@@ -26,11 +24,6 @@ export function deriveChecklist({
|
|
|
26
24
|
skills,
|
|
27
25
|
capabilities,
|
|
28
26
|
}) {
|
|
29
|
-
const targetStage = CHECKLIST_STAGE_MAP[stageId];
|
|
30
|
-
if (!targetStage) {
|
|
31
|
-
return [];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
27
|
// Build skill lookup
|
|
35
28
|
const skillById = new Map(skills.map((s) => [s.id, s]));
|
|
36
29
|
|
|
@@ -45,8 +38,12 @@ export function deriveChecklist({
|
|
|
45
38
|
continue;
|
|
46
39
|
}
|
|
47
40
|
|
|
48
|
-
const stageData = skill.agent.stages[
|
|
49
|
-
if (
|
|
41
|
+
const stageData = skill.agent.stages[stageId];
|
|
42
|
+
if (
|
|
43
|
+
!stageData ||
|
|
44
|
+
!stageData.confirmChecklist ||
|
|
45
|
+
stageData.confirmChecklist.length === 0
|
|
46
|
+
) {
|
|
50
47
|
continue;
|
|
51
48
|
}
|
|
52
49
|
|
|
@@ -66,7 +63,7 @@ export function deriveChecklist({
|
|
|
66
63
|
name: capability.name,
|
|
67
64
|
emojiIcon: capability.emojiIcon,
|
|
68
65
|
},
|
|
69
|
-
items: stageData.
|
|
66
|
+
items: stageData.confirmChecklist,
|
|
70
67
|
});
|
|
71
68
|
}
|
|
72
69
|
|
package/src/index.js
CHANGED
|
@@ -177,9 +177,8 @@ export {
|
|
|
177
177
|
composeFilters,
|
|
178
178
|
// Orderings
|
|
179
179
|
ORDER_SKILL_TYPE,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
CHECKLIST_STAGE_MAP,
|
|
180
|
+
getStageOrder,
|
|
181
|
+
compareByStageOrder,
|
|
183
182
|
compareByLevelDesc,
|
|
184
183
|
compareByType,
|
|
185
184
|
compareBySkillPriority,
|
package/src/job.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import { deriveChecklist } from "./checklist.js";
|
|
15
15
|
import { deriveToolkit } from "./toolkit.js";
|
|
16
16
|
import { getOrCreateJob } from "./job-cache.js";
|
|
17
|
+
import { getStageOrder } from "@forwardimpact/schema/levels";
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* @typedef {Object} JobDetailView
|
|
@@ -43,6 +44,7 @@ import { getOrCreateJob } from "./job-cache.js";
|
|
|
43
44
|
* @param {Array} params.behaviours
|
|
44
45
|
* @param {Array} params.drivers
|
|
45
46
|
* @param {Array} [params.capabilities]
|
|
47
|
+
* @param {Array} [params.stages] - Loaded stages for checklist derivation
|
|
46
48
|
* @returns {JobDetailView|null}
|
|
47
49
|
*/
|
|
48
50
|
export function prepareJobDetail({
|
|
@@ -53,6 +55,7 @@ export function prepareJobDetail({
|
|
|
53
55
|
behaviours,
|
|
54
56
|
drivers,
|
|
55
57
|
capabilities,
|
|
58
|
+
stages,
|
|
56
59
|
}) {
|
|
57
60
|
// Track is optional (null = generalist)
|
|
58
61
|
if (!discipline || !grade) return null;
|
|
@@ -73,10 +76,10 @@ export function prepareJobDetail({
|
|
|
73
76
|
drivers,
|
|
74
77
|
});
|
|
75
78
|
|
|
76
|
-
// Derive checklists for each stage
|
|
79
|
+
// Derive checklists for each stage from loaded stage data
|
|
77
80
|
const checklists = {};
|
|
78
|
-
if (capabilities) {
|
|
79
|
-
const stageIds =
|
|
81
|
+
if (capabilities && stages) {
|
|
82
|
+
const stageIds = getStageOrder(stages);
|
|
80
83
|
for (const stageId of stageIds) {
|
|
81
84
|
checklists[stageId] = deriveChecklist({
|
|
82
85
|
stageId,
|
package/src/policies/index.js
CHANGED
|
@@ -117,9 +117,9 @@ export {
|
|
|
117
117
|
export {
|
|
118
118
|
// Canonical orders
|
|
119
119
|
ORDER_SKILL_TYPE,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
// Data-driven stage ordering
|
|
121
|
+
getStageOrder,
|
|
122
|
+
compareByStageOrder,
|
|
123
123
|
// Skill comparators
|
|
124
124
|
compareByLevelDesc,
|
|
125
125
|
compareByLevelAsc,
|
|
@@ -12,8 +12,12 @@ import {
|
|
|
12
12
|
getSkillLevelIndex,
|
|
13
13
|
getBehaviourMaturityIndex,
|
|
14
14
|
getCapabilityOrder,
|
|
15
|
+
getStageOrder,
|
|
15
16
|
} from "@forwardimpact/schema/levels";
|
|
16
17
|
|
|
18
|
+
// Re-export getStageOrder for consumers
|
|
19
|
+
export { getStageOrder };
|
|
20
|
+
|
|
17
21
|
// =============================================================================
|
|
18
22
|
// Canonical Orderings
|
|
19
23
|
// =============================================================================
|
|
@@ -24,27 +28,27 @@ import {
|
|
|
24
28
|
*/
|
|
25
29
|
export const ORDER_SKILL_TYPE = ["primary", "secondary", "broad", "track"];
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export const ORDER_STAGE = ["specify", "plan", "code", "review", "deploy"];
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Agent stage ordering (subset used for agent generation)
|
|
34
|
-
*/
|
|
35
|
-
export const ORDER_AGENT_STAGE = ["plan", "code", "review"];
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// Stage Comparators
|
|
33
|
+
// =============================================================================
|
|
36
34
|
|
|
37
35
|
/**
|
|
38
|
-
*
|
|
36
|
+
* Create a comparator for sorting by stage lifecycle order
|
|
37
|
+
*
|
|
38
|
+
* The returned comparator uses the canonical order from loaded stage data,
|
|
39
|
+
* making the ordering data-driven rather than hardcoded.
|
|
39
40
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
41
|
+
* @param {Object[]} stages - Loaded stages array from stages.yaml
|
|
42
|
+
* @returns {(a: Object, b: Object) => number} Comparator function
|
|
42
43
|
*/
|
|
43
|
-
export
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
export function compareByStageOrder(stages) {
|
|
45
|
+
const order = getStageOrder(stages);
|
|
46
|
+
return (a, b) => {
|
|
47
|
+
const stageA = a.stageId || a.id || "";
|
|
48
|
+
const stageB = b.stageId || b.id || "";
|
|
49
|
+
return order.indexOf(stageA) - order.indexOf(stageB);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
48
52
|
|
|
49
53
|
// =============================================================================
|
|
50
54
|
// Skill Comparators
|