# AGENTS.md
> Canonical AI policy for this repo.
## Project
Lifeloop is the provider-neutral lifecycle abstraction and normalizer for AI
harnesses. It exposes normalized lifecycle events, capability manifests,
callback envelopes, payload delivery metadata, and receipts so clients can
operate on harness lifecycle without importing CCD or reimplementing adapter
quirks.
## Scope
Lifeloop owns:
- harness identity, aliases, and adapter manifests;
- lifecycle event vocabulary;
- hook timing normalization;
- integration modes such as native hook, launcher wrapper, manual skill,
telemetry-only, and reference adapter;
- capability negotiation;
- lifecycle receipts;
- payload placement and delivery metadata;
- lifecycle-relevant telemetry such as context pressure and recent activity;
- failure classes and retry posture for lifecycle operations;
- extension dispatch as a lifecycle mechanism.
Lifeloop does not own:
- CCD continuity semantics;
- memory, recall, promotion, compaction, or governance;
- recursive inference policy;
- prompt semantics above placement metadata;
- model selection;
- tool or skill abstraction;
- a universal IDE.
For the full boundary decision on harness concepts (skills, plugins, slash
commands, agents/subagents, hooks, tools/permissions, MCP, memory/rule
files), see [`docs/harness-concept-boundary.md`](docs/harness-concept-boundary.md).
The single rule is: *Lifeloop normalizes lifecycle reach. It does not
normalize meaning.*
## Coding Standards
- Read `README.md` and `docs/product-thesis.md` before deep implementation
work.
- Keep the library contract first; the CLI is an adapter and inspection
surface.
- Prefer deterministic, machine-readable behavior and fail-closed error
handling.
- Keep client semantics out of core types. CCD, RLM, Reforge, Fixity, and
other clients attach through public contracts.
- Add dependencies conservatively. Protocol and adapter boundaries should stay
auditable.
## Architecture Rules
- Lifeloop may normalize lifecycle moments; clients decide what those moments
mean.
- Public event, capability, receipt, and callback schema changes require tests
and docs in the same change.
- Do not add CCD, RLM, Reforge, or Fixity dependencies to core Lifeloop.
- Compatibility shims are acceptable only as explicit tombstones with removal
criteria, not as hidden old implementations.
## Workflow
- Run `git status` and `git diff --minimal` before any commit.
- Stage explicit paths. Never use `git add .`.
- AI-authored commits include a `Co-Authored-By:` trailer naming the model
and harness, so AI authorship stays auditable in `git log`.
## Automation Substrate
Dev-workflow automations live in harness-neutral surfaces so Claude Code,
Codex CLI, Hermes, OpenClaw, Pi, and bare CI run the same checks. Harness
configs (`.claude/`, `.codex/`, etc.) are thin shims that delegate.
- `scripts/` — reusable shell logic.
- `Makefile` — named workflows (`make verify`, `make commit`, `make bump-schema`,
`make wire-check`, `make lockfile-check`).
- `lefthook.yml` — pre-commit / pre-push gates.
- `docs/playbooks/` — review checklists referenced by every harness wrapper.
- `.cargo/config.toml` — cargo aliases (`cargo wire-test`).
Add no logic to harness configs. Logic must be reachable from `make`, `git`,
and CI without a harness present.
## Pituitary Governance Gate
A lexical governance gate (Pituitary) audits the prose corpus for
terminology drift. It is the lexical complement to `tests/spec_alignment.rs`
(structural drift between code and the lifecycle-contract spec body) — both
must stay green for a release-ready posture.
- Config: `.pituitary/pituitary.toml` (terminology policies + indexed
source bundles: spec, docs, AGENTS.md, README.md, harness wrapper
directories).
- CI jobs: `pituitary-precheck` (push) and `pituitary-mr` (MR), both
defined in `.gitlab-ci.yml` via the `nanto/infra` template. Both run
`allow_failure: true` during the rollout window; flip to fail-closed
once the runner path is proven on one MR cycle.
- Runtime profiles: the config selects the `fixture` embedder for CI
speed and determinism. Switch the `[runtime.embedder]` block to a
`local-lm-studio`-style profile (see Pituitary's docs) for release
prep when real semantic checks are wanted.
- Reading output: `pituitary-precheck` fast-fails on policy load and
index errors; `pituitary-mr` reports per-finding terminology
violations with `severity` (`error` blocks once fail-closed,
`warning` is advisory) and `classification`
(`historical_alias` / `forbidden_current` / `deprecated_term`).
Local equivalent: `pituitary index --rebuild && pituitary check-terminology`.
## Testing
- Run the smallest check that proves the change.
- Prefer `cargo test --all-targets --all-features` for repo-wide validation.
- For public contracts, add serialization tests that pin wire names.
### Two contract test surfaces
These look similar; they are not. Touching one usually means touching the
other.
- `tests/wire_contract.rs` — pins the **current** JSON shape. Catches
accidental wire drift on already-shipped types. Failures here mean
*somebody changed the wire without updating the assertion or bumping
the schema*.
- `tests/spec_alignment.rs` — pins the implementation against the
**target** vocabulary in `docs/specs/lifecycle-contract/body.md`. Catches
drift between the spec and the code as the contract evolves. Failures
here are a migration checklist: each failing assertion names the
spec section it disagrees with. Acceptable to mark individual
assertions `#[ignore]` only when they are expected to fail and have a
corresponding tombstone or owning issue named in the comment (e.g.
the `AdapterManifest` shape is owned by issue #6).
When a wire-affecting change lands, update *both* tests in the same
commit: `wire_contract.rs` to reflect the new on-the-wire shape, and
`spec_alignment.rs` to confirm the new shape still matches the spec
target. If they disagree, the spec is the goal — file a tombstone and
move toward the spec, do not weaken `spec_alignment.rs` to accept
drift.
## Source File Rendering
Lifeloop owns the *managed section* inside model instruction source files
(`AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `HERMES.md`, `OPENCLAW.md`). The
implementation is `src/source_files/`; the boundary and sentinel-marker
format are documented in
[`docs/harness-concepts/source-files.md`](docs/harness-concepts/source-files.md).
Lifeloop renders only lifecycle integration metadata; client semantics
ride through the opaque client slot. The host integration assets
(`.claude/settings.json`, `.codex/config.toml`) stay in
[`src/host_assets.rs`](src/host_assets.rs) and are out of scope for the
source-file module.
## Safety
- No secrets in tracked files, docs, fixtures, receipts, or diagnostics.
- Do not overwrite user changes or reset the worktree without explicit
approval.