@hone-ai/cli 1.29.0 → 1.29.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/lib/run-report.js +34 -0
- package/package.json +1 -1
package/lib/run-report.js
CHANGED
|
@@ -60,6 +60,40 @@ function buildReport(run, extra = {}) {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
// 1b. HC-GF-044: a STEP can be failed while the RUN says completed.
|
|
64
|
+
//
|
|
65
|
+
// Everything above keys on `run.status`. Nothing read `steps[].status`, so a run
|
|
66
|
+
// reported `completed` that contained a `failed` step produced ZERO items and the
|
|
67
|
+
// empty-state branch then printed the affirmative "nothing outstanding". Observed on
|
|
68
|
+
// run 08c27392: `Status: completed` / `Error: MAX_RETRIES_EXCEEDED: step_5 retried 2
|
|
69
|
+
// times` / `✗ step_5 (code-reviewer) failed`, and then `NEEDS YOU (0)`. The STEPS block
|
|
70
|
+
// below rendered the failure correctly, so the data was present and read — only the
|
|
71
|
+
// actionable layer missed it.
|
|
72
|
+
//
|
|
73
|
+
// This is the exact class HC-GF-016 exists to prevent, and the sharp part is that its
|
|
74
|
+
// empty-state rule was HONOURED: the section rendered and named what it checked. It
|
|
75
|
+
// checked the wrong field. A well-formed "nothing" is only as true as its predicate.
|
|
76
|
+
//
|
|
77
|
+
// DELIBERATELY INDEPENDENT OF HC-GF-043. That story stops the orchestrator writing
|
|
78
|
+
// `completed` over a failed step, which would make THIS run fire here via the branch
|
|
79
|
+
// above. It would not help a `completed` run whose step failed for any other reason, or
|
|
80
|
+
// a report built from a run recorded before that fix shipped. Both are needed; neither
|
|
81
|
+
// substitutes for the other.
|
|
82
|
+
//
|
|
83
|
+
// Keyed on the step's OWN state, and `rejected` counts alongside `failed`: a rejected
|
|
84
|
+
// gate is a human decision awaiting follow-up, not a null result.
|
|
85
|
+
const brokenSteps = steps.filter(s => s.status === 'failed' || s.gateResult === 'rejected');
|
|
86
|
+
for (const s of brokenSteps) {
|
|
87
|
+
// Skip the one the run-level item already names, so one problem is one entry.
|
|
88
|
+
if (run.status === 'failed' && s.stepKey === run.currentStep) continue;
|
|
89
|
+
needsYou.push({
|
|
90
|
+
what: `${s.stepKey} (${s.agent || 'agent'}) ${s.status === 'failed' ? 'FAILED' : 'was REJECTED'}`
|
|
91
|
+
+ ` — the run is recorded ${run.status}, so nothing downstream will revisit it`,
|
|
92
|
+
how: `hone show step ${run.runId} ${s.stepKey}`,
|
|
93
|
+
howLabel: 'inspect',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
63
97
|
// 2. The last verification is ONE event, so it becomes ONE item with sub-lines.
|
|
64
98
|
// Listing "verification failed" and "lint failed" separately gave two entries
|
|
65
99
|
// for one problem resolved by one fix — and NEEDS YOU is a list of DISTINCT
|