Skip to content

feat(setup-steward): multi-install + committed/local lock split + drift detection - #40

Merged
potiuk merged 1 commit into
apache:mainfrom
potiuk:feat/setup-steward-multi-install-lock-split
May 4, 2026
Merged

feat(setup-steward): multi-install + committed/local lock split + drift detection#40
potiuk merged 1 commit into
apache:mainfrom
potiuk:feat/setup-steward-multi-install-lock-split

Conversation

@potiuk

@potiuk potiuk commented May 4, 2026

Copy link
Copy Markdown
Member

Summary

Rewrite setup-steward to support three install methods, split the lock file into committed (project pin) + local (per-machine fetch), and drive every framework-skill invocation through a drift check that compares the two locks.

This is the design step that makes apache-steward behave like a proper distribution-aware framework: a project commits one pin, every contributor's machine fetches against it, drift is detected and remediated automatically.

Three install methods (copy-pasteable in docs/setup/install-recipes.md)

Method When Reproducibility
svn-zip Signed zip from ASF dist (https://dist.apache.org/repos/dist/release/<project>/) — the canonical ASF release distribution path per release-policy and infra release-distribution guidelines. Verified via SHA-512 + optional OpenPGP. Recommended for production once the framework ships official releases. Frozen by version
git-tag Pinned to a specific git tag. Frozen by tag
git-branch (default main) Tracks a branch tip — the WIP path during the framework's pre-release phase. Tracks tip

Each recipe is one shell block that adds gitignore entries, downloads + verifies + extracts the framework into .apache-steward/, copies the bootstrap skill into the adopter's skills dir (matching flat or double-symlinked convention), and tells the user to follow /setup-steward from there.

Lock-file split

File Tracked? Records
.apache-steward.lock committed The project's pin: method, url, ref, plus a verification anchor (commit for tag, sha512 for zip). Edited only by /setup-steward; bumping it is a deliberate project-level commit visible in PR diffs.
.apache-steward.local.lock gitignored What THIS machine fetched: source_method, source_url, source_ref, fetched_commit, fetched_at. Per-developer, per-checkout.

Drift detection

Every framework skill (and /setup-steward verify) compares the local lock to the committed lock at the top of its run.

Drift Severity Remediation
Method or URL differ /setup-steward upgrade (full re-install)
Ref differs (project bumped tag, or git-branch local behind upstream tip) /setup-steward upgrade (sync)
svn-zip SHA-512 differs from committed anchor Investigate before upgrading — the released zip changed under the same version

upgrade deletes the gitignored snapshot outright, re-installs per the committed lock, refreshes the gitignored framework-skill symlinks (adds newly-added framework skills, removes renamed-away ones), and reconciles agentic overrides against the new framework structure (surfaces conflicts; never auto-rewrites).

Changes

  • Rewrite .claude/skills/setup-steward/{SKILL,adopt,upgrade,verify}.md to express the new model.
  • New: docs/setup/install-recipes.md with the three copy-pasteable recipes + explanatory framing (when to use each, what each step does, what the skill takes over post-recipe).
  • README's "Adopting the framework" section split into Bootstrap (the shell recipe) → Skill takeover (the interactive part /setup-steward does) → Subsequent contributors (read the committed lock + reinstall) → Drift detection (the run-time mechanism).

Test plan

  • All prek run --all-files hooks pass (markdownlint, typos, doctoc, check-placeholders)
  • setup-steward re-registers in Claude Code's available-skills list (live discovery picked up the rewrite in-session)
  • docs/setup/install-recipes.md recipes are syntactically valid bash (each is a single fenced block, no obvious shell errors)
  • Reviewer copies a recipe verbatim into a scratch repo and confirms it runs cleanly through "snapshot on disk + setup-steward in skills dir"
  • Reviewer eyeballs the committed-vs-local lock model for security gaps (especially around the SHA-512 mismatch flow)
  • CI link-check (lychee) passes

Out of scope (follow-up PR)

Wire the drift check into each framework skill's pre-flight section, alongside the override-consultation hook from #39. 15 skills to touch; mechanical change, deferred to keep this PR focused on the mechanism design rather than the rollout.

🤖 Generated with Claude Code

…ft detection

Rewrite setup-steward to support three install methods, split
the lock file into committed (project pin) and local
(per-machine fetch), and drive every framework-skill invocation
through a drift check that compares the two locks.

Three install methods (copy-pasteable recipes in
docs/setup/install-recipes.md)

- svn-zip: signed zip from ASF dist
  (`https://dist.apache.org/repos/dist/release/<project>/`),
  the canonical ASF release distribution path. Verified via
  SHA-512 + OpenPGP. Recommended for production once the
  framework ships official releases.
- git-tag: pinned to a specific git tag — frozen by tag.
- git-branch: tracks a branch tip (default: main) — the WIP
  path during pre-release.

Each recipe is a single shell block: adds the right gitignore
entries, downloads + verifies + extracts, copies the
setup-steward skill into the adopter's skills dir (matching the
flat or double-symlinked convention), and tells the user to
follow /setup-steward from there.

Lock-file split

- .apache-steward.lock (committed) — the project's pin: method,
  url, ref, plus a verification anchor (commit SHA for tag,
  sha512 for zip). Edited only by /setup-steward; bumping it is
  a deliberate project-level commit.
- .apache-steward.local.lock (gitignored) — what THIS machine
  actually fetched: source_method, source_url, source_ref,
  fetched_commit, fetched_at. Per-developer, per-checkout.

Drift detection

Every framework skill (and /setup-steward verify) compares the
local lock to the committed lock at the top of its run. On
mismatch:

- Method or URL differ → ✗ full re-install
- Ref differs (project bumped tag, or git-branch local is
  behind upstream) → ⚠ sync
- svn-zip SHA-512 differs from the committed anchor → ✗
  security-flagged; investigate before upgrading

The proposal is always /setup-steward upgrade. On user OK,
upgrade:

1. Deletes the gitignored snapshot outright.
2. Re-installs per the committed lock.
3. Refreshes gitignored framework-skill symlinks (adds new
   skills, removes renamed-away ones).
4. Reconciles agentic overrides against the new framework
   structure (surfaces conflicts; never auto-rewrites).
5. Updates the local lock.

Changes

- Rewrite setup-steward/SKILL.md, adopt.md, upgrade.md,
  verify.md to express the new model.
- New: docs/setup/install-recipes.md with the three
  copy-pasteable recipes + explanatory framing.
- README's Adopting the framework section split into
  Bootstrap (shell) + Skill takeover + Subsequent
  contributors + Drift detection.

Out of scope (follow-up): wire the drift check into each
framework skill's pre-flight section (alongside the
override-consultation hook from apache#39). 15 skills to touch;
mechanical, deferred to keep this PR focused on the
mechanism.

Generated-by: Claude Code (Claude Opus 4.7)
@potiuk
potiuk merged commit d58fec6 into apache:main May 4, 2026
7 checks passed
potiuk added a commit that referenced this pull request May 4, 2026
#41)

Mirror of #39's override-consultation hook for the new
drift-detection mechanism that landed in #40. Every framework
skill (excluding setup-steward, which IS the drift mechanism)
now declares a `## Snapshot drift` section right after its
`## Adopter overrides` section.

The standard block in every skill:

  ## Snapshot drift

  Also at the top of every run, this skill compares the
  gitignored `.apache-steward.local.lock` (per-machine
  fetch) against the committed `.apache-steward.lock` (the
  project pin). On mismatch the skill surfaces the gap and
  proposes [`/setup-steward upgrade`]. The proposal is
  non-blocking — the user may defer if they want to run with
  the local snapshot for now.

  Drift severity:
    - method or URL differ        → ✗ full re-install
    - ref differs                 → ⚠ sync needed
    - svn-zip SHA-512 mismatches  → ✗ security-flagged

15 skills updated:

  setup-isolated-setup-install         security-issue-import
  setup-isolated-setup-update          security-issue-import-from-md
  setup-isolated-setup-verify          security-issue-import-from-pr
  setup-shared-config-sync             security-issue-invalidate
                                        security-issue-sync
  pr-management-code-review            security-cve-allocate
  pr-management-stats                  security-issue-deduplicate
  pr-management-triage                 security-issue-fix

Skill not updated:

  setup-steward — IS the bootstrap + upgrade + verify +
  override-management skill; the drift check it would
  perform is the same one its `verify` sub-action exposes.

The hook is documented behaviour, not runtime injection. A
skill that has the `## Snapshot drift` section commits to
performing the check when invoked. Future tooling can enforce
mechanically; for now the convention is binding via the
published contract.

Generated-by: Claude Code (Claude Opus 4.7)
@andreahlert andreahlert added the mode:platform Substrate / infra — not a mode (sandbox, CI, validators) label May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mode:platform Substrate / infra — not a mode (sandbox, CI, validators)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants