# Decision: Agent source files are user-owned

**Status:** Accepted on 2026-05-16, scope `lifeloop.v0.2`.

**Supersedes:** the source-file portion of
[`docs/decisions/asset-apply-boundary.md`](asset-apply-boundary.md).
**Related tombstone:**
[`docs/tombstones/source-files-managed-section.md`](../tombstones/source-files-managed-section.md).

## Decision

Lifeloop does not write to model instruction source files and does not
render replacement bodies for them.

In-scope source files include `AGENTS.md`, `CLAUDE.md`,
`.claude/CLAUDE.md`, `GEMINI.md`, `HERMES.md`, `OPENCLAW.md`, and any
future repo-rooted file a harness reads at session boot to configure
model behavior. These files are user-authored project policy. Lifeloop
may read them and may report divergence or suggestions in a separate
artifact, but it must not own the whole file, a sentinel-bounded managed
section, or a single appended line inside one.

Host integration assets remain in scope. Files such as
`.claude/settings.json`, `.codex/config.toml`, `.codex/hooks.json`, and
equivalent harness configuration files are lifecycle wiring assets, not
user prose, and stay under `src/host_assets.rs`.

## Why

Instruction files carry the user's direct guidance to their agents.
Generated regions inside that prose create the wrong ownership model even
when the renderer is pure and the caller performs the filesystem write.

The managed-section model failed three boundary tests:

1. **Ownership:** the user no longer owns the entire instruction file.
2. **Merge surface:** generated blocks inside prose create recurring
   conflicts on regenerate.
3. **Trust:** users who expect tools to rewrite instruction prose stop
   putting nuanced guidance there.

This tightens the earlier asset-apply decision. The earlier decision drew
the filesystem boundary correctly, but it left `src/source_files::apply`
as a pure string renderer. Returning a replacement body for a user-owned
instruction file still points callers toward a write path Lifeloop should
not define.

## Implications

### `src/source_files/`

The public managed-section rendering API is removed. Lifeloop no longer
exports `RenderedSourceFile`, `ApplyOutcome`, `ApplyError`,
`SourceFileAdapter`, `TEMPLATE_VERSION`, `render_for`, or `apply`.

There is no replacement API. Callers that wanted a managed-section model
must not write into instruction files through Lifeloop. A future
read-only divergence detector may inspect instruction files, but it must
emit findings or suggested patches separately and leave the source files
unchanged.

### `AGENTS.md`

Repository instruction files may cite this decision as policy, but
Lifeloop must not treat them as renderer targets.

### `README.md`

The current surface description must not list managed-section rendering as
a shipped Lifeloop capability. The docs list should point at this
decision instead of the superseded source-files boundary note.

### `docs/release-gates.md`

Gate #23 remains the filesystem-apply boundary for host integration
assets. The source-file half is stricter: pure rendering of replacement
bodies for instruction files is also out of scope.

## How to revisit

Reopen this decision only if all of the following are true:

- at least two non-CCD clients present concrete evidence that suggestions
  are insufficient and that the same lifecycle-essential source-file
  write would otherwise be reimplemented inconsistently;
- no host integration asset, tool-owned config, or separate suggestion
  artifact can carry the same lifecycle wiring;
- the proposed write is explicitly opt-in, minimal, reversible, and
  surfaced to the user before it occurs.

As of this decision, no known CCD or Lifeloop use case meets that bar.
