@shahboura/harness 3.0.4

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 (62) hide show
  1. package/.opencode/agents/developer.md +60 -0
  2. package/.opencode/agents/planner.md +51 -0
  3. package/.opencode/agents/reviewer.md +53 -0
  4. package/.opencode/commands/add-repo.md +26 -0
  5. package/.opencode/commands/dev-workflow.md +40 -0
  6. package/.opencode/commands/init-workspace.md +22 -0
  7. package/.opencode/commands/migrate-workspace.md +28 -0
  8. package/.opencode/commands/repo-map-refresh.md +23 -0
  9. package/.opencode/commands/story-workflow.md +24 -0
  10. package/.opencode/commands/workflow-status.md +23 -0
  11. package/.opencode/commands/workspace-config.md +27 -0
  12. package/.opencode/package.json +9 -0
  13. package/.opencode/plugins/harness-guards.ts +290 -0
  14. package/.opencode/skills/add-repo/SKILL.md +96 -0
  15. package/.opencode/skills/dev-workflow/SKILL.md +105 -0
  16. package/.opencode/skills/dev-workflow/shared/diagram-styling.md +65 -0
  17. package/.opencode/skills/dev-workflow/shared/engineering.md +14 -0
  18. package/.opencode/skills/dev-workflow/shared/status-block.md +29 -0
  19. package/.opencode/skills/dev-workflow/steps/analyze-comments.md +32 -0
  20. package/.opencode/skills/dev-workflow/steps/apply-fixes.md +24 -0
  21. package/.opencode/skills/dev-workflow/steps/comment-analysis.md +11 -0
  22. package/.opencode/skills/dev-workflow/steps/create-pr.md +39 -0
  23. package/.opencode/skills/dev-workflow/steps/develop-task.md +54 -0
  24. package/.opencode/skills/dev-workflow/steps/develop.md +60 -0
  25. package/.opencode/skills/dev-workflow/steps/fetch.md +34 -0
  26. package/.opencode/skills/dev-workflow/steps/fixup-task.md +12 -0
  27. package/.opencode/skills/dev-workflow/steps/gate.md +53 -0
  28. package/.opencode/skills/dev-workflow/steps/harden-task.md +12 -0
  29. package/.opencode/skills/dev-workflow/steps/harden.md +30 -0
  30. package/.opencode/skills/dev-workflow/steps/intake.md +52 -0
  31. package/.opencode/skills/dev-workflow/steps/metrics.md +21 -0
  32. package/.opencode/skills/dev-workflow/steps/plan-task.md +108 -0
  33. package/.opencode/skills/dev-workflow/steps/plan.md +80 -0
  34. package/.opencode/skills/dev-workflow/steps/pre-pr-fixes.md +16 -0
  35. package/.opencode/skills/dev-workflow/steps/pre-pr-review.md +14 -0
  36. package/.opencode/skills/dev-workflow/steps/pre-pr.md +14 -0
  37. package/.opencode/skills/dev-workflow/steps/preflight.md +32 -0
  38. package/.opencode/skills/dev-workflow/steps/quick-recheck.md +14 -0
  39. package/.opencode/skills/dev-workflow/steps/reconcile.md +27 -0
  40. package/.opencode/skills/dev-workflow/steps/review-task.md +32 -0
  41. package/.opencode/skills/dev-workflow/steps/security.md +18 -0
  42. package/.opencode/skills/dev-workflow/steps/triage-request.md +15 -0
  43. package/.opencode/skills/init-workspace/SKILL.md +155 -0
  44. package/.opencode/skills/migrate-workspace/SKILL.md +122 -0
  45. package/.opencode/skills/repo-map-refresh/SKILL.md +43 -0
  46. package/.opencode/skills/story-workflow/SKILL.md +78 -0
  47. package/.opencode/skills/story-workflow/commands/analyze.md +40 -0
  48. package/.opencode/skills/story-workflow/commands/groom.md +58 -0
  49. package/.opencode/skills/story-workflow/commands/improve.md +47 -0
  50. package/.opencode/skills/story-workflow/commands/refine.md +44 -0
  51. package/.opencode/skills/story-workflow/shared/context.md +22 -0
  52. package/.opencode/skills/story-workflow/shared/provider-io.md +73 -0
  53. package/.opencode/skills/story-workflow/templates/readiness-report.md +57 -0
  54. package/.opencode/skills/story-workflow/templates/story-template.md +51 -0
  55. package/.opencode/skills/story-workflow/templates/technical-notes.md +48 -0
  56. package/.opencode/skills/workflow-status/SKILL.md +30 -0
  57. package/.opencode/skills/workspace-config/SKILL.md +97 -0
  58. package/.opencode/tsconfig.json +11 -0
  59. package/CHANGELOG.md +396 -0
  60. package/LICENSE +21 -0
  61. package/README.md +351 -0
  62. package/package.json +32 -0
@@ -0,0 +1,155 @@
1
+ ---
2
+ name: init-workspace
3
+ version: "3.0.0"
4
+ author: "Mostafa Ashraf"
5
+ description: >
6
+ One-time workspace setup for the ai-sdlc-harness pipeline. USER-ENTRY and
7
+ HUMAN-ONLY — invoke only when the user explicitly runs /init-workspace;
8
+ ---
9
+
10
+
11
+ # init-workspace — the interview (M7)
12
+
13
+ Human-only: the user's consent point for the whole workspace. Every command
14
+ below is `bin/harness <verb> …` — always the full
15
+ path; a bare `harness` is not on PATH, and shell variables set in one Bash
16
+ call do not persist to the next. Re-running refreshes **one section at a
17
+ time** (`init-section`), never a full-nuke.
18
+
19
+ ## 0 · Environment bootstrap (do this FIRST)
20
+
21
+ The harness needs PyYAML; system pythons are often externally managed
22
+ (PEP 668), so the plugin owns a venv that `bin/harness` resolves
23
+ automatically on every future call:
24
+
25
+ ```
26
+ PY=".venv/bin/python"
27
+ [ -x "$PY" ] || PY=".venv/Scripts/python.exe"
28
+ "$PY" -c "import yaml" 2>/dev/null || {
29
+ SYS="$(command -v python3 || command -v python)" &&
30
+ "$SYS" -m venv ".venv" &&
31
+ PY=".venv/bin/python" &&
32
+ { [ -x "$PY" ] || PY=".venv/Scripts/python.exe"; } &&
33
+ "$PY" -m pip install --quiet pyyaml; }
34
+ ```
35
+
36
+ One snippet for every OS: the Bash tool is Git Bash on Windows, so this
37
+ stays POSIX shell there too — the two `.venv` probes cover the `bin/` (POSIX)
38
+ vs `Scripts/` (Windows) venv layouts, and the `python3 || python` fallback
39
+ covers hosts where only one spelling exists. Until this step runs,
40
+ `bin/harness` itself still works (it falls back to the same system
41
+ interpreter probe, which is what fails on a PyYAML-less system — that's why
42
+ this step exists), and the spawn/skill guards degrade open with a one-line
43
+ notice rather than erroring — expected pre-setup behavior, not a bug to chase.
44
+
45
+ ## 1 · Must-provide (no defaults — ask)
46
+
47
+ - **Work-item provider**: local-markdown / github / gitlab / ado (CLI) /
48
+ ado-mcp / jira / zoho (MCP — walk the user through the model-in-the-loop MCP
49
+ integration probe). ADO is available on either transport (`ado` = `az boards`,
50
+ `ado-mcp` = Azure DevOps MCP server). Plus its specifics (stories dir,
51
+ `github_repo`, `ado_org`, `ado_project`, …).
52
+ - **Git provider**: local / github / gitlab / ado (CLI) / ado-mcp (MCP).
53
+ If the user didn't state one, `local` is the sanctioned inference ONLY
54
+ when every registered repo has no remote (`git remote` empty) — say so
55
+ in one line rather than asking; any repo with a remote → ask.
56
+ - **Repos**: `name=path` per target repo.
57
+
58
+ Every `init-section` write is merged straight into the flat config by its
59
+ top-level keys, so `provider`, `repos`, and `language` payloads must be
60
+ **self-nested** under their own section key:
61
+
62
+ ```
63
+ bin/harness init-section --section provider --json \
64
+ '{"provider": {"work_item": "local-markdown", "git": "local", "stories_dir": "stories"}}'
65
+ bin/harness init-section --section repos --json \
66
+ '{"repos": {"backend": "/path/to/backend", "frontend": "/path/to/frontend"}}'
67
+ ```
68
+
69
+ `overrides` is the one exception on both counts: it's a flat grab-bag of
70
+ top-level config keys (`status_mapping`, `subagent_models`, `quick_mode`,
71
+ …), never self-nested under an `"overrides"` key, and unlike
72
+ `provider`/`repos`/`language` (each write replaces the whole file — always
73
+ send the complete current set) its writes **merge**, so separate
74
+ `--section overrides` calls for different settings accumulate rather than
75
+ clobbering each other. See step 3.
76
+
77
+ ## 2 · Discovered, then confirmed
78
+
79
+ Run `bin/harness discover --repo <path>` per repo. `discover` first
80
+ ensures the repo is clean and on its default branch (`ensure_default_branch`
81
+ — the same reusable precondition `preflight` uses later): a dirty repo, or
82
+ one mid-rebase/merge, refuses with a clear error — surface it to the user
83
+ (never auto-stash/discard/continue) — and a clean repo on a different
84
+ branch is switched, reported back in `branch_check` so the interview can
85
+ tell the user it happened. If the guessed default branch doesn't exist
86
+ locally (no resolvable `origin/HEAD`), pass `--branch <name>` explicitly —
87
+ note this only catches a *nonexistent* guess; a repo with no `origin` and
88
+ a stray local branch that happens to be named `main` cannot be told apart
89
+ from a genuine one, so confirm the branch name with the user for any repo
90
+ without a resolvable `origin/HEAD`.
91
+ **Known risk:** re-running this against a repo that already has an active
92
+ `/dev-workflow` run in progress can switch that run's feature-branch
93
+ checkout back to default — avoid re-running discovery for a repo with
94
+ in-flight work. Present the proposals (language, `test_cmd`, default
95
+ branch) as defaults-to-confirm. A `monorepo_split` proposal means this "one
96
+ repo" is actually several logical repos sharing one `.git` at the physical
97
+ root — **this isn't yet representable as separate registered repos**
98
+ (`init-verify`'s `repo:<name>` check requires a `.git` directly under the
99
+ registered path, which no subtree has, so registering subtrees separately
100
+ leaves every one of them permanently failing verification with no
101
+ available fix). Tell the user this is a known gap; register the repo once,
102
+ at its physical root.
103
+ **Language-config is per repo**, under `language.repos`, keyed by the same
104
+ names used in `--section repos` (a sub-key, not a sibling of the global
105
+ `test_paths`/`test_closure` settings, so a repo name can never collide with
106
+ those) — confirm each repo's own `test_cmd` by running it, never collapse
107
+ differing repos onto one command. **`coverage_cmd` gets the same
108
+ treatment**: discover proposes one only on repo evidence (a `coverage`
109
+ script, jest/vitest+provider, jacoco in the pom) — confirm it by running
110
+ it. No proposal → ask the user for one (the harden step consumes it and
111
+ never improvises); an explicit skip is a valid answer, recorded by simply
112
+ omitting the key — tell the user harden will re-ask at run time. Write the
113
+ whole set in one `--section language` call, e.g. `{"language": {"repos":
114
+ {"backend": {"test_cmd": "sh mvnw -q test", "coverage_cmd": "sh mvnw -q
115
+ test jacoco:report"}, "frontend": {"test_cmd": "npm test"}}}}`.
116
+
117
+ ## 3 · Choose-or-default (offer "default" explicitly, every time)
118
+
119
+ Status-mapping override (provider defaults usually suffice), change-types +
120
+ naming templates, `subagent_models` (default all `inherit`), quick-mode
121
+ thresholds/keywords, repo-map staleness N, review-policy team rules,
122
+ `security.scan_cmd` (if a scanner is configured, it's per-repo-keyed the
123
+ same way `language` is — no scanner configured stays informational-only).
124
+ Only what the user changes goes in `--section overrides` — shipped
125
+ defaults cover the rest. Unlike `provider`/`repos`/`language`, this payload
126
+ is **flat, not self-nested** (these are top-level config keys in their own
127
+ right), e.g. `--section overrides --json '{"quick_mode": {"loc_max":
128
+ 50}}'` — never `{"overrides": {...}}`. Each call deep-merges into whatever is
129
+ already there, so it's fine to write these one setting at a time as the
130
+ user decides them; there's no way to *unset* a previously-written override
131
+ through this verb though — that needs a direct edit to `overrides.yaml`.
132
+
133
+ ## 4 · Verify (a real gate) + finish
134
+
135
+ 1. `bin/harness init-verify` — every check must pass
136
+ (or be `manual` with the user's explicit acknowledgment for MCP
137
+ providers). Failures show remediation; fix and re-run. **Do not proceed
138
+ on failures.**
139
+ 2. `bin/harness init-finalize` — writes the permissions
140
+ allowlist and the bootstrap marker (section writes alone do not write
141
+ either of these). It re-runs the same verify gate itself and refuses
142
+ (exit 1) if any check still fails, so it can't mark a half-configured
143
+ workspace bootstrapped even if step 1 above was skipped by mistake.
144
+ Confirm `.claude/settings.json` merged cleanly (non-destructive).
145
+ 3. **Repo-map**: offer to generate one now per repo, following
146
+ `/repo-map-refresh`'s step 2 exactly (subagent_type-guessing warning,
147
+ `harness-mode: repo-map` header, and stamp-it-yourself rule all live
148
+ there — this file doesn't keep its own copy).
149
+ 4. Tell the user: `/dev-workflow <work-item-id>` is ready.
150
+
151
+ ## 5 · Adding a repo after the fact
152
+
153
+ Use the dedicated `/add-repo` skill — it's the one place this procedure
154
+ (discover → confirm → register → verify → finalize) is maintained; don't
155
+ hand-roll it here too.
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: migrate-workspace
3
+ version: "3.0.0"
4
+ author: "Mostafa Ashraf"
5
+ description: >
6
+ Adopt a v2.x ai-sdlc-harness workspace into v3.0 — config carries over,
7
+ run history stays archived in place. USER-ENTRY and HUMAN-ONLY — invoke
8
+ only when the user explicitly runs /migrate-workspace; never autonomously,
9
+ ---
10
+
11
+
12
+ # migrate-workspace — adopt a v2.x workspace
13
+
14
+ **The fork seam:** this file and `harness/migrate.py` are the replaceable
15
+ unit — forks ship different adoption logic by swapping them and nothing
16
+ else. Everything that WRITES goes through the same owned path as
17
+ `/init-workspace` (`init-section` → `init-verify` → `init-finalize`);
18
+ migrate verbs are read-only proposals.
19
+
20
+ Human-only, same invocation rules as every skill here: always the full
21
+ `bin/harness <verb>` path. First run
22
+ `/init-workspace`'s **step 0 environment bootstrap** exactly as written
23
+ there (that file owns the procedure — don't re-derive it).
24
+
25
+ ## 1 · Detect (stop conditions first)
26
+
27
+ ```
28
+ bin/harness migrate-detect
29
+ ```
30
+
31
+ - Surface `warnings` verbatim whenever present — e.g. an unreadable
32
+ `overrides.yaml` reports as bootstrapped *fail-closed*, and the
33
+ remediation lives in the warning, not here.
34
+ - `already_bootstrapped: true` → this workspace already runs v3.0. If
35
+ `inventory.legacy_context_files` is non-empty, a prior migration stopped
36
+ before archiving — offer the **archive-only finish** (steps 5–6; the
37
+ report on this path records `inventory` only, since `migrate-extract`
38
+ rightly refuses post-bootstrap — the carried-config record lives in the
39
+ earlier attempt's confirmations); otherwise **stop** and point the user
40
+ at `/workspace-config`.
41
+ - `legacy: null` → **stop**: nothing to adopt; point at `/init-workspace`.
42
+ - Otherwise show the `evidence` list (why this looks like v2.x), then the
43
+ `inventory`:
44
+ - **`in_flight` runs get a hard boundary, stated plainly:** run history
45
+ is never converted — v3.0 state is sealed evidence (red-proofs,
46
+ ledgers) that v2.x never produced, so migrating a half-done run would
47
+ fabricate its audit trail. **Recommend finishing or abandoning those
48
+ stories on v2.x before migrating**: step 5 archives the very config
49
+ files v2.x resumes from, so proceeding now means a later v2.x session
50
+ must first hand-restore them from `legacy-2.1/`. Proceeding anyway is
51
+ the user's call — record the choice in the step-5 report.
52
+ - Old `ai/` run dirs and `aborted` leftovers stay exactly where they are
53
+ as readable archives; v3.0 run discovery ignores them.
54
+
55
+ ## 2 · Extract & confirm (propose-only)
56
+
57
+ ```
58
+ bin/harness migrate-extract
59
+ ```
60
+
61
+ Present the proposal per section — `provider`, `repos`, `language` — next
62
+ to every `notes` entry (missing repo paths, unverifiable stories_dir) and
63
+ the `unmapped` list (what v2.x config has no v3.0 home, and why). The user
64
+ confirms or corrects **each section**; anything extract could not fill
65
+ falls through to the matching `/init-workspace` interview question — never
66
+ guess a value extraction didn't find.
67
+
68
+ **Re-entry:** if a target section file already exists under
69
+ `.claude/context/` (a prior attempt got that far), read it and present its
70
+ current value next to the legacy-derived proposal — never silently
71
+ re-propose stale legacy data over a correction the user already confirmed.
72
+
73
+ `optional_overrides.naming` is **opt-in, default NO**: translated v2.1
74
+ naming templates are usually the v2.1 defaults the user never chose, and
75
+ v3.0's `{type}/{id}-{slug}` handles change-types better than a frozen
76
+ `feature/` prefix. Offer it only as "did you deliberately customize
77
+ naming in v2.x?".
78
+
79
+ ## 3 · Apply through the owned init path
80
+
81
+ Write each confirmed section with `init-section` exactly as
82
+ `/init-workspace` step 1 documents (self-nested payloads; `overrides`
83
+ flat). Then fill the gaps the same way that interview does:
84
+
85
+ - No `language` proposal for a repo → `discover --repo <path>` and confirm
86
+ (its dirty-repo/default-branch cautions live in `/init-workspace` step 2).
87
+ **`discover` switches a clean repo back to its default branch** — if
88
+ `inventory.in_flight` names a story whose v2.x feature branch may be
89
+ checked out in that repo, say so and get explicit confirmation first.
90
+ - MCP-transport providers (`jira`, `zoho`, `ado-mcp`) → the
91
+ model-in-the-loop MCP checklist from the interview applies unchanged.
92
+
93
+ ## 4 · Verify + finalize (the same real gate)
94
+
95
+ `/init-workspace` step 4, verbatim: `init-verify` must pass (fix failures,
96
+ re-run), then `init-finalize`. A migrated workspace ends in exactly the
97
+ state a freshly-interviewed one does — there is no "migrated" flavor to
98
+ special-case later.
99
+
100
+ ## 5 · Archive the legacy config
101
+
102
+ List the v2.x context files (`inventory.legacy_context_files`), confirm
103
+ with the user, then move them aside so nobody mistakes them for live
104
+ config:
105
+
106
+ ```
107
+ mkdir -p .claude/context/legacy-2.1 && mv .claude/context/*.md .claude/context/legacy-2.1/
108
+ ```
109
+
110
+ Write `.claude/context/legacy-2.1/migration-report.md`: what carried over
111
+ (per section), the full `unmapped` and `notes` lists, and any in-flight
112
+ v2.x stories with the finish-on-v2.x guidance. The old `ai/` dirs are the
113
+ run archive; this report is the config-decision record.
114
+
115
+ ## 6 · Hand over
116
+
117
+ - `local-markdown` users: existing story files work in place — v2.1
118
+ `> Status:` blockquotes are read tolerantly and upgrade to the v3.0
119
+ `Status:` form on first write-back.
120
+ - Remote-provider users: work items live server-side; nothing moved.
121
+ - Offer repo-map generation (`/repo-map-refresh` owns the procedure),
122
+ then: `/dev-workflow <work-item-id>` is ready.
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: repo-map-refresh
3
+ version: "3.0.0"
4
+ author: "Mostafa Ashraf"
5
+ description: >
6
+ Regenerate the auto-generated repo map the planner grounds its plans in.
7
+ USER-ENTRY — invoke only when the user explicitly runs /repo-map-refresh;
8
+ ---
9
+
10
+
11
+ # repo-map-refresh
12
+
13
+ The repo map is a navigation aid, never hand-maintained — corrections go
14
+ through regeneration (design.md piece 5B). `/init-workspace` and
15
+ `/add-repo` both point here for the identical generate-or-regenerate
16
+ procedure (step 2 below) — this is the one place it's maintained; don't
17
+ fork a second copy of it elsewhere.
18
+
19
+ 1. `bin/harness repo-map-check --repo-name <n> --repo <path>` — report
20
+ missing / fresh / stale (+ commits behind) to the user.
21
+ 2. To regenerate: spawn the planner shape with `harness-mode: repo-map` as
22
+ the prompt's FIRST line (the spawn guard regex-matches this exact
23
+ header — prose that merely mentions repo-map does not satisfy it; this
24
+ is a declared out-of-run spawn, `pipeline/surfaces.yaml`'s
25
+ `out_of_run_spawns`, legal regardless of whether other runs exist in the
26
+ workspace) and the repo path. Do not guess the planner's `subagent_type`
27
+ string: check your currently available subagent types for whichever one
28
+ corresponds to this plugin's planner (`agents/planner.md`'s frontmatter
29
+ `name: planner` is the identifying detail to match against) —
30
+ `hooks/guards.py`'s spawn guard matches on this shape by the LAST
31
+ `:`-segment of whatever string you pass, and a wrong guess doesn't
32
+ error, it just silently skips the guard's enforcement (fail-closed
33
+ spawn gating, planner's write-confinement to `ai/`/`.claude/context/`),
34
+ which is worse than the guess looking right. The planner can only write
35
+ under `ai/<run>/` and `.claude/context/` (guard-enforced — never repo
36
+ source), so point it at `.claude/context/repo-map/<name>/`. It writes
37
+ the tiered map there: a short top-level index (directories/modules by
38
+ purpose) plus per-area detail files, each loadable alone.
39
+ 3. Stamp it yourself, not the planner:
40
+ `bin/harness repo-map-stamp --repo-name <n> --repo <path>`
41
+ — stamping is the orchestrator's job, never the planner's own.
42
+ 4. Remind the user: the planner still reads real code for areas it plans to
43
+ touch — the map speeds targeting, it doesn't replace reading.
@@ -0,0 +1,78 @@
1
+ ---
2
+ name: story-workflow
3
+ version: "3.0.0"
4
+ author: "Mostafa Ashraf"
5
+ description: >
6
+ Refine, analyze, improve, and groom user stories / work items for quality —
7
+ readiness reports, template restructuring, adaptive gap-filling, and
8
+ codebase-aware technical grooming. USER-ENTRY and HUMAN-ONLY — invoke only
9
+ when the user explicitly runs /story-workflow <command>; never autonomously
10
+ from conversation, never from a subagent (guard-enforced). Distinct from the
11
+ ---
12
+
13
+
14
+ # story-workflow — story-quality refinement (PO-facing)
15
+
16
+ Improves work-item quality through four commands. Read-mostly: it fetches a
17
+ work item, helps shape it, and — only with the user's consent — posts the
18
+ result back as a comment. It never starts a dev run and never touches
19
+ `ai/<run>/` run state.
20
+
21
+ Every harness call is `bin/harness <verb> …` — the full
22
+ path, run by you via Bash (a bare `harness` is not on PATH, and shell variables
23
+ set in one Bash call do not persist to the next). Non-zero exit = refused; read
24
+ the JSON error and act on it.
25
+
26
+ ## Usage
27
+
28
+ ```
29
+ /story-workflow <command> <work-item-id> [session-notes…]
30
+ ```
31
+
32
+ `<command>` is one of `analyze`, `refine`, `improve`, `groom`. `<work-item-id>`
33
+ is whatever the configured provider uses — a number (ADO / GitHub / GitLab), a
34
+ key (`PROJ-123`, Jira), or, for `local-markdown`, the story's **id** (the file
35
+ stem inside `provider.stories_dir`, e.g. `WORK-7` for `WORK-7.md` — not a
36
+ path). Any trailing tokens are session notes, passed through to `improve` and
37
+ `refine`.
38
+
39
+ ## Routing
40
+
41
+ | command | file | one-line |
42
+ |---|---|---|
43
+ | `improve` | `commands/improve.md` | adaptive single-pass: assess → gap-fill → draft (the recommended default) |
44
+ | `analyze` | `commands/analyze.md` | standalone readiness report with flags |
45
+ | `refine` | `commands/refine.md` | slow, section-by-section interactive restructure |
46
+ | `groom` | `commands/groom.md` | codebase-aware per-repo technical notes |
47
+
48
+ Parse `$ARGUMENTS`: the first token is the command, the second is the work-item
49
+ id, the rest are notes. If the command is missing or unknown, print the usage
50
+ line plus the table above and stop — do not guess. If the id is missing, ask
51
+ for it — never proceed without one. Then read the one matching command file and
52
+ follow it (context economy: load a single command file, not all four).
53
+
54
+ ## Before routing
55
+
56
+ 1. Confirm the workspace is bootstrapped: `.claude/context/provider.yaml` must
57
+ exist. If it doesn't, `/init-workspace` never ran — send the user there and
58
+ stop. The active provider is resolved from config by the harness; you never
59
+ hand-pick it.
60
+ 2. The recipe for fetching a work item and posting a result back — for every
61
+ provider and both transports — lives once in `shared/provider-io.md`. Read
62
+ it; the commands cite it instead of repeating it.
63
+ 3. Domain and convention context (for `improve` and `groom`) lives once in
64
+ `shared/context.md`.
65
+
66
+ ## Guardrails (all four commands)
67
+
68
+ - On a remote provider, never edit the item's Description or Acceptance-Criteria
69
+ fields — post back as a **comment** only. The single exception is a
70
+ `local-markdown` story the user explicitly asks you to rewrite in place; see
71
+ `shared/provider-io.md`.
72
+ - Never invent business requirements. A gap is a question for the human, not an
73
+ assertion of what "should" be there.
74
+ - Mirror the user's domain language; don't rename their "platform" to "system".
75
+ - Files in `templates/` are read-only references — don't modify them while a
76
+ command runs.
77
+ - If a story is already well-formed, say so. "This looks ready" is a valid,
78
+ valuable outcome — don't manufacture flags or questions to look busy.
@@ -0,0 +1,40 @@
1
+ # /story-workflow analyze
2
+
3
+ Pre-refinement readiness check. Evaluates a work item against quality criteria
4
+ and produces a readiness report with actionable flags. Standalone and
5
+ non-destructive — it never rewrites the story.
6
+
7
+ > For most sessions `improve` is the better choice — it folds readiness analysis
8
+ > into refinement in one adaptive pass. Reach for `analyze` when you want a
9
+ > standalone report to share with the PO *before* touching the story.
10
+
11
+ ## Steps
12
+
13
+ 1. **Fetch** the work item per `shared/provider-io.md`. Extract title, type,
14
+ state, description, and acceptance criteria. If it isn't found, stop.
15
+ 2. **Domain context (optional)**: skim `shared/context.md` only if you need the
16
+ repo landscape to judge whether the story's scope is realistic.
17
+ 3. **Evaluate** the story against every dimension in
18
+ `templates/readiness-report.md`. For each, assign a 🔴/🟡/🟢 flag with a
19
+ *specific* explanation. Rules:
20
+ - **Be specific, not generic.** Not "ACs could be improved" but "AC #2 says
21
+ 'handles errors gracefully' — untestable; suggest 'Given an invalid token,
22
+ When login is attempted, Then a 401 with code `AUTH_INVALID_TOKEN` is
23
+ returned'."
24
+ - **Suggest, don't only critique.** Every 🔴/🟡 carries a concrete fix —
25
+ draft the replacement text where you can.
26
+ - **Constructive tone.** The PO and team will read this.
27
+ 4. **Write the report** in the `templates/readiness-report.md` format: flags
28
+ with explanations, suggested improvements (draft Given/When/Then ACs where
29
+ ACs are missing or vague), and a 2–3 sentence summary assessment.
30
+ 5. **Present** the full report in the conversation, then ask whether to post it
31
+ as a comment on the item. On yes, post it per `shared/provider-io.md`. For
32
+ `local-markdown` (or any provider), the report is a **comment** — never
33
+ overwrite the story with it; if the user wants it persisted separately,
34
+ offer a sibling file (e.g. `<id>-readiness.md`) via the `Write` tool.
35
+
36
+ ## Notes
37
+
38
+ - Never modify the item's Description or AC fields — comments only.
39
+ - Don't force flags. A report that says "this story is ready" is a good result.
40
+ - Flag missing pieces as **questions**, not assertions about what should exist.
@@ -0,0 +1,58 @@
1
+ # /story-workflow groom
2
+
3
+ Technical enrichment pass. Analyzes the relevant repos to identify affected
4
+ components, migration concerns, testing strategy, and risks, and produces
5
+ per-repo technical notes. This is where Claude Code's native codebase awareness
6
+ is the main tool.
7
+
8
+ ## Steps
9
+
10
+ 1. **Fetch** the work item per `shared/provider-io.md`. If it has no clear ACs
11
+ yet, offer to run `improve` first — grooming is more effective on a refined
12
+ story — but proceed if the user wants to.
13
+ 2. **Identify relevant repos.** Read the repo landscape per `shared/context.md`
14
+ (`repos.yaml` + each `repo-map/<name>/`). From the story, propose which repos
15
+ are affected, each with a one-line reason, and **wait for the user to confirm**
16
+ before scanning anything. Don't scan repos they didn't approve.
17
+ 3. **Refresh remote knowledge, then check position (never mutate the tree).**
18
+ For each confirmed repo, using its path from `repos.yaml`:
19
+ - `git -C "<path>" fetch origin` — allowed, and updates remote refs without
20
+ touching the working tree. If it fails (no network/remote), report and skip
21
+ that repo — don't scan a repo you couldn't refresh.
22
+ - `git -C "<path>" rev-list HEAD..origin/<default-branch> --count` — a read;
23
+ how far behind the checkout is.
24
+ - **The harness blocks raw `git pull` / `merge` inside any workspace that has
25
+ completed `/init-workspace`** (owned-entry-point rule; this skill only ever
26
+ runs inside one), so this command does **not** update the working
27
+ tree. If a repo is behind, say so and offer two choices: **(a)** analyze the
28
+ current checkout as-is — and stamp the staleness into the notes so the
29
+ reader knows the analysis reflects commit `<short-sha>`, N commits behind
30
+ `origin/<default>`; or **(b)** stop for that repo so the user can update it
31
+ themselves (outside the harness) and re-run `groom`. Never switch branches
32
+ or discard changes to "help".
33
+ 4. **Analyze each confirmed, fetched repo** against the story. Use `Grep` for
34
+ content, `Glob` for file patterns, `Read` for inspection — not `Bash` for
35
+ searches. Look for: affected files/classes/methods; database & migration
36
+ impact; API surface (controllers, routes, DTOs); configuration & DI; existing
37
+ test coverage for the touched areas; and cross-service dependencies. Align
38
+ with the team's real patterns from the repo-map (repository pattern, MediatR,
39
+ etc.). **Be concrete** — name the file and method, e.g. "`AuthService.cs`
40
+ `ValidateToken` (~line 45) is what this story changes; tests live in
41
+ `AuthServiceTests.cs`", not "the auth module might be affected."
42
+ 5. **Produce technical notes** in `templates/technical-notes.md` — a section per
43
+ repo, plus Cross-Repo Considerations when more than one repo is involved.
44
+ 6. **Present** the notes and ask whether to post them as a comment. Iterate on
45
+ the user's input (they know planned refactors and constraints the code
46
+ doesn't show), then post per `shared/provider-io.md`. For `local-markdown`,
47
+ notes are a **comment** by default; do not overwrite the story — if the user
48
+ wants them persisted separately, offer a sibling `<id>-technical-notes.md`.
49
+
50
+ ## Notes
51
+
52
+ - Comments only — never edit the item's Description or AC fields.
53
+ - Frame findings as "here's what I see in the code," not "here's how to build
54
+ it." The goal is a head start on scope, not a prescribed implementation.
55
+ - If you can't determine the impact with confidence, say so — "I couldn't tell
56
+ how X is handled; discuss at grooming" is a valid, useful finding.
57
+ - Note unrelated concerns (a bug, tech debt) in one line, but don't derail the
58
+ grooming with them.
@@ -0,0 +1,47 @@
1
+ # /story-workflow improve
2
+
3
+ Single-pass story improvement — assess readiness internally, fill gaps
4
+ conversationally, and produce a refined story, all in one adaptive flow. This
5
+ is the recommended default: it replaces the separate analyze-then-refine dance.
6
+
7
+ ## Steps
8
+
9
+ 1. **Fetch** the work item per `shared/provider-io.md` (title, description,
10
+ acceptance criteria, state, links). If it isn't found, stop.
11
+ 2. **Load** `templates/story-template.md` (target format),
12
+ `templates/readiness-report.md` (used only as an internal rubric — do *not*
13
+ present a standalone report), and `shared/context.md` for domain language.
14
+ 3. **Assess readiness internally** against the rubric, then classify into a tier:
15
+ - **Tier 1 — Solid**: ≤1–2 yellow flags, no red. Draft immediately.
16
+ - **Tier 2 — Some gaps**: 1–3 issues. Specific areas need clarification.
17
+ - **Tier 3 — Rough**: 4+ issues, or a whole section missing (no ACs, no
18
+ description). Needs substantial input.
19
+ 4. **Fill gaps conversationally**, adapted to the tier:
20
+ - **Tier 1**: skip questions, acknowledge what's good, draft.
21
+ - **Tier 2**: ask 2–5 targeted questions — each references the specific gap
22
+ and *proposes an answer to confirm or correct* (the user validates, not
23
+ drafts). Present them all at once.
24
+ - **Tier 3**: say so honestly, ask up to 5 questions, then (if critical gaps
25
+ remain) one more round of up to 3, then draft.
26
+ - **Session notes** (passed after the id) are gold: mine them before asking
27
+ anything, and don't ask what they already answer. If none and the story is
28
+ Tier 2/3, ask once whether any exist.
29
+ 5. **Draft the whole story at once** in `templates/story-template.md`: Context,
30
+ Description, Acceptance Criteria (happy path then error/edge), Out of Scope,
31
+ Open Questions (`[PO]`/`[Tech]`/`[Team]`), and an empty Technical Notes
32
+ (that's `groom`'s). For Tier 2/3, prepend a short "What was improved" list;
33
+ skip it for Tier 1.
34
+ 6. **Review and iterate** — present the full draft, adjust any section the user
35
+ flags. If it's grown too large (>7 ACs, multiple capabilities), suggest a
36
+ split. After minor edits, just confirm the change; don't re-dump the story.
37
+ 7. **Post** on approval per `shared/provider-io.md` — one comment carrying the
38
+ "What was improved" summary (if any) plus the full story. For
39
+ `local-markdown`, offer the in-place overwrite of the source file (this
40
+ command is one of the two that may rewrite a story in place).
41
+
42
+ ## Notes
43
+
44
+ - **Adapt, don't interrogate.** If the story is good, say so and draft fast.
45
+ - **Suggest answers.** The user should be confirming, not drafting from scratch.
46
+ - **One comment, one artifact** — the whole output in a single comment, not one
47
+ per section.
@@ -0,0 +1,44 @@
1
+ # /story-workflow refine
2
+
3
+ Interactive, section-by-section restructuring of a story into the canonical
4
+ template through a collaborative conversation. Slower than `improve` on purpose.
5
+
6
+ > For most sessions `improve` is the better choice. Reach for `refine` when a
7
+ > story is complex or contentious and you want to work through it one section at
8
+ > a time, confirming each before moving on.
9
+
10
+ ## Steps
11
+
12
+ 1. **Fetch** the work item per `shared/provider-io.md` (title, description,
13
+ acceptance criteria, state, links).
14
+ 2. **Session notes**: if the user passed notes after the id, use them. If not,
15
+ ask once: "Any notes from the refinement session — bullet points, rough
16
+ notes, decisions? If not, I'll work from the work item." Notes capture PO
17
+ clarifications and scope calls that never made it into the item.
18
+ 3. **Load** `templates/story-template.md` (the target format) and, for
19
+ terminology, `shared/context.md`.
20
+ 4. **Work the template one section at a time**, proposing content and getting
21
+ approval before moving on:
22
+ - **Context** — draft the business "why"; ask if it's captured correctly.
23
+ - **Description** — one `As a … I want … so that …`. If it spans multiple
24
+ capabilities, flag a possible split before continuing.
25
+ - **Acceptance Criteria** — draft Given/When/Then, happy path first then
26
+ error/edge cases; present them together and ask what's missing.
27
+ - **Out of Scope** — propose explicit exclusions from the notes and context;
28
+ ask what else to exclude.
29
+ - **Open Questions** — collect unresolved items, tag each `[PO]` / `[Tech]` /
30
+ `[Team]`, ask if any remain.
31
+ - **Technical Notes** — leave empty; it's populated by `groom`. If the user
32
+ volunteers technical context, note it but say the full analysis is `groom`.
33
+ 5. **Assemble** the complete story and present it whole for a final review.
34
+ 6. **Post** on approval per `shared/provider-io.md` — a comment on remote
35
+ providers; for `local-markdown`, offer the in-place overwrite of the source
36
+ file (this command is one of the two that may rewrite a story in place).
37
+
38
+ ## Notes
39
+
40
+ - The interactivity is the value — don't rush sections; give the user room to
41
+ correct. Be transparent about inferences: "I'm inferring X from the
42
+ description — right?"
43
+ - If the story looks too large mid-refinement (many ACs, broad scope), suggest
44
+ splitting rather than pushing a bloated story through.
@@ -0,0 +1,22 @@
1
+ # shared/context.md — domain + convention context
2
+
3
+ `improve` and `groom` are stronger when grounded in the team's actual repos and
4
+ patterns. v3.0 keeps that context in two places (there are no `repos-metadata`
5
+ or `conventions` markdown files — those were v2.x, and are gone):
6
+
7
+ - **`.claude/context/repos.yaml`** — the registered repos and their local
8
+ paths. This is the map of what exists and where it lives on disk.
9
+ - **`.claude/context/repo-map/<repo-name>/`** — the auto-generated, tiered
10
+ codebase map (purpose by directory, key abstractions, notable patterns),
11
+ stamped with the SHA it was generated at. This is where "the team uses the
12
+ repository pattern / MediatR / …" comes from; read it rather than re-deriving
13
+ the codebase from scratch.
14
+
15
+ Read both with the `Read` tool. Treat them as **context, not gospel**: the
16
+ repo-map may be stale (it records its own generation SHA) and the user knows
17
+ things the code doesn't. If a repo-map is absent for a repo, say so — `groom`
18
+ can still scan the repository directly (see `commands/groom.md`), and `improve`
19
+ proceeds on the work item alone.
20
+
21
+ Never write anything under `.claude/context/` from this skill — that tree is
22
+ owned by `/init-workspace`, `/add-repo`, and `/repo-map-refresh`.