pi-smart-router 0.9.3 → 0.11.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/README.md +55 -11
- package/config/benchmark-profiles.json +2 -2
- package/package.json +6 -1
- package/skills/router-backlog-orchestrator/SKILL.md +23 -2
- package/skills/router-backlog-orchestrator/references/prioritization-rubric.md +7 -2
- package/skills/router-release-operator/SKILL.md +292 -0
- package/skills/router-release-operator/references/issue-intake-checklist.md +113 -0
- package/skills/router-release-operator/references/release-manifest-template.md +117 -0
- package/skills/router-release-operator/references/release-profiles.md +127 -0
package/README.md
CHANGED
|
@@ -590,6 +590,11 @@ npm run routing:ingest-fc-rewardbench -- \
|
|
|
590
590
|
--output /tmp/fc-rewardbench-pack.jsonl
|
|
591
591
|
|
|
592
592
|
# Optional weak TwinRouterBench tier proxy (exclude from holdout ECE)
|
|
593
|
+
# Preferred input: checked-in CI subset (SP-199/SP-201); full-track after SP-200 is local-only.
|
|
594
|
+
npm run routing:ingest-twinrouterbench-weak -- \
|
|
595
|
+
--input tests/eval/corpus/twinrouterbench/ci-subset.json \
|
|
596
|
+
--output /tmp/trb-weak-from-ci-subset.jsonl
|
|
597
|
+
|
|
593
598
|
npm run routing:ingest-twinrouterbench-weak -- \
|
|
594
599
|
--input tests/eval/corpus/label-packs/twinrouterbench-weak/ci-fixture.jsonl \
|
|
595
600
|
--output /tmp/trb-weak-pack.jsonl
|
|
@@ -604,6 +609,11 @@ npm run routing:calibration-dry-run
|
|
|
604
609
|
# Operator packs (schema-valid JSONL)
|
|
605
610
|
npm run routing:calibration-dry-run -- --packs /tmp/swe-gym-pack.jsonl /tmp/fc-rewardbench-pack.jsonl
|
|
606
611
|
|
|
612
|
+
# Warm-start: weak / exclude_from_holdout_ece rows join the **fit** pool only
|
|
613
|
+
npm run routing:calibration-dry-run -- \
|
|
614
|
+
--packs /tmp/swe-gym-pack.jsonl /tmp/trb-weak-from-ci-subset.jsonl \
|
|
615
|
+
--include-excluded-in-fit
|
|
616
|
+
|
|
607
617
|
# Soft ECE advisory fail (threshold 0.25 calibrated ECE; not a release-gate absolute)
|
|
608
618
|
npm run routing:calibration-dry-run -- --packs /tmp/swe-gym-pack.jsonl --enforce-soft-ece
|
|
609
619
|
```
|
|
@@ -615,9 +625,10 @@ Dry-run behavior:
|
|
|
615
625
|
| < 30 ECE-eligible rows | `SAMPLE_STARVED` report-only (exit 0); no soft pass/fail |
|
|
616
626
|
| ≥ 30 ECE-eligible rows | Fit logistic + isotonic; report `holdout_ece_raw` / `holdout_ece_calibrated` |
|
|
617
627
|
| Rows with `exclude_from_holdout_ece` | Counted separately; **never** enter holdout ECE metrics (weak TwinRouterBench) |
|
|
628
|
+
| `--include-excluded-in-fit` | Weak rows may warm-start the fit pool; `ece_eligible` / holdout ECE stay verifier-grade |
|
|
618
629
|
| Soft threshold | Advisory `0.25` calibrated ECE — **does not** change `config/release-gates.json` |
|
|
619
630
|
|
|
620
|
-
**#96 / `modernbert_k4` advisory:** when deciding whether to enable ModernBERT K=4 heads, use **pack holdout ECE / Top-1 error on verifier-grade packs** (SWE-Gym + FC-RewardBench), not fixture-only QR. Weak TwinRouterBench rows are warm-start only. This task does **not** flip `modernbert_k4` defaults.
|
|
631
|
+
**#96 / `modernbert_k4` advisory:** when deciding whether to enable ModernBERT K=4 heads, use **pack holdout ECE / Top-1 error on verifier-grade packs** (SWE-Gym + FC-RewardBench), not fixture-only QR and **not** weak-fit ECE. Weak TwinRouterBench rows are warm-start only. This task does **not** flip `modernbert_k4` defaults. Go/no-go evidence (SP-204 / #113): [`spine-tasks/_authoring/release-v0.11.0/encoder-gonogo-artifact.md`](spine-tasks/_authoring/release-v0.11.0/encoder-gonogo-artifact.md).
|
|
621
632
|
|
|
622
633
|
### Operator tuning (frugality slider)
|
|
623
634
|
|
|
@@ -842,10 +853,10 @@ Contributors must run `npm run build` before publishing or consuming the library
|
|
|
842
853
|
| `npm run routing:train-calibration` | Train routing calibration artifact bundle |
|
|
843
854
|
| `npm run routing:train-p-success` | Train standalone `config/p-success-weights.json` (synthetic fixture by default) |
|
|
844
855
|
| `npm run routing:verify-calibration` | Verify calibration bundle against benchmark prompts |
|
|
845
|
-
| `npm run routing:calibration-dry-run` | Pack-fed isotonic dry-run: holdout ECE on label packs (CI fixtures by default) |
|
|
856
|
+
| `npm run routing:calibration-dry-run` | Pack-fed isotonic dry-run: holdout ECE on label packs (CI fixtures by default); optional `--include-excluded-in-fit` |
|
|
846
857
|
| `npm run routing:ingest-swe-gym` | Convert SWE-Gym verifier-style JSONL → privacy-safe label pack |
|
|
847
858
|
| `npm run routing:ingest-fc-rewardbench` | Convert FC-RewardBench JSONL → privacy-safe label pack |
|
|
848
|
-
| `npm run routing:ingest-twinrouterbench-weak` | Convert TwinRouterBench weak tier labels → pack (exclude from ECE) |
|
|
859
|
+
| `npm run routing:ingest-twinrouterbench-weak` | Convert TwinRouterBench weak tier labels → pack (prefer `ci-subset.json`; exclude from ECE) |
|
|
849
860
|
| `npm run routing:ingest-benchmarks` | Regenerate `config/benchmark-profiles.json` from leaderboard fixtures |
|
|
850
861
|
| `npm run routing:verify-benchmark-profiles` | CI smoke: assert checked-in profiles match fixture ingest |
|
|
851
862
|
| `npm run routing:eval-replay` | Counterfactual replay on eval trace fixtures |
|
|
@@ -853,6 +864,10 @@ Contributors must run `npm run build` before publishing or consuming the library
|
|
|
853
864
|
| `npm run routing:eval-harness:smoke` | Harness summary JSON only (CI smoke; no network) |
|
|
854
865
|
| `npm run routing:eval-harness:corpus-smoke` | Harness summary on TwinRouterBench CI corpus subset (`tests/eval/corpus/twinrouterbench`) |
|
|
855
866
|
| `npm run routing:assert-release-gates:corpus-report` | Soft-feed: assert corpus vs absolute gates with `--report-only` (exit 0; does not gate releases) |
|
|
867
|
+
| `npm run routing:analyze-overrouting` | TwinRouterBench over-routing breakdown by stage / reason_code / tiers (#112; see `spine-tasks/_authoring/release-v0.11.0/over-routing-analysis.md`) |
|
|
868
|
+
| `npm run routing:twinrouterbench:full-track` | Local/nightly: pin fetch → full convert (no `--limit`) → harness + gates `--report-only` (gitignored cache) |
|
|
869
|
+
| `npm run routing:twinrouterbench:full-ingest` | Convert cached `question_bank.jsonl` → full static-track JSON (no `--limit`) |
|
|
870
|
+
| `npm run routing:twinrouterbench:full-report` | Harness summary + gates `--report-only` on cached full track |
|
|
856
871
|
| `npm run routing:ingest-twinrouterbench` | Convert TwinRouterBench `question_bank.jsonl` → CI subset / full corpus JSON |
|
|
857
872
|
| `npm run routing:ingest-llmrouterbench` | Convert LLMRouterBench BaselineRecord JSONL → static-track subset JSON |
|
|
858
873
|
| `npm run routing:llmrouterbench-regret` | Offline regret / CS report on vendored LLMRouterBench subset (optional; not PR CI) |
|
|
@@ -874,7 +889,7 @@ npm run routing:eval-harness
|
|
|
874
889
|
# CI-style summary only (default fixtures under tests/eval/fixtures)
|
|
875
890
|
npm run routing:eval-harness:smoke
|
|
876
891
|
|
|
877
|
-
# TwinRouterBench CI corpus subset (≤
|
|
892
|
+
# TwinRouterBench CI corpus subset (≤150 code/tool records; offline)
|
|
878
893
|
npm run routing:eval-harness:corpus-smoke
|
|
879
894
|
|
|
880
895
|
# Custom fixture directory (includes TwinRouterBench static track subdirs)
|
|
@@ -882,24 +897,45 @@ npm run routing:eval-harness -- --fixtures tests/eval/fixtures
|
|
|
882
897
|
|
|
883
898
|
# Counterfactual replay only (SP-151)
|
|
884
899
|
npm run routing:eval-replay
|
|
900
|
+
|
|
901
|
+
# Full ~970-row static track (local / nightly only — do not check JSON into git)
|
|
902
|
+
npm run routing:twinrouterbench:full-track
|
|
885
903
|
```
|
|
886
904
|
|
|
887
|
-
**CI smoke:** `.github/workflows/eval-harness-smoke.yml` runs on PRs that touch eval scripts, fixtures, or the workflow. It executes `routing:eval-harness:smoke`, `routing:eval-harness:corpus-smoke`, and eval unit tests — fast, offline, no provider network calls. Job timeout stays at 10 minutes.
|
|
905
|
+
**CI smoke:** `.github/workflows/eval-harness-smoke.yml` runs on PRs that touch eval scripts, fixtures, or the workflow. It executes `routing:eval-harness:smoke`, `routing:eval-harness:corpus-smoke`, and eval unit tests — fast, offline, no provider network calls. Job timeout stays at 10 minutes. The optional full-track nightly (`.github/workflows/twinrouterbench-full-nightly.yml`, `schedule` + `workflow_dispatch` only) is **not** on `pull_request` and must not be configured as a required status check — failures there do not gate PR CI or `release:functional-smoke`.
|
|
888
906
|
|
|
889
907
|
**TwinRouterBench static track:** import step-level router-visible prefixes with execution-verified target tiers (`track: "static"`). The adapter in `scripts/eval/twinrouterbench-adapter.ts` converts static track records into native eval fixtures for the three-track harness. See `docs/gemini-research.md` §9 for methodology context.
|
|
890
908
|
|
|
891
|
-
#### TwinRouterBench CI corpus (SP-186 / SP-187 / SP-188)
|
|
909
|
+
#### TwinRouterBench CI corpus (SP-186 / SP-187 / SP-188 / SP-199)
|
|
892
910
|
|
|
893
911
|
| Item | Location / command |
|
|
894
912
|
|------|--------------------|
|
|
895
913
|
| **Pinned upstream** | CommonstackAI/TwinRouterBench `@430acecac71141de77afd8e5e13690d236d58e93` (Apache-2.0) |
|
|
896
|
-
| **CI subset** | `tests/eval/corpus/twinrouterbench/ci-subset.json` (≤
|
|
914
|
+
| **CI subset** | `tests/eval/corpus/twinrouterbench/ci-subset.json` (≤150 code/tool records) |
|
|
897
915
|
| **Provenance** | `tests/eval/corpus/twinrouterbench/PROVENANCE.md` |
|
|
898
|
-
| **Regenerate** | `npm run routing:ingest-twinrouterbench -- --input <question_bank.jsonl> --output tests/eval/corpus/twinrouterbench/ci-subset.json --limit
|
|
916
|
+
| **Regenerate** | `npm run routing:ingest-twinrouterbench -- --input <question_bank.jsonl> --output tests/eval/corpus/twinrouterbench/ci-subset.json --limit 150 --prefer-code-tool` |
|
|
899
917
|
| **Harness smoke** | `npm run routing:eval-harness:corpus-smoke` |
|
|
900
918
|
| **Gate soft-feed** | `npm run routing:assert-release-gates:corpus-report` |
|
|
919
|
+
| **Over-routing breakdown** | `npm run routing:analyze-overrouting` · [v0.11.0 analysis](spine-tasks/_authoring/release-v0.11.0/over-routing-analysis.md) (#112 / #95) |
|
|
920
|
+
| **Human QA protocol** | [`docs/qa/shadow-dogfood-protocol.md`](docs/qa/shadow-dogfood-protocol.md) · `npm run qa:shadow-dogfood` |
|
|
921
|
+
|
|
922
|
+
**Absolute release gates stay on default fixtures.** `npm run release:functional-smoke` continues to assert `tests/eval/fixtures` against `config/release-gates.json` — do not point it at the corpus without operator review. Today the corpus subset fails `mean_over_routing_rate_max` (≈0.85 vs absolute max 0.15); that gap is intentional soft signal for the [#95](https://github.com/beettlle/pi-smart-router/issues/95) public static-track acceptance criteria alongside live dogfood traces. Use `--fixtures tests/eval/corpus/twinrouterbench` (or the corpus-report script) for #95 public-track scoring; keep absolute threshold edits out of band until operators approve. For live shadow dogfood steps and sign-off, see the [shadow dogfood protocol](docs/qa/shadow-dogfood-protocol.md).
|
|
901
923
|
|
|
902
|
-
|
|
924
|
+
#### TwinRouterBench full static track (SP-200 / #107)
|
|
925
|
+
|
|
926
|
+
First-class **local / optional nightly** path for the pinned ~970-row bank. **Do not check the full JSON into git.**
|
|
927
|
+
|
|
928
|
+
| Item | Location / command |
|
|
929
|
+
|------|--------------------|
|
|
930
|
+
| **One-shot** | `npm run routing:twinrouterbench:full-track` |
|
|
931
|
+
| **Cache (gitignored)** | `.pi-smart-router/eval-cache/twinrouterbench/` (override with `TRB_CACHE_DIR`) |
|
|
932
|
+
| **Steps** | pin fetch → `routing:ingest-twinrouterbench` **without** `--limit` → harness `--summary-only` + gates `--report-only` |
|
|
933
|
+
| **Nightly** | `.github/workflows/twinrouterbench-full-nightly.yml` (`schedule` + `workflow_dispatch`) — advisory only |
|
|
934
|
+
| **Provenance** | `tests/eval/corpus/twinrouterbench/PROVENANCE.md` |
|
|
935
|
+
|
|
936
|
+
PR corpus smoke remains the vendored ≤150 subset. Absolute `config/release-gates.json` thresholds and `release:functional-smoke` stay fixture-backed.
|
|
937
|
+
|
|
938
|
+
**[#95 dual-gate protocol](https://github.com/beettlle/pi-smart-router/issues/95):** (1) live shadow dogfood (`docs/qa/shadow-dogfood-protocol.md` · `npm run qa:shadow-dogfood`) and (2) public static-track soft-feed (CI subset report, or full-track report above). Neither path edits absolute release thresholds.
|
|
903
939
|
|
|
904
940
|
**Deferred:** RouterBench classic (outcome-matrix) smoke is out of scope for SP-188; prefer TwinRouterBench static track + dogfood for #95.
|
|
905
941
|
|
|
@@ -932,6 +968,12 @@ npm run routing:community-bench -- \
|
|
|
932
968
|
--output /tmp/community-bench-report.json \
|
|
933
969
|
--email-file /tmp/community-bench-report.txt
|
|
934
970
|
|
|
971
|
+
# Optional Track B: labeled dogfood export → harness gates (skips if incomplete — never invents labels)
|
|
972
|
+
npm run routing:community-bench -- \
|
|
973
|
+
--dogfood-export tests/eval/dogfood-track-b/synthetic-labeled-export.json \
|
|
974
|
+
--output /tmp/community-bench-report.json \
|
|
975
|
+
--email-file /tmp/community-bench-report.txt
|
|
976
|
+
|
|
935
977
|
# Optional Track C: offline LLMRouterBench regret/CS on the vendored subset (no full HF download)
|
|
936
978
|
npm run routing:community-bench -- \
|
|
937
979
|
--llmrouterbench \
|
|
@@ -941,7 +983,7 @@ npm run routing:community-bench -- \
|
|
|
941
983
|
|
|
942
984
|
**How to send:**
|
|
943
985
|
|
|
944
|
-
1. **Email `.txt`** — open `/tmp/community-bench-report.txt` (or your `--email-file` path). It includes a `Subject:` line, privacy blurb, fingerprint, Track A PASS/FAIL, and optional Track C metrics. Paste into your mail client; attach `community-bench-report.json` if useful. Do **not** expect the CLI to send mail.
|
|
986
|
+
1. **Email `.txt`** — open `/tmp/community-bench-report.txt` (or your `--email-file` path). It includes a `Subject:` line, privacy blurb, fingerprint, Track A PASS/FAIL, and optional Track B/C metrics. Paste into your mail client; attach `community-bench-report.json` if useful. Do **not** expect the CLI to send mail.
|
|
945
987
|
2. **GitHub issue** — open the [maintainer contact](https://github.com/beettlle/pi-smart-router/issues/new?labels=community-bench) URL, or run with `--print-issue-body` and paste stdout into a new issue. Issues list: https://github.com/beettlle/pi-smart-router/issues
|
|
946
988
|
|
|
947
989
|
**Tracks:**
|
|
@@ -949,7 +991,7 @@ npm run routing:community-bench -- \
|
|
|
949
991
|
| Track | Corpus | When |
|
|
950
992
|
|-------|--------|------|
|
|
951
993
|
| **A (required)** | [TwinRouterBench CI corpus](#twinrouterbench-ci-corpus-sp-186--sp-187--sp-188) (`tests/eval/corpus/twinrouterbench`) | Always |
|
|
952
|
-
| **B (optional)** |
|
|
994
|
+
| **B (optional)** | Labeled dogfood export (`--dogfood-export PATH`) | Runs when adapter + export present with required outcome labels (`success_label`, `min_tier`, `min_model_id`); skips with an explicit reason when incomplete — never invents labels. Example: `tests/eval/dogfood-track-b/synthetic-labeled-export.json` ([#111](https://github.com/beettlle/pi-smart-router/issues/111)) |
|
|
953
995
|
| **C (optional)** | [LLMRouterBench offline subset](#llmrouterbench-offline-regret-sp-192--sp-193) (`tests/eval/corpus/llmrouterbench`) | `--llmrouterbench` or `--full`; offline only |
|
|
954
996
|
|
|
955
997
|
PR CI does **not** download full TwinRouterBench / LLMRouterBench corpora. Absolute gate thresholds in `config/release-gates.json` are unchanged by this CLI.
|
|
@@ -1030,6 +1072,8 @@ npm run routing:verify-benchmark-profiles
|
|
|
1030
1072
|
|
|
1031
1073
|
Tag-triggered publish via GitHub Actions (requires `NPMSECRET` repository secret). pi.dev gallery listing syncs automatically from npm (`pi-package` keyword); no separate submit step.
|
|
1032
1074
|
|
|
1075
|
+
**Scope composition:** use `/skill:router-release-operator` for themed release planning (not open-ended backlog cycles). **Patch** = docs + bugfixes only; **minor** = new capability (1–3 related issues under one theme). Budgets and audit rules: [`skills/router-release-operator/references/release-profiles.md`](skills/router-release-operator/references/release-profiles.md).
|
|
1076
|
+
|
|
1033
1077
|
**Tier 0 functional smoke** (`release:functional-smoke`) runs before tag publish and chains:
|
|
1034
1078
|
|
|
1035
1079
|
1. `routing:verify-calibration --skip-embed` — artifact shape + triage benchmark gates (no ONNX embedding)
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"livecodebench": "https://livecodebench.github.io/leaderboard.html",
|
|
8
8
|
"bfcl": "https://gorilla.cs.berkeley.edu/leaderboard.html"
|
|
9
9
|
},
|
|
10
|
-
"scrape_date": "2026-07-
|
|
11
|
-
"catalog_freeze_date": "2026-07-
|
|
10
|
+
"scrape_date": "2026-07-12",
|
|
11
|
+
"catalog_freeze_date": "2026-07-12"
|
|
12
12
|
},
|
|
13
13
|
"aliases": {
|
|
14
14
|
"claude-3-5-sonnet": "claude-sonnet-4-6",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-smart-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Auto-model router middleware for the pi.dev coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -73,6 +73,10 @@
|
|
|
73
73
|
"routing:eval-harness:smoke": "tsx scripts/eval/run-harness.ts --summary-only",
|
|
74
74
|
"routing:eval-harness:corpus-smoke": "tsx scripts/eval/run-harness.ts --fixtures tests/eval/corpus/twinrouterbench --summary-only",
|
|
75
75
|
"routing:assert-release-gates:corpus-report": "tsx scripts/eval/assert-release-gates.ts --fixtures tests/eval/corpus/twinrouterbench --report-only",
|
|
76
|
+
"routing:analyze-overrouting": "tsx scripts/eval/analyze-twinrouterbench-overrouting.ts",
|
|
77
|
+
"routing:twinrouterbench:full-ingest": "bash -c 'set -euo pipefail; CACHE=\"${TRB_CACHE_DIR:-.pi-smart-router/eval-cache/twinrouterbench}\"; mkdir -p \"$CACHE\"; npm run routing:ingest-twinrouterbench -- --input \"$CACHE/question_bank.jsonl\" --output \"$CACHE/full-static-track.json\"'",
|
|
78
|
+
"routing:twinrouterbench:full-report": "bash -c 'set -euo pipefail; CACHE=\"${TRB_CACHE_DIR:-.pi-smart-router/eval-cache/twinrouterbench}\"; DIR=\"$CACHE/full-track\"; mkdir -p \"$DIR\"; cp \"$CACHE/full-static-track.json\" \"$DIR/full-static-track.json\"; npm run routing:eval-harness -- --fixtures \"$DIR\" --summary-only; npx tsx scripts/eval/assert-release-gates.ts --fixtures \"$DIR\" --report-only'",
|
|
79
|
+
"routing:twinrouterbench:full-track": "bash scripts/eval/twinrouterbench-full-track.sh",
|
|
76
80
|
"routing:community-bench": "tsx scripts/eval/community-bench.ts",
|
|
77
81
|
"routing:ingest-twinrouterbench": "tsx scripts/eval/ingest-twinrouterbench-corpus.ts",
|
|
78
82
|
"routing:ingest-llmrouterbench": "tsx scripts/eval/ingest-llmrouterbench-subset.ts",
|
|
@@ -83,6 +87,7 @@
|
|
|
83
87
|
"routing:capture-baseline": "tsx scripts/eval/capture-baseline.ts",
|
|
84
88
|
"routing:test-projection": "npm run build && node --experimental-strip-types scripts/test-hydra-projection.ts",
|
|
85
89
|
"benchmark:encoder": "tsx scripts/benchmark-encoder-latency.ts",
|
|
90
|
+
"qa:shadow-dogfood": "bash scripts/qa/shadow-dogfood-session.sh",
|
|
86
91
|
"verify:ci": "npm run build && npm run typecheck && npm run lint && npm test && npm run coverage:check"
|
|
87
92
|
},
|
|
88
93
|
"peerDependencies": {
|
|
@@ -14,13 +14,23 @@ Invoke explicitly: `/skill:router-backlog-orchestrator`
|
|
|
14
14
|
**Compose with:**
|
|
15
15
|
- pi-spine `create-spine-tasks` skill — packet structure and size rules
|
|
16
16
|
- [`skills/spine-autonomous-operator/SKILL.md`](../spine-autonomous-operator/SKILL.md) — preflight, wave loop, recovery, pi-spine issue filing
|
|
17
|
+
- [`skills/router-release-operator/SKILL.md`](../router-release-operator/SKILL.md) — themed semver release composition and publish
|
|
17
18
|
- [`.cursor/rules/spine-task-authoring.mdc`](../../.cursor/rules/spine-task-authoring.mdc) — PROMPT/STATUS contracts
|
|
18
19
|
- [`.cursor/rules/spine-operator-cursor.mdc`](../../.cursor/rules/spine-operator-cursor.mdc) — spine CLI reference
|
|
19
20
|
|
|
21
|
+
## Skill boundaries
|
|
22
|
+
|
|
23
|
+
| Concern | Owner |
|
|
24
|
+
|---------|-------|
|
|
25
|
+
| Development **cycle** triage (docs → 3–5 bugs → 1 feature) | This skill |
|
|
26
|
+
| Versioned **release** composition (theme, patch/minor/major, publish) | [`router-release-operator`](../router-release-operator/SKILL.md) |
|
|
27
|
+
|
|
28
|
+
When the operator asks for a versioned release (`release v0.x.y`, `patch release`, `minor release`, `ship to npm`), **do not** invent feature-patch scopes here. Optionally write a backlog snapshot, then **hand off** to `/skill:router-release-operator`.
|
|
29
|
+
|
|
20
30
|
## Success criteria
|
|
21
31
|
|
|
22
32
|
1. Backlog plan approved by operator before batch start
|
|
23
|
-
2. Documentation issues processed before bugs; feature ratio **1 per 3–5 bugs**
|
|
33
|
+
2. Documentation issues processed before bugs; feature ratio **1 per 3–5 bugs** (cycle policy only)
|
|
24
34
|
3. New `SP-*` packets validate (`spine tasks validate pending`)
|
|
25
35
|
4. Queued scope lands on `main` via gate + integrate
|
|
26
36
|
5. Linked GitHub issues commented/closed when tasks complete
|
|
@@ -32,8 +42,10 @@ Invoke explicitly: `/skill:router-backlog-orchestrator`
|
|
|
32
42
|
- **Never** start a batch without operator approval of the backlog plan table
|
|
33
43
|
- **Never** claim batch/test success without CLI output
|
|
34
44
|
- **Never** create XL tasks; split epics into S/M packets
|
|
45
|
+
- **Never** choose npm bump type or release profile from this skill — use `router-release-operator`
|
|
35
46
|
- **Always** run docs bucket completely before bug/feature ratio units
|
|
36
47
|
- **Always** link packets to GitHub issues in `## Source`
|
|
48
|
+
- **Always** hand off versioned release requests to `router-release-operator` after optional snapshot
|
|
37
49
|
|
|
38
50
|
## Phase 0 — Baseline
|
|
39
51
|
|
|
@@ -46,6 +58,8 @@ git status && git branch --show-current # must be main
|
|
|
46
58
|
|
|
47
59
|
Stop if not on `main` or `gh`/`spine` unavailable.
|
|
48
60
|
|
|
61
|
+
**Release handoff:** if the invocation names a target version or patch/minor/major **release** (not a plain backlog cycle), stop after optional snapshot and invoke [`router-release-operator`](../router-release-operator/SKILL.md).
|
|
62
|
+
|
|
49
63
|
Optional snapshot:
|
|
50
64
|
|
|
51
65
|
```bash
|
|
@@ -90,6 +104,8 @@ Dedup:
|
|
|
90
104
|
|
|
91
105
|
## Phase 3 — Prioritize
|
|
92
106
|
|
|
107
|
+
**Applies to development cycles only** — not versioned releases (see Skill boundaries).
|
|
108
|
+
|
|
93
109
|
**Order:**
|
|
94
110
|
1. All **documentation** issues
|
|
95
111
|
2. **Bugs** — user-facing / CI blockers first, then wiring/refactors; decompose epics
|
|
@@ -100,6 +116,8 @@ Dedup:
|
|
|
100
116
|
- Then **one ratio unit**: 3–5 bugs + 1 feature
|
|
101
117
|
- Repeat until operator stops or backlog empty
|
|
102
118
|
|
|
119
|
+
If the operator’s goal for this invocation is **ship a release**, do not expand the ratio unit into a release scope — hand off to [`router-release-operator`](../router-release-operator/SKILL.md) with the intended theme/version.
|
|
120
|
+
|
|
103
121
|
## Phase 4 — Operator approval
|
|
104
122
|
|
|
105
123
|
Present a **Backlog Plan** table before any writes:
|
|
@@ -143,6 +161,8 @@ Hand off to [`skills/spine-autonomous-operator/SKILL.md`](../spine-autonomous-op
|
|
|
143
161
|
|
|
144
162
|
Do not advance waves until current wave is integrated on `main`.
|
|
145
163
|
|
|
164
|
+
If this cycle’s approved plan is explicitly a **release ship** (version bump / npm publish), stop cycle execution and continue under [`router-release-operator`](../router-release-operator/SKILL.md) (manifest, theme audit, `release:check`, publish gates).
|
|
165
|
+
|
|
146
166
|
## Phase 7 — Issue filing
|
|
147
167
|
|
|
148
168
|
| Situation | Repo | Action |
|
|
@@ -177,7 +197,8 @@ Do not claim orchestrator success unless `npm run verify:ci` exits 0 and the tab
|
|
|
177
197
|
## Short prompt (resume)
|
|
178
198
|
|
|
179
199
|
```text
|
|
180
|
-
Run router-backlog-orchestrator:
|
|
200
|
+
Run router-backlog-orchestrator: if operator asked for release vX.Y.Z / patch|minor,
|
|
201
|
+
hand off to router-release-operator. Else: collect GitHub + spine backlog → classify →
|
|
181
202
|
prioritize (docs first, 3-5 bugs + 1 feature) → show plan → author SP packets →
|
|
182
203
|
spine preflight → batch waves → file issues → final report.
|
|
183
204
|
```
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Use when classifying and ordering work in `router-backlog-orchestrator`.
|
|
4
4
|
|
|
5
|
+
**Scope:** development **cycle** planning only. Do **not** choose npm bump type (patch/minor/major) or release composition from this rubric — use [`router-release-operator` release profiles](../../router-release-operator/references/release-profiles.md).
|
|
6
|
+
|
|
5
7
|
## Buckets
|
|
6
8
|
|
|
7
9
|
### documentation
|
|
@@ -33,11 +35,14 @@ Use when classifying and ordering work in `router-backlog-orchestrator`.
|
|
|
33
35
|
|
|
34
36
|
## Feature-to-bug ratio
|
|
35
37
|
|
|
36
|
-
After documentation bucket is empty for this cycle:
|
|
38
|
+
**Cycle policy** (not a release profile). After documentation bucket is empty for this cycle:
|
|
37
39
|
|
|
38
40
|
- Queue **3 to 5 bugs**, then **exactly 1 feature**
|
|
39
41
|
- One **ratio unit** per orchestrator invocation (default)
|
|
40
|
-
- If fewer than 3 bugs remain, queue remaining bugs + 1 feature (or 0 features if none left)
|
|
42
|
+
- If fewer than 3 bugs remain, queue remaining bugs + at most 1 feature (or 0 features if none left)
|
|
43
|
+
- Empty or short bug queues are normal — do not invent fake bugs to fill a 3–5 quota for a **cycle**
|
|
44
|
+
|
|
45
|
+
Shipping that work as an npm version is a separate step: hand off to `router-release-operator` (patch = docs+bugs only; enhancements require **minor** + theme).
|
|
41
46
|
|
|
42
47
|
## Dedup rules
|
|
43
48
|
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: router-release-operator
|
|
3
|
+
description: >-
|
|
4
|
+
End-to-end pi-smart-router release operator. Intakes GitHub issues and pending
|
|
5
|
+
spine tasks, composes a themed semver-profiled release (patch = docs+bugs only;
|
|
6
|
+
enhancements require minor), authors/audits packets, executes waves, and
|
|
7
|
+
publishes after operator approval. Use when asked to run a router release,
|
|
8
|
+
release vX.Y.Z, patch/minor/major for pi-smart-router, or ship to npm.
|
|
9
|
+
disable-model-invocation: true
|
|
10
|
+
compatibility: Requires gh CLI, spine CLI, git, Node >= 20. Run from pi-smart-router repo root on main.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Router Release Operator
|
|
14
|
+
|
|
15
|
+
You are the **pi-smart-router release operator**. Drive a **curated, themed release** from intake through publish: select work by **local** semver profiles, author/audit packets, execute batches, verify, and bump version — with **operator approval** before publish.
|
|
16
|
+
|
|
17
|
+
Invoke explicitly: `/skill:router-release-operator` or "release v0.10.0" / "patch release" / "minor release".
|
|
18
|
+
|
|
19
|
+
**Not** for executing all pending tasks or open-ended backlog cycles — use [`router-backlog-orchestrator`](../router-backlog-orchestrator/SKILL.md) for development cycles. This skill selects a **subset** fitting the release profile and theme.
|
|
20
|
+
|
|
21
|
+
## Skill boundaries
|
|
22
|
+
|
|
23
|
+
| Concern | Delegate to |
|
|
24
|
+
|---------|-------------|
|
|
25
|
+
| Semver scope budgets / theme audit | [references/release-profiles.md](references/release-profiles.md) (**this repo — not pi-spine**) |
|
|
26
|
+
| Issue intake | [references/issue-intake-checklist.md](references/issue-intake-checklist.md) |
|
|
27
|
+
| Manifest format | [references/release-manifest-template.md](references/release-manifest-template.md) |
|
|
28
|
+
| PROMPT/STATUS/Contract authoring | `create-spine-tasks` + [packet-from-issue.md](../router-backlog-orchestrator/references/packet-from-issue.md) |
|
|
29
|
+
| Batch land / recovery / detached policy | pi-spine `spine-release-operator` Phase 4+ **or** `spine-autonomous-operator` + [`.cursor/rules/spine-operator-cursor.mdc`](../../.cursor/rules/spine-operator-cursor.mdc) |
|
|
30
|
+
| Cycle triage (docs → bugs → features) | [`router-backlog-orchestrator`](../router-backlog-orchestrator/SKILL.md) — hand off **here** when operator asks for a versioned release |
|
|
31
|
+
|
|
32
|
+
## Success criteria
|
|
33
|
+
|
|
34
|
+
1. Release manifest written with **theme** and operator-approved scope
|
|
35
|
+
2. Profile audit **PASS** (or PASS with cap override only — never feature-in-patch OVERRIDE)
|
|
36
|
+
3. All **release-scoped** tasks `.DONE` and integrated on `main`
|
|
37
|
+
4. `spine preflight` green; **`npm run release:check` green (blocking)** on current `main`
|
|
38
|
+
5. **CI workflow green on `HEAD`** before tag push
|
|
39
|
+
6. Operator explicitly approved publish; version bumped and tag pushed (if approved)
|
|
40
|
+
7. Final report with theme, composition table, deferred backlog, verification output
|
|
41
|
+
|
|
42
|
+
## Hard rules
|
|
43
|
+
|
|
44
|
+
- **Never** hand-edit `.spine/batch-state.json` or `.spine/runtime/**`
|
|
45
|
+
- **Never** ship enhancements in a **patch** — reclassify as **minor** or drop (no OVERRIDE theater)
|
|
46
|
+
- **Never** omit the release **theme** or select work that contradicts it
|
|
47
|
+
- **Never** treat empty open-bug queue as audit failure — use `PASS (no open bugs)`
|
|
48
|
+
- **Never** run `npm version` or `git push --tags` without explicit operator approval
|
|
49
|
+
- **Never** run `npm version` / tag push when `npm run release:check` exits non-zero on current `main`
|
|
50
|
+
- **Never** run `npm version` / tag push when CI is not green on current `HEAD`
|
|
51
|
+
- **Always** parse target version / bump type **before** task selection (Phase 2)
|
|
52
|
+
- **Always** use [references/release-profiles.md](references/release-profiles.md) for budgets (not pi-spine profiles)
|
|
53
|
+
- **Always** prioritize documentation before enhancements within the theme
|
|
54
|
+
- **Always** run `spine gate approve` before `spine integrate`
|
|
55
|
+
- **Always** run `npm install` on `main` after successful integrate
|
|
56
|
+
- **Always** run post-integrate `npm run release:check` on `main` after each wave before the next wave or push
|
|
57
|
+
- **Never** judge `release:check` from `| tail` / `| head` alone — verify exit code
|
|
58
|
+
- **Do not** execute tasks outside the approved manifest scope
|
|
59
|
+
- **Do not** start a second batch while another is **running** on this repo
|
|
60
|
+
- **Release batches:** prefer detached `spine batch start|resume` (omit `--attached`); see spine-operator rules
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Pre-work — GitNexus index (recommended)
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cd <repo-root>
|
|
68
|
+
# Prefer: node .gitnexus/run.cjs analyze OR npx gitnexus analyze
|
|
69
|
+
gitnexus status # when available — Status up-to-date with HEAD
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
If analyze fails, report and continue only if operator accepts stale index risk.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Phase 0 — Baseline and target version
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cd <repo-root> # pi-smart-router root
|
|
80
|
+
spine --version && spine doctor
|
|
81
|
+
node -p "require('./package.json').version"
|
|
82
|
+
git status
|
|
83
|
+
git branch --show-current # must be main
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Parse invocation** for target version or bump type — see [release-profiles.md](references/release-profiles.md).
|
|
87
|
+
|
|
88
|
+
If not on `main`, stop. If git is dirty, commit or stash hygiene before release work.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Phase 1 — Intake inventory
|
|
93
|
+
|
|
94
|
+
Follow [references/issue-intake-checklist.md](references/issue-intake-checklist.md).
|
|
95
|
+
|
|
96
|
+
**GitHub** (`beettlle/pi-smart-router` only):
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
gh issue list --repo beettlle/pi-smart-router --state open --limit 100 \
|
|
100
|
+
--json number,title,labels,body
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Pending tasks:**
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
spine plan pending
|
|
107
|
+
spine tasks validate pending
|
|
108
|
+
spine tasks analyze pending
|
|
109
|
+
rg 'GitHub: beettlle/pi-smart-router#|Closes:|Partial:' spine-tasks/*/PROMPT.md
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Read `spine-tasks/CONTEXT.md` for `Next Task ID`. Skim `docs/routing-roadmap.md` for enhancement priority.
|
|
113
|
+
|
|
114
|
+
**Output:** intake table (issue #, labels, mapped SP-* or gap, bucket, theme fit, profile fit).
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Phase 2 — Compose release manifest
|
|
119
|
+
|
|
120
|
+
Write:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
spine-tasks/_authoring/release-v{TARGET}/manifest.md
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Use [references/release-manifest-template.md](references/release-manifest-template.md).
|
|
127
|
+
|
|
128
|
+
### Selection order (strict)
|
|
129
|
+
|
|
130
|
+
1. State the **theme** (one sentence)
|
|
131
|
+
2. **Documentation** fitting the theme
|
|
132
|
+
3. **Bug fixes** (all high-impact that fit the cap; 0 OK)
|
|
133
|
+
4. **Enhancements** — only if profile is minor/major; 1–3 related issues completing the theme
|
|
134
|
+
5. **Defer** everything else with one-line rationale
|
|
135
|
+
|
|
136
|
+
Apply [release-profiles.md](references/release-profiles.md) budgets. **FAIL** if enhancements appear under patch — ask operator to bump to minor or drop features.
|
|
137
|
+
|
|
138
|
+
### Operator gate
|
|
139
|
+
|
|
140
|
+
Present:
|
|
141
|
+
|
|
142
|
+
- Target version, profile, **theme**
|
|
143
|
+
- Selected SP-* / issues by bucket
|
|
144
|
+
- Deferred count + reasons
|
|
145
|
+
- Profile audit status
|
|
146
|
+
|
|
147
|
+
Require explicit **"approve release scope"** before Phase 3.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Phase 3 — Author gaps and audit packets
|
|
152
|
+
|
|
153
|
+
### 3.1 Author new tasks (gaps only)
|
|
154
|
+
|
|
155
|
+
For issues in manifest without SP-*:
|
|
156
|
+
|
|
157
|
+
- Follow `create-spine-tasks` (lean) + [packet-from-issue.md](../router-backlog-orchestrator/references/packet-from-issue.md)
|
|
158
|
+
- Link GitHub in `## Source`; Mission `Closes: #NNN` or `Partial:`
|
|
159
|
+
- Size S/M; ≤4 impl steps; Contract + Testing step
|
|
160
|
+
- Update `dependencies.json`, `CONTEXT.md`, `Next Task ID`
|
|
161
|
+
- Serialize hot files: `.pi/extensions/smart-router/index.ts`, `src/domain/pipeline/router-pipeline.ts`, `src/api/middleware/pi-router-middleware.ts`
|
|
162
|
+
|
|
163
|
+
### 3.2 Audit release-scoped packets
|
|
164
|
+
|
|
165
|
+
| Size | Action |
|
|
166
|
+
|------|--------|
|
|
167
|
+
| **S** | Keep if ≤4 impl steps |
|
|
168
|
+
| **M** | OK if disjoint; in patch only for bug-fix decomposition |
|
|
169
|
+
| **L/XL** | **Split** before inclusion |
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
spine tasks validate <release-scope>
|
|
173
|
+
spine tasks analyze <release-scope>
|
|
174
|
+
spine plan <release-scope>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 3.3 Commit packet changes
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
git add spine-tasks/
|
|
181
|
+
git commit -m "chore(spine): release v{TARGET} task packets"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Phase 4 — Execute release scope
|
|
187
|
+
|
|
188
|
+
Delegate wave start / monitor / land / recovery to pi-spine **spine-release-operator** Phase 4 (or spine-autonomous-operator) with these **repo-specific** gates:
|
|
189
|
+
|
|
190
|
+
**Scope:** manifest tasks only — comma-separated release scope ID list.
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
spine preflight
|
|
194
|
+
spine run sequence <release-scope> --dry-run
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
For each wave until release-scoped tasks are `.DONE`:
|
|
198
|
+
|
|
199
|
+
1. Detached `spine batch start <release-scope> --wave N` (omit `--attached` unless persistent interactive terminal)
|
|
200
|
+
2. `spine status --diagnose` / `spine wait`
|
|
201
|
+
3. Land: `spine gate approve` → `spine integrate` → `npm install` → `spine batch complete`
|
|
202
|
+
4. **Post-integrate regression gate (blocking):**
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npm run release:check 2>&1 | tee /tmp/pi-smart-router-post-integrate-wave-${N}.log
|
|
206
|
+
test "${PIPESTATUS[0]}" -eq 0
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Do **not** start wave N+1, push, or publish until exit 0. Fix on `main` and re-run if failed.
|
|
210
|
+
|
|
211
|
+
Wave sizing: ≤4 M-sized tasks per wave; serialize hot shared files.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Phase 5 — Pre-publish verification (STOP)
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
spine plan <release-scope> # 0 pending for scope
|
|
219
|
+
spine preflight
|
|
220
|
+
npm run release:check 2>&1 | tee /tmp/pi-smart-router-release-check.log
|
|
221
|
+
test "${PIPESTATUS[0]}" -eq 0
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**If non-zero:** STOP. Fix on `main`, re-run Phase 5. Do not ask for publish approval.
|
|
225
|
+
|
|
226
|
+
Present checklist (only after exit 0):
|
|
227
|
+
|
|
228
|
+
- [ ] All release-scoped tasks done
|
|
229
|
+
- [ ] Theme + profile audit still accurate
|
|
230
|
+
- [ ] `npm run release:check` exit 0
|
|
231
|
+
- [ ] CI green on `HEAD` (`gh run list --workflow ci.yml --commit "$(git rev-parse HEAD)"`)
|
|
232
|
+
- [ ] Clean git tree
|
|
233
|
+
- [ ] Bump type matches Phase 2 profile
|
|
234
|
+
|
|
235
|
+
**Human gate:** do not bump or push until operator approves publish **and** Phase 5 passed.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Phase 6 — Publish (after approval only)
|
|
240
|
+
|
|
241
|
+
**Prerequisites:** Phase 5 `release:check` exit 0; CI green on `HEAD`; operator said approve publish + confirmed bump type.
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
COMMIT=$(git rev-parse HEAD)
|
|
245
|
+
gh run list --workflow ci.yml --commit "$COMMIT" --json databaseId,conclusion,status --limit 5
|
|
246
|
+
# Fail closed unless conclusion: success
|
|
247
|
+
|
|
248
|
+
npm version patch # or minor / major — must match Phase 2
|
|
249
|
+
git push && git push --tags
|
|
250
|
+
gh run list --workflow release.yml --limit 3
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Post-publish:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npm view pi-smart-router version
|
|
257
|
+
# optional: pi install npm:pi-smart-router@<version>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Update `spine-tasks/CONTEXT.md` release note. Close GitHub issues where acceptance was met (`Closes:`).
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Final report (required)
|
|
265
|
+
|
|
266
|
+
1. Manifest path, target version, profile, **theme**, composition table
|
|
267
|
+
2. Tasks completed — SP-IDs, waves, issues closed
|
|
268
|
+
3. Deferred backlog — count and top items
|
|
269
|
+
4. Profile audit result (no feature-in-patch OVERRIDE)
|
|
270
|
+
5. Verification — `release:check` log path / exit code; CI run URL
|
|
271
|
+
6. Publish — version bumped (Y/N), tag, workflow URL, or awaiting approval
|
|
272
|
+
|
|
273
|
+
## Repo-specific notes
|
|
274
|
+
|
|
275
|
+
| Item | Value |
|
|
276
|
+
|------|-------|
|
|
277
|
+
| Tasks root | `spine-tasks/` |
|
|
278
|
+
| Issues repo | `beettlle/pi-smart-router` |
|
|
279
|
+
| Profiles | `skills/router-release-operator/references/release-profiles.md` |
|
|
280
|
+
| Pre-publish gate | `npm run release:check` |
|
|
281
|
+
| Publish | Tag-triggered `.github/workflows/release.yml` |
|
|
282
|
+
|
|
283
|
+
## Short prompt (resume mid-release)
|
|
284
|
+
|
|
285
|
+
```text
|
|
286
|
+
Resume router release v{TARGET}: check manifest at
|
|
287
|
+
spine-tasks/_authoring/release-v{TARGET}/manifest.md (theme + profile audit) →
|
|
288
|
+
spine status --diagnose → preflight → for each wave: batch start → diagnose →
|
|
289
|
+
gate approve → integrate → npm install → batch complete →
|
|
290
|
+
post-integrate release:check (exit 0) → final release:check → CI green on HEAD →
|
|
291
|
+
STOP for publish approval. Post final report with theme and composition table.
|
|
292
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Issue intake checklist (pi-smart-router)
|
|
2
|
+
|
|
3
|
+
Run during **Phase 1** before composing the release manifest.
|
|
4
|
+
|
|
5
|
+
## GitHub queries
|
|
6
|
+
|
|
7
|
+
Repo: `beettlle/pi-smart-router`
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
gh issue list --repo beettlle/pi-smart-router --state open --limit 100 \
|
|
11
|
+
--json number,title,labels,body
|
|
12
|
+
|
|
13
|
+
gh issue list --repo beettlle/pi-smart-router --state open --label documentation \
|
|
14
|
+
--json number,title,labels
|
|
15
|
+
|
|
16
|
+
gh issue list --repo beettlle/pi-smart-router --state open --label bug \
|
|
17
|
+
--json number,title,labels
|
|
18
|
+
|
|
19
|
+
gh issue list --repo beettlle/pi-smart-router --state open --label enhancement \
|
|
20
|
+
--json number,title,labels
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Label taxonomy
|
|
24
|
+
|
|
25
|
+
| Label | Release bucket | Priority notes |
|
|
26
|
+
|-------|----------------|----------------|
|
|
27
|
+
| `documentation` | Documentation | Highest — address before enhancements when theme allows |
|
|
28
|
+
| `bug` | Bug fix | Prefer user-impact, reproducible, already-tasked |
|
|
29
|
+
| `enhancement` | Enhancement | Minor/major only; zero per patch |
|
|
30
|
+
| Priority in title/body (P0–P3) | Any | Prefer P0/P1 dogfood over P3 eval when choosing among enhancements |
|
|
31
|
+
|
|
32
|
+
## Roadmap and theme fit
|
|
33
|
+
|
|
34
|
+
Read [`docs/routing-roadmap.md`](../../../docs/routing-roadmap.md) before selecting enhancements.
|
|
35
|
+
|
|
36
|
+
| Kind | Examples | Theme wording |
|
|
37
|
+
|------|----------|---------------|
|
|
38
|
+
| User-facing routing | Pinning, triage, local_zero, dogfood fixes | Name the user-visible behavior |
|
|
39
|
+
| Eval / infra | Corpora, benches, release gates soft-feed | Name the eval/tooling track; do not mix with unrelated dogfood unless one theme |
|
|
40
|
+
|
|
41
|
+
When multiple enhancements compete, prefer P0/P1 dogfood / routing quality over P3 bench/community work unless the operator sets an eval theme.
|
|
42
|
+
|
|
43
|
+
## Issue → task mapping
|
|
44
|
+
|
|
45
|
+
1. Grep pending and done tasks for issue links:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
rg 'GitHub: beettlle/pi-smart-router#|Closes:|Partial:' spine-tasks/*/PROMPT.md
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
2. Classify each open issue:
|
|
52
|
+
|
|
53
|
+
| State | Action |
|
|
54
|
+
|-------|--------|
|
|
55
|
+
| Mapped to pending SP-* | Candidate for manifest if fits profile + theme |
|
|
56
|
+
| Mapped to `.DONE` SP-* | Closed by shipped work — exclude |
|
|
57
|
+
| No SP-* yet | **Gap** — author with `create-spine-tasks` in Phase 3 |
|
|
58
|
+
| Epic / `[Epic]` in title | Defer unless major profile with operator approval |
|
|
59
|
+
| Hardware (#1/#25/#26) | Defer — physical access |
|
|
60
|
+
|
|
61
|
+
## Documentation issue heuristics
|
|
62
|
+
|
|
63
|
+
Prefer for release inclusion when:
|
|
64
|
+
|
|
65
|
+
- `label:documentation` or title/body is README, quickstart, operator guide, env vars
|
|
66
|
+
- Pending SP-* with docs-only File Scope
|
|
67
|
+
- Docs required to ship the release theme (minor)
|
|
68
|
+
|
|
69
|
+
## Bug issue heuristics
|
|
70
|
+
|
|
71
|
+
Prefer when:
|
|
72
|
+
|
|
73
|
+
- Repro steps in issue body or linked diagnosis
|
|
74
|
+
- Already has pending SP-* linked to the GitHub issue
|
|
75
|
+
- S/M size, disjoint file scope from parallel neighbors
|
|
76
|
+
- User-visible failure (routing, failover, pin, install)
|
|
77
|
+
|
|
78
|
+
Exclude when:
|
|
79
|
+
|
|
80
|
+
- Fixed on `main` but issue not closed
|
|
81
|
+
- Blocked by epic infrastructure not in this release
|
|
82
|
+
|
|
83
|
+
If **no open bugs**, record that for audit — do not invent OVERRIDE.
|
|
84
|
+
|
|
85
|
+
## Enhancement issue heuristics
|
|
86
|
+
|
|
87
|
+
**Patch profile:** exclude all. If operator wants them, **reclassify release as minor**.
|
|
88
|
+
|
|
89
|
+
**Minor profile:** pick 1–3 **related** issues that complete the theme:
|
|
90
|
+
|
|
91
|
+
- User-visible or operator-visible improvement
|
|
92
|
+
- S/M size; split L/XL first
|
|
93
|
+
- Disjoint `fileScopeMustChange` from bug tasks in same wave
|
|
94
|
+
- Prefer roadmap P0/P1 over P3 when both fit
|
|
95
|
+
|
|
96
|
+
## Pending task inventory
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
spine plan pending
|
|
100
|
+
spine tasks validate pending
|
|
101
|
+
spine tasks analyze pending
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Read `spine-tasks/CONTEXT.md` for `Next Task ID` and phase notes.
|
|
105
|
+
|
|
106
|
+
Cross-reference pending SP-* with open issues. The release executes **manifest scope only**, not all pending tasks.
|
|
107
|
+
|
|
108
|
+
## Intake output table
|
|
109
|
+
|
|
110
|
+
| Issue # | Labels | Mapped SP-* | Bucket | Theme fit | Profile fit | Notes |
|
|
111
|
+
|---------|--------|-------------|--------|-----------|-------------|-------|
|
|
112
|
+
| #97 | bug | SP-176 | bug | dogfood ✓ | minor ✓ | triage fix |
|
|
113
|
+
| #101 | enhancement | — | enh | eval corpus | patch ✗ → use minor | TwinRouterBench |
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Release manifest — v{TARGET_VERSION}
|
|
2
|
+
|
|
3
|
+
**Created:** {YYYY-MM-DD}
|
|
4
|
+
**Current version:** {from package.json}
|
|
5
|
+
**Target version:** v{TARGET_VERSION}
|
|
6
|
+
**Bump type:** patch | minor | major
|
|
7
|
+
**Profile:** patch | minor | major
|
|
8
|
+
**Theme:** {one sentence — required}
|
|
9
|
+
**Operator approved scope:** no | yes ({date})
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Composition audit
|
|
14
|
+
|
|
15
|
+
| Bucket | Selected | Profile limit | Status |
|
|
16
|
+
|--------|----------|---------------|--------|
|
|
17
|
+
| Theme | {sentence} | required | PASS / FAIL |
|
|
18
|
+
| Documentation | {n} | patch 0–2 / minor theme docs | PASS / WARN |
|
|
19
|
+
| Bug fixes | {n} | soft; 0 OK if none open | PASS / PASS (no open bugs) / WARN |
|
|
20
|
+
| Enhancements | {n} | patch **0** / minor 1–3 related | PASS / FAIL |
|
|
21
|
+
| **Total tasks** | {n} | patch ≤8 / minor ≤15 | PASS / WARN |
|
|
22
|
+
|
|
23
|
+
**Profile audit:** PASS | PASS with operator override (caps only) | FAIL (do not proceed)
|
|
24
|
+
|
|
25
|
+
**Hygiene (patch only, if any):** {one-line justification or "none"}
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Selected tasks
|
|
30
|
+
|
|
31
|
+
| SP-ID | Issue | Bucket | Size | Title | Notes |
|
|
32
|
+
|-------|-------|--------|------|-------|-------|
|
|
33
|
+
| SP-### | #NNN | doc / bug / enh | S/M | … | Closes / Partial |
|
|
34
|
+
|
|
35
|
+
**Release scope ID:** comma-separated SP-IDs for `spine plan`, `spine batch start`, and `spine run sequence` (e.g. `SP-196,SP-197,SP-199`). No spaces.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Sequence runner (Phase 4)
|
|
40
|
+
|
|
41
|
+
The manifest is the operator contract; the CLI takes the **scope ID string**, not the manifest file path.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
spine tasks validate <SP-IDs...>
|
|
45
|
+
spine plan <release-scope-id>
|
|
46
|
+
spine run sequence <release-scope-id> --dry-run
|
|
47
|
+
spine run sequence <release-scope-id> # detached — omit --attached
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Per-wave manual loop (alternative to full sequence):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
spine batch start <release-scope-id> --wave N
|
|
54
|
+
spine status --diagnose
|
|
55
|
+
spine gate approve && spine integrate && npm install && spine batch complete
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Regression gate** (after each integrate, before next wave):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm run release:check 2>&1 | tee /tmp/pi-smart-router-post-integrate-wave-${WAVE:-main}.log
|
|
62
|
+
test "${PIPESTATUS[0]}" -eq 0
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Do **not** use `| tail` alone for pass/fail — verify exit code.
|
|
66
|
+
|
|
67
|
+
**Operator gates** (human only):
|
|
68
|
+
|
|
69
|
+
1. Approve this manifest (operator sign-off on scope + theme)
|
|
70
|
+
2. `spine gate approve` per integrate wave
|
|
71
|
+
3. Publish approval before `npm version <bump>`
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Gaps requiring new packets
|
|
76
|
+
|
|
77
|
+
| Issue | Bucket | Proposed SP-ID | Author with |
|
|
78
|
+
|-------|--------|----------------|-------------|
|
|
79
|
+
| #90 | doc | SP-### | create-spine-tasks (lean) |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Wave plan snapshot
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
(paste output of: spine plan <release-scope>)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Deferred backlog
|
|
92
|
+
|
|
93
|
+
| Item | Type | Rationale |
|
|
94
|
+
|------|------|-----------|
|
|
95
|
+
| SP-### / #NNN | enh | Outside theme; defer to next minor |
|
|
96
|
+
| #1 / #25 / #26 | epic | Hardware — blocked on physical access |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Risks and blockers
|
|
101
|
+
|
|
102
|
+
- {e.g. hot-file serialization on router-pipeline.ts}
|
|
103
|
+
- {e.g. release:check flaky assert — fix before tag}
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Publish checklist (Phase 5–6)
|
|
108
|
+
|
|
109
|
+
- [ ] All release-scoped tasks `.DONE` on `main`
|
|
110
|
+
- [ ] Post-integrate `release:check` green after **each wave** (log paths recorded)
|
|
111
|
+
- [ ] `spine preflight` green
|
|
112
|
+
- [ ] `npm run release:check` green on final `HEAD` (exit 0 verified)
|
|
113
|
+
- [ ] CI workflow green on `HEAD` (`gh run list` / `gh run watch`)
|
|
114
|
+
- [ ] `git status` clean
|
|
115
|
+
- [ ] Operator approved publish bump type: patch | minor | major (matches Phase 2)
|
|
116
|
+
- [ ] `npm version <bump>` + `git push && git push --tags`
|
|
117
|
+
- [ ] `release.yml` succeeded; `npm view pi-smart-router version` matches target
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Release profiles (pi-smart-router)
|
|
2
|
+
|
|
3
|
+
Use at **Phase 2** after parsing the operator's target version. Compare `package.json` version to the target to derive bump type.
|
|
4
|
+
|
|
5
|
+
These budgets **replace** pi-spine `spine-release-operator` profile math for this repo. Batch land / publish mechanics still follow spine-release-operator or spine-autonomous-operator.
|
|
6
|
+
|
|
7
|
+
## Derive bump type
|
|
8
|
+
|
|
9
|
+
| Current → Target | Bump type | Profile |
|
|
10
|
+
|------------------|-----------|---------|
|
|
11
|
+
| `0.9.3` → `0.9.4` | **patch** | `patch` |
|
|
12
|
+
| `0.9.3` → `0.10.0` | **minor** | `minor` |
|
|
13
|
+
| `0.10.0` → `1.0.0` | **major** | `major` |
|
|
14
|
+
|
|
15
|
+
If the operator says only `patch` / `minor` / `major` without a version, compute the next version from `package.json` and record both in the manifest.
|
|
16
|
+
|
|
17
|
+
## Invocation parsing
|
|
18
|
+
|
|
19
|
+
| Operator says | Profile |
|
|
20
|
+
|---------------|---------|
|
|
21
|
+
| "release for v0.9.4", "patch release", "hotfix release" | `patch` |
|
|
22
|
+
| "release for v0.10.0", "minor release", "feature release" | `minor` |
|
|
23
|
+
| "release for v1.0.0", "major release", "breaking release" | `major` |
|
|
24
|
+
| "run a router release cycle" (no version) | **Ask** operator for target version or bump type |
|
|
25
|
+
|
|
26
|
+
## Theme (all profiles)
|
|
27
|
+
|
|
28
|
+
Every release **requires** a one-sentence **theme** in the manifest (e.g. "Dogfood routing fixes", "Eval corpora & community bench", "Stability hotfix").
|
|
29
|
+
|
|
30
|
+
- Selected issues/tasks must **complete or clearly serve** that theme.
|
|
31
|
+
- Prefer **sibling clusters** that finish the theme over thin single-issue versions.
|
|
32
|
+
- Theme missing or selected work contradicts the theme → **FAIL** (do not proceed).
|
|
33
|
+
|
|
34
|
+
## Profile budgets
|
|
35
|
+
|
|
36
|
+
### Patch (`patch`)
|
|
37
|
+
|
|
38
|
+
Stability and correctness only. No new capability.
|
|
39
|
+
|
|
40
|
+
| Bucket | Target | Hard limits |
|
|
41
|
+
|--------|--------|-------------|
|
|
42
|
+
| Theme | Required (stability / hotfix) | Must match selected work |
|
|
43
|
+
| Documentation | 0–2 clarifications | No new feature docs; defer large doc epics |
|
|
44
|
+
| Bug fixes | Soft target 1–5 high-impact | Include open high-impact bugs that fit the cap; **0 OK** when none open |
|
|
45
|
+
| Enhancements | **0** | **Hard fail** if any enhancement included — reclassify as minor or drop |
|
|
46
|
+
| Total tasks | **≤8** | WARN if >8; proceed only with operator override that keeps bump type honest |
|
|
47
|
+
| Max waves | 1–2 | Prefer single wave when possible |
|
|
48
|
+
| Task sizes | S preferred; M OK | M allowed only for bug-fix decomposition with disjoint scope; split L/XL |
|
|
49
|
+
|
|
50
|
+
**Hygiene exception (patch only):** non-user-facing fixes (typo, flake clock, lint-only) allowed with a **one-line justification** in the manifest. Still **no** new capability.
|
|
51
|
+
|
|
52
|
+
**Defer by default:** all enhancements, roadmap items, eval/infra features, epics, hardware.
|
|
53
|
+
|
|
54
|
+
### Minor (`minor`)
|
|
55
|
+
|
|
56
|
+
One capability theme plus related stability work.
|
|
57
|
+
|
|
58
|
+
| Bucket | Target | Hard limits |
|
|
59
|
+
|--------|--------|-------------|
|
|
60
|
+
| Theme | Required (capability name) | Sibling issues that complete the theme preferred |
|
|
61
|
+
| Documentation | Docs for the theme | Include operator-facing docs for shipped capability |
|
|
62
|
+
| Bug fixes | Open high-impact that fit | Soft; **0 OK** when no open bugs (`PASS (no open bugs)`) |
|
|
63
|
+
| Enhancements | **1–3 related** issues | Must serve the theme; defer unrelated P2/P3 |
|
|
64
|
+
| Total tasks | **≤15** | WARN if >15 without override |
|
|
65
|
+
| Max waves | 2–4 | ≤4 M-sized tasks per wave |
|
|
66
|
+
| Task sizes | S/M | Split L/XL before inclusion |
|
|
67
|
+
|
|
68
|
+
**Defer by default:** unrelated roadmap slices, hardware epics, work needing >4 waves.
|
|
69
|
+
|
|
70
|
+
**Priority among enhancements:** prefer [`docs/routing-roadmap.md`](../../../docs/routing-roadmap.md) P0/P1 dogfood over P3 eval when choosing what completes the theme.
|
|
71
|
+
|
|
72
|
+
### Major (`major`)
|
|
73
|
+
|
|
74
|
+
Breaking changes and large migrations (e.g. 1.0 readiness). Operator-defined epic scope.
|
|
75
|
+
|
|
76
|
+
| Bucket | Target | Hard limits |
|
|
77
|
+
|--------|--------|-------------|
|
|
78
|
+
| Theme | Required (breaking / 1.0) | Explicit epic boundaries in manifest |
|
|
79
|
+
| Documentation | Migration guides + comprehensive pass | Required for breaking changes |
|
|
80
|
+
| Bug fixes | Critical blockers | Prioritize regressions blocking migration |
|
|
81
|
+
| Enhancements | Multiple allowed | Breaking API changes OK with migration path |
|
|
82
|
+
| Total tasks | Operator-defined | Manifest must list epic boundaries |
|
|
83
|
+
| Max waves | Planned in manifest | Expect multi-cycle execution |
|
|
84
|
+
|
|
85
|
+
**Require:** explicit operator approval of epic scope before Phase 3. Do not auto-select major scope from backlog alone.
|
|
86
|
+
|
|
87
|
+
## Selection order (all profiles)
|
|
88
|
+
|
|
89
|
+
Apply in this order; stop when profile budget is full:
|
|
90
|
+
|
|
91
|
+
1. **Documentation** — `label:documentation`, README/operator-guide clarifications fitting the theme
|
|
92
|
+
2. **Bug fixes** — open `label:bug` with user impact; prefer already-tasked or quick S/M
|
|
93
|
+
3. **Enhancements** — **minor/major only**; only theme-completing related issues
|
|
94
|
+
4. **Defer** everything else with one-line rationale
|
|
95
|
+
|
|
96
|
+
## Profile audit (must pass before Phase 3)
|
|
97
|
+
|
|
98
|
+
| Check | Patch | Minor | Major |
|
|
99
|
+
|-------|-------|-------|-------|
|
|
100
|
+
| Theme present and coherent | Required | Required | Required |
|
|
101
|
+
| Enhancement count | **>0 → FAIL** (reclassify or drop) | >3 without override → WARN | — |
|
|
102
|
+
| Bug count | 0 + no open bugs → **PASS (no open bugs)**; open bugs skipped without deferral → WARN | Same | Critical blockers skipped → WARN |
|
|
103
|
+
| Total tasks | >8 → WARN | >15 → WARN | — |
|
|
104
|
+
| M/L in patch | L/XL → split; M only for bug-fix decomposition | — | — |
|
|
105
|
+
| Bump type vs content | Features in scope → must be **minor**, not patch OVERRIDE | — | — |
|
|
106
|
+
|
|
107
|
+
**Do not** use OVERRIDE to ship enhancements as patch. Change bump type to minor or drop the enhancement.
|
|
108
|
+
|
|
109
|
+
Record `Profile audit: PASS` or `PASS with operator override` (caps/waves only; never for feature-in-patch) before proceeding.
|
|
110
|
+
|
|
111
|
+
## Version ↔ publish alignment
|
|
112
|
+
|
|
113
|
+
The bump type chosen in Phase 2 must match `npm version` in Phase 6:
|
|
114
|
+
|
|
115
|
+
- `patch` profile → `npm version patch`
|
|
116
|
+
- `minor` profile → `npm version minor`
|
|
117
|
+
- `major` profile → `npm version major`
|
|
118
|
+
|
|
119
|
+
If the operator changes bump type at publish gate, update the manifest and confirm scope still fits the new profile.
|
|
120
|
+
|
|
121
|
+
## Sanity checks (read-through)
|
|
122
|
+
|
|
123
|
+
| Proposal | Result |
|
|
124
|
+
|----------|--------|
|
|
125
|
+
| Ship #106 + #107 as **patch** | **FAIL** — enhancements; recommend **minor** with theme e.g. "TwinRouterBench fit & CI track" |
|
|
126
|
+
| Hotfix only open bugs as **patch**, theme "Stability hotfix" | **PASS** |
|
|
127
|
+
| Feature-only minor, 0 open bugs, theme "Live leaderboard ingest" | **PASS (no open bugs)** |
|