# Semantic Validation Matrix

> **Purpose:** Define all semantic validation checks and contract verification rules required before consolidation approval.
> These checks catch data integrity gaps and ensure downstream skills have complete information.

## 13 Semantic Checks (Per Module)

Execute these checks for each completed module:

```javascript
const semanticChecks = [
  { check: "permission-orpheline", severity: "WARNING" },
  { check: "uc-sans-fr", severity: "WARNING" },
  { check: "entity-sans-endpoint", severity: "WARNING" },
  { check: "uc-sans-scenario", severity: "WARNING" },
  { check: "role-sans-permissions", severity: "WARNING" },
  { check: "navigation-sans-traduction", severity: "ERROR" },
  { check: "lifecycle-terminal", severity: "WARNING" },
  { check: "schema-conformity", severity: "ERROR" },
  { check: "wireframe-coverage", severity: "ERROR" },
  { check: "entity-doublon", severity: "ERROR" },
  { check: "permission-fantome", severity: "ERROR" },
  { check: "dashboard-coverage", severity: "WARNING" },
  { check: "permission-uc-alignment", severity: "WARNING" }
];
```

**Blocking rule:** 0 ERROR → PASS, ≥1 ERROR → BLOCK (user must fix before proceeding)

## Contract Verification (Per Module)

Verify the data contract that downstream skills (`/business-analyse-handoff`, `/business-analyse-develop`) depend on.
These checks catch gaps that abstract semantic checks miss.

```javascript
for (const module of completedModules) {
  const ent = module.entities || [];
  const brs = ba-reader.readSection(module.code, "rules")?.rules || [];
  const ucs = ba-reader.readSection(module.code, "usecases")?.useCases || [];
  const perms = ba-reader.readSection(module.code, "permissions");

  // CHECK 1: BR-CALC must have formula (C13)
  for (const br of brs) {
    if (br.category === 'calculation' && !br.formula) {
      errors.push({module: module.code, check: "br-calc-sans-formula",
        details: `${br.id} is category:calculation but missing 'formula' field`});
    }
  }

  // CHECK 2: Computed attributes must have corresponding BR-CALC (C11)
  for (const entity of ent) {
    for (const attr of (entity.attributes || [])) {
      if (attr.computed === true) {
        const hasBRCalc = brs.some(br =>
          br.category === 'calculation' && (br.entities || []).includes(entity.name)
        );
        if (!hasBRCalc) {
          errors.push({module: module.code, check: "computed-sans-br-calc",
            details: `${entity.name}.${attr.name} is computed:true but no BR-CALC references ${entity.name}`});
        }
      }
    }
  }

  // CHECK 3: UC count minimum (C6)
  if (ucs.length < 4) {
    errors.push({module: module.code, check: "uc-count-critical",
      details: `Only ${ucs.length} use cases (minimum: 4)`});
  } else if (ucs.length < 6) {
    warnings.push({module: module.code, check: "uc-count-low",
      details: `Only ${ucs.length} use cases (recommended: >= 6)`});
  }

  // CHECK 4: Permission path count (C7)
  const permCount = perms?.permissionPaths?.length || 0;
  if (permCount < 5) {
    warnings.push({module: module.code, check: "permission-count-low",
      details: `Only ${permCount} permission paths (recommended: >= 5 — check for missing Export/Import)`});
  }

  // CHECK 5: Versioned attributes detection (C15)
  const sensitiveKeywords = ['salary', 'rate', 'grade', 'price', 'tarif'];
  for (const entity of ent) {
    for (const attr of (entity.attributes || [])) {
      if (sensitiveKeywords.some(k => attr.name.toLowerCase().includes(k))) {
        if (!entity.versionedAttributes?.length) {
          warnings.push({module: module.code, check: "missing-versioned-attributes",
            details: `${entity.name}.${attr.name} may need versioning but no versionedAttributes defined`});
        }
      }
    }
  }
}
```

## Execution Logic

```javascript
for (const module of completedModules) {
  for (const check of semanticChecks) {
    const result = executeSemanticCheck(module, check);
    if (result.status === "ERROR") {
      errors.push({module: module.code, check: check.check, details: result.details});
    } else if (result.status === "WARNING") {
      warnings.push({module: module.code, check: check.check, details: result.details});
    }
  }
}

// Blocking rule: 0 ERROR → PASS, ≥1 ERROR → BLOCK (ask user for each)
if (errors.length > 0) {
  BLOCKING_ERROR("Semantic validation failed");
  for (const error of errors) {
    ERROR(`  [${error.module}] ${error.check}: ${error.details}`);
  }
  STOP - User must fix before proceeding
}
```
