Skip to content

fix(profile): make default state paths consistently profile-aware (workspace + doctor migration) - #2

Closed
xiejiahao wants to merge 23 commits into
codex/upstream-main-syncfrom
codex/profile-aware-workspace-clean
Closed

fix(profile): make default state paths consistently profile-aware (workspace + doctor migration)#2
xiejiahao wants to merge 23 commits into
codex/upstream-main-syncfrom
codex/profile-aware-workspace-clean

Conversation

@xiejiahao

@xiejiahao xiejiahao commented Feb 25, 2026

Copy link
Copy Markdown
Owner

AI-assisted (Claude Opus 4.6) — Fully tested locally. Session logs available on request. I understand what this code does.

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem:
    • In profiled runs, defaults were mixed across roots: profile state lived under ~/.openclaw-<profile>, while some defaults/messages still pointed to ~/.openclaw/....
    • A major confusion point was that, under one profile, the default agent workspace and newly-created agent workspace could appear under different roots.
  • Why it matters:
    • Weakens profile isolation semantics and increases migration/backup/operator confusion.
    • Makes profile-level orchestration harder because runtime state is not consistently co-located.
  • What changed:
    • Core defaults now derive from active stateDir for workspace + exec-approvals behavior.
    • Doctor adds profile-aware migration prompts for legacy workspace and legacy exec-approvals layout.
    • Runtime/default path strings in relevant areas were aligned to stateDir semantics.
    • Docs (EN + zh-CN) were updated to the canonical model: state dir is profile-resolved, default workspace is <stateDir>/workspace, explicit config overrides defaults.
    • Extensions (feishu, memory-lancedb, voice-call) adapted to resolve state paths from stateDir, with backward-compatible legacy fallback. Tests added for each (64 lines code, 237 lines tests).
  • What did NOT change (scope boundary):
    • No new CLI flags.
    • No protocol/wire changes.
    • Explicitly configured custom paths remain authoritative.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #N/A
  • Related #N/A

User-visible / Behavior Changes

  • In profile mode, default runtime-derived state paths are consistently rooted at active stateDir.
  • Doctor shows profile-aware migration prompts for legacy workspace and legacy exec approvals paths.
  • Doctor platform notes check launch-agent disable marker with profile-aware behavior.
  • Docs/examples now consistently use <stateDir>/... defaults where applicable.

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (Yes)
  • If any Yes, explain risk + mitigation:
    • Risk: legacy layouts may observe different default-resolved locations.
    • Mitigation: explicit config remains authoritative; migration is prompted and non-destructive.

Repro + Verification

Environment

  • OS: macOS (Apple Silicon)
  • Runtime/container: local Node + pnpm
  • Model/provider: N/A
  • Integration/channel (if any): workspace/doctor + affected extensions
  • Relevant config (redacted): profile-mode (--profile <name>)

Steps

  1. Run profile-mode setup/onboard/doctor flows and inspect resolved default paths.
  2. Validate doctor migration detection/prompting for legacy workspace and approvals paths.
  3. Run targeted tests for workspace/doctor/exec-approvals/security path assertions.

Expected

  • Defaults resolve under active stateDir in profile mode.
  • Doctor migrations are guided and non-destructive.
  • Explicit user path config is preserved.

Actual

  • Matches expected in targeted verification.

Evidence

Local CI checks (macOS Apple Silicon, Node + pnpm)

Format (oxfmt --check):

All matched files use the correct format.
Finished in 4703ms on 5455 files using 10 threads.

Type check (tsgo / @typescript/native-preview 7.0.0-dev):

7 pre-existing errors on the base branch (codex/upstream-main-sync), confirmed by running tsgo on the base branch directly. None introduced by this PR.

Lint (oxlint --type-aware):

Found 0 warnings and 0 errors.
Finished in 4.8s on 3971 files with 136 rules using 10 threads.

Tests (pnpm test:macmini — serial profile, 1 worker):

Unit:    1295 files passed | 10460 tests passed | 1 skipped | 576.49s
Gateway:   97 files passed |   851 tests passed |           |  74.37s
Total:   1392 files passed | 11311 tests passed | 0 failed

Protocol check (pnpm protocol:check):

wrote dist/protocol.schema.json
wrote apps/macos/Sources/OpenClawProtocol/GatewayModels.swift
wrote apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift
git diff --exit-code  ✓  (no diff)

Docs check (pnpm check:docs):

Format:    All matched files use the correct format. (644 files)
Markdown:  0 error(s) (331 files)
Links:     checked_internal_links=2828, broken_links=0

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • Full test suite (pnpm test:macmini): 1392 files, 11311 tests, 0 failures.
    • Full lint + format + type check + protocol + docs check suite.
    • Targeted unit tests for workspace/doctor/exec-approvals/security path assertions.
  • Edge cases checked:
    • profile-aware path string assertions in security/config-help tests
    • doctor migration prompt flow and related behavior tests
    • extension stateDir fallback paths (feishu dedup, lancedb DB, voice-call storage)
  • What you did not verify:
    • CI on upstream runners (fork lacks blacksmith-16vcpu-ubuntu-2404 custom runners)
    • Windows / Linux platform-specific behavior (macOS only)

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (Recommended for legacy profile layouts)
  • If yes, exact upgrade steps:
    1. openclaw --profile <name> doctor
    2. approve prompted migration where safe
    3. re-run doctor to confirm clean state

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly:
    • Revert this PR (or roll back to previous known-good commit).
  • Files/config to restore:
    • Move migrated workspace/approvals files back to prior paths if rollback is required.
    • Restore openclaw.json from backup (.bak) when needed.
  • Known bad symptoms reviewers should watch for:
    • mixed-root behavior still appearing in profile mode
    • migration prompts inconsistent with active profile state dir

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk:
    • Partial legacy/manual deployments may require operator migration decisions.
    • Mitigation:
      • guided doctor prompts, conflict-safe handling, and no forced overwrite.

Note: CI checks on this fork use custom runners (blacksmith-16vcpu-ubuntu-2404) not available here.
All checks were run locally — see Evidence section above.
CI will run on the upstream PR after rebasing.

@xiejiahao
xiejiahao changed the base branch from main to codex/upstream-main-sync February 25, 2026 00:33
steipete and others added 9 commits February 25, 2026 00:35
…ocalFile

On Windows, device IDs (dev) returned by handle.stat() and fs.lstat()
may differ even for the same file, causing false-positive 'path-mismatch'
errors when reading local media files.

This fix introduces a statsMatch() helper that:
- Always compares inode (ino) values
- Skips device ID (dev) comparison on Windows where it's unreliable
- Maintains full comparison on Unix platforms

Fixes openclaw#25699
@xiejiahao
xiejiahao force-pushed the codex/profile-aware-workspace-clean branch from 8f95e09 to b471e1b Compare February 25, 2026 01:07
steipete and others added 12 commits February 25, 2026 01:10
…#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
…penclaw#25682)

Land PR openclaw#25682 from @lairtonlelis after maintainer rework:
track dispatcher updates when network decision changes to avoid stale global fetch behavior.

Co-authored-by: Ailton <lairton@telnyx.com>
…penclaw#25827)

Carry fail-closed empty-allowlist guard clarity and changelog attribution for PR openclaw#25827.

Co-authored-by: Brian Mendonca <brianmendonca@Brians-MacBook-Air.local>
)

Land PR openclaw#25680 from @lairtonlelis.
Retain explicit status/code/http 402 detection for oversized structured payloads.

Co-authored-by: Ailton <lairton@telnyx.com>
…#25729)

Land PR openclaw#25729 from @Suko.
Use shared fallback-resolution helper and add regression coverage for default, override, and explicit-empty cases.

Co-authored-by: suko <miha.sukic@gmail.com>
…directory

Change resolveDefaultAgentWorkspaceDir() to derive the workspace path
from resolveStateDir() instead of manual profile-based path construction.
Similarly update exec-approvals path resolution to use stateDir, with
legacy fallback for backward compatibility.

Before: ~/.openclaw/workspace-{profile}, ~/.openclaw/exec-approvals.json
After:  <stateDir>/workspace, <stateDir>/exec-approvals.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add doctor checks that detect legacy profile workspace layouts
(~/.openclaw/workspace-{profile}) and exec-approvals files
(~/.openclaw/exec-approvals.json), offering interactive migration to
the new stateDir-based locations.

- Extract runDoctorMigrationPrompt() helper to deduplicate the
  detect → preview → confirm → move → result pattern
- Remove dead detectLegacyWorkspaceDirs() stub (gutted during
  moltbot→openclaw rename, always returned empty array)
- Fix config migration to remove agents.defaults.workspace key
  (falls back to implicit stateDir-derived default) instead of
  setting it to a new absolute path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update documentation and source string literals to reflect the new
stateDir-based default paths. Documentation uses <stateDir>/... as a
placeholder; runtime user-facing messages use dynamically resolved paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clear OPENCLAW_STATE_DIR in tests that stub OPENCLAW_HOME, since
Windows test harness sets OPENCLAW_STATE_DIR which takes precedence
in resolveStateDir(). Also use JSON.parse instead of toContain for
path assertions in doctor-exec-approvals to avoid backslash escaping
mismatches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@xiejiahao
xiejiahao force-pushed the codex/profile-aware-workspace-clean branch from b471e1b to 8549a68 Compare February 25, 2026 01:40
Extension resolveStateDirFromEnv helpers were producing
~/.openclaw-default instead of ~/.openclaw when OPENCLAW_PROFILE=default
was set without OPENCLAW_STATE_DIR. Align with the core CLI behaviour in
src/cli/profile.ts which treats "default" as the empty suffix.

Fixes review comment on feishu/dedup.ts, feishu/dynamic-agent.ts,
voice-call/utils.ts, memory-lancedb/config.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@xiejiahao
xiejiahao deleted the branch codex/upstream-main-sync March 1, 2026 14:36
@xiejiahao xiejiahao closed this Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants