Summary
Rule::check(&self, &mut RuleContext<'_>) reports through RuleContext's report()/report_fixable() helpers, but ProjectRule::check(&self, skills: &[Skill], config: &Config, severity: Severity) -> Vec has no equivalent context object, so both UniqueName and DistinctDescriptions in project.rs hand-construct full Message struct literals (rule, severity, message, advice, location, source, file, fix, reference, confidence) inline, duplicating exactly the bookkeeping RuleContext exists to centralize.
Scope
- Severity (reporter's assessment): medium
- Area:
arch
- Code:
packages/core/src/rules/mod.rs:199-211, packages/core/src/rules/project.rs:41-135
- Reproduced empirically: yes
Minimal reproduction
Compare packages/core/src/rules/naming.rs:87-119 (context.report(format!(...), Location::at(line, 1)) — one line) against packages/core/src/rules/project.rs:69-81 (a 12-line Message { rule: UNIQUE_NAME.name.to_string(), severity, message: format!(...), advice: UNIQUE_NAME.advice.to_string(), location: ..., source: Source::Static, file: skill.document.clone(), fix: None, reference: UNIQUE_NAME.reference(), confidence: 1.0 } literal) for the same conceptual action of 'report one finding against one skill'.
Expected
A single reporting surface (e.g. a RuleContext variant that is either per-skill or per-project, or a shared MessageBuilder used by both trait's default methods) so a rule author writing a project rule gets the same ergonomics and cannot forget a field (e.g. confidence, source) that RuleContext::push already defaults correctly.
Sources
- Direct code comparison, no external source needed
Notes
Only two ProjectRule implementors exist today (UniqueName, DistinctDescriptions), so the duplication is small, but every future project rule repeats the same 10-field literal by hand.
Filed as part of a systematic pre-release audit. Triage and de-duplication pending.
Summary
Rule::check(&self, &mut RuleContext<'_>) reports through RuleContext's report()/report_fixable() helpers, but ProjectRule::check(&self, skills: &[Skill], config: &Config, severity: Severity) -> Vec has no equivalent context object, so both UniqueName and DistinctDescriptions in project.rs hand-construct full Message struct literals (rule, severity, message, advice, location, source, file, fix, reference, confidence) inline, duplicating exactly the bookkeeping RuleContext exists to centralize.
Scope
archpackages/core/src/rules/mod.rs:199-211,packages/core/src/rules/project.rs:41-135Minimal reproduction
Compare packages/core/src/rules/naming.rs:87-119 (
context.report(format!(...), Location::at(line, 1))— one line) against packages/core/src/rules/project.rs:69-81 (a 12-lineMessage { rule: UNIQUE_NAME.name.to_string(), severity, message: format!(...), advice: UNIQUE_NAME.advice.to_string(), location: ..., source: Source::Static, file: skill.document.clone(), fix: None, reference: UNIQUE_NAME.reference(), confidence: 1.0 }literal) for the same conceptual action of 'report one finding against one skill'.Expected
A single reporting surface (e.g. a RuleContext variant that is either per-skill or per-project, or a shared
MessageBuilderused by both trait's default methods) so a rule author writing a project rule gets the same ergonomics and cannot forget a field (e.g. confidence, source) that RuleContext::push already defaults correctly.Sources
Notes
Only two ProjectRule implementors exist today (UniqueName, DistinctDescriptions), so the duplication is small, but every future project rule repeats the same 10-field literal by hand.
Filed as part of a systematic pre-release audit. Triage and de-duplication pending.