oxios 0.2.0

Oxios Agent OS — Agent Operating System powered by oxi-sdk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
# RFC-001: KernelHandle Facade 분리 설계

> **날짜**: 2026-05-10
> **상태**: 초안 v2 (리뷰 피드백 반영)
> **범위**: `oxios-kernel/src/kernel_handle.rs`

---

## 1. 배경

### 현재 문제

`KernelHandle`은 19개 서브시스템을 단일 struct에 평면적으로 나열하고,
101개 공개 메서드를 하나의 `impl` 블록에 정의한다.

**문제점:**
- God Object: 101개 메서드가 하나의 `impl`에 집중
- 발견성: "내가 필요한 메서드가 어디 있는지" 파악 어려움
- 테스트: 특정 도메인만 모킹하기 어려움
- 응집도: 무관한 메서드가 같은 스코프에 존재

**실제 사용 패턴 (Web routes 103곳 + CLI 7곳 + Guardian 8곳):**
```
고빈도 (4회+):  workspace_path, load_markdown, list_category
중빈도 (2회):   subscribe, publish, list_agents, query_audit, ...
저빈도 (1회):   60+ 메서드
미사용:         auto_commit_enabled, verify(), persona_store(), mcp_servers(), ...
```

---

## 2. 설계 원칙

1. **같은 프로세스, 같은 바이너리** — Micro-kernel IPC가 아닌 Facade 패턴
2. **Rust 소유권 활용** — Arc<> 공유는 그대로, 인터페이스만 재구성
3. **호환성** — Web routes의 호출부 변경은 최소화
4. **7개 도메인** — 각 Facade는 하나의 명확한 책임 영역 (8–16개 메서드)
5. **점진적 마이그레이션** — 컴파일 에러로 누락 파악

---

## 3. 새로운 구조

### 3.1 KernelHandle (재설계)

```rust
// kernel_handle/mod.rs

pub mod state_api;
pub mod agent_api;
pub mod security_api;
pub mod persona_api;
pub mod extension_api;
pub mod mcp_api;
pub mod infra_api;

pub use state_api::StateApi;
pub use agent_api::AgentApi;
pub use security_api::SecurityApi;
pub use persona_api::PersonaApi;
pub use extension_api::ExtensionApi;
pub use mcp_api::McpApi;
pub use infra_api::InfraApi;

/// Oxios 커널 시스템 콜 API — 7개 도메인 Facade로 구성.
///
/// 각 Facade는 특정 도메인의 시스템 콜을 그룹화한다.
/// 모든 Facade는 동일한 서브시스템의 Arc<>를 공유한다 (같은 프로세스).
pub struct KernelHandle {
    /// 상태 관리: 저장/로드/세션/Git 커밋
    pub state: StateApi,
    /// 에이전트 관리: 라이프사이클/예산/메모리
    pub agents: AgentApi,
    /// 보안: 인증/감사/RBAC/승인
    pub security: SecurityApi,
    /// 페르소나: 멀티 페르소나 관리
    pub persona: PersonaApi,
    /// 확장: 프로그램/스킬/호스트 도구
    pub extensions: ExtensionApi,
    /// MCP: 외부 도구 서버 브릿지
    pub mcp: McpApi,
    /// 인프라: 스케줄러/크론/리소스/이벤트/Git 조회/시스템
    pub infra: InfraApi,
}
```

### 3.2 파일 구조

```
crates/oxios-kernel/src/
├── kernel_handle/
│   ├── mod.rs              KernelHandle 정의 + 생성자
│   ├── state_api.rs        StateApi    (15개 메서드)
│   ├── agent_api.rs        AgentApi    (11개 메서드)
│   ├── security_api.rs     SecurityApi (15개 메서드)
│   ├── persona_api.rs      PersonaApi  (9개 메서드)
│   ├── extension_api.rs    ExtensionApi (12개 메서드)
│   ├── mcp_api.rs          McpApi      (8개 메서드)
│   └── infra_api.rs        InfraApi    (15개 메서드)
├── kernel_handle.rs        → 삭제 (디렉토리로 대체)
└── lib.rs                  pub mod kernel_handle; (변경 없음)
```

---

## 4. 각 Facade 상세 설계

### 4.1 StateApi — "저장하고 불러오기"

**책임**: 데이터 지속성, 세션 관리

```rust
pub struct StateApi {
    pub(crate) state_store: Arc<StateStore>,
}
```

| # | 메서드 | 시그니처 | 설명 |
|---|--------|----------|------|
| 1 | `save` | `async fn save<T: Serialize>(category, name, data) → Result<()>` | JSON 저장 |
| 2 | `save_markdown` | `async fn save_markdown(category, name, content) → Result<()>` | Markdown 저장 |
| 3 | `load` | `async fn load<T: DeserializeOwned>(category, name) → Result<Option<T>>` | JSON 로드 |
| 4 | `load_markdown` | `async fn load_markdown(category, name) → Result<Option<String>>` | Markdown 로드 |
| 5 | `delete` | `async fn delete(category, name) → Result<bool>` | 파일 삭제 |
| 6 | `list_category` | `async fn list_category(category) → Result<Vec<String>>` | 카테고리 내 파일 목록 |
| 7 | `commit_all` | `fn commit_all(git: &GitLayer, message) → Result<Option<CommitInfo>>` | 전체 Git 커밋 |
| 8 | `save_and_commit` | `async fn save_and_commit<T>(git: &GitLayer, category, name, data) → Result<()>` | 저장 + 커밋 |
| 9 | `save_md_and_commit` | `async fn save_md_and_commit(git: &GitLayer, category, name, content) → Result<()>` | Markdown 저장 + 커밋 |
| 10 | `delete_and_commit` | `async fn delete_and_commit(git: &GitLayer, category, name) → Result<bool>` | 삭제 + 커밋 |
| 11 | `save_session` | `async fn save_session(session) → Result<()>` | 세션 저장 |
| 12 | `load_session` | `async fn load_session(id) → Result<Option<Session>>` | 세션 로드 |
| 13 | `list_sessions` | `async fn list_sessions() → Result<Vec<SessionSummary>>` | 세션 목록 |
| 14 | `delete_session` | `async fn delete_session(id) → Result<bool>` | 세션 삭제 |
| 15 | `workspace_path` | `fn workspace_path() → &Path` | 워크스페이스 경로 |

**v1에서의 변경:**
- `base_path` 제거 → `workspace_path`와 동일, 하나로 통일
- `auto_commit_enabled` 제거 → 1곳도 사용 안 함. 필요시 `infra.config().git.auto_commit`로 확인
- Git 커밋 메서드(`save_and_commit` 등)는 `git_layer`를 명시적 파라미터로 받음 → StateApi는 `git_layer`를 소유하지 않고 InfraApi에서 전달

> **설계 결정**: StateApi는 `git_layer`를 소유하지 않습니다.
> 커밋이 필요한 호출부에서 `handle.state.save_and_commit(&handle.infra.git(), "cat", "name", &data)` 처럼
> InfraApi의 Git 레퍼런스를 전달합니다.
> 또는 KernelHandle 수준에서 `handle.save_and_commit()` 편의 메서드를 제공합니다.
> (자세한 내용은 Section 6 참조)

---

### 4.2 AgentApi — "에이전트 관리"

**책임**: 에이전트 라이프사이클, 예산, 에이전트별 메모리

```rust
pub struct AgentApi {
    pub(crate) supervisor: Arc<dyn Supervisor>,
    pub(crate) budget_manager: Arc<BudgetManager>,
    pub(crate) memory_manager: Arc<MemoryManager>,
}
```

| # | 메서드 | 시그니처 | 설명 |
|---|--------|----------|------|
| 1 | `list` | `async fn list() → Result<Vec<AgentInfo>>` | 에이전트 목록 |
| 2 | `kill` | `async fn kill(agent_id) → Result<()>` | 에이전트 종료 |
| 3 | `check_budget` | `fn check_budget(agent_id) → BudgetInfo` | 예산 확인 |
| 4 | `set_budget` | `fn set_budget(limit: BudgetLimit)` | 예산 설정 |
| 5 | `remove_budget` | `fn remove_budget(agent_id)` | 예산 제거 |
| 6 | `reserve_budget` | `fn reserve_budget(agent_id, tokens) → Result<(), BudgetExceeded>` | 토큰 예약 |
| 7 | `reset_budget` | `fn reset_budget(agent_id)` | 예산 윈도우 리셋 |
| 8 | `memory_stats` | `async fn memory_stats() → (usize, usize)` | 메모리 통계 |
| 9 | `remember` | `async fn remember(entry: MemoryEntry) → Result<String>` | 메모리 저장 |
| 10 | `search_memory` | `async fn search_memory(query, type?, limit) → Result<Vec<MemoryEntry>>` | 메모리 검색 |
| 11 | `recall` | `async fn recall(query) → Result<Vec<MemoryEntry>>` | 메모리 리콜 (단순 래퍼) |

**v1에서의 변경:**
- `memory_stats()` (sync) 제거 → `memory_stats_async()``memory_stats()`로 통일
- `memory_remember``remember`, `memory_search``search_memory` (Facade 스코프 안에서 접두사 불필요)
- `recall` 추가 → `search_memory(query, None, 5)`의 편의 래퍼

---

### 4.3 SecurityApi — "보안과 감사"

**책임**: 인증, 감사 추적, 접근 제어, Human-in-the-Loop 승인

```rust
pub struct SecurityApi {
    pub(crate) auth_manager: Arc<parking_lot::Mutex<AuthManager>>,
    pub(crate) audit_trail: Arc<AuditTrail>,
    pub(crate) access_manager: Arc<parking_lot::Mutex<AccessManager>>,
}
```

| # | 메서드 | 시그니처 | 설명 |
|---|--------|----------|------|
| **감사 추적** | | | |
| 1 | `audit` | `fn audit(actor, action, resource) → String` | 감사 기록 |
| 2 | `verify_chain` | `fn verify_chain() → Result<bool>` | 체인 무결성 검증 |
| 3 | `query_audit` | `fn query_audit(from, to) → Vec<AuditEntry>` | 범위 조회 |
| 4 | `query_audit_by_agent` | `fn query_audit_by_agent(agent_id) → Vec<AuditEntry>` | 에이전트별 조회 |
| 5 | `audit_count` | `fn audit_count() → usize` | 총 항목 수 |
| 6 | `flush` | `fn flush() → Result<()>` | 감사 플러시 |
| **인증** | | | |
| 7 | `validate_token` | `fn validate_token(token) → bool` | Bearer 토큰 검증 |
| **접근 제어** | | | |
| 8 | `get_permissions` | `fn get_permissions(agent) → Option<AgentPermissions>` | 권한 조회 |
| 9 | `update_permissions` | `fn update_permissions(agent, update) → Result<()>` | 권한 수정 |
| 10 | `get_audit_log` | `fn get_audit_log() → Vec<AuditEntry>` | 접근 로그 |
| 11 | `log_action` | `fn log_action(agent, action, resource)` | 접근 로깅 |
| **승인 (HitL)** | | | |
| 12 | `list_approvals` | `fn list_approvals() → Vec<(PendingApproval, ApprovalStatus)>` | 승인 대기 목록 |
| 13 | `approve` | `fn approve(id) → bool` | 승인 |
| 14 | `reject` | `fn reject(id) → bool` | 거부 |
| 15 | `ensure_permissions` | `fn ensure_permissions(agent) → AgentPermissions` | 권한 보장 (get or create) |

**v1에서의 변경:**
- `verify_audit``verify_chain` (감사 "체인" 검증이라는 의미 명확화)
- `approve_request``approve`, `reject_request``reject`
- `audit_log_action``log_action`
- `get_or_create_permissions``ensure_permissions` (의미 명확화)

---

### 4.4 PersonaApi — "페르소나 관리"

**책임**: 멀티 페르소나 정의, 활성 페르소나 전환

```rust
pub struct PersonaApi {
    pub(crate) persona_manager: Arc<PersonaManager>,
}
```

| # | 메서드 | 시그니처 | 설명 |
|---|--------|----------|------|
| 1 | `list` | `fn list() → Vec<Persona>` | 전체 페르소나 목록 |
| 2 | `get` | `fn get(id) → Option<Persona>` | 특정 페르소나 |
| 3 | `create` | `fn create(persona)` | 생성 |
| 4 | `update` | `fn update(id, persona) → Result<()>` | 수정 |
| 5 | `delete` | `fn delete(id) → Result<()>` | 삭제 |
| 6 | `active` | `fn active() → Option<Persona>` | 활성 페르소나 |
| 7 | `set_active` | `fn set_active(id) → Result<()>` | 활성화 설정 |
| 8 | `count` | `fn count() → usize` ||
| 9 | `list_enabled` | `fn list_enabled() → Vec<Persona>` | 활성 목록 |

**v1에서의 변경:**
- ExtensionApi에서 독립 Facade로 분리 (9개 메서드, 명확한 단일 책임)
- `list_personas``list`, `get_persona``get` 등 (Facade 스코프 안에서 접두사 불필요)
- `persona_store()` 내부 노출 제거 → 모든 접근은 API 메서드를 통해서

---

### 4.5 ExtensionApi — "확장성"

**책임**: 프로그램, 스킬, 호스트 도구

```rust
pub struct ExtensionApi {
    pub(crate) program_manager: Arc<ProgramManager>,
    pub(crate) skill_store: Arc<SkillStore>,
    pub(crate) host_tool_validator: Arc<HostToolValidator>,
}
```

| # | 메서드 | 시그니처 | 설명 |
|---|--------|----------|------|
| **프로그램** | | | |
| 1 | `list_programs` | `async fn list_programs() → Vec<ProgramMeta>` | 프로그램 목록 |
| 2 | `get_program` | `async fn get_program(name) → Option<Program>` | 프로그램 상세 |
| 3 | `install_program` | `async fn install_program(source) → Result<Program>` | 설치 |
| 4 | `uninstall_program` | `async fn uninstall_program(name) → Result<()>` | 제거 |
| 5 | `enable_program` | `async fn enable_program(name) → Result<()>` | 활성화 |
| 6 | `disable_program` | `async fn disable_program(name) → Result<()>` | 비활성화 |
| 7 | `check_host_requirements` | `async fn check_host_requirements(name) → Result<HostRequirementsCheck>` | 호스트 요구사항 |
| **스킬** | | | |
| 8 | `list_skills` | `async fn list_skills() → Result<Vec<SkillMeta>>` | 스킬 목록 |
| 9 | `load_skill` | `async fn load_skill(name) → Result<Option<Skill>>` | 스킬 로드 |
| 10 | `create_skill` | `async fn create_skill(name, desc, content) → Result<()>` | 스킬 생성 |
| 11 | `delete_skill` | `async fn delete_skill(name) → Result<()>` | 스킬 삭제 |
| **호스트 도구** | | | |
| 12 | `check_host_tools` | `fn check_host_tools() → HostToolStatus` | 전체 체크 |

**v1에서의 변경:**
- Persona(9개)와 MCP(8개)를 별도 Facade로 분리 → 12개 메서드로 축소
- Program + Skill + HostTools = "설치 가능한 확장"이라는 응집된 도메인

---

### 4.6 McpApi — "외부 도구 서버"

**책임**: MCP 서버 등록/관리, 도구 호출

```rust
pub struct McpApi {
    pub(crate) mcp_bridge: Arc<McpBridge>,
}
```

| # | 메서드 | 시그니처 | 설명 |
|---|--------|----------|------|
| 1 | `list_servers` | `fn list_servers() → Vec<String>` | 서버 목록 |
| 2 | `get_server` | `fn get_server(name) → Option<McpServer>` | 서버 정보 |
| 3 | `register_server` | `fn register_server(server)` | 서버 등록 |
| 4 | `init_server` | `async fn init_server(name) → Result<()>` | 서버 초기화 |
| 5 | `client_status` | `async fn client_status(name) → Option<bool>` | 클라이언트 상태 |
| 6 | `list_tools` | `async fn list_tools() → Result<Vec<ToolDef>>` | 전체 도구 목록 |
| 7 | `cached_tools` | `async fn cached_tools(server) → Option<Vec<ToolDef>>` | 캐시된 도구 |
| 8 | `call_tool` | `async fn call_tool(server, tool, args) → Result<McpToolCallResult>` | 도구 호출 |

**v1에서의 변경:**
- ExtensionApi에서 독립 Facade로 분리
- `mcp_list_servers``list_servers`, `mcp_initialize_server``init_server` 등 (접두사 `mcp_` 제거)
- `mcp_servers()` (중복) 제거 → `list_servers()`로 통일

---

### 4.7 InfraApi — "시스템 인프라"

**책임**: Git 버전 관리, 스케줄링, 크론, 리소스 모니터링, 이벤트 버스, 시스템 정보

```rust
pub struct InfraApi {
    pub(crate) git_layer: Arc<GitLayer>,
    pub(crate) scheduler: Arc<AgentScheduler>,
    pub(crate) cron_scheduler: Arc<CronScheduler>,
    pub(crate) resource_monitor: Arc<ResourceMonitor>,
    pub(crate) event_bus: EventBus,
    pub(crate) config: OxiosConfig,
    pub(crate) start_time: Instant,
}
```

| # | 메서드 | 시그니처 | 설명 |
|---|--------|----------|------|
| **Git** | | | |
| 1 | `git_log` | `fn git_log(max) → Result<Vec<LogEntry>>` | 커밋 로그 |
| 2 | `git_tag` | `fn git_tag(name, message) → Result<()>` | 태그 |
| 3 | `git_restore` | `fn git_restore(path, hash) → Result<()>` | 파일 복원 |
| 4 | `git_verify` | `fn git_verify() → Result<bool>` | 무결성 검증 |
| 5 | `git_tags` | `fn git_tags() → Result<Vec<String>>` | 태그 목록 |
| 6 | `git` | `fn git() → &GitLayer` | GitLayer 직접 접근 |
| **스케줄러** | | | |
| 7 | `scheduler_stats` | `fn scheduler_stats() → SchedulerStats` | 스케줄러 통계 |
| 8 | `queued_tasks` | `fn queued_tasks() → Vec<ScheduledTask>` | 대기 태스크 |
| 9 | `running_tasks` | `fn running_tasks() → Vec<ScheduledTask>` | 실행 태스크 |
| **크론** | | | |
| 10 | `add_cron` | `async fn add_cron(job: CronJob) → Result<Uuid>` | 크론 등록 |
| 11 | `get_cron` | `fn get_cron(id) → Option<CronJob>` | 크론 조회 |
| 12 | `update_cron` | `async fn update_cron(id, update) → Result<()>` | 크론 수정 |
| 13 | `remove_cron` | `async fn remove_cron(id) → Result<()>` | 크론 제거 |
| 14 | `trigger_cron` | `fn trigger_cron(id) → Result<CronJob>` | 수동 트리거 |
| 15 | `complete_cron` | `async fn complete_cron(id, success, summary)` | 완료 표시 |
| **리소스** | | | |
| 16 | `resource_snapshot` | `fn resource_snapshot() → ResourceSnapshot` | 현재 리소스 |
| 17 | `resource_history` | `fn resource_history(last_n) → Vec<ResourceSnapshot>` | 이력 |
| 18 | `is_overloaded` | `fn is_overloaded() → bool` | 과부하 여부 |
| **이벤트** | | | |
| 19 | `subscribe` | `fn subscribe() → Receiver<KernelEvent>` | 이벤트 구독 |
| 20 | `publish` | `fn publish(event) → Result<()>` | 이벤트 발행 |
| **시스템** | | | |
| 21 | `config` | `fn config() → &OxiosConfig` | 설정 참조 |
| 22 | `uptime` | `fn uptime() → Duration` | 가동 시간 |

**v1에서의 변경:**
- `git()` 접근자 추가 → StateApi의 `save_and_commit` 등에서 GitLayer 참조 필요
- 크론 API 중복 제거: `schedule()`/`unschedule()`/`list_schedules()` 제거 → `add_cron()`/`remove_cron()`/목록은 `get_cron()`으로 통일
- `scheduler_rate_remaining` 제거 → `scheduler_stats()`에 포함. 실제 1곳(infra.rs:43)만 사용, stats에서 가져오면 됨
- `overload_threshold` 제거 → `is_overloaded()`로 충분
- `start_time()` 메서드 제거 → `uptime()`으로 충분

---

## 5. KernelHandle 편의 메서드

Guardian daemon이나 자주 쓰는 패턴을 위해 KernelHandle 수준의 편의 메서드를 제공한다.

```rust
impl KernelHandle {
    /// 저장 + Git 커밋 (StateApi + InfraApi 연동)
    pub async fn save_and_commit<T: Serialize>(
        &self,
        category: &str,
        name: &str,
        data: &T,
    ) -> Result<()> {
        self.state.save(category, name, data).await?;
        self.state.commit_all(&self.infra.git(), format!("save {}/{}", category, name))?;
        Ok(())
    }

    /// Markdown 저장 + Git 커밋
    pub async fn save_md_and_commit(
        &self,
        category: &str,
        name: &str,
        content: &str,
    ) -> Result<()> {
        self.state.save_markdown(category, name, content).await?;
        self.state.commit_all(&self.infra.git(), format!("save {}/{}", category, name))?;
        Ok(())
    }

    /// 삭제 + Git 커밋
    pub async fn delete_and_commit(
        &self,
        category: &str,
        name: &str,
    ) -> Result<bool> {
        let deleted = self.state.delete(category, name).await?;
        if deleted {
            self.state.commit_all(&self.infra.git(), format!("delete {}/{}", category, name))?;
        }
        Ok(deleted)
    }

    /// 감사 플러시 + Git 커밋
    pub fn flush_audit(&self) -> Result<()> {
        let _ = self.infra.git().commit_file("audit", "audit trail flush");
        Ok(())
    }
}
```

> **설계 결정**: `save_and_commit` 등은 KernelHandle 수준 편의 메서드로 제공.
> StateApi는 순수하게 데이터 저장에만 집중하고, Git 커밋과의 연동은
> KernelHandle에서 조율한다. 이것이 Facade 간 결합을 명시적으로 만든다.

---

## 6. KernelHandle 생성자

```rust
// kernel_handle/mod.rs

impl KernelHandle {
    /// 7개 Facade를 직접 받아 생성.
    ///
    /// `kernel.rs`의 `Kernel::handle()`에서 각 Facade를 개별적으로 조립 후 전달.
    /// 테스트에서는 필요한 Facade만 생성 가능.
    pub fn new(
        state: StateApi,
        agents: AgentApi,
        security: SecurityApi,
        persona: PersonaApi,
        extensions: ExtensionApi,
        mcp: McpApi,
        infra: InfraApi,
    ) -> Self {
        Self {
            state,
            agents,
            security,
            persona,
            extensions,
            mcp,
            infra,
        }
    }
}
```

`kernel.rs`에서의 조립:

```rust
impl Kernel {
    pub fn handle(&self) -> Arc<KernelHandle> {
        Arc::new(KernelHandle::new(
            StateApi {
                state_store: self.state_store.clone(),
            },
            AgentApi {
                supervisor: self.supervisor.clone(),
                budget_manager: self.budget_manager.clone(),
                memory_manager: self.memory_manager.clone(),
            },
            SecurityApi {
                auth_manager: self.auth_manager.clone(),
                audit_trail: self.audit_trail.clone(),
                access_manager: self.access_manager.clone(),
            },
            PersonaApi {
                persona_manager: Arc::new(self.persona_manager.clone()),
            },
            ExtensionApi {
                program_manager: self.program_manager.clone(),
                skill_store: Arc::new(self.skill_store.clone()),
                host_tool_validator: Arc::new(self.host_tool_validator.clone()),
            },
            McpApi {
                mcp_bridge: self.mcp_bridge.clone(),
            },
            InfraApi {
                git_layer: self.git_layer.clone(),
                scheduler: self.scheduler.clone(),
                cron_scheduler: self.cron_scheduler.clone(),
                resource_monitor: self.resource_monitor.clone(),
                event_bus: self.event_bus.clone(),
                config: self.config.clone(),
                start_time: self.start_time,
            },
        ))
    }
}
```

**v1에서의 변경:**
- `new()`가 19개 파라미터 → 7개 Facade 파라미터
- 각 Facade를 독립적으로 조립 → 테스트에서는 필요한 Facade만 생성 가능

---

## 7. 공유 Arc 맵 (수정됨)

```
서브시스템                State  Agent  Security  Persona  Extension  Mcp  Infra
─────────────────────────────────────────────────────────────────────────────────
state_store (Arc)           ●
event_bus (EventBus)                                                       ●
supervisor (Arc<dyn>)               ●
scheduler (Arc)                                                            ●
memory_manager (Arc)                ●
git_layer (Arc)                                                            ●
audit_trail (Arc)                            ●
budget_manager (Arc)                ●
resource_monitor (Arc)                                                     ●
cron_scheduler (Arc)                                                       ●
program_manager (Arc)                                          ●
skill_store (Arc)                                              ●
persona_manager (Arc)                               ●
mcp_bridge (Arc)                                                    ●
auth_manager (Arc<Mutex>)                    ●
access_manager (Arc<Mutex>)                  ●
host_tool_validator (Arc)                                      ●
config (OxiosConfig)                                                       ●
start_time (Instant)                                                       ●
─────────────────────────────────────────────────────────────────────────────────
서브시스템 수:              1      3      3         1        3         1     6
```

**v1에서의 수정:**
- `auth_manager` → SecurityApi (v1에서 ExtensionApi로 잘못 분류되었던 것 수정)
- `access_manager` → SecurityApi (동일)
- `persona_manager` → PersonaApi (ExtensionApi에서 분리)
- `mcp_bridge` → McpApi (ExtensionApi에서 분리)
- `git_layer` → InfraApi만 소유 (v1에서 State+Infra 양쪽에 있던 것을 Infra로 통일)

**공유 서브시스템 없음** — 모든 Arc가 정확히 하나의 Facade에만 속한다.
이것이 가장 큰 개선: v1에서 유일했던 교차 소유권(git_layer)이 제거됨.

---

## 8. 제거/병합된 메서드 목록

기존 101개에서 85개로 축소. 16개 제거/병합:

| # | 제거된 메서드 | 사유 | 대안 |
|---|--------------|------|------|
| 1 | `memory_stats()` (sync) | 동일 기능의 async 버전 존재 | `agents.memory_stats()` (async로 통일) |
| 2 | `auto_commit_enabled()` | 사용처 0곳 | `infra.config().git.auto_commit` |
| 3 | `verify()` | 테스트 전용, 프로덕션 미사용 | `security.verify_chain()` |
| 4 | `state_store_base_path()` | `workspace_path()`와 동일 | `state.workspace_path()` |
| 5 | `persona_store()` | 내부 타입 노출 | `persona.*` API 메서드 |
| 6 | `mcp_servers()` | `mcp_list_servers()`와 중복 | `mcp.list_servers()` |
| 7 | `scheduler_rate_remaining()` | 1곳 사용, `scheduler_stats()`에 포함 | `infra.scheduler_stats().rate_remaining` |
| 8 | `schedule()` | `add_cron_job()`과 중복 | `infra.add_cron(CronJob::new(...))` |
| 9 | `unschedule()` | `remove_cron`으로 통일 | `infra.remove_cron(id)` |
| 10 | `list_schedules()` | 크론 목록은 `get_cron` + 순회로 대체 | 크론 라우트에서 `list_schedules()` 추가 시 별도 구현 |
| 11 | `get_or_create_permissions()` | 혼합 read/write 의미 | `security.ensure_permissions()`로 명확화 |
| 12 | `overload_threshold()` | `is_overloaded()`로 충분 | `infra.is_overloaded()` |
| 13 | `start_time()` 메서드 | `uptime()`으로 충분 | `infra.uptime()` |
| 14 | `flush_audit()` (SecurityApi) | Git 커밋과 연동 필요 | KernelHandle 편의 메서드로 이동 |
| 15 | `save_and_commit()` (StateApi) | Git 커밋과 연동 필요 | KernelHandle 편의 메서드로 이동 |
| 16 | `save_markdown_and_commit()` | 동일 | KernelHandle 편의 메서드로 이동 |

---

## 9. 메서드 분류별 통계

```
┌────────────────┬──────────┬──────────────────────────────┐
│ Facade         │ 메서드 수 │ 서브시스템                    │
├────────────────┼──────────┼──────────────────────────────┤
│ StateApi       │    15    │ StateStore                    │
│ AgentApi       │    11    │ Supervisor, Budget, Memory    │
│ SecurityApi    │    15    │ Auth, AuditTrail, AccessMgr   │
│ PersonaApi     │     9    │ PersonaManager                │
│ ExtensionApi   │    12    │ Program, Skill, HostTools     │
│ McpApi         │     8    │ McpBridge                     │
│ InfraApi       │    22    │ Git, Scheduler, Cron,         │
│                │          │ Resource, EventBus, Config    │
├────────────────┼──────────┼──────────────────────────────┤
│ Facade 계      │    92    │                               │
│ KernelHandle   │     4    │ 편의 메서드                   │
│ 편의           │          │ (save_and_commit 등)          │
├────────────────┼──────────┼──────────────────────────────┤
│ Total          │    96    │ 기존 101 → 96                │
└────────────────┴──────────┴──────────────────────────────┘
```

---

## 10. 호출부 변경 예시

### Web Route Handler (88곳)

```rust
// ── agents/list ──────────────────────────────────────────
// Before:  state.kernel.list_agents().await
// After:   state.kernel.agents.list().await

// ── budget/get ───────────────────────────────────────────
// Before:  state.kernel.check_budget(&aid)
// After:   state.kernel.agents.check_budget(&aid)

// ── audit/entries ────────────────────────────────────────
// Before:  state.kernel.query_audit(from_seq, to_seq)
// After:   state.kernel.security.query_audit(from_seq, to_seq)

// ── git/log ──────────────────────────────────────────────
// Before:  state.kernel.git_log(100)
// After:   state.kernel.infra.git_log(100)

// ── personas/list ────────────────────────────────────────
// Before:  state.kernel.list_personas()
// After:   state.kernel.persona.list()

// ── programs/list ────────────────────────────────────────
// Before:  state.kernel.list_programs().await
// After:   state.kernel.extensions.list_programs().await

// ── mcp/list_tools ───────────────────────────────────────
// Before:  state.kernel.mcp_list_tools().await
// After:   state.kernel.mcp.list_tools().await

// ── cron/list ────────────────────────────────────────────
// Before:  state.kernel.list_schedules()
// After:   state.kernel.infra.list_crons()  (또는 별도 쿼리)

// ── chat/stream (session) ────────────────────────────────
// Before:  state.kernel.load_session(&session_id).await
// After:   state.kernel.state.load_session(&session_id).await

// ── chat (auth) ──────────────────────────────────────────
// Before:  state.kernel.validate_token(token)
// After:   state.kernel.security.validate_token(token)
```

### CLI (main.rs, 7곳)

```rust
// Before:  kernel.handle().query_audit(0, 20)
// After:   kernel.handle().security.query_audit(0, 20)

// Before:  kernel.handle().check_budget(&uuid)
// After:   kernel.handle().agents.check_budget(&uuid)

// Before:  kernel.handle().git_log(limit)?
// After:   kernel.handle().infra.git_log(limit)?
```

### Guardian Daemon (src/kernel.rs, 8곳)

```rust
// Before:  handle.verify_audit()
// After:   handle.security.verify_chain()

// Before:  handle.is_overloaded()
// After:   handle.infra.is_overloaded()

// Before:  handle.resource_snapshot()
// After:   handle.infra.resource_snapshot()

// Before:  handle.git_verify()
// After:   handle.infra.git_verify()

// Before:  handle.commit_all("guardian: checkpoint")
// After:   handle.save_and_commit(...) / handle.state.commit_all(&handle.infra.git(), "...")
//       또는 KernelHandle 편의 메서드: handle.commit_all("guardian: checkpoint")
```

---

## 11. 마이그레이션 계획

### Phase 1: 디렉토리 생성 + 위임 (기계적, 컴파일 가능 상태 유지)

1. `kernel_handle.rs``kernel_handle/mod.rs` 로 이름 변경
2. 7개 Facade 파일 생성 (각 메서드를 기존 `self.xxx`에서 `self.<subsystem>.xxx`로 위임)
3. 기존 KernelHandle의 모든 메서드를 `#[deprecated]`로 표시하고 Facade에 위임
4. `cargo build` 성공 확인

```
// 예: 위임 패턴
impl KernelHandle {
    #[deprecated(note = "use handle.agents.list()")]
    pub async fn list_agents(&self) -> Result<Vec<AgentInfo>> {
        self.agents.list().await
    }
}
```

### Phase 2: Web routes 업데이트

1. `channels/oxios-web/src/routes/*.rs` (88곳) 일괄 변경
2. `channels/oxios-web/src/persona_routes.rs` (12곳) 일괄 변경
3. `channels/oxios-web/src/middleware.rs` (1곳) 변경
4. 컴파일 에러 + `#[deprecated]` 경고로 누락 파악

### Phase 3: CLI + Guardian 업데이트

1. `src/main.rs` (7곳) 변경
2. `src/kernel.rs` Guardian (8곳) 변경
3. `#[deprecated]` 메서드 제거

### Phase 4: 이름 정리

1. 접두사 제거 (`list_agents``list`, `mcp_list_servers``list_servers`)
2. 명확화 (`verify_audit``verify_chain`)

### Phase 5: 정리

1. 사용되지 않는 메서드 제거
2. `#[warn(dead_code)]` 확인
3. 문서 업데이트

---

## 12. 테스트 전략

### Facade 독립 테스트

```rust
#[cfg(test)]
mod tests {
    // StateApi: 임시 디렉토리로 StateStore 생성
    fn test_state_api() {
        let dir = tempfile::tempdir().unwrap();
        let state = StateApi {
            state_store: Arc::new(StateStore::new(dir.path().to_path_buf()).unwrap()),
        };
        // save → load → delete 사이클 테스트
    }

    // AgentApi: Mock Supervisor 주입
    fn test_agent_api() {
        let agents = AgentApi {
            supervisor: Arc::new(MockSupervisor::new()),
            budget_manager: Arc::new(BudgetManager::new()),
            memory_manager: Arc::new(MemoryManager::new(state_store)),
        };
        // list → check_budget → kill 테스트
    }

    // SecurityApi: 인메모리 AuthManager
    fn test_security_api() {
        let security = SecurityApi {
            auth_manager: Arc::new(Mutex::new(AuthManager::new())),
            audit_trail: Arc::new(AuditTrail::new(100)),
            access_manager: Arc::new(Mutex::new(AccessManager::new())),
        };
        // validate_token → audit → verify_chain 테스트
    }
}
```

### 통합 테스트

```rust
#[test]
fn test_kernel_handle_facade_composition() {
    let handle = create_test_kernel_handle();
    
    // Facade 간 독립성: 각 Facade의 메서드가 정상 동작
    assert!(handle.agents.list().await.is_ok());
    assert!(handle.security.validate_token("invalid") == false);
    assert!(handle.persona.list().is_empty());
    
    // KernelHandle 편의 메서드: State + Infra 연동
    handle.save_and_commit("test", "key", &serde_json::json!({"v": 1})).await.unwrap();
    let log = handle.infra.git_log(10).unwrap();
    assert!(log.len() > 0);
}
```

---

## 13. 리스크와 대응

| 리스크 | 영향 | 대응 |
|--------|------|------|
| Arc 공유 교차 | 없음 (v2에서 모든 Arc가 정확히 1개 Facade에만 속함) | 해당 없음 |
| InfraApi 22개 메서드로 가장 큼 | 발견성 약간 저하 | 하위 도메인별로 메서드가 명확히 구분됨 (Git/스케줄러/크론/리소스/이벤트/시스템). 추후 분리 필요시 CronApi 등으로 분리 가능 |
| KernelHandle 편의 메서드가 Facade 간 결합 생성 | State ↔ Infra 연동 명시적 | 4개뿐이고, 결합이 명시적이라 관리 가능 |
| 기존 API 호환성 깨짐 | 103곳 호출부 수정 필요 | `#[deprecated]` + Phase별 점진적 마이그레이션 |

---

## 14. v1→v2 변경 요약

| 항목 | v1 | v2 (본 문서) |
|------|----|----|
| Facade 수 | 5개 | 7개 (Persona, Mcp 분리) |
| 최대 Facade 크기 | 25개 (ExtensionApi) | 22개 (InfraApi) |
| Arc 교차 소유 | 1개 (git_layer) | 0개 |
| `new()` 파라미터 | 19개 서브시스템 | 7개 Facade |
| 크론 중복 | schedule/unschedule + add_cron/remove_cron | add_cron/remove_cron으로 통일 |
| 제거 메서드 | "15개" (명시 안 됨) | 16개 (구체적 목록) |
| 편의 메서드 | 없음 | 4개 (save_and_commit 등) |

---

## 15. 결론

이 설계는:
- **Micro-kernel이 아님** — 같은 프로세스, Arc 공유
- **God Object 해소** — 7개 Facade로 책임 분산, 최대 22개 메서드
- **Arc 교차 소유 제거** — 모든 서브시스템이 정확히 하나의 Facade에 속함
- **Rust 친화적** — 타입 안전, Arc 소유권, zero-cost
- **테스트 가능** — 각 Facade 독립 생성/테스트
- **실용적**`#[deprecated]`로 점진적 마이그레이션, 컴파일 에러로 검증