Skip to content
Merged
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
1 change: 1 addition & 0 deletions .claude/agent-memory/archgate-developer/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Skipping steps 2 or 3 is a workflow violation. The user should NEVER have to inv
- **GitHub CodeQL "default setup" can silently skip PRs — use an explicit workflow** — The repository-level "default setup" for CodeQL does not guarantee analysis on every PR. PR #279 (Renovate deps update) had zero CodeQL analyses, dropping the Scorecard SAST score from 10 to 9. Fix: add an explicit `.github/workflows/codeql.yml` that runs on `push: [main]`, `pull_request: [main]`, and a weekly schedule. After merging, disable the "default setup" in repository Settings > Code security > Code scanning to avoid duplicate analyses. The explicit workflow gives Scorecard a detectable `github/codeql-action` reference and guarantees coverage.
- **`GITHUB_TOKEN`-authored pushes do NOT trigger downstream workflows — release.yml MUST use the GH App token** — When an Actions workflow pushes commits or opens PRs using `${{ github.token }}` / `secrets.GITHUB_TOKEN`, GitHub intentionally suppresses the resulting `push` / `pull_request` events to prevent recursion. Symptom on release PRs: the head SHA has no `pull_request`-event check runs, so `Validate Code` / `Lint, Test & Check` / `DCO Sign-off Check` are missing from the PR rollup and branch protection treats the PR as missing required checks. PR [#131](https://github.com/archgate/cli/pull/131) papered over this by manually `gh workflow run` + posting commit statuses, but `workflow_dispatch` runs land on `head_branch: release` with `pull_requests: []` — they are not associated with the PR ref, so `Lint, Test & Check` stayed orphaned and the bug recurred on PR [#251](https://github.com/archgate/cli/pull/251). Root-cause fix: in `release.yml` the `pull-request` job MUST generate a GitHub App installation token via `actions/create-github-app-token` (using `secrets.GH_APP_APP_ID` / `secrets.GH_APP_PRIVATE_KEY`) and pass it to BOTH `actions/checkout` and `simple-release-action`. App-token-authored pushes DO trigger `pull_request` events naturally. Apply the same pattern to any future workflow that pushes to a branch whose downstream CI must run.

- **`Bun.env` modifications in parallel test files leak into integration test subprocesses** — Bun test runner runs all test files in a single process sharing `Bun.env`. Tests that set `Bun.env.HOME`, `Bun.env.GIT_CONFIG_NOSYSTEM`, or `Bun.env.GIT_CONFIG_GLOBAL` (e.g., `auth.test.ts`, `credential-store.test.ts`) modify the shared environment. Integration tests that spawn CLI subprocesses via `runCli()` spread `process.env` (which IS `Bun.env`) into the child, inheriting the leaked values. Symptom: git operations in the subprocess fail with "not a git repo" or similar, but the test passes in isolation. Fix: integration tests that rely on git must explicitly reset git-related env vars in the `runCli` call: `runCli(args, dir, { GIT_CONFIG_NOSYSTEM: "", GIT_CONFIG_GLOBAL: "" })`. Applied in `tests/integration/check.test.ts` for the `--base` tests.
- **Cross-command I/O sharing: export from the existing command file, don't create shared files** — When two commands need to share I/O functions (console.log with styleText), you CANNOT put them in `src/helpers/` (ARCH-002 forbids console.log in helpers) or create a new file under `src/commands/<parent>/` without a register function (ARCH-001 requires register\*Command export, ARCH-016 requires docs heading). The correct pattern: export the shared functions from the command file that already defines them (e.g., `plugin/install.ts` exports `installForEditor()` and `printManualInstructions()`) and import them in the other command. Applied in `upgrade.ts` importing from `./plugin/install`.

## Validation Pipeline
Expand Down
92 changes: 69 additions & 23 deletions docs/public/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -789,11 +789,11 @@ The `check` function receives a `RuleContext` object that provides everything a

### Project Information

| Property | Type | Description |
| ------------------ | ---------- | -------------------------------------------------------------------------------- |
| `ctx.projectRoot` | `string` | Absolute path to the project root directory |
| `ctx.scopedFiles` | `string[]` | Files matching the ADR's `files` globs, or all project files if no globs are set |
| `ctx.changedFiles` | `string[]` | Files changed in git (populated when running with `--staged`) |
| Property | Type | Description |
| ------------------ | ---------- | ---------------------------------------------------------------------------------- |
| `ctx.projectRoot` | `string` | Absolute path to the project root directory |
| `ctx.scopedFiles` | `string[]` | Files matching the ADR's `files` globs, or all project files if no globs are set |
| `ctx.changedFiles` | `string[]` | Files changed in git (auto-detected from branch diff, or from `--staged`/`--base`) |

### File Operations

Expand Down Expand Up @@ -897,7 +897,7 @@ Rules execute with the following guarantees:
- **Parallel across ADRs** -- Rules from different ADRs run concurrently for faster execution.
- **Sequential within an ADR** -- Rules belonging to the same ADR run one after another, so earlier rules can establish context for later ones.
- **Scoped files are pre-resolved** -- The `ctx.scopedFiles` array is populated before your `check` function is called, based on the ADR's `files` globs.
- **Changed files for staged mode** -- When running `archgate check --staged`, `ctx.changedFiles` contains only the files staged in git, letting rules skip unchanged files for faster feedback.
- **Changed files auto-detected** -- `ctx.changedFiles` is automatically populated with the branch diff against the base branch (e.g., `main`). Use `--staged` for pre-commit hooks (staged files only) or `--base <ref>` for an explicit base. This enables cross-file dependency rules to work locally, not just in CI.

The editor plugins for [Claude Code](/guides/claude-code-plugin/) and [Cursor](/guides/cursor-integration/) run `archgate check` automatically after every code change. The agent reads the applicable ADRs, writes compliant code, and validates -- no manual check commands needed. [Sign up for beta access](https://plugins.archgate.dev).

Expand Down Expand Up @@ -1045,6 +1045,16 @@ Warnings (severity `warning`) are logged but do not affect the exit code. Only `

## Narrowing scope

### Check files changed in the PR

Use `--base` to compare against the PR's base branch. This gives cross-file dependency rules the full picture of what changed:

```yaml
- run: archgate check --base origin/${{ github.base_ref }}
```

Without `--base`, the base branch is auto-detected from `origin/HEAD`. The explicit form is recommended in CI for deterministic behavior.

### Check only staged files

Use `--staged` to limit checking to git-staged files. This is useful in pre-commit hooks or when you only want to validate what is about to be committed:
Expand Down Expand Up @@ -2721,14 +2731,22 @@ Use `ctx.scopedFiles` when your rule should only apply to files the ADR governs.

### ctx.changedFiles

An array of file paths that have been modified (git staged or changed). Useful for incremental checking -- only validate files that were actually touched.
An array of file paths that differ from the base branch. Auto-detected by default, or populated from `--staged` / `--base <ref>`. Useful for incremental checking and cross-file dependency rules.

```typescript
// Incremental checking -- only validate changed files
const filesToCheck = ctx.scopedFiles.filter((f) =>
ctx.changedFiles.includes(f)
);
for (const file of filesToCheck) {
// Only check changed files

// Cross-file dependency -- if file A changed, file B must also change
if (ctx.changedFiles.includes("config/database.yml")) {
if (!ctx.changedFiles.includes("deploy/manifest.yml")) {
ctx.report.violation({
message: "config changed but manifest was not bumped",
file: "config/database.yml",
});
}
}
```

Expand Down Expand Up @@ -2899,7 +2917,7 @@ ARCH-006/no-unapproved-deps
}
```

2. **Use `ctx.changedFiles` for incremental checking.** When running `archgate check --staged`, `ctx.changedFiles` contains only the git-staged files. Filter `ctx.scopedFiles` against it to check only what changed.
2. **Use `ctx.changedFiles` for incremental checking.** `ctx.changedFiles` is auto-populated with the branch diff (or staged files with `--staged`). Filter `ctx.scopedFiles` against it to check only what changed, or use it directly for cross-file dependency rules.

3. **Keep rules focused on one concern.** A rule that checks both naming conventions and import patterns should be split into two rules with separate IDs.

Expand Down Expand Up @@ -3571,13 +3589,14 @@ Loads every ADR with `rules: true` in its frontmatter, executes the companion `.

## Options

| Option | Description |
| ------------ | --------------------------------------------------------- |
| `--staged` | Only check git-staged files (useful for pre-commit hooks) |
| `--json` | Machine-readable JSON output |
| `--ci` | GitHub Actions annotation format |
| `--adr <id>` | Only check rules from a specific ADR |
| `--verbose` | Show passing rules and timing info |
| Option | Description |
| -------------- | -------------------------------------------------------------------- |
| `--staged` | Only check git-staged files (useful for pre-commit hooks) |
| `--base [ref]` | Compare changed files against a base ref (auto-detects when omitted) |
| `--json` | Machine-readable JSON output |
| `--ci` | GitHub Actions annotation format |
| `--adr <id>` | Only check rules from a specific ADR |
| `--verbose` | Show passing rules and timing info |

## Arguments

Expand Down Expand Up @@ -3607,6 +3626,12 @@ Check only staged files before committing:
archgate check --staged
```

Check all files changed on the current branch vs `main`:

```bash
archgate check --base main
```

Check a single ADR:

```bash
Expand Down Expand Up @@ -3637,6 +3662,26 @@ Get GitHub Actions annotations:
archgate check --ci
```

## Changed files detection

By default, `archgate check` auto-detects the base branch and populates `ctx.changedFiles` with the branch diff (`git diff <base>...HEAD`). This enables cross-file dependency rules to work locally -- not just in CI.

The base ref is resolved in priority order:

| Priority | Source | `changedFiles` populated with |
| -------- | ------------------------------------ | -------------------------------- |
| 1 | `--staged` | Git staging area only |
| 2 | `--base <ref>` | `git diff <ref>...HEAD` |
| 3 | `.archgate/config.json` `baseBranch` | `git diff <resolved-ref>...HEAD` |
| 4 | Git auto-detect | `git diff <detected-ref>...HEAD` |
| 5 | Detection fails | Empty (full-scan mode) |

Auto-detection tries `origin/HEAD`, then `origin/main`, `origin/master`, local `main`, and local `master`. To set a project default, add `baseBranch` to `.archgate/config.json`:

```json
{ "baseBranch": "main" }
```

## Diagnostics

During execution, `archgate check` emits warnings for common misconfigurations that may cause slow or unexpected results:
Expand Down Expand Up @@ -4108,11 +4153,12 @@ archgate review-context [options]

## Options

| Option | Description |
| ------------------- | ------------------------------------ |
| `--staged` | Only include git-staged files |
| `--run-checks` | Include ADR compliance check results |
| `--domain <domain>` | Filter to a single domain |
| Option | Description |
| ------------------- | -------------------------------------------------------------------- |
| `--staged` | Only include git-staged files |
| `--base [ref]` | Compare changed files against a base ref (auto-detects when omitted) |
| `--run-checks` | Include ADR compliance check results |
| `--domain <domain>` | Filter to a single domain |

## Example

Expand Down Expand Up @@ -4624,7 +4670,7 @@ Files matching the ADR's `files` glob patterns from its frontmatter. If the ADR
changedFiles: string[];
```

Files that have been modified according to git. When `--staged` is used, this contains only staged files. When running without `--staged`, this contains all changed files (staged and unstaged). Empty when no git changes are detected.
Files that have been modified according to git. By default, this is auto-populated with the branch diff against the detected base branch (e.g., `origin/main`). When `--staged` is used, this contains only staged files. When `--base <ref>` is used, this contains all files changed since that ref. Empty when base detection fails or no changes are found. Use this to build cross-file dependency rules (e.g., "if file A changed, file B must also change").

#### report

Expand Down
12 changes: 6 additions & 6 deletions docs/src/content/docs/concepts/rules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ The `check` function receives a `RuleContext` object that provides everything a

### Project Information

| Property | Type | Description |
| ------------------ | ---------- | -------------------------------------------------------------------------------- |
| `ctx.projectRoot` | `string` | Absolute path to the project root directory |
| `ctx.scopedFiles` | `string[]` | Files matching the ADR's `files` globs, or all project files if no globs are set |
| `ctx.changedFiles` | `string[]` | Files changed in git (populated when running with `--staged`) |
| Property | Type | Description |
| ------------------ | ---------- | ---------------------------------------------------------------------------------- |
| `ctx.projectRoot` | `string` | Absolute path to the project root directory |
| `ctx.scopedFiles` | `string[]` | Files matching the ADR's `files` globs, or all project files if no globs are set |
| `ctx.changedFiles` | `string[]` | Files changed in git (auto-detected from branch diff, or from `--staged`/`--base`) |

### File Operations

Expand Down Expand Up @@ -163,7 +163,7 @@ Rules execute with the following guarantees:
- **Parallel across ADRs** -- Rules from different ADRs run concurrently for faster execution.
- **Sequential within an ADR** -- Rules belonging to the same ADR run one after another, so earlier rules can establish context for later ones.
- **Scoped files are pre-resolved** -- The `ctx.scopedFiles` array is populated before your `check` function is called, based on the ADR's `files` globs.
- **Changed files for staged mode** -- When running `archgate check --staged`, `ctx.changedFiles` contains only the files staged in git, letting rules skip unchanged files for faster feedback.
- **Changed files auto-detected** -- `ctx.changedFiles` is automatically populated with the branch diff against the base branch (e.g., `main`). Use `--staged` for pre-commit hooks (staged files only) or `--base <ref>` for an explicit base. This enables cross-file dependency rules to work locally, not just in CI.

:::tip[Run checks automatically with editor plugins]
The editor plugins for [Claude Code](/guides/claude-code-plugin/) and [Cursor](/guides/cursor-integration/) run `archgate check` automatically after every code change. The agent reads the applicable ADRs, writes compliant code, and validates -- no manual check commands needed. [Sign up for beta access](https://plugins.archgate.dev).
Expand Down
10 changes: 10 additions & 0 deletions docs/src/content/docs/guides/ci-integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ Warnings (severity `warning`) are logged but do not affect the exit code. Only `

## Narrowing scope

### Check files changed in the PR

Use `--base` to compare against the PR's base branch. This gives cross-file dependency rules the full picture of what changed:

```yaml
- run: archgate check --base origin/${{ github.base_ref }}
```

Without `--base`, the base branch is auto-detected from `origin/HEAD`. The explicit form is recommended in CI for deterministic behavior.

### Check only staged files

Use `--staged` to limit checking to git-staged files. This is useful in pre-commit hooks or when you only want to validate what is about to be committed:
Expand Down
16 changes: 12 additions & 4 deletions docs/src/content/docs/guides/writing-rules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,22 @@ Use `ctx.scopedFiles` when your rule should only apply to files the ADR governs.

### ctx.changedFiles

An array of file paths that have been modified (git staged or changed). Useful for incremental checking -- only validate files that were actually touched.
An array of file paths that differ from the base branch. Auto-detected by default, or populated from `--staged` / `--base <ref>`. Useful for incremental checking and cross-file dependency rules.

```typescript
// Incremental checking -- only validate changed files
const filesToCheck = ctx.scopedFiles.filter((f) =>
ctx.changedFiles.includes(f)
);
for (const file of filesToCheck) {
// Only check changed files

// Cross-file dependency -- if file A changed, file B must also change
if (ctx.changedFiles.includes("config/database.yml")) {
if (!ctx.changedFiles.includes("deploy/manifest.yml")) {
ctx.report.violation({
message: "config changed but manifest was not bumped",
file: "config/database.yml",
});
}
}
```

Expand Down Expand Up @@ -277,7 +285,7 @@ ARCH-006/no-unapproved-deps
}
```

2. **Use `ctx.changedFiles` for incremental checking.** When running `archgate check --staged`, `ctx.changedFiles` contains only the git-staged files. Filter `ctx.scopedFiles` against it to check only what changed.
2. **Use `ctx.changedFiles` for incremental checking.** `ctx.changedFiles` is auto-populated with the branch diff (or staged files with `--staged`). Filter `ctx.scopedFiles` against it to check only what changed, or use it directly for cross-file dependency rules.

3. **Keep rules focused on one concern.** A rule that checks both naming conventions and import patterns should be split into two rules with separate IDs.

Expand Down
Loading
Loading