align-cli-webapp-reports
$
npx mdskill add microsoft/agentrc/align-cli-webapp-reportsYou are debugging consistency between two readiness report outputs for the **AgentRC** project:
SKILL.md
.github/skills/align-cli-webapp-reportsView on GitHub ↗
---
name: align-cli-webapp-reports
description: Compare CLI visual readiness report with local webapp report for a given repo, identify differences in checks/rendering/scoring, and fix them
disable-model-invocation: true
---
You are debugging consistency between two readiness report outputs for the **AgentRC** project:
1. **CLI visual report** — generated by `npm run dev -- readiness --visual` from the repo root (produces an HTML file)
2. **Webapp report** — rendered by the local dev server at `http://localhost:3000/{owner}/{repo}`
Both should produce identical results for the same repository because they share the same core engine (`packages/core/src/services/readiness.ts`). In practice they can diverge due to rendering differences or scoring logic bugs.
## Architecture Reference
### Shared Core (source of truth for checks)
- `packages/core/src/services/readiness.ts` — All criteria definitions, `countStatus()`, `buildCriteria()`, `buildExtras()`, pillar/level aggregation
- Criteria scopes: `repo` (always), `app` (per-application), `area` (only with `--per-area`)
- `countStatus()` **excludes** skipped checks from the denominator when computing pillar pass/total
- Extras (bonus checks) are **not scored** — they don't affect levels or totals
### CLI Rendering
- `packages/core/src/services/visualReport.ts` — Generates the standalone HTML report
- `calculateAiToolingData()` — Aggregates AI criteria across repos (counts all including skipped in the hero display)
- Total checks: `report.pillars.reduce((s, p) => s + p.total, 0)`
- Does **not** render bonus/extras section in HTML output
### Webapp Backend
- `webapp/backend/src/services/scanner.js` — Clones repo, calls `runReadinessReport()` from `@agentrc/core`
- `webapp/backend/src/routes/scan.js` — `POST /api/scan` endpoint
- Returns the raw `ReadinessReport` JSON (same shape as CLI)
- Uses `@agentrc/core` as a `file:../../packages/core` dependency — always uses local source code
### Webapp Frontend
- `webapp/frontend/src/report.js` — Independent rendering implementation (NOT shared with CLI)
- `buildHero()` — Total from `report.pillars.reduce((s, p) => s + p.total, 0)`
- `buildAiToolingHero()` — Renders all AI criteria (including skipped) with pass/total count
- `buildPillarDetails()` — Shows per-pillar expandable cards
- **Does** render bonus checks section (unlike CLI)
- Has Service Information section (policy chain, engine signals) — CLI doesn't
### Known Inconsistency Patterns
- **AI Hero vs Pillar scoring**: Both implementations count skipped checks as non-passing in the AI Hero but exclude them from pillar denominator via `countStatus()`
- **Rendering gaps**: Webapp shows bonus checks + service info; CLI doesn't
- **Icon mapping**: CLI uses HTML entities via `getAiCriterionIcon()`; webapp uses emoji via `AI_ICONS` map — new criteria IDs may get fallback icon (`🔧`) in webapp
## Step-by-Step Procedure
### Phase 0: Start Local Webapp
1. Start the webapp backend dev server (from the repo root):
```
cd webapp/backend && npm run dev
```
This starts the Express server at `http://localhost:3000` with the local `@agentrc/core` source.
2. Optionally serve the frontend for full visual testing:
```
cd webapp/frontend && npx vite --port 5173
```
### Phase 1: Generate Both Reports
3. Run the CLI against the target repo to produce the visual HTML report:
```
npm run dev -- readiness --visual --repo {owner}/{repo}
```
Save the output HTML (typically `readiness-report.html`).
4. Hit the local webapp API to get the raw JSON:
```
POST http://localhost:3000/api/scan
Body: {"repo_url":"https://github.com/{owner}/{repo}"}
```
Example with PowerShell:
```powershell
$response = Invoke-RestMethod -Uri "http://localhost:3000/api/scan" -Method POST -ContentType "application/json" -Body '{"repo_url":"https://github.com/{owner}/{repo}"}' -TimeoutSec 120
```
5. Also open the local webapp page for visual comparison: `http://localhost:5173/{owner}/{repo}` (if frontend dev server is running) or `http://localhost:3000/{owner}/{repo}` (if backend serves static files).
### Phase 2: Compare Data Layer
6. Extract from CLI HTML: total checks, per-pillar passed/total, AI hero passed/total/percentage, criteria list with statuses, achieved level, fix-first items.
7. Extract from webapp JSON: same fields. Use:
```powershell
$pillars = $response.pillars
$totalPassed = ($pillars | Measure-Object -Property passed -Sum).Sum
$totalChecks = ($pillars | Measure-Object -Property total -Sum).Sum
Write-Host "Total: $totalPassed of $totalChecks checks"
Write-Host "Criteria count: $($response.criteria.Count)"
```
8. Diff the two — check for:
- **Missing criteria** in either side (criteria list length mismatch)
- **Status mismatches** for the same criterion ID
- **Total check count** differences (pillar aggregation)
- **AI Tooling hero** percentage/label differences
- **Achieved level** and next-level calculation differences
- **Fix-first** list ordering differences
### Phase 3: Compare Rendering Layer
9. Compare how both renderers handle:
- Skipped checks display (icon, text, inclusion in totals)
- Bonus/extras section presence
- Pillar grouping (repo-health vs ai-setup)
- AI criterion icons for new/unknown IDs
- Score thresholds for labels (Excellent/Good/Fair/Getting Started/Not Started)
### Phase 4: Root Cause & Fix
10. For each difference found, classify as:
- **Rendering divergence** → Fix in either `visualReport.ts` (CLI) or `report.js` (webapp) to align
- **Scoring logic bug** → Fix in `readiness.ts` (core) which fixes both
- **Icon/label mapping gap** → Update the icon map in the affected renderer
11. Implement the fixes directly in the source files.
12. After fixing, restart the webapp dev server and re-run Phase 1-2 to verify alignment.
### Phase 5: Validate
13. Confirm both reports show identical:
- Total check count (e.g., "11 of 20")
- Per-pillar passed/total
- AI Tooling hero percentage and label
- Achieved maturity level
- Fix-first items (same set, same order)
14. Note any **acceptable differences** that are by-design (e.g., webapp shows bonus checks, CLI doesn't).
15. Run existing tests to ensure no regressions:
```
npm test
cd webapp/backend && npm test
```
## Output Format
Produce a comparison table:
| Aspect | CLI Value | Webapp Value | Match? | Root Cause | Fix |
| ------------ | --------- | ------------ | ------ | ---------- | --- |
| Total checks | X of Y | X of Z | ... | ... | ... |
| AI Hero % | ...% | ...% | ... | ... | ... |
| ... | ... | ... | ... | ... | ... |
Then implement the fixes and verify.