{"_id":"@consevangelou/accessibility-audit-core","_rev":"5-85c0fd3c5e66a0b5f4fa2a2c3e6a7938","name":"@consevangelou/accessibility-audit-core","dist-tags":{"latest":"1.0.9"},"versions":{"1.0.4":{"name":"@consevangelou/accessibility-audit-core","version":"1.0.4","keywords":["accessibility","a11y","wcag","en301549","axe-core","audit"],"author":{"name":"Constantinos Evangelou"},"license":"MIT","_id":"@consevangelou/accessibility-audit-core@1.0.4","maintainers":[{"name":"consevangelou","email":"consevangelou@gmail.com"}],"homepage":"https://github.com/gieglas/accessibility-audit-core","bugs":{"url":"https://github.com/gieglas/accessibility-audit-core/issues"},"dist":{"shasum":"5779ced4ce11818382d2d3df5c5b98b73bc93fd5","tarball":"https://registry.npmjs.org/@consevangelou/accessibility-audit-core/-/accessibility-audit-core-1.0.4.tgz","fileCount":11,"integrity":"sha512-L9p2vIpGT0YhhC9tGvJhTsw5W2TFod7Zc1hL1IIUKmSolh3G4d6rD6Xa1Cm38CRfu53oo36Nnw+Lp21z3dF/qg==","signatures":[{"sig":"MEQCIC4jxTH8GkvRvU5ZvwJFCBzq2pTZWm4Rnt8PlBNuVUXJAiBiES5VN3o39G/SpVasWt4t9ZNJL1cRbo9eEyoyLx9PgQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31737},"type":"module","engines":{"node":">=20"},"exports":{".":"./core/index.mjs"},"gitHead":"457e23874323e9f4eac164fd594d277f61d6ea90","scripts":{"test":"node --test","audit":"node cli/run-audit.mjs"},"_npmUser":{"name":"consevangelou","email":"consevangelou@gmail.com"},"repository":{"url":"git+https://github.com/gieglas/accessibility-audit-core.git","type":"git"},"_npmVersion":"11.6.1","description":"Core logic for accessibility audits (WCAG / EN 301 549), reusable across CLI, browser, and extensions","directories":{},"_nodeVersion":"22.20.0","dependencies":{"pa11y":"^9.0.1","axe-core":"^4.11.0","puppeteer":"^24.33.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/accessibility-audit-core_1.0.4_1767533384834_0.336703002568032","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@consevangelou/accessibility-audit-core","version":"1.0.5","keywords":["accessibility","a11y","wcag","en301549","axe-core","audit"],"author":{"name":"Constantinos Evangelou"},"license":"MIT","_id":"@consevangelou/accessibility-audit-core@1.0.5","maintainers":[{"name":"consevangelou","email":"consevangelou@gmail.com"}],"homepage":"https://github.com/gieglas/accessibility-audit-core","bugs":{"url":"https://github.com/gieglas/accessibility-audit-core/issues"},"dist":{"shasum":"30823067259f997bf136456402280177be07a0e0","tarball":"https://registry.npmjs.org/@consevangelou/accessibility-audit-core/-/accessibility-audit-core-1.0.5.tgz","fileCount":11,"integrity":"sha512-Al4U7Gga3KsqWR3QF+LUpcW5phSWsFtMv93FEn+BmLOXMHFmznsZzttG4Ph2Ouw16bcHq6TiKlwiFXJCTpmJKw==","signatures":[{"sig":"MEUCIQDspvoSAwiJISMZU6CfdF72UG1iE6xFOqWlmIVD5ULQwQIgG7HYYbzm2Y958QP24eEG2Ck9XnN+7Oe84lBsz4eOhC4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@consevangelou%2faccessibility-audit-core@1.0.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":31737},"type":"module","engines":{"node":">=20"},"exports":{".":"./core/index.mjs"},"gitHead":"7e2798b3ed86d1e112e8f1c86a68828db90a1794","scripts":{"test":"node --test","audit":"node cli/run-audit.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8f3a16e3-e4a0-48e9-a136-55f077ea2b6e"}},"repository":{"url":"git+https://github.com/gieglas/accessibility-audit-core.git","type":"git"},"_npmVersion":"11.7.0","description":"Core logic for accessibility audits (WCAG / EN 301 549), reusable across CLI, browser, and extensions","directories":{},"_nodeVersion":"20.19.6","dependencies":{"pa11y":"^9.0.1","axe-core":"^4.11.0","puppeteer":"^24.33.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/accessibility-audit-core_1.0.5_1767533752161_0.8433324614858804","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@consevangelou/accessibility-audit-core","version":"1.0.6","keywords":["accessibility","a11y","wcag","en301549","axe-core","audit"],"author":{"name":"Constantinos Evangelou"},"license":"MIT","_id":"@consevangelou/accessibility-audit-core@1.0.6","maintainers":[{"name":"consevangelou","email":"consevangelou@gmail.com"}],"homepage":"https://github.com/gieglas/accessibility-audit-core","bugs":{"url":"https://github.com/gieglas/accessibility-audit-core/issues"},"dist":{"shasum":"8c24e82a35e3a82f02a468ef8b10e256e647b5b7","tarball":"https://registry.npmjs.org/@consevangelou/accessibility-audit-core/-/accessibility-audit-core-1.0.6.tgz","fileCount":11,"integrity":"sha512-S1JyB1s+cVmIKABPh1MUqHPJRxEsyezEkKN2MhnVmjQXvYdxQA0cfICmlO8eWxT8EjEDPcrxMNkRCw1zfDfytQ==","signatures":[{"sig":"MEUCIQC6XJUAb4yWc/EdwcamKUSbofLuyO9sTbd7MN/SjB1akQIgVxLTFtb5RUYDJjfq4dgI1FfDAH0S57zNJm2nXIN9RbE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@consevangelou%2faccessibility-audit-core@1.0.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":32426},"type":"module","engines":{"node":">=20"},"exports":{".":"./core/index.mjs"},"gitHead":"4eb2f6ed97c59152e0fc1e304b0d34b4e5be1e9e","scripts":{"test":"node --test","audit":"node cli/run-audit.mjs","coverage":"c8 --reporter=html --reporter=text --reporter=lcov --reporter=json-summary npm test","coverage:copy":"node -e \"try{require('fs').copyFileSync('coverage/coverage-summary.json','./coverage-summary.json')}catch(e){process.exit(0)}\"","coverage:badge":"coverage-badges --output ./coverage-badges.svg && npm run coverage:copy","coverage:report":"c8 report"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8f3a16e3-e4a0-48e9-a136-55f077ea2b6e"}},"repository":{"url":"git+https://github.com/gieglas/accessibility-audit-core.git","type":"git"},"_npmVersion":"11.7.0","description":"Core logic for accessibility audits (WCAG / EN 301 549), reusable across CLI, browser, and extensions","directories":{},"_nodeVersion":"20.19.6","dependencies":{"pa11y":"^9.0.1","axe-core":"^4.11.0","puppeteer":"^24.33.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","coverage-badges-cli":"^2.2.0"},"_npmOperationalInternal":{"tmp":"tmp/accessibility-audit-core_1.0.6_1767537730036_0.9151432346236641","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@consevangelou/accessibility-audit-core","version":"1.0.8","keywords":["accessibility","a11y","wcag","en301549","axe-core","audit"],"author":{"name":"Constantinos Evangelou"},"license":"MIT","_id":"@consevangelou/accessibility-audit-core@1.0.8","maintainers":[{"name":"consevangelou","email":"consevangelou@gmail.com"}],"homepage":"https://github.com/gieglas/accessibility-audit-core","bugs":{"url":"https://github.com/gieglas/accessibility-audit-core/issues"},"dist":{"shasum":"bfc464c4870f585976d0fdaa7f26951829c22e80","tarball":"https://registry.npmjs.org/@consevangelou/accessibility-audit-core/-/accessibility-audit-core-1.0.8.tgz","fileCount":12,"integrity":"sha512-iEb3CjgHePysXZ8A0Hi/qCMS+dqFcyQRGt+i4SNUe48ZMz9ErZwLjuMgoly/2iLU7MLK3zdpoWOFBUeYyksZow==","signatures":[{"sig":"MEYCIQC8QRQCuyeGP4OQtxieuwfgf0YOs3x3BVg6e6KVDMOSAwIhAOkNDVE8KCvypaqb/2ok+rcuJPGCZAVGbFf3PTCSOu0I","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIAOnbyvTSCBLnB/slRJUJzI2OjIL1QKnwE7LHPkyIhjzAiEAj0dLFleVoi5VXZd9BxfE3Q6yAK62a/15Y2wAkxRTxrg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@consevangelou%2faccessibility-audit-core@1.0.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":43670},"type":"module","engines":{"node":">=20"},"exports":{".":"./core/index.mjs"},"gitHead":"ef4cc1da15b59247194dfa44c5284d09c8a75002","scripts":{"test":"node --test","audit":"node cli/run-audit.mjs","coverage":"c8 --reporter=html --reporter=text --reporter=lcov --reporter=json-summary npm test","coverage:copy":"node -e \"try{require('fs').copyFileSync('coverage/coverage-summary.json','./coverage-summary.json')}catch(e){process.exit(0)}\"","coverage:badge":"coverage-badges --output ./coverage-badges.svg && npm run coverage:copy","coverage:report":"c8 report"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8f3a16e3-e4a0-48e9-a136-55f077ea2b6e"}},"repository":{"url":"git+https://github.com/gieglas/accessibility-audit-core.git","type":"git"},"_npmVersion":"11.5.1","description":"Core logic for accessibility audits (WCAG / EN 301 549), reusable across CLI, browser, and extensions","directories":{},"_nodeVersion":"20.20.2","dependencies":{"axe-core":"^4.11.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","coverage-badges-cli":"^2.2.0"},"_npmOperationalInternal":{"tmp":"tmp/accessibility-audit-core_1.0.8_1789109804545_0.7807580464441144","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"_id":"@consevangelou/accessibility-audit-core@1.0.9","bugs":{"url":"https://github.com/gieglas/accessibility-audit-core/issues"},"dist":{"shasum":"54adfe5fc5c744a8549796e80af64c084087516b","tarball":"https://registry.npmjs.org/@consevangelou/accessibility-audit-core/-/accessibility-audit-core-1.0.9.tgz","fileCount":12,"integrity":"sha512-QZU4Ihb2vn2f7jwiyf/iAZgLBhmJqg/5l9o/Oh93ET/54xJSf9utesvQS2T8c8YSUGSmv4DPkVwNV7Dx86DyFw==","signatures":[{"sig":"MEUCIQD3xr9dZBskMR9aUgq7rhqrroFcxU99AvJp3RpgvYGCPwIgC8sq0t9NogwZbcuB1tnRuaIi1HRucj/7bxGNW6T8K8I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICWW7b1ojSzKCH/Aa56Ku5Ha9hg+x2aCd8wEHl8WOM4gAiA8jBORpdGMA6TtwxHUUZZE+Axh5QnhVEwe/CZhhjfsdQ=="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@consevangelou%2faccessibility-audit-core@1.0.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":43670},"name":"@consevangelou/accessibility-audit-core","type":"module","author":{"name":"Constantinos Evangelou"},"engines":{"node":">=20"},"exports":{".":"./core/index.mjs"},"gitHead":"64e0e256b2ee1c96ecf3661f62de15367443ba93","license":"MIT","scripts":{"test":"node --test","audit":"node cli/run-audit.mjs","coverage":"c8 --reporter=html --reporter=text --reporter=lcov --reporter=json-summary npm test","coverage:copy":"node -e \"try{require('fs').copyFileSync('coverage/coverage-summary.json','./coverage-summary.json')}catch(e){process.exit(0)}\"","coverage:badge":"coverage-badges --output ./coverage-badges.svg && npm run coverage:copy","coverage:report":"c8 report"},"version":"1.0.9","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8f3a16e3-e4a0-48e9-a136-55f077ea2b6e"}},"homepage":"https://github.com/gieglas/accessibility-audit-core","keywords":["accessibility","a11y","wcag","en301549","axe-core","audit"],"repository":{"url":"git+https://github.com/gieglas/accessibility-audit-core.git","type":"git"},"_npmVersion":"11.5.1","description":"Core logic for accessibility audits (WCAG / EN 301 549), reusable across CLI, browser, and extensions","directories":{},"maintainers":[{"name":"consevangelou","email":"consevangelou@gmail.com"}],"_nodeVersion":"20.20.2","dependencies":{"axe-core":"^4.11.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","coverage-badges-cli":"^2.2.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/accessibility-audit-core_1.0.9_1789110282337_0.9222400412887855"}}},"time":{"created":"2026-01-04T13:29:44.756Z","modified":"2026-09-11T07:04:42.863Z","1.0.4":"2026-01-04T13:29:44.990Z","1.0.5":"2026-01-04T13:35:52.299Z","1.0.6":"2026-01-04T14:42:10.195Z","1.0.8":"2026-09-11T06:56:44.618Z","1.0.9":"2026-09-11T07:04:42.417Z"},"bugs":{"url":"https://github.com/gieglas/accessibility-audit-core/issues"},"author":{"name":"Constantinos Evangelou"},"license":"MIT","homepage":"https://github.com/gieglas/accessibility-audit-core","keywords":["accessibility","a11y","wcag","en301549","axe-core","audit"],"repository":{"url":"git+https://github.com/gieglas/accessibility-audit-core.git","type":"git"},"description":"Core logic for accessibility audits (WCAG / EN 301 549), reusable across CLI, browser, and extensions","maintainers":[{"name":"consevangelou","email":"consevangelou@gmail.com"}],"readme":"# accessibility-audit-core\n[![npm (scoped)](https://img.shields.io/npm/v/@consevangelou/accessibility-audit-core)](https://www.npmjs.com/package/@consevangelou/accessibility-audit-core)\n![License](https://img.shields.io/github/license/gieglas/accessibility-audit-core)\n[![Unit test](https://github.com/gieglas/accessibility-audit-core/actions/workflows/unit-test.yml/badge.svg)](https://github.com/gieglas/accessibility-audit-core/actions/workflows/unit-test.yml)\n[![tag-and-publish-on-version-change](https://github.com/gieglas/accessibility-audit-core/actions/workflows/tag-and-publish-on-version-change.yml/badge.svg)](https://github.com/gieglas/accessibility-audit-core/actions/workflows/tag-and-publish-on-version-change.yml)\n[![coverage](coverage-badges.svg)](coverage-summary.json)\n\nCore utilities for automated web accessibility auditing.\n\nThis package provides **standards-aware processing** of accessibility findings, including:\n\n- Conversion of automated tool output (e.g. axe-core)\n- Normalisation and grouping of findings\n- Mapping to WCAG / EN 301 549 criteria\n- Severity and classification logic\n\nIt is **tool-agnostic** and **framework-agnostic** by design.\n\n## What this package is (and is not)\n\n### ✅ This package **does**\n\n- Convert raw accessibility tool results into structured findings\n- Align findings with WCAG / EN 301 549\n- Provide consistent grouping and severity logic\n- Bundle and load official accessibility standards\n\n### ❌ This package **does not**\n\n- Crawl websites\n- Run browsers\n- Persist results to disk\n- Generate reports or dashboards\n- Provide a CLI\n\nThose concerns intentionally live in **separate projects**.\n\n## Installation\n\n```bash\nnpm install @consevangelou/accessibility-audit-core\n```\n\n## Basic usage\n\n### Convert axe-core results into raw findings\n\n```js\nimport { axeToRawFindings } from \"@consevangelou/accessibility-audit-core\";\n\nconst rawFindings = axeToRawFindings(axeResults, {\n  auditRunId: \"run-123\",\n  siteId: \"example-site\",\n  pageId: \"home\",\n  pageUrl: \"https://example.com\"\n});\n```\n\nThe `axeToRawFindings` function **always returns an array**. \nEach entry represents a **single violation on a single DOM node**.\n\nIf no violations are found, an empty array is returned.\n\nRaw findings are intentionally tool-oriented and not suitable for direct compliance reporting.\nThey must be normalised before being used in WCAG or EN 301 549 assessments.\n\n#### RawFinding schema\n\nA RawFinding represents **one axe-core violation on one DOM node**.\n\n```c#\n{\n  rawFindingId: string,\n  auditRunId: string,\n  siteId: string,\n  pageId: string,\n  pageUrl: string,\n\n  source: string,          // e.g. \"cli\", \"extension\", \"ci\"\n  tool: string,            // e.g. \"axe-core\"\n  timestamp: ISODateString,\n\n  ruleId: string,\n  message: string,\n  selector?: string,\n\n  wcagTags: string[],\n  impact?: \"minor\" | \"moderate\" | \"serious\" | \"critical\",\n\n  findingType: \"violation\"\n}\n```\n\nRaw findings should **never aggregated or altered**.\n\n#### Example raw findings:\n\n```json\n[\n  {\n    \"rawFindingId\": \"6c04cb29-580f-49f7-9a7d-6402c97e8a17\",\n    \"auditRunId\": \"run-123\",\n    \"siteId\": \"example-site\",\n    \"pageId\": \"home\",\n    \"pageUrl\": \"https://example.com\",\n    \"source\": \"cli\",\n    \"tool\": \"axe-core\",\n    \"timestamp\": \"2025-12-30T17:26:13.218Z\",\n    \"ruleId\": \"landmark-main-is-top-level\",\n    \"message\": \"Ensure the main landmark is at top level\",\n    \"selector\": \"#webchat\",\n    \"wcagTags\": [\n      \"cat.semantics\",\n      \"best-practice\"\n    ],\n    \"impact\": \"moderate\",\n    \"findingType\": \"violation\"\n  },\n  {\n    \"rawFindingId\": \"8f79304d-ddb4-4575-aaf3-6af1a6d4d05a\",\n    \"auditRunId\": \"run-123\",\n    \"siteId\": \"example-site\",\n    \"pageId\": \"home\",\n    \"pageUrl\": \"https://example.com\",\n    \"source\": \"cli\",\n    \"tool\": \"axe-core\",\n    \"timestamp\": \"2025-12-30T17:26:18.442Z\",\n    \"ruleId\": \"label\",\n    \"message\": \"Ensure every form element has a label\",\n    \"selector\": \"#service-type-filter\",\n    \"wcagTags\": [\n      \"cat.forms\",\n      \"wcag2a\",\n      \"wcag412\",\n      \"section508\",\n      \"section508.22.n\",\n      \"TTv5\",\n      \"TT5.c\",\n      \"EN-301-549\",\n      \"EN-9.4.1.2\",\n      \"ACT\",\n      \"RGAAv4\",\n      \"RGAA-11.1.1\"\n    ],\n    \"impact\": \"critical\",\n    \"findingType\": \"violation\"\n  }\n]\n\n```\n\n------------------\n\n### Load an accessibility standard\n\nStandards are bundled with the package.\n\n```js\nimport { loadStandard } from \"@consevangelou/accessibility-audit-core\";\n\nconst standard = await loadStandard(\"EN301549_v3.2.1\");\n```\n\nThe returned object is a reference standard used during normalisation to:\n\n- Validate WCAG success criteria\n- Map findings to compliance requirements\n- Ensure conservative, standards-aligned reporting\n\nCurrently supported:\n\n- EN301549_v3.2.1 (WCAG 2.1)\n\n#### Standard schema\n\n```c#\n{\n  standardId: string,\n  wcagVersion: string,\n\n  criteria: {\n    [wcagCriterionId: string]: {\n      title: string,\n      level: \"A\" | \"AA\" | \"AAA\",\n      principle: string,\n      enClause: string,\n      userNeeds?: string[]\n    }\n  }\n}\n```\n\n- `criteria` is keyed by WCAG success criterion ID (e.g. `\"1.4.3\"`)\n- Only criteria present in this object are treated as **normative compliance targets**\n\n### Example standard object (excerpt)\n\n```json\n{\n  \"standardId\": \"EN301549_v3.2.1\",\n  \"wcagVersion\": \"2.1\",\n  \"criteria\": {\n    \"1.1.1\": {\n      \"title\": \"Non-text Content\",\n      \"level\": \"A\",\n      \"principle\": \"Perceivable\",\n      \"enClause\": \"9.1.1.1\",\n      \"userNeeds\": [\"WV\", \"LV\", \"LC\"]\n    },\n    \"1.4.3\": {\n      \"title\": \"Contrast (Minimum)\",\n      \"level\": \"AA\",\n      \"principle\": \"Perceivable\",\n      \"enClause\": \"9.1.4.3\",\n      \"userNeeds\": [\"LV\", \"LC\"]\n    },\n    \"4.1.2\": {\n      \"title\": \"Name, Role, Value\",\n      \"level\": \"A\",\n      \"principle\": \"Robust\",\n      \"enClause\": \"9.4.1.2\"\n    }\n  }\n}\n```\n\n\n------------------\n\n### Normalise findings\n\n```js\nimport { normaliseFindings } from \"@consevangelou/accessibility-audit-core\";\n\nconst normalised = normaliseFindings(rawFindings, standard);\n```\n\nThis function converts low-level raw findings into **grouped, standards-aligned summaries**.\n\nThe result separates findings into two categories:\n\n- **Compliance findings** — mapped to WCAG success criteria defined in the reference standard\n- **Other findings** — best-practice or non-normative issues not mapped to WCAG\n\n#### NormalisedFinding schema\n\nA **NormalisedFinding** represents a grouped summary of one or more raw findings,\n suitable for reporting and analysis.\n\n```c#\n{\n  auditRunId: string,\n  siteId: string,\n  pageId: string,\n  pageUrl: string,\n\n  wcagCriterionId: string | null // e.g. \"1.4.3\", \"4.1.2\"\n  ruleId: string | null,\n\n  classification: string        // e.g. \"automated-violation\",\n  severity: \"low\" | \"medium\" | \"high\" | \"critical\",\n\n  occurrenceCount: number,\n  sourceRawFindingIds: string[]\n}\n```\n\n#### Normalisation Grouping rules\n\n- If a WCAG success criterion can be resolved **and exists in the reference standard**\n   → the finding is grouped under **`compliance`**\n- If no WCAG criterion is resolved\n   → the finding is grouped under **`other`**\n\nThis separation ensures:\n\n- **Conservative compliance reporting**\n- **Clear distinction between normative and best-practice issues**\n- **Stable aggregation across multiple tools and runs**\n\n#### Example normalised finding\n\n```json\n{\n  \"compliance\": [\n    {\n      \"auditRunId\": \"run-123\",\n      \"siteId\": \"example-site\",\n      \"pageId\": \"home\",\n      \"pageUrl\": \"https://example.com\",\n      \"wcagCriterionId\": \"4.1.2\",\n      \"ruleId\": null,\n      \"classification\": \"automated-violation\",\n      \"severity\": \"critical\",\n      \"occurrenceCount\": 1,\n      \"sourceRawFindingIds\": [\n        \"8f79304d-ddb4-4575-aaf3-6af1a6d4d05a\"\n      ]\n    }\n  ],\n  \"other\": [\n    {\n      \"auditRunId\": \"run-123\",\n      \"siteId\": \"example-site\",\n      \"pageId\": \"home\",\n      \"pageUrl\": \"https://example.com\",\n      \"wcagCriterionId\": null,\n      \"ruleId\": \"landmark-main-is-top-level\",\n      \"classification\": \"automated-violation\",\n      \"severity\": \"medium\",\n      \"occurrenceCount\": 1,\n      \"sourceRawFindingIds\": [\n        \"6c04cb29-580f-49f7-9a7d-6402c97e8a17\"\n      ]\n    }\n  ]\n}\n```\n\n------------------\n\n## Output model (high-level)\n\nNormalised findings are grouped by:\n\n- WCAG Success Criterion (when applicable)\n- Tool rule ID (for non-WCAG findings)\n\nEach finding includes:\n\n- WCAG criterion (or `null`)\n- Severity\n- Classification\n- Occurrence count\n- Traceability to raw findings\n\nThis structure is designed for:\n\n- Compliance audits\n- Aggregation\n- Reporting pipelines\n- Manual audit supplementation\n\n## Compliance philosophy\n\nThis package follows a **conservative compliance model**:\n\n- A finding is only treated as a compliance issue when it can be reliably mapped to a normative WCAG Success Criterion.\n- Best-practice and advisory issues are preserved but explicitly separated.\n- No automated claim of conformance is made.\n\nFinal compliance decisions **must always involve human judgment**.\n\nFor more detail, see `NOTES.md`.\n\n## Intended consumers\n\nThis package is designed to be used by:\n\n- CLI audit tools\n- Browser extensions\n- Continuous monitoring systems\n- Internal government accessibility tooling\n\n## Notes\n\n- Empty arrays are always returned if no findings exist.\n- Compliance findings are strictly WCAG-mapped.\n\n## License\n\nMIT © 2025 Constantinos Evangelou\n","readmeFilename":"README.md"}