# SATE Audit Report v0

**Project:** `/home/amari/projects/maktabi_core`
**Generated:** 2026-05-23T16:39:17.563Z
**Schema:** 1 (SATE_AUDIT_REPORT_V0)

## Laravel Version Resolution
- **Resolved:** 11.51.0
- **Confidence:** HIGH
- **Authority Source:** RUNTIME
- **SATE Mode:** FULL_DETERMINISTIC

Per-source values:
  - declared: 11.31.0
  - locked: 11.51.0
  - installed: (none)
  - runtime: 11.51.0

**Drift findings:**
  - `LARAVEL_VERSION_DRIFT_DECLARED`: composer.json declares 11.31.0 but runtime reports 11.51.0 (declared constraint is looser than installed)

## Surface Enumeration
**Application surfaces** (what SATE audits):
- Total: 3281
- Proof-ready: 2815
- Blocked: 466

**Test corpus** (what MANUAL stage gates — different counter):
- Test files on disk: 5039
- MANUAL tests discovered: 0
- Files scanned during MANUAL discovery: 0

> APPLICATION SURFACES and TEST CORPUS are different counters — per MANUAL_STAGE_CONTRACT v1 they must not be folded. App surfaces are what SATE audits; test corpus is what MANUAL gates.

```
MANUAL_INPUT_SCOPE:
  source: discoverPhpTestFiles
  files_total: 0
  files_considered: 0
  tests_discovered: 0 (extracted test blocks; many files contain no tests)
```

## MANUAL Stage Verdict (v1 — SAFETY + QUALITY independent)
> SAFETY and QUALITY are INDEPENDENT gates per MANUAL_STAGE_CONTRACT v1. Never folded.

| Gate | Spec | Pass files |
|---|---|---:|
| SAFETY | v1 (refiner/validator.js) | 4718 |
| QUALITY | v1 (v1, enabled=true) | 4523 |
| KB_ELIGIBLE | binary v1 (YES if QUALITY passes; LIMITED reserved for v2) | 4502 |
| RUNNER allowlist | file-level | 1 |

## Tier Classification (God Mode)
| Tier | Count |
|---|---:|
| A | 216 |
| B | 33 |
| C | 2472 |
| FRAGILE | 94 |
| QUARANTINED | 0 |
| UNCLASSIFIED | 0 |

## Refusal Ledger
> Each refusal cites the specific signal that triggered it. No mystery refusals.

Total blocked surfaces: 466

| Reason | Count | Example surface |
|---|---:|---|
| `NO_EXPLICIT_RETURN` | 465 | `App\Actions\Billing\AddOrganizationSubscriptionCreditsAction@execute` |
| `FRAMEWORK_IMPLICIT_ONLY` | 1 | `App\Livewire\Landing\ContactForm@__invoke` |

## Dead-Code Triage
Total triaged: 2787

| Bucket | Count | Action | Example |
|---|---:|---|---|
| DELETE | 1365 | Remove | `App\AIBr\Support\Helpers@normalizeText` |
| WIRE | 0 | Suggest binding | — |
| PROMOTE | 0 | Suggest promotion path | — |
| DEFER | 1422 | Flag, recheck next audit | `App\Actions\Auth\FilamentAgencyRegisterAction@execute` |

*Excluded 494 framework entry points from triage — see "Framework Entry Points" section below.*

## Framework Entry Points
Framework entry points are invoked by Laravel's runtime (schedulers, queue workers, HTTP kernel, event dispatcher, Filament/Livewire lifecycles, etc.). They have zero direct PHP callers by design — excluded from dead-code triage so the DEFER bucket reflects truly uncertain surfaces, not framework hooks.

Total excluded from dead-code triage: 494

| Kind | Count |
|---|---:|
| form_request | 150 |
| policy | 129 |
| queued_job | 107 |
| console_command | 93 |
| event_listener | 14 |
| livewire_component | 1 |

## Duplication Map
Total clusters: 294; surfaces in clusters: 1516

| Cluster | Canonical | Duplicates |
|---|---|---|
| cluster_001 | `App\Actions\EmailTemplates\IsEmailTemplateEnabledForOrganizationAction@__construct` | `App\Actions\EmailTemplates\RenderEmailTemplateAction@__construct`, `App\Actions\EmailTemplates\SendEmailTemplateAction@__construct`, `App\Actions\SendEmailTemplateAction@__construct` |
| cluster_002 | `App\Actions\EmailTemplates\SendEmailTemplateAction@execute` | `App\Actions\SendEmailTemplateAction@execute` |
| cluster_003 | `App\Actions\EmailTemplates\SendEmailTemplateToManyRecipientsAction@__construct` | `App\Actions\EmailTemplates\SendEmailTemplateToUsersUsingTheirLocaleAction@__construct` |
| cluster_004 | `App\Actions\OutreachAI\AssignClusterAction@execute` | `App\Actions\OutreachAI\ComputeAttributionAction@execute`, `App\Actions\OutreachAI\OutputInsightsAction@execute` |
| cluster_005 | `App\Actions\OutreachAI\SalesAcceleration\RunQualificationOutcomeAction@execute` | `App\Actions\OutreachAI\SalesAcceleration\RunSalesAccelerationOutcomeAction@execute`, `App\Services\OutreachAI\Sales\IntentToBuyDetector@detect`, `App\Services\OutreachAI\Sales\PainPointExtractor@extract`, `App\Services\OutreachAI\SalesAcceleration\SalesIntentDetector@detect`, `App\Services\OutreachAI\UX\MessageClarityService@analyzeClarity` |
| cluster_006 | `App\Actions\Payments\CreatePaymentDeductionAction@__construct` | `App\Actions\Payments\RecordPaymentAction@__construct`, `App\Domains\Payments\Actions\RecordPaymentAction@__construct` |
| cluster_007 | `App\Actions\Payments\FinalizeTransactionAction@__construct` | `App\Domains\Payments\Actions\CreateTransactionAction@__construct`, `App\Domains\Payments\Actions\FinalizeTransactionAction@__construct` |
| cluster_008 | `App\Actions\Zoho\SyncZohoCustomerAction@__construct` | `App\Actions\Zoho\SyncZohoInvoiceAction@__construct` |
| cluster_009 | `App\Actions\Zoho\SyncZohoCustomerAction@execute` | `App\Services\OutreachAI\SubscriptionService@getEffectiveLimits` |
| cluster_010 | `App\AIBr\Domain\Knowledge\RetrievalConstraintService@applyConstraints` | `App\Services\OutreachAI\PricingPrimitives@getAvailablePrimitives` |
| cluster_011 | `App\AIBr\Domain\Scoring\LeadPriorityService@calculateScore` | `App\Services\OutreachAI\LeadPriorityService@calculateScore` |
| cluster_012 | `App\AIBr\Support\Helpers@normalizeText` | `App\AIBr\Support\TextFilters@sanitize`, `App\Support\OutreachAI\Knowledge\ForbiddenPhrasesRegistry@sanitize`, `App\Support\OutreachAI\Persona\StyleRules@addStructure`, `App\Support\OutreachAI\Persona\StyleRules@beMoreDirect`, `App\Support\OutreachAI\Persona\StyleRules@clarify`, `App\Support\OutreachAI\Persona\StyleRules@lengthen`, `App\Support\OutreachAI\Persona\StyleRules@removeFiller`, `App\Support\OutreachAI\Persona\StyleRules@simplify`, `App\Support\OutreachAI\Persona\StyleRules@softenTone` |
| cluster_013 | `App\Api\Controllers\BookingController@cancel` | `App\Api\Controllers\BookingController@convert` |
| cluster_014 | `App\Api\Controllers\BookingController@store` | `App\Api\Controllers\BookingController@store`, `App\Http\Controllers\Api\MaintenanceTicketController@store` |
| cluster_015 | `App\Api\Controllers\FileController@index` | `App\Api\Controllers\LandlordController@index`, `App\Api\Controllers\LandlordController@index`, `App\Api\Controllers\LandlordDashboardController@leases`, `App\Api\Controllers\LandlordDashboardController@properties`, `App\Api\Controllers\LeaseController@expiringSoon`, `App\Api\Controllers\LeaseController@index`, `App\Api\Controllers\LeaseController@index`, `App\Api\Controllers\PaymentController@index`, `App\Api\Controllers\PaymentController@index`, `App\Api\Controllers\PaymentController@recent`, `App\Api\Controllers\PropertyController@index`, `App\Api\Controllers\PropertyController@index`, `App\Api\Controllers\ReminderController@index`, `App\Api\Controllers\ReminderController@index`, `App\Api\Controllers\ReminderController@recent`, `App\Api\Controllers\RentCycleController@dueSoon`, `App\Api\Controllers\TenantController@index`, `App\Api\Controllers\TenantController@index`, `App\Api\Controllers\UnitController@index`, `App\Api\Controllers\UnitController@index`, `App\Http\Controllers\Api\MaintenanceTicketController@index`, `App\Http\Controllers\Api\MaintenanceTicketController@index` |
| cluster_016 | `App\Api\Controllers\FileController@stats` | `App\Api\Controllers\FileController@stats`, `App\Api\Controllers\ReportController@occupancyTrends`, `App\Api\Controllers\TransferController@stats` |
| cluster_017 | `App\Api\Controllers\GatewayController@register` | `App\Api\Controllers\GatewayController@register` |
| cluster_018 | `App\Api\Controllers\LandlordController@stats` | `App\Api\Controllers\TenantController@stats` |
| cluster_019 | `App\Api\Controllers\LandlordDashboardController@__construct` | `App\Api\Controllers\TenantDashboardController@__construct` |
| cluster_020 | `App\Api\Controllers\LandlordDashboardController@dashboard` | `App\Api\Controllers\LandlordDashboardController@dashboard` |

*+ 274 more clusters in the JSON report.*

## Coverage Gaps
Coverage rate: 44.8%; total gaps: 1554

Top gaps by domain (full list in JSON):

| Domain | Gaps | Example surface |
|---|---:|---|
| Other | 845 | `App\Actions\Auth\FilamentAgencyRegisterAction@execute` |
| Controllers | 303 | `App\Api\Controllers\BookingController@cancel` |
| Services | 279 | `App\Domains\Files\Services\FileSecurityService@scanForVirus` |
| Console Commands | 81 | `App\Console\Commands\AuditCollectionInbox@handle` |
| Jobs | 36 | `App\Domains\Maintenance\Jobs\AggregateMaintenanceMetricsJob@handle` |
| Listeners | 6 | `App\Domains\Payments\Listeners\RecordForfeitedBookingRevenue@handle` |
| Models | 3 | `App\Models\OutreachAI\HumanHandoffState@getActiveConversation` |
| Notifications | 1 | `App\Support\Notifications\NotificationSender@sendForSubscriptionEvent` |

## Candidates (require human decision)
| Source | Count |
|---|---:|
| Dead-code | 2787 |
| Duplication | 1222 |
| Coverage gaps | 1554 |
| **Total** | **5563** |

Submit decisions via:
```bash
node public/sate.js review-queue --run-id <runId> --candidates <candidates.json>
node public/sate.js submit-decision --run-id <runId> --candidate-id <id> --decision APPROVE|REJECT|DEFER
```

## Governance History
> Decisions are append-only per CORE_FREEZE. No retroactive mutation.

Total decisions on record: 0
| Decision | Count |
|---|---:|
| APPROVE | 0 |
| REJECT | 0 |
| DEFER | 0 |
| OTHER | 0 |

## Version Pins
Every KB-derived fact carries: `learned_under: { safety_gate: v1, quality_gate: v1, manual_contract: v1 }`

## Runner Allowlist Reference
- Path: `.ai/manual/approved-tests.json`
- Approved test files: 1
- RUNNER enforcement is file-level. Per MANUAL_STAGE_CONTRACT v1, requested PHPUnit tests must be in this allowlist or RUNNER aborts.
