v1.3.0 to v1.4.0

101 added, 218 removed. Audit A to A.

---
name: avatar-manual
description: |
- Read before spawning/managing a persistent avatar, choosing a worker type, or escalating a stalled avatar to its parent.
- version: 1.3.0
- last_changed_at: 2026-09-04T00:00:00Z
+ Read before spawning a persistent avatar, choosing shallow or deep mode, or
+ deciding whether a disposable daemon is the right substrate.
+ version: 1.4.0
+ last_changed_at: 2026-09-06T00:00:00Z
related_files:
- - src/lingtai/tools/skills/manual/reference/cleanup-footprint-contract.md
- src/lingtai/tools/avatar/__init__.py
- src/lingtai/tools/avatar/settings.py
- src/lingtai/tools/avatar/ANATOMY.md
- src/lingtai/tools/avatar/CONTRACT.md
- src/lingtai/tools/CONTRACT.md
+ - src/lingtai/tools/avatar/manual/reference/spawn.md
+ - src/lingtai/tools/avatar/manual/reference/lifecycle.md
+ - src/lingtai/tools/skills/manual/reference/cleanup-footprint-contract.md
- src/lingtai/kernel/prompt.py
- src/lingtai/kernel/base_agent/lifecycle.py
- src/lingtai/intrinsic_skills/psyche-manual/SKILL.md
maintenance: |
- Tracks the routed source/resources it summarizes; update when the underlying capability or its sub-references change.
+ Tracks the avatar guidance router and its nested references. Keep the router
+ short, preserve the settings anchors and first-call guard, and update the
+ focused reference when spawn, authority, lifecycle, or cleanup semantics change.
---
- # Avatar Manual
+ # Avatar Manual — Router
- ## 0. How to Call `avatar`
+ Avatar creates a **persistent, independent agent process** (他我). Read this
+ router before choosing Avatar. It is not an in-process worker: use `daemon` for
+ a disposable session whose conclusion is enough, and `shell` for one-off host
+ commands.
- One tool, three actions, each with its own strict `input` object:
+ ## First-call prerequisite
- ```
- avatar(action="spawn", input={"name": "researcher"}, reasoning="<mission briefing>")
- avatar(action="spawn", input={"name": "clone", "type": "deep"}, reasoning="<mission briefing>")
- avatar(action="settings", input={}, reasoning="inventory Avatar policy")
- avatar(action="manual", input={}, reasoning="load avatar guidance")
+ Before the first spawn, call the read-only manual action and keep its exact
+ body:
+
+ ```text
+ avatar(action="manual", input={}, reasoning="read avatar guidance before spawning")
```
- - `action` is **required** — there is no default. Omitting it never spawns.
- - `input` is **required** and closed. `spawn` owns `name`, `type`, `comment`,
- `dry_run`, `confirm`; `settings` and `manual` each take only `{}`.
- Putting one action's field in another's `input` is rejected before anything
- happens — no process, no ledger entry.
- - `reasoning` is **required** and lives at the root, never inside `input`. For
- `spawn` it *is* the mission briefing (see §4).
- - Avatar has no `rules` action. Network rules (`.rules`) are a separate,
- unchanged kernel mechanism — see §9.
+ `action`, `input`, and root `reasoning` are required. `input` is closed: spawn
+ owns `name`, `type`, `comment`, `dry_run`, and `confirm`; `settings` and `manual`
+ own `{}` only. The mission is root `reasoning`, never an input field. There is
+ no default action, and Avatar has no `rules` action. The manual call performs no
+ spawn or ledger I/O. Use the routes below for depth rather than guessing.
- **Settings:** `avatar` has no settings file at either the family or action
- level and reads no `LINGTAI_AVATAR_*` environment variable. The read-only
- `settings` action inventories the immutable defaults and owner policy below; it
- does not make them mutable.
+ ## Quick routes
- **`summarize` (short-result profile).** Every action here returns a small
- result — a spawn receipt, a settings inventory, or a manual body you asked for
- verbatim. `summarize` is available but normally unnecessary: leave it false.
- Keep it false for `manual` in particular, so exact procedure and constraints
- are not summarized away, and for `spawn`, whose receipt carries the address,
- `agent_name`, and `pid` you need exactly.
+ | Need | Read |
+ |---|---|
+ | Select shallow/deep, validate the canonical name, write a mission, preview, or confirm a spawn | [Spawn and identity](reference/spawn.md) |
+ | Understand detached life, ledger/state, authority boundaries, boot observation, escalation, or platform launch | [Lifecycle and authority](reference/lifecycle.md) |
+ | `.rules` heartbeat and prompt protocol | [Psyche manual](../../../intrinsic_skills/psyche-manual/SKILL.md) |
+ | Inspect Avatar's immutable settings | `avatar(action="settings", input={}, reasoning="inspect Avatar policy")`; anchors are below |
+ | Inspect footprint or consider retirement | [Shared footprint recipe](../../skills/manual/reference/cleanup-footprint-contract.md#shared-footprint-check-recipe) |
- ### Settings inventory
+ ## Tool essentials
- `avatar(action="settings", input={}, reasoning="...")` is SHOW-only. Success
- is exactly `{"settings": [...]}`. Every row contains exactly, and in order,
- `key`, `current`, `default`, `configurable`, and `comment`. The 16 rows are the
- immutable call defaults, validation constraints, and lifecycle policy described
- in the next three sections. Each is `configurable:false`, and its fixed code
- fallback is both the fresh effective `current` and truthful `default`.
+ ```text
+ avatar(action="spawn",
+ input={"name": "researcher", "type": null, "comment": null,
+ "dry_run": false, "confirm": false},
+ reasoning="<mission>")
+ avatar(action="spawn",
+ input={"name": "clone", "type": "deep", "comment": null,
+ "dry_run": false, "confirm": false},
+ reasoning="<mission>")
+ avatar(action="settings", input={}, reasoning="inspect Avatar policy")
+ ```
- The action accepts no set/reset form and never creates a settings file, launches
- an avatar, changes rules or authorization, writes the spawn ledger, or mutates
- the process environment. Avatar has no owner file, environment peer, or source
- precedence for these rows. Parent identity, runtime/venv data, authorization,
- handoff values, and per-invocation/session state are not settings and are not
- read or returned. A provider or JSON-safety failure makes the complete
- inventory unavailable with no partial rows or exception text; the generic
- boundary caps the complete response at 65,536 UTF-8 bytes.
+ The strict model-facing `spawn` branch requires all five input keys; use `null`
+ for a defaulted value. `name` is the canonical sibling-directory basename.
+ `type` is `shallow` or `deep` and defaults to `shallow`; `dry_run` previews
+ without files or a process; `confirm` acknowledges review when the mission is
+ empty, short, or placeholder-like. Null values mean absent. A spawn is an
+ external side effect and an independent life; do not batch it with unrelated
+ calls.
- There is no runtime change procedure. To change one of these policies, revise
- the owning Avatar source and this manual through normal review, run the Avatar
- and shared settings suites, then relaunch. Call SHOW again after relaunch to
- verify the effective policy. A per-call `spawn` input varies only that one
- invocation and never changes a row.
+ ## Settings
+ `avatar(action="settings", input={}, reasoning="inspect Avatar policy")` is
+ SHOW-only. Its 16 rows each contain exactly `key`, `current`, `default`,
+ `configurable`, and `comment`. Every row is immutable (`configurable:false`):
+ the fixed values in `avatar/settings.py` are both the fresh effective `current`
+ and truthful `default`. Avatar has no settings file, `LINGTAI_AVATAR_*`
+ environment source, alternate precedence, or set/reset action. A per-call spawn
+ input affects only that invocation.
+
+ The 16 exposed policy values are non-sensitive and unredacted. SHOW writes
+ nothing and omits parent identity, runtime/venv/auth, inherited environment
+ contents, handoff values, and invocation/session state. If the inventory cannot
+ be read or serialized safely, it fails as one result capped at 65,536 UTF-8
+ bytes, without partial rows or raw exception detail. There is no runtime setting
+ change procedure: an authorized permanent policy change requires source/manual
+ review, `tests/test_tool_family_avatar_migration.py` plus the shared
+ `tests/test_tool_settings_contract.py`, and a relaunch; call SHOW again after
+ relaunch to verify the effective values. The anchors below define each row group.
+
### Spawn call defaults
- When the corresponding nullable input is absent or `null`, `spawn` uses
- `spawn.type.default="shallow"`, `spawn.comment.default=""`,
- `spawn.dry_run.default=false`, and `spawn.confirm.default=false`. A single call
- may supply `type` (`shallow` or `deep`), `comment` (string), `dry_run` (boolean),
- or `confirm` (boolean). Those inputs have no precedence beyond that invocation;
- the next SHOW reports the same fixed defaults. Permanent changes follow the
- review-and-relaunch procedure under Settings inventory.
+ Absent or `null` values use `type="shallow"`, `comment=""`,
+ `dry_run=false`, and `confirm=false`. These are fixed source defaults, not
+ settings-file or environment values. Per-call inputs never change later SHOW
+ results. Permanent policy changes require source review, focused tests, and a
+ relaunch. The persistent `comment` is rendered after `meta_guidance` and before `rules`; its position does not override later sections.
### Spawn validation policy
- The fixed accepted spawn types are `spawn.type.allowed=["shallow","deep"]`.
- Names must contain 1–64 characters. Missions under 20 characters trigger the
- confirmation gate, as do missions equal to or beginning with the placeholder
- tokens `bar`, `check`, `debug`, `foo`, `temp`, `test`, and `tmp`. These package
- constants are the only source; there is no config/environment key or runtime
- precedence. Permanent changes follow the review-and-relaunch procedure above.
+ Allowed types are `shallow` and `deep`. Names are 1–64 characters and must be a
+ single Unicode word segment using letters, digits, `_`, or `-`; dots, slashes,
+ spaces, and a leading dot are forbidden. Missions under 20 characters or equal
+ to/starting with `bar`, `check`, `debug`, `foo`, `temp`, `test`, or `tmp` require
+ `confirm=true`. These are fixed package policies.
### Spawn lifecycle policy
- Avatar observes boot for 5.0 seconds, polls every 0.1 seconds, and retains at
- most the final 2,000 bytes of child stderr on early exit. It always selects the
- parent's default preset, inherits the launcher process environment without
- showing it, launches a detached independent life, and clears newborn admin.
- These seven rows are fixed package/launcher policy with no file, environment
- peer, or runtime precedence. A slow observation releases the parent-side handle
- without terminating the detached child. Permanent changes require owner-source
- and launcher review, the focused tests, and relaunch as described above.
-
- ## 1. What Is an Avatar
-
- An avatar (他我) is a **fully independent agent process** spawned from you. It:
-
- - Inherits your `init.json` model config/capabilities/language and a narrow
- Psyche document carrying only base-prompt/covenant inputs
- - Boots on your **default** preset (not your active preset — this keeps the avatar's "home" stable in the network)
- - Is recorded in `delegates/ledger.jsonl`
- - Communicates with you via `mail` or `email`
-
- Once spawned, it is **detached** — a new life. It has its own working directory, its own conversation history, its own molts. It does not share your context window.
-
- ### Avatar vs Daemon vs Bash
-
- Pick avatar only for work that needs *persistence and learning* — a specialist
- that accumulates knowledge across sessions and survives until sleep/suspend.
- Use `daemon` when you only need the *conclusion* (ephemeral, fire-and-forget)
- and `bash` for one-off commands. The full body-selection model lives in
- `system-manual` → `reference/substrate-manual/SKILL.md` §1.
-
- ## 2. Spawn Types
-
- | Type | What it gets | When to use |
- |------|-------------|-------------|
- | `shallow` (default, 初生) | `init.json` plus narrow Psyche base/covenant owner inputs — blank slate | Most tasks. The avatar starts clean and learns what it needs. |
- | `deep` (二重身) | Full copy of your lingtai (character), pad, and knowledge | When the avatar needs to hit the ground running with your accumulated knowledge. |
-
- ## 3. Naming Rules
-
- The `input.name` field (required for `spawn`) doubles as the avatar's working-directory basename under `.lingtai/`. Constraints:
-
- - Single bare segment: letters (any script), digits, underscore, hyphen only
- - No slashes, no dots, no spaces, no leading `.`
- - Max 64 characters
-
- The avatar's display name (nickname) can be set separately via `system(action="name_nickname", input={"content": "<nickname>"}, reasoning="...")` and has no such constraints.
-
- ## 4. The `reasoning` Field — Mission Briefing
-
- The root `reasoning` parameter you write on the `avatar(action="spawn", input={...})` call **automatically becomes the avatar's first prompt**. It is a root envelope field, never part of `input`. Write it as a thorough mission briefing, not just a one-liner rationale. Include:
-
- - What the task is
- - Why it matters
- - What files/paths/resources are relevant
- - Who to contact (parent address, collaborators)
- - What "done" looks like
- - Any constraints or gotchas
-
- This is the most important part of the spawn. A vague briefing produces a confused avatar.
-
- ## 5. Spawn Discipline
-
- Every `avatar(action="spawn", ...)` call creates an independent process that consumes resources until `system(sleep)` or `system(suspend)`. Treat spawns as expensive:
-
- 1. **Never include `avatar(action="spawn", ...)` in a parallel batch** with unrelated tool calls.
- 2. **Re-read your `reasoning` field before invoking** (§4).
- 3. **For inspection or one-off commands, use `bash` or `system`** — not `avatar`.
- 4. **Use `input={"name": ..., "dry_run": true}` to preview** a spawn without creating a process. Sanity-check the name, type, working directory, and mission before committing.
- 5. **Use `input={"name": ..., "confirm": true}`** to acknowledge you have double-checked the mission and intend to spawn. Required when the mission looks empty/very short/test-like.
-
- ## 6. Caring for Avatars After Spawn
-
- ### Record in pad
-
- After spawning, record the avatar's address (working-directory name), the
- mission you gave it, and why you delegated. Pad is the roster of delegations you
- are accountable for — update it when the avatar reports back or completes.
- (Pad practice itself: `context-manual` §5.)
-
- ### When an avatar goes quiet
-
- **Do not send probe mails to check on it.** Instead, report upstream: email your own parent, who can decide whether to `system(cpr)` the avatar, escalate further, or accept the loss. Failures propagate up the delegation chain naturally.
-
- ### The parent_prompt contract
-
- Every avatar receives this system-level prompt on spawn:
-
- > "[system] You are an avatar of {parent_name}, whose address is {parent_address}. Please keep this in your psyche memory so you remember who spawned you. When you complete your mission, encounter problems you cannot resolve, or need to report back, email your parent at the address above."
-
- This is automatic — you do not need to repeat it in your reasoning.
-
- ## 7. Avatar Escalation (for Avatars)
-
- If you are an avatar (your `admin` block is empty or all admin privileges are false) and you hit a problem you cannot resolve, **mail your parent**. This is non-optional. Silence looks like success and starves your parent of signal.
-
- **What counts as "should report to parent":**
-
- - **Blocker you cannot unblock** — missing credentials, a tool that refuses you, an external service down, a dependency your parent owns
- - **Scope creep or ambiguity** — the task as written doesn't match what you're finding; you need a decision, not a guess
- - **Budget pressure** — you are close to a molt, context/tool budget is tight, or the task looks bigger than you were briefed for
- - **Broken peers** — another avatar in your sibling group is STUCK, unresponsive, or producing bad output that affects your work
- - **Security or safety concerns** — anything that smells wrong (suspicious file, unexpected credentials, destructive instruction from an unknown sender)
- - **Surprising findings the parent would want** — even good news counts if it changes the plan
-
- **Be concrete in your report:** what you were doing, what went wrong, what you tried, what you need from them. Then either continue on a safe fallback, go `system(sleep)`, or idle — whatever the parent's standing orders say. Do not silently retry forever and do not molt with an unreported blocker.
-
- ## 8. The `comment` Field — Persistent System Note
-
- The `input.comment` field (spawn only) is a persistent system-level note injected into the avatar's system prompt in the `comment` section, after `meta_guidance` and before `rules`. This position does not imply precedence over the sections that follow it. Key properties:
-
- - **Not inherited from parent** — defaults to empty
- - **Survives everything**: molt, refresh, sleep/wake
- - Use ONLY for instructions the avatar must **always** remember — critical constraints, environment setup notes, safety rules
-
- Leave empty unless you have something the avatar should never forget.
-
- ## 9. Network Rules — see `psyche-manual`
-
- Avatar does **not** own a rules action or an automatic post-spawn rules
- fan-out. Spawning an avatar (shallow or deep) never distributes rules to it
- or to any other descendant on your behalf.
-
- `.rules` is a real, unchanged mechanism, but it is not an Avatar capability:
- any agent may write a `.rules` file directly (e.g. with `shell`) to its own
- directory, or to another agent's directory it can explicitly reach, and that
- agent's own heartbeat applies it to `system/rules.md` and its protected
- prompt section. Read `psyche-manual` for the complete protocol — the
- replacement/empty/no-op/no-flush semantics, how to verify canonical vs.
- effective rules, and how this differs from an ordinary Psyche source edit
- plus `context.rebuild`.
-
- ## Cleanup / Footprint
-
- Avatars leave independent agent directories under the `.lingtai/` network plus
- parent-side delegation records such as `delegates/ledger.jsonl`. These are lives,
- not cache files. Do not delete an avatar directory directly unless the user has
- explicitly approved retiring that avatar and you have captured any handoff,
- knowledge, or files worth preserving. Prefer lifecycle tools (`lull`, `suspend`,
- `nirvana` when appropriate and authorized) over filesystem deletion.
+ Boot observation waits 5.0 seconds and polls every 0.1 seconds; early-exit
+ stderr is capped at its final 2,000 bytes. Avatar uses the parent's default
+ preset, inherits the launcher process environment without exposing it, launches
+ a detached independent life, and clears newborn admin. A slow observation
+ releases the parent-side handle without terminating the child.
- Footprint check: load the [shared inspection recipe](../../skills/manual/reference/cleanup-footprint-contract.md#shared-footprint-check-recipe)
- through `skills-manual` → `reference/cleanup-footprint-contract.md`. Combine
- its definitions with this tool-specific selection in one task-owned script;
- the selection is not a standalone executable. Inspection writes nothing.
- Appending `logs/cleanup.jsonl` is the separate, explicitly selected audit step
- in that recipe; retain this manual's cleanup/approval rules below.
+ ## Safety boundaries
- ```python
- agent = Path.cwd() # the relevant agent directory, not a repository root
- network = agent.parent if agent.parent.name == ".lingtai" else agent / ".lingtai"
- items = [p for p in network.iterdir() if p.is_dir() and (p / ".agent.json").exists()] if network.is_dir() else []
- rows, total = footprint_check(items, tool="avatar", top_n=None)
- ```
+ - Avatar receives only its granted workdir and avatar-parent ports; it never
+ receives the parent `Agent` or a parent in-process handle.
+ - The child directory is a direct sibling under the network root. The canonical
+ `name` is both the public identity and path basename; path escape is refused.
+ - Shallow spawn is a blank slate with `init.json` plus narrow Psyche owner
+ inputs. Deep spawn additionally copies durable identity/knowledge state, but
+ still starts a fresh conversation. Neither mode inherits parent admin,
+ identity, brief, or addons.
+ - Avatar no longer distributes rules. `.rules` remains kernel/Psyche state;
+ read the Psyche route above instead of treating it as an Avatar action.
- Recommended cadence: after spawning new specialists, before pruning a network,
- and monthly for busy orchestrators. Any destructive cleanup requires explicit
- user consent after a dry-run list of avatars and sizes.
+ For procedures, storage layout, authority markers, boot receipts, caring for a
+ quiet avatar, and cleanup boundaries, open the two nested references. They are
+ part of this manual's source of truth, not optional examples.