Drive a new integration feature (e.g. a price provider or inverter platform)
through its full lifecycle: research → ship experimental → collect a real
user config → lock it into the regression suite → re-ship green → user confirms
→ graduate (strip "experimental"). Designed to be run by an autonomous agent
that communicates with the user in the PR and the originating issue, runs
the release skill, and polls CI between human gates.
This skill orchestrates other skills — it does not re-implement them:
- Implementation →
add-price-provider(or the equivalent for the feature). - Deployment →
release(release beta, thenreleasefor prod).
- Gates are human-in-the-loop. Stages 2 and 5 wait for the user. Do not fabricate logs or confirmation. Post a clear ask, then stop and poll.
- Communicate in the open. Use
gh pr comment/gh issue commentfor every ask and every result. The originating issue is the source of truth for lifecycle state — the Stage 1 PR merges immediately and can't carry state across later stages. - Never claim real-world validation until Stage 5. Keep the
experimentalmarker until the user confirms against their own hardware. - Track state with a checklist in the issue body/comments (one box per stage) so a resumed agent knows where it is.
- Honour repo rules: tests green before push, draft PRs, beta vs prod remotes
(
releaseskill owns the remote logic), CHANGELOG always updated.
- Run the implementation skill end-to-end (
add-price-provider): verified discovery from integration source, source class + wiring + frontend, unit + discovery tests, a source-derived scenario fixture, and the wizard E2E. - Mark the feature experimental everywhere the user sees it — this label
is the stability flag for this codebase. Only the README/USER_GUIDE tag
has real precedent today (used for the ENTSO-e/Belpex price provider);
the other two are new conventions this feature would establish:
- Docs (real, precedented):
README.mdtag*(experimental)*+docs/USER_GUIDE.mdnote in the style of the ENTSO-e/Belpex entry ("Experimental: not yet real-world validated"). - UI (aspirational — not implemented anywhere in
frontend/srctoday): if feasible, add a provider/platform option label or help text such as "(experimental)"; otherwise skip it and rely on the docs tag alone. - Maturity record (new — does not exist on
mainyet): createdocs/agents/memory/project_platform_maturity.mdwith an "Experimental / not yet real-world validated" section naming the new platform/provider key. This is the first feature to use this file; there is no existing GEN3/SolaX entry to extend — those platforms are candidates for future entries, not current precedent. Once created, later features extend this same file instead of re-creating it.
- Docs (real, precedented):
- Open a draft PR against
origin/mainreferencing the issue (e.g. "Relates to #") — do not useCloses/Fixes #<issue>here. This PR merges immediately in step 4, long before the feature is real-world validated or graduated, so it must not close the reporter's issue; only Stage 6's graduation PR does that. Put the lifecycle checklist in the issue (see template below), not the PR body — the PR won't persist across later stages.origin/mainis the PR target for every stage of this lifecycle, including this initial experimental merge — there is no beta-first branch. Beta is a downstream mirror ofmain(seereleaseskill) and is never a place code is authored. - Merge to
origin/mainwith the experimental markers from step 2 in place. Then runrelease betato mirror the currentmain(now including this feature) into a beta build. Comment on the issue that an experimental build is available and ask the user to install it and report back.
- Exit: feature merged to
origin/mainbehind the experimental markers, mirrored into a published beta build, issue comment posted requesting a trial.
The user installs the experimental build and exports a debug report
(docs/bess-debug-*.md) — which includes the entity snapshot (their full
config: inverter platform, sensors, and the new provider entity).
- Poll the issue/PR for the user's debug log (or a "it works / it doesn't" report). If absent, wait — re-ask politely on a sensible cadence.
- When the log arrives, verify it against the real data:
- Confirm the new integration's entity + attributes are present and parse.
- If discovery/parse fails, this is a real bug — loop back to Stage 1
(fix on
main, re-runrelease betato re-mirror) before proceeding. Do not skip.
- Exit: a real debug log is in hand and the feature demonstrably works on it.
This is the durable payoff: the user's whole rig becomes a permanent regression test, not just the price source — so their inverter, sensors, and provider together never silently break.
- Generate a verbatim-replay scenario from their log:
python scripts/mock_ha/scenarios/from_debug_log.py docs/bess-debug-<ts>.md # → scripts/mock_ha/scenarios/<ts>.json (every entity state, verbatim) - Anonymize: strip/replace serial numbers, device IDs, API keys, MPANs, coordinates, and any account identifiers — keep the structure and entity shapes. (The debug export allowlist already drops most secrets; double-check the snapshot.)
- Add an
expected_discoveryblock (andrequired_sensors) so the scenario runs as a discovery regression intest_scenario_discovery.py. - Wire it into the frontend wizard E2E too:
wizard-expectations.ts,setup-wizard.spec.ts(if a new provider label/branch is needed),e2e/run-e2e.sh, and.github/workflows/ci.yml(per-scenario step). - Rename the fixture meaningfully (e.g.
ci-wizard-<provider>-<user>.json) and reference the issue number in itsdescription.
- Exit: the user's anonymized config is a green regression scenario in both the backend suite and the frontend E2E.
This stage is usually a loop of rapid minor fixes (the feature can't be
self-validated, so issues surface only against real configs). Batch them —
do NOT cut a beta release + CHANGELOG entry per fix; that spams users and the
changelog. Accumulate fixes as commits on the PR to origin/main and cut a
consolidated beta mirror only at a meaningful checkpoint, with one combined
CHANGELOG entry.
- Local gate on each iteration:
pytest -m "not slow",black/ruff,tsc/vitest/build, and the new scenario's wizard E2E. - At a checkpoint (not per fix): merge the accumulated fixes + regression
fixture to
origin/main, then runrelease betato mirror that checkpoint into beta, one consolidated CHANGELOG entry. - Poll CI until green:
On failure:
gh pr checks <pr> --repo <repo> --watchgh run view <id> --log-failed, fix locally, re-push, re-poll. Keep batching — fold the CI fix into the same checkpoint, don't cut a new release for it.
- Exit: beta CI green with the user's scenario in the matrix.
- Comment on the issue/PR: the regression test for their config is in and CI is green — ask them to confirm the experimental build works as expected.
- Wait for explicit confirmation. If they report a problem, loop to Stage 1/2.
- Exit: user has confirmed it works on their hardware.
Graduation only removes the stability flag from Stage 1 — it is a follow-up
PR to origin/main, never a branch change (the feature already lives on
main; beta was only ever a mirror of it).
- Open a follow-up PR to
origin/main,Closes #<issue>— this graduation PR is the one that closes the reporter's issue, per repo rule (only the final prod PR closes the issue; Stage 1's PR must not). It changes only the experimental markers added in Stage 1's step 2: strip the UI label/help text, theREADME.mdtag, thedocs/USER_GUIDE.mdnote, and move the platform/provider key indocs/agents/memory/project_platform_maturity.mdfrom "Experimental / not yet real-world validated" to the real-world-tested list, crediting the confirming user's scenario. No implementation changes belong in this PR. Also hand-add a## [Unreleased]CHANGELOG entry ("Added — now stable") as part of this PR's merge, so it lands onmainahead of the nextrelease prodrun. - Merge the graduation PR, then run the production
releaseskill (release/release prod): version bump, rename## [Unreleased]to the version heading (the entry from step 1 is already there — the release skill's only changelog edit is the rename, it does not hand-author content), PR toorigin/main, CI green, tag, GitHub Release. - Update the issue's lifecycle checklist to all-checked and post a final thank-you comment to the user; the graduation PR merged in step 2 already closed the issue.
- Exit: feature stable in a production release; issue closed.
Post/update this on the originating issue (not the PR body — the Stage 1 PR merges immediately and doesn't persist as a lifecycle tracker):
### Lifecycle: <feature> (#<issue>)
- [x] 1. Merged to main + shipped experimental (beta vX.Y.Zb_)
- [ ] 2. User debug log received + verified
- [ ] 3. Anonymized user-config regression scenario added (backend + E2E)
- [ ] 4. Re-shipped beta, CI green
- [ ] 5. User confirmed on their hardware
- [ ] 6. Experimental removed, promoted to stable (prod vX.Y.Z)
| Concern | Where |
|---|---|
| Implementation steps | .claude/skills/add-price-provider/SKILL.md |
| Beta + prod deploy | .claude/skills/release/SKILL.md |
| Debug log → scenario | scripts/mock_ha/scenarios/from_debug_log.py |
| Backend regression harness | core/bess/tests/unit/test_scenario_discovery.py |
| Frontend wizard E2E | e2e/tests/setup-wizard.spec.ts, e2e/run-e2e.sh, .github/workflows/ci.yml |
| Maturity record (the stability flag) | README.md *(experimental)* tag + docs/USER_GUIDE.md note (real, precedented today via ENTSO-e/Belpex) + docs/agents/memory/project_platform_maturity.md (new file, first created by this feature) + optional UI "(experimental)" label (aspirational, no current precedent in frontend/src) |
| Agent comms | gh pr comment, gh issue comment, gh pr checks --watch |