@kaddo/mcp 3.124.0 → 3.124.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.
Files changed (2) hide show
  1. package/dist/index.js +28 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10466,7 +10466,7 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
10466
10466
  let withAcceptance = 0;
10467
10467
  let withDoD = 0;
10468
10468
  let withValidation = 0;
10469
- let connectedRoadmap = 0;
10469
+ const connectedRoadmapCandidates = /* @__PURE__ */ new Set();
10470
10470
  const globCounts = /* @__PURE__ */ new Map();
10471
10471
  const globOwners = /* @__PURE__ */ new Map();
10472
10472
  const gaps = {
@@ -10490,13 +10490,17 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
10490
10490
  for (const wi of wis) {
10491
10491
  const id = wi.id || wi.title;
10492
10492
  if (wi.codeGlobs.length > 0) withOwnership++;
10493
- else gaps.missing_code_ownership.push(gapItem(wi, "Add `code:` globs to connect this Work Item to source paths (`kaddo owners suggest`)."));
10494
- const hasSource = Boolean(wi.sourceId) || wi.source === "roadmap";
10493
+ else if (wi.type === "bugfix" || wi.type === "hotfix") {
10494
+ gaps.missing_code_ownership.push(gapItem(wi, "Add `code:` globs to connect this corrective Work Item to source paths (`kaddo owners suggest`)."));
10495
+ }
10496
+ const roadmapOrigin = wi.source === "roadmap";
10497
+ const hasSource = Boolean(wi.source) || Boolean(wi.sourceId);
10495
10498
  if (hasSource) withSource++;
10496
- else gaps.missing_source.push(gapItem(wi, "Add `source` or `source_id` if this Work Item came from the roadmap."));
10497
- if (hasSource || wi.initiative) connectedRoadmap++;
10499
+ if (roadmapOrigin && !wi.sourceId) {
10500
+ gaps.missing_source.push(gapItem(wi, "Add `source_id` for this roadmap-originated Work Item."));
10501
+ }
10502
+ if (roadmapOrigin && wi.sourceId) connectedRoadmapCandidates.add(wi.sourceId);
10498
10503
  if (wi.initiative) withInitiative++;
10499
- else gaps.missing_initiative.push(gapItem(wi, "Add `initiative` to connect this Work Item to a delivery initiative."));
10500
10504
  if (wi.knowledgeLevel) withLevel++;
10501
10505
  else gaps.missing_knowledge_level.push(gapItem(wi, "Add `knowledge_level` (K0\u2013K4) to the front matter."));
10502
10506
  for (const g2 of wi.codeGlobs) {
@@ -10518,10 +10522,11 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
10518
10522
  }
10519
10523
  }
10520
10524
  const ownedCodePaths = [...globCounts.values()].reduce((a2, b2) => a2 + b2, 0);
10525
+ const connectedRoadmap = connectedRoadmapCandidates.size;
10521
10526
  const broadGlobs = [...globCounts.keys()].filter((g2) => isBroadGlob(g2)).length;
10522
10527
  for (const [glob, owners] of globOwners) {
10523
10528
  if (owners.length > 1) {
10524
- gaps.ownership_overlaps.push({ code_path: glob, work_items: [...new Set(owners)], suggested_action: "Review whether the overlap is expected or should be narrowed." });
10529
+ gaps.ownership_overlaps.push({ code_path: glob, work_items: [...new Set(owners)], suggested_action: "Shared historical modification path; it is not a conflict unless incompatible ownership is documented." });
10525
10530
  }
10526
10531
  }
10527
10532
  const ownershipOverlaps = gaps.ownership_overlaps.length;
@@ -10593,9 +10598,10 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
10593
10598
  const deliveryTrace = levelFromRatio(
10594
10599
  coverageRatio(withOwnership) * 0.5 + (g.available && g.edges > 0 ? 1 : 0) * 0.25 + (exp.roadmap.present ? 1 : 0) * 0.25
10595
10600
  );
10601
+ const guardHistory = buildGuardHistory(dir);
10596
10602
  const impact_signals = {
10597
10603
  ambiguity_reduction: levelFromRatio(ambiguityRatio),
10598
- drift_prevention: withOwnership > 0 ? "Active" : "Limited",
10604
+ drift_prevention: guardHistory.available && guardHistory.resolved > 0 ? "Observed" : "Unknown",
10599
10605
  onboarding_support: onboarding,
10600
10606
  delivery_traceability: deliveryTrace,
10601
10607
  ai_context_readiness: aiReady,
@@ -10604,17 +10610,19 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
10604
10610
  let score = null;
10605
10611
  let score_breakdown = null;
10606
10612
  if (total > 0) {
10607
- const healthPts = [layerStatus("Business"), layerStatus("Product"), layerStatus("Tech"), layerStatus("Delivery")].filter((s) => s !== "Missing").length / 4 * 20;
10613
+ const layerMaturity = { Consolidated: 1, Structured: 0.8, Traceable: 0.75, Weak: 0.4, Missing: 0 };
10614
+ const healthPts = [layerStatus("Business"), layerStatus("Product"), layerStatus("Tech"), layerStatus("Delivery")].reduce((sum, status) => sum + (layerMaturity[status] ?? 0), 0) / 4 * 20;
10608
10615
  const applicableCoverage = knowledge_coverage.filter((c) => c.label !== "Work Items using optional initiatives");
10609
10616
  const covAvg = applicableCoverage.reduce((a2, c) => a2 + coverageRatio(c.have), 0) / applicableCoverage.length;
10610
10617
  const coveragePts = covAvg * 20;
10611
10618
  const ownPts = coverageRatio(withOwnership) * 15;
10612
- const traceBlend = (exp.roadmap.candidates > 0 ? exp.roadmap.materialized / exp.roadmap.candidates : 1) * 0.5 + coverageRatio(withOwnership) * 0.5;
10619
+ const roadmapTraceRatio = exp.roadmap.candidates > 0 ? Math.min(connectedRoadmap, exp.roadmap.candidates) / exp.roadmap.candidates : null;
10620
+ const traceSignals = [coverageRatio(withOwnership), ...roadmapTraceRatio === null ? [] : [roadmapTraceRatio]];
10621
+ const traceBlend = traceSignals.reduce((sum, value) => sum + value, 0) / traceSignals.length;
10613
10622
  const tracePts = traceBlend * 20;
10614
10623
  const qualityMap = { good: 1, partial: 0.6, sparse: 0.3, empty: 0, unknown: 0 };
10615
10624
  const graphPts = (g.available ? qualityMap[g.quality] ?? 0 : 0) * 15;
10616
10625
  const ctxPts = { Low: 0.25, Medium: 0.5, High: 0.8, "Very High": 1 }[ctxLevel] * 10;
10617
- score = Math.round(healthPts + coveragePts + ownPts + tracePts + graphPts + ctxPts);
10618
10626
  score_breakdown = {
10619
10627
  knowledge_health: { points: Math.round(healthPts), max: 20 },
10620
10628
  knowledge_coverage: { points: Math.round(coveragePts), max: 20 },
@@ -10623,6 +10631,7 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
10623
10631
  graph_quality: { points: Math.round(graphPts), max: 15 },
10624
10632
  context_readiness: { points: Math.round(ctxPts), max: 10 }
10625
10633
  };
10634
+ score = Object.values(score_breakdown).reduce((sum, component) => sum + component.points, 0);
10626
10635
  }
10627
10636
  const idsOf = (items) => items.map((i) => i.id);
10628
10637
  const groupedAction = (items, verb) => {
@@ -10661,7 +10670,7 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
10661
10670
  { id: "work-items.lifecycle", label: "Work Item lifecycle", classification: total > 0 ? "observed" : "unknown", reason: total > 0 ? `${total} Work Item artifact(s) were discovered.` : "No Work Item artifacts were discovered." },
10662
10671
  { id: "delivery.verification", label: "Verified delivery outcomes", classification: verifiedWorkItems > 0 ? "observed" : "unknown", reason: verifiedWorkItems > 0 ? `${verifiedWorkItems} Work Item(s) have persisted validation_status: passed.` : "Acceptance Criteria and Definition of Done sections show declared intent, not completed verification evidence." },
10663
10672
  ...deliveryCapabilityEvidence(dir, projectContext),
10664
- { id: "guard-history", label: "Guard consistency history", classification: buildGuardHistory(dir).available ? "observed" : "unknown", reason: buildGuardHistory(dir).available ? "Recorded Guard runs provide current consistency evidence." : "No recorded Guard history is available." }
10673
+ { id: "guard-history", label: "Guard consistency history", classification: guardHistory.available ? "observed" : "unknown", reason: guardHistory.available ? "Recorded Guard runs provide current consistency evidence." : "No recorded Guard history is available." }
10665
10674
  ],
10666
10675
  scope: g.scope,
10667
10676
  default_scope: "all",
@@ -10699,7 +10708,7 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
10699
10708
  },
10700
10709
  graph_quality: g.available ? { available: true, scope: g.scope, quality: g.quality, nodes: g.nodes, edges: g.edges, hints: g.hints, reason: g.scopeReason, last_exported: g.generatedAt } : { available: false, suggestion: "Run `kaddo graph export --scope all`." },
10701
10710
  guard_activity: (() => {
10702
- const gh = buildGuardHistory(dir);
10711
+ const gh = guardHistory;
10703
10712
  return gh.available ? { available: true, runs_recorded: gh.total_runs, detected: gh.detected, open: gh.open, resolved: gh.resolved, resolution_rate: gh.resolution_rate } : { available: false, note: "Guard history is not persisted. Run `kaddo guard --record` to record runs for trend analysis." };
10704
10713
  })(),
10705
10714
  impact_signals,
@@ -10810,7 +10819,7 @@ function renderImpactMarkdown(r2) {
10810
10819
  L.push("## Impact Signals", "");
10811
10820
  const s = r2.impact_signals;
10812
10821
  L.push(`- Ambiguity reduction: ${s.ambiguity_reduction}`);
10813
- L.push(`- Drift prevention: ${s.drift_prevention}`);
10822
+ L.push(`- Drift prevention evidence: ${s.drift_prevention}`);
10814
10823
  L.push(`- Onboarding support: ${s.onboarding_support}`);
10815
10824
  L.push(`- Delivery traceability: ${s.delivery_traceability}`);
10816
10825
  L.push(`- AI context readiness: ${s.ai_context_readiness}`);
@@ -10845,7 +10854,7 @@ function renderImpactMarkdown(r2) {
10845
10854
  L.push("");
10846
10855
  }
10847
10856
  if (gp.ownership_overlaps.length > 0) {
10848
- L.push("### Ownership overlaps", "");
10857
+ L.push("### Shared code-path history (review only)", "");
10849
10858
  for (const o2 of gp.ownership_overlaps) {
10850
10859
  L.push(`- \`${o2.code_path}\``);
10851
10860
  L.push(` - Owned by: ${o2.work_items.join(", ")}`);
@@ -10853,7 +10862,7 @@ function renderImpactMarkdown(r2) {
10853
10862
  }
10854
10863
  L.push("");
10855
10864
  }
10856
- const anyGaps = gp.missing_source.length + gp.missing_initiative.length + gp.missing_code_ownership.length + gp.missing_knowledge_level.length + gp.missing_acceptance_criteria.length + gp.missing_definition_of_done.length + gp.missing_validation.length + gp.broad_ownership_globs.length + gp.ownership_overlaps.length;
10865
+ const anyGaps = gp.missing_source.length + gp.missing_initiative.length + gp.missing_code_ownership.length + gp.missing_knowledge_level.length + gp.missing_acceptance_criteria.length + gp.missing_definition_of_done.length + gp.missing_validation.length + gp.broad_ownership_globs.length;
10857
10866
  if (anyGaps === 0) {
10858
10867
  L.push("No actionable knowledge gaps detected. \u{1F389}", "");
10859
10868
  }
@@ -11206,6 +11215,9 @@ function renderDriftMarkdown(r2) {
11206
11215
  L.push("## Guard History", "");
11207
11216
  L.push("No guard history recorded yet.");
11208
11217
  L.push("");
11218
+ L.push("## Historical Drift Trend", "");
11219
+ L.push("Not available \u2014 no recorded Guard runs.");
11220
+ L.push("");
11209
11221
  L.push("Run `kaddo guard --record` to start recording drift evidence.");
11210
11222
  L.push("");
11211
11223
  L.push("## Suggested Actions", "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/mcp",
3
- "version": "3.124.0",
3
+ "version": "3.124.2",
4
4
  "description": "MCP server for Kaddo project knowledge: read-only resources/tools/prompts plus safe derived generation under .kaddo/.",
5
5
  "license": "MIT",
6
6
  "repository": {