@harness-engineering/cli 4.0.1 → 4.2.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.
- package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +40 -8
- package/dist/agents/skills/claude-code/harness-catalog-retrospective/SKILL.md +124 -0
- package/dist/agents/skills/claude-code/harness-catalog-retrospective/skill.yaml +48 -0
- package/dist/agents/skills/claude-code/harness-execution/SKILL.md +13 -0
- package/dist/agents/skills/claude-code/harness-parallel-agents/SKILL.md +3 -0
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +3 -1
- package/dist/agents/skills/claude-code/pre-merge-brief/SKILL.md +86 -0
- package/dist/agents/skills/claude-code/pre-merge-brief/skill.yaml +67 -0
- package/dist/agents/skills/codex/harness-autopilot/SKILL.md +40 -8
- package/dist/agents/skills/codex/harness-catalog-retrospective/SKILL.md +124 -0
- package/dist/agents/skills/codex/harness-catalog-retrospective/skill.yaml +48 -0
- package/dist/agents/skills/codex/harness-execution/SKILL.md +13 -0
- package/dist/agents/skills/codex/harness-parallel-agents/SKILL.md +3 -0
- package/dist/agents/skills/codex/harness-planning/SKILL.md +3 -1
- package/dist/agents/skills/codex/pre-merge-brief/SKILL.md +86 -0
- package/dist/agents/skills/codex/pre-merge-brief/skill.yaml +67 -0
- package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +40 -8
- package/dist/agents/skills/cursor/harness-catalog-retrospective/SKILL.md +124 -0
- package/dist/agents/skills/cursor/harness-catalog-retrospective/skill.yaml +48 -0
- package/dist/agents/skills/cursor/harness-execution/SKILL.md +13 -0
- package/dist/agents/skills/cursor/harness-parallel-agents/SKILL.md +3 -0
- package/dist/agents/skills/cursor/harness-planning/SKILL.md +3 -1
- package/dist/agents/skills/cursor/pre-merge-brief/SKILL.md +86 -0
- package/dist/agents/skills/cursor/pre-merge-brief/skill.yaml +67 -0
- package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +40 -8
- package/dist/agents/skills/gemini-cli/harness-catalog-retrospective/SKILL.md +124 -0
- package/dist/agents/skills/gemini-cli/harness-catalog-retrospective/skill.yaml +48 -0
- package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +13 -0
- package/dist/agents/skills/gemini-cli/harness-parallel-agents/SKILL.md +3 -0
- package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +3 -1
- package/dist/agents/skills/gemini-cli/pre-merge-brief/SKILL.md +86 -0
- package/dist/agents/skills/gemini-cli/pre-merge-brief/skill.yaml +67 -0
- package/dist/{agents-md-VJLYEH2S.js → agents-md-BK2UPKUC.js} +4 -4
- package/dist/analyzer-XRCV63KC-6T2Z32XC.js +26 -0
- package/dist/{architecture-YQH2NYXY.js → architecture-7PNQZOWV.js} +5 -5
- package/dist/{assess-project-KOTAPAHD.js → assess-project-2QPCNN7N.js} +5 -3
- package/dist/bin/harness-mcp.js +15 -15
- package/dist/bin/harness.js +26 -26
- package/dist/{check-phase-gate-CHU2E3OU.js → check-phase-gate-RZUSDB3O.js} +5 -5
- package/dist/{chunk-MMLQPHZ5.js → chunk-33OU3LYX.js} +380 -15
- package/dist/{chunk-XAVMTAUT.js → chunk-6STDKKAM.js} +19 -3
- package/dist/{chunk-I3CGCZJF.js → chunk-BJDT3VGQ.js} +6 -6
- package/dist/{chunk-M7F2PPN3.js → chunk-D5YCPIK6.js} +2 -2
- package/dist/{chunk-SDMV4QHM.js → chunk-DBCC7KIW.js} +25 -7
- package/dist/{chunk-E5EW5HVJ.js → chunk-DVG6DDX6.js} +1 -1
- package/dist/{chunk-4VXFZSYF.js → chunk-DW6HE5DH.js} +2 -2
- package/dist/{chunk-7PJCK7UE.js → chunk-E5KJOUHI.js} +7 -7
- package/dist/{chunk-6SCYTIF4.js → chunk-HU7NS7JA.js} +32 -7
- package/dist/{chunk-36GQREOE.js → chunk-HUC73DZC.js} +3 -3
- package/dist/{chunk-EYMOPFSD.js → chunk-J5MFNKE7.js} +2 -2
- package/dist/{chunk-JPVOI7GP.js → chunk-J7H5I4FO.js} +2 -2
- package/dist/{chunk-RG3TNIUB.js → chunk-K5R2I37T.js} +208 -97
- package/dist/{chunk-AAUY53CC.js → chunk-KHL6WFRL.js} +2 -2
- package/dist/{chunk-OQ6KOQEV.js → chunk-KYFXXEK3.js} +3 -3
- package/dist/{chunk-5RSXUAMN.js → chunk-MHHISNS2.js} +2 -2
- package/dist/{chunk-GHBFNLV2.js → chunk-RRCS27GT.js} +1531 -1175
- package/dist/{chunk-6YFHUIGT.js → chunk-RZTLXZHJ.js} +59 -21
- package/dist/{chunk-AX5KGRM6.js → chunk-SI4O2W4H.js} +2 -2
- package/dist/{chunk-BDGTZRZ6.js → chunk-UEXQMI6K.js} +56 -44
- package/dist/{chunk-7TIJXWG3.js → chunk-V2GJE5J5.js} +3 -3
- package/dist/{chunk-T746REAE.js → chunk-VC2B275U.js} +2 -2
- package/dist/{chunk-SEA2PFVI.js → chunk-XACP5P2J.js} +2 -2
- package/dist/{chunk-UWVMJEUJ.js → chunk-YTJIRQON.js} +2 -2
- package/dist/{chunk-YANR2RL7.js → chunk-ZIJABBGZ.js} +2 -2
- package/dist/{ci-workflow-HO4WKGNG.js → ci-workflow-LGN7LHHO.js} +4 -4
- package/dist/{dist-ICW4QUEW.js → dist-FBBADRYS.js} +3 -1
- package/dist/{dist-6D2F2J57.js → dist-LE5AU7FR.js} +19 -3
- package/dist/{docs-FP47JONV.js → docs-3BTPSHKE.js} +5 -5
- package/dist/{engine-YUA6IYOG.js → engine-GWGU4AMH.js} +4 -4
- package/dist/{entropy-DBW2INZU.js → entropy-35XURODP.js} +7 -4
- package/dist/{feedback-BPHADTRQ.js → feedback-NDGZZ37W.js} +1 -1
- package/dist/{generate-agent-definitions-KPVGBGDY.js → generate-agent-definitions-PYZ3E7SP.js} +5 -5
- package/dist/hooks/sentinel-pre.js +15 -138
- package/dist/index.d.ts +61 -0
- package/dist/index.js +25 -25
- package/dist/{loader-QOJQ6NZM.js → loader-QK2OJXKB.js} +4 -4
- package/dist/{mcp-ZPX6O767.js → mcp-Z5YMV7TA.js} +15 -15
- package/dist/{performance-FXYTGJGQ.js → performance-VAYOYPVK.js} +5 -5
- package/dist/{review-pipeline-2TFQ5OAE.js → review-pipeline-UETEOWSS.js} +4 -4
- package/dist/{runtime-XK6ZCHKE.js → runtime-J7KFACTK.js} +4 -4
- package/dist/{security-4W2P5ZGI.js → security-6AIUZXF5.js} +1 -1
- package/dist/{state-events-ECQAIZLU.js → state-events-XQPHGLG5.js} +4 -4
- package/dist/{validate-64KTEGIE.js → validate-ON7YMVLY.js} +5 -5
- package/dist/{validate-cross-check-J5PVGICB.js → validate-cross-check-HKKQA7K5.js} +4 -4
- package/package.json +8 -7
- package/dist/analyzer-V633GUHY-OV335HGM.js +0 -26
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Harness Catalog Retrospective
|
|
2
|
+
|
|
3
|
+
> Monthly retrospective over skill-adoption telemetry. Reads `.harness/metrics/adoption.jsonl`, ranks the most-invoked, most-failing, and abandoned-mid-workflow skills, flags ever-invoked skills that have gone quiet, and reports how much of the catalog emits any telemetry at all. Produces a dated Markdown report and surfaces the highlights that warrant follow-up. Compounding-via-learning at the catalog grain.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
- On a regular cadence (monthly is the intended grain) to review how the skill catalog is actually being used.
|
|
8
|
+
- After a milestone, to see which skills carried the work and which never fired.
|
|
9
|
+
- When deciding what to prune, fix, or promote in the catalog — the report feeds catalog-rationalization work.
|
|
10
|
+
- NOT as a real-time dashboard — for point-in-time lookups use `harness adoption skills` / `harness adoption recent`.
|
|
11
|
+
- NOT when `.harness/metrics/adoption.jsonl` is absent or empty (the report will be honest but empty; there is nothing to retrospect on yet).
|
|
12
|
+
|
|
13
|
+
## Process
|
|
14
|
+
|
|
15
|
+
### Iron Law
|
|
16
|
+
|
|
17
|
+
**Separate real signal from telemetry gaps before you recommend anything.** The single most common misread of this data is treating "no telemetry" as "abandoned." Adoption records are emitted only from instrumented entry points, so a skill with zero records is usually uninstrumented, not unused. The report's coverage line and the stale-skills section exist to keep that distinction visible — never collapse it.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
### Phase 1: SCAN — Derive the Report
|
|
22
|
+
|
|
23
|
+
1. Run the retrospective command from the project root:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
harness adoption retrospective # writes docs/retrospectives/<date>.md
|
|
27
|
+
harness adoption retrospective --no-write # print to stdout without writing a file
|
|
28
|
+
harness adoption retrospective --json # structured output for further processing
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Optional flags: `--inactive-days <n>` (stale threshold, default 90), `--top <n>` (rows per section, default 10), `--out <path>` (override the output file).
|
|
32
|
+
|
|
33
|
+
2. The command reads `.harness/metrics/adoption.jsonl` via `readAdoptionRecords`, derives the report via `getCatalogRetrospectiveReport`, and renders it via `renderRetrospectiveMarkdown` (all in `@harness-engineering/core`). Coverage context is computed against the skills discovered under `agents/skills/claude-code/`; when that directory is absent (a consumer project), the coverage line is omitted rather than reporting a false zero.
|
|
34
|
+
|
|
35
|
+
3. If there are no records, say so plainly and stop: "No adoption telemetry found at `.harness/metrics/adoption.jsonl`. Nothing to retrospect on yet."
|
|
36
|
+
|
|
37
|
+
### Phase 2: INTERPRET — Signal vs. Noise
|
|
38
|
+
|
|
39
|
+
Read the report with these discriminations:
|
|
40
|
+
|
|
41
|
+
- **Coverage line first.** "N/total catalog skills have emitted telemetry" frames everything below it. A low ratio means the rankings describe the _instrumented_ slice, not the whole catalog. State the ratio explicitly in your summary.
|
|
42
|
+
- **Failing skills are not automatically broken.** Some commands fail _by design_ (a gate like `ci.check` returning non-zero on a real violation is the gate working). Before flagging a high failure rate as a problem, note whether the skill is a checker/gate whose failures are expected. Call out only failures that look like defects (crashes, unexpected non-zero on clean input).
|
|
43
|
+
- **Abandoned mid-workflow** uses the broadened definition: an explicit `abandoned` outcome, or a non-completed run that had already reached ≥1 phase. Small counts here are meaningful — a workflow skill people start and bail out of mid-way is a UX signal even at n=1.
|
|
44
|
+
- **Stale skills** are drawn only from _ever-invoked_ skills quiet ≥ the threshold. When the record window is shorter than the threshold, the section says so and reports nothing — do not present that emptiness as "everything is healthy."
|
|
45
|
+
|
|
46
|
+
### Phase 3: REPORT — Surface and Recommend
|
|
47
|
+
|
|
48
|
+
1. Confirm where the report was written (`docs/retrospectives/<date>.md`) or present the rendered Markdown.
|
|
49
|
+
2. Summarize the 3–5 findings that actually warrant action, each tied to a section and a number. Prefer specifics ("`cli/review-ci` failed 23/23 — likely a real defect, worth a look") over restating the tables.
|
|
50
|
+
3. When the coverage ratio is the dominant finding (e.g. most of the catalog is uninstrumented), name that as the top follow-up: instrumentation, not pruning, is the lever.
|
|
51
|
+
4. Do not delete, prune, or edit skills from this skill — it reports. Hand any pruning decision to the human or to catalog-rationalization work.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Harness Integration
|
|
56
|
+
|
|
57
|
+
- **`harness adoption retrospective`** — the CLI entry point (a subcommand of the existing `adoption` command group). Writes `docs/retrospectives/<date>.md` by default.
|
|
58
|
+
- **`getCatalogRetrospectiveReport` / `renderRetrospectiveMarkdown` / `isAbandonedMidWorkflow`** — the pure aggregation + render functions in `@harness-engineering/core` (`packages/core/src/adoption/retrospective.ts`). Callers can supply a fixed `now` and `catalogSkills` for deterministic output.
|
|
59
|
+
- **`readAdoptionRecords`** — reads and parses `.harness/metrics/adoption.jsonl` (read-only; the file is appended by the adoption-tracker hook, never by this skill).
|
|
60
|
+
- **`harness adoption skills` / `recent` / `skill <name>`** — the point-in-time siblings; this skill is the periodic, persisted counterpart.
|
|
61
|
+
|
|
62
|
+
## Success Criteria
|
|
63
|
+
|
|
64
|
+
1. The retrospective is derived from `.harness/metrics/adoption.jsonl` without mutating it.
|
|
65
|
+
2. The report ranks top-invoked, top-failing, and abandoned-mid-workflow skills, and flags ever-invoked stale skills.
|
|
66
|
+
3. The report states telemetry coverage (how much of the catalog emits any signal) when the catalog is discoverable.
|
|
67
|
+
4. The stale-skills section notes when the record window is shorter than the inactivity threshold instead of silently reporting zero.
|
|
68
|
+
5. The summary separates real signal (defect-shaped failures, mid-workflow abandonment) from telemetry gaps (uninstrumented skills) and from expected gate failures.
|
|
69
|
+
6. A dated report is written to `docs/retrospectives/<date>.md` (unless `--no-write`/`--json` is requested).
|
|
70
|
+
7. The skill recommends but never prunes, edits, or deletes catalog skills.
|
|
71
|
+
|
|
72
|
+
## Rationalizations to Reject
|
|
73
|
+
|
|
74
|
+
| Rationalization | Reality |
|
|
75
|
+
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
76
|
+
| "756 skills have no telemetry, so 756 skills are abandoned — recommend deleting them." | Zero telemetry almost always means _uninstrumented_, not unused. The coverage line exists to prevent exactly this misread; the fix is instrumentation, not pruning. |
|
|
77
|
+
| "`ci.check` fails 97% of the time — it's broken." | A gate returning non-zero on a real violation is the gate working. Check whether the skill is a checker before flagging its failures as defects. |
|
|
78
|
+
| "The stale section is empty, so the catalog is healthy." | If the record window is shorter than the threshold, the signal simply cannot fire yet. Empty ≠ healthy; report the window caveat. |
|
|
79
|
+
| "n=1 abandonment is noise, ignore it." | A workflow skill users start and bail out of mid-way is a UX signal even at low n. Surface it; let the human weigh it. |
|
|
80
|
+
| "I'll prune the low-usage skills while I'm here." | This skill reports; it does not prune. Pruning is a human/catalog-rationalization decision. |
|
|
81
|
+
|
|
82
|
+
## Examples
|
|
83
|
+
|
|
84
|
+
### Example: Monthly retrospective on the dogfood repo
|
|
85
|
+
|
|
86
|
+
**Context:** ~67 days of telemetry (3.2k records) across 50 invoked skills, run at month end.
|
|
87
|
+
|
|
88
|
+
**Phase 1 — SCAN:**
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
harness adoption retrospective
|
|
92
|
+
# → Catalog retrospective written to docs/retrospectives/2026-07-06.md
|
|
93
|
+
# 3246 records · 50 skills · window 67d
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Phase 2 — INTERPRET:** The report's overview leads with `Telemetry coverage: 5/761 catalog skills have emitted telemetry (756 never invoked)`. Top-invoked is dominated by `cli/*` commands; `cli/ci.check` shows a 97% failure rate; the abandoned-mid-workflow section lists four workflow skills at n=1; the stale section is empty with the note that the 67-day window is shorter than the 90-day threshold.
|
|
97
|
+
|
|
98
|
+
**Phase 3 — REPORT:**
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Retrospective written to docs/retrospectives/2026-07-06.md. Findings that warrant action:
|
|
102
|
+
|
|
103
|
+
1. Coverage is the headline: only 5/761 catalog skills emit any telemetry. The rankings
|
|
104
|
+
describe the instrumented slice, not the catalog. Top follow-up is instrumentation, not pruning.
|
|
105
|
+
2. `cli/ci.check` failed 97% (721/741) — but it is a gate; non-zero on a real violation is
|
|
106
|
+
expected. Not flagged as a defect.
|
|
107
|
+
3. `cli/review-ci` failed 23/23 (100%) — defect-shaped, worth a look. Routed to debugging.
|
|
108
|
+
4. Four workflow skills were abandoned mid-run (n=1 each) — low volume, a UX signal to watch.
|
|
109
|
+
5. Stale skills: none — the 67-day window can't satisfy the 90-day threshold yet.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
No skills were pruned or edited — the pruning decision is left to the human.
|
|
113
|
+
|
|
114
|
+
## Gates
|
|
115
|
+
|
|
116
|
+
- **No mutation of `adoption.jsonl`.** The telemetry file is read-only input.
|
|
117
|
+
- **No catalog edits.** This skill never adds, edits, or deletes skills — it only reports on them.
|
|
118
|
+
- **Coverage must be stated when discoverable.** If the catalog can be scanned, the summary must include the telemetry-coverage ratio so rankings are read in context.
|
|
119
|
+
|
|
120
|
+
## Escalation
|
|
121
|
+
|
|
122
|
+
- **When there are no records:** State that telemetry is absent/empty and stop. Suggest confirming the adoption-tracker hook is installed if telemetry is unexpectedly missing.
|
|
123
|
+
- **When coverage is very low:** Name instrumentation as the top follow-up and note that the rankings describe only the instrumented slice.
|
|
124
|
+
- **When a failing skill looks like a real defect:** Flag it specifically (skill, failure count/rate, why it looks defect-shaped) and route it to debugging or an issue, rather than burying it in the table.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: harness-catalog-retrospective
|
|
2
|
+
version: '1.0.0'
|
|
3
|
+
description: Monthly retrospective over skill-adoption telemetry — ranks most-invoked, failing, and abandoned-mid-workflow skills, flags stale ones, and reports catalog telemetry coverage
|
|
4
|
+
stability: static
|
|
5
|
+
cognitive_mode: analytical-reporter
|
|
6
|
+
triggers:
|
|
7
|
+
- manual
|
|
8
|
+
- on_milestone
|
|
9
|
+
platforms:
|
|
10
|
+
- claude-code
|
|
11
|
+
- gemini-cli
|
|
12
|
+
- cursor
|
|
13
|
+
- codex
|
|
14
|
+
tools:
|
|
15
|
+
- Bash
|
|
16
|
+
- Read
|
|
17
|
+
- Glob
|
|
18
|
+
- Grep
|
|
19
|
+
cli:
|
|
20
|
+
command: harness skill run harness-catalog-retrospective
|
|
21
|
+
args:
|
|
22
|
+
- name: path
|
|
23
|
+
description: Project root path
|
|
24
|
+
required: false
|
|
25
|
+
- name: inactive-days
|
|
26
|
+
description: 'Inactivity threshold in days for the stale-skills section (default: 90)'
|
|
27
|
+
required: false
|
|
28
|
+
mcp:
|
|
29
|
+
tool: run_skill
|
|
30
|
+
input:
|
|
31
|
+
skill: harness-catalog-retrospective
|
|
32
|
+
path: string
|
|
33
|
+
type: rigid
|
|
34
|
+
tier: 2
|
|
35
|
+
phases:
|
|
36
|
+
- name: scan
|
|
37
|
+
description: Read adoption telemetry and derive the retrospective report
|
|
38
|
+
required: true
|
|
39
|
+
- name: interpret
|
|
40
|
+
description: Read the rankings and coverage, separating real signal from telemetry gaps
|
|
41
|
+
required: true
|
|
42
|
+
- name: report
|
|
43
|
+
description: Write the dated report and surface highlights plus recommendations
|
|
44
|
+
required: true
|
|
45
|
+
state:
|
|
46
|
+
persistent: false
|
|
47
|
+
files: []
|
|
48
|
+
depends_on: []
|
|
@@ -131,6 +131,19 @@ RMH005 (`harness validate`).
|
|
|
131
131
|
|
|
132
132
|
- If no roadmap row matches this plan (e.g. ad-hoc execution), skip the claim.
|
|
133
133
|
|
|
134
|
+
#### Step 0.5: Plan parallelization (standard automatic parallelism)
|
|
135
|
+
|
|
136
|
+
Before the per-task loop, decide the safe parallel structure so independent tasks dispatch concurrently by default (no human typing "in parallel").
|
|
137
|
+
|
|
138
|
+
1. Collect this run's tasks with their `files` and `dependsOn` (from the plan's task headers) and call the `plan_parallelization` MCP tool (`{ path, tasks, depth: 1 }`). It returns `ParallelizationPlan` (`waves[]`, `serialized[]`, `cyclic[]`, `narration`).
|
|
139
|
+
2. If `cyclic` is non-empty, STOP and escalate (dependency cycle = plan defect). Do not execute.
|
|
140
|
+
3. Emit `narration` (announce-and-proceed — do not pause).
|
|
141
|
+
4. Run `serialized` tasks first (serially, in order — cross-bucket prerequisites), then process `waves` **in array order** (topologically sorted; do not reorder, do not key off `firing` alone).
|
|
142
|
+
5. Per wave: `auto-dispatch` (multi-task) → dispatch the wave via **harness-parallel-agents** with worktree-per-unit isolation (`docs/guides/agent-worktree-patterns.md`), announce and proceed; `confirm` → one plain-text confirmation, then parallel or serial per the answer; `serialize` / single-task → run through the per-task loop below serially.
|
|
143
|
+
6. **Serial fallback preserved:** when independent tasks < `minWaveSize` (default 3), a `confirm` is declined, or no graph is available and the human does not confirm, run every task through the per-task loop below serially — the standing "when in doubt, run serially" default.
|
|
144
|
+
|
|
145
|
+
Tasks dispatched into a parallel wave are executed by harness-parallel-agents' focused agents; tasks that fall to serial run through the loop below unchanged.
|
|
146
|
+
|
|
134
147
|
For each task, starting from current position:
|
|
135
148
|
|
|
136
149
|
1. **Read task instructions completely** before writing any code.
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
> Dispatch independent tasks to concurrent agents, integrate results, and verify no conflicts. Only for truly independent problems.
|
|
4
4
|
|
|
5
|
+
**Invoked automatically by `harness-autopilot` (and standalone `harness-execution`), not only manually.** When a plan's phase has an auto-dispatch wave, the execution loop calls this skill to run that wave. In that mode the caller supplies worktree-per-unit isolation per `docs/guides/agent-worktree-patterns.md` (one worktree per task, sequential commits, squash-merge on integrate) and has already verified independence via `plan_parallelization`; this skill still owns the focused agent briefs (Step 2), concurrent dispatch (Step 3), and integration/verification (Steps 4–5). Manual invocation (a human asking to "work in parallel") continues to work unchanged.
|
|
6
|
+
|
|
5
7
|
## When to Use
|
|
6
8
|
|
|
7
9
|
- When 3 or more tasks are truly independent (no shared state, no shared files, different subsystems)
|
|
8
10
|
- When tasks involve investigation or implementation in separate parts of the codebase
|
|
9
11
|
- When parallel execution would meaningfully reduce wall-clock time
|
|
10
12
|
- When a plan has tasks explicitly marked as parallelizable
|
|
13
|
+
- When `harness-autopilot`/`harness-execution` reaches an `auto-dispatch` (or confirmed) wave from `plan_parallelization` — this skill is the wave's dispatcher
|
|
11
14
|
- NOT when failures across tasks might be related (investigate serially to find the common cause)
|
|
12
15
|
- NOT when tasks need full system understanding to complete correctly
|
|
13
16
|
- NOT when agents would modify the same files or shared state
|
|
@@ -256,7 +256,7 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
|
|
|
256
256
|
### Phase 3: SEQUENCE — Order Tasks and Identify Dependencies
|
|
257
257
|
|
|
258
258
|
1. **Order by dependency.** Types before implementations. Implementations before integrations. Integration tasks (tagged `category: "integration"`) after all implementation tasks. Tests alongside implementations (same task, TDD style).
|
|
259
|
-
2. **Identify parallel opportunities.** Tasks touching different subsystems with no shared state can
|
|
259
|
+
2. **Identify parallel opportunities and record dependency edges.** Tasks touching different subsystems with no shared state can run in parallel. Record each task's real dependencies as `dependsOn` (the task IDs it must follow) in the task header `**Depends on:**` line, and keep the task's `**Files:**` list accurate — together these are exactly the edges `plan_parallelization` consumes (explicit `dependsOn` unioned with file-overlap edges) to build the wave DAG at execution time. A task with no dependencies records `**Depends on:** none`.
|
|
260
260
|
3. **Number tasks sequentially.** Use `Task 1`, `Task 2`, etc. Dependencies reference task numbers.
|
|
261
261
|
4. **Estimate total time.** Sum 2-5 minutes per task. If total exceeds available time, identify a milestone boundary for pausing.
|
|
262
262
|
|
|
@@ -327,6 +327,8 @@ One sentence.
|
|
|
327
327
|
|
|
328
328
|
**Depends on:** none | **Files:** path/to/file.ts, path/to/file.test.ts
|
|
329
329
|
|
|
330
|
+
<!-- `Depends on` lists the task IDs this task must follow (its `dependsOn` edges); `Files` is the independence-checking input. Both feed `plan_parallelization` during execution. -->
|
|
331
|
+
|
|
330
332
|
1. Create test file with exact test code
|
|
331
333
|
2. Run test — observe failure
|
|
332
334
|
3. Create implementation with exact code
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Pre-Merge Brief
|
|
2
|
+
|
|
3
|
+
> The harness pointed at the human who clicks merge. A thin wrapper over `harness pre-merge-brief` that composes a senior-facing accountability brief — the diff summary, the multi-persona review verdict (from `review-ci --json`), the curated **Signal status** snapshot, the outcome-eval result, and a derived **"👀 Worth your eyes"** section — and posts it as a single sticky PR comment (upsert by marker). All composition and degradation logic lives in the command; this skill orchestrates invocation, reports which sections degraded, and hands off. Advisory and non-blocking: the brief never flips the review gate.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
- On every PR, so the senior engineer who merges sees "you are pushing this — here's what deserves your eyes" before they click merge.
|
|
8
|
+
- `on_pr` (dogfooded via the `required-review` workflow, reusing that run's `review-ci --json` artifact) and `manual` (a senior running it locally against the current branch's PR).
|
|
9
|
+
- NOT as a merge gate — the acknowledgment gate is deliberately deferred (spec D3). The brief is advisory; the review gate's exit code is what blocks.
|
|
10
|
+
- NOT a replacement for `review-ci` — this skill CONSUMES the review verdict, it does not re-run the review (spec D1).
|
|
11
|
+
- NOT for recomputing signals a different way — signals come from `@harness-engineering/signals` via the command (spec D2/D6).
|
|
12
|
+
|
|
13
|
+
## Process
|
|
14
|
+
|
|
15
|
+
### Phase 1: GATHER — Resolve inputs
|
|
16
|
+
|
|
17
|
+
1. Locate the `review-ci --json` artifact for this run and record its path for `--from`. In CI it is the JSON the `required-review` workflow's `review-ci` step wrote (e.g. `/tmp/review.json`); locally, run `harness review-ci --json <path>` first if a verdict is wanted. Absent `--from` is tolerated — the review section degrades to "unavailable".
|
|
18
|
+
2. Resolve the diff range for `--diff` (default `origin/<base>...HEAD` via the command's own resolver). Override only when the base is non-standard.
|
|
19
|
+
3. Resolve the head sha for `--head` (default `git rev-parse HEAD`) — used for the `execution_outcome` graph lookup. Pre-merge the node is commonly absent, which is the documented degradation path, not an error.
|
|
20
|
+
4. If posting (`--comment`), confirm `gh` is authenticated. Delivery failure never crashes the command (spec S1): it prints the brief and warns, still exiting 0.
|
|
21
|
+
|
|
22
|
+
### Phase 2: COMPOSE — Run the command
|
|
23
|
+
|
|
24
|
+
Invoke `harness pre-merge-brief` with the resolved inputs:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
harness pre-merge-brief --from <review.json> --diff <range> --head <sha> [--comment]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The command builds the six-section brief (marker + header → Diff summary → Review verdict → **Signal status** → Outcome evaluation → **👀 Worth your eyes**) and, with `--comment`, upserts the sticky PR comment by its marker (`<!-- harness:pre-merge-brief -->`) — patching the existing comment in place rather than posting a new one on each push. Without `--comment` it prints the brief to stdout. Each input degrades independently to an explicit "unavailable" line; the command exits 0 on a successful render regardless of which inputs were present.
|
|
31
|
+
|
|
32
|
+
### Phase 3: REPORT — Surface what matters
|
|
33
|
+
|
|
34
|
+
1. Report which sections rendered with real data and which degraded to "unavailable / not yet evaluated", so the senior knows the brief's coverage.
|
|
35
|
+
2. Surface the **"👀 Worth your eyes"** items verbatim — the union of blocking review findings, signals in `warn`/`alert`, and unmet outcome criteria. This is the section the accountable human should read first.
|
|
36
|
+
|
|
37
|
+
### Phase 4: HANDOFF — Advisory transition
|
|
38
|
+
|
|
39
|
+
Emit the transition via `emit_interaction`. The brief is advisory and non-blocking: it never flips the review gate's pass/fail status (spec D3, D4). In the dogfood workflow the brief step is `continue-on-error`, so a brief failure never fails the PR.
|
|
40
|
+
|
|
41
|
+
## Harness Integration
|
|
42
|
+
|
|
43
|
+
- **`harness pre-merge-brief`** — the command this skill wraps. Flags: `--from <path>` (review-ci verdict JSON), `--comment` (sticky-upsert to the current branch's PR via `gh`), `--diff <range>`, `--head <sha>`. Pure render (`buildBriefBody`) + injected seams (`postBrief`, `RunGit`, graph store); no `process.exit` in the pure core.
|
|
44
|
+
- **`review-ci`** — upstream producer of the review verdict. This skill reuses its `--json` artifact via `--from`; it never re-runs the review (D1). `review-ci` remains the single source of review truth.
|
|
45
|
+
- **`@harness-engineering/signals`** — the shared leaf package (extracted in spec Phase 1/D6) providing `gatherSignals`. The command computes the Signal status snapshot from it; the CLI does not route signal computation through the dashboard app.
|
|
46
|
+
- **`execution_outcome` graph nodes** — the outcome-eval result, looked up by head sha from `.harness/graph`; commonly absent pre-merge (degrades to "not yet evaluated").
|
|
47
|
+
- **`required-review.yml` (dogfood)** — the `on_pr` delivery path: a `continue-on-error` step runs the brief after the existing `review-ci` run, reusing its artifact (spec Phase 4/D4). Adopter template graduation is a tracked follow-up (D5).
|
|
48
|
+
|
|
49
|
+
## Gates
|
|
50
|
+
|
|
51
|
+
- **Never re-run the review.** Consume `review-ci --json`; do not invoke the review pipeline from this skill (D1).
|
|
52
|
+
- **Never block the merge.** The brief is advisory; the review gate's exit code is authoritative. No acknowledgment gate in v1 (D3).
|
|
53
|
+
- **Never crash `--comment`.** A `gh`/PR delivery failure prints the brief and warns, still exiting 0 (S1).
|
|
54
|
+
- **Thin wrapper only.** No brief composition, signal computation, or union logic in the skill — all of it lives in the command.
|
|
55
|
+
|
|
56
|
+
## Success Criteria
|
|
57
|
+
|
|
58
|
+
Maps to spec `docs/changes/senior-accountability-surface/proposal.md`. This skill satisfies criterion #2 (the skill wrapping the command, `on_pr` + `manual`) and supports #1/#3/#4 by driving the command whose pure functions are unit-tested. Introduces no new `harness validate` findings.
|
|
59
|
+
|
|
60
|
+
## Escalation
|
|
61
|
+
|
|
62
|
+
- **No PR for the current branch (`--comment`).** The command warns and prints the brief to stdout instead of posting, still exiting 0. Surface the warning; do not treat it as a failure.
|
|
63
|
+
- **No review artifact (`--from` missing/absent).** The review-verdict section degrades to "unavailable". If a verdict is wanted, run `harness review-ci --json <path>` first and pass it.
|
|
64
|
+
- **`gh` unauthenticated or API error while posting.** Delivery fails soft (brief printed, one-line stderr warning, exit 0). Fix `gh auth` and re-run; nothing is lost.
|
|
65
|
+
- **Signals or outcome-eval unavailable.** Each degrades independently to its "unavailable"/"not yet evaluated" line — expected pre-merge, not an error. Do not block the brief on them.
|
|
66
|
+
- **Someone asks to make the brief block merges.** That is the deferred acknowledgment gate (spec D3), a separate future spec. Keep the brief advisory; point them at the follow-up roadmap row.
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
### Example: brief on a PR in CI (dogfood)
|
|
71
|
+
|
|
72
|
+
The `required-review.yml` workflow runs `review-ci --json /tmp/review.json`, then this skill's command:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
harness pre-merge-brief --from /tmp/review.json --diff "origin/main...HEAD" --comment
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The brief is composed and upserted as a sticky PR comment. The review found one blocking finding and two `alert` signals, so **👀 Worth your eyes** lists exactly those three; the outcome section shows "not yet evaluated" (no `execution_outcome` node pre-merge). The step is `continue-on-error`, so even if `gh` posting fails the review gate is unaffected.
|
|
79
|
+
|
|
80
|
+
### Example: senior running it locally
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
harness pre-merge-brief --comment
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
No `--from`, so the review-verdict section renders "unavailable"; signals are gathered live and the diff summary uses the default `origin/<base>...HEAD` range. The senior sees the current signal status and diff before clicking merge.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: harness-pre-merge-brief
|
|
2
|
+
version: "0.1.0"
|
|
3
|
+
description: >-
|
|
4
|
+
Thin-wrapper skill that runs the `harness pre-merge-brief` command to compose
|
|
5
|
+
and post the senior-facing pre-merge accountability brief — the diff summary,
|
|
6
|
+
the multi-persona review verdict (from review-ci --json), the curated Signal
|
|
7
|
+
status snapshot, the outcome-eval result, and a derived "Worth your eyes"
|
|
8
|
+
section — as a single sticky PR comment (upsert by marker). All composition and
|
|
9
|
+
degradation logic lives in the command; the skill orchestrates invocation,
|
|
10
|
+
communicates which sections degraded to "unavailable", and hands off. Runs on
|
|
11
|
+
on_pr and manual. The harness pointed at the human who clicks merge.
|
|
12
|
+
stability: draft
|
|
13
|
+
cognitive_mode: constructive-architect
|
|
14
|
+
triggers:
|
|
15
|
+
- on_pr
|
|
16
|
+
- manual
|
|
17
|
+
platforms:
|
|
18
|
+
- claude-code
|
|
19
|
+
- gemini-cli
|
|
20
|
+
- cursor
|
|
21
|
+
- codex
|
|
22
|
+
tools:
|
|
23
|
+
- Bash
|
|
24
|
+
- Read
|
|
25
|
+
- Glob
|
|
26
|
+
- Grep
|
|
27
|
+
- emit_interaction
|
|
28
|
+
cli:
|
|
29
|
+
command: harness pre-merge-brief
|
|
30
|
+
args:
|
|
31
|
+
- name: from
|
|
32
|
+
description: Path to the review-ci --json CiReviewResult artifact to reuse
|
|
33
|
+
required: false
|
|
34
|
+
- name: comment
|
|
35
|
+
description: Upsert the brief as a sticky PR comment via gh (by marker)
|
|
36
|
+
required: false
|
|
37
|
+
- name: diff
|
|
38
|
+
description: "git diff range for the diff summary (e.g. origin/main...HEAD)"
|
|
39
|
+
required: false
|
|
40
|
+
- name: head
|
|
41
|
+
description: "head commit sha for the outcome-eval lookup (default: git rev-parse HEAD)"
|
|
42
|
+
required: false
|
|
43
|
+
mcp:
|
|
44
|
+
tool: run_skill
|
|
45
|
+
input:
|
|
46
|
+
skill: harness-pre-merge-brief
|
|
47
|
+
path: string
|
|
48
|
+
type: rigid
|
|
49
|
+
tier: 2
|
|
50
|
+
phases:
|
|
51
|
+
- name: gather
|
|
52
|
+
description: Locate the review-ci --json artifact, resolve the diff range, confirm gh auth for --comment
|
|
53
|
+
required: true
|
|
54
|
+
- name: compose
|
|
55
|
+
description: Run `harness pre-merge-brief` with the resolved inputs; the command builds the brief and (with --comment) upserts the sticky PR comment
|
|
56
|
+
required: true
|
|
57
|
+
- name: report
|
|
58
|
+
description: Report which sections rendered and which degraded to "unavailable"; surface the "Worth your eyes" items
|
|
59
|
+
required: true
|
|
60
|
+
- name: handoff
|
|
61
|
+
description: Emit the transition; the brief is advisory (non-blocking) and never flips the review gate
|
|
62
|
+
required: true
|
|
63
|
+
state:
|
|
64
|
+
persistent: false
|
|
65
|
+
depends_on:
|
|
66
|
+
- harness-code-review
|
|
67
|
+
- outcome-eval
|
|
@@ -108,6 +108,37 @@ On return: read `planPath` from `{sessionDir}/handoff.json`. Complexity override
|
|
|
108
108
|
|
|
109
109
|
### EXECUTE
|
|
110
110
|
|
|
111
|
+
**Pre-dispatch: plan parallelization (standard automatic parallelism).** Before dispatching tasks, decide the safe parallel structure. This is orchestration, not reimplementation — autopilot chooses HOW to dispatch; the persona agents still do the work.
|
|
112
|
+
|
|
113
|
+
1. Collect the phase's tasks with their `files` and `dependsOn` (from the plan's task headers). Call the `plan_parallelization` MCP tool:
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"path": "<project-root>",
|
|
118
|
+
"tasks": [{ "id": "task-1", "files": ["..."], "dependsOn": [] }],
|
|
119
|
+
"depth": 1
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
It returns a `ParallelizationPlan`: `waves[]` (each `{ tasks, severity, firing, analysisLevel }`), `serialized[]`, `cyclic[]`, `narration`.
|
|
124
|
+
|
|
125
|
+
2. **If `cyclic` is non-empty:** STOP. Surface the cycle and route back to PLAN/APPROVE_PLAN (a dependency cycle is a plan defect). Do not dispatch.
|
|
126
|
+
|
|
127
|
+
3. **Announce (announce-and-proceed):** emit `narration` verbatim. Do NOT pause here — announcing is not a gate.
|
|
128
|
+
|
|
129
|
+
4. **Dispatch in dependency order — prerequisites first, then waves in array order:**
|
|
130
|
+
- First, run every task in `serialized` (high-severity-group / cycle-adjacent members) **serially**, one `harness-task-executor` per task, in listed order. These are cross-bucket prerequisites: they MUST complete before any wave that depends on them.
|
|
131
|
+
- Then process `waves` **in array order**. The `waves` array is already topologically sorted (earlier waves are prerequisites of later ones). Do NOT reorder waves and do NOT key dispatch off the `firing` field alone — the Phase-2 cross-bucket cap (a wave depending on a serialized/cyclic task is downgraded to `confirm` and marked "cross-bucket prerequisite gates this wave" in `narration`) is only sound if serialized/cyclic ran first and waves run in order.
|
|
132
|
+
|
|
133
|
+
5. **For each wave, honor its `firing`:**
|
|
134
|
+
- `auto-dispatch` (multi-task): emit that wave's line from `narration`, then dispatch the wave via the **harness-parallel-agents** skill with **worktree-per-unit isolation** per `docs/guides/agent-worktree-patterns.md` ("Worktree-per-Milestone" / "Parallel Agent Work": one worktree per task, sequential commits, squash-merge at integrate). **Announce and proceed — do NOT stop for confirmation.**
|
|
135
|
+
- `confirm`: surface the wave and its `narration` line, then take exactly ONE plain-text confirmation — "Dispatch wave [{tasks}] in parallel? (yes / serial)". `yes` → dispatch via harness-parallel-agents (worktree-per-unit). `serial` or decline → run the wave's tasks serially (`harness-task-executor` each). Record the choice in `decisions[]`.
|
|
136
|
+
- `serialize`, or any single-task wave: run serially via `harness-task-executor`, exactly as today.
|
|
137
|
+
|
|
138
|
+
6. **Serial fallback is preserved** when a phase has fewer than `minWaveSize` (default 3) independent tasks, when a `confirm` is declined, or when no graph is available and the human does not confirm — honoring the standing "when in doubt, run serially" default.
|
|
139
|
+
|
|
140
|
+
Each dispatched unit (parallel wave or serial task) then follows the existing per-task contract below (state.json per task, checkpoints, retry budget).
|
|
141
|
+
|
|
111
142
|
Dispatch harness-task-executor:
|
|
112
143
|
|
|
113
144
|
```
|
|
@@ -204,7 +235,7 @@ Persist findings to `{sessionDir}/phase-{N}-review.json`. No blocking → PHASE_
|
|
|
204
235
|
### DONE
|
|
205
236
|
|
|
206
237
|
1. Present: total phases, tasks, retries, time, `finalReview.status` + findings count, any overridden findings.
|
|
207
|
-
2. Ask "Create a PR? (yes / no)."
|
|
238
|
+
2. Ask "Create a PR? (yes / no)." When creating the PR, include a bare closing line `Closes #<N>` where `<N>` is the issue number from the roadmap row's `External-ID`. The keyword MUST sit IMMEDIATELY before the ref — no intervening words (`Closes #<N>`, never `Closes roadmap #<N>`), or GitHub will not link/close the issue and roadmap auto-done will skip the row.
|
|
208
239
|
3. Write final handoff to `{sessionDir}/handoff.json`. Append learnings to `.harness/learnings.md`. Call `promoteSessionLearnings(projectPath, sessionSlug)`. If learnings count > 30, suggest `harness learnings prune`.
|
|
209
240
|
4. If `docs/roadmap.md` exists: call `manage_roadmap update` to set feature done. Skip if not found.
|
|
210
241
|
5. Write final `writeSessionSummary()`. Set `currentState: "DONE"` in autopilot-state.json.
|
|
@@ -254,13 +285,14 @@ Persist findings to `{sessionDir}/phase-{N}-review.json`. No blocking → PHASE_
|
|
|
254
285
|
|
|
255
286
|
## Rationalizations to Reject
|
|
256
287
|
|
|
257
|
-
| Rationalization | Reality
|
|
258
|
-
| ----------------------------------------------------------------------- |
|
|
259
|
-
| "Low complexity means I can skip APPROVE_PLAN" | Low complexity means auto-approval only when no signals fire. Signals override complexity.
|
|
260
|
-
| "I can inline planning logic instead of dispatching to harness-planner" | Iron Law. Autopilot delegates, never reimplements. No exceptions.
|
|
261
|
-
| "Retry budget exhausted but one more approach might work" | 3-attempt budget prevents compounding failure. Exceeding it without human input is unrecoverable.
|
|
262
|
-
| "Keeping research in conversation is faster than scratchpad" | Scratchpad gated by rigor level. At standard/thorough, >500 words must go to scratchpad.
|
|
263
|
-
| "Plan auto-approved, so I can skip recording the decision" | Every approval—auto or manual—is recorded in `decisions[]`. That array is the audit trail.
|
|
288
|
+
| Rationalization | Reality |
|
|
289
|
+
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
290
|
+
| "Low complexity means I can skip APPROVE_PLAN" | Low complexity means auto-approval only when no signals fire. Signals override complexity. |
|
|
291
|
+
| "I can inline planning logic instead of dispatching to harness-planner" | Iron Law. Autopilot delegates, never reimplements. No exceptions. |
|
|
292
|
+
| "Retry budget exhausted but one more approach might work" | 3-attempt budget prevents compounding failure. Exceeding it without human input is unrecoverable. |
|
|
293
|
+
| "Keeping research in conversation is faster than scratchpad" | Scratchpad gated by rigor level. At standard/thorough, >500 words must go to scratchpad. |
|
|
294
|
+
| "Plan auto-approved, so I can skip recording the decision" | Every approval—auto or manual—is recorded in `decisions[]`. That array is the audit trail. |
|
|
295
|
+
| "`Closes roadmap #123` reads fine, GitHub will figure out the issue" | An intervening word breaks GitHub's closing-keyword parser: `closingIssuesReferences` stays empty and auto-done leaves the row `planned`. Use a bare `Closes #123`. |
|
|
264
296
|
|
|
265
297
|
## Success Criteria
|
|
266
298
|
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Harness Catalog Retrospective
|
|
2
|
+
|
|
3
|
+
> Monthly retrospective over skill-adoption telemetry. Reads `.harness/metrics/adoption.jsonl`, ranks the most-invoked, most-failing, and abandoned-mid-workflow skills, flags ever-invoked skills that have gone quiet, and reports how much of the catalog emits any telemetry at all. Produces a dated Markdown report and surfaces the highlights that warrant follow-up. Compounding-via-learning at the catalog grain.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
- On a regular cadence (monthly is the intended grain) to review how the skill catalog is actually being used.
|
|
8
|
+
- After a milestone, to see which skills carried the work and which never fired.
|
|
9
|
+
- When deciding what to prune, fix, or promote in the catalog — the report feeds catalog-rationalization work.
|
|
10
|
+
- NOT as a real-time dashboard — for point-in-time lookups use `harness adoption skills` / `harness adoption recent`.
|
|
11
|
+
- NOT when `.harness/metrics/adoption.jsonl` is absent or empty (the report will be honest but empty; there is nothing to retrospect on yet).
|
|
12
|
+
|
|
13
|
+
## Process
|
|
14
|
+
|
|
15
|
+
### Iron Law
|
|
16
|
+
|
|
17
|
+
**Separate real signal from telemetry gaps before you recommend anything.** The single most common misread of this data is treating "no telemetry" as "abandoned." Adoption records are emitted only from instrumented entry points, so a skill with zero records is usually uninstrumented, not unused. The report's coverage line and the stale-skills section exist to keep that distinction visible — never collapse it.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
### Phase 1: SCAN — Derive the Report
|
|
22
|
+
|
|
23
|
+
1. Run the retrospective command from the project root:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
harness adoption retrospective # writes docs/retrospectives/<date>.md
|
|
27
|
+
harness adoption retrospective --no-write # print to stdout without writing a file
|
|
28
|
+
harness adoption retrospective --json # structured output for further processing
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Optional flags: `--inactive-days <n>` (stale threshold, default 90), `--top <n>` (rows per section, default 10), `--out <path>` (override the output file).
|
|
32
|
+
|
|
33
|
+
2. The command reads `.harness/metrics/adoption.jsonl` via `readAdoptionRecords`, derives the report via `getCatalogRetrospectiveReport`, and renders it via `renderRetrospectiveMarkdown` (all in `@harness-engineering/core`). Coverage context is computed against the skills discovered under `agents/skills/claude-code/`; when that directory is absent (a consumer project), the coverage line is omitted rather than reporting a false zero.
|
|
34
|
+
|
|
35
|
+
3. If there are no records, say so plainly and stop: "No adoption telemetry found at `.harness/metrics/adoption.jsonl`. Nothing to retrospect on yet."
|
|
36
|
+
|
|
37
|
+
### Phase 2: INTERPRET — Signal vs. Noise
|
|
38
|
+
|
|
39
|
+
Read the report with these discriminations:
|
|
40
|
+
|
|
41
|
+
- **Coverage line first.** "N/total catalog skills have emitted telemetry" frames everything below it. A low ratio means the rankings describe the _instrumented_ slice, not the whole catalog. State the ratio explicitly in your summary.
|
|
42
|
+
- **Failing skills are not automatically broken.** Some commands fail _by design_ (a gate like `ci.check` returning non-zero on a real violation is the gate working). Before flagging a high failure rate as a problem, note whether the skill is a checker/gate whose failures are expected. Call out only failures that look like defects (crashes, unexpected non-zero on clean input).
|
|
43
|
+
- **Abandoned mid-workflow** uses the broadened definition: an explicit `abandoned` outcome, or a non-completed run that had already reached ≥1 phase. Small counts here are meaningful — a workflow skill people start and bail out of mid-way is a UX signal even at n=1.
|
|
44
|
+
- **Stale skills** are drawn only from _ever-invoked_ skills quiet ≥ the threshold. When the record window is shorter than the threshold, the section says so and reports nothing — do not present that emptiness as "everything is healthy."
|
|
45
|
+
|
|
46
|
+
### Phase 3: REPORT — Surface and Recommend
|
|
47
|
+
|
|
48
|
+
1. Confirm where the report was written (`docs/retrospectives/<date>.md`) or present the rendered Markdown.
|
|
49
|
+
2. Summarize the 3–5 findings that actually warrant action, each tied to a section and a number. Prefer specifics ("`cli/review-ci` failed 23/23 — likely a real defect, worth a look") over restating the tables.
|
|
50
|
+
3. When the coverage ratio is the dominant finding (e.g. most of the catalog is uninstrumented), name that as the top follow-up: instrumentation, not pruning, is the lever.
|
|
51
|
+
4. Do not delete, prune, or edit skills from this skill — it reports. Hand any pruning decision to the human or to catalog-rationalization work.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Harness Integration
|
|
56
|
+
|
|
57
|
+
- **`harness adoption retrospective`** — the CLI entry point (a subcommand of the existing `adoption` command group). Writes `docs/retrospectives/<date>.md` by default.
|
|
58
|
+
- **`getCatalogRetrospectiveReport` / `renderRetrospectiveMarkdown` / `isAbandonedMidWorkflow`** — the pure aggregation + render functions in `@harness-engineering/core` (`packages/core/src/adoption/retrospective.ts`). Callers can supply a fixed `now` and `catalogSkills` for deterministic output.
|
|
59
|
+
- **`readAdoptionRecords`** — reads and parses `.harness/metrics/adoption.jsonl` (read-only; the file is appended by the adoption-tracker hook, never by this skill).
|
|
60
|
+
- **`harness adoption skills` / `recent` / `skill <name>`** — the point-in-time siblings; this skill is the periodic, persisted counterpart.
|
|
61
|
+
|
|
62
|
+
## Success Criteria
|
|
63
|
+
|
|
64
|
+
1. The retrospective is derived from `.harness/metrics/adoption.jsonl` without mutating it.
|
|
65
|
+
2. The report ranks top-invoked, top-failing, and abandoned-mid-workflow skills, and flags ever-invoked stale skills.
|
|
66
|
+
3. The report states telemetry coverage (how much of the catalog emits any signal) when the catalog is discoverable.
|
|
67
|
+
4. The stale-skills section notes when the record window is shorter than the inactivity threshold instead of silently reporting zero.
|
|
68
|
+
5. The summary separates real signal (defect-shaped failures, mid-workflow abandonment) from telemetry gaps (uninstrumented skills) and from expected gate failures.
|
|
69
|
+
6. A dated report is written to `docs/retrospectives/<date>.md` (unless `--no-write`/`--json` is requested).
|
|
70
|
+
7. The skill recommends but never prunes, edits, or deletes catalog skills.
|
|
71
|
+
|
|
72
|
+
## Rationalizations to Reject
|
|
73
|
+
|
|
74
|
+
| Rationalization | Reality |
|
|
75
|
+
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
76
|
+
| "756 skills have no telemetry, so 756 skills are abandoned — recommend deleting them." | Zero telemetry almost always means _uninstrumented_, not unused. The coverage line exists to prevent exactly this misread; the fix is instrumentation, not pruning. |
|
|
77
|
+
| "`ci.check` fails 97% of the time — it's broken." | A gate returning non-zero on a real violation is the gate working. Check whether the skill is a checker before flagging its failures as defects. |
|
|
78
|
+
| "The stale section is empty, so the catalog is healthy." | If the record window is shorter than the threshold, the signal simply cannot fire yet. Empty ≠ healthy; report the window caveat. |
|
|
79
|
+
| "n=1 abandonment is noise, ignore it." | A workflow skill users start and bail out of mid-way is a UX signal even at low n. Surface it; let the human weigh it. |
|
|
80
|
+
| "I'll prune the low-usage skills while I'm here." | This skill reports; it does not prune. Pruning is a human/catalog-rationalization decision. |
|
|
81
|
+
|
|
82
|
+
## Examples
|
|
83
|
+
|
|
84
|
+
### Example: Monthly retrospective on the dogfood repo
|
|
85
|
+
|
|
86
|
+
**Context:** ~67 days of telemetry (3.2k records) across 50 invoked skills, run at month end.
|
|
87
|
+
|
|
88
|
+
**Phase 1 — SCAN:**
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
harness adoption retrospective
|
|
92
|
+
# → Catalog retrospective written to docs/retrospectives/2026-07-06.md
|
|
93
|
+
# 3246 records · 50 skills · window 67d
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Phase 2 — INTERPRET:** The report's overview leads with `Telemetry coverage: 5/761 catalog skills have emitted telemetry (756 never invoked)`. Top-invoked is dominated by `cli/*` commands; `cli/ci.check` shows a 97% failure rate; the abandoned-mid-workflow section lists four workflow skills at n=1; the stale section is empty with the note that the 67-day window is shorter than the 90-day threshold.
|
|
97
|
+
|
|
98
|
+
**Phase 3 — REPORT:**
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Retrospective written to docs/retrospectives/2026-07-06.md. Findings that warrant action:
|
|
102
|
+
|
|
103
|
+
1. Coverage is the headline: only 5/761 catalog skills emit any telemetry. The rankings
|
|
104
|
+
describe the instrumented slice, not the catalog. Top follow-up is instrumentation, not pruning.
|
|
105
|
+
2. `cli/ci.check` failed 97% (721/741) — but it is a gate; non-zero on a real violation is
|
|
106
|
+
expected. Not flagged as a defect.
|
|
107
|
+
3. `cli/review-ci` failed 23/23 (100%) — defect-shaped, worth a look. Routed to debugging.
|
|
108
|
+
4. Four workflow skills were abandoned mid-run (n=1 each) — low volume, a UX signal to watch.
|
|
109
|
+
5. Stale skills: none — the 67-day window can't satisfy the 90-day threshold yet.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
No skills were pruned or edited — the pruning decision is left to the human.
|
|
113
|
+
|
|
114
|
+
## Gates
|
|
115
|
+
|
|
116
|
+
- **No mutation of `adoption.jsonl`.** The telemetry file is read-only input.
|
|
117
|
+
- **No catalog edits.** This skill never adds, edits, or deletes skills — it only reports on them.
|
|
118
|
+
- **Coverage must be stated when discoverable.** If the catalog can be scanned, the summary must include the telemetry-coverage ratio so rankings are read in context.
|
|
119
|
+
|
|
120
|
+
## Escalation
|
|
121
|
+
|
|
122
|
+
- **When there are no records:** State that telemetry is absent/empty and stop. Suggest confirming the adoption-tracker hook is installed if telemetry is unexpectedly missing.
|
|
123
|
+
- **When coverage is very low:** Name instrumentation as the top follow-up and note that the rankings describe only the instrumented slice.
|
|
124
|
+
- **When a failing skill looks like a real defect:** Flag it specifically (skill, failure count/rate, why it looks defect-shaped) and route it to debugging or an issue, rather than burying it in the table.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: harness-catalog-retrospective
|
|
2
|
+
version: '1.0.0'
|
|
3
|
+
description: Monthly retrospective over skill-adoption telemetry — ranks most-invoked, failing, and abandoned-mid-workflow skills, flags stale ones, and reports catalog telemetry coverage
|
|
4
|
+
stability: static
|
|
5
|
+
cognitive_mode: analytical-reporter
|
|
6
|
+
triggers:
|
|
7
|
+
- manual
|
|
8
|
+
- on_milestone
|
|
9
|
+
platforms:
|
|
10
|
+
- claude-code
|
|
11
|
+
- gemini-cli
|
|
12
|
+
- cursor
|
|
13
|
+
- codex
|
|
14
|
+
tools:
|
|
15
|
+
- Bash
|
|
16
|
+
- Read
|
|
17
|
+
- Glob
|
|
18
|
+
- Grep
|
|
19
|
+
cli:
|
|
20
|
+
command: harness skill run harness-catalog-retrospective
|
|
21
|
+
args:
|
|
22
|
+
- name: path
|
|
23
|
+
description: Project root path
|
|
24
|
+
required: false
|
|
25
|
+
- name: inactive-days
|
|
26
|
+
description: 'Inactivity threshold in days for the stale-skills section (default: 90)'
|
|
27
|
+
required: false
|
|
28
|
+
mcp:
|
|
29
|
+
tool: run_skill
|
|
30
|
+
input:
|
|
31
|
+
skill: harness-catalog-retrospective
|
|
32
|
+
path: string
|
|
33
|
+
type: rigid
|
|
34
|
+
tier: 2
|
|
35
|
+
phases:
|
|
36
|
+
- name: scan
|
|
37
|
+
description: Read adoption telemetry and derive the retrospective report
|
|
38
|
+
required: true
|
|
39
|
+
- name: interpret
|
|
40
|
+
description: Read the rankings and coverage, separating real signal from telemetry gaps
|
|
41
|
+
required: true
|
|
42
|
+
- name: report
|
|
43
|
+
description: Write the dated report and surface highlights plus recommendations
|
|
44
|
+
required: true
|
|
45
|
+
state:
|
|
46
|
+
persistent: false
|
|
47
|
+
files: []
|
|
48
|
+
depends_on: []
|