dwmkerr / dwmkerr/openspec-flow

feat: shim upgrade flow for repos where the template has moved on

Open
#76 0 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.