The AI Incident & Anomaly Log is the primary tracking console for AI-related security events, policy violations, and operational anomalies across the environment. It is part of the AI Governance suite and is designed to be reviewed at each AI Steering Committee meeting.
The console is a single self-contained HTML file. It runs in the browser, requires no backend server or build process, and in Phase 1 reads from and writes to a SharePoint list using the user's existing browser session for authentication.
The console has two operating modes controlled by a single flag in the script. Switching from demo to live requires no UI changes — only the data layer swaps.
The page loads a hardcoded dataset of 15 seed incidents directly from the script. No network calls are made. All filtering, sorting, form submissions, and chart rendering work identically to production — the only difference is that new records are not persisted between page refreshes. This mode lets teams use and evaluate the tool immediately without any SharePoint setup.
On page load, the console calls the SharePoint REST API to fetch all items from the AI Incident Log list. When a new incident is logged, it fires a POST to create a new list item. Authentication is handled automatically by the user's existing SharePoint browser session — no API keys, no app registrations, no OAuth configuration required.
| LAYER | PHASE 0 (DEMO) | PHASE 1 (LIVE) |
|---|---|---|
| Data Source | getMockData() — 15 seed records in script | SharePoint REST GET on list items |
| Write | In-memory push to ALL_INCIDENTS array | SharePoint REST POST to list |
| Auth | None required | Browser session cookie + X-RequestDigest |
| Persistence | Lost on page refresh | Permanent in SharePoint list |
| UI / Charts | Identical in both modes — no changes required | |
Four cards sit across the top of the console. They calculate against the full dataset regardless of any active table filters and update automatically when new incidents are logged.
Three charts sit below the stat cards. All three calculate against the full dataset and do not respond to table filters — they always show the complete picture.
The Log New Incident form sits directly above the register table. The Date field auto-fills to today on page load. Required fields are Date, Category, Severity, and Description — Owner and Resolution Notes can be filled in later.
- 1Confirm or adjust the Date.Defaults to today. Change it if logging a past incident.
- 2Select a Category.Pick the type that best fits. See Section 10 for full category definitions. If nothing fits, use Other and explain in the Description field.
- 3Select a Severity.High for confirmed data exposure, active bypass, unauthorized production changes, or any client impact. Medium for policy violations without confirmed exposure. Low for benign anomalies or near-misses. See Section 11 for the full matrix.
- 4Enter the Owner.The engineer or lead responsible for driving this to resolution. Can be left blank at log time and assigned during triage.
- 5Write a factual one-line Description.What happened, where, and which AI tool or workflow was involved. No speculation — stick to what is confirmed at time of logging.
- 6Add initial Resolution Notes if available.Paste any immediate containment steps already taken. This can be left blank and updated later directly in SharePoint once Phase 1 is live.
- 7Click LOG INCIDENT.The record appears at the top of the register immediately. All four stat cards and all three charts update. A green confirmation toast appears in the bottom-right corner with the assigned Incident ID.
The toolbar above the register table has four controls that work simultaneously. Filtering is instant — no button press required. The export always reflects the current filtered view.
Clicking any column header sorts by that column. Clicking the same header again reverses direction. The sorted column header is highlighted in cyan.
Category: DLP Block — full DLP trend for policy review.
Search: [engineer name] — all incidents assigned to a specific owner.
Status: Investigating — everything currently in active triage.
Clicking any row in the register opens the Incident Detail modal. The modal shows all fields for that record in full — Description and Resolution Notes are not truncated as they are in the table view.
- 1Click any rowin the register. The modal appears centered on screen.
- 2Review all fieldsincluding the full Resolution Notes block at the bottom of the modal panel.
- 3Close by clicking ✕in the top-right of the modal, or by clicking anywhere outside the modal panel.
The ↓ CSV button in the table toolbar exports the rows currently visible after all active filters are applied. The file is generated entirely in the browser — no server call is made. The filename includes today's date automatically.
- 1Apply filters if needed.The export reflects exactly what is shown in the table. Set no filters to export the full register.
- 2Click ↓ CSV.File downloads as
AI-Incident-Log-YYYY-MM-DD.csvimmediately. - 3Open in Excelfor committee reporting, pivot analysis, or pasting into a quarterly review document.
| FIELD | REQUIRED | SP COLUMN | NOTES |
|---|---|---|---|
| Incident ID | Auto | SP Item ID | Generated from SharePoint item ID on read. Format INC-0001. No dedicated column needed in the list. |
| Date | Yes | IncidentDate | Date the incident occurred — not the date logged. Date and Time column type; date-only format is sufficient. |
| Category | Yes | Category | Choice column. See Section 10 for allowed values and definitions. |
| Description | Yes | Title (renamed) | Rename the default SharePoint Title column to Description. Single line of text. Factual one-liner — what happened, what tool, what impact. |
| Severity | Yes | Severity | Choice column: High, Medium, Low. See Section 11 for the severity decision matrix. |
| Status | Auto | Status | Choice column: Open, Investigating, Resolved. Default value Open. Set during triage and updated as the incident progresses. |
| Owner | No | Owner | Single line of text. Engineer or lead responsible for resolution. Can be blank at log time. |
| Resolution Notes | No | ResolutionNotes | Multiple lines of text, plain text. Containment steps, root cause, follow-up actions. Required before marking Resolved. |
These are the allowed values for the Category field in both the console form and the SharePoint list. Use the most specific category that fits. If none fit, use Other and explain in the Description.
| LEVEL | CRITERIA | RESPONSE SLA |
|---|---|---|
| HIGH | Confirmed or probable data exposure. Active policy bypass in production. Unauthorized agent or tool deployed to client environment. Any incident with client impact or regulatory implication. | Acknowledge within 2 hours. Escalate to InfoSec lead same day. Post-incident review required before closing. |
| MEDIUM | Policy violation with no confirmed data exposure. Cost spike traced to a specific workflow but no external impact. Jailbreak attempt that did not succeed in extracting restricted output. | Acknowledge within 24 hours. Assign owner within 48 hours. Review at next weekly team meeting. |
| LOW | Benign anomaly, near-miss, or informational observation with no external impact. Incidents that are fully self-contained. | Log and monitor. No immediate action required. Review in monthly AI Steering Committee meeting. |
| STATUS | MEANING | WHEN TO SET | WHO SETS IT |
|---|---|---|---|
| OPEN | Logged but not yet assigned or actively investigated. | Default on creation — set by the system. | System |
| INVESTIGATING | Owner assigned, active triage or remediation underway. | As soon as an owner picks it up. | Assigned owner |
| RESOLVED | Root cause confirmed, containment complete, follow-up actions documented. | Only after Resolution Notes are populated. Never close without documenting what was done. | Assigned owner + InfoSec review for High |
Phase 0 (demo) has no prerequisites — open the file in any browser and it runs. Phase 1 (live SharePoint) requires the following before you start.
https://TENANT.sharepoint.com/sites/SITENAME. Navigate to the site in your browser and copy from the address bar — stop before any page path or query string.pages/) create it before uploading.ai-incident-log.html in Microsoft Word or any rich-text editor — it will corrupt the file silently.The console is a single self-contained HTML file. No dependencies to install, no build step, no backend server. Upload it and it runs.
- 1Navigate to your document libraryon the destination SharePoint site.
- 2Upload
ai-incident-log.htmlusing the Upload button or drag-and-drop directly into the library. - 3Click the file nameto open it. SharePoint renders the HTML inline. You should see the console in demo mode with the orange DEMO MODE badge top-right.
- 4Copy the URL from the address bar.This is the link you will share with users:
https://TENANT.sharepoint.com/sites/SITE/Shared%20Documents/ai-incident-log.html
incident-log.html, ai-incidents.html — the name has no effect on functionality. Update your nav.js entry to match whatever you choose.
The console reads and writes to a SharePoint list named AI Incident Log on the same site. The list name must match exactly — the REST call references it by title.
- 1Go to Site Contents.Gear icon → Site Contents, or navigate to
/sites/SITENAME/_layouts/15/viewlsts.aspx - 2Click + New → List → Blank list.Name it exactly:
AI Incident Log. No description needed. Click Create. - 3Rename the default Title column to Description.Click the Title column header → Column Settings → Rename → type
Description→ Save. - 4Add the following columnsusing + Add Column in the list view:
| COLUMN NAME | TYPE | ALLOWED VALUES / NOTES |
|---|---|---|
IncidentDate | Date and Time | Date only. No time component needed. |
Category | Choice | DLP Block · Jailbreak Attempt · Cost Spike · Unauthorized Deploy · Data Exfiltration · Policy Violation · Other |
Severity | Choice | High · Medium · Low |
Status | Choice | Open · Investigating · Resolved — set default value to Open |
Owner | Single line of text | Free text. No validation. |
ResolutionNotes | Multiple lines of text | Plain text. No rich text or enhanced formatting. |
incident_x0020_date and the field mapping will break. Create each column using the exact names in the table above.
Field= parameter shows the internal name. Compare against the table above. If there is a mismatch, delete the column and recreate it with the correct name.
Open ai-incident-log.html in a text editor. Near the top of the <script> section, find the SP_CONFIG block:
- 1Replace
siteUrlwith your actual SharePoint site URL. Example:https://cyberadvisors.sharepoint.com/sites/AIHub. No trailing slash. No page path after the site name. - 2Confirm
listNamematches the exact name you gave the list in C3 — including spaces and capitalization. If you named it differently, update this value. - 3Leave
demoMode: truefor now.You will flip this to false in C5 after the REST code blocks are uncommented and the list is confirmed to exist. - 4Save the fileas .html. Do not allow your editor to save it as .txt or any other format.
With the list created and SP_CONFIG updated, activate the SharePoint connection by making three changes in the script and re-uploading the file. All changes are commented inline and clearly marked.
Inside fetchIncidents(), find the block labeled "Production path (uncomment in Phase 1)". Remove the // prefix from each line of the REST GET fetch block. This replaces the getMockData() call with a live SharePoint read.
Inside submitIncident(), find the block labeled "PHASE 1: Replace this block with the SP POST call below". Remove the // prefix from each line of the REST POST block. The getRequestDigest() helper at the bottom of the script is already active — no changes needed there.
- 1Set
demoMode: falsein SP_CONFIG. - 2Delete the orange wiring banner.Find
<div class="wire-banner" id="wireBanner">in the HTML body and delete the entire element including its closing</div>. - 3Save the fileand re-upload to SharePoint, replacing the previous version. Confirm the overwrite when prompted.
- 4Open the file in your browser.The status badge should show a solid green dot and read SP CONNECTED. Demo seed data will be replaced by the actual contents of your SharePoint list.
__metadata.type value SP.Data.AI_x0020_Incident_x0020_LogListItem is derived from the list name with spaces encoded as _x0020_. If you named your list something other than AI Incident Log, this value must be updated to match. Confirm the correct value by fetching: /_api/web/lists/getbytitle('YOUR LIST NAME')?$select=ListItemEntityTypeFullName in your browser while logged into SharePoint.
SP_CONFIG.siteUrl. If you are opening the file locally from your desktop (e.g. a C:\ path), the session cookie will not be present and all calls will fail. The file must be opened from SharePoint.
Run through each item below after going live. Do not share the console URL with users until all items pass.
- ✓SP badge is green. Top-right shows solid green dot and reads SP CONNECTED. If still orange, demoMode was not set to false or the file was not re-uploaded.
- ✓No JS errors on load. Open browser console (F12 → Console tab). No errors should be present. Stat cards show real numbers — zeros are fine for an empty list, dashes (—) mean the fetch failed.
- ✓Log a test incident. Fill the form, submit. Confirm the toast appears, the row appears in the table, and the stat cards update. Then open the SharePoint list directly and confirm the item is there.
- ✓Open the detail modal. Click the test row. Confirm all fields display correctly including Description and Resolution Notes.
- ✓Test all filters. Apply severity, status, and category filters individually and together. Confirm they narrow the table correctly and that clearing them restores all rows.
- ✓Test CSV export. Click ↓ CSV. Confirm the file downloads with correct columns and the test row is present.
- ✓Test as a non-owner user. Have a technician without Site Owner permissions open the page and log an incident. If they get a 403 on the POST, check list permissions — the user needs at least Contribute. The list inherits from the site by default.
- ✓Delete the test incident. Open the SharePoint list directly and delete the test row. Refresh the console and confirm it is gone. The list is the source of truth.
| SYMPTOM | LIKELY CAUSE | FIX |
|---|---|---|
| Badge still orange after upload | demoMode still true, or browser cached old file | Confirm demoMode: false in script. Hard-refresh: Ctrl+Shift+R. |
| Stat cards show — on load | fetchIncidents() threw an error | Check F12 Console for the error. Usually a 403 (permissions) or wrong siteUrl. |
| 403 on GET | User not signed into SP, or list does not exist | Confirm user is signed in. Confirm list name matches SP_CONFIG.listName exactly including case and spaces. |
| 403 on POST (log incident) | Request digest failed, or list permissions deny write | Confirm POST block is uncommented. Check list permissions — user needs Contribute minimum. |
| Items appear in SP list but not console | Browser showing cached page | Hard-refresh. The console fetches fresh data on every page load. |
| Metadata type error on POST | List name in __metadata.type does not match actual list name | Fetch /_api/web/lists/getbytitle('AI Incident Log')?$select=ListItemEntityTypeFullName and update the type value to match. |
| File downloads instead of opening | Tenant blocks HTML rendering in document libraries | Enable Custom Script in SharePoint Admin Center, or convert file to .aspx. |
AI Incident Log.Update the breadcrumb link in this KB file's topbar to point to your governance index.
Add the SharePoint list URL to your internal tool register so admins can find it without opening the console.