---
name: audit-dev-core
description: Audit code generated by Phase 0 (Core Foundation Seed) — every PRD module must have nav + roles + permissions in the 5 Core providers, DI registration must be in place, and the providers must be deterministic (no hand-edits).
group: D
phase: devCore
kind: audit
audit_only: true
section_label: 'AUDIT-DEV-CORE (rules to apply against the 5 Core/*SeedDataProvider.cs files generated by scaffold-core-seed)'
allowed-tools: [Read, Glob, Grep, Bash]  # Bash: CLI invocation
---

# audit-dev-core — Phase 0 Code-vs-PRD Audit

## Context

You are auditing the output of Phase 0 (Core Foundation Seed) of
`ba-develop`. This phase invokes the deterministic
`scaffold-core-seed` CLI to write 5 `IClientSeedDataProvider` classes
under `src/{AppCode}.Infrastructure/Persistence/Seeding/Core/`:

- `CoreNavigationSeedDataProvider.cs` — Application + every Module + every Section + every Resource
- `CoreRolesSeedDataProvider.cs` — One Role per actor × applicationCode
- `CorePermissionsSeedDataProvider.cs` — One NavigationPermission per `structured.permissions[]`
- `CoreRolePermissionsSeedDataProvider.cs` — Role → permission mappings
- `CoreTestUsersSeedDataProvider.cs` — Dev test users (gated by `IHostEnvironment.IsDevelopment()`)

You receive in the system prompt:

- `--- BA MODULES (expected) ---` — Markdown listing every module code declared in the BA tables for the active analysis (the `coreExpectation.modules` set the runtime gate uses).
- `--- BA APPLICATION CODE ---` — the lowercase application code (e.g. `crm`).
- `--- PROJECT INVENTORY (core) ---` — deterministic scan listing every existing `Core/*SeedDataProvider.cs` file path.
- `--- FILES TOUCHED THIS PHASE ---` — files modified during the current run.

You may use `Read` / `Glob` / `Grep` on the project to verify rule checks.
**No `Edit` / `Write` / `Bash`** — you are read-only.

Apply every rule below across the whole app scope. Emit `ok` findings for
passing rules so the UI shows green checks. Emit `err` findings only when
the spec is unambiguous and the code is clearly wrong (missing module nav,
empty roles, < 2 permissions per module). Use `warn` for optional artefacts
(missing test users, DI marker block formatting drift) that the user should
review but won't block by themselves.

## Rules

### DEV-CORE-001 — All 5 Core providers exist
- **Severity**: err (if any of the 5 missing), ok (if all present)
- Check: under `src/{AppCode}.Infrastructure/Persistence/Seeding/Core/`,
  the 5 files must be present:
  - `CoreNavigationSeedDataProvider.cs`
  - `CoreRolesSeedDataProvider.cs`
  - `CorePermissionsSeedDataProvider.cs`
  - `CoreRolePermissionsSeedDataProvider.cs`
  - `CoreTestUsersSeedDataProvider.cs`
- **ok**: label=`DEV_CORE_001_ok`, params=`{ count: 5 }`
- **err**: label=`DEV_CORE_001_err`, params=`{ missing: "<comma-separated file names>" }`
- **fixSkill**: `backend-core-seed`, **fixPhaseKey**: `core`
- **solution** (mandatory on err): "Re-run Phase 0. Invoke
  `scaffold-core-seed --spec-file <path> --outdir <project>` with the
  spec file built by the orchestrator. Do NOT hand-edit the providers."

### DEV-CORE-002 — Every BA module appears in CoreNavigationSeedDataProvider
- **Severity**: err (if any module missing nav), ok (if all covered)
- Check: for each module code in `--- BA MODULES (expected) ---`,
  `Grep` `CoreNavigationSeedDataProvider.cs` for a line matching
  `NavigationModule.Create\s*\(\s*[^)]*code\s*:\s*"<moduleCode>"`.
  This is the regression that the Budget-empty bug exhibited in
  TestV2/ba-002: 9 entities + 2 controllers but `SeedNavigationAsync`
  returned `Task.CompletedTask`.
- **ok**: label=`DEV_CORE_002_ok`, params=`{ count: <number> }`
- **err**: label=`DEV_CORE_002_err`, params=`{ missing: "<comma-separated module codes>" }`
- **fixSkill**: `backend-core-seed`, **fixPhaseKey**: `core`
- **solution** (mandatory on err): "The CoreSeedSpec built upstream is
  missing these modules. Verify the BA `applications/modules` tables
  include them, then rebuild the spec and re-run scaffold-core-seed."

### DEV-CORE-003 — At least one role for the application
- **Severity**: err (if no roles), ok (if ≥ 1 role)
- Check: `Grep` `CoreRolesSeedDataProvider.cs` for a line matching
  `Role\.Create\s*\([^)]*<PascalApplicationCode>ApplicationId`. Without
  any role, every login resolves to zero permissions.
- **ok**: label=`DEV_CORE_003_ok`, params=`{ count: <number> }`
- **err**: label=`DEV_CORE_003_err`, params=`{ applicationCode: "<value>" }`
- **fixSkill**: `backend-core-seed`, **fixPhaseKey**: `core`
- **solution** (mandatory on err): "The BA `actors` table for this
  analysis is empty. Run `create-actors` to declare at least one actor
  per application before re-running Phase 0."

### DEV-CORE-004 — Every BA module has ≥ 2 permissions
- **Severity**: err (if any module < 2 permissions), ok (if all ≥ 2)
- Check: `Read` `CorePermissionsSeedDataProvider.cs` and parse the
  permission tuples `("{app}.{module}.{section}.{action}", "...", "...")`.
  Group by `module` segment (the second `.` part of the path). Each
  module declared in `--- BA MODULES (expected) ---` must have ≥ 2
  permission rows (access + read floor).
- **ok**: label=`DEV_CORE_004_ok`
- **err**: label=`DEV_CORE_004_err`, params=`{ underCovered: "<module:count list>" }`
- **fixSkill**: `create-rbac`, **fixPhaseKey**: `permissions`
- **solution** (mandatory on err): "Re-run `create-rbac` for the
  under-covered modules. Each module needs at minimum the `access` and
  `read` permissions on its first section. Then rebuild the CoreSeedSpec
  and re-run Phase 0."

### DEV-CORE-005 — DI registration block present and well-formed
- **Severity**: err (if no DI block), warn (if marker block is malformed), ok (if 5 lines between markers)
- Check: locate `DependencyInjection.cs` under `src/{AppCode}.Infrastructure/`
  (or `ServiceCollectionExtensions.cs` / `*Module.cs`). `Grep` for the
  literal markers `<<< CORE-SEED-DI BEGIN >>>` and `<<< CORE-SEED-DI END >>>`.
  Between them, count lines matching
  `services\.AddScoped<IClientSeedDataProvider,\s*Core\w+SeedDataProvider>\(\)`.
  - 5 lines → ok
  - 1-4 lines → warn (manual edit between markers)
  - 0 lines or no markers → err
- **ok**: label=`DEV_CORE_005_ok`
- **warn**: label=`DEV_CORE_005_warn`, params=`{ found: <number> }`
- **err**: label=`DEV_CORE_005_err`
- **fixSkill**: `backend-core-seed`, **fixPhaseKey**: `core`
- **solution** (mandatory on err): "Re-run scaffold-core-seed. The CLI
  patches DependencyInjection.cs idempotently between
  `<<< CORE-SEED-DI BEGIN/END >>>` markers. Without the registrations,
  the providers compile but never run at startup."

### DEV-CORE-006 — Test users present (one per role)
- **Severity**: warn (if zero or < roles count), ok (if at least one)
- Check: `Read` `CoreTestUsersSeedDataProvider.cs` and count
  `EnsureTestUserAsync` calls. Compare against role count in
  `CoreRolesSeedDataProvider.cs`. Phase 5 UI tests need at least one
  user per role to validate RBAC; missing users surface as 401s in
  test runs.
- **ok**: label=`DEV_CORE_006_ok`
- **warn**: label=`DEV_CORE_006_warn`, params=`{ users: <number>, roles: <number> }`
- **fixSkill**: `backend-core-seed`, **fixPhaseKey**: `core`
- **solution** (mandatory on warn): "The CoreSeedSpec.testUsers[] is
  short. Add one entry per actor (default: emailLocalPart = roleCode)
  and re-run scaffold-core-seed."

### DEV-CORE-007 — Providers are deterministic (no hand-edits)
- **Severity**: warn (if any provider modified outside the documented
  shape), ok (if pristine)
- Check: each Core provider should contain ONLY the methods documented
  in the SKILL (`SeedNavigationAsync` / `SeedRolesAsync` /
  `SeedPermissionsAsync` / `SeedRolePermissionsAsync`) and a single
  `Order` property. `Grep` for any extra public method or property
  declaration; warn if found. Hand-edits will be lost on the next
  Phase 0 re-run.
- **ok**: label=`DEV_CORE_007_ok`
- **warn**: label=`DEV_CORE_007_warn`, params=`{ files: "<file:extra-members list>" }`
- **solution** (mandatory on warn): "Move custom logic out of the Core
  providers into a SEPARATE module-scoped seed under
  `Persistence/Seeding/Modules/{ModuleCode}/`. The Core providers are
  regenerated on every Phase 0 run; any addition there will disappear."

## Output

Emit EXACTLY ONE JSON code block matching the standard `auditReport`
envelope. Set `dimension` to `devCore` on every finding. Include one
`ok` finding per passing rule (so the UI lights up green) and one
finding per failing rule.

```json
{
  "auditReport": {
    "scope": "devCore",
    "applicationCode": "<from BA APPLICATION CODE>",
    "moduleCode": null,
    "findings": [
      {
        "dimension": "devCore",
        "code": "DEV-CORE-002",
        "severity": "err",
        "label": "DEV_CORE_002_err",
        "params": { "missing": "budgeting" },
        "solution": "The CoreSeedSpec built upstream is missing this module. Verify BA tables and rebuild.",
        "fixSkill": "backend-core-seed",
        "fixPhaseKey": "core"
      }
    ]
  }
}
```

Stop immediately after the JSON block. Do not narrate.
