@kaddo/mcp 3.124.2 → 3.124.3
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 +169 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10404,6 +10404,20 @@ function buildGuardHistory(dir) {
|
|
|
10404
10404
|
}
|
|
10405
10405
|
|
|
10406
10406
|
// ../cli/src/core/reporting-evidence.ts
|
|
10407
|
+
function graphHintFinding(hint) {
|
|
10408
|
+
const affected = [hint.artifact_id, ...hint.path ? [hint.path] : []];
|
|
10409
|
+
return {
|
|
10410
|
+
id: `graph-hint:${hint.artifact_id}:${hint.missing.join(",")}`,
|
|
10411
|
+
category: "topology",
|
|
10412
|
+
source: "graph-hints",
|
|
10413
|
+
affected_artifacts: affected,
|
|
10414
|
+
// Graph Hints are intentionally informational; review is useful but not a blocking error.
|
|
10415
|
+
priority: "medium",
|
|
10416
|
+
evidence: hint.reason,
|
|
10417
|
+
explanation: hint.message,
|
|
10418
|
+
suggested_action: `Review the declared relationships for ${hint.artifact_id}${hint.path ? ` at ${hint.path}` : ""}.`
|
|
10419
|
+
};
|
|
10420
|
+
}
|
|
10407
10421
|
function reportingProjectContext(dir) {
|
|
10408
10422
|
const config = loadConfig(dir);
|
|
10409
10423
|
if (!config) return { state: "unknown", mode: "unknown", repository_structure: "unknown" };
|
|
@@ -10458,7 +10472,11 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10458
10472
|
const projectContext = reportingProjectContext(dir);
|
|
10459
10473
|
const wis = discoverWorkItems(dir);
|
|
10460
10474
|
const total = wis.length;
|
|
10461
|
-
const
|
|
10475
|
+
const completedWis = wis.filter((wi) => wi.lifecycle === "completed");
|
|
10476
|
+
const verifiedWorkItems = completedWis.filter((wi) => wi.validationStatus === "passed").length;
|
|
10477
|
+
const failedValidationWorkItems = completedWis.filter((wi) => wi.validationStatus === "failed").length;
|
|
10478
|
+
const pendingValidationWorkItems = completedWis.filter((wi) => Boolean(wi.validationStatus) && !["passed", "failed"].includes(wi.validationStatus)).length;
|
|
10479
|
+
const notRecordedValidationWorkItems = completedWis.length - verifiedWorkItems - failedValidationWorkItems - pendingValidationWorkItems;
|
|
10462
10480
|
let withOwnership = 0;
|
|
10463
10481
|
let withSource = 0;
|
|
10464
10482
|
let withInitiative = 0;
|
|
@@ -10531,10 +10549,12 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10531
10549
|
}
|
|
10532
10550
|
const ownershipOverlaps = gaps.ownership_overlaps.length;
|
|
10533
10551
|
let g;
|
|
10552
|
+
let graphHintEntries = [];
|
|
10534
10553
|
const config = loadConfig(dir);
|
|
10535
10554
|
if (config) {
|
|
10536
10555
|
const graph = buildGraph(dir, config, { scope: resolvedScope }, now);
|
|
10537
10556
|
const hints = buildGraphHints(dir, graph, now);
|
|
10557
|
+
graphHintEntries = hints.hints;
|
|
10538
10558
|
g = { available: true, scope: graph.scope, scopeReason: graph.scope_reason, nodes: graph.nodes.length, edges: graph.edges.length, quality: hints.quality, hints: hints.summary.hints, generatedAt: graph.generated_at };
|
|
10539
10559
|
} else {
|
|
10540
10560
|
g = { available: false, scope: resolvedScope, scopeReason: "", nodes: 0, edges: 0, quality: "unknown", hints: 0, generatedAt: "" };
|
|
@@ -10607,6 +10627,37 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10607
10627
|
ai_context_readiness: aiReady,
|
|
10608
10628
|
maintenance_readiness: levelFromRatio((coverageRatio(withOwnership) + (deliveryTraceable ? 1 : 0)) / 2)
|
|
10609
10629
|
};
|
|
10630
|
+
const baselineLayers = projectContext.mode === "poc" ? ["Tech", "Delivery"] : ["Business", "Product", "Tech", "Delivery"];
|
|
10631
|
+
const findings = [];
|
|
10632
|
+
for (const layer2 of baselineLayers) {
|
|
10633
|
+
const status = layerStatus(layer2);
|
|
10634
|
+
if (status !== "Weak" && status !== "Missing") continue;
|
|
10635
|
+
findings.push({
|
|
10636
|
+
id: `knowledge-health:${layer2.toLowerCase()}`,
|
|
10637
|
+
category: "knowledge",
|
|
10638
|
+
source: "knowledge-health",
|
|
10639
|
+
affected_artifacts: [layer2],
|
|
10640
|
+
priority: status === "Missing" ? "high" : "medium",
|
|
10641
|
+
evidence: `${layer2} knowledge maturity is ${status}.`,
|
|
10642
|
+
explanation: `This assesses documented ${layer2} knowledge, not the quality of the product or implementation.`,
|
|
10643
|
+
suggested_action: `Review ${layer2} knowledge coverage and the artifacts or relationships available for it.`
|
|
10644
|
+
});
|
|
10645
|
+
}
|
|
10646
|
+
for (const gap of gaps.missing_code_ownership) {
|
|
10647
|
+
findings.push({
|
|
10648
|
+
id: `ownership:${gap.id}`,
|
|
10649
|
+
category: "delivery",
|
|
10650
|
+
source: "work-item-ownership",
|
|
10651
|
+
affected_artifacts: [gap.id, gap.path],
|
|
10652
|
+
priority: "medium",
|
|
10653
|
+
evidence: "A corrective Work Item has no declared code ownership.",
|
|
10654
|
+
explanation: gap.title,
|
|
10655
|
+
suggested_action: gap.suggested_action
|
|
10656
|
+
});
|
|
10657
|
+
}
|
|
10658
|
+
findings.push(...graphHintEntries.map(graphHintFinding));
|
|
10659
|
+
const priorityOrder = { high: 0, medium: 1, low: 2, unknown: 3 };
|
|
10660
|
+
findings.sort((a2, b2) => priorityOrder[a2.priority] - priorityOrder[b2.priority] || a2.id.localeCompare(b2.id));
|
|
10610
10661
|
let score = null;
|
|
10611
10662
|
let score_breakdown = null;
|
|
10612
10663
|
if (total > 0) {
|
|
@@ -10645,16 +10696,18 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10645
10696
|
if (exp.roadmap.remaining > 0) actions.push(`Materialize the ${exp.roadmap.remaining} remaining roadmap candidate(s) with \`kaddo create --from roadmap\`.`);
|
|
10646
10697
|
for (const a2 of [
|
|
10647
10698
|
groupedAction(gaps.missing_code_ownership, "Add `code:` ownership to"),
|
|
10648
|
-
groupedAction(gaps.missing_source, "Add `source`/`source_id` to")
|
|
10649
|
-
groupedAction(gaps.missing_acceptance_criteria, "Add Acceptance Criteria to"),
|
|
10650
|
-
groupedAction(gaps.missing_definition_of_done, "Add a Definition of Done to"),
|
|
10651
|
-
groupedAction(gaps.missing_validation, "Add a validation (How to test it) section to")
|
|
10699
|
+
groupedAction(gaps.missing_source, "Add `source`/`source_id` to")
|
|
10652
10700
|
]) if (a2) actions.push(a2);
|
|
10653
10701
|
if (gaps.broad_ownership_globs.length > 0) actions.push(`Narrow ${gaps.broad_ownership_globs.length} broad ownership glob(s) into specific paths.`);
|
|
10654
|
-
|
|
10702
|
+
for (const finding of findings) {
|
|
10703
|
+
if (!actions.includes(finding.suggested_action)) actions.push(finding.suggested_action);
|
|
10704
|
+
}
|
|
10655
10705
|
if (skills.length === 0) actions.push("Install reusable skills with `kaddo add skills`.");
|
|
10656
10706
|
actions.push("Run `kaddo guard` before committing to catch knowledge drift.");
|
|
10657
10707
|
const summary = [];
|
|
10708
|
+
if (completedWis.length > 0) {
|
|
10709
|
+
summary.push(`Delivery evidence: ${completedWis.length} completed; ${verifiedWorkItems} validation passed; ${notRecordedValidationWorkItems} not confirmed by persisted validation.`);
|
|
10710
|
+
}
|
|
10658
10711
|
if (total > 0) summary.push(`${withOwnership}/${total} Work Items include code ownership.`);
|
|
10659
10712
|
if (g.available) summary.push(`The knowledge graph is ${g.quality} with ${g.nodes} nodes and ${g.edges} edges (${g.scope} scope).`);
|
|
10660
10713
|
else summary.push("The knowledge graph has not been exported yet.");
|
|
@@ -10676,6 +10729,15 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10676
10729
|
default_scope: "all",
|
|
10677
10730
|
scope_source: scopeSource,
|
|
10678
10731
|
executive_summary: summary,
|
|
10732
|
+
delivery_evidence: {
|
|
10733
|
+
completed: completedWis.length,
|
|
10734
|
+
validation_passed: verifiedWorkItems,
|
|
10735
|
+
validation_failed: failedValidationWorkItems,
|
|
10736
|
+
validation_pending: pendingValidationWorkItems,
|
|
10737
|
+
validation_not_recorded: notRecordedValidationWorkItems,
|
|
10738
|
+
completion_with_passed_validation_percent: completedWis.length > 0 ? Math.round(verifiedWorkItems / completedWis.length * 1e3) / 10 : null
|
|
10739
|
+
},
|
|
10740
|
+
findings,
|
|
10679
10741
|
knowledge_health,
|
|
10680
10742
|
knowledge_coverage,
|
|
10681
10743
|
ownership_coverage: {
|
|
@@ -10739,6 +10801,27 @@ function renderImpactMarkdown(r2) {
|
|
|
10739
10801
|
L.push("## Executive Summary", "");
|
|
10740
10802
|
for (const s2 of r2.executive_summary) L.push(`- ${s2}`);
|
|
10741
10803
|
L.push("");
|
|
10804
|
+
L.push("## Key Findings", "");
|
|
10805
|
+
if (r2.findings.length === 0) L.push("No current findings detected by the executed deterministic checks.");
|
|
10806
|
+
if (r2.findings.length > 0) {
|
|
10807
|
+
const cell = (value) => value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
10808
|
+
L.push("| Priority | Source | Affected | Finding | Suggested action |");
|
|
10809
|
+
L.push("|---|---|---|---|---|");
|
|
10810
|
+
for (const finding of r2.findings) {
|
|
10811
|
+
L.push(`| ${finding.priority} | ${cell(finding.source)} | ${cell(finding.affected_artifacts.join(", ") || "not available")} | ${cell(finding.explanation)} Evidence: ${cell(finding.evidence)} | ${cell(finding.suggested_action)} |`);
|
|
10812
|
+
}
|
|
10813
|
+
}
|
|
10814
|
+
L.push("");
|
|
10815
|
+
L.push("## Delivery Evidence", "");
|
|
10816
|
+
const de = r2.delivery_evidence;
|
|
10817
|
+
L.push(`- Completed Work Items: ${de.completed}`);
|
|
10818
|
+
L.push(`- Validation passed: ${de.validation_passed}`);
|
|
10819
|
+
L.push(`- Validation failed: ${de.validation_failed}`);
|
|
10820
|
+
L.push(`- Validation pending: ${de.validation_pending}`);
|
|
10821
|
+
L.push(`- Validation not recorded: ${de.validation_not_recorded}`);
|
|
10822
|
+
L.push(`- Completion with passed validation: ${de.completion_with_passed_validation_percent === null ? "not available" : `${de.completion_with_passed_validation_percent}%`}`);
|
|
10823
|
+
L.push("- \u201CNot recorded\u201D means persisted evidence is absent; it does not prove validation never happened.");
|
|
10824
|
+
L.push("");
|
|
10742
10825
|
L.push("## Evidence and Applicability", "");
|
|
10743
10826
|
for (const item of r2.evidence) L.push(`- ${item.label}: ${item.classification} \u2014 ${item.reason}`);
|
|
10744
10827
|
L.push("");
|
|
@@ -10838,12 +10921,7 @@ function renderImpactMarkdown(r2) {
|
|
|
10838
10921
|
L.push("");
|
|
10839
10922
|
};
|
|
10840
10923
|
gapSection("Work Items missing source", gp.missing_source);
|
|
10841
|
-
gapSection("Work Items missing initiative", gp.missing_initiative);
|
|
10842
10924
|
gapSection("Work Items missing code ownership", gp.missing_code_ownership);
|
|
10843
|
-
gapSection("Work Items missing knowledge level", gp.missing_knowledge_level);
|
|
10844
|
-
gapSection("Work Items missing acceptance criteria", gp.missing_acceptance_criteria);
|
|
10845
|
-
gapSection("Work Items missing Definition of Done", gp.missing_definition_of_done);
|
|
10846
|
-
gapSection("Work Items missing validation", gp.missing_validation);
|
|
10847
10925
|
if (gp.broad_ownership_globs.length > 0) {
|
|
10848
10926
|
L.push("### Broad ownership globs", "");
|
|
10849
10927
|
for (const b2 of gp.broad_ownership_globs) {
|
|
@@ -10862,10 +10940,26 @@ function renderImpactMarkdown(r2) {
|
|
|
10862
10940
|
}
|
|
10863
10941
|
L.push("");
|
|
10864
10942
|
}
|
|
10865
|
-
const anyGaps = gp.missing_source.length + gp.
|
|
10943
|
+
const anyGaps = gp.missing_source.length + gp.missing_code_ownership.length + gp.broad_ownership_globs.length;
|
|
10866
10944
|
if (anyGaps === 0) {
|
|
10867
10945
|
L.push("No actionable knowledge gaps detected. \u{1F389}", "");
|
|
10868
10946
|
}
|
|
10947
|
+
const historical = [
|
|
10948
|
+
["knowledge level", gp.missing_knowledge_level],
|
|
10949
|
+
["Acceptance Criteria", gp.missing_acceptance_criteria],
|
|
10950
|
+
["Definition of Done", gp.missing_definition_of_done],
|
|
10951
|
+
["validation section", gp.missing_validation]
|
|
10952
|
+
];
|
|
10953
|
+
L.push("## Historical Documentation Completeness", "");
|
|
10954
|
+
for (const [label, items] of historical) {
|
|
10955
|
+
const completed = items.filter((item) => item.status === "completed");
|
|
10956
|
+
if (completed.length > 0) L.push(`- Completed Work Items without detected ${label}: ${completed.length}`);
|
|
10957
|
+
}
|
|
10958
|
+
if (!historical.some(([, items]) => items.some((item) => item.status === "completed"))) {
|
|
10959
|
+
L.push("No historical documentation completeness gaps were detected.");
|
|
10960
|
+
}
|
|
10961
|
+
L.push("- This is an inventory for review, not a recommendation to rewrite historical Work Items merely to increase a metric.");
|
|
10962
|
+
L.push("");
|
|
10869
10963
|
if (r2.score_breakdown) {
|
|
10870
10964
|
L.push("## Score Breakdown", "");
|
|
10871
10965
|
const b2 = r2.score_breakdown;
|
|
@@ -11015,6 +11109,16 @@ function buildSavingsReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
11015
11109
|
} else {
|
|
11016
11110
|
actions.push("Use drift history to calibrate `rework_hours_avoided_per_resolved_drift`.");
|
|
11017
11111
|
}
|
|
11112
|
+
const calibrationOpportunities = !a2.calibrated_at ? {
|
|
11113
|
+
available: true,
|
|
11114
|
+
reason: source3 === "default" ? "Default assumptions are uncalibrated estimates." : "Project assumptions are not marked as calibrated.",
|
|
11115
|
+
opportunities: [
|
|
11116
|
+
{ area: "Context preparation", suggested_evidence: "Compare preparation effort on comparable tasks before and after using the knowledge artifacts." },
|
|
11117
|
+
{ area: "Review effort", suggested_evidence: "Record a baseline for comparable reviews with similar ownership coverage." },
|
|
11118
|
+
{ area: "Clarification reduction", suggested_evidence: "Estimate effort spent resolving repeated scope or context questions." },
|
|
11119
|
+
{ area: "Architecture discovery", suggested_evidence: "Compare discovery time for similar dependency or relationship analyses." }
|
|
11120
|
+
]
|
|
11121
|
+
} : { available: false, reason: `Assumptions are marked as calibrated on ${a2.calibrated_at}.`, opportunities: [] };
|
|
11018
11122
|
return {
|
|
11019
11123
|
generated_at: now.toISOString(),
|
|
11020
11124
|
project: impact.project,
|
|
@@ -11066,6 +11170,7 @@ function buildSavingsReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
11066
11170
|
},
|
|
11067
11171
|
total: { estimated_hours_saved: observedHours, estimated_value: observedValue, currency: a2.currency },
|
|
11068
11172
|
confidence: { level, reasons },
|
|
11173
|
+
calibration_opportunities: calibrationOpportunities,
|
|
11069
11174
|
suggested_actions: actions
|
|
11070
11175
|
};
|
|
11071
11176
|
}
|
|
@@ -11147,6 +11252,17 @@ function renderSavingsMarkdown(r2) {
|
|
|
11147
11252
|
L.push(`Confidence: ${r2.confidence.level}`, "", "Reason:");
|
|
11148
11253
|
for (const reason of r2.confidence.reasons) L.push(`- ${reason}`);
|
|
11149
11254
|
L.push("");
|
|
11255
|
+
L.push("## Calibration Opportunities", "");
|
|
11256
|
+
if (!r2.calibration_opportunities.available) {
|
|
11257
|
+
L.push(`- ${r2.calibration_opportunities.reason}`);
|
|
11258
|
+
} else {
|
|
11259
|
+
L.push(`- ${r2.calibration_opportunities.reason}`);
|
|
11260
|
+
L.push("- Use external, aggregate project observations; do not collect or store personal data.");
|
|
11261
|
+
for (const opportunity of r2.calibration_opportunities.opportunities) {
|
|
11262
|
+
L.push(`- ${opportunity.area}: ${opportunity.suggested_evidence}`);
|
|
11263
|
+
}
|
|
11264
|
+
}
|
|
11265
|
+
L.push("");
|
|
11150
11266
|
L.push("## Suggested Actions", "");
|
|
11151
11267
|
r2.suggested_actions.forEach((act, i) => L.push(`${i + 1}. ${act}`));
|
|
11152
11268
|
L.push("");
|
|
@@ -11167,10 +11283,24 @@ function buildDriftReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
11167
11283
|
const deprecationFindings = plans.flatMap((plan) => getDeprecationPlan(dir, plan.id)?.targets.flatMap(validateTarget) ?? []);
|
|
11168
11284
|
const config = loadConfig(dir);
|
|
11169
11285
|
const topology = config ? buildGraph(dir, config, { scope: "all" }, now) : null;
|
|
11170
|
-
const
|
|
11286
|
+
const graphHints = topology ? buildGraphHints(dir, topology, now) : null;
|
|
11287
|
+
const topologyHints = graphHints?.summary.hints ?? null;
|
|
11288
|
+
const currentConsistencyFindings = [
|
|
11289
|
+
...graphHints?.hints.map(graphHintFinding) ?? [],
|
|
11290
|
+
...deprecationFindings.map((finding, index) => ({
|
|
11291
|
+
id: `deprecation-target:${index + 1}`,
|
|
11292
|
+
category: "consistency",
|
|
11293
|
+
source: "deprecation-target-validation",
|
|
11294
|
+
affected_artifacts: [],
|
|
11295
|
+
priority: "medium",
|
|
11296
|
+
evidence: String(finding),
|
|
11297
|
+
explanation: "A deterministic deprecation target consistency check reported a finding.",
|
|
11298
|
+
suggested_action: "Review the affected deprecation target and its declared lifecycle evidence."
|
|
11299
|
+
}))
|
|
11300
|
+
];
|
|
11171
11301
|
const actions = [];
|
|
11172
11302
|
if (!h2.available) {
|
|
11173
|
-
actions.push("
|
|
11303
|
+
actions.push("Start recording Guard runs at relevant delivery checkpoints with `kaddo guard --record`; one run creates an observation, while multiple comparable runs are needed for a historical trend.");
|
|
11174
11304
|
} else {
|
|
11175
11305
|
if (h2.open > 0) actions.push("Review open drift warnings and update related Work Items or ownership.");
|
|
11176
11306
|
actions.push("Run `kaddo guard --record` before important commits.");
|
|
@@ -11186,6 +11316,11 @@ function buildDriftReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
11186
11316
|
{ 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.` },
|
|
11187
11317
|
{ 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).` }
|
|
11188
11318
|
],
|
|
11319
|
+
current_consistency_findings: currentConsistencyFindings,
|
|
11320
|
+
structural_consistency: {
|
|
11321
|
+
deprecation_target_checks: plans.length === 0 ? "not_applicable" : deprecationFindings.length === 0 ? "passed" : "findings_detected",
|
|
11322
|
+
note: plans.length === 0 ? "No deprecation plans exist in this project." : "Target consistency checks validate declared structural state only; they do not verify operational removal from infrastructure, production or external consumers."
|
|
11323
|
+
},
|
|
11189
11324
|
guard_history: {
|
|
11190
11325
|
available: h2.available,
|
|
11191
11326
|
total_runs: h2.total_runs,
|
|
@@ -11211,6 +11346,24 @@ function renderDriftMarkdown(r2) {
|
|
|
11211
11346
|
L.push("## Consistency Evidence", "");
|
|
11212
11347
|
for (const item of r2.consistency_evidence) L.push(`- ${item.label}: ${item.classification} \u2014 ${item.reason}`);
|
|
11213
11348
|
L.push("");
|
|
11349
|
+
L.push("## Current Consistency Findings", "");
|
|
11350
|
+
if (r2.current_consistency_findings.length === 0) {
|
|
11351
|
+
L.push("No findings detected by the executed consistency checks.");
|
|
11352
|
+
L.push("");
|
|
11353
|
+
}
|
|
11354
|
+
if (r2.current_consistency_findings.length > 0) {
|
|
11355
|
+
const cell = (value) => value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
11356
|
+
L.push("| Priority | Source | Affected | Finding | Suggested action |");
|
|
11357
|
+
L.push("|---|---|---|---|---|");
|
|
11358
|
+
for (const finding of r2.current_consistency_findings) {
|
|
11359
|
+
L.push(`| ${finding.priority} | ${cell(finding.source)} | ${cell(finding.affected_artifacts.join(", ") || "not available")} | ${cell(finding.explanation)} Evidence: ${cell(finding.evidence)} | ${cell(finding.suggested_action)} |`);
|
|
11360
|
+
}
|
|
11361
|
+
L.push("");
|
|
11362
|
+
}
|
|
11363
|
+
L.push("## Structural Consistency Boundaries", "");
|
|
11364
|
+
L.push(`- Deprecation target checks: ${r2.structural_consistency.deprecation_target_checks}`);
|
|
11365
|
+
L.push(`- Note: ${r2.structural_consistency.note}`);
|
|
11366
|
+
L.push("");
|
|
11214
11367
|
if (!r2.guard_history.available) {
|
|
11215
11368
|
L.push("## Guard History", "");
|
|
11216
11369
|
L.push("No guard history recorded yet.");
|
|
@@ -11282,6 +11435,8 @@ function serializeDriftJson(r2) {
|
|
|
11282
11435
|
project: r2.project,
|
|
11283
11436
|
project_context: r2.project_context,
|
|
11284
11437
|
consistency_evidence: r2.consistency_evidence,
|
|
11438
|
+
current_consistency_findings: r2.current_consistency_findings,
|
|
11439
|
+
structural_consistency: r2.structural_consistency,
|
|
11285
11440
|
guard_history: r2.guard_history,
|
|
11286
11441
|
drift_warnings: r2.drift_warnings,
|
|
11287
11442
|
hotspots: r2.hotspots,
|
package/package.json
CHANGED