@kevinrabun/judges-cli 3.124.0
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/README.md +24 -0
- package/agents/accessibility.judge.md +44 -0
- package/agents/agent-instructions.judge.md +44 -0
- package/agents/ai-code-safety.judge.md +55 -0
- package/agents/api-contract.judge.md +37 -0
- package/agents/api-design.judge.md +55 -0
- package/agents/authentication.judge.md +61 -0
- package/agents/backwards-compatibility.judge.md +44 -0
- package/agents/caching.judge.md +44 -0
- package/agents/ci-cd.judge.md +44 -0
- package/agents/cloud-readiness.judge.md +51 -0
- package/agents/code-structure.judge.md +48 -0
- package/agents/compliance.judge.md +47 -0
- package/agents/concurrency.judge.md +46 -0
- package/agents/configuration-management.judge.md +44 -0
- package/agents/cost-effectiveness.judge.md +40 -0
- package/agents/cybersecurity.judge.md +61 -0
- package/agents/data-security.judge.md +48 -0
- package/agents/data-sovereignty.judge.md +58 -0
- package/agents/database.judge.md +49 -0
- package/agents/dependency-health.judge.md +46 -0
- package/agents/documentation.judge.md +53 -0
- package/agents/error-handling.judge.md +53 -0
- package/agents/ethics-bias.judge.md +46 -0
- package/agents/false-positive-review.judge.md +85 -0
- package/agents/framework-safety.judge.md +47 -0
- package/agents/hallucination-detection.judge.md +46 -0
- package/agents/iac-security.judge.md +45 -0
- package/agents/intent-alignment.judge.md +44 -0
- package/agents/internationalization.judge.md +42 -0
- package/agents/logging-privacy.judge.md +44 -0
- package/agents/logic-review.judge.md +34 -0
- package/agents/maintainability.judge.md +44 -0
- package/agents/model-fingerprint.judge.md +31 -0
- package/agents/multi-turn-coherence.judge.md +36 -0
- package/agents/observability.judge.md +52 -0
- package/agents/over-engineering.judge.md +48 -0
- package/agents/performance.judge.md +44 -0
- package/agents/portability.judge.md +44 -0
- package/agents/rate-limiting.judge.md +53 -0
- package/agents/reliability.judge.md +55 -0
- package/agents/scalability.judge.md +50 -0
- package/agents/security.judge.md +62 -0
- package/agents/software-practices.judge.md +54 -0
- package/agents/testing.judge.md +52 -0
- package/agents/ux.judge.md +44 -0
- package/bin/judges.js +8 -0
- package/dist/a2a-protocol.d.ts +136 -0
- package/dist/a2a-protocol.js +218 -0
- package/dist/agent-loader.d.ts +107 -0
- package/dist/agent-loader.js +260 -0
- package/dist/api.d.ts +169 -0
- package/dist/api.js +195 -0
- package/dist/ast/cross-file-taint.d.ts +42 -0
- package/dist/ast/cross-file-taint.js +679 -0
- package/dist/ast/index.d.ts +25 -0
- package/dist/ast/index.js +148 -0
- package/dist/ast/structural-parser.d.ts +2 -0
- package/dist/ast/structural-parser.js +756 -0
- package/dist/ast/taint-tracker.d.ts +48 -0
- package/dist/ast/taint-tracker.js +1033 -0
- package/dist/ast/tree-sitter-ast.d.ts +33 -0
- package/dist/ast/tree-sitter-ast.js +1164 -0
- package/dist/ast/types.d.ts +50 -0
- package/dist/ast/types.js +7 -0
- package/dist/audit-trail.d.ts +245 -0
- package/dist/audit-trail.js +257 -0
- package/dist/auto-tune.d.ts +146 -0
- package/dist/auto-tune.js +373 -0
- package/dist/cache.d.ts +53 -0
- package/dist/cache.js +86 -0
- package/dist/calibration.d.ts +108 -0
- package/dist/calibration.js +219 -0
- package/dist/cli-dispatch.d.ts +7 -0
- package/dist/cli-dispatch.js +654 -0
- package/dist/cli-formatters.d.ts +6 -0
- package/dist/cli-formatters.js +186 -0
- package/dist/cli-helpers.d.ts +29 -0
- package/dist/cli-helpers.js +129 -0
- package/dist/cli.d.ts +30 -0
- package/dist/cli.js +1487 -0
- package/dist/commands/adoption-report.d.ts +7 -0
- package/dist/commands/adoption-report.js +218 -0
- package/dist/commands/adoption-track.d.ts +4 -0
- package/dist/commands/adoption-track.js +246 -0
- package/dist/commands/ai-gate.d.ts +7 -0
- package/dist/commands/ai-gate.js +212 -0
- package/dist/commands/ai-model-trust.d.ts +16 -0
- package/dist/commands/ai-model-trust.js +234 -0
- package/dist/commands/ai-output-compare.d.ts +8 -0
- package/dist/commands/ai-output-compare.js +202 -0
- package/dist/commands/ai-pattern-trend.d.ts +8 -0
- package/dist/commands/ai-pattern-trend.js +223 -0
- package/dist/commands/ai-prompt-audit.d.ts +22 -0
- package/dist/commands/ai-prompt-audit.js +254 -0
- package/dist/commands/ai-provenance.d.ts +4 -0
- package/dist/commands/ai-provenance.js +247 -0
- package/dist/commands/api-audit.d.ts +8 -0
- package/dist/commands/api-audit.js +359 -0
- package/dist/commands/api-misuse.d.ts +4 -0
- package/dist/commands/api-misuse.js +260 -0
- package/dist/commands/api-versioning-audit.d.ts +5 -0
- package/dist/commands/api-versioning-audit.js +233 -0
- package/dist/commands/approve-chain.d.ts +7 -0
- package/dist/commands/approve-chain.js +234 -0
- package/dist/commands/arch-audit.d.ts +8 -0
- package/dist/commands/arch-audit.js +283 -0
- package/dist/commands/assertion-density.d.ts +4 -0
- package/dist/commands/assertion-density.js +263 -0
- package/dist/commands/assign-findings.d.ts +36 -0
- package/dist/commands/assign-findings.js +177 -0
- package/dist/commands/async-safety.d.ts +4 -0
- package/dist/commands/async-safety.js +266 -0
- package/dist/commands/audit-bundle.d.ts +28 -0
- package/dist/commands/audit-bundle.js +234 -0
- package/dist/commands/audit-trail.d.ts +17 -0
- package/dist/commands/audit-trail.js +154 -0
- package/dist/commands/auto-approve.d.ts +4 -0
- package/dist/commands/auto-approve.js +188 -0
- package/dist/commands/auto-calibrate.d.ts +14 -0
- package/dist/commands/auto-calibrate.js +106 -0
- package/dist/commands/auto-detect.d.ts +61 -0
- package/dist/commands/auto-detect.js +328 -0
- package/dist/commands/auto-fix.d.ts +17 -0
- package/dist/commands/auto-fix.js +240 -0
- package/dist/commands/auto-triage.d.ts +31 -0
- package/dist/commands/auto-triage.js +125 -0
- package/dist/commands/baseline.d.ts +47 -0
- package/dist/commands/baseline.js +353 -0
- package/dist/commands/batch-review.d.ts +4 -0
- package/dist/commands/batch-review.js +180 -0
- package/dist/commands/benchmark-advanced.d.ts +14 -0
- package/dist/commands/benchmark-advanced.js +5057 -0
- package/dist/commands/benchmark-ai-agents.d.ts +8 -0
- package/dist/commands/benchmark-ai-agents.js +4123 -0
- package/dist/commands/benchmark-ai-output.d.ts +9 -0
- package/dist/commands/benchmark-ai-output.js +365 -0
- package/dist/commands/benchmark-compliance-ethics.d.ts +8 -0
- package/dist/commands/benchmark-compliance-ethics.js +3060 -0
- package/dist/commands/benchmark-expanded-2.d.ts +12 -0
- package/dist/commands/benchmark-expanded-2.js +5530 -0
- package/dist/commands/benchmark-expanded.d.ts +12 -0
- package/dist/commands/benchmark-expanded.js +2599 -0
- package/dist/commands/benchmark-infrastructure.d.ts +8 -0
- package/dist/commands/benchmark-infrastructure.js +2882 -0
- package/dist/commands/benchmark-languages.d.ts +8 -0
- package/dist/commands/benchmark-languages.js +1963 -0
- package/dist/commands/benchmark-quality-ops.d.ts +8 -0
- package/dist/commands/benchmark-quality-ops.js +3415 -0
- package/dist/commands/benchmark-security-deep.d.ts +9 -0
- package/dist/commands/benchmark-security-deep.js +2335 -0
- package/dist/commands/benchmark.d.ts +233 -0
- package/dist/commands/benchmark.js +3214 -0
- package/dist/commands/blame-review.d.ts +4 -0
- package/dist/commands/blame-review.js +266 -0
- package/dist/commands/boundary-enforce.d.ts +5 -0
- package/dist/commands/boundary-enforce.js +255 -0
- package/dist/commands/build-optimize.d.ts +6 -0
- package/dist/commands/build-optimize.js +256 -0
- package/dist/commands/burndown.d.ts +26 -0
- package/dist/commands/burndown.js +179 -0
- package/dist/commands/cache-audit.d.ts +4 -0
- package/dist/commands/cache-audit.js +219 -0
- package/dist/commands/calibration-dashboard.d.ts +1 -0
- package/dist/commands/calibration-dashboard.js +294 -0
- package/dist/commands/calibration-share.d.ts +30 -0
- package/dist/commands/calibration-share.js +182 -0
- package/dist/commands/chat-notify.d.ts +8 -0
- package/dist/commands/chat-notify.js +258 -0
- package/dist/commands/ci-template.d.ts +14 -0
- package/dist/commands/ci-template.js +211 -0
- package/dist/commands/ci-templates.d.ts +9 -0
- package/dist/commands/ci-templates.js +89 -0
- package/dist/commands/clarity-score.d.ts +8 -0
- package/dist/commands/clarity-score.js +260 -0
- package/dist/commands/clone-detect.d.ts +4 -0
- package/dist/commands/clone-detect.js +232 -0
- package/dist/commands/coach-mode.d.ts +7 -0
- package/dist/commands/coach-mode.js +229 -0
- package/dist/commands/code-health.d.ts +4 -0
- package/dist/commands/code-health.js +195 -0
- package/dist/commands/code-owner-suggest.d.ts +16 -0
- package/dist/commands/code-owner-suggest.js +214 -0
- package/dist/commands/code-similarity.d.ts +8 -0
- package/dist/commands/code-similarity.js +231 -0
- package/dist/commands/comment-drift.d.ts +4 -0
- package/dist/commands/comment-drift.js +228 -0
- package/dist/commands/commit-hygiene.d.ts +5 -0
- package/dist/commands/commit-hygiene.js +175 -0
- package/dist/commands/community-patterns.d.ts +1 -0
- package/dist/commands/community-patterns.js +131 -0
- package/dist/commands/compare-runs.d.ts +37 -0
- package/dist/commands/compare-runs.js +228 -0
- package/dist/commands/completion-audit.d.ts +4 -0
- package/dist/commands/completion-audit.js +296 -0
- package/dist/commands/completions.d.ts +1 -0
- package/dist/commands/completions.js +257 -0
- package/dist/commands/compliance-map.d.ts +8 -0
- package/dist/commands/compliance-map.js +374 -0
- package/dist/commands/compliance-report.d.ts +34 -0
- package/dist/commands/compliance-report.js +161 -0
- package/dist/commands/compliance-weight.d.ts +8 -0
- package/dist/commands/compliance-weight.js +272 -0
- package/dist/commands/config-drift.d.ts +24 -0
- package/dist/commands/config-drift.js +213 -0
- package/dist/commands/config-lint.d.ts +4 -0
- package/dist/commands/config-lint.js +187 -0
- package/dist/commands/config-migrate.d.ts +43 -0
- package/dist/commands/config-migrate.js +240 -0
- package/dist/commands/config-share.d.ts +95 -0
- package/dist/commands/config-share.js +406 -0
- package/dist/commands/context-blind.d.ts +4 -0
- package/dist/commands/context-blind.js +272 -0
- package/dist/commands/context-inject.d.ts +8 -0
- package/dist/commands/context-inject.js +211 -0
- package/dist/commands/contract-verify.d.ts +4 -0
- package/dist/commands/contract-verify.js +316 -0
- package/dist/commands/correlate.d.ts +27 -0
- package/dist/commands/correlate.js +241 -0
- package/dist/commands/cost-forecast.d.ts +18 -0
- package/dist/commands/cost-forecast.js +193 -0
- package/dist/commands/coverage-map.d.ts +22 -0
- package/dist/commands/coverage-map.js +222 -0
- package/dist/commands/coverage.d.ts +40 -0
- package/dist/commands/coverage.js +147 -0
- package/dist/commands/cross-file-consistency.d.ts +4 -0
- package/dist/commands/cross-file-consistency.js +254 -0
- package/dist/commands/cross-pr-regression.d.ts +8 -0
- package/dist/commands/cross-pr-regression.js +297 -0
- package/dist/commands/custom-rule.d.ts +4 -0
- package/dist/commands/custom-rule.js +210 -0
- package/dist/commands/dead-code-detect.d.ts +4 -0
- package/dist/commands/dead-code-detect.js +255 -0
- package/dist/commands/dedup-report.d.ts +12 -0
- package/dist/commands/dedup-report.js +137 -0
- package/dist/commands/dep-audit.d.ts +52 -0
- package/dist/commands/dep-audit.js +277 -0
- package/dist/commands/dep-correlate.d.ts +8 -0
- package/dist/commands/dep-correlate.js +207 -0
- package/dist/commands/deploy-readiness.d.ts +5 -0
- package/dist/commands/deploy-readiness.js +211 -0
- package/dist/commands/deprecated.d.ts +47 -0
- package/dist/commands/deprecated.js +201 -0
- package/dist/commands/deps.d.ts +5 -0
- package/dist/commands/deps.js +122 -0
- package/dist/commands/design-audit.d.ts +8 -0
- package/dist/commands/design-audit.js +301 -0
- package/dist/commands/dev-score.d.ts +36 -0
- package/dist/commands/dev-score.js +203 -0
- package/dist/commands/diff-explain.d.ts +4 -0
- package/dist/commands/diff-explain.js +142 -0
- package/dist/commands/diff-only.d.ts +33 -0
- package/dist/commands/diff-only.js +151 -0
- package/dist/commands/diff-review.d.ts +4 -0
- package/dist/commands/diff-review.js +190 -0
- package/dist/commands/diff.d.ts +6 -0
- package/dist/commands/diff.js +449 -0
- package/dist/commands/digest.d.ts +19 -0
- package/dist/commands/digest.js +221 -0
- package/dist/commands/doc-drift.d.ts +8 -0
- package/dist/commands/doc-drift.js +258 -0
- package/dist/commands/doc-gen.d.ts +7 -0
- package/dist/commands/doc-gen.js +208 -0
- package/dist/commands/docs.d.ts +1 -0
- package/dist/commands/docs.js +156 -0
- package/dist/commands/doctor.d.ts +55 -0
- package/dist/commands/doctor.js +362 -0
- package/dist/commands/encoding-safety.d.ts +4 -0
- package/dist/commands/encoding-safety.js +275 -0
- package/dist/commands/error-taxonomy.d.ts +5 -0
- package/dist/commands/error-taxonomy.js +226 -0
- package/dist/commands/error-ux.d.ts +4 -0
- package/dist/commands/error-ux.js +252 -0
- package/dist/commands/event-leak.d.ts +4 -0
- package/dist/commands/event-leak.js +262 -0
- package/dist/commands/evidence-chain.d.ts +4 -0
- package/dist/commands/evidence-chain.js +309 -0
- package/dist/commands/example-leak.d.ts +4 -0
- package/dist/commands/example-leak.js +232 -0
- package/dist/commands/exception-consistency.d.ts +6 -0
- package/dist/commands/exception-consistency.js +192 -0
- package/dist/commands/exec-report.d.ts +8 -0
- package/dist/commands/exec-report.js +271 -0
- package/dist/commands/explain-finding.d.ts +7 -0
- package/dist/commands/explain-finding.js +278 -0
- package/dist/commands/false-negatives.d.ts +34 -0
- package/dist/commands/false-negatives.js +165 -0
- package/dist/commands/feedback-rules.d.ts +28 -0
- package/dist/commands/feedback-rules.js +173 -0
- package/dist/commands/feedback.d.ts +182 -0
- package/dist/commands/feedback.js +550 -0
- package/dist/commands/finding-age-analysis.d.ts +4 -0
- package/dist/commands/finding-age-analysis.js +144 -0
- package/dist/commands/finding-age-report.d.ts +4 -0
- package/dist/commands/finding-age-report.js +154 -0
- package/dist/commands/finding-age-tracker.d.ts +7 -0
- package/dist/commands/finding-age-tracker.js +152 -0
- package/dist/commands/finding-age.d.ts +4 -0
- package/dist/commands/finding-age.js +145 -0
- package/dist/commands/finding-ancestry-trace.d.ts +1 -0
- package/dist/commands/finding-ancestry-trace.js +69 -0
- package/dist/commands/finding-annotation-export.d.ts +1 -0
- package/dist/commands/finding-annotation-export.js +97 -0
- package/dist/commands/finding-annotation-layer.d.ts +4 -0
- package/dist/commands/finding-annotation-layer.js +128 -0
- package/dist/commands/finding-auto-categorize.d.ts +1 -0
- package/dist/commands/finding-auto-categorize.js +109 -0
- package/dist/commands/finding-auto-fix-suggest.d.ts +1 -0
- package/dist/commands/finding-auto-fix-suggest.js +76 -0
- package/dist/commands/finding-auto-fix.d.ts +4 -0
- package/dist/commands/finding-auto-fix.js +188 -0
- package/dist/commands/finding-auto-group.d.ts +4 -0
- package/dist/commands/finding-auto-group.js +108 -0
- package/dist/commands/finding-auto-label.d.ts +4 -0
- package/dist/commands/finding-auto-label.js +220 -0
- package/dist/commands/finding-auto-priority.d.ts +1 -0
- package/dist/commands/finding-auto-priority.js +100 -0
- package/dist/commands/finding-auto-suppress.d.ts +4 -0
- package/dist/commands/finding-auto-suppress.js +126 -0
- package/dist/commands/finding-auto-tag.d.ts +4 -0
- package/dist/commands/finding-auto-tag.js +113 -0
- package/dist/commands/finding-auto-triage.d.ts +4 -0
- package/dist/commands/finding-auto-triage.js +108 -0
- package/dist/commands/finding-autofix-preview.d.ts +4 -0
- package/dist/commands/finding-autofix-preview.js +86 -0
- package/dist/commands/finding-batch-resolve.d.ts +4 -0
- package/dist/commands/finding-batch-resolve.js +165 -0
- package/dist/commands/finding-batch-suppress.d.ts +4 -0
- package/dist/commands/finding-batch-suppress.js +85 -0
- package/dist/commands/finding-batch-triage.d.ts +1 -0
- package/dist/commands/finding-batch-triage.js +90 -0
- package/dist/commands/finding-blast-radius.d.ts +4 -0
- package/dist/commands/finding-blast-radius.js +91 -0
- package/dist/commands/finding-budget.d.ts +4 -0
- package/dist/commands/finding-budget.js +232 -0
- package/dist/commands/finding-category-map.d.ts +4 -0
- package/dist/commands/finding-category-map.js +103 -0
- package/dist/commands/finding-category-stats.d.ts +4 -0
- package/dist/commands/finding-category-stats.js +104 -0
- package/dist/commands/finding-category.d.ts +4 -0
- package/dist/commands/finding-category.js +109 -0
- package/dist/commands/finding-change-impact.d.ts +4 -0
- package/dist/commands/finding-change-impact.js +107 -0
- package/dist/commands/finding-cluster-analysis.d.ts +4 -0
- package/dist/commands/finding-cluster-analysis.js +133 -0
- package/dist/commands/finding-cluster-group.d.ts +4 -0
- package/dist/commands/finding-cluster-group.js +105 -0
- package/dist/commands/finding-cluster-summary.d.ts +1 -0
- package/dist/commands/finding-cluster-summary.js +85 -0
- package/dist/commands/finding-cluster.d.ts +4 -0
- package/dist/commands/finding-cluster.js +157 -0
- package/dist/commands/finding-code-context.d.ts +4 -0
- package/dist/commands/finding-code-context.js +96 -0
- package/dist/commands/finding-code-smell.d.ts +4 -0
- package/dist/commands/finding-code-smell.js +113 -0
- package/dist/commands/finding-compare-runs.d.ts +4 -0
- package/dist/commands/finding-compare-runs.js +105 -0
- package/dist/commands/finding-compliance-tag.d.ts +1 -0
- package/dist/commands/finding-compliance-tag.js +106 -0
- package/dist/commands/finding-confidence-boost.d.ts +1 -0
- package/dist/commands/finding-confidence-boost.js +88 -0
- package/dist/commands/finding-confidence-calibrate.d.ts +4 -0
- package/dist/commands/finding-confidence-calibrate.js +111 -0
- package/dist/commands/finding-confidence-filter.d.ts +4 -0
- package/dist/commands/finding-confidence-filter.js +77 -0
- package/dist/commands/finding-contest.d.ts +7 -0
- package/dist/commands/finding-contest.js +192 -0
- package/dist/commands/finding-context-enrich.d.ts +4 -0
- package/dist/commands/finding-context-enrich.js +89 -0
- package/dist/commands/finding-context-expand.d.ts +4 -0
- package/dist/commands/finding-context-expand.js +102 -0
- package/dist/commands/finding-context-link.d.ts +1 -0
- package/dist/commands/finding-context-link.js +94 -0
- package/dist/commands/finding-context-summary.d.ts +1 -0
- package/dist/commands/finding-context-summary.js +85 -0
- package/dist/commands/finding-context-window.d.ts +4 -0
- package/dist/commands/finding-context-window.js +126 -0
- package/dist/commands/finding-context.d.ts +4 -0
- package/dist/commands/finding-context.js +140 -0
- package/dist/commands/finding-correlate.d.ts +4 -0
- package/dist/commands/finding-correlate.js +88 -0
- package/dist/commands/finding-correlation-map.d.ts +4 -0
- package/dist/commands/finding-correlation-map.js +101 -0
- package/dist/commands/finding-correlation.d.ts +4 -0
- package/dist/commands/finding-correlation.js +103 -0
- package/dist/commands/finding-cross-file-link.d.ts +1 -0
- package/dist/commands/finding-cross-file-link.js +101 -0
- package/dist/commands/finding-cross-ref.d.ts +4 -0
- package/dist/commands/finding-cross-ref.js +98 -0
- package/dist/commands/finding-cve-lookup.d.ts +4 -0
- package/dist/commands/finding-cve-lookup.js +97 -0
- package/dist/commands/finding-cwe-lookup.d.ts +4 -0
- package/dist/commands/finding-cwe-lookup.js +148 -0
- package/dist/commands/finding-cwe-map.d.ts +4 -0
- package/dist/commands/finding-cwe-map.js +133 -0
- package/dist/commands/finding-dedup-cross-file.d.ts +4 -0
- package/dist/commands/finding-dedup-cross-file.js +95 -0
- package/dist/commands/finding-dedup-cross.d.ts +4 -0
- package/dist/commands/finding-dedup-cross.js +90 -0
- package/dist/commands/finding-dedup-merge.d.ts +1 -0
- package/dist/commands/finding-dedup-merge.js +107 -0
- package/dist/commands/finding-dedup-report.d.ts +4 -0
- package/dist/commands/finding-dedup-report.js +101 -0
- package/dist/commands/finding-dedup-smart.d.ts +1 -0
- package/dist/commands/finding-dedup-smart.js +109 -0
- package/dist/commands/finding-deduplicate.d.ts +4 -0
- package/dist/commands/finding-deduplicate.js +141 -0
- package/dist/commands/finding-dependency-check.d.ts +4 -0
- package/dist/commands/finding-dependency-check.js +119 -0
- package/dist/commands/finding-dependency-impact.d.ts +1 -0
- package/dist/commands/finding-dependency-impact.js +97 -0
- package/dist/commands/finding-dependency-link.d.ts +4 -0
- package/dist/commands/finding-dependency-link.js +73 -0
- package/dist/commands/finding-dependency-risk.d.ts +4 -0
- package/dist/commands/finding-dependency-risk.js +117 -0
- package/dist/commands/finding-dependency-tree.d.ts +4 -0
- package/dist/commands/finding-dependency-tree.js +116 -0
- package/dist/commands/finding-diff-highlight.d.ts +4 -0
- package/dist/commands/finding-diff-highlight.js +107 -0
- package/dist/commands/finding-dismiss-workflow.d.ts +4 -0
- package/dist/commands/finding-dismiss-workflow.js +119 -0
- package/dist/commands/finding-duplicate-detect.d.ts +4 -0
- package/dist/commands/finding-duplicate-detect.js +113 -0
- package/dist/commands/finding-duplicate-rule.d.ts +4 -0
- package/dist/commands/finding-duplicate-rule.js +103 -0
- package/dist/commands/finding-effort-rank.d.ts +1 -0
- package/dist/commands/finding-effort-rank.js +93 -0
- package/dist/commands/finding-evidence-chain.d.ts +4 -0
- package/dist/commands/finding-evidence-chain.js +147 -0
- package/dist/commands/finding-evidence-collect.d.ts +4 -0
- package/dist/commands/finding-evidence-collect.js +114 -0
- package/dist/commands/finding-explain.d.ts +4 -0
- package/dist/commands/finding-explain.js +93 -0
- package/dist/commands/finding-export-csv.d.ts +4 -0
- package/dist/commands/finding-export-csv.js +78 -0
- package/dist/commands/finding-false-neg-check.d.ts +8 -0
- package/dist/commands/finding-false-neg-check.js +139 -0
- package/dist/commands/finding-false-positive-learn.d.ts +4 -0
- package/dist/commands/finding-false-positive-learn.js +85 -0
- package/dist/commands/finding-false-positive-log.d.ts +4 -0
- package/dist/commands/finding-false-positive-log.js +150 -0
- package/dist/commands/finding-false-positive.d.ts +4 -0
- package/dist/commands/finding-false-positive.js +134 -0
- package/dist/commands/finding-filter-view.d.ts +4 -0
- package/dist/commands/finding-filter-view.js +107 -0
- package/dist/commands/finding-fix-chain.d.ts +1 -0
- package/dist/commands/finding-fix-chain.js +78 -0
- package/dist/commands/finding-fix-estimate.d.ts +1 -0
- package/dist/commands/finding-fix-estimate.js +95 -0
- package/dist/commands/finding-fix-playbook.d.ts +1 -0
- package/dist/commands/finding-fix-playbook.js +110 -0
- package/dist/commands/finding-fix-priority.d.ts +4 -0
- package/dist/commands/finding-fix-priority.js +98 -0
- package/dist/commands/finding-fix-rate.d.ts +4 -0
- package/dist/commands/finding-fix-rate.js +141 -0
- package/dist/commands/finding-fix-suggest.d.ts +4 -0
- package/dist/commands/finding-fix-suggest.js +88 -0
- package/dist/commands/finding-fix-validation.d.ts +4 -0
- package/dist/commands/finding-fix-validation.js +115 -0
- package/dist/commands/finding-fix-verify.d.ts +4 -0
- package/dist/commands/finding-fix-verify.js +198 -0
- package/dist/commands/finding-group-by.d.ts +4 -0
- package/dist/commands/finding-group-by.js +86 -0
- package/dist/commands/finding-group.d.ts +15 -0
- package/dist/commands/finding-group.js +164 -0
- package/dist/commands/finding-groupby-file.d.ts +4 -0
- package/dist/commands/finding-groupby-file.js +94 -0
- package/dist/commands/finding-hotfix-suggest.d.ts +7 -0
- package/dist/commands/finding-hotfix-suggest.js +170 -0
- package/dist/commands/finding-hotspot-detect.d.ts +1 -0
- package/dist/commands/finding-hotspot-detect.js +120 -0
- package/dist/commands/finding-hotspot-map.d.ts +4 -0
- package/dist/commands/finding-hotspot-map.js +106 -0
- package/dist/commands/finding-hotspot.d.ts +4 -0
- package/dist/commands/finding-hotspot.js +115 -0
- package/dist/commands/finding-impact-radius.d.ts +1 -0
- package/dist/commands/finding-impact-radius.js +94 -0
- package/dist/commands/finding-impact-rank.d.ts +4 -0
- package/dist/commands/finding-impact-rank.js +85 -0
- package/dist/commands/finding-impact-score.d.ts +4 -0
- package/dist/commands/finding-impact-score.js +123 -0
- package/dist/commands/finding-impact.d.ts +4 -0
- package/dist/commands/finding-impact.js +135 -0
- package/dist/commands/finding-line-blame.d.ts +7 -0
- package/dist/commands/finding-line-blame.js +129 -0
- package/dist/commands/finding-link-graph.d.ts +4 -0
- package/dist/commands/finding-link-graph.js +144 -0
- package/dist/commands/finding-link.d.ts +4 -0
- package/dist/commands/finding-link.js +128 -0
- package/dist/commands/finding-merge-results.d.ts +4 -0
- package/dist/commands/finding-merge-results.js +110 -0
- package/dist/commands/finding-merge-strategy.d.ts +1 -0
- package/dist/commands/finding-merge-strategy.js +84 -0
- package/dist/commands/finding-metadata-enrich.d.ts +4 -0
- package/dist/commands/finding-metadata-enrich.js +92 -0
- package/dist/commands/finding-noise-filter.d.ts +7 -0
- package/dist/commands/finding-noise-filter.js +140 -0
- package/dist/commands/finding-noise-reduce.d.ts +1 -0
- package/dist/commands/finding-noise-reduce.js +81 -0
- package/dist/commands/finding-noise-score.d.ts +1 -0
- package/dist/commands/finding-noise-score.js +93 -0
- package/dist/commands/finding-owner-assign.d.ts +4 -0
- package/dist/commands/finding-owner-assign.js +133 -0
- package/dist/commands/finding-owner-notify.d.ts +1 -0
- package/dist/commands/finding-owner-notify.js +121 -0
- package/dist/commands/finding-ownership-assign.d.ts +4 -0
- package/dist/commands/finding-ownership-assign.js +101 -0
- package/dist/commands/finding-ownership-map.d.ts +4 -0
- package/dist/commands/finding-ownership-map.js +118 -0
- package/dist/commands/finding-patch-chain.d.ts +1 -0
- package/dist/commands/finding-patch-chain.js +90 -0
- package/dist/commands/finding-patch-preview.d.ts +4 -0
- package/dist/commands/finding-patch-preview.js +103 -0
- package/dist/commands/finding-pattern-detect.d.ts +4 -0
- package/dist/commands/finding-pattern-detect.js +127 -0
- package/dist/commands/finding-pattern-library.d.ts +4 -0
- package/dist/commands/finding-pattern-library.js +145 -0
- package/dist/commands/finding-pattern-match.d.ts +4 -0
- package/dist/commands/finding-pattern-match.js +165 -0
- package/dist/commands/finding-prioritize.d.ts +4 -0
- package/dist/commands/finding-prioritize.js +119 -0
- package/dist/commands/finding-priority-matrix.d.ts +4 -0
- package/dist/commands/finding-priority-matrix.js +102 -0
- package/dist/commands/finding-priority-queue.d.ts +4 -0
- package/dist/commands/finding-priority-queue.js +131 -0
- package/dist/commands/finding-priority-rank.d.ts +1 -0
- package/dist/commands/finding-priority-rank.js +82 -0
- package/dist/commands/finding-quality-gate.d.ts +4 -0
- package/dist/commands/finding-quality-gate.js +107 -0
- package/dist/commands/finding-rank.d.ts +4 -0
- package/dist/commands/finding-rank.js +138 -0
- package/dist/commands/finding-reachability-check.d.ts +4 -0
- package/dist/commands/finding-reachability-check.js +102 -0
- package/dist/commands/finding-reachability.d.ts +4 -0
- package/dist/commands/finding-reachability.js +131 -0
- package/dist/commands/finding-recurrence-check.d.ts +1 -0
- package/dist/commands/finding-recurrence-check.js +103 -0
- package/dist/commands/finding-recurrence-detect.d.ts +4 -0
- package/dist/commands/finding-recurrence-detect.js +77 -0
- package/dist/commands/finding-recurrence.d.ts +4 -0
- package/dist/commands/finding-recurrence.js +135 -0
- package/dist/commands/finding-regression-check.d.ts +4 -0
- package/dist/commands/finding-regression-check.js +112 -0
- package/dist/commands/finding-regression-detect.d.ts +1 -0
- package/dist/commands/finding-regression-detect.js +86 -0
- package/dist/commands/finding-related-rules.d.ts +4 -0
- package/dist/commands/finding-related-rules.js +151 -0
- package/dist/commands/finding-remediation-cost.d.ts +1 -0
- package/dist/commands/finding-remediation-cost.js +79 -0
- package/dist/commands/finding-remediation-plan.d.ts +4 -0
- package/dist/commands/finding-remediation-plan.js +107 -0
- package/dist/commands/finding-reopen-detect.d.ts +1 -0
- package/dist/commands/finding-reopen-detect.js +77 -0
- package/dist/commands/finding-repeat-detect.d.ts +1 -0
- package/dist/commands/finding-repeat-detect.js +92 -0
- package/dist/commands/finding-resolution-track.d.ts +4 -0
- package/dist/commands/finding-resolution-track.js +150 -0
- package/dist/commands/finding-resolution-tracker.d.ts +4 -0
- package/dist/commands/finding-resolution-tracker.js +163 -0
- package/dist/commands/finding-resolution-workflow.d.ts +1 -0
- package/dist/commands/finding-resolution-workflow.js +91 -0
- package/dist/commands/finding-resolution.d.ts +4 -0
- package/dist/commands/finding-resolution.js +142 -0
- package/dist/commands/finding-risk-label.d.ts +1 -0
- package/dist/commands/finding-risk-label.js +72 -0
- package/dist/commands/finding-risk-matrix.d.ts +4 -0
- package/dist/commands/finding-risk-matrix.js +126 -0
- package/dist/commands/finding-risk-score.d.ts +4 -0
- package/dist/commands/finding-risk-score.js +95 -0
- package/dist/commands/finding-root-cause.d.ts +4 -0
- package/dist/commands/finding-root-cause.js +184 -0
- package/dist/commands/finding-rule-explain.d.ts +4 -0
- package/dist/commands/finding-rule-explain.js +140 -0
- package/dist/commands/finding-scope-filter.d.ts +1 -0
- package/dist/commands/finding-scope-filter.js +77 -0
- package/dist/commands/finding-scope-impact.d.ts +1 -0
- package/dist/commands/finding-scope-impact.js +83 -0
- package/dist/commands/finding-search-index.d.ts +4 -0
- package/dist/commands/finding-search-index.js +99 -0
- package/dist/commands/finding-security-hotspot.d.ts +4 -0
- package/dist/commands/finding-security-hotspot.js +175 -0
- package/dist/commands/finding-severity-dist.d.ts +4 -0
- package/dist/commands/finding-severity-dist.js +105 -0
- package/dist/commands/finding-severity-drift.d.ts +4 -0
- package/dist/commands/finding-severity-drift.js +92 -0
- package/dist/commands/finding-severity-heatmap.d.ts +4 -0
- package/dist/commands/finding-severity-heatmap.js +108 -0
- package/dist/commands/finding-severity-histogram.d.ts +4 -0
- package/dist/commands/finding-severity-histogram.js +66 -0
- package/dist/commands/finding-severity-override.d.ts +4 -0
- package/dist/commands/finding-severity-override.js +131 -0
- package/dist/commands/finding-severity-rebalance.d.ts +1 -0
- package/dist/commands/finding-severity-rebalance.js +108 -0
- package/dist/commands/finding-severity-trend.d.ts +4 -0
- package/dist/commands/finding-severity-trend.js +127 -0
- package/dist/commands/finding-similar-match.d.ts +1 -0
- package/dist/commands/finding-similar-match.js +112 -0
- package/dist/commands/finding-snippet.d.ts +4 -0
- package/dist/commands/finding-snippet.js +102 -0
- package/dist/commands/finding-summary-digest.d.ts +7 -0
- package/dist/commands/finding-summary-digest.js +145 -0
- package/dist/commands/finding-suppress-pattern.d.ts +4 -0
- package/dist/commands/finding-suppress-pattern.js +148 -0
- package/dist/commands/finding-suppress.d.ts +4 -0
- package/dist/commands/finding-suppress.js +164 -0
- package/dist/commands/finding-suppression-audit.d.ts +4 -0
- package/dist/commands/finding-suppression-audit.js +137 -0
- package/dist/commands/finding-suppression-list.d.ts +4 -0
- package/dist/commands/finding-suppression-list.js +119 -0
- package/dist/commands/finding-suppression-log.d.ts +4 -0
- package/dist/commands/finding-suppression-log.js +174 -0
- package/dist/commands/finding-time-to-fix.d.ts +1 -0
- package/dist/commands/finding-time-to-fix.js +98 -0
- package/dist/commands/finding-timeline-view.d.ts +4 -0
- package/dist/commands/finding-timeline-view.js +98 -0
- package/dist/commands/finding-timeline.d.ts +4 -0
- package/dist/commands/finding-timeline.js +143 -0
- package/dist/commands/finding-top-offender.d.ts +1 -0
- package/dist/commands/finding-top-offender.js +75 -0
- package/dist/commands/finding-trace.d.ts +4 -0
- package/dist/commands/finding-trace.js +118 -0
- package/dist/commands/finding-trend-alert.d.ts +1 -0
- package/dist/commands/finding-trend-alert.js +126 -0
- package/dist/commands/finding-trend-analysis.d.ts +4 -0
- package/dist/commands/finding-trend-analysis.js +95 -0
- package/dist/commands/finding-trend-forecast.d.ts +4 -0
- package/dist/commands/finding-trend-forecast.js +106 -0
- package/dist/commands/finding-trend-report.d.ts +4 -0
- package/dist/commands/finding-trend-report.js +107 -0
- package/dist/commands/finding-trend.d.ts +4 -0
- package/dist/commands/finding-trend.js +118 -0
- package/dist/commands/fix-pr.d.ts +22 -0
- package/dist/commands/fix-pr.js +286 -0
- package/dist/commands/fix-suggest.d.ts +4 -0
- package/dist/commands/fix-suggest.js +171 -0
- package/dist/commands/fix-verify.d.ts +4 -0
- package/dist/commands/fix-verify.js +123 -0
- package/dist/commands/fix.d.ts +117 -0
- package/dist/commands/fix.js +445 -0
- package/dist/commands/focus-area.d.ts +5 -0
- package/dist/commands/focus-area.js +192 -0
- package/dist/commands/generate.d.ts +7 -0
- package/dist/commands/generate.js +403 -0
- package/dist/commands/governance.d.ts +31 -0
- package/dist/commands/governance.js +202 -0
- package/dist/commands/group-findings.d.ts +22 -0
- package/dist/commands/group-findings.js +154 -0
- package/dist/commands/guided-tour.d.ts +8 -0
- package/dist/commands/guided-tour.js +287 -0
- package/dist/commands/habit-tracker.d.ts +7 -0
- package/dist/commands/habit-tracker.js +194 -0
- package/dist/commands/hallucination-detect.d.ts +4 -0
- package/dist/commands/hallucination-detect.js +350 -0
- package/dist/commands/hallucination-score.d.ts +8 -0
- package/dist/commands/hallucination-score.js +316 -0
- package/dist/commands/help.d.ts +7 -0
- package/dist/commands/help.js +302 -0
- package/dist/commands/hook-install.d.ts +21 -0
- package/dist/commands/hook-install.js +142 -0
- package/dist/commands/hook.d.ts +8 -0
- package/dist/commands/hook.js +145 -0
- package/dist/commands/iac-lint.d.ts +7 -0
- package/dist/commands/iac-lint.js +312 -0
- package/dist/commands/idempotency-audit.d.ts +4 -0
- package/dist/commands/idempotency-audit.js +222 -0
- package/dist/commands/ignore-list.d.ts +18 -0
- package/dist/commands/ignore-list.js +152 -0
- package/dist/commands/impact-scan.d.ts +8 -0
- package/dist/commands/impact-scan.js +281 -0
- package/dist/commands/incident-response.d.ts +7 -0
- package/dist/commands/incident-response.js +254 -0
- package/dist/commands/incremental-review.d.ts +4 -0
- package/dist/commands/incremental-review.js +236 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.js +265 -0
- package/dist/commands/input-guard.d.ts +4 -0
- package/dist/commands/input-guard.js +255 -0
- package/dist/commands/interactive-fix.d.ts +22 -0
- package/dist/commands/interactive-fix.js +139 -0
- package/dist/commands/judge-author.d.ts +7 -0
- package/dist/commands/judge-author.js +260 -0
- package/dist/commands/judge-config.d.ts +4 -0
- package/dist/commands/judge-config.js +151 -0
- package/dist/commands/judge-learn.d.ts +8 -0
- package/dist/commands/judge-learn.js +217 -0
- package/dist/commands/judge-reputation.d.ts +28 -0
- package/dist/commands/judge-reputation.js +198 -0
- package/dist/commands/kb.d.ts +40 -0
- package/dist/commands/kb.js +228 -0
- package/dist/commands/language-packs.d.ts +42 -0
- package/dist/commands/language-packs.js +150 -0
- package/dist/commands/learn.d.ts +26 -0
- package/dist/commands/learn.js +288 -0
- package/dist/commands/learning-path.d.ts +8 -0
- package/dist/commands/learning-path.js +325 -0
- package/dist/commands/license-scan.d.ts +8 -0
- package/dist/commands/license-scan.js +183 -0
- package/dist/commands/llm-benchmark-optimizer.d.ts +78 -0
- package/dist/commands/llm-benchmark-optimizer.js +241 -0
- package/dist/commands/llm-benchmark.d.ts +156 -0
- package/dist/commands/llm-benchmark.js +670 -0
- package/dist/commands/log-quality.d.ts +5 -0
- package/dist/commands/log-quality.js +211 -0
- package/dist/commands/logic-lint.d.ts +4 -0
- package/dist/commands/logic-lint.js +255 -0
- package/dist/commands/lsp.d.ts +23 -0
- package/dist/commands/lsp.js +285 -0
- package/dist/commands/merge-verdict.d.ts +4 -0
- package/dist/commands/merge-verdict.js +287 -0
- package/dist/commands/metrics-dashboard.d.ts +21 -0
- package/dist/commands/metrics-dashboard.js +334 -0
- package/dist/commands/metrics.d.ts +57 -0
- package/dist/commands/metrics.js +241 -0
- package/dist/commands/migration-safety.d.ts +5 -0
- package/dist/commands/migration-safety.js +256 -0
- package/dist/commands/model-report.d.ts +8 -0
- package/dist/commands/model-report.js +194 -0
- package/dist/commands/model-risk.d.ts +27 -0
- package/dist/commands/model-risk.js +220 -0
- package/dist/commands/monorepo.d.ts +37 -0
- package/dist/commands/monorepo.js +232 -0
- package/dist/commands/multi-lang-review.d.ts +4 -0
- package/dist/commands/multi-lang-review.js +230 -0
- package/dist/commands/noise-advisor.d.ts +29 -0
- package/dist/commands/noise-advisor.js +170 -0
- package/dist/commands/notify.d.ts +78 -0
- package/dist/commands/notify.js +324 -0
- package/dist/commands/null-safety-audit.d.ts +5 -0
- package/dist/commands/null-safety-audit.js +221 -0
- package/dist/commands/observability-gap.d.ts +5 -0
- package/dist/commands/observability-gap.js +211 -0
- package/dist/commands/onboard.d.ts +12 -0
- package/dist/commands/onboard.js +178 -0
- package/dist/commands/org-metrics.d.ts +23 -0
- package/dist/commands/org-metrics.js +237 -0
- package/dist/commands/org-policy.d.ts +7 -0
- package/dist/commands/org-policy.js +207 -0
- package/dist/commands/over-abstraction.d.ts +4 -0
- package/dist/commands/over-abstraction.js +307 -0
- package/dist/commands/override.d.ts +61 -0
- package/dist/commands/override.js +268 -0
- package/dist/commands/ownership-map.d.ts +5 -0
- package/dist/commands/ownership-map.js +217 -0
- package/dist/commands/parity.d.ts +30 -0
- package/dist/commands/parity.js +212 -0
- package/dist/commands/pattern-registry.d.ts +22 -0
- package/dist/commands/pattern-registry.js +226 -0
- package/dist/commands/perf-compare.d.ts +8 -0
- package/dist/commands/perf-compare.js +245 -0
- package/dist/commands/perf-hotspot.d.ts +7 -0
- package/dist/commands/perf-hotspot.js +273 -0
- package/dist/commands/phantom-import.d.ts +4 -0
- package/dist/commands/phantom-import.js +260 -0
- package/dist/commands/pii-scan.d.ts +7 -0
- package/dist/commands/pii-scan.js +299 -0
- package/dist/commands/plugin-search.d.ts +39 -0
- package/dist/commands/plugin-search.js +327 -0
- package/dist/commands/plugins.d.ts +12 -0
- package/dist/commands/plugins.js +104 -0
- package/dist/commands/policy-audit.d.ts +52 -0
- package/dist/commands/policy-audit.js +160 -0
- package/dist/commands/pr-quality-gate.d.ts +28 -0
- package/dist/commands/pr-quality-gate.js +207 -0
- package/dist/commands/pr-summary.d.ts +25 -0
- package/dist/commands/pr-summary.js +187 -0
- package/dist/commands/predict.d.ts +7 -0
- package/dist/commands/predict.js +218 -0
- package/dist/commands/privilege-path.d.ts +4 -0
- package/dist/commands/privilege-path.js +233 -0
- package/dist/commands/profile.d.ts +37 -0
- package/dist/commands/profile.js +101 -0
- package/dist/commands/prompt-replay.d.ts +7 -0
- package/dist/commands/prompt-replay.js +176 -0
- package/dist/commands/quality-gate.d.ts +69 -0
- package/dist/commands/quality-gate.js +252 -0
- package/dist/commands/query.d.ts +19 -0
- package/dist/commands/query.js +229 -0
- package/dist/commands/quick-check.d.ts +4 -0
- package/dist/commands/quick-check.js +173 -0
- package/dist/commands/recommend.d.ts +20 -0
- package/dist/commands/recommend.js +282 -0
- package/dist/commands/refactor-safety.d.ts +8 -0
- package/dist/commands/refactor-safety.js +273 -0
- package/dist/commands/reg-watch.d.ts +20 -0
- package/dist/commands/reg-watch.js +219 -0
- package/dist/commands/regression-alert.d.ts +31 -0
- package/dist/commands/regression-alert.js +215 -0
- package/dist/commands/remediation-lib.d.ts +8 -0
- package/dist/commands/remediation-lib.js +265 -0
- package/dist/commands/remediation.d.ts +20 -0
- package/dist/commands/remediation.js +256 -0
- package/dist/commands/report-template.d.ts +16 -0
- package/dist/commands/report-template.js +290 -0
- package/dist/commands/report.d.ts +12 -0
- package/dist/commands/report.js +139 -0
- package/dist/commands/resource-cleanup.d.ts +6 -0
- package/dist/commands/resource-cleanup.js +235 -0
- package/dist/commands/retro.d.ts +22 -0
- package/dist/commands/retro.js +211 -0
- package/dist/commands/retry-pattern-audit.d.ts +5 -0
- package/dist/commands/retry-pattern-audit.js +215 -0
- package/dist/commands/review-ab-test.d.ts +4 -0
- package/dist/commands/review-ab-test.js +224 -0
- package/dist/commands/review-access-log.d.ts +4 -0
- package/dist/commands/review-access-log.js +65 -0
- package/dist/commands/review-action-item-gen.d.ts +1 -0
- package/dist/commands/review-action-item-gen.js +72 -0
- package/dist/commands/review-adoption-metrics.d.ts +4 -0
- package/dist/commands/review-adoption-metrics.js +95 -0
- package/dist/commands/review-adoption-score.d.ts +1 -0
- package/dist/commands/review-adoption-score.js +181 -0
- package/dist/commands/review-ai-feedback-loop.d.ts +1 -0
- package/dist/commands/review-ai-feedback-loop.js +116 -0
- package/dist/commands/review-annotate.d.ts +4 -0
- package/dist/commands/review-annotate.js +122 -0
- package/dist/commands/review-annotation-export.d.ts +4 -0
- package/dist/commands/review-annotation-export.js +105 -0
- package/dist/commands/review-annotation.d.ts +4 -0
- package/dist/commands/review-annotation.js +133 -0
- package/dist/commands/review-api-export.d.ts +4 -0
- package/dist/commands/review-api-export.js +98 -0
- package/dist/commands/review-approval-criteria.d.ts +1 -0
- package/dist/commands/review-approval-criteria.js +99 -0
- package/dist/commands/review-approval-gate.d.ts +7 -0
- package/dist/commands/review-approval-gate.js +190 -0
- package/dist/commands/review-approval.d.ts +4 -0
- package/dist/commands/review-approval.js +133 -0
- package/dist/commands/review-archive-search.d.ts +4 -0
- package/dist/commands/review-archive-search.js +70 -0
- package/dist/commands/review-archive.d.ts +4 -0
- package/dist/commands/review-archive.js +135 -0
- package/dist/commands/review-audit-export.d.ts +4 -0
- package/dist/commands/review-audit-export.js +93 -0
- package/dist/commands/review-audit-log.d.ts +4 -0
- package/dist/commands/review-audit-log.js +140 -0
- package/dist/commands/review-audit-trail.d.ts +4 -0
- package/dist/commands/review-audit-trail.js +96 -0
- package/dist/commands/review-auto-merge.d.ts +4 -0
- package/dist/commands/review-auto-merge.js +175 -0
- package/dist/commands/review-badge.d.ts +4 -0
- package/dist/commands/review-badge.js +152 -0
- package/dist/commands/review-batch-files.d.ts +4 -0
- package/dist/commands/review-batch-files.js +82 -0
- package/dist/commands/review-batch-mode.d.ts +4 -0
- package/dist/commands/review-batch-mode.js +97 -0
- package/dist/commands/review-batch-run.d.ts +4 -0
- package/dist/commands/review-batch-run.js +149 -0
- package/dist/commands/review-benchmark-self.d.ts +4 -0
- package/dist/commands/review-benchmark-self.js +140 -0
- package/dist/commands/review-blame-map.d.ts +4 -0
- package/dist/commands/review-blame-map.js +100 -0
- package/dist/commands/review-branch-compare.d.ts +4 -0
- package/dist/commands/review-branch-compare.js +108 -0
- package/dist/commands/review-branch-policy.d.ts +4 -0
- package/dist/commands/review-branch-policy.js +102 -0
- package/dist/commands/review-bulk-action.d.ts +4 -0
- package/dist/commands/review-bulk-action.js +109 -0
- package/dist/commands/review-bulk-apply.d.ts +4 -0
- package/dist/commands/review-bulk-apply.js +102 -0
- package/dist/commands/review-cache-clear.d.ts +4 -0
- package/dist/commands/review-cache-clear.js +160 -0
- package/dist/commands/review-cache-warm.d.ts +4 -0
- package/dist/commands/review-cache-warm.js +70 -0
- package/dist/commands/review-cache.d.ts +22 -0
- package/dist/commands/review-cache.js +134 -0
- package/dist/commands/review-changelog-entry.d.ts +7 -0
- package/dist/commands/review-changelog-entry.js +109 -0
- package/dist/commands/review-changelog-gen.d.ts +4 -0
- package/dist/commands/review-changelog-gen.js +117 -0
- package/dist/commands/review-changelog-impact.d.ts +1 -0
- package/dist/commands/review-changelog-impact.js +89 -0
- package/dist/commands/review-checklist.d.ts +4 -0
- package/dist/commands/review-checklist.js +144 -0
- package/dist/commands/review-checkpoint.d.ts +4 -0
- package/dist/commands/review-checkpoint.js +163 -0
- package/dist/commands/review-ci-gate.d.ts +4 -0
- package/dist/commands/review-ci-gate.js +114 -0
- package/dist/commands/review-ci-insight.d.ts +1 -0
- package/dist/commands/review-ci-insight.js +100 -0
- package/dist/commands/review-ci-integration.d.ts +4 -0
- package/dist/commands/review-ci-integration.js +125 -0
- package/dist/commands/review-ci-status.d.ts +4 -0
- package/dist/commands/review-ci-status.js +200 -0
- package/dist/commands/review-cicd-integrate.d.ts +4 -0
- package/dist/commands/review-cicd-integrate.js +122 -0
- package/dist/commands/review-code-health-score.d.ts +1 -0
- package/dist/commands/review-code-health-score.js +100 -0
- package/dist/commands/review-code-owner.d.ts +7 -0
- package/dist/commands/review-code-owner.js +164 -0
- package/dist/commands/review-code-ownership.d.ts +1 -0
- package/dist/commands/review-code-ownership.js +88 -0
- package/dist/commands/review-comment.d.ts +4 -0
- package/dist/commands/review-comment.js +165 -0
- package/dist/commands/review-commit-hook.d.ts +7 -0
- package/dist/commands/review-commit-hook.js +134 -0
- package/dist/commands/review-commit-quality.d.ts +1 -0
- package/dist/commands/review-commit-quality.js +94 -0
- package/dist/commands/review-comparative.d.ts +4 -0
- package/dist/commands/review-comparative.js +149 -0
- package/dist/commands/review-compare-version.d.ts +4 -0
- package/dist/commands/review-compare-version.js +108 -0
- package/dist/commands/review-compare.d.ts +4 -0
- package/dist/commands/review-compare.js +200 -0
- package/dist/commands/review-compliance-check.d.ts +4 -0
- package/dist/commands/review-compliance-check.js +202 -0
- package/dist/commands/review-compliance-gate.d.ts +4 -0
- package/dist/commands/review-compliance-gate.js +151 -0
- package/dist/commands/review-compliance-map.d.ts +4 -0
- package/dist/commands/review-compliance-map.js +110 -0
- package/dist/commands/review-compliance-report.d.ts +4 -0
- package/dist/commands/review-compliance-report.js +127 -0
- package/dist/commands/review-confidence-explain.d.ts +1 -0
- package/dist/commands/review-confidence-explain.js +99 -0
- package/dist/commands/review-config-diff.d.ts +4 -0
- package/dist/commands/review-config-diff.js +108 -0
- package/dist/commands/review-config-export.d.ts +4 -0
- package/dist/commands/review-config-export.js +124 -0
- package/dist/commands/review-config-health.d.ts +1 -0
- package/dist/commands/review-config-health.js +172 -0
- package/dist/commands/review-config-migrate.d.ts +4 -0
- package/dist/commands/review-config-migrate.js +123 -0
- package/dist/commands/review-config-template.d.ts +4 -0
- package/dist/commands/review-config-template.js +112 -0
- package/dist/commands/review-config-validate.d.ts +4 -0
- package/dist/commands/review-config-validate.js +110 -0
- package/dist/commands/review-contract.d.ts +4 -0
- package/dist/commands/review-contract.js +199 -0
- package/dist/commands/review-coverage-gap.d.ts +4 -0
- package/dist/commands/review-coverage-gap.js +120 -0
- package/dist/commands/review-coverage-map.d.ts +4 -0
- package/dist/commands/review-coverage-map.js +194 -0
- package/dist/commands/review-custom-judge-config.d.ts +4 -0
- package/dist/commands/review-custom-judge-config.js +103 -0
- package/dist/commands/review-custom-judge.d.ts +4 -0
- package/dist/commands/review-custom-judge.js +182 -0
- package/dist/commands/review-custom-prompt.d.ts +4 -0
- package/dist/commands/review-custom-prompt.js +170 -0
- package/dist/commands/review-custom-rule.d.ts +4 -0
- package/dist/commands/review-custom-rule.js +169 -0
- package/dist/commands/review-dashboard-data.d.ts +4 -0
- package/dist/commands/review-dashboard-data.js +142 -0
- package/dist/commands/review-dashboard.d.ts +4 -0
- package/dist/commands/review-dashboard.js +140 -0
- package/dist/commands/review-data-retention.d.ts +4 -0
- package/dist/commands/review-data-retention.js +119 -0
- package/dist/commands/review-dependency-graph.d.ts +4 -0
- package/dist/commands/review-dependency-graph.js +94 -0
- package/dist/commands/review-dependency-review.d.ts +1 -0
- package/dist/commands/review-dependency-review.js +104 -0
- package/dist/commands/review-deployment-gate.d.ts +4 -0
- package/dist/commands/review-deployment-gate.js +94 -0
- package/dist/commands/review-depth.d.ts +4 -0
- package/dist/commands/review-depth.js +142 -0
- package/dist/commands/review-diff-annotate.d.ts +4 -0
- package/dist/commands/review-diff-annotate.js +104 -0
- package/dist/commands/review-diff-context.d.ts +4 -0
- package/dist/commands/review-diff-context.js +158 -0
- package/dist/commands/review-diff-highlight.d.ts +4 -0
- package/dist/commands/review-diff-highlight.js +179 -0
- package/dist/commands/review-diff-stats.d.ts +4 -0
- package/dist/commands/review-diff-stats.js +90 -0
- package/dist/commands/review-diff-summary.d.ts +4 -0
- package/dist/commands/review-diff-summary.js +154 -0
- package/dist/commands/review-digest-gen.d.ts +1 -0
- package/dist/commands/review-digest-gen.js +100 -0
- package/dist/commands/review-digest.d.ts +4 -0
- package/dist/commands/review-digest.js +265 -0
- package/dist/commands/review-dry-run.d.ts +4 -0
- package/dist/commands/review-dry-run.js +120 -0
- package/dist/commands/review-engagement-score.d.ts +1 -0
- package/dist/commands/review-engagement-score.js +111 -0
- package/dist/commands/review-env-check.d.ts +4 -0
- package/dist/commands/review-env-check.js +115 -0
- package/dist/commands/review-environment-config.d.ts +4 -0
- package/dist/commands/review-environment-config.js +102 -0
- package/dist/commands/review-escalation-path.d.ts +1 -0
- package/dist/commands/review-escalation-path.js +86 -0
- package/dist/commands/review-exclude-vendor.d.ts +4 -0
- package/dist/commands/review-exclude-vendor.js +158 -0
- package/dist/commands/review-explain.d.ts +5 -0
- package/dist/commands/review-explain.js +194 -0
- package/dist/commands/review-export-pdf.d.ts +7 -0
- package/dist/commands/review-export-pdf.js +131 -0
- package/dist/commands/review-export.d.ts +4 -0
- package/dist/commands/review-export.js +179 -0
- package/dist/commands/review-feedback-loop.d.ts +4 -0
- package/dist/commands/review-feedback-loop.js +113 -0
- package/dist/commands/review-feedback-summary.d.ts +1 -0
- package/dist/commands/review-feedback-summary.js +130 -0
- package/dist/commands/review-feedback.d.ts +4 -0
- package/dist/commands/review-feedback.js +145 -0
- package/dist/commands/review-file-complexity.d.ts +4 -0
- package/dist/commands/review-file-complexity.js +137 -0
- package/dist/commands/review-file-filter.d.ts +4 -0
- package/dist/commands/review-file-filter.js +121 -0
- package/dist/commands/review-file-stats.d.ts +4 -0
- package/dist/commands/review-file-stats.js +130 -0
- package/dist/commands/review-filter.d.ts +4 -0
- package/dist/commands/review-filter.js +161 -0
- package/dist/commands/review-finding-link.d.ts +7 -0
- package/dist/commands/review-finding-link.js +115 -0
- package/dist/commands/review-focus-area.d.ts +1 -0
- package/dist/commands/review-focus-area.js +96 -0
- package/dist/commands/review-focus.d.ts +4 -0
- package/dist/commands/review-focus.js +196 -0
- package/dist/commands/review-gate-config.d.ts +4 -0
- package/dist/commands/review-gate-config.js +153 -0
- package/dist/commands/review-gate.d.ts +4 -0
- package/dist/commands/review-gate.js +212 -0
- package/dist/commands/review-goal-track.d.ts +1 -0
- package/dist/commands/review-goal-track.js +123 -0
- package/dist/commands/review-guardrail.d.ts +4 -0
- package/dist/commands/review-guardrail.js +155 -0
- package/dist/commands/review-handoff.d.ts +4 -0
- package/dist/commands/review-handoff.js +208 -0
- package/dist/commands/review-health-check.d.ts +4 -0
- package/dist/commands/review-health-check.js +148 -0
- package/dist/commands/review-health-trend.d.ts +1 -0
- package/dist/commands/review-health-trend.js +107 -0
- package/dist/commands/review-history-compare.d.ts +4 -0
- package/dist/commands/review-history-compare.js +93 -0
- package/dist/commands/review-history-search.d.ts +4 -0
- package/dist/commands/review-history-search.js +214 -0
- package/dist/commands/review-ide-sync.d.ts +4 -0
- package/dist/commands/review-ide-sync.js +91 -0
- package/dist/commands/review-ignore-path.d.ts +4 -0
- package/dist/commands/review-ignore-path.js +147 -0
- package/dist/commands/review-ignore-pattern.d.ts +5 -0
- package/dist/commands/review-ignore-pattern.js +138 -0
- package/dist/commands/review-incident-link.d.ts +4 -0
- package/dist/commands/review-incident-link.js +93 -0
- package/dist/commands/review-incremental.d.ts +4 -0
- package/dist/commands/review-incremental.js +128 -0
- package/dist/commands/review-integration-health.d.ts +4 -0
- package/dist/commands/review-integration-health.js +84 -0
- package/dist/commands/review-integration-test.d.ts +4 -0
- package/dist/commands/review-integration-test.js +145 -0
- package/dist/commands/review-integration.d.ts +4 -0
- package/dist/commands/review-integration.js +236 -0
- package/dist/commands/review-interactive.d.ts +4 -0
- package/dist/commands/review-interactive.js +85 -0
- package/dist/commands/review-knowledge-capture.d.ts +1 -0
- package/dist/commands/review-knowledge-capture.js +94 -0
- package/dist/commands/review-language-profile.d.ts +4 -0
- package/dist/commands/review-language-profile.js +72 -0
- package/dist/commands/review-language-stats.d.ts +4 -0
- package/dist/commands/review-language-stats.js +152 -0
- package/dist/commands/review-lock-file.d.ts +4 -0
- package/dist/commands/review-lock-file.js +153 -0
- package/dist/commands/review-lock.d.ts +4 -0
- package/dist/commands/review-lock.js +107 -0
- package/dist/commands/review-log.d.ts +22 -0
- package/dist/commands/review-log.js +164 -0
- package/dist/commands/review-mentor-suggest.d.ts +1 -0
- package/dist/commands/review-mentor-suggest.js +112 -0
- package/dist/commands/review-merge-check.d.ts +4 -0
- package/dist/commands/review-merge-check.js +101 -0
- package/dist/commands/review-merge-config.d.ts +4 -0
- package/dist/commands/review-merge-config.js +119 -0
- package/dist/commands/review-merge-readiness.d.ts +1 -0
- package/dist/commands/review-merge-readiness.js +90 -0
- package/dist/commands/review-merge-request.d.ts +4 -0
- package/dist/commands/review-merge-request.js +95 -0
- package/dist/commands/review-merge.d.ts +4 -0
- package/dist/commands/review-merge.js +145 -0
- package/dist/commands/review-metric-export.d.ts +4 -0
- package/dist/commands/review-metric-export.js +62 -0
- package/dist/commands/review-milestone.d.ts +4 -0
- package/dist/commands/review-milestone.js +136 -0
- package/dist/commands/review-multi-repo-sync.d.ts +4 -0
- package/dist/commands/review-multi-repo-sync.js +115 -0
- package/dist/commands/review-multi-repo.d.ts +4 -0
- package/dist/commands/review-multi-repo.js +145 -0
- package/dist/commands/review-note.d.ts +4 -0
- package/dist/commands/review-note.js +104 -0
- package/dist/commands/review-notification-config.d.ts +4 -0
- package/dist/commands/review-notification-config.js +122 -0
- package/dist/commands/review-notification-digest.d.ts +4 -0
- package/dist/commands/review-notification-digest.js +64 -0
- package/dist/commands/review-notification.d.ts +4 -0
- package/dist/commands/review-notification.js +126 -0
- package/dist/commands/review-notify.d.ts +4 -0
- package/dist/commands/review-notify.js +143 -0
- package/dist/commands/review-offline.d.ts +4 -0
- package/dist/commands/review-offline.js +125 -0
- package/dist/commands/review-onboard-checklist.d.ts +4 -0
- package/dist/commands/review-onboard-checklist.js +119 -0
- package/dist/commands/review-onboard-wizard.d.ts +4 -0
- package/dist/commands/review-onboard-wizard.js +92 -0
- package/dist/commands/review-onboard.d.ts +4 -0
- package/dist/commands/review-onboard.js +154 -0
- package/dist/commands/review-onboarding-check.d.ts +1 -0
- package/dist/commands/review-onboarding-check.js +93 -0
- package/dist/commands/review-org-dashboard.d.ts +4 -0
- package/dist/commands/review-org-dashboard.js +68 -0
- package/dist/commands/review-output-filter.d.ts +4 -0
- package/dist/commands/review-output-filter.js +112 -0
- package/dist/commands/review-output-format.d.ts +4 -0
- package/dist/commands/review-output-format.js +144 -0
- package/dist/commands/review-output-transform.d.ts +4 -0
- package/dist/commands/review-output-transform.js +119 -0
- package/dist/commands/review-owner.d.ts +4 -0
- package/dist/commands/review-owner.js +129 -0
- package/dist/commands/review-parallel-diff.d.ts +4 -0
- package/dist/commands/review-parallel-diff.js +146 -0
- package/dist/commands/review-parallel-files.d.ts +7 -0
- package/dist/commands/review-parallel-files.js +134 -0
- package/dist/commands/review-parallel-run.d.ts +4 -0
- package/dist/commands/review-parallel-run.js +116 -0
- package/dist/commands/review-parallel.d.ts +4 -0
- package/dist/commands/review-parallel.js +164 -0
- package/dist/commands/review-perf-profile.d.ts +4 -0
- package/dist/commands/review-perf-profile.js +98 -0
- package/dist/commands/review-permission-model.d.ts +4 -0
- package/dist/commands/review-permission-model.js +149 -0
- package/dist/commands/review-pipeline-status.d.ts +4 -0
- package/dist/commands/review-pipeline-status.js +54 -0
- package/dist/commands/review-plugin-config.d.ts +4 -0
- package/dist/commands/review-plugin-config.js +167 -0
- package/dist/commands/review-plugin-list.d.ts +4 -0
- package/dist/commands/review-plugin-list.js +99 -0
- package/dist/commands/review-plugin-manage.d.ts +4 -0
- package/dist/commands/review-plugin-manage.js +137 -0
- package/dist/commands/review-plugin-status.d.ts +4 -0
- package/dist/commands/review-plugin-status.js +53 -0
- package/dist/commands/review-policy-enforce.d.ts +1 -0
- package/dist/commands/review-policy-enforce.js +92 -0
- package/dist/commands/review-policy-engine.d.ts +4 -0
- package/dist/commands/review-policy-engine.js +135 -0
- package/dist/commands/review-pr-comment-gen.d.ts +4 -0
- package/dist/commands/review-pr-comment-gen.js +62 -0
- package/dist/commands/review-pr-comment.d.ts +4 -0
- package/dist/commands/review-pr-comment.js +106 -0
- package/dist/commands/review-pr-label-suggest.d.ts +1 -0
- package/dist/commands/review-pr-label-suggest.js +77 -0
- package/dist/commands/review-pr-size-check.d.ts +1 -0
- package/dist/commands/review-pr-size-check.js +98 -0
- package/dist/commands/review-pr-template.d.ts +4 -0
- package/dist/commands/review-pr-template.js +104 -0
- package/dist/commands/review-preset-save.d.ts +4 -0
- package/dist/commands/review-preset-save.js +159 -0
- package/dist/commands/review-priority.d.ts +4 -0
- package/dist/commands/review-priority.js +157 -0
- package/dist/commands/review-profile.d.ts +4 -0
- package/dist/commands/review-profile.js +168 -0
- package/dist/commands/review-progress-bar.d.ts +4 -0
- package/dist/commands/review-progress-bar.js +157 -0
- package/dist/commands/review-progress-report.d.ts +1 -0
- package/dist/commands/review-progress-report.js +95 -0
- package/dist/commands/review-progress-track.d.ts +4 -0
- package/dist/commands/review-progress-track.js +94 -0
- package/dist/commands/review-quality-baseline.d.ts +1 -0
- package/dist/commands/review-quality-baseline.js +134 -0
- package/dist/commands/review-quality-gate.d.ts +1 -0
- package/dist/commands/review-quality-gate.js +86 -0
- package/dist/commands/review-quality-score.d.ts +4 -0
- package/dist/commands/review-quality-score.js +127 -0
- package/dist/commands/review-quality-trend.d.ts +4 -0
- package/dist/commands/review-quality-trend.js +57 -0
- package/dist/commands/review-queue.d.ts +33 -0
- package/dist/commands/review-queue.js +225 -0
- package/dist/commands/review-quickstart.d.ts +4 -0
- package/dist/commands/review-quickstart.js +107 -0
- package/dist/commands/review-quota-check.d.ts +4 -0
- package/dist/commands/review-quota-check.js +97 -0
- package/dist/commands/review-quota.d.ts +4 -0
- package/dist/commands/review-quota.js +126 -0
- package/dist/commands/review-rate-limit.d.ts +4 -0
- package/dist/commands/review-rate-limit.js +130 -0
- package/dist/commands/review-readiness-check.d.ts +1 -0
- package/dist/commands/review-readiness-check.js +98 -0
- package/dist/commands/review-receipt.d.ts +4 -0
- package/dist/commands/review-receipt.js +220 -0
- package/dist/commands/review-release-gate.d.ts +1 -0
- package/dist/commands/review-release-gate.js +81 -0
- package/dist/commands/review-replay.d.ts +8 -0
- package/dist/commands/review-replay.js +264 -0
- package/dist/commands/review-repo-onboard.d.ts +4 -0
- package/dist/commands/review-repo-onboard.js +114 -0
- package/dist/commands/review-report-archive.d.ts +4 -0
- package/dist/commands/review-report-archive.js +100 -0
- package/dist/commands/review-report-merge.d.ts +4 -0
- package/dist/commands/review-report-merge.js +90 -0
- package/dist/commands/review-report-pdf.d.ts +4 -0
- package/dist/commands/review-report-pdf.js +163 -0
- package/dist/commands/review-report-schedule.d.ts +4 -0
- package/dist/commands/review-report-schedule.js +96 -0
- package/dist/commands/review-retrospective.d.ts +1 -0
- package/dist/commands/review-retrospective.js +118 -0
- package/dist/commands/review-retry.d.ts +4 -0
- package/dist/commands/review-retry.js +91 -0
- package/dist/commands/review-review-cadence.d.ts +1 -0
- package/dist/commands/review-review-cadence.js +85 -0
- package/dist/commands/review-review-comments.d.ts +4 -0
- package/dist/commands/review-review-comments.js +84 -0
- package/dist/commands/review-reviewer-match.d.ts +1 -0
- package/dist/commands/review-reviewer-match.js +108 -0
- package/dist/commands/review-risk-matrix.d.ts +1 -0
- package/dist/commands/review-risk-matrix.js +96 -0
- package/dist/commands/review-risk-score.d.ts +4 -0
- package/dist/commands/review-risk-score.js +156 -0
- package/dist/commands/review-role-assignment.d.ts +4 -0
- package/dist/commands/review-role-assignment.js +98 -0
- package/dist/commands/review-rollback.d.ts +4 -0
- package/dist/commands/review-rollback.js +171 -0
- package/dist/commands/review-rollout-plan.d.ts +4 -0
- package/dist/commands/review-rollout-plan.js +123 -0
- package/dist/commands/review-rule-filter.d.ts +4 -0
- package/dist/commands/review-rule-filter.js +116 -0
- package/dist/commands/review-rule-stats.d.ts +4 -0
- package/dist/commands/review-rule-stats.js +161 -0
- package/dist/commands/review-sandbox.d.ts +4 -0
- package/dist/commands/review-sandbox.js +191 -0
- package/dist/commands/review-schedule.d.ts +4 -0
- package/dist/commands/review-schedule.js +169 -0
- package/dist/commands/review-scope-limit.d.ts +4 -0
- package/dist/commands/review-scope-limit.js +100 -0
- package/dist/commands/review-scope-lock.d.ts +7 -0
- package/dist/commands/review-scope-lock.js +138 -0
- package/dist/commands/review-scope-select.d.ts +4 -0
- package/dist/commands/review-scope-select.js +98 -0
- package/dist/commands/review-scope-suggest.d.ts +1 -0
- package/dist/commands/review-scope-suggest.js +112 -0
- package/dist/commands/review-scope.d.ts +4 -0
- package/dist/commands/review-scope.js +197 -0
- package/dist/commands/review-score-history.d.ts +4 -0
- package/dist/commands/review-score-history.js +137 -0
- package/dist/commands/review-security-posture.d.ts +1 -0
- package/dist/commands/review-security-posture.js +105 -0
- package/dist/commands/review-session-replay.d.ts +4 -0
- package/dist/commands/review-session-replay.js +81 -0
- package/dist/commands/review-session-save.d.ts +4 -0
- package/dist/commands/review-session-save.js +173 -0
- package/dist/commands/review-session.d.ts +4 -0
- package/dist/commands/review-session.js +150 -0
- package/dist/commands/review-skip-list.d.ts +4 -0
- package/dist/commands/review-skip-list.js +135 -0
- package/dist/commands/review-skip-rule.d.ts +4 -0
- package/dist/commands/review-skip-rule.js +105 -0
- package/dist/commands/review-sla-config.d.ts +4 -0
- package/dist/commands/review-sla-config.js +88 -0
- package/dist/commands/review-slack-format.d.ts +4 -0
- package/dist/commands/review-slack-format.js +113 -0
- package/dist/commands/review-snapshot-diff.d.ts +4 -0
- package/dist/commands/review-snapshot-diff.js +100 -0
- package/dist/commands/review-sprint-plan.d.ts +1 -0
- package/dist/commands/review-sprint-plan.js +79 -0
- package/dist/commands/review-stakeholder-notify.d.ts +1 -0
- package/dist/commands/review-stakeholder-notify.js +134 -0
- package/dist/commands/review-stakeholder-report.d.ts +4 -0
- package/dist/commands/review-stakeholder-report.js +75 -0
- package/dist/commands/review-stale-finding-clean.d.ts +1 -0
- package/dist/commands/review-stale-finding-clean.js +81 -0
- package/dist/commands/review-standup.d.ts +4 -0
- package/dist/commands/review-standup.js +95 -0
- package/dist/commands/review-stats.d.ts +4 -0
- package/dist/commands/review-stats.js +175 -0
- package/dist/commands/review-status-badge.d.ts +4 -0
- package/dist/commands/review-status-badge.js +120 -0
- package/dist/commands/review-streak.d.ts +4 -0
- package/dist/commands/review-streak.js +150 -0
- package/dist/commands/review-summary-dashboard.d.ts +4 -0
- package/dist/commands/review-summary-dashboard.js +96 -0
- package/dist/commands/review-summary-email.d.ts +4 -0
- package/dist/commands/review-summary-email.js +102 -0
- package/dist/commands/review-summary.d.ts +4 -0
- package/dist/commands/review-summary.js +174 -0
- package/dist/commands/review-tag-manager.d.ts +4 -0
- package/dist/commands/review-tag-manager.js +128 -0
- package/dist/commands/review-tag.d.ts +4 -0
- package/dist/commands/review-tag.js +136 -0
- package/dist/commands/review-team-analytics.d.ts +1 -0
- package/dist/commands/review-team-analytics.js +94 -0
- package/dist/commands/review-team-assign.d.ts +7 -0
- package/dist/commands/review-team-assign.js +211 -0
- package/dist/commands/review-team-coverage.d.ts +1 -0
- package/dist/commands/review-team-coverage.js +95 -0
- package/dist/commands/review-team-dashboard.d.ts +4 -0
- package/dist/commands/review-team-dashboard.js +98 -0
- package/dist/commands/review-team-rotation.d.ts +1 -0
- package/dist/commands/review-team-rotation.js +99 -0
- package/dist/commands/review-team-skill-map.d.ts +1 -0
- package/dist/commands/review-team-skill-map.js +102 -0
- package/dist/commands/review-team-stats.d.ts +4 -0
- package/dist/commands/review-team-stats.js +97 -0
- package/dist/commands/review-team-summary.d.ts +4 -0
- package/dist/commands/review-team-summary.js +155 -0
- package/dist/commands/review-team-velocity.d.ts +1 -0
- package/dist/commands/review-team-velocity.js +103 -0
- package/dist/commands/review-template-export.d.ts +4 -0
- package/dist/commands/review-template-export.js +146 -0
- package/dist/commands/review-template-library.d.ts +4 -0
- package/dist/commands/review-template-library.js +155 -0
- package/dist/commands/review-template-suggest.d.ts +1 -0
- package/dist/commands/review-template-suggest.js +119 -0
- package/dist/commands/review-template.d.ts +4 -0
- package/dist/commands/review-template.js +212 -0
- package/dist/commands/review-tenant-config.d.ts +4 -0
- package/dist/commands/review-tenant-config.js +116 -0
- package/dist/commands/review-threshold-tune.d.ts +4 -0
- package/dist/commands/review-threshold-tune.js +135 -0
- package/dist/commands/review-timeline.d.ts +4 -0
- package/dist/commands/review-timeline.js +76 -0
- package/dist/commands/review-token-budget.d.ts +4 -0
- package/dist/commands/review-token-budget.js +117 -0
- package/dist/commands/review-velocity-track.d.ts +1 -0
- package/dist/commands/review-velocity-track.js +94 -0
- package/dist/commands/review-watch-mode.d.ts +7 -0
- package/dist/commands/review-watch-mode.js +132 -0
- package/dist/commands/review-webhook-dispatch.d.ts +4 -0
- package/dist/commands/review-webhook-dispatch.js +99 -0
- package/dist/commands/review-webhook-notify.d.ts +4 -0
- package/dist/commands/review-webhook-notify.js +145 -0
- package/dist/commands/review-webhook.d.ts +4 -0
- package/dist/commands/review-webhook.js +140 -0
- package/dist/commands/review-whitelist.d.ts +4 -0
- package/dist/commands/review-whitelist.js +150 -0
- package/dist/commands/review-workflow-suggest.d.ts +1 -0
- package/dist/commands/review-workflow-suggest.js +129 -0
- package/dist/commands/review-workload-balance.d.ts +1 -0
- package/dist/commands/review-workload-balance.js +86 -0
- package/dist/commands/review-workspace-init.d.ts +4 -0
- package/dist/commands/review-workspace-init.js +104 -0
- package/dist/commands/review-workspace-scan.d.ts +4 -0
- package/dist/commands/review-workspace-scan.js +144 -0
- package/dist/commands/review.d.ts +155 -0
- package/dist/commands/review.js +1114 -0
- package/dist/commands/risk-heatmap.d.ts +7 -0
- package/dist/commands/risk-heatmap.js +223 -0
- package/dist/commands/rollback-safety.d.ts +4 -0
- package/dist/commands/rollback-safety.js +191 -0
- package/dist/commands/rule-catalog.d.ts +4 -0
- package/dist/commands/rule-catalog.js +128 -0
- package/dist/commands/rule-metrics.d.ts +43 -0
- package/dist/commands/rule-metrics.js +113 -0
- package/dist/commands/rule-owner.d.ts +30 -0
- package/dist/commands/rule-owner.js +181 -0
- package/dist/commands/rule-share.d.ts +34 -0
- package/dist/commands/rule-share.js +202 -0
- package/dist/commands/rule-test.d.ts +4 -0
- package/dist/commands/rule-test.js +201 -0
- package/dist/commands/rule.d.ts +114 -0
- package/dist/commands/rule.js +295 -0
- package/dist/commands/sbom-export.d.ts +7 -0
- package/dist/commands/sbom-export.js +161 -0
- package/dist/commands/scaffold-plugin.d.ts +15 -0
- package/dist/commands/scaffold-plugin.js +270 -0
- package/dist/commands/secret-age.d.ts +5 -0
- package/dist/commands/secret-age.js +214 -0
- package/dist/commands/secret-scan.d.ts +7 -0
- package/dist/commands/secret-scan.js +244 -0
- package/dist/commands/security-maturity.d.ts +7 -0
- package/dist/commands/security-maturity.js +312 -0
- package/dist/commands/security-theater.d.ts +4 -0
- package/dist/commands/security-theater.js +278 -0
- package/dist/commands/setup-wizard.d.ts +4 -0
- package/dist/commands/setup-wizard.js +174 -0
- package/dist/commands/severity-tune.d.ts +4 -0
- package/dist/commands/severity-tune.js +208 -0
- package/dist/commands/sla-track.d.ts +56 -0
- package/dist/commands/sla-track.js +268 -0
- package/dist/commands/smart-output.d.ts +38 -0
- package/dist/commands/smart-output.js +175 -0
- package/dist/commands/smart-select.d.ts +26 -0
- package/dist/commands/smart-select.js +345 -0
- package/dist/commands/snapshot.d.ts +139 -0
- package/dist/commands/snapshot.js +478 -0
- package/dist/commands/snippet-eval.d.ts +7 -0
- package/dist/commands/snippet-eval.js +223 -0
- package/dist/commands/spec-conform.d.ts +4 -0
- package/dist/commands/spec-conform.js +304 -0
- package/dist/commands/stale-pattern.d.ts +4 -0
- package/dist/commands/stale-pattern.js +293 -0
- package/dist/commands/state-integrity.d.ts +4 -0
- package/dist/commands/state-integrity.js +283 -0
- package/dist/commands/suppress.d.ts +39 -0
- package/dist/commands/suppress.js +203 -0
- package/dist/commands/team-config.d.ts +4 -0
- package/dist/commands/team-config.js +234 -0
- package/dist/commands/team-leaderboard.d.ts +24 -0
- package/dist/commands/team-leaderboard.js +227 -0
- package/dist/commands/team-rules-sync.d.ts +7 -0
- package/dist/commands/team-rules-sync.js +250 -0
- package/dist/commands/team-trust.d.ts +7 -0
- package/dist/commands/team-trust.js +174 -0
- package/dist/commands/test-correlate.d.ts +7 -0
- package/dist/commands/test-correlate.js +221 -0
- package/dist/commands/test-isolation.d.ts +5 -0
- package/dist/commands/test-isolation.js +234 -0
- package/dist/commands/test-quality.d.ts +5 -0
- package/dist/commands/test-quality.js +160 -0
- package/dist/commands/test-suggest.d.ts +8 -0
- package/dist/commands/test-suggest.js +247 -0
- package/dist/commands/ticket-sync.d.ts +25 -0
- package/dist/commands/ticket-sync.js +235 -0
- package/dist/commands/timeout-audit.d.ts +4 -0
- package/dist/commands/timeout-audit.js +210 -0
- package/dist/commands/trace.d.ts +64 -0
- package/dist/commands/trace.js +245 -0
- package/dist/commands/trend-report.d.ts +4 -0
- package/dist/commands/trend-report.js +148 -0
- package/dist/commands/triage.d.ts +15 -0
- package/dist/commands/triage.js +171 -0
- package/dist/commands/trust-adaptive.d.ts +8 -0
- package/dist/commands/trust-adaptive.js +193 -0
- package/dist/commands/trust-ramp.d.ts +29 -0
- package/dist/commands/trust-ramp.js +189 -0
- package/dist/commands/tune.d.ts +24 -0
- package/dist/commands/tune.js +380 -0
- package/dist/commands/type-boundary.d.ts +4 -0
- package/dist/commands/type-boundary.js +235 -0
- package/dist/commands/upload.d.ts +13 -0
- package/dist/commands/upload.js +172 -0
- package/dist/commands/validate-config.d.ts +16 -0
- package/dist/commands/validate-config.js +267 -0
- package/dist/commands/vendor-lock-detect.d.ts +7 -0
- package/dist/commands/vendor-lock-detect.js +288 -0
- package/dist/commands/vote.d.ts +31 -0
- package/dist/commands/vote.js +200 -0
- package/dist/commands/warm-cache.d.ts +30 -0
- package/dist/commands/warm-cache.js +165 -0
- package/dist/commands/watch-judge.d.ts +7 -0
- package/dist/commands/watch-judge.js +179 -0
- package/dist/commands/watch.d.ts +22 -0
- package/dist/commands/watch.js +147 -0
- package/dist/comparison.d.ts +67 -0
- package/dist/comparison.js +253 -0
- package/dist/config.d.ts +108 -0
- package/dist/config.js +694 -0
- package/dist/context/context-snippets.d.ts +15 -0
- package/dist/context/context-snippets.js +36 -0
- package/dist/context/embedding-cache.d.ts +30 -0
- package/dist/context/embedding-cache.js +48 -0
- package/dist/data-adapter.d.ts +123 -0
- package/dist/data-adapter.js +212 -0
- package/dist/dedup.d.ts +105 -0
- package/dist/dedup.js +606 -0
- package/dist/disk-cache.d.ts +59 -0
- package/dist/disk-cache.js +236 -0
- package/dist/errors.d.ts +43 -0
- package/dist/errors.js +63 -0
- package/dist/escalation.d.ts +100 -0
- package/dist/escalation.js +292 -0
- package/dist/evaluation-session.d.ts +74 -0
- package/dist/evaluation-session.js +152 -0
- package/dist/evaluators/accessibility.d.ts +2 -0
- package/dist/evaluators/accessibility.js +559 -0
- package/dist/evaluators/agent-instructions.d.ts +2 -0
- package/dist/evaluators/agent-instructions.js +214 -0
- package/dist/evaluators/ai-code-safety.d.ts +8 -0
- package/dist/evaluators/ai-code-safety.js +410 -0
- package/dist/evaluators/api-contract.d.ts +9 -0
- package/dist/evaluators/api-contract.js +203 -0
- package/dist/evaluators/api-design.d.ts +2 -0
- package/dist/evaluators/api-design.js +260 -0
- package/dist/evaluators/app-builder.d.ts +33 -0
- package/dist/evaluators/app-builder.js +155 -0
- package/dist/evaluators/authentication.d.ts +2 -0
- package/dist/evaluators/authentication.js +455 -0
- package/dist/evaluators/backwards-compatibility.d.ts +2 -0
- package/dist/evaluators/backwards-compatibility.js +168 -0
- package/dist/evaluators/caching.d.ts +2 -0
- package/dist/evaluators/caching.js +171 -0
- package/dist/evaluators/ci-cd.d.ts +2 -0
- package/dist/evaluators/ci-cd.js +218 -0
- package/dist/evaluators/cloud-readiness.d.ts +2 -0
- package/dist/evaluators/cloud-readiness.js +231 -0
- package/dist/evaluators/code-structure.d.ts +21 -0
- package/dist/evaluators/code-structure.js +195 -0
- package/dist/evaluators/compliance.d.ts +2 -0
- package/dist/evaluators/compliance.js +329 -0
- package/dist/evaluators/concurrency.d.ts +2 -0
- package/dist/evaluators/concurrency.js +307 -0
- package/dist/evaluators/configuration-management.d.ts +2 -0
- package/dist/evaluators/configuration-management.js +232 -0
- package/dist/evaluators/cost-effectiveness.d.ts +2 -0
- package/dist/evaluators/cost-effectiveness.js +418 -0
- package/dist/evaluators/cybersecurity.d.ts +2 -0
- package/dist/evaluators/cybersecurity.js +1197 -0
- package/dist/evaluators/data-security.d.ts +2 -0
- package/dist/evaluators/data-security.js +467 -0
- package/dist/evaluators/data-sovereignty.d.ts +2 -0
- package/dist/evaluators/data-sovereignty.js +495 -0
- package/dist/evaluators/database.d.ts +2 -0
- package/dist/evaluators/database.js +240 -0
- package/dist/evaluators/dependencies.d.ts +5 -0
- package/dist/evaluators/dependencies.js +228 -0
- package/dist/evaluators/dependency-health.d.ts +2 -0
- package/dist/evaluators/dependency-health.js +477 -0
- package/dist/evaluators/documentation.d.ts +2 -0
- package/dist/evaluators/documentation.js +432 -0
- package/dist/evaluators/error-handling.d.ts +2 -0
- package/dist/evaluators/error-handling.js +426 -0
- package/dist/evaluators/ethics-bias.d.ts +2 -0
- package/dist/evaluators/ethics-bias.js +263 -0
- package/dist/evaluators/false-positive-review.d.ts +21 -0
- package/dist/evaluators/false-positive-review.js +1246 -0
- package/dist/evaluators/framework-rules.d.ts +58 -0
- package/dist/evaluators/framework-rules.js +291 -0
- package/dist/evaluators/framework-safety.d.ts +12 -0
- package/dist/evaluators/framework-safety.js +1205 -0
- package/dist/evaluators/hallucination-detection.d.ts +2 -0
- package/dist/evaluators/hallucination-detection.js +1250 -0
- package/dist/evaluators/iac-security.d.ts +8 -0
- package/dist/evaluators/iac-security.js +701 -0
- package/dist/evaluators/index.d.ts +167 -0
- package/dist/evaluators/index.js +994 -0
- package/dist/evaluators/intent-alignment.d.ts +18 -0
- package/dist/evaluators/intent-alignment.js +405 -0
- package/dist/evaluators/internationalization.d.ts +2 -0
- package/dist/evaluators/internationalization.js +287 -0
- package/dist/evaluators/judge-selector.d.ts +19 -0
- package/dist/evaluators/judge-selector.js +141 -0
- package/dist/evaluators/logging-privacy.d.ts +2 -0
- package/dist/evaluators/logging-privacy.js +190 -0
- package/dist/evaluators/logic-review.d.ts +2 -0
- package/dist/evaluators/logic-review.js +289 -0
- package/dist/evaluators/maintainability.d.ts +2 -0
- package/dist/evaluators/maintainability.js +430 -0
- package/dist/evaluators/model-fingerprint.d.ts +2 -0
- package/dist/evaluators/model-fingerprint.js +151 -0
- package/dist/evaluators/multi-turn-coherence.d.ts +13 -0
- package/dist/evaluators/multi-turn-coherence.js +149 -0
- package/dist/evaluators/observability.d.ts +2 -0
- package/dist/evaluators/observability.js +238 -0
- package/dist/evaluators/over-engineering.d.ts +2 -0
- package/dist/evaluators/over-engineering.js +160 -0
- package/dist/evaluators/performance.d.ts +2 -0
- package/dist/evaluators/performance.js +649 -0
- package/dist/evaluators/portability.d.ts +2 -0
- package/dist/evaluators/portability.js +254 -0
- package/dist/evaluators/project.d.ts +48 -0
- package/dist/evaluators/project.js +817 -0
- package/dist/evaluators/rate-limiting.d.ts +2 -0
- package/dist/evaluators/rate-limiting.js +193 -0
- package/dist/evaluators/recall-boost.d.ts +27 -0
- package/dist/evaluators/recall-boost.js +409 -0
- package/dist/evaluators/reliability.d.ts +2 -0
- package/dist/evaluators/reliability.js +245 -0
- package/dist/evaluators/scalability.d.ts +2 -0
- package/dist/evaluators/scalability.js +230 -0
- package/dist/evaluators/security.d.ts +12 -0
- package/dist/evaluators/security.js +1013 -0
- package/dist/evaluators/shared.d.ts +219 -0
- package/dist/evaluators/shared.js +1169 -0
- package/dist/evaluators/software-practices.d.ts +2 -0
- package/dist/evaluators/software-practices.js +395 -0
- package/dist/evaluators/suppressions.d.ts +49 -0
- package/dist/evaluators/suppressions.js +185 -0
- package/dist/evaluators/testing.d.ts +2 -0
- package/dist/evaluators/testing.js +348 -0
- package/dist/evaluators/ux.d.ts +2 -0
- package/dist/evaluators/ux.js +309 -0
- package/dist/evaluators/v2.d.ts +26 -0
- package/dist/evaluators/v2.js +354 -0
- package/dist/ext-to-lang.d.ts +16 -0
- package/dist/ext-to-lang.js +60 -0
- package/dist/feedback-loop.d.ts +62 -0
- package/dist/feedback-loop.js +179 -0
- package/dist/finding-lifecycle.d.ts +215 -0
- package/dist/finding-lifecycle.js +547 -0
- package/dist/fingerprint.d.ts +39 -0
- package/dist/fingerprint.js +179 -0
- package/dist/fix-history.d.ts +103 -0
- package/dist/fix-history.js +164 -0
- package/dist/formatters/badge.d.ts +16 -0
- package/dist/formatters/badge.js +78 -0
- package/dist/formatters/codeclimate.d.ts +24 -0
- package/dist/formatters/codeclimate.js +80 -0
- package/dist/formatters/csv.d.ts +16 -0
- package/dist/formatters/csv.js +53 -0
- package/dist/formatters/diagnostics.d.ts +81 -0
- package/dist/formatters/diagnostics.js +152 -0
- package/dist/formatters/github-actions.d.ts +6 -0
- package/dist/formatters/github-actions.js +68 -0
- package/dist/formatters/html.d.ts +12 -0
- package/dist/formatters/html.js +194 -0
- package/dist/formatters/junit.d.ts +6 -0
- package/dist/formatters/junit.js +68 -0
- package/dist/formatters/pdf.d.ts +12 -0
- package/dist/formatters/pdf.js +114 -0
- package/dist/formatters/sarif.d.ts +92 -0
- package/dist/formatters/sarif.js +256 -0
- package/dist/formatters/shared.d.ts +4 -0
- package/dist/formatters/shared.js +29 -0
- package/dist/git-diff.d.ts +62 -0
- package/dist/git-diff.js +282 -0
- package/dist/github-app.d.ts +152 -0
- package/dist/github-app.js +716 -0
- package/dist/import-resolver.d.ts +51 -0
- package/dist/import-resolver.js +213 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +38 -0
- package/dist/judge-registry.d.ts +156 -0
- package/dist/judge-registry.js +272 -0
- package/dist/judges/accessibility.d.ts +2 -0
- package/dist/judges/accessibility.js +46 -0
- package/dist/judges/agent-instructions.d.ts +2 -0
- package/dist/judges/agent-instructions.js +46 -0
- package/dist/judges/ai-code-safety.d.ts +2 -0
- package/dist/judges/ai-code-safety.js +57 -0
- package/dist/judges/api-contract.d.ts +2 -0
- package/dist/judges/api-contract.js +40 -0
- package/dist/judges/api-design.d.ts +2 -0
- package/dist/judges/api-design.js +57 -0
- package/dist/judges/authentication.d.ts +2 -0
- package/dist/judges/authentication.js +63 -0
- package/dist/judges/backwards-compatibility.d.ts +2 -0
- package/dist/judges/backwards-compatibility.js +46 -0
- package/dist/judges/caching.d.ts +2 -0
- package/dist/judges/caching.js +46 -0
- package/dist/judges/ci-cd.d.ts +2 -0
- package/dist/judges/ci-cd.js +46 -0
- package/dist/judges/cloud-readiness.d.ts +2 -0
- package/dist/judges/cloud-readiness.js +53 -0
- package/dist/judges/code-structure.d.ts +2 -0
- package/dist/judges/code-structure.js +50 -0
- package/dist/judges/compliance.d.ts +2 -0
- package/dist/judges/compliance.js +49 -0
- package/dist/judges/concurrency.d.ts +2 -0
- package/dist/judges/concurrency.js +48 -0
- package/dist/judges/configuration-management.d.ts +2 -0
- package/dist/judges/configuration-management.js +46 -0
- package/dist/judges/cost-effectiveness.d.ts +2 -0
- package/dist/judges/cost-effectiveness.js +42 -0
- package/dist/judges/cybersecurity.d.ts +2 -0
- package/dist/judges/cybersecurity.js +63 -0
- package/dist/judges/data-security.d.ts +2 -0
- package/dist/judges/data-security.js +50 -0
- package/dist/judges/data-sovereignty.d.ts +2 -0
- package/dist/judges/data-sovereignty.js +60 -0
- package/dist/judges/database.d.ts +2 -0
- package/dist/judges/database.js +51 -0
- package/dist/judges/dependency-health.d.ts +2 -0
- package/dist/judges/dependency-health.js +48 -0
- package/dist/judges/documentation.d.ts +2 -0
- package/dist/judges/documentation.js +55 -0
- package/dist/judges/error-handling.d.ts +2 -0
- package/dist/judges/error-handling.js +55 -0
- package/dist/judges/ethics-bias.d.ts +2 -0
- package/dist/judges/ethics-bias.js +48 -0
- package/dist/judges/false-positive-review.d.ts +2 -0
- package/dist/judges/false-positive-review.js +85 -0
- package/dist/judges/framework-safety.d.ts +2 -0
- package/dist/judges/framework-safety.js +49 -0
- package/dist/judges/hallucination-detection.d.ts +2 -0
- package/dist/judges/hallucination-detection.js +48 -0
- package/dist/judges/iac-security.d.ts +2 -0
- package/dist/judges/iac-security.js +47 -0
- package/dist/judges/index.d.ts +88 -0
- package/dist/judges/index.js +128 -0
- package/dist/judges/intent-alignment.d.ts +2 -0
- package/dist/judges/intent-alignment.js +46 -0
- package/dist/judges/internationalization.d.ts +2 -0
- package/dist/judges/internationalization.js +44 -0
- package/dist/judges/logging-privacy.d.ts +2 -0
- package/dist/judges/logging-privacy.js +46 -0
- package/dist/judges/logic-review.d.ts +2 -0
- package/dist/judges/logic-review.js +36 -0
- package/dist/judges/maintainability.d.ts +2 -0
- package/dist/judges/maintainability.js +46 -0
- package/dist/judges/model-fingerprint.d.ts +2 -0
- package/dist/judges/model-fingerprint.js +35 -0
- package/dist/judges/multi-turn-coherence.d.ts +2 -0
- package/dist/judges/multi-turn-coherence.js +39 -0
- package/dist/judges/observability.d.ts +2 -0
- package/dist/judges/observability.js +54 -0
- package/dist/judges/over-engineering.d.ts +2 -0
- package/dist/judges/over-engineering.js +50 -0
- package/dist/judges/performance.d.ts +2 -0
- package/dist/judges/performance.js +46 -0
- package/dist/judges/portability.d.ts +2 -0
- package/dist/judges/portability.js +46 -0
- package/dist/judges/rate-limiting.d.ts +2 -0
- package/dist/judges/rate-limiting.js +55 -0
- package/dist/judges/reliability.d.ts +2 -0
- package/dist/judges/reliability.js +57 -0
- package/dist/judges/scalability.d.ts +2 -0
- package/dist/judges/scalability.js +52 -0
- package/dist/judges/security.d.ts +2 -0
- package/dist/judges/security.js +64 -0
- package/dist/judges/software-practices.d.ts +2 -0
- package/dist/judges/software-practices.js +56 -0
- package/dist/judges/testing.d.ts +2 -0
- package/dist/judges/testing.js +54 -0
- package/dist/judges/ux.d.ts +2 -0
- package/dist/judges/ux.js +46 -0
- package/dist/language-patterns.d.ts +653 -0
- package/dist/language-patterns.js +851 -0
- package/dist/parallel.d.ts +52 -0
- package/dist/parallel.js +157 -0
- package/dist/patches/apply.d.ts +15 -0
- package/dist/patches/apply.js +37 -0
- package/dist/patches/index.d.ts +9 -0
- package/dist/patches/index.js +2544 -0
- package/dist/plugins.d.ts +59 -0
- package/dist/plugins.js +76 -0
- package/dist/presets.d.ts +35 -0
- package/dist/presets.js +406 -0
- package/dist/probabilistic/llm-response-validator.d.ts +26 -0
- package/dist/probabilistic/llm-response-validator.js +122 -0
- package/dist/reports/public-repo-report.d.ts +42 -0
- package/dist/reports/public-repo-report.js +579 -0
- package/dist/review-conversation.d.ts +87 -0
- package/dist/review-conversation.js +307 -0
- package/dist/sast-integration.d.ts +112 -0
- package/dist/sast-integration.js +215 -0
- package/dist/scoring.d.ts +36 -0
- package/dist/scoring.js +437 -0
- package/dist/security-ids.d.ts +23 -0
- package/dist/security-ids.js +239 -0
- package/dist/skill-loader.d.ts +33 -0
- package/dist/skill-loader.js +167 -0
- package/dist/tools/command-safety.d.ts +13 -0
- package/dist/tools/command-safety.js +95 -0
- package/dist/tools/deep-review.d.ts +38 -0
- package/dist/tools/deep-review.js +302 -0
- package/dist/tools/prompts.d.ts +27 -0
- package/dist/tools/prompts.js +122 -0
- package/dist/tools/register-evaluation.d.ts +6 -0
- package/dist/tools/register-evaluation.js +587 -0
- package/dist/tools/register-fix.d.ts +5 -0
- package/dist/tools/register-fix.js +175 -0
- package/dist/tools/register-resources.d.ts +6 -0
- package/dist/tools/register-resources.js +177 -0
- package/dist/tools/register-review.d.ts +6 -0
- package/dist/tools/register-review.js +564 -0
- package/dist/tools/register-scaffold.d.ts +2 -0
- package/dist/tools/register-scaffold.js +398 -0
- package/dist/tools/register-workflow.d.ts +6 -0
- package/dist/tools/register-workflow.js +1037 -0
- package/dist/tools/register-workspace.d.ts +2 -0
- package/dist/tools/register-workspace.js +214 -0
- package/dist/tools/register.d.ts +6 -0
- package/dist/tools/register.js +21 -0
- package/dist/tools/schemas.d.ts +25 -0
- package/dist/tools/schemas.js +41 -0
- package/dist/tools/validation.d.ts +13 -0
- package/dist/tools/validation.js +77 -0
- package/dist/types.d.ts +898 -0
- package/dist/types.js +1 -0
- package/package.json +54 -0
- package/skills/ai-code-review.skill.md +57 -0
- package/skills/release-gate.skill.md +27 -0
- package/skills/security-review.skill.md +32 -0
|
@@ -0,0 +1,3060 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance, ethics, accessibility, internationalization, UX, compatibility,
|
|
3
|
+
* portability, and dependency health benchmark cases.
|
|
4
|
+
*
|
|
5
|
+
* Covers COMP, SOV, ETHICS, A11Y, I18N, UX, COMPAT, DEPS, PORTA prefixes.
|
|
6
|
+
*/
|
|
7
|
+
export const BENCHMARK_COMPLIANCE_ETHICS = [
|
|
8
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
9
|
+
// COMP — Compliance violations (HIPAA, PCI-DSS, SOX, GDPR patterns)
|
|
10
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
11
|
+
{
|
|
12
|
+
id: "comp-deep-pii-plaintext-log",
|
|
13
|
+
description: "Logging PII (SSN, email, phone) in plaintext — HIPAA/GDPR violation",
|
|
14
|
+
language: "typescript",
|
|
15
|
+
code: `import { logger } from "./logger";
|
|
16
|
+
|
|
17
|
+
export async function processPatientIntake(patient: PatientRecord) {
|
|
18
|
+
logger.info("Processing patient intake", {
|
|
19
|
+
ssn: patient.ssn,
|
|
20
|
+
firstName: patient.firstName,
|
|
21
|
+
lastName: patient.lastName,
|
|
22
|
+
dateOfBirth: patient.dateOfBirth,
|
|
23
|
+
email: patient.email,
|
|
24
|
+
phone: patient.phone,
|
|
25
|
+
insuranceId: patient.insuranceId,
|
|
26
|
+
diagnosis: patient.diagnosis,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const result = await db.patients.insert(patient);
|
|
30
|
+
logger.info(\`Patient record created: \${patient.ssn}, DOB: \${patient.dateOfBirth}\`);
|
|
31
|
+
return result;
|
|
32
|
+
}`,
|
|
33
|
+
expectedRuleIds: ["DATA-001"],
|
|
34
|
+
category: "compliance",
|
|
35
|
+
difficulty: "easy",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "comp-deep-credit-card-storage",
|
|
39
|
+
description: "Storing full credit card numbers in database — PCI-DSS violation",
|
|
40
|
+
language: "typescript",
|
|
41
|
+
code: `interface PaymentRecord {
|
|
42
|
+
id: string;
|
|
43
|
+
userId: string;
|
|
44
|
+
cardNumber: string;
|
|
45
|
+
expiryMonth: number;
|
|
46
|
+
expiryYear: number;
|
|
47
|
+
cvv: string;
|
|
48
|
+
amount: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function savePayment(payment: PaymentRecord) {
|
|
52
|
+
await db.query(
|
|
53
|
+
\`INSERT INTO payments (id, user_id, card_number, expiry_month, expiry_year, cvv, amount)
|
|
54
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)\`,
|
|
55
|
+
[payment.id, payment.userId, payment.cardNumber,
|
|
56
|
+
payment.expiryMonth, payment.expiryYear, payment.cvv, payment.amount]
|
|
57
|
+
);
|
|
58
|
+
console.log(\`Payment saved: card ending \${payment.cardNumber.slice(-4)}\`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function getPaymentHistory(userId: string) {
|
|
62
|
+
return db.query("SELECT * FROM payments WHERE user_id = $1", [userId]);
|
|
63
|
+
// Returns full card numbers and CVVs
|
|
64
|
+
}`,
|
|
65
|
+
expectedRuleIds: ["COMP-001"],
|
|
66
|
+
category: "compliance",
|
|
67
|
+
difficulty: "easy",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "comp-deep-audit-trail-missing",
|
|
71
|
+
description: "Admin operations without audit trail — SOX compliance failure",
|
|
72
|
+
language: "typescript",
|
|
73
|
+
code: `export async function adminDeleteUser(userId: string) {
|
|
74
|
+
await db.query("DELETE FROM user_sessions WHERE user_id = $1", [userId]);
|
|
75
|
+
await db.query("DELETE FROM user_orders WHERE user_id = $1", [userId]);
|
|
76
|
+
await db.query("DELETE FROM users WHERE id = $1", [userId]);
|
|
77
|
+
// No audit log, no record of who deleted, no reason captured
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function adminModifyFinancialRecord(
|
|
81
|
+
recordId: string,
|
|
82
|
+
newAmount: number
|
|
83
|
+
) {
|
|
84
|
+
await db.query(
|
|
85
|
+
"UPDATE financial_records SET amount = $1 WHERE id = $2",
|
|
86
|
+
[newAmount, recordId]
|
|
87
|
+
);
|
|
88
|
+
// No versioning, no before/after snapshot, no approval workflow
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function adminGrantPermission(userId: string, role: string) {
|
|
92
|
+
await db.query(
|
|
93
|
+
"UPDATE users SET role = $1 WHERE id = $2",
|
|
94
|
+
[role, userId]
|
|
95
|
+
);
|
|
96
|
+
// No record of privilege escalation
|
|
97
|
+
}`,
|
|
98
|
+
expectedRuleIds: ["COMP-001"],
|
|
99
|
+
category: "compliance",
|
|
100
|
+
difficulty: "medium",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "comp-deep-gdpr-no-consent",
|
|
104
|
+
description: "Collecting user data without consent management — GDPR violation",
|
|
105
|
+
language: "typescript",
|
|
106
|
+
code: `import express from "express";
|
|
107
|
+
|
|
108
|
+
const app = express();
|
|
109
|
+
|
|
110
|
+
app.post("/api/register", async (req, res) => {
|
|
111
|
+
const { email, name, phone, address, dateOfBirth } = req.body;
|
|
112
|
+
|
|
113
|
+
const user = await db.users.create({
|
|
114
|
+
email, name, phone, address, dateOfBirth,
|
|
115
|
+
marketingOptIn: true, // Auto-opted in
|
|
116
|
+
dataSharing: true, // No explicit consent
|
|
117
|
+
trackingEnabled: true, // No option to decline
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Share data with third parties immediately
|
|
121
|
+
await analytics.track("user_registered", { email, name, phone });
|
|
122
|
+
await emailProvider.addSubscriber(email, { name, phone });
|
|
123
|
+
await adNetwork.syncAudience({ email, dateOfBirth, address });
|
|
124
|
+
|
|
125
|
+
res.json({ userId: user.id });
|
|
126
|
+
});`,
|
|
127
|
+
expectedRuleIds: ["COMP-001"],
|
|
128
|
+
category: "compliance",
|
|
129
|
+
difficulty: "medium",
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: "comp-deep-data-retention-none",
|
|
133
|
+
description: "No data retention policy — records kept indefinitely",
|
|
134
|
+
language: "typescript",
|
|
135
|
+
code: `export async function logUserActivity(userId: string, action: string, details: any) {
|
|
136
|
+
await db.query(
|
|
137
|
+
"INSERT INTO activity_logs (user_id, action, details, ip_address, user_agent, timestamp) VALUES ($1, $2, $3, $4, $5, NOW())",
|
|
138
|
+
[userId, action, JSON.stringify(details), details.ip, details.userAgent]
|
|
139
|
+
);
|
|
140
|
+
// Logs stored forever — no retention policy
|
|
141
|
+
// No periodic cleanup job
|
|
142
|
+
// No anonymization after retention period
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export async function storeSessionRecording(userId: string, recording: Buffer) {
|
|
146
|
+
await s3.putObject({
|
|
147
|
+
Bucket: "session-recordings",
|
|
148
|
+
Key: \`\${userId}/\${Date.now()}.webm\`,
|
|
149
|
+
Body: recording,
|
|
150
|
+
});
|
|
151
|
+
// Full session recordings stored indefinitely
|
|
152
|
+
// No lifecycle policy, no user deletion capability
|
|
153
|
+
}`,
|
|
154
|
+
expectedRuleIds: ["COMP-001"],
|
|
155
|
+
category: "compliance",
|
|
156
|
+
difficulty: "hard",
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: "comp-deep-phi-api-response",
|
|
160
|
+
description: "API returning Protected Health Information without access controls",
|
|
161
|
+
language: "typescript",
|
|
162
|
+
code: `import express from "express";
|
|
163
|
+
|
|
164
|
+
const app = express();
|
|
165
|
+
|
|
166
|
+
// No authentication middleware
|
|
167
|
+
app.get("/api/patients/:id", async (req, res) => {
|
|
168
|
+
const patient = await db.query(
|
|
169
|
+
"SELECT * FROM patients WHERE id = $1",
|
|
170
|
+
[req.params.id]
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
// Returns all PHI fields including SSN, diagnosis, medications
|
|
174
|
+
res.json(patient);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
app.get("/api/patients/search", async (req, res) => {
|
|
178
|
+
const { name, dob } = req.query;
|
|
179
|
+
const patients = await db.query(
|
|
180
|
+
"SELECT id, ssn, first_name, last_name, date_of_birth, diagnosis, medications FROM patients WHERE first_name ILIKE $1 OR date_of_birth = $2",
|
|
181
|
+
[\`%\${name}%\`, dob]
|
|
182
|
+
);
|
|
183
|
+
res.json(patients);
|
|
184
|
+
});`,
|
|
185
|
+
expectedRuleIds: ["COMP-001"],
|
|
186
|
+
category: "compliance",
|
|
187
|
+
difficulty: "easy",
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: "comp-deep-encryption-at-rest-missing",
|
|
191
|
+
description: "Sensitive data stored without encryption at rest",
|
|
192
|
+
language: "typescript",
|
|
193
|
+
code: `import fs from "fs";
|
|
194
|
+
import path from "path";
|
|
195
|
+
|
|
196
|
+
export function storeUserDocuments(userId: string, documents: Document[]) {
|
|
197
|
+
const userDir = path.join("/data/documents", userId);
|
|
198
|
+
fs.mkdirSync(userDir, { recursive: true });
|
|
199
|
+
|
|
200
|
+
for (const doc of documents) {
|
|
201
|
+
// Storing tax returns, medical records, IDs as plain files
|
|
202
|
+
fs.writeFileSync(
|
|
203
|
+
path.join(userDir, doc.filename),
|
|
204
|
+
doc.content
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Store metadata in plain JSON
|
|
209
|
+
fs.writeFileSync(
|
|
210
|
+
path.join(userDir, "metadata.json"),
|
|
211
|
+
JSON.stringify({
|
|
212
|
+
ssn: documents[0]?.ssn,
|
|
213
|
+
taxId: documents[0]?.taxId,
|
|
214
|
+
uploadedAt: new Date().toISOString(),
|
|
215
|
+
})
|
|
216
|
+
);
|
|
217
|
+
}`,
|
|
218
|
+
expectedRuleIds: ["COMP-001"],
|
|
219
|
+
category: "compliance",
|
|
220
|
+
difficulty: "medium",
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: "comp-deep-minor-data-no-coppa",
|
|
224
|
+
description: "Collecting data from minors without COPPA compliance",
|
|
225
|
+
language: "typescript",
|
|
226
|
+
code: `export async function registerUser(data: RegistrationData) {
|
|
227
|
+
const user = await db.users.create({
|
|
228
|
+
email: data.email,
|
|
229
|
+
name: data.name,
|
|
230
|
+
age: data.age,
|
|
231
|
+
school: data.school,
|
|
232
|
+
parentEmail: data.parentEmail,
|
|
233
|
+
location: data.location,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// No age verification
|
|
237
|
+
// No parental consent for users under 13
|
|
238
|
+
// Collecting school information from minors
|
|
239
|
+
// No special data handling for children's data
|
|
240
|
+
|
|
241
|
+
await analytics.identify(user.id, {
|
|
242
|
+
age: data.age,
|
|
243
|
+
school: data.school,
|
|
244
|
+
location: data.location,
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
await adNetwork.targetUser(user.id, {
|
|
248
|
+
ageGroup: data.age < 13 ? "child" : "teen",
|
|
249
|
+
interests: await inferInterests(user.id),
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
return user;
|
|
253
|
+
}`,
|
|
254
|
+
expectedRuleIds: ["COMP-001"],
|
|
255
|
+
category: "compliance",
|
|
256
|
+
difficulty: "hard",
|
|
257
|
+
},
|
|
258
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
259
|
+
// SOV — Data sovereignty violations
|
|
260
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
261
|
+
{
|
|
262
|
+
id: "sov-deep-cross-region-transfer",
|
|
263
|
+
description: "EU user data replicated to US region without safeguards",
|
|
264
|
+
language: "typescript",
|
|
265
|
+
code: `const S3_BUCKETS = {
|
|
266
|
+
primary: "s3://us-east-1-data-lake",
|
|
267
|
+
backup: "s3://us-west-2-backup",
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export async function storeUserData(userId: string, region: string, data: UserData) {
|
|
271
|
+
// All data goes to US buckets regardless of user region
|
|
272
|
+
await s3.putObject({
|
|
273
|
+
Bucket: S3_BUCKETS.primary.replace("s3://", ""),
|
|
274
|
+
Key: \`users/\${userId}/profile.json\`,
|
|
275
|
+
Body: JSON.stringify(data),
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Backup also in US
|
|
279
|
+
await s3.putObject({
|
|
280
|
+
Bucket: S3_BUCKETS.backup.replace("s3://", ""),
|
|
281
|
+
Key: \`users/\${userId}/profile.json\`,
|
|
282
|
+
Body: JSON.stringify(data),
|
|
283
|
+
});
|
|
284
|
+
// EU users' personal data stored in US without SCCs or adequacy decision
|
|
285
|
+
}`,
|
|
286
|
+
expectedRuleIds: ["SOV-001"],
|
|
287
|
+
category: "sovereignty",
|
|
288
|
+
difficulty: "medium",
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
id: "sov-deep-analytics-third-country",
|
|
292
|
+
description: "Sending analytics data to servers in non-adequate countries",
|
|
293
|
+
language: "typescript",
|
|
294
|
+
code: `import Analytics from "analytics-sdk";
|
|
295
|
+
|
|
296
|
+
const analytics = new Analytics({
|
|
297
|
+
writeKey: process.env.ANALYTICS_KEY!,
|
|
298
|
+
host: "https://analytics.example-cn.com", // Server in non-adequate jurisdiction
|
|
299
|
+
flushAt: 20,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
export function trackUserBehavior(userId: string, event: string, properties: any) {
|
|
303
|
+
analytics.track({
|
|
304
|
+
userId,
|
|
305
|
+
event,
|
|
306
|
+
properties: {
|
|
307
|
+
...properties,
|
|
308
|
+
email: properties.email,
|
|
309
|
+
ipAddress: properties.ip,
|
|
310
|
+
deviceId: properties.deviceId,
|
|
311
|
+
location: properties.location,
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
// Personal data (email, IP, location) sent to third-country server
|
|
315
|
+
// No data processing agreement
|
|
316
|
+
// No user notification about cross-border transfer
|
|
317
|
+
}`,
|
|
318
|
+
expectedRuleIds: ["SOV-001"],
|
|
319
|
+
category: "sovereignty",
|
|
320
|
+
difficulty: "hard",
|
|
321
|
+
},
|
|
322
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
323
|
+
// ETHICS — Ethical coding violations
|
|
324
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
325
|
+
{
|
|
326
|
+
id: "ethics-deep-discriminatory-pricing",
|
|
327
|
+
description: "Pricing algorithm discriminating by demographic attributes",
|
|
328
|
+
language: "python",
|
|
329
|
+
code: `def calculate_insurance_premium(user_profile):
|
|
330
|
+
base_rate = 500
|
|
331
|
+
|
|
332
|
+
# Discriminatory factors
|
|
333
|
+
if user_profile['gender'] == 'female':
|
|
334
|
+
base_rate *= 1.2
|
|
335
|
+
|
|
336
|
+
if user_profile['zip_code'] in LOW_INCOME_ZIPS:
|
|
337
|
+
base_rate *= 1.5
|
|
338
|
+
|
|
339
|
+
if user_profile['ethnicity'] in ['hispanic', 'african_american']:
|
|
340
|
+
base_rate *= 1.3
|
|
341
|
+
|
|
342
|
+
# Age-based surcharge (may violate age discrimination laws)
|
|
343
|
+
if user_profile['age'] > 60:
|
|
344
|
+
base_rate *= 2.0
|
|
345
|
+
|
|
346
|
+
if user_profile['marital_status'] == 'single':
|
|
347
|
+
base_rate *= 1.1
|
|
348
|
+
|
|
349
|
+
return base_rate`,
|
|
350
|
+
expectedRuleIds: ["ETHICS-001"],
|
|
351
|
+
category: "ethics",
|
|
352
|
+
difficulty: "easy",
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
id: "ethics-deep-dark-pattern-unsubscribe",
|
|
356
|
+
description: "Dark pattern making unsubscription difficult",
|
|
357
|
+
language: "typescript",
|
|
358
|
+
code: `export function renderUnsubscribePage(userId: string) {
|
|
359
|
+
return \`
|
|
360
|
+
<div style="max-width: 400px; margin: 100px auto;">
|
|
361
|
+
<h2>We're sorry to see you go!</h2>
|
|
362
|
+
<p>Are you sure? You'll miss out on exclusive deals!</p>
|
|
363
|
+
<form action="/api/unsubscribe" method="POST">
|
|
364
|
+
<input type="hidden" name="userId" value="\${userId}" />
|
|
365
|
+
<p>Please tell us why (required):</p>
|
|
366
|
+
<textarea name="reason" required minlength="50"></textarea>
|
|
367
|
+
<p>Type "UNSUBSCRIBE" to confirm:</p>
|
|
368
|
+
<input type="text" name="confirmation" pattern="UNSUBSCRIBE" required />
|
|
369
|
+
<div style="margin-top: 20px;">
|
|
370
|
+
<button type="submit"
|
|
371
|
+
style="background: #ccc; color: #999; font-size: 10px; border: none; padding: 2px 5px;">
|
|
372
|
+
Unsubscribe
|
|
373
|
+
</button>
|
|
374
|
+
<button type="button" onclick="window.location='/'"
|
|
375
|
+
style="background: #007bff; color: white; font-size: 16px; padding: 10px 30px; border: none; border-radius: 5px;">
|
|
376
|
+
Keep my subscription!
|
|
377
|
+
</button>
|
|
378
|
+
</div>
|
|
379
|
+
</form>
|
|
380
|
+
</div>
|
|
381
|
+
\`;
|
|
382
|
+
}`,
|
|
383
|
+
expectedRuleIds: ["A11Y-001"],
|
|
384
|
+
category: "ethics",
|
|
385
|
+
difficulty: "medium",
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
id: "ethics-deep-hidden-data-collection",
|
|
389
|
+
description: "Hidden data collection beyond stated purpose",
|
|
390
|
+
language: "typescript",
|
|
391
|
+
code: `export class WeatherWidget {
|
|
392
|
+
async getWeather(location: string) {
|
|
393
|
+
const weather = await fetch(\`https://api.weather.com/\${location}\`);
|
|
394
|
+
|
|
395
|
+
// Silently collect additional data beyond weather functionality
|
|
396
|
+
const fingerprint = {
|
|
397
|
+
screenResolution: \`\${screen.width}x\${screen.height}\`,
|
|
398
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
399
|
+
language: navigator.language,
|
|
400
|
+
plugins: Array.from(navigator.plugins).map(p => p.name),
|
|
401
|
+
canvas: this.getCanvasFingerprint(),
|
|
402
|
+
fonts: await this.detectFonts(),
|
|
403
|
+
battery: await (navigator as any).getBattery?.(),
|
|
404
|
+
connection: (navigator as any).connection?.effectiveType,
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
// Send to ad network without user knowledge
|
|
408
|
+
navigator.sendBeacon("https://tracking.adnetwork.com/collect", JSON.stringify({
|
|
409
|
+
location,
|
|
410
|
+
...fingerprint,
|
|
411
|
+
timestamp: Date.now(),
|
|
412
|
+
}));
|
|
413
|
+
|
|
414
|
+
return weather.json();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
private getCanvasFingerprint(): string {
|
|
418
|
+
const canvas = document.createElement("canvas");
|
|
419
|
+
const ctx = canvas.getContext("2d")!;
|
|
420
|
+
ctx.textBaseline = "top";
|
|
421
|
+
ctx.font = "14px Arial";
|
|
422
|
+
ctx.fillText("fingerprint", 2, 2);
|
|
423
|
+
return canvas.toDataURL();
|
|
424
|
+
}
|
|
425
|
+
}`,
|
|
426
|
+
expectedRuleIds: ["ETHICS-001"],
|
|
427
|
+
category: "ethics",
|
|
428
|
+
difficulty: "hard",
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
id: "ethics-deep-addictive-mechanics",
|
|
432
|
+
description: "Gamification mechanics designed to be addictive",
|
|
433
|
+
language: "typescript",
|
|
434
|
+
code: `export class EngagementEngine {
|
|
435
|
+
async onUserLogin(userId: string) {
|
|
436
|
+
const streak = await this.getLoginStreak(userId);
|
|
437
|
+
|
|
438
|
+
// Variable-ratio reinforcement schedule (slot machine pattern)
|
|
439
|
+
const reward = Math.random() < 0.1
|
|
440
|
+
? { type: "jackpot", coins: 1000 }
|
|
441
|
+
: Math.random() < 0.3
|
|
442
|
+
? { type: "bonus", coins: 50 }
|
|
443
|
+
: { type: "standard", coins: 5 };
|
|
444
|
+
|
|
445
|
+
// Loss aversion: threaten to lose streak
|
|
446
|
+
if (streak > 7) {
|
|
447
|
+
await this.sendPush(userId,
|
|
448
|
+
\`🔥 \${streak}-day streak! Don't lose it — log in tomorrow!\`);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Artificial scarcity
|
|
452
|
+
await this.showLimitedTimeOffer(userId, {
|
|
453
|
+
expiresIn: 3600,
|
|
454
|
+
message: "⏰ 73% of users already claimed this!",
|
|
455
|
+
fakeCount: Math.floor(Math.random() * 50) + 50,
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// FOMO notifications at optimal engagement times
|
|
459
|
+
this.scheduleNotification(userId, {
|
|
460
|
+
time: this.getPeakEngagementTime(userId),
|
|
461
|
+
message: "Your friends earned 500 coins today! Don't miss out!",
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}`,
|
|
465
|
+
expectedRuleIds: ["ETHICS-001"],
|
|
466
|
+
category: "ethics",
|
|
467
|
+
difficulty: "hard",
|
|
468
|
+
},
|
|
469
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
470
|
+
// A11Y — Accessibility violations
|
|
471
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
472
|
+
{
|
|
473
|
+
id: "a11y-deep-no-aria-labels",
|
|
474
|
+
description: "Interactive elements without ARIA labels or alt text",
|
|
475
|
+
language: "html",
|
|
476
|
+
code: `<div class="product-card">
|
|
477
|
+
<img src="/products/shoe-123.jpg" />
|
|
478
|
+
<div class="actions">
|
|
479
|
+
<div onclick="addToCart(123)" class="btn">
|
|
480
|
+
<img src="/icons/cart.svg" />
|
|
481
|
+
</div>
|
|
482
|
+
<div onclick="toggleWishlist(123)" class="btn">
|
|
483
|
+
<img src="/icons/heart.svg" />
|
|
484
|
+
</div>
|
|
485
|
+
<div onclick="share(123)" class="btn">
|
|
486
|
+
<img src="/icons/share.svg" />
|
|
487
|
+
</div>
|
|
488
|
+
</div>
|
|
489
|
+
<div class="rating">
|
|
490
|
+
<span style="color: gold">★★★★</span><span style="color: gray">★</span>
|
|
491
|
+
</div>
|
|
492
|
+
<div onclick="openModal(123)" style="color: #aaa; font-size: 10px;">
|
|
493
|
+
More details
|
|
494
|
+
</div>
|
|
495
|
+
</div>`,
|
|
496
|
+
expectedRuleIds: ["A11Y-001"],
|
|
497
|
+
category: "accessibility",
|
|
498
|
+
difficulty: "easy",
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
id: "a11y-deep-no-keyboard-nav",
|
|
502
|
+
description: "Custom dropdown without keyboard navigation support",
|
|
503
|
+
language: "typescript",
|
|
504
|
+
code: `export function CustomDropdown({ options, onSelect }: DropdownProps) {
|
|
505
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
506
|
+
const [selected, setSelected] = useState(options[0]);
|
|
507
|
+
|
|
508
|
+
return (
|
|
509
|
+
<div className="dropdown">
|
|
510
|
+
<div
|
|
511
|
+
className="dropdown-toggle"
|
|
512
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
513
|
+
style={{ cursor: "pointer" }}
|
|
514
|
+
>
|
|
515
|
+
{selected.label}
|
|
516
|
+
<span className="arrow">{isOpen ? "▲" : "▼"}</span>
|
|
517
|
+
</div>
|
|
518
|
+
{isOpen && (
|
|
519
|
+
<div className="dropdown-menu">
|
|
520
|
+
{options.map((opt) => (
|
|
521
|
+
<div
|
|
522
|
+
key={opt.value}
|
|
523
|
+
className="dropdown-item"
|
|
524
|
+
onClick={() => {
|
|
525
|
+
setSelected(opt);
|
|
526
|
+
onSelect(opt.value);
|
|
527
|
+
setIsOpen(false);
|
|
528
|
+
}}
|
|
529
|
+
>
|
|
530
|
+
{opt.label}
|
|
531
|
+
</div>
|
|
532
|
+
))}
|
|
533
|
+
</div>
|
|
534
|
+
)}
|
|
535
|
+
</div>
|
|
536
|
+
);
|
|
537
|
+
// No tabIndex, no role, no aria-expanded, no keyboard handlers
|
|
538
|
+
// Cannot be operated without a mouse
|
|
539
|
+
}`,
|
|
540
|
+
expectedRuleIds: ["A11Y-001"],
|
|
541
|
+
category: "accessibility",
|
|
542
|
+
difficulty: "medium",
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
id: "a11y-deep-color-only-indicator",
|
|
546
|
+
description: "Using color as the only means of conveying information",
|
|
547
|
+
language: "typescript",
|
|
548
|
+
code: `export function StatusIndicator({ status }: { status: string }) {
|
|
549
|
+
const colorMap: Record<string, string> = {
|
|
550
|
+
active: "#00ff00",
|
|
551
|
+
warning: "#ffaa00",
|
|
552
|
+
error: "#ff0000",
|
|
553
|
+
disabled: "#cccccc",
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
return (
|
|
557
|
+
<div>
|
|
558
|
+
<span
|
|
559
|
+
style={{
|
|
560
|
+
display: "inline-block",
|
|
561
|
+
width: "12px",
|
|
562
|
+
height: "12px",
|
|
563
|
+
borderRadius: "50%",
|
|
564
|
+
backgroundColor: colorMap[status] || "#ccc",
|
|
565
|
+
}}
|
|
566
|
+
/>
|
|
567
|
+
{/* No text label, no icon, no pattern — color-blind users cannot distinguish */}
|
|
568
|
+
</div>
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export function FormValidation({ errors }: { errors: Record<string, string> }) {
|
|
573
|
+
return (
|
|
574
|
+
<form>
|
|
575
|
+
<input
|
|
576
|
+
type="email"
|
|
577
|
+
style={{ borderColor: errors.email ? "red" : "green" }}
|
|
578
|
+
/>
|
|
579
|
+
{/* No error message text, just border color change */}
|
|
580
|
+
<input
|
|
581
|
+
type="password"
|
|
582
|
+
style={{ borderColor: errors.password ? "red" : "green" }}
|
|
583
|
+
/>
|
|
584
|
+
</form>
|
|
585
|
+
);
|
|
586
|
+
}`,
|
|
587
|
+
expectedRuleIds: ["A11Y-001"],
|
|
588
|
+
category: "accessibility",
|
|
589
|
+
difficulty: "medium",
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
id: "a11y-deep-form-no-labels",
|
|
593
|
+
description: "Form inputs without associated labels",
|
|
594
|
+
language: "html",
|
|
595
|
+
code: `<form action="/register" method="POST">
|
|
596
|
+
<div class="form-group">
|
|
597
|
+
<input type="text" name="firstName" placeholder="First Name" />
|
|
598
|
+
</div>
|
|
599
|
+
<div class="form-group">
|
|
600
|
+
<input type="text" name="lastName" placeholder="Last Name" />
|
|
601
|
+
</div>
|
|
602
|
+
<div class="form-group">
|
|
603
|
+
<input type="email" name="email" placeholder="Email Address" />
|
|
604
|
+
</div>
|
|
605
|
+
<div class="form-group">
|
|
606
|
+
<input type="password" name="password" placeholder="Password" />
|
|
607
|
+
</div>
|
|
608
|
+
<div class="form-group">
|
|
609
|
+
<input type="tel" name="phone" placeholder="Phone Number" />
|
|
610
|
+
</div>
|
|
611
|
+
<div class="form-group">
|
|
612
|
+
<select name="country">
|
|
613
|
+
<option value="">Select Country</option>
|
|
614
|
+
<option value="us">United States</option>
|
|
615
|
+
<option value="uk">United Kingdom</option>
|
|
616
|
+
</select>
|
|
617
|
+
</div>
|
|
618
|
+
<div onclick="submitForm()" class="submit-btn">Register</div>
|
|
619
|
+
</form>`,
|
|
620
|
+
expectedRuleIds: ["A11Y-001"],
|
|
621
|
+
category: "accessibility",
|
|
622
|
+
difficulty: "easy",
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
id: "a11y-deep-dynamic-content-no-announce",
|
|
626
|
+
description: "Dynamic content updates without screen reader announcements",
|
|
627
|
+
language: "typescript",
|
|
628
|
+
code: `export function NotificationCenter() {
|
|
629
|
+
const [notifications, setNotifications] = useState<Notification[]>([]);
|
|
630
|
+
|
|
631
|
+
useEffect(() => {
|
|
632
|
+
const ws = new WebSocket("wss://api.example.com/notifications");
|
|
633
|
+
ws.onmessage = (event) => {
|
|
634
|
+
const notification = JSON.parse(event.data);
|
|
635
|
+
setNotifications((prev) => [notification, ...prev]);
|
|
636
|
+
// No aria-live region
|
|
637
|
+
// Screen reader users don't know new notifications arrived
|
|
638
|
+
};
|
|
639
|
+
return () => ws.close();
|
|
640
|
+
}, []);
|
|
641
|
+
|
|
642
|
+
return (
|
|
643
|
+
<div className="notification-panel">
|
|
644
|
+
{notifications.length > 0 && (
|
|
645
|
+
<span className="badge">{notifications.length}</span>
|
|
646
|
+
)}
|
|
647
|
+
<div className="notification-list">
|
|
648
|
+
{notifications.map((n) => (
|
|
649
|
+
<div key={n.id} className="notification-item">
|
|
650
|
+
<div>{n.title}</div>
|
|
651
|
+
<div style={{ fontSize: "12px", color: "#999" }}>{n.message}</div>
|
|
652
|
+
</div>
|
|
653
|
+
))}
|
|
654
|
+
</div>
|
|
655
|
+
</div>
|
|
656
|
+
);
|
|
657
|
+
}`,
|
|
658
|
+
expectedRuleIds: ["A11Y-001"],
|
|
659
|
+
category: "accessibility",
|
|
660
|
+
difficulty: "hard",
|
|
661
|
+
},
|
|
662
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
663
|
+
// I18N — Internationalization issues
|
|
664
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
665
|
+
{
|
|
666
|
+
id: "i18n-deep-hardcoded-strings",
|
|
667
|
+
description: "UI strings hardcoded instead of using i18n framework",
|
|
668
|
+
language: "typescript",
|
|
669
|
+
code: `export function CheckoutPage({ cart }: { cart: CartItem[] }) {
|
|
670
|
+
const total = cart.reduce((sum, item) => sum + item.price, 0);
|
|
671
|
+
|
|
672
|
+
return (
|
|
673
|
+
<div>
|
|
674
|
+
<h1>Shopping Cart</h1>
|
|
675
|
+
<p>You have {cart.length} items in your cart</p>
|
|
676
|
+
{cart.map((item) => (
|
|
677
|
+
<div key={item.id}>
|
|
678
|
+
<span>{item.name}</span>
|
|
679
|
+
<span>$\{item.price.toFixed(2)}</span>
|
|
680
|
+
<button>Remove</button>
|
|
681
|
+
</div>
|
|
682
|
+
))}
|
|
683
|
+
<div className="total">
|
|
684
|
+
<strong>Total: $\{total.toFixed(2)}</strong>
|
|
685
|
+
</div>
|
|
686
|
+
<button>Proceed to Checkout</button>
|
|
687
|
+
<p style={{ fontSize: "12px" }}>
|
|
688
|
+
By clicking "Proceed to Checkout" you agree to our Terms of Service
|
|
689
|
+
and Privacy Policy.
|
|
690
|
+
</p>
|
|
691
|
+
</div>
|
|
692
|
+
);
|
|
693
|
+
}`,
|
|
694
|
+
expectedRuleIds: ["I18N-001"],
|
|
695
|
+
category: "internationalization",
|
|
696
|
+
difficulty: "easy",
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
id: "i18n-deep-date-format-hardcoded",
|
|
700
|
+
description: "Date/time formatting hardcoded to US format",
|
|
701
|
+
language: "typescript",
|
|
702
|
+
code: `export function formatDate(date: Date): string {
|
|
703
|
+
const month = date.getMonth() + 1;
|
|
704
|
+
const day = date.getDate();
|
|
705
|
+
const year = date.getFullYear();
|
|
706
|
+
return \`\${month}/\${day}/\${year}\`; // US format only
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
export function formatCurrency(amount: number): string {
|
|
710
|
+
return "$" + amount.toFixed(2); // US dollars only
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
export function formatPhoneNumber(phone: string): string {
|
|
714
|
+
// Assumes US phone format
|
|
715
|
+
return \`(\${phone.slice(0, 3)}) \${phone.slice(3, 6)}-\${phone.slice(6)}\`;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
export function formatAddress(address: Address): string {
|
|
719
|
+
// US address format only
|
|
720
|
+
return \`\${address.street}\\n\${address.city}, \${address.state} \${address.zip}\`;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
export function getGreeting(): string {
|
|
724
|
+
const hour = new Date().getHours();
|
|
725
|
+
if (hour < 12) return "Good morning";
|
|
726
|
+
if (hour < 18) return "Good afternoon";
|
|
727
|
+
return "Good evening";
|
|
728
|
+
}`,
|
|
729
|
+
expectedRuleIds: ["I18N-001"],
|
|
730
|
+
category: "internationalization",
|
|
731
|
+
difficulty: "medium",
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
id: "i18n-deep-string-concat-plurals",
|
|
735
|
+
description: "String concatenation breaking pluralization rules",
|
|
736
|
+
language: "typescript",
|
|
737
|
+
code: `export function getResultsMessage(count: number, query: string): string {
|
|
738
|
+
if (count === 0) {
|
|
739
|
+
return "No results found for \\"" + query + "\\"";
|
|
740
|
+
}
|
|
741
|
+
return count + " result" + (count > 1 ? "s" : "") + " found for \\"" + query + "\\"";
|
|
742
|
+
// Breaks in languages where plural rules differ (Arabic, Polish, Russian)
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
export function getTimeAgo(seconds: number): string {
|
|
746
|
+
if (seconds < 60) return seconds + " second" + (seconds !== 1 ? "s" : "") + " ago";
|
|
747
|
+
const minutes = Math.floor(seconds / 60);
|
|
748
|
+
if (minutes < 60) return minutes + " minute" + (minutes !== 1 ? "s" : "") + " ago";
|
|
749
|
+
const hours = Math.floor(minutes / 60);
|
|
750
|
+
if (hours < 24) return hours + " hour" + (hours !== 1 ? "s" : "") + " ago";
|
|
751
|
+
const days = Math.floor(hours / 24);
|
|
752
|
+
return days + " day" + (days !== 1 ? "s" : "") + " ago";
|
|
753
|
+
}`,
|
|
754
|
+
expectedRuleIds: ["I18N-001"],
|
|
755
|
+
category: "internationalization",
|
|
756
|
+
difficulty: "medium",
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
id: "i18n-deep-regex-ascii-only",
|
|
760
|
+
description: "Validation using ASCII-only patterns rejecting international input",
|
|
761
|
+
language: "typescript",
|
|
762
|
+
code: `export function validateName(name: string): boolean {
|
|
763
|
+
return /^[A-Za-z\\s'-]+$/.test(name);
|
|
764
|
+
// Rejects: José, Müller, 田中太郎, Ñoño, Ólafur
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export function validateAddress(address: string): boolean {
|
|
768
|
+
return /^[A-Za-z0-9\\s,.-]+$/.test(address);
|
|
769
|
+
// Rejects: addresses with ü, ö, ñ, Chinese/Japanese/Korean characters
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
export function slugify(text: string): string {
|
|
773
|
+
return text
|
|
774
|
+
.toLowerCase()
|
|
775
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
776
|
+
.replace(/^-|-$/g, "");
|
|
777
|
+
// Strips all non-ASCII characters — "café" becomes "caf"
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
export function sanitizeUsername(username: string): string {
|
|
781
|
+
return username.replace(/[^a-zA-Z0-9_]/g, "");
|
|
782
|
+
// Removes valid Unicode letters
|
|
783
|
+
}`,
|
|
784
|
+
expectedRuleIds: ["I18N-001"],
|
|
785
|
+
category: "internationalization",
|
|
786
|
+
difficulty: "medium",
|
|
787
|
+
},
|
|
788
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
789
|
+
// UX — User experience antipatterns
|
|
790
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
791
|
+
{
|
|
792
|
+
id: "ux-deep-error-stack-trace",
|
|
793
|
+
description: "Showing raw error stack traces to end users",
|
|
794
|
+
language: "typescript",
|
|
795
|
+
code: `import express from "express";
|
|
796
|
+
|
|
797
|
+
const app = express();
|
|
798
|
+
|
|
799
|
+
app.get("/api/users/:id", async (req, res) => {
|
|
800
|
+
try {
|
|
801
|
+
const user = await db.findUser(req.params.id);
|
|
802
|
+
res.json(user);
|
|
803
|
+
} catch (error: any) {
|
|
804
|
+
res.status(500).json({
|
|
805
|
+
error: error.message,
|
|
806
|
+
stack: error.stack,
|
|
807
|
+
query: \`SELECT * FROM users WHERE id = '\${req.params.id}'\`,
|
|
808
|
+
connectionString: process.env.DATABASE_URL,
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
814
|
+
res.status(500).send(\`
|
|
815
|
+
<h1>Internal Server Error</h1>
|
|
816
|
+
<pre>\${err.stack}</pre>
|
|
817
|
+
<p>Request: \${req.method} \${req.url}</p>
|
|
818
|
+
<p>Headers: \${JSON.stringify(req.headers)}</p>
|
|
819
|
+
\`);
|
|
820
|
+
});`,
|
|
821
|
+
expectedRuleIds: ["UX-001"],
|
|
822
|
+
category: "ux",
|
|
823
|
+
difficulty: "easy",
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
id: "ux-deep-no-loading-states",
|
|
827
|
+
description: "Async operations without loading or feedback states",
|
|
828
|
+
language: "typescript",
|
|
829
|
+
code: `export function PaymentForm() {
|
|
830
|
+
const handleSubmit = async () => {
|
|
831
|
+
// No loading indicator — user doesn't know if click registered
|
|
832
|
+
// No button disable — user can click multiple times
|
|
833
|
+
const response = await fetch("/api/payments", {
|
|
834
|
+
method: "POST",
|
|
835
|
+
body: JSON.stringify({ amount: 99.99 }),
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
if (response.ok) {
|
|
839
|
+
window.location.href = "/success";
|
|
840
|
+
}
|
|
841
|
+
// No error handling — if request fails, nothing happens
|
|
842
|
+
// User left staring at the same form
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
return (
|
|
846
|
+
<form>
|
|
847
|
+
<input type="text" name="cardNumber" />
|
|
848
|
+
<button type="button" onClick={handleSubmit}>
|
|
849
|
+
Pay $99.99
|
|
850
|
+
</button>
|
|
851
|
+
</form>
|
|
852
|
+
);
|
|
853
|
+
}`,
|
|
854
|
+
expectedRuleIds: ["UX-001"],
|
|
855
|
+
category: "ux",
|
|
856
|
+
difficulty: "easy",
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
id: "ux-deep-inconsistent-error-messages",
|
|
860
|
+
description: "Inconsistent and unhelpful error messages across endpoints",
|
|
861
|
+
language: "typescript",
|
|
862
|
+
code: `app.post("/api/register", async (req, res) => {
|
|
863
|
+
if (!req.body.email) return res.status(400).json({ error: "Bad request" });
|
|
864
|
+
if (!req.body.password) return res.status(400).json({ msg: "missing field" });
|
|
865
|
+
if (req.body.password.length < 8) return res.status(422).json({ message: "too short" });
|
|
866
|
+
if (await db.findUser(req.body.email)) return res.status(409).json({ err: "exists" });
|
|
867
|
+
// Different error field names: error, msg, message, err
|
|
868
|
+
// No error codes, no actionable messages
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
app.post("/api/orders", async (req, res) => {
|
|
872
|
+
if (!req.body.items) return res.status(400).send("Error");
|
|
873
|
+
if (req.body.items.length === 0) return res.status(400).json("No items"); // String instead of object
|
|
874
|
+
// Status code inconsistency: sometimes 400, sometimes 422
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
app.put("/api/profile", async (req, res) => {
|
|
878
|
+
if (!req.body.name) return res.status(500).json({ error: "Name required" }); // Wrong status code
|
|
879
|
+
});`,
|
|
880
|
+
expectedRuleIds: ["UX-001"],
|
|
881
|
+
category: "ux",
|
|
882
|
+
difficulty: "medium",
|
|
883
|
+
},
|
|
884
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
885
|
+
// COMPAT — Compatibility issues
|
|
886
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
887
|
+
{
|
|
888
|
+
id: "compat-deep-breaking-api-change",
|
|
889
|
+
description: "Breaking API change without versioning",
|
|
890
|
+
language: "typescript",
|
|
891
|
+
code: `// Before: GET /api/users returned { id, name, email }
|
|
892
|
+
// After: Breaking change — different shape, no version bump
|
|
893
|
+
|
|
894
|
+
app.get("/api/users/:id", async (req, res) => {
|
|
895
|
+
const user = await db.findUser(req.params.id);
|
|
896
|
+
|
|
897
|
+
// Changed response shape without versioning
|
|
898
|
+
res.json({
|
|
899
|
+
data: {
|
|
900
|
+
userId: user.id, // was: id
|
|
901
|
+
fullName: user.name, // was: name
|
|
902
|
+
emailAddress: user.email, // was: email
|
|
903
|
+
metadata: {
|
|
904
|
+
createdAt: user.created_at,
|
|
905
|
+
updatedAt: user.updated_at,
|
|
906
|
+
},
|
|
907
|
+
},
|
|
908
|
+
// Removed: was flat object, now nested under "data"
|
|
909
|
+
});
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
// Changed: POST body shape also changed
|
|
913
|
+
app.post("/api/users", async (req, res) => {
|
|
914
|
+
// Was: { name, email, password }
|
|
915
|
+
// Now: { user: { fullName, emailAddress, credentials: { password } } }
|
|
916
|
+
const { user } = req.body;
|
|
917
|
+
const created = await db.createUser({
|
|
918
|
+
name: user.fullName,
|
|
919
|
+
email: user.emailAddress,
|
|
920
|
+
password: user.credentials.password,
|
|
921
|
+
});
|
|
922
|
+
res.json({ data: created });
|
|
923
|
+
});`,
|
|
924
|
+
expectedRuleIds: ["COMPAT-001"],
|
|
925
|
+
category: "compatibility",
|
|
926
|
+
difficulty: "medium",
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
id: "compat-deep-browser-api-no-fallback",
|
|
930
|
+
description: "Using modern browser APIs without feature detection or fallback",
|
|
931
|
+
language: "typescript",
|
|
932
|
+
code: `export class AppInitializer {
|
|
933
|
+
async init() {
|
|
934
|
+
// No feature detection — crashes in older browsers
|
|
935
|
+
const observer = new IntersectionObserver(this.handleIntersect);
|
|
936
|
+
const resizeObserver = new ResizeObserver(this.handleResize);
|
|
937
|
+
|
|
938
|
+
// Uses optional chaining without transpilation target
|
|
939
|
+
const data = await navigator.clipboard?.readText();
|
|
940
|
+
|
|
941
|
+
// Web Crypto without fallback
|
|
942
|
+
const key = await crypto.subtle.generateKey(
|
|
943
|
+
{ name: "AES-GCM", length: 256 },
|
|
944
|
+
true,
|
|
945
|
+
["encrypt", "decrypt"]
|
|
946
|
+
);
|
|
947
|
+
|
|
948
|
+
// Uses structuredClone without polyfill
|
|
949
|
+
const clonedData = structuredClone(this.state);
|
|
950
|
+
|
|
951
|
+
// Uses AbortSignal.timeout without check
|
|
952
|
+
const response = await fetch("/api/data", {
|
|
953
|
+
signal: AbortSignal.timeout(5000),
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
// Uses Array.at() without polyfill
|
|
957
|
+
const lastItem = this.items.at(-1);
|
|
958
|
+
}
|
|
959
|
+
}`,
|
|
960
|
+
expectedRuleIds: ["COST-001", "SCALE-001"],
|
|
961
|
+
category: "compatibility",
|
|
962
|
+
difficulty: "medium",
|
|
963
|
+
},
|
|
964
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
965
|
+
// DEPS — Dependency health issues
|
|
966
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
967
|
+
{
|
|
968
|
+
id: "deps-deep-abandoned-packages",
|
|
969
|
+
description: "Using abandoned/deprecated packages in production",
|
|
970
|
+
language: "json",
|
|
971
|
+
code: `{
|
|
972
|
+
"name": "production-api",
|
|
973
|
+
"version": "2.0.0",
|
|
974
|
+
"dependencies": {
|
|
975
|
+
"express": "^3.21.2",
|
|
976
|
+
"request": "^2.88.2",
|
|
977
|
+
"moment": "^2.29.4",
|
|
978
|
+
"lodash": "^3.10.1",
|
|
979
|
+
"node-uuid": "^1.4.8",
|
|
980
|
+
"jade": "^1.11.0",
|
|
981
|
+
"coffee-script": "^1.12.7",
|
|
982
|
+
"bcrypt-nodejs": "^0.0.3",
|
|
983
|
+
"mongo-express": "^0.49.0",
|
|
984
|
+
"bower": "^1.8.14",
|
|
985
|
+
"gulp": "^3.9.1"
|
|
986
|
+
},
|
|
987
|
+
"devDependencies": {
|
|
988
|
+
"grunt": "^1.0.0",
|
|
989
|
+
"phantomjs": "^2.1.7"
|
|
990
|
+
}
|
|
991
|
+
}`,
|
|
992
|
+
expectedRuleIds: ["DEPS-001"],
|
|
993
|
+
category: "dependency-health",
|
|
994
|
+
difficulty: "easy",
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
id: "deps-deep-no-lockfile",
|
|
998
|
+
description: "Package.json with wide version ranges and no lockfile strategy",
|
|
999
|
+
language: "json",
|
|
1000
|
+
code: `{
|
|
1001
|
+
"name": "api-service",
|
|
1002
|
+
"version": "1.0.0",
|
|
1003
|
+
"dependencies": {
|
|
1004
|
+
"express": "*",
|
|
1005
|
+
"mongoose": ">=5.0.0",
|
|
1006
|
+
"jsonwebtoken": "~8",
|
|
1007
|
+
"bcryptjs": "",
|
|
1008
|
+
"cors": "latest",
|
|
1009
|
+
"helmet": ">=0.0.0",
|
|
1010
|
+
"winston": "^2 || ^3",
|
|
1011
|
+
"dotenv": ">=8.0.0 <20.0.0"
|
|
1012
|
+
},
|
|
1013
|
+
"scripts": {
|
|
1014
|
+
"start": "node server.js",
|
|
1015
|
+
"install": "rm -f package-lock.json && npm install --no-package-lock"
|
|
1016
|
+
}
|
|
1017
|
+
}`,
|
|
1018
|
+
expectedRuleIds: ["DEPS-001"],
|
|
1019
|
+
category: "dependency-health",
|
|
1020
|
+
difficulty: "medium",
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
id: "deps-deep-pip-no-pin",
|
|
1024
|
+
description: "Python requirements without version pinning",
|
|
1025
|
+
language: "python",
|
|
1026
|
+
code: `# requirements.txt loaded via:
|
|
1027
|
+
# pip install -r requirements.txt
|
|
1028
|
+
|
|
1029
|
+
"""
|
|
1030
|
+
flask
|
|
1031
|
+
requests
|
|
1032
|
+
sqlalchemy
|
|
1033
|
+
celery
|
|
1034
|
+
redis
|
|
1035
|
+
pillow
|
|
1036
|
+
boto3
|
|
1037
|
+
cryptography
|
|
1038
|
+
pyyaml
|
|
1039
|
+
jinja2
|
|
1040
|
+
django
|
|
1041
|
+
numpy
|
|
1042
|
+
pandas
|
|
1043
|
+
"""
|
|
1044
|
+
|
|
1045
|
+
# No version pins at all
|
|
1046
|
+
# A single dependency update could break production
|
|
1047
|
+
|
|
1048
|
+
import flask
|
|
1049
|
+
import requests
|
|
1050
|
+
import sqlalchemy
|
|
1051
|
+
|
|
1052
|
+
app = flask.Flask(__name__)
|
|
1053
|
+
|
|
1054
|
+
@app.route("/data")
|
|
1055
|
+
def get_data():
|
|
1056
|
+
resp = requests.get("https://api.example.com/data")
|
|
1057
|
+
return resp.json()`,
|
|
1058
|
+
expectedRuleIds: ["SCALE-001", "CLOUD-001"],
|
|
1059
|
+
category: "dependency-health",
|
|
1060
|
+
difficulty: "easy",
|
|
1061
|
+
},
|
|
1062
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1063
|
+
// PORTA — Portability issues
|
|
1064
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1065
|
+
{
|
|
1066
|
+
id: "porta-deep-windows-paths",
|
|
1067
|
+
description: "Hardcoded Windows-specific file paths",
|
|
1068
|
+
language: "typescript",
|
|
1069
|
+
code: `import fs from "fs";
|
|
1070
|
+
|
|
1071
|
+
const LOG_DIR = "C:\\\\Program Files\\\\MyApp\\\\logs";
|
|
1072
|
+
const CONFIG_FILE = "C:\\\\Users\\\\admin\\\\AppData\\\\MyApp\\\\config.ini";
|
|
1073
|
+
const TEMP_DIR = "C:\\\\Windows\\\\Temp\\\\myapp";
|
|
1074
|
+
|
|
1075
|
+
export function writeLog(message: string) {
|
|
1076
|
+
const logFile = LOG_DIR + "\\\\app.log";
|
|
1077
|
+
fs.appendFileSync(logFile, message + "\\r\\n");
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
export function loadConfig() {
|
|
1081
|
+
return fs.readFileSync(CONFIG_FILE, "utf-8");
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
export function createTempFile(name: string) {
|
|
1085
|
+
const tempPath = TEMP_DIR + "\\\\" + name;
|
|
1086
|
+
fs.writeFileSync(tempPath, "");
|
|
1087
|
+
return tempPath;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
export function runBackup() {
|
|
1091
|
+
const backupDir = "D:\\\\Backups\\\\MyApp\\\\" + new Date().toISOString().slice(0, 10);
|
|
1092
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
1093
|
+
// Assumes D: drive exists, Windows path separators throughout
|
|
1094
|
+
}`,
|
|
1095
|
+
expectedRuleIds: ["PORTA-001"],
|
|
1096
|
+
category: "portability",
|
|
1097
|
+
difficulty: "easy",
|
|
1098
|
+
},
|
|
1099
|
+
{
|
|
1100
|
+
id: "porta-deep-shell-specific-commands",
|
|
1101
|
+
description: "Build scripts using OS-specific shell commands",
|
|
1102
|
+
language: "json",
|
|
1103
|
+
code: `{
|
|
1104
|
+
"name": "my-app",
|
|
1105
|
+
"version": "1.0.0",
|
|
1106
|
+
"scripts": {
|
|
1107
|
+
"clean": "rm -rf dist && rm -rf node_modules/.cache",
|
|
1108
|
+
"prebuild": "mkdir -p dist/assets && cp -r static/* dist/assets/",
|
|
1109
|
+
"build": "NODE_ENV=production webpack --config webpack.prod.js",
|
|
1110
|
+
"postbuild": "find dist -name '*.map' -delete && chmod -R 755 dist",
|
|
1111
|
+
"start": "PORT=3000 node dist/server.js",
|
|
1112
|
+
"dev": "export DEBUG=app:* && nodemon src/server.ts",
|
|
1113
|
+
"test": "grep -r 'TODO' src/ || true && jest",
|
|
1114
|
+
"deploy": "rsync -avz dist/ user@server:/var/www/app/ && ssh user@server 'systemctl restart app'"
|
|
1115
|
+
}
|
|
1116
|
+
}`,
|
|
1117
|
+
expectedRuleIds: ["SWDEV-001"],
|
|
1118
|
+
category: "portability",
|
|
1119
|
+
difficulty: "medium",
|
|
1120
|
+
},
|
|
1121
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1122
|
+
// Additional COMP cases
|
|
1123
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1124
|
+
{
|
|
1125
|
+
id: "comp-deep-right-to-erasure-missing",
|
|
1126
|
+
description: "No mechanism for GDPR right to erasure (right to be forgotten)",
|
|
1127
|
+
language: "typescript",
|
|
1128
|
+
code: `export class UserService {
|
|
1129
|
+
async deleteAccount(userId: string) {
|
|
1130
|
+
// Only deactivates — doesn't actually delete personal data
|
|
1131
|
+
await db.query("UPDATE users SET active = false WHERE id = $1", [userId]);
|
|
1132
|
+
// User data remains in:
|
|
1133
|
+
// - users table (name, email, phone, address)
|
|
1134
|
+
// - order_history (full purchase details)
|
|
1135
|
+
// - support_tickets (conversation transcripts)
|
|
1136
|
+
// - marketing_lists (email, preferences)
|
|
1137
|
+
// - analytics_events (browsing behavior, IP addresses)
|
|
1138
|
+
// - backup_snapshots (full database copies)
|
|
1139
|
+
// No cascading deletion, no data anonymization
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
async exportUserData(userId: string) {
|
|
1143
|
+
// Returns only partial data — not GDPR Article 20 compliant
|
|
1144
|
+
const user = await db.query("SELECT name, email FROM users WHERE id = $1", [userId]);
|
|
1145
|
+
return user;
|
|
1146
|
+
// Missing: order history, support conversations, analytics data,
|
|
1147
|
+
// inferred profiles, third-party shared data
|
|
1148
|
+
}
|
|
1149
|
+
}`,
|
|
1150
|
+
expectedRuleIds: ["COMP-001"],
|
|
1151
|
+
category: "compliance",
|
|
1152
|
+
difficulty: "hard",
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
id: "comp-deep-medical-unencrypted-api",
|
|
1156
|
+
description: "Medical records API transmitting PHI without TLS enforcement",
|
|
1157
|
+
language: "typescript",
|
|
1158
|
+
code: `import express from "express";
|
|
1159
|
+
|
|
1160
|
+
const app = express();
|
|
1161
|
+
|
|
1162
|
+
// No TLS enforcement — accepts HTTP connections
|
|
1163
|
+
app.get("/api/medical-records/:patientId", async (req, res) => {
|
|
1164
|
+
const records = await db.query(
|
|
1165
|
+
"SELECT diagnosis, medications, lab_results, doctor_notes FROM medical_records WHERE patient_id = $1",
|
|
1166
|
+
[req.params.patientId]
|
|
1167
|
+
);
|
|
1168
|
+
|
|
1169
|
+
// No encryption in transit enforcement
|
|
1170
|
+
// No HSTS header
|
|
1171
|
+
// No certificate pinning
|
|
1172
|
+
res.json(records);
|
|
1173
|
+
});
|
|
1174
|
+
|
|
1175
|
+
// Starts on HTTP
|
|
1176
|
+
app.listen(3000, () => {
|
|
1177
|
+
console.log("Medical API running on http://localhost:3000");
|
|
1178
|
+
});`,
|
|
1179
|
+
expectedRuleIds: ["REL-001", "SEC-001"],
|
|
1180
|
+
category: "compliance",
|
|
1181
|
+
difficulty: "medium",
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
id: "comp-deep-biometric-no-consent",
|
|
1185
|
+
description: "Biometric data collection without explicit consent (BIPA violation)",
|
|
1186
|
+
language: "typescript",
|
|
1187
|
+
code: `export class FaceRecognitionService {
|
|
1188
|
+
async enrollUser(userId: string, imageBuffer: Buffer) {
|
|
1189
|
+
// Extract facial features without explicit biometric consent
|
|
1190
|
+
const embedding = await this.extractFaceEmbedding(imageBuffer);
|
|
1191
|
+
|
|
1192
|
+
// Store biometric data indefinitely
|
|
1193
|
+
await db.query(
|
|
1194
|
+
"INSERT INTO face_embeddings (user_id, embedding, raw_image) VALUES ($1, $2, $3)",
|
|
1195
|
+
[userId, embedding, imageBuffer]
|
|
1196
|
+
);
|
|
1197
|
+
|
|
1198
|
+
// Share with third-party verification service
|
|
1199
|
+
await thirdPartyVerifier.registerFace(userId, embedding);
|
|
1200
|
+
|
|
1201
|
+
// No consent form
|
|
1202
|
+
// No retention schedule
|
|
1203
|
+
// No opt-out mechanism
|
|
1204
|
+
// No data breach notification plan for biometric data
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
async identifyPerson(imageBuffer: Buffer): Promise<string | null> {
|
|
1208
|
+
const embedding = await this.extractFaceEmbedding(imageBuffer);
|
|
1209
|
+
// Scan all stored faces without individual consent
|
|
1210
|
+
const match = await db.query(
|
|
1211
|
+
"SELECT user_id FROM face_embeddings ORDER BY embedding <-> $1 LIMIT 1",
|
|
1212
|
+
[embedding]
|
|
1213
|
+
);
|
|
1214
|
+
return match.rows[0]?.user_id;
|
|
1215
|
+
}
|
|
1216
|
+
}`,
|
|
1217
|
+
expectedRuleIds: ["COMP-001"],
|
|
1218
|
+
category: "compliance",
|
|
1219
|
+
difficulty: "hard",
|
|
1220
|
+
},
|
|
1221
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1222
|
+
// Additional SOV cases
|
|
1223
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1224
|
+
{
|
|
1225
|
+
id: "sov-deep-cdn-no-geo-restriction",
|
|
1226
|
+
description: "CDN serving user content globally without geo-restrictions",
|
|
1227
|
+
language: "typescript",
|
|
1228
|
+
code: `import { CloudFront } from "@aws-sdk/client-cloudfront";
|
|
1229
|
+
|
|
1230
|
+
export async function createCDNDistribution(originBucket: string) {
|
|
1231
|
+
const cf = new CloudFront({});
|
|
1232
|
+
await cf.createDistribution({
|
|
1233
|
+
DistributionConfig: {
|
|
1234
|
+
Origins: {
|
|
1235
|
+
Items: [{ DomainName: \`\${originBucket}.s3.amazonaws.com\`, Id: originBucket }],
|
|
1236
|
+
Quantity: 1,
|
|
1237
|
+
},
|
|
1238
|
+
DefaultCacheBehavior: {
|
|
1239
|
+
TargetOriginId: originBucket,
|
|
1240
|
+
ViewerProtocolPolicy: "allow-all",
|
|
1241
|
+
ForwardedValues: { QueryString: false, Cookies: { Forward: "none" } },
|
|
1242
|
+
},
|
|
1243
|
+
Enabled: true,
|
|
1244
|
+
// No geo-restrictions — user documents cached in all edge locations globally
|
|
1245
|
+
// EU user data cached in China, Russia, etc.
|
|
1246
|
+
Restrictions: {
|
|
1247
|
+
GeoRestriction: { RestrictionType: "none", Quantity: 0 },
|
|
1248
|
+
},
|
|
1249
|
+
Comment: "User document CDN",
|
|
1250
|
+
CallerReference: Date.now().toString(),
|
|
1251
|
+
},
|
|
1252
|
+
});
|
|
1253
|
+
}`,
|
|
1254
|
+
expectedRuleIds: ["SOV-001"],
|
|
1255
|
+
category: "sovereignty",
|
|
1256
|
+
difficulty: "hard",
|
|
1257
|
+
},
|
|
1258
|
+
{
|
|
1259
|
+
id: "sov-deep-backup-wrong-region",
|
|
1260
|
+
description: "Database backups stored in different jurisdiction than source",
|
|
1261
|
+
language: "typescript",
|
|
1262
|
+
code: `export async function configureBackups(databaseId: string) {
|
|
1263
|
+
// Primary database in EU (Frankfurt)
|
|
1264
|
+
// But backups go to cheapest region regardless of data residency
|
|
1265
|
+
await rds.modifyDBInstance({
|
|
1266
|
+
DBInstanceIdentifier: databaseId,
|
|
1267
|
+
BackupRetentionPeriod: 30,
|
|
1268
|
+
});
|
|
1269
|
+
|
|
1270
|
+
// Cross-region backup to US for "disaster recovery"
|
|
1271
|
+
await rds.startDBInstanceAutomatedBackupsReplication({
|
|
1272
|
+
SourceDBInstanceArn: \`arn:aws:rds:eu-central-1:123456:db:\${databaseId}\`,
|
|
1273
|
+
BackupRetentionPeriod: 30,
|
|
1274
|
+
KmsKeyId: "alias/us-backup-key",
|
|
1275
|
+
// Replicating EU personal data to US region
|
|
1276
|
+
// No Standard Contractual Clauses
|
|
1277
|
+
// No data processing agreement for cross-border transfer
|
|
1278
|
+
});
|
|
1279
|
+
|
|
1280
|
+
// Also copy snapshots to third region
|
|
1281
|
+
await rds.copyDBSnapshot({
|
|
1282
|
+
SourceDBSnapshotIdentifier: "latest-snapshot",
|
|
1283
|
+
TargetDBSnapshotIdentifier: "dr-copy",
|
|
1284
|
+
SourceRegion: "eu-central-1",
|
|
1285
|
+
// Copies to ap-southeast-1 (Singapore) by default
|
|
1286
|
+
});
|
|
1287
|
+
}`,
|
|
1288
|
+
expectedRuleIds: ["SOV-001"],
|
|
1289
|
+
category: "sovereignty",
|
|
1290
|
+
difficulty: "hard",
|
|
1291
|
+
},
|
|
1292
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1293
|
+
// Additional ETHICS cases
|
|
1294
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1295
|
+
{
|
|
1296
|
+
id: "ethics-deep-manipulative-urgency",
|
|
1297
|
+
description: "Fake urgency and scarcity tactics to pressure purchases",
|
|
1298
|
+
language: "typescript",
|
|
1299
|
+
code: `export function ProductPage({ product }: { product: Product }) {
|
|
1300
|
+
// Fake "limited stock" — always shows low number
|
|
1301
|
+
const fakeStock = Math.floor(Math.random() * 3) + 1;
|
|
1302
|
+
|
|
1303
|
+
// Fake "other viewers" count
|
|
1304
|
+
const fakeViewers = Math.floor(Math.random() * 20) + 15;
|
|
1305
|
+
|
|
1306
|
+
// Countdown timer that resets every visit
|
|
1307
|
+
const fakeDeadline = new Date(Date.now() + 2 * 60 * 60 * 1000);
|
|
1308
|
+
|
|
1309
|
+
return (
|
|
1310
|
+
<div>
|
|
1311
|
+
<h1>{product.name}</h1>
|
|
1312
|
+
<div className="urgency-banner" style={{ color: "red" }}>
|
|
1313
|
+
⚠️ Only {fakeStock} left in stock!
|
|
1314
|
+
</div>
|
|
1315
|
+
<div className="social-proof">
|
|
1316
|
+
👀 {fakeViewers} people are viewing this right now
|
|
1317
|
+
</div>
|
|
1318
|
+
<div className="timer">
|
|
1319
|
+
⏰ Sale ends in: <Countdown deadline={fakeDeadline} />
|
|
1320
|
+
</div>
|
|
1321
|
+
<div className="recent-purchases">
|
|
1322
|
+
{/* Fabricated recent purchase notifications */}
|
|
1323
|
+
<p>🛒 Sarah from NYC just bought this 3 minutes ago</p>
|
|
1324
|
+
<p>🛒 Mike from LA just bought this 7 minutes ago</p>
|
|
1325
|
+
</div>
|
|
1326
|
+
<button>Buy Now — Before It's Gone!</button>
|
|
1327
|
+
</div>
|
|
1328
|
+
);
|
|
1329
|
+
}`,
|
|
1330
|
+
expectedRuleIds: ["ETHICS-001"],
|
|
1331
|
+
category: "ethics",
|
|
1332
|
+
difficulty: "medium",
|
|
1333
|
+
},
|
|
1334
|
+
{
|
|
1335
|
+
id: "ethics-deep-shadow-banning",
|
|
1336
|
+
description: "Shadow banning users without notification or appeal",
|
|
1337
|
+
language: "typescript",
|
|
1338
|
+
code: `export class ModerationService {
|
|
1339
|
+
async shadowBan(userId: string, reason: string) {
|
|
1340
|
+
await db.query(
|
|
1341
|
+
"UPDATE users SET shadow_banned = true, shadow_ban_reason = $1 WHERE id = $2",
|
|
1342
|
+
[reason, userId]
|
|
1343
|
+
);
|
|
1344
|
+
// User is never notified
|
|
1345
|
+
// No appeal mechanism
|
|
1346
|
+
// No time limit — permanent by default
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
async getPostsForFeed(viewerId: string, posts: Post[]) {
|
|
1350
|
+
return posts.map(post => {
|
|
1351
|
+
if (post.authorId === viewerId) {
|
|
1352
|
+
// Banned user sees their own posts normally
|
|
1353
|
+
return { ...post, visible: true };
|
|
1354
|
+
}
|
|
1355
|
+
// But everyone else can't see them
|
|
1356
|
+
const author = await db.findUser(post.authorId);
|
|
1357
|
+
if (author.shadow_banned) {
|
|
1358
|
+
return null; // Silently removed
|
|
1359
|
+
}
|
|
1360
|
+
return { ...post, visible: true };
|
|
1361
|
+
}).filter(Boolean);
|
|
1362
|
+
// User thinks their posts are public but nobody can see them
|
|
1363
|
+
// No transparency, no due process
|
|
1364
|
+
}
|
|
1365
|
+
}`,
|
|
1366
|
+
expectedRuleIds: ["ETHICS-001"],
|
|
1367
|
+
category: "ethics",
|
|
1368
|
+
difficulty: "hard",
|
|
1369
|
+
},
|
|
1370
|
+
{
|
|
1371
|
+
id: "ethics-deep-algorithmic-bias-hiring",
|
|
1372
|
+
description: "Hiring algorithm with biased training features",
|
|
1373
|
+
language: "python",
|
|
1374
|
+
code: `import pandas as pd
|
|
1375
|
+
from sklearn.ensemble import GradientBoostingClassifier
|
|
1376
|
+
|
|
1377
|
+
def train_resume_screener(training_data: pd.DataFrame):
|
|
1378
|
+
# Features that introduce bias
|
|
1379
|
+
features = [
|
|
1380
|
+
'years_experience',
|
|
1381
|
+
'university_ranking', # Biased against non-traditional education
|
|
1382
|
+
'zip_code', # Proxy for race/socioeconomic status
|
|
1383
|
+
'name_origin_score', # Directly discriminatory
|
|
1384
|
+
'graduation_year', # Age proxy
|
|
1385
|
+
'has_gap_in_employment', # Biased against caregivers/parents
|
|
1386
|
+
'club_memberships', # Cultural bias
|
|
1387
|
+
'linkedin_connections', # Network privilege bias
|
|
1388
|
+
]
|
|
1389
|
+
|
|
1390
|
+
X = training_data[features]
|
|
1391
|
+
# Labels from historical hiring decisions (which were themselves biased)
|
|
1392
|
+
y = training_data['was_hired']
|
|
1393
|
+
|
|
1394
|
+
model = GradientBoostingClassifier()
|
|
1395
|
+
model.fit(X, y)
|
|
1396
|
+
# No bias audit
|
|
1397
|
+
# No disparate impact analysis
|
|
1398
|
+
# No fairness metrics evaluation
|
|
1399
|
+
return model
|
|
1400
|
+
|
|
1401
|
+
def screen_resume(model, resume_data):
|
|
1402
|
+
score = model.predict_proba([resume_data])[0][1]
|
|
1403
|
+
return {
|
|
1404
|
+
'score': score,
|
|
1405
|
+
'recommendation': 'proceed' if score > 0.7 else 'reject',
|
|
1406
|
+
# No explanation for rejection
|
|
1407
|
+
# No human review requirement
|
|
1408
|
+
}`,
|
|
1409
|
+
expectedRuleIds: ["ETHICS-001"],
|
|
1410
|
+
category: "ethics",
|
|
1411
|
+
difficulty: "hard",
|
|
1412
|
+
},
|
|
1413
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1414
|
+
// Additional A11Y cases
|
|
1415
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1416
|
+
{
|
|
1417
|
+
id: "a11y-deep-video-no-captions",
|
|
1418
|
+
description: "Video player without captions or transcript support",
|
|
1419
|
+
language: "typescript",
|
|
1420
|
+
code: `export function VideoPlayer({ src, title }: VideoProps) {
|
|
1421
|
+
return (
|
|
1422
|
+
<div className="video-container">
|
|
1423
|
+
<video
|
|
1424
|
+
src={src}
|
|
1425
|
+
controls
|
|
1426
|
+
autoPlay
|
|
1427
|
+
style={{ width: "100%" }}
|
|
1428
|
+
>
|
|
1429
|
+
{/* No <track> elements for captions/subtitles */}
|
|
1430
|
+
{/* No aria-label */}
|
|
1431
|
+
{/* autoPlay without user consent — problematic for screen readers */}
|
|
1432
|
+
</video>
|
|
1433
|
+
<div className="video-info">
|
|
1434
|
+
<span style={{ fontWeight: "bold" }}>{title}</span>
|
|
1435
|
+
</div>
|
|
1436
|
+
{/* No transcript available */}
|
|
1437
|
+
{/* No audio description track */}
|
|
1438
|
+
</div>
|
|
1439
|
+
);
|
|
1440
|
+
}`,
|
|
1441
|
+
expectedRuleIds: ["A11Y-001"],
|
|
1442
|
+
category: "accessibility",
|
|
1443
|
+
difficulty: "medium",
|
|
1444
|
+
},
|
|
1445
|
+
{
|
|
1446
|
+
id: "a11y-deep-table-no-headers",
|
|
1447
|
+
description: "Data table without proper header associations",
|
|
1448
|
+
language: "html",
|
|
1449
|
+
code: `<div class="data-table">
|
|
1450
|
+
<div style="display: flex; background: #eee; font-weight: bold;">
|
|
1451
|
+
<div style="flex: 1; padding: 8px;">Name</div>
|
|
1452
|
+
<div style="flex: 1; padding: 8px;">Role</div>
|
|
1453
|
+
<div style="flex: 1; padding: 8px;">Status</div>
|
|
1454
|
+
<div style="flex: 1; padding: 8px;">Actions</div>
|
|
1455
|
+
</div>
|
|
1456
|
+
<div style="display: flex; border-bottom: 1px solid #ddd;">
|
|
1457
|
+
<div style="flex: 1; padding: 8px;">Alice Smith</div>
|
|
1458
|
+
<div style="flex: 1; padding: 8px;">Admin</div>
|
|
1459
|
+
<div style="flex: 1; padding: 8px;">
|
|
1460
|
+
<span style="color: green;">●</span>
|
|
1461
|
+
</div>
|
|
1462
|
+
<div style="flex: 1; padding: 8px;">
|
|
1463
|
+
<img src="/icons/edit.svg" onclick="edit(1)" style="cursor: pointer;" />
|
|
1464
|
+
<img src="/icons/delete.svg" onclick="del(1)" style="cursor: pointer;" />
|
|
1465
|
+
</div>
|
|
1466
|
+
</div>
|
|
1467
|
+
</div>
|
|
1468
|
+
<!-- Using divs instead of <table>, <th>, <td> -->
|
|
1469
|
+
<!-- No scope attributes, no caption, no summary -->
|
|
1470
|
+
<!-- Status uses color-only indicator -->
|
|
1471
|
+
<!-- Action icons have no alt text -->`,
|
|
1472
|
+
expectedRuleIds: ["A11Y-001"],
|
|
1473
|
+
category: "accessibility",
|
|
1474
|
+
difficulty: "medium",
|
|
1475
|
+
},
|
|
1476
|
+
{
|
|
1477
|
+
id: "a11y-deep-focus-trap",
|
|
1478
|
+
description: "Modal dialog with no focus management or escape handling",
|
|
1479
|
+
language: "typescript",
|
|
1480
|
+
code: `export function Modal({ isOpen, children }: ModalProps) {
|
|
1481
|
+
if (!isOpen) return null;
|
|
1482
|
+
|
|
1483
|
+
return (
|
|
1484
|
+
<div
|
|
1485
|
+
className="modal-overlay"
|
|
1486
|
+
style={{
|
|
1487
|
+
position: "fixed",
|
|
1488
|
+
top: 0,
|
|
1489
|
+
left: 0,
|
|
1490
|
+
right: 0,
|
|
1491
|
+
bottom: 0,
|
|
1492
|
+
background: "rgba(0,0,0,0.5)",
|
|
1493
|
+
zIndex: 9999,
|
|
1494
|
+
}}
|
|
1495
|
+
>
|
|
1496
|
+
<div className="modal-content" style={{ background: "white", padding: "20px" }}>
|
|
1497
|
+
{children}
|
|
1498
|
+
<div
|
|
1499
|
+
className="close-btn"
|
|
1500
|
+
onClick={() => {/* close */}}
|
|
1501
|
+
style={{ cursor: "pointer", float: "right" }}
|
|
1502
|
+
>
|
|
1503
|
+
✕
|
|
1504
|
+
</div>
|
|
1505
|
+
</div>
|
|
1506
|
+
</div>
|
|
1507
|
+
);
|
|
1508
|
+
// No role="dialog"
|
|
1509
|
+
// No aria-modal="true"
|
|
1510
|
+
// No focus trap — Tab key goes to elements behind modal
|
|
1511
|
+
// No Escape key handler
|
|
1512
|
+
// No aria-labelledby
|
|
1513
|
+
// Close button is a div, not a button
|
|
1514
|
+
// Focus not returned to trigger element on close
|
|
1515
|
+
}`,
|
|
1516
|
+
expectedRuleIds: ["A11Y-001"],
|
|
1517
|
+
category: "accessibility",
|
|
1518
|
+
difficulty: "hard",
|
|
1519
|
+
},
|
|
1520
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1521
|
+
// Additional I18N cases
|
|
1522
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1523
|
+
{
|
|
1524
|
+
id: "i18n-deep-rtl-not-supported",
|
|
1525
|
+
description: "Layout hardcoded to LTR, breaks for RTL languages",
|
|
1526
|
+
language: "typescript",
|
|
1527
|
+
code: `export function ChatBubble({ message, isSent }: ChatBubbleProps) {
|
|
1528
|
+
return (
|
|
1529
|
+
<div
|
|
1530
|
+
style={{
|
|
1531
|
+
display: "flex",
|
|
1532
|
+
justifyContent: isSent ? "flex-end" : "flex-start",
|
|
1533
|
+
// Hardcoded flex-end/start — breaks in RTL
|
|
1534
|
+
marginLeft: isSent ? "40px" : "0",
|
|
1535
|
+
marginRight: isSent ? "0" : "40px",
|
|
1536
|
+
// Hardcoded left/right margins — inverted in RTL
|
|
1537
|
+
}}
|
|
1538
|
+
>
|
|
1539
|
+
<div
|
|
1540
|
+
style={{
|
|
1541
|
+
background: isSent ? "#007bff" : "#e9ecef",
|
|
1542
|
+
borderRadius: "18px 18px 4px 18px",
|
|
1543
|
+
// Asymmetric border-radius — wrong corners in RTL
|
|
1544
|
+
padding: "8px 16px",
|
|
1545
|
+
textAlign: "left",
|
|
1546
|
+
// Always left-aligned — should be "start" for RTL
|
|
1547
|
+
}}
|
|
1548
|
+
>
|
|
1549
|
+
{message.text}
|
|
1550
|
+
<div style={{ fontSize: "11px", textAlign: "right" }}>
|
|
1551
|
+
{/* Timestamp always right-aligned */}
|
|
1552
|
+
{formatTime(message.timestamp)}
|
|
1553
|
+
</div>
|
|
1554
|
+
</div>
|
|
1555
|
+
</div>
|
|
1556
|
+
);
|
|
1557
|
+
}`,
|
|
1558
|
+
expectedRuleIds: ["I18N-001"],
|
|
1559
|
+
category: "internationalization",
|
|
1560
|
+
difficulty: "hard",
|
|
1561
|
+
},
|
|
1562
|
+
{
|
|
1563
|
+
id: "i18n-deep-number-formatting",
|
|
1564
|
+
description: "Number formatting hardcoded to Western conventions",
|
|
1565
|
+
language: "typescript",
|
|
1566
|
+
code: `export function formatNumber(val: number): string {
|
|
1567
|
+
// US-centric: 1,000,000.50
|
|
1568
|
+
// Germany expects: 1.000.000,50
|
|
1569
|
+
// India expects: 10,00,000.50
|
|
1570
|
+
return val.toFixed(2).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
export function formatPercentage(val: number): string {
|
|
1574
|
+
return val.toFixed(1) + "%";
|
|
1575
|
+
// Turkey uses: %50,0 (percent sign before number)
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
export function formatFileSize(bytes: number): string {
|
|
1579
|
+
const units = ["bytes", "KB", "MB", "GB"];
|
|
1580
|
+
// Hardcoded English unit names
|
|
1581
|
+
let i = 0;
|
|
1582
|
+
let size = bytes;
|
|
1583
|
+
while (size >= 1024 && i < units.length - 1) {
|
|
1584
|
+
size /= 1024;
|
|
1585
|
+
i++;
|
|
1586
|
+
}
|
|
1587
|
+
return size.toFixed(1) + " " + units[i];
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
export function parseUserInput(input: string): number {
|
|
1591
|
+
// Only handles 1,234.56 format — fails for 1.234,56
|
|
1592
|
+
return parseFloat(input.replace(/,/g, ""));
|
|
1593
|
+
}`,
|
|
1594
|
+
expectedRuleIds: ["PERF-001"],
|
|
1595
|
+
category: "internationalization",
|
|
1596
|
+
difficulty: "medium",
|
|
1597
|
+
},
|
|
1598
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1599
|
+
// Additional UX cases
|
|
1600
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1601
|
+
{
|
|
1602
|
+
id: "ux-deep-destructive-no-confirmation",
|
|
1603
|
+
description: "Destructive actions without confirmation or undo",
|
|
1604
|
+
language: "typescript",
|
|
1605
|
+
code: `export function ProjectDashboard({ projects }: DashboardProps) {
|
|
1606
|
+
const handleDelete = async (projectId: string) => {
|
|
1607
|
+
// Immediate hard delete — no confirmation dialog
|
|
1608
|
+
await fetch(\`/api/projects/\${projectId}\`, { method: "DELETE" });
|
|
1609
|
+
window.location.reload();
|
|
1610
|
+
// No undo capability
|
|
1611
|
+
// No soft delete / trash
|
|
1612
|
+
// Page reload loses scroll position and context
|
|
1613
|
+
};
|
|
1614
|
+
|
|
1615
|
+
return (
|
|
1616
|
+
<div>
|
|
1617
|
+
{projects.map((project) => (
|
|
1618
|
+
<div key={project.id} className="project-card">
|
|
1619
|
+
<h3>{project.name}</h3>
|
|
1620
|
+
<button onClick={() => handleDelete(project.id)}>
|
|
1621
|
+
Delete
|
|
1622
|
+
</button>
|
|
1623
|
+
{/* Delete button same style as other actions */}
|
|
1624
|
+
{/* No visual distinction for destructive action */}
|
|
1625
|
+
</div>
|
|
1626
|
+
))}
|
|
1627
|
+
</div>
|
|
1628
|
+
);
|
|
1629
|
+
}`,
|
|
1630
|
+
expectedRuleIds: ["SCALE-001"],
|
|
1631
|
+
category: "ux",
|
|
1632
|
+
difficulty: "easy",
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
id: "ux-deep-infinite-scroll-no-fallback",
|
|
1636
|
+
description: "Infinite scroll with no pagination fallback or position memory",
|
|
1637
|
+
language: "typescript",
|
|
1638
|
+
code: `export function ProductList() {
|
|
1639
|
+
const [products, setProducts] = useState<Product[]>([]);
|
|
1640
|
+
const [page, setPage] = useState(1);
|
|
1641
|
+
|
|
1642
|
+
useEffect(() => {
|
|
1643
|
+
const observer = new IntersectionObserver((entries) => {
|
|
1644
|
+
if (entries[0].isIntersecting) {
|
|
1645
|
+
fetch(\`/api/products?page=\${page}\`)
|
|
1646
|
+
.then(r => r.json())
|
|
1647
|
+
.then(data => {
|
|
1648
|
+
setProducts(prev => [...prev, ...data]);
|
|
1649
|
+
setPage(p => p + 1);
|
|
1650
|
+
});
|
|
1651
|
+
// No loading indicator during fetch
|
|
1652
|
+
// No error handling if fetch fails
|
|
1653
|
+
}
|
|
1654
|
+
});
|
|
1655
|
+
observer.observe(document.getElementById("sentinel")!);
|
|
1656
|
+
}, [page]);
|
|
1657
|
+
|
|
1658
|
+
return (
|
|
1659
|
+
<div>
|
|
1660
|
+
{products.map(p => (
|
|
1661
|
+
<a key={p.id} href={\`/products/\${p.id}\`}>
|
|
1662
|
+
{/* Clicking a product, then pressing Back loses scroll position */}
|
|
1663
|
+
{/* User must re-scroll through hundreds of items */}
|
|
1664
|
+
<div>{p.name}</div>
|
|
1665
|
+
</a>
|
|
1666
|
+
))}
|
|
1667
|
+
<div id="sentinel" />
|
|
1668
|
+
{/* No way to jump to a specific page */}
|
|
1669
|
+
{/* No total count shown */}
|
|
1670
|
+
{/* Footer unreachable — pushed down infinitely */}
|
|
1671
|
+
</div>
|
|
1672
|
+
);
|
|
1673
|
+
}`,
|
|
1674
|
+
expectedRuleIds: ["SCALE-001", "ERR-001", "FW-001"],
|
|
1675
|
+
category: "ux",
|
|
1676
|
+
difficulty: "medium",
|
|
1677
|
+
},
|
|
1678
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1679
|
+
// Additional COMPAT cases
|
|
1680
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1681
|
+
{
|
|
1682
|
+
id: "compat-deep-deprecated-node-apis",
|
|
1683
|
+
description: "Using deprecated Node.js APIs without migration plan",
|
|
1684
|
+
language: "typescript",
|
|
1685
|
+
code: `import { createCipher, createDecipher } from "crypto";
|
|
1686
|
+
import { exists } from "fs";
|
|
1687
|
+
import { parse } from "url";
|
|
1688
|
+
import { createServer } from "http";
|
|
1689
|
+
|
|
1690
|
+
// crypto.createCipher deprecated since Node 10
|
|
1691
|
+
export function encrypt(data: string, key: string): string {
|
|
1692
|
+
const cipher = createCipher("aes-256-cbc", key);
|
|
1693
|
+
let encrypted = cipher.update(data, "utf8", "hex");
|
|
1694
|
+
encrypted += cipher.final("hex");
|
|
1695
|
+
return encrypted;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
// fs.exists deprecated since Node 1.0
|
|
1699
|
+
export function checkFile(path: string): Promise<boolean> {
|
|
1700
|
+
return new Promise((resolve) => {
|
|
1701
|
+
exists(path, resolve);
|
|
1702
|
+
});
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
// url.parse deprecated since Node 11
|
|
1706
|
+
export function getPathname(urlStr: string): string {
|
|
1707
|
+
const parsed = parse(urlStr);
|
|
1708
|
+
return parsed.pathname || "/";
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
const server = createServer((req, res) => {
|
|
1712
|
+
// Using deprecated req.connection
|
|
1713
|
+
const ip = req.connection.remoteAddress;
|
|
1714
|
+
// Using deprecated Buffer constructor
|
|
1715
|
+
const body = new Buffer(1024);
|
|
1716
|
+
res.end("OK");
|
|
1717
|
+
});`,
|
|
1718
|
+
expectedRuleIds: ["REL-001"],
|
|
1719
|
+
category: "compatibility",
|
|
1720
|
+
difficulty: "medium",
|
|
1721
|
+
},
|
|
1722
|
+
{
|
|
1723
|
+
id: "compat-deep-vendor-lock-in",
|
|
1724
|
+
description: "Deep vendor lock-in with no abstraction layer",
|
|
1725
|
+
language: "typescript",
|
|
1726
|
+
code: `import {
|
|
1727
|
+
DynamoDB, S3, SQS, SNS, Lambda,
|
|
1728
|
+
CloudWatch, SecretsManager,
|
|
1729
|
+
} from "aws-sdk";
|
|
1730
|
+
|
|
1731
|
+
export class OrderService {
|
|
1732
|
+
private dynamo = new DynamoDB.DocumentClient();
|
|
1733
|
+
private s3 = new S3();
|
|
1734
|
+
private sqs = new SQS();
|
|
1735
|
+
private sns = new SNS();
|
|
1736
|
+
|
|
1737
|
+
async createOrder(order: Order) {
|
|
1738
|
+
// DynamoDB-specific: using DynamoDB expressions directly
|
|
1739
|
+
await this.dynamo.put({
|
|
1740
|
+
TableName: "Orders",
|
|
1741
|
+
Item: order,
|
|
1742
|
+
ConditionExpression: "attribute_not_exists(orderId)",
|
|
1743
|
+
}).promise();
|
|
1744
|
+
|
|
1745
|
+
// SQS-specific: using SQS message attributes
|
|
1746
|
+
await this.sqs.sendMessage({
|
|
1747
|
+
QueueUrl: process.env.ORDER_QUEUE_URL!,
|
|
1748
|
+
MessageBody: JSON.stringify(order),
|
|
1749
|
+
MessageGroupId: order.customerId,
|
|
1750
|
+
MessageDeduplicationId: order.orderId,
|
|
1751
|
+
}).promise();
|
|
1752
|
+
|
|
1753
|
+
// SNS-specific: using SNS message filtering
|
|
1754
|
+
await this.sns.publish({
|
|
1755
|
+
TopicArn: process.env.ORDER_TOPIC!,
|
|
1756
|
+
Message: JSON.stringify(order),
|
|
1757
|
+
MessageAttributes: {
|
|
1758
|
+
orderType: { DataType: "String", StringValue: order.type },
|
|
1759
|
+
},
|
|
1760
|
+
}).promise();
|
|
1761
|
+
|
|
1762
|
+
// Lambda invoke — tight coupling to AWS Lambda
|
|
1763
|
+
await new Lambda().invoke({
|
|
1764
|
+
FunctionName: "processOrderPayment",
|
|
1765
|
+
InvocationType: "Event",
|
|
1766
|
+
Payload: JSON.stringify(order),
|
|
1767
|
+
}).promise();
|
|
1768
|
+
// No abstraction layer — impossible to migrate to GCP/Azure
|
|
1769
|
+
}
|
|
1770
|
+
}`,
|
|
1771
|
+
expectedRuleIds: ["AICS-001"],
|
|
1772
|
+
category: "compatibility",
|
|
1773
|
+
difficulty: "hard",
|
|
1774
|
+
},
|
|
1775
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1776
|
+
// Additional DEPS cases
|
|
1777
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1778
|
+
{
|
|
1779
|
+
id: "deps-deep-typosquat-risk",
|
|
1780
|
+
description: "Dependencies with names similar to popular packages (typosquatting risk)",
|
|
1781
|
+
language: "json",
|
|
1782
|
+
code: `{
|
|
1783
|
+
"name": "my-api",
|
|
1784
|
+
"dependencies": {
|
|
1785
|
+
"expresss": "^4.18.0",
|
|
1786
|
+
"loadash": "^4.17.21",
|
|
1787
|
+
"axois": "^1.6.0",
|
|
1788
|
+
"cross-env2": "^7.0.3",
|
|
1789
|
+
"colurs": "^1.4.0",
|
|
1790
|
+
"electorn": "^28.0.0",
|
|
1791
|
+
"babel-coree": "^6.26.3"
|
|
1792
|
+
},
|
|
1793
|
+
"devDependencies": {
|
|
1794
|
+
"eslintt": "^8.56.0",
|
|
1795
|
+
"webpackk": "^5.90.0"
|
|
1796
|
+
}
|
|
1797
|
+
}`,
|
|
1798
|
+
expectedRuleIds: ["DEPS-001"],
|
|
1799
|
+
category: "dependency-health",
|
|
1800
|
+
difficulty: "easy",
|
|
1801
|
+
},
|
|
1802
|
+
{
|
|
1803
|
+
id: "deps-deep-excessive-dependencies",
|
|
1804
|
+
description: "Massively bloated dependencies for simple functionality",
|
|
1805
|
+
language: "typescript",
|
|
1806
|
+
code: `// Using huge libraries for tiny tasks
|
|
1807
|
+
import _ from "lodash"; // 70KB for one function
|
|
1808
|
+
import moment from "moment"; // 300KB+ for date formatting
|
|
1809
|
+
import jQuery from "jquery"; // 87KB for DOM query
|
|
1810
|
+
import { v4 as uuid } from "uuid"; // Could use crypto.randomUUID()
|
|
1811
|
+
|
|
1812
|
+
export function processItems(items: any[]) {
|
|
1813
|
+
// Using lodash just for array flatten
|
|
1814
|
+
const flat = _.flatten(items); // Array.flat() is native
|
|
1815
|
+
|
|
1816
|
+
// Using moment just for ISO string
|
|
1817
|
+
const now = moment().toISOString(); // new Date().toISOString()
|
|
1818
|
+
|
|
1819
|
+
// Using jQuery for querySelector
|
|
1820
|
+
const el = jQuery("#app"); // document.querySelector("#app")
|
|
1821
|
+
|
|
1822
|
+
// Using uuid when crypto.randomUUID exists
|
|
1823
|
+
const id = uuid(); // crypto.randomUUID()
|
|
1824
|
+
|
|
1825
|
+
return { flat, now, id };
|
|
1826
|
+
}`,
|
|
1827
|
+
expectedRuleIds: ["DEPS-001"],
|
|
1828
|
+
category: "dependency-health",
|
|
1829
|
+
difficulty: "medium",
|
|
1830
|
+
},
|
|
1831
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1832
|
+
// Additional PORTA cases
|
|
1833
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1834
|
+
{
|
|
1835
|
+
id: "porta-deep-linux-specific-syscalls",
|
|
1836
|
+
description: "Using Linux-specific system calls and paths in Node.js",
|
|
1837
|
+
language: "typescript",
|
|
1838
|
+
code: `import { execSync } from "child_process";
|
|
1839
|
+
import fs from "fs";
|
|
1840
|
+
|
|
1841
|
+
export function getSystemInfo() {
|
|
1842
|
+
// Linux-specific /proc filesystem
|
|
1843
|
+
const memInfo = fs.readFileSync("/proc/meminfo", "utf-8");
|
|
1844
|
+
const cpuInfo = fs.readFileSync("/proc/cpuinfo", "utf-8");
|
|
1845
|
+
const loadAvg = fs.readFileSync("/proc/loadavg", "utf-8");
|
|
1846
|
+
|
|
1847
|
+
// Linux-specific commands
|
|
1848
|
+
const diskUsage = execSync("df -h /").toString();
|
|
1849
|
+
const networkInterfaces = execSync("ifconfig").toString();
|
|
1850
|
+
const runningProcesses = execSync("ps aux | grep node").toString();
|
|
1851
|
+
|
|
1852
|
+
// Linux-specific signals
|
|
1853
|
+
process.on("SIGUSR2", () => {
|
|
1854
|
+
console.log("Received SIGUSR2 — dumping heap");
|
|
1855
|
+
execSync("kill -USR1 " + process.pid);
|
|
1856
|
+
});
|
|
1857
|
+
|
|
1858
|
+
// Hardcoded Linux paths
|
|
1859
|
+
const logDir = "/var/log/myapp";
|
|
1860
|
+
const pidFile = "/var/run/myapp.pid";
|
|
1861
|
+
const configDir = "/etc/myapp";
|
|
1862
|
+
|
|
1863
|
+
fs.writeFileSync(pidFile, process.pid.toString());
|
|
1864
|
+
|
|
1865
|
+
return { memInfo, cpuInfo, loadAvg, diskUsage };
|
|
1866
|
+
}`,
|
|
1867
|
+
expectedRuleIds: ["PORTA-001"],
|
|
1868
|
+
category: "portability",
|
|
1869
|
+
difficulty: "medium",
|
|
1870
|
+
},
|
|
1871
|
+
{
|
|
1872
|
+
id: "porta-deep-env-specific-docker",
|
|
1873
|
+
description: "Dockerfile assuming specific host environment",
|
|
1874
|
+
language: "dockerfile",
|
|
1875
|
+
code: `FROM node:18
|
|
1876
|
+
|
|
1877
|
+
# Assumes x86_64 architecture — fails on ARM (Apple Silicon, Graviton)
|
|
1878
|
+
RUN wget https://example.com/binary-linux-x86_64 -O /usr/local/bin/mytool
|
|
1879
|
+
RUN chmod +x /usr/local/bin/mytool
|
|
1880
|
+
|
|
1881
|
+
# Hardcoded UID/GID that may conflict with host
|
|
1882
|
+
RUN useradd -u 1000 -g 1000 appuser
|
|
1883
|
+
|
|
1884
|
+
# Mounts host-specific paths
|
|
1885
|
+
VOLUME /mnt/nfs-share
|
|
1886
|
+
VOLUME /dev/sda1
|
|
1887
|
+
|
|
1888
|
+
# Assumes specific network configuration
|
|
1889
|
+
RUN echo "nameserver 10.0.0.1" > /etc/resolv.conf
|
|
1890
|
+
|
|
1891
|
+
# Uses apt-get for Debian — won't work with Alpine base
|
|
1892
|
+
RUN apt-get update && apt-get install -y \\
|
|
1893
|
+
libpng-dev \\
|
|
1894
|
+
libjpeg-dev
|
|
1895
|
+
|
|
1896
|
+
# Hardcoded timezone — should use TZ env var
|
|
1897
|
+
RUN ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
|
|
1898
|
+
|
|
1899
|
+
WORKDIR /app
|
|
1900
|
+
COPY . .
|
|
1901
|
+
RUN npm install
|
|
1902
|
+
CMD ["node", "server.js"]`,
|
|
1903
|
+
expectedRuleIds: ["PORTA-001"],
|
|
1904
|
+
category: "portability",
|
|
1905
|
+
difficulty: "hard",
|
|
1906
|
+
},
|
|
1907
|
+
// Additional mixed cases for underrepresented judges
|
|
1908
|
+
{
|
|
1909
|
+
id: "comp-deep-cookie-consent-bypass",
|
|
1910
|
+
description: "Tracking cookies set before user consent",
|
|
1911
|
+
language: "typescript",
|
|
1912
|
+
code: `export function initializeApp() {
|
|
1913
|
+
// Set tracking cookies BEFORE showing consent banner
|
|
1914
|
+
document.cookie = "tracking_id=" + generateId() + "; max-age=31536000; path=/";
|
|
1915
|
+
document.cookie = "user_fingerprint=" + fingerprint() + "; max-age=31536000; path=/";
|
|
1916
|
+
document.cookie = "ad_preferences=" + JSON.stringify(getAdPrefs()) + "; max-age=31536000; path=/";
|
|
1917
|
+
|
|
1918
|
+
// Start tracking immediately
|
|
1919
|
+
window.gtag("config", "GA-XXXXX", {
|
|
1920
|
+
send_page_view: true,
|
|
1921
|
+
cookie_flags: "SameSite=None;Secure",
|
|
1922
|
+
});
|
|
1923
|
+
|
|
1924
|
+
// Show consent banner (but tracking already started)
|
|
1925
|
+
setTimeout(() => {
|
|
1926
|
+
showConsentBanner();
|
|
1927
|
+
}, 2000);
|
|
1928
|
+
|
|
1929
|
+
// Even if user declines, cookies already set
|
|
1930
|
+
// No mechanism to delete tracking cookies on decline
|
|
1931
|
+
}`,
|
|
1932
|
+
expectedRuleIds: ["A11Y-001"],
|
|
1933
|
+
category: "compliance",
|
|
1934
|
+
difficulty: "medium",
|
|
1935
|
+
},
|
|
1936
|
+
{
|
|
1937
|
+
id: "ethics-deep-deceptive-countdown",
|
|
1938
|
+
description: "Deceptive subscription cancellation flow with fake countdown",
|
|
1939
|
+
language: "typescript",
|
|
1940
|
+
code: `export function CancellationFlow({ userId }: { userId: string }) {
|
|
1941
|
+
const [step, setStep] = useState(0);
|
|
1942
|
+
|
|
1943
|
+
const steps = [
|
|
1944
|
+
// Step 1: Emotional manipulation
|
|
1945
|
+
() => (
|
|
1946
|
+
<div>
|
|
1947
|
+
<h2>We'll miss you! 😢</h2>
|
|
1948
|
+
<p>Are you really sure? Your team of 12 relies on this account.</p>
|
|
1949
|
+
<button onClick={() => setStep(1)}>I still want to cancel</button>
|
|
1950
|
+
<button onClick={() => window.location.href = "/dashboard"}
|
|
1951
|
+
style={{ background: "green", color: "white", fontSize: "18px" }}>
|
|
1952
|
+
Keep my account!
|
|
1953
|
+
</button>
|
|
1954
|
+
</div>
|
|
1955
|
+
),
|
|
1956
|
+
// Step 2: Fake special offer
|
|
1957
|
+
() => (
|
|
1958
|
+
<div>
|
|
1959
|
+
<h2>Wait! Exclusive offer just for you</h2>
|
|
1960
|
+
<p>⏰ 50% off for 6 months — offer expires in <FakeCounter initial={300} /></p>
|
|
1961
|
+
<button onClick={() => setStep(2)} style={{ fontSize: "10px", color: "#999" }}>
|
|
1962
|
+
No thanks, continue cancellation
|
|
1963
|
+
</button>
|
|
1964
|
+
</div>
|
|
1965
|
+
),
|
|
1966
|
+
// Step 3: Survey (required, 20 questions)
|
|
1967
|
+
// Step 4: "Processing" with 60-second fake wait
|
|
1968
|
+
// Step 5: Final "Are you sure?" with pre-checked "pause instead" option
|
|
1969
|
+
// Step 6: "Cancellation scheduled for end of billing period" (30 days away)
|
|
1970
|
+
];
|
|
1971
|
+
|
|
1972
|
+
return steps[step]?.() || <div>Processing...</div>;
|
|
1973
|
+
}`,
|
|
1974
|
+
expectedRuleIds: ["ETHICS-001"],
|
|
1975
|
+
category: "ethics",
|
|
1976
|
+
difficulty: "medium",
|
|
1977
|
+
},
|
|
1978
|
+
{
|
|
1979
|
+
id: "a11y-deep-image-carousel-no-alt",
|
|
1980
|
+
description: "Image carousel with no alt text and auto-rotation",
|
|
1981
|
+
language: "typescript",
|
|
1982
|
+
code: `export function ImageCarousel({ images }: { images: string[] }) {
|
|
1983
|
+
const [current, setCurrent] = useState(0);
|
|
1984
|
+
|
|
1985
|
+
useEffect(() => {
|
|
1986
|
+
// Auto-rotates every 3 seconds — pauses for no one
|
|
1987
|
+
const timer = setInterval(() => {
|
|
1988
|
+
setCurrent(prev => (prev + 1) % images.length);
|
|
1989
|
+
}, 3000);
|
|
1990
|
+
return () => clearInterval(timer);
|
|
1991
|
+
// No pause button
|
|
1992
|
+
// No respect for prefers-reduced-motion
|
|
1993
|
+
}, [images.length]);
|
|
1994
|
+
|
|
1995
|
+
return (
|
|
1996
|
+
<div className="carousel">
|
|
1997
|
+
<img src={images[current]} style={{ width: "100%" }} />
|
|
1998
|
+
{/* No alt text on images */}
|
|
1999
|
+
<div
|
|
2000
|
+
onClick={() => setCurrent(prev => (prev - 1 + images.length) % images.length)}
|
|
2001
|
+
style={{ cursor: "pointer", position: "absolute", left: "10px" }}
|
|
2002
|
+
>
|
|
2003
|
+
◀
|
|
2004
|
+
</div>
|
|
2005
|
+
<div
|
|
2006
|
+
onClick={() => setCurrent(prev => (prev + 1) % images.length)}
|
|
2007
|
+
style={{ cursor: "pointer", position: "absolute", right: "10px" }}
|
|
2008
|
+
>
|
|
2009
|
+
▶
|
|
2010
|
+
</div>
|
|
2011
|
+
{/* Navigation arrows are divs, not buttons */}
|
|
2012
|
+
{/* No keyboard support */}
|
|
2013
|
+
{/* No live region announcing slide changes */}
|
|
2014
|
+
<div className="dots">
|
|
2015
|
+
{images.map((_, i) => (
|
|
2016
|
+
<span
|
|
2017
|
+
key={i}
|
|
2018
|
+
style={{ color: i === current ? "black" : "gray" }}
|
|
2019
|
+
onClick={() => setCurrent(i)}
|
|
2020
|
+
>●</span>
|
|
2021
|
+
))}
|
|
2022
|
+
</div>
|
|
2023
|
+
</div>
|
|
2024
|
+
);
|
|
2025
|
+
}`,
|
|
2026
|
+
expectedRuleIds: ["A11Y-001"],
|
|
2027
|
+
category: "accessibility",
|
|
2028
|
+
difficulty: "hard",
|
|
2029
|
+
},
|
|
2030
|
+
{
|
|
2031
|
+
id: "i18n-deep-locale-dependent-sorting",
|
|
2032
|
+
description: "String sorting without locale-aware collation",
|
|
2033
|
+
language: "typescript",
|
|
2034
|
+
code: `export function sortNames(names: string[]): string[] {
|
|
2035
|
+
return names.sort();
|
|
2036
|
+
// JavaScript default sort uses UTF-16 code unit order
|
|
2037
|
+
// "Ä" sorts after "Z" instead of near "A" (German)
|
|
2038
|
+
// "ñ" sorts after all ASCII (Spanish)
|
|
2039
|
+
// "å" sorts wrong (Swedish: å comes after ö)
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
export function searchFilter(items: Item[], query: string): Item[] {
|
|
2043
|
+
const lower = query.toLowerCase();
|
|
2044
|
+
return items.filter(item =>
|
|
2045
|
+
item.name.toLowerCase().includes(lower)
|
|
2046
|
+
);
|
|
2047
|
+
// toLowerCase() doesn't handle Turkish İ/i dotted/dotless correctly
|
|
2048
|
+
// Turkish: "I".toLowerCase() should be "ı" not "i"
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
export function compareStrings(a: string, b: string): number {
|
|
2052
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
2053
|
+
// Locale-unaware comparison
|
|
2054
|
+
// Should use Intl.Collator for proper locale ordering
|
|
2055
|
+
}`,
|
|
2056
|
+
expectedRuleIds: ["I18N-001"],
|
|
2057
|
+
category: "internationalization",
|
|
2058
|
+
difficulty: "hard",
|
|
2059
|
+
},
|
|
2060
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2061
|
+
// CLEAN compliance/ethics cases — FP validation
|
|
2062
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2063
|
+
{
|
|
2064
|
+
id: "clean-comp-gdpr-compliant-api",
|
|
2065
|
+
description: "Clean: GDPR-compliant user data API with consent management",
|
|
2066
|
+
language: "typescript",
|
|
2067
|
+
code: `import { z } from "zod";
|
|
2068
|
+
import { auditLog } from "./audit";
|
|
2069
|
+
|
|
2070
|
+
const ConsentSchema = z.object({
|
|
2071
|
+
marketing: z.boolean(),
|
|
2072
|
+
analytics: z.boolean(),
|
|
2073
|
+
thirdPartySharing: z.boolean(),
|
|
2074
|
+
dataRetentionAck: z.boolean(),
|
|
2075
|
+
});
|
|
2076
|
+
|
|
2077
|
+
export async function registerUser(data: RegistrationInput) {
|
|
2078
|
+
const consent = ConsentSchema.parse(data.consent);
|
|
2079
|
+
|
|
2080
|
+
const user = await db.users.create({
|
|
2081
|
+
email: data.email,
|
|
2082
|
+
name: data.name,
|
|
2083
|
+
consent: {
|
|
2084
|
+
marketing: consent.marketing,
|
|
2085
|
+
analytics: consent.analytics,
|
|
2086
|
+
thirdPartySharing: consent.thirdPartySharing,
|
|
2087
|
+
consentedAt: new Date(),
|
|
2088
|
+
ipAddress: maskIP(data.ip),
|
|
2089
|
+
},
|
|
2090
|
+
dataRetention: {
|
|
2091
|
+
policy: "36_months",
|
|
2092
|
+
reviewDate: addMonths(new Date(), 36),
|
|
2093
|
+
},
|
|
2094
|
+
});
|
|
2095
|
+
|
|
2096
|
+
await auditLog.record({
|
|
2097
|
+
action: "USER_REGISTERED",
|
|
2098
|
+
userId: user.id,
|
|
2099
|
+
details: { consentGiven: consent },
|
|
2100
|
+
performedBy: "self-registration",
|
|
2101
|
+
});
|
|
2102
|
+
|
|
2103
|
+
if (consent.analytics) {
|
|
2104
|
+
await analytics.identify(user.id, {
|
|
2105
|
+
// Only pseudonymized data
|
|
2106
|
+
segment: user.segment,
|
|
2107
|
+
region: user.region,
|
|
2108
|
+
});
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
return { userId: user.id, message: "Account created" };
|
|
2112
|
+
}`,
|
|
2113
|
+
expectedRuleIds: [],
|
|
2114
|
+
category: "clean",
|
|
2115
|
+
difficulty: "hard",
|
|
2116
|
+
},
|
|
2117
|
+
{
|
|
2118
|
+
id: "clean-comp-pci-tokenized",
|
|
2119
|
+
description: "Clean: PCI-DSS compliant payment processing with tokenization",
|
|
2120
|
+
language: "typescript",
|
|
2121
|
+
code: `import Stripe from "stripe";
|
|
2122
|
+
|
|
2123
|
+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
|
2124
|
+
apiVersion: "2023-10-16",
|
|
2125
|
+
});
|
|
2126
|
+
|
|
2127
|
+
export async function processPayment(
|
|
2128
|
+
paymentMethodId: string,
|
|
2129
|
+
amount: number,
|
|
2130
|
+
currency: string,
|
|
2131
|
+
userId: string
|
|
2132
|
+
) {
|
|
2133
|
+
// Card details never touch our server — handled by Stripe tokenization
|
|
2134
|
+
const paymentIntent = await stripe.paymentIntents.create({
|
|
2135
|
+
amount: Math.round(amount * 100),
|
|
2136
|
+
currency,
|
|
2137
|
+
payment_method: paymentMethodId,
|
|
2138
|
+
confirm: true,
|
|
2139
|
+
metadata: { userId },
|
|
2140
|
+
return_url: process.env.RETURN_URL!,
|
|
2141
|
+
});
|
|
2142
|
+
|
|
2143
|
+
// Store only non-sensitive reference
|
|
2144
|
+
await db.payments.insert({
|
|
2145
|
+
userId,
|
|
2146
|
+
stripePaymentId: paymentIntent.id,
|
|
2147
|
+
amount,
|
|
2148
|
+
currency,
|
|
2149
|
+
status: paymentIntent.status,
|
|
2150
|
+
last4: paymentIntent.payment_method_types?.[0] || "unknown",
|
|
2151
|
+
createdAt: new Date(),
|
|
2152
|
+
});
|
|
2153
|
+
|
|
2154
|
+
return {
|
|
2155
|
+
paymentId: paymentIntent.id,
|
|
2156
|
+
status: paymentIntent.status,
|
|
2157
|
+
};
|
|
2158
|
+
}`,
|
|
2159
|
+
expectedRuleIds: [],
|
|
2160
|
+
category: "clean",
|
|
2161
|
+
difficulty: "medium",
|
|
2162
|
+
},
|
|
2163
|
+
{
|
|
2164
|
+
id: "clean-comp-audit-trail",
|
|
2165
|
+
description: "Clean: Comprehensive audit trail for admin operations",
|
|
2166
|
+
language: "typescript",
|
|
2167
|
+
code: `import { z } from "zod";
|
|
2168
|
+
|
|
2169
|
+
interface AuditEntry {
|
|
2170
|
+
id: string;
|
|
2171
|
+
timestamp: Date;
|
|
2172
|
+
action: string;
|
|
2173
|
+
performedBy: string;
|
|
2174
|
+
targetResource: string;
|
|
2175
|
+
targetId: string;
|
|
2176
|
+
details: {
|
|
2177
|
+
before?: Record<string, unknown>;
|
|
2178
|
+
after?: Record<string, unknown>;
|
|
2179
|
+
reason: string;
|
|
2180
|
+
};
|
|
2181
|
+
ipAddress: string;
|
|
2182
|
+
userAgent: string;
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
export class AuditedAdminService {
|
|
2186
|
+
constructor(
|
|
2187
|
+
private db: Database,
|
|
2188
|
+
private auditLog: AuditLogger,
|
|
2189
|
+
) {}
|
|
2190
|
+
|
|
2191
|
+
async deleteUser(adminId: string, userId: string, reason: string, context: RequestContext) {
|
|
2192
|
+
const existing = await this.db.users.findById(userId);
|
|
2193
|
+
if (!existing) throw new NotFoundError("User not found");
|
|
2194
|
+
|
|
2195
|
+
await this.db.transaction(async (tx) => {
|
|
2196
|
+
await tx.users.softDelete(userId);
|
|
2197
|
+
|
|
2198
|
+
await this.auditLog.record({
|
|
2199
|
+
action: "USER_DELETED",
|
|
2200
|
+
performedBy: adminId,
|
|
2201
|
+
targetResource: "users",
|
|
2202
|
+
targetId: userId,
|
|
2203
|
+
details: {
|
|
2204
|
+
before: { status: existing.status, email: maskEmail(existing.email) },
|
|
2205
|
+
after: { status: "deleted" },
|
|
2206
|
+
reason,
|
|
2207
|
+
},
|
|
2208
|
+
ipAddress: context.ip,
|
|
2209
|
+
userAgent: context.userAgent,
|
|
2210
|
+
});
|
|
2211
|
+
});
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
async modifyFinancialRecord(
|
|
2215
|
+
adminId: string,
|
|
2216
|
+
recordId: string,
|
|
2217
|
+
newAmount: number,
|
|
2218
|
+
reason: string,
|
|
2219
|
+
approvedBy: string,
|
|
2220
|
+
context: RequestContext
|
|
2221
|
+
) {
|
|
2222
|
+
const existing = await this.db.financialRecords.findById(recordId);
|
|
2223
|
+
|
|
2224
|
+
await this.db.transaction(async (tx) => {
|
|
2225
|
+
await tx.financialRecords.update(recordId, { amount: newAmount });
|
|
2226
|
+
await tx.financialRecordVersions.insert({
|
|
2227
|
+
recordId,
|
|
2228
|
+
previousAmount: existing.amount,
|
|
2229
|
+
newAmount,
|
|
2230
|
+
changedBy: adminId,
|
|
2231
|
+
approvedBy,
|
|
2232
|
+
reason,
|
|
2233
|
+
});
|
|
2234
|
+
|
|
2235
|
+
await this.auditLog.record({
|
|
2236
|
+
action: "FINANCIAL_RECORD_MODIFIED",
|
|
2237
|
+
performedBy: adminId,
|
|
2238
|
+
targetResource: "financial_records",
|
|
2239
|
+
targetId: recordId,
|
|
2240
|
+
details: {
|
|
2241
|
+
before: { amount: existing.amount },
|
|
2242
|
+
after: { amount: newAmount },
|
|
2243
|
+
reason,
|
|
2244
|
+
},
|
|
2245
|
+
ipAddress: context.ip,
|
|
2246
|
+
userAgent: context.userAgent,
|
|
2247
|
+
});
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
}`,
|
|
2251
|
+
expectedRuleIds: [],
|
|
2252
|
+
category: "clean",
|
|
2253
|
+
difficulty: "hard",
|
|
2254
|
+
},
|
|
2255
|
+
{
|
|
2256
|
+
id: "clean-a11y-accessible-form",
|
|
2257
|
+
description: "Clean: Fully accessible form with proper ARIA and keyboard support",
|
|
2258
|
+
language: "html",
|
|
2259
|
+
code: `<form action="/register" method="POST" aria-labelledby="form-title" novalidate>
|
|
2260
|
+
<h2 id="form-title">Create an Account</h2>
|
|
2261
|
+
|
|
2262
|
+
<div class="form-group">
|
|
2263
|
+
<label for="firstName">First Name <span aria-hidden="true">*</span></label>
|
|
2264
|
+
<input type="text" id="firstName" name="firstName" required
|
|
2265
|
+
aria-required="true" aria-describedby="firstName-help"
|
|
2266
|
+
autocomplete="given-name" />
|
|
2267
|
+
<span id="firstName-help" class="help-text">Enter your legal first name</span>
|
|
2268
|
+
</div>
|
|
2269
|
+
|
|
2270
|
+
<div class="form-group">
|
|
2271
|
+
<label for="email">Email Address <span aria-hidden="true">*</span></label>
|
|
2272
|
+
<input type="email" id="email" name="email" required
|
|
2273
|
+
aria-required="true" aria-describedby="email-error"
|
|
2274
|
+
autocomplete="email" />
|
|
2275
|
+
<span id="email-error" class="error-text" role="alert" aria-live="polite"></span>
|
|
2276
|
+
</div>
|
|
2277
|
+
|
|
2278
|
+
<div class="form-group">
|
|
2279
|
+
<label for="password">Password <span aria-hidden="true">*</span></label>
|
|
2280
|
+
<input type="password" id="password" name="password" required
|
|
2281
|
+
aria-required="true" aria-describedby="password-requirements"
|
|
2282
|
+
autocomplete="new-password" minlength="8" />
|
|
2283
|
+
<div id="password-requirements" class="help-text">
|
|
2284
|
+
Must be at least 8 characters with one uppercase, one number, and one symbol.
|
|
2285
|
+
</div>
|
|
2286
|
+
</div>
|
|
2287
|
+
|
|
2288
|
+
<div class="form-group">
|
|
2289
|
+
<label for="country">Country</label>
|
|
2290
|
+
<select id="country" name="country" autocomplete="country">
|
|
2291
|
+
<option value="">Select your country</option>
|
|
2292
|
+
<option value="us">United States</option>
|
|
2293
|
+
<option value="uk">United Kingdom</option>
|
|
2294
|
+
</select>
|
|
2295
|
+
</div>
|
|
2296
|
+
|
|
2297
|
+
<button type="submit">Create Account</button>
|
|
2298
|
+
</form>`,
|
|
2299
|
+
expectedRuleIds: [],
|
|
2300
|
+
category: "clean",
|
|
2301
|
+
difficulty: "medium",
|
|
2302
|
+
},
|
|
2303
|
+
{
|
|
2304
|
+
id: "clean-i18n-proper-localization",
|
|
2305
|
+
description: "Clean: Proper internationalization with ICU message format",
|
|
2306
|
+
language: "typescript",
|
|
2307
|
+
code: `import { IntlMessageFormat } from "intl-messageformat";
|
|
2308
|
+
|
|
2309
|
+
const messages: Record<string, Record<string, string>> = {
|
|
2310
|
+
en: {
|
|
2311
|
+
"cart.title": "Shopping Cart",
|
|
2312
|
+
"cart.items": "{count, plural, =0 {No items} one {1 item} other {# items}} in your cart",
|
|
2313
|
+
"cart.total": "Total: {total, number, ::currency/USD}",
|
|
2314
|
+
"cart.checkout": "Proceed to Checkout",
|
|
2315
|
+
},
|
|
2316
|
+
de: {
|
|
2317
|
+
"cart.title": "Warenkorb",
|
|
2318
|
+
"cart.items": "{count, plural, =0 {Keine Artikel} one {1 Artikel} other {# Artikel}} in Ihrem Warenkorb",
|
|
2319
|
+
"cart.total": "Gesamt: {total, number, ::currency/EUR}",
|
|
2320
|
+
"cart.checkout": "Zur Kasse gehen",
|
|
2321
|
+
},
|
|
2322
|
+
ja: {
|
|
2323
|
+
"cart.title": "ショッピングカート",
|
|
2324
|
+
"cart.items": "カートに{count}個の商品があります",
|
|
2325
|
+
"cart.total": "合計: {total, number, ::currency/JPY}",
|
|
2326
|
+
"cart.checkout": "レジに進む",
|
|
2327
|
+
},
|
|
2328
|
+
};
|
|
2329
|
+
|
|
2330
|
+
export function t(key: string, locale: string, values?: Record<string, unknown>): string {
|
|
2331
|
+
const template = messages[locale]?.[key] || messages.en[key] || key;
|
|
2332
|
+
if (!values) return template;
|
|
2333
|
+
return new IntlMessageFormat(template, locale).format(values) as string;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
export function formatDate(date: Date, locale: string): string {
|
|
2337
|
+
return new Intl.DateTimeFormat(locale, {
|
|
2338
|
+
year: "numeric",
|
|
2339
|
+
month: "long",
|
|
2340
|
+
day: "numeric",
|
|
2341
|
+
}).format(date);
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
export function formatCurrency(amount: number, currency: string, locale: string): string {
|
|
2345
|
+
return new Intl.NumberFormat(locale, {
|
|
2346
|
+
style: "currency",
|
|
2347
|
+
currency,
|
|
2348
|
+
}).format(amount);
|
|
2349
|
+
}`,
|
|
2350
|
+
expectedRuleIds: [],
|
|
2351
|
+
category: "clean",
|
|
2352
|
+
difficulty: "hard",
|
|
2353
|
+
},
|
|
2354
|
+
{
|
|
2355
|
+
id: "clean-ethics-fair-pricing",
|
|
2356
|
+
description: "Clean: Fair pricing algorithm without discriminatory factors",
|
|
2357
|
+
language: "python",
|
|
2358
|
+
code: `from dataclasses import dataclass
|
|
2359
|
+
from typing import Optional
|
|
2360
|
+
|
|
2361
|
+
@dataclass
|
|
2362
|
+
class PricingFactors:
|
|
2363
|
+
base_rate: float
|
|
2364
|
+
risk_score: float # Based on objective, non-discriminatory factors
|
|
2365
|
+
coverage_level: str
|
|
2366
|
+
deductible: float
|
|
2367
|
+
claim_history_years: int
|
|
2368
|
+
claims_count: int
|
|
2369
|
+
|
|
2370
|
+
def calculate_premium(factors: PricingFactors) -> float:
|
|
2371
|
+
"""
|
|
2372
|
+
Calculate insurance premium based on objective risk factors only.
|
|
2373
|
+
Prohibited factors (per fair lending/insurance laws):
|
|
2374
|
+
- Race, ethnicity, national origin
|
|
2375
|
+
- Gender, sexual orientation
|
|
2376
|
+
- Religion
|
|
2377
|
+
- Disability status
|
|
2378
|
+
- Marital status (in some jurisdictions)
|
|
2379
|
+
"""
|
|
2380
|
+
rate = factors.base_rate
|
|
2381
|
+
|
|
2382
|
+
# Coverage level multiplier
|
|
2383
|
+
coverage_multipliers = {
|
|
2384
|
+
"basic": 1.0,
|
|
2385
|
+
"standard": 1.5,
|
|
2386
|
+
"premium": 2.0,
|
|
2387
|
+
}
|
|
2388
|
+
rate *= coverage_multipliers.get(factors.coverage_level, 1.0)
|
|
2389
|
+
|
|
2390
|
+
# Deductible discount (higher deductible = lower premium)
|
|
2391
|
+
if factors.deductible >= 2000:
|
|
2392
|
+
rate *= 0.8
|
|
2393
|
+
elif factors.deductible >= 1000:
|
|
2394
|
+
rate *= 0.9
|
|
2395
|
+
|
|
2396
|
+
# Claims history (objective, gender-neutral factor)
|
|
2397
|
+
if factors.claims_count == 0 and factors.claim_history_years >= 3:
|
|
2398
|
+
rate *= 0.85 # No-claims discount
|
|
2399
|
+
|
|
2400
|
+
return round(rate, 2)`,
|
|
2401
|
+
expectedRuleIds: [],
|
|
2402
|
+
category: "clean",
|
|
2403
|
+
difficulty: "medium",
|
|
2404
|
+
},
|
|
2405
|
+
{
|
|
2406
|
+
id: "clean-ux-consistent-errors",
|
|
2407
|
+
description: "Clean: Consistent error response format across all endpoints",
|
|
2408
|
+
language: "typescript",
|
|
2409
|
+
code: `interface ApiError {
|
|
2410
|
+
code: string;
|
|
2411
|
+
message: string;
|
|
2412
|
+
details?: Record<string, string[]>;
|
|
2413
|
+
requestId: string;
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
function createError(
|
|
2417
|
+
code: string,
|
|
2418
|
+
message: string,
|
|
2419
|
+
details?: Record<string, string[]>
|
|
2420
|
+
): ApiError {
|
|
2421
|
+
return {
|
|
2422
|
+
code,
|
|
2423
|
+
message,
|
|
2424
|
+
details,
|
|
2425
|
+
requestId: crypto.randomUUID(),
|
|
2426
|
+
};
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
export const errorMiddleware = (
|
|
2430
|
+
err: Error,
|
|
2431
|
+
req: express.Request,
|
|
2432
|
+
res: express.Response,
|
|
2433
|
+
_next: express.NextFunction
|
|
2434
|
+
) => {
|
|
2435
|
+
if (err instanceof ValidationError) {
|
|
2436
|
+
return res.status(400).json(
|
|
2437
|
+
createError("VALIDATION_ERROR", "Invalid input provided", err.details)
|
|
2438
|
+
);
|
|
2439
|
+
}
|
|
2440
|
+
if (err instanceof NotFoundError) {
|
|
2441
|
+
return res.status(404).json(
|
|
2442
|
+
createError("NOT_FOUND", err.message)
|
|
2443
|
+
);
|
|
2444
|
+
}
|
|
2445
|
+
if (err instanceof ConflictError) {
|
|
2446
|
+
return res.status(409).json(
|
|
2447
|
+
createError("CONFLICT", err.message)
|
|
2448
|
+
);
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
// Never expose internal details
|
|
2452
|
+
console.error("Unhandled error:", err);
|
|
2453
|
+
return res.status(500).json(
|
|
2454
|
+
createError("INTERNAL_ERROR", "An unexpected error occurred. Please try again later.")
|
|
2455
|
+
);
|
|
2456
|
+
};`,
|
|
2457
|
+
expectedRuleIds: [],
|
|
2458
|
+
category: "clean",
|
|
2459
|
+
difficulty: "medium",
|
|
2460
|
+
},
|
|
2461
|
+
{
|
|
2462
|
+
id: "clean-compat-versioned-api",
|
|
2463
|
+
description: "Clean: Versioned API with backward compatibility",
|
|
2464
|
+
language: "typescript",
|
|
2465
|
+
code: `import express from "express";
|
|
2466
|
+
|
|
2467
|
+
const app = express();
|
|
2468
|
+
|
|
2469
|
+
// API versioning via URL path
|
|
2470
|
+
const v1Router = express.Router();
|
|
2471
|
+
const v2Router = express.Router();
|
|
2472
|
+
|
|
2473
|
+
// V1: Original response format (maintained for backward compatibility)
|
|
2474
|
+
v1Router.get("/users/:id", async (req, res) => {
|
|
2475
|
+
const user = await db.findUser(req.params.id);
|
|
2476
|
+
res.json({
|
|
2477
|
+
id: user.id,
|
|
2478
|
+
name: user.name,
|
|
2479
|
+
email: user.email,
|
|
2480
|
+
});
|
|
2481
|
+
});
|
|
2482
|
+
|
|
2483
|
+
// V2: Enhanced response format with envelope
|
|
2484
|
+
v2Router.get("/users/:id", async (req, res) => {
|
|
2485
|
+
const user = await db.findUser(req.params.id);
|
|
2486
|
+
res.json({
|
|
2487
|
+
data: {
|
|
2488
|
+
id: user.id,
|
|
2489
|
+
name: user.name,
|
|
2490
|
+
email: user.email,
|
|
2491
|
+
createdAt: user.created_at,
|
|
2492
|
+
updatedAt: user.updated_at,
|
|
2493
|
+
},
|
|
2494
|
+
meta: {
|
|
2495
|
+
apiVersion: "v2",
|
|
2496
|
+
deprecations: [],
|
|
2497
|
+
},
|
|
2498
|
+
});
|
|
2499
|
+
});
|
|
2500
|
+
|
|
2501
|
+
app.use("/api/v1", v1Router);
|
|
2502
|
+
app.use("/api/v2", v2Router);
|
|
2503
|
+
|
|
2504
|
+
// Deprecation warning for v1
|
|
2505
|
+
app.use("/api/v1", (req, res, next) => {
|
|
2506
|
+
res.setHeader("Deprecation", "true");
|
|
2507
|
+
res.setHeader("Sunset", "2025-06-01");
|
|
2508
|
+
res.setHeader("Link", '</api/v2>; rel="successor-version"');
|
|
2509
|
+
next();
|
|
2510
|
+
});`,
|
|
2511
|
+
expectedRuleIds: [],
|
|
2512
|
+
category: "clean",
|
|
2513
|
+
difficulty: "medium",
|
|
2514
|
+
},
|
|
2515
|
+
{
|
|
2516
|
+
id: "clean-deps-well-maintained",
|
|
2517
|
+
description: "Clean: Well-maintained dependencies with precise version pinning",
|
|
2518
|
+
language: "json",
|
|
2519
|
+
code: `{
|
|
2520
|
+
"name": "production-api",
|
|
2521
|
+
"version": "2.0.0",
|
|
2522
|
+
"engines": {
|
|
2523
|
+
"node": ">=20.0.0",
|
|
2524
|
+
"npm": ">=10.0.0"
|
|
2525
|
+
},
|
|
2526
|
+
"dependencies": {
|
|
2527
|
+
"express": "4.18.2",
|
|
2528
|
+
"zod": "3.22.4",
|
|
2529
|
+
"drizzle-orm": "0.29.3",
|
|
2530
|
+
"pg": "8.11.3",
|
|
2531
|
+
"ioredis": "5.3.2",
|
|
2532
|
+
"pino": "8.17.2",
|
|
2533
|
+
"helmet": "7.1.0",
|
|
2534
|
+
"cors": "2.8.5",
|
|
2535
|
+
"jsonwebtoken": "9.0.2",
|
|
2536
|
+
"bcryptjs": "2.4.3"
|
|
2537
|
+
},
|
|
2538
|
+
"devDependencies": {
|
|
2539
|
+
"typescript": "5.3.3",
|
|
2540
|
+
"vitest": "1.2.1",
|
|
2541
|
+
"@types/express": "4.17.21",
|
|
2542
|
+
"@types/node": "20.11.5",
|
|
2543
|
+
"eslint": "8.56.0"
|
|
2544
|
+
},
|
|
2545
|
+
"overrides": {
|
|
2546
|
+
"semver": ">=7.5.4"
|
|
2547
|
+
}
|
|
2548
|
+
}`,
|
|
2549
|
+
expectedRuleIds: [],
|
|
2550
|
+
category: "clean",
|
|
2551
|
+
difficulty: "easy",
|
|
2552
|
+
},
|
|
2553
|
+
{
|
|
2554
|
+
id: "clean-porta-cross-platform-paths",
|
|
2555
|
+
description: "Clean: Cross-platform file path handling",
|
|
2556
|
+
language: "typescript",
|
|
2557
|
+
code: `import path from "path";
|
|
2558
|
+
import os from "os";
|
|
2559
|
+
import fs from "fs/promises";
|
|
2560
|
+
|
|
2561
|
+
export function getAppDataDir(): string {
|
|
2562
|
+
const appName = "myapp";
|
|
2563
|
+
switch (process.platform) {
|
|
2564
|
+
case "win32":
|
|
2565
|
+
return path.join(process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming"), appName);
|
|
2566
|
+
case "darwin":
|
|
2567
|
+
return path.join(os.homedir(), "Library", "Application Support", appName);
|
|
2568
|
+
default:
|
|
2569
|
+
return path.join(process.env.XDG_DATA_HOME || path.join(os.homedir(), ".local", "share"), appName);
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
|
|
2573
|
+
export function getLogDir(): string {
|
|
2574
|
+
return path.join(getAppDataDir(), "logs");
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
export function getTempDir(): string {
|
|
2578
|
+
return path.join(os.tmpdir(), "myapp");
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
export async function writeLog(message: string): Promise<void> {
|
|
2582
|
+
const logDir = getLogDir();
|
|
2583
|
+
await fs.mkdir(logDir, { recursive: true });
|
|
2584
|
+
const logFile = path.join(logDir, "app.log");
|
|
2585
|
+
await fs.appendFile(logFile, message + os.EOL);
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
export async function loadConfig(): Promise<Record<string, unknown>> {
|
|
2589
|
+
const configPath = path.join(getAppDataDir(), "config.json");
|
|
2590
|
+
const content = await fs.readFile(configPath, "utf-8");
|
|
2591
|
+
return JSON.parse(content);
|
|
2592
|
+
}`,
|
|
2593
|
+
expectedRuleIds: [],
|
|
2594
|
+
category: "clean",
|
|
2595
|
+
difficulty: "medium",
|
|
2596
|
+
},
|
|
2597
|
+
{
|
|
2598
|
+
id: "clean-a11y-accessible-dropdown",
|
|
2599
|
+
description: "Clean: Custom dropdown with full keyboard and screen reader support",
|
|
2600
|
+
language: "typescript",
|
|
2601
|
+
code: `export function AccessibleDropdown({ options, onSelect, label }: DropdownProps) {
|
|
2602
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
2603
|
+
const [selected, setSelected] = useState(options[0]);
|
|
2604
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
2605
|
+
const listRef = useRef<HTMLUListElement>(null);
|
|
2606
|
+
|
|
2607
|
+
const handleKeyDown = (e: React.KeyboardEvent) => {
|
|
2608
|
+
switch (e.key) {
|
|
2609
|
+
case "ArrowDown":
|
|
2610
|
+
e.preventDefault();
|
|
2611
|
+
if (!isOpen) {
|
|
2612
|
+
setIsOpen(true);
|
|
2613
|
+
} else {
|
|
2614
|
+
setActiveIndex((prev) => Math.min(prev + 1, options.length - 1));
|
|
2615
|
+
}
|
|
2616
|
+
break;
|
|
2617
|
+
case "ArrowUp":
|
|
2618
|
+
e.preventDefault();
|
|
2619
|
+
setActiveIndex((prev) => Math.max(prev - 1, 0));
|
|
2620
|
+
break;
|
|
2621
|
+
case "Enter":
|
|
2622
|
+
case " ":
|
|
2623
|
+
e.preventDefault();
|
|
2624
|
+
if (isOpen) {
|
|
2625
|
+
setSelected(options[activeIndex]);
|
|
2626
|
+
onSelect(options[activeIndex].value);
|
|
2627
|
+
setIsOpen(false);
|
|
2628
|
+
} else {
|
|
2629
|
+
setIsOpen(true);
|
|
2630
|
+
}
|
|
2631
|
+
break;
|
|
2632
|
+
case "Escape":
|
|
2633
|
+
setIsOpen(false);
|
|
2634
|
+
break;
|
|
2635
|
+
}
|
|
2636
|
+
};
|
|
2637
|
+
|
|
2638
|
+
return (
|
|
2639
|
+
<div className="dropdown" onKeyDown={handleKeyDown}>
|
|
2640
|
+
<label id="dropdown-label">{label}</label>
|
|
2641
|
+
<button
|
|
2642
|
+
role="combobox"
|
|
2643
|
+
aria-expanded={isOpen}
|
|
2644
|
+
aria-haspopup="listbox"
|
|
2645
|
+
aria-labelledby="dropdown-label"
|
|
2646
|
+
aria-activedescendant={isOpen ? \`option-\${activeIndex}\` : undefined}
|
|
2647
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
2648
|
+
tabIndex={0}
|
|
2649
|
+
>
|
|
2650
|
+
{selected.label}
|
|
2651
|
+
</button>
|
|
2652
|
+
{isOpen && (
|
|
2653
|
+
<ul role="listbox" ref={listRef} aria-labelledby="dropdown-label">
|
|
2654
|
+
{options.map((opt, idx) => (
|
|
2655
|
+
<li
|
|
2656
|
+
key={opt.value}
|
|
2657
|
+
id={\`option-\${idx}\`}
|
|
2658
|
+
role="option"
|
|
2659
|
+
aria-selected={idx === activeIndex}
|
|
2660
|
+
onClick={() => {
|
|
2661
|
+
setSelected(opt);
|
|
2662
|
+
onSelect(opt.value);
|
|
2663
|
+
setIsOpen(false);
|
|
2664
|
+
}}
|
|
2665
|
+
>
|
|
2666
|
+
{opt.label}
|
|
2667
|
+
</li>
|
|
2668
|
+
))}
|
|
2669
|
+
</ul>
|
|
2670
|
+
)}
|
|
2671
|
+
</div>
|
|
2672
|
+
);
|
|
2673
|
+
}`,
|
|
2674
|
+
expectedRuleIds: [],
|
|
2675
|
+
category: "clean",
|
|
2676
|
+
difficulty: "hard",
|
|
2677
|
+
},
|
|
2678
|
+
{
|
|
2679
|
+
id: "clean-sov-region-aware-storage",
|
|
2680
|
+
description: "Clean: Region-aware data storage with sovereignty compliance",
|
|
2681
|
+
language: "typescript",
|
|
2682
|
+
code: `interface RegionConfig {
|
|
2683
|
+
bucket: string;
|
|
2684
|
+
region: string;
|
|
2685
|
+
encryptionKeyId: string;
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
const REGION_CONFIGS: Record<string, RegionConfig> = {
|
|
2689
|
+
EU: {
|
|
2690
|
+
bucket: "eu-west-1-user-data",
|
|
2691
|
+
region: "eu-west-1",
|
|
2692
|
+
encryptionKeyId: "alias/eu-data-key",
|
|
2693
|
+
},
|
|
2694
|
+
US: {
|
|
2695
|
+
bucket: "us-east-1-user-data",
|
|
2696
|
+
region: "us-east-1",
|
|
2697
|
+
encryptionKeyId: "alias/us-data-key",
|
|
2698
|
+
},
|
|
2699
|
+
APAC: {
|
|
2700
|
+
bucket: "ap-southeast-1-user-data",
|
|
2701
|
+
region: "ap-southeast-1",
|
|
2702
|
+
encryptionKeyId: "alias/apac-data-key",
|
|
2703
|
+
},
|
|
2704
|
+
};
|
|
2705
|
+
|
|
2706
|
+
export async function storeUserData(
|
|
2707
|
+
userId: string,
|
|
2708
|
+
userRegion: string,
|
|
2709
|
+
data: UserData
|
|
2710
|
+
): Promise<void> {
|
|
2711
|
+
const config = REGION_CONFIGS[userRegion];
|
|
2712
|
+
if (!config) {
|
|
2713
|
+
throw new Error(\`No storage configuration for region: \${userRegion}\`);
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
const s3 = new S3Client({ region: config.region });
|
|
2717
|
+
|
|
2718
|
+
await s3.send(new PutObjectCommand({
|
|
2719
|
+
Bucket: config.bucket,
|
|
2720
|
+
Key: \`users/\${userId}/profile.json\`,
|
|
2721
|
+
Body: JSON.stringify(data),
|
|
2722
|
+
ServerSideEncryption: "aws:kms",
|
|
2723
|
+
SSEKMSKeyId: config.encryptionKeyId,
|
|
2724
|
+
Metadata: {
|
|
2725
|
+
"data-residency": userRegion,
|
|
2726
|
+
"encryption-standard": "AES-256-KMS",
|
|
2727
|
+
},
|
|
2728
|
+
}));
|
|
2729
|
+
|
|
2730
|
+
await auditLog.record({
|
|
2731
|
+
action: "USER_DATA_STORED",
|
|
2732
|
+
userId,
|
|
2733
|
+
region: config.region,
|
|
2734
|
+
bucket: config.bucket,
|
|
2735
|
+
});
|
|
2736
|
+
}`,
|
|
2737
|
+
expectedRuleIds: [],
|
|
2738
|
+
category: "clean",
|
|
2739
|
+
difficulty: "hard",
|
|
2740
|
+
},
|
|
2741
|
+
{
|
|
2742
|
+
id: "clean-comp-data-retention",
|
|
2743
|
+
description: "Clean: Data retention policy with automatic cleanup",
|
|
2744
|
+
language: "typescript",
|
|
2745
|
+
code: `interface RetentionPolicy {
|
|
2746
|
+
table: string;
|
|
2747
|
+
retentionDays: number;
|
|
2748
|
+
dateColumn: string;
|
|
2749
|
+
anonymize?: string[];
|
|
2750
|
+
softDelete?: boolean;
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2753
|
+
const RETENTION_POLICIES: RetentionPolicy[] = [
|
|
2754
|
+
{ table: "activity_logs", retentionDays: 90, dateColumn: "created_at" },
|
|
2755
|
+
{ table: "session_recordings", retentionDays: 30, dateColumn: "recorded_at" },
|
|
2756
|
+
{ table: "audit_logs", retentionDays: 2555, dateColumn: "timestamp" }, // 7 years for compliance
|
|
2757
|
+
{
|
|
2758
|
+
table: "user_profiles",
|
|
2759
|
+
retentionDays: 1095, // 3 years after account deletion
|
|
2760
|
+
dateColumn: "deleted_at",
|
|
2761
|
+
anonymize: ["email", "phone", "address"],
|
|
2762
|
+
softDelete: true,
|
|
2763
|
+
},
|
|
2764
|
+
];
|
|
2765
|
+
|
|
2766
|
+
export async function enforceRetention(db: Database): Promise<RetentionReport> {
|
|
2767
|
+
const report: RetentionReport = { processed: [], errors: [] };
|
|
2768
|
+
|
|
2769
|
+
for (const policy of RETENTION_POLICIES) {
|
|
2770
|
+
try {
|
|
2771
|
+
const cutoffDate = new Date();
|
|
2772
|
+
cutoffDate.setDate(cutoffDate.getDate() - policy.retentionDays);
|
|
2773
|
+
|
|
2774
|
+
if (policy.anonymize) {
|
|
2775
|
+
const anonymizeSet = policy.anonymize
|
|
2776
|
+
.map((col) => \`\${col} = 'REDACTED'\`)
|
|
2777
|
+
.join(", ");
|
|
2778
|
+
const result = await db.query(
|
|
2779
|
+
\`UPDATE \${policy.table} SET \${anonymizeSet} WHERE \${policy.dateColumn} < $1 AND email != 'REDACTED'\`,
|
|
2780
|
+
[cutoffDate]
|
|
2781
|
+
);
|
|
2782
|
+
report.processed.push({ table: policy.table, action: "anonymized", count: result.rowCount });
|
|
2783
|
+
} else {
|
|
2784
|
+
const result = await db.query(
|
|
2785
|
+
\`DELETE FROM \${policy.table} WHERE \${policy.dateColumn} < $1\`,
|
|
2786
|
+
[cutoffDate]
|
|
2787
|
+
);
|
|
2788
|
+
report.processed.push({ table: policy.table, action: "deleted", count: result.rowCount });
|
|
2789
|
+
}
|
|
2790
|
+
} catch (error) {
|
|
2791
|
+
report.errors.push({ table: policy.table, error: String(error) });
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
|
|
2795
|
+
return report;
|
|
2796
|
+
}`,
|
|
2797
|
+
expectedRuleIds: [],
|
|
2798
|
+
category: "clean",
|
|
2799
|
+
difficulty: "hard",
|
|
2800
|
+
},
|
|
2801
|
+
{
|
|
2802
|
+
id: "clean-a11y-video-accessible",
|
|
2803
|
+
description: "Clean: Accessible video player with captions and keyboard controls",
|
|
2804
|
+
language: "typescript",
|
|
2805
|
+
code: `export function AccessibleVideoPlayer({ src, title, captionsSrc, transcriptUrl }: VideoProps) {
|
|
2806
|
+
const videoRef = useRef<HTMLVideoElement>(null);
|
|
2807
|
+
const prefersReducedMotion = useMediaQuery("(prefers-reduced-motion: reduce)");
|
|
2808
|
+
|
|
2809
|
+
return (
|
|
2810
|
+
<div role="region" aria-label={\`Video: \${title}\`}>
|
|
2811
|
+
<video
|
|
2812
|
+
ref={videoRef}
|
|
2813
|
+
src={src}
|
|
2814
|
+
controls
|
|
2815
|
+
aria-label={title}
|
|
2816
|
+
preload="metadata"
|
|
2817
|
+
>
|
|
2818
|
+
<track
|
|
2819
|
+
kind="captions"
|
|
2820
|
+
src={captionsSrc}
|
|
2821
|
+
srcLang="en"
|
|
2822
|
+
label="English Captions"
|
|
2823
|
+
default
|
|
2824
|
+
/>
|
|
2825
|
+
<track
|
|
2826
|
+
kind="descriptions"
|
|
2827
|
+
src={captionsSrc.replace(".vtt", "-descriptions.vtt")}
|
|
2828
|
+
srcLang="en"
|
|
2829
|
+
label="Audio Descriptions"
|
|
2830
|
+
/>
|
|
2831
|
+
Your browser does not support the video tag.
|
|
2832
|
+
</video>
|
|
2833
|
+
<div className="video-controls">
|
|
2834
|
+
<button aria-label="Play/Pause" onClick={() => {
|
|
2835
|
+
videoRef.current?.paused ? videoRef.current.play() : videoRef.current?.pause();
|
|
2836
|
+
}}>
|
|
2837
|
+
⏯
|
|
2838
|
+
</button>
|
|
2839
|
+
<a href={transcriptUrl} target="_blank" rel="noopener">
|
|
2840
|
+
View Full Transcript
|
|
2841
|
+
</a>
|
|
2842
|
+
</div>
|
|
2843
|
+
</div>
|
|
2844
|
+
);
|
|
2845
|
+
}`,
|
|
2846
|
+
expectedRuleIds: [],
|
|
2847
|
+
category: "clean",
|
|
2848
|
+
difficulty: "medium",
|
|
2849
|
+
},
|
|
2850
|
+
{
|
|
2851
|
+
id: "clean-i18n-rtl-support",
|
|
2852
|
+
description: "Clean: Proper RTL layout support with logical properties",
|
|
2853
|
+
language: "typescript",
|
|
2854
|
+
code: `export function ChatBubble({ message, isSent, dir }: ChatBubbleProps) {
|
|
2855
|
+
return (
|
|
2856
|
+
<div
|
|
2857
|
+
dir={dir}
|
|
2858
|
+
style={{
|
|
2859
|
+
display: "flex",
|
|
2860
|
+
justifyContent: isSent ? "flex-end" : "flex-start",
|
|
2861
|
+
marginInlineStart: isSent ? "40px" : "0",
|
|
2862
|
+
marginInlineEnd: isSent ? "0" : "40px",
|
|
2863
|
+
}}
|
|
2864
|
+
>
|
|
2865
|
+
<div
|
|
2866
|
+
style={{
|
|
2867
|
+
background: isSent ? "#007bff" : "#e9ecef",
|
|
2868
|
+
borderStartStartRadius: "18px",
|
|
2869
|
+
borderStartEndRadius: "18px",
|
|
2870
|
+
borderEndStartRadius: isSent ? "18px" : "4px",
|
|
2871
|
+
borderEndEndRadius: isSent ? "4px" : "18px",
|
|
2872
|
+
padding: "8px 16px",
|
|
2873
|
+
textAlign: "start",
|
|
2874
|
+
}}
|
|
2875
|
+
>
|
|
2876
|
+
{message.text}
|
|
2877
|
+
<div style={{ fontSize: "11px", textAlign: "end" }}>
|
|
2878
|
+
{new Intl.DateTimeFormat(message.locale, {
|
|
2879
|
+
hour: "numeric",
|
|
2880
|
+
minute: "numeric",
|
|
2881
|
+
}).format(message.timestamp)}
|
|
2882
|
+
</div>
|
|
2883
|
+
</div>
|
|
2884
|
+
</div>
|
|
2885
|
+
);
|
|
2886
|
+
}`,
|
|
2887
|
+
expectedRuleIds: [],
|
|
2888
|
+
category: "clean",
|
|
2889
|
+
difficulty: "hard",
|
|
2890
|
+
},
|
|
2891
|
+
{
|
|
2892
|
+
id: "clean-ethics-transparent-algo",
|
|
2893
|
+
description: "Clean: Transparent content recommendation with user control",
|
|
2894
|
+
language: "typescript",
|
|
2895
|
+
code: `export class TransparentRecommender {
|
|
2896
|
+
async getRecommendations(userId: string, preferences: UserPreferences) {
|
|
2897
|
+
const recommendations = await this.engine.recommend({
|
|
2898
|
+
userId,
|
|
2899
|
+
factors: {
|
|
2900
|
+
interests: preferences.selectedTopics,
|
|
2901
|
+
recency: preferences.preferRecent ? 0.8 : 0.3,
|
|
2902
|
+
diversity: preferences.diversityLevel,
|
|
2903
|
+
},
|
|
2904
|
+
excludeFactors: [
|
|
2905
|
+
"demographics",
|
|
2906
|
+
"inferredIncome",
|
|
2907
|
+
"locationHistory",
|
|
2908
|
+
],
|
|
2909
|
+
});
|
|
2910
|
+
|
|
2911
|
+
return {
|
|
2912
|
+
items: recommendations.map(rec => ({
|
|
2913
|
+
...rec,
|
|
2914
|
+
whyRecommended: rec.explanation,
|
|
2915
|
+
confidenceScore: rec.score,
|
|
2916
|
+
})),
|
|
2917
|
+
controls: {
|
|
2918
|
+
canDismiss: true,
|
|
2919
|
+
canBlockTopic: true,
|
|
2920
|
+
canAdjustWeights: true,
|
|
2921
|
+
dataUsedUrl: "/settings/recommendation-data",
|
|
2922
|
+
optOutUrl: "/settings/disable-recommendations",
|
|
2923
|
+
},
|
|
2924
|
+
};
|
|
2925
|
+
}
|
|
2926
|
+
}`,
|
|
2927
|
+
expectedRuleIds: [],
|
|
2928
|
+
category: "clean",
|
|
2929
|
+
difficulty: "hard",
|
|
2930
|
+
},
|
|
2931
|
+
{
|
|
2932
|
+
id: "clean-compat-graceful-deprecation",
|
|
2933
|
+
description: "Clean: Graceful API deprecation with migration timeline",
|
|
2934
|
+
language: "typescript",
|
|
2935
|
+
code: `import { Router } from "express";
|
|
2936
|
+
|
|
2937
|
+
export function deprecatedRoute(
|
|
2938
|
+
router: Router,
|
|
2939
|
+
oldPath: string,
|
|
2940
|
+
newPath: string,
|
|
2941
|
+
sunsetDate: string
|
|
2942
|
+
) {
|
|
2943
|
+
router.all(oldPath, (req, res, next) => {
|
|
2944
|
+
res.setHeader("Deprecation", \`date="\${sunsetDate}"\`);
|
|
2945
|
+
res.setHeader("Sunset", sunsetDate);
|
|
2946
|
+
res.setHeader("Link", \`<\${newPath}>; rel="successor-version"\`);
|
|
2947
|
+
|
|
2948
|
+
console.warn(\`Deprecated endpoint accessed: \${oldPath} by client \${req.get("User-Agent")}\`);
|
|
2949
|
+
|
|
2950
|
+
// Still serve the request — don't break existing clients
|
|
2951
|
+
next();
|
|
2952
|
+
});
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2955
|
+
// Usage
|
|
2956
|
+
const v1 = Router();
|
|
2957
|
+
const v2 = Router();
|
|
2958
|
+
|
|
2959
|
+
deprecatedRoute(v1, "/api/v1/users", "/api/v2/users", "2025-12-31");
|
|
2960
|
+
|
|
2961
|
+
v1.get("/api/v1/users/:id", async (req, res) => {
|
|
2962
|
+
const user = await db.findUser(req.params.id);
|
|
2963
|
+
// Transform to v1 format for backward compatibility
|
|
2964
|
+
res.json({ id: user.id, name: user.name, email: user.email });
|
|
2965
|
+
});
|
|
2966
|
+
|
|
2967
|
+
v2.get("/api/v2/users/:id", async (req, res) => {
|
|
2968
|
+
const user = await db.findUser(req.params.id);
|
|
2969
|
+
res.json({
|
|
2970
|
+
data: { id: user.id, name: user.name, email: user.email, createdAt: user.createdAt },
|
|
2971
|
+
meta: { apiVersion: "v2" },
|
|
2972
|
+
});
|
|
2973
|
+
});`,
|
|
2974
|
+
expectedRuleIds: [],
|
|
2975
|
+
category: "clean",
|
|
2976
|
+
difficulty: "medium",
|
|
2977
|
+
},
|
|
2978
|
+
{
|
|
2979
|
+
id: "clean-porta-cross-platform-scripts",
|
|
2980
|
+
description: "Clean: Cross-platform npm scripts using cross-env",
|
|
2981
|
+
language: "json",
|
|
2982
|
+
code: `{
|
|
2983
|
+
"name": "cross-platform-app",
|
|
2984
|
+
"scripts": {
|
|
2985
|
+
"clean": "rimraf dist",
|
|
2986
|
+
"prebuild": "mkdirp dist/assets && cpy 'static/**' dist/assets",
|
|
2987
|
+
"build": "cross-env NODE_ENV=production webpack --config webpack.prod.js",
|
|
2988
|
+
"start": "cross-env PORT=3000 node dist/server.js",
|
|
2989
|
+
"dev": "cross-env DEBUG=app:* nodemon src/server.ts",
|
|
2990
|
+
"test": "vitest run",
|
|
2991
|
+
"lint": "eslint src/"
|
|
2992
|
+
},
|
|
2993
|
+
"devDependencies": {
|
|
2994
|
+
"cross-env": "7.0.3",
|
|
2995
|
+
"rimraf": "5.0.5",
|
|
2996
|
+
"mkdirp": "3.0.1",
|
|
2997
|
+
"cpy-cli": "5.0.0"
|
|
2998
|
+
}
|
|
2999
|
+
}`,
|
|
3000
|
+
expectedRuleIds: [],
|
|
3001
|
+
category: "clean",
|
|
3002
|
+
difficulty: "easy",
|
|
3003
|
+
},
|
|
3004
|
+
{
|
|
3005
|
+
id: "clean-ux-proper-loading-states",
|
|
3006
|
+
description: "Clean: Async operations with proper loading, error, and success states",
|
|
3007
|
+
language: "typescript",
|
|
3008
|
+
code: `export function PaymentForm() {
|
|
3009
|
+
const [state, setState] = useState<"idle" | "loading" | "success" | "error">("idle");
|
|
3010
|
+
const [error, setError] = useState<string | null>(null);
|
|
3011
|
+
|
|
3012
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
3013
|
+
e.preventDefault();
|
|
3014
|
+
setState("loading");
|
|
3015
|
+
setError(null);
|
|
3016
|
+
|
|
3017
|
+
try {
|
|
3018
|
+
const response = await fetch("/api/payments", {
|
|
3019
|
+
method: "POST",
|
|
3020
|
+
body: JSON.stringify({ amount: 99.99 }),
|
|
3021
|
+
signal: AbortSignal.timeout(30000),
|
|
3022
|
+
});
|
|
3023
|
+
|
|
3024
|
+
if (!response.ok) {
|
|
3025
|
+
const data = await response.json();
|
|
3026
|
+
throw new Error(data.message || "Payment failed");
|
|
3027
|
+
}
|
|
3028
|
+
|
|
3029
|
+
setState("success");
|
|
3030
|
+
setTimeout(() => window.location.href = "/success", 1500);
|
|
3031
|
+
} catch (err) {
|
|
3032
|
+
setState("error");
|
|
3033
|
+
setError(err instanceof Error ? err.message : "An unexpected error occurred");
|
|
3034
|
+
}
|
|
3035
|
+
};
|
|
3036
|
+
|
|
3037
|
+
return (
|
|
3038
|
+
<form onSubmit={handleSubmit}>
|
|
3039
|
+
<input type="text" name="cardNumber" disabled={state === "loading"} />
|
|
3040
|
+
<button
|
|
3041
|
+
type="submit"
|
|
3042
|
+
disabled={state === "loading"}
|
|
3043
|
+
aria-busy={state === "loading"}
|
|
3044
|
+
>
|
|
3045
|
+
{state === "loading" ? "Processing..." : "Pay $99.99"}
|
|
3046
|
+
</button>
|
|
3047
|
+
{state === "error" && (
|
|
3048
|
+
<div role="alert" className="error-message">{error}</div>
|
|
3049
|
+
)}
|
|
3050
|
+
{state === "success" && (
|
|
3051
|
+
<div role="status" className="success-message">Payment successful! Redirecting...</div>
|
|
3052
|
+
)}
|
|
3053
|
+
</form>
|
|
3054
|
+
);
|
|
3055
|
+
}`,
|
|
3056
|
+
expectedRuleIds: [],
|
|
3057
|
+
category: "clean",
|
|
3058
|
+
difficulty: "medium",
|
|
3059
|
+
},
|
|
3060
|
+
];
|