Change Recipes

Concrete change paths for common contribution scenarios, plus a contributor checklist.

Use these recipes to route changes through the correct modules without crossing layer boundaries.

Add or Modify a Session Workflow🔗

  1. Update orchestration in crates/agentty/src/app/session/ (lifecycle.rs, worker.rs, task.rs, etc.).
  2. Keep persistence in crates/agentty/src/infra/db/ domain modules and keep crates/agentty/src/infra/db.rs router-only. Use repository.rs for repository bundle composition and connection.rs for pool wiring.
  3. Keep git operations behind GitClient in crates/ag-git/src/client.rs.
  4. Preserve the session-branch invariant: one evolving commit per session branch, with the first file-changing turn creating it and later file-changing turns updating it by amending HEAD.
  5. Update docs when lifecycle/status behavior changes: docs/site/content/docs/usage/workflow.md.

Add a New Agent Backend or Model🔗

  1. Update provider model declarations in crates/ag-agent/src/model/agent.rs.
  2. Add backend behavior in crates/ag-agent/src/agent/ and register it in crates/ag-agent/src/agent/provider.rs.
  3. If app-server-based, wire the provider client through crates/ag-agent/src/agent/provider.rs so the provider owns its runtime wiring.
  4. Register any shared parsing, prompt-transport, streaming, or thought-policy changes in crates/ag-agent/src/agent/provider.rs.
  5. The channel factory re-exported by the ag-agent crate root routes automatically based on the backend-owned transport mode - no change needed there unless the runtime contract itself changes.
  6. Update docs/site/content/docs/agents/backends.md with backend/model documentation.

Add or Change a Utility Agent Prompt🔗

  1. Submit an owned OneShotRequest through OneShotClient; do not select a CLI, app-server, backend, or protocol-repair helper from application orchestration.
  2. Inject &dyn OneShotClient into the smallest workflow helper that needs deterministic coverage and test it with MockOneShotClient.
  3. Keep provider routing, protocol repair, usage aggregation, and runtime cleanup in crates/ag-agent/src/agent/submission.rs.

Add a Keybinding or Mode Interaction🔗

  1. For basic text editing, add or update the semantic command in crates/agentty/src/domain/input.rs, then map terminal keys once in crates/agentty/src/runtime/mode/input_key.rs.
  2. Let prompt, question, branch-publish, and settings input modes intercept only their context-specific actions before falling back to the shared input command mapping.
  3. For other interactions, update the handler in crates/agentty/src/runtime/mode/, or in crates/agentty/src/runtime/key_handler.rs when the interaction is a cross-mode overlay dispatch.
  4. If a new mode/state is needed, extend crates/agentty/src/presentation/app_mode.rs.
  5. If help content changes, update crates/agentty/src/presentation/help_action.rs as needed.
  6. Update docs/site/content/docs/usage/keybindings.md.

Add or Change Database Schema🔗

  1. Add a new migration file in crates/agentty/migrations/ (NNN_description.sql).
  2. Never modify existing migration files.
  3. Keep query changes in the matching crates/agentty/src/infra/db/*.rs domain module instead of expanding the router-only crates/agentty/src/infra/db.rs.
  4. Ensure any status/model behavior changes are reflected in docs pages affected by user-facing behavior.

Add a New UI Page or Component🔗

  1. Add the page in crates/agentty/src/ui/page/ or component in crates/agentty/src/ui/component/.
  2. Wire the page into crates/agentty/src/ui/router.rs.
  3. If a new AppMode is needed, extend the shared presentation contract implemented in crates/agentty/src/presentation/app_mode.rs and exported through crates/agentty/src/presentation.rs, then add a key handler in crates/agentty/src/runtime/mode/.

Contributor Checklist for Architecture-Safe Changes🔗

  1. Keep workflow/state transitions in app/, not in UI rendering modules.
  2. Keep external integrations in infra/ behind traits.
  3. Keep business entities and enums in domain/.
  4. In app/ and runtime/ orchestration, avoid direct Command::new, Instant::now, SystemTime::now, and direct filesystem/process calls unless they run behind trait boundaries.
  5. For helpers that need timestamps in app/ or runtime/, reuse the shared app/session/core.rs Clock boundary instead of adding direct Instant::now() or SystemTime::now() calls.
  6. New external boundaries should get a trait with #[cfg_attr(test, mockall::automock)].
  7. Update docs in docs/site/content/docs/ whenever user-facing behavior changes.
  8. Update docs/site/content/docs/architecture/module-map.md, docs/site/content/docs/architecture/runtime-flow.md, and docs/site/content/docs/architecture/testability-boundaries.md when architecture responsibilities change.
  9. Keep the nearest semantic AGENTS.md guides aligned when a major module's purpose, invariants, or change-routing guidance changes.
  10. Treat render-time helpers as hot paths: avoid per-frame cloning of large render inputs, and make line-count/layout helpers reuse the same cached derived data as the final paint path.
  11. When changing TurnRequest/TurnContinuation/TurnEvent/TurnResult shapes in crates/ag-agent/src/channel/contract.rs (re-exported by the ag-agent crate root), update the key-types table in docs/site/content/docs/architecture/runtime-flow.md.
  12. When adding/removing #[cfg_attr(test, mockall::automock)] external-boundary traits, update docs/site/content/docs/architecture/testability-boundaries.md.
  13. Run quality gates from AGENTS.md before opening a PR.