dwmkerr / dwmkerr/openspec-flow
feat: shim upgrade flow for repos where the template has moved on
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 3d 23h
- Merged PRs (30d)
- 1
Description
## Problem
Today `runAppInit` is idempotent on marker presence — once an init PR
has been merged, re-running `app-init` or re-installing the App is a
no-op even if the canonical shim template has moved on.
That bit us when adding the `permissions:` block to the shim template
(needed for the reusable workflow to mint write tokens — without it,
runs fail with `is requesting 'contents: write…' but is only allowed
'contents: read…'`). Repos installed before the template fix carry the
old shim forever; the App and CLI both see them as `already-initialised`.
Concrete example: https://github.com/dwmkerr/shellwright/pull/76
(hand-rolled fix that the system should have produced automatically).
## Current planner state (drift is already detected, just not surfaced)
`src/install/plan.ts` distinguishes:
- workflow absent → write
- workflow === template → noop, reason `matches template`
- workflow !== template → noop, reason `diverges from template — re-run with --force`
The App-init layer collapses both noop outcomes into one
`skipped: already-initialised` via `allNoop`. Drift is invisible.
## Scope to consider in a follow-up change
- **Distinguish four states**: fresh / current / stale / drifted.
- **Decide push vs pull**: bot opens upgrade PRs on its own, or operator runs `--upgrade`?
- **Pin shim's `uses:` to a semver ref** so drift is unambiguous — ties into the `ideas.md` "fetch-from-release + version pin" item. Without a pin, `@main` is implicitly always upgrading on the reusable side; only the shim is static.
- **Hand-edit safety**: divergence vs drift — never clobber user edits without an explicit opt-in.
## Bonus suggestion — self-check inside the reusable workflow
Cheap first move that needs no new infrastructure: have the reusable workflow itself probe the shim it was called from and, if it detects the shim is out of date vs the in-tree template, emit a hint into the job log:
```
::warning:: openspec-flow shim is out of date. Run `openspec-flow app-init --repo /` to get an upgrade PR, or copy the latest template from https://github.com/dwmkerr/openspec-flow/blob/main/templates/openspec-flow.yml
```
This makes the staleness visible in the place users actually look (the failing workflow run) without committing to a full push/pull upgrade flow. Implementation: a short step at the top of the `flow` job that reads `${{ github.workspace }}/.github/workflows/openspec-flow.yml` (after a sparse checkout of the caller repo) and compares against `templates/openspec-flow.yml` in the openspec-flow checkout. The reusable workflow already checks itself out at `job_workflow_sha` so both files are available.
Out of scope of `app-install-init-pr`.
Contributor guide
No contributing guide indexed for this repository
Research direction
Read src/install/plan.ts and the runAppInit/app-init path first; confirm how allNoop collapses template matches and divergence. Decide whether upgrades are push or pull, how fresh/current/stale/drifted states are surfaced, and how hand-edited shims are protected; done means the chosen behavior is specified and covered without clobbering user edits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, typescript
- Domain
- ci-cd, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100