Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion .github/instructions/agent-skills.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,32 @@ Before shipping any skill/instruction:
`TestOverlaysSkillCoversAllOverlayTypes` extracts the overlay-type enum from the jsonschema tag
on `projectconfig.ComponentOverlay.Type` and fails if the skill omits a type.

## Mode-specific content

azldev has two modes, and the emitted content follows the one it runs in. A `Catalog`
(`NewCatalog(withoutLockfile)`) resolves the skills, instruction wrappers, and templates;
the package-level `Skills`, `Instructions`, `FindSkill`, `SkillDocument`, and `Files`
helpers are the default (lock-file) mode.

- **Shared by default.** Registry entries and templates under `content/` describe the
default mode and are used by both, so most edits need nothing extra.
- **Replace only what differs.** `withoutLockfileSkills` replaces registry entries by the
name of the default-mode skill it supersedes, and `withoutLockfileInstructions` replaces
instruction descriptions. Pointers to a replaced skill are rewritten automatically.
- **Templates layer.** A template under `content/withoutlockfile/` replaces the
same-named default template for that mode; add one only when the document's content
actually differs.

When you add or edit a skill, check whether its content names a command that exists in
only one mode (for example `comp update` versus `comp refresh-upstream-commit`) and, if
so, provide the mode-specific variant. Verify both with
`./out/bin/azldev docs agent show --skill <name>` and
`./out/bin/azldev --without-lockfile docs agent show --skill <name>`.

## Config-resolved bindings

Repo-specific values (lock dir, rendered-specs dir, work dir) are resolved from the target `azldev.toml` in
Repo-specific values (lock dir, generated upstream-commit dir, rendered-specs dir, work
dir) are resolved from the target `azldev.toml` in
[cmds/docs/agent.go](../../internal/app/azldev/cmds/docs/agent.go) and degrade to azldev's defaults
when no config is present. To add a binding, extend `Bindings`, resolve it in `resolveBindings`, and
reference it in a template as `{{ .FieldName }}`.
Expand Down
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,51 @@ All notable changes to `azldev` are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **`--without-lockfile` preview mode.** Add a global `--without-lockfile`
flag that opts in to a preview of tracking resolved upstream commits in
generated component configuration instead of per-component lock files. The
flag defaults to off; without it azldev's behavior, command set, and
configuration handling are unchanged. The preview surface is not stable and
may change.
- **Generated upstream commit configuration.** With `--without-lockfile`,
record snapshot-selected upstream commits as normal layered TOML under
`base/upstream-commits`. Generated pin files participate in standard
configuration loading, merging, provenance tracking, and validation, and the
project's `lock-dir` setting is accepted but ignored.
- **Upstream commit refresh command.** With `--without-lockfile`, `azldev
component refresh-upstream-commit` resolves and records upstream commits. It
supports check-only operation, removes obsolete pins for selected
non-upstream components, and prunes orphaned generated files when all
components are selected. Configuration is loaded permissively for this
command so stale generated pins can be removed after a component is deleted
or converted to another source type.

### Changed

- **Mode-specific component commands.** With `--without-lockfile`, `azldev
component update`, `component history`, and `component query` are replaced by
hidden no-op shims, and the lock-file-only `--skip-lock-validation` flag is
not registered. All of them are unchanged in the default mode.
- **Configuration-based component change detection.** With
`--without-lockfile`, `azldev component changed` loads each historical
project configuration independently and compares normalized build inputs
instead of stored fingerprints. It handles added and deleted components,
resolves recursive includes and inherited defaults at each ref, compares
local source and overlay content, and reports rendered `sources` changes
separately.
- **Synthetic source history.** With `--without-lockfile`, synthetic dist-git
history is built from configured upstream commit transitions and walks
first-parent history to the repository root instead of relying on
lock-recorded import commits.
- **Component workflow guidance.** Agent skills, instruction files, and MCP
tools describe the workflow of the mode azldev runs in. The generated CLI
reference continues to document the default mode; the preview mode is
documented in the user guide.

## [0.3.0] - 2026-08-10

### Added
Expand Down
1 change: 1 addition & 0 deletions docs/user/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Build a Component](./how-to/build-component.md) — build RPMs from component definitions
- [Build an Image](./how-to/build-image.md) — build and boot Azure Linux images
- [Set Up AI Coding Agents](./how-to/set-up-ai-agents.md) — emit agent skill and instruction files
- [Preview the Lock-File-Free Mode](./how-to/preview-without-lockfile.md) — opt in to `--without-lockfile`

## Explanation

Expand Down
2 changes: 2 additions & 0 deletions docs/user/explanation/config-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ Component definitions are merged additively. If the same component name (e.g., `

> **Note:** Slice fields (like `overlays`) are **appended**, not replaced, following the same merge behavior used by component configuration inheritance.

> **Preview:** With the global `--without-lockfile` flag, component definitions merge with override semantics instead, and component validation runs only after every included file has been merged, so an individual file may hold a partial component definition. See [Preview the Lock-File-Free Mode](../how-to/preview-without-lockfile.md).

### Component Groups and Images

These are strict-union maps: each name may appear in exactly one config file across the entire include tree. If two files both define `[component-groups.my-group]` or `[images.my-image]`, azldev reports an error. This prevents accidental shadowing and makes it clear where each definition lives.
Expand Down
109 changes: 109 additions & 0 deletions docs/user/how-to/preview-without-lockfile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# How To: Preview the Lock-File-Free Mode

`--without-lockfile` is a **preview** global flag. It selects an alternative way of
tracking a component's resolved upstream commit: instead of per-component lock
files, azldev records the commit in generated component TOML that the project
includes like any other config file.

The flag is opt-in and defaults to off. Without it, azldev behaves exactly as it
always has — lock files, `component update`, `component history`, and
`component query` are unchanged. Nothing in the preview mode is stable yet; both
the command surface and the generated file layout may change.

```bash
# Default behavior: lock files.
azldev component render -p curl

# Preview behavior: generated upstream-commit config.
azldev --without-lockfile component render -p curl
```

Pass the flag on every invocation that should use the preview mode, before the
command name. `--without-lockfile=false` explicitly selects the default mode.

## What Changes

| Area | Default | `--without-lockfile` |
|------|---------|----------------------|
| Resolved commit storage | `locks/<name>.lock` | `base/upstream-commits/<name>.toml` |
| Refresh command | `azldev component update` | `azldev component refresh-upstream-commit` |
| Inspecting resolved state | `azldev component history`, `azldev component query` | read the generated TOML; no equivalent commands |
| Lock consistency checks | On, with `--skip-lock-validation` to opt out | Not applicable; the flag is not registered |
| `component changed` | Compares stored input fingerprints | Compares project configuration resolved at each ref |
| Synthetic dist-git history | Derived from lock-file fingerprint changes | Derived from generated upstream-commit TOML changes |
| Agent skills and MCP tools | Describe the lock-file workflow | Describe the upstream-commit workflow |

`component update`, `component history`, and `component query` remain registered
in preview mode as hidden no-ops so that existing scripts report clearly that the
commands do nothing, rather than failing with "unknown command".

## Configure the Project

Include the generated directory **before** the component-specific TOML, so that a
component definition can still override the generated pin:

```toml
includes = [
"base/upstream-commits/*.toml",
"base/components/*.toml",
]
```

Generated files hold only `spec.upstream-commit`; the component's own TOML
supplies the source type and everything else. Because a single file may hold a
partial component definition in this mode, component validation runs after all
config files have been merged.

An existing `[project] lock-dir` setting is accepted and ignored in preview mode,
so the same project config works in both modes.

## Refresh a Component

```bash
# Resolve and record the upstream commit for one component.
azldev --without-lockfile component refresh-upstream-commit -p curl

# Refresh everything and prune generated files for components that no longer exist.
azldev --without-lockfile component refresh-upstream-commit -a

# CI gate: exit 1 when any generated file is out of date.
azldev --without-lockfile component refresh-upstream-commit -a --check-only -q
```

Refresh after changing a commit pin, upstream distro or version, or snapshot.
Overlay, build-config, and metadata changes do not affect the resolved commit, so
they need only a re-render.

Commit the refreshed TOML together with the rendered output: synthetic dist-git
history — and therefore `%autorelease` and `%autochangelog` expansion — is derived
from committed changes to the generated file. Unlike the default mode, there is no
fingerprint to compare the working tree against, so uncommitted changes do not
produce a synthetic commit.

## Detect Changed Components

```bash
azldev --without-lockfile component changed --from main -a -q -O json
```

In preview mode this loads the project configuration independently at both refs
and compares the resolved component build inputs: normalized component
configuration, upstream commit or local spec-directory contents, overlay source
filenames and contents, and the effective distro release version. Documentation,
publishing, test-selection, scheduling-hint, snapshot-time, and checkout-path-only
fields do not mark a component as changed.

## Emit Agent Files for the Preview Mode

`azldev docs agent install` emits the content for the mode it runs in, so pass the
flag when the target repository uses the preview workflow:

```bash
azldev --without-lockfile docs agent install
```

## Reference Documentation

The generated CLI reference under [reference/cli/](../reference/cli/azldev.md)
documents azldev's default mode. Use `azldev --without-lockfile <command> --help`
to see the preview mode's command surface and help text.
1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_mcp.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_mock.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_mock_build-rpms.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_mock_shell.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_wget.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion_bash.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion_fish.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion_powershell.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion_zsh.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_add.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_build.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_changed.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_diff-sources.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_history.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_list.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/user/reference/cli/azldev_component_query.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading