@kaddo/mcp 3.123.0 → 3.124.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/dist/index.js +113 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10403,6 +10403,39 @@ function buildGuardHistory(dir) {
|
|
|
10403
10403
|
};
|
|
10404
10404
|
}
|
|
10405
10405
|
|
|
10406
|
+
// ../cli/src/core/reporting-evidence.ts
|
|
10407
|
+
function reportingProjectContext(dir) {
|
|
10408
|
+
const config = loadConfig(dir);
|
|
10409
|
+
if (!config) return { state: "unknown", mode: "unknown", repository_structure: "unknown" };
|
|
10410
|
+
return {
|
|
10411
|
+
state: config.project.state,
|
|
10412
|
+
mode: projectMode(config),
|
|
10413
|
+
repository_structure: config.project.structure
|
|
10414
|
+
};
|
|
10415
|
+
}
|
|
10416
|
+
function knowledgeLayerEvidence(context, layer2, present) {
|
|
10417
|
+
const baseline = context.mode === "poc" ? ["Tech", "Delivery"] : ["Business", "Product", "Tech", "Delivery"];
|
|
10418
|
+
if (!baseline.includes(layer2)) {
|
|
10419
|
+
return { id: `knowledge.${layer2.toLowerCase()}`, label: `${layer2} knowledge`, classification: "not_applicable", reason: "This layer is outside the configured POC baseline." };
|
|
10420
|
+
}
|
|
10421
|
+
return {
|
|
10422
|
+
id: `knowledge.${layer2.toLowerCase()}`,
|
|
10423
|
+
label: `${layer2} knowledge`,
|
|
10424
|
+
classification: present ? "observed" : "unknown",
|
|
10425
|
+
reason: present ? "A structured knowledge artifact is present." : "No structured artifact was found; absence is not proof that knowledge does not exist."
|
|
10426
|
+
};
|
|
10427
|
+
}
|
|
10428
|
+
function deliveryCapabilityEvidence(dir, context) {
|
|
10429
|
+
const initiatives = discoverInitiatives(dir);
|
|
10430
|
+
const resources = getResources(dir);
|
|
10431
|
+
const modules = loadMappedModules(dir);
|
|
10432
|
+
return [
|
|
10433
|
+
{ id: "initiatives", label: "Initiatives", classification: initiatives.length ? "observed" : "not_applicable", reason: initiatives.length ? `${initiatives.length} optional Initiative artifact(s) were discovered.` : "Initiatives are optional and no Initiative artifacts were discovered." },
|
|
10434
|
+
{ id: "resources", label: "Project Resources", classification: resources.length ? "observed" : "not_applicable", reason: resources.length ? `${resources.length} Project Resource artifact(s) were discovered.` : "Resources are optional and no Resource artifacts were discovered." },
|
|
10435
|
+
{ id: "multirepo", label: "Multirepo mapping", classification: context.repository_structure === "multirepo" ? modules.length ? "observed" : "unknown" : "not_applicable", reason: context.repository_structure === "multirepo" ? modules.length ? `${modules.length} module mapping(s) were discovered.` : "Project is multirepo but no module mappings were found." : "The project is configured as a monorepo." }
|
|
10436
|
+
];
|
|
10437
|
+
}
|
|
10438
|
+
|
|
10406
10439
|
// ../cli/src/core/impact-report.ts
|
|
10407
10440
|
function isBroadGlob(glob) {
|
|
10408
10441
|
if (!glob.endsWith("/**")) return false;
|
|
@@ -10422,8 +10455,10 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10422
10455
|
const resolvedScope = opts.scope ?? "all";
|
|
10423
10456
|
const scopeSource = opts.scopeSource ?? (opts.scope ? "explicit" : "default");
|
|
10424
10457
|
const exp = buildProjectExplanation(dir);
|
|
10458
|
+
const projectContext = reportingProjectContext(dir);
|
|
10425
10459
|
const wis = discoverWorkItems(dir);
|
|
10426
10460
|
const total = wis.length;
|
|
10461
|
+
const verifiedWorkItems = wis.filter((wi) => wi.validationStatus === "passed").length;
|
|
10427
10462
|
let withOwnership = 0;
|
|
10428
10463
|
let withSource = 0;
|
|
10429
10464
|
let withInitiative = 0;
|
|
@@ -10515,7 +10550,8 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10515
10550
|
const knowledge_coverage = [
|
|
10516
10551
|
{ label: "Work Items with ownership", have: withOwnership, total },
|
|
10517
10552
|
{ label: "Work Items with source", have: withSource, total },
|
|
10518
|
-
|
|
10553
|
+
// Initiatives are optional: report their observed use, but do not use absence as a gap or score input.
|
|
10554
|
+
{ label: "Work Items using optional initiatives", have: withInitiative, total },
|
|
10519
10555
|
{ label: "Work Items with acceptance criteria", have: withAcceptance, total },
|
|
10520
10556
|
{ label: "Work Items with Definition of Done", have: withDoD, total },
|
|
10521
10557
|
{ label: "Work Items with knowledge level", have: withLevel, total }
|
|
@@ -10569,7 +10605,8 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10569
10605
|
let score_breakdown = null;
|
|
10570
10606
|
if (total > 0) {
|
|
10571
10607
|
const healthPts = [layerStatus("Business"), layerStatus("Product"), layerStatus("Tech"), layerStatus("Delivery")].filter((s) => s !== "Missing").length / 4 * 20;
|
|
10572
|
-
const
|
|
10608
|
+
const applicableCoverage = knowledge_coverage.filter((c) => c.label !== "Work Items using optional initiatives");
|
|
10609
|
+
const covAvg = applicableCoverage.reduce((a2, c) => a2 + coverageRatio(c.have), 0) / applicableCoverage.length;
|
|
10573
10610
|
const coveragePts = covAvg * 20;
|
|
10574
10611
|
const ownPts = coverageRatio(withOwnership) * 15;
|
|
10575
10612
|
const traceBlend = (exp.roadmap.candidates > 0 ? exp.roadmap.materialized / exp.roadmap.candidates : 1) * 0.5 + coverageRatio(withOwnership) * 0.5;
|
|
@@ -10600,7 +10637,6 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10600
10637
|
for (const a2 of [
|
|
10601
10638
|
groupedAction(gaps.missing_code_ownership, "Add `code:` ownership to"),
|
|
10602
10639
|
groupedAction(gaps.missing_source, "Add `source`/`source_id` to"),
|
|
10603
|
-
groupedAction(gaps.missing_initiative, "Add an `initiative` to"),
|
|
10604
10640
|
groupedAction(gaps.missing_acceptance_criteria, "Add Acceptance Criteria to"),
|
|
10605
10641
|
groupedAction(gaps.missing_definition_of_done, "Add a Definition of Done to"),
|
|
10606
10642
|
groupedAction(gaps.missing_validation, "Add a validation (How to test it) section to")
|
|
@@ -10619,6 +10655,14 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10619
10655
|
return {
|
|
10620
10656
|
generated_at: now.toISOString(),
|
|
10621
10657
|
project: exp.project.name,
|
|
10658
|
+
project_context: projectContext,
|
|
10659
|
+
evidence: [
|
|
10660
|
+
...["Business", "Product", "Tech", "Delivery"].map((layer2) => knowledgeLayerEvidence(projectContext, layer2, layerStatus(layer2) !== "Missing")),
|
|
10661
|
+
{ 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
|
+
{ 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
|
+
...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." }
|
|
10665
|
+
],
|
|
10622
10666
|
scope: g.scope,
|
|
10623
10667
|
default_scope: "all",
|
|
10624
10668
|
scope_source: scopeSource,
|
|
@@ -10673,9 +10717,10 @@ function renderImpactMarkdown(r2) {
|
|
|
10673
10717
|
L.push("# Kaddo Knowledge Impact Report", "");
|
|
10674
10718
|
L.push(`Generated at: ${r2.generated_at}`);
|
|
10675
10719
|
L.push(`Project: ${r2.project}`);
|
|
10720
|
+
L.push(`Project context: state=${r2.project_context.state}; mode=${r2.project_context.mode}; repositories=${r2.project_context.repository_structure}`);
|
|
10676
10721
|
L.push(`Scope: ${r2.scope}`);
|
|
10677
|
-
if (r2.score !== null) L.push(`Knowledge Impact Score: ${r2.score}/100`);
|
|
10678
|
-
else L.push("Knowledge Impact Score: not available");
|
|
10722
|
+
if (r2.score !== null) L.push(`Legacy Knowledge Impact Score: ${r2.score}/100 (deprecated; use Evidence and Applicability)`);
|
|
10723
|
+
else L.push("Legacy Knowledge Impact Score: not available");
|
|
10679
10724
|
if (r2.scope_source === "default") {
|
|
10680
10725
|
L.push("Scope note: Impact reports use `all` by default to measure accumulated knowledge impact.");
|
|
10681
10726
|
} else if (r2.scope === "active" && r2.graph_quality.available === false) {
|
|
@@ -10685,6 +10730,9 @@ function renderImpactMarkdown(r2) {
|
|
|
10685
10730
|
L.push("## Executive Summary", "");
|
|
10686
10731
|
for (const s2 of r2.executive_summary) L.push(`- ${s2}`);
|
|
10687
10732
|
L.push("");
|
|
10733
|
+
L.push("## Evidence and Applicability", "");
|
|
10734
|
+
for (const item of r2.evidence) L.push(`- ${item.label}: ${item.classification} \u2014 ${item.reason}`);
|
|
10735
|
+
L.push("");
|
|
10688
10736
|
L.push("## Knowledge Health", "");
|
|
10689
10737
|
for (const [k2, v] of Object.entries(r2.knowledge_health)) L.push(`- ${k2}: ${v}`);
|
|
10690
10738
|
L.push("");
|
|
@@ -10856,6 +10904,7 @@ function loadAssumptions(dir) {
|
|
|
10856
10904
|
source: "file",
|
|
10857
10905
|
assumptions: {
|
|
10858
10906
|
currency: raw?.currency ?? DEFAULT_ASSUMPTIONS.currency,
|
|
10907
|
+
...typeof raw?.calibrated_at === "string" && raw.calibrated_at.trim() ? { calibrated_at: raw.calibrated_at.trim() } : {},
|
|
10859
10908
|
hourly_cost: num(raw?.hourly_cost, DEFAULT_ASSUMPTIONS.hourly_cost),
|
|
10860
10909
|
context_preparation_minutes_saved_per_work_item: num(a2.context_preparation_minutes_saved_per_work_item, DEFAULT_ASSUMPTIONS.context_preparation_minutes_saved_per_work_item),
|
|
10861
10910
|
rework_hours_avoided_per_resolved_drift: num(a2.rework_hours_avoided_per_resolved_drift, DEFAULT_ASSUMPTIONS.rework_hours_avoided_per_resolved_drift),
|
|
@@ -10882,6 +10931,7 @@ var SAVINGS_DISCLAIMER = "These are evidence-based estimates, not exact ROI. Adj
|
|
|
10882
10931
|
function buildSavingsReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
10883
10932
|
const { assumptions: a2, source: source3 } = loadAssumptions(dir);
|
|
10884
10933
|
const impact = buildImpactReport(dir, { scope: opts.scope, scopeSource: opts.scopeSource }, now);
|
|
10934
|
+
const projectContext = reportingProjectContext(dir);
|
|
10885
10935
|
const completed = impact.traceability.completed_work_items;
|
|
10886
10936
|
const wiWithOwnership = parseRatioNumerator(impact.traceability.work_items_connected_to_code);
|
|
10887
10937
|
const acceptanceCov = impact.knowledge_coverage.find((c) => c.label.toLowerCase().includes("acceptance"));
|
|
@@ -10913,20 +10963,28 @@ function buildSavingsReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10913
10963
|
reason: "Guard history exists, but no resolved drift warnings have been recorded yet."
|
|
10914
10964
|
};
|
|
10915
10965
|
}
|
|
10916
|
-
const
|
|
10917
|
-
const
|
|
10966
|
+
const observedHours = round2(ctxPrepH + reviewH + clarH + driftSavings.hours);
|
|
10967
|
+
const projectedHours = round2(onboardH + archH);
|
|
10968
|
+
const observedValue = Math.round(observedHours * a2.hourly_cost);
|
|
10969
|
+
const projectedValue = Math.round(projectedHours * a2.hourly_cost);
|
|
10918
10970
|
const reasons = [];
|
|
10919
10971
|
let level;
|
|
10920
|
-
|
|
10972
|
+
const verifiedDelivery = impact.evidence.some((item) => item.id === "delivery.verification" && item.classification === "observed");
|
|
10973
|
+
const evidenceStrong = graphQuality === "good" && impact.ownership_coverage.coverage_percent >= 70 && verifiedDelivery;
|
|
10974
|
+
if (!evidenceStrong || graphQuality === "empty") {
|
|
10921
10975
|
level = "Low";
|
|
10922
|
-
reasons.push("
|
|
10923
|
-
} else if (
|
|
10976
|
+
reasons.push("Delivery, ownership or graph evidence is insufficient for a reliable estimate.");
|
|
10977
|
+
} else if (evidenceStrong && source3 === "file" && Boolean(a2.calibrated_at) && guard.available && guard.resolved > 0) {
|
|
10924
10978
|
level = "High";
|
|
10925
|
-
reasons.push("Strong evidence,
|
|
10979
|
+
reasons.push("Strong evidence, calibrated assumptions and recorded drift resolution.");
|
|
10926
10980
|
} else {
|
|
10927
10981
|
level = "Medium";
|
|
10928
10982
|
reasons.push("Strong knowledge and graph evidence.");
|
|
10929
10983
|
}
|
|
10984
|
+
if (!a2.calibrated_at && level === "High") {
|
|
10985
|
+
level = "Medium";
|
|
10986
|
+
reasons.push("Uncalibrated assumptions cannot support High confidence.");
|
|
10987
|
+
}
|
|
10930
10988
|
if (!guard.available) {
|
|
10931
10989
|
reasons.push("Guard history is not persisted yet \u2014 avoided rework is not estimated.");
|
|
10932
10990
|
} else if (guard.resolved > 0) {
|
|
@@ -10951,7 +11009,15 @@ function buildSavingsReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10951
11009
|
return {
|
|
10952
11010
|
generated_at: now.toISOString(),
|
|
10953
11011
|
project: impact.project,
|
|
11012
|
+
project_context: projectContext,
|
|
10954
11013
|
scope: impact.scope,
|
|
11014
|
+
reporting_period: { observed: "all recorded project history", projected: "per month", note: "Historical estimates and future monthly projections are intentionally not added together." },
|
|
11015
|
+
evidence_classification: [
|
|
11016
|
+
{ id: "completed-work-items", label: "Completed Work Items", classification: completed > 0 ? "observed" : "unknown", reason: completed > 0 ? "Lifecycle state is recorded in Work Items." : "No completed Work Items were recorded." },
|
|
11017
|
+
{ id: "guard-resolution", label: "Resolved drift warnings", classification: guard.available ? "observed" : "unknown", reason: guard.available ? "Derived from recorded Guard history." : "No Guard history was recorded." },
|
|
11018
|
+
{ id: "assumptions", label: "Savings assumptions", classification: "estimated", reason: a2.calibrated_at ? `Project assumptions were calibrated on ${a2.calibrated_at}.` : source3 === "file" ? "Project-provided assumptions are not marked as calibrated." : "Defaults are uncalibrated estimates." },
|
|
11019
|
+
{ id: "team-expectations", label: "Future team activity", classification: "projected", reason: "Monthly contributor and Work Item expectations model a future scenario." }
|
|
11020
|
+
],
|
|
10955
11021
|
currency: a2.currency,
|
|
10956
11022
|
disclaimer: SAVINGS_DISCLAIMER,
|
|
10957
11023
|
assumptions_source: source3,
|
|
@@ -10985,7 +11051,11 @@ function buildSavingsReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10985
11051
|
architecture_discovery: { hours: archH, formula: `${a2.architecture_discovery_hours_saved_when_graph_good} h \xD7 ${graphMult.toFixed(2)} graph multiplier` },
|
|
10986
11052
|
drift_prevention: driftSavings
|
|
10987
11053
|
},
|
|
10988
|
-
|
|
11054
|
+
totals: {
|
|
11055
|
+
observed_history_estimate: { estimated_hours: observedHours, estimated_value: observedValue, currency: a2.currency },
|
|
11056
|
+
monthly_projection: { estimated_hours: projectedHours, estimated_value: projectedValue, currency: a2.currency }
|
|
11057
|
+
},
|
|
11058
|
+
total: { estimated_hours_saved: observedHours, estimated_value: observedValue, currency: a2.currency },
|
|
10989
11059
|
confidence: { level, reasons },
|
|
10990
11060
|
suggested_actions: actions
|
|
10991
11061
|
};
|
|
@@ -10995,14 +11065,18 @@ function renderSavingsMarkdown(r2) {
|
|
|
10995
11065
|
L.push("# Kaddo Estimated Savings Report", "");
|
|
10996
11066
|
L.push(`Generated at: ${r2.generated_at}`);
|
|
10997
11067
|
L.push(`Project: ${r2.project}`);
|
|
11068
|
+
L.push(`Project context: state=${r2.project_context.state}; mode=${r2.project_context.mode}; repositories=${r2.project_context.repository_structure}`);
|
|
10998
11069
|
L.push(`Scope: ${r2.scope}`);
|
|
10999
11070
|
L.push(`Currency: ${r2.currency}`);
|
|
11000
11071
|
L.push("");
|
|
11001
11072
|
L.push("## Disclaimer", "");
|
|
11002
11073
|
L.push(r2.disclaimer, "");
|
|
11074
|
+
L.push("## Evidence Classification", "");
|
|
11075
|
+
for (const item of r2.evidence_classification) L.push(`- ${item.label}: ${item.classification} \u2014 ${item.reason}`);
|
|
11076
|
+
L.push("");
|
|
11003
11077
|
L.push("## Executive Summary", "");
|
|
11004
|
-
L.push(`-
|
|
11005
|
-
L.push(`-
|
|
11078
|
+
L.push(`- Historical estimate: ${r2.totals.observed_history_estimate.estimated_hours} hours`);
|
|
11079
|
+
L.push(`- Monthly projection: ${r2.totals.monthly_projection.estimated_hours} hours`);
|
|
11006
11080
|
L.push(`- Confidence: ${r2.confidence.level}`);
|
|
11007
11081
|
if (r2.assumptions_source === "default") L.push("- Using default assumptions. Run `kaddo savings init` to customize them.");
|
|
11008
11082
|
L.push("");
|
|
@@ -11055,9 +11129,10 @@ function renderSavingsMarkdown(r2) {
|
|
|
11055
11129
|
L.push("- Not available yet.");
|
|
11056
11130
|
L.push(`- Reason: ${s.drift_prevention.reason}`, "");
|
|
11057
11131
|
}
|
|
11058
|
-
L.push("## Total", "");
|
|
11059
|
-
L.push(`-
|
|
11060
|
-
L.push(`-
|
|
11132
|
+
L.push("## Total (Period-separated)", "");
|
|
11133
|
+
L.push(`- Historical estimate (all recorded project history): ${r2.totals.observed_history_estimate.estimated_hours} h / ${r2.totals.observed_history_estimate.estimated_value} ${r2.currency}`);
|
|
11134
|
+
L.push(`- Monthly projection: ${r2.totals.monthly_projection.estimated_hours} h / ${r2.totals.monthly_projection.estimated_value} ${r2.currency}`);
|
|
11135
|
+
L.push(`- Note: ${r2.reporting_period.note}`);
|
|
11061
11136
|
L.push("");
|
|
11062
11137
|
L.push("## Confidence", "");
|
|
11063
11138
|
L.push(`Confidence: ${r2.confidence.level}`, "", "Reason:");
|
|
@@ -11076,6 +11151,14 @@ function serializeSavingsJson(r2) {
|
|
|
11076
11151
|
function buildDriftReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
11077
11152
|
const h2 = buildGuardHistory(dir);
|
|
11078
11153
|
const project = loadConfig(dir)?.project.name ?? "unknown";
|
|
11154
|
+
const projectContext = reportingProjectContext(dir);
|
|
11155
|
+
const workItems = discoverWorkItems(dir);
|
|
11156
|
+
const verificationEvidence = workItems.filter((wi) => wi.validationStatus && wi.validationStatus !== "not-started");
|
|
11157
|
+
const plans = getDeprecationPlans(dir);
|
|
11158
|
+
const deprecationFindings = plans.flatMap((plan) => getDeprecationPlan(dir, plan.id)?.targets.flatMap(validateTarget) ?? []);
|
|
11159
|
+
const config = loadConfig(dir);
|
|
11160
|
+
const topology = config ? buildGraph(dir, config, { scope: "all" }, now) : null;
|
|
11161
|
+
const topologyHints = topology ? buildGraphHints(dir, topology, now).summary.hints : null;
|
|
11079
11162
|
const actions = [];
|
|
11080
11163
|
if (!h2.available) {
|
|
11081
11164
|
actions.push("Run `kaddo guard --record` to start recording guard history.");
|
|
@@ -11087,6 +11170,13 @@ function buildDriftReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
11087
11170
|
return {
|
|
11088
11171
|
generated_at: now.toISOString(),
|
|
11089
11172
|
project,
|
|
11173
|
+
project_context: projectContext,
|
|
11174
|
+
consistency_evidence: [
|
|
11175
|
+
{ id: "guard-current-consistency", label: "Current Guard consistency", classification: h2.available ? "observed" : "unknown", reason: h2.available ? `${h2.total_runs} recorded Guard run(s) provide deterministic consistency evidence.` : "No recorded Guard history is available." },
|
|
11176
|
+
{ id: "lifecycle-consistency", label: "Lifecycle evidence consistency", classification: verificationEvidence.length > 0 ? "observed" : "unknown", reason: verificationEvidence.length > 0 ? `${verificationEvidence.length} Work Item(s) persist an implementation validation status.` : "No persisted Work Item validation status is available." },
|
|
11177
|
+
{ id: "deprecation-consistency", label: "Deprecation consistency", classification: plans.length === 0 ? "not_applicable" : deprecationFindings.length === 0 ? "derived" : "observed", reason: plans.length === 0 ? "No deprecation plans exist in this project." : deprecationFindings.length === 0 ? `${plans.length} plan(s) passed deterministic target consistency checks.` : `${deprecationFindings.length} deterministic deprecation consistency finding(s) were detected.` },
|
|
11178
|
+
{ id: "topology-consistency", label: "Knowledge topology consistency", classification: topology === null ? "unknown" : topologyHints === 0 ? "derived" : "observed", reason: topology === null ? "No project configuration is available to construct the topology." : topologyHints === 0 ? `The in-memory topology has ${topology.nodes.length} node(s) and no open deterministic hints.` : `The in-memory topology has ${topologyHints} open deterministic hint(s).` }
|
|
11179
|
+
],
|
|
11090
11180
|
guard_history: {
|
|
11091
11181
|
available: h2.available,
|
|
11092
11182
|
total_runs: h2.total_runs,
|
|
@@ -11107,6 +11197,10 @@ function renderDriftMarkdown(r2) {
|
|
|
11107
11197
|
L.push("# Kaddo Drift Trend Report", "");
|
|
11108
11198
|
L.push(`Generated at: ${r2.generated_at}`);
|
|
11109
11199
|
L.push(`Project: ${r2.project}`);
|
|
11200
|
+
L.push(`Project context: state=${r2.project_context.state}; mode=${r2.project_context.mode}; repositories=${r2.project_context.repository_structure}`);
|
|
11201
|
+
L.push("");
|
|
11202
|
+
L.push("## Consistency Evidence", "");
|
|
11203
|
+
for (const item of r2.consistency_evidence) L.push(`- ${item.label}: ${item.classification} \u2014 ${item.reason}`);
|
|
11110
11204
|
L.push("");
|
|
11111
11205
|
if (!r2.guard_history.available) {
|
|
11112
11206
|
L.push("## Guard History", "");
|
|
@@ -11174,6 +11268,8 @@ function serializeDriftJson(r2) {
|
|
|
11174
11268
|
const out = {
|
|
11175
11269
|
generated_at: r2.generated_at,
|
|
11176
11270
|
project: r2.project,
|
|
11271
|
+
project_context: r2.project_context,
|
|
11272
|
+
consistency_evidence: r2.consistency_evidence,
|
|
11177
11273
|
guard_history: r2.guard_history,
|
|
11178
11274
|
drift_warnings: r2.drift_warnings,
|
|
11179
11275
|
hotspots: r2.hotspots,
|
package/package.json
CHANGED