mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
docs: tighten refactor storage policy
This commit is contained in:
14
AGENTS.md
14
AGENTS.md
@@ -65,6 +65,15 @@ Skills own workflows; root owns hard policy and routing.
|
||||
- Compatibility is opt-in. "Shipped" means reachable from a release Git tag; main/GitHub/PR/unreleased code is not shipped.
|
||||
- Refactor default: one canonical path. Delete the old path unless user explicitly wants compat or the shipped public contract is obvious and cited.
|
||||
- Core runtime consumes only current canonical shapes/config/data. Legacy or retired shapes normalize only in doctor/migration code before runtime; no runtime shims, aliases, or fallback readers.
|
||||
- State/storage migrations are database-first. Runtime reads/writes the canonical store only. Old file stores, sidecars, aliases, and fallback readers belong in `openclaw doctor --fix` migration code only, never steady-state runtime.
|
||||
- Storage default: SQLite only. Do not add JSON/JSONL/TXT/sidecar files for OpenClaw-owned runtime state, caches, queues, registries, indexes, cursors, checkpoints, or plugin scratch data.
|
||||
- Use the shared state DB (`state/openclaw.sqlite`) for global runtime state and plugin KV data. Use the per-agent DB (`agents/<agentId>/agent/openclaw-agent.sqlite`) for agent-scoped state/cache. Use a dedicated SQLite DB only when schema, volume, or lifecycle clearly does not fit those stores.
|
||||
- Legacy state/cache files are migration debt. When touching code that reads/writes them, prefer moving the data into SQLite or calling out the refactor follow-up; do not add parallel file paths.
|
||||
- File storage must be a named product artifact: import/export, user attachment, log, backup, or external tool contract. If it is app state or cache, it belongs in SQLite.
|
||||
- Before adding any path under state dirs, choose one: shared state DB, plugin KV, agent DB, or dedicated SQLite schema. If none fits, design the SQLite owner/schema first.
|
||||
- Cache/transient state gets no compat migration unless a shipped user contract is cited. Prefer delete/drop/rebuild over import. If old state can be lost without user-visible data loss, remove the old path entirely.
|
||||
- Persistent user state gets one migration owner. Doctor migrates, verifies, and then runtime assumes the new shape. No dual-write, read-through fallback, lazy import, or "if SQLite fails use JSON" branches.
|
||||
- Fallback is a product decision, not an implementation convenience. Before adding one, name the shipped contract, failure mode, removal plan, and why doctor cannot solve it. Otherwise delete it.
|
||||
- Keep old behavior only for an explicit public API/config/plugin SDK/data contract, tagged upgrade path, security/migration boundary, dependency contract, or observed prod state.
|
||||
- If unsure, ask before preserving compat. Do not keep aliases, shims, fallback stacks, stale names, or obsolete tests just in case.
|
||||
- Tests alone do not make internals contracts. If compat stays, name the contract and migration/removal plan in code, test, or PR.
|
||||
@@ -159,12 +168,17 @@ Skills own workflows; root owns hard policy and routing.
|
||||
- Use named intermediates only for domain meaning or readability; avoid temp-variable soup.
|
||||
- Code size matters. Prefer small clear code; maintainability includes not growing LOC without payoff.
|
||||
- Refactors should delete about as much local complexity as they add. If LOC grows, the new ownership/API needs to clearly pay for it.
|
||||
- Refactors should reduce non-test LOC unless they remove a larger architectural cost. Treat positive prod LOC as a smell. Before closeout, run `git diff --numstat`; if non-test LOC grew, trim or explicitly justify why fewer paths now exist.
|
||||
- Prefer deleting branches, modes, adapters, and tests over preserving them. A refactor that adds a second path has probably failed unless the old path is a cited shipped contract.
|
||||
- New helpers/files must pay rent immediately: fewer call paths, fewer concepts, or less repeated logic. No helpers for one-off compat, naming translation, or speculative resilience.
|
||||
- Before adding helpers/files, check whether existing code can absorb the behavior with less new surface.
|
||||
- Keep APIs narrow: export only current caller needs; keep types/helpers local by default.
|
||||
- Return the smallest useful shape. Avoid broad result objects, flags, metadata unless callers use them.
|
||||
- Avoid adapter layers that only rename fields. Move real responsibility or leave code local.
|
||||
- Inline simple one-use objects/spreads when clearer. Extract only when it removes duplication or hard logic.
|
||||
- Tests prove behavior/regressions, not every internal branch.
|
||||
- Tests are welcome, but review them before landing for duplication and value. Delete useless tests, such as assertions for behavior or paths just removed.
|
||||
- Tests protect canonical behavior and migration boundaries, not obsolete internals. Delete tests for removed fallback paths instead of updating them.
|
||||
- For non-trivial refactors, check `git diff --numstat` before closeout. If LOC grew, trim or explain why.
|
||||
- Prefer existing narrow helpers over repeated casts/guards. Add local helpers when 2+ nearby call sites share real boundary logic.
|
||||
- Prefer ctor parameter properties for injected deps/config. Do not ban them for erasable-syntax purity.
|
||||
|
||||
Reference in New Issue
Block a user