diff --git a/mirai-console/backend/mirai-console/src/command/CommandExecuteResult.kt b/mirai-console/backend/mirai-console/src/command/CommandExecuteResult.kt
index acb70caf5..bf9234215 100644
--- a/mirai-console/backend/mirai-console/src/command/CommandExecuteResult.kt
+++ b/mirai-console/backend/mirai-console/src/command/CommandExecuteResult.kt
@@ -21,7 +21,6 @@ import kotlin.contracts.contract
 /**
  * 指令的执行返回
  */
-@ExperimentalCommandDescriptors
 public sealed class CommandExecuteResult {
     /** 指令执行时发生的错误 (如果有) */
     public abstract val exception: Throwable?
@@ -127,7 +126,6 @@ public sealed class CommandExecuteResult {
         /** 解析的 [CommandCall] (如果匹配到) */
         public override val call: CommandCall,
         /** 尝试执行的指令 */
-        @ExperimentalCommandDescriptors
         public val failureReasons: List<UnmatchedCommandSignature>,
     ) : Failure() {
         /** 指令执行时发生的错误, 总是 `null` */
@@ -138,8 +136,7 @@ public sealed class CommandExecuteResult {
     }
 }
 
-@ExperimentalCommandDescriptors
-public class UnmatchedCommandSignature(
+public class UnmatchedCommandSignature @ExperimentalCommandDescriptors public constructor(
     public val signature: CommandSignature,
     public val failureReason: FailureReason,
 )
diff --git a/mirai-console/backend/mirai-console/src/command/descriptor/TypeVariant.kt b/mirai-console/backend/mirai-console/src/command/descriptor/TypeVariant.kt
index e7f3e15c8..fc0abd16e 100644
--- a/mirai-console/backend/mirai-console/src/command/descriptor/TypeVariant.kt
+++ b/mirai-console/backend/mirai-console/src/command/descriptor/TypeVariant.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2021 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -13,6 +13,7 @@ import net.mamoe.mirai.console.command.parse.CommandValueArgument
 import net.mamoe.mirai.console.internal.data.castOrNull
 import net.mamoe.mirai.console.internal.data.kClassQualifiedName
 import net.mamoe.mirai.message.data.*
+import net.mamoe.mirai.utils.NotStableForInheritance
 import kotlin.reflect.KType
 import kotlin.reflect.typeOf
 
@@ -30,7 +31,7 @@ import kotlin.reflect.typeOf
  *
  * @see CommandValueArgument.typeVariants
  */
-@ExperimentalCommandDescriptors
+@NotStableForInheritance
 public interface TypeVariant<out OutType> {
     /**
      * The reified type of [OutType]
@@ -43,25 +44,21 @@ public interface TypeVariant<out OutType> {
      * @see CommandValueArgument.value
      */
     public fun mapValue(valueArgument: Message): OutType
+}
 
-    public companion object {
-        /**
-         * Creates a [TypeVariant] with reified [OutType].
-         */
-        @OptIn(ExperimentalStdlibApi::class)
-        @JvmSynthetic
-        public inline operator fun <reified OutType> invoke(crossinline block: (valueParameter: Message) -> OutType): TypeVariant<OutType> {
-            return object : TypeVariant<OutType> {
-                override val outType: KType = typeOf<OutType>()
-                override fun mapValue(valueArgument: Message): OutType = block(valueArgument)
-            }
-        }
+/**
+ * Creates a [TypeVariant] with reified [OutType].
+ * @since 2.15
+ */
+public inline fun <reified OutType> TypeVariant(crossinline mapValue: (valueParameter: Message) -> OutType): TypeVariant<OutType> {
+    return object : TypeVariant<OutType> {
+        override val outType: KType = typeOf<OutType>()
+        override fun mapValue(valueArgument: Message): OutType = mapValue(valueArgument)
     }
 }
 
 @ExperimentalCommandDescriptors
 public object MessageContentTypeVariant : TypeVariant<MessageContent> {
-    @OptIn(ExperimentalStdlibApi::class)
     override val outType: KType = typeOf<MessageContent>()
     override fun mapValue(valueArgument: Message): MessageContent =
         valueArgument.castOrNull<MessageContent>()
@@ -70,14 +67,12 @@ public object MessageContentTypeVariant : TypeVariant<MessageContent> {
 
 @ExperimentalCommandDescriptors
 public object MessageChainTypeVariant : TypeVariant<MessageChain> {
-    @OptIn(ExperimentalStdlibApi::class)
     override val outType: KType = typeOf<MessageChain>()
     override fun mapValue(valueArgument: Message): MessageChain = valueArgument.toMessageChain()
 }
 
 @ExperimentalCommandDescriptors
 public object ContentStringTypeVariant : TypeVariant<String> {
-    @OptIn(ExperimentalStdlibApi::class)
     override val outType: KType = typeOf<String>()
     override fun mapValue(valueArgument: Message): String = valueArgument.content
 }
diff --git a/mirai-console/backend/mirai-console/src/command/parse/CommandCall.kt b/mirai-console/backend/mirai-console/src/command/parse/CommandCall.kt
index 57ea066f2..0ced0fd00 100644
--- a/mirai-console/backend/mirai-console/src/command/parse/CommandCall.kt
+++ b/mirai-console/backend/mirai-console/src/command/parse/CommandCall.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -18,6 +18,7 @@ import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
 import net.mamoe.mirai.console.command.resolve.CommandCallResolver
 import net.mamoe.mirai.console.command.resolve.ResolvedCommandCall
 import net.mamoe.mirai.message.data.MessageChain
+import net.mamoe.mirai.utils.NotStableForInheritance
 
 /**
  * Unresolved [CommandCall].
@@ -31,7 +32,7 @@ import net.mamoe.mirai.message.data.MessageChain
  *
  * @see ResolvedCommandCall
  */
-@ExperimentalCommandDescriptors
+@NotStableForInheritance
 public interface CommandCall {
     /**
      * The [CommandSender] responsible to this call.
diff --git a/mirai-console/backend/mirai-console/src/command/parse/CommandCallParser.kt b/mirai-console/backend/mirai-console/src/command/parse/CommandCallParser.kt
index 5389d677f..d870656f2 100644
--- a/mirai-console/backend/mirai-console/src/command/parse/CommandCallParser.kt
+++ b/mirai-console/backend/mirai-console/src/command/parse/CommandCallParser.kt
@@ -10,7 +10,6 @@
 package net.mamoe.mirai.console.command.parse
 
 import net.mamoe.mirai.console.command.CommandSender
-import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
 import net.mamoe.mirai.console.command.resolve.CommandCallResolver
 import net.mamoe.mirai.console.command.resolve.ResolvedCommandCall
 import net.mamoe.mirai.console.extensions.CommandCallParserProvider
@@ -18,18 +17,17 @@ import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
 import net.mamoe.mirai.message.data.MessageChain
 
 /**
- * Lexical and syntactical parser for transforming a [MessageChain] into [CommandCall]
+ * 负责将 [MessageChain] 解析为 [CommandCall].
  *
  * @see CommandCallResolver The call resolver for [CommandCall] to become [ResolvedCommandCall]
  * @see CommandCallParserProvider The extension point
  *
  * @see SpaceSeparatedCommandCallParser
  */
-@ExperimentalCommandDescriptors
 public interface CommandCallParser {
 
     /**
-     * Lexically and syntactically parse a [message] into [CommandCall], but performs nothing about resolving a call.
+     * 将 [message] 解析为 [CommandCall]
      *
      * @return `null` if unable to parse (i.e. due to syntax errors).
      */
diff --git a/mirai-console/backend/mirai-console/src/command/parse/CommandValueArgument.kt b/mirai-console/backend/mirai-console/src/command/parse/CommandValueArgument.kt
index 64f1e09f8..86445b2e4 100644
--- a/mirai-console/backend/mirai-console/src/command/parse/CommandValueArgument.kt
+++ b/mirai-console/backend/mirai-console/src/command/parse/CommandValueArgument.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2021 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -14,11 +14,11 @@ package net.mamoe.mirai.console.command.parse
 import net.mamoe.mirai.console.command.descriptor.*
 import net.mamoe.mirai.console.internal.data.castOrInternalError
 import net.mamoe.mirai.console.internal.data.classifierAsKClass
-import net.mamoe.mirai.console.util.ConsoleExperimentalApi
 import net.mamoe.mirai.message.data.Message
 import net.mamoe.mirai.message.data.MessageChain
 import net.mamoe.mirai.message.data.MessageContent
 import net.mamoe.mirai.message.data.SingleMessage
+import net.mamoe.mirai.utils.NotStableForInheritance
 import kotlin.reflect.KType
 import kotlin.reflect.full.isSubtypeOf
 import kotlin.reflect.typeOf
@@ -27,20 +27,22 @@ import kotlin.reflect.typeOf
 /**
  * @see CommandValueArgument
  */
-@ExperimentalCommandDescriptors
-public interface CommandArgument
+@NotStableForInheritance
+public sealed interface CommandArgument
 
 /**
  * @see DefaultCommandValueArgument
  */
-@ExperimentalCommandDescriptors
-public interface CommandValueArgument : CommandArgument {
+@NotStableForInheritance
+public sealed interface CommandValueArgument : CommandArgument {
+    @ExperimentalCommandDescriptors
     public val type: KType
 
     /**
      * [MessageContent] if single argument
      * [MessageChain] is vararg
      */
+    @ExperimentalCommandDescriptors
     public val value: Message
 
     /**
@@ -54,12 +56,9 @@ public interface CommandValueArgument : CommandArgument {
 /**
  * The [CommandValueArgument] that doesn't vary in type (remaining [MessageContent]).
  */
-@ConsoleExperimentalApi
-@ExperimentalCommandDescriptors
 public data class DefaultCommandValueArgument(
     public override val value: Message,
 ) : CommandValueArgument {
-    @OptIn(ExperimentalStdlibApi::class)
     override val type: KType = typeOf<MessageContent>()
     override val typeVariants: List<TypeVariant<*>> = listOf(
         MessageContentTypeVariant,
@@ -124,7 +123,6 @@ private fun KType.createArray(size: Int): Array<Any?> {
 
 @OptIn(ExperimentalCommandDescriptors::class)
 private fun CommandValueArgument.mapToTypeOrNullImpl(expectingType: KType, value: Message): Any? {
-    @OptIn(ExperimentalStdlibApi::class)
     val result = typeVariants
         .filter { it.outType.isSubtypeOf(expectingType) }
         .ifEmpty {
diff --git a/mirai-console/backend/mirai-console/src/command/parse/SpaceSeparatedCommandCallParser.kt b/mirai-console/backend/mirai-console/src/command/parse/SpaceSeparatedCommandCallParser.kt
index 299fd8cd1..703621d79 100644
--- a/mirai-console/backend/mirai-console/src/command/parse/SpaceSeparatedCommandCallParser.kt
+++ b/mirai-console/backend/mirai-console/src/command/parse/SpaceSeparatedCommandCallParser.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -10,7 +10,6 @@
 package net.mamoe.mirai.console.command.parse
 
 import net.mamoe.mirai.console.command.CommandSender
-import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
 import net.mamoe.mirai.console.extensions.CommandCallParserProvider
 import net.mamoe.mirai.console.internal.command.flattenCommandComponents
 import net.mamoe.mirai.console.util.ConsoleExperimentalApi
@@ -19,12 +18,9 @@ import net.mamoe.mirai.message.data.MessageContent
 import net.mamoe.mirai.message.data.content
 
 @ConsoleExperimentalApi
-@ExperimentalCommandDescriptors
 public object SpaceSeparatedCommandCallParser : CommandCallParser {
 
-    @ConsoleExperimentalApi
-    @ExperimentalCommandDescriptors
-    public object Provider : CommandCallParserProvider {
+    internal object Provider : CommandCallParserProvider {
         override val instance: CommandCallParser get() = SpaceSeparatedCommandCallParser
         override val priority: Int get() = -1
     }
diff --git a/mirai-console/backend/mirai-console/src/command/resolve/CommandCallInterceptor.kt b/mirai-console/backend/mirai-console/src/command/resolve/CommandCallInterceptor.kt
index 4c2a534ff..7fe8d889f 100644
--- a/mirai-console/backend/mirai-console/src/command/resolve/CommandCallInterceptor.kt
+++ b/mirai-console/backend/mirai-console/src/command/resolve/CommandCallInterceptor.kt
@@ -7,21 +7,19 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-@file:Suppress("unused", "NOTHING_TO_INLINE")
+@file:Suppress("unused")
 
 package net.mamoe.mirai.console.command.resolve
 
-import kotlinx.serialization.Serializable
 import net.mamoe.mirai.console.command.CommandSender
 import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
 import net.mamoe.mirai.console.command.parse.CommandCall
 import net.mamoe.mirai.console.command.parse.CommandCallParser
 import net.mamoe.mirai.console.extensions.CommandCallInterceptorProvider
 import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
-import net.mamoe.mirai.console.internal.util.UNREACHABLE_CLAUSE
 import net.mamoe.mirai.console.util.safeCast
 import net.mamoe.mirai.message.data.Message
-import org.jetbrains.annotations.Contract
+import net.mamoe.mirai.utils.NotStableForInheritance
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
 
@@ -29,7 +27,6 @@ import kotlin.contracts.contract
 /**
  * 指令解析和调用拦截器. 用于在指令各解析阶段拦截或转换调用.
  */
-@ExperimentalCommandDescriptors
 public interface CommandCallInterceptor {
     /**
      * 在指令[语法解析][CommandCallParser]前调用.
@@ -70,9 +67,9 @@ public interface CommandCallInterceptor {
                 val intercepted = ext.instance.interceptBeforeCall(acc, caller)
                 intercepted?.fold(
                     onIntercepted = { return intercepted },
-                    otherwise = { it }
+                    onProceed = { it }
                 ) ?: acc
-            }.let { InterceptResult(it) }
+            }.let { InterceptResult.proceed(it) }
         }
 
         /**
@@ -85,9 +82,9 @@ public interface CommandCallInterceptor {
                 val intercepted = ext.instance.interceptCall(acc)
                 intercepted?.fold(
                     onIntercepted = { return intercepted },
-                    otherwise = { it }
+                    onProceed = { it }
                 ) ?: acc
-            }.let { InterceptResult(it) }
+            }.let { InterceptResult.proceed(it) }
         }
 
         /**
@@ -100,78 +97,95 @@ public interface CommandCallInterceptor {
                 val intercepted = ext.instance.interceptResolvedCall(acc)
                 intercepted?.fold(
                     onIntercepted = { return intercepted },
-                    otherwise = { it }
+                    onProceed = { it }
                 ) ?: acc
-            }.let { InterceptResult(it) }
+            }.let { InterceptResult.proceed(it) }
         }
     }
 }
 
+
 /**
  * [CommandCallInterceptor] 拦截结果
  */
-@ExperimentalCommandDescriptors
-public class InterceptResult<T> internal constructor(
-    private val _value: Any?,
-    @Suppress("UNUSED_PARAMETER") primaryConstructorMark: Any?,
+public class InterceptResult<T> private constructor(
+    @Suppress("PropertyName")
+    @PublishedApi
+    internal val _value: Any?,
 ) {
     /**
-     * 构造一个 [InterceptResult], 以 [value] 继续处理后续指令执行.
+     * 当未被拦截时返回未被拦截的值, 否则返回 `null`.
      */
-    public constructor(value: T) : this(value as Any?, null)
-
-    /**
-     * 构造一个 [InterceptResult], 以 [原因][reason] 中断指令执行.
-     */
-    public constructor(reason: InterceptedReason) : this(reason as Any?, null)
-
-    @get:Contract(pure = true)
     public val value: T?
-        @Suppress("UNCHECKED_CAST")
         get() {
             val value = this._value
+            @Suppress("UNCHECKED_CAST")
             return if (value is InterceptedReason) null else value as T
         }
 
-    @get:Contract(pure = true)
+    /**
+     * 获取拦截原因, 当未被拦截时返回 `null`.
+     */
     public val reason: InterceptedReason?
         get() = this._value.safeCast()
+
+    /**
+     * 当被拦截时返回 `true`, 否则返回 `false`.
+     * @since 2.15
+     */
+    public val isIntercepted: Boolean get() = _value is InterceptedReason
+
+    public companion object {
+        /**
+         * 构造一个 [InterceptResult], 以 [value] 继续处理后续指令执行.
+         */
+        @JvmStatic
+        @JvmName("proceed")
+        public fun <T> proceed(value: T): InterceptResult<T> = InterceptResult(value)
+
+        /**
+         * 构造一个 [InterceptResult], 以 [原因][reason] 中断指令执行.
+         */
+        @JvmStatic
+        @JvmName("intercepted")
+        public fun <T> intercepted(reason: InterceptedReason): InterceptResult<T> = InterceptResult(reason)
+    }
 }
 
-@ExperimentalCommandDescriptors
 public inline fun <T, R> InterceptResult<T>.fold(
     onIntercepted: (reason: InterceptedReason) -> R,
-    otherwise: (call: T) -> R,
+    onProceed: (call: T) -> R,
 ): R {
     contract {
         callsInPlace(onIntercepted, InvocationKind.AT_MOST_ONCE)
-        callsInPlace(otherwise, InvocationKind.AT_MOST_ONCE)
+        callsInPlace(onProceed, InvocationKind.AT_MOST_ONCE)
+    }
+    val value = _value
+    if (value is InterceptedReason) {
+        return onIntercepted(value)
+    } else {
+        @Suppress("UNCHECKED_CAST")
+        return onProceed(value as T)
     }
-    value?.let { return otherwise(it) }
-    reason?.let { return onIntercepted(it) }
-    UNREACHABLE_CLAUSE
-}
-
-@ExperimentalCommandDescriptors
-public inline fun <T : R, R> InterceptResult<T>.getOrElse(onIntercepted: (reason: InterceptedReason) -> R): R {
-    contract { callsInPlace(onIntercepted, InvocationKind.AT_MOST_ONCE) }
-    reason?.let(onIntercepted)
-    return value!!
 }
 
 /**
- * 创建一个 [InterceptedReason]
- *
- * @see InterceptedReason.create
+ * 当 [InterceptResult] 为未被拦截时, 返回值. 当为被拦截时, 计算并返回 [onIntercepted].
  */
-@ExperimentalCommandDescriptors
-@JvmSynthetic
-public inline fun InterceptedReason(message: String): InterceptedReason = InterceptedReason.create(message)
+public inline fun <T : R, R> InterceptResult<T>.getOrElse(onIntercepted: (reason: InterceptedReason) -> R): R {
+    contract { callsInPlace(onIntercepted, InvocationKind.AT_MOST_ONCE) }
+    val value = _value
+    if (value is InterceptedReason) {
+        return onIntercepted(value)
+    }
+    @Suppress("UNCHECKED_CAST")
+    return value as R
+}
 
 /**
  * 拦截原因
  */
-@ExperimentalCommandDescriptors
+@NotStableForInheritance
 public interface InterceptedReason {
     public val message: String
 
@@ -179,10 +193,10 @@ public interface InterceptedReason {
         /**
          * 创建一个 [InterceptedReason]
          */
-        public fun create(message: String): InterceptedReason = InterceptedReasonData(message)
+        @JvmStatic
+        public fun simple(message: String): InterceptedReason = InterceptedReasonData(message)
     }
 }
 
 @OptIn(ExperimentalCommandDescriptors::class)
-@Serializable
 private data class InterceptedReasonData(override val message: String) : InterceptedReason
diff --git a/mirai-console/backend/mirai-console/src/command/resolve/CommandCallResolver.kt b/mirai-console/backend/mirai-console/src/command/resolve/CommandCallResolver.kt
index 86465fc53..6d6749d4d 100644
--- a/mirai-console/backend/mirai-console/src/command/resolve/CommandCallResolver.kt
+++ b/mirai-console/backend/mirai-console/src/command/resolve/CommandCallResolver.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -14,7 +14,6 @@ import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
 import net.mamoe.mirai.console.command.parse.CommandCall
 import net.mamoe.mirai.console.extensions.CommandCallResolverProvider
 import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
-import net.mamoe.mirai.console.util.ConsoleExperimentalApi
 import net.mamoe.mirai.console.util.safeCast
 import org.jetbrains.annotations.Contract
 import kotlin.contracts.InvocationKind
@@ -67,14 +66,11 @@ public inline fun CommandResolveResult.getOrElse(
  * @see CommandCallResolverProvider The provider to instances of this class
  * @see BuiltInCommandCallResolver The builtin implementation
  */
-@ExperimentalCommandDescriptors
 public interface CommandCallResolver {
     public fun resolve(call: CommandCall): CommandResolveResult
 
     public companion object {
         @JvmName("resolveCall")
-        @ConsoleExperimentalApi
-        @ExperimentalCommandDescriptors
         public fun CommandCall.resolve(): CommandResolveResult {
             return GlobalComponentStorage.getExtensions(CommandCallResolverProvider).first()
                 .extension.instance
diff --git a/mirai-console/backend/mirai-console/src/command/resolve/ResolvedCommandCall.kt b/mirai-console/backend/mirai-console/src/command/resolve/ResolvedCommandCall.kt
index b494c817b..7f493e94f 100644
--- a/mirai-console/backend/mirai-console/src/command/resolve/ResolvedCommandCall.kt
+++ b/mirai-console/backend/mirai-console/src/command/resolve/ResolvedCommandCall.kt
@@ -31,7 +31,6 @@ import net.mamoe.mirai.message.data.MessageChain
  *
  * @see ResolvedCommandCallImpl
  */
-@ExperimentalCommandDescriptors
 public interface ResolvedCommandCall {
     /**
      * The [CommandSender] responsible to this call.
@@ -58,7 +57,7 @@ public interface ResolvedCommandCall {
      *
      * **Default implementation details**: Lazy calculation.
      */
-    @ConsoleExperimentalApi
+    @ExperimentalCommandDescriptors
     public val resolvedValueArguments: List<ResolvedCommandValueArgument<*>>
 
     /**
diff --git a/mirai-console/backend/mirai-console/src/extension/Extension.kt b/mirai-console/backend/mirai-console/src/extension/Extension.kt
index d46d63780..576fcba1e 100644
--- a/mirai-console/backend/mirai-console/src/extension/Extension.kt
+++ b/mirai-console/backend/mirai-console/src/extension/Extension.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -14,7 +14,6 @@ import net.mamoe.mirai.console.extensions.PermissionServiceProvider
 import net.mamoe.mirai.console.extensions.PluginLoaderProvider
 import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
 import net.mamoe.mirai.console.plugin.jvm.JvmPlugin.Companion.onLoad
-import net.mamoe.mirai.console.util.ConsoleExperimentalApi
 import net.mamoe.mirai.utils.DeprecatedSinceMirai
 
 /**
@@ -46,7 +45,6 @@ public interface Extension {
      *
      * @since 2.11
      */ // https://github.com/mamoe/mirai/issues/1860
-    @ConsoleExperimentalApi
     public val priority: Int
         get() = 0
 }
diff --git a/mirai-console/backend/mirai-console/src/extensions/CommandCallInterceptorProvider.kt b/mirai-console/backend/mirai-console/src/extensions/CommandCallInterceptorProvider.kt
index 5329d90a7..b3be90732 100644
--- a/mirai-console/backend/mirai-console/src/extensions/CommandCallInterceptorProvider.kt
+++ b/mirai-console/backend/mirai-console/src/extensions/CommandCallInterceptorProvider.kt
@@ -9,16 +9,14 @@
 
 package net.mamoe.mirai.console.extensions
 
-import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
 import net.mamoe.mirai.console.command.resolve.CommandCallInterceptor
 import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint
 import net.mamoe.mirai.console.extension.InstanceExtension
 import net.mamoe.mirai.console.util.ConsoleExperimentalApi
 
-@ExperimentalCommandDescriptors
 public interface CommandCallInterceptorProvider : InstanceExtension<CommandCallInterceptor> {
+
     @OptIn(ConsoleExperimentalApi::class)
-    @ExperimentalCommandDescriptors
     public companion object ExtensionPoint :
         AbstractInstanceExtensionPoint<CommandCallInterceptorProvider, CommandCallInterceptor>(
             CommandCallInterceptorProvider::class
diff --git a/mirai-console/backend/mirai-console/src/extensions/CommandCallParserProvider.kt b/mirai-console/backend/mirai-console/src/extensions/CommandCallParserProvider.kt
index defe9a7c0..61ce71285 100644
--- a/mirai-console/backend/mirai-console/src/extensions/CommandCallParserProvider.kt
+++ b/mirai-console/backend/mirai-console/src/extensions/CommandCallParserProvider.kt
@@ -9,7 +9,6 @@
 
 package net.mamoe.mirai.console.extensions
 
-import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
 import net.mamoe.mirai.console.command.parse.CommandCallParser
 import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint
 import net.mamoe.mirai.console.extension.InstanceExtension
@@ -18,10 +17,9 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalApi
 /**
  * The provider of [CommandCallParser]
  */
-@ExperimentalCommandDescriptors
 public interface CommandCallParserProvider : InstanceExtension<CommandCallParser> {
+
     @OptIn(ConsoleExperimentalApi::class)
-    @ExperimentalCommandDescriptors
     public companion object ExtensionPoint :
         AbstractInstanceExtensionPoint<CommandCallParserProvider, CommandCallParser>(CommandCallParserProvider::class)
 }