@produtype/core 0.55.0 → 0.56.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.
@@ -167,9 +167,18 @@ function sortStates(states) {
167
167
  }
168
168
  return ordered;
169
169
  }
170
- function summarizePlan(tasks, actionableFindingCount) {
170
+ function summarizePlan(tasks, actionableFindingCount, inconclusive) {
171
171
  if (tasks.length === 0) {
172
- return 'ProdKit found no actionable remediation tasks from the current deterministic findings.';
172
+ /**
173
+ * An empty plan means two different things and said one sentence for both.
174
+ *
175
+ * "Found no actionable remediation tasks" reads as "there is nothing to do". On a
176
+ * repository this analyzer could not read, there is nothing to do *because it
177
+ * could not look* — and that is the opposite advice.
178
+ */
179
+ return inconclusive
180
+ ? 'No plan: too little of this repository could be read to say what it needs.'
181
+ : 'ProdKit found no actionable remediation tasks from the current deterministic findings.';
173
182
  }
174
183
  const quickWins = tasks.filter((task) => task.effort === 'small' && (task.risk === 'low' || task.risk === 'medium')).length;
175
184
  const highRisk = tasks.filter((task) => task.risk === 'high').length;
@@ -234,7 +243,7 @@ function buildPlan(report) {
234
243
  generatedAt: new Date().toISOString(),
235
244
  score: report.overallScore,
236
245
  maturityLevel: report.maturityLevel,
237
- summary: summarizePlan(tasks, actionableFindings.length),
246
+ summary: summarizePlan(tasks, actionableFindings.length, report.inconclusive),
238
247
  phases,
239
248
  tasks,
240
249
  quickWins,
@@ -66,8 +66,26 @@ const DAYS_BY_SEVERITY = {
66
66
  low: 0.5,
67
67
  info: 0,
68
68
  };
69
- function estimateEffort(findings, profile) {
70
- if (!profile)
69
+ function estimateEffort(findings, profile, inconclusive) {
70
+ /**
71
+ * "Nothing outstanding to estimate" is a claim about the work, and a report that
72
+ * could not read the repository has no basis for it.
73
+ *
74
+ * A Python transcription script whose verdict says "ProdKit could not judge this
75
+ * project" was told there was nothing to do. It is the last number in the report and
76
+ * the same mistake as all the others: an empty list of findings read as an empty
77
+ * list of problems.
78
+ */
79
+ if (inconclusive)
80
+ return 'Not estimated: too little of this repository could be read.';
81
+ /**
82
+ * The inconclusive-inference profile is no profile.
83
+ *
84
+ * It carries an empty capability set, so estimating against it measures the observed
85
+ * findings and calls the answer an estimate of the gap. The sentence for having no
86
+ * profile already exists and is the true one.
87
+ */
88
+ if (!profile || profile.selectedProfile === 'auto')
71
89
  return 'Not estimated without a product profile.';
72
90
  const open = findings.filter((f) => f.status !== 'passed' && f.status !== 'unknown');
73
91
  if (open.length === 0)
@@ -265,7 +283,7 @@ function buildExecutiveSummary(args) {
265
283
  * the same praise.
266
284
  */
267
285
  strengths: args.inconclusive ? [] : buildStrengths(args.categoryScores, args.findings),
268
- estimatedEffort: estimateEffort(args.findings, args.profile),
286
+ estimatedEffort: estimateEffort(args.findings, args.profile, args.inconclusive),
269
287
  scoreExplanation,
270
288
  };
271
289
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "0.55.0",
3
+ "version": "0.56.0",
4
4
  "description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
5
5
  "license": "MIT",
6
6
  "bin": {