Skip to content

IDENTITY.md is overwritten on every redeploy, clobbering user edits #2387

@kvnkho

Description

@kvnkho

Summary

/root/.openclaw/workspace/IDENTITY.md is regenerated from env vars on every controller boot, so any edits a user makes to the file are lost on the next redeploy.

Expected

If a user edits IDENTITY.md, the edits should persist across redeploys — matching the behavior of TOOLS.md, which is only seeded on first provision.

Actual

Every boot overwrites IDENTITY.md with content freshly generated from KILOCLAW_BOT_NAME / KILOCLAW_BOT_NATURE / KILOCLAW_BOT_VIBE / KILOCLAW_BOT_EMOJI.

Code path

In services/kiloclaw/controller/src/bootstrap.ts:

  1. bootstrap()bootstrapNonCritical() runs the onboard/doctor step on every start.
  2. runOnboardOrDoctor() ends with an unconditional call to writeBotIdentityFile(env, deps) — it runs in both the fresh-install branch and the existing-config branch.
  3. writeBotIdentityFile() calls atomicWrite(IDENTITY_MD_DEST, formatBotIdentityMarkdown(env), ...), unconditionally replacing the file.

Asymmetry with TOOLS.md

TOOLS.md is seeded only inside the if (!configExists) branch, so user edits there survive redeploys. IDENTITY.md is written outside that guard, so it doesn't.

if (!configExists) {
  // ...
  if (deps.existsSync(TOOLS_MD_SOURCE)) {
    deps.mkdirSync(path.dirname(TOOLS_MD_DEST), { recursive: true });
    deps.copyFileSync(TOOLS_MD_SOURCE, TOOLS_MD_DEST);
  }
} else {
  // doctor path
}

writeBotIdentityFile(env, deps); // ← runs every boot

Suggested fix

Either:

  • (a) Move writeBotIdentityFile(env, deps) inside the !configExists branch so it only runs on first provision (mirrors TOOLS.md), or
  • (b) Inside writeBotIdentityFile, skip the write if IDENTITY_MD_DEST already exists — preserves any existing file (including user edits) while still seeding on first boot.

(b) is slightly friendlier if the env-var-driven identity should still be able to seed a fresh container even when a config already exists for other reasons.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions