- Issue 1: Recompute WCAG A/AA compliance badges after dismissing issues (JS +
backend); exported reports now reflect updated pass/fail status
- Issue 2: Group document-wide table issues into collapsible cards with
Dismiss All button; reduces noise for multi-table documents
- Issue 3: Split cleanup retention — uploads deleted after 24h, result/meta
JSONs retained 30 days (RESULTS_RETENTION_HOURS env var, default 720h)
- Issue 4A: Library shows adjusted score when available (.adjusted.json preferred)
- Issue 4B: History page groups documents by retention countdown (red/yellow/green
sections); adds 30-day retention banner
- Issue 5+6: AI prompt updated — describe people by role/action not appearance,
use specific brand names; flags images with people for human review
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- api.php: add save_adjusted_result action that merges dismissed issues,
check overrides and recalculated score into {job_id}.adjusted.json;
handleExport() now prefers .adjusted.json over .result.json
- js/results.js: displayMatterhorn() shows Mark as Passed / Undo buttons
for H-type CPs (CP04, CP13) linked to overridden checks; overrideCheck /
unoverrideCheck refresh Matterhorn table and recompute overall banner
- js/batch.js: exportReport() saves adjusted result before opening export
URL, using pre-opened window to avoid popup blockers
- report_generator.py: filter dismissed issues, show (Adjusted) badge,
Manual Pass in checks and Matterhorn tables; switch generate_html() to
Montserrat + Oliver branding (#1a1a1a header, #FFC407 skip-link)
- css/styles.css: fix dark-mode log-header from blue-ish #252840 to #242424
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- api.php: read accessibility_score (not score) from result.json
- api.php: handleDelete() also removes .dismissed.json, .overrides.json, .error.log
- js/app.js: add Delete button to each history row with confirm dialog
- css/styles.css: red hover style for delete button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- api.php: extractUserFromToken() decodes Azure AD JWT payload (oid/name/email)
- Upload: stores user_id, user_name, user_email in job .meta.json
- handleList(): filters jobs by authenticated user's oid — full user isolation
(jobs without user_id are excluded for authenticated users to prevent leakage);
enriches each entry with score, grade, critical/error counts from result JSON
- index.html: "My Documents" history section, shown after login
- js/app.js: showAuthenticatedUI() triggers loadHistory(); full renderHistory()
renders sortable table with score, grade, severity badges, and Open/HTML/PDF/JSON
action buttons; openHistoryJob() loads any past result into the results panel
- js/results.js: calls loadHistory() after displayResults() so table refreshes
immediately after a new check completes
- css/styles.css: history table styles with colour-coded score/grade/severity badges
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
.score-display had overflow:hidden which cut off the right half of the
btn-recheck button. Changed to overflow:visible — decorative ::before
and ::after pseudo-elements use position:absolute;inset:0 so they remain
visually contained within the border-radius.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each issue card's WCAG criterion (e.g. "1.4.3") is now a link to the
WAI Understanding page at w3.org. Comma-separated multi-criteria and
PDF/UA are handled separately. Links open in a new tab.
- js/utils.js: WCAG_SLUGS map + wcagCriterionLinks() helper
- js/results.js: issue-meta now calls wcagCriterionLinks()
- css/styles.css: .wcag-link style (dotted underline, hover accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Part 1 — CSS/Contrast/Accessibility:
- Raise --text-muted contrast to WCAG AA (#696969 light, #9a9a9a dark)
- Add body font-size: 16px baseline
- Enlarge #themeToggle to 15px / 10px 20px padding
Part 2 — Start Button (user-controlled analysis):
- Upload no longer auto-starts check; shows ready state with filename/size
- New showReadyState() / removeFile() functions in upload.js
- beginCheck() now shows progress + hides ready state on click
- Add prominent "Check Another PDF" button at bottom of results
Part 3 — Scoring recalibration:
- Replace deduction formula with check-pass ratio + soft penalty (cap 20)
- Fix run_check() to only examine issues added by the current check
- Add score_breakdown (per-check table) to JSON output + results UI
- Downgrade readability ERROR → WARNING (advisory, not hard failure)
Part 4 — Auto-fix debugging:
- Remediation failure now returns up to 2000 chars of log (was 500)
- pdf_remediation.py: stderr output, sys.exit(0/1), output dir creation
Part 5 — Error location: View on Page button on each issue card
Part 6 — Matterhorn Protocol PDF/UA-1:
- _build_matterhorn_summary() maps 19 checks → 31 checkpoints
- Matterhorn card in index.html with grouped PASS/FAIL/Not-tested table
- Correct M/H badges per checkpoint
Part 7 — Dismiss / False Positive:
- dismissed_issues table in db/init.sql + dismiss/undismiss in db_manager.py
- api.php: dismiss/undismiss endpoints (file-backed), dismissed_indices
injected into both handleStatus and handleResult responses
- results.js: dismissIssue/undismissIssue with visual strikethrough
- CSS: .dismissed, .btn-dismiss, .btn-undismiss styles
Part 8 — PDF Report (WeasyPrint):
- generate_pdf() in report_generator.py: PAC-style A4, Oliver branding
- api.php handleExport() supports format=pdf
- index.html: "PDF Report" download button in results header
- requirements.txt: weasyprint>=60.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Font: Outfit/Figtree → Montserrat
- Accent: coral #e8553d → Oliver yellow #FFC407 with black text
- Dark mode: neutral blacks instead of blue-tinted navy
- Fix score display, stat cards, and log entries contrast in dark mode
- Replace hardcoded light-mode colors in JS with CSS variables
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>