diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IDeathModule.cs b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IDeathModule.cs
new file mode 100644
index 00000000..10a758a8
--- /dev/null
+++ b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IDeathModule.cs
@@ -0,0 +1,16 @@
+using BaseGames.AI;
+
+namespace BaseGames.Enemies
+{
+ ///
+ /// 死亡层:单态终结(演出交给物理状态机)/ 单段死亡能力 / 两段演出(可带生成物)。
+ /// 骨架只挂一条 Global → EntryState 的 Died 事件边,链条内容全归本模块。
+ ///
+ public interface IDeathModule
+ {
+ void Build(BrainBuilder b);
+
+ /// 骨架全局死亡边指向的态。
+ string EntryState { get; }
+ }
+}
diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IDeathModule.cs.meta b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IDeathModule.cs.meta
new file mode 100644
index 00000000..449f7816
--- /dev/null
+++ b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IDeathModule.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ca95968c577c65244bfb6c5a9a908ef4
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IEngagementModule.cs b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IEngagementModule.cs
new file mode 100644
index 00000000..b2139d00
--- /dev/null
+++ b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IEngagementModule.cs
@@ -0,0 +1,31 @@
+using System;
+using BaseGames.AI;
+
+namespace BaseGames.Enemies
+{
+ ///
+ /// 交战层:发现玩家之后怎么打。骨架只认这四件事——从哪个态进、什么条件进、
+ /// 边标签是什么、内部怎么打。新增一种打法 = 新增一个实现,骨架与其他模块不受影响。
+ ///
+ /// CanEngage 归本模块所有是关键:像"冲锋冷却门"这种只对某一种打法有意义的条件,
+ /// 若留在骨架上就会变成骨架的开关字段,并与其他开关互相耦合。
+ ///
+ /// 实现注意:模块会经 [SerializeReference] 反序列化,构造函数不保证被调用。
+ /// 不要在构造函数里预计算缓存或做参数校验——缓存用惰性属性,校验放 Build()。
+ ///
+ public interface IEngagementModule
+ {
+ /// 声明交战态与脱战边。
+ /// 脱战后回到的未发现态,由骨架传入。
+ void Build(BrainBuilder b, string rest);
+
+ /// 骨架从未发现态 / 警觉态连过来的目标。
+ string EntryState { get; }
+
+ /// 进入交战的条件。惰性构建并缓存。
+ Func CanEngage { get; }
+
+ /// CanEngage 的可读标签(trace / 图导出用)。
+ string EngageLabel { get; }
+ }
+}
diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IEngagementModule.cs.meta b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IEngagementModule.cs.meta
new file mode 100644
index 00000000..c7640663
--- /dev/null
+++ b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IEngagementModule.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0941f7f7a28a5374fbfd2971bde2ef54
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IUnawareModule.cs b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IUnawareModule.cs
new file mode 100644
index 00000000..eda45fe4
--- /dev/null
+++ b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IUnawareModule.cs
@@ -0,0 +1,30 @@
+using System.Collections.Generic;
+using BaseGames.AI;
+
+namespace BaseGames.Enemies
+{
+ ///
+ /// 未发现层:玩家尚未被发现时的行为形状(单一站桩 / 单向降级 / 定时交替 …)。
+ ///
+ /// 刻意拆成两阶段:AiRuntime 按声明顺序评估条件边,若本模块的内部边(如巡逻计时)
+ /// 早于骨架的升级边声明,玩家进入追逐区那一帧若恰好计时到点,敌人会切去另一个待机态
+ /// 而不是扑上来。骨架的调用顺序固定为 Declare → 挂升级边 → Link。
+ ///
+ public interface IUnawareModule
+ {
+ /// 只声明状态与行为回调,不挂任何转换。
+ void Declare(BrainBuilder b);
+
+ /// 挂内部转换(如站立 ⇄ 巡逻的计时边)。没有内部边的模块留空实现。
+ void Link(BrainBuilder b);
+
+ /// 图入口(出生态)。
+ string Entry { get; }
+
+ /// 脱战 / 警觉丢失后回到的态。必须属于 States。
+ string Rest { get; }
+
+ /// 需要挂升级边的所有未发现态。
+ IReadOnlyList States { get; }
+ }
+}
diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IUnawareModule.cs.meta b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IUnawareModule.cs.meta
new file mode 100644
index 00000000..fa7be118
--- /dev/null
+++ b/Assets/_Game/Scripts/Enemies/AIBrain/Modules/IUnawareModule.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bad88c851589dbe4fa0efbb66331e399
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: