Skip to content

Commit 81d985d

Browse files
authored
feat(skills): add upgrade-apache-steward skill + git submodule update guidance in AGENTS.md / README.md (#27)
Adds a fifth secure-config skill plus the missing post-pull submodule-update guidance for adopters who consume the framework as a tracker submodule. - `upgrade-apache-steward` skill: pulls the user's local `airflow-steward` checkout to `origin/main` with `--ff-only` after pre-flight checks. Refuses on a dirty working tree, on local commits ahead of upstream, and on a non-tracking branch. Surfaces the commits and the per-file change summary with explicit focus on the secure-setup blast radius (`.claude/settings.json`, `tools/agent-isolation/`, the two setup docs, `pinned-versions.toml`). Hands off to `update-secure-config` for the user-side drift report and reminds the user to handle the parent-tracker submodule pointer when the framework is consumed as a submodule. - `update-secure-config`: framework-behind branch now cross-references `upgrade-apache-steward` instead of just printing the bare `git pull` command — the new skill wraps the same operation in the right pre-flight checks plus the submodule-pointer reminder. - `secure-agent-setup.md` Quick start: agent-guided list grows from four to five skills and explicitly names the upgrade / drift-report split (run `/upgrade-apache-steward` to advance the framework, then `/update-secure-config` to see what that did to the user-side install). - `AGENTS.md` Local setup: opens with the `git submodule update --init --recursive` rule for adopter trackers — plain `git pull` only advances the framework submodule pointer in the tracker's index, not the framework's working tree, and stale-submodule failures are silent. Names a one-line `.git/hooks/post-merge` so adopters can wire it in once. - `README.md` Adopting the framework: same submodule-update rule with the explicit post-merge hook recipe, plus a cross-reference to the new skill for upgrading the framework itself. Generated-by: Claude Code (Opus 4.7)
1 parent a9dbf6a commit 81d985d

5 files changed

Lines changed: 268 additions & 7 deletions

File tree

.claude/skills/update-secure-config/SKILL.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,12 @@ explicitly and stop.
112112
If something is out-of-date or has drifted, name the concrete
113113
follow-up:
114114

115-
- Framework checkout behind → user runs `git pull --ff-only` in
116-
their `airflow-steward` clone.
115+
- Framework checkout behind → run
116+
[`upgrade-apache-steward`](../upgrade-apache-steward/SKILL.md),
117+
which performs the `git pull --ff-only` after the same
118+
pre-flight checks this skill recommends, surfaces what
119+
arrived, and reminds the user to handle the parent-tracker
120+
submodule pointer if applicable.
117121
- Pinned-tool upgrade candidate worth adopting → manifest bump PR
118122
per [Bumping a pinned version](../../../secure-agent-setup.md#bumping-a-pinned-version).
119123
- User-scope script drift → re-`cp` from the framework checkout,
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
---
2+
name: upgrade-apache-steward
3+
description: |
4+
Pull the user's local `airflow-steward` framework checkout to the
5+
latest `origin/main` and surface what changed — the commits
6+
pulled, the files touched (with focus on the secure-setup blast
7+
radius: `.claude/settings.json`, `tools/agent-isolation/`,
8+
`secure-agent-setup.md`, `secure-agent-internals.md`,
9+
`pinned-versions.toml`), and the next-step recommendation. Never
10+
applies user-side propagation itself — that is the job of
11+
`update-secure-config` (drift report) and the framework
12+
maintainer's manual re-`cp` of any user-scope script copies that
13+
drifted. Refuses to act if the working tree is dirty or the
14+
branch has unpushed commits, since both states are signs the
15+
user has work in flight that a `git pull` could clobber.
16+
when_to_use: |
17+
Invoke when the user says "upgrade apache-steward", "pull the
18+
framework to latest", "bring my airflow-steward clone up to
19+
date", or after Claude Code surfaces something new from the
20+
framework's release notes. Also appropriate as the entry point
21+
to a periodic update routine — recommended cadence per
22+
secure-agent-setup.md is once per Claude Code upgrade or once
23+
a month, whichever comes first; this skill is the *first* step
24+
of that routine, with `update-secure-config` (read-only drift
25+
report) and any subsequent re-`cp` / `/sync-shared-config` runs
26+
following on. Do **not** invoke when the user has uncommitted
27+
changes in the framework checkout or when they have local
28+
commits ahead of origin — the skill will refuse and surface
29+
the state.
30+
---
31+
32+
<!-- Placeholder convention (see AGENTS.md#placeholder-convention-used-in-skill-files):
33+
<project-config> → adopting project's `.apache-steward/` directory -->
34+
35+
# upgrade-apache-steward
36+
37+
This skill is the **upstream** half of the framework's update flow.
38+
It moves the user's local `airflow-steward` checkout forward to
39+
`origin/main` and reports what arrived. The downstream half — what
40+
this upgrade means for the user's *installed* secure setup
41+
(user-scope script copies, project `.claude/settings.json`, pinned
42+
tool versions on the host) — is the
43+
[`update-secure-config`](../update-secure-config/SKILL.md) skill,
44+
which is read-only and runs naturally as the next step.
45+
46+
## Golden rules
47+
48+
- **Refuse on a dirty working tree.** If `git status --short` in
49+
the framework checkout reports any modified, staged, or
50+
conflicted files, surface them and stop. A `git pull` on top of
51+
uncommitted edits is one of the quickest ways to lose work; the
52+
user is in flight on something and needs to commit / stash it
53+
themselves before any pull. Do not auto-stash.
54+
- **Refuse on local commits ahead of `origin/main`.** Adopters
55+
generally consume `airflow-steward` as a read-only checkout —
56+
modifications happen via PRs that land on `main` upstream, then
57+
the user's checkout is `git pull`ed. If the user has commits
58+
ahead of `origin/main`, that is either (a) work in progress for
59+
a PR they have not pushed, or (b) a local fork they are
60+
maintaining. Both cases need explicit user direction; the skill
61+
does not assume.
62+
- **`--ff-only` only.** Use `git pull --ff-only`. Never
63+
`--rebase`, never a merge commit. The skill is for the simple
64+
case where the user's checkout is strictly behind upstream;
65+
anything else is the user's call. If the fast-forward fails
66+
(history diverged), surface and stop.
67+
- **Show what arrived.** After a successful pull, surface the
68+
commit list and a per-file change summary, with explicit focus
69+
on the secure-setup blast radius (`.claude/settings.json`,
70+
`tools/agent-isolation/`, `secure-agent-setup.md`,
71+
`secure-agent-internals.md`,
72+
`tools/agent-isolation/pinned-versions.toml`). The user should
73+
walk away knowing whether this upgrade has user-side
74+
follow-through to do.
75+
- **Do not propagate to user-scope.** This skill ends at the
76+
framework checkout. It does not re-`cp` `claude-iso.sh`,
77+
`sandbox-bypass-warn.sh`, or `sandbox-status-line.sh` into
78+
`~/.claude/`. It does not edit any project's
79+
`.claude/settings.json`. It does not bump installed tool
80+
versions on the host. All of those are surfaced by the
81+
follow-on `update-secure-config` skill, which is read-only by
82+
design — the user decides what to apply.
83+
84+
## Walk-through
85+
86+
1. **Locate the framework checkout.** Confirm with the user the
87+
path to their local `airflow-steward` clone. If they don't
88+
have one, surface that and stop — they need to `git clone`
89+
first.
90+
91+
2. **Pre-flight checks.**
92+
- `git -C <path> status --short` — must be empty. If not, list
93+
the modified files and stop.
94+
- `git -C <path> rev-parse --abbrev-ref HEAD` — must be `main`
95+
(or the local equivalent that tracks `origin/main`). If not,
96+
name the branch and stop; the user is on a feature branch
97+
and a pull would be the wrong action.
98+
- `git -C <path> rev-list --count @{u}..HEAD` — must be `0`.
99+
If not, surface the local commits and stop.
100+
101+
3. **Fetch + diff against upstream.**
102+
- `git -C <path> fetch origin` (always, even if behind).
103+
- `git -C <path> rev-list --count HEAD..@{u}` — if `0`, the
104+
checkout is already up to date; report and stop.
105+
- Otherwise, list the commits that will land:
106+
`git -C <path> log --oneline HEAD..@{u}`.
107+
- List per-file changes with secure-setup focus:
108+
`git -C <path> diff --name-status HEAD..@{u}` — call out
109+
entries under `.claude/settings.json`,
110+
`tools/agent-isolation/**`, `secure-agent-setup.md`,
111+
`secure-agent-internals.md`, `pinned-versions.toml` if they
112+
appear.
113+
114+
4. **Confirm with the user before pulling.** Show the commits
115+
and the file-touch summary, then ask for explicit OK. The
116+
skill does not auto-pull on a "looks routine" judgement —
117+
even a doc-only upgrade can move anchors that the user's
118+
bookmarks or scripts depend on.
119+
120+
5. **Pull.** `git -C <path> pull --ff-only`. If the fast-forward
121+
fails for any reason, surface the error and stop.
122+
123+
6. **Post-pull report.** Confirm the new HEAD SHA matches
124+
`origin/main`. Re-print the commit list (now landed) and the
125+
file-touch summary with the secure-setup focus.
126+
127+
7. **Hand off to follow-up actions.** Always finish by naming
128+
the next-step skills the user is likely to want, with explicit
129+
conditions:
130+
131+
- **If the framework checkout is a submodule of an adopter
132+
tracker repo** (the path is
133+
`<adopter-tracker>/.apache-steward/apache-steward/`), remind
134+
the user that **the parent tracker now has a stale submodule
135+
pointer**. Pulling the framework standalone moved the
136+
framework's `HEAD`, but the parent tracker's index still
137+
records the previous SHA. The user has two options: (a)
138+
commit the new pointer in the parent tracker
139+
(`git -C <tracker> add .apache-steward/apache-steward && git
140+
commit -m "Bump apache-steward submodule"`), or (b) revert
141+
the framework checkout to the SHA the parent tracker pins.
142+
Option (a) is the usual path. Either way, a follow-up
143+
`git -C <tracker> submodule update --init --recursive` on
144+
any other clone of the tracker is what makes that clone see
145+
the new framework. Mention the post-merge hook documented in
146+
`README.md → Adopting the framework` for users who want this
147+
automatic.
148+
149+
- **Always after a successful pull**, recommend
150+
[`update-secure-config`](../update-secure-config/SKILL.md)
151+
to surface user-side drift the upgrade may have introduced
152+
(new `permissions.deny` patterns the user's tracker repo
153+
hasn't picked up, drift between user-scope `~/.claude/`
154+
copies and the just-updated framework source-of-truth, a
155+
pinned-tool version bump that warrants a host-side
156+
`npm install` / `apt-get install`).
157+
158+
- **If `tools/agent-isolation/*.sh` files changed in the
159+
pulled commits AND the user maintains a `~/.claude-config`
160+
sync repo with copies of those scripts**, recommend
161+
re-`cp`'ing the updated framework scripts over the
162+
`~/.claude-config/scripts/` (or
163+
`~/.claude/agent-isolation/`) copies and then running
164+
[`sync-shared-config`](../sync-shared-config/SKILL.md) to
165+
push the propagated changes to the sync remote so other
166+
machines pick them up.
167+
168+
- **If `pinned-versions.toml` changed**, name the specific
169+
tool(s) bumped and remind the user that the host install
170+
commands in `secure-agent-setup.md → Required tools` may
171+
now reference newer versions; the user runs the `apt-get`
172+
/ `dnf` / `npm install` themselves (the skill does not
173+
touch system tools).
174+
175+
- **If `.claude/settings.json` changed**, name the kinds of
176+
changes (new `denyRead`, new `allowedDomains`, new
177+
`permissions.ask` entry) and remind the user that adopter
178+
tracker repos copying the framework's settings will need a
179+
manual merge — the skill does not auto-merge into adopter
180+
repos.
181+
182+
## What this skill is NOT for
183+
184+
- Not for upgrading a tracker repo (the user's own private
185+
repo where they consume the framework). Tracker-repo updates
186+
are normal `git pull` operations the user does themselves.
187+
- Not for upgrading installed tools (`bubblewrap`, `socat`,
188+
`claude-code`). Those bumps happen on the host via the
189+
package manager, surfaced by `check-tool-updates.sh` and
190+
approved per the
191+
[Bumping a pinned version](../../../secure-agent-setup.md#bumping-a-pinned-version)
192+
flow.
193+
- Not for syncing user-scope edits to `~/.claude-config`. That
194+
is `sync-shared-config`'s job.
195+
196+
## Failure modes
197+
198+
- **Working tree dirty.** Stop. Surface `git status` output. The
199+
user commits / stashes themselves before re-invoking.
200+
- **Local commits ahead of upstream.** Stop. Surface the commit
201+
list. The user pushes their PR / decides what to do, then
202+
re-invokes.
203+
- **Not on `main` (or tracking branch).** Stop. Surface the
204+
current branch. The user switches branches themselves.
205+
- **`fetch` fails.** Network or auth issue. Stop and surface.
206+
The skill does not retry.
207+
- **`pull --ff-only` fails (diverged history).** This means
208+
someone force-pushed `main` upstream, or the user's local
209+
`main` has untracked commits. Stop and surface. The user
210+
resolves themselves; the skill never `--force`-pulls or
211+
resets.

AGENTS.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,14 +309,31 @@ projects is a config change, not a code change.
309309

310310
## Local setup
311311

312+
**Always run `git submodule update --init --recursive` after pulling
313+
the adopter tracker repository.** The framework lives at
314+
`<adopter-tracker>/.apache-steward/apache-steward/` as a git
315+
submodule (see [Repository purpose](#repository-purpose) above);
316+
plain `git pull` on the tracker advances the submodule *pointer*
317+
in the tracker's index but does **not** update the working tree
318+
of the submodule itself. Skills then run against the previous
319+
version of the framework — same skill names, stale skill bodies —
320+
and the failure mode is silent. Make `git submodule update --init
321+
--recursive` part of muscle memory after every pull, or wire it
322+
into a post-merge hook (`.git/hooks/post-merge`
323+
`#!/bin/sh\nexec git submodule update --init --recursive`). Same
324+
rule applies to the framework's own
325+
[`upgrade-apache-steward`](.claude/skills/upgrade-apache-steward/SKILL.md)
326+
skill: when invoked from inside an adopter tracker, it reminds
327+
the user to follow up with submodule update on the parent.
328+
312329
**Run the agent in the credential-isolation setup.** The skills
313330
operate against pre-disclosure CVE content; running Claude Code (or
314331
another `SKILL.md`-aware agent) with default-permissive access to
315332
`~/`, env vars, and arbitrary network egress is a real exfiltration
316333
risk. See [`secure-agent-setup.md`](secure-agent-setup.md) for the
317334
layered defence the framework dogfoods (`.claude/settings.json`
318335
sandbox + tool permissions + clean-env wrapper, with system tools
319-
pinned at a 7-day upstream cooldown).
336+
pinned per-tool with a 7-day default upstream cooldown).
320337

321338
This repository uses [`prek`](https://github.com/j178/prek) (a fast, Rust-based drop-in
322339
replacement for `pre-commit`) to run pre-commit hooks that keep the documentation

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,3 +1114,26 @@ into `<project-config>/` in your tracker repo, fill in the TODO
11141114
placeholders, and point the framework's skills at it via the path
11151115
resolution documented in
11161116
[`AGENTS.md` — Placeholder convention](AGENTS.md#placeholder-convention-used-in-skill-files).
1117+
1118+
**Always run `git submodule update --init --recursive` after every
1119+
pull on the tracker repository.** A plain `git pull` on the tracker
1120+
advances the framework submodule *pointer* in the index but does
1121+
**not** update the framework's working tree — skills will run
1122+
against the version of the framework checked out on disk, which is
1123+
the *previous* version after any pull that bumped the submodule
1124+
pointer. Wire it into a post-merge hook to make it automatic:
1125+
1126+
```bash
1127+
# In the adopter tracker repo, one-time setup:
1128+
cat >.git/hooks/post-merge <<'SH'
1129+
#!/bin/sh
1130+
exec git submodule update --init --recursive
1131+
SH
1132+
chmod +x .git/hooks/post-merge
1133+
```
1134+
1135+
The framework's `upgrade-apache-steward` skill (in this repo's
1136+
[`.claude/skills/upgrade-apache-steward/SKILL.md`](.claude/skills/upgrade-apache-steward/SKILL.md))
1137+
upgrades the framework checkout itself; if the user is consuming
1138+
the framework as a tracker submodule, the skill reminds them to
1139+
follow up with submodule update on the parent tracker.

secure-agent-setup.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ each layer, see
8282
### Agent-guided (recommended)
8383

8484
If you have Claude Code installed and a clone of `airflow-steward`
85-
on the host, the framework ships four skills that walk every
85+
on the host, the framework ships five skills that walk every
8686
step interactively. Each surfaces sudo / shell-rc / settings-file
8787
changes for explicit approval before applying — nothing
8888
privilege-elevating runs without you saying so.
@@ -91,9 +91,14 @@ privilege-elevating runs without you saying so.
9191
1. Open Claude Code in your tracker repo (or any directory).
9292
2. Run /setup-secure-config — guided first-time install.
9393
3. Run /verify-secure-config — confirms ✓/✗/⚠ for every piece.
94-
4. Run /update-secure-config periodically (per Claude Code
95-
upgrade or once a month) to surface drift + upgrade
96-
candidates. Read-only — surfaces, never auto-applies.
94+
4. When you want to be on the framework's latest, run
95+
/upgrade-apache-steward — pulls your local airflow-steward
96+
checkout to origin/main with --ff-only, refuses to touch a
97+
dirty working tree, surfaces what arrived. Then run
98+
/update-secure-config to surface user-side drift the
99+
upgrade introduced (new permissions.deny entries,
100+
user-scope script copies older than the framework, pinned
101+
tool bumps that warrant a host install).
97102
5. Optional: if you maintain a private dotfile-style sync repo
98103
per
99104
[Syncing user-scope config across machines](#syncing-user-scope-config-across-machines),
@@ -104,6 +109,7 @@ privilege-elevating runs without you saying so.
104109
The skills are at
105110
[`.claude/skills/setup-secure-config/`](.claude/skills/setup-secure-config/SKILL.md),
106111
[`.claude/skills/verify-secure-config/`](.claude/skills/verify-secure-config/SKILL.md),
112+
[`.claude/skills/upgrade-apache-steward/`](.claude/skills/upgrade-apache-steward/SKILL.md),
107113
[`.claude/skills/update-secure-config/`](.claude/skills/update-secure-config/SKILL.md),
108114
[`.claude/skills/sync-shared-config/`](.claude/skills/sync-shared-config/SKILL.md).
109115
Each skill references back into the canonical sections of this

0 commit comments

Comments
 (0)