From 46101a6df52d852fb60d2dd6aa3fe32f1dcc3b42 Mon Sep 17 00:00:00 2001 From: Daniel McIlvaney Date: Wed, 8 Jul 2026 14:27:28 -0700 Subject: [PATCH 1/4] docs(ai): move to new azldev emitted instructions and skills, add azldev mcp A new feature of azldev will emit instruction files and skills for using the tool. Update the instructions and skills to the new version. Once the feature is available in a stable release of azldev, a workflow will be added to ensure these instructions are kept fresh. --- .agents/skills/azldev-add-component/SKILL.md | 83 +++++ .../skills/azldev-build-component/SKILL.md | 60 ++++ .agents/skills/azldev-comp-toml/SKILL.md | 109 +++++++ .agents/skills/azldev-image/SKILL.md | 60 ++++ .agents/skills/azldev-mock/SKILL.md | 92 ++++++ .agents/skills/azldev-overlays/SKILL.md | 126 ++++++++ .../skills/azldev-remove-component/SKILL.md | 73 +++++ .../skills/azldev-update-component/SKILL.md | 70 +++++ .agents/skills/azldev/SKILL.md | 81 +++++ .../skills/skill-aks-health/SKILL.md | 0 .../skills/skill-deployment-context/SKILL.md | 0 .../skills/skill-koji-triage/SKILL.md | 0 .../skills/skill-kql-queries/SKILL.md | 0 .../skills/skill-mass-triage/SKILL.md | 4 +- .../skills/skill-metrics/SKILL.md | 0 .github/copilot-instructions.md | 2 +- .github/instructions/azldev.instructions.md | 15 + .../instructions/comp-toml.instructions.md | 290 +----------------- .../rendered-specs.instructions.md | 52 +--- .github/instructions/review.instructions.md | 10 + .github/instructions/spec.instructions.md | 4 +- .github/plugin/plugin.json | 6 +- .github/prompts/azl-add-component.prompt.md | 2 +- .github/prompts/azl-debug-component.prompt.md | 10 +- .../prompts/azl-remove-component.prompt.md | 2 +- .../prompts/azl-review-component.prompt.md | 4 +- .../prompts/azl-update-component.prompt.md | 4 +- .github/skills/skill-add-component/SKILL.md | 98 ------ .github/skills/skill-build-component/SKILL.md | 143 --------- .github/skills/skill-fix-overlay/SKILL.md | 77 ----- .github/skills/skill-mock/SKILL.md | 93 ------ .../skills/skill-remove-component/SKILL.md | 96 ------ .../skills/skill-review-component/SKILL.md | 73 ----- .../skills/skill-update-component/SKILL.md | 123 -------- .vscode/mcp.json | 150 ++++----- AGENTS.md | 42 +-- base/comps/AGENTS.md | 10 +- base/comps/exfatprogs/modify_source.sh | 2 +- docs/prds/agent-instructions.prd.md | 29 +- 39 files changed, 941 insertions(+), 1154 deletions(-) create mode 100644 .agents/skills/azldev-add-component/SKILL.md create mode 100644 .agents/skills/azldev-build-component/SKILL.md create mode 100644 .agents/skills/azldev-comp-toml/SKILL.md create mode 100644 .agents/skills/azldev-image/SKILL.md create mode 100644 .agents/skills/azldev-mock/SKILL.md create mode 100644 .agents/skills/azldev-overlays/SKILL.md create mode 100644 .agents/skills/azldev-remove-component/SKILL.md create mode 100644 .agents/skills/azldev-update-component/SKILL.md create mode 100644 .agents/skills/azldev/SKILL.md rename {.github => .agents}/skills/skill-aks-health/SKILL.md (100%) rename {.github => .agents}/skills/skill-deployment-context/SKILL.md (100%) rename {.github => .agents}/skills/skill-koji-triage/SKILL.md (100%) rename {.github => .agents}/skills/skill-kql-queries/SKILL.md (100%) rename {.github => .agents}/skills/skill-mass-triage/SKILL.md (98%) rename {.github => .agents}/skills/skill-metrics/SKILL.md (100%) create mode 100644 .github/instructions/azldev.instructions.md create mode 100644 .github/instructions/review.instructions.md delete mode 100644 .github/skills/skill-add-component/SKILL.md delete mode 100644 .github/skills/skill-build-component/SKILL.md delete mode 100644 .github/skills/skill-fix-overlay/SKILL.md delete mode 100644 .github/skills/skill-mock/SKILL.md delete mode 100644 .github/skills/skill-remove-component/SKILL.md delete mode 100644 .github/skills/skill-review-component/SKILL.md delete mode 100644 .github/skills/skill-update-component/SKILL.md diff --git a/.agents/skills/azldev-add-component/SKILL.md b/.agents/skills/azldev-add-component/SKILL.md new file mode 100644 index 00000000000..70a92017e42 --- /dev/null +++ b/.agents/skills/azldev-add-component/SKILL.md @@ -0,0 +1,83 @@ +--- +name: azldev-add-component +description: Read this before adding or importing a component; follow the workflow instead of guessing. Explains how to add a new component to an azldev distro, covering inspecting the upstream spec, the inline-versus-dedicated-file decision, and validating with render, diff-sources, and build. Triggers include add component, new package, import package, create comp.toml, new component. +--- + +# Add a component + +## Before you start + +Confirm the component does not already exist: + +```sh +azldev comp list -p -q -O json +``` + +### Inspect the upstream spec first + +The reliable way to see what you are importing (direct web fetches of upstream +dist-git often fail bot detection): + +1. Add a bare entry so azldev can resolve the component: run `azldev comp add ` + (it appends `[components.]` to the root config file), or hand-add + `[components.]` to an included config file if you want it to live elsewhere. + A bare root entry is *perfect* for initial testing, but real distros will usually + segment the configuration into included files. Once the initial pass is done, + ensure the component is in the right place and remove the root entry. + +2. Pull the sources without overlays into a scratch dir under the work dir: + + ```sh + azldev comp prep-sources -p --skip-overlays --force -o base/build/work/scratch/ -q + ``` + +3. Read the spec and plan any overlays. + +## Inline vs dedicated file + +- **Inline** — a bare upstream import with no changes stays in a shared config file: + + ```toml + [components.jq] + ``` + +- **Dedicated** — anything that needs overlays, build config, or a local spec gets its + own `/.comp.toml`. Rule of thumb: more than `[components.]` earns a + dedicated file. An `includes = ["**/*.comp.toml"]` glob picks it up automatically. + +`azldev comp add [...]` adds bare `[components.]` entries that inherit +the distro defaults; it writes to the **root** config file and does not scaffold spec or +source files. If your distro keeps components in included or dedicated files, move the +entry there afterward. + +## Customize + +For spec source types and overlays, read the `azldev-comp-toml` and `azldev-overlays` skills. Key +points when adding a component: + +- Prefer **overlays** over forking the spec — overlays get upstream updates for free. + Forking a spec is a last resort and a long-term maintenance commitment. Get explicit + user sign-off first, document every change, and keep the delta minimal. +- Every overlay needs a `description` explaining why it is needed. +- Keep `%check` enabled. Disable it only as a last resort via `build.check.skip = true` + with a required `build.check.skip_reason` (see the `azldev-build-component` skill). + +## Validate + +A new upstream component has no lock yet, and `render`, `diff-sources`, and `build` all +resolve it first — which fails lock validation until the lock exists. Create the lock, +then validate: + +```sh +azldev comp update -p # resolve the upstream commit and write the lock +azldev comp render -p # apply overlays and write the rendered spec +azldev comp diff-sources -p # see exactly what the overlays change +azldev comp build -p # build the RPMs +``` + +Inspect the rendered spec under `specs/`. A new component always needs a +smoke test — see the `azldev-build-component` and `azldev-mock` skills. After committing, +re-run `azldev comp update -p ` to finalize the lock before a PR (see the +`azldev-update-component` skill). + +Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-build-component/SKILL.md b/.agents/skills/azldev-build-component/SKILL.md new file mode 100644 index 00000000000..115ce8bd85b --- /dev/null +++ b/.agents/skills/azldev-build-component/SKILL.md @@ -0,0 +1,60 @@ +--- +name: azldev-build-component +description: Read this before building a component or diagnosing a build failure; do not guess build flags or the inner loop. Explains how to build, iterate on, and debug an azldev component, covering comp build flags (local-repo, preserve-buildenv), the render/build/test inner loop, diff-sources, and disabling a failing %check via check.skip. Triggers include build component, build failed, build error, inner loop, preserve buildenv, local repo, disable check. +--- + +# Build and debug a component + +**Never install built RPMs on your host** — they target the distro, not your dev +machine. Test them in a chroot with the `azldev-mock` skill. Building and testing are separate +steps: `azldev comp build` produces RPMs; it does not test them. + +## Build + +```sh +azldev comp build -p # one component +azldev comp build -p -p --local-repo-with-publish # chain deps via a local repo +azldev comp build -p --local-repo # rebuild against a populated repo +``` + +Build foundational packages before their dependents. RPMs land in the project's +configured output directory (`out` by default). `-q` quiets output but hides build +progress — use it only for inner-loop builds you expect to succeed. + +## The inner loop + +investigate → modify → render → build → test → inspect + +| Step | Command | +| --- | --- | +| Investigate | read the rendered spec under `specs/`, or `azldev comp diff-sources -p ` | +| Modify | edit the component's `.comp.toml` (see the `azldev-overlays` and `azldev-comp-toml` skills) | +| Verify | `azldev comp render -p ` (fast — skips source tarballs) | +| Build | `azldev comp build -p ` | +| Test | `azldev adv mock shell --add-package ` (see the `azldev-mock` skill) | +| Inspect | `azldev comp build -p --preserve-buildenv always`, then a mock shell | + +Prefer `comp render` for quick overlay verification; use `comp diff-sources` to see the +exact overlay effect (it fetches sources once, applies overlays to a copy, and diffs the +two trees). Builds can be slow — set generous timeouts. + +Finalize with `azldev comp update -p ` before opening a PR (see the +`azldev-update-component` skill). + +## Debugging build failures + +1. **Render error mentioning a non-standard `Release` tag** — a release-calculation + issue; see the `azldev-comp-toml` skill. +2. **Overlay did not apply as expected** — `azldev comp diff-sources -p ` shows + what the overlays actually change. +3. **Inspect the build environment** — `azldev comp build -p --preserve-buildenv + on-failure` (values `on-failure`, `always`, `never`), then enter a mock shell. +4. **Failing `%check`** — fix the tests first (root cause, upstream patches, targeted + fixes). Only as a last resort, disable with `build.check.skip = true` and a required + `build.check.skip_reason` explaining what fails, why it cannot be fixed, and whether it + is temporary. A transient `--no-check` build flag exists for one-off local builds. + +Per-component build tweaks (`build.defines`, `build.without`) live in the `.comp.toml` — +see the `azldev-comp-toml` skill. + +Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-comp-toml/SKILL.md b/.agents/skills/azldev-comp-toml/SKILL.md new file mode 100644 index 00000000000..590715f1fc4 --- /dev/null +++ b/.agents/skills/azldev-comp-toml/SKILL.md @@ -0,0 +1,109 @@ +--- +name: azldev-comp-toml +description: Read this before authoring or editing a *.comp.toml file; do not hand-write component config from memory. Explains the azldev component definition format, covering the component structure, choosing a spec source (upstream, pinned upstream-distro, upstream-name, or local), build config (defines/with/without), release calculation modes (auto/autorelease/static/manual), render options, and file organization (inline versus dedicated files and includes). Triggers include comp.toml, component config, spec source, upstream-distro, build defines, release calculation, includes. +--- + +# Component definition files (`*.comp.toml`) + +A component definition tells azldev where a package's spec comes from and how to +customize it for your distro. Every component lives under `[components.]`. + +Get the authoritative, always-current field list from the schema: + +```sh +azldev config generate-schema +``` + +## Structure + +A bare entry inherits everything from your distro's defaults — most upstream packages +need nothing more: + +```toml +[components.curl] +``` + +Add sub-tables only for what you change. The fields you will reach for most: + +| Field | Purpose | +| --- | --- | +| `spec` | where the spec comes from (see below) | +| `overlays` / `overlay-files` | targeted spec/source edits (see the `azldev-overlays` skill) | +| `build.defines` / `build.with` / `build.without` | RPM macro and bcond build tweaks | +| `release.calculation` | how the `Release` tag is managed | +| `render.skip-file-filter` | rendering edge-case escape hatch | + +## Spec source + +The `spec` field selects where the spec is fetched from. When omitted, the component +inherits the distro default (normally an upstream import). + +```toml +# Upstream import (the usual case) — inherits the distro's upstream version +[components.curl] + +# Upstream, but pinned to a specific upstream distro/version +[components.curl] +spec = { type = "upstream", upstream-distro = { name = "fedora", version = "rawhide" } } + +# Upstream package whose name differs from the component name +[components.mydistro-rpm-config] +spec = { type = "upstream", upstream-name = "redhat-rpm-config" } + +# Local spec that lives in your repo (not imported from an upstream distro) +[components.mydistro-release] +spec = { type = "local", path = "mydistro-release.spec" } +``` + +## Build configuration + +```toml +[components.mypackage.build] +defines = { rhel = "11" } # override RPM macros +with = ["feature_x"] # enable %bcond_with conditionals +without = ["plugin_rhsm"] # disable %bcond_with conditionals +``` + +## Release calculation + +`release.calculation` controls the `Release:` tag. There are four modes: + +- `auto` (default) — auto-detect whether the spec uses `%autorelease` or a static + release and handle it accordingly. Correct for most packages. +- `autorelease` — force `%autorelease` handling (use when auto-detection misreads a + spec that wraps `%autorelease` in a conditional). +- `static` — force static-integer handling and bump the integer on render (the + inverse of `autorelease`). +- `manual` — you own the `Release:` value. Use this only when render fails with a + "non-standard Release tag" error. **A `manual` component is not bumped by the + render/commit/amend cycle, so increment its release yourself in the same change** + (see the `azldev-update-component` skill). + +```toml +[components.mypackage.release] +calculation = "manual" +``` + +## Render configuration + +`render.skip-file-filter = true` keeps all source and patch files during render. +azldev normally prunes files not referenced by the rendered spec; set this only for +the rare spec whose `Source`/`Patch` filenames use macros the filter cannot expand. + +## File organization + +- **Inline** — put simple, customization-free components directly in a shared config + file (e.g. `[components.jq]`). +- **Dedicated** — give a component its own `/.comp.toml` once it needs + overlays, build config, or a local spec. Rule of thumb: anything more than + `[components.]` earns a dedicated file. +- A parent config picks up dedicated files through an `includes` glob, for example + `includes = ["**/*.comp.toml"]`. + +## Documenting changes + +Add a TOML comment explaining *why* a non-obvious field is set (a version pin, a +workaround), and link the upstream commit or bug when the change is based on one. For +overlays, use the overlay `metadata` table instead (see the `azldev-overlays` skill). + +Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-image/SKILL.md b/.agents/skills/azldev-image/SKILL.md new file mode 100644 index 00000000000..0edd5b5393c --- /dev/null +++ b/.agents/skills/azldev-image/SKILL.md @@ -0,0 +1,60 @@ +--- +name: azldev-image +description: Read this before building, booting, or configuring an azldev image. Explains the azldev image commands (list, build, boot, test, customize) and the [images.] config (kiwi definition, capabilities, tests, publish); the kiwi XML format itself is upstream KIWI NG. Triggers include image build, image boot, kiwi, container image, VM image, images.toml. +--- + +# Build and boot images + +An image assembles built RPMs into a deliverable — a container or a bootable VM. +azldev drives the build from a kiwi-ng definition; the `.kiwi` file itself is +**upstream KIWI NG** ([docs](https://osinside.github.io/kiwi/)) and azldev does not +own its schema. + +## Commands + +Images are selected by their **name as a positional argument** (not `-p`). + +| Task | Command | +| --- | --- | +| List images | `azldev image list` | +| Build an image (kiwi-ng) | `azldev image build ` | +| Boot an image in a QEMU VM | `azldev image boot ` | +| Run an image's tests | `azldev image test ` | +| Customize a pre-built image | `azldev image customize` | + +`azldev image build` takes `--local-repo` / `--remote-repo` to add package sources and +`--arch` to target an architecture. `azldev image boot` takes a built image name, or an +explicit `--image-path` / `--iso`. Confirm current flags with +`azldev image --help` (there are more subcommands, e.g. `inject-files`). + +## Registering an image + +Images are declared under `[images.]` (conventionally in an `images.toml`): + +```toml +[images.container-base] +description = "Container base image" +definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "core" } + + [images.container-base.capabilities] + container = true + systemd = false + + [images.container-base.tests] + test-suites = ["smoke"] +``` + +- `definition.type` is `kiwi` (the only type today); `path` points at the `.kiwi` file; + `profile` selects a kiwi profile (optional). +- `capabilities` are tri-state flags describing the image — `machine-bootable`, + `container`, `systemd`, `runtime-package-management`. Set only the ones that apply. +- `tests.test-suites` lists the test suites `azldev image test` runs. +- `publish.channels` lists the channels the image publishes to. + +## The kiwi definition + +The `.kiwi` file is upstream KIWI NG XML — azldev does not own its schema. It selects the +image type (container vs. VM), package lists, repositories, and boot configuration. See +the [KIWI NG documentation](https://osinside.github.io/kiwi/) for the format and elements. + +Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-mock/SKILL.md b/.agents/skills/azldev-mock/SKILL.md new file mode 100644 index 00000000000..55c1377d753 --- /dev/null +++ b/.agents/skills/azldev-mock/SKILL.md @@ -0,0 +1,92 @@ +--- +name: azldev-mock +description: Read this before testing or inspecting a built RPM; do not drive mock by hand from memory. Explains how to test and inspect built packages in a mock chroot with 'azldev adv mock shell', covering non-interactive (heredoc) and interactive chroot workflows, the -p/--add-package flag, and resetting stale chroot state. Triggers include test package, mock shell, inspect rpm, smoke test, chroot, verify build output. +--- + +# Test and inspect packages in a mock chroot + +> **Never install built RPMs on the host.** They target the distro you are +> building, not your dev machine. Use a mock chroot instead. + +azldev tests and inspects packages inside `mock` build roots via `mock shell`, +which lives under the hidden `advanced` group (`azldev adv` is an alias for +`azldev advanced`; it does not appear in `azldev --help`). + +## Non-interactive chroot (preferred for agents) + +Pipe commands in via a heredoc — fully autonomous, no user interaction needed: + +```sh +azldev adv mock shell --add-package /path/to/package.rpm <<'CMDS' + --version +echo "exit code: $?" +exit +CMDS +``` + +Use this for automated checks: running binaries, querying installed packages, +inspecting paths. + +## Inspect an RPM without installing it + +When `--add-package` fails to install, or you just want to look at an RPM's +contents, get the file inside the chroot and inspect it there rather than +installing on the host. If the RPM is not already reachable inside the build +root, copy it in first with `mock --copyin /tmp/` (using the project's +distro mock config), then: + +```sh +azldev adv mock shell <<'CMDS' +rpm -qip /tmp/*.rpm # package info +rpm -qlp /tmp/*.rpm # file list +rpm -qRp /tmp/*.rpm # dependencies +dnf install /tmp/*.rpm # retry the install to see the error details +exit +CMDS +``` + +This gives you the full distro environment for debugging dependency issues, file +conflicts, and failed installs, without touching the host. + +## Interactive chroot + +Use when you need to explore interactively or react to output between commands: + +```sh +azldev adv mock shell --add-package /path/to/package.rpm --enable-network +``` + +When driving an interactive shell as an agent: + +1. Run a simple command (e.g. `echo ready`) in a foreground terminal to establish a shared shell. +2. Ask the user to run the `azldev adv mock shell` command in that same terminal. +3. Wait for confirmation that they are inside the mock shell. +4. Run diagnostic commands in the same foreground terminal — they execute inside the chroot. +5. Run `exit` to leave the chroot. + +Prefer the non-interactive heredoc approach; use interactive only when you must +react to output between commands. + +## Key flags + +| Flag | Purpose | +| --- | --- | +| `-p`, `--add-package ` | Install a package into the chroot before entering. Accepts an RPM file path or a package name. May be repeated. | +| `--enable-network` | Allow network access (dependency resolution, downloads). | + +> **`-p` means `--add-package`, not a component name.** Unlike `azldev comp build -p `, +> `mock shell` has no component selector. `-p ` installs a package *by name* from the +> configured repos — it does not set up a chroot with that component's build dependencies. + +## Gotchas + +- **Don't mix `-p ` with `--add-package /path/to/.rpm` for the same package** — that + installs both the repo build and your local build, which conflict. Use one or the other. +- **The mock chroot is persistent** across `azldev adv mock shell` sessions — installed packages and + created files survive. Handy (install once, re-enter later), but stale state can confuse. azldev + has no built-in reset; clear it with `mock` directly (`--scrub=chroot`, or `--scrub=all` to also + drop the bootstrap), pointing at the project's distro mock config. +- **One mock session per terminal.** Running `azldev adv mock shell` while a terminal is already + inside a mock shell fails — run `exit` first. + +Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-overlays/SKILL.md b/.agents/skills/azldev-overlays/SKILL.md new file mode 100644 index 00000000000..374a620e3a5 --- /dev/null +++ b/.agents/skills/azldev-overlays/SKILL.md @@ -0,0 +1,126 @@ +--- +name: azldev-overlays +description: Read this before adding or changing any overlay; never edit a spec or rendered file from memory. Explains how to modify a component's RPM spec or loose source files with azldev overlays (semantic patches applied at render time) instead of forking the spec, covering choosing the overlay type, required fields, the render-and-inspect loop, common pitfalls, and metadata categories. Triggers include overlay, spec-add-tag, patch-add, fix spec, backport, disable test, prune subpackage, edit spec. +--- + +# Working with overlays + +Overlays are **semantic patches** applied to a component's RPM spec and loose +source files at render time. They let you make targeted changes to an upstream +spec without forking it. Prefer an overlay over hand-editing a rendered spec: +overlays are re-applied on every render, so a manual edit to a rendered spec is +overwritten. + +## The inner loop + +Overlays live in the component's TOML config — inline `[[components..overlays]]` +entries, or per-file overlay documents referenced by the component's `overlay-files` +glob. They apply **in order** and are **non-atomic**: if one fails part-way, the +overlays before it stay applied. + +1. Add or edit the overlay in the component config. +2. Re-render and inspect the result: + + ```sh + azldev comp render -p + ``` + + Read the rendered spec (under `specs/`) to confirm the change + landed where you intended, and iterate until it is correct. +3. Finalize the lock and changelog with the normal end-of-work refresh (see the + `azldev-update-component` skill): update the lock, commit, then re-render and amend. + +Config errors reference the offending overlay by its `description`, so give every +overlay a short, specific `description`. + +## Choosing an overlay type + +Match the change to the narrowest overlay type. Required fields are enforced when +the config loads, so a missing field fails fast rather than at apply time. + +### Spec overlays (structured `.spec` edits) + +| Type | Use for | Required | +| --- | --- | --- | +| `spec-add-tag` | add a tag; fails if it already exists | `tag`, `value` | +| `spec-insert-tag` | add a tag next to its family (e.g. after the last `Source*`) | `tag`, `value` | +| `spec-set-tag` | set a tag, replacing it if present or adding it if not | `tag`, `value` | +| `spec-update-tag` | change an existing tag; fails if it is missing | `tag`, `value` | +| `spec-remove-tag` | delete a tag; fails if it is missing | `tag` | +| `spec-prepend-lines` | insert lines at the top of a section (or the whole file) | `lines` | +| `spec-append-lines` | insert lines at the end of a section (or the whole file) | `lines` | +| `spec-search-replace` | regex replace within a section (or the whole spec) | `regex` | +| `spec-remove-section` | delete a whole section | `section` | +| `spec-remove-subpackage` | delete every section of a sub-package | `package` | +| `patch-add` | add a `.patch` file and register it in the spec | `source` | +| `patch-remove` | remove a patch and its spec references | `file` | + +### File overlays (loose non-spec files; never `.spec`) + +| Type | Use for | Required | +| --- | --- | --- | +| `file-prepend-lines` | prepend lines to a file | `file`, `lines` | +| `file-search-replace` | regex replace in a file | `file`, `regex` | +| `file-add` | copy in a new file; fails if it already exists | `file`, `source` | +| `file-remove` | delete a file | `file` | +| `file-rename` | rename a file in place | `file`, `replacement` | + +## Rules that trip people up + +- **`section` is optional only** for `spec-prepend-lines`, `spec-append-lines`, and + `spec-search-replace` (omit it to target the whole spec). It is **required** for + `spec-remove-section`. +- **`package` needs `section`** on the whole-file-capable overlays — a sub-package is + a sub-qualifier of a section. `spec-remove-subpackage` is the exception: it takes + `package` and rejects `section`. +- **`replacement` is literal** — `$1`-style capture-group references are not expanded; + omit it to delete matched text. +- **Quote `regex` as a TOML literal string** — write `regex = '\.so$'`, not + `regex = "\.so$"`. A basic (double-quoted) TOML string interprets backslash escapes, so + `\s`, `\.`, `\d` and friends are mangled before the regex engine ever sees them; single + quotes keep the pattern verbatim. +- **`spec-search-replace` matches one line at a time** — the pattern is applied to each + spec line independently, so it can never span a newline and `(?s)`/DOTALL does nothing. + For a multi-line change use a structured spec overlay (`spec-remove-section`, + `spec-prepend-lines`/`spec-append-lines`, etc.). `file-search-replace` is different: it + matches against the whole file, so multi-line patterns (and `(?s)`) work there. +- **`file` is a glob** (`**` supported) for the multi-file file overlays; for `file-add` + and `file-rename` it is a single name, and `file-rename`'s `replacement` is a + filename only (not a path). +- **`source` paths are relative** to the config that declares the overlay — the overlay + file when loaded via `overlay-files`, otherwise the component config. +- **`file-add` lands beside the spec**, in the dist-git sources root — not inside the + extracted upstream tree. Adding a file there does not make the build use it; wire it in + with a `SourceN` tag plus `%prep`/`%install` steps, or use `patch-add` to change tracked + sources. +- **Don't rename the `Name:` tag** with `spec-update-tag`/`spec-set-tag`. `%{name}` feeds + `Source*` URLs, `%setup -n`, and `%files` paths, so renaming it silently breaks those + references. Keep the spec `Name` aligned with the component instead. +- To add a real `.patch` file (rather than an inline edit), use `patch-add`; it copies + the `source` into the component sources and registers a `PatchN` tag or `%patchlist` + entry. + +## Document intent with `metadata` + +Give non-trivial overlays a `metadata` table. It is documentation only — excluded from +the component fingerprint, so editing it never invalidates the build cache — but it +records *why* the overlay exists and *when* it can be dropped. `category` is required; +pick the narrowest of: + +`backport-dist-git`, `azl-pruning`, `azl-compatibility`, `azl-dep-missing-workaround`, +`azl-branding-policy`, `azl-disable-flaky-tests`, `azl-disable-unsupported-tests`, +`azl-security-compliance`, `azl-release-management`, `azl-platform-adaptation`. + +Add `commits` (upstream URLs — required for `backport-dist-git`), `bugs` +(`{ url = ... }` entries), and `upstreamable` (`true`/`false`, omit if not yet +assessed) where they apply. When several overlays share one provenance, put them in a +per-file overlay document (`overlay-files`) with a single file-level `[metadata]`. + +## Full reference + +The tables above are the working subset. For the exhaustive field rules, metadata +constraints, and the per-file overlay format, generate the machine-readable schema +with `azldev config generate-schema` (see the `ComponentOverlay` definition), or read +azldev's overlays configuration reference. + +Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-remove-component/SKILL.md b/.agents/skills/azldev-remove-component/SKILL.md new file mode 100644 index 00000000000..9a6b25675d4 --- /dev/null +++ b/.agents/skills/azldev-remove-component/SKILL.md @@ -0,0 +1,73 @@ +--- +name: azldev-remove-component +description: Read this before deleting or dropping a component; there is no azldev remove command, so doing it wrong leaves dangling state. Explains how to remove a component from an azldev distro as a manual, metadata-only edit (delete the component config, its lock, and rendered spec, then clean references). Triggers include remove component, delete package, drop component, prune dependency. +--- + +# Remove a component + +There is **no `azldev` command to remove a component** — it is a manual, +metadata-only edit (no builds or tests needed). The steps below delete the +component's definition, lock, and rendered spec, then clean up references. + +## Before you start + +Confirm the component exists and see what it produces: + +```sh +azldev comp list -p -q -O json +``` + +Check for **reverse dependencies** first: if other components `BuildRequires` or +`Requires` this one, removing it breaks their builds. Search the tree for the +component and its binary subpackage names before deleting anything. + +## Steps + +1. **Remove the definition.** Delete the component's dedicated + `/.comp.toml` directory, or remove its inline `[components.]` + entry from whichever included TOML defines it. +2. **Remove publish / package config references.** If your project configures + publish channels or package groups, drop any references to the component or to + its binary subpackages. Publishing is component-scoped; per-binary exceptions + are binary-RPM-scoped — search for both. +3. **Remove the lock.** There is no azldev command for this: + + ```sh + rm locks/.lock + ``` + +4. **Remove the rendered spec.** Let azldev prune orphaned spec directories: + + ```sh + azldev comp render -a --clean-stale + ``` + + `--clean-stale` (only valid with `-a`) removes rendered-spec directories that no + longer correspond to a configured component. It re-renders everything, so it is + slow; for a targeted removal you can instead delete the component's rendered + spec under `specs/` by hand. +5. **Check other references.** Grep for the component (and its binary names) in + image definitions and any `*.kiwi` / package-list files, and remove or replace + them — an image that installs a now-removed package will not build. + +## Verify + +```sh +azldev comp list -p -q -O json # should report the component is not found +``` + +Also confirm the lock and rendered spec directory are gone and that no image or +package configuration still references the component. + +## Notes + +- **Dependants with manual release.** If removing this component forces a change + in a *dependant* (e.g. dropping a `BuildRequires`), and that dependant sets + `release.calculation = "manual"`, bump its release counter yourself in the same + change. Components with automatic release calculation (`auto`, `autorelease`, + `static`) are handled by the normal commit/render/amend cycle. +- **Remove exclusive dependencies together.** If a package is only needed by the + component you are dropping, remove it in the same change to keep the tree + consistent. + +Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-update-component/SKILL.md b/.agents/skills/azldev-update-component/SKILL.md new file mode 100644 index 00000000000..0e33223155a --- /dev/null +++ b/.agents/skills/azldev-update-component/SKILL.md @@ -0,0 +1,70 @@ +--- +name: azldev-update-component +description: Read this before finalizing a component change, bumping an upstream pin, or touching a lock file; lock edits are easy to get wrong. Explains how to refresh azldev component lock files with 'azldev comp update', covering when to run update versus render, the update/render/commit/re-render/amend workflow, and per-component versus -a refresh. Triggers include comp update, refresh lock, bump pin, lock drift, version bump, finalize component. +--- + +# Update component lock files + +`azldev comp update` (`comp` is an alias for `component`) refreshes one or more +component lock files under `locks/`. A lock pins the resolved upstream commit plus +an input fingerprint computed from the component's render inputs — its TOML config, +overlays, the pinned upstream commit, and the distro release version. If any of +those change, the lock is stale. + +## When to run `update` + +| Situation | Run `update`? | +| --- | --- | +| Adding a new upstream component (no lock yet) | **Yes** — first, to create the lock before `render`/`build` can resolve it | +| Finalizing a component change for a PR | **Yes** — once at the end | +| Bumping an upstream commit pin | **Yes** — also mid-workflow (see below) | +| Iterating on overlays / build config / metadata | No — once the lock exists, `render` alone is enough while iterating | +| Just reading or building existing components | No | + +Refresh a single component with `-p `. Use `-a` (all components) only for +coordinated mass refreshes (e.g. a new distro snapshot) or when investigating +lock drift across many components — it is slow. For day-to-day work use `-p`. Add +`-O json` for machine-readable lock output when debugging. + +## End-of-work refresh (the common case) + +For most edits — overlays, build flags, metadata — run `update` once at the end, +then re-render *after committing* so the generated changelog and release reflect +your new commit: + +```sh +azldev comp update -p +azldev comp render -p +# stage the component config, its lock (`locks/.lock`), and the rendered spec +git commit -m "fix(): ..." + +# Re-render and amend so the changelog / Release: track the new commit. +azldev comp render -p +git commit --amend --no-edit +``` + +### Why the second render-and-amend? + +Unless a component sets `release.calculation = "manual"`, azldev derives its +`%changelog` and `Release:` from the component's **git history**, not the working +tree — the renderer walks the commit log every time. The first render happens +before your commit exists, so a fresh render *after* committing adds a new +changelog entry and bumps `Release:`. Amending folds that into a single clean +commit and keeps any rendered-spec / lock CI gate (which runs against committed +state) green. + +For a `release.calculation = "manual"` component the renderer does **not** bump +`Release:` for you — increment the release counter yourself in the same change. + +## Bumping an upstream commit pin + +A pin bump follows the same rule, split across two commits: + +1. Move the pin (edit the pinned commit or snapshot time), then `azldev comp update -p `; sanity-check `locks/.lock`. +2. `azldev comp render -p ` — the spec body now tracks the new pin. `%changelog` / `Release:` still show the old pin; that is expected until you commit. +3. Iterate on overlays / patches / build config as the new version requires, re-rendering after each change. Re-run `update` only if you change the pin itself again. +4. `azldev comp update -p ` and commit the lock. +5. `azldev comp render -p ` — `%changelog` / `Release:` now reflect the new lock. +6. `git commit --amend --no-edit` so the lock bump and rendered spec land together. + +Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev/SKILL.md b/.agents/skills/azldev/SKILL.md new file mode 100644 index 00000000000..1556846ffae --- /dev/null +++ b/.agents/skills/azldev/SKILL.md @@ -0,0 +1,81 @@ +--- +name: azldev +description: Read this before running azldev or editing azldev config, and whenever working in a repo that contains an azldev.toml file; do not guess azldev's commands or config. Explains how to use the azldev CLI to build a distro from TOML config, including the core concepts (components, overlays, distros, rendered specs, locks), running azldev (repo root or -C, plus the -q and -O json flags), the common commands, and where to go for each workflow. Triggers include azldev, comp build, comp render, comp update, build a component, add a component, distro config. +--- + +# Using azldev + +azldev builds a Linux distribution from TOML configuration. It imports RPM specs +from an upstream distro and customizes them with an overlay system — no spec +forking. Components render to RPMs; images assemble RPMs into bootable artifacts. + +## Orient yourself + +- Run azldev from the repo root (where `azldev.toml` lives), or pass `-C `. +- Global, agent-friendly flags: **`-q`** (quiet) and **`-O json`** (machine-readable + output). They work on every command. +- Config is a stitched TOML hierarchy: `azldev.toml` includes the distro and project + config, which include the component files (`**/*.comp.toml`) into one namespace. + +## Core concepts + +- **Component** — a unit of packaging that renders to one or more RPMs. Its spec + source is upstream (default), a pinned upstream distro/version, or a local spec. +- **Overlay** — a semantic patch applied to a spec or source file at render time, so + you customize upstream without forking it. +- **Distro** — a named build target (`*.distro.toml`) with upstream URIs, release + versions, and build inputs. +- **Rendered spec** — the generated `.spec` after overlays; a build input, never + hand-edited. +- **Lock** — a per-component file pinning the resolved upstream commit and an input + fingerprint. + +## Common commands + +Top-level commands in this build: + +- `azldev completion` — Generate the autocompletion script for the specified shell +- `azldev component` — Manage components +- `azldev config` — Manage tool configuration +- `azldev docs` — Documentation commands +- `azldev image` — Manage Azure Linux images +- `azldev package` — Manage binary package configuration +- `azldev project` — Manage Azure Linux projects +- `azldev repo` — Inspect and manage RPM repositories +- `azldev version` — Print the CLI version + +Everyday tasks (add `-q -O json` when scripting): + +| Task | Command | +| --- | --- | +| List components | `azldev comp list -a` | +| Inspect one component | `azldev comp list -p ` | +| Add a component | `azldev comp add` | +| Build a component | `azldev comp build -p ` | +| Render specs | `azldev comp render -p ` (or `-a`) | +| Refresh a lock | `azldev comp update -p ` | +| List / build images | `azldev image list` / `azldev image build` | + +`comp` is an alias for `component`. Always confirm current syntax with +`azldev --help`. + +## Where to go next + +- Add a new component — read the `azldev-add-component` skill. +- Edit a component's TOML — read the `azldev-comp-toml` skill. +- Add or change overlays — read the `azldev-overlays` skill. +- Build, iterate, and debug a component — read the `azldev-build-component` skill. +- Build, boot, and register images — read the `azldev-image` skill. +- Refresh a lock and finalize for a PR — read the `azldev-update-component` skill. +- Remove a component — read the `azldev-remove-component` skill. +- Test built RPMs in a chroot — read the `azldev-mock` skill. + +## Golden rules + +- **Never edit generated output** — rendered specs and the output/work/log dirs are + produced by azldev. Change the source config and re-render. +- **Re-run `azldev comp update` before opening a PR** — the lock fingerprint covers + the whole component config, and lock / rendered-spec CI checks run on committed state. +- **Every overlay needs a `description`** explaining why the change is needed. + +Generated for azldev version `v0.1.0`. diff --git a/.github/skills/skill-aks-health/SKILL.md b/.agents/skills/skill-aks-health/SKILL.md similarity index 100% rename from .github/skills/skill-aks-health/SKILL.md rename to .agents/skills/skill-aks-health/SKILL.md diff --git a/.github/skills/skill-deployment-context/SKILL.md b/.agents/skills/skill-deployment-context/SKILL.md similarity index 100% rename from .github/skills/skill-deployment-context/SKILL.md rename to .agents/skills/skill-deployment-context/SKILL.md diff --git a/.github/skills/skill-koji-triage/SKILL.md b/.agents/skills/skill-koji-triage/SKILL.md similarity index 100% rename from .github/skills/skill-koji-triage/SKILL.md rename to .agents/skills/skill-koji-triage/SKILL.md diff --git a/.github/skills/skill-kql-queries/SKILL.md b/.agents/skills/skill-kql-queries/SKILL.md similarity index 100% rename from .github/skills/skill-kql-queries/SKILL.md rename to .agents/skills/skill-kql-queries/SKILL.md diff --git a/.github/skills/skill-mass-triage/SKILL.md b/.agents/skills/skill-mass-triage/SKILL.md similarity index 98% rename from .github/skills/skill-mass-triage/SKILL.md rename to .agents/skills/skill-mass-triage/SKILL.md index f56d4a1c967..fe2770a69b6 100644 --- a/.github/skills/skill-mass-triage/SKILL.md +++ b/.agents/skills/skill-mass-triage/SKILL.md @@ -136,11 +136,11 @@ You are diagnosing Koji build failures for Azure Linux. For each task below, inv - Output directory: {{OUTPUT_DIR}} ## Investigation procedure -Read the skill file at `.github/skills/skill-koji-triage/SKILL.md` for the full investigation +Read the skill file at `.agents/skills/skill-koji-triage/SKILL.md` for the full investigation workflow — including how to use MCP tools, fetch logs, and categorize failures. Follow it exactly. ## Setup -1. Read `.github/skills/skill-koji-triage/SKILL.md` (MUST do this first). +1. Read `.agents/skills/skill-koji-triage/SKILL.md` (MUST do this first). 2. The orchestrator has already configured the default Koji base URL and SSL settings. **Do NOT call `set_koji_url`** — changing the default would affect other parallel sub-agents sharing the same MCP server. - If you need to fetch from a different Koji instance for some reason, pass `override_base_url` directly to `koji_fetch` or `koji_allow_insecure` instead. 3. If the koji tools do not work as-is, inform the orchestrator of the issue — do not attempt to reconfigure them yourself, as that may cause issues for other parallel sub-agents. diff --git a/.github/skills/skill-metrics/SKILL.md b/.agents/skills/skill-metrics/SKILL.md similarity index 100% rename from .github/skills/skill-metrics/SKILL.md rename to .agents/skills/skill-metrics/SKILL.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 3c056b50f73..b17e7892f44 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -53,7 +53,7 @@ azldev comp update -a # Refresh all locks **Always re-run `update` before opening a PR**, even after minor edits — the input fingerprint is computed from the full component config, and the `Update Locks` CI check runs against the committed state. -**⚠️ Critical quirk** — `%changelog` and `Release:` are derived from `git log` for the component, not the working tree. In this mono-repo, commits that change a component's tracked inputs (for example `base/comps//` and/or `locks/.lock`) drift the rendered output, so after committing you must re-render and amend (or commit the spec separately). See [`skill-update-component`](skills/skill-update-component/SKILL.md) for the finalize-and-amend pattern that keeps `Check Rendered Specs` and `Update Locks` both green, including the pin-bump variant. +**⚠️ Critical quirk** — `%changelog` and `Release:` are derived from `git log` for the component, not the working tree. In this mono-repo, commits that change a component's tracked inputs (for example `base/comps//` and/or `locks/.lock`) drift the rendered output, so after committing you must re-render and amend (or commit the spec separately). See [`azldev-update-component`](../.agents/skills/azldev-update-component/SKILL.md) for the finalize-and-amend pattern that keeps `Check Rendered Specs` and `Update Locks` both green, including the pin-bump variant. ### Prior to PR diff --git a/.github/instructions/azldev.instructions.md b/.github/instructions/azldev.instructions.md new file mode 100644 index 00000000000..05434237fcd --- /dev/null +++ b/.github/instructions/azldev.instructions.md @@ -0,0 +1,15 @@ +--- +description: This repo is an azldev distro project (azldev.toml present). Before running azldev or editing its config, load the azldev skill; do not guess azldev's commands or config. Triggers include azldev, comp build, comp render, comp update, build a component, add a component, distro config. +applyTo: "**/azldev.toml" +--- + +# Working with azldev projects + +This repository is an azldev distro project; its top-level configuration lives in `azldev.toml`. + +**Do not work from memory or guess.** Before you add, edit, or remove anything in scope +here, you MUST first read the relevant azldev skill(s) below. They are the authoritative, +version-matched source and override any prior assumptions: + +- You MUST read the `azldev` skill for how to use the azldev CLI. + diff --git a/.github/instructions/comp-toml.instructions.md b/.github/instructions/comp-toml.instructions.md index dedbe2d55b6..5433ccfbe6c 100644 --- a/.github/instructions/comp-toml.instructions.md +++ b/.github/instructions/comp-toml.instructions.md @@ -1,287 +1,19 @@ --- +description: These are azldev component definition files (*.comp.toml). Before editing one, load the azldev-comp-toml skill (and azldev-overlays for spec changes); do not hand-write component config from memory. Triggers include comp.toml, component config, spec source, build defines, release calculation, overlays. applyTo: "**/*.comp.toml" --- -# Component Definition Files (`*.comp.toml`) +# Component definition files (`*.comp.toml`) -Component definitions tell `azldev` where to find a spec and how to customize it. Schema: [`azldev.schema.json`](../../external/schemas/azldev.schema.json) (or `azldev config generate-schema` for latest). +These files define a distro's components — each one's spec source and how azldev customizes it. -## Structure +**Do not work from memory or guess.** Before you add, edit, or remove anything in scope +here, you MUST first read the relevant azldev skill(s) below. They are the authoritative, +version-matched source and override any prior assumptions: -Every component lives under `[components.]`. A bare entry inherits defaults from the distro config: +- You MUST read the `azldev-comp-toml` skill for the component TOML format. +- You MUST read the `azldev-add-component` skill to add a new component. +- You MUST read the `azldev-overlays` skill to add or change overlays. +- You MUST read the `azldev-update-component` skill to refresh a component's lock. +- You MUST read the `azldev-remove-component` skill to remove a component. -```toml -[components.curl] -``` - -### Key fields - -| Field | Purpose | Example | -|-------|---------|---------| -| `spec` | Where to find the spec | `{ type = "upstream" }`, `{ type = "local", path = "mypackage.spec" }` | -| `spec.upstream-name` | Upstream package name (if different) | `"redhat-rpm-config"` | -| `spec.upstream-distro` | Pin to a specific distro/version | `{ name = "fedora", version = "rawhide" }` | -| `overlays` | List of spec/source modifications | See Overlays section | -| `release.calculation` | Release tag handling (`"auto"`, `"autorelease"`, `"static"`, or `"manual"`) | `"manual"` | -| `render.skip-file-filter` | Keep all source files during render (edge case) | `true` | -| `build.defines` | RPM macro overrides | `{ rhel = "11" }` | -| `build.with` | Enable build conditionals | `["feature_x"]` | -| `build.without` | Disable build conditionals | `["plugin_rhsm"]` | - -## Spec Source Types - -```toml -# Upstream (default) — inherits distro's Fedora version -[components.curl] - -# Upstream — pinned version -[components.curl] -spec = { type = "upstream", upstream-distro = { name = "fedora", version = "rawhide" } } - -# Upstream — different package name -[components.azurelinux-rpm-config] -spec = { type = "upstream", upstream-name = "redhat-rpm-config" } - -# Local spec (Azure Linux-originating package) -[components.azurelinux-release] -spec = { type = "local", path = "azurelinux-release.spec" } -``` - -## Overlays - -Overlays modify upstream specs/sources without forking. Every overlay **MUST** have a `description` field explaining *why* the change is needed. - -### TOML syntax - -Use **array-of-tables** (multi-line) for overlays — one `[[...overlays]]` block per overlay: - -```toml -# Targeted type (preferred) — more robust to upstream changes -[[components.curl.overlays]] -description = "Add missing build dependency for Azure Linux" -type = "spec-add-tag" -tag = "BuildRequires" -value = "golang >= 1.21" - -# Regex type (last resort) — brittle if upstream changes the line -[[components.rpm.overlays]] -description = "Customize RPM vendor" -type = "spec-search-replace" -regex = "RPM_VENDOR=redhat" -replacement = "RPM_VENDOR=azurelinux" -``` - -### Overlay types - -| Type | Does | Key fields | -|------|------|------------| -| `spec-add-tag` | Add a new tag; **fails if already exists** | `tag`, `value` | -| `spec-insert-tag` | Insert tag after the last tag of the same family (e.g., `Source9999` after last `Source*`); falls back to after last tag of any kind | `tag`, `value` | -| `spec-set-tag` | Set tag value; replaces entire value if exists, adds if not | `tag`, `value` | -| `spec-update-tag` | Replace value of existing tag; **fails if tag doesn't exist** | `tag`, `value` | -| `spec-remove-tag` | Remove a tag; **fails if tag doesn't exist** | `tag`, optionally `value` to match | -| `spec-prepend-lines` | Insert at start of section body | `section`, `lines` | -| `spec-append-lines` | Insert at end of section body | `section`, `lines` | -| `spec-search-replace` | Regex replace in spec (**last resort**) | `regex`, `replacement` | -| `patch-add` | Copy a patch file into sources and register it in the spec (`PatchN` or `%patchlist`) | `source`, optionally `file` | -| `patch-remove` | Remove patch files and their spec references matching a glob | `file` | -| `file-add` | Add a file to sources root | `file`, `source` | -| `file-remove` | Remove a file from sources | `file` | -| `file-rename` | Rename a source file | `file`, `replacement` | -| `file-prepend-lines` | Prepend lines to a file | `file`, `lines` | -| `file-search-replace` | Regex replace in source files | `file`, `regex`, `replacement` | - -Optional fields that apply to multiple types: `section` (target spec section), `package` (target sub-package). - -**Up-to-date details can be found from the azldev schema command, or by inspecting [azldev.schema.json](../../external/schemas/azldev.schema.json)**. - -### Choosing the right overlay type (avoiding regex) - -`spec-search-replace` is fragile — it breaks when upstream changes the matched text. Before reaching for regex, check if a targeted type can do the job: - -| Task | Use this | NOT this | -|------|----------|----------| -| Add a `BuildRequires` or `Requires` | `spec-add-tag` | regex to insert a line | -| Add a `Source` tag alongside existing ones | `spec-insert-tag` (e.g., `tag = "Source9999"`) | regex to find the last Source line | -| Change `Version`, `Release`, or `Summary` | `spec-set-tag` | regex `s/old/new/` | -| Remove a specific dependency | `spec-remove-tag` with `tag` + `value` | regex to delete the line | -| Add commands at end of `%install` | `spec-append-lines` with `section = "%install"` | regex to find and insert after a line | -| Add entries to `%files` | `spec-append-lines` with `section = "%files"` | regex to append after existing entries | -| Add env/export at start of `%build` | `spec-prepend-lines` with `section = "%build"` | regex to insert before existing content | -| Add a patch | `patch-add` (auto-registers `PatchN` or `%patchlist`) | manual `spec-add-tag` for PatchN + `file-add` | -| Remove a patch | `patch-remove` with glob (e.g., `file = "CVE-*.patch"`) | regex to delete PatchN line + `file-remove` | -| Target a sub-package's `%files` | `spec-append-lines` with `section = "%files"`, `package = "devel"` | regex scoped to a section | - -**When regex IS appropriate:** modifying arbitrary text mid-section (e.g., changing a configure flag, replacing a variable value, removing a conditional block). Even then, always scope with `section` and `package` to limit the blast radius. - -### Overlay pitfalls - -- **Do NOT use inline array syntax for overlays.** Write each overlay as a separate `[[components..overlays]]` block (array-of-tables), not as `overlays = [{ ... }, { ... }]`. The inline form is valid TOML but harder to read and review. Some older components in the repo use the inline style — don't copy it. -- **No `$schema` in TOML.** `$` is invalid at the start of a bare TOML key. -- **Scope regex overlays with `section` and `package`.** When using `spec-search-replace`, always set `section` (e.g. `"%files"`, `"%install"`) and `package` (e.g. `"foo"` for a `%files foo` section) to limit where the regex matches if possible. The `package` value is the **short sub-package suffix** as it appears after the section tag in the spec (e.g. `%files foo` → `package = "foo"`, not `package = "mypkg-foo"`). Unscoped regex overlays risk matching unintended lines elsewhere in the spec, especially after upstream updates. If the overlay targets a specific sub-package's `%files` section, both fields should be set. -- **No multi-line regex.** `spec-search-replace` doesn't support `(?s)`/DOTALL. Use multiple single-line replacements. -- **No backreferences in `spec-search-replace`.** `${1}` or `$1` in `replacement` is literal text, not a capture group backreference. Repeat the matched text in the replacement instead. -- **`lines` must be an array of strings.** Use `lines = ["single line"]` for single-element lists, or a multi-line array for multiple elements (not a bare string like `lines = "..."`). - ```toml - lines = [ - "line 1", - "line 2", - ] - ``` -- **`file-add` places files at the sources root**, alongside the tarball and other Source files — NOT inside the extracted source tree. To install the added file, also add a `spec-add-tag` for the corresponding `Source` tag and a `spec-append-lines` in `%install` to install it. To modify files inside the extracted tree, use `file-search-replace` or add a `sed` command in `%prep` via `spec-append-lines`. -- **Use TOML literal strings for regex.** `regex = 'RPM_VENDOR=redhat'` avoids double-escaping backslashes. -- **Prefer multi-line format for TOML arrays.** When a list field (`lines`, `with`, `without`, etc.) has 2+ elements, split it across multiple lines with a trailing comma for readability: - ```toml - lines = [ - "# Comment explaining the change", - "rm -f broken_test", - ] - ``` -- **Prefer targeted types over regex.** `spec-add-tag`, `spec-set-tag`, `spec-prepend-lines`, etc. are more robust to upstream changes. Use `spec-search-replace` as a last resort. -- **`spec-prepend-lines` and `spec-append-lines` operate *within* a section body.** `spec-prepend-lines` inserts right after the section header (start of body); `spec-append-lines` inserts at the end of the section body (before the next section). Neither inserts outside the section boundary. For example, to add install commands at the end of `%install`, use `spec-append-lines` with `section = "%install"` — do NOT use `spec-prepend-lines` with `section = "%files"` (that would put the lines inside `%files`). -- **Don't rename `Name:`.** Changing the spec `Name:` tag causes cascading breakage (`%{name}` in Source0, `%setup`, paths, `%files`). -- **`file-search-replace` supports globs.** Use `file = "**/*"` to replace across all source files. - -## File Organization - -- **Inline** (in `components.toml`): for simple imports with no customization (`[components.jq]`) -- **Dedicated** (`/.comp.toml`): when overlays, build config, or local spec are needed -- Rule of thumb: if it's more than `[components.]`, give it a dedicated file -- `components.toml` has `includes = ["**/*.comp.toml"]` — dedicated files are picked up automatically - -## Build Configuration - -```toml -# Override RPM macros -[components.wget2.build] -defines = { rhel = "11" } - -# Enable build conditionals -[components.mypackage.build] -with = ["feature_x"] - -# Disable build conditionals -[components.dnf5.build] -without = ["plugin_rhsm"] -``` - -## Release Configuration - -By default (`release.calculation = "auto"`), `azldev` auto-calculates the `Release` tag during rendering. There are four modes: - -### `auto` (default) - -Auto-detects whether the spec uses `%autorelease` or a static release value and handles it accordingly. Works for most packages. - -### `autorelease` - -Forces `azldev` to treat the spec as using `%autorelease`, preserving the `%autorelease` macro in the rendered spec. Use this when auto-detection gets it wrong — typically when the spec wraps `%autorelease` in a conditional: - -```spec -%if %{defined autorelease} -Release: %autorelease -%else -Release: 1 -%endif -``` - -In this pattern, auto-detection may see the conditional and misidentify the release mode, expanding `%autorelease` to a hardcoded integer. Setting `calculation = "autorelease"` forces correct behavior: - -```toml -[components.gvisor-tap-vsock] -# Upstream spec uses conditional %autorelease — auto-detection misidentifies it -[components.gvisor-tap-vsock.release] -calculation = "autorelease" -``` - -**When to use `autorelease`:** When `render` produces a hardcoded integer where `%autorelease` should be, or when the spec has conditional `%autorelease` logic that confuses auto-detection. - -### `static` - -Forces `azldev` to treat the spec as using a static (hardcoded) release value, even if auto-detection thinks it uses `%autorelease`. Uses a regex to match release patterns like `5.%{dist}` and bumps the integer component automatically during rendering. The inverse of `autorelease` — use when auto-detection incorrectly identifies a static release as `%autorelease`. - -```toml -[components.mypackage.release] -calculation = "static" -``` - -**When to use `static`:** When auto-detection misidentifies a static release as `%autorelease` and produces incorrect rendering (e.g., inserts `%autorelease` where a hardcoded integer release should be). - -### `manual` - -Some upstream specs use non-standard Release tag values (e.g., `%{baserelease}%{?dist}`, `%{pkg_release}`) that the auto-calculator can't parse. These fail with: - -``` -non-standard Release tag value ... does not start with an integer -``` - -Fix: set `release.calculation = "manual"` and add a `spec-set-tag` overlay to set a concrete Release value: - -```toml -[components.gcc] -release = { calculation = "manual" } - -[[components.gcc.overlays]] -description = "Set explicit Release tag — upstream uses %{gcc_release} macro which azldev cannot auto-calculate" -type = "spec-set-tag" -tag = "Release" -value = "1%{?dist}" -``` - -**When to use `manual`:** Only when `render` fails with the "non-standard Release tag" error. Don't preemptively set it — most packages work fine with `auto`. - -**When using `manual`:** You take ownership of bumping the Release value when needed (e.g., rebuild without a version change). The auto-calculator will not touch it. - -> **Pitfall — modifying a component with manual release:** Unlike `auto`/`static`/`autorelease` modes, `manual` release components do NOT get their Release bumped by the commit-render-amend cycle. When you change a manual-release component (add/remove build flags, modify overlays, etc.), you **must** also increment the release counter in the same change — typically an `azl_release` define in `[components..build.defines]` or the `value` in a `spec-set-tag` overlay for `Release`. - -## Render Configuration - -The `render` section controls spec rendering behavior. Currently has one field: - -```toml -[components.mypackage.render] -skip-file-filter = true -``` - -`skip-file-filter` disables post-render file filtering. During rendering, `azldev` normally prunes source/patch files not referenced by the rendered spec. If a spec uses unexpandable macros in `Source` or `Patch` tags (e.g., `Source0: %{name}-%{version}%{?prerelease}.tar.gz`), the filter can't resolve the filename and may incorrectly remove needed files. Setting `skip-file-filter = true` keeps all files. The tool auto-detects unexpandable macros and handles them correctly in the vast majority of cases - this is an edge case escape hatch that should almost never be needed in practice. - -## Adding Description Comments - -When adding or modifying fields in a `.comp.toml` file, check the schema (`external/schemas/azldev.schema.json`) for a `description` on that field. If the schema field **does not** have a `description` key (or equivalent, i.e. `skip_reason` for check skip), add a TOML comment above the field explaining what it does and why it's set to that value. This helps future readers (human and agent) understand fields that aren't self-documenting via the schema. - -**BUT**... don't add pointless noise - if the change is self-explanatory and requires no additional context, a comment may not be necessary. Use your judgement, but when in doubt, add a comment. - -DO: - -```toml -# Pin to Fedora rawhide since we need feature 'x' that is not in stable releases yet. -# Re-align to a stable release once the feature is backported or a new release is available. -spec = { type = "upstream", upstream-distro = { name = "fedora", version = "rawhide" } } -``` - -Offers important context about *why* the component is pinned to rawhide, which is not obvious from the TOML field alone. Future readers will understand the rationale and know to check for backports or new releases to remove the rawhide pin. - -DO NOT: - -```toml -# Need new stuff. -spec = { type = "upstream", upstream-distro = { name = "fedora", version = "rawhide" } } -``` - -This offers no real information beyond what the TOML field already says, and doesn't explain *why* the new stuff is needed, or what that new stuff is. It's just noise. - -### References - -When making changes based on external information (e.g. a bug report, an upstream commit, a changelog entry, etc.), include a link to the relevant source in a comment (prefer full URL for ease of use). This provides valuable context for future readers to understand the reasoning behind the change and investigate further if needed. It also makes it easier to determine if the change is still relevant or if there have been updates since. - -```toml -# ... -# Fixed upstream in my-package-1.2.3 (rawhide): https://src.fedoraproject.org/rpms/my-package/c/abcdef123456 (rhbz#1234567) -[[components.mypackage.overlays]] -description = "Fix build failure due to missing dependency that was added in my-package-1.2.3" -... -``` - -## Validation - -Verify overlays apply cleanly with `azldev comp prep-sources` before committing. See skills `skill-build-component` and `skill-fix-overlay` for step-by-step workflows. diff --git a/.github/instructions/rendered-specs.instructions.md b/.github/instructions/rendered-specs.instructions.md index 5e8e73b1a46..146a8ca3216 100644 --- a/.github/instructions/rendered-specs.instructions.md +++ b/.github/instructions/rendered-specs.instructions.md @@ -1,49 +1,17 @@ --- -applyTo: "specs/**/*" -description: ALWAYS refer to this when working with rendered spec files (`*.spec`) in the `specs/` directory. +description: Rendered RPM spec files produced by 'azldev comp render'. They are build inputs and must not be hand-edited. Before changing one, load the azldev-overlays or azldev-comp-toml skill, edit the source, and re-render. Read this when viewing or tempted to edit a generated spec. +applyTo: "specs/**/*.spec" --- -# Rendered Spec Files (`specs/*.spec`) +# Rendered spec files -## What are rendered specs? +These `.spec` files are generated by `azldev comp render` and are build inputs; do not edit them directly — change the component's `.comp.toml` or its overlays and re-render. -Rendered specs are generated by the `azldev comp render` command based on the component definitions and overlays. They are output to the `specs/` directory (as specified by `rendered-specs-dir` config) and should not be edited directly. +**Do not work from memory or guess.** Before you add, edit, or remove anything in scope +here, you MUST first read the relevant azldev skill(s) below. They are the authoritative, +version-matched source and override any prior assumptions: -They are meant to be consumed by downstream processes (e.g., build pipelines) and are the source of truth for all subsequent steps. Any changes to the spec should be made via the component definition and overlays, not by editing the rendered spec. +- You MUST read the `azldev-comp-toml` skill for the component TOML format. +- You MUST read the `azldev-overlays` skill to change a spec via overlays. +- You MUST read the `azldev-update-component` skill to refresh and finalize a component. -## Changing a rendered spec - -To change a rendered spec, modify the component's `.comp.toml` and/or its overlays. Then re-run the render command to regenerate the spec: - -```bash -# VERY SLOW - Re-render all specs, removes any stale specs that are no longer defined in the components -azldev comp render -a --clean-stale -O json -``` - -```bash -# Small set, will NOT remove stale specs, faster for iterative development -azldev comp render -p -p -O json -``` - -```bash -# Custom output directory, useful for debugging. When not using the automatically configured spec directory, --force is -# required to delete and re-create the output folders if they already exist. -azldev comp render -p -O json -o ./base/build/work/scratch/rendered-specs --force -``` - -## Render output drifts after every commit - -`%changelog` and `Release:` are derived from `git log` for the component (rpmautospec). Every commit that touches the component, its overlays, or its lock will bump the `Release:` integer and add a new `%changelog` entry on the next render. So when finalizing a change for PR you'll typically need to render twice: - -1. Render before the commit to validate the rendered spec body/output content for review. This pre-commit render is not expected to have the final `%changelog` / `Release:` yet, because those only pick up the new work after the commit exists and you render again. -2. `git commit` your work. -3. Re-render -- this picks up the new commit in `%changelog` / `Release:`. -4. `git commit --amend --no-edit` (or commit the spec separately) so the rendered output matches the committed history. - -Without step 3-4 the `Check Rendered Specs` CI check fails with a one-line `Release:` diff and a new `%changelog` entry. See [`skill-update-component`](../skills/skill-update-component/SKILL.md) for the full pattern, including the pin-bump variant. - -## Common render errors - -### `non-standard Release tag value ... does not start with an integer` - -See [Release Configuration](../instructions/comp-toml.instructions.md#release-configuration). diff --git a/.github/instructions/review.instructions.md b/.github/instructions/review.instructions.md new file mode 100644 index 00000000000..e7f7820fd69 --- /dev/null +++ b/.github/instructions/review.instructions.md @@ -0,0 +1,10 @@ +--- +description: When performing a code review, read this file to understand the review process and expectations. It applies to all files in the repository. +applyTo: "**/*" +--- + +# Working with azldev projects + +This project uses the [azldev](https://github.com/microsoft/azure-linux-dev-tools) tool to manage components and provide various utilities. + +Additional instructions for this repo are available only from the azldev tool itself. When using an azldev skill for the first time, you will be prompted to use the tool to view the skill's instructions. Follow the instructions in [DEVELOPING.md](../../DEVELOPING.md) to install azldev and view the instructions for each skill. If the specified tools are not available (i.e. MCP server is not configured in the current environment), use the `azldev` tool directly. diff --git a/.github/instructions/spec.instructions.md b/.github/instructions/spec.instructions.md index 7751d8b3fa1..a805ffe953a 100644 --- a/.github/instructions/spec.instructions.md +++ b/.github/instructions/spec.instructions.md @@ -9,7 +9,7 @@ description: Read this when working with spec files (`*.spec`) that are hand-mai Most components import specs from upstream (Fedora) via `*.comp.toml` — hand-coded specs are only for **Azure Linux-originating packages** that don't exist upstream (e.g., `azurelinux-release`, `azurelinux-repos`). -If the package exists upstream, **prefer overlays** over maintaining a forked spec. Overlays get automatic upstream updates and are more resilient to changes. See the `skill-add-component` skill for the decision tree. +If the package exists upstream, **prefer overlays** over maintaining a forked spec. Overlays get automatic upstream updates and are more resilient to changes. See the `azldev-add-component` skill for the decision tree. ## Relationship to `.comp.toml` @@ -38,4 +38,4 @@ To see the upstream spec before overlays: `azldev comp prep-sources -p -- ## Debugging a spec -If overlays produce an incorrect spec, use `prep-sources` to compare before/after. See skills `skill-fix-overlay` and `skill-build-component` for step-by-step workflows. +If overlays produce an incorrect spec, use `prep-sources` to compare before/after. See skills `azldev-overlays` and `azldev-build-component` for step-by-step workflows. diff --git a/.github/plugin/plugin.json b/.github/plugin/plugin.json index a68f568df90..05f8ab0c461 100644 --- a/.github/plugin/plugin.json +++ b/.github/plugin/plugin.json @@ -2,7 +2,9 @@ "name": "azurelinux", "description": "Azure Linux OS development skills — component builds, overlays, mock testing, Koji triage, AKS health", "version": "1.0.0", - "author": "Azure Linux Team", - "skills": ".github/skills/", + "author": { + "name": "Azure Linux Team" + }, + "skills": ".agents/skills/", "agents": ".github/agents/" } diff --git a/.github/prompts/azl-add-component.prompt.md b/.github/prompts/azl-add-component.prompt.md index 5a5564c1556..e9f1c0ca681 100644 --- a/.github/prompts/azl-add-component.prompt.md +++ b/.github/prompts/azl-add-component.prompt.md @@ -6,7 +6,7 @@ description: "Add a new component to Azure Linux" Add the component **${input:component_name}** to the **${input:project:base}** project, sourcing from **${input:source_distro:fedora}**. -Follow the workflow in the [skill-add-component skill](../skills/skill-add-component/SKILL.md) and use the structural patterns from [comp-toml.instructions.md](../instructions/comp-toml.instructions.md). +Follow the workflow in the [azldev-add-component skill](../../.agents/skills/azldev-add-component/SKILL.md) and use the structural patterns from [comp-toml.instructions.md](../instructions/comp-toml.instructions.md). ## Workflow diff --git a/.github/prompts/azl-debug-component.prompt.md b/.github/prompts/azl-debug-component.prompt.md index a983427cf61..23ba0b82d8a 100644 --- a/.github/prompts/azl-debug-component.prompt.md +++ b/.github/prompts/azl-debug-component.prompt.md @@ -8,23 +8,23 @@ Debug issues with **${input:component_name}**. Error context: ${input:error_context:paste error or describe issue} -Use the [skill-fix-overlay skill](../skills/skill-fix-overlay/SKILL.md) for overlay failures, the [skill-build-component skill](../skills/skill-build-component/SKILL.md) for build debugging, and the [skill-mock skill](../skills/skill-mock/SKILL.md) for runtime/packaging inspection. +Use the [azldev-overlays skill](../../.agents/skills/azldev-overlays/SKILL.md) for overlay failures, the [azldev-build-component skill](../../.agents/skills/azldev-build-component/SKILL.md) for build debugging, and the [azldev-mock skill](../../.agents/skills/azldev-mock/SKILL.md) for runtime/packaging inspection. ## Triage First, determine the error category: 1. **Overlay failure** — errors during `prep-sources` or early in build mentioning overlay application, pattern matching, or section/tag not found: - - Follow the `skill-fix-overlay` workflow: diff pre/post overlay output, diagnose pattern failures, suggest fixes + - Follow the `azldev-overlays` workflow: diff pre/post overlay output, diagnose pattern failures, suggest fixes - Common causes: upstream spec changed, section renamed/removed, wrong overlay type 2. **Build failure** — compilation errors, missing dependencies, test failures during `comp build`: - - Follow the `skill-build-component` inner loop: check build logs in `base/build/logs/`, use `--preserve-buildenv on-failure`, inspect mock chroot + - Follow the `azldev-build-component` inner loop: check build logs in `base/build/logs/`, use `--preserve-buildenv on-failure`, inspect mock chroot - Common causes: missing BuildRequires, incompatible compiler flags, test failures - **`%check` failures:** Always attempt to fix failing tests first. Disabling `%check` (via `build.without = ["check"]`) is an **absolute last resort** — only after exhausting other options. If you must disable it, the `skip_reason` must clearly explain why the tests cannot be fixed. 3. **Runtime/packaging issue** — wrong file permissions, missing files, dependency conflicts in built RPMs: - - Follow the `skill-mock` workflow: install RPMs in a mock chroot, verify contents, check dependencies + - Follow the `azldev-mock` workflow: install RPMs in a mock chroot, verify contents, check dependencies - Common causes: missing Requires, wrong file paths, permission issues **When in doubt**, start with a render to determine if the issue is overlay-related: @@ -45,4 +45,4 @@ If both render and `prep-sources` succeed but `comp build` fails, it's a build i ## Fix -**IF** a request has been made to fix the issue, attempt a fix. Before declaring success, ensure the fix actually resolves the issue by running tests. Also, queue a sub-agent and tell it to use the `skill-review-component` skill to review the fix and confirm it follows best practices and won't cause future maintenance issues. If the review agent raises concerns, address them, and then re-run the review (repeat as needed). +**IF** a request has been made to fix the issue, attempt a fix. Before declaring success, ensure the fix actually resolves the issue by running tests. Also, queue a sub-agent and tell it to use the `azldev-comp-toml` and `azldev-overlays` skills to review the fix and confirm it follows best practices and won't cause future maintenance issues. If the review agent raises concerns, address them, and then re-run the review (repeat as needed). diff --git a/.github/prompts/azl-remove-component.prompt.md b/.github/prompts/azl-remove-component.prompt.md index 6c7ae1603e4..a64a5d6336a 100644 --- a/.github/prompts/azl-remove-component.prompt.md +++ b/.github/prompts/azl-remove-component.prompt.md @@ -6,7 +6,7 @@ description: "Remove component(s) from Azure Linux" Remove the component(s) **${input:component_names}** from the **${input:project:base}** project. -Follow the workflow in the [skill-remove-component skill](../skills/skill-remove-component/SKILL.md). +Follow the workflow in the [azldev-remove-component skill](../../.agents/skills/azldev-remove-component/SKILL.md). ## Workflow diff --git a/.github/prompts/azl-review-component.prompt.md b/.github/prompts/azl-review-component.prompt.md index 50a13333e81..4e5b255baa8 100644 --- a/.github/prompts/azl-review-component.prompt.md +++ b/.github/prompts/azl-review-component.prompt.md @@ -7,11 +7,11 @@ argument-hint: "Component to review. Indicate if the review should be a full rev Review **${input:component_name}** for hygiene and best practices. -Follow the review checklist in the [skill-review-component skill](../skills/skill-review-component/SKILL.md). Reference [comp-toml.instructions.md](../instructions/comp-toml.instructions.md) for structural patterns and [base/comps/AGENTS.md](../../base/comps/AGENTS.md) for file organization rules. +Follow the component structure guidance in the [azldev-comp-toml skill](../../.agents/skills/azldev-comp-toml/SKILL.md) and overlay guidance in the [azldev-overlays skill](../../.agents/skills/azldev-overlays/SKILL.md). Reference [comp-toml.instructions.md](../instructions/comp-toml.instructions.md) for structural patterns and [base/comps/AGENTS.md](../../base/comps/AGENTS.md) for file organization rules. ## Steps 1. Query the component: `azldev comp query -p ${input:component_name}` 2. Read the component's `.comp.toml` file (or inline definition in `components.toml`) -3. Run through the review checklist from the skill +3. Run through the review checklist from the component and overlay guidance 4. Produce a structured report grouped by severity: **Errors** (must-fix), **Warnings** (should-fix), **Info** (suggestions) diff --git a/.github/prompts/azl-update-component.prompt.md b/.github/prompts/azl-update-component.prompt.md index bbab2bf3d46..57272157700 100644 --- a/.github/prompts/azl-update-component.prompt.md +++ b/.github/prompts/azl-update-component.prompt.md @@ -6,7 +6,7 @@ description: "Update an existing Azure Linux component (version bump, dependency Update **${input:component_name}** — target version: **${input:new_version:target version}**, update type: **${input:update_type:version|dependency|overlay|config}**. -Use structural patterns from [comp-toml.instructions.md](../instructions/comp-toml.instructions.md). If overlays break, follow the [skill-fix-overlay skill](../skills/skill-fix-overlay/SKILL.md). Test changes using the [skill-build-component skill](../skills/skill-build-component/SKILL.md). +Use structural patterns from [comp-toml.instructions.md](../instructions/comp-toml.instructions.md). If overlays break, follow the [azldev-overlays skill](../../.agents/skills/azldev-overlays/SKILL.md). Test changes using the [azldev-build-component skill](../../.agents/skills/azldev-build-component/SKILL.md). ## Workflow @@ -27,7 +27,7 @@ Use structural patterns from [comp-toml.instructions.md](../instructions/comp-to azldev comp prep-sources -p ${input:component_name} -o base/build/work/scratch/${input:component_name}-post --force diff -r base/build/work/scratch/${input:component_name}-pre base/build/work/scratch/${input:component_name}-post ``` - If overlays fail, follow the [skill-fix-overlay skill](../skills/skill-fix-overlay/SKILL.md). + If overlays fail, follow the [azldev-overlays skill](../../.agents/skills/azldev-overlays/SKILL.md). 5. **Migrate to dedicated file** if the component is still inline and now needs customization (use `/azl-migrate-component`) 6. **Build and test:** `azldev comp build -p ${input:component_name}` 7. **Smoke-test** the built RPMs in a mock chroot diff --git a/.github/skills/skill-add-component/SKILL.md b/.github/skills/skill-add-component/SKILL.md deleted file mode 100644 index 6753f9dcde3..00000000000 --- a/.github/skills/skill-add-component/SKILL.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -name: skill-add-component -description: "[Skill] Add a new component to Azure Linux. Use when importing packages from Fedora, creating comp.toml files, choosing inline vs dedicated definitions, or setting up a new component with overlays. Triggers: add component, new package, import from fedora, create comp.toml." ---- - -# Add a Component - -## Before You Start - -```bash -# Check if it already exists -azldev comp list -p -q -O json -``` - -### Inspect the upstream spec first - -The fastest way to see what you're working with: - -1. Add a bare inline entry in `components.toml`: `[components.]` -2. Pull the spec: `azldev comp prep-sources -p --skip-overlays --force -o base/build/work/scratch/ -q` -3. Read the spec, plan your overlays -4. Decide if overlays are required, if so: Remove the inline entry, create a dedicated `/.comp.toml` - -Fedora dist-git is behind bot detection — direct web fetches often fail. Use `prep-sources` to pull specs reliably. - -> Note: `prep-sources -o` writes to the directory you specify — this is ad-hoc output, separate from the project's configured build output dirs in `base/project.toml`. - -## Decision: Inline vs Dedicated File - -**Inline** (in `components.toml`) — simple upstream import, no modifications: - -```toml -[components.jq] -``` - -**Dedicated file** (`/.comp.toml`) — needs overlays, build config, or local spec: - -```toml -# /.comp.toml -[components.] - -[[components..overlays]] -description = "Why this change is needed" -type = "spec-add-tag" -tag = "BuildRequires" -value = "some-dependency" -``` - -Rule of thumb: if it's more than `[components.]`, give it a dedicated file. The `includes = ["**/*.comp.toml"]` in `components.toml` picks it up automatically. - -## Spec Sources & Overlays - -For spec source types, overlay syntax, overlay types, and pitfalls, see [`comp-toml.instructions.md`](../../instructions/comp-toml.instructions.md). - -Key points for adding components: -- Every overlay MUST have a `description` explaining *why* -- Test incrementally — apply one overlay at a time, verify with `prep-sources` -- Prefer targeted overlay types (`spec-add-tag`, `spec-set-tag`) over regex (`spec-search-replace`) -- **Keep `%check` enabled** — do not disable tests unless there is a documented, unavoidable reason (upstream bug, missing test infra, etc.). If you must disable, provide a clear `skip_reason`. -- **Release calculation:** If `render` fails with "non-standard Release tag value", or if `%autorelease` is incorrectly expanded (e.g., conditional `%autorelease` specs), see [Release Configuration](../../instructions/comp-toml.instructions.md#release-configuration). - -### Overlays vs. Dedicated spec - -Overlays are vastly preferable to maintaining a forked spec, they get automatic updates from upstream and are more resilient to changes. Only fork the spec as a **last resort** when the required changes are so extensive that overlays become unmanageable. Even then, try to minimize the delta from upstream as much as possible to reduce maintenance burden: - - Clearly document the rationale for each change. - - Add comments to the spec itself for EVERY change (so future maintainers can differentiate local changes vs. upstream drift when version bumps happen). - - Recommend to the user contributing necessary changes upstream to reduce divergence over time, where possible. - -**Using a forked spec is a commitment to maintain it indefinitely, coordinate with the user to decide if it's truly necessary. Get explicit sign-off from the user before proceeding with a forked spec.** - -## Validate - -After adding overlays or customizations, render the spec to verify: - -```bash -azldev comp render -p -# Inspect the result -cat specs///.spec -``` - -For deeper debugging (diffing pre/post overlay output with full sources): - -> Use a temp dir for `prep-sources` output. Use `--force` to overwrite an existing output dir. - -`prep-sources -o ` writes to a user-specified directory (NOT `base/out/` — that's for `comp build` output). - -```bash -azldev comp prep-sources -p --skip-overlays --force -o base/build/work/scratch/-pre -q -azldev comp prep-sources -p --force -o base/build/work/scratch/-post -q -diff -r base/build/work/scratch/-pre base/build/work/scratch/-post -``` - -```bash -# Test build (RPMs land in base/out/ per project.toml output-dir) -azldev comp build -p -q -``` - -For testing the built RPMs, see the [`skill-mock`](../skill-mock/SKILL.md) skill. New components always need a smoke-test. For the full inner loop cycle (investigate → modify → render → build → test → inspect), see [`skill-build-component`](../skill-build-component/SKILL.md). diff --git a/.github/skills/skill-build-component/SKILL.md b/.github/skills/skill-build-component/SKILL.md deleted file mode 100644 index 0e79142983d..00000000000 --- a/.github/skills/skill-build-component/SKILL.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -name: skill-build-component -description: "[Skill] Build and test Azure Linux components using azldev. Use when building packages, debugging build failures, inspecting mock chroots, preparing sources, or working with the build inner loop. Triggers: build component, build failed, mock shell, prepare sources, debug build, build error." ---- - -# Build & Debug Components - -> **Never install built RPMs on the host.** They target Azure Linux, not your dev machine. Use [`skill-mock`](../skill-mock/SKILL.md) for testing. - -## Mandatory Testing - -> **A successful build is NOT the finish line.** If your change could affect the built RPMs, smoke-test before reporting success. See [`skill-mock`](../skill-mock/SKILL.md). - -Pure organizational changes (moving definitions between files, editing comments/descriptions) don't need a rebuild. When in doubt, test. - -## Build Output Directories - -Build output paths are configured in `base/project.toml` (`output-dir`, `log-dir`, `work-dir`). Default layout: - -| `project.toml` key | Default value | Resolves to | Contents | -|---------------------|---------------|-------------|----------| -| `output-dir` | `out` | `base/out/` | Built RPMs and SRPMs | -| `log-dir` | `build/logs` | `base/build/logs/` | Build logs | -| `work-dir` | `build/work` | `base/build/work/` | Per-component working dirs (`/`) | - -Paths are relative to the project root (`base/`). Don't edit anything in these dirs — they are generated output. - -> **`prep-sources` output is separate.** `comp prep-sources -o ` writes to a user-specified directory, NOT to the project's configured output dirs. Don't look in `base/out/` for `prep-sources` results. - -## Build Sequence - -```bash -# Build a single component -azldev comp build -p - -# Build multiple components, auto-publishing RPMs to local repo for chained deps -azldev comp build --local-repo-with-publish ./base/out -p -p - -# Rebuild a single component against an already-populated local repo -azldev comp build -p --local-repo ./base/out -``` - -**NOTE:** `-q` (silent) can be used with all commands for cleaner logs, but will limit visibility into build progress. Only use `-q` for inner-loop builds when you know the build will run to completion without infrastructure issues. - -Build foundational packages first (e.g., `azurelinux-rpm-config`), then dependents. See [`scripts/demo-build.sh`](../../../scripts/demo-build.sh) for a working example. - -## Dev Inner Loop - -The standard cycle for investigating, modifying, and verifying components: - -``` -investigate → modify → render → build → test → inspect -``` - -> **Finalize with `azldev comp update -p ` before opening a PR** — lock fingerprints are computed from the full component config, so any TOML change can invalidate them. The `Update Locks` CI check enforces this. After committing your change, **re-render and amend** so `%changelog` / `Release:` track the new commit (rpmautospec walks `git log` every render). See [`skill-update-component`](../skill-update-component/SKILL.md) for the full finalize-and-amend pattern, plus the pin-bump variant. - -| Step | Command | What to check | -|------|---------|---------------| -| **Investigate** | Read `specs///.spec` or `prep-sources --skip-overlays --force -o base/build/work/scratch/-pre` | Upstream spec/sources as-is | -| **Compare** | `prep-sources --force -o base/build/work/scratch/-post` + `diff -r ...-pre ...-post` | Current overlay effect (deep debug) | -| **Modify** | Edit `*.comp.toml` (overlays, defines, without) | — | -| **Verify** | `comp render -p ` + inspect `specs///` | Overlay applies cleanly (fast path) | -| **Build** | `comp build -p ` | RPMs appear in `base/out/` | -| **Test** | `adv mock shell --add-package base/out/*.rpm` | Package installs, binary runs, basic functionality works | -| **Inspect** | `comp build --preserve-buildenv always` + `adv mock shell` | BUILDROOT contents, file lists | - -> **Prefer `comp render` for quick verification.** It's faster than `prep-sources` since it skips downloading source tarballs. Use `prep-sources` when you need the full source tree or want to diff pre/post overlay output for debugging. - -> Use a temp dir for `prep-sources` output. Use `--force` to overwrite an existing output dir. - -> Package builds are often very long, so adjust command timeouts accordingly when using shell tools to run builds, or use background mode if available. - -## Debugging Build Failures - -### 0. Release calculation errors - -If `render` fails with `non-standard Release tag value ... does not start with an integer`, or if `%autorelease` is incorrectly expanded to a hardcoded integer (common with conditional `%autorelease` specs), see [Release Configuration](../../instructions/comp-toml.instructions.md#release-configuration). - -### 1. Render and inspect the spec - -The fastest way to verify overlays applied correctly: - -```bash -azldev comp render -p -# Inspect the result -cat specs///.spec -``` - -### 2. Diff sources pre/post overlay (deep debug) - -When you need to understand exactly what upstream provides vs. what overlays change: - -```bash -azldev comp prep-sources -p --skip-overlays --force -o base/build/work/scratch/-pre -q -azldev comp prep-sources -p --force -o base/build/work/scratch/-post -q -diff -r base/build/work/scratch/-pre base/build/work/scratch/-post -``` - -This reveals whether overlays apply as intended or whether upstream changed. - -### 3. Preserve build environment on failure - -```bash -azldev comp build -p --preserve-buildenv on-failure -q -# Use `always` to inspect even successful builds -``` - -### 4. Enter mock shell (deep debug) - -For testing built RPMs or inspecting the chroot, see the [`skill-mock`](../skill-mock/SKILL.md) skill. Quick reference: - -```bash -# Non-interactive (preferred for agents) -azldev adv mock shell --add-package /path/to/rpm <<'CMDS' -rpm -q -exit -CMDS - -# Interactive (requires user cooperation — see skill-mock for agent workflow) -azldev adv mock shell --add-package /path/to/rpm --enable-network -``` - -> ⚠️ **Don't mix `-p ` with `--add-package` for the same package.** `-p` is shorthand for `--add-package`, so `-p cowsay --add-package ./cowsay.rpm` installs two conflicting builds. Use one or the other. See [`skill-mock`](../skill-mock/SKILL.md) for details. - -Inside the chroot: `rpmbuild`, `find`, `dnf5` — standard RPM tooling. `BUILDROOT` is at `builddir/build/BUILD/--build/BUILDROOT/`. - -## Per-Component Build Overrides - -Use `build.defines` (macros) and `build.without` (disable conditionals) in the component's `.comp.toml`. See [`comp-toml.instructions.md`](../../instructions/comp-toml.instructions.md#build-configuration) for syntax and examples. - -Verify with `prep-sources` before doing a full build. - -### Disabling `%check` (test suites) - -Disabling `%check` (via `build.without = ["check"]`) is an **absolute last resort**. Always attempt to fix failing tests first — investigate the root cause, check upstream for patches or known issues, and try targeted fixes. If disabling is truly unavoidable, the component's `skip_reason` field MUST clearly explain: -- What tests fail and how -- Why the failures cannot be fixed (e.g., upstream bug with link, environment limitation, missing test infrastructure) -- Whether this is expected to be temporary (and if so, what would unblock re-enabling) - -## Reference -- CLI help: `azldev comp build --help`, `azldev advanced mock --help` -- `azldev advanced` (alias `adv`) is hidden from `azldev --help` but contains `mock shell`, `mock build-rpms`, `mcp`, and `wget`. -- [schema reference](../../../external/schemas/azldev.schema.json) (or `azldev config generate-schema > base/build/work/scratch/schema.json` for latest changes) diff --git a/.github/skills/skill-fix-overlay/SKILL.md b/.github/skills/skill-fix-overlay/SKILL.md deleted file mode 100644 index 70f801255d8..00000000000 --- a/.github/skills/skill-fix-overlay/SKILL.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -name: skill-fix-overlay -description: "[Skill] Diagnose and fix overlay issues in Azure Linux components. Use when overlays fail to apply, produce unexpected results, or need debugging. Triggers: overlay error, fix overlay, overlay not applying, spec-search-replace failed, overlay debug." ---- - -# Fix an Overlay - -## Diagnosis Workflow - -### 1. Render and inspect - -The fastest way to check if overlays apply cleanly: - -```bash -azldev comp render -p -# Inspect the result -cat specs///.spec -``` - -If `render` fails, the error message will identify which overlay failed and why. - -### 2. Diff pre/post overlay (deep debug) - -When you need to understand exactly what upstream provides vs. what overlays change: - -> Use a temp dir for `prep-sources` output. Use `--force` to overwrite an existing output dir. - -`prep-sources -o ` writes to a user-specified directory (NOT `base/out/` — that's for `comp build` output). - -```bash -azldev comp prep-sources -p --skip-overlays --force -o base/build/work/scratch/-pre -q -azldev comp prep-sources -p --force -o base/build/work/scratch/-post -q -diff -r base/build/work/scratch/-pre base/build/work/scratch/-post -``` - -### 3. Inspect the upstream spec/sources - -Look at the pre-overlay output dir — this is what the overlay is trying to modify. Common root cause: upstream changed and the overlay's assumptions no longer hold. - -## Common Failures - -### `spec-add-tag`: "tag already exists" - -The tag is already in the upstream spec. Fix: use `spec-set-tag` (replaces value if exists, adds if not) or `spec-update-tag` (replaces value, but fails if tag doesn't exist — use when you want to guarantee the tag was already present) instead. - -### `spec-search-replace`: no match - -The regex doesn't match anything in the spec. Causes: -- Upstream changed the line (check `/.spec`) -- Regex escaping issues — TOML basic strings need `\\` for literal backslash -- Use TOML literal strings (`'...'`) to avoid escaping: `regex = 'RPM_VENDOR=redhat'` -- **No multi-line regex** — `(?s)`/DOTALL is not supported. Use multiple targeted single-line replacements instead. - -### `spec-*-lines`: section not found - -The spec section (`%prep`, `%build`, `%install`, etc.) doesn't exist or has different casing. Check the actual section names in `/.spec`. - -### `file-*`: file not found - -The file doesn't exist in the upstream sources. Check `ls /` for actual filenames. Globs (`**/*`) are supported for `file-search-replace`. - -### Overlay applies but build still fails - -The overlay applied cleanly but the *result* is wrong. Compare `/.spec` against what you expect. Common issues: -- Regex matched more/fewer lines than intended (try to avoid regex, they are brittle) -- Replacement introduced syntax errors in the spec -- Missing dependency that the overlay was supposed to add - -For overlay type reference (all 12 types with key fields), see [`comp-toml.instructions.md`](../../instructions/comp-toml.instructions.md#overlay-types). Full schema: [`azldev.schema.json`](../../../external/schemas/azldev.schema.json). - -## Tips - -- **Test incrementally.** Apply one overlay at a time and verify with `prep-sources`. Debugging 10 overlays at once is painful. -- **Minimize overlays.** Each is a potential failure point. Prefer the smallest delta from upstream. -- **Verify in chroot.** If overlays apply but the build still fails, use [`skill-mock`](../skill-mock/SKILL.md) to inspect the build environment. -- **Follow the inner loop.** The full cycle is: investigate → modify → render → build → test → inspect. See [`skill-build-component`](../skill-build-component/SKILL.md) for details. -- **Smoke-test after fixing overlays.** A clean apply and successful build don't guarantee working RPMs. See [`skill-mock`](../skill-mock/SKILL.md). diff --git a/.github/skills/skill-mock/SKILL.md b/.github/skills/skill-mock/SKILL.md deleted file mode 100644 index ab262bbf93d..00000000000 --- a/.github/skills/skill-mock/SKILL.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: skill-mock -description: "[Skill] Test and inspect packages in Azure Linux mock chroots. Use when testing built RPMs, inspecting dependencies, debugging runtime issues, or verifying package contents. Triggers: test package, mock shell, inspect rpm, smoke test, chroot, verify build output." ---- - -# Test & Inspect in Mock Chroot - -> **Never install built RPMs on the host.** They target Azure Linux, not your dev machine. Use the methods below instead. - -## Resetting the Mock Chroot - -`azldev` has no built-in mock reset. Use `mock` directly when you need to clear stale state: - -```bash -# Clean just the chroot (fast, keeps bootstrap) -mock --quiet -r distro/mock/azurelinux-4.0-x86_64.cfg --configdir distro/mock --scrub=chroot - -# Nuclear — clean everything including bootstrap -mock --quiet -r distro/mock/azurelinux-4.0-x86_64.cfg --configdir distro/mock --scrub=all -``` - -## Non-Interactive Chroot (preferred for agents) - -Pipe commands via heredoc — fully autonomous, no user interaction needed: - -```bash -azldev adv mock shell --add-package /path/to/package.rpm <<'CMDS' - --version -echo "exit code: $?" -exit -CMDS -``` - -Use this for automated checks: running binaries, querying installed packages, inspecting paths. - -## Inspect RPM Without Installing (debug failed installs, examine contents) - -When `--add-package` fails, or you just want to inspect without installing, use `mock --copyin` to copy the RPM into the chroot and inspect it there: - -```bash -# Copy the RPM into the chroot (does NOT install it) -mock -r distro/mock/azurelinux-4.0-x86_64.cfg --configdir distro/mock \ - --copyin base/out/*.rpm /tmp/ - -# Enter the chroot and inspect -azldev adv mock shell <<'CMDS' -rpm -qip /tmp/*.rpm # package info -rpm -qlp /tmp/*.rpm # file list -rpm -qRp /tmp/*.rpm # dependencies -dnf install /tmp/*.rpm # retry install to see error details -exit -CMDS -``` - -This avoids installing on the host and gives you the full Azure Linux environment for debugging dependency issues, file conflicts, etc. - -## Interactive Chroot - -Use when you need to explore interactively or run multiple diagnostic commands: - -```bash -azldev adv mock shell --add-package /path/to/package.rpm --enable-network -``` - -### Agent workflow — follow these steps exactly: - -1. Run a simple command (e.g., `echo "ready"`) in a **non-background** terminal to establish the shared shell. -2. Ask the user to run the `azldev adv mock shell` command above **in that same terminal**. -3. Wait for the user to confirm they are in the mock shell. -4. Run diagnostic commands in the **same non-background terminal** — they execute inside the chroot. Do NOT use background terminals (`isBackground=true`) — you cannot send commands to them. -5. The Ctrl+C sent before each command is harmless — interactive shells trap SIGINT. -6. Run `exit` when done to leave the chroot. - -Prefer the non-interactive heredoc approach when possible. Use interactive only when you need to react to output between commands. - -## Key Flags - -| Flag | Purpose | -|------|---------| -| `-p`, `--add-package ` | Install a package into the chroot before entering. Accepts RPM file paths or package names. Can be repeated. | -| `--enable-network` | Allow network access (dependency resolution, downloads) | - -> ⚠️ **`-p` means `--add-package`, not component name.** Unlike `comp build -p `, `mock shell` has no component selector. The `-p` shorthand is `--add-package`. Passing `-p ` installs a package by name from configured repos — it does NOT set up a chroot with that component's build dependencies. - -## Gotchas - -- **Don't mix `-p ` with `--add-package /path/to/name.rpm` for the same package.** Since `-p` IS `--add-package`, passing both `-p cowsay --add-package ./cowsay.rpm` tells dnf to install the repo version AND your local RPM — two different builds of the same package, which conflicts. Use one or the other: - - `--add-package /path/to/rpm` to install your locally built RPM - - `-p ` to install a package by name from configured repos -- **Mock chroot is persistent.** State survives between `azldev adv mock shell` sessions — installed packages, created files, etc. all persist. This is useful (install once, re-enter later) but can cause confusion from stale state. Use `mock --scrub=chroot` to reset when needed (see "Resetting the Mock Chroot" above). -- **Use a temp dir for `prep-sources` output.** Use `--force` to overwrite an existing output dir. Note that `prep-sources -o ` writes to a user-specified dir, NOT `base/out/` (that's for `comp build` output). -- **One mock session per terminal.** If a terminal is already inside mock shell, running `azldev adv mock shell` again will fail. Run `exit` first. -- **`advanced` is hidden.** `azldev adv` (alias for `advanced`) doesn't appear in `azldev --help` but contains `mock shell`, `mock build-rpms`, `mcp`, and `wget`. diff --git a/.github/skills/skill-remove-component/SKILL.md b/.github/skills/skill-remove-component/SKILL.md deleted file mode 100644 index 13c17df7188..00000000000 --- a/.github/skills/skill-remove-component/SKILL.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -name: skill-remove-component -description: "[Skill] Remove components from Azure Linux. Use when deleting packages, cleaning up unused dependencies, or pruning the distro. Triggers: remove component, delete package, drop component, prune dependency." ---- - -# Remove a Component - -## Before You Start - -Verify the component exists and understand what it produces: - -```bash -azldev comp list -p -q -O json -``` - -Then check for all artifacts that need to be removed: - -1. Component definition — `base/comps/components.toml` (inline) or `base/comps//.comp.toml` (dedicated) -2. Publish-channel references — `base/comps/components-publish-channels.toml` (component name in `component-groups.base-packages.components`, plus any per-binary entries in `package-groups.exceptions-packages.packages`) -3. Lock file — `locks/.lock` -4. Rendered specs — `specs///` -5. Other references — image definitions (`base/images/`), `comps.xml`, etc. - -## Removal Steps - -### 1. Remove the component definition - -- **Inline entry**: remove `[components.]` from `base/comps/components.toml` -- **Dedicated directory**: delete `base/comps//` (contains `.comp.toml` and possibly local spec/sources) - -### 2. Remove publish-channel references - -Publishing is configured per *component* (not per binary subpackage) in `base/comps/components-publish-channels.toml`. For each component being removed: - -- Remove its entry from the `components = [...]` array in `[component-groups.base-packages]` if present (otherwise it inherits the project-wide `sdk` default and needs no edit there). -- Remove any per-binary carve-outs for its subpackages from `[package-groups.exceptions-packages].packages`. Exception lines carry a `# srpm: ` trailing comment — grep that to find them all: - -```bash -grep "srpm: " base/comps/components-publish-channels.toml -``` - -Remove every matching line. When removing many components at once, editing by hand is error-prone — prefer using your editor's multi-cursor or find-and-replace to remove all lines matching the SRPM name. - -### 3. Remove the lock file - -```bash -rm locks/.lock -``` - -There is no `azldev` command for this — manual deletion is the only way. - -### 4. Remove rendered specs - -The preferred approach is to let `azldev` handle cleanup after removing the component definition: - -```bash -azldev comp render -a --clean-stale -``` - -This re-renders all components and removes spec directories for components that no longer exist. It's slow (renders everything), but is the most reliable method. - -For targeted removal when you don't want to re-render everything: - -```bash -rm -rf specs/// -``` - -### 5. Check for other references - -Search for the component name in image definitions, kiwi files, and other config: - -```bash -grep -rn "" base/images/ base/comps/comps.xml -grep -rn "" --include="*.kiwi" . -``` - -Kiwi files (`*.kiwi`) define image package lists — if any subpackage produced by the component is referenced there, it must be removed or replaced before the component can be dropped. - -## Verify - -After removal, confirm nothing was missed: - -```bash -azldev comp list -p -q -O json # should fail with "component not found" -grep -n "\"\"\|srpm: " base/comps/components-publish-channels.toml # should return nothing -ls locks/.lock specs/*// 2>/dev/null # should return nothing -grep -rn "" --include="*.kiwi" . # should return nothing -``` - -## Notes - -- **Check for reverse dependencies** before removing a component. If other components depend on it (via `BuildRequires` or `Requires`), removing it will break their builds. -- **When modifying dependants, check their release calculation.** If you disable a feature or remove a `BuildRequires` from a dependant component that uses `release = { calculation = "manual" }`, you must also bump its release counter (e.g., increment the `azl_release` define). Components with automatic release calculation (`auto`, `static`, `autorelease`) handle this via the commit-render-amend cycle, but manual-release components do not. -- **Publishing is component-scoped, exceptions are binary-scoped.** The `base-packages` group lists *component* names; the `exceptions-packages` group lists *binary RPM* names with `# srpm: ` comments. Always search by `# srpm:` comment rather than guessing suffix patterns. -- **This is a metadata-only change.** No builds or tests are needed — the component is simply being dropped from the distro definition. -- **When removing a component and its exclusive dependencies** (packages only needed by the component being removed), remove them all in the same change to keep the tree consistent. diff --git a/.github/skills/skill-review-component/SKILL.md b/.github/skills/skill-review-component/SKILL.md deleted file mode 100644 index 36521d0d0d5..00000000000 --- a/.github/skills/skill-review-component/SKILL.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -name: skill-review-component -description: "[Skill] Review an Azure Linux component definition for hygiene and best practices. Use when reviewing comp.toml files, checking overlay quality, validating file organization, or auditing component definitions. Triggers: review component, check hygiene, audit component, validate comp.toml, component review. NOTE: This skill is a work-in-progress — the checklist below covers basics but the full review workflow is still being refined." ---- - -# Review a Component - -## Review Checklist - -### 1. Query the component - -```bash -azldev comp list -p -q -O json -``` - -Review the resolved output for correctness, then dig deeper with query (it's slow since it parses the spec in mock): - -```bash -azldev comp query -p -q -O json -``` - -### 2. File organization - -- Components with overlays or any customization SHOULD have a dedicated `/.comp.toml` file -- Component names should match the upstream package name; use `upstream-name` when they differ -- No stale or orphaned files in the component directory - -### 3. Overlay quality - -- Every overlay MUST have a `description` field explaining *why* the change is needed -- Prefer targeted overlay types (`spec-set-tag`, `spec-add-tag`) over regex (`spec-search-replace`) where possible - - Regex overlays should be a last resort and must be carefully reviewed for correctness and potential unintended matches. Almost always prefer more specific overlay types that target the exact change needed, rather than broad regex patterns that could match multiple unintended places in the spec on future updates etc. -- When `spec-search-replace` is unavoidable, **make every effort to always scope it** with `section` and/or `package` fields to limit where the regex can match. For example, a replacement targeting a `%files` entry in a sub-package should set `section = "%files"` and `package = ""` (the short sub-package suffix as it appears in the spec header, e.g. `"foo"` for `%files foo`, not `"mypkg-foo"`). Unscoped regex overlays are fragile and may silently match unintended lines after upstream updates. -- No multi-line regex patterns (unsupported) -- Use TOML literal strings (`'...'`) for regex to avoid escaping issues -- No unnecessary overlays — if upstream already provides what's needed, don't overlay it - -### 4. Naming conventions - -- Component name matches upstream package name -- `upstream-name` is set when the component name differs from upstream (e.g., `azurelinux-rpm-config` with `upstream-name = "redhat-rpm-config"`) - -### 5. Build configuration - -- `build.defines` and `build.without` are used appropriately -- No unnecessary build overrides -- Conditional builds (`build.without`) match available spec conditionals -- **`%check` disabled?** If `build.without` includes `"check"`, flag as a **Warning** — disabling tests is an absolute last resort. Verify that a `skip_reason` is present and clearly explains why the tests cannot be fixed. If the justification is missing or weak, recommend re-enabling `%check` and fixing the underlying test failures instead. -- **`release.calculation = "manual"`?** Verify it's actually needed and has a matching `spec-set-tag` overlay for Release. See [Release Configuration](../../instructions/comp-toml.instructions.md#release-configuration). -- **`release.calculation = "autorelease"`?** Verify the upstream spec actually uses conditional `%autorelease` (e.g., `%if %{defined autorelease}`). If not conditional, `auto` should suffice. - -### 6. Source configuration - -- Spec source type is appropriate (upstream default vs pinned version vs local spec) -- Pinned versions have a reason (comment or overlay description) -- Local specs are a last resort and clearly justified - -### 7. Testing verification - -- If the change could affect built RPMs, verify they were tested — not just built -- Pure organizational changes (moving definitions, editing comments) don't need a rebuild - -## Output - -Produce a structured report grouped by severity: - -- **Errors:** Must-fix issues (missing overlay descriptions, broken patterns) -- **Warnings:** Should-fix issues (suboptimal overlay types, naming mismatches) -- **Info:** Suggestions and best practices - -## Scope of Changes - -If the review includes a subset of the file (i.e., git diff), focus on that subset but also consider the overall context to ensure changes fit well with the existing structure and conventions. Offer actionable recommendations for any issues with the changes, but also consider if there are broader improvements that could be made to the component definition as a whole. The goal should be to minimize changes while maximizing maintainability and adherence to best practices. This is a balance - if the proposed change aligns with the existing structure and conventions, it's likely better to keep it as-is even if it's not perfect, rather than suggesting a large refactor that may introduce new issues or require additional testing. However, if the fix would be fairly small and would improve the overall quality and maintainability of the component, it's worth suggesting. Use your judgement to weigh the benefits of the change against the potential risks and effort involved in both making the changes, testing them, and getting final review sign-off from the maintainers (who will likely prefer smaller, incremental improvements over large refactors, especially if the current structure is already reasonably good and the proposed change is more of a "nice to have" than a "must have"). diff --git a/.github/skills/skill-update-component/SKILL.md b/.github/skills/skill-update-component/SKILL.md deleted file mode 100644 index daf489651fb..00000000000 --- a/.github/skills/skill-update-component/SKILL.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -name: skill-update-component -description: "[Skill] Refresh component lock files with `azldev comp update`. Use when finalizing a component change for PR, bumping an upstream commit pin, or investigating lock-drift CI failures. Triggers: comp update, refresh lock, bump pin, lock drift, version bump, finalize component change." ---- - -# Update Component Lock Files - -`azldev comp update` refreshes one or more component lock files in `locks/`. A lock file pins the upstream commit + an input fingerprint computed from the component's TOML config; if either changes, the lock is stale and the `Update Locks` CI check fails. - -## When to run it - -| Situation | Run `update`? | -|-----------|---------------| -| Finalizing any component change for PR | **Yes** — once at the end | -| Bumping an upstream commit pin | **Yes** — also mid-workflow (see below) | -| Iterative overlay/build-config/metadata edits | No — `render` alone is enough during iteration *See section on changelog/release quirks in the pin-bump workflow below* | -| Just reading or building existing components | No | - -> **Always re-run `update` before opening a PR**, even if all you did was tweak an overlay description. The fingerprint is computed from the full component config, so any TOML change may invalidate the lock. - -## End-of-work refresh (the common case) - -For most component edits — overlays, build flags, metadata, descriptions — run `update` once at the end, then re-render *after committing* so the changelog and release reflect your new commit. - -```bash -azldev comp update -p -azldev comp render -p -git add base/comps// locks/.lock specs/// -git commit -m "fix(pkg): Fix bug" - -# Now re-render and amend so %changelog / Release: track the new commit. -azldev comp render -p -git add specs/// -git commit --amend --no-edit -``` - -### Why the second render-and-amend? - -> **`%changelog` and `Release:` are derived from `git log` for the component, not from the working tree.** rpmautospec walks the commit history every time it renders. The first render happens before your commit exists, so it produces a spec keyed off `HEAD`. The moment you `git commit`, the rendered output drifts — a fresh render will add a new `%changelog` entry for your commit and bump the `Release:` integer. Without the post-commit re-render and amend, the `Check Rendered Specs` CI check will fail with that exact diff. - -This applies to **every** commit that touches a component or its lock -- pin bumps, overlay tweaks, build-config changes, metadata edits. There's nothing special about pin bumps. - -During iterative work (before any commit) the changelog/release fields are not expected to track the working tree. Only worry about the post-commit re-render once you're finalizing for a PR. - -> **Manual release components:** Keep the same post-commit re-render/amend workflow when finalizing, because rpmautospec-generated `%changelog` can still drift after you commit. The difference is that components with `release = { calculation = "manual" }` do **not** get their `Release:` value bumped automatically by that cycle. When modifying such a component, you must **manually increment** its release counter in the same change (for example via an `azl_release` define or a `spec-set-tag` overlay value). Check the component's `release.calculation` field before finalizing — if it's `manual`, do the re-render/amend step and bump the release counter yourself. - -## Bumping an upstream commit pin - -Pin bumps follow the same rule as every other change: the changelog/release fields are derived from `git log`, so you need a post-commit re-render. The pin-bump variant just splits the work across two commits (lock first, then iterate, then amend), and adds an *extra* up-front `update` to move the pin. - -> **Recap:** automatic changelog and release calculations are derived from `git log` for the component. Commit pinning works fine off the working-tree lock, so the spec body tracks the new pin immediately after `update` + `render`. But the changelog entry and release number won't reflect your work until your commit lands on the branch and you re-render. Don't panic if a freshly-bumped pin's changelog still shows the old version mid-loop -- iterate as needed, commit the lock, then re-render to see the final changelog and release. - -### Inner loop for a pin bump - -``` -update → render → iterate → commit lock → render → amend -``` - -1. **Bump the pin** - - Update a pinned commit, or a snapshot time, then update: - - ```bash - azldev comp update -p - git diff locks/.lock # sanity check the new upstream commit - ``` - -2. **Render** - - ```bash - azldev comp render -p - ``` - - Spec body tracks the new pin. `%changelog` / `Release:` still reflect the previous lock — that's expected, your bump isn't committed yet. - -3. **Iterate** - Adjust overlays/patches/build config as the new upstream version requires. Re-render after each change. - - Re-running update is likely unnecessary during this iteration phase — the working-tree lock already reflects the new upstream commit, and `render` will show the spec body changes immediately. Only re-run `update` if you make changes that would affect the pinned commit itself (for example, changing the upstream commit hash or snapshot time) — otherwise `render` alone is sufficient to see the spec body changes. - -4. **Commit the lock** - - ```bash - azldev comp update -p - git add locks/.lock - git commit -m "chore(pkg): update to " - ``` - -5. **Re-render** — now `%changelog` / `Release:` reflect the new lock. - - ```bash - azldev comp render -p - ``` - -6. **Amend** so the lock bump and rendered spec land in a single commit. Stage the whole component directory — render can touch nested sidecars (`.fmf`, `.azl.macros`, etc.) alongside `.spec`: - - ```bash - git add specs/// - git commit --amend --no-edit - ``` - -## CI gotcha - -`Check Rendered Specs` and `Update Locks` both run against the **PR's committed state**, not the working tree. The end-of-work refresh (or the amend in step 6 of a pin bump) is what keeps both checks green together — without it, render check would flag a stale changelog or lock check would flag a stale fingerprint. - -## When to use `-a` - -Wholesale lock refresh is slow. Use it only when: - -- Doing a coordinated mass-bump (e.g., refreshing everything against a new Fedora snapshot). -- Investigating CI lock-drift failures that span many components. - -For day-to-day work, always use `-p `. - -## Lock Debugging - -The update command supports `-O json` for easier reading of the output. - -## Related - -- [`skill-build-component`](../skill-build-component/SKILL.md) — the standard `edit → render → build → test` loop. `update` is the finalizing step on top of that loop. -- [`skill-fix-overlay`](../skill-fix-overlay/SKILL.md) — when bumping a pin breaks an existing overlay. -- [`skill-mock`](../skill-mock/SKILL.md) — smoke-testing built RPMs after a pin bump. diff --git a/.vscode/mcp.json b/.vscode/mcp.json index 0b7d49ba19d..c298e2bc8a7 100644 --- a/.vscode/mcp.json +++ b/.vscode/mcp.json @@ -1,73 +1,81 @@ { - "servers": { - "koji": { - "type": "stdio", - "command": "python3", - "args": [ - "scripts/mcps/koji-mcp.py" - ] - }, - "fedora-distgit": { - "type": "stdio", - "command": "python3", - "args": [ - "scripts/mcps/fedora-distgit-mcp.py" - ] - }, - "azure-mcp-server": { - "type": "stdio", - "command": "npx", - "args": [ - "-y", - "@azure/mcp@latest", - "server", - "start", - "--tool", - "monitor_metrics_definitions", - "--tool", - "monitor_metrics_query", - "--tool", - "monitor_workspace_log_query", - "--tool", - "monitor_activitylog_list", - "--tool", - "monitor_resource_log_query", - "--tool", - "monitor_table_list", - "--tool", - "aks_cluster_get", - "--tool", - "aks_nodepool_get" - ], - "env": { - "AZURE_TOKEN_CREDENTIALS": "AzureCliCredential" - } - }, - "microsoft/azure-devops-mcp": { - "type": "stdio", - "command": "npx", - "args": [ - "-y", - "@azure-devops/mcp@latest", - "${input:ado_org}", - "-d", - "${input:ado_domain}" - ], - "gallery": "https://api.mcp.github.com", - "version": "1.0.0" - } - }, - "inputs": [ - { - "id": "ado_org", - "type": "promptString", - "description": "Azure DevOps organization name (e.g. 'contoso')" - }, - { - "id": "ado_domain", - "type": "promptString", - "description": "Repeat to enable specific domains: core, work, work-items, search, test-plans, repositories, wiki, pipelines, advanced-security.", - "password": false - } - ] + "inputs": [ + { + "description": "Azure DevOps organization name (e.g. 'contoso')", + "id": "ado_org", + "type": "promptString" + }, + { + "description": "Repeat to enable specific domains: core, work, work-items, search, test-plans, repositories, wiki, pipelines, advanced-security.", + "id": "ado_domain", + "password": false, + "type": "promptString" + } + ], + "servers": { + "azldev": { + "args": [ + "advanced", + "mcp" + ], + "command": "azldev", + "type": "stdio" + }, + "azure-mcp-server": { + "args": [ + "-y", + "@azure/mcp@latest", + "server", + "start", + "--tool", + "monitor_metrics_definitions", + "--tool", + "monitor_metrics_query", + "--tool", + "monitor_workspace_log_query", + "--tool", + "monitor_activitylog_list", + "--tool", + "monitor_resource_log_query", + "--tool", + "monitor_table_list", + "--tool", + "aks_cluster_get", + "--tool", + "aks_nodepool_get" + ], + "command": "npx", + "env": { + "AZURE_TOKEN_CREDENTIALS": "AzureCliCredential" + }, + "type": "stdio" + }, + "fedora-distgit": { + "args": [ + "scripts/mcps/fedora-distgit-mcp.py" + ], + "command": "python3", + "type": "stdio" + }, + "koji": { + "args": [ + "scripts/mcps/koji-mcp.py" + ], + "command": "python3", + "type": "stdio" + }, + "microsoft/azure-devops-mcp": { + "args": [ + "-y", + "@azure-devops/mcp@latest", + "${input:ado_org}", + "-d", + "${input:ado_domain}" + ], + "command": "npx", + "gallery": "https://api.mcp.github.com", + "type": "stdio", + "version": "1.0.0" + } + } } diff --git a/AGENTS.md b/AGENTS.md index 529cc846e76..d1b3b6ea09b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ For project context and architecture, see [`.github/copilot-instructions.md`](.g ## Mandatory Testing -> **USE YOUR BEST JUDGEMENT**, but when in doubt, test. If your change could affect the built RPMs, smoke-test before reporting success. See [`skill-mock`](.github/skills/skill-mock/SKILL.md). +> **USE YOUR BEST JUDGEMENT**, but when in doubt, test. If your change could affect the built RPMs, smoke-test before reporting success. See [`azldev-mock`](.agents/skills/azldev-mock/SKILL.md). ### Examples of changes that should trigger a final test prior to sign-off (not an exhaustive list) @@ -24,8 +24,8 @@ For project context and architecture, see [`.github/copilot-instructions.md`](.g ### Minimum required testing 1. **Build** — `azldev comp build -p ` succeeds, RPMs appear in `base/out/`. -2. **Inspect** — Use `mock --copyin` to copy the RPM into the chroot and inspect with `rpm -qlp` without installing. See [`skill-mock`](.github/skills/skill-mock/SKILL.md). -3. **Smoke-test** — Use a mock chroot (`azldev adv mock shell --add-package /path/to/rpm`) to install and validate basic functionality (e.g., ` --version`, service starts, library loads). See [`skill-mock`](.github/skills/skill-mock/SKILL.md). +2. **Inspect** — Use `mock --copyin` to copy the RPM into the chroot and inspect with `rpm -qlp` without installing. See [`azldev-mock`](.agents/skills/azldev-mock/SKILL.md). +3. **Smoke-test** — Use a mock chroot (`azldev adv mock shell --add-package /path/to/rpm`) to install and validate basic functionality (e.g., ` --version`, service starts, library loads). See [`azldev-mock`](.agents/skills/azldev-mock/SKILL.md). Do NOT skip testing for changes that affect RPM output. Do NOT tell the user "the build succeeded" without also running the smoke-test. If testing cannot be performed (e.g., the package has no runnable binary, or some other issue), explicitly document why and what was verified instead. @@ -35,10 +35,10 @@ Do NOT skip testing for changes that affect RPM output. Do NOT tell the user "th - Prefer overlays over forking/local specs when customizing upstream packages. - After modifying overlays or component config, re-render with `azldev comp render -p ` and inspect `specs///` to verify the result. This is the fastest verification path. - Note: Changing a global snapshot time may affect all components that depend on it, potentially causing widespread rebuilds. Full re-render is time-consuming, but may be done by `azldev comp render -a --clean-stale`. -- **Always re-run `azldev comp update -p ` before opening a PR**, even for minor edits — lock fingerprints are computed from the full component config, and the `Update Locks` CI check runs against the committed state. See [`skill-update-component`](.github/skills/skill-update-component/SKILL.md). -- **Every commit that touches a component bumps `%changelog` / `Release:` on the next render** (rpmautospec walks `git log` for the spec). After committing, re-render and amend so the spec tracks your commit, otherwise `Check Rendered Specs` will fail. See [`skill-update-component`](.github/skills/skill-update-component/SKILL.md) for the finalize-and-amend pattern, plus the pin-bump variant. +- **Always re-run `azldev comp update -p ` before opening a PR**, even for minor edits — lock fingerprints are computed from the full component config, and the `Update Locks` CI check runs against the committed state. See [`azldev-update-component`](.agents/skills/azldev-update-component/SKILL.md). +- **Every commit that touches a component bumps `%changelog` / `Release:` on the next render** (rpmautospec walks `git log` for the spec). After committing, re-render and amend so the spec tracks your commit, otherwise `Check Rendered Specs` will fail. See [`azldev-update-component`](.agents/skills/azldev-update-component/SKILL.md) for the finalize-and-amend pattern, plus the pin-bump variant. - Use `prep-sources` for deeper debugging: `azldev comp prep-sources -p --skip-overlays --force -o -q` and `azldev comp prep-sources -p --force -o -q` to diff pre/post overlay output when you need to understand what upstream provides vs. what overlays change. Always use `--force` to overwrite an existing output dir, `rm -rf` requires user confirmation which is disruptive. -- Follow the inner loop cycle: investigate → modify → render → build → test → inspect. See [`skill-build-component`](.github/skills/skill-build-component/SKILL.md). +- Follow the inner loop cycle: investigate → modify → render → build → test → inspect. See [`azldev-build-component`](.agents/skills/azldev-build-component/SKILL.md). - Note: Use your best judgement, some packages are VERY slow to build (e.g., `kernel`), in those cases you may want to do multiple iterations of investigate → modify → verify with `render` before doing a full build + test. - `prep-sources -o ` output is ad-hoc (user-chosen dir). `comp build` output goes to project-configured dirs (`base/out/`, `base/build/`). Don't conflate them. - For temporary files, ensure they are all placed inside the project's defined work directory (`azldev config dump -q -f json 2>&1 | grep 'workDir'`). Example commands use `base/build/work/scratch/`, and all temp directories should be inside it unless there's a specific reason not to be. @@ -53,21 +53,21 @@ Detailed workflows live in skills (loaded on-demand when relevant): | Task | Skill | | ---- | ----- | -| Build a component, debug build failures | [`skill-build-component`](.github/skills/skill-build-component/SKILL.md) | -| Bump a component's upstream pin (lock files) | [`skill-update-component`](.github/skills/skill-update-component/SKILL.md) | -| Add a new component to the distro | [`skill-add-component`](.github/skills/skill-add-component/SKILL.md) | -| Remove component(s) from the distro | [`skill-remove-component`](.github/skills/skill-remove-component/SKILL.md) | -| Diagnose and fix overlay issues | [`skill-fix-overlay`](.github/skills/skill-fix-overlay/SKILL.md) | -| Test and inspect packages in mock chroot | [`skill-mock`](.github/skills/skill-mock/SKILL.md) | -| Review component for hygiene and best practices | [`skill-review-component`](.github/skills/skill-review-component/SKILL.md) | -| Triage Koji build failures | [`skill-koji-triage`](.github/skills/skill-koji-triage/SKILL.md) | -| Batch-triage build failures from results file | [`skill-mass-triage`](.github/skills/skill-mass-triage/SKILL.md) | -| Inspect Koji AKS cluster health and node pools | [`skill-aks-health`](.github/skills/skill-aks-health/SKILL.md) | -| Resolve Koji AKS deployment context | [`skill-deployment-context`](.github/skills/skill-deployment-context/SKILL.md) | -| KQL queries for Koji logs, pods, and events | [`skill-kql-queries`](.github/skills/skill-kql-queries/SKILL.md) | -| Query Azure Monitor metrics for Koji AKS | [`skill-metrics`](.github/skills/skill-metrics/SKILL.md) | - -> **Azure infra workflow ordering:** Before running any KQL log queries, metrics queries, or AKS health checks, **always resolve deployment context first** using [`skill-deployment-context`](.github/skills/skill-deployment-context/SKILL.md). This provides the resource group, cluster name, subscription, and Log Analytics workspace needed by the other Azure skills. +| Build a component, debug build failures | [`azldev-build-component`](.agents/skills/azldev-build-component/SKILL.md) | +| Bump a component's upstream pin (lock files) | [`azldev-update-component`](.agents/skills/azldev-update-component/SKILL.md) | +| Add a new component to the distro | [`azldev-add-component`](.agents/skills/azldev-add-component/SKILL.md) | +| Remove component(s) from the distro | [`azldev-remove-component`](.agents/skills/azldev-remove-component/SKILL.md) | +| Diagnose and fix overlay issues | [`azldev-overlays`](.agents/skills/azldev-overlays/SKILL.md) | +| Test and inspect packages in mock chroot | [`azldev-mock`](.agents/skills/azldev-mock/SKILL.md) | +| Review component for hygiene and best practices | [`azldev-comp-toml`](.agents/skills/azldev-comp-toml/SKILL.md) | +| Triage Koji build failures | [`skill-koji-triage`](.agents/skills/skill-koji-triage/SKILL.md) | +| Batch-triage build failures from results file | [`skill-mass-triage`](.agents/skills/skill-mass-triage/SKILL.md) | +| Inspect Koji AKS cluster health and node pools | [`skill-aks-health`](.agents/skills/skill-aks-health/SKILL.md) | +| Resolve Koji AKS deployment context | [`skill-deployment-context`](.agents/skills/skill-deployment-context/SKILL.md) | +| KQL queries for Koji logs, pods, and events | [`skill-kql-queries`](.agents/skills/skill-kql-queries/SKILL.md) | +| Query Azure Monitor metrics for Koji AKS | [`skill-metrics`](.agents/skills/skill-metrics/SKILL.md) | + +> **Azure infra workflow ordering:** Before running any KQL log queries, metrics queries, or AKS health checks, **always resolve deployment context first** using [`skill-deployment-context`](.agents/skills/skill-deployment-context/SKILL.md). This provides the resource group, cluster name, subscription, and Log Analytics workspace needed by the other Azure skills. ## Directory Guidance diff --git a/base/comps/AGENTS.md b/base/comps/AGENTS.md index 20f79a12e72..9213ac561ac 100644 --- a/base/comps/AGENTS.md +++ b/base/comps/AGENTS.md @@ -9,8 +9,8 @@ ## Skills -- Adding a new component → [`skill-add-component`](../../.github/skills/skill-add-component/SKILL.md) -- Removing component(s) → [`skill-remove-component`](../../.github/skills/skill-remove-component/SKILL.md) -- Fixing overlay issues → [`skill-fix-overlay`](../../.github/skills/skill-fix-overlay/SKILL.md) -- Building and debugging → [`skill-build-component`](../../.github/skills/skill-build-component/SKILL.md) -- Testing in mock chroot → [`skill-mock`](../../.github/skills/skill-mock/SKILL.md) +- Adding a new component → [`azldev-add-component`](../../.agents/skills/azldev-add-component/SKILL.md) +- Removing component(s) → [`azldev-remove-component`](../../.agents/skills/azldev-remove-component/SKILL.md) +- Fixing overlay issues → [`azldev-overlays`](../../.agents/skills/azldev-overlays/SKILL.md) +- Building and debugging → [`azldev-build-component`](../../.agents/skills/azldev-build-component/SKILL.md) +- Testing in mock chroot → [`azldev-mock`](../../.agents/skills/azldev-mock/SKILL.md) diff --git a/base/comps/exfatprogs/modify_source.sh b/base/comps/exfatprogs/modify_source.sh index eead224a5a6..b82cdd3db1e 100755 --- a/base/comps/exfatprogs/modify_source.sh +++ b/base/comps/exfatprogs/modify_source.sh @@ -2,7 +2,7 @@ # # exfatprogs: deterministic strip-and-repack of upstream `exfatprogs-1.3.1.tar.xz` # with the `tests/` directory removed. Rationale lives in the comp.toml -# `replace-reason` field; see also `.github/skills/skill-modify-source/SKILL.md`. +# `replace-reason` field. # # Usage: bash base/comps/exfatprogs/modify_source.sh # Output: base/build/work/scratch/exfatprogs/exfatprogs-1.3.1.tar.xz (+ .sha512) diff --git a/docs/prds/agent-instructions.prd.md b/docs/prds/agent-instructions.prd.md index ccd0d9ce2d6..8dfc2af5ae3 100644 --- a/docs/prds/agent-instructions.prd.md +++ b/docs/prds/agent-instructions.prd.md @@ -42,7 +42,7 @@ Instruction files should work across GitHub Copilot surfaces where possible: VS | --------- | --------- | ------------------ | | `.github/copilot-instructions.md` | Auto | VS Code, Visual Studio, GitHub.com, Copilot CLI | | `AGENTS.md` (root and subdirectories) | Auto | VS Code, Copilot CLI | -| Agent Skills (`.github/skills/*/SKILL.md`) | On-demand (description match) | VS Code, Copilot CLI, Copilot coding agent ([open standard](https://agentskills.io/)) | +| Agent Skills (`.agents/skills/*/SKILL.md`) | On-demand (description match) | VS Code, Copilot CLI, Copilot coding agent ([open standard](https://agentskills.io/)) | | `.github/instructions/*.instructions.md` | Auto (via `applyTo` globs) | VS Code, Copilot CLI | | `.github/agents/*.agent.md` | User-selected / inferred | VS Code, Copilot CLI | | `.github/prompts/*.prompt.md` | User-invoked (`/command`) | VS Code only | @@ -76,7 +76,7 @@ Instruction files should work across GitHub Copilot surfaces where possible: VS - `distro/AGENTS.md` - Distro configuration guidance (build defaults, shared config) - **Design principle:** AGENTS.md files should be short guardrail documents — conventions and "do/don't" rules. Detailed workflows and examples belong in skills or `.instructions.md` files. -4. **Agent Skills** (`.github/skills/*/SKILL.md`) — *cross-platform ([open standard](https://agentskills.io/))* +4. **Agent Skills** (`.agents/skills/*/SKILL.md`) — *cross-platform ([open standard](https://agentskills.io/))* - `azl-add-component/SKILL.md` - Adding a new component to the distro - `azl-fix-overlay/SKILL.md` - Diagnosing and fixing overlay issues - `azl-build-component/SKILL.md` - Building, testing, and debugging components @@ -122,8 +122,9 @@ azurelinux/ │ ├── prompts/ # Prompt templates (VS Code only) │ │ ├── azl-add-component.prompt.md │ │ └── ... -│ ├── agents/ # Custom agents (cross-platform) -│ │ └── *.agent.md +│ └── agents/ # Custom agents (cross-platform) +│ └── *.agent.md +├── .agents/ │ └── skills/ # Agent Skills (cross-platform, open standard) │ ├── azl-add-component/ │ │ └── SKILL.md @@ -150,7 +151,7 @@ azurelinux/ Based on research and practical experimentation, we use a passive-first approach: domain knowledge is placed where agents receive it automatically, while skills handle explicit task workflows. | Content type | Mechanism | Why | -|---|---|---| +| --- | --- | --- | | Project overview, key concepts, CLI reference | `copilot-instructions.md` | Always needed; not in model training data | | Guardrails ("overlays need descriptions", "don't edit build/") | `AGENTS.md` | Short rules, always enforced near relevant directories | | Structural patterns (TOML syntax, valid overlay shapes, examples) | `.instructions.md` with `applyTo` globs | Passive context fired by file type — no agent decision point | @@ -553,7 +554,7 @@ Both cover similar topics but serve different purposes. Skills answer "how does - [x] Create `AGENTS.md` (root) — lean: conventions, skill table, directory pointers - [x] Create `base/comps/AGENTS.md` — lean: file organization rules, skill pointers - [x] Create `distro/AGENTS.md` — build defaults, structure overview, shared config warning -- [x] Create skill stubs (`.github/skills/azl-{add-component,fix-overlay,build-component,mock,review-component}/SKILL.md`) +- [x] Create skill stubs (`.agents/skills/azl-{add-component,fix-overlay,build-component,mock,review-component}/SKILL.md`) ### Phase 2: Agent Skills (cross-platform, open standard) @@ -561,11 +562,11 @@ Each skill is a directory with a `SKILL.md` file following the [Agent Skills sta Skills are for explicit task workflows only — domain knowledge goes in passive context (Phase 1 + Phase 3). -- [x] Create `.github/skills/azl-build-component/SKILL.md` (full content) -- [x] Flesh out `.github/skills/azl-add-component/SKILL.md` -- [x] Flesh out `.github/skills/azl-fix-overlay/SKILL.md` -- [x] Create `.github/skills/azl-mock/SKILL.md` (mock chroot testing and inspection) -- [ ] Flesh out `.github/skills/azl-review-component/SKILL.md` (component hygiene review) +- [x] Create `.agents/skills/azl-build-component/SKILL.md` (full content) +- [x] Flesh out `.agents/skills/azl-add-component/SKILL.md` +- [x] Flesh out `.agents/skills/azl-fix-overlay/SKILL.md` +- [x] Create `.agents/skills/azl-mock/SKILL.md` (mock chroot testing and inspection) +- [ ] Flesh out `.agents/skills/azl-review-component/SKILL.md` (component hygiene review) - [x] Write clear `description` fields with trigger phrases so Copilot can match skills to user requests - [x] Link skills from `AGENTS.md` files for discoverability @@ -606,11 +607,11 @@ Agents are `.agent.md` files in `.github/agents/`. Both VS Code and Copilot CLI - [ ] Implement 0-2 agents based on evaluation - [ ] If multiple agents, consider handoffs between them for workflow continuity -### Phase 6: MCP and VS Code Integration (VS Code only) +### Phase 6: MCP and VS Code Integration -- [ ] Create `.vscode/mcp.json` configuration for azldev MCP tools +- [x] Create `.vscode/mcp.json` configuration for VS Code MCP tools - [ ] Document MCP tool usage in instructions once end-to-end flow is complete -- [ ] If Copilot CLI gains MCP support, evaluate a cross-platform MCP config location +- [ ] Package cross-repository distribution through a Copilot plugin marketplace ## Areas to Revisit Regularly From dfeea94bcc99b5a892d283c359018f77d897dd00 Mon Sep 17 00:00:00 2001 From: Daniel McIlvaney Date: Fri, 10 Jul 2026 11:38:10 -0700 Subject: [PATCH 2/4] fixup! docs(ai): move to new azldev emitted instructions and skills, add azldev mcp --- .agents/skills/azldev-add-component/SKILL.md | 2 +- .../skills/azldev-build-component/SKILL.md | 2 +- .agents/skills/azldev-comp-toml/SKILL.md | 2 +- .agents/skills/azldev-image/SKILL.md | 2 +- .agents/skills/azldev-mock/SKILL.md | 2 +- .agents/skills/azldev-overlays/SKILL.md | 2 +- .../skills/azldev-remove-component/SKILL.md | 2 +- .../skills/azldev-update-component/SKILL.md | 5 +- .agents/skills/azldev/SKILL.md | 2 +- .github/instructions/azldev.instructions.md | 2 +- .../instructions/comp-toml.instructions.md | 2 +- .../rendered-specs.instructions.md | 12 +-- .mcp.json | 81 +++++++++++++++++++ 13 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 .mcp.json diff --git a/.agents/skills/azldev-add-component/SKILL.md b/.agents/skills/azldev-add-component/SKILL.md index 70a92017e42..1635c5b5aef 100644 --- a/.agents/skills/azldev-add-component/SKILL.md +++ b/.agents/skills/azldev-add-component/SKILL.md @@ -80,4 +80,4 @@ smoke test — see the `azldev-build-component` and `azldev-mock` skills. After re-run `azldev comp update -p ` to finalize the lock before a PR (see the `azldev-update-component` skill). -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-build-component/SKILL.md b/.agents/skills/azldev-build-component/SKILL.md index 115ce8bd85b..d1b2ca10154 100644 --- a/.agents/skills/azldev-build-component/SKILL.md +++ b/.agents/skills/azldev-build-component/SKILL.md @@ -57,4 +57,4 @@ Finalize with `azldev comp update -p ` before opening a PR (see the Per-component build tweaks (`build.defines`, `build.without`) live in the `.comp.toml` — see the `azldev-comp-toml` skill. -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-comp-toml/SKILL.md b/.agents/skills/azldev-comp-toml/SKILL.md index 590715f1fc4..8c7a60a5386 100644 --- a/.agents/skills/azldev-comp-toml/SKILL.md +++ b/.agents/skills/azldev-comp-toml/SKILL.md @@ -106,4 +106,4 @@ Add a TOML comment explaining *why* a non-obvious field is set (a version pin, a workaround), and link the upstream commit or bug when the change is based on one. For overlays, use the overlay `metadata` table instead (see the `azldev-overlays` skill). -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-image/SKILL.md b/.agents/skills/azldev-image/SKILL.md index 0edd5b5393c..ec36f5b749a 100644 --- a/.agents/skills/azldev-image/SKILL.md +++ b/.agents/skills/azldev-image/SKILL.md @@ -57,4 +57,4 @@ The `.kiwi` file is upstream KIWI NG XML — azldev does not own its schema. It image type (container vs. VM), package lists, repositories, and boot configuration. See the [KIWI NG documentation](https://osinside.github.io/kiwi/) for the format and elements. -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-mock/SKILL.md b/.agents/skills/azldev-mock/SKILL.md index 55c1377d753..a12e0bc34e1 100644 --- a/.agents/skills/azldev-mock/SKILL.md +++ b/.agents/skills/azldev-mock/SKILL.md @@ -89,4 +89,4 @@ react to output between commands. - **One mock session per terminal.** Running `azldev adv mock shell` while a terminal is already inside a mock shell fails — run `exit` first. -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-overlays/SKILL.md b/.agents/skills/azldev-overlays/SKILL.md index 374a620e3a5..4794131ad81 100644 --- a/.agents/skills/azldev-overlays/SKILL.md +++ b/.agents/skills/azldev-overlays/SKILL.md @@ -123,4 +123,4 @@ constraints, and the per-file overlay format, generate the machine-readable sche with `azldev config generate-schema` (see the `ComponentOverlay` definition), or read azldev's overlays configuration reference. -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-remove-component/SKILL.md b/.agents/skills/azldev-remove-component/SKILL.md index 9a6b25675d4..c83a9396563 100644 --- a/.agents/skills/azldev-remove-component/SKILL.md +++ b/.agents/skills/azldev-remove-component/SKILL.md @@ -70,4 +70,4 @@ package configuration still references the component. component you are dropping, remove it in the same change to keep the tree consistent. -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-update-component/SKILL.md b/.agents/skills/azldev-update-component/SKILL.md index 0e33223155a..53ef762310d 100644 --- a/.agents/skills/azldev-update-component/SKILL.md +++ b/.agents/skills/azldev-update-component/SKILL.md @@ -40,6 +40,7 @@ git commit -m "fix(): ..." # Re-render and amend so the changelog / Release: track the new commit. azldev comp render -p +git add specs/// git commit --amend --no-edit ``` @@ -65,6 +66,6 @@ A pin bump follows the same rule, split across two commits: 3. Iterate on overlays / patches / build config as the new version requires, re-rendering after each change. Re-run `update` only if you change the pin itself again. 4. `azldev comp update -p ` and commit the lock. 5. `azldev comp render -p ` — `%changelog` / `Release:` now reflect the new lock. -6. `git commit --amend --no-edit` so the lock bump and rendered spec land together. +6. `git add specs///`, then `git commit --amend --no-edit` so the lock bump and rendered output land together. -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev/SKILL.md b/.agents/skills/azldev/SKILL.md index 1556846ffae..4249a739fb1 100644 --- a/.agents/skills/azldev/SKILL.md +++ b/.agents/skills/azldev/SKILL.md @@ -78,4 +78,4 @@ Everyday tasks (add `-q -O json` when scripting): the whole component config, and lock / rendered-spec CI checks run on committed state. - **Every overlay needs a `description`** explaining why the change is needed. -Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.github/instructions/azldev.instructions.md b/.github/instructions/azldev.instructions.md index 05434237fcd..62a1e4a2d2a 100644 --- a/.github/instructions/azldev.instructions.md +++ b/.github/instructions/azldev.instructions.md @@ -12,4 +12,4 @@ here, you MUST first read the relevant azldev skill(s) below. They are the autho version-matched source and override any prior assumptions: - You MUST read the `azldev` skill for how to use the azldev CLI. - +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.github/instructions/comp-toml.instructions.md b/.github/instructions/comp-toml.instructions.md index 5433ccfbe6c..e603bef0b8a 100644 --- a/.github/instructions/comp-toml.instructions.md +++ b/.github/instructions/comp-toml.instructions.md @@ -16,4 +16,4 @@ version-matched source and override any prior assumptions: - You MUST read the `azldev-overlays` skill to add or change overlays. - You MUST read the `azldev-update-component` skill to refresh a component's lock. - You MUST read the `azldev-remove-component` skill to remove a component. - +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.github/instructions/rendered-specs.instructions.md b/.github/instructions/rendered-specs.instructions.md index 146a8ca3216..95158a74d51 100644 --- a/.github/instructions/rendered-specs.instructions.md +++ b/.github/instructions/rendered-specs.instructions.md @@ -1,17 +1,17 @@ --- -description: Rendered RPM spec files produced by 'azldev comp render'. They are build inputs and must not be hand-edited. Before changing one, load the azldev-overlays or azldev-comp-toml skill, edit the source, and re-render. Read this when viewing or tempted to edit a generated spec. -applyTo: "specs/**/*.spec" +description: Rendered component files produced by 'azldev comp render'. They are build inputs and must not be hand-edited. Before changing one, load the azldev-overlays or azldev-comp-toml skill, edit the source, and re-render. Read this when viewing or tempted to edit generated output. +applyTo: "specs/**/*" --- -# Rendered spec files +# Rendered component files -These `.spec` files are generated by `azldev comp render` and are build inputs; do not edit them directly — change the component's `.comp.toml` or its overlays and re-render. +These files are generated by `azldev comp render` and are build inputs; do not edit them directly — change the component's `.comp.toml`, overlays, or source files and re-render. **Do not work from memory or guess.** Before you add, edit, or remove anything in scope here, you MUST first read the relevant azldev skill(s) below. They are the authoritative, version-matched source and override any prior assumptions: - You MUST read the `azldev-comp-toml` skill for the component TOML format. -- You MUST read the `azldev-overlays` skill to change a spec via overlays. +- You MUST read the `azldev-overlays` skill to change generated output via overlays. - You MUST read the `azldev-update-component` skill to refresh and finalize a component. - +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 00000000000..ec66095d585 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,81 @@ +{ + "mcpServers": { + "azldev": { + "args": [ + "advanced", + "mcp" + ], + "command": "azldev", + "tools": [ + "*" + ], + "type": "stdio" + }, + "azure-mcp-server": { + "args": [ + "-y", + "@azure/mcp@latest", + "server", + "start", + "--tool", + "monitor_metrics_definitions", + "--tool", + "monitor_metrics_query", + "--tool", + "monitor_workspace_log_query", + "--tool", + "monitor_activitylog_list", + "--tool", + "monitor_resource_log_query", + "--tool", + "monitor_table_list", + "--tool", + "aks_cluster_get", + "--tool", + "aks_nodepool_get" + ], + "command": "npx", + "env": { + "AZURE_TOKEN_CREDENTIALS": "AzureCliCredential" + }, + "tools": [ + "*" + ], + "type": "stdio" + }, + "fedora-distgit": { + "args": [ + "scripts/mcps/fedora-distgit-mcp.py" + ], + "command": "python3", + "tools": [ + "*" + ], + "type": "stdio" + }, + "koji": { + "args": [ + "scripts/mcps/koji-mcp.py" + ], + "command": "python3", + "tools": [ + "*" + ], + "type": "stdio" + }, + "microsoft/azure-devops-mcp": { + "args": [ + "-y", + "@azure-devops/mcp@latest", + "$AZURE_DEVOPS_ORG", + "-d", + "$AZURE_DEVOPS_DOMAIN" + ], + "command": "npx", + "tools": [ + "*" + ], + "type": "stdio" + } + } +} From 2068e75836eaf8593540d875373bdd69fea47df7 Mon Sep 17 00:00:00 2001 From: Daniel McIlvaney Date: Fri, 10 Jul 2026 14:00:10 -0700 Subject: [PATCH 3/4] fixup! docs(ai): move to new azldev emitted instructions and skills, add azldev mcp --- .agents/skills/azldev-add-component/SKILL.md | 11 +- .agents/skills/azldev-comp-toml/SKILL.md | 36 +++++- .../skills/azldev-update-component/SKILL.md | 4 +- .agents/skills/azldev/SKILL.md | 2 +- .github/copilot-instructions.md | 4 +- .../instructions/comp-toml.instructions.md | 4 +- .github/instructions/review.instructions.md | 9 +- .github/prompts/azl-debug-component.prompt.md | 2 +- .../prompts/azl-review-component.prompt.md | 3 +- .../prompts/azl-update-component.prompt.md | 4 +- AGENTS.md | 2 +- docs/prds/agent-instructions.prd.md | 103 ++++++++++-------- 12 files changed, 122 insertions(+), 62 deletions(-) diff --git a/.agents/skills/azldev-add-component/SKILL.md b/.agents/skills/azldev-add-component/SKILL.md index 1635c5b5aef..62580dd9cb7 100644 --- a/.agents/skills/azldev-add-component/SKILL.md +++ b/.agents/skills/azldev-add-component/SKILL.md @@ -76,8 +76,13 @@ azldev comp build -p # build the RPMs ``` Inspect the rendered spec under `specs/`. A new component always needs a -smoke test — see the `azldev-build-component` and `azldev-mock` skills. After committing, -re-run `azldev comp update -p ` to finalize the lock before a PR (see the -`azldev-update-component` skill). +smoke test — see the `azldev-build-component` and `azldev-mock` skills. + +After all component inputs are final, run `azldev comp update -p ` again and +re-render. Stage the component definition and sources, `locks/.lock`, and +the rendered output before committing. Then re-render, stage +`specs///`, and amend the commit so `%changelog` and +`Release:` reflect it. See the `azldev-update-component` skill for the complete +finalization workflow. Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.agents/skills/azldev-comp-toml/SKILL.md b/.agents/skills/azldev-comp-toml/SKILL.md index 8c7a60a5386..5a8c68b9c28 100644 --- a/.agents/skills/azldev-comp-toml/SKILL.md +++ b/.agents/skills/azldev-comp-toml/SKILL.md @@ -1,6 +1,6 @@ --- name: azldev-comp-toml -description: Read this before authoring or editing a *.comp.toml file; do not hand-write component config from memory. Explains the azldev component definition format, covering the component structure, choosing a spec source (upstream, pinned upstream-distro, upstream-name, or local), build config (defines/with/without), release calculation modes (auto/autorelease/static/manual), render options, and file organization (inline versus dedicated files and includes). Triggers include comp.toml, component config, spec source, upstream-distro, build defines, release calculation, includes. +description: Read this before authoring, editing, or reviewing a *.comp.toml file; do not work from memory. Explains the azldev component definition format and review workflow, covering component structure, spec sources, build config, release calculation, render options, file organization, overlay hygiene, stale files, disabled tests, and testing verification. Triggers include comp.toml, component config, review component, component hygiene, spec source, upstream-distro, build defines, release calculation, includes. --- # Component definition files (`*.comp.toml`) @@ -100,10 +100,42 @@ the rare spec whose `Source`/`Patch` filenames use macros the filter cannot expa - A parent config picks up dedicated files through an `includes` glob, for example `includes = ["**/*.comp.toml"]`. +## Review checklist + +Start with `azldev comp list -p -q -O json`, then use +`azldev comp query -p -q -O json` when the review needs parsed spec details. +For a change review, focus on the diff while checking enough surrounding context to +ensure it fits the component and repository conventions. + +- **Organization:** The component follows the repository's inline-versus-dedicated-file + convention; its name matches upstream or sets `spec.upstream-name`; no stale or + orphaned component files remain. +- **Spec source:** The default upstream source is preferred. Pins explain why they are + needed, and local specs are used only when overlays cannot express the change. +- **Overlays:** Every overlay explains why it exists. Prefer structured overlay types + over regex; scope unavoidable `spec-search-replace` expressions by section and, when + applicable, package, and use TOML literal strings. `spec-search-replace` cannot span + lines. Remove overlays that upstream has made unnecessary. See the `azldev-overlays` skill. +- **Build config:** Defines and bcond overrides are necessary and correspond to the + spec. If `build.check.skip = true`, require a specific `build.check.skip_reason` and + verify that fixing the tests is impractical; skipped `%check` is a last resort. +- **Release mode:** `auto` is the default. Force `autorelease` or `static` only when + auto-detection is wrong. Use `manual` only for a non-standard release tag, and verify + the component increments its release itself. +- **Generated state:** The lock matches the final component inputs, and rendered output + contains the intended changes without unrelated drift. +- **Testing:** Changes that can affect RPM output were built and smoke-tested in a mock + chroot. Organization, comment, or documentation-only metadata edits do not require a + rebuild when the resolved component inputs are unchanged. + +Report findings by severity: errors for correctness or required-policy violations, +warnings for maintainability risks, and info for optional improvements. Prefer small, +actionable fixes over unrelated cleanup. + ## Documenting changes Add a TOML comment explaining *why* a non-obvious field is set (a version pin, a workaround), and link the upstream commit or bug when the change is based on one. For overlays, use the overlay `metadata` table instead (see the `azldev-overlays` skill). -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.1-0.20260710205927-98842ba3a5c7`. diff --git a/.agents/skills/azldev-update-component/SKILL.md b/.agents/skills/azldev-update-component/SKILL.md index 53ef762310d..690c4ac8cd7 100644 --- a/.agents/skills/azldev-update-component/SKILL.md +++ b/.agents/skills/azldev-update-component/SKILL.md @@ -59,12 +59,12 @@ For a `release.calculation = "manual"` component the renderer does **not** bump ## Bumping an upstream commit pin -A pin bump follows the same rule, split across two commits: +A pin bump follows the same rule, using one commit followed by a post-render amend: 1. Move the pin (edit the pinned commit or snapshot time), then `azldev comp update -p `; sanity-check `locks/.lock`. 2. `azldev comp render -p ` — the spec body now tracks the new pin. `%changelog` / `Release:` still show the old pin; that is expected until you commit. 3. Iterate on overlays / patches / build config as the new version requires, re-rendering after each change. Re-run `update` only if you change the pin itself again. -4. `azldev comp update -p ` and commit the lock. +4. `azldev comp update -p `, then stage all component inputs changed above (the pin, config, overlays, and patches), `locks/.lock`, and the rendered output. Commit them together. 5. `azldev comp render -p ` — `%changelog` / `Release:` now reflect the new lock. 6. `git add specs///`, then `git commit --amend --no-edit` so the lock bump and rendered output land together. diff --git a/.agents/skills/azldev/SKILL.md b/.agents/skills/azldev/SKILL.md index 4249a739fb1..04ffbdae9c3 100644 --- a/.agents/skills/azldev/SKILL.md +++ b/.agents/skills/azldev/SKILL.md @@ -62,7 +62,7 @@ Everyday tasks (add `-q -O json` when scripting): ## Where to go next - Add a new component — read the `azldev-add-component` skill. -- Edit a component's TOML — read the `azldev-comp-toml` skill. +- Edit or review a component's TOML — read the `azldev-comp-toml` skill. - Add or change overlays — read the `azldev-overlays` skill. - Build, iterate, and debug a component — read the `azldev-build-component` skill. - Build, boot, and register images — read the `azldev-image` skill. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index b17e7892f44..14be3c2409d 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -61,9 +61,9 @@ When making a PR, the lock and rendered specs must be updated and self-consisten ## Key Concepts -**Components** = unit of packaging (→ one or more RPMs). Spec sources: upstream (default, from Fedora dist-git), local, or pinned upstream. See [`comp-toml.instructions.md`](instructions/comp-toml.instructions.md#spec-source-types) for syntax. +**Components** = unit of packaging (→ one or more RPMs). Spec sources: upstream (default, from Fedora dist-git), local, or pinned upstream. See the [`azldev-comp-toml` skill](../.agents/skills/azldev-comp-toml/SKILL.md#spec-source) for syntax. -**Overlays** modify upstream specs/sources without forking. See [`comp-toml.instructions.md`](instructions/comp-toml.instructions.md#overlays) for types, syntax, and pitfalls. Schema: [`azldev.schema.json`](../external/schemas/azldev.schema.json). +**Overlays** modify upstream specs/sources without forking. See the [`azldev-overlays` skill](../.agents/skills/azldev-overlays/SKILL.md) for types, syntax, and pitfalls. Schema: [`azldev.schema.json`](../external/schemas/azldev.schema.json). **TOML include hierarchy**: `azldev.toml` → `distro/distro.toml` + `base/project.toml` → `base/comps/components.toml` → `**/*.comp.toml` (stitched into single namespace). diff --git a/.github/instructions/comp-toml.instructions.md b/.github/instructions/comp-toml.instructions.md index e603bef0b8a..fc175a0473c 100644 --- a/.github/instructions/comp-toml.instructions.md +++ b/.github/instructions/comp-toml.instructions.md @@ -1,5 +1,5 @@ --- -description: These are azldev component definition files (*.comp.toml). Before editing one, load the azldev-comp-toml skill (and azldev-overlays for spec changes); do not hand-write component config from memory. Triggers include comp.toml, component config, spec source, build defines, release calculation, overlays. +description: These are azldev component definition files (*.comp.toml). Before editing or reviewing one, load the azldev-comp-toml skill (and azldev-overlays for spec changes); do not hand-write component config from memory. Triggers include comp.toml, component config, spec source, build defines, release calculation, overlays, review component. applyTo: "**/*.comp.toml" --- @@ -11,7 +11,7 @@ These files define a distro's components — each one's spec source and how azld here, you MUST first read the relevant azldev skill(s) below. They are the authoritative, version-matched source and override any prior assumptions: -- You MUST read the `azldev-comp-toml` skill for the component TOML format. +- You MUST read the `azldev-comp-toml` skill for the component TOML format and review checklist. - You MUST read the `azldev-add-component` skill to add a new component. - You MUST read the `azldev-overlays` skill to add or change overlays. - You MUST read the `azldev-update-component` skill to refresh a component's lock. diff --git a/.github/instructions/review.instructions.md b/.github/instructions/review.instructions.md index e7f7820fd69..05b04b251f6 100644 --- a/.github/instructions/review.instructions.md +++ b/.github/instructions/review.instructions.md @@ -7,4 +7,11 @@ applyTo: "**/*" This project uses the [azldev](https://github.com/microsoft/azure-linux-dev-tools) tool to manage components and provide various utilities. -Additional instructions for this repo are available only from the azldev tool itself. When using an azldev skill for the first time, you will be prompted to use the tool to view the skill's instructions. Follow the instructions in [DEVELOPING.md](../../DEVELOPING.md) to install azldev and view the instructions for each skill. If the specified tools are not available (i.e. MCP server is not configured in the current environment), use the `azldev` tool directly. +The version-matched guidance is checked in under [`.agents/skills/`](../../.agents/skills/). +Before reviewing an azldev component or configuration change, read the relevant skill +listed in [AGENTS.md](../../AGENTS.md); for component hygiene reviews, use the +[`azldev-comp-toml` review checklist](../../.agents/skills/azldev-comp-toml/SKILL.md#review-checklist). + +Use the configured azldev MCP server or the `azldev` CLI to execute the commands in +those skills. See [DEVELOPING.md](../../DEVELOPING.md) if azldev is not installed or +the MCP server is unavailable. diff --git a/.github/prompts/azl-debug-component.prompt.md b/.github/prompts/azl-debug-component.prompt.md index 23ba0b82d8a..c9ef1acc805 100644 --- a/.github/prompts/azl-debug-component.prompt.md +++ b/.github/prompts/azl-debug-component.prompt.md @@ -21,7 +21,7 @@ First, determine the error category: 2. **Build failure** — compilation errors, missing dependencies, test failures during `comp build`: - Follow the `azldev-build-component` inner loop: check build logs in `base/build/logs/`, use `--preserve-buildenv on-failure`, inspect mock chroot - Common causes: missing BuildRequires, incompatible compiler flags, test failures - - **`%check` failures:** Always attempt to fix failing tests first. Disabling `%check` (via `build.without = ["check"]`) is an **absolute last resort** — only after exhausting other options. If you must disable it, the `skip_reason` must clearly explain why the tests cannot be fixed. + - **`%check` failures:** Always attempt to fix failing tests first. Disabling `%check` (via `build.check.skip = true` with a required `build.check.skip_reason`) is an **absolute last resort** — only after exhausting other options. The reason must clearly explain why the tests cannot be fixed. 3. **Runtime/packaging issue** — wrong file permissions, missing files, dependency conflicts in built RPMs: - Follow the `azldev-mock` workflow: install RPMs in a mock chroot, verify contents, check dependencies diff --git a/.github/prompts/azl-review-component.prompt.md b/.github/prompts/azl-review-component.prompt.md index 4e5b255baa8..2febdf46737 100644 --- a/.github/prompts/azl-review-component.prompt.md +++ b/.github/prompts/azl-review-component.prompt.md @@ -13,5 +13,6 @@ Follow the component structure guidance in the [azldev-comp-toml skill](../../.a 1. Query the component: `azldev comp query -p ${input:component_name}` 2. Read the component's `.comp.toml` file (or inline definition in `components.toml`) -3. Run through the review checklist from the component and overlay guidance +3. Run through the `azldev-comp-toml` skill's **Review checklist**, using the + `azldev-overlays` skill for the overlay-specific checks 4. Produce a structured report grouped by severity: **Errors** (must-fix), **Warnings** (should-fix), **Info** (suggestions) diff --git a/.github/prompts/azl-update-component.prompt.md b/.github/prompts/azl-update-component.prompt.md index 57272157700..1d1fb316969 100644 --- a/.github/prompts/azl-update-component.prompt.md +++ b/.github/prompts/azl-update-component.prompt.md @@ -6,7 +6,7 @@ description: "Update an existing Azure Linux component (version bump, dependency Update **${input:component_name}** — target version: **${input:new_version:target version}**, update type: **${input:update_type:version|dependency|overlay|config}**. -Use structural patterns from [comp-toml.instructions.md](../instructions/comp-toml.instructions.md). If overlays break, follow the [azldev-overlays skill](../../.agents/skills/azldev-overlays/SKILL.md). Test changes using the [azldev-build-component skill](../../.agents/skills/azldev-build-component/SKILL.md). +Use structural patterns from [comp-toml.instructions.md](../instructions/comp-toml.instructions.md). If overlays break, follow the [azldev-overlays skill](../../.agents/skills/azldev-overlays/SKILL.md). Test changes using the [azldev-build-component skill](../../.agents/skills/azldev-build-component/SKILL.md), then finalize the lock and rendered output with the [azldev-update-component skill](../../.agents/skills/azldev-update-component/SKILL.md). ## Workflow @@ -31,6 +31,8 @@ Use structural patterns from [comp-toml.instructions.md](../instructions/comp-to 5. **Migrate to dedicated file** if the component is still inline and now needs customization (use `/azl-migrate-component`) 6. **Build and test:** `azldev comp build -p ${input:component_name}` 7. **Smoke-test** the built RPMs in a mock chroot +8. **Finalize** the lock, commit, post-commit render, and amend by following the + `azldev-update-component` workflow ## Versioning Risk Assessment diff --git a/AGENTS.md b/AGENTS.md index d1b3b6ea09b..cda64ab6049 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,7 +59,7 @@ Detailed workflows live in skills (loaded on-demand when relevant): | Remove component(s) from the distro | [`azldev-remove-component`](.agents/skills/azldev-remove-component/SKILL.md) | | Diagnose and fix overlay issues | [`azldev-overlays`](.agents/skills/azldev-overlays/SKILL.md) | | Test and inspect packages in mock chroot | [`azldev-mock`](.agents/skills/azldev-mock/SKILL.md) | -| Review component for hygiene and best practices | [`azldev-comp-toml`](.agents/skills/azldev-comp-toml/SKILL.md) | +| Review component for hygiene and best practices | [`azldev-comp-toml` review checklist](.agents/skills/azldev-comp-toml/SKILL.md#review-checklist) | | Triage Koji build failures | [`skill-koji-triage`](.agents/skills/skill-koji-triage/SKILL.md) | | Batch-triage build failures from results file | [`skill-mass-triage`](.agents/skills/skill-mass-triage/SKILL.md) | | Inspect Koji AKS cluster health and node pools | [`skill-aks-health`](.agents/skills/skill-aks-health/SKILL.md) | diff --git a/docs/prds/agent-instructions.prd.md b/docs/prds/agent-instructions.prd.md index 8dfc2af5ae3..a237db9aab6 100644 --- a/docs/prds/agent-instructions.prd.md +++ b/docs/prds/agent-instructions.prd.md @@ -3,7 +3,7 @@ Title: PRD: Agent Instructions and Skills for Azure Linux Author: Daniel McIlvaney Created: 2026-01-29 -Updated: 2026-02-11 +Updated: 2026-07-10 Status: Draft ## Overview @@ -77,11 +77,13 @@ Instruction files should work across GitHub Copilot surfaces where possible: VS - **Design principle:** AGENTS.md files should be short guardrail documents — conventions and "do/don't" rules. Detailed workflows and examples belong in skills or `.instructions.md` files. 4. **Agent Skills** (`.agents/skills/*/SKILL.md`) — *cross-platform ([open standard](https://agentskills.io/))* - - `azl-add-component/SKILL.md` - Adding a new component to the distro - - `azl-fix-overlay/SKILL.md` - Diagnosing and fixing overlay issues - - `azl-build-component/SKILL.md` - Building, testing, and debugging components - - `azl-mock/SKILL.md` - Testing and inspecting packages in mock chroots - - `azl-review-component/SKILL.md` - Reviewing component definitions for hygiene and best practices + - `azldev-add-component/SKILL.md` - Adding a new component to the distro + - `azldev-overlays/SKILL.md` - Authoring and diagnosing overlays + - `azldev-build-component/SKILL.md` - Building and debugging components + - `azldev-mock/SKILL.md` - Testing and inspecting packages in mock chroots + - `azldev-update-component/SKILL.md` - Refreshing locks and finalizing component changes + - `azldev-remove-component/SKILL.md` - Removing components without leaving stale state + - `azldev-comp-toml/SKILL.md` - Authoring and reviewing component definitions - Each skill is a directory containing a `SKILL.md` (with required `name` and `description` YAML frontmatter) plus optional scripts, examples, and resources. Skills are discovered on-demand based on description matching. - **Design principle:** Skills are for explicit, multi-step task workflows — not general domain knowledge. Domain knowledge belongs in passive context (`.instructions.md`, `AGENTS.md`) where it's available without the agent needing to decide to load it. AGENTS.md files link to skills for discoverability, but links are not required for skill triggering. @@ -126,13 +128,19 @@ azurelinux/ │ └── *.agent.md ├── .agents/ │ └── skills/ # Agent Skills (cross-platform, open standard) -│ ├── azl-add-component/ +│ ├── azldev-add-component/ │ │ └── SKILL.md -│ ├── azl-fix-overlay/ +│ ├── azldev-overlays/ │ │ └── SKILL.md -│ ├── azl-build-component/ +│ ├── azldev-build-component/ │ │ └── SKILL.md -│ └── azl-mock/ +│ ├── azldev-comp-toml/ +│ │ └── SKILL.md +│ ├── azldev-mock/ +│ │ └── SKILL.md +│ ├── azldev-remove-component/ +│ │ └── SKILL.md +│ └── azldev-update-component/ │ └── SKILL.md ├── .vscode/ │ └── mcp.json # MCP tool configuration (VS Code) @@ -262,7 +270,7 @@ Skills are loaded on-demand via progressive disclosure: The `description` field is critical: write it to clearly describe both what the skill does and when to use it, so Copilot can match it to user requests. Include trigger phrases in the description — this is what causes skill loading. "When to use" guidance belongs in the description, not in the body (the body loads *after* triggering). -#### `azl-add-component/SKILL.md` +#### `azldev-add-component/SKILL.md` **Trigger:** User wants to add a new component @@ -274,7 +282,7 @@ The `description` field is critical: write it to clearly describe both what the - When to use inline definition vs dedicated `.comp.toml` file - Adding overlays when customizations are needed — tips: test incrementally, avoid renaming `Name:`, no `$schema` in TOML, no multi-line regex, prefer targeted overlay types over regex - **Overlays vs forked spec**: overlays are vastly preferable; forked specs are a last resort, require explicit user sign-off, and commit to indefinite maintenance -- Validating the component definition (`prep-sources` pre/post diff → `comp build` → smoke test via `azl-mock`) +- Validating the component definition (`comp render`/`comp diff-sources` → `comp build` → smoke test via `azldev-mock`) **Decision tree:** @@ -282,9 +290,9 @@ The `description` field is critical: write it to clearly describe both what the - Needs overlays or customizations → Create `/.comp.toml` - Needs extensive changes that overlays can't handle → Forked local spec (last resort, requires user sign-off) -#### `azl-update-component/SKILL.md` — Not planned +#### `azldev-update-component/SKILL.md` -Updating a component is primarily "edit a `.comp.toml` file" (structural knowledge provided by `comp-toml.instructions.md`), optionally combined with `azl-fix-overlay` (if overlays break) or `azl-build-component` (to test). A dedicated update skill may be added if a distinct workflow emerges that isn't covered by those mechanisms. +The update skill owns lock refresh and finalization after component inputs change. It covers when to run `comp update`, staging the component inputs, lock, and rendered output together, and the required post-commit render-and-amend cycle. Its pin-bump workflow also accounts for overlays or build configuration that must change with a new upstream revision. Component editing, overlay repair, and testing remain in `azldev-comp-toml`, `azldev-overlays`, and `azldev-build-component` respectively. **Versioning and Compatibility Considerations** (to be incorporated into `comp-toml.instructions.md` or a future update skill): @@ -305,7 +313,7 @@ Agents should: When in doubt, recommend the user review the upstream changelog before proceeding, with references if available. -#### `azl-fix-overlay/SKILL.md` +#### `azldev-overlays/SKILL.md` **Trigger:** Overlay errors during build or validation @@ -319,7 +327,7 @@ When in doubt, recommend the user review the upstream changelog before proceedin - Diagnosing regex overlay failures (pattern matching, TOML literal strings, no multi-line regex) - Diagnosing `file-*` overlay failures (file existence, glob support for `file-search-replace`) - Overlay type quick reference table (all 12 types with key fields) -- Tips: test incrementally, minimize overlays, verify in chroot via `azl-mock`, follow inner loop from `azl-build-component` +- Tips: test incrementally, minimize overlays, verify in chroot via `azldev-mock`, follow the inner loop from `azldev-build-component` **Common failure patterns:** @@ -329,19 +337,19 @@ When in doubt, recommend the user review the upstream changelog before proceedin - `file-*`: file not found → check pre-overlay dir listing - Overlay applies but build still fails → compare post-overlay spec against expectations (regex matched wrong lines, replacement introduced syntax errors, missing dependency) -#### `azl-build-component/SKILL.md` +#### `azldev-build-component/SKILL.md` **Trigger:** Building components, debugging build failures, inspecting build environments **Concepts to cover:** -- "Never install built RPMs on the host" — they target Azure Linux, not the dev machine. Use `azl-mock` instead. +- "Never install built RPMs on the host" — they target Azure Linux, not the dev machine. Use `azldev-mock` instead. - **Build Output Directories** table mapping `project.toml` keys (`output-dir`, `log-dir`, `work-dir`) → resolved paths (`base/out/`, `base/build/logs/`, `base/build/work/`). Note that `prep-sources -o ` output is separate from these. - Build sequence: single build, chained builds with `--local-repo-with-publish`, rebuild against local repo - **Dev Inner Loop** as a formal table: investigate → compare → modify → verify → build → inspect - Use a temp dir for prep-sources output dirs — use `--force` to overwrite an existing output dir - How to preserve build state on failure for inspection (`--preserve-buildenv`) -- Entering the mock shell environment for interactive debugging (cross-ref to `azl-mock`) +- Entering the mock shell environment for interactive debugging (cross-ref to `azldev-mock`) - Warning about `-p` flag meaning in `mock shell` vs `comp build` (different semantics) - Per-component build overrides via `build.defines` (macros) and `build.without` (disable conditionals) - Source inspection: comparing pre/post overlay sources with `prep-sources` + `diff -r` @@ -354,7 +362,7 @@ When in doubt, recommend the user review the upstream changelog before proceedin - Mock chroot (when preserved with `--preserve-buildenv`) - `prep-sources` output (user-specified dir, NOT in `base/out/`) -#### `azl-mock/SKILL.md` +#### `azldev-mock/SKILL.md` **Trigger:** Testing built RPMs, inspecting dependencies, debugging runtime issues, verifying package contents @@ -415,9 +423,9 @@ Prompts are reusable, parameterized workflows that users can invoke directly via Prompts follow one of two tiers depending on whether a dedicated skill exists: -- **Tier 1 (skill-backed):** When a dedicated skill covers the workflow, the prompt is a thin wrapper. It collects user input via `${input:...}` variables, references the skill via a Markdown link (so the skill's instructions load into context), and adds VS Code-specific affordances (`agent:`, `tools:`, built-in variables). The prompt orchestrates the step-by-step sequence but delegates the "how" to the skill. Example: `azl-add-component.prompt.md` → `azl-add-component/SKILL.md`. +- **Tier 1 (skill-backed):** When a dedicated skill covers the workflow, the prompt is a thin wrapper. It collects user input via `${input:...}` variables, references the skill via a Markdown link (so the skill's instructions load into context), and adds VS Code-specific affordances (`agent:`, `tools:`, built-in variables). The prompt orchestrates the step-by-step sequence but delegates the "how" to the skill. Example: `azl-add-component.prompt.md` → `azldev-add-component/SKILL.md`. -- **Tier 2 (orchestrator):** When no dedicated skill exists — because the workflow is a composition of existing skills, instruction files, and AGENTS.md content — the prompt encodes the workflow logic directly. It references *multiple* existing resources via Markdown links (e.g., `comp-toml.instructions.md` + `azl-fix-overlay/SKILL.md` + `azl-build-component/SKILL.md`). Creating a skill just to back a prompt violates YAGNI when the workflow is a straightforward composition. Example: `azl-update-component.prompt.md` combines structural knowledge from `comp-toml.instructions.md` with overlay repair from `azl-fix-overlay` and testing from `azl-build-component`. +- **Tier 2 (orchestrator):** When a workflow composes several skills, instruction files, and AGENTS.md content, the prompt encodes the routing logic directly. It references *multiple* existing resources rather than duplicating them. Example: `azl-update-component.prompt.md` combines structural knowledge from `comp-toml.instructions.md`, overlay repair from `azldev-overlays`, testing from `azldev-build-component`, and finalization from `azldev-update-component`. Both tiers ensure Copilot CLI users get equivalent guidance: Tier 1 prompts have a directly matching skill, and Tier 2 prompts compose skills that are independently discoverable. See the [VS Code prompt files documentation](https://code.visualstudio.com/docs/copilot/customization/prompt-files) for prompt file syntax and features. @@ -431,7 +439,7 @@ Both cover similar topics but serve different purposes. Skills answer "how does #### `azl-add-component.prompt.md` **Purpose:** Guided workflow for adding a new component to Azure Linux -**References:** `azl-add-component/SKILL.md` (linked via Markdown, provides domain knowledge) +**References:** `azldev-add-component/SKILL.md` (linked via Markdown, provides domain knowledge) **Input variables** (via `${input:...}` syntax): @@ -451,8 +459,8 @@ Both cover similar topics but serve different purposes. Skills answer "how does #### `azl-update-component.prompt.md` — Tier 2 (orchestrator) **Purpose:** Guided workflow for updating an existing component -**References:** `comp-toml.instructions.md` (structural knowledge), `azl-fix-overlay/SKILL.md` (if overlays break), `azl-build-component/SKILL.md` (to test) — all linked via Markdown -**Tier rationale:** No dedicated update skill exists (see `azl-update-component — Not planned` above). The update workflow is a composition of structural editing (from `comp-toml.instructions.md`), overlay repair (from `azl-fix-overlay`), and build testing (from `azl-build-component`). The prompt encodes the meta-workflow that ties these together, including versioning risk assessment (update policy will be encoded in the components TOML if non-standard). +**References:** `comp-toml.instructions.md` (structural knowledge), `azldev-overlays/SKILL.md` (if overlays break), `azldev-build-component/SKILL.md` (to test), and `azldev-update-component/SKILL.md` (to finalize) — all linked via Markdown +**Tier rationale:** The prompt composes component editing, overlay repair, build testing, version-risk assessment, and the dedicated lock/finalization workflow. **Input variables:** @@ -466,9 +474,10 @@ Both cover similar topics but serve different purposes. Skills answer "how does 2. Identify scope of update (version bump, dependency change, overlay edit, config tweak) 3. For version bumps: assess versioning risk (major/minor/patch), flag soname changes, note new dependencies, recommend upstream changelog review 4. Apply changes to `.comp.toml` (structural knowledge from `comp-toml.instructions.md`) -5. Verify overlays still apply: `prep-sources` pre/post diff (if overlays break, follow `azl-fix-overlay`) +5. Verify overlays still apply: render and use `comp diff-sources` for deeper inspection (if overlays break, follow `azldev-overlays`) 6. Migrate to dedicated file if needed (see `migrate-component` prompt) -7. Build and test: follow `azl-build-component` inner loop +7. Build and test: follow the `azldev-build-component` inner loop +8. Finalize the lock and rendered output with `azldev-update-component` **Versioning risk assessment** (encoded in prompt body, sourced from the Versioning and Compatibility Considerations section of this PRD): @@ -477,11 +486,11 @@ Both cover similar topics but serve different purposes. Skills answer "how does - **Patch bumps** (1.2.3 → 1.2.4): Low risk — usually safe - Always: check upstream release notes, flag soname changes, examine overlay compatibility, warn about feature removal, summarize risks -#### `azl-review-component.prompt.md` — Tier 1 (skill-backed) +#### `azl-review-component.prompt.md` — Tier 2 (multi-skill composition) **Purpose:** Review a component definition for hygiene and best practices -**References:** `azl-review-component/SKILL.md` (review checklist and workflow), plus `copilot-instructions.md` (hygiene rules), `base/comps/AGENTS.md` (file organization), `comp-toml.instructions.md` (overlay patterns) — all linked via Markdown -**Tier rationale:** Backed by the `azl-review-component` skill, which owns the canonical review checklist. +**References:** The review checklist in `azldev-comp-toml/SKILL.md`, overlay details in `azldev-overlays/SKILL.md`, and repository organization rules in `base/comps/AGENTS.md` +**Tier rationale:** Component structure and review checks share one source of truth, while detailed overlay checks remain in the overlay skill. **Input variables:** @@ -494,13 +503,14 @@ Both cover similar topics but serve different purposes. Skills answer "how does - **Naming conventions:** Does the component name match the upstream package name? Is `upstream-name` used when they differ? - **Build configuration:** Are `build.defines` and `build.without` used appropriately? Any missing or unnecessary build overrides? - **Source configuration:** Is the spec source type appropriate (upstream default vs pinned vs local)? +- **Generated state and testing:** Does the lock match the inputs, is rendered output clean, and were output-affecting changes built and smoke-tested? **Output:** Structured report with findings and recommendations, grouped by severity #### `azl-debug-component.prompt.md` — Tier 2 (multi-skill composition) **Purpose:** Diagnose and fix component build failures, including overlay application errors -**References:** `azl-fix-overlay/SKILL.md` (overlay diagnosis), `azl-build-component/SKILL.md` (build debugging/inner loop), `azl-mock/SKILL.md` (chroot inspection) — all linked via Markdown +**References:** `azldev-overlays/SKILL.md` (overlay diagnosis), `azldev-build-component/SKILL.md` (build debugging/inner loop), `azldev-mock/SKILL.md` (chroot inspection) — all linked via Markdown **Tier rationale:** This is a Tier 2 prompt that composes multiple skills. It triages the error type and routes to the appropriate skill's workflow. **Input variables:** @@ -510,9 +520,9 @@ Both cover similar topics but serve different purposes. Skills answer "how does **Triage logic** (encoded in prompt body): -1. If the error is an overlay application failure (overlay errors during `prep-sources` or early in build): follow `azl-fix-overlay` skill workflow — diff pre/post overlay output, diagnose pattern failures, suggest fixes -2. If the error is a build failure (compilation errors, missing dependencies, test failures): follow `azl-build-component` inner loop — check logs, preserve buildenv, inspect mock chroot -3. If the error is a runtime/packaging issue (wrong file permissions, missing files, dependency conflicts): follow `azl-mock` skill workflow — install in chroot, verify contents, check dependencies +1. If the error is an overlay application failure (overlay errors during `prep-sources` or early in build): follow the `azldev-overlays` workflow — inspect `comp diff-sources`, diagnose pattern failures, suggest fixes +2. If the error is a build failure (compilation errors, missing dependencies, test failures): follow the `azldev-build-component` inner loop — check logs, preserve buildenv, inspect the mock chroot +3. If the error is a runtime/packaging issue (wrong file permissions, missing files, dependency conflicts): follow the `azldev-mock` workflow — install in chroot, verify contents, check dependencies 4. When in doubt, start with `prep-sources` pre/post diff to determine if the issue is overlay-related or build-related **Common diagnoses:** @@ -554,7 +564,7 @@ Both cover similar topics but serve different purposes. Skills answer "how does - [x] Create `AGENTS.md` (root) — lean: conventions, skill table, directory pointers - [x] Create `base/comps/AGENTS.md` — lean: file organization rules, skill pointers - [x] Create `distro/AGENTS.md` — build defaults, structure overview, shared config warning -- [x] Create skill stubs (`.agents/skills/azl-{add-component,fix-overlay,build-component,mock,review-component}/SKILL.md`) +- [x] Check in the azldev-emitted skills under `.agents/skills/azldev-*/SKILL.md` ### Phase 2: Agent Skills (cross-platform, open standard) @@ -562,11 +572,13 @@ Each skill is a directory with a `SKILL.md` file following the [Agent Skills sta Skills are for explicit task workflows only — domain knowledge goes in passive context (Phase 1 + Phase 3). -- [x] Create `.agents/skills/azl-build-component/SKILL.md` (full content) -- [x] Flesh out `.agents/skills/azl-add-component/SKILL.md` -- [x] Flesh out `.agents/skills/azl-fix-overlay/SKILL.md` -- [x] Create `.agents/skills/azl-mock/SKILL.md` (mock chroot testing and inspection) -- [ ] Flesh out `.agents/skills/azl-review-component/SKILL.md` (component hygiene review) +- [x] Generate `.agents/skills/azldev-build-component/SKILL.md` +- [x] Generate `.agents/skills/azldev-add-component/SKILL.md` +- [x] Generate `.agents/skills/azldev-overlays/SKILL.md` +- [x] Generate `.agents/skills/azldev-mock/SKILL.md` +- [x] Generate `.agents/skills/azldev-update-component/SKILL.md` +- [x] Generate `.agents/skills/azldev-remove-component/SKILL.md` +- [x] Add the component review checklist to `.agents/skills/azldev-comp-toml/SKILL.md` - [x] Write clear `description` fields with trigger phrases so Copilot can match skills to user requests - [x] Link skills from `AGENTS.md` files for discoverability @@ -592,10 +604,10 @@ These `.instructions.md` files use `applyTo` globs for automatic context injecti Prompts follow a two-tier model: **Tier 1** prompts are thin wrappers around existing skills, while **Tier 2** prompts encode their own workflow logic and compose multiple existing skills/instructions. Both tiers collect user input via `${input:...}` variables and use Markdown links to pull in domain knowledge. Use optional `agent:`/`tools:` frontmatter for VS Code-specific affordances. See the [VS Code prompt files documentation](https://code.visualstudio.com/docs/copilot/customization/prompt-files) for syntax reference. -- [x] Create `.github/prompts/azl-add-component.prompt.md` — Tier 1 (wraps `azl-add-component`) -- [x] Create `.github/prompts/azl-update-component.prompt.md` — Tier 2 (composes `comp-toml.instructions.md` + `azl-fix-overlay` + `azl-build-component`) -- [x] Create `.github/prompts/azl-review-component.prompt.md` — Tier 1 (wraps `azl-review-component`) -- [x] Create `.github/prompts/azl-debug-component.prompt.md` — Tier 2 (triages between `azl-fix-overlay` + `azl-build-component` + `azl-mock`) +- [x] Create `.github/prompts/azl-add-component.prompt.md` — Tier 1 (wraps `azldev-add-component`) +- [x] Create `.github/prompts/azl-update-component.prompt.md` — Tier 2 (composes component, overlay, build, and update skills) +- [x] Create `.github/prompts/azl-review-component.prompt.md` — Tier 2 (composes the `azldev-comp-toml` checklist and `azldev-overlays`) +- [x] Create `.github/prompts/azl-debug-component.prompt.md` — Tier 2 (triages between `azldev-overlays`, `azldev-build-component`, and `azldev-mock`) - [x] Create `.github/prompts/azl-migrate-component.prompt.md` — Tier 2 (composes `comp-toml.instructions.md` + `base/comps/AGENTS.md`) ### Phase 5: Experimental Agents (cross-platform) @@ -652,11 +664,12 @@ These aspects of the PRD should be reviewed and updated as the project evolves: - **Resolution:** Agents should warn and explain, not block. The goal is AI code reviewers flagging bad practices and ensuring new agent-written code is clean. Enforcement checks will be added incrementally over time. 3. **Skill naming convention:** Should skills be prefixed (`azl-`) or namespaced differently? The Agent Skills standard requires lowercase names with hyphens (max 64 chars). + - **Resolution:** Skills emitted by azldev use the `azldev-` prefix. Repository-specific skills retain their existing descriptive names. The `azl-` prefix remains the VS Code prompt namespace. 4. **Agent scope:** Should experimental agents be repo-specific or potentially shared across Azure Linux repos? Should azldev have a command to install the resources into other repos? 5. **Prompts vs Skills overlap:** Some workflows exist as both skills and prompts (e.g., add-component). Should we consolidate, or keep both for different use cases (reference vs interactive)? - - **Resolution:** Keep both, using a two-tier model. **Tier 1** prompts are thin wrappers around an existing skill (e.g., `add-component` → `azl-add-component`). **Tier 2** prompts encode their own workflow logic when no dedicated skill exists, composing multiple existing skills and instruction files (e.g., `update-component` composes `comp-toml.instructions.md` + `azl-fix-overlay` + `azl-build-component`). This avoids both knowledge duplication and creating skills just to satisfy a pattern (YAGNI). Copilot CLI users get equivalent guidance: Tier 1 skills are directly discoverable, and Tier 2 prompts compose independently discoverable skills. + - **Resolution:** Keep both, using a two-tier model. **Tier 1** prompts are thin wrappers around an existing skill (e.g., `azl-add-component.prompt.md` → `azldev-add-component`). **Tier 2** prompts encode routing logic for workflows that compose multiple resources (e.g., `azl-update-component.prompt.md` composes component, overlay, build, and finalization guidance). This avoids knowledge duplication while giving Copilot CLI users equivalent guidance through independently discoverable skills. 6. **Passive vs active context balance:** Research shows passive context (AGENTS.md) dramatically outperforms skills for domain knowledge. But passive context is a per-interaction token tax. Our current split: lean AGENTS.md (guardrails) + `.instructions.md` (domain knowledge, scoped by file type) + skills (task workflows). This may need tuning based on real usage — if agents still miss domain knowledge when `.instructions.md` doesn't fire (e.g., asking about components without a `.comp.toml` open), we may need to move some content back to always-on AGENTS.md. From 36ebe383647cd6405ab9a2d830313216e4d1ee6c Mon Sep 17 00:00:00 2001 From: Daniel McIlvaney Date: Fri, 10 Jul 2026 15:14:27 -0700 Subject: [PATCH 4/4] fixup! docs(ai): move to new azldev emitted instructions and skills, add azldev mcp --- .agents/skills/azldev-comp-toml/SKILL.md | 2 +- .github/agents/azl-diagnose.agent.md | 2 +- .github/prompts/azl-mass-triage.prompt.md | 2 +- .mcp.json | 4 ++++ DEVELOPING.md | 6 +++++- docs/prds/agent-instructions.prd.md | 10 +++++++--- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.agents/skills/azldev-comp-toml/SKILL.md b/.agents/skills/azldev-comp-toml/SKILL.md index 5a8c68b9c28..f882fbe5eef 100644 --- a/.agents/skills/azldev-comp-toml/SKILL.md +++ b/.agents/skills/azldev-comp-toml/SKILL.md @@ -138,4 +138,4 @@ Add a TOML comment explaining *why* a non-obvious field is set (a version pin, a workaround), and link the upstream commit or bug when the change is based on one. For overlays, use the overlay `metadata` table instead (see the `azldev-overlays` skill). -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.1-0.20260710205927-98842ba3a5c7`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.1.0`. diff --git a/.github/agents/azl-diagnose.agent.md b/.github/agents/azl-diagnose.agent.md index 8d7c54ba4f1..38ab4aef5af 100644 --- a/.github/agents/azl-diagnose.agent.md +++ b/.github/agents/azl-diagnose.agent.md @@ -25,7 +25,7 @@ handoffs: --- # Build Failure Diagnosis -This agent diagnoses build failures — Koji triage, upstream investigation, root cause analysis, and fix recommendations. Follow the [skill-koji-triage skill](../skills/skill-koji-triage/SKILL.md) for the full investigation workflow, including discovery, log analysis, and failure categorization (unless working as an orchestrator, have sub-agents use the triage skill for you if so). +This agent diagnoses build failures — Koji triage, upstream investigation, root cause analysis, and fix recommendations. Follow the [skill-koji-triage skill](../../.agents/skills/skill-koji-triage/SKILL.md) for the full investigation workflow, including discovery, log analysis, and failure categorization (unless working as an orchestrator, have sub-agents use the triage skill for you if so). ## Workflow diff --git a/.github/prompts/azl-mass-triage.prompt.md b/.github/prompts/azl-mass-triage.prompt.md index ffdff679576..a715b365bcb 100644 --- a/.github/prompts/azl-mass-triage.prompt.md +++ b/.github/prompts/azl-mass-triage.prompt.md @@ -9,6 +9,6 @@ argument-hint: Path to a JSON file containing build results (e.g., results.json) - **Results file**: `${input:results_file:path to results JSON file}` - **Koji base URL**: `${input:koji_url:Koji base URL (e.g. https://koji.example.com)}` -Follow the [skill-mass-triage skill](../skills/skill-mass-triage/SKILL.md) to triage all failed builds in `${input:results_file}`. +Follow the [skill-mass-triage skill](../../.agents/skills/skill-mass-triage/SKILL.md) to triage all failed builds in `${input:results_file}`. Pass the Koji base URL (`${input:koji_url}`) and the results file path to the skill workflow. You will be acting as an orchestrator here, so even though you have the skills to diagnose build failures directly you should NOT do that work yourself. Instead, follow the instructions in the skill file on how to coordinate other agents. diff --git a/.mcp.json b/.mcp.json index ec66095d585..a51963a49e1 100644 --- a/.mcp.json +++ b/.mcp.json @@ -72,6 +72,10 @@ "$AZURE_DEVOPS_DOMAIN" ], "command": "npx", + "env": { + "AZURE_DEVOPS_DOMAIN": "$AZURE_DEVOPS_DOMAIN", + "AZURE_DEVOPS_ORG": "$AZURE_DEVOPS_ORG" + }, "tools": [ "*" ], diff --git a/DEVELOPING.md b/DEVELOPING.md index 6a2edbbfde6..eb8b763d05f 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -90,7 +90,11 @@ copilot --add-dir . copilot --add-dir . -i "Upgrade vim to the next stable release" ``` -Note: `copilot` supports fully autonomous operation (no interactive mode) with `-p ` however, until azldev supports a full MCP mode the tool approvals are very difficult. `--yolo` (same as `--allow-all-tools --allow-all-paths --allow-all-urls`) is an option, but use with extreme caution since it grants the agent unrestricted access to your filesystem and network. For now, it's recommended to use `-i` to at least have visibility into the agent's thought process and tool usage. +The repository configures MCP servers for both VS Code (`.vscode/mcp.json`) and +Copilot CLI (`.mcp.json`), including the `azldev advanced mcp` server. Run Copilot +CLI from the repository root so it discovers the project configuration. + +Note: `copilot` supports fully autonomous operation (no interactive mode) with `-p `. `--yolo` (same as `--allow-all-tools --allow-all-paths --allow-all-urls`) is an option, but use with extreme caution since it grants the agent unrestricted access to your filesystem and network. For now, it's recommended to use `-i` to at least have visibility into the agent's thought process and tool usage. #### Using as a plugin (cross-repo access) diff --git a/docs/prds/agent-instructions.prd.md b/docs/prds/agent-instructions.prd.md index a237db9aab6..5e3776e90ce 100644 --- a/docs/prds/agent-instructions.prd.md +++ b/docs/prds/agent-instructions.prd.md @@ -46,6 +46,7 @@ Instruction files should work across GitHub Copilot surfaces where possible: VS | `.github/instructions/*.instructions.md` | Auto (via `applyTo` globs) | VS Code, Copilot CLI | | `.github/agents/*.agent.md` | User-selected / inferred | VS Code, Copilot CLI | | `.github/prompts/*.prompt.md` | User-invoked (`/command`) | VS Code only | +| `.mcp.json` | Auto | Copilot CLI | | `.vscode/mcp.json` | Auto | VS Code only | **Guiding principles:** @@ -106,7 +107,8 @@ Instruction files should work across GitHub Copilot surfaces where possible: VS - CI/CD integration (no meaningful CI exists yet) - Pre-commit hooks should be considered future work -- Full MCP server integration (partial support exists; see MCP Integration Roadmap section) +- Replacing all CLI-command guidance with MCP-specific workflows; the checked-in MCP + configurations currently coexist with CLI guidance - External contributor onboarding flows - Automated regeneration of agent instructions via `azldev` @@ -142,6 +144,7 @@ azurelinux/ │ │ └── SKILL.md │ └── azldev-update-component/ │ └── SKILL.md +├── .mcp.json # MCP tool configuration (Copilot CLI) ├── .vscode/ │ └── mcp.json # MCP tool configuration (VS Code) ├── base/ @@ -619,9 +622,10 @@ Agents are `.agent.md` files in `.github/agents/`. Both VS Code and Copilot CLI - [ ] Implement 0-2 agents based on evaluation - [ ] If multiple agents, consider handoffs between them for workflow continuity -### Phase 6: MCP and VS Code Integration +### Phase 6: MCP Integration - [x] Create `.vscode/mcp.json` configuration for VS Code MCP tools +- [x] Create `.mcp.json` configuration for Copilot CLI MCP tools - [ ] Document MCP tool usage in instructions once end-to-end flow is complete - [ ] Package cross-repository distribution through a Copilot plugin marketplace @@ -632,7 +636,7 @@ These aspects of the PRD should be reviewed and updated as the project evolves: | Area | Trigger for Review | Notes | | ---- | ------------------ | ----- | | **azldev commands** | New azldev release | Command syntax or new features may change | -| **MCP integration** | MCP server available | Switch from shell to MCP tools in instructions | +| **MCP integration** | MCP interface changes | Keep VS Code and Copilot CLI configs aligned; migrate CLI guidance where MCP tools improve the workflow | | **CI/CD guidance** | CI pipeline added | Add validation/testing instructions | | **Overlay patterns** | New overlay types | Document new overlay capabilities | | **Hygiene rules** | Team feedback | Rules may need adjustment based on practice |