@nebulacomponents/citable 0.1.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/CHANGELOG.md +26 -0
- package/LICENSE +201 -0
- package/README.md +150 -0
- package/cli/bin/citable.js +5 -0
- package/dist/universal/.agents/skills/citable/SKILL.md +137 -0
- package/dist/universal/.agents/skills/citable/VERSION +1 -0
- package/dist/universal/.agents/skills/citable/commands/README.md +36 -0
- package/dist/universal/.agents/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.agents/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.agents/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.agents/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.agents/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.agents/skills/citable/manifest.json +54 -0
- package/dist/universal/.agents/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.agents/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.agents/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.agents/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.agents/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.agents/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.agents/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.agents/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.agents/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.agents/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.agents/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.agents/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.agents/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.agents/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.agents/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.agents/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.agents/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.agents/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.agents/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.agents/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.agents/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.agents/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.agents/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.agents/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.agents/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.agents/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.agents/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.agents/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.agents/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.agents/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.agents/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.agents/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.agents/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.claude/skills/citable/SKILL.md +137 -0
- package/dist/universal/.claude/skills/citable/VERSION +1 -0
- package/dist/universal/.claude/skills/citable/commands/README.md +36 -0
- package/dist/universal/.claude/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.claude/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.claude/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.claude/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.claude/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.claude/skills/citable/manifest.json +54 -0
- package/dist/universal/.claude/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.claude/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.claude/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.claude/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.claude/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.claude/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.claude/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.claude/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.claude/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.claude/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.claude/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.claude/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.claude/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.claude/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.claude/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.claude/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.claude/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.claude/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.claude/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.claude/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.claude/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.claude/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.claude/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.claude/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.claude/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.claude/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.claude/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.claude/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.claude/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.claude/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.claude/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.claude/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.claude/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.cursor/skills/citable/SKILL.md +137 -0
- package/dist/universal/.cursor/skills/citable/VERSION +1 -0
- package/dist/universal/.cursor/skills/citable/commands/README.md +36 -0
- package/dist/universal/.cursor/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.cursor/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.cursor/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.cursor/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.cursor/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.cursor/skills/citable/manifest.json +54 -0
- package/dist/universal/.cursor/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.cursor/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.cursor/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.cursor/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.cursor/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.cursor/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.cursor/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.cursor/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.cursor/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.cursor/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.cursor/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.cursor/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.cursor/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.cursor/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.cursor/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.cursor/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.cursor/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.cursor/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.cursor/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.cursor/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.cursor/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.cursor/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.cursor/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.cursor/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.cursor/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.cursor/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.cursor/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.cursor/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.cursor/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.cursor/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.cursor/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.cursor/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.cursor/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.gemini/skills/citable/SKILL.md +137 -0
- package/dist/universal/.gemini/skills/citable/VERSION +1 -0
- package/dist/universal/.gemini/skills/citable/commands/README.md +36 -0
- package/dist/universal/.gemini/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.gemini/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.gemini/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.gemini/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.gemini/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.gemini/skills/citable/manifest.json +54 -0
- package/dist/universal/.gemini/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.gemini/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.gemini/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.gemini/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.gemini/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.gemini/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.gemini/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.gemini/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.gemini/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.gemini/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.gemini/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.gemini/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.gemini/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.gemini/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.gemini/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.gemini/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.gemini/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.gemini/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.gemini/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.gemini/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.gemini/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.gemini/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.gemini/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.gemini/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.gemini/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.gemini/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.gemini/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.gemini/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.gemini/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.gemini/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.gemini/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.gemini/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.gemini/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.github/skills/citable/SKILL.md +137 -0
- package/dist/universal/.github/skills/citable/VERSION +1 -0
- package/dist/universal/.github/skills/citable/commands/README.md +36 -0
- package/dist/universal/.github/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.github/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.github/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.github/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.github/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.github/skills/citable/manifest.json +54 -0
- package/dist/universal/.github/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.github/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.github/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.github/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.github/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.github/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.github/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.github/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.github/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.github/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.github/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.github/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.github/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.github/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.github/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.github/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.github/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.github/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.github/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.github/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.github/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.github/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.github/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.github/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.github/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.github/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.github/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.github/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.github/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.github/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.github/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.github/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.github/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.kiro/skills/citable/SKILL.md +137 -0
- package/dist/universal/.kiro/skills/citable/VERSION +1 -0
- package/dist/universal/.kiro/skills/citable/commands/README.md +36 -0
- package/dist/universal/.kiro/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.kiro/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.kiro/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.kiro/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.kiro/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.kiro/skills/citable/manifest.json +54 -0
- package/dist/universal/.kiro/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.kiro/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.kiro/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.kiro/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.kiro/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.kiro/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.kiro/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.kiro/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.kiro/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.kiro/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.kiro/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.kiro/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.kiro/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.kiro/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.kiro/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.kiro/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.kiro/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.kiro/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.kiro/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.kiro/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.kiro/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.kiro/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.kiro/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.kiro/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.kiro/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.kiro/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.kiro/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.kiro/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.kiro/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.kiro/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.kiro/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.kiro/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.kiro/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.opencode/skills/citable/SKILL.md +137 -0
- package/dist/universal/.opencode/skills/citable/VERSION +1 -0
- package/dist/universal/.opencode/skills/citable/commands/README.md +36 -0
- package/dist/universal/.opencode/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.opencode/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.opencode/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.opencode/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.opencode/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.opencode/skills/citable/manifest.json +54 -0
- package/dist/universal/.opencode/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.opencode/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.opencode/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.opencode/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.opencode/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.opencode/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.opencode/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.opencode/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.opencode/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.opencode/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.opencode/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.opencode/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.opencode/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.opencode/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.opencode/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.opencode/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.opencode/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.opencode/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.opencode/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.opencode/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.opencode/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.opencode/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.opencode/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.opencode/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.opencode/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.opencode/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.opencode/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.opencode/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.opencode/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.opencode/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.opencode/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.opencode/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.opencode/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.pi/agent/skills/citable/SKILL.md +137 -0
- package/dist/universal/.pi/agent/skills/citable/VERSION +1 -0
- package/dist/universal/.pi/agent/skills/citable/commands/README.md +36 -0
- package/dist/universal/.pi/agent/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.pi/agent/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.pi/agent/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.pi/agent/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.pi/agent/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.pi/agent/skills/citable/manifest.json +54 -0
- package/dist/universal/.pi/agent/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.pi/agent/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.pi/agent/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.pi/agent/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.pi/agent/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.qoder/skills/citable/SKILL.md +137 -0
- package/dist/universal/.qoder/skills/citable/VERSION +1 -0
- package/dist/universal/.qoder/skills/citable/commands/README.md +36 -0
- package/dist/universal/.qoder/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.qoder/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.qoder/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.qoder/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.qoder/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.qoder/skills/citable/manifest.json +54 -0
- package/dist/universal/.qoder/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.qoder/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.qoder/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.qoder/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.qoder/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.qoder/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.qoder/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.qoder/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.qoder/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.qoder/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.qoder/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.qoder/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.qoder/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.qoder/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.qoder/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.qoder/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.qoder/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.qoder/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.qoder/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.qoder/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.qoder/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.qoder/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.qoder/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.qoder/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.qoder/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.qoder/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.qoder/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.qoder/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.qoder/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.qoder/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.qoder/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.qoder/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.qoder/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.rovodev/skills/citable/SKILL.md +137 -0
- package/dist/universal/.rovodev/skills/citable/VERSION +1 -0
- package/dist/universal/.rovodev/skills/citable/commands/README.md +36 -0
- package/dist/universal/.rovodev/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.rovodev/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.rovodev/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.rovodev/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.rovodev/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.rovodev/skills/citable/manifest.json +54 -0
- package/dist/universal/.rovodev/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.rovodev/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.rovodev/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.rovodev/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.rovodev/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.rovodev/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.rovodev/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.rovodev/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.rovodev/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.rovodev/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.rovodev/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.rovodev/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.rovodev/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.rovodev/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.rovodev/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.rovodev/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.rovodev/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.rovodev/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.rovodev/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.rovodev/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.rovodev/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.trae/skills/citable/SKILL.md +137 -0
- package/dist/universal/.trae/skills/citable/VERSION +1 -0
- package/dist/universal/.trae/skills/citable/commands/README.md +36 -0
- package/dist/universal/.trae/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.trae/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.trae/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.trae/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.trae/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.trae/skills/citable/manifest.json +54 -0
- package/dist/universal/.trae/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.trae/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.trae/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.trae/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.trae/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.trae/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.trae/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.trae/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.trae/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.trae/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.trae/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.trae/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.trae/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.trae/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.trae/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.trae/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.trae/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.trae/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.trae/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.trae/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.trae/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.trae/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.trae/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.trae/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.trae/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.trae/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.trae/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.trae/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.trae/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.trae/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.trae/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.trae/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.trae/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/.trae-cn/skills/citable/SKILL.md +137 -0
- package/dist/universal/.trae-cn/skills/citable/VERSION +1 -0
- package/dist/universal/.trae-cn/skills/citable/commands/README.md +36 -0
- package/dist/universal/.trae-cn/skills/citable/commands/ingest.md +44 -0
- package/dist/universal/.trae-cn/skills/citable/commands/measurement.md +49 -0
- package/dist/universal/.trae-cn/skills/citable/commands/optimize-page.md +53 -0
- package/dist/universal/.trae-cn/skills/citable/commands/page-work.md +48 -0
- package/dist/universal/.trae-cn/skills/citable/commands/validate-render.md +24 -0
- package/dist/universal/.trae-cn/skills/citable/manifest.json +54 -0
- package/dist/universal/.trae-cn/skills/citable/policies/crawler-policy-template.md +47 -0
- package/dist/universal/.trae-cn/skills/citable/references/anti-patterns.md +61 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/README.md +30 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/answer-extractability.md +44 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/claim-boundedness.md +36 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/comparison-fairness.md +30 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/conversion-alignment.md +37 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/entity-clarity.md +41 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/evidence-strength.md +53 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/information-gain.md +33 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/intent-alignment.md +41 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/narrative-accuracy.md +46 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/recommendation-eligibility.md +36 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/semantic-clarity.md +42 -0
- package/dist/universal/.trae-cn/skills/citable/rubrics/source-authority.md +37 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/claim.schema.json +53 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/common.defs.json +33 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/competitor.schema.json +28 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/config.schema.json +41 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/crawler.schema.json +33 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/detector-quality.schema.json +39 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/entity.schema.json +39 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/evidence.schema.json +41 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/experiment.schema.json +37 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/finding.schema.json +101 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/page.schema.json +40 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/project.schema.json +29 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/prompt-result.schema.json +37 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/prompt.schema.json +41 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/query.schema.json +43 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/run.schema.json +36 -0
- package/dist/universal/.trae-cn/skills/citable/scripts/README.md +4 -0
- package/dist/universal/.trae-cn/skills/citable/templates/finding-review.md +54 -0
- package/dist/universal/manifest.json +598 -0
- package/package.json +89 -0
- package/schemas/claim.schema.json +53 -0
- package/schemas/common.defs.json +33 -0
- package/schemas/competitor.schema.json +28 -0
- package/schemas/config.schema.json +41 -0
- package/schemas/crawler.schema.json +33 -0
- package/schemas/detector-quality.schema.json +39 -0
- package/schemas/entity.schema.json +39 -0
- package/schemas/evidence.schema.json +41 -0
- package/schemas/experiment.schema.json +37 -0
- package/schemas/finding.schema.json +101 -0
- package/schemas/page.schema.json +40 -0
- package/schemas/project.schema.json +29 -0
- package/schemas/prompt-result.schema.json +37 -0
- package/schemas/prompt.schema.json +41 -0
- package/schemas/query.schema.json +43 -0
- package/schemas/run.schema.json +36 -0
- package/scripts/build-dist.js +143 -0
- package/skill/SKILL.md +137 -0
- package/skill/commands/README.md +36 -0
- package/skill/commands/ingest.md +44 -0
- package/skill/commands/measurement.md +49 -0
- package/skill/commands/optimize-page.md +53 -0
- package/skill/commands/page-work.md +48 -0
- package/skill/commands/validate-render.md +24 -0
- package/skill/policies/crawler-policy-template.md +47 -0
- package/skill/references/anti-patterns.md +61 -0
- package/skill/rubrics/README.md +30 -0
- package/skill/rubrics/answer-extractability.md +44 -0
- package/skill/rubrics/claim-boundedness.md +36 -0
- package/skill/rubrics/comparison-fairness.md +30 -0
- package/skill/rubrics/conversion-alignment.md +37 -0
- package/skill/rubrics/entity-clarity.md +41 -0
- package/skill/rubrics/evidence-strength.md +53 -0
- package/skill/rubrics/information-gain.md +33 -0
- package/skill/rubrics/intent-alignment.md +41 -0
- package/skill/rubrics/narrative-accuracy.md +46 -0
- package/skill/rubrics/recommendation-eligibility.md +36 -0
- package/skill/rubrics/semantic-clarity.md +42 -0
- package/skill/rubrics/source-authority.md +37 -0
- package/skill/templates/finding-review.md +54 -0
- package/src/cli/index.js +135 -0
- package/src/commands/audit.js +111 -0
- package/src/commands/compareSnapshots.js +48 -0
- package/src/commands/context.js +62 -0
- package/src/commands/init.js +111 -0
- package/src/commands/inspect.js +61 -0
- package/src/commands/mapClaims.js +89 -0
- package/src/commands/schemaCmd.js +71 -0
- package/src/commands/substantiate.js +121 -0
- package/src/commands/validate.js +27 -0
- package/src/crawler/fetch.js +31 -0
- package/src/crawler/robots.js +67 -0
- package/src/crawler/sitemap.js +25 -0
- package/src/detectors/ans.js +219 -0
- package/src/detectors/arch.js +154 -0
- package/src/detectors/claim.js +230 -0
- package/src/detectors/crawl.js +143 -0
- package/src/detectors/entity.js +202 -0
- package/src/detectors/evd.js +164 -0
- package/src/detectors/framework.js +137 -0
- package/src/detectors/geoReco.js +218 -0
- package/src/detectors/index.js +50 -0
- package/src/detectors/lifeMeas.js +212 -0
- package/src/detectors/link.js +121 -0
- package/src/detectors/page.js +202 -0
- package/src/detectors/schemaData.js +249 -0
- package/src/detectors/tech.js +397 -0
- package/src/evidence/run.js +88 -0
- package/src/extractor/page.js +125 -0
- package/src/extractor/site.js +175 -0
- package/src/installer/index.js +1117 -0
- package/src/installer/providers.js +164 -0
- package/src/registries/index.js +127 -0
- package/src/reporting/report.js +82 -0
- package/src/shared/io.js +56 -0
- package/src/shared/schemaValidator.js +29 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { defineDetector, indexTargets, pageSubject, entrySubject, sitePageFor } from './framework.js';
|
|
2
|
+
|
|
3
|
+
const D = [];
|
|
4
|
+
|
|
5
|
+
D.push(defineDetector({
|
|
6
|
+
id: 'ARCH-001', name: 'Orphan page', namespace: 'ARCH',
|
|
7
|
+
description: 'An index-target page receives no internal links from any other audited page.',
|
|
8
|
+
discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['site'],
|
|
9
|
+
impact: { retrieval: 'high', ranking: 'medium' },
|
|
10
|
+
applicable_requirement: 'SEO §3 no orphan pages; AEO §9 eliminate orphan pages',
|
|
11
|
+
remediation: 'Link the page from its topic hub and at least one relevant contextual page.',
|
|
12
|
+
verification: 'Rebuild the internal link graph and confirm at least one inbound link.',
|
|
13
|
+
check(ctx) {
|
|
14
|
+
const root = ctx.site.normalize(new URL('/', ctx.site.baseUrl).href);
|
|
15
|
+
return indexTargets(ctx)
|
|
16
|
+
.filter((p) => ctx.site.normalize(p.url) !== root)
|
|
17
|
+
.filter((p) => (ctx.site.inbound.get(ctx.site.normalize(p.url)) || []).length === 0)
|
|
18
|
+
.map((p) => ({
|
|
19
|
+
subject: pageSubject(p),
|
|
20
|
+
summary: 'Page has no inbound internal links (orphan)',
|
|
21
|
+
evidence: ['0 inbound internal links in audited link graph'],
|
|
22
|
+
}));
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
D.push(defineDetector({
|
|
27
|
+
id: 'ARCH-002', name: 'Dead-end page', namespace: 'ARCH',
|
|
28
|
+
description: 'A page has no outbound internal links; users and crawlers cannot continue anywhere.',
|
|
29
|
+
discipline: ['seo'], severity: 'medium', deterministic: true, requires: ['site'],
|
|
30
|
+
impact: { ranking: 'low', conversion: 'medium' },
|
|
31
|
+
applicable_requirement: 'SEO §3 internal links: link upward, laterally, and to the commercial next step',
|
|
32
|
+
remediation: 'Add links to the topic hub, related material, and the relevant commercial next step.',
|
|
33
|
+
verification: 'Confirm at least one outbound internal link.',
|
|
34
|
+
check(ctx) {
|
|
35
|
+
return indexTargets(ctx)
|
|
36
|
+
.filter((p) => p.status === 200 && (ctx.site.outbound.get(ctx.site.normalize(p.url)) || []).length === 0)
|
|
37
|
+
.map((p) => ({
|
|
38
|
+
subject: pageSubject(p),
|
|
39
|
+
summary: 'Page has no outbound internal links (dead end)',
|
|
40
|
+
evidence: ['0 outbound internal links in audited link graph'],
|
|
41
|
+
}));
|
|
42
|
+
},
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
D.push(defineDetector({
|
|
46
|
+
id: 'ARCH-003', name: 'Excessive crawl depth', namespace: 'ARCH',
|
|
47
|
+
description: 'An index-target page requires more than the configured number of clicks from the home page.',
|
|
48
|
+
discipline: ['seo'], severity: 'medium', deterministic: true, requires: ['site'],
|
|
49
|
+
impact: { retrieval: 'medium', ranking: 'medium' },
|
|
50
|
+
applicable_requirement: 'SEO §3 shallow access to important pages',
|
|
51
|
+
remediation: 'Add hub or navigation links to reduce click depth for important pages.',
|
|
52
|
+
verification: 'Recompute shortest-path depth from the home page.',
|
|
53
|
+
check(ctx) {
|
|
54
|
+
const max = ctx.config?.audit?.max_crawl_depth ?? 4;
|
|
55
|
+
return indexTargets(ctx)
|
|
56
|
+
.filter((p) => {
|
|
57
|
+
const d = ctx.site.depth.get(ctx.site.normalize(p.url));
|
|
58
|
+
return d !== undefined && d > max;
|
|
59
|
+
})
|
|
60
|
+
.map((p) => ({
|
|
61
|
+
subject: pageSubject(p),
|
|
62
|
+
summary: `Page is ${ctx.site.depth.get(ctx.site.normalize(p.url))} clicks from home (max ${max})`,
|
|
63
|
+
evidence: [`crawl depth: ${ctx.site.depth.get(ctx.site.normalize(p.url))}`],
|
|
64
|
+
}));
|
|
65
|
+
},
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
D.push(defineDetector({
|
|
69
|
+
id: 'ARCH-004', name: 'Duplicate query target', namespace: 'ARCH',
|
|
70
|
+
description: 'Two or more registry pages target the same query — internal competition for one intent.',
|
|
71
|
+
discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['registries'],
|
|
72
|
+
impact: { ranking: 'high', citation: 'medium' },
|
|
73
|
+
applicable_requirement: 'SEO §3 one canonical URL per primary intent; AEO §9 one clear canonical answer page per question',
|
|
74
|
+
remediation: 'Consolidate the overlapping pages or re-target one of them; record the decision in the page registry.',
|
|
75
|
+
verification: 'Each query_id appears in target_queries of at most one active page.',
|
|
76
|
+
check(ctx) {
|
|
77
|
+
const byQuery = new Map();
|
|
78
|
+
for (const p of ctx.registries.pages?.entries || []) {
|
|
79
|
+
if (p.status === 'retired') continue;
|
|
80
|
+
for (const q of p.target_queries || []) {
|
|
81
|
+
if (!byQuery.has(q)) byQuery.set(q, []);
|
|
82
|
+
byQuery.get(q).push(p.page_id);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return [...byQuery.entries()]
|
|
86
|
+
.filter(([, pages]) => pages.length > 1)
|
|
87
|
+
.map(([q, pages]) => ({
|
|
88
|
+
subject: { type: 'query', identifier: q },
|
|
89
|
+
summary: `Query ${q} is targeted by ${pages.length} pages: ${pages.join(', ')}`,
|
|
90
|
+
evidence: pages.map((p) => `pages/${p} targets ${q}`),
|
|
91
|
+
}));
|
|
92
|
+
},
|
|
93
|
+
}));
|
|
94
|
+
|
|
95
|
+
D.push(defineDetector({
|
|
96
|
+
id: 'ARCH-005', name: 'Overlapping primary intent', namespace: 'ARCH',
|
|
97
|
+
description: 'Two active registry pages declare the same primary intent and share a primary entity.',
|
|
98
|
+
discipline: ['seo'], severity: 'medium', deterministic: true, requires: ['registries'],
|
|
99
|
+
impact: { ranking: 'medium' },
|
|
100
|
+
applicable_requirement: 'SEO §3 consolidated duplicate or overlapping pages; §9 detectors: overlapping intent',
|
|
101
|
+
remediation: 'Differentiate the intents explicitly or consolidate the pages.',
|
|
102
|
+
verification: 'No two active pages share identical primary_intent and a primary entity.',
|
|
103
|
+
check(ctx) {
|
|
104
|
+
const entries = (ctx.registries.pages?.entries || []).filter((p) => p.status !== 'retired' && p.primary_intent);
|
|
105
|
+
const hits = [];
|
|
106
|
+
for (let i = 0; i < entries.length; i++) {
|
|
107
|
+
for (let j = i + 1; j < entries.length; j++) {
|
|
108
|
+
const a = entries[i], b = entries[j];
|
|
109
|
+
if (a.primary_intent === b.primary_intent && (a.primary_entities || []).some((e) => (b.primary_entities || []).includes(e))) {
|
|
110
|
+
hits.push({
|
|
111
|
+
subject: entrySubject('pages', `${a.page_id}+${b.page_id}`),
|
|
112
|
+
summary: `Pages ${a.page_id} and ${b.page_id} share primary intent "${a.primary_intent}" and a primary entity`,
|
|
113
|
+
evidence: [`${a.page_id}: intent=${a.primary_intent}, entities=${(a.primary_entities || []).join('/')}`, `${b.page_id}: intent=${b.primary_intent}, entities=${(b.primary_entities || []).join('/')}`],
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return hits;
|
|
119
|
+
},
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
D.push(defineDetector({
|
|
123
|
+
id: 'ARCH-006', name: 'Page without topic-hub relationship', namespace: 'ARCH',
|
|
124
|
+
description: 'A non-hub content page has no internal link to any hub/category page.',
|
|
125
|
+
discipline: ['seo', 'aeo'], severity: 'low', deterministic: true, requires: ['site', 'registries'],
|
|
126
|
+
impact: { ranking: 'medium' },
|
|
127
|
+
applicable_requirement: 'SEO §3 clear hub-and-spoke relationships; AEO §9 link back to canonical topic hubs',
|
|
128
|
+
remediation: 'Add an upward link from the page to its topic hub.',
|
|
129
|
+
verification: 'Page links to at least one page registered as hub/category.',
|
|
130
|
+
check(ctx) {
|
|
131
|
+
const hubs = new Set(
|
|
132
|
+
(ctx.registries.pages?.entries || [])
|
|
133
|
+
.filter((p) => ['hub', 'category', 'home'].includes(p.page_type))
|
|
134
|
+
.map((p) => ctx.site.normalize(new URL(p.url, ctx.site.baseUrl).href))
|
|
135
|
+
);
|
|
136
|
+
if (hubs.size === 0) return [];
|
|
137
|
+
const hits = [];
|
|
138
|
+
for (const reg of (ctx.registries.pages?.entries || []).filter((p) => !['hub', 'category', 'home', 'legal', 'policy', 'contact'].includes(p.page_type) && p.status !== 'retired')) {
|
|
139
|
+
const page = sitePageFor(ctx, reg);
|
|
140
|
+
if (!page) continue;
|
|
141
|
+
const out = ctx.site.outbound.get(ctx.site.normalize(page.url)) || [];
|
|
142
|
+
if (!out.some((e) => hubs.has(e.to))) {
|
|
143
|
+
hits.push({
|
|
144
|
+
subject: pageSubject(page),
|
|
145
|
+
summary: `Page ${reg.page_id} has no link to any registered topic hub`,
|
|
146
|
+
evidence: [`outbound internal links: ${out.length}; none targets a hub/category/home page`],
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return hits;
|
|
151
|
+
},
|
|
152
|
+
}));
|
|
153
|
+
|
|
154
|
+
export default D;
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { defineDetector, indexTargets, pageSubject, entrySubject } from './framework.js';
|
|
2
|
+
import { isPastDate } from '../shared/io.js';
|
|
3
|
+
|
|
4
|
+
const D = [];
|
|
5
|
+
|
|
6
|
+
const SUPERLATIVE_RX = /\b(the (best|leading|top|most (advanced|powerful|trusted|secure)|fastest|#?1|number one|first and only)|world[- ]class|industry[- ]leading|unmatched|unrivalled|unrivaled|best[- ]in[- ]class)\b/i;
|
|
7
|
+
|
|
8
|
+
function evidenceById(ctx) {
|
|
9
|
+
return new Map((ctx.registries.evidence?.entries || []).map((e) => [e.evidence_id, e]));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
D.push(defineDetector({
|
|
13
|
+
id: 'CLAIM-001', name: 'Verified claim without evidence', namespace: 'CLAIM',
|
|
14
|
+
description: 'A claim is marked verified but references no evidence entries.',
|
|
15
|
+
discipline: ['aeo', 'geo'], severity: 'critical', deterministic: true, requires: ['registries'],
|
|
16
|
+
impact: { legal: 'high', reputational: 'high', citation: 'medium' },
|
|
17
|
+
applicable_requirement: 'Premise 3.5: owned claims require evidence; acceptance criterion 11: claims cannot become verified without evidence',
|
|
18
|
+
remediation: 'Attach verified evidence or downgrade the claim to insufficient_evidence.',
|
|
19
|
+
verification: 'Every verified claim lists at least one evidence id.',
|
|
20
|
+
check(ctx) {
|
|
21
|
+
return (ctx.registries.claims?.entries || [])
|
|
22
|
+
.filter((c) => ['verified', 'verified_narrowed'].includes(c.status) && (c.evidence || []).length === 0)
|
|
23
|
+
.map((c) => ({
|
|
24
|
+
subject: entrySubject('claims', c.claim_id),
|
|
25
|
+
summary: `Claim "${truncate(c.claim)}" is marked ${c.status} with no evidence`,
|
|
26
|
+
evidence: [`claims/${c.claim_id}: status=${c.status}, evidence=[]`],
|
|
27
|
+
}));
|
|
28
|
+
},
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
D.push(defineDetector({
|
|
32
|
+
id: 'CLAIM-002', name: 'Verified claim depends on expired or revoked evidence', namespace: 'CLAIM',
|
|
33
|
+
description: 'All evidence supporting a verified claim is expired, stale, revoked, or inaccessible.',
|
|
34
|
+
discipline: ['aeo', 'geo'], severity: 'high', deterministic: true, requires: ['registries'],
|
|
35
|
+
impact: { legal: 'high', reputational: 'high' },
|
|
36
|
+
applicable_requirement: 'Acceptance criterion 12: expired evidence invalidates dependent claims; §8.5 substantiate outcomes',
|
|
37
|
+
remediation: 'Re-validate with current evidence or downgrade the claim status.',
|
|
38
|
+
verification: 'At least one supporting evidence entry is verified/reviewed and unexpired.',
|
|
39
|
+
check(ctx) {
|
|
40
|
+
const ev = evidenceById(ctx);
|
|
41
|
+
const hits = [];
|
|
42
|
+
for (const c of (ctx.registries.claims?.entries || []).filter((c) => ['verified', 'verified_narrowed'].includes(c.status) && (c.evidence || []).length > 0)) {
|
|
43
|
+
const statuses = (c.evidence || []).map((id) => {
|
|
44
|
+
const e = ev.get(id);
|
|
45
|
+
if (!e) return `${id}: missing`;
|
|
46
|
+
if (['revoked', 'stale', 'inaccessible'].includes(e.verification_status)) return `${id}: ${e.verification_status}`;
|
|
47
|
+
if (isPastDate(e.valid_until, ctx.refDate)) return `${id}: expired ${e.valid_until}`;
|
|
48
|
+
return null;
|
|
49
|
+
});
|
|
50
|
+
if (statuses.every((s) => s !== null)) {
|
|
51
|
+
hits.push({
|
|
52
|
+
subject: entrySubject('claims', c.claim_id),
|
|
53
|
+
summary: `Claim "${truncate(c.claim)}" remains ${c.status} but no supporting evidence is currently valid`,
|
|
54
|
+
evidence: statuses,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return hits;
|
|
59
|
+
},
|
|
60
|
+
}));
|
|
61
|
+
|
|
62
|
+
D.push(defineDetector({
|
|
63
|
+
id: 'CLAIM-003', name: 'Claim active after expiry', namespace: 'CLAIM',
|
|
64
|
+
description: 'A claim has passed its expires date but is not marked expired/retired.',
|
|
65
|
+
discipline: ['aeo', 'geo'], severity: 'high', deterministic: true, requires: ['registries'],
|
|
66
|
+
impact: { legal: 'high' },
|
|
67
|
+
applicable_requirement: 'Detector spec (lifecycle): claim remains active after expiry',
|
|
68
|
+
remediation: 'Re-verify and extend, narrow, or expire the claim.',
|
|
69
|
+
verification: 'No non-expired status on claims past their expires date.',
|
|
70
|
+
check(ctx) {
|
|
71
|
+
return (ctx.registries.claims?.entries || [])
|
|
72
|
+
.filter((c) => isPastDate(c.expires, ctx.refDate) && !['expired', 'retired', 'prohibited'].includes(c.status))
|
|
73
|
+
.map((c) => ({
|
|
74
|
+
subject: entrySubject('claims', c.claim_id),
|
|
75
|
+
summary: `Claim "${truncate(c.claim)}" passed expiry ${c.expires} but status is still "${c.status}"`,
|
|
76
|
+
evidence: [`expires: ${c.expires}; status: ${c.status}`],
|
|
77
|
+
}));
|
|
78
|
+
},
|
|
79
|
+
}));
|
|
80
|
+
|
|
81
|
+
D.push(defineDetector({
|
|
82
|
+
id: 'CLAIM-004', name: 'Quantitative or comparative claim without evidence', namespace: 'CLAIM',
|
|
83
|
+
description: 'A performance or comparative claim (any status except prohibited/retired) has no supporting evidence recorded.',
|
|
84
|
+
discipline: ['seo', 'aeo', 'geo'], severity: 'high', deterministic: true, requires: ['registries'],
|
|
85
|
+
impact: { legal: 'high', reputational: 'medium' },
|
|
86
|
+
applicable_requirement: 'Detector spec: unsupported quantitative claim, comparative claim without evidence; SEO §4 defensible claims',
|
|
87
|
+
remediation: 'Gather methodology-backed evidence, or mark the claim insufficient_evidence and remove it from publication surfaces.',
|
|
88
|
+
verification: 'Performance/comparative claims all reference evidence.',
|
|
89
|
+
check(ctx) {
|
|
90
|
+
return (ctx.registries.claims?.entries || [])
|
|
91
|
+
.filter((c) => ['performance', 'comparative'].includes(c.claim_type) && !['prohibited', 'retired', 'expired'].includes(c.status) && (c.evidence || []).length === 0)
|
|
92
|
+
.map((c) => ({
|
|
93
|
+
subject: entrySubject('claims', c.claim_id),
|
|
94
|
+
summary: `${c.claim_type} claim "${truncate(c.claim)}" has no supporting evidence`,
|
|
95
|
+
evidence: [`claims/${c.claim_id}: claim_type=${c.claim_type}, evidence=[]`],
|
|
96
|
+
}));
|
|
97
|
+
},
|
|
98
|
+
}));
|
|
99
|
+
|
|
100
|
+
D.push(defineDetector({
|
|
101
|
+
id: 'CLAIM-005', name: 'Opinion or aspiration represented as verified fact', namespace: 'CLAIM',
|
|
102
|
+
description: 'An opinion, position, or aspirational claim carries a "verified" status, flattening the claim hierarchy.',
|
|
103
|
+
discipline: ['geo'], severity: 'medium', deterministic: true, requires: ['registries'],
|
|
104
|
+
impact: { representation: 'high', legal: 'medium' },
|
|
105
|
+
applicable_requirement: 'GEO §4 claim hierarchy: engines may flatten distinctions, your content must not; §6.4 prevent opinion/aspiration silently becoming fact',
|
|
106
|
+
remediation: 'Keep opinion/position/aspirational claims in their own status track (active, not verified); label them as positions on publication surfaces.',
|
|
107
|
+
verification: 'No opinion/position/aspirational claim holds a verified status.',
|
|
108
|
+
check(ctx) {
|
|
109
|
+
return (ctx.registries.claims?.entries || [])
|
|
110
|
+
.filter((c) => ['opinion', 'position', 'aspirational'].includes(c.claim_type) && ['verified', 'verified_narrowed'].includes(c.status))
|
|
111
|
+
.map((c) => ({
|
|
112
|
+
subject: entrySubject('claims', c.claim_id),
|
|
113
|
+
summary: `${c.claim_type} claim "${truncate(c.claim)}" is marked "${c.status}" — opinions and aspirations cannot be verified facts`,
|
|
114
|
+
evidence: [`claim_type=${c.claim_type}, status=${c.status}`],
|
|
115
|
+
}));
|
|
116
|
+
},
|
|
117
|
+
}));
|
|
118
|
+
|
|
119
|
+
D.push(defineDetector({
|
|
120
|
+
id: 'CLAIM-006', name: 'Regulated claim without required review', namespace: 'CLAIM',
|
|
121
|
+
description: 'A legal/regulatory, security, or commercial claim has no legal_status assessment.',
|
|
122
|
+
discipline: ['aeo', 'geo'], severity: 'high', deterministic: true, requires: ['registries'],
|
|
123
|
+
impact: { legal: 'high' },
|
|
124
|
+
applicable_requirement: '§8.4: human review required for regulated, contractual, security, financial claims',
|
|
125
|
+
remediation: 'Route the claim to legal/subject-matter review and record legal_status.',
|
|
126
|
+
verification: 'Regulated claim types carry a legal_status other than not_assessed.',
|
|
127
|
+
check(ctx) {
|
|
128
|
+
return (ctx.registries.claims?.entries || [])
|
|
129
|
+
.filter((c) => ['legal_regulatory', 'security', 'commercial'].includes(c.claim_type) && !['prohibited', 'retired'].includes(c.status))
|
|
130
|
+
.filter((c) => !c.legal_status || c.legal_status === 'not_assessed')
|
|
131
|
+
.map((c) => ({
|
|
132
|
+
subject: entrySubject('claims', c.claim_id),
|
|
133
|
+
summary: `${c.claim_type} claim "${truncate(c.claim)}" has no legal/SME review recorded`,
|
|
134
|
+
evidence: [`legal_status: ${c.legal_status ?? 'missing'}`],
|
|
135
|
+
}));
|
|
136
|
+
},
|
|
137
|
+
}));
|
|
138
|
+
|
|
139
|
+
D.push(defineDetector({
|
|
140
|
+
id: 'CLAIM-007', name: 'Unbounded superlative in page text', namespace: 'CLAIM',
|
|
141
|
+
description: 'Page text contains a superlative ("best", "industry-leading", "#1") with no registered comparative claim covering that page.',
|
|
142
|
+
discipline: ['seo', 'aeo', 'geo'], severity: 'medium', deterministic: false, requires: ['site', 'registries'],
|
|
143
|
+
impact: { legal: 'medium', reputational: 'medium', citation: 'low' },
|
|
144
|
+
applicable_requirement: 'Detector spec: superlative without comparison set; SEO §4 no unsupported claims of superiority; anti-pattern: unbounded superlatives',
|
|
145
|
+
false_positive_conditions: ['superlatives inside quotations from attributed third parties'],
|
|
146
|
+
remediation: 'Remove the superlative, or register a comparative claim with a defined comparison set and evidence.',
|
|
147
|
+
verification: 'Superlatives on the page map to registered, evidenced comparative claims.',
|
|
148
|
+
check(ctx) {
|
|
149
|
+
const claims = ctx.registries.claims?.entries || [];
|
|
150
|
+
const hits = [];
|
|
151
|
+
for (const p of indexTargets(ctx)) {
|
|
152
|
+
if (p.status !== 200) continue;
|
|
153
|
+
const m = p.text.match(SUPERLATIVE_RX);
|
|
154
|
+
if (!m) continue;
|
|
155
|
+
const covered = claims.some((c) => c.claim_type === 'comparative' && (c.evidence || []).length > 0 && (c.publication_surfaces || []).some((s) => p.url.includes(s) || s.includes(new URL(p.url).pathname)));
|
|
156
|
+
if (!covered) {
|
|
157
|
+
hits.push({
|
|
158
|
+
subject: pageSubject(p),
|
|
159
|
+
summary: `Superlative "${m[0]}" with no registered comparative claim for this page`,
|
|
160
|
+
evidence: [`matched: "${m[0]}"`, 'no comparative claim lists this page as a publication surface'],
|
|
161
|
+
confidence: 'high',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return hits;
|
|
166
|
+
},
|
|
167
|
+
}));
|
|
168
|
+
|
|
169
|
+
D.push(defineDetector({
|
|
170
|
+
id: 'CLAIM-008', name: 'Published claim missing from page text (surface drift)', namespace: 'CLAIM',
|
|
171
|
+
description: 'A claim lists a page as a publication surface, but the page no longer contains recognizably similar text.',
|
|
172
|
+
discipline: ['geo'], severity: 'low', deterministic: false, requires: ['site', 'registries'],
|
|
173
|
+
impact: { representation: 'medium', maintainability: 'medium' },
|
|
174
|
+
applicable_requirement: '§6.4 publication_surfaces tracking; contradiction management',
|
|
175
|
+
false_positive_conditions: ['legitimate paraphrase beyond token-overlap detection'],
|
|
176
|
+
remediation: 'Update the claim’s publication_surfaces, or restore the claim text on the page.',
|
|
177
|
+
verification: 'Claim key terms appear on each listed surface.',
|
|
178
|
+
check(ctx) {
|
|
179
|
+
const hits = [];
|
|
180
|
+
for (const c of (ctx.registries.claims?.entries || []).filter((c) => (c.publication_surfaces || []).length > 0 && !['retired', 'expired'].includes(c.status))) {
|
|
181
|
+
const keywords = (c.claim.toLowerCase().match(/[a-z][a-z-]{4,}/g) || []).slice(0, 8);
|
|
182
|
+
if (keywords.length < 3) continue;
|
|
183
|
+
for (const surface of c.publication_surfaces) {
|
|
184
|
+
const page = ctx.site.pages.find((p) => p.url.includes(surface) || surface.includes(new URL(p.url).pathname));
|
|
185
|
+
if (!page) continue;
|
|
186
|
+
const text = page.text.toLowerCase();
|
|
187
|
+
const present = keywords.filter((k) => text.includes(k)).length;
|
|
188
|
+
if (present / keywords.length < 0.4) {
|
|
189
|
+
hits.push({
|
|
190
|
+
subject: entrySubject('claims', c.claim_id),
|
|
191
|
+
summary: `Claim "${truncate(c.claim)}" lists ${surface} as a surface but only ${present}/${keywords.length} key terms appear there`,
|
|
192
|
+
evidence: [`surface: ${surface}`, `key-term overlap: ${present}/${keywords.length}`],
|
|
193
|
+
confidence: 'medium',
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return hits;
|
|
199
|
+
},
|
|
200
|
+
}));
|
|
201
|
+
|
|
202
|
+
D.push(defineDetector({
|
|
203
|
+
id: 'CLAIM-009', name: 'Verified claim without semantic support assessment', namespace: 'CLAIM',
|
|
204
|
+
description: 'A claim holds verified status without a recorded assessment that the evidence semantically supports the claim as worded (entailment, not just linkage). Valid evidence references, dates, and owners do not establish that the wording matches what the evidence proves.',
|
|
205
|
+
discipline: ['aeo', 'geo'], severity: 'high', deterministic: true, requires: ['registries'],
|
|
206
|
+
impact: { legal: 'high', representation: 'high' },
|
|
207
|
+
applicable_requirement: 'Premise 3.5 + evidence-strength rubric: verified status requires semantic adequacy review, not only deterministic linkage',
|
|
208
|
+
remediation: 'Run the evidence-strength rubric with a named assessor; record support_assessment (status, assessor, method, supporting passages). Downgrade to review_required until directly_supported or partially_supported.',
|
|
209
|
+
verification: 'Verified claims carry support_assessment.status of directly_supported or partially_supported with a named assessor.',
|
|
210
|
+
check(ctx) {
|
|
211
|
+
return (ctx.registries.claims?.entries || [])
|
|
212
|
+
.filter((c) => ['verified', 'verified_narrowed'].includes(c.status))
|
|
213
|
+
.filter((c) => {
|
|
214
|
+
const sa = c.support_assessment;
|
|
215
|
+
return !sa || !['directly_supported', 'partially_supported'].includes(sa.status) || !sa.assessor;
|
|
216
|
+
})
|
|
217
|
+
.map((c) => ({
|
|
218
|
+
subject: entrySubject('claims', c.claim_id),
|
|
219
|
+
summary: `Verified claim "${truncate(c.claim)}" has no adequate semantic support assessment (${c.support_assessment ? `status: ${c.support_assessment.status}${c.support_assessment.assessor ? '' : ', no assessor'}` : 'absent'})`,
|
|
220
|
+
evidence: [`claims/${c.claim_id}: status=${c.status}; support_assessment=${c.support_assessment ? JSON.stringify({ status: c.support_assessment.status, assessor: c.support_assessment.assessor ?? null }) : 'missing'}`],
|
|
221
|
+
}));
|
|
222
|
+
},
|
|
223
|
+
}));
|
|
224
|
+
|
|
225
|
+
function truncate(s, n = 70) {
|
|
226
|
+
s = String(s).replace(/\s+/g, ' ').trim();
|
|
227
|
+
return s.length > n ? s.slice(0, n) + '…' : s;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export default D;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { defineDetector, entrySubject } from './framework.js';
|
|
2
|
+
import { isAllowed } from '../crawler/robots.js';
|
|
3
|
+
import { isPastDate } from '../shared/io.js';
|
|
4
|
+
|
|
5
|
+
const D = [];
|
|
6
|
+
|
|
7
|
+
D.push(defineDetector({
|
|
8
|
+
id: 'CRAWL-001', name: 'robots.txt contradicts crawler policy decision', namespace: 'CRAWL',
|
|
9
|
+
description: 'The deployed robots.txt outcome for a crawler differs from the decision recorded in the crawler policy registry.',
|
|
10
|
+
discipline: ['seo', 'aeo', 'geo'], severity: 'high', deterministic: true, requires: ['site', 'registries'],
|
|
11
|
+
impact: { retrieval: 'high', legal: 'medium' },
|
|
12
|
+
applicable_requirement: 'GEO §2 crawler-policy matrix; premise 3.3 crawler access managed by crawler and purpose',
|
|
13
|
+
remediation: 'Align robots.txt with the registry decision, or update the registry with a new decision, owner, and rationale.',
|
|
14
|
+
verification: 'Evaluate robots.txt for the crawler user-agent against / and compare with the registry decision.',
|
|
15
|
+
check(ctx) {
|
|
16
|
+
if (!ctx.site?.robots) return [];
|
|
17
|
+
const hits = [];
|
|
18
|
+
for (const c of ctx.registries.crawlers?.entries || []) {
|
|
19
|
+
if (c.decision === 'undecided' || c.status === 'retired') continue;
|
|
20
|
+
const verdict = isAllowed(ctx.site.robots, c.user_agent, '/');
|
|
21
|
+
const deployed = verdict.allowed ? 'allow' : 'block';
|
|
22
|
+
if (deployed !== c.decision) {
|
|
23
|
+
hits.push({
|
|
24
|
+
subject: entrySubject('crawlers', c.crawler_id),
|
|
25
|
+
summary: `Registry decision for ${c.user_agent} is "${c.decision}" but robots.txt effectively "${deployed}s" it`,
|
|
26
|
+
evidence: [`registry decision: ${c.decision} (purpose: ${c.purpose})`, `robots.txt evaluation at /: ${deployed}${verdict.rule ? ` via ${verdict.rule}` : ' (no matching rule)'}`],
|
|
27
|
+
captured: deployed, expected: c.decision,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return hits;
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
D.push(defineDetector({
|
|
36
|
+
id: 'CRAWL-002', name: 'Training-purpose access not decided separately', namespace: 'CRAWL',
|
|
37
|
+
description: 'A vendor has an allow decision for search discovery, but no separate recorded decision for its model-training crawler.',
|
|
38
|
+
discipline: ['geo'], severity: 'medium', deterministic: true, requires: ['registries'],
|
|
39
|
+
impact: { legal: 'high', representation: 'low' },
|
|
40
|
+
applicable_requirement: 'Premise 3.3: crawler access for search is not permission for model training; GEO §2 access layers must not be conflated',
|
|
41
|
+
remediation: 'Record an explicit allow/block decision, owner, and legal rationale for each training-purpose crawler of vendors whose search crawlers are allowed.',
|
|
42
|
+
verification: 'Confirm a crawler registry entry with purpose model_training exists for the vendor.',
|
|
43
|
+
check(ctx) {
|
|
44
|
+
const entries = ctx.registries.crawlers?.entries || [];
|
|
45
|
+
const hits = [];
|
|
46
|
+
const vendors = new Set(entries.filter((e) => ['search_indexing', 'ai_search_discovery'].includes(e.purpose) && e.decision === 'allow').map((e) => e.vendor).filter(Boolean));
|
|
47
|
+
for (const v of vendors) {
|
|
48
|
+
const training = entries.filter((e) => e.vendor === v && e.purpose === 'model_training');
|
|
49
|
+
if (training.length === 0) {
|
|
50
|
+
hits.push({
|
|
51
|
+
subject: { type: 'crawler', identifier: v },
|
|
52
|
+
summary: `Vendor "${v}" has search-crawler access allowed but no recorded model-training decision`,
|
|
53
|
+
evidence: [`crawlers registry contains no purpose=model_training entry for vendor ${v}`],
|
|
54
|
+
});
|
|
55
|
+
} else {
|
|
56
|
+
for (const t of training.filter((t) => t.decision === 'undecided')) {
|
|
57
|
+
hits.push({
|
|
58
|
+
subject: entrySubject('crawlers', t.crawler_id),
|
|
59
|
+
summary: `Model-training decision for ${t.user_agent} is still "undecided" while search access is allowed`,
|
|
60
|
+
evidence: [`entry ${t.crawler_id}: decision=undecided, purpose=model_training`],
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return hits;
|
|
66
|
+
},
|
|
67
|
+
}));
|
|
68
|
+
|
|
69
|
+
D.push(defineDetector({
|
|
70
|
+
id: 'CRAWL-003', name: 'robots.txt missing', namespace: 'CRAWL',
|
|
71
|
+
description: 'No robots.txt was found; crawler access is uncontrolled and sitemap discovery is weakened.',
|
|
72
|
+
discipline: ['seo', 'aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['site'],
|
|
73
|
+
impact: { retrieval: 'medium' },
|
|
74
|
+
applicable_requirement: 'SEO §2 crawl controls; GEO §2 crawler-policy matrix',
|
|
75
|
+
remediation: 'Publish robots.txt implementing the crawler policy registry, including a Sitemap directive.',
|
|
76
|
+
verification: 'Fetch /robots.txt and confirm 200 with expected rules.',
|
|
77
|
+
check(ctx) {
|
|
78
|
+
if (ctx.site.robotsText != null) return [];
|
|
79
|
+
return [{
|
|
80
|
+
subject: { type: 'site', identifier: ctx.site.baseUrl, url: ctx.site.baseUrl },
|
|
81
|
+
summary: 'robots.txt not found',
|
|
82
|
+
evidence: ['no robots.txt in audited output'],
|
|
83
|
+
}];
|
|
84
|
+
},
|
|
85
|
+
}));
|
|
86
|
+
|
|
87
|
+
D.push(defineDetector({
|
|
88
|
+
id: 'CRAWL-004', name: 'robots.txt parse problems', namespace: 'CRAWL',
|
|
89
|
+
description: 'robots.txt contains unparseable or misplaced directives.',
|
|
90
|
+
discipline: ['seo'], severity: 'medium', deterministic: true, requires: ['site'],
|
|
91
|
+
impact: { retrieval: 'medium' },
|
|
92
|
+
applicable_requirement: 'SEO §2 explicit control over robots.txt',
|
|
93
|
+
remediation: 'Fix the malformed lines; regenerate robots.txt from the crawler policy registry.',
|
|
94
|
+
verification: 'Re-parse robots.txt and confirm zero errors.',
|
|
95
|
+
check(ctx) {
|
|
96
|
+
if (!ctx.site.robots || ctx.site.robots.errors.length === 0) return [];
|
|
97
|
+
return [{
|
|
98
|
+
subject: { type: 'site', identifier: `${ctx.site.baseUrl}/robots.txt`, url: `${ctx.site.baseUrl}/robots.txt` },
|
|
99
|
+
summary: `robots.txt has ${ctx.site.robots.errors.length} parse problem(s)`,
|
|
100
|
+
evidence: ctx.site.robots.errors.slice(0, 10),
|
|
101
|
+
}];
|
|
102
|
+
},
|
|
103
|
+
}));
|
|
104
|
+
|
|
105
|
+
D.push(defineDetector({
|
|
106
|
+
id: 'CRAWL-005', name: 'Crawler policy review overdue', namespace: 'CRAWL',
|
|
107
|
+
description: 'A crawler policy decision has passed its next review date.',
|
|
108
|
+
discipline: ['seo', 'aeo', 'geo'], severity: 'low', deterministic: true, requires: ['registries'],
|
|
109
|
+
impact: { legal: 'medium', maintainability: 'medium' },
|
|
110
|
+
applicable_requirement: 'Registry §6.7 review_date/next_review_date; lifecycle premise',
|
|
111
|
+
remediation: 'Re-review the crawler decision against current vendor documentation and update review dates.',
|
|
112
|
+
verification: 'Confirm next_review_date is in the future.',
|
|
113
|
+
check(ctx) {
|
|
114
|
+
return (ctx.registries.crawlers?.entries || [])
|
|
115
|
+
.filter((c) => c.status !== 'retired' && isPastDate(c.next_review_date, ctx.refDate))
|
|
116
|
+
.map((c) => ({
|
|
117
|
+
subject: entrySubject('crawlers', c.crawler_id),
|
|
118
|
+
summary: `Crawler policy for ${c.user_agent} review overdue (due ${c.next_review_date})`,
|
|
119
|
+
evidence: [`next_review_date: ${c.next_review_date}`],
|
|
120
|
+
}));
|
|
121
|
+
},
|
|
122
|
+
}));
|
|
123
|
+
|
|
124
|
+
D.push(defineDetector({
|
|
125
|
+
id: 'CRAWL-006', name: 'Undecided crawler with observed governance relevance', namespace: 'CRAWL',
|
|
126
|
+
description: 'A crawler policy entry remains "undecided" — access is currently whatever robots.txt happens to say, not a governed decision.',
|
|
127
|
+
discipline: ['geo'], severity: 'low', deterministic: true, requires: ['registries'],
|
|
128
|
+
impact: { legal: 'medium' },
|
|
129
|
+
applicable_requirement: 'GEO §2: decision required per crawler and purpose',
|
|
130
|
+
remediation: 'Record an explicit allow/block decision with owner and business and legal rationale.',
|
|
131
|
+
verification: 'Registry entry decision is allow or block.',
|
|
132
|
+
check(ctx) {
|
|
133
|
+
return (ctx.registries.crawlers?.entries || [])
|
|
134
|
+
.filter((c) => c.decision === 'undecided' && c.status === 'active')
|
|
135
|
+
.map((c) => ({
|
|
136
|
+
subject: entrySubject('crawlers', c.crawler_id),
|
|
137
|
+
summary: `No decision recorded for ${c.user_agent} (${c.purpose})`,
|
|
138
|
+
evidence: [`entry ${c.crawler_id}: decision=undecided`],
|
|
139
|
+
}));
|
|
140
|
+
},
|
|
141
|
+
}));
|
|
142
|
+
|
|
143
|
+
export default D;
|