# Config Resolution (load-bearing)

Lisa configuration lives in `.lisa.config.json` (committed) and `.lisa.config.local.json` (gitignored, per-developer). The local file wins where they overlap. Developer-specific identity (`atlassian.email`, etc.) MUST live in the local file, never committed.

## Atlassian access — assistant-level rule

When the user asks about Atlassian (Jira / Confluence) connection state, or you are about to run a Jira/Confluence operation, and `acli` is installed:

1. Run `acli auth status` and read the active `Site:`.
2. Read `atlassian.site` from `.lisa.config.json` (and `atlassian.email` from `.lisa.config.local.json` if present).
3. **If the active site does not match config, do NOT report "not connected." Run:**
   ```sh
   acli auth switch --site "$ATLASSIAN_SITE" --email "$ATLASSIAN_EMAIL"
   ```
   acli supports multiple authenticated profiles; the switch is fast and non-interactive when a profile already exists.
4. Only after the switch fails (no matching profile) should you report not-connected and suggest `/lisa:setup:atlassian` to add one.

This applies before declaring connection state, before running any `acli jira *` / `acli confluence *` command, and before falling back to the Atlassian MCP or curl substrates. Identity mismatch is treated as silent-misroute risk, not as a hard not-connected.

## Tracker selection

Project tracker (`jira` / `github` / `linear`) is read from `.lisa.config.json` `tracker`. Vendor-neutral skills MUST dispatch through the configured tracker, never infer it from arguments. Missing `tracker` → stop and instruct the user to run the matching `/lisa:setup:*` skill.

## Tracker status vocabulary

**A status transition may target only a status named in the project's configured workflow map** (`jira.workflow.*` for JIRA; the equivalent label/state map for GitHub and Linear). The configured map is the COMPLETE authorized vocabulary — not a starting point.

- **Never adopt statuses discovered from the tracker's live workflow metadata** — transition lists (`getTransitionsForJiraIssue` targets), board columns, status descriptions, or statuses seen on other tickets. A tracker workflow usually contains more statuses than the config names; those extra statuses are not lisa's to use. The live workflow is consulted only to find the transition *id* that reaches a config-named status.
- **A lifecycle stage with no configured status gets no transition.** If the flow reaches a stage the map does not name (e.g. "PR open awaiting review" when `jira.workflow.review` is unset, or a QA-ready stage with no `qa` mapping), leave the status where it is and record the stage in a comment. Do not pick the nearest-sounding tracker status.
- **This binds every actor that writes to the tracker** — the lead as much as any subagent. In runtimes where interactively-authenticated MCPs are lead-only, the lead performs the tracker writes for the whole flow; loading an implement/sync skill without the agent definition does not relax this rule.

This is the shared slug for the config-bound-transitions policy (the `leaf-only-lifecycle` precedent: one slug, never divergent per-surface prose). Skills and agent definitions cite it rather than restating it.

## Repo identity

`repo:<name>` is the canonical label for which repo a work item belongs to. Resolve current-repo identity in this priority order: `.lisa.config.local.json` `repo` → `.lisa.config.json` `repo` → `.lisa.config.json` `github.repo` → `basename -s .git "$(git remote get-url origin)"`. If none resolve, stop with a clear error.

## Project rules and learnings

Host-authored project rules live in the fixed, agent-neutral directory
`.agents/rules/` — not a configurable file. Every agent reaches it through the
Lisa-managed pointer block in `AGENTS.md`, so it is read once, on demand. A
project that still carries the retired `.claude/rules/PROJECT_RULES.md` keeps
it, untouched and authoritative; the pointer names it too. Automated
learnings never append to host rules: they use the separate machine-managed
ledger resolved from `.lisa.config.json` — the optional `learnings.file`
override, else the default `.lisa/PROJECT_LEARNINGS.md`. The ledger lives in the
cold `.lisa/` tree (never an auto-loaded rules directory) and is consumed only
through the contract's bounded projection, never read raw wholesale. Both
writers and budget checks import the executable contract from
`@codyswann/lisa/learnings`; they must not copy its numeric limits.

## Optional Kane browser provider

Kane is selected only through `verification.browser.kane`: require `enabled: true`, exact version
`0.6.3`, `cloudUploadApproved: true`, an explicit non-production `allowedEnvironments` entry, a
Test Manager `projectId`, and a resolved `exploration` mutation policy of `full`. Credentials never
live in Lisa config. Run `lisa kane probe` before use and invoke only through `lisa-kane-browser`;
provider/auth/upload/schema failures are tooling failures, not product failures. Kane supplies
empirical evidence only—native Playwright/Cypress/Maestro remains the regression authority.

## Env → base branch

The `## Target Backend Environment` grammar is durable: human-confirmed values
are a bare configured key or `Confirmed: <env>`; automation writes either
`Inferred: <env> — evidence: <title|body|reproduction|hostname>` or
`Assumption: <env> — remote default branch <branch>`. When no unique environment
maps to the default branch, use `Assumption: remote default branch <branch>`.
Human confirmation replaces an automated annotation with a bare key or
`Confirmed: <env>`. For legacy bare values, use managed draft markers and current
ticket content only; provider edit history is not required. A marker proves
automation and requires re-annotation; otherwise unknown provenance with
conflicting evidence stops for confirmation.

Resolution order is human-confirmed value; validated `Inferred:` evidence; then
one unambiguous signal from the human-authored title, body, and reproduction
steps or a URL hostname. Exclude the complete `Target Backend Environment`
section and other machine-authored metadata/draft blocks from the scan so an
annotation cannot validate or conflict with itself. Evidence supersedes only an
`Assumption:`. A signal must be an exact
`deploy.branches` key as a complete token/hostname label. The sole normalization
is `prod` ↔ `production` when exactly one is configured; no other aliases exist.
Conflicting signals stop. Never infer from arbitrary branch text, URL paths or
query strings, or substrings. With no signals, use the remote default branch and
record an assumption: include `<env>` only for a unique reverse-map, otherwise
use the branch-only form without inventing an environment or blocking. Require
any selected environment mapping and its remote branch to exist.
A non-integration environment bug is fixed, merged, and verified on that
environment branch first, then
forward cherry-picked down to the integration branch via a linked follow-up.

Full reference: [reference/config-resolution.md](../reference/config-resolution.md).
