# Configuration

OAS config answers two questions:

1. Which integration solves each pluggable layer here?
2. Which instructions and skills should every soul under this level receive?

The file is always named `oas-config.yaml` and sits at a **level root**.
It is not stored inside `.agents/`.

## Levels and workspaces

A level is a directory that can govern agents below it. In normal use there
are three roles:

| Level | Example | What it controls |
|---|---|---|
| Laptop | `~/oas-config.yaml` | Defaults for all your OAS work. |
| Workspace | `~/lfx/oas-config.yaml` | Shared setup for a folder of related repos. |
| Repo | `~/lfx/project-service/oas-config.yaml` | Repo-specific choices that travel with the repo. |

When we say "workspace" in these docs, we usually mean the level where config
resolves for the work at hand. That can be a single repo, a multi-repo folder
like `~/lfx`, or your laptop root.

Resolution walks upward from the context directory. Deeper nesting works.

## Minimal examples

Laptop defaults:

```yaml
name: laptop
layers:
  knowledge: okf
  messaging: aweb
  tasks: linear
```

A repo that wants no messaging:

```yaml
name: quiet-repo
layers:
  messaging: none
```

A workspace that overrides only tasks:

```yaml
name: lfx
layers:
  tasks: jira
```

Absent means inherit. `none` means stop walking and disable that layer.

## Schema

```yaml
name: lfx

oas:
  agents-md-injection: default   # kernel OAS block; a path overrides; "none" removes

layers:
  knowledge: okf          # selected integration for this layer
  messaging: aweb
  tasks: jira

integrations:
  jira:                   # hand-rolled integration
    skills: .agents/skills/lfx-agent-tasks
    agents-md-injection: .agents/injections/jira.md
  okf:                    # bundled integration
    package: oas-okf
  aweb:
    package: oas-aweb
    settings:
      team: default:lfx.aweb.ai

agents-md-injection:      # unconditional soul AGENTS.md blocks
  framework: injects/team-conventions.md

skills: .agents/skills/shared-extra

work-modes:
  worktree:
    agents-md-injection: default
    setup: ./scripts/setup-worktree.sh
  checkout:
    agents-md-injection: default
```

`providers:` is accepted as a legacy alias for `integrations:`.

## Layers and integrations

`layers:` selects what you use. `integrations:` defines what a name means.
They are separate on purpose.

A level can define `jira`, and a repo below it can select `tasks: jira`.
A bundled integration such as `okf` can be selected with no local definition
because OAS already knows its manifest.

Definitions can come from four places:

| Source | How |
|---|---|
| Bundled | `integrations/<name>/` in this package. |
| Inline config | A block under `integrations:`. |
| Local manifest | `<level>/.agents/integrations/<name>/oas.json`. |
| Cloned repo | `path: ../shared-integrations/team-chat`. |

`oas use <integration> --for <layer>` writes the `layers:` binding for you.
Use `--path <dir>` for a cloned integration.

## Resolution rules

1. **Each layer resolves independently.** `tasks` can resolve at `~/lfx` while
   `messaging` resolves at `~`.
2. **Closest declaration wins per layer.** Repo beats workspace. Workspace
   beats laptop.
3. **No deep merge.** The winning layer declaration takes its settings,
   skills, hooks, and injection from the winning level.
4. **`none` is real.** It disables a layer and stops the walk.
5. **Provenance is recorded.** `instance.json` records the resolved layer
   origins, and `oas doctor` prints them.

Example resolution:

```text
~/oas-config.yaml       knowledge: okf, messaging: aweb, tasks: linear
~/lfx/oas-config.yaml   tasks: jira
~/lfx/api/              no repo config
```

An agent in `~/lfx/api` resolves:

```text
knowledge -> okf   from ~
messaging -> aweb  from ~
tasks     -> jira  from ~/lfx
```

## Injections

Injections are instruction blocks written into a soul's `AGENTS.md`.
They are how config teaches all agents under a level what they need to know.
They are applied when a soul is created and reconciled later at spawn or with
`oas sync`.

Injection sources compose in this order:

1. **Kernel OAS injection** — tells agents they run on OAS. Configure with
   `oas.agents-md-injection` (`default`, path, or `none`).
2. **Work-mode injection** — tells worktree or checkout souls their work
   discipline. Configure with `work-modes.<mode>.agents-md-injection`.
3. **Integration injections** — tell agents how to work with a resolved layer
   integration. Configure with that integration's `agents-md-injection`.
4. **Workspace injections** — extra conventions for every soul under the
   config. Configure with the top-level `agents-md-injection:` map.

Every block has a marker with its source path:

```html
<!-- oas:layer:knowledge:okf src=/path/to/injects/okf.md -->
...
<!-- /oas:layer:knowledge:okf -->
```

Edit the source file. Do not edit inside the block.

For configurable injections, the values mean:

| Value | Meaning |
|---|---|
| absent or `default` | Use the shipped default, when that source has one. |
| path | Use that file instead. Paths are relative to the level root. |
| `none` | Do not inject that instruction block. Skills still attach. |

## Worked examples

### Laptop defaults, one workspace that differs

Your laptop config gives every OAS workspace the same defaults: OKF for
knowledge, aweb for messaging, and Linear for tasks.

```yaml
# ~/oas-config.yaml
name: laptop
layers:
  knowledge: okf
  messaging: aweb
  tasks: linear
integrations:
  okf:  { package: oas-okf }
  aweb: { package: oas-aweb }
  linear:
    skills: agent-skills/linear
    agents-md-injection: injects/linear.md
```

Your LFX work uses Jira instead of Linear:

```yaml
# ~/lfx/oas-config.yaml
name: lfx
layers:
  tasks: jira
integrations:
  jira:
    skills: .agents/skills/lfx-agent-tasks
    agents-md-injection: .agents/injections/jira.md
```

Now `oas doctor ~/lfx/lfx-v2-project-service` shows:

```text
Layers:
  knowledge  okf  [okf @ /Users/you]
  messaging  aweb  [aweb @ /Users/you]
  tasks      jira  [jira @ /Users/you/lfx]
```

The LFX agent gets okf and aweb from the laptop, plus Jira from `~/lfx`.
A side repo outside `~/lfx` still gets Linear from the laptop.

### A repo that brings its own integration

One repo in LFX keeps knowledge in a team wiki and wants no messaging. It
ships `.agents/integrations/team-kb/oas.json`, then selects it:

```yaml
# ~/lfx/internal-wiki-tools/oas-config.yaml
name: internal-wiki-tools
layers:
  knowledge: team-kb
  messaging: none
```

Doctor now shows three origins:

```text
Layers:
  knowledge  team-kb  [team-kb @ /Users/you/lfx/internal-wiki-tools]
  messaging  none  [none @ /Users/you/lfx/internal-wiki-tools]
  tasks      jira  [jira @ /Users/you/lfx]
```

The repo owns knowledge, turns messaging off, and inherits Jira from the
workspace. Other repos are untouched.

## CLI workflow

```bash
oas init                         # default okf + aweb config here
oas init --raw                   # all layers set to none
oas use jira --for tasks         # bind an integration
oas use none --for messaging     # disable a layer
oas doctor                       # inspect the resolved config
oas sync                         # re-apply injections to all souls
```

Existing souls pick up config and injection changes at next spawn. Run
`oas sync` when you want to reconcile immediately.

## Work modes

Work-mode injections are configured under `work-modes:`. They are soul-level
instructions, because work mode is part of a soul's identity.

`worktree` can also define `setup`, a command the kernel runs inside each new
worktree. A failing setup is a warning, not a blocked spawn.
