@zhuk/spego 0.22.0 → 0.23.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/CHANGELOG.md +14 -0
- package/README.md +37 -240
- package/dist/cli/commands/board.d.ts +4 -4
- package/dist/cli/commands/board.js +12 -5
- package/dist/cli/commands/board.js.map +1 -1
- package/dist/cli/commands/workspace.js +1 -1
- package/dist/cli/commands/workspace.js.map +1 -1
- package/dist/delivery/load.js +2 -0
- package/dist/delivery/load.js.map +1 -1
- package/dist/delivery/mirror.d.ts +4 -1
- package/dist/delivery/mirror.js +27 -1
- package/dist/delivery/mirror.js.map +1 -1
- package/dist/delivery/openspec-adapter.js +6 -3
- package/dist/delivery/openspec-adapter.js.map +1 -1
- package/dist/delivery/openspec-parse.d.ts +2 -0
- package/dist/delivery/openspec-parse.js +8 -8
- package/dist/delivery/openspec-parse.js.map +1 -1
- package/dist/delivery/types.d.ts +2 -0
- package/dist/workflows/registry.js +1 -1
- package/dist/workflows/registry.js.map +1 -1
- package/docs/agent-targets.md +32 -0
- package/docs/cli.md +49 -0
- package/docs/delivery-board.md +63 -0
- package/docs/estimation.md +90 -0
- package/docs/openspec-adapter.md +40 -0
- package/docs/workflows.md +129 -0
- package/package.json +2 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Estimation
|
|
2
|
+
|
|
3
|
+
The board prices changes in hours when the workspace declares a `flows` block. Every figure is derived on render and never stored.
|
|
4
|
+
|
|
5
|
+
Vocabulary — Flow, Harness, Flow Hours, Human Hours, Size Tier, Flow Profile, Bias — is defined in [`CONTEXT.md`](../CONTEXT.md).
|
|
6
|
+
|
|
7
|
+
## Configuration
|
|
8
|
+
|
|
9
|
+
Declared in `.spego/config.yaml`. The hours below are illustrative — seed your own, or derive them from history (see [Seeding the first profile](#seeding-the-first-profile)).
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
flows:
|
|
13
|
+
default: zapply
|
|
14
|
+
crossProject: false
|
|
15
|
+
profiles:
|
|
16
|
+
zapply:
|
|
17
|
+
xs: 0.5
|
|
18
|
+
s: 1
|
|
19
|
+
m: 2
|
|
20
|
+
l: 4
|
|
21
|
+
xl: 8
|
|
22
|
+
human:
|
|
23
|
+
xs: 2
|
|
24
|
+
s: 4
|
|
25
|
+
m: 8
|
|
26
|
+
l: 16
|
|
27
|
+
xl: 32
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- `default` names the Flow that prices changes with no per-epic override.
|
|
31
|
+
- `profiles` maps each declared Flow to a seed table over the fixed Size Tier scale (`xs`, `s`, `m`, `l`, `xl`). The scale is not configurable.
|
|
32
|
+
- `human` is one table shared across every Flow.
|
|
33
|
+
- `crossProject` opts into the cross-project rung and defaults to off.
|
|
34
|
+
|
|
35
|
+
Config parsing rejects a `default` naming no declared profile, a table missing a tier or declaring an unknown one, and any hours value that is negative or not finite. A workspace with no `flows` block stays valid and prices nothing.
|
|
36
|
+
|
|
37
|
+
## Pricing
|
|
38
|
+
|
|
39
|
+
For every change whose epic carries a `tier`, the board derives a Flow Estimate from the epic's `flow` profile — the workspace default when unset — and a Human Estimate from the shared table.
|
|
40
|
+
|
|
41
|
+
A change without a `tier`, or naming a `flow` absent from `flows.profiles`, renders `?` in the `hours` column and does not count toward its sprint's total; a sprint holding such pending changes renders its total with a `+?` suffix. Hours render as decimals with trailing zeros trimmed, and sprint totals sum unrounded values. Each sprint panel's title reports the remaining total Flow Estimate of its pending changes.
|
|
42
|
+
|
|
43
|
+
`--json` carries `flowEstimate`, `humanEstimate`, `rung`, and `bias` per priced change, and `flowTotal` and `unpricedPending` per sprint. A workspace with no `flows` block omits the column, the totals, and every one of those fields.
|
|
44
|
+
|
|
45
|
+
## The ladder
|
|
46
|
+
|
|
47
|
+
Each price reports the rung it came from, so a measured number is never mistaken for a guess. Rungs resolve independently per Flow and Size Tier pair — one tier can price from observation while another falls back to the seed on the same board — and runs recorded under one Flow never price another.
|
|
48
|
+
|
|
49
|
+
| Rung | Source | Condition |
|
|
50
|
+
|------|--------|-----------|
|
|
51
|
+
| `observed` | median of this repo's recorded runs | at least three runs for the pair |
|
|
52
|
+
| `cross-project` | median of the cross-project store | `crossProject: true`, local runs below the threshold, store holds three or more |
|
|
53
|
+
| `config-seed` | the declared `profiles` table | everything else |
|
|
54
|
+
|
|
55
|
+
Observed hours carry a `*` in the `hours` column, with a dim legend line whenever a rendered change is observed.
|
|
56
|
+
|
|
57
|
+
Runs arrive through `spego record <change> --flow <name> --hours <n>`, which appends to the epic's `actuals` rather than overwriting — a change delivered across several runs accumulates.
|
|
58
|
+
|
|
59
|
+
## Bias
|
|
60
|
+
|
|
61
|
+
The mirror derives a bias per Flow and Size Tier pair: the median ratio of recorded runs over the price those runs' changes carried. Seeded prices are corrected by it, clamped to `[0.5, 2]` so one pathological run cannot swing a profile. An observed price is never corrected by its own residual. `--json` carries the unclamped `bias`.
|
|
62
|
+
|
|
63
|
+
A pair whose bias falls outside `[1/1.5, 1.5]` raises the `stale-profile` warning, naming the Flow, the tier, and the direction. The repair is judgment — a wrong seed, or inconsistent tier calls — so the warning points at re-grooming, not at an automatic fix. Several drifted pairs aggregate into one human Warnings row while `--json` keeps one entry per pair.
|
|
64
|
+
|
|
65
|
+
## Cross-project history
|
|
66
|
+
|
|
67
|
+
`spego record` appends every tiered run to an append-only `runs.jsonl` under the platform configuration directory — `$XDG_CONFIG_HOME/spego` or `~/.config/spego`, `%APPDATA%\spego` on Windows, `~/Library/Application Support/spego` on macOS. Each line is one `{flow, tier, hours}` record with no repo attribution.
|
|
68
|
+
|
|
69
|
+
With `crossProject: true`, a pair whose local runs are below the sample threshold prices from the store's median once the store holds three or more runs for that pair. The flag defaults to off: a workspace that says nothing prices from repo observations and the seed alone, and its board stays reproducible from the repo. Opting in trades that reproducibility away, since the store lives outside the repo and grows with every run recorded anywhere.
|
|
70
|
+
|
|
71
|
+
`SPEGO_STORE_ROOT` overrides the store root ahead of the configuration directory, so a test suite or a reproducible run can point it somewhere hermetic; the suite sets it for every spawned CLI run. The store is plain data, not a workspace — losing it costs evidence, not correctness, and the ladder simply falls back a rung. Recording writes the epic first and the store second, so a failed store write (`WRITE_FAILED`) never costs the epic entry, and the store is written whether or not the workspace opts in.
|
|
72
|
+
|
|
73
|
+
## Seeding the first profile
|
|
74
|
+
|
|
75
|
+
The first seed does not have to be invented. `node scripts/calibrate-seed.mjs` joins the agent sessions already recorded for this project to archived changes by time window and branch, sums elapsed wall-clock per change, and prints a per-change table for review — then, given a Size Tier per change, a `flows` block holding the median hours per tier, ready to paste into `.spego/config.yaml`.
|
|
76
|
+
|
|
77
|
+
The script is calibration scaffolding, not product code: it reads a vendor-specific session format, its join is a heuristic the maintainer confirms before trusting, and it ships nowhere. It lives under `scripts/`, outside the published package, which is where the CLI's design keeps that format out of the npm artifact.
|
|
78
|
+
|
|
79
|
+
## Authoring a priced change
|
|
80
|
+
|
|
81
|
+
This project forks OpenSpec's `spec-driven` schema into `openspec/schemas/spec-driven-custom` (selected in `openspec/config.yaml`) and adds an `estimating` artifact between `proposal` and `tasks`. Once the proposal settles the scope, the author judges the change's Size Tier — sizing the change itself, not the flow machinery that will build it — and persists it through `spego sync` plus `spego update` onto the change's epic.
|
|
82
|
+
|
|
83
|
+
The generated `estimating.md` records the tier and its one-line rationale as the human-readable trace; the epic's `tier` meta is the state the board prices from, so a change arrives priced instead of waiting for the next groom run. OpenSpec owns the ritual, spego owns the state — the step writes nothing under `openspec/` beyond its own artifact file.
|
|
84
|
+
|
|
85
|
+
Changes authored without the fork are unaffected: grooming judges their tier as before. The `openspec schema` surface is experimental; if it changes, the prompt disappears and every recorded tier stays on its epic.
|
|
86
|
+
|
|
87
|
+
## Related
|
|
88
|
+
|
|
89
|
+
- [Delivery board](delivery-board.md) — where prices and sprint totals render
|
|
90
|
+
- [Workflows](workflows.md#groom) — groom judges each epic's `tier` during analyze
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# OpenSpec delivery adapter
|
|
2
|
+
|
|
3
|
+
The default delivery adapter is OpenSpec. `spego epics` exposes active OpenSpec changes as delivery epics, and `spego tasks --change <name>` exposes checklist items from the change's `tasks.md`.
|
|
4
|
+
|
|
5
|
+
| Source | spego view |
|
|
6
|
+
|--------|------------|
|
|
7
|
+
| `openspec/changes/<name>/proposal.md` | Epic title |
|
|
8
|
+
| `openspec/changes/<name>/tasks.md` | Task status and counts |
|
|
9
|
+
|
|
10
|
+
The `openspec` binary is not required on PATH — board and epics resolve status entirely from `tasks.md` on disk.
|
|
11
|
+
|
|
12
|
+
## Read-only contract
|
|
13
|
+
|
|
14
|
+
The adapter observes OpenSpec state. It does not create, continue, apply, verify, sync, or archive OpenSpec changes.
|
|
15
|
+
|
|
16
|
+
`spego sync` reconciles the delivery mirror — it creates a missing epic for every ungroomed change, closes every finished sprint, and retires the epic of any archived change. It is unrelated to OpenSpec's own `sync` / `/opsx:sync`, which merges a change's spec deltas into the main specs tree.
|
|
17
|
+
|
|
18
|
+
## Status derivation
|
|
19
|
+
|
|
20
|
+
Archived changes under `openspec/changes/archive/` are excluded from the active set. Of the remainder:
|
|
21
|
+
|
|
22
|
+
- no `tasks.md`, an empty one, or one whose items are all unchecked → `backlog`
|
|
23
|
+
- some items checked, some not → `in-progress`
|
|
24
|
+
- all items checked → `done`
|
|
25
|
+
|
|
26
|
+
A task item is a Markdown checkbox line — `-`, `*`, or `+`, at any indent. A change with no items at all also raises a `no-task-plan` warning, so a change nobody has planned stays distinguishable from one that is planned but unstarted.
|
|
27
|
+
|
|
28
|
+
Archived changes always resolve to `completed`. See [Delivery board](delivery-board.md#status) for how the two finished states differ and how manual overrides interact with them.
|
|
29
|
+
|
|
30
|
+
## Example
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
spego epics --json
|
|
34
|
+
spego tasks --change <change-name> --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Related
|
|
38
|
+
|
|
39
|
+
- [Delivery board](delivery-board.md)
|
|
40
|
+
- [Workflows](workflows.md#combined-openspec--spego-workflows) — which surface owns which state
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Workflow skills
|
|
2
|
+
|
|
3
|
+
Workflow skills guide an agent through a multi-persona process inside the chat, persisting results as spego artifacts at well-defined checkpoints. They are generated per agent target — see [Agent targets](agent-targets.md).
|
|
4
|
+
|
|
5
|
+
`spego workflows` lists them with their metadata.
|
|
6
|
+
|
|
7
|
+
| Skill | Personas | Output |
|
|
8
|
+
|-------|----------|--------|
|
|
9
|
+
| [`brainstorm-party`](#brainstorm-party) | PM, Architect, UX, Dev, QA, Skeptic | `brainstorm`, optionally `prd` or `design` |
|
|
10
|
+
| [`brainstorm-deep`](#brainstorm-deep) | Ideator | `brainstorm` |
|
|
11
|
+
| [`review-adversarial`](#review-adversarial) | Skeptic, Security, Reliability, UX, Cost | `qa` or `risk`, optionally `decision` or `retro` |
|
|
12
|
+
| [`review-edge-cases`](#review-edge-cases) | Path-tracer, Boundary-checker, Concurrency-skeptic | `qa` |
|
|
13
|
+
| [`editorial-prose`](#editorial-prose) | Copy-editor | `qa` plus in-place edits |
|
|
14
|
+
| [`editorial-structure`](#editorial-structure) | Structural editor | `qa` |
|
|
15
|
+
| [`elicit`](#elicit) | Refiner | `qa` plus in-place edits |
|
|
16
|
+
| [`groom`](#groom) | Groomer | `epic`, `sprint-plan` |
|
|
17
|
+
| [`help`](#help) | Guide | none — chat only |
|
|
18
|
+
|
|
19
|
+
## brainstorm-party
|
|
20
|
+
|
|
21
|
+
Multi-persona collaborative brainstorming. Six roles take turns framing, expanding, challenging, and converging on ideas.
|
|
22
|
+
|
|
23
|
+
Use when exploring a problem space broadly or stress-testing a concept before committing.
|
|
24
|
+
|
|
25
|
+
## brainstorm-deep
|
|
26
|
+
|
|
27
|
+
Single-persona, high-volume ideation targeting 50-100 ideas on a focused topic. One Ideator generates breadth, then clusters, deduplicates, and ranks the output.
|
|
28
|
+
|
|
29
|
+
Use when you have a focused problem and want maximum idea throughput without persona debate.
|
|
30
|
+
|
|
31
|
+
| Scenario | Use |
|
|
32
|
+
|----------|-----|
|
|
33
|
+
| Focused problem, need volume | `brainstorm-deep` |
|
|
34
|
+
| Broad problem, need diverse perspectives | `brainstorm-party` |
|
|
35
|
+
| One voice, fast iteration | `brainstorm-deep` |
|
|
36
|
+
| Multiple viewpoints, stress-test ideas | `brainstorm-party` |
|
|
37
|
+
|
|
38
|
+
## review-adversarial
|
|
39
|
+
|
|
40
|
+
Adversarial critique of an existing artifact. Five roles attack from different angles, surface gaps, and prioritize findings.
|
|
41
|
+
|
|
42
|
+
Use when you need rigorous review before approval or implementation.
|
|
43
|
+
|
|
44
|
+
## review-edge-cases
|
|
45
|
+
|
|
46
|
+
Method-driven edge-case enumeration. Three roles mechanically trace branching paths, derive edge classes (off-by-one, unguarded inputs, missing else/default, race conditions, timeout gaps), filter already-handled cases, and report only unhandled paths. The `qa` artifact carries a fenced JSON array of findings.
|
|
47
|
+
|
|
48
|
+
Use when you need to find logic defects that adversarial review may miss.
|
|
49
|
+
|
|
50
|
+
## editorial-prose
|
|
51
|
+
|
|
52
|
+
Clinical copy-edit pass. The Copy-editor identifies ambiguous sentences, unnecessary jargon, long sentences, passive voice, and redundancy. Confirmed edits are applied in place via `spego update --expected-revision`; declined edits are recorded as recommendations.
|
|
53
|
+
|
|
54
|
+
Use when the ideas are sound but the prose needs tightening.
|
|
55
|
+
|
|
56
|
+
## editorial-structure
|
|
57
|
+
|
|
58
|
+
Structural review without mutation. The Structural editor outlines the current structure, proposes cuts, merges, reorders, and splits, and produces a prioritized recommendation list. The source artifact is not modified.
|
|
59
|
+
|
|
60
|
+
Use when content is correct but organization needs improvement.
|
|
61
|
+
|
|
62
|
+
## elicit
|
|
63
|
+
|
|
64
|
+
Iterative refinement of an existing artifact using named methods: clarify, sharpen, generalize, specialize, stress-test, contextualize, simplify, formalize. The Refiner proposes changes, confirms with the user, and applies via `spego update --expected-revision`. Maximum 5 cycles per session.
|
|
65
|
+
|
|
66
|
+
Use when you have a draft that needs systematic improvement.
|
|
67
|
+
|
|
68
|
+
## groom
|
|
69
|
+
|
|
70
|
+
Delivery-mirror workflow reconciling active OpenSpec changes with `epic` and `sprint-plan` artifacts. Five phases:
|
|
71
|
+
|
|
72
|
+
1. `orient` — read `spego board --json` and `spego epics --json`, then classify drift warnings.
|
|
73
|
+
2. `sync` — run `spego sync` to mechanically create missing epics, close finished sprints, and retire epics of archived changes, then propose disposition for orphans resolving to no OpenSpec change.
|
|
74
|
+
3. `analyze` — update deps, requires, supporting links, gap notes, conflict tracks, and Size Tiers on epics.
|
|
75
|
+
4. `plan` — propose releasable, testable sprint groupings and create or update `sprint-plan` artifacts after confirmation.
|
|
76
|
+
5. `summarize` — report epics, dispositions, sprint plans, and the next-change suggestion.
|
|
77
|
+
|
|
78
|
+
Sole writers: groom and `spego sync` persist mirror state only through `spego create` / `spego update` with `--expected-revision`. Neither writes `openspec/` or mutates OpenSpec lifecycle state. Orphan disposition — only for epics resolving to no OpenSpec change — requires explicit confirmation; the default is keep. Epics of archived changes are retired, and finished sprints closed, deterministically by `spego sync` (preview with `--dry-run`), not by hand in groom.
|
|
79
|
+
|
|
80
|
+
## help
|
|
81
|
+
|
|
82
|
+
Orientation workflow that reads workspace state and recommends next steps. The Guide runs `spego status`, `spego list`, and `spego epics`, then applies a recommendation rubric to suggest the most impactful action. Produces no artifact.
|
|
83
|
+
|
|
84
|
+
Use when starting a session, unsure what to do next, or asking "what should I work on?".
|
|
85
|
+
|
|
86
|
+
## Authoring loop
|
|
87
|
+
|
|
88
|
+
1. **Orient** — `spego-help` for workspace state and recommendations.
|
|
89
|
+
2. **Ideate** — `spego-brainstorm-party` (multi-perspective breadth) or `spego-brainstorm-deep` (single-voice volume).
|
|
90
|
+
3. **Capture** — `spego create --type prd` (or `architecture`, `design`, …) to persist the output.
|
|
91
|
+
4. **Refine** — `spego-elicit` to iteratively improve the draft with structured methods.
|
|
92
|
+
5. **Review** — `spego-review-adversarial` and `spego-review-edge-cases` for technical coverage, `spego-editorial-prose` / `spego-editorial-structure` for communication quality.
|
|
93
|
+
|
|
94
|
+
## Complementary reviews
|
|
95
|
+
|
|
96
|
+
Combine reviewers for orthogonal coverage:
|
|
97
|
+
|
|
98
|
+
- **Technical defects** — `review-adversarial` is attitude-driven, hunting gaps and weak assumptions; `review-edge-cases` is method-driven, enumerating unhandled branching paths. Together they catch almost all technical defects.
|
|
99
|
+
- **Communication defects** — `editorial-prose` (copy-edit) and `editorial-structure` (organizational review) catch confusion, ambiguity, and poor organization that technical reviewers do not flag.
|
|
100
|
+
- **Recommended minimum** — at least one technical reviewer and at least one editorial reviewer before declaring an artifact ready.
|
|
101
|
+
|
|
102
|
+
## Combined OpenSpec + spego workflows
|
|
103
|
+
|
|
104
|
+
OpenSpec prompts and spego workflow skills are separate surfaces:
|
|
105
|
+
|
|
106
|
+
- OPSX/OpenSpec prompts live under `.claude/commands/opsx/` and `.claude/skills/openspec-*/`.
|
|
107
|
+
- spego-generated commands and workflow skills live under `.claude/commands/spego/` and `.claude/skills/spego-*/`.
|
|
108
|
+
|
|
109
|
+
OpenSpec owns change execution and lifecycle state: proposal, design, specs, tasks, apply, verify, sync, archive. spego owns durable product-thinking artifacts — `brainstorm`, `qa`, `risk`, `retro` — plus delivery-mirror state, `epic` and `sprint-plan`, written only by the groom workflow. The [OpenSpec delivery adapter](openspec-adapter.md) is read-only.
|
|
110
|
+
|
|
111
|
+
Use combined workflows when an OpenSpec change needs durable thinking around it:
|
|
112
|
+
|
|
113
|
+
| Lane | OpenSpec action | spego action |
|
|
114
|
+
|------|-----------------|--------------|
|
|
115
|
+
| Before implementation | Create or continue a change with OPSX/OpenSpec, then read `proposal.md`, `design.md`, specs, and `tasks.md` | `spego-groom` grooms the delivery mirror; `spego-change-brainstorm` creates a `brainstorm` artifact |
|
|
116
|
+
| During implementation | Keep task state and artifact mutations in OPSX/OpenSpec | `spego-change-review` creates `qa` or `risk` findings |
|
|
117
|
+
| Before archive | Run OPSX/OpenSpec verification | `spego-change-verify-report` creates a `qa` verification report |
|
|
118
|
+
| After completion | Archive or complete the OpenSpec change | `spego-change-retro` creates a `retro` artifact |
|
|
119
|
+
|
|
120
|
+
Persistence checkpoints:
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
spego --json create --type brainstorm --title "<change-name> brainstorm" --body "<brainstorm output>"
|
|
124
|
+
spego --json create --type qa --title "<change-name> review" --body "<quality findings>"
|
|
125
|
+
spego --json create --type risk --title "<change-name> risks" --body "<risk findings>"
|
|
126
|
+
spego --json create --type retro --title "<change-name> retro" --body "<retrospective>"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
If a combined workflow discovers that OpenSpec artifacts need to change, use the matching OPSX/OpenSpec command. Do not mutate OpenSpec lifecycle state through spego.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhuk/spego",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Agent-first product orchestration: markdown-first artifact engine with SQLite indexing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
+
"docs/*.md",
|
|
11
12
|
"README.md",
|
|
12
13
|
"CHANGELOG.md"
|
|
13
14
|
],
|