Skip to content

Commit 2b4e80b

Browse files
Add 'validate-rebase-rules' skill
Signed-off-by: Roman Nikitenko <rnikiten@redhat.com> Generated-by: Cursor AI
1 parent a7b3c80 commit 2b4e80b

3 files changed

Lines changed: 324 additions & 0 deletions

File tree

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
name: validate-rebase-rules
3+
description: Validates that .rebase/ rules (replace, add, override) are still current against upstream VS Code. Generates a rebase-rules-validation.md report with mismatches and proposed fixes. Use when asked to check, validate, or audit rebase rules, or before a rebase.
4+
---
5+
6+
# Validate Rebase Rules
7+
8+
Check whether `.rebase/` rules are still applicable to the current upstream VS Code version and the current che-code branch. Produce a `rebase-rules-validation.md` report listing any problems found.
9+
10+
## Prerequisites
11+
12+
Ensure the `upstream-code` remote exists and is fetched:
13+
14+
```bash
15+
git remote get-url upstream-code || git remote add upstream-code https://github.com/microsoft/vscode
16+
git fetch upstream-code
17+
```
18+
19+
## Step 1 — Resolve versions from rebase.sh
20+
21+
Read `rebase.sh` and extract two variables:
22+
23+
- `CURRENT_UPSTREAM_VERSION` — e.g. `release/1.108`
24+
- `PREVIOUS_UPSTREAM_VERSION` — e.g. `release/1.104`
25+
26+
These are defined near the top of `rebase.sh` as shell variable assignments.
27+
28+
Use the upstream git ref `upstream-code/<version>` when fetching file content:
29+
30+
```bash
31+
git show upstream-code/<version>:<path>
32+
```
33+
34+
Where `<path>` is **without** the `code/` prefix (upstream stores VS Code sources at repo root).
35+
36+
## Step 2 — Validate `.rebase/replace/` rules
37+
38+
Each file under `.rebase/replace/` has the form `.rebase/replace/<code-path>.json` and contains a JSON array of `{ "from": "...", "by": "..." }` objects.
39+
40+
**Path mapping:**
41+
42+
| Context | Path |
43+
|---------|------|
44+
| Rule file | `.rebase/replace/<code-path>.json` |
45+
| Upstream file | `<code-path>` with leading `code/` stripped → use as path in `git show upstream-code/CURRENT_UPSTREAM_VERSION:<stripped-path>` |
46+
| che-code file | `<code-path>` in the current working tree |
47+
48+
**For each rule entry:**
49+
50+
1. **Check `from` in upstream.** Fetch the upstream file at `CURRENT_UPSTREAM_VERSION`. Verify the `from` string exists verbatim in that file content. Handle escape sequences in the JSON: `\n` → newline, `\t` → tab, `\\` → backslash. The actual file content must contain the **decoded** string.
51+
52+
2. **Check `by` in che-code.** Read the che-code file from the current working tree. Verify the decoded `by` string exists in it. Again, decode JSON escapes before matching.
53+
54+
3. **On mismatch — propose a fix.**
55+
- Fetch the same file at `PREVIOUS_UPSTREAM_VERSION`.
56+
- Compare the `PREVIOUS_UPSTREAM_VERSION` content with the `CURRENT_UPSTREAM_VERSION` content around the area where `from` was expected.
57+
- Identify what changed and propose the corrected `from` or `by` value.
58+
59+
**Important note on escape handling in replace rules:**
60+
The replace rules use a custom escaping convention (not standard JSON escapes). For example `\\\n` means literal newline, `\\\t` means literal tab. When reading the JSON with `jq -r`, these are automatically decoded to actual newline/tab characters. Always use `jq -r '.from'` and `jq -r '.by'` to get the real strings for comparison.
61+
62+
## Step 3 — Validate `.rebase/add/` rules
63+
64+
Files under `.rebase/add/` are JSON fragments that get **merged into** upstream files using jq: `jq -s '.[1] * .[0]' <add-file> <upstream-file>` — the add-rule values take priority for conflicting keys. By convention, add rules are intended for keys absent in upstream, so conflicts should not occur.
65+
66+
### 3a — Check upstream for conflicts
67+
68+
The purpose of `add` rules is to add keys that **do not exist** in upstream. If a key now exists in upstream, the rule may be redundant or causing a silent override.
69+
70+
**For each file in `.rebase/add/`:**
71+
72+
1. Identify the upstream file path (strip `code/` prefix).
73+
2. Read the add rule JSON.
74+
3. Fetch the upstream file at `CURRENT_UPSTREAM_VERSION`.
75+
4. For every leaf key/value in the add rule, check if that key exists in the upstream file:
76+
- **Key absent in upstream** → OK, the add rule is still needed.
77+
- **Key exists with the same value** → WARNING: add rule is redundant, upstream already has this value. Consider removing it.
78+
- **Key exists with a different value** → WARNING: the add rule silently overrides the upstream value. This is a potential conflict.
79+
- For version-like values (semver): if upstream version ≥ add-rule version → the add rule may be downgrading. Report as WARNING.
80+
- For non-version values: report the upstream value vs add-rule value for manual review.
81+
82+
### 3b — Check che-code for correct application
83+
84+
Verify that the add rule values are actually present in the current che-code working tree.
85+
86+
**For each file in `.rebase/add/`:**
87+
88+
1. Identify the corresponding che-code file (same path, e.g. `.rebase/add/code/package.json``code/package.json`).
89+
2. Read the che-code file from the working tree.
90+
3. Read the add rule JSON.
91+
4. For every leaf key/value in the add rule, verify it is present in the che-code file:
92+
- For flat key-value pairs, check exact key and value presence.
93+
- For nested objects (e.g. `dependencies`, `devDependencies`, `overrides`), check that each leaf key-value from the add rule appears in the corresponding section of the che-code file.
94+
5. If a value from the add rule is **not** found in the che-code file, report it as ERROR: rule was not applied or was overwritten.
95+
96+
**Note:** For `product.json` add rules, check nested arrays and objects similarly — verify each element/key is present.
97+
98+
## Step 4 — Validate `.rebase/override/` rules
99+
100+
Files under `.rebase/override/` are JSON fragments merged **over** upstream files using jq: `jq -s '.[0] * .[1]' <upstream-file> <override-file>` — override values take priority.
101+
102+
**For each file in `.rebase/override/`:**
103+
104+
1. Identify the upstream file path (strip `code/` prefix).
105+
2. Read the override rule JSON.
106+
3. Fetch the upstream file at `CURRENT_UPSTREAM_VERSION`.
107+
4. For every leaf key in the override rule:
108+
a. **Check key still exists in upstream.** If the key no longer exists in the upstream file at `CURRENT_UPSTREAM_VERSION`, report a warning: the override may be unnecessary or the upstream structure changed.
109+
b. **For version-like values (semver patterns like `^X.Y.Z`):** Compare the upstream value with the override value. Use semver logic:
110+
- If upstream version ≥ override version → report a warning (override may no longer be needed because upstream already meets or exceeds the required version).
111+
- If upstream version < override version → OK, override is still needed.
112+
c. **For non-version values:** If the upstream value already equals the override value, report a warning (override is redundant).
113+
114+
**Semver comparison guidance:**
115+
Strip leading `^`, `~`, `>=` etc. before comparing. Compare major.minor.patch numerically. For example, `^5.1.9` override vs `^5.1.0` upstream → upstream `5.1.0 < 5.1.9` → OK. But `^5.1.9` override vs `^5.2.0` upstream → upstream `5.2.0 > 5.1.9` → warn.
116+
117+
## Step 5 — Generate the report
118+
119+
Create `rebase-rules-validation.md` in the repository root. Only create this file if there are findings to report. If all rules are valid, inform the user and do not create the file.
120+
121+
### Report format
122+
123+
```markdown
124+
# Rebase Rules Validation Report
125+
126+
> Generated against upstream `<CURRENT_UPSTREAM_VERSION>` (previous: `<PREVIOUS_UPSTREAM_VERSION>`)
127+
128+
## Critical findings
129+
130+
<!-- Numbered list of the most important actionable items, e.g.: -->
131+
1. **Short description** — Why it matters and what to do.
132+
2. ...
133+
134+
---
135+
136+
## Replace Rules
137+
138+
| Rule file | Problematic value | Proposed fix |
139+
|-----------|-------------------|--------------|
140+
| `.rebase/replace/code/src/server-main.js.json` | `"from": "const product = ..."` not found in upstream | `"from": "const product = <new value>"` |
141+
142+
## Add Rules
143+
144+
| Rule file | Issue |
145+
|-----------|-------|
146+
| `.rebase/add/code/package.json` | Key `dependencies.ws` with value `8.2.3` not found in `code/package.json` |
147+
148+
## Override Rules
149+
150+
| Rule file | Key | Issue |
151+
|-----------|-----|-------|
152+
| `.rebase/override/code/extensions/npm/package.json` | `dependencies.minimatch` | Upstream already at `^5.2.0` which is ≥ override `^5.1.9` — override may be unnecessary |
153+
```
154+
155+
### Severity indicators
156+
157+
Use these prefixes in the Issue/Proposed fix column:
158+
159+
- **ERROR**`from` or `by` value not found; rule will fail during rebase
160+
- **WARNING** — override may be unnecessary or redundant
161+
- **INFO** — value changed but rule still works
162+
163+
## Workflow summary
164+
165+
1. Fetch upstream remote.
166+
2. Extract versions from `rebase.sh`.
167+
3. Enumerate all files under `.rebase/replace/`, `.rebase/add/`, `.rebase/override/`.
168+
4. For each rule, perform the checks described above.
169+
5. Collect all findings.
170+
6. Generate `rebase-rules-validation.md` if there are findings. Otherwise report success.
171+
172+
## Parallelization guidance
173+
174+
When checking rules, launch parallel subagents or batch operations where possible:
175+
176+
- All `.rebase/replace/` rule files can be checked independently.
177+
- All `.rebase/add/` rule files can be checked independently.
178+
- All `.rebase/override/` rule files can be checked independently.
179+
- Upstream file fetches (`git show`) can be batched.
180+
181+
## Missing file handling
182+
183+
Apply these rules across all steps when a target file cannot be found:
184+
185+
| File missing | Behavior |
186+
|--------------|----------|
187+
| **Upstream file not found** (`git show` fails) | Report as ERROR: the file was likely removed or renamed in VS Code. The entire rule file is suspect and should be reviewed. |
188+
| **Che-code file not found** in working tree | Report as ERROR: the file is missing. The rule targets a file that does not exist in che-code. |
189+
190+
## Edge cases
191+
192+
- Some replace rules use multiline `from`/`by` values with `\\\n` and `\\\t` escapes. Always decode before matching.
193+
- `code/package.json` can have both replace, add, and override rules simultaneously. Check each independently.
194+
- `product.json` uses tab indentation (see `override_json_file` call with `"tab"` parameter in `rebase.sh`).

0 commit comments

Comments
 (0)