feat(code-assessment): add AEM as a Cloud Service code-quality skill#170
feat(code-assessment): add AEM as a Cloud Service code-quality skill#170mandeep294 wants to merge 2 commits into
Conversation
A self-contained, local-only skill that detects and fixes AEM as a Cloud
Service code-quality issues — no external services or network calls.
Structure:
- SKILL.md — control plane: routing, classification, scope & limitations.
- references/runbook.md — the shared run procedure (preflight → resolve/
discover → plan → confirm → apply → verify), git or in-place edit modes,
report-vs-apply intent, and a structured run log.
- references/ — git-workflow (branch lifecycle + run-log schema),
shared-principles (design rationale), troubleshooting, the pattern catalog,
an authoring _template, and a reserved scripts/ home for future
deterministic detection.
- Per-pattern "expert skills" (self-contained subdirectories):
* inject-in-sling-model — migrate @Inject in @model classes to
injector-specific annotations (@ValueMapValue / @OSGiService /
@SlingObject), with per-field optional handling.
* outdated-dependencies — bump stale Maven versions (user-supplied targets).
- patterns.md catalogs 9 further high-value patterns as `planned`, drawn from
our CSO outage analysis and ordered by remediation value.
Design: detection and remediation are separable through a stable findings
shape; LLM scan today with a reserved deterministic-analyzer path; warn-don't-
gate pre-checks; surgical edits only; one pattern per apply session; the skill
never commits, pushes, or opens a PR — the customer reviews the diff.
Also adds a "Code Assessment" entry to the repo skill index (README.md).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
122f4da to
e076017
Compare
rombert
left a comment
There was a problem hiding this comment.
Thanks for the PR @mandeep294 . I think this generally goes in the right direction:
- single entry point for code assessment
- 'pluggable' recipes/patterns to fix
What I am still debating in my head is what to do with wide-reaching topics that already have (or are going to have) their own specialised skill, like workflow. We will want to run code assessments for these domains as well.
I am sort of leaning towards saying that we need a contract to be implemented for sub-skills, e.g.
aem-workflow/
workflow-debugging/
workflow-assessment/ [new]
where the aem-workflow would implement the contract (similar to each recipe in your PR) and the code-assessment workflow would reach out to the sub-skill of aem-workflow.
What is your take on that?
Can you also share some prompts that you used for testing? I am curious if you tried prompts that should hit individual recipes, e.g. Check that my Sling Models are implemented correcty. I am not sure if sub-skills are registered automatically and the prompt in the router skill (code-assessment) can't be relied on to expose all recipes.
As a low-level nitpick, there are several occurences of 'customer' which I think is not the ideal term for the coding agent to understand. Perhaps 'developer'?
…ce, multi-detector)
Add the Tier-1 detection engine for the AEM Cloud Service code-assessment skill:
a zero-install (JDK-only) analyzer that parses the workspace once and runs all
registered detectors over the shared parse. Replaces LLM-scan discovery as the
primary detection path; remediation stays recipe-driven.
Engine
- analyze.sh: compile-cache wrapper — hashes analyzer/ sources, compiles once to
a temp cache, reuses on subsequent runs; exit codes 0/2/3/4/5.
- analyzer/ package: Corpus (parse once, shared), Detector interface with
needsJava()/needsPoms() gating, JavaUnit/PomUnit, Registry, Finding.
- JDK Tree API (parse-level only): no symbol resolution, no classpath, no network.
- pom.xml DOM parsing hardened against XXE (secure processing, no doctype/external
entities).
- Findings emitted as {pattern,file,line,snippet} JSON to stdout AND
<root>/.autofix/analyzer-output.json (self-ignored via .autofix/.gitignore).
Detectors
- inject-in-sling-model: import-aware @model + field @Inject (javax + jakarta).
- outdated-dependencies: locate versioned pom <dependency> blocks (dependencies +
dependencyManagement); skip plugin/management/inherited/reactor-self-ref versions
(${project.version}, ${revision}, ...). Scoped to an extensible allowlist
(aem-sdk-api, org.mockito:*); --all lists every versioned dependency.
Tests + docs
- run-tests.sh: dependency-free harness, 51 assertions over 20 fixtures, incl. a
[wiring] invariant binding detector.pattern() == expert-skill dir == ready+analyzer
catalog row == Manual Pattern Hints row.
- adding-a-pattern.md: single end-to-end SOP for adding a new pattern.
- SKILL.md / runbook / patterns / shared-principles / expert skills / scripts README
updated: analyzer-driven discovery, JDK preflight, anti-substitution guardrails,
report count invariant, abstracted internals so triggering scales without
description edits.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0c18361 to
54accf2
Compare
What
Adds
code-assessment— a self-contained, local-only AEM as a Cloud Service code-quality skill. It detects and fixes code-quality issues entirely against the workspace. Name the files to fix, or ask it to scan the repo; it plans, applies surgical edits (git branch or in-place), and verifies withmvn compile.Detection for the production-ready patterns is performed by a deterministic local analyzer rather than an LLM scan — the same finding can no longer drift run-to-run.
Fixing recipe is provided by Expert skills.
Structure
SKILL.md— control plane: routing, classification, scope & limitations.references/runbook.md— the shared run procedure (preflight → resolve/discover → plan → confirm → apply → verify); git vs in-place edit modes; report-vs-apply intent; structured run log.references/—git-workflow.md(branch lifecycle + run-log schema),shared-principles.md(design rationale),troubleshooting.md,patterns.md(the pattern catalog),_template.md(authoring standard).scripts/— the deterministic analyzer:analyze.sh— compile-cache + run wrapper. Requires a JDK (javac/java); compiles the analyzer once into a temp cache keyed by source hash and writes nothing to the project tree.analyzer/— a parse-onceCorpus(PomUnit/JavaUnit) fed to a multi-detectorRegistry. Each detector emits a stableFinding({pattern, file, line, snippet}). Detection is parse-level only: no network lookups, no classpath or symbol resolution.test/— 14 fixtures driven by a 51-case harness (run-tests.sh).adding-a-pattern.md— how to add a detector + keep the wiring invariant.inject-in-sling-model— migrate@Injectin@Modelclasses to injector-specific annotations (@ValueMapValue/@OSGiService/@SlingObject), with per-field optional handling. Detection:analyzer.outdated-dependencies— bump stale Maven versions (user-supplied targets); literal<version>and same-pom${property}shapes. Detection:analyzer, scoped by default to a curated allowlist of actionable AEM CS coordinates (aem-sdk-api,org.mockito:*);--allfor an explicit full audit.patterns.mdcatalogs 9 further high-value patterns asplanned(LLMscandetection until a detector is built), drawn from CSO outage analysis and ordered by remediation value.Design
Findingshape — a pattern's detection method can be upgraded (LLMscan→ deterministicanalyzer) without touching its recipe. Both ready patterns have made that transition.Validation
bash scripts/test/run-tests.sh→ 51/51 pass.npm run validatepasses for all skills.🤖 Generated with Claude Code