@mnemom/agent-alignment-protocol 0.6.1 → 0.6.2

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/dist/index.d.mts CHANGED
@@ -40,7 +40,24 @@ interface ValueDefinition {
40
40
  }
41
41
  /** Value declarations (SPEC Section 4.4). */
42
42
  interface Values {
43
- /** List of value identifiers */
43
+ /**
44
+ * Behavioral and ethical values the agent applies in its decision-making.
45
+ *
46
+ * This field is actively monitored by AIP at runtime: every value listed here
47
+ * is expected to appear in AP-Trace `values_applied` fields when it influences
48
+ * a decision. Declaring a value the agent never applies produces verification
49
+ * warnings and degrades trust scoring.
50
+ *
51
+ * **Include**: Ethical and behavioral commitments — e.g. `transparency`,
52
+ * `honesty`, `accuracy`, `safety`, `accountability`, `helpfulness`,
53
+ * `deliberation_before_action`. These describe HOW the agent reasons.
54
+ *
55
+ * **Do not include**: Role capabilities, operational principles, or job-function
56
+ * descriptors — e.g. `fiduciary_precision`, `organizational_clarity`. These
57
+ * describe WHAT the agent is in its role and belong in `extensions.clpi.role`
58
+ * or other `extensions` metadata. Capability names (e.g. `read_documents`)
59
+ * belong in `autonomy_envelope.bounded_actions`.
60
+ */
44
61
  declared: string[];
45
62
  /** Definitions for non-standard values */
46
63
  definitions?: Record<string, ValueDefinition> | null;
package/dist/index.d.ts CHANGED
@@ -40,7 +40,24 @@ interface ValueDefinition {
40
40
  }
41
41
  /** Value declarations (SPEC Section 4.4). */
42
42
  interface Values {
43
- /** List of value identifiers */
43
+ /**
44
+ * Behavioral and ethical values the agent applies in its decision-making.
45
+ *
46
+ * This field is actively monitored by AIP at runtime: every value listed here
47
+ * is expected to appear in AP-Trace `values_applied` fields when it influences
48
+ * a decision. Declaring a value the agent never applies produces verification
49
+ * warnings and degrades trust scoring.
50
+ *
51
+ * **Include**: Ethical and behavioral commitments — e.g. `transparency`,
52
+ * `honesty`, `accuracy`, `safety`, `accountability`, `helpfulness`,
53
+ * `deliberation_before_action`. These describe HOW the agent reasons.
54
+ *
55
+ * **Do not include**: Role capabilities, operational principles, or job-function
56
+ * descriptors — e.g. `fiduciary_precision`, `organizational_clarity`. These
57
+ * describe WHAT the agent is in its role and belong in `extensions.clpi.role`
58
+ * or other `extensions` metadata. Capability names (e.g. `read_documents`)
59
+ * belong in `autonomy_envelope.bounded_actions`.
60
+ */
44
61
  declared: string[];
45
62
  /** Definitions for non-standard values */
46
63
  definitions?: Record<string, ValueDefinition> | null;
package/dist/index.js CHANGED
@@ -834,23 +834,29 @@ function analyzeFaultLines(coherenceResult, cards, options) {
834
834
  coordinationOverlap = count > 0 ? total / count : 0.5;
835
835
  }
836
836
  }
837
- let impactScore = impact_on_fleet_score * coordinationOverlap;
838
- if (reputationScores && involvedAgents.length > 0) {
839
- const repValues = involvedAgents.map((id2) => (reputationScores[id2] ?? 500) / 1e3).map((r) => Math.max(1e-3, r));
840
- const logSum = repValues.reduce((sum, r) => sum + Math.log(r), 0);
841
- const geoMean = Math.exp(logSum / repValues.length);
842
- impactScore *= geoMean;
843
- }
844
- impactScore = Math.min(1, Math.max(0, impactScore));
837
+ let impactScore;
845
838
  let severity;
846
- if (impactScore >= 0.7) {
847
- severity = "critical";
848
- } else if (impactScore >= 0.4) {
849
- severity = "high";
850
- } else if (impactScore >= 0.2) {
851
- severity = "medium";
852
- } else {
839
+ if (classification === "complementary") {
840
+ impactScore = 0;
853
841
  severity = "low";
842
+ } else {
843
+ impactScore = impact_on_fleet_score * coordinationOverlap;
844
+ if (reputationScores && involvedAgents.length > 0) {
845
+ const repValues = involvedAgents.map((id2) => (reputationScores[id2] ?? 500) / 1e3).map((r) => Math.max(1e-3, r));
846
+ const logSum = repValues.reduce((sum, r) => sum + Math.log(r), 0);
847
+ const geoMean = Math.exp(logSum / repValues.length);
848
+ impactScore *= geoMean;
849
+ }
850
+ impactScore = Math.min(1, Math.max(0, impactScore));
851
+ if (impactScore >= 0.7) {
852
+ severity = "critical";
853
+ } else if (impactScore >= 0.4) {
854
+ severity = "high";
855
+ } else if (impactScore >= 0.2) {
856
+ severity = "medium";
857
+ } else {
858
+ severity = "low";
859
+ }
854
860
  }
855
861
  let resolutionHint;
856
862
  switch (classification) {
@@ -901,12 +907,15 @@ function analyzeFaultLines(coherenceResult, cards, options) {
901
907
  return b.impact_score - a.impact_score;
902
908
  });
903
909
  const alignments = [];
910
+ const actionableFaultLines = faultLines.filter(
911
+ (fl) => fl.classification === "resolvable" || fl.classification === "incompatible"
912
+ );
904
913
  const grouped = /* @__PURE__ */ new Map();
905
914
  const groupAssignment = /* @__PURE__ */ new Map();
906
915
  let nextGroupId = 0;
907
- for (let i = 0; i < faultLines.length; i++) {
908
- for (let j = i + 1; j < faultLines.length; j++) {
909
- const sim = jaccardSimilarity(faultLines[i].agents_missing, faultLines[j].agents_missing);
916
+ for (let i = 0; i < actionableFaultLines.length; i++) {
917
+ for (let j = i + 1; j < actionableFaultLines.length; j++) {
918
+ const sim = jaccardSimilarity(actionableFaultLines[i].agents_missing, actionableFaultLines[j].agents_missing);
910
919
  if (sim > 0.6) {
911
920
  const gi = groupAssignment.get(i);
912
921
  const gj = groupAssignment.get(j);
@@ -939,7 +948,7 @@ function analyzeFaultLines(coherenceResult, cards, options) {
939
948
  for (const [, members] of grouped) {
940
949
  if (members.length < 2) continue;
941
950
  const unique = [...new Set(members)];
942
- const groupFaultLines = unique.map((i) => faultLines[i]);
951
+ const groupFaultLines = unique.map((i) => actionableFaultLines[i]);
943
952
  const minorityAgents = [
944
953
  ...new Set(groupFaultLines.flatMap((fl) => fl.agents_missing))
945
954
  ];
package/dist/index.mjs CHANGED
@@ -777,23 +777,29 @@ function analyzeFaultLines(coherenceResult, cards, options) {
777
777
  coordinationOverlap = count > 0 ? total / count : 0.5;
778
778
  }
779
779
  }
780
- let impactScore = impact_on_fleet_score * coordinationOverlap;
781
- if (reputationScores && involvedAgents.length > 0) {
782
- const repValues = involvedAgents.map((id2) => (reputationScores[id2] ?? 500) / 1e3).map((r) => Math.max(1e-3, r));
783
- const logSum = repValues.reduce((sum, r) => sum + Math.log(r), 0);
784
- const geoMean = Math.exp(logSum / repValues.length);
785
- impactScore *= geoMean;
786
- }
787
- impactScore = Math.min(1, Math.max(0, impactScore));
780
+ let impactScore;
788
781
  let severity;
789
- if (impactScore >= 0.7) {
790
- severity = "critical";
791
- } else if (impactScore >= 0.4) {
792
- severity = "high";
793
- } else if (impactScore >= 0.2) {
794
- severity = "medium";
795
- } else {
782
+ if (classification === "complementary") {
783
+ impactScore = 0;
796
784
  severity = "low";
785
+ } else {
786
+ impactScore = impact_on_fleet_score * coordinationOverlap;
787
+ if (reputationScores && involvedAgents.length > 0) {
788
+ const repValues = involvedAgents.map((id2) => (reputationScores[id2] ?? 500) / 1e3).map((r) => Math.max(1e-3, r));
789
+ const logSum = repValues.reduce((sum, r) => sum + Math.log(r), 0);
790
+ const geoMean = Math.exp(logSum / repValues.length);
791
+ impactScore *= geoMean;
792
+ }
793
+ impactScore = Math.min(1, Math.max(0, impactScore));
794
+ if (impactScore >= 0.7) {
795
+ severity = "critical";
796
+ } else if (impactScore >= 0.4) {
797
+ severity = "high";
798
+ } else if (impactScore >= 0.2) {
799
+ severity = "medium";
800
+ } else {
801
+ severity = "low";
802
+ }
797
803
  }
798
804
  let resolutionHint;
799
805
  switch (classification) {
@@ -844,12 +850,15 @@ function analyzeFaultLines(coherenceResult, cards, options) {
844
850
  return b.impact_score - a.impact_score;
845
851
  });
846
852
  const alignments = [];
853
+ const actionableFaultLines = faultLines.filter(
854
+ (fl) => fl.classification === "resolvable" || fl.classification === "incompatible"
855
+ );
847
856
  const grouped = /* @__PURE__ */ new Map();
848
857
  const groupAssignment = /* @__PURE__ */ new Map();
849
858
  let nextGroupId = 0;
850
- for (let i = 0; i < faultLines.length; i++) {
851
- for (let j = i + 1; j < faultLines.length; j++) {
852
- const sim = jaccardSimilarity(faultLines[i].agents_missing, faultLines[j].agents_missing);
859
+ for (let i = 0; i < actionableFaultLines.length; i++) {
860
+ for (let j = i + 1; j < actionableFaultLines.length; j++) {
861
+ const sim = jaccardSimilarity(actionableFaultLines[i].agents_missing, actionableFaultLines[j].agents_missing);
853
862
  if (sim > 0.6) {
854
863
  const gi = groupAssignment.get(i);
855
864
  const gj = groupAssignment.get(j);
@@ -882,7 +891,7 @@ function analyzeFaultLines(coherenceResult, cards, options) {
882
891
  for (const [, members] of grouped) {
883
892
  if (members.length < 2) continue;
884
893
  const unique = [...new Set(members)];
885
- const groupFaultLines = unique.map((i) => faultLines[i]);
894
+ const groupFaultLines = unique.map((i) => actionableFaultLines[i]);
886
895
  const minorityAgents = [
887
896
  ...new Set(groupFaultLines.flatMap((fl) => fl.agents_missing))
888
897
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnemom/agent-alignment-protocol",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Agent Alignment Protocol (AAP) - Verification and drift detection for AI agents",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -49,7 +49,24 @@ export interface ValueDefinition {
49
49
 
50
50
  /** Value declarations (SPEC Section 4.4). */
51
51
  export interface Values {
52
- /** List of value identifiers */
52
+ /**
53
+ * Behavioral and ethical values the agent applies in its decision-making.
54
+ *
55
+ * This field is actively monitored by AIP at runtime: every value listed here
56
+ * is expected to appear in AP-Trace `values_applied` fields when it influences
57
+ * a decision. Declaring a value the agent never applies produces verification
58
+ * warnings and degrades trust scoring.
59
+ *
60
+ * **Include**: Ethical and behavioral commitments — e.g. `transparency`,
61
+ * `honesty`, `accuracy`, `safety`, `accountability`, `helpfulness`,
62
+ * `deliberation_before_action`. These describe HOW the agent reasons.
63
+ *
64
+ * **Do not include**: Role capabilities, operational principles, or job-function
65
+ * descriptors — e.g. `fiduciary_precision`, `organizational_clarity`. These
66
+ * describe WHAT the agent is in its role and belong in `extensions.clpi.role`
67
+ * or other `extensions` metadata. Capability names (e.g. `read_documents`)
68
+ * belong in `autonomy_envelope.bounded_actions`.
69
+ */
53
70
  declared: string[];
54
71
  /** Definitions for non-standard values */
55
72
  definitions?: Record<string, ValueDefinition> | null;
@@ -923,30 +923,38 @@ export function analyzeFaultLines(
923
923
  }
924
924
 
925
925
  // --- impact_score ---
926
- let impactScore = impact_on_fleet_score * coordinationOverlap;
927
-
928
- // Reputation weighting: multiply by geometric mean of reputation/1000
929
- if (reputationScores && involvedAgents.length > 0) {
930
- const repValues = involvedAgents
931
- .map(id => (reputationScores[id] ?? 500) / 1000)
932
- .map(r => Math.max(0.001, r)); // avoid log(0)
933
- const logSum = repValues.reduce((sum, r) => sum + Math.log(r), 0);
934
- const geoMean = Math.exp(logSum / repValues.length);
935
- impactScore *= geoMean;
936
- }
937
-
938
- impactScore = Math.min(1, Math.max(0, impactScore));
939
-
940
- // --- Severity ---
926
+ // Complementary faults are intentional — they carry zero risk by definition.
927
+ let impactScore: number;
941
928
  let severity: Severity;
942
- if (impactScore >= 0.7) {
943
- severity = 'critical';
944
- } else if (impactScore >= 0.4) {
945
- severity = 'high';
946
- } else if (impactScore >= 0.2) {
947
- severity = 'medium';
948
- } else {
929
+
930
+ if (classification === 'complementary') {
931
+ impactScore = 0;
949
932
  severity = 'low';
933
+ } else {
934
+ impactScore = impact_on_fleet_score * coordinationOverlap;
935
+
936
+ // Reputation weighting: multiply by geometric mean of reputation/1000
937
+ if (reputationScores && involvedAgents.length > 0) {
938
+ const repValues = involvedAgents
939
+ .map(id => (reputationScores[id] ?? 500) / 1000)
940
+ .map(r => Math.max(0.001, r)); // avoid log(0)
941
+ const logSum = repValues.reduce((sum, r) => sum + Math.log(r), 0);
942
+ const geoMean = Math.exp(logSum / repValues.length);
943
+ impactScore *= geoMean;
944
+ }
945
+
946
+ impactScore = Math.min(1, Math.max(0, impactScore));
947
+
948
+ // --- Severity ---
949
+ if (impactScore >= 0.7) {
950
+ severity = 'critical';
951
+ } else if (impactScore >= 0.4) {
952
+ severity = 'high';
953
+ } else if (impactScore >= 0.2) {
954
+ severity = 'medium';
955
+ } else {
956
+ severity = 'low';
957
+ }
950
958
  }
951
959
 
952
960
  // --- Resolution hint ---
@@ -1007,17 +1015,22 @@ export function analyzeFaultLines(
1007
1015
  });
1008
1016
 
1009
1017
  // --- Fault line alignment detection ---
1018
+ // Only consider resolvable and incompatible faults — complementary faults are intentional
1019
+ // role specialization and should NEVER trigger a structural fault line alert.
1010
1020
  const alignments: FaultLineAlignment[] = [];
1021
+ const actionableFaultLines = faultLines.filter(
1022
+ fl => fl.classification === 'resolvable' || fl.classification === 'incompatible'
1023
+ );
1011
1024
 
1012
- // For each pair of fault lines, compute Jaccard of agents_missing sets
1025
+ // For each pair of actionable fault lines, compute Jaccard of agents_missing sets
1013
1026
  // Group fault lines with similarity > 0.6
1014
1027
  const grouped = new Map<number, number[]>(); // groupId → faultLine indices
1015
1028
  const groupAssignment = new Map<number, number>(); // faultLine index → groupId
1016
1029
  let nextGroupId = 0;
1017
1030
 
1018
- for (let i = 0; i < faultLines.length; i++) {
1019
- for (let j = i + 1; j < faultLines.length; j++) {
1020
- const sim = jaccardSimilarity(faultLines[i].agents_missing, faultLines[j].agents_missing);
1031
+ for (let i = 0; i < actionableFaultLines.length; i++) {
1032
+ for (let j = i + 1; j < actionableFaultLines.length; j++) {
1033
+ const sim = jaccardSimilarity(actionableFaultLines[i].agents_missing, actionableFaultLines[j].agents_missing);
1021
1034
  if (sim > 0.6) {
1022
1035
  // Find or create groups for i and j
1023
1036
  const gi = groupAssignment.get(i);
@@ -1054,7 +1067,7 @@ export function analyzeFaultLines(
1054
1067
  for (const [, members] of grouped) {
1055
1068
  if (members.length < 2) continue;
1056
1069
  const unique = [...new Set(members)];
1057
- const groupFaultLines = unique.map(i => faultLines[i]);
1070
+ const groupFaultLines = unique.map(i => actionableFaultLines[i]);
1058
1071
 
1059
1072
  const minorityAgents = [
1060
1073
  ...new Set(groupFaultLines.flatMap(fl => fl.agents_missing)),