# Configuration Guide

This guide explains not only what each `smart-commit-host-agent` setting does, but also how to choose a good value for it.

If you are new to the project, read [`getting-started.md`](./getting-started.md) first. Then use this page when you start asking:

- which fields are actually required
- which defaults are safe
- which settings you should change first
- which settings are easy to misconfigure

This package has **no** `connection` block. Model text always comes from Host-Agent turns. Do not add `baseUrl`, `apiKey`, or `model`.

## Start Here

For most first-time users, the real minimum is:

- `review.threshold`
- `git.autoCommit`
- `git.autoPush`

Use this as your safe starting point:

```json
{
  "smartCommitHostAgent": {
    "review": {
      "threshold": 6,
      "language": "zh-cn"
    },
    "git": {
      "autoCommit": false,
      "autoPush": false
    }
  }
}
```

This gives you a review-first workflow with no commit or push side effects.

Built-in defaults currently enable `git.autoCommit`, `git.autoPush`, and `pullRequestCreation.autoCreateAfterPush`. First-use configs should override those to `false`.

## Recommended Format

Use the canonical JSON format:

```json
{
  "smartCommitHostAgent": {
    "review": {
      "threshold": 6,
      "language": "zh-cn"
    }
  }
}
```

Config files, including overlay files, must use the root key `smartCommitHostAgent` only. A `smartCommitCli` root key is rejected. Any `connection` object inside `smartCommitHostAgent` is stripped.

## How Configuration Is Resolved

The CLI merges config from high to low precedence:

1. CLI arguments
2. environment variables
3. `smartCommitHostAgent` in a JSON config file, then an optional creation or review overlay
4. built-in defaults

The command line always wins, which is useful for temporarily overriding a shared config file.

Explicit `--config <path>` is required to load a file. There is no silent auto-discovery of a default filename.

`pullRequestCreation.configFilePath` and `pullRequestReview.configFilePath` accept a comma-separated list of local overlay paths. The CLI uses the first existing file. Relative paths resolve against `--repo` when that flag is set, otherwise against the current working directory. Overlay files must also use the root key `smartCommitHostAgent` only. A creation overlay may contain only `pullRequestCreation` and must not set `configFilePath` or `autoCreateAfterPush`. A review overlay may contain only `pullRequestReview` and must not set `configFilePath`.

## `env:VAR_NAME` References

Config strings that match `env:VAR_NAME` are resolved from the process environment after merge and before validation.

Recommended for secrets:

```json
{
  "smartCommitHostAgent": {
    "pullRequest": {
      "authToken": "env:SMART_COMMIT_PULL_REQUEST_AUTH_TOKEN"
    }
  }
}
```

Rules:

- `pullRequest.authToken` may resolve to `""` when the env var is missing, so local-only commands can still load config
- other `env:VAR` fields fail validation if the variable is missing or empty
- never put raw tokens in committed config when you can avoid it

## The Most Important Warning

Do not copy built-in defaults blindly for first use.

Built-in defaults currently set:

- `git.autoCommit = true`
- `git.autoPush = true`
- `pullRequestCreation.autoCreateAfterPush = true`

Until you trust the workflow, keep those `false` in your config file and start with `bridge --review-only`.

## Full Configuration Example

This is the complete `smartCommitHostAgent` surface with **built-in default values**. Copy it as a field reference, then change only the fields you need.

Do not copy the Git side-effect defaults into a first-use file. Built-in defaults currently set `git.autoCommit`, `git.autoPush`, and `pullRequestCreation.autoCreateAfterPush` to `true`.

```json
{
  "smartCommitHostAgent": {
    "review": {
      "threshold": 6,
      "language": "zh-cn",
      "maxDiffChars": 200000,
      "skill": {
        "id": "code-review",
        "path": "",
        "promptTuning": ""
      }
    },
    "commitMessage": {
      "language": "zh-cn",
      "input": "",
      "maxDiffChars": 150000,
      "structure": "subjectOnly",
      "scope": "auto",
      "autoGenerate": true,
      "hybridGenerate": false,
      "skill": {
        "id": "conventional",
        "path": "",
        "promptTuning": ""
      },
      "validation": {
        "protocol": "none",
        "pattern": "",
        "extractTicketIdFromBranch": true,
        "requireTicketIdInMessage": false
      }
    },
    "git": {
      "autoStageWhenNothingStaged": true,
      "autoCommit": true,
      "autoPush": true,
      "pushTimeoutMs": 180000
    },
    "pullRequest": {
      "provider": "auto",
      "apiBaseUrl": "",
      "authToken": ""
    },
    "pullRequestCreation": {
      "autoCreateAfterPush": true,
      "configFilePath": "",
      "targetBranch": "",
      "titlePrompt": "",
      "descriptionPrompt": "",
      "maxDiffChars": 200000,
      "assignees": [],
      "reviewers": [],
      "labels": [],
      "milestone": "",
      "draft": false,
      "removeSourceBranch": true,
      "skipBranches": ["main", "master", "develop"]
    },
    "pullRequestReview": {
      "threshold": 6,
      "autoApprove": false,
      "autoMerge": false,
      "summarySeverities": ["P0", "P1", "P2"],
      "commentSeverities": ["P0", "P1"],
      "skillPromptTuning": "",
      "skipSummaryOnPass": true,
      "skipCommentOnPass": true,
      "configFilePath": ""
    },
    "myPullRequest": {
      "listScope": "account",
      "listKinds": ["created", "assigned", "reviewer"],
      "batchReviewKinds": ["reviewer", "assigned"],
      "remoteHost": ""
    },
    "passHistory": {
      "enabled": false,
      "writeStage": "review_passed",
      "outputDirPath": "",
      "maxEntries": 3000
    },
    "reporting": {
      "language": "zh-cn",
      "weekStartsOn": "monday",
      "outputDirPath": "",
      "maxInputChars": 200000,
      "prompt": "",
      "ai": {
        "enabled": false
      }
    },
    "output": {
      "format": "json",
      "logLevel": "info"
    }
  }
}
```

## Safe Team Rollout Example

```json
{
  "smartCommitHostAgent": {
    "review": {
      "threshold": 6,
      "language": "zh-cn"
    },
    "git": {
      "autoStageWhenNothingStaged": true,
      "autoCommit": false,
      "autoPush": false
    },
    "pullRequest": {
      "provider": "auto",
      "authToken": "env:SMART_COMMIT_PULL_REQUEST_AUTH_TOKEN"
    },
    "pullRequestCreation": {
      "autoCreateAfterPush": false
    },
    "pullRequestReview": {
      "autoApprove": false,
      "autoMerge": false
    },
    "passHistory": {
      "enabled": true,
      "writeStage": "review_passed"
    },
    "output": {
      "format": "json",
      "logLevel": "info"
    }
  }
}
```

This keeps the workflow review-first, allows local history for reporting, and stays safe for skills until you enable Git side effects.

## Field-By-Field Decision Guide

### `review.*`

These settings control review quality, language, and pass-or-block behavior.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `review.threshold` | `6` | `6` | Lower it if you get too many false blocks; raise it if you want stricter gating | Misreading the rule: `score <= threshold` blocks, `score > threshold` passes |
| `review.language` | `zh-cn` | `zh-cn` or `en`, depending on your team | Change it when your team wants review output in a different language | Assuming it changes Git behavior instead of review text |
| `review.maxDiffChars` | `200000` | Leave default first | Lower it if very large diffs are too slow | Setting it below `1000`, which fails validation |
| `review.skill.id` | `code-review` | `code-review` | Change it when the repo needs domain-specific built-in review guidance | Using an unsupported id |
| `review.skill.path` | empty string | Leave empty first | Set a custom review rules file relative to the repository root | Setting a path and expecting the built-in id to still load |
| `review.skill.promptTuning` | empty string | Leave empty first | Short extra instruction when a full skill file is too heavy | Putting a handbook into one string |

Supported built-in review skill ids:

- `code-review`
- `frontend-code-review`
- `mobile-code-review`
- `c-code-review`
- `python-code-review`
- `golang-code-review`
- `java-code-review`
- `cpp-code-review`
- `csharp-code-review`
- `rust-code-review`
- `php-code-review`

When `review.skill.path` is non-empty, only that custom file is used: the bundled id is ignored, and the classifier selected domain is `generic`. A relative `path` is resolved against the reviewed `repositoryPath`, not the config file directory. The domain classifier can fall back to generic review when the diff does not match a specialized id.

Line-number annotation and per-line finding rules apply only to `pull-request review` / `my-pull-request batch-review`, not staged `bridge`.

### `commitMessage.*`

These settings control where the commit message comes from and how it is validated.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `commitMessage.input` | empty string | Leave empty first | Set it when you already know the exact message | Setting it and expecting auto-generation to replace it |
| `commitMessage.language` | `zh-cn` | `zh-cn` or `en` | Match the team's commit language | Mixing English convention with a non-English expectation |
| `commitMessage.maxDiffChars` | `150000` | Leave default first | Lower it if commit-message turns are too large | Setting it below `1000` |
| `commitMessage.structure` | `subjectOnly` | `subjectOnly` | Change when the team wants body/footer | Expecting extra lines while `subjectOnly` is active |
| `commitMessage.scope` | `auto` | `auto` | Set `required` or `forbidden` to force or strip Conventional/Semantic `(scope)` | Confusing this with `myPullRequest.listScope`, or expecting Gitmoji to grow a typed scope |
| `commitMessage.autoGenerate` | `true` | `true` | Set `false` only if users always provide a message | Turning it off with no provided message |
| `commitMessage.hybridGenerate` | `false` | `false` | Set `true` when a draft should be refined by a turn | Expecting hybrid without `commitMessage.input` / `--commit-message` |
| `commitMessage.skill.id` | `conventional` | `conventional` | Change when you prefer semantic or gitmoji guidance | Assuming skill id validates the subject; `validation.protocol` does |
| `commitMessage.skill.path` | empty string | Leave empty first | Set a custom policy file | Empty custom file |
| `commitMessage.skill.promptTuning` | empty string | Leave empty first | Short extra guidance | Putting a handbook into one string |
| `commitMessage.validation.protocol` | `none` | `none` first, then `conventional` if the team standardizes on it | When the team enforces a commit style | Enabling validation before generation matches that style |
| `commitMessage.validation.pattern` | empty string | Leave empty first | Extra JavaScript regex on the subject | Invalid regex |
| `commitMessage.validation.extractTicketIdFromBranch` | `true` | `true` if branches contain ticket ids | Set `false` if they do not | Expecting extraction from branches with no ticket ids |
| `commitMessage.validation.requireTicketIdInMessage` | `false` | `false` first | Set `true` only if process requires ticket ids | Enforcing it before branch naming is aligned |

`--commit-message` is equivalent to provided `commitMessage.input`. How `hybridGenerate` actually works:

- if `commitMessage.input` is present and `hybridGenerate=false`, validate and use the provided message directly
- if `commitMessage.input` is present and `hybridGenerate=true`, use the draft as input to a host-agent turn and return a refined message
- if `commitMessage.input` is empty and `autoGenerate=true`, generate from the diff
- if `commitMessage.input` is empty and `autoGenerate=false`, error because no message source exists

How `commitMessage.scope` actually works:

- `auto` keeps today's optional `(scope)` behavior for Conventional / Semantic subjects
- `required` demands a non-empty `type(scope):` on typed subjects; generation and provided messages fail immediately
- `forbidden` strips `(scope)` from typed subjects without an extra host-agent turn
- Gitmoji and other non-typed subjects are left unchanged
- `required` / `forbidden` make Conventional and Semantic subjects look the same; only `auto` still differs by skill examples
- this setting does not affect `myPullRequest.listScope`

Supported commit message structures:

- `subjectOnly`
- `subjectBody`
- `subjectBodyFooter`

Supported validation protocols:

- `none`
- `conventional`
- `semantic`
- `gitmoji`

Supported built-in commit message skill ids:

- `conventional`
- `semantic`
- `gitmoji`

### `git.*`

These settings control whether the CLI changes Git state.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `git.autoStageWhenNothingStaged` | `true` | `true` for convenience or `false` for stricter control | Set `false` if your team wants users to explicitly stage exact files | Forgetting it is enabled and wondering why unstaged files were included |
| `git.autoCommit` | `true` | `false` | Set `true` only after review-only mode is stable | Leaving the default on during first rollout |
| `git.autoPush` | `true` | `false` | Set `true` only after your team accepts automatic push behavior | Letting first rollout push unexpectedly |
| `git.pushTimeoutMs` | `180000` | Leave default first | Increase it only if pushes are slow in your environment | Setting it below `5000`, which fails validation |

Per-run overrides: `--no-commit` and `--no-push`.

### `passHistory.*`

These settings control local storage for successful run history.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `passHistory.enabled` | `false` | `true` if you want reporting later | Turn it on when you want local historical reporting | Forgetting to enable it and then expecting `report generate` to summarize past work |
| `passHistory.writeStage` | `review_passed` | `review_passed` | Change it when you want pass-history records to start only after commit or push success | Assuming it changes the stored `eventType`, when it actually changes the earliest write point |
| `passHistory.outputDirPath` | empty string | Leave empty first or set `.smart-commit-cli` explicitly | Change it only if you want a custom location | Thinking empty means broken, when it actually falls back to the repo-local default directory |
| `passHistory.maxEntries` | `3000` | `3000` | Change it only if you need much shorter or longer retention | Setting it to `0` or a non-integer, which fails validation |

If `passHistory.outputDirPath` is empty, pass history is stored under the repository's `.smart-commit-cli` directory.

`passHistory.writeStage` means "the earliest successful stage that is allowed to create a record." After a record exists, later successful stages update the same record instead of appending duplicates.

- `review_passed` writes immediately after review success and can later upgrade to `commit_completed` or `commit_push_completed`
- `commit_completed` waits for a successful local commit and still preserves that record if a later push cannot start, fails, or times out
- `commit_push_completed` waits for both commit and push success; if push never succeeds, no record is written

### `reporting.*`

These settings control report generation behavior.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `reporting.language` | `zh-cn` | `zh-cn` or `en` | Change it when your team wants report output in another language | Assuming this changes review or commit-message language too |
| `reporting.weekStartsOn` | `monday` | `monday` | Change it to `sunday` only if your reporting convention starts weeks on Sunday | Picking a week start different from your team's reporting habit |
| `reporting.outputDirPath` | empty string | Leave empty first | Change it only when you want reports in a different directory | Thinking empty means invalid, when it actually falls back to the repo-local default directory |
| `reporting.maxInputChars` | `200000` | Leave default first | Lower it if report generation is too slow | Setting it below `1000`, which fails validation |
| `reporting.prompt` | empty string | Leave empty first | Add it when you want reports to emphasize business outcomes or another angle | Writing a very large prompt when a short focus instruction would do |
| `reporting.ai.enabled` | `false` | `false` first | Enable it when you want richer AI-rendered reports via a Host-Agent turn | Expecting it to call an LLM HTTP API |

If `reporting.outputDirPath` is empty, reports are written to `.smart-commit-cli/reports` under the repository root.

`--report-ai` enables the AI path for one run. That path emits `needs_host_agent` with `purpose: "report"`. On non-turn AI failures, the CLI falls back to local Markdown.

### `pullRequest.*`

These settings are shared by PR/MR creation and PR/MR review.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `pullRequest.provider` | `auto` | `auto` | Use `github` or `gitlab` when remote detection is ambiguous | Setting a provider that does not match the remote host |
| `pullRequest.apiBaseUrl` | empty string | Leave empty for public GitHub/GitLab | Set it for GitHub Enterprise or self-managed GitLab | Including a trailing slash or a repository path instead of the API base |
| `pullRequest.authToken` | empty string | `env:SMART_COMMIT_PULL_REQUEST_AUTH_TOKEN` | Set it when creating or reviewing PRs/MRs through provider APIs | Hardcoding a token in committed config |

PR/MR auth tokens are used only for provider API authentication headers. They are redacted from resolved config and visible error output.

A missing `env:` value for `pullRequest.authToken` resolves to `""`. Platform commands still require a non-empty token; local-only commands do not.

### `pullRequestCreation.*`

These settings control GitHub pull request and GitLab merge request creation from the current branch.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `pullRequestCreation.autoCreateAfterPush` | `true` | `false` first | Set `true` when `bridge` should create a PR/MR after a successful push | Expecting it to run when push is disabled or fails |
| `pullRequestCreation.configFilePath` | empty string | Leave empty first, or point it at a comma-separated local fallback list | Change it when you want a local PR/MR creation config file to override creation settings | Putting shared PR auth fields here or expecting it to support `pullRequestCreation.configFilePath` inside the local file |
| `pullRequestCreation.targetBranch` | empty string | Your default integration branch | Set it when most branches target the same branch | Leaving it empty: `bridge` records a PR/MR creation error after push, and `pull-request create` fails. Neither command guesses `main` |
| `pullRequestCreation.titlePrompt` | empty string | Leave empty first | Add short team guidance for generated PR/MR titles | Putting auth tokens, reviewer names, or process notes into the title prompt |
| `pullRequestCreation.descriptionPrompt` | empty string | Leave empty first | Add concise PR/MR template guidance | Asking it to invent tests, links, or approvals |
| `pullRequestCreation.maxDiffChars` | `200000` | `200000` | Lower it for very large repositories | Setting it below `1000`, which fails validation |
| `pullRequestCreation.assignees` | `[]` | `[]` | Set default assignees for created PRs/MRs | Assuming these are prompt hints; they are sent to the provider API |
| `pullRequestCreation.reviewers` | `[]` | `[]` | Set default reviewers for created PRs/MRs | Assuming every provider accepts every reviewer identifier format |
| `pullRequestCreation.labels` | `[]` | `[]` | Apply standard labels during creation | Expecting missing provider labels to be created automatically |
| `pullRequestCreation.milestone` | empty string | Leave empty first | Set it when your provider project uses milestones | Using a display name where the provider expects an id |
| `pullRequestCreation.draft` | `false` | `false` | Set `true` when generated PRs/MRs should start as drafts | Expecting GitLab draft behavior to exactly match GitHub |
| `pullRequestCreation.removeSourceBranch` | `true` | `true` for GitLab if you want accepted MRs to remove the source branch | Set `false` when you want to keep the source branch | Expecting GitHub to support this GitLab-only field |
| `pullRequestCreation.skipBranches` | `["main", "master", "develop"]` | Keep the defaults | Add protected branch names that should never auto-create PRs/MRs | Forgetting this only applies to source branch names |

`pullRequestCreation.configFilePath` accepts a comma-separated list of local file paths. The CLI picks the first existing file, then loads only `pullRequestCreation` settings from a canonical `smartCommitHostAgent.pullRequestCreation` object. Paths are resolved relative to `--repo` when that flag is set, otherwise relative to the current working directory. Overlay files must use the root key `smartCommitHostAgent` only. The overlay must not contain `configFilePath` or `autoCreateAfterPush`. Shared PR auth settings are not supported inside this local file.

`bridge` and `pull-request create` generate title and description through a Host-Agent `pr-content` turn. When the branch range has exactly one commit and `titlePrompt` is empty, the PR/MR title reuses that commit subject. A non-empty `titlePrompt` skips that reuse and keeps the generated title. Explicit `--title` / `--description` are not overwritten.

### `pullRequestReview.*`

These settings control the standalone `pull-request review` command.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `pullRequestReview.configFilePath` | empty string | Leave empty first, or point it at a comma-separated local fallback list | Change it when you want a local PR/MR review config file to override shared config | Putting shared PR auth fields here or expecting it to support `pullRequestReview.configFilePath` inside the local file |
| `pullRequestReview.threshold` | `6` | `6` | Lower it if reviews block too often; raise it if you want stricter gating | Forgetting the pass rule is still score-based |
| `pullRequestReview.autoApprove` | `false` | `false` | Enable it when you want passing reviews to approve on the provider | Assuming it is only about UI decoration |
| `pullRequestReview.autoMerge` | `false` | `false` | Enable it only when your platform flow and merge gate are ready | Assuming approval alone implies merge |
| `pullRequestReview.summarySeverities` | `["P0", "P1", "P2"]` | Keep default first | Narrow it when you want the summary comment to focus on fewer severities | Expecting all severities to appear regardless of the filter |
| `pullRequestReview.commentSeverities` | `["P0", "P1"]` | Keep default first | Broaden it when you want more inline comments | Assuming summary and inline filters are linked |
| `pullRequestReview.skipSummaryOnPass` | `true` | `true` | Set `false` when you want a summary comment even on passing reviews | Expecting it to affect inline comments too |
| `pullRequestReview.skipCommentOnPass` | `true` | `true` | Set `false` when you want inline comments even on passing reviews | Expecting it to affect the summary comment too |
| `pullRequestReview.skillPromptTuning` | empty string | Leave empty first | Override `review.skill.promptTuning` for PR/MR review only | Expecting it to change staged `bridge` review |

`pullRequestReview.configFilePath` accepts a comma-separated list of local file paths. The CLI picks the first existing file, then loads only `pullRequestReview` settings from a canonical `smartCommitHostAgent.pullRequestReview` object. Paths are resolved relative to `--repo` when that flag is set, otherwise relative to the current working directory. Overlay files must use the root key `smartCommitHostAgent` only. The overlay must not contain `configFilePath`. Shared PR auth settings are not supported inside this local file.

`--dry-run` still runs the Host-Agent review, but skips comments, approval, and merge. `--fixture-pr` is an optional offline fixture for tests.

### `myPullRequest.*`

These settings control `my-pull-request list` and `my-pull-request batch-review`.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `myPullRequest.listScope` | `account` | `account` | Use `workspace` when you only want PRs/MRs from specific local repositories | Expecting `workspace` to work without `--repo` paths or `cwd` |
| `myPullRequest.listKinds` | `["created", "assigned", "reviewer"]` | Keep default first | Narrow the list when you only care about one relationship type | Passing an empty array |
| `myPullRequest.batchReviewKinds` | `["reviewer", "assigned"]` | Keep default first | Change it when batch review should target a different subset than the list command | Assuming batch review always uses `listKinds` |
| `myPullRequest.remoteHost` | empty string | Leave empty first | Set to a host (`gitlab.example.com`) or URL so `account` list/batch-review can run outside a git repo | Expecting `apiBaseUrl` to supply the remote host; using this field under `workspace` scope |

Allowed kind values: `created`, `assigned`, `reviewer`.

`account` scope lists platform-wide items related to the authenticated account. `workspace` scope limits the list to repositories resolved from repeated `--repo` paths, or from `cwd` when no `--repo` is passed.

For `account` scope, host resolution priority is: configured `myPullRequest.remoteHost` first, then local git remotes. When `remoteHost` is set, list and batch-review do not require a local git repository. `workspace` scope ignores `remoteHost`.

`my-pull-request list` requires `pullRequest.authToken` only. `my-pull-request batch-review` requires PR auth and Host-Agent turns for each review.

### `output.*`

These settings control how results are presented.

| Field | Built-in default | Recommended first value | When to change it | Common mistake |
| --- | --- | --- | --- | --- |
| `output.format` | `json` | `json` for skills and scripts, `text` for `config resolve` in a terminal | Change it based on whether a human or a script will read stdout | Using `text` in a skill that expects structured JSON |
| `output.logLevel` | `info` | `info` | Use `debug` when diagnosing behavior | Leaving `debug` on in normal automation and creating noisy logs |

## Supported Value Sets

### Pull request provider

- `auto`
- `github`
- `gitlab`

### Commit-message structure

- `subjectOnly`
- `subjectBody`
- `subjectBodyFooter`

### Commit-message validation protocol

- `none`
- `conventional`
- `semantic`
- `gitmoji`

### Commit-message skill ids

- `conventional`
- `semantic`
- `gitmoji`

### Review skill ids

- `code-review`
- `frontend-code-review`
- `mobile-code-review`
- `c-code-review`
- `python-code-review`
- `golang-code-review`
- `java-code-review`
- `cpp-code-review`
- `csharp-code-review`
- `rust-code-review`
- `php-code-review`

### Pass-history write stage

- `review_passed`
- `commit_completed`
- `commit_push_completed`

### My-pull-request scope and kinds

- scope: `account`, `workspace`
- kinds: `created`, `assigned`, `reviewer`

### Review severities

- `P0`, `P1`, `P2`, `P3`

### Report week start

- `monday`
- `sunday`

### Output format / log level

- format: `json`, `text`
- log level: `debug`, `info`, `warn`, `error`

## Common CLI Flags

```bash
--config <path>
--repo <path>
--output <json|text>
--session <path>
--session-base <dir>
--dry-run
--commit-message <text>
--no-commit
--no-push
--title
--description
--fixture-pr <path>
--period <daily|yesterday|weekly|last-week|monthly|last-month|quarterly|last-quarter|yearly|custom>
--start-date <YYYY-MM-DD>
--end-date <YYYY-MM-DD>
--report-ai
--pull-request-auth-token <token>
--pull-request-provider <auto|github|gitlab>
--pull-request-api-base-url <url>
--my-pull-request-list-scope <account|workspace>
--my-pull-request-list-kinds <created,assigned,reviewer>
--my-pull-request-batch-review-kinds <created,assigned,reviewer>
--my-pull-request-remote-host <host-or-url>
```

Rejected flags: `--api-key`, `--base-url`, `--model`, `--llm-provider`.

## Common Environment Variables

```bash
SMART_COMMIT_PULL_REQUEST_AUTH_TOKEN
```

`SMART_COMMIT_API_KEY` is not used.

Any other `env:NAME` referenced in the config file is resolved at load time.

## Command-Specific Notes

- `config resolve` never requires a platform token or a Host-Agent turn
- `bridge --review-only` never commits or pushes
- full `bridge` may commit, push, and create a PR/MR depending on config
- `commit-message generate` treats `--commit-message` as provided input; with `hybridGenerate=false` that skips the turn, and with `hybridGenerate=true` it still runs a refine turn
- `pull-request create` / `pull-request review` / `my-pull-request *` require a non-empty `pullRequest.authToken`
- `report generate` is local by default; `--report-ai` uses a Host-Agent turn

## Validation Workflow

1. write a conservative config
2. run `smart-commit-host-agent config resolve --config ./smart-commit.host-agent.json`
3. confirm secrets are redacted and `autoCommit` / `autoPush` are still false
4. run `bridge --review-only` before enabling Git side effects

## Common Mistakes

### Adding a `connection` block

This package strips `connection` and never calls an LLM HTTP API. Remove it.

### Passing `--api-key` / `--base-url` / `--model`

Those flags are rejected. Model text comes from Host-Agent turns.

### Leaving default auto-commit / auto-push on

Set them to `false` until review-only is stable.

### Expecting the config file to be auto-loaded

Pass `--config <path>` explicitly.

### Treating a missing PR token as a config-load failure

`pullRequest.authToken` `env:` refs resolve to empty. The failure happens later, only on commands that call GitHub/GitLab.

## Where To Go Next

- first successful run: [`getting-started.md`](./getting-started.md)
- skill and script patterns: [`integrations.md`](./integrations.md)
- JSON status and exit codes: [`contracts.md`](./contracts.md)
- overview: [`../README.md`](../README.md)
