AccessAuditLog
Corex\Config\Access\AccessAuditLog · class · Config layer
The access audit log (spec 067, design: “Corex Access & Abilities” → Audit log). Records REAL access refusals only: permission-denied attempts on CoreX screens, published through the corex_admin_access_denied action by {@see \Corex\Admin\AdminPage::permissionDenied()} and {@see AccessDeniedGate}. Access requests and decisions are in the shared activity stream. One person’s refusals of one section are one entry for an hour from the first of them, with a count and the first and last time (spec 112, FR-009 to FR-012), so a page reloaded a thousand times is one line and does not push anybody else’s out. Each person keeps at most {@see MAX_PER_PERSON} entries before the log’s own cap applies. Where the host has a persistent object cache, a repeat within the hour is counted there and the database is written once for the window: when it starts, and again when the next refusal after it closes it or {@see settle()} runs. Without one, a repeat updates that person’s entry in place. Entries live in an autoload-off option, pruned to 30 days by their last refusal (DECISIONS #114).
Public API
Section titled “Public API”register(): void
Section titled “register(): void”recordDenied(string $section): void
Section titled “recordDenied(string $section): void”Action callback: a CoreX screen refused the current user. The screen’s section key (from AdminPage) and its page slug (from the menu-level gate) name the same screen, so both are recorded under the page slug and counted together.
refused(int $userId, string $kind, string $section): void
Section titled “refused(int $userId, string $kind, string $section): void”A refusal outside the CoreX screens: a Data screen model (spec 112, FR-031).
record(string $kind, string $section, int $userId, ?int $at): void
Section titled “record(string $kind, string $section, int $userId, ?int $at): void”entries(?int $now): array
Section titled “entries(?int $now): array”The retained entries, newest first by their last refusal, with any count still held in the object cache added in.
settle(?int $now): void
Section titled “settle(?int $now): void”Stores the counts the object cache holds, so a window that nobody closes is not lost when the cache is emptied. Run daily; does nothing without a persistent object cache.