Is your feature request related to a problem? Please describe.
When the AI rule-authoring assistant generates custom-framework rules (a Dubbo provider project in this case), it discriminates between class-context and method-context evaluation with Groovy meta-programming instead of the built-in discriminator:
// from the generated custom.method.is.api / custom.http.method / custom.path rules
def isMethod = !it.respondsTo('containingClass').isEmpty()
if (!isMethod) {
return it.hasAnn('org.apache.dubbo.config.annotation.DubboService')
// ...
}
The rules work at runtime — Groovy MOP respondsTo('containingClass') returns a non-empty list on method contexts and an empty list on class contexts — but the pattern is non-idiomatic and fragile: it encodes the implicit assumption "only method contexts expose containingClass()" rather than asking the context what it is.
Root cause (traced in source): the official discriminator exists but is invisible to the model.
ScriptItContext.contextType() returns "class" / "method" / "field" / "param", and built-in extension config already relies on it (jackson.config: if(it.contextType()!="field")).
RuleScriptContextCatalog.objectApi() reflects context methods into ScriptMethodApi, which carries only name/returns/parameters — no description. So the model sees a bare contextType(): String signature buried among 100+ methods in a ~32KB JSON payload.
- The agent system prompt (
agent-base.md) documents containingClass() / defineClass() in detail with examples — but never mentions contextType(). Neither do the knowledge-base docs.
- No agent tool surfaces built-in extension scripts (e.g.
jackson.config) as working examples.
- Meanwhile
get_rule_context reports itKinds = [METHOD, CLASS] for custom.method.is.api / custom.http.method / custom.path, with the binding description "Its concrete type depends on this rule key" — the contract requires the model to discriminate the context kind but never says how.
RuleProposalValidator has no warning for respondsTo( usage.
So when the model must answer "is it a class or a method right now?", it combines the most salient method-only API in its context (containingClass()) with the Groovy MOP idiom from its training data. Notably, this happens even when the agent follows the recommended workflow — the logs show it called get_rule_context for all three keys before proposing.
Describe the solution you'd like
- Highest value / one-line change: in
RuleScriptContextCatalog, when a key's itKinds contains more than one kind, make the it binding description state the discriminator explicitly — e.g. "Discriminate with it.contextType() — returns 'class'/'method'/'field'/'param'."
- Document
contextType() in the agent-base.md "Class identity in Groovy is context-sensitive" section.
- Add a soft warning in
RuleProposalValidator when a proposal uses respondsTo(, suggesting contextType().
- Longer term: give
ScriptMethodApi a description field (or a curated override for key methods), and/or expose built-in extension scripts as few-shot examples via an agent tool.
Describe alternatives you've considered
- Do nothing: generated rules are functionally correct today, but the
respondsTo heuristic breaks silently if a class context ever grows a method named containingClass(), and the generated files are harder for users to read and maintain.
- Hard-reject
respondsTo( in the validator: too strict while nothing teaches the model the alternative.
Additional context
- Reproduction: run the AI rule assistant against a project whose framework is not built-in (custom
class.is.api / method.is.api / path rules requiring class-vs-method discrimination).
- Verified on current main (v3.0 rewrite); the generated rules were functionally correct — the issue is the idiom/robustness of AI output, not a runtime failure.
Is your feature request related to a problem? Please describe.
When the AI rule-authoring assistant generates custom-framework rules (a Dubbo provider project in this case), it discriminates between class-context and method-context evaluation with Groovy meta-programming instead of the built-in discriminator:
The rules work at runtime — Groovy MOP
respondsTo('containingClass')returns a non-empty list on method contexts and an empty list on class contexts — but the pattern is non-idiomatic and fragile: it encodes the implicit assumption "only method contexts exposecontainingClass()" rather than asking the context what it is.Root cause (traced in source): the official discriminator exists but is invisible to the model.
ScriptItContext.contextType()returns"class"/"method"/"field"/"param", and built-in extension config already relies on it (jackson.config:if(it.contextType()!="field")).RuleScriptContextCatalog.objectApi()reflects context methods intoScriptMethodApi, which carries onlyname/returns/parameters— no description. So the model sees a barecontextType(): Stringsignature buried among 100+ methods in a ~32KB JSON payload.agent-base.md) documentscontainingClass()/defineClass()in detail with examples — but never mentionscontextType(). Neither do the knowledge-base docs.jackson.config) as working examples.get_rule_contextreportsitKinds = [METHOD, CLASS]forcustom.method.is.api/custom.http.method/custom.path, with the binding description "Its concrete type depends on this rule key" — the contract requires the model to discriminate the context kind but never says how.RuleProposalValidatorhas no warning forrespondsTo(usage.So when the model must answer "is
ita class or a method right now?", it combines the most salient method-only API in its context (containingClass()) with the Groovy MOP idiom from its training data. Notably, this happens even when the agent follows the recommended workflow — the logs show it calledget_rule_contextfor all three keys before proposing.Describe the solution you'd like
RuleScriptContextCatalog, when a key'sitKindscontains more than one kind, make theitbinding description state the discriminator explicitly — e.g. "Discriminate withit.contextType()— returns 'class'/'method'/'field'/'param'."contextType()in theagent-base.md"Class identity in Groovy is context-sensitive" section.RuleProposalValidatorwhen a proposal usesrespondsTo(, suggestingcontextType().ScriptMethodApiadescriptionfield (or a curated override for key methods), and/or expose built-in extension scripts as few-shot examples via an agent tool.Describe alternatives you've considered
respondsToheuristic breaks silently if a class context ever grows a method namedcontainingClass(), and the generated files are harder for users to read and maintain.respondsTo(in the validator: too strict while nothing teaches the model the alternative.Additional context
class.is.api/method.is.api/pathrules requiring class-vs-method discrimination).