Skip to content

Commit e0dfd28

Browse files
committed
chore(skills): sync updating + updating-xport from canonical
The /updating umbrella's Phase 3 was read-only (just `pnpm run xport`) while Phase 4 claimed drift was already auto-bumped. It wasn't — locked rows would get flagged as drift but nothing would record why we held. This sync brings the canonical fix from socket-repo-template + socket-registry: Phase 3 classifies, Phase 4 invokes updating-xport which auto-bumps track-latest/major-gate version-pins and emits advisory notes for everything else. - updating/SKILL.md: synced from socket-registry canonical. - updating-xport/SKILL.md: new in this repo — synced from socket-registry canonical.
1 parent 5218f6e commit e0dfd28

2 files changed

Lines changed: 436 additions & 22 deletions

File tree

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
---
2+
name: updating-xport
3+
description: Acts on `xport.json` drift for repos that carry the xport lock-step manifest. Reads `pnpm run xport --json`, then for each row acts per-kind — auto-bump `version-pin` rows (low-risk mechanical updates), advisory-only for `file-fork` / `feature-parity` / `spec-conformance` / `lang-parity` (upstream semantics need human judgment). Invoked by the `updating` umbrella skill; can also be invoked standalone.
4+
user-invocable: true
5+
allowed-tools: Bash(pnpm:*), Bash(npm:*), Bash(git:*), Bash(node:*), Bash(rg:*), Bash(grep:*), Bash(find:*), Bash(ls:*), Bash(cat:*), Bash(head:*), Bash(tail:*), Bash(wc:*), Bash(diff:*), Read, Edit, Grep, Glob---
6+
7+
# updating-xport
8+
9+
<task>
10+
Act on drift findings in `xport.json`. Auto-apply mechanical version-pin bumps; surface everything else as advisory notes for human review. Commit each actioned row as its own atomic commit so the PR reviewer can accept/reject per-row.
11+
</task>
12+
13+
<context>
14+
**xport** is a cross-project lock-step manifest. Not every repo has one; this skill exits cleanly when `xport.json` is absent. See `xport.schema.json` (deployed via `socket-repo-template/sync-scaffolding.mjs`) for the five row kinds.
15+
16+
The harness at `scripts/xport.mts` emits JSON reports with `severity ∈ {ok, drift, error}` per row. This skill consumes that JSON.
17+
18+
**Per-kind action policy:**
19+
20+
| Kind | Drift signal | Action |
21+
|------|--------------|--------|
22+
| `version-pin` | Upstream commits on default ref since pinned SHA | **Auto-bump** per `upgrade_policy`: `track-latest` → advance to latest stable tag; `major-gate` → advance patch/minor only; `locked` → advisory only |
23+
| `file-fork` | Upstream file changed since `forked_at_sha` | **Advisory** — note in PR body; do NOT auto-merge (forks carry local deltas that need human review) |
24+
| `feature-parity` | Parity score below `criticality/10` floor | **Advisory** — note in PR body; human decides implement vs downgrade criticality |
25+
| `spec-conformance` | Spec submodule moved | **Advisory** — note in PR body; human decides whether to bump `spec_version` |
26+
| `lang-parity` | Port divergence / `rejected` anti-pattern reintroduced | **Advisory** — note in PR body; humans fix the port or update the manifest |
27+
28+
The common rule: **version-pin is mechanical** (safe to auto-apply with `track-latest`/`major-gate` policies); everything else is **advisory** (upstream semantics and local deltas matter, humans decide).
29+
</context>
30+
31+
<constraints>
32+
**Requirements:**
33+
- Start with clean working directory (check via `git status --porcelain`)
34+
- Run from repo root
35+
- Exit 0 cleanly if `xport.json` is absent (the repo doesn't use xport)
36+
- Conventional commit format: `chore(deps): bump <upstream> to <tag>`
37+
- Update `.gitmodules` version comments when submodule tags change (pattern: `# <name>-<version>` on the line above the submodule block)
38+
- Target stable releases only (filter `-rc`, `-alpha`, `-beta`, `-dev`, `-snapshot`, `-nightly`, `-preview`)
39+
40+
**Forbidden:**
41+
- Never auto-edit `file-fork`, `feature-parity`, `spec-conformance`, or `lang-parity` rows' tracked state
42+
- Never bump a `locked` version-pin without human approval
43+
- Never skip the tag-stability filter
44+
- Never use `npx`, `pnpm dlx`, `yarn dlx` — use `pnpm exec` or `pnpm run`
45+
46+
**CI mode** (`CI=true` or `GITHUB_ACTIONS`): skip per-row test validation (workflow validates at the end); emit advisory summary to `$GITHUB_OUTPUT` when present.
47+
48+
**Interactive mode** (default): validate each auto-bump with `pnpm test` before committing the next.
49+
</constraints>
50+
51+
<instructions>
52+
53+
## Phase 1 — Pre-flight
54+
55+
```bash
56+
test -f xport.json || { echo "no xport.json; skill n/a"; exit 0; }
57+
test -f xport.schema.json || { echo "xport.schema.json missing — malformed scaffolding"; exit 1; }
58+
test -f scripts/xport.mts || { echo "scripts/xport.mts missing — malformed scaffolding"; exit 1; }
59+
60+
git status --porcelain | grep -v '^??' && { echo "dirty tree; aborting"; exit 1; } || true
61+
62+
[ "$CI" = "true" ] || [ -n "$GITHUB_ACTIONS" ] && CI_MODE=true || CI_MODE=false
63+
```
64+
65+
## Phase 2 — Collect drift
66+
67+
```bash
68+
pnpm run xport --json > /tmp/xport-report.json
69+
```
70+
71+
Parse `reports[]` from the JSON. Split into:
72+
73+
- **auto** — rows where `severity == "drift"` AND `kind == "version-pin"` AND `upgrade_policy` ∈ `{ "track-latest", "major-gate" }`
74+
- **advisory** — everything else with `severity != "ok"`
75+
76+
If both lists empty: exit 0 with "no xport drift".
77+
78+
## Phase 3 — Auto-bump version-pin rows
79+
80+
For each row in **auto** list, in manifest declaration order:
81+
82+
**3a. Resolve the upstream submodule + fetch tags**
83+
84+
```bash
85+
SUBMODULE=$(jq -r --arg a "$UPSTREAM_ALIAS" '.upstreams[$a].submodule' xport.json)
86+
cd "$SUBMODULE"
87+
git fetch origin --tags --quiet
88+
OLD_SHA=$(git rev-parse HEAD)
89+
```
90+
91+
**3b. Find the target tag**
92+
93+
Examine existing `pinned_tag` to identify the tag scheme, then match:
94+
95+
- `v1.2.3` (v-prefixed semver)
96+
- `1.2.3` (bare semver)
97+
- `<prefix>-1.2.3` (project-prefixed)
98+
- `<prefix>_1_2_3` (underscore style; curl, liburing)
99+
100+
For `major-gate` policy: parse major version from `LATEST` vs current `pinned_tag`. If majors differ, skip — add to advisory with note "major bump needs human review".
101+
102+
**3c. Check out + capture new SHA**
103+
104+
```bash
105+
NEW_SHA_FOR_CHECK=$(git rev-parse "$LATEST")
106+
[ "$OLD_SHA" = "$NEW_SHA_FOR_CHECK" ] && { cd -; continue; }
107+
git checkout "$LATEST" --quiet
108+
NEW_SHA=$(git rev-parse HEAD)
109+
cd -
110+
```
111+
112+
**3d. Update `xport.json` + `.gitmodules`**
113+
114+
Use `jq` for structured edit:
115+
116+
```bash
117+
jq --arg id "$ROW_ID" --arg sha "$NEW_SHA" --arg tag "$LATEST" \
118+
'(.rows[] | select(.id == $id) | .pinned_sha) = $sha
119+
| (.rows[] | select(.id == $id) | .pinned_tag) = $tag' \
120+
xport.json > xport.json.tmp && mv xport.json.tmp xport.json
121+
```
122+
123+
Update `.gitmodules` version comment via Edit tool (NOT sed per CLAUDE.md) — replace `# <prefix>-<old>` with `# <prefix>-<new>` on the comment line above the submodule block.
124+
125+
**3e. Validate + commit**
126+
127+
```bash
128+
# Confirm xport harness accepts the new state
129+
pnpm run xport --json > /tmp/xport-post.json
130+
jq --arg id "$ROW_ID" '.reports[] | select(.id == $id) | .severity' /tmp/xport-post.json
131+
# expect "ok"
132+
133+
if [ "$CI_MODE" = "false" ]; then
134+
pnpm test || {
135+
echo "tests failed; rolling back $ROW_ID"
136+
git checkout xport.json .gitmodules "$SUBMODULE"
137+
continue
138+
}
139+
fi
140+
141+
git add xport.json .gitmodules "$SUBMODULE"
142+
git commit -m "chore(deps): bump $UPSTREAM_ALIAS to $LATEST"
143+
```
144+
145+
Record bumped row in summary accumulator.
146+
147+
## Phase 4 — Compose advisory notes
148+
149+
For each row in **advisory**, accumulate a markdown line:
150+
151+
```
152+
- **file-fork** `<id>`: `<local>` — <N> upstream commit(s) since <forked_at_sha[0:12]>. Review diff, cherry-pick if applicable, bump forked_at_sha.
153+
- **feature-parity** `<id>`: parity score <score> below floor <floor>. Implement or downgrade criticality with reason.
154+
- **spec-conformance** `<id>`: upstream spec repo moved. Review for breaking changes before bumping spec_version.
155+
- **lang-parity** `<id>`: <details from messages[]>.
156+
- **version-pin** `<id>`: major bump to <LATEST> — policy=major-gate requires human review.
157+
- **version-pin** `<id>`: upgrade_policy=locked — skipped.
158+
```
159+
160+
## Phase 5 — Report + emit
161+
162+
Final human-readable report to stdout:
163+
164+
```
165+
## updating-xport report
166+
167+
**Auto-bumped:** <N> row(s)
168+
<list>
169+
170+
**Advisory (human review):** <M> row(s)
171+
<list>
172+
```
173+
174+
In CI mode, emit the advisory block to `$GITHUB_OUTPUT` (base64-encoded) under key `xport-advisory` so the weekly-update workflow can include it in the PR body:
175+
176+
```bash
177+
if [ -n "$GITHUB_OUTPUT" ]; then
178+
echo "xport-advisory=$(printf '%s' "$ADVISORY" | base64 | tr -d '\n')" >> "$GITHUB_OUTPUT"
179+
fi
180+
```
181+
182+
Emit a HANDOFF block per `_shared/report-format.md`:
183+
184+
```
185+
=== HANDOFF: updating-xport ===
186+
Status: {pass|fail}
187+
Findings: {auto_bumped: N, advisory: M}
188+
Summary: {one-line description}
189+
=== END HANDOFF ===
190+
```
191+
192+
</instructions>
193+
194+
## Success Criteria
195+
196+
- All actionable `version-pin` rows bumped atomically (one commit per row)
197+
- Advisory rows collected for PR body / workflow output
198+
- No edits to non-version-pin row state
199+
- `pnpm run xport` exits 0 or 2 at end (never 1 — no schema errors introduced)
200+
- `.gitmodules` version comments synchronized with `pinned_tag`
201+
202+
## Commands
203+
204+
- `pnpm run xport --json` — drift report (consumed by this skill)
205+
- `jq` — parse + edit `xport.json` (structured JSON edits)
206+
- `git submodule status` — verify submodule state after bumps
207+
208+
## When to use
209+
210+
- Invoked by the `updating` umbrella skill (weekly-update workflow)
211+
- Standalone: `/updating-xport` when syncing just the xport manifest
212+
- After manual submodule bumps, to refresh `xport.json` metadata

0 commit comments

Comments
 (0)