@kaddo/mcp 3.92.0 → 3.95.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.
Files changed (2) hide show
  1. package/dist/index.js +643 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4904,7 +4904,8 @@ var IMPLEMENTATION_PLANNING = skill(
4904
4904
 
4905
4905
  ## Purpose
4906
4906
 
4907
- Standardize the plan produced before implementation starts.
4907
+ Standardize the plan produced before implementation starts and ensure design deliberation is
4908
+ explicit before coding begins.
4908
4909
 
4909
4910
  ## When to use
4910
4911
 
@@ -4912,33 +4913,96 @@ Before writing code for a ready Work Item.
4912
4913
 
4913
4914
  ## Inputs
4914
4915
 
4915
- The context pack and the ready Work Item.
4916
+ Assemble context proportionally from the Build Contract's five sources:
4917
+
4918
+ 1. **Work Item:** outcome, acceptance criteria, constraints, out-of-scope, affected_modules, domains.
4919
+ 2. **Knowledge:** business, product, tech and delivery knowledge relevant to the Work Item's domains.
4920
+ 3. **System Context:** topology, module dependencies, system graph when available.
4921
+ 4. **Repository Context:** existing patterns, file structure, test conventions in affected modules.
4922
+ 5. **Related Work Items:** dependencies (depends_on), completed related Work Items for precedent.
4923
+
4924
+ ## Context assembly
4925
+
4926
+ Assemble proportionally to scope. A single-module bugfix needs the affected module's codebase
4927
+ and tests. A cross-cutting feature needs topology, multiple modules, and business context.
4928
+ Do not load everything \u2014 load what the scope demands.
4916
4929
 
4917
4930
  ## Output
4918
4931
 
4919
- A plan with: technical scope, expected files, risks, validations, out of scope, implementation
4920
- steps, and stop criteria (when to pause and ask).
4932
+ A plan covering the template below, ending with a confirmation gate.
4933
+
4934
+ ### Output template
4935
+
4936
+ \`\`\`markdown
4937
+ # Implementation Plan \u2014 <WI id>
4938
+
4939
+ ## Context Summary
4940
+ <!-- Relevant knowledge, system context, and repository observations assembled for this WI. -->
4941
+
4942
+ ## Design Deliberation
4943
+
4944
+ ### Technical Approach
4945
+ <!-- How this will be implemented. Be specific about patterns, modules, layers involved. -->
4946
+
4947
+ ### Rationale
4948
+ <!-- Why this approach. Reference existing patterns, constraints, or WI requirements. -->
4949
+
4950
+ ### Alternatives Considered
4951
+ <!-- When the change is non-trivial. May be omitted for trivial/obvious changes with a note. -->
4952
+
4953
+ ### Trade-offs
4954
+ <!-- When alternatives exist. Explicitly state what is gained and lost. -->
4955
+
4956
+ ### ADR Recommendation
4957
+ <!-- When the decision is architecturally significant: recommend materializing as ADR
4958
+ via adr-writing skill. Remove this section if not applicable. -->
4959
+
4960
+ ## Affected Areas
4961
+ <!-- Modules, files, surfaces impacted by this change. -->
4962
+
4963
+ ## Implementation Steps
4964
+ <!-- Numbered steps with expected files per step. -->
4965
+
4966
+ ## Validation Plan
4967
+ <!-- How to verify: test commands, manual steps, AC verification. -->
4968
+
4969
+ ## Stop Criteria
4970
+ <!-- When to pause and ask: scope expansion, contradictions, missing knowledge,
4971
+ architectural uncertainty. -->
4972
+
4973
+ ## Confirmation Gate
4974
+ Do not start coding without explicit human confirmation of this plan.
4975
+ \`\`\`
4921
4976
 
4922
4977
  ## Rules
4923
4978
 
4979
+ - Document Technical Approach and Rationale before listing implementation steps.
4924
4980
  - Do not start coding without confirmation.
4925
4981
  - Do not expand scope without updating the Work Item.
4926
4982
  - Never make commits or push \u2014 suggest only.
4927
4983
  - Review scope coverage before planning: check that expected result, current/target behavior,
4928
4984
  module coverage, and acceptance criteria are consistent. Flag contradictions (e.g., user-facing
4929
4985
  change with unassessed frontend module).
4986
+ - When you discover an architecturally significant decision during planning, recommend the
4987
+ adr-writing skill and pause.
4988
+ - When alternatives exist, document them. For trivial or obvious changes, Alternatives and
4989
+ Trade-offs may be omitted with a note explaining why.
4990
+ - Context assembly is proportional: do not load all project knowledge for a small fix.
4930
4991
 
4931
4992
  ## Quality checklist
4932
4993
 
4933
4994
  - Pre-implementation scope review is documented.
4995
+ - Technical Approach is documented with specific patterns and modules.
4996
+ - Rationale references WI requirements or existing project patterns.
4997
+ - Alternatives documented when non-trivial, or explicitly noted as not applicable.
4998
+ - ADR recommendation present when the decision is architecturally significant.
4999
+ - Context sources consulted are listed in Context Summary.
4934
5000
  - Scope and expected files are explicit.
4935
5001
  - Risks and validations are listed.
5002
+ - Validation plan includes how to verify each AC.
4936
5003
  - Stop criteria are defined.
4937
5004
  - Module coverage aligns with planned changes.
4938
-
4939
- ## Example output
4940
-
4941
- A numbered plan covering the sections above, ending with a request to confirm before coding.
5005
+ - Confirmation gate is present.
4942
5006
  `
4943
5007
  );
4944
5008
  var MODULE_CONTEXT_REFINEMENT = skill(
@@ -4993,6 +5057,56 @@ A refined \`module-context.md\` with real, project-specific content in all secti
4993
5057
  A \`module-context.md\` with all placeholder sections filled in.
4994
5058
  `
4995
5059
  );
5060
+ var EVIDENCE_VERIFICATION = skill(
5061
+ "evidence-verification",
5062
+ "Evidence Verification Skill",
5063
+ "delivery",
5064
+ ["implementation-agent", "guard-agent"],
5065
+ `
5066
+ # Evidence Verification Skill
5067
+
5068
+ ## Purpose
5069
+
5070
+ Estandarizar la recolecci\xF3n de evidencia de implementaci\xF3n y la verificaci\xF3n de Criterios de
5071
+ Aceptaci\xF3n antes de completar un Work Item.
5072
+
5073
+ ## When to use
5074
+
5075
+ Despu\xE9s de que la implementaci\xF3n y las pruebas de un Work Item terminan, antes de llamar
5076
+ \`kaddo learn\`.
5077
+
5078
+ ## Inputs
5079
+
5080
+ - El Work Item (id, ACs, affected_modules, release_gates, completion_exceptions).
5081
+ - El diff o lista de archivos modificados.
5082
+ - Resultados de pruebas y validaciones.
5083
+ - Excepciones propuestas con categor\xEDa e impacto.
5084
+
5085
+ ## Output
5086
+
5087
+ Un reporte de verificaci\xF3n: estado por AC, release gates, excepciones, desviaciones planned vs
5088
+ actual, y decisi\xF3n de completitud (READY_TO_COMPLETE | NEEDS_WORK | BLOCKED | READY_WITH_EXCEPTIONS).
5089
+
5090
+ ## Rules
5091
+
5092
+ - Nunca marcar un AC como passed sin evidencia concreta.
5093
+ - Nunca omitir un release gate fallido sin registrar una excepci\xF3n aceptada.
5094
+ - No incluir rutas de secretos en changed_paths.
5095
+ - Usar \`kaddo verify\` o MCP tools \`kaddo_collect_evidence\`/\`kaddo_verify_work_item\`.
5096
+
5097
+ ## Quality checklist
5098
+
5099
+ - Cada AC tiene un status expl\xEDcito.
5100
+ - Los release gates fallidos tienen blocker documentado.
5101
+ - Las excepciones aceptadas tienen approved_by y raz\xF3n.
5102
+ - No hay rutas de secretos en la evidencia.
5103
+ - La decisi\xF3n de completitud es coherente con ACs y gates.
5104
+
5105
+ ## Example output
5106
+
5107
+ Un reporte de verificaci\xF3n con ACs, gates, excepciones y decisi\xF3n de completitud.
5108
+ `
5109
+ );
4996
5110
  var SKILLS = [
4997
5111
  ADR_WRITING,
4998
5112
  WORK_ITEM_REFINEMENT,
@@ -5001,10 +5115,11 @@ var SKILLS = [
5001
5115
  CAPSULE_WRITING,
5002
5116
  LEARNING_CAPTURE,
5003
5117
  IMPLEMENTATION_PLANNING,
5004
- MODULE_CONTEXT_REFINEMENT
5118
+ MODULE_CONTEXT_REFINEMENT,
5119
+ EVIDENCE_VERIFICATION
5005
5120
  ];
5006
5121
  var SKILL_GROUPS = {
5007
- delivery: ["work-item-refinement", "implementation-planning", "learning-capture"],
5122
+ delivery: ["work-item-refinement", "implementation-planning", "learning-capture", "evidence-verification"],
5008
5123
  tech: ["adr-writing", "ownership-suggestion", "graph-metadata-review", "module-context-refinement"],
5009
5124
  integration: ["capsule-writing"]
5010
5125
  };
@@ -12686,7 +12801,8 @@ var IMPLEMENTATION_PLANNING2 = skill2(
12686
12801
 
12687
12802
  ## Purpose
12688
12803
 
12689
- Standardize the plan produced before implementation starts.
12804
+ Standardize the plan produced before implementation starts and ensure design deliberation is
12805
+ explicit before coding begins.
12690
12806
 
12691
12807
  ## When to use
12692
12808
 
@@ -12694,33 +12810,96 @@ Before writing code for a ready Work Item.
12694
12810
 
12695
12811
  ## Inputs
12696
12812
 
12697
- The context pack and the ready Work Item.
12813
+ Assemble context proportionally from the Build Contract's five sources:
12814
+
12815
+ 1. **Work Item:** outcome, acceptance criteria, constraints, out-of-scope, affected_modules, domains.
12816
+ 2. **Knowledge:** business, product, tech and delivery knowledge relevant to the Work Item's domains.
12817
+ 3. **System Context:** topology, module dependencies, system graph when available.
12818
+ 4. **Repository Context:** existing patterns, file structure, test conventions in affected modules.
12819
+ 5. **Related Work Items:** dependencies (depends_on), completed related Work Items for precedent.
12820
+
12821
+ ## Context assembly
12822
+
12823
+ Assemble proportionally to scope. A single-module bugfix needs the affected module's codebase
12824
+ and tests. A cross-cutting feature needs topology, multiple modules, and business context.
12825
+ Do not load everything \u2014 load what the scope demands.
12698
12826
 
12699
12827
  ## Output
12700
12828
 
12701
- A plan with: technical scope, expected files, risks, validations, out of scope, implementation
12702
- steps, and stop criteria (when to pause and ask).
12829
+ A plan covering the template below, ending with a confirmation gate.
12830
+
12831
+ ### Output template
12832
+
12833
+ \`\`\`markdown
12834
+ # Implementation Plan \u2014 <WI id>
12835
+
12836
+ ## Context Summary
12837
+ <!-- Relevant knowledge, system context, and repository observations assembled for this WI. -->
12838
+
12839
+ ## Design Deliberation
12840
+
12841
+ ### Technical Approach
12842
+ <!-- How this will be implemented. Be specific about patterns, modules, layers involved. -->
12843
+
12844
+ ### Rationale
12845
+ <!-- Why this approach. Reference existing patterns, constraints, or WI requirements. -->
12846
+
12847
+ ### Alternatives Considered
12848
+ <!-- When the change is non-trivial. May be omitted for trivial/obvious changes with a note. -->
12849
+
12850
+ ### Trade-offs
12851
+ <!-- When alternatives exist. Explicitly state what is gained and lost. -->
12852
+
12853
+ ### ADR Recommendation
12854
+ <!-- When the decision is architecturally significant: recommend materializing as ADR
12855
+ via adr-writing skill. Remove this section if not applicable. -->
12856
+
12857
+ ## Affected Areas
12858
+ <!-- Modules, files, surfaces impacted by this change. -->
12859
+
12860
+ ## Implementation Steps
12861
+ <!-- Numbered steps with expected files per step. -->
12862
+
12863
+ ## Validation Plan
12864
+ <!-- How to verify: test commands, manual steps, AC verification. -->
12865
+
12866
+ ## Stop Criteria
12867
+ <!-- When to pause and ask: scope expansion, contradictions, missing knowledge,
12868
+ architectural uncertainty. -->
12869
+
12870
+ ## Confirmation Gate
12871
+ Do not start coding without explicit human confirmation of this plan.
12872
+ \`\`\`
12703
12873
 
12704
12874
  ## Rules
12705
12875
 
12876
+ - Document Technical Approach and Rationale before listing implementation steps.
12706
12877
  - Do not start coding without confirmation.
12707
12878
  - Do not expand scope without updating the Work Item.
12708
12879
  - Never make commits or push \u2014 suggest only.
12709
12880
  - Review scope coverage before planning: check that expected result, current/target behavior,
12710
12881
  module coverage, and acceptance criteria are consistent. Flag contradictions (e.g., user-facing
12711
12882
  change with unassessed frontend module).
12883
+ - When you discover an architecturally significant decision during planning, recommend the
12884
+ adr-writing skill and pause.
12885
+ - When alternatives exist, document them. For trivial or obvious changes, Alternatives and
12886
+ Trade-offs may be omitted with a note explaining why.
12887
+ - Context assembly is proportional: do not load all project knowledge for a small fix.
12712
12888
 
12713
12889
  ## Quality checklist
12714
12890
 
12715
12891
  - Pre-implementation scope review is documented.
12892
+ - Technical Approach is documented with specific patterns and modules.
12893
+ - Rationale references WI requirements or existing project patterns.
12894
+ - Alternatives documented when non-trivial, or explicitly noted as not applicable.
12895
+ - ADR recommendation present when the decision is architecturally significant.
12896
+ - Context sources consulted are listed in Context Summary.
12716
12897
  - Scope and expected files are explicit.
12717
12898
  - Risks and validations are listed.
12899
+ - Validation plan includes how to verify each AC.
12718
12900
  - Stop criteria are defined.
12719
12901
  - Module coverage aligns with planned changes.
12720
-
12721
- ## Example output
12722
-
12723
- A numbered plan covering the sections above, ending with a request to confirm before coding.
12902
+ - Confirmation gate is present.
12724
12903
  `
12725
12904
  );
12726
12905
  var MODULE_CONTEXT_REFINEMENT2 = skill2(
@@ -12775,6 +12954,56 @@ A refined \`module-context.md\` with real, project-specific content in all secti
12775
12954
  A \`module-context.md\` with all placeholder sections filled in.
12776
12955
  `
12777
12956
  );
12957
+ var EVIDENCE_VERIFICATION2 = skill2(
12958
+ "evidence-verification",
12959
+ "Evidence Verification Skill",
12960
+ "delivery",
12961
+ ["implementation-agent", "guard-agent"],
12962
+ `
12963
+ # Evidence Verification Skill
12964
+
12965
+ ## Purpose
12966
+
12967
+ Estandarizar la recolecci\xF3n de evidencia de implementaci\xF3n y la verificaci\xF3n de Criterios de
12968
+ Aceptaci\xF3n antes de completar un Work Item.
12969
+
12970
+ ## When to use
12971
+
12972
+ Despu\xE9s de que la implementaci\xF3n y las pruebas de un Work Item terminan, antes de llamar
12973
+ \`kaddo learn\`.
12974
+
12975
+ ## Inputs
12976
+
12977
+ - El Work Item (id, ACs, affected_modules, release_gates, completion_exceptions).
12978
+ - El diff o lista de archivos modificados.
12979
+ - Resultados de pruebas y validaciones.
12980
+ - Excepciones propuestas con categor\xEDa e impacto.
12981
+
12982
+ ## Output
12983
+
12984
+ Un reporte de verificaci\xF3n: estado por AC, release gates, excepciones, desviaciones planned vs
12985
+ actual, y decisi\xF3n de completitud (READY_TO_COMPLETE | NEEDS_WORK | BLOCKED | READY_WITH_EXCEPTIONS).
12986
+
12987
+ ## Rules
12988
+
12989
+ - Nunca marcar un AC como passed sin evidencia concreta.
12990
+ - Nunca omitir un release gate fallido sin registrar una excepci\xF3n aceptada.
12991
+ - No incluir rutas de secretos en changed_paths.
12992
+ - Usar \`kaddo verify\` o MCP tools \`kaddo_collect_evidence\`/\`kaddo_verify_work_item\`.
12993
+
12994
+ ## Quality checklist
12995
+
12996
+ - Cada AC tiene un status expl\xEDcito.
12997
+ - Los release gates fallidos tienen blocker documentado.
12998
+ - Las excepciones aceptadas tienen approved_by y raz\xF3n.
12999
+ - No hay rutas de secretos en la evidencia.
13000
+ - La decisi\xF3n de completitud es coherente con ACs y gates.
13001
+
13002
+ ## Example output
13003
+
13004
+ Un reporte de verificaci\xF3n con ACs, gates, excepciones y decisi\xF3n de completitud.
13005
+ `
13006
+ );
12778
13007
  var SKILLS2 = [
12779
13008
  ADR_WRITING2,
12780
13009
  WORK_ITEM_REFINEMENT2,
@@ -12783,10 +13012,11 @@ var SKILLS2 = [
12783
13012
  CAPSULE_WRITING2,
12784
13013
  LEARNING_CAPTURE2,
12785
13014
  IMPLEMENTATION_PLANNING2,
12786
- MODULE_CONTEXT_REFINEMENT2
13015
+ MODULE_CONTEXT_REFINEMENT2,
13016
+ EVIDENCE_VERIFICATION2
12787
13017
  ];
12788
13018
  var SKILL_GROUPS2 = {
12789
- delivery: ["work-item-refinement", "implementation-planning", "learning-capture"],
13019
+ delivery: ["work-item-refinement", "implementation-planning", "learning-capture", "evidence-verification"],
12790
13020
  tech: ["adr-writing", "ownership-suggestion", "graph-metadata-review", "module-context-refinement"],
12791
13021
  integration: ["capsule-writing"]
12792
13022
  };
@@ -15583,6 +15813,103 @@ var USER_FACING_KEYWORDS_ES = [
15583
15813
  "mensaje"
15584
15814
  ];
15585
15815
  var USER_FACING_KEYWORDS = /* @__PURE__ */ new Set([...USER_FACING_KEYWORDS_EN, ...USER_FACING_KEYWORDS_ES]);
15816
+ function analyzeCrossRepoEvidence(input) {
15817
+ const findings = [];
15818
+ const { id, lifecycle, implementationStatus, validationStatus, releaseStatus, affectedModules } = input;
15819
+ const raw = input.rawFrontmatter;
15820
+ const evidence = raw.implementation_evidence;
15821
+ const repos = evidence?.repositories ?? {};
15822
+ const releaseGates = Array.isArray(raw.release_gates) ? raw.release_gates : [];
15823
+ const exceptions = Array.isArray(raw.completion_exceptions) ? raw.completion_exceptions : [];
15824
+ const repoEvidence = {};
15825
+ for (const [repoId, data] of Object.entries(repos)) {
15826
+ const d3 = data;
15827
+ repoEvidence[repoId] = {
15828
+ role: String(d3.role ?? (repoId === "core" ? "core" : "module")),
15829
+ status: String(d3.status ?? "unknown")
15830
+ };
15831
+ }
15832
+ for (const mod of affectedModules) {
15833
+ if (mod === "core") continue;
15834
+ if (!input.registeredModuleIds.includes(mod)) {
15835
+ findings.push({ id, severity: "blocking", message: `Affected module "${mod}" is not registered in .kaddo/modules.yml.` });
15836
+ }
15837
+ }
15838
+ for (const repoId of input.modifiedRepoIds) {
15839
+ if (!affectedModules.includes(repoId) && repoId !== "core") {
15840
+ findings.push({ id, severity: "blocking", message: `Repository "${repoId}" was modified but not declared in affected_modules.` });
15841
+ }
15842
+ }
15843
+ for (const mod of affectedModules) {
15844
+ if (!repoEvidence[mod] && Object.keys(repos).length > 0) {
15845
+ findings.push({ id, severity: "warning", message: `Declared affected module "${mod}" has no implementation evidence.` });
15846
+ }
15847
+ }
15848
+ for (const [repoId, data] of Object.entries(repos)) {
15849
+ const d3 = data;
15850
+ const validations = Array.isArray(d3.validations) ? d3.validations : [];
15851
+ for (const v of validations) {
15852
+ if (v.status === "not-run") {
15853
+ findings.push({ id, severity: "warning", message: `Validation "${v.command}" in ${repoId} was not executed.` });
15854
+ }
15855
+ }
15856
+ const migrations = Array.isArray(d3.migrations) ? d3.migrations : [];
15857
+ for (const m2 of migrations) {
15858
+ if (m2.status === "blocked") {
15859
+ findings.push({ id, severity: "warning", message: `Migration "${m2.id}" (${m2.environment}) in ${repoId} is blocked.` });
15860
+ }
15861
+ }
15862
+ }
15863
+ if (lifecycle === "completed") {
15864
+ const proposedExceptions = exceptions.filter((e) => e.status === "proposed");
15865
+ if (proposedExceptions.length > 0) {
15866
+ findings.push({ id, severity: "blocking", message: "Work Item is completed but has proposed (not accepted) exceptions." });
15867
+ }
15868
+ if (releaseStatus === "ready") {
15869
+ const blockedGates = releaseGates.filter((g) => g.status === "blocked" || g.status === "failed");
15870
+ if (blockedGates.length > 0) {
15871
+ findings.push({ id, severity: "blocking", message: `Release status is "ready" but ${blockedGates.length} gate(s) are blocked/failed.` });
15872
+ }
15873
+ }
15874
+ }
15875
+ for (const [repoId, data] of Object.entries(repos)) {
15876
+ const d3 = data;
15877
+ const validations = Array.isArray(d3.validations) ? d3.validations : [];
15878
+ for (const v of validations) {
15879
+ if (v.status === "passed" && (!v.command || !v.command.trim())) {
15880
+ findings.push({ id, severity: "blocking", message: `Evidence in ${repoId} marked "passed" without a command record.` });
15881
+ }
15882
+ }
15883
+ }
15884
+ if (validationStatus === "accepted-with-exceptions") {
15885
+ const hasExceptions = exceptions.length > 0;
15886
+ const hasValidationGate = releaseGates.some(
15887
+ (g) => (g.status === "pending" || g.status === "blocked") && (g.id.includes("validation") || g.id.includes("test"))
15888
+ );
15889
+ if (!hasExceptions && !hasValidationGate) {
15890
+ findings.push({ id, severity: "warning", message: "Validation status is accepted-with-exceptions, but no exception evidence was found." });
15891
+ }
15892
+ }
15893
+ if (raw.status === "done") {
15894
+ findings.push({ id, severity: "warning", message: "Legacy status `done` detected. Canonical status is `completed`." });
15895
+ }
15896
+ if (raw.refined_by && raw.implemented_by && raw.refined_by === raw.implemented_by) {
15897
+ findings.push({ id, severity: "fyi", message: "refined_by and implemented_by point to the same agent." });
15898
+ }
15899
+ const historicalDefault = lifecycle === "completed" || lifecycle === "archived" ? "not-assessed" : "not-started";
15900
+ return {
15901
+ id,
15902
+ lifecycle,
15903
+ implementationStatus: implementationStatus || historicalDefault,
15904
+ validationStatus: validationStatus || historicalDefault,
15905
+ releaseStatus: releaseStatus || "not-assessed",
15906
+ affectedModules,
15907
+ findings,
15908
+ releaseGates,
15909
+ completionExceptions: exceptions,
15910
+ repoEvidence
15911
+ };
15912
+ }
15586
15913
  var TOPOLOGY_FILE = "knowledge/tech/system-topology.yml";
15587
15914
  var SYSTEM_ENTITY_KINDS = /* @__PURE__ */ new Set([
15588
15915
  "system",
@@ -16435,6 +16762,228 @@ function buildRefinementHandoff(dir, workItemId) {
16435
16762
  text: lines.join("\n")
16436
16763
  };
16437
16764
  }
16765
+ var WorkItemNotInProgressError = class extends Error {
16766
+ constructor(workItemId, actualState) {
16767
+ super(`Work Item "${workItemId}" must be in "in-progress" state for verification, but is "${actualState}".`);
16768
+ this.workItemId = workItemId;
16769
+ this.actualState = actualState;
16770
+ this.name = "WorkItemNotInProgressError";
16771
+ }
16772
+ workItemId;
16773
+ actualState;
16774
+ };
16775
+ var SECRET_PATTERNS = [
16776
+ /\.env($|\.)/i,
16777
+ /credential/i,
16778
+ /secret/i,
16779
+ /token/i,
16780
+ /\.key$/i,
16781
+ /\.pem$/i,
16782
+ /\.p12$/i,
16783
+ /\.pfx$/i
16784
+ ];
16785
+ function filterSecretPaths(paths) {
16786
+ return paths.filter((p2) => !SECRET_PATTERNS.some((re) => re.test(p2)));
16787
+ }
16788
+ function collectImplementationEvidence(dir, workItemId, input) {
16789
+ const artifacts = discoverWorkItems2(dir);
16790
+ const match = artifacts.find((a2) => (a2.id || a2.title) === workItemId);
16791
+ if (!match) throw new WorkItemNotFoundError(workItemId);
16792
+ const lifecycle = lifecycleStateOf2({ status: match.status, filePath: match.filePath });
16793
+ if (lifecycle !== "in-progress") throw new WorkItemNotInProgressError(workItemId, lifecycle);
16794
+ const repositories = {};
16795
+ for (const repo of input.repos) {
16796
+ repositories[repo.repoId] = {
16797
+ role: repo.role ?? (repo.repoId === "core" ? "core" : "module"),
16798
+ status: deriveRepoStatus(repo),
16799
+ changed_paths: filterSecretPaths(repo.changedPaths),
16800
+ validations: repo.validations.map((v) => ({
16801
+ command: v.command,
16802
+ status: v.status,
16803
+ ...v.reason ? { reason: v.reason } : {}
16804
+ })),
16805
+ ...repo.migrations?.length ? {
16806
+ migrations: repo.migrations.map((m2) => ({
16807
+ id: m2.id,
16808
+ environment: m2.environment,
16809
+ status: m2.status,
16810
+ ...m2.reason ? { reason: m2.reason } : {}
16811
+ }))
16812
+ } : {}
16813
+ };
16814
+ }
16815
+ return { repositories };
16816
+ }
16817
+ function verifyWorkItem(dir, workItemId, input) {
16818
+ const evidence = collectImplementationEvidence(dir, workItemId, input);
16819
+ const artifacts = discoverWorkItems2(dir);
16820
+ const match = artifacts.find((a2) => (a2.id || a2.title) === workItemId);
16821
+ const lifecycle = lifecycleStateOf2({ status: match.status, filePath: match.filePath });
16822
+ const fm = match.rawFrontmatter;
16823
+ const acVerifications = mapACVerifications(input.acVerifications);
16824
+ const acSummary = computeACSummary(acVerifications);
16825
+ const releaseGates = Array.isArray(fm.release_gates) ? fm.release_gates : [];
16826
+ const completionExceptions = Array.isArray(fm.completion_exceptions) ? fm.completion_exceptions : [];
16827
+ const plannedVsActual = computePlannedVsActual(match.affectedModules, input.repos);
16828
+ const registeredModuleIds = loadMappedModules2(dir).map((m2) => m2.id);
16829
+ const modifiedRepoIds = input.repos.map((r2) => r2.repoId);
16830
+ const crossRepo = analyzeCrossRepoEvidence({
16831
+ id: workItemId,
16832
+ lifecycle,
16833
+ implementationStatus: match.implementationStatus || "not-started",
16834
+ validationStatus: match.validationStatus || "not-started",
16835
+ releaseStatus: match.releaseStatus || "not-assessed",
16836
+ affectedModules: match.affectedModules,
16837
+ rawFrontmatter: fm,
16838
+ registeredModuleIds,
16839
+ modifiedRepoIds
16840
+ });
16841
+ const validationStatus = deriveValidationStatus(input.repos, acVerifications, completionExceptions);
16842
+ const implementationStatus = deriveImplementationStatus(input.repos);
16843
+ return {
16844
+ workItemId,
16845
+ lifecycle,
16846
+ implementationEvidence: evidence,
16847
+ acVerifications,
16848
+ acSummary,
16849
+ releaseGates,
16850
+ completionExceptions,
16851
+ findings: crossRepo.findings,
16852
+ plannedVsActual,
16853
+ validationStatus,
16854
+ implementationStatus
16855
+ };
16856
+ }
16857
+ function evaluateCompletion(verification) {
16858
+ const blockers = [];
16859
+ const warnings = [];
16860
+ const reasons = [];
16861
+ for (const gate of verification.releaseGates) {
16862
+ if (gate.status === "failed" || gate.status === "blocked") {
16863
+ blockers.push(`Release gate "${gate.id}" is ${gate.status}${gate.reason ? ": " + gate.reason : ""}.`);
16864
+ } else if (gate.status === "pending") {
16865
+ warnings.push(`Release gate "${gate.id}" is still pending.`);
16866
+ }
16867
+ }
16868
+ for (const ex of verification.completionExceptions) {
16869
+ if (ex.status === "rejected") {
16870
+ blockers.push(`Completion exception "${ex.id}" was rejected${ex.reason ? ": " + ex.reason : ""}.`);
16871
+ } else if (ex.status === "proposed") {
16872
+ warnings.push(`Completion exception "${ex.id}" is still proposed (not yet accepted).`);
16873
+ }
16874
+ }
16875
+ if (verification.acSummary.failed > 0) {
16876
+ const failedACs = verification.acVerifications.filter((ac) => ac.status === "failed");
16877
+ for (const ac of failedACs) {
16878
+ blockers.push(`AC failed: "${ac.criterion}".`);
16879
+ }
16880
+ }
16881
+ const blockingFindings = verification.findings.filter((f3) => f3.severity === "blocking");
16882
+ for (const f3 of blockingFindings) {
16883
+ blockers.push(f3.message);
16884
+ }
16885
+ if (verification.acSummary.manualReview > 0) {
16886
+ warnings.push(`${verification.acSummary.manualReview} AC(s) require manual review.`);
16887
+ }
16888
+ if (verification.acSummary.notVerified > 0) {
16889
+ warnings.push(`${verification.acSummary.notVerified} AC(s) not yet verified.`);
16890
+ }
16891
+ const warningFindings = verification.findings.filter((f3) => f3.severity === "warning");
16892
+ for (const f3 of warningFindings) {
16893
+ warnings.push(f3.message);
16894
+ }
16895
+ if (verification.plannedVsActual) {
16896
+ const pva = verification.plannedVsActual;
16897
+ if (pva.missingModules.length > 0) {
16898
+ warnings.push(`Planned modules not touched: ${pva.missingModules.join(", ")}.`);
16899
+ }
16900
+ if (pva.addedModules.length > 0) {
16901
+ warnings.push(`Unplanned modules modified: ${pva.addedModules.join(", ")}.`);
16902
+ }
16903
+ }
16904
+ let readiness;
16905
+ if (blockers.length > 0) {
16906
+ const hasOnlyACFailures = blockers.every((b2) => b2.startsWith("AC failed:"));
16907
+ if (hasOnlyACFailures) {
16908
+ readiness = "NEEDS_WORK";
16909
+ reasons.push("Acceptance criteria have failures that must be addressed.");
16910
+ } else {
16911
+ readiness = "BLOCKED";
16912
+ reasons.push("Blocking conditions prevent completion.");
16913
+ }
16914
+ } else {
16915
+ const hasAcceptedExceptions = verification.completionExceptions.some((e) => e.status === "accepted");
16916
+ if (hasAcceptedExceptions) {
16917
+ readiness = "READY_WITH_EXCEPTIONS";
16918
+ reasons.push("All required criteria pass. Accepted exceptions are documented.");
16919
+ } else {
16920
+ readiness = "READY_TO_COMPLETE";
16921
+ reasons.push("All acceptance criteria pass. No blocking conditions.");
16922
+ }
16923
+ }
16924
+ return { readiness, reasons, blockers, warnings };
16925
+ }
16926
+ function deriveRepoStatus(repo) {
16927
+ if (repo.validations.length === 0 && repo.changedPaths.length === 0) return "not-started";
16928
+ const hasFailure = repo.validations.some((v) => v.status === "failed" || v.status === "error");
16929
+ if (hasFailure) return "failed";
16930
+ const allPassed = repo.validations.length > 0 && repo.validations.every((v) => v.status === "passed" || v.status === "skipped");
16931
+ if (allPassed) return "completed";
16932
+ return "in-progress";
16933
+ }
16934
+ function mapACVerifications(verifications) {
16935
+ return verifications.map((v) => ({ ...v }));
16936
+ }
16937
+ function computeACSummary(verifications) {
16938
+ return {
16939
+ total: verifications.length,
16940
+ passed: verifications.filter((v) => v.status === "passed").length,
16941
+ failed: verifications.filter((v) => v.status === "failed").length,
16942
+ notVerified: verifications.filter((v) => v.status === "not-verified").length,
16943
+ manualReview: verifications.filter((v) => v.status === "manual-review-required").length
16944
+ };
16945
+ }
16946
+ function computePlannedVsActual(affectedModules, repos) {
16947
+ if (affectedModules.length === 0) return null;
16948
+ const actualModules = [...new Set(repos.map((r2) => r2.repoId))];
16949
+ const plannedSet = new Set(affectedModules);
16950
+ const actualSet = new Set(actualModules);
16951
+ return {
16952
+ hasHandoff: true,
16953
+ plannedModules: affectedModules,
16954
+ actualModules,
16955
+ addedModules: actualModules.filter((m2) => !plannedSet.has(m2)),
16956
+ missingModules: affectedModules.filter((m2) => !actualSet.has(m2))
16957
+ };
16958
+ }
16959
+ function deriveValidationStatus(repos, acVerifications, completionExceptions) {
16960
+ const allValidations = repos.flatMap((r2) => r2.validations);
16961
+ if (allValidations.length === 0 && acVerifications.length === 0) return "not-started";
16962
+ const hasFailed = allValidations.some((v) => v.status === "failed" || v.status === "error") || acVerifications.some((v) => v.status === "failed");
16963
+ if (hasFailed) {
16964
+ const hasAccepted = completionExceptions.some((e) => e.status === "accepted");
16965
+ if (hasAccepted) return "accepted-with-exceptions";
16966
+ return "failed";
16967
+ }
16968
+ const hasBlocked = allValidations.some((v) => v.status === "error");
16969
+ if (hasBlocked) return "blocked";
16970
+ const allComplete = allValidations.every((v) => v.status === "passed" || v.status === "skipped") && acVerifications.every((v) => v.status === "passed" || v.status === "not-verified");
16971
+ if (allComplete && allValidations.length > 0) return "passed";
16972
+ return "in-progress";
16973
+ }
16974
+ function deriveImplementationStatus(repos) {
16975
+ if (repos.length === 0) return "not-started";
16976
+ const hasChanges = repos.some((r2) => r2.changedPaths.length > 0);
16977
+ if (!hasChanges) return "not-started";
16978
+ const allComplete = repos.every((r2) => {
16979
+ const status = deriveRepoStatus(r2);
16980
+ return status === "completed";
16981
+ });
16982
+ if (allComplete) return "completed";
16983
+ const hasFailed = repos.some((r2) => deriveRepoStatus(r2) === "failed");
16984
+ if (hasFailed) return "partial";
16985
+ return "in-progress";
16986
+ }
16438
16987
  var MAX_INPUT_BYTES = 102400;
16439
16988
  var LIFECYCLE_FIELDS = /* @__PURE__ */ new Set([
16440
16989
  "id",
@@ -17465,6 +18014,27 @@ function importWorkItemTool(root, args) {
17465
18014
  return fail("Work Item import failed.");
17466
18015
  }
17467
18016
  }
18017
+ function collectEvidenceTool(root, args) {
18018
+ try {
18019
+ const result = collectImplementationEvidence(root, args.workItemId, args.evidence);
18020
+ return ok({ workItemId: args.workItemId, evidence: result });
18021
+ } catch (err) {
18022
+ if (err instanceof WorkItemNotFoundError) return fail(err.message);
18023
+ if (err instanceof WorkItemNotInProgressError) return fail(err.message);
18024
+ return fail("Evidence collection failed.");
18025
+ }
18026
+ }
18027
+ function verifyWorkItemTool(root, args) {
18028
+ try {
18029
+ const verification = verifyWorkItem(root, args.workItemId, args.evidence);
18030
+ const evaluation = evaluateCompletion(verification);
18031
+ return ok({ verification, evaluation });
18032
+ } catch (err) {
18033
+ if (err instanceof WorkItemNotFoundError) return fail(err.message);
18034
+ if (err instanceof WorkItemNotInProgressError) return fail(err.message);
18035
+ return fail("Work Item verification failed.");
18036
+ }
18037
+ }
17468
18038
 
17469
18039
  // src/multirepo.ts
17470
18040
  import fs5 from "fs";
@@ -21026,6 +21596,59 @@ function createServer(root) {
21026
21596
  },
21027
21597
  async (args) => toolText(guarded(root, () => importWorkItemTool(root, args)))
21028
21598
  );
21599
+ const evidenceRepoSchema = z4.object({
21600
+ repoId: z4.string(),
21601
+ role: z4.string().optional(),
21602
+ changedPaths: z4.array(z4.string()),
21603
+ validations: z4.array(z4.object({
21604
+ command: z4.string(),
21605
+ status: z4.enum(["passed", "failed", "skipped", "error"]),
21606
+ reason: z4.string().optional()
21607
+ })),
21608
+ migrations: z4.array(z4.object({
21609
+ id: z4.string(),
21610
+ environment: z4.string(),
21611
+ status: z4.string(),
21612
+ reason: z4.string().optional()
21613
+ })).optional()
21614
+ });
21615
+ const acVerificationSchema = z4.object({
21616
+ criterion: z4.string(),
21617
+ status: z4.enum(["passed", "failed", "not-verified", "manual-review-required"]),
21618
+ evidence: z4.string().optional()
21619
+ });
21620
+ const evidenceInputSchema = z4.object({
21621
+ repos: z4.array(evidenceRepoSchema),
21622
+ summary: z4.string().optional(),
21623
+ deviations: z4.array(z4.string()).optional(),
21624
+ issues: z4.array(z4.string()).optional(),
21625
+ knowledgeGaps: z4.array(z4.string()).optional(),
21626
+ acVerifications: z4.array(acVerificationSchema)
21627
+ });
21628
+ server.registerTool(
21629
+ "kaddo_collect_evidence",
21630
+ {
21631
+ title: "Collect Implementation Evidence",
21632
+ description: "Collect structured evidence of what changed during implementation of an in-progress Work Item. Accepts repository changes, validations, and AC verifications. Returns structured evidence ready for frontmatter.",
21633
+ inputSchema: {
21634
+ workItemId: z4.string().describe("The Work Item ID (e.g. WI-005)"),
21635
+ evidence: evidenceInputSchema
21636
+ }
21637
+ },
21638
+ async (args) => toolText(guarded(root, () => collectEvidenceTool(root, args)))
21639
+ );
21640
+ server.registerTool(
21641
+ "kaddo_verify_work_item",
21642
+ {
21643
+ title: "Verify Work Item",
21644
+ description: "Verify implementation evidence, acceptance criteria, release gates, and completion exceptions for an in-progress Work Item. Returns a verification result with AC status, findings, and a completion decision (READY_TO_COMPLETE, NEEDS_WORK, BLOCKED, READY_WITH_EXCEPTIONS).",
21645
+ inputSchema: {
21646
+ workItemId: z4.string().describe("The Work Item ID (e.g. WI-005)"),
21647
+ evidence: evidenceInputSchema
21648
+ }
21649
+ },
21650
+ async (args) => toolText(guarded(root, () => verifyWorkItemTool(root, args)))
21651
+ );
21029
21652
  let installedSkills = [];
21030
21653
  try {
21031
21654
  assertKaddoProject(root);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/mcp",
3
- "version": "3.92.0",
3
+ "version": "3.95.0",
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": {