Files
AirCoding/AirPlan/docs/architecture/decisions-round-2.md
AirCoding 33a76a1ebc Move project from external drive to local NVMe
迁移路径: /run/media/airlongdian/EasyU/AirCoding -> /home/airlongdian/DataDevices/AirWorkSpace/AirCoding

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 09:51:49 +08:00

8.0 KiB
Executable File
Raw Permalink Blame History

Architecture Decisions — Round 2

Date: 2026-05-26 Source: idea.md discussion, questions 1930

D-021: Project Model Version Migration

  • Decision: Backup before migrate, user confirmation required.
  • Mechanism: On opening a project with old-version project.json, auto-detect and prompt user. Backup to ~/.air/projects/<id>/backups/ before migration. Migration failure → rollback to backup, notify user.

D-022: Scanner — Full Directory Tree, No Exclusions

  • Decision: Scanner collects complete directory tree (file system metadata only — paths, extensions, file types), no recursion depth limit, no directory exclusions.
  • Why: Directory tree traversal is fast (kernel inode walk), and the full tree provides useful structural information (e.g., detecting referenced components). File content is NOT read during scanning.
  • Timeout: 15 seconds hard timeout as safety net. On timeout, return partial results with incomplete marker.
  • Update strategy: First scan is full. Subsequent scans are incremental (mtime diff). On re-open, load project.json + quick check for top-level directory changes; trigger incremental scan only if changes detected.
  • Informed by: Claude Code's zero-pre-scan approach (agentic search, no indexing), OpenCode's Tree-sitter AST + LLM hybrid.

D-023: Project Rules Format — Markdown + Frontmatter

  • Decision: Claude Code style — Markdown body with YAML frontmatter for structured metadata. Human-readable, git diff friendly, LLM natively understands.
  • Storage: ~/.air/projects/<id>/project-rules.md (project-authoritative). Export via air memory export --project-rules AIR.md.
  • Informed by: Claude Code's CLAUDE.md format with frontmatter metadata.

D-024: ExperienceMiner — Mid-Session Trigger + Curator + Self-Patch

  • Decision:
    • Triggers: DebugRecord produced + session end + N-turn interval (Hermes-style Nudge Engine counter, ~10 turns or 10 tool calls). Background sub-agent, never blocks Main Agent.
    • Scope: Full extraction, no range limits. LLM decides what's worth saving.
    • Validation: Non-debug experiences use occurrence count (N=3) as threshold for promotion prompt. Debug experiences use evidence (build/test pass) as confidence; no numeric score needed.
    • Deduplication: Curator Daemon runs periodically (weekly), identifies overlapping skills, suggests merges, marks stale entries, archives unused ones.
    • Self-patch: When agent finds existing skill/rules wrong during execution, forwards to ExperienceMiner to patch.
    • Data format: SKILL.md (YAML frontmatter + Markdown body) under ~/.air/skills/. Memories in ~/.air/projects/<id>/learned-memory.db.
  • Informed by: Hermes Agent's Nudge Engine, Curator Daemon, self-patching mechanism, and SKILL.md format.

D-025: Context Compaction — Rule-File Driven, Copy-on-Write, Async

  • Decision:
    • Trigger: 70% of context window capacity.
    • Strategy: Rule-file driven with three-tier inheritance (system default → user template at ~/.air/compaction-rules.yaml → project override at .air/compaction-rules.yaml). System default template ensures projects without custom rules work normally. Editing user template affects all future new projects.
    • Mechanism: Copy-on-Write. On trigger, snapshot current messages 1-N. Compression runs asynchronously (independent Compactor sub-agent). New messages continue appending to original chain. On completion, a compaction marker is inserted between the compressed summary and post-snapshot messages. LLM sees: summary + marker + new messages. Original messages preserved for explicit LLM backtracking.
    • Executor: Independent Compactor sub-agent (not ContextAssembler, not Main Agent).
  • Decision: Symlinks resolved to physical path (follow realpath). This prevents project escape via symlink chains.

D-027: Permission — .git/ Write Protection

  • Decision: .git/ directory write-protected by default (requires user confirmation). Can be overridden in .air/permissions.yaml project settings.

D-028: Permission — Build Directory Unrestricted

  • Decision: Build directories (build/, out/, etc.) have no special restrictions. C++ packaging workflows require agent ability to manually organize runtime libraries (.so/.dll deployment, rpath, resource file organization), so build directory access must be unrestricted.

D-029: Permission — ~/.air/ System-Managed

  • Decision: ~/.air/ and all contents are managed by AirCoding internally. PermissionEngine does not check AirCoding's own internal operations.

D-030: Backup — Git-Based Repo

  • Decision: Project-external file backup is a git repository at ~/.air/projects/<id>/backups/. Each external file modification: cp to backups/ → git add && git commit (commit message: session_id, agent_type, reason). Version history, diff, compression all provided by git natively. air restore --listgit log; air restore --session <id>git log --grep <id>. User manually deletes backups; no automatic cleanup.

D-031: High-Risk Action Detection — Static Path Whitelist + LLM Escape Hatch

  • Decision: Static path whitelist covers clearly-system paths (/etc/fstab, /boot/, /etc/default/grub, Windows registry system hives). sudo is NOT treated as high-risk (development machines need it for routine operations). LLM judgment only used as escape hatch when path matching can't decide.

D-032: Restore Granularity

  • Decision: Three levels — single file (most recent backup), specified time point, entire session. Git-backed storage makes all three straightforward.

D-033: Testing Strategy

  • Decision: Three layers:
    • Unit tests (bun test, CI per push, <30s, no LLM): Tool schema validation, PermissionEngine, ContextAssembler token math, EventBus routing, build system detection, config loading priority.
    • Integration tests (CI per push, <1min, recorded LLM fixture replay): Agent Loop state machine, Scheduler dependency resolution, sub-agent spawn → IPC → WorkerResult, session persist/restore, compaction Copy-on-Write, worktree lifecycle.
    • E2E tests (Release gate, real LLM): Full C++ project scenarios — add function + test, fix build error, multi-task dependency order, session resume. Must pass before every release.

D-034: Distribution — Binary Tarball

  • Decision: Binary distribution (Bun compile standalone executable, bundled Bun runtime). Distribution package = binary executable + Python scripts + default resource files (compaction rule templates, HUD presets, etc.). No public npm/channel until stable. Language-specific toolchains are first-class plugins, not bundled special treatment.

D-035: Logging — Dual-File, 7-Day Retention

  • Decision:
    • air.log — User-readable. Records startup failures, exceptions, environment configuration issues. Helps users self-diagnose.
    • air.developer.log — Full debug log, encrypted (may contain user privacy data, only decryptable by development team). Performance metrics written here. 7-day retention, auto-rotated.
    • Crash diagnostics: air doctor command collects version info, system environment, recent logs, crash stack trace into diagnostic package. Auto-detect abnormal exit on next startup, prompt user.

D-036: Multi-Language Extension — Per-Language toolchain-* Packages

  • Decision: Runtime (Agent Loop, Session, Scheduler, ToolRegistry, PermissionEngine) is language-agnostic. Each language is a toolchain-<lang> package + a LanguageDetector plugin implementing a common interface. Adding a new language = adding a toolchain-python/toolchain-rust etc. package, no core changes required. MVP ships with toolchain-cpp.

D-037: Compaction Rules — Three-Tier Inheritance

  • Decision: System default (built-in, never deleted, always fallback) → User template (~/.air/compaction-rules.yaml, editable, affects all future new projects) → Project rules (.air/compaction-rules.yaml, project-specific, highest priority).