# How SPECIFYFEATURE Environment Variable Overrides Feature Detection in Non-Git Repositories

> Learn how the SPECIFYFEATURE environment variable overrides Spec-Kit feature detection in non-Git repositories. Force feature enablement or disablement bypassing auto-detection.

- Repository: [GitHub/spec-kit](https://github.com/github/spec-kit)
- Tags: how-to-guide
- Published: 2026-03-05

---

**The `SPECIFYFEATURE` environment variable forces specific features to be enabled or disabled in Spec-Kit when running outside a Git repository, bypassing automatic detection that relies on the presence of a `.git` folder.**

Spec-Kit performs automatic feature detection to determine available capabilities by scanning for Git metadata and configuration files. When operating in directories without version control initialization, the `SPECIFYFEATURE` environment variable allows developers to explicitly override conservative defaults and control which features remain active.

## Feature Detection in Non-Git Environments

When Spec-Kit initializes in a directory lacking a `.git` folder, the detection routine in [`src/specify_cli/feature_detection.py`](https://github.com/github/spec-kit/blob/main/src/specify_cli/feature_detection.py) falls back to a conservative feature set. This prevents unintended modifications by defaulting to a restricted mode that disables capabilities like auto-commit workflows and changelog generation.

The `SPECIFYFEATURE` environment variable provides an override mechanism defined in [`src/specify_cli/config.py`](https://github.com/github/spec-kit/blob/main/src/specify_cli/config.py), allowing explicit feature control even when repository metadata is absent.

## How SPECIFYFEATURE Processing Works

According to the implementation in `github/spec-kit`, the environment variable undergoes four processing stages during CLI initialization:

1. **Variable Retrieval** – The configuration loader executes:
   
   ```python
   SPECIFYFEATURE = os.getenv("SPECIFYFEATURE", "")
   ```

2. **Tokenization** – The string splits on commas to produce a list of feature identifiers, such as `["changelog", "gitignore"]`.

3. **Feature Merge** – The parsed list merges with automatically detected features. Features present in the variable are forced enabled, while those prefixed with a leading `!` are forced disabled.

4. **Global Activation** – The resulting feature set populates the `ACTIVE_FEATURES` object, which commands like `specify init`, `specify add`, and `specify release` reference to determine available functionality.

## Practical Usage Examples

### Force-Enabling Features Outside Git

To enable changelog and gitignore generation when initializing a project in a non-Git directory:

```bash
export SPECIFYFEATURE=changelog,gitignore
specify init --ai opencode

```

### Disabling Specific Capabilities

To suppress the auto-commit feature while retaining other detected capabilities:

```bash
export SPECIFYFEATURE=!autocommit
specify init

```

### CI Pipeline Configuration

For automated environments where Git context may be unavailable:

```bash
SPECIFYFEATURE=changelog,gitignore SPECIFYCI=true spec-ci-run

```

## Key Implementation Files

The override mechanism spans three critical components:

- **[`src/specify_cli/config.py`](https://github.com/github/spec-kit/blob/main/src/specify_cli/config.py)** – Contains the `os.getenv` retrieval and parsing logic that transforms the environment string into the `ACTIVE_FEATURES` data structure.

- **[`src/specify_cli/feature_detection.py`](https://github.com/github/spec-kit/blob/main/src/specify_cli/feature_detection.py)** – Implements the default detection logic that executes when no `.git` folder exists, establishing the baseline feature set that `SPECIFYFEATURE` modifies.

- **[`src/specify_cli/commands/init.py`](https://github.com/github/spec-kit/blob/main/src/specify_cli/commands/init.py)** – Consumes the resolved `ACTIVE_FEATURES` object to determine which scaffolding files and workflows to generate during project initialization.

## Summary

- The `SPECIFYFEATURE` environment variable explicitly controls feature availability when automatic Git-based detection is unavailable or produces conservative results.
- Values are comma-separated feature names; prefix with `!` to disable rather than enable specific capabilities.
- The override integrates with detection results in [`src/specify_cli/config.py`](https://github.com/github/spec-kit/blob/main/src/specify_cli/config.py), storing the final configuration in the global `ACTIVE_FEATURES` object.
- This mechanism enables full Spec-Kit functionality in non-Git directories, containerized environments, and CI pipelines where repository metadata is absent.

## Frequently Asked Questions

### What is the difference between SPECIFYFEATURE and SPECIFYCI?

`SPECIFYFEATURE` controls which capabilities are enabled (e.g., changelog, gitignore), while `SPECIFYCI` indicates the tool is running in a continuous integration environment, potentially altering output formatting or interactive prompts. They can be used together to configure headless, non-Git environments.

### Can I use SPECIFYFEATURE in a normal Git repository?

Yes. While primarily useful for non-Git directories, setting `SPECIFYFEATURE` in a Git repository still overrides the automatic detection results in [`src/specify_cli/feature_detection.py`](https://github.com/github/spec-kit/blob/main/src/specify_cli/feature_detection.py), allowing you to force-disable features that would otherwise be enabled based on repository metadata.

### How do I disable multiple features at once using SPECIFYFEATURE?

Prefix each feature name with an exclamation mark and separate them with commas. For example, `export SPECIFYFEATURE=!autocommit,!changelog` forces both features to be disabled regardless of the automatic detection results.

### Where is the final feature configuration stored after parsing?

After parsing in [`src/specify_cli/config.py`](https://github.com/github/spec-kit/blob/main/src/specify_cli/config.py), the resolved feature set is stored in the global `ACTIVE_FEATURES` object. This object is referenced by command implementations including `specify init`, `specify add`, and `specify release` to determine which functionality to expose during execution.