@skillsmith/core 0.11.3 → 0.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -9
- package/README.md +10 -7
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js +15 -5
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.private-registry.d.ts +80 -0
- package/dist/src/api/client.private-registry.d.ts.map +1 -0
- package/dist/src/api/client.private-registry.js +97 -0
- package/dist/src/api/client.private-registry.js.map +1 -0
- package/dist/src/api/client.private-registry.test.d.ts +9 -0
- package/dist/src/api/client.private-registry.test.d.ts.map +1 -0
- package/dist/src/api/client.private-registry.test.js +127 -0
- package/dist/src/api/client.private-registry.test.js.map +1 -0
- package/dist/src/api/client.toSkill.test.d.ts +25 -0
- package/dist/src/api/client.toSkill.test.d.ts.map +1 -0
- package/dist/src/api/client.toSkill.test.js +97 -0
- package/dist/src/api/client.toSkill.test.js.map +1 -0
- package/dist/src/api/client.token-refresh.d.ts +8 -0
- package/dist/src/api/client.token-refresh.d.ts.map +1 -1
- package/dist/src/api/client.token-refresh.js +26 -0
- package/dist/src/api/client.token-refresh.js.map +1 -1
- package/dist/src/api/client.token-refresh.test.js +82 -0
- package/dist/src/api/client.token-refresh.test.js.map +1 -1
- package/dist/src/api/index.d.ts +2 -0
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js +9 -0
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/security-summary.d.ts +73 -0
- package/dist/src/api/security-summary.d.ts.map +1 -0
- package/dist/src/api/security-summary.js +88 -0
- package/dist/src/api/security-summary.js.map +1 -0
- package/dist/src/api/security-summary.test.d.ts +9 -0
- package/dist/src/api/security-summary.test.d.ts.map +1 -0
- package/dist/src/api/security-summary.test.js +94 -0
- package/dist/src/api/security-summary.test.js.map +1 -0
- package/dist/src/config/config-atomic-write.d.ts +30 -10
- package/dist/src/config/config-atomic-write.d.ts.map +1 -1
- package/dist/src/config/config-atomic-write.js +33 -80
- package/dist/src/config/config-atomic-write.js.map +1 -1
- package/dist/src/config/config-atomic-write.test.d.ts +8 -0
- package/dist/src/config/config-atomic-write.test.d.ts.map +1 -1
- package/dist/src/config/config-atomic-write.test.js +64 -12
- package/dist/src/config/config-atomic-write.test.js.map +1 -1
- package/dist/src/config/owned-lock.acquire.d.ts +53 -0
- package/dist/src/config/owned-lock.acquire.d.ts.map +1 -0
- package/dist/src/config/owned-lock.acquire.js +140 -0
- package/dist/src/config/owned-lock.acquire.js.map +1 -0
- package/dist/src/config/owned-lock.claim.d.ts +84 -0
- package/dist/src/config/owned-lock.claim.d.ts.map +1 -0
- package/dist/src/config/owned-lock.claim.js +310 -0
- package/dist/src/config/owned-lock.claim.js.map +1 -0
- package/dist/src/config/owned-lock.d.ts +113 -0
- package/dist/src/config/owned-lock.d.ts.map +1 -0
- package/dist/src/config/owned-lock.js +121 -0
- package/dist/src/config/owned-lock.js.map +1 -0
- package/dist/src/config/owned-lock.test.d.ts +12 -0
- package/dist/src/config/owned-lock.test.d.ts.map +1 -0
- package/dist/src/config/owned-lock.test.js +412 -0
- package/dist/src/config/owned-lock.test.js.map +1 -0
- package/dist/src/config/owned-lock.types.d.ts +78 -0
- package/dist/src/config/owned-lock.types.d.ts.map +1 -0
- package/dist/src/config/owned-lock.types.js +30 -0
- package/dist/src/config/owned-lock.types.js.map +1 -0
- package/dist/src/db/createDatabase.d.ts.map +1 -1
- package/dist/src/db/createDatabase.js +19 -7
- package/dist/src/db/createDatabase.js.map +1 -1
- package/dist/src/embeddings/hnsw-store.exports.d.ts +11 -0
- package/dist/src/embeddings/hnsw-store.exports.d.ts.map +1 -0
- package/dist/src/embeddings/hnsw-store.exports.js +10 -0
- package/dist/src/embeddings/hnsw-store.exports.js.map +1 -0
- package/dist/src/embeddings/index.d.ts +1 -2
- package/dist/src/embeddings/index.d.ts.map +1 -1
- package/dist/src/embeddings/index.js +17 -3
- package/dist/src/embeddings/index.js.map +1 -1
- package/dist/src/embeddings/probe.d.ts.map +1 -1
- package/dist/src/embeddings/probe.js +4 -8
- package/dist/src/embeddings/probe.js.map +1 -1
- package/dist/src/exports/services.d.ts +4 -1
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.js +22 -0
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/index.d.ts +5 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +17 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/index.d.ts +1 -1
- package/dist/src/install/index.d.ts.map +1 -1
- package/dist/src/install/index.js +1 -1
- package/dist/src/install/index.js.map +1 -1
- package/dist/src/install/paths.d.ts +10 -0
- package/dist/src/install/paths.d.ts.map +1 -1
- package/dist/src/install/paths.js +19 -0
- package/dist/src/install/paths.js.map +1 -1
- package/dist/src/logging/logger.test.js +57 -0
- package/dist/src/logging/logger.test.js.map +1 -1
- package/dist/src/logging/rotation.d.ts +27 -2
- package/dist/src/logging/rotation.d.ts.map +1 -1
- package/dist/src/logging/rotation.js +44 -3
- package/dist/src/logging/rotation.js.map +1 -1
- package/dist/src/logging/rotation.test.js +69 -0
- package/dist/src/logging/rotation.test.js.map +1 -1
- package/dist/src/logging/types.d.ts +8 -2
- package/dist/src/logging/types.d.ts.map +1 -1
- package/dist/src/security/index.d.ts +2 -1
- package/dist/src/security/index.d.ts.map +1 -1
- package/dist/src/security/index.js +3 -0
- package/dist/src/security/index.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.d.ts +2 -2
- package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.evidence.d.ts +76 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.js +176 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.exec.d.ts +8 -1
- package/dist/src/security/scanner/SecurityScanner.exec.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.exec.js +58 -2
- package/dist/src/security/scanner/SecurityScanner.exec.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts +35 -10
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.js +106 -59
- package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.js +41 -13
- package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.pii.js +23 -1
- package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js +15 -3
- package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts +11 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.js +18 -7
- package/dist/src/security/scanner/SecurityScanner.ssrf.js.map +1 -1
- package/dist/src/security/scanner/index.d.ts +3 -3
- package/dist/src/security/scanner/index.d.ts.map +1 -1
- package/dist/src/security/scanner/index.js +5 -2
- package/dist/src/security/scanner/index.js.map +1 -1
- package/dist/src/security/scanner/multiline-category-closure.test.d.ts +80 -0
- package/dist/src/security/scanner/multiline-category-closure.test.d.ts.map +1 -0
- package/dist/src/security/scanner/multiline-category-closure.test.js +287 -0
- package/dist/src/security/scanner/multiline-category-closure.test.js.map +1 -0
- package/dist/src/security/scanner/patterns.d.ts +41 -14
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.jailbreak.d.ts +41 -0
- package/dist/src/security/scanner/patterns.jailbreak.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.d.ts +35 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.js +119 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.js.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.js +370 -0
- package/dist/src/security/scanner/patterns.jailbreak.js.map +1 -0
- package/dist/src/security/scanner/patterns.js +101 -82
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/security/scanner/patterns.scope.d.ts +62 -0
- package/dist/src/security/scanner/patterns.scope.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.scope.js +207 -0
- package/dist/src/security/scanner/patterns.scope.js.map +1 -0
- package/dist/src/security/scanner/regex-utils.d.ts +20 -0
- package/dist/src/security/scanner/regex-utils.d.ts.map +1 -1
- package/dist/src/security/scanner/regex-utils.js +20 -0
- package/dist/src/security/scanner/regex-utils.js.map +1 -1
- package/dist/src/security/scanner/types.d.ts +35 -0
- package/dist/src/security/scanner/types.d.ts.map +1 -1
- package/dist/src/services/recommend-guard.d.ts +28 -0
- package/dist/src/services/recommend-guard.d.ts.map +1 -0
- package/dist/src/services/recommend-guard.js +34 -0
- package/dist/src/services/recommend-guard.js.map +1 -0
- package/dist/src/services/recommend-guard.test.d.ts +2 -0
- package/dist/src/services/recommend-guard.test.d.ts.map +1 -0
- package/dist/src/services/recommend-guard.test.js +28 -0
- package/dist/src/services/recommend-guard.test.js.map +1 -0
- package/dist/src/services/skill-installation.content.d.ts +88 -0
- package/dist/src/services/skill-installation.content.d.ts.map +1 -0
- package/dist/src/services/skill-installation.content.js +319 -0
- package/dist/src/services/skill-installation.content.js.map +1 -0
- package/dist/src/services/skill-installation.helpers.d.ts +32 -1
- package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
- package/dist/src/services/skill-installation.helpers.js +39 -6
- package/dist/src/services/skill-installation.helpers.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.test.js +34 -2
- package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
- package/dist/src/services/skill-installation.io.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.js +86 -2
- package/dist/src/services/skill-installation.io.js.map +1 -1
- package/dist/src/services/skill-installation.service.d.ts +20 -1
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.js +26 -4
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/services/skill-installation.types.d.ts +42 -1
- package/dist/src/services/skill-installation.types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.types.js.map +1 -1
- package/dist/src/services/skill-resolution.d.ts +67 -0
- package/dist/src/services/skill-resolution.d.ts.map +1 -0
- package/dist/src/services/skill-resolution.js +67 -0
- package/dist/src/services/skill-resolution.js.map +1 -0
- package/dist/src/services/skill-resolution.test.d.ts +2 -0
- package/dist/src/services/skill-resolution.test.d.ts.map +1 -0
- package/dist/src/services/skill-resolution.test.js +143 -0
- package/dist/src/services/skill-resolution.test.js.map +1 -0
- package/dist/src/sync/inventory-collector.d.ts.map +1 -1
- package/dist/src/sync/inventory-collector.js +2 -2
- package/dist/src/sync/inventory-collector.js.map +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +4 -0
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/quiet-mode.d.ts +21 -0
- package/dist/src/utils/quiet-mode.d.ts.map +1 -0
- package/dist/src/utils/quiet-mode.js +26 -0
- package/dist/src/utils/quiet-mode.js.map +1 -0
- package/dist/tests/EmbeddingService.test.js +58 -1
- package/dist/tests/EmbeddingService.test.js.map +1 -1
- package/dist/tests/SecurityScanner.ai-defence.test.js +32 -7
- package/dist/tests/SecurityScanner.ai-defence.test.js.map +1 -1
- package/dist/tests/SecurityScanner.exec.test.js +79 -0
- package/dist/tests/SecurityScanner.exec.test.js.map +1 -1
- package/dist/tests/SecurityScanner.performance.test.js +5 -2
- package/dist/tests/SecurityScanner.performance.test.js.map +1 -1
- package/dist/tests/db/database-abstraction.test.js +45 -1
- package/dist/tests/db/database-abstraction.test.js.map +1 -1
- package/dist/tests/helpers/deterministic-dead-pid.d.ts +13 -0
- package/dist/tests/helpers/deterministic-dead-pid.d.ts.map +1 -0
- package/dist/tests/helpers/deterministic-dead-pid.js +31 -0
- package/dist/tests/helpers/deterministic-dead-pid.js.map +1 -0
- package/dist/tests/integration/owned-lock-lost-update.test.d.ts +12 -0
- package/dist/tests/integration/owned-lock-lost-update.test.d.ts.map +1 -0
- package/dist/tests/integration/owned-lock-lost-update.test.js +52 -0
- package/dist/tests/integration/owned-lock-lost-update.test.js.map +1 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts +19 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts.map +1 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.js +177 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.js.map +1 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.js +6 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.js.map +1 -1
- package/dist/tests/security/ContinuousSecurity.test.js +15 -0
- package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
- package/dist/tests/security/ad-crlf-injection.test.d.ts +18 -0
- package/dist/tests/security/ad-crlf-injection.test.d.ts.map +1 -0
- package/dist/tests/security/ad-crlf-injection.test.js +150 -0
- package/dist/tests/security/ad-crlf-injection.test.js.map +1 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts +25 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts.map +1 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.js +138 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.js.map +1 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.d.ts +15 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.d.ts.map +1 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.js +60 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.js.map +1 -0
- package/dist/tests/security/pattern-scope.test.d.ts +17 -0
- package/dist/tests/security/pattern-scope.test.d.ts.map +1 -0
- package/dist/tests/security/pattern-scope.test.js +128 -0
- package/dist/tests/security/pattern-scope.test.js.map +1 -0
- package/dist/tests/security/pii-detection.test.js +39 -0
- package/dist/tests/security/pii-detection.test.js.map +1 -1
- package/dist/tests/security/scanner-evidence-tiers.test.d.ts +30 -0
- package/dist/tests/security/scanner-evidence-tiers.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-evidence-tiers.test.js +258 -0
- package/dist/tests/security/scanner-evidence-tiers.test.js.map +1 -0
- package/dist/tests/security/scanner-privesc-severity.test.d.ts +23 -0
- package/dist/tests/security/scanner-privesc-severity.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-privesc-severity.test.js +43 -0
- package/dist/tests/security/scanner-privesc-severity.test.js.map +1 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.d.ts +20 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.js +71 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.js.map +1 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts +24 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.js +59 -3
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
- package/dist/tests/security/scanner-ssrf-word-boundary.test.d.ts +19 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.js +65 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.js.map +1 -0
- package/dist/tests/security.test.js +11 -2
- package/dist/tests/security.test.js.map +1 -1
- package/dist/tests/skill-scanner/allowlist.test.js +15 -7
- package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.content.test.d.ts +10 -0
- package/dist/tests/unit/services/skill-installation.content.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.content.test.js +290 -0
- package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts +8 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.js +72 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.test.js +54 -1
- package/dist/tests/unit/services/skill-installation.io.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts +15 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js +190 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts +17 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.js +126 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.test.js +7 -112
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/dist/tests/utils/quiet-mode.test.d.ts +12 -0
- package/dist/tests/utils/quiet-mode.test.d.ts.map +1 -0
- package/dist/tests/utils/quiet-mode.test.js +42 -0
- package/dist/tests/utils/quiet-mode.test.js.map +1 -0
- package/package.json +17 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../../src/security/scanner/patterns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,0BAA0B;AAC1B,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,YAAY;IACZ,uBAAuB;IACvB,2BAA2B;IAC3B,WAAW;IACX,WAAW;IACX,oBAAoB;IACpB,eAAe;IACf,WAAW;IACX,iBAAiB;IACjB,uBAAuB;IACvB,YAAY;IACZ,oBAAoB;CACrB,CAAA;AAED,+BAA+B;AAC/B,qFAAqF;AACrF,0EAA0E;AAC1E,kFAAkF;AAClF,4EAA4E;AAC5E,EAAE;AACF,oFAAoF;AACpF,uFAAuF;AACvF,gFAAgF;AAChF,mFAAmF;AACnF,sFAAsF;AACtF,+EAA+E;AAC/E,2EAA2E;AAC3E,mFAAmF;AACnF,iEAAiE;AACjE,oCAAoC;AACpC,uFAAuF;AACvF,sFAAsF;AACtF,oFAAoF;AACpF,kFAAkF;AAClF,mDAAmD;AAEnD,uFAAuF;AACvF,mFAAmF;AACnF,uFAAuF;AACvF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,iEAAiE,CAAA;AAEjG,6FAA6F;AAC7F,MAAM,eAAe,GAAG,cAAc,CAAA;AACtC,MAAM,kBAAkB,GAAG,iBAAiB,CAAA;AAE5C,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,gBAAgB;IAChB,iEAAiE;IACjE,2CAA2C;IAC3C,qBAAqB;IACrB,wDAAwD;IACxD,oBAAoB;IACpB,2BAA2B;IAC3B,SAAS;IACT,SAAS;IACT,SAAS;IACT,0EAA0E;IAC1E,kBAAkB;IAClB,eAAe;IACf,kBAAkB;IAClB,WAAW;IACX,WAAW;IACX,cAAc;IACd,wEAAwE;IACxE,uEAAuE;IACvE,0EAA0E;IAC1E,2CAA2C;CAC5C,CAAA;AAED,sFAAsF;AACtF,gFAAgF;AAChF,MAAM,CAAC,MAAM,4BAA4B,GAAwB,IAAI,GAAG,CAAC;IACvE,eAAe;IACf,kBAAkB;CACnB,CAAC,CAAA;AAEF,6BAA6B;AAC7B,
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../../src/security/scanner/patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5881: Pattern scope model — replaces the old per-source-text
|
|
3
|
+
* multiline-detection heuristic function (formerly in
|
|
4
|
+
* SecurityScanner.helpers.ts, deleted entirely, no compatibility shim).
|
|
5
|
+
* @module @skillsmith/core/security/scanner/patterns.scope
|
|
6
|
+
*
|
|
7
|
+
* The deleted heuristic sniffed a regex's SOURCE TEXT for the literal
|
|
8
|
+
* two-character sequences `\r`/`\n` (or a `(?:^|\n)` prefix) to decide
|
|
9
|
+
* whether a pattern should be tested against the full document (`content`)
|
|
10
|
+
* or per-line. This heuristic was wrong in BOTH directions:
|
|
11
|
+
*
|
|
12
|
+
* - False negative: a pattern that spans lines via a bounded `[\s\S]{0,N}`
|
|
13
|
+
* character class (which matches a literal newline character at runtime)
|
|
14
|
+
* but has no literal `\r`/`\n` ESCAPE SEQUENCE in its regex source was
|
|
15
|
+
* scanned per-line only, so a genuinely cross-line attack could never fire
|
|
16
|
+
* (AD_HTML_COMMENT_VERB/NOUN, AD_NESTED_INSTRUCTION_BLOCK, AD_ZERO_WIDTH).
|
|
17
|
+
* - False positive: a pattern containing a NEGATED newline-excluding class
|
|
18
|
+
* (`[^\n]{0,80}?`, deliberately forbidding a newline crossing) still
|
|
19
|
+
* contains the literal substring `\n` in its `.source` text, so the naive
|
|
20
|
+
* heuristic misclassified it as content-scope anyway (JB_JS3A/JS3B,
|
|
21
|
+
* AD_AN3A) — harmless today (these patterns are correctly kept out of the
|
|
22
|
+
* per-line pass since they were never meant to be tested there either) but
|
|
23
|
+
* still a real classification bug, not deliberate design.
|
|
24
|
+
*
|
|
25
|
+
* PATTERN_SCOPE replaces the heuristic with an explicit, fail-closed,
|
|
26
|
+
* per-pattern declaration: `'line'` (per-line pass only), `'content'`
|
|
27
|
+
* (full-document pass only), or `'both'` (tested in both passes — needed to
|
|
28
|
+
* fix the false-negative class above without losing existing single-line
|
|
29
|
+
* coverage). There is no default: an unmapped pattern throws at scan time
|
|
30
|
+
* (`resolvePatternScope`) and the whole module fails to load if any pattern
|
|
31
|
+
* in `SCOPED_PATTERN_SETS` is missing an entry (`assertScopeCoverage`, called
|
|
32
|
+
* at the bottom of this file). Unlike the evidence-tier map (which safely
|
|
33
|
+
* defaults an unmapped pattern to its STRONGEST tier), scope has no
|
|
34
|
+
* analogous safe default — a pattern silently scanned in the WRONG pass (or
|
|
35
|
+
* neither) is a silent coverage gap, not a conservative failure mode.
|
|
36
|
+
*
|
|
37
|
+
* Every scope assignment below is BASELINE-PRESERVING relative to the old
|
|
38
|
+
* heuristic's actual current behavior, with exactly 4 explicit promotions
|
|
39
|
+
* (`'line'` → `'both'`, section 1.4 of the SMI-5881 design): AD_HTML_COMMENT_
|
|
40
|
+
* VERB, AD_HTML_COMMENT_NOUN, AD_NESTED_INSTRUCTION_BLOCK, AD_ZERO_WIDTH.
|
|
41
|
+
* Every other pattern — including the two known false positives above
|
|
42
|
+
* (JB_JS3A/JS3B, AD_AN3A) — keeps whatever scope the old heuristic already
|
|
43
|
+
* computed for it; re-scoping any of those changes finding cardinality and
|
|
44
|
+
* needs its own corpus review, out of scope for this P0 fix.
|
|
45
|
+
*/
|
|
46
|
+
export type PatternScope = 'line' | 'content' | 'both';
|
|
47
|
+
export declare const PATTERN_SCOPE: ReadonlyMap<RegExp, PatternScope>;
|
|
48
|
+
/** Every pattern array consumed by a scope-resolving scan function. */
|
|
49
|
+
export declare const SCOPED_PATTERN_SETS: ReadonlyArray<{
|
|
50
|
+
name: string;
|
|
51
|
+
patterns: readonly RegExp[];
|
|
52
|
+
}>;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve a pattern's scope by object identity. Throws (does NOT default) for
|
|
55
|
+
* any pattern reaching a scope-resolving scanner without a PATTERN_SCOPE
|
|
56
|
+
* entry — there is no safe default direction for scope the way there is for
|
|
57
|
+
* evidence tier (classifyEvidence's fail-closed-to-strongest-tier doesn't
|
|
58
|
+
* apply here: a pattern scanned in the wrong pass, or neither, is a silent
|
|
59
|
+
* coverage gap regardless of which "direction" you'd guess).
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolvePatternScope(pattern: RegExp): PatternScope;
|
|
62
|
+
//# sourceMappingURL=patterns.scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.scope.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/patterns.scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAKH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAA;AA+EtD,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAI1D,CAAA;AAEF,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAI5F,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CASjE"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5881: Pattern scope model — replaces the old per-source-text
|
|
3
|
+
* multiline-detection heuristic function (formerly in
|
|
4
|
+
* SecurityScanner.helpers.ts, deleted entirely, no compatibility shim).
|
|
5
|
+
* @module @skillsmith/core/security/scanner/patterns.scope
|
|
6
|
+
*
|
|
7
|
+
* The deleted heuristic sniffed a regex's SOURCE TEXT for the literal
|
|
8
|
+
* two-character sequences `\r`/`\n` (or a `(?:^|\n)` prefix) to decide
|
|
9
|
+
* whether a pattern should be tested against the full document (`content`)
|
|
10
|
+
* or per-line. This heuristic was wrong in BOTH directions:
|
|
11
|
+
*
|
|
12
|
+
* - False negative: a pattern that spans lines via a bounded `[\s\S]{0,N}`
|
|
13
|
+
* character class (which matches a literal newline character at runtime)
|
|
14
|
+
* but has no literal `\r`/`\n` ESCAPE SEQUENCE in its regex source was
|
|
15
|
+
* scanned per-line only, so a genuinely cross-line attack could never fire
|
|
16
|
+
* (AD_HTML_COMMENT_VERB/NOUN, AD_NESTED_INSTRUCTION_BLOCK, AD_ZERO_WIDTH).
|
|
17
|
+
* - False positive: a pattern containing a NEGATED newline-excluding class
|
|
18
|
+
* (`[^\n]{0,80}?`, deliberately forbidding a newline crossing) still
|
|
19
|
+
* contains the literal substring `\n` in its `.source` text, so the naive
|
|
20
|
+
* heuristic misclassified it as content-scope anyway (JB_JS3A/JS3B,
|
|
21
|
+
* AD_AN3A) — harmless today (these patterns are correctly kept out of the
|
|
22
|
+
* per-line pass since they were never meant to be tested there either) but
|
|
23
|
+
* still a real classification bug, not deliberate design.
|
|
24
|
+
*
|
|
25
|
+
* PATTERN_SCOPE replaces the heuristic with an explicit, fail-closed,
|
|
26
|
+
* per-pattern declaration: `'line'` (per-line pass only), `'content'`
|
|
27
|
+
* (full-document pass only), or `'both'` (tested in both passes — needed to
|
|
28
|
+
* fix the false-negative class above without losing existing single-line
|
|
29
|
+
* coverage). There is no default: an unmapped pattern throws at scan time
|
|
30
|
+
* (`resolvePatternScope`) and the whole module fails to load if any pattern
|
|
31
|
+
* in `SCOPED_PATTERN_SETS` is missing an entry (`assertScopeCoverage`, called
|
|
32
|
+
* at the bottom of this file). Unlike the evidence-tier map (which safely
|
|
33
|
+
* defaults an unmapped pattern to its STRONGEST tier), scope has no
|
|
34
|
+
* analogous safe default — a pattern silently scanned in the WRONG pass (or
|
|
35
|
+
* neither) is a silent coverage gap, not a conservative failure mode.
|
|
36
|
+
*
|
|
37
|
+
* Every scope assignment below is BASELINE-PRESERVING relative to the old
|
|
38
|
+
* heuristic's actual current behavior, with exactly 4 explicit promotions
|
|
39
|
+
* (`'line'` → `'both'`, section 1.4 of the SMI-5881 design): AD_HTML_COMMENT_
|
|
40
|
+
* VERB, AD_HTML_COMMENT_NOUN, AD_NESTED_INSTRUCTION_BLOCK, AD_ZERO_WIDTH.
|
|
41
|
+
* Every other pattern — including the two known false positives above
|
|
42
|
+
* (JB_JS3A/JS3B, AD_AN3A) — keeps whatever scope the old heuristic already
|
|
43
|
+
* computed for it; re-scoping any of those changes finding cardinality and
|
|
44
|
+
* needs its own corpus review, out of scope for this P0 fix.
|
|
45
|
+
*/
|
|
46
|
+
import { JAILBREAK_PATTERNS, AI_DEFENCE_PATTERNS } from './patterns.jailbreak.js';
|
|
47
|
+
import { SSRF_INSTRUCTION_PATTERNS } from './patterns.js';
|
|
48
|
+
// Index-aligned with JAILBREAK_PATTERNS (patterns.jailbreak.ts). Every entry
|
|
49
|
+
// here is 'line' except the two naive-heuristic false positives (JB_JS3A/
|
|
50
|
+
// JS3B, index 17/18 — see module doc comment) and the 3 genuinely multi-line
|
|
51
|
+
// split-word patterns (index 20-22), both baseline-preserving, not promoted.
|
|
52
|
+
const JAILBREAK_SCOPE = [
|
|
53
|
+
'line', // JB_IGNORE_PREVIOUS
|
|
54
|
+
'line', // JB_DISREGARD_PREVIOUS
|
|
55
|
+
'line', // JB_DEVELOPER_MODE
|
|
56
|
+
'line', // JB_DAN_BARE
|
|
57
|
+
'line', // JB_DO_ANYTHING_NOW
|
|
58
|
+
'line', // JB_JAILBREAK_BARE
|
|
59
|
+
'line', // JB_BYPASS_RESTRICTIONS
|
|
60
|
+
'line', // JB_PRETEND_NO_RESTRICTIONS
|
|
61
|
+
'line', // JB_ACT_NO_ETHICS
|
|
62
|
+
'line', // JB_YOU_ARE_NOW_FREE
|
|
63
|
+
'line', // JB_IGNORE_SAFETY_GUIDELINES
|
|
64
|
+
'line', // JB_HYPOTHETICAL_SCENARIO
|
|
65
|
+
'line', // JB_JN1_MODE_FRAME
|
|
66
|
+
'line', // JB_JN2_DEVELOPER_MODE_FRAME
|
|
67
|
+
'line', // JB_JN3_PERSONA_FRAME
|
|
68
|
+
'line', // JB_JS1_STATE_BARE
|
|
69
|
+
'line', // JB_JS2_NOUN_MODE_STATE
|
|
70
|
+
'content', // JB_JS3A_DEV_MODE_THEN_CAPABILITY (naive-heuristic FP, baseline-preserved)
|
|
71
|
+
'content', // JB_JS3B_CAPABILITY_THEN_DEV_MODE (naive-heuristic FP, baseline-preserved)
|
|
72
|
+
'line', // JB_JS4_OBEDIENCE_COMPULSION
|
|
73
|
+
'content', // JB_SPLIT_IGNORE (genuinely multi-line)
|
|
74
|
+
'content', // JB_SPLIT_DISREGARD (genuinely multi-line)
|
|
75
|
+
'content', // JB_SPLIT_BYPASS (genuinely multi-line)
|
|
76
|
+
];
|
|
77
|
+
// Index-aligned with AI_DEFENCE_PATTERNS (patterns.jailbreak.ts). Indices
|
|
78
|
+
// 2, 3, 10, 13 are the 4 explicit promotions ('line' -> 'both', SMI-5881 P0
|
|
79
|
+
// follow-up); index 19 (AD_AN3A) is the naive-heuristic FP, baseline-preserved
|
|
80
|
+
// as 'content' despite its own name/comment implying line-scope.
|
|
81
|
+
const AI_DEFENCE_SCOPE = [
|
|
82
|
+
'content', // AD_ROLE_MARKER_BARE
|
|
83
|
+
'line', // AD_BRACKET_HIDDEN (deliberately kept line-only, see patterns.jailbreak.ts)
|
|
84
|
+
'both', // AD_HTML_COMMENT_VERB — PROMOTED (was 'line')
|
|
85
|
+
'both', // AD_HTML_COMMENT_NOUN — PROMOTED (was 'line')
|
|
86
|
+
'line', // AD_HOMOGRAPH_RUN_PLUS_KEYWORD
|
|
87
|
+
'line', // AD_MIXED_SCRIPT_WORD
|
|
88
|
+
'line', // AD_XML_TAG_BARE (deliberately kept line-only, see patterns.jailbreak.ts)
|
|
89
|
+
'line', // AD_BASE64_INSTRUCTIONS
|
|
90
|
+
'content', // AD_DELIMITER_BARE
|
|
91
|
+
'line', // AD_JSON_ROLE_FIELD
|
|
92
|
+
'both', // AD_NESTED_INSTRUCTION_BLOCK — PROMOTED (was 'line')
|
|
93
|
+
'content', // AD_CRLF_INJECTION (the P0 pattern — see patterns.jailbreak.ts)
|
|
94
|
+
'line', // AD_TEMPLATE_LITERAL
|
|
95
|
+
'both', // AD_ZERO_WIDTH — PROMOTED (was 'line')
|
|
96
|
+
'line', // AD_MARKDOWN_LINK_PAYLOAD
|
|
97
|
+
'line', // AD_ESCAPE_SEQUENCE_ABUSE
|
|
98
|
+
'line', // AD_ZALGO_COMBINING
|
|
99
|
+
'line', // AD_AN1_ROLE_BODY_SAME_LINE
|
|
100
|
+
'content', // AD_AN2_ROLE_BODY_NEXT_LINE
|
|
101
|
+
'content', // AD_AN3A_CHAT_TOKEN_BODY_SAME_LINE (naive-heuristic FP, baseline-preserved)
|
|
102
|
+
'content', // AD_AN3B_CHAT_TOKEN_BODY_NEXT_LINE
|
|
103
|
+
];
|
|
104
|
+
// Index-aligned with SSRF_INSTRUCTION_PATTERNS (patterns.ts). None are 'both'
|
|
105
|
+
// — scanSsrfPatterns' older skip-based two-pass cannot correctly service it
|
|
106
|
+
// (see assertScopeCoverage's SSRF-never-'both' assertion below).
|
|
107
|
+
const SSRF_SCOPE = [
|
|
108
|
+
'line', // file://
|
|
109
|
+
'line', // gopher://
|
|
110
|
+
'line', // dict://
|
|
111
|
+
'line', // ldap://
|
|
112
|
+
'line', // localhost
|
|
113
|
+
'line', // 127.0.0.\d+
|
|
114
|
+
'line', // 0.0.0.0
|
|
115
|
+
'line', // 169.254.169.254 (cloud metadata, bare)
|
|
116
|
+
'line', // file:///etc/(passwd|shadow|hosts) (bare)
|
|
117
|
+
'line', // gopher://localhost (bare)
|
|
118
|
+
'content', // multiline file://
|
|
119
|
+
'content', // multiline localhost/127/0.0.0.0
|
|
120
|
+
'content', // multiline gopher://
|
|
121
|
+
];
|
|
122
|
+
export const PATTERN_SCOPE = new Map([
|
|
123
|
+
...JAILBREAK_PATTERNS.map((p, i) => [p, JAILBREAK_SCOPE[i]]),
|
|
124
|
+
...AI_DEFENCE_PATTERNS.map((p, i) => [p, AI_DEFENCE_SCOPE[i]]),
|
|
125
|
+
...SSRF_INSTRUCTION_PATTERNS.map((p, i) => [p, SSRF_SCOPE[i]]),
|
|
126
|
+
]);
|
|
127
|
+
/** Every pattern array consumed by a scope-resolving scan function. */
|
|
128
|
+
export const SCOPED_PATTERN_SETS = [
|
|
129
|
+
{ name: 'JAILBREAK_PATTERNS', patterns: JAILBREAK_PATTERNS },
|
|
130
|
+
{ name: 'AI_DEFENCE_PATTERNS', patterns: AI_DEFENCE_PATTERNS },
|
|
131
|
+
{ name: 'SSRF_INSTRUCTION_PATTERNS', patterns: SSRF_INSTRUCTION_PATTERNS },
|
|
132
|
+
];
|
|
133
|
+
/**
|
|
134
|
+
* Resolve a pattern's scope by object identity. Throws (does NOT default) for
|
|
135
|
+
* any pattern reaching a scope-resolving scanner without a PATTERN_SCOPE
|
|
136
|
+
* entry — there is no safe default direction for scope the way there is for
|
|
137
|
+
* evidence tier (classifyEvidence's fail-closed-to-strongest-tier doesn't
|
|
138
|
+
* apply here: a pattern scanned in the wrong pass, or neither, is a silent
|
|
139
|
+
* coverage gap regardless of which "direction" you'd guess).
|
|
140
|
+
*/
|
|
141
|
+
export function resolvePatternScope(pattern) {
|
|
142
|
+
const scope = PATTERN_SCOPE.get(pattern);
|
|
143
|
+
if (scope === undefined) {
|
|
144
|
+
throw new Error(`[SecurityScanner] pattern /${pattern.source}/${pattern.flags} has no PATTERN_SCOPE entry. ` +
|
|
145
|
+
`Every pattern reaching a scope-resolving scanner must declare 'line' | 'content' | 'both'.`);
|
|
146
|
+
}
|
|
147
|
+
return scope;
|
|
148
|
+
}
|
|
149
|
+
const VALID_SCOPES = new Set(['line', 'content', 'both']);
|
|
150
|
+
/**
|
|
151
|
+
* Named (patterns, scope) pairs consumed by the length-parity and
|
|
152
|
+
* value-validity checks below. Kept separate from SCOPED_PATTERN_SETS (which
|
|
153
|
+
* only names the pattern arrays, not their scope-array counterpart) so a
|
|
154
|
+
* length mismatch between a PATTERNS array and its SCOPE array is caught
|
|
155
|
+
* directly, rather than relying on index-aligned `.map()` silently reading
|
|
156
|
+
* past the shorter array's end (see assertScopeCoverage's doc comment).
|
|
157
|
+
*/
|
|
158
|
+
const SCOPE_ARRAY_PAIRS = [
|
|
159
|
+
{ name: 'JAILBREAK_PATTERNS', patterns: JAILBREAK_PATTERNS, scopes: JAILBREAK_SCOPE },
|
|
160
|
+
{ name: 'AI_DEFENCE_PATTERNS', patterns: AI_DEFENCE_PATTERNS, scopes: AI_DEFENCE_SCOPE },
|
|
161
|
+
{ name: 'SSRF_INSTRUCTION_PATTERNS', patterns: SSRF_INSTRUCTION_PATTERNS, scopes: SSRF_SCOPE },
|
|
162
|
+
];
|
|
163
|
+
/**
|
|
164
|
+
* Module-load gate: throws (making this module un-importable) if any pattern
|
|
165
|
+
* in SCOPED_PATTERN_SETS lacks a PATTERN_SCOPE entry, if any
|
|
166
|
+
* SSRF_INSTRUCTION_PATTERNS member is scoped 'both' (scanSsrfPatterns' older
|
|
167
|
+
* skip-based two-pass, SecurityScanner.ssrf.ts, cannot correctly service
|
|
168
|
+
* 'both' — see its own inline comment), OR — the case `Map.has()` alone
|
|
169
|
+
* cannot catch — if a PATTERNS array and its index-aligned SCOPE array have
|
|
170
|
+
* drifted out of length parity (e.g. a pattern appended without a
|
|
171
|
+
* corresponding scope entry). `new Map([[p, undefined]])` still reports
|
|
172
|
+
* `.has(p) === true`, so an out-of-range `SCOPE[i]` read during the Map's
|
|
173
|
+
* construction would silently pass a has()-only check; the explicit
|
|
174
|
+
* length-equality and value-membership checks below close that gap.
|
|
175
|
+
* Deterministic (no data dependence), so it can't be silently skipped by a
|
|
176
|
+
* lucky test-ordering fluke.
|
|
177
|
+
*/
|
|
178
|
+
function assertScopeCoverage() {
|
|
179
|
+
for (const { name, patterns, scopes } of SCOPE_ARRAY_PAIRS) {
|
|
180
|
+
if (patterns.length !== scopes.length) {
|
|
181
|
+
throw new Error(`[SecurityScanner] ${name} has ${patterns.length} pattern(s) but its scope array has ` +
|
|
182
|
+
`${scopes.length} entries — they must be index-aligned and equal length. ` +
|
|
183
|
+
`Add or remove a scope entry in patterns.scope.ts to match.`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
for (const { name, patterns } of SCOPED_PATTERN_SETS) {
|
|
187
|
+
patterns.forEach((pattern, index) => {
|
|
188
|
+
const scope = PATTERN_SCOPE.get(pattern);
|
|
189
|
+
if (!PATTERN_SCOPE.has(pattern) || scope === undefined) {
|
|
190
|
+
throw new Error(`[SecurityScanner] ${name}[${index}] (/${pattern.source}/${pattern.flags}) has no ` +
|
|
191
|
+
`PATTERN_SCOPE entry. Add one to patterns.scope.ts before this pattern can be scanned.`);
|
|
192
|
+
}
|
|
193
|
+
if (!VALID_SCOPES.has(scope)) {
|
|
194
|
+
throw new Error(`[SecurityScanner] ${name}[${index}] (/${pattern.source}/${pattern.flags}) has an invalid ` +
|
|
195
|
+
`PATTERN_SCOPE value ${JSON.stringify(scope)} — must be 'line', 'content', or 'both'.`);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
SSRF_INSTRUCTION_PATTERNS.forEach((pattern, index) => {
|
|
200
|
+
if (PATTERN_SCOPE.get(pattern) === 'both') {
|
|
201
|
+
throw new Error(`[SecurityScanner] SSRF_INSTRUCTION_PATTERNS[${index}] (/${pattern.source}/${pattern.flags}) ` +
|
|
202
|
+
`is scoped 'both', but scanSsrfPatterns' two-pass cannot service 'both' — use 'line' or 'content'.`);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
assertScopeCoverage();
|
|
207
|
+
//# sourceMappingURL=patterns.scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.scope.js","sourceRoot":"","sources":["../../../../src/security/scanner/patterns.scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,26 @@
|
|
|
10
10
|
* to prevent catastrophic backtracking attacks.
|
|
11
11
|
*/
|
|
12
12
|
export declare const MAX_LINE_LENGTH_FOR_REGEX = 10000;
|
|
13
|
+
/**
|
|
14
|
+
* SMI-5881: Cap for the FULL-CONTENT (multiline "pass 1") regex scan, in
|
|
15
|
+
* UTF-16 code units (JavaScript `string.length` — NOT bytes/code points; see
|
|
16
|
+
* SecurityScanner.ts's content-length finding message).
|
|
17
|
+
*
|
|
18
|
+
* Equal to MAX_LINE_LENGTH_FOR_REGEX today (both 10_000) but declared
|
|
19
|
+
* separately because the two caps protect different scan passes (per-line vs
|
|
20
|
+
* whole-document) and may need to diverge later. This is a ReDoS budget
|
|
21
|
+
* input, not a free parameter — raising it requires first proving
|
|
22
|
+
* AD_CRLF_INJECTION-class patterns stay linear at the new size. Measured
|
|
23
|
+
* (SMI-5881): the fixed AD_CRLF_INJECTION pattern is already ~4x slower per
|
|
24
|
+
* doubling of input size on some adversarial inputs at sizes past this cap,
|
|
25
|
+
* extrapolating to unacceptable latency well before 1,000,000 — so this cap
|
|
26
|
+
* is NOT raised as part of SMI-5881 even though larger trust tiers allow a
|
|
27
|
+
* much bigger `maxContentLength`. See SecurityScanner.ts's
|
|
28
|
+
* `effectiveMultilineLimit` (`Math.min(MAX_CONTENT_LENGTH_FOR_REGEX,
|
|
29
|
+
* maxContentLength)`) for how this interacts with the per-tier content-length
|
|
30
|
+
* ceiling.
|
|
31
|
+
*/
|
|
32
|
+
export declare const MAX_CONTENT_LENGTH_FOR_REGEX = 10000;
|
|
13
33
|
/**
|
|
14
34
|
* SMI-882: Safe regex test with length limit
|
|
15
35
|
* Applies input length limit before regex matching to prevent ReDoS attacks.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regex-utils.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/regex-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAAQ,CAAA;AAE9C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAkC,GAC5C,gBAAgB,GAAG,IAAI,CAIzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAkC,GAC5C,OAAO,CAIT"}
|
|
1
|
+
{"version":3,"file":"regex-utils.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/regex-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAAQ,CAAA;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,4BAA4B,QAA4B,CAAA;AAErE;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAkC,GAC5C,gBAAgB,GAAG,IAAI,CAIzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAkC,GAC5C,OAAO,CAIT"}
|
|
@@ -10,6 +10,26 @@
|
|
|
10
10
|
* to prevent catastrophic backtracking attacks.
|
|
11
11
|
*/
|
|
12
12
|
export const MAX_LINE_LENGTH_FOR_REGEX = 10000;
|
|
13
|
+
/**
|
|
14
|
+
* SMI-5881: Cap for the FULL-CONTENT (multiline "pass 1") regex scan, in
|
|
15
|
+
* UTF-16 code units (JavaScript `string.length` — NOT bytes/code points; see
|
|
16
|
+
* SecurityScanner.ts's content-length finding message).
|
|
17
|
+
*
|
|
18
|
+
* Equal to MAX_LINE_LENGTH_FOR_REGEX today (both 10_000) but declared
|
|
19
|
+
* separately because the two caps protect different scan passes (per-line vs
|
|
20
|
+
* whole-document) and may need to diverge later. This is a ReDoS budget
|
|
21
|
+
* input, not a free parameter — raising it requires first proving
|
|
22
|
+
* AD_CRLF_INJECTION-class patterns stay linear at the new size. Measured
|
|
23
|
+
* (SMI-5881): the fixed AD_CRLF_INJECTION pattern is already ~4x slower per
|
|
24
|
+
* doubling of input size on some adversarial inputs at sizes past this cap,
|
|
25
|
+
* extrapolating to unacceptable latency well before 1,000,000 — so this cap
|
|
26
|
+
* is NOT raised as part of SMI-5881 even though larger trust tiers allow a
|
|
27
|
+
* much bigger `maxContentLength`. See SecurityScanner.ts's
|
|
28
|
+
* `effectiveMultilineLimit` (`Math.min(MAX_CONTENT_LENGTH_FOR_REGEX,
|
|
29
|
+
* maxContentLength)`) for how this interacts with the per-tier content-length
|
|
30
|
+
* ceiling.
|
|
31
|
+
*/
|
|
32
|
+
export const MAX_CONTENT_LENGTH_FOR_REGEX = MAX_LINE_LENGTH_FOR_REGEX;
|
|
13
33
|
/**
|
|
14
34
|
* SMI-882: Safe regex test with length limit
|
|
15
35
|
* Applies input length limit before regex matching to prevent ReDoS attacks.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regex-utils.js","sourceRoot":"","sources":["../../../../src/security/scanner/regex-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAA;AAE9C;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,KAAa,EACb,YAAoB,yBAAyB;IAE7C,2DAA2D;IAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAC9E,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,KAAa,EACb,YAAoB,yBAAyB;IAE7C,2DAA2D;IAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAC9E,OAAO,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AAChC,CAAC"}
|
|
1
|
+
{"version":3,"file":"regex-utils.js","sourceRoot":"","sources":["../../../../src/security/scanner/regex-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAA;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAA;AAErE;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,KAAa,EACb,YAAoB,yBAAyB;IAE7C,2DAA2D;IAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAC9E,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,KAAa,EACb,YAAoB,yBAAyB;IAE7C,2DAA2D;IAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAC9E,OAAO,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AAChC,CAAC"}
|
|
@@ -18,6 +18,37 @@ export type SecuritySeverity = 'low' | 'medium' | 'high' | 'critical';
|
|
|
18
18
|
* - low: Likely false positive (e.g., in documentation/examples)
|
|
19
19
|
*/
|
|
20
20
|
export type FindingConfidence = 'high' | 'medium' | 'low';
|
|
21
|
+
/**
|
|
22
|
+
* SMI-5876: evidence tier behind a jailbreak/ai_defence finding. A pattern is
|
|
23
|
+
* `mention`-tier iff its matched text, read in isolation, instructs nothing
|
|
24
|
+
* (a bare noun/name/label/structural marker/payload-free obfuscation
|
|
25
|
+
* artifact). Anything with a verb+object pairing or a second-person
|
|
26
|
+
* predicate is directive-tier.
|
|
27
|
+
*
|
|
28
|
+
* - `mention` — payload-free vocabulary (e.g. bare `jailbreak`,
|
|
29
|
+
* `DAN`, `developer mode`, a bare role marker with no body).
|
|
30
|
+
* - `role_turn_with_body` — a fabricated conversation-turn boundary WITH an
|
|
31
|
+
* instructing body (e.g. a role marker followed by a directive, or a
|
|
32
|
+
* `<instruction>...</instruction>` block with content).
|
|
33
|
+
* - `imperative_instruction` — a second-person directive without an explicit
|
|
34
|
+
* "override prior instructions" framing (e.g. "pretend you have no
|
|
35
|
+
* restrictions").
|
|
36
|
+
* - `instruction_override` — an explicit "ignore/disregard/override prior
|
|
37
|
+
* instructions" directive.
|
|
38
|
+
* - `state_assertion` — a DECLARATIVE assertion that a jailbroken/
|
|
39
|
+
* unrestricted state is active, with no verb/frame aimed at the model
|
|
40
|
+
* (e.g. "Jailbreak activated", "DAN mode enabled", "Developer mode: ON.
|
|
41
|
+
* Restrictions: OFF"). Distinct machine-readable reason code from
|
|
42
|
+
* `imperative_instruction` (the design REJECTED aimed-at-the-model framing
|
|
43
|
+
* as a requirement here — a state assertion is evidence of an already-
|
|
44
|
+
* completed jailbreak, not a request), but carries the SAME severity tuple
|
|
45
|
+
* (critical non-doc / high doc) — see `EVIDENCE_SEVERITY_TABLE`.
|
|
46
|
+
*
|
|
47
|
+
* See `SecurityScanner.evidence.ts` for how this maps to severity/confidence,
|
|
48
|
+
* and `patterns.jailbreak.evidence.ts`'s `EVIDENCE_TYPE_BY_PATTERN` for the
|
|
49
|
+
* per-pattern classification.
|
|
50
|
+
*/
|
|
51
|
+
export type EvidenceType = 'mention' | 'role_turn_with_body' | 'imperative_instruction' | 'instruction_override' | 'state_assertion';
|
|
21
52
|
/**
|
|
22
53
|
* Individual security finding from a scan
|
|
23
54
|
*/
|
|
@@ -35,6 +66,10 @@ export interface SecurityFinding {
|
|
|
35
66
|
confidence?: FindingConfidence;
|
|
36
67
|
/** SMI-5436: Path of the skill bundle file that triggered this finding, relative to the skill root. Absent for SKILL.md-only findings. */
|
|
37
68
|
filePath?: string;
|
|
69
|
+
/** SMI-5876: machine-readable evidence class behind this finding (jailbreak/ai_defence only). */
|
|
70
|
+
evidenceType?: EvidenceType;
|
|
71
|
+
/** SMI-5876: a mention-tier finding lifted by a co-occurring non-documentation high/critical signal. */
|
|
72
|
+
corroborated?: boolean;
|
|
38
73
|
}
|
|
39
74
|
/**
|
|
40
75
|
* Risk score breakdown by category
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAC3B,KAAK,GACL,gBAAgB,GAChB,WAAW,GACX,oBAAoB,GACpB,oBAAoB,GACpB,gBAAgB,GAChB,mBAAmB,GACnB,sBAAsB,GACtB,YAAY,GACZ,MAAM,GACN,KAAK,GACL,gBAAgB,GAChB,sBAAsB,GACtB,WAAW,CAAA;AAEf;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAA;AAErE;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;AAEzD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAA;IACzB,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iFAAiF;IACjF,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,qEAAqE;IACrE,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,0IAA0I;IAC1I,QAAQ,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared empty-derived-stack guard for skill recommendations.
|
|
3
|
+
* @module @skillsmith/core/services/recommend-guard
|
|
4
|
+
* @see SMI-5896 (Wave 3, discovery-tool consistency): CLI `recommend` and MCP
|
|
5
|
+
* `skill_recommend` each derive a technology "stack" client-side — CLI from
|
|
6
|
+
* codebase analysis (`buildStackFromAnalysis`), MCP from installed skills +
|
|
7
|
+
* project context keywords — and either can legitimately derive `[]` (a
|
|
8
|
+
* non-Node stack, an all-devDeps project, or an unsupported language). The
|
|
9
|
+
* `skills-recommend` edge function hard-rejects an empty `stack` with a 400
|
|
10
|
+
* (defense in depth, intentionally unchanged by this fix — see the plan's
|
|
11
|
+
* Wave 3 Step 2 "decided contract").
|
|
12
|
+
*
|
|
13
|
+
* Both callers now detect the empty-stack case BEFORE calling the API
|
|
14
|
+
* instead of letting the guaranteed-400 round trip happen and reacting to
|
|
15
|
+
* the failure after the fact — this is the one guidance string they both
|
|
16
|
+
* surface, so it can't drift between CLI and MCP wording the way the two
|
|
17
|
+
* tools' pre-fix behavior already had (a hard `process.exit(1)` crash on
|
|
18
|
+
* CLI vs a silently-swallowed warning on MCP for the exact same input
|
|
19
|
+
* shape).
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Guidance shown when no technology stack could be derived for
|
|
23
|
+
* recommendations. Written to read naturally from both a terminal (CLI) and
|
|
24
|
+
* an MCP tool response consumed by a calling agent — neither surface names
|
|
25
|
+
* its own flag here, since the same string serves both.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildEmptyStackGuidance(): string;
|
|
28
|
+
//# sourceMappingURL=recommend-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend-guard.d.ts","sourceRoot":"","sources":["../../../src/services/recommend-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAQhD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared empty-derived-stack guard for skill recommendations.
|
|
3
|
+
* @module @skillsmith/core/services/recommend-guard
|
|
4
|
+
* @see SMI-5896 (Wave 3, discovery-tool consistency): CLI `recommend` and MCP
|
|
5
|
+
* `skill_recommend` each derive a technology "stack" client-side — CLI from
|
|
6
|
+
* codebase analysis (`buildStackFromAnalysis`), MCP from installed skills +
|
|
7
|
+
* project context keywords — and either can legitimately derive `[]` (a
|
|
8
|
+
* non-Node stack, an all-devDeps project, or an unsupported language). The
|
|
9
|
+
* `skills-recommend` edge function hard-rejects an empty `stack` with a 400
|
|
10
|
+
* (defense in depth, intentionally unchanged by this fix — see the plan's
|
|
11
|
+
* Wave 3 Step 2 "decided contract").
|
|
12
|
+
*
|
|
13
|
+
* Both callers now detect the empty-stack case BEFORE calling the API
|
|
14
|
+
* instead of letting the guaranteed-400 round trip happen and reacting to
|
|
15
|
+
* the failure after the fact — this is the one guidance string they both
|
|
16
|
+
* surface, so it can't drift between CLI and MCP wording the way the two
|
|
17
|
+
* tools' pre-fix behavior already had (a hard `process.exit(1)` crash on
|
|
18
|
+
* CLI vs a silently-swallowed warning on MCP for the exact same input
|
|
19
|
+
* shape).
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Guidance shown when no technology stack could be derived for
|
|
23
|
+
* recommendations. Written to read naturally from both a terminal (CLI) and
|
|
24
|
+
* an MCP tool response consumed by a calling agent — neither surface names
|
|
25
|
+
* its own flag here, since the same string serves both.
|
|
26
|
+
*/
|
|
27
|
+
export function buildEmptyStackGuidance() {
|
|
28
|
+
return ('No technology stack could be derived for recommendations — this usually ' +
|
|
29
|
+
'means a non-Node project, a stack with no production dependencies, or an ' +
|
|
30
|
+
'unsupported language, not a backend or registry problem. Provide project ' +
|
|
31
|
+
'context (a short description of the project or its tooling) or an ' +
|
|
32
|
+
'explicit list of installed/currently-used skills, then try again.');
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=recommend-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend-guard.js","sourceRoot":"","sources":["../../../src/services/recommend-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,CACL,0EAA0E;QAC1E,2EAA2E;QAC3E,2EAA2E;QAC3E,oEAAoE;QACpE,mEAAmE,CACpE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend-guard.test.d.ts","sourceRoot":"","sources":["../../../src/services/recommend-guard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Unit tests for the shared empty-derived-stack guidance string
|
|
3
|
+
* (SMI-5896 Wave 3 Step 2). Both CLI `recommend` and MCP `skill_recommend`
|
|
4
|
+
* surface this exact string so their empty-stack messaging can't drift.
|
|
5
|
+
* @module @skillsmith/core/services/recommend-guard.test
|
|
6
|
+
*/
|
|
7
|
+
import { describe, expect, it } from 'vitest';
|
|
8
|
+
import { buildEmptyStackGuidance } from './recommend-guard.js';
|
|
9
|
+
describe('buildEmptyStackGuidance (SMI-5896 Wave 3 Step 2)', () => {
|
|
10
|
+
it('returns a non-empty string', () => {
|
|
11
|
+
const guidance = buildEmptyStackGuidance();
|
|
12
|
+
expect(typeof guidance).toBe('string');
|
|
13
|
+
expect(guidance.length).toBeGreaterThan(0);
|
|
14
|
+
});
|
|
15
|
+
it('explains the empty stack is a legitimate under-detection, not a backend fault', () => {
|
|
16
|
+
const guidance = buildEmptyStackGuidance();
|
|
17
|
+
expect(guidance).toContain('No technology stack could be derived');
|
|
18
|
+
});
|
|
19
|
+
it('guides the caller toward providing context or an installed-skills list', () => {
|
|
20
|
+
const guidance = buildEmptyStackGuidance();
|
|
21
|
+
expect(guidance.toLowerCase()).toContain('project context');
|
|
22
|
+
expect(guidance.toLowerCase()).toContain('installed');
|
|
23
|
+
});
|
|
24
|
+
it('is deterministic (identical wording every call) so CLI and MCP never drift apart', () => {
|
|
25
|
+
expect(buildEmptyStackGuidance()).toBe(buildEmptyStackGuidance());
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=recommend-guard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend-guard.test.js","sourceRoot":"","sources":["../../../src/services/recommend-guard.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,QAAQ,GAAG,uBAAuB,EAAE,CAAA;QAC1C,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,MAAM,QAAQ,GAAG,uBAAuB,EAAE,CAAA;QAC1C,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,QAAQ,GAAG,uBAAuB,EAAE,CAAA;QAC1C,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QAC3D,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kFAAkF,EAAE,GAAG,EAAE;QAC1F,MAAM,CAAC,uBAAuB,EAAE,CAAC,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|