@forwardimpact/model 0.5.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/README.md CHANGED
@@ -29,8 +29,8 @@ import {
29
29
  deriveSkillMatrix,
30
30
  deriveBehaviourProfile,
31
31
  } from "@forwardimpact/model/derivation";
32
- import { prepareAgentProfile } from "@forwardimpact/model/agent";
33
- import { selectInterviewQuestions } from "@forwardimpact/model/interview";
32
+ import { prepareAgentProfile } from "@forwardimpact/model/profile";
33
+ import { deriveInterviewQuestions } from "@forwardimpact/model/interview";
34
34
  import { analyzeProgression } from "@forwardimpact/model/progression";
35
35
  ```
36
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forwardimpact/model",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Derivation engine for roles, skills, and AI agent profiles",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -10,25 +10,27 @@
10
10
  },
11
11
  "homepage": "https://www.forwardimpact.team/model",
12
12
  "type": "module",
13
- "main": "lib/index.js",
13
+ "main": "src/index.js",
14
14
  "files": [
15
- "lib/"
15
+ "src/"
16
16
  ],
17
17
  "exports": {
18
- ".": "./lib/index.js",
19
- "./derivation": "./lib/derivation.js",
20
- "./modifiers": "./lib/modifiers.js",
21
- "./agent": "./lib/agent.js",
22
- "./interview": "./lib/interview.js",
23
- "./job": "./lib/job.js",
24
- "./job-cache": "./lib/job-cache.js",
25
- "./checklist": "./lib/checklist.js",
26
- "./matching": "./lib/matching.js",
27
- "./profile": "./lib/profile.js",
28
- "./progression": "./lib/progression.js"
18
+ ".": "./src/index.js",
19
+ "./derivation": "./src/derivation.js",
20
+ "./modifiers": "./src/modifiers.js",
21
+ "./agent": "./src/agent.js",
22
+ "./interview": "./src/interview.js",
23
+ "./job": "./src/job.js",
24
+ "./job-cache": "./src/job-cache.js",
25
+ "./checklist": "./src/checklist.js",
26
+ "./matching": "./src/matching.js",
27
+ "./profile": "./src/profile.js",
28
+ "./progression": "./src/progression.js",
29
+ "./policies": "./src/policies/index.js",
30
+ "./toolkit": "./src/toolkit.js"
29
31
  },
30
32
  "dependencies": {
31
- "@forwardimpact/schema": "^0.4.0"
33
+ "@forwardimpact/schema": "^0.6.0"
32
34
  },
33
35
  "engines": {
34
36
  "node": ">=18.0.0"
@@ -21,10 +21,11 @@
21
21
  import { deriveSkillMatrix, deriveBehaviourProfile } from "./derivation.js";
22
22
  import { deriveChecklist } from "./checklist.js";
23
23
  import {
24
- filterSkillsForAgent,
25
- sortByLevelDescending,
26
- sortByMaturityDescending,
27
- } from "./profile.js";
24
+ filterAgentSkills,
25
+ sortAgentSkills,
26
+ sortAgentBehaviours,
27
+ } from "./policies/composed.js";
28
+ import { ORDER_AGENT_STAGE } from "./policies/orderings.js";
28
29
  import { SkillLevel } from "@forwardimpact/schema/levels";
29
30
 
30
31
  /**
@@ -123,9 +124,9 @@ export function deriveAgentSkills({ discipline, track, grade, skills }) {
123
124
  skills,
124
125
  });
125
126
 
126
- // Apply agent-specific filtering and sorting
127
- const filtered = filterSkillsForAgent(skillMatrix);
128
- return sortByLevelDescending(filtered);
127
+ // Apply agent-specific filtering and sorting using policies
128
+ const filtered = filterAgentSkills(skillMatrix);
129
+ return sortAgentSkills(filtered);
129
130
  }
130
131
 
131
132
  /**
@@ -151,7 +152,7 @@ export function deriveAgentBehaviours({
151
152
  behaviours,
152
153
  });
153
154
 
154
- return sortByMaturityDescending(profile);
155
+ return sortAgentBehaviours(profile);
155
156
  }
156
157
 
157
158
  /**
@@ -229,7 +230,7 @@ function buildWorkingStyleFromBehaviours(
229
230
  * @param {Array} stages - All stage entities
230
231
  * @returns {Object} Skill with frontmatter, title, stages array, reference, dirname
231
232
  */
232
- export function generateSkillMd(skillData, stages) {
233
+ export function generateSkillMarkdown(skillData, stages) {
233
234
  const { agent, name } = skillData;
234
235
 
235
236
  if (!agent) {
@@ -272,10 +273,11 @@ export function generateSkillMd(skillData, stages) {
272
273
  },
273
274
  );
274
275
 
275
- // Sort stages in order: plan, code, review
276
- const stageOrder = ["plan", "code", "review"];
276
+ // Sort stages using canonical ordering from policies
277
277
  stagesArray.sort(
278
- (a, b) => stageOrder.indexOf(a.stageId) - stageOrder.indexOf(b.stageId),
278
+ (a, b) =>
279
+ ORDER_AGENT_STAGE.indexOf(a.stageId) -
280
+ ORDER_AGENT_STAGE.indexOf(b.stageId),
279
281
  );
280
282
 
281
283
  return {
@@ -18,6 +18,7 @@ import {
18
18
  } from "@forwardimpact/schema/levels";
19
19
 
20
20
  import { resolveSkillModifier } from "./modifiers.js";
21
+ import { ORDER_SKILL_TYPE } from "./policies/orderings.js";
21
22
 
22
23
  /**
23
24
  * Build a Map of skillId → skillType for a discipline
@@ -226,14 +227,10 @@ export function deriveSkillMatrix({ discipline, grade, track = null, skills }) {
226
227
  }
227
228
 
228
229
  // Sort by type (primary first, then secondary, then broad, then track) and then by name
229
- const typeOrder = {
230
- [SkillType.PRIMARY]: 0,
231
- [SkillType.SECONDARY]: 1,
232
- [SkillType.BROAD]: 2,
233
- [SkillType.TRACK]: 3,
234
- };
230
+ // Use ORDER_SKILL_TYPE from policies for canonical ordering
235
231
  matrix.sort((a, b) => {
236
- const typeCompare = typeOrder[a.type] - typeOrder[b.type];
232
+ const typeCompare =
233
+ ORDER_SKILL_TYPE.indexOf(a.type) - ORDER_SKILL_TYPE.indexOf(b.type);
237
234
  if (typeCompare !== 0) return typeCompare;
238
235
  return a.skillName.localeCompare(b.skillName);
239
236
  });
@@ -485,7 +482,7 @@ export function deriveResponsibilities({
485
482
  capability: capabilityId,
486
483
  capabilityName: capability.name,
487
484
  emojiIcon: capability.emojiIcon || "💡",
488
- displayOrder: capability.displayOrder ?? 999,
485
+ ordinalRank: capability.ordinalRank ?? 999,
489
486
  responsibility: responsibilityText,
490
487
  level,
491
488
  levelIndex: SKILL_LEVEL_ORDER.indexOf(level),
@@ -498,7 +495,7 @@ export function deriveResponsibilities({
498
495
  if (b.levelIndex !== a.levelIndex) {
499
496
  return b.levelIndex - a.levelIndex;
500
497
  }
501
- return a.displayOrder - b.displayOrder;
498
+ return a.ordinalRank - b.ordinalRank;
502
499
  });
503
500
 
504
501
  // Remove levelIndex from output (internal use only)
@@ -33,11 +33,11 @@ export {
33
33
 
34
34
  // Job caching
35
35
  export {
36
- makeJobKey,
36
+ buildJobKey,
37
37
  getOrCreateJob,
38
- clearJobCache,
39
- invalidateJob,
40
- getCacheSize,
38
+ clearCache,
39
+ invalidateCachedJob,
40
+ getCachedJobCount,
41
41
  } from "./job-cache.js";
42
42
 
43
43
  // Modifiers
@@ -45,17 +45,17 @@ export {
45
45
  isCapability,
46
46
  getSkillsByCapability,
47
47
  buildCapabilityToSkillsMap,
48
- expandSkillModifiers,
48
+ expandModifiersToSkills,
49
49
  extractCapabilityModifiers,
50
- extractIndividualModifiers,
50
+ extractSkillModifiers,
51
51
  resolveSkillModifier,
52
52
  } from "./modifiers.js";
53
53
 
54
54
  // Matching
55
55
  export {
56
56
  MatchTier,
57
- MATCH_TIER_CONFIG,
58
- classifyMatchTier,
57
+ CONFIG_MATCH_TIER,
58
+ classifyMatch,
59
59
  GAP_SCORES,
60
60
  calculateGapScore,
61
61
  calculateJobMatch,
@@ -87,16 +87,18 @@ export {
87
87
  deriveShortInterview,
88
88
  deriveBehaviourQuestions,
89
89
  deriveFocusedInterview,
90
+ deriveMissionFitInterview,
91
+ deriveDecompositionInterview,
92
+ deriveStakeholderInterview,
90
93
  } from "./interview.js";
91
94
 
92
95
  // Agent generation
93
96
  export {
94
97
  deriveReferenceGrade,
95
98
  getDisciplineAbbreviation,
96
- toKebabCase,
97
99
  deriveAgentSkills,
98
100
  deriveAgentBehaviours,
99
- generateSkillMd,
101
+ generateSkillMarkdown,
100
102
  validateAgentProfile,
101
103
  validateAgentSkill,
102
104
  deriveHandoffs,
@@ -111,15 +113,55 @@ export { deriveChecklist, formatChecklistMarkdown } from "./checklist.js";
111
113
  // Toolkit
112
114
  export { deriveToolkit } from "./toolkit.js";
113
115
 
114
- // Profile filtering (for agents)
116
+ // Profile derivation
115
117
  export {
116
118
  getPositiveTrackCapabilities,
117
- filterHumanOnlySkills,
118
- filterByHighestLevel,
119
- filterSkillsForAgent,
120
- sortByLevelDescending,
121
- sortByMaturityDescending,
122
119
  prepareBaseProfile,
123
- AGENT_PROFILE_OPTIONS,
124
120
  prepareAgentProfile,
125
121
  } from "./profile.js";
122
+
123
+ // Policies - re-export key items for convenience
124
+ export {
125
+ // Thresholds
126
+ THRESHOLD_MATCH_STRONG,
127
+ THRESHOLD_MATCH_GOOD,
128
+ THRESHOLD_MATCH_STRETCH,
129
+ THRESHOLD_MATCH_ASPIRATIONAL,
130
+ SCORE_GAP,
131
+ WEIGHT_SKILL_TYPE,
132
+ WEIGHT_CAPABILITY_BOOST,
133
+ // Predicates
134
+ isHumanOnly,
135
+ isAgentEligible,
136
+ isPrimary,
137
+ isSecondary,
138
+ isBroad,
139
+ isTrack,
140
+ isCore,
141
+ isSupporting,
142
+ hasMinLevel,
143
+ allOf,
144
+ anyOf,
145
+ not,
146
+ // Filters
147
+ filterHighestLevel,
148
+ filterAboveAwareness,
149
+ applyFilters,
150
+ composeFilters,
151
+ // Orderings
152
+ ORDER_SKILL_TYPE,
153
+ ORDER_STAGE,
154
+ ORDER_AGENT_STAGE,
155
+ compareByLevelDesc,
156
+ compareByType,
157
+ compareBySkillPriority,
158
+ compareByMaturityDesc,
159
+ compareByBehaviourPriority,
160
+ // Composed policies
161
+ filterAgentSkills,
162
+ filterToolkitSkills,
163
+ sortAgentSkills,
164
+ sortAgentBehaviours,
165
+ prepareAgentSkillMatrix,
166
+ prepareAgentBehaviourProfile,
167
+ } from "./policies/index.js";