> ## Documentation Index
> Fetch the complete documentation index at: https://docs.driftless.icu/llms.txt
> Use this file to discover all available pages before exploring further.

# Drift Detection

> How Driftless detects when code has changed relative to team context.

## How drift works

When a push arrives on a tracked branch, the API matches changed files against all workspace topics using glob pattern intersection. Any topic whose anchored patterns overlap with the changed files gets marked **drifted** with a human-readable reason.

For example, if a push to `main` changes `src/auth/guard.ts` and `src/auth/service.ts`, the `auth-flow` topic anchored to `src/auth/**` becomes:

> Drifted: 3 files changed in commit `abc1234`: `src/auth/guard.ts`, `src/auth/service.ts`, `src/auth/dto/login.dto.ts`

## Tracked branches

The **default branch** is always tracked. Additional branches can be added:

```bash theme={"theme":"github-light"}
driftless branches add staging
driftless branches add release/*
driftless branches
driftless branches rm staging
```

Feature branches are **not tracked by default**. This prevents noise because most feature work is in progress and does not represent settled architecture. Drift is reserved for branches where changes signal durable context shifts.

## Second drift source: local git (no GitHub App)

Drift normally comes from push webhooks, so a team without the GitHub App installed gets no signal. To close that gap, the CLI can report drift from your **local** checkout:

```bash theme={"theme":"github-light"}
driftless context get --diff          # show topics matching local changes (display only)
driftless context get --diff --mark   # …and flag those topics drifted on Cloud
```

`--mark` is **opt-in and explicit**. Plain `--diff` only displays, so work-in-progress never flips team state unless you ask. It's idempotent (already-drifted topics are left alone).

## A nudge, not an alarm

Drift is a **nudge**, not an error: "the code under this topic moved, worth a look." It tolerates false positives by design: trust the code, and only update the topic if the change actually altered how the area works. A deleted anchor file produces a distinct nudge: *"anchored file deleted: re-anchor or archive this topic."*

## Lifecycle

```
drifted → agent reviews → driftless context update topic --status reviewed → fresh again
drifted → no repo claims it → orphaned
```

When a topic goes drifted:

1. `driftless sync` surfaces it to every team member
2. An agent or human reviews the change
3. If the context still holds, add it to knowledge (`--status reviewed`) to make it fresh again
4. If no repo claims the topic anymore, it becomes orphaned

```bash theme={"theme":"github-light"}
driftless context update auth-flow --status reviewed
```

## Checking for drift

```bash theme={"theme":"github-light"}
driftless sync                         # shows drifted topics and what changed
driftless context doctor               # full health audit across all topics
driftless context get --diff            # drift for current local (uncommitted) changes
```

<AccordionGroup>
  <Accordion title="What triggers drift?">
    Only pushes to tracked branches. PRs do **not** trigger drift; they trigger PR observation instead (the match is recorded, and the Auditor, if configured, reviews and comments only when it has a finding). This distinction keeps drift meaningful: a push to `main` or `staging` means the code has actually changed, while a PR is still under review and may not merge.
  </Accordion>

  <Accordion title="Can I manually mark a topic as drifted?">
    Yes. Run `driftless context update <slug> --status draft` to mark it for review, or update the content and set `--status reviewed` to clear drift. You can also let the next push naturally trigger a drift check.
  </Accordion>

  <Accordion title="What happens if a topic's anchored files are deleted?">
    The topic becomes drifted on the next push. If the glob patterns no longer match any file in the repo, `context doctor` flags it as a **zombie**, an anchor pointing at nothing. Fix the patterns or archive the topic.
  </Accordion>
</AccordionGroup>
