@nebulacomponents/citable 1.12.0 → 1.13.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 +140 -0
- package/README.md +23 -1
- package/dist/universal/.agents/skills/citable/SKILL.md +12 -1
- package/dist/universal/.agents/skills/citable/VERSION +1 -1
- package/dist/universal/.agents/skills/citable/commands/README.md +2 -1
- package/dist/universal/.agents/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.agents/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.agents/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.agents/skills/citable/manifest.json +30 -10
- package/dist/universal/.agents/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.agents/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.agents/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.agents/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.agents/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.agents/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.agents/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.agents/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.agents/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.agents/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.agents/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.agents/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.agents/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.agents/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.agents/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.agents/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.agents/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.agents/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.agents/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.agents/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.agents/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.claude/skills/citable/SKILL.md +12 -1
- package/dist/universal/.claude/skills/citable/VERSION +1 -1
- package/dist/universal/.claude/skills/citable/commands/README.md +2 -1
- package/dist/universal/.claude/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.claude/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.claude/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.claude/skills/citable/manifest.json +30 -10
- package/dist/universal/.claude/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.claude/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.claude/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.claude/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.claude/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.claude/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.claude/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.claude/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.claude/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.claude/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.claude/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.claude/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.claude/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.claude/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.claude/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.claude/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.claude/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.claude/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.claude/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.claude/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.claude/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.cursor/skills/citable/SKILL.md +12 -1
- package/dist/universal/.cursor/skills/citable/VERSION +1 -1
- package/dist/universal/.cursor/skills/citable/commands/README.md +2 -1
- package/dist/universal/.cursor/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.cursor/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.cursor/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.cursor/skills/citable/manifest.json +30 -10
- package/dist/universal/.cursor/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.cursor/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.cursor/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.cursor/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.cursor/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.cursor/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.cursor/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.cursor/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.cursor/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.cursor/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.cursor/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.cursor/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.cursor/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.cursor/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.cursor/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.cursor/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.cursor/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.cursor/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.cursor/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.cursor/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.cursor/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.gemini/skills/citable/SKILL.md +12 -1
- package/dist/universal/.gemini/skills/citable/VERSION +1 -1
- package/dist/universal/.gemini/skills/citable/commands/README.md +2 -1
- package/dist/universal/.gemini/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.gemini/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.gemini/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.gemini/skills/citable/manifest.json +30 -10
- package/dist/universal/.gemini/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.gemini/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.gemini/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.gemini/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.gemini/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.gemini/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.gemini/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.gemini/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.gemini/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.gemini/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.gemini/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.gemini/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.gemini/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.gemini/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.gemini/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.gemini/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.gemini/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.gemini/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.gemini/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.gemini/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.gemini/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.github/skills/citable/SKILL.md +12 -1
- package/dist/universal/.github/skills/citable/VERSION +1 -1
- package/dist/universal/.github/skills/citable/commands/README.md +2 -1
- package/dist/universal/.github/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.github/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.github/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.github/skills/citable/manifest.json +30 -10
- package/dist/universal/.github/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.github/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.github/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.github/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.github/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.github/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.github/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.github/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.github/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.github/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.github/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.github/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.github/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.github/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.github/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.github/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.github/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.github/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.github/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.github/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.github/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.kiro/skills/citable/SKILL.md +12 -1
- package/dist/universal/.kiro/skills/citable/VERSION +1 -1
- package/dist/universal/.kiro/skills/citable/commands/README.md +2 -1
- package/dist/universal/.kiro/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.kiro/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.kiro/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.kiro/skills/citable/manifest.json +30 -10
- package/dist/universal/.kiro/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.kiro/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.kiro/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.kiro/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.kiro/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.kiro/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.kiro/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.kiro/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.kiro/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.kiro/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.kiro/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.kiro/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.kiro/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.kiro/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.kiro/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.kiro/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.kiro/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.kiro/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.kiro/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.kiro/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.kiro/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.opencode/skills/citable/SKILL.md +12 -1
- package/dist/universal/.opencode/skills/citable/VERSION +1 -1
- package/dist/universal/.opencode/skills/citable/commands/README.md +2 -1
- package/dist/universal/.opencode/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.opencode/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.opencode/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.opencode/skills/citable/manifest.json +30 -10
- package/dist/universal/.opencode/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.opencode/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.opencode/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.opencode/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.opencode/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.opencode/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.opencode/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.opencode/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.opencode/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.opencode/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.opencode/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.opencode/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.opencode/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.opencode/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.opencode/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.opencode/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.opencode/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.opencode/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.opencode/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.opencode/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.opencode/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.pi/agent/skills/citable/SKILL.md +12 -1
- package/dist/universal/.pi/agent/skills/citable/VERSION +1 -1
- package/dist/universal/.pi/agent/skills/citable/commands/README.md +2 -1
- package/dist/universal/.pi/agent/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.pi/agent/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.pi/agent/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.pi/agent/skills/citable/manifest.json +30 -10
- package/dist/universal/.pi/agent/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.pi/agent/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.pi/agent/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.pi/agent/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.qoder/skills/citable/SKILL.md +12 -1
- package/dist/universal/.qoder/skills/citable/VERSION +1 -1
- package/dist/universal/.qoder/skills/citable/commands/README.md +2 -1
- package/dist/universal/.qoder/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.qoder/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.qoder/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.qoder/skills/citable/manifest.json +30 -10
- package/dist/universal/.qoder/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.qoder/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.qoder/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.qoder/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.qoder/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.qoder/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.qoder/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.qoder/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.qoder/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.qoder/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.qoder/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.qoder/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.qoder/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.qoder/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.qoder/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.qoder/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.qoder/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.qoder/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.qoder/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.qoder/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.qoder/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.rovodev/skills/citable/SKILL.md +12 -1
- package/dist/universal/.rovodev/skills/citable/VERSION +1 -1
- package/dist/universal/.rovodev/skills/citable/commands/README.md +2 -1
- package/dist/universal/.rovodev/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.rovodev/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.rovodev/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.rovodev/skills/citable/manifest.json +30 -10
- package/dist/universal/.rovodev/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.rovodev/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.rovodev/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.rovodev/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.rovodev/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.rovodev/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.rovodev/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.rovodev/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.rovodev/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.rovodev/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.rovodev/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.rovodev/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.rovodev/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.rovodev/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.rovodev/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.rovodev/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.rovodev/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.rovodev/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.rovodev/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.rovodev/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.rovodev/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.trae/skills/citable/SKILL.md +12 -1
- package/dist/universal/.trae/skills/citable/VERSION +1 -1
- package/dist/universal/.trae/skills/citable/commands/README.md +2 -1
- package/dist/universal/.trae/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.trae/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.trae/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.trae/skills/citable/manifest.json +30 -10
- package/dist/universal/.trae/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.trae/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.trae/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.trae/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.trae/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.trae/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.trae/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.trae/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.trae/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.trae/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.trae/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.trae/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.trae/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.trae/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.trae/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.trae/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.trae/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.trae/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.trae/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.trae/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.trae/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/.trae-cn/skills/citable/SKILL.md +12 -1
- package/dist/universal/.trae-cn/skills/citable/VERSION +1 -1
- package/dist/universal/.trae-cn/skills/citable/commands/README.md +2 -1
- package/dist/universal/.trae-cn/skills/citable/commands/artifact-interchange.md +28 -0
- package/dist/universal/.trae-cn/skills/citable/commands/field-validation.md +71 -0
- package/dist/universal/.trae-cn/skills/citable/commands/observe-and-act.md +5 -0
- package/dist/universal/.trae-cn/skills/citable/manifest.json +30 -10
- package/dist/universal/.trae-cn/skills/citable/references/aeo-geo-validation.md +1 -1
- package/dist/universal/.trae-cn/skills/citable/references/capability-boundaries.md +1 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/artifact-interchange.schema.json +58 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/assumption.schema.json +119 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/customer-outcome.schema.json +119 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/decision.schema.json +154 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/deployment-receipt.schema.json +51 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/initiative.schema.json +185 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/kpi.schema.json +108 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/observation.schema.json +1 -1
- package/dist/universal/.trae-cn/skills/citable/schemas/release-manifest.schema.json +74 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/release-state.schema.json +40 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/risk.schema.json +172 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/scenario.schema.json +165 -0
- package/dist/universal/.trae-cn/skills/citable/schemas/variance.schema.json +112 -0
- package/dist/universal/manifest.json +363 -123
- package/package.json +4 -1
- package/release/surfaces.json +21 -0
- package/schemas/acceptance-corpus.schema.json +168 -0
- package/schemas/acceptance-run-context.schema.json +17 -0
- package/schemas/acceptance-run-receipt.schema.json +88 -0
- package/schemas/artifact-interchange.schema.json +58 -0
- package/schemas/assumption.schema.json +119 -0
- package/schemas/browser-evidence-plan.schema.json +76 -0
- package/schemas/corpus-publication-receipt.schema.json +24 -0
- package/schemas/customer-outcome.schema.json +119 -0
- package/schemas/decision.schema.json +154 -0
- package/schemas/deployment-receipt.schema.json +51 -0
- package/schemas/field-validation-metrics.schema.json +15 -0
- package/schemas/initiative.schema.json +185 -0
- package/schemas/kpi.schema.json +108 -0
- package/schemas/observation.schema.json +1 -1
- package/schemas/release-manifest.schema.json +74 -0
- package/schemas/release-state.schema.json +40 -0
- package/schemas/risk.schema.json +172 -0
- package/schemas/scenario.schema.json +165 -0
- package/schemas/variance.schema.json +112 -0
- package/scripts/release-governance.js +123 -0
- package/skill/SKILL.md +12 -1
- package/skill/commands/README.md +2 -1
- package/skill/commands/artifact-interchange.md +28 -0
- package/skill/commands/field-validation.md +71 -0
- package/skill/commands/observe-and-act.md +5 -0
- package/skill/references/aeo-geo-validation.md +1 -1
- package/skill/references/capability-boundaries.md +1 -0
- package/src/acceptance/reproducibility.js +180 -0
- package/src/artifacts/interchange.js +179 -0
- package/src/cli/index.js +143 -4
- package/src/commands/assumptionAudit.js +111 -0
- package/src/commands/audit.js +6 -0
- package/src/commands/boardReport.js +251 -0
- package/src/commands/competitiveIntel.js +124 -0
- package/src/commands/corpus.js +322 -0
- package/src/commands/decisionMemo.js +202 -0
- package/src/commands/executive.js +167 -0
- package/src/commands/executiveReview.js +206 -0
- package/src/commands/init.js +14 -1
- package/src/commands/kpi.js +86 -0
- package/src/commands/monitor.js +9 -0
- package/src/commands/observe.js +84 -2
- package/src/commands/outcomes.js +113 -0
- package/src/commands/prioritize.js +108 -0
- package/src/commands/risk.js +104 -0
- package/src/commands/scenario.js +98 -0
- package/src/commands/variance.js +102 -0
- package/src/detectors/framework.js +37 -0
- package/src/detectors/page.js +10 -10
- package/src/detectors/tech.js +5 -3
- package/src/extractor/site.js +21 -6
- package/src/observations/browserJourney.js +167 -0
- package/src/observations/media.js +8 -1
- package/src/registries/index.js +107 -6
- package/src/release/governance.js +331 -0
- package/src/shared/asOf.js +18 -0
package/src/detectors/tech.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineDetector, indexTargets, registryPageFor, pageSubject, safePath } from './framework.js';
|
|
1
|
+
import { defineDetector, hasHtmlDocumentMarkup, indexTargets, isHtmlDocument, isHtmlDocumentUrl, registryPageFor, pageSubject, safePath } from './framework.js';
|
|
2
2
|
import { isAllowed } from '../crawler/robots.js';
|
|
3
3
|
|
|
4
4
|
const D = [];
|
|
@@ -177,7 +177,9 @@ D.push(defineDetector({
|
|
|
177
177
|
for (const sm of ctx.site.sitemaps) {
|
|
178
178
|
for (const u of sm.parsed.urls) {
|
|
179
179
|
const page = ctx.site.byUrl.get(ctx.site.normalize(u.loc));
|
|
180
|
-
if (!page) {
|
|
180
|
+
if (!page && ctx.site.mode === 'url' && ctx.site.crawl?.truncated) {
|
|
181
|
+
continue;
|
|
182
|
+
} else if (!page) {
|
|
181
183
|
hits.push({
|
|
182
184
|
subject: { type: 'url', identifier: u.loc, url: u.loc, source_location: sm.source },
|
|
183
185
|
summary: 'Sitemap URL not present in audited output',
|
|
@@ -227,7 +229,7 @@ D.push(defineDetector({
|
|
|
227
229
|
verification: 'Inspect the Content-Type response header.',
|
|
228
230
|
check(ctx) {
|
|
229
231
|
return indexTargets(ctx)
|
|
230
|
-
.filter((p) => p.status === 200 && p.contentType &&
|
|
232
|
+
.filter((p) => p.status === 200 && p.contentType && (isHtmlDocumentUrl(p.url) || hasHtmlDocumentMarkup(p)) && !isHtmlDocument(p))
|
|
231
233
|
.map((p) => ({
|
|
232
234
|
subject: pageSubject(p),
|
|
233
235
|
summary: `HTML page served with Content-Type "${p.contentType}"`,
|
package/src/extractor/site.js
CHANGED
|
@@ -59,6 +59,7 @@ export function buildSiteFromDir(dir, { baseUrl = 'https://example.test' } = {})
|
|
|
59
59
|
export async function buildSiteFromUrl(startUrl, {
|
|
60
60
|
maxPages = 50, userAgent, pageMaxBytes = 5 * 1024 * 1024,
|
|
61
61
|
robotsMaxBytes = 512 * 1024, sitemapMaxBytes = 5 * 1024 * 1024,
|
|
62
|
+
fetcher = fetchUrl,
|
|
62
63
|
} = {}) {
|
|
63
64
|
const origin = new URL(startUrl).origin;
|
|
64
65
|
const seen = new Set();
|
|
@@ -71,7 +72,7 @@ export async function buildSiteFromUrl(startUrl, {
|
|
|
71
72
|
if (seen.has(key)) continue;
|
|
72
73
|
seen.add(key);
|
|
73
74
|
try {
|
|
74
|
-
const res = await
|
|
75
|
+
const res = await fetcher(url, { userAgent, maxBodyBytes: pageMaxBytes });
|
|
75
76
|
const page = extractPage({
|
|
76
77
|
url: res.url, html: res.body, status: res.status, headers: res.headers, redirectChain: res.redirectChain,
|
|
77
78
|
});
|
|
@@ -81,7 +82,8 @@ export async function buildSiteFromUrl(startUrl, {
|
|
|
81
82
|
for (const l of page.links) {
|
|
82
83
|
try {
|
|
83
84
|
const u = new URL(l.href, res.url);
|
|
84
|
-
|
|
85
|
+
u.hash = '';
|
|
86
|
+
if (u.origin === origin && !isProviderUtilityPath(u.pathname) && !seen.has(u.href)) queue.push(u.href);
|
|
85
87
|
} catch { /* unresolvable href — surfaced by LINK detectors */ }
|
|
86
88
|
}
|
|
87
89
|
}
|
|
@@ -92,7 +94,7 @@ export async function buildSiteFromUrl(startUrl, {
|
|
|
92
94
|
let robotsText = null;
|
|
93
95
|
const sitemaps = [];
|
|
94
96
|
try {
|
|
95
|
-
const r = await
|
|
97
|
+
const r = await fetcher(new URL('/robots.txt', origin).href, { userAgent, maxBodyBytes: robotsMaxBytes });
|
|
96
98
|
if (r.status === 200) robotsText = r.body;
|
|
97
99
|
} catch { /* recorded as missing robots */ }
|
|
98
100
|
const smUrls = robotsText ? parseRobots(robotsText).sitemaps : [new URL('/sitemap.xml', origin).href];
|
|
@@ -103,16 +105,24 @@ export async function buildSiteFromUrl(startUrl, {
|
|
|
103
105
|
errors.push(`${sitemapUrl.href}: sitemap URL leaves audited origin`);
|
|
104
106
|
continue;
|
|
105
107
|
}
|
|
106
|
-
const r = await
|
|
108
|
+
const r = await fetcher(sitemapUrl.href, { userAgent, maxBodyBytes: sitemapMaxBytes });
|
|
107
109
|
if (r.status === 200) sitemaps.push({ source: sm, parsed: parseSitemap(r.body) });
|
|
108
110
|
} catch { /* absence handled by TECH detectors */ }
|
|
109
111
|
}
|
|
110
|
-
const
|
|
112
|
+
const pendingUrls = [...new Set(queue.map((url) => url.replace(/#.*$/, '')).filter((url) => !seen.has(url)))];
|
|
113
|
+
const crawl = {
|
|
114
|
+
maxPages,
|
|
115
|
+
pagesFetched: pages.length,
|
|
116
|
+
truncated: pages.length >= maxPages && pendingUrls.length > 0,
|
|
117
|
+
pendingUrlCount: pendingUrls.length,
|
|
118
|
+
pendingUrls,
|
|
119
|
+
};
|
|
120
|
+
const site = assembleSite({ baseUrl: origin, pages, robotsText, sitemaps, transport: {}, mode: 'url', location: startUrl, crawl });
|
|
111
121
|
site.fetchErrors = errors;
|
|
112
122
|
return site;
|
|
113
123
|
}
|
|
114
124
|
|
|
115
|
-
function assembleSite({ baseUrl, pages, robotsText, sitemaps, transport, mode, location }) {
|
|
125
|
+
function assembleSite({ baseUrl, pages, robotsText, sitemaps, transport, mode, location, crawl = null }) {
|
|
116
126
|
const byUrl = new Map();
|
|
117
127
|
for (const p of pages) byUrl.set(normalize(p.url), p);
|
|
118
128
|
|
|
@@ -168,9 +178,14 @@ function assembleSite({ baseUrl, pages, robotsText, sitemaps, transport, mode, l
|
|
|
168
178
|
outbound,
|
|
169
179
|
depth,
|
|
170
180
|
normalize,
|
|
181
|
+
crawl,
|
|
171
182
|
};
|
|
172
183
|
}
|
|
173
184
|
|
|
185
|
+
function isProviderUtilityPath(pathname) {
|
|
186
|
+
return pathname === '/cdn-cgi' || pathname.startsWith('/cdn-cgi/');
|
|
187
|
+
}
|
|
188
|
+
|
|
174
189
|
export function normalize(url) {
|
|
175
190
|
try {
|
|
176
191
|
const u = new URL(url);
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { envelope, observationRun, readInput } from './common.js';
|
|
2
|
+
import { fetchUrl } from '../crawler/fetch.js';
|
|
3
|
+
import { sha256 } from '../shared/io.js';
|
|
4
|
+
import { validateAgainst } from '../shared/schemaValidator.js';
|
|
5
|
+
|
|
6
|
+
async function executeStep(page, step) {
|
|
7
|
+
const locator = step.locator ? page.locator(step.locator).first() : null;
|
|
8
|
+
if (step.action === 'navigate') await page.goto(step.url, { waitUntil: 'networkidle' });
|
|
9
|
+
else if (step.action === 'click') await locator.click();
|
|
10
|
+
else if (step.action === 'fill') {
|
|
11
|
+
const value = process.env[step.value_env];
|
|
12
|
+
if (value == null) throw new Error(`environment input ${step.value_env} is unavailable`);
|
|
13
|
+
await locator.fill(value);
|
|
14
|
+
} else if (step.action === 'select_option') {
|
|
15
|
+
const value = process.env[step.value_env];
|
|
16
|
+
if (value == null) throw new Error(`environment input ${step.value_env} is unavailable`);
|
|
17
|
+
await locator.selectOption(value);
|
|
18
|
+
} else if (step.action === 'check') await locator.check();
|
|
19
|
+
else if (step.action === 'press') await locator.press(step.key);
|
|
20
|
+
else if (step.action === 'wait_for') await locator.waitFor({ state: 'visible' });
|
|
21
|
+
else if (step.action === 'assert_visible' && !(await locator.isVisible())) throw new Error(`locator is not visible: ${step.locator}`);
|
|
22
|
+
else if (step.action === 'scroll') await locator.scrollIntoViewIfNeeded();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function playwrightCapture(profile, plan, playwright) {
|
|
26
|
+
if (profile.authentication_state !== 'anonymous') throw new Error(`authentication state ${profile.authentication_state} requires a disclosed custom adapter`);
|
|
27
|
+
const browserType = playwright[profile.browser.engine];
|
|
28
|
+
if (!browserType) throw new Error(`Playwright engine ${profile.browser.engine} is unavailable`);
|
|
29
|
+
const browser = await browserType.launch({ headless: true });
|
|
30
|
+
try {
|
|
31
|
+
const context = await browser.newContext({
|
|
32
|
+
viewport: profile.device.viewport,
|
|
33
|
+
isMobile: profile.device.is_mobile,
|
|
34
|
+
javaScriptEnabled: profile.javascript_enabled,
|
|
35
|
+
locale: profile.locale,
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
const page = await context.newPage();
|
|
39
|
+
const consoleErrors = [], networkFailures = [], steps = [], stepScreenshots = {};
|
|
40
|
+
page.on('console', (message) => { if (message.type() === 'error') consoleErrors.push(message.text()); });
|
|
41
|
+
page.on('requestfailed', (request) => networkFailures.push({ url: request.url(), error: request.failure()?.errorText || 'unknown' }));
|
|
42
|
+
const response = await page.goto(plan.target, { waitUntil: 'networkidle' });
|
|
43
|
+
for (const step of profile.steps) {
|
|
44
|
+
const record = { step_id: step.step_id, action: step.action, status: 'completed', failure: null, screenshot_ref: null };
|
|
45
|
+
try {
|
|
46
|
+
await executeStep(page, step);
|
|
47
|
+
if (step.capture_screenshot) {
|
|
48
|
+
record.screenshot_ref = `journeys/${profile.profile_id}/steps/${step.step_id}.png`;
|
|
49
|
+
stepScreenshots[record.screenshot_ref] = await page.screenshot({ fullPage: true });
|
|
50
|
+
}
|
|
51
|
+
} catch (error) {
|
|
52
|
+
record.status = 'failed';
|
|
53
|
+
record.failure = error.message;
|
|
54
|
+
steps.push(record);
|
|
55
|
+
if (step.required) throw Object.assign(new Error(`required step ${step.step_id} failed: ${error.message}`), { steps, stepScreenshots });
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
steps.push(record);
|
|
59
|
+
}
|
|
60
|
+
const dom = await page.content();
|
|
61
|
+
const text = await page.locator('body').innerText();
|
|
62
|
+
const accessibilityTree = typeof page.locator('body').ariaSnapshot === 'function' ? await page.locator('body').ariaSnapshot() : null;
|
|
63
|
+
return {
|
|
64
|
+
final_url: page.url(), status: response?.status() ?? null, browser_version: browser.version(),
|
|
65
|
+
dom, text, accessibility_tree: accessibilityTree, screenshot: await page.screenshot({ fullPage: true }),
|
|
66
|
+
console_errors: consoleErrors, network_failures: networkFailures, steps, step_screenshots: stepScreenshots,
|
|
67
|
+
};
|
|
68
|
+
} finally {
|
|
69
|
+
await context.close();
|
|
70
|
+
}
|
|
71
|
+
} finally {
|
|
72
|
+
await browser.close();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function observeBrowserPlan(root, options) {
|
|
77
|
+
const input = readInput(options.input);
|
|
78
|
+
const plan = input.value;
|
|
79
|
+
const check = validateAgainst('browser-evidence-plan.schema.json', plan);
|
|
80
|
+
if (!check.valid) throw new Error(`browser evidence plan violates contract: ${check.errors.join('; ')}`);
|
|
81
|
+
if (options.target && options.target !== plan.target) throw new Error('browser evidence target differs from the plan target');
|
|
82
|
+
const profileIds = plan.profiles.map((item) => item.profile_id);
|
|
83
|
+
if (new Set(profileIds).size !== profileIds.length) throw new Error('browser evidence plan contains duplicate profile ids');
|
|
84
|
+
const targetOrigin = new URL(plan.target).origin;
|
|
85
|
+
for (const profile of plan.profiles) {
|
|
86
|
+
const stepIds = profile.steps.map((item) => item.step_id);
|
|
87
|
+
if (new Set(stepIds).size !== stepIds.length) throw new Error(`${profile.profile_id}: duplicate journey step ids`);
|
|
88
|
+
for (const step of profile.steps) {
|
|
89
|
+
if (step.action === 'navigate') {
|
|
90
|
+
if (!step.url) throw new Error(`${profile.profile_id}/${step.step_id}: navigate requires url`);
|
|
91
|
+
if (new URL(step.url).origin !== targetOrigin) throw new Error(`${profile.profile_id}/${step.step_id}: cross-origin navigation is not allowed`);
|
|
92
|
+
} else if (!step.locator) throw new Error(`${profile.profile_id}/${step.step_id}: ${step.action} requires locator`);
|
|
93
|
+
if (['fill', 'select_option'].includes(step.action) && !step.value_env) throw new Error(`${profile.profile_id}/${step.step_id}: ${step.action} requires value_env`);
|
|
94
|
+
if (step.action === 'press' && !step.key) throw new Error(`${profile.profile_id}/${step.step_id}: press requires key`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let playwright = options.playwright;
|
|
99
|
+
if (!options.captureJourney && !playwright) {
|
|
100
|
+
try { playwright = await import('playwright'); } catch {
|
|
101
|
+
const item = envelope('browser_journey', { plan_id: plan.plan_id, target: plan.target }, { method: 'browser', source: 'playwright', state: 'not_evidenced', confidence: 'unknown', limitations: ['Optional Playwright dependency is not installed.'] });
|
|
102
|
+
return observationRun(root, 'observe render', plan.target, [item], { rawInputs: { browser_evidence_plan: input.raw }, incomplete: ['Cross-browser journey collection unavailable: install Playwright and browser engines.'] });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const initial = await (options.fetchUrl || fetchUrl)(plan.target, { maxRetries: 1 });
|
|
107
|
+
const observations = [], incomplete = [], artifacts = {
|
|
108
|
+
'initial/response.html': initial.body,
|
|
109
|
+
'initial/headers.json': initial.headers || {},
|
|
110
|
+
};
|
|
111
|
+
for (const profile of plan.profiles) {
|
|
112
|
+
const prefix = `journeys/${profile.profile_id}`;
|
|
113
|
+
try {
|
|
114
|
+
const capture = options.captureJourney
|
|
115
|
+
? await options.captureJourney(profile, plan)
|
|
116
|
+
: await playwrightCapture(profile, plan, playwright);
|
|
117
|
+
if (!capture || typeof capture.dom !== 'string' || typeof capture.text !== 'string' || typeof capture.browser_version !== 'string' || capture.screenshot == null) {
|
|
118
|
+
throw new Error('browser adapter returned an incomplete capture contract');
|
|
119
|
+
}
|
|
120
|
+
const refs = {
|
|
121
|
+
raw_response: 'initial/response.html',
|
|
122
|
+
rendered_dom: `${prefix}/dom.html`,
|
|
123
|
+
rendered_text: `${prefix}/text.txt`,
|
|
124
|
+
accessibility_tree: capture.accessibility_tree == null ? null : `${prefix}/accessibility-tree.txt`,
|
|
125
|
+
screenshot: `${prefix}/final.png`,
|
|
126
|
+
failures: `${prefix}/failures.json`,
|
|
127
|
+
interactions: `${prefix}/steps.json`,
|
|
128
|
+
};
|
|
129
|
+
artifacts[refs.rendered_dom] = capture.dom;
|
|
130
|
+
artifacts[refs.rendered_text] = capture.text;
|
|
131
|
+
if (refs.accessibility_tree) artifacts[refs.accessibility_tree] = capture.accessibility_tree;
|
|
132
|
+
artifacts[refs.screenshot] = capture.screenshot;
|
|
133
|
+
artifacts[refs.failures] = { console_errors: capture.console_errors || [], network_failures: capture.network_failures || [] };
|
|
134
|
+
artifacts[refs.interactions] = capture.steps || [];
|
|
135
|
+
for (const [name, value] of Object.entries(capture.step_screenshots || {})) {
|
|
136
|
+
if (!name.startsWith(`${prefix}/steps/`) || name.includes('..')) throw new Error(`browser adapter returned unsafe artifact path: ${name}`);
|
|
137
|
+
artifacts[name] = value;
|
|
138
|
+
}
|
|
139
|
+
const versionMatches = profile.browser.expected_version == null || profile.browser.expected_version === capture.browser_version;
|
|
140
|
+
const data = {
|
|
141
|
+
plan_id: plan.plan_id, target: plan.target, profile_id: profile.profile_id,
|
|
142
|
+
browser: { ...profile.browser, observed_version: capture.browser_version, version_matches_expectation: versionMatches },
|
|
143
|
+
device: profile.device, javascript_enabled: profile.javascript_enabled, locale: profile.locale,
|
|
144
|
+
consent_state: profile.consent_state, authentication_state: profile.authentication_state,
|
|
145
|
+
final_url: capture.final_url, status: capture.status, dom_hash: sha256(capture.dom), text_hash: sha256(capture.text),
|
|
146
|
+
steps: capture.steps || [], artifact_refs: refs,
|
|
147
|
+
interpretation_boundary: 'Observed differences do not establish semantic, retrieval, citation, ranking, or business impact.',
|
|
148
|
+
};
|
|
149
|
+
const limitations = [...plan.limitations, ...profile.limitations];
|
|
150
|
+
if (!versionMatches) limitations.push('Observed browser version differs from the planned version.');
|
|
151
|
+
observations.push(envelope('browser_journey', data, { method: 'browser', source: `playwright/${profile.browser.engine}`, raw: capture.dom, limitations }));
|
|
152
|
+
} catch (error) {
|
|
153
|
+
incomplete.push(`${profile.profile_id}: ${error.message}`);
|
|
154
|
+
const failureRef = `${prefix}/failure.json`;
|
|
155
|
+
artifacts[failureRef] = { profile_id: profile.profile_id, error: error.message, completed_steps: error.steps || [] };
|
|
156
|
+
for (const [name, value] of Object.entries(error.stepScreenshots || {})) artifacts[name] = value;
|
|
157
|
+
observations.push(envelope('browser_journey', {
|
|
158
|
+
plan_id: plan.plan_id, target: plan.target, profile_id: profile.profile_id, browser: profile.browser,
|
|
159
|
+
device: profile.device, javascript_enabled: profile.javascript_enabled, locale: profile.locale,
|
|
160
|
+
consent_state: profile.consent_state, authentication_state: profile.authentication_state,
|
|
161
|
+
steps: error.steps || [], artifact_refs: { failure: failureRef },
|
|
162
|
+
interpretation_boundary: 'Profile failure does not invalidate successful profiles or establish semantic impact.',
|
|
163
|
+
}, { method: 'browser', source: `playwright/${profile.browser.engine}`, state: 'failed', confidence: 'confirmed', raw: error.message, limitations: [...plan.limitations, ...profile.limitations, error.message] }));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return observationRun(root, 'observe render', plan.target, observations, { rawInputs: { browser_evidence_plan: input.raw }, incomplete, artifacts });
|
|
167
|
+
}
|
|
@@ -29,7 +29,14 @@ async function pdfEvidence(item, file, artifacts) {
|
|
|
29
29
|
|
|
30
30
|
function transcriptEvidence(item, file, artifacts) {
|
|
31
31
|
const raw = fs.readFileSync(file, 'utf8');
|
|
32
|
-
const cues = raw.split(/\r?\n\r?\n/).map((block) => {
|
|
32
|
+
const cues = raw.split(/\r?\n\r?\n/).map((block) => {
|
|
33
|
+
const lines = block.split(/\r?\n/).filter(Boolean);
|
|
34
|
+
const timing = lines.find((line) => line.includes('-->')) || null;
|
|
35
|
+
const fragment = parse(lines.filter((line) => line !== 'WEBVTT' && line !== timing && !/^\d+$/.test(line)).join(' '));
|
|
36
|
+
for (const node of fragment.querySelectorAll('script,style')) node.remove();
|
|
37
|
+
const text = fragment.textContent.replace(/\s+/g, ' ').trim();
|
|
38
|
+
return text ? { timing, text } : null;
|
|
39
|
+
}).filter(Boolean);
|
|
33
40
|
const text = cues.map((cue) => cue.text).join(' ');
|
|
34
41
|
artifacts[`media/${item.media_id}/transcript.txt`] = text;
|
|
35
42
|
return envelope('media_transcript', { media_id: item.media_id, source_url: item.source_url, page_url: item.page_url, claim_ids: item.claim_ids, permission_status: item.permission_status, language: item.language || null, published_at: item.published_at || null, cues, word_count: text ? text.split(/\s+/).length : 0 }, { method: 'owner_import', source: file, raw, limitations: ['Speaker identity, transcription accuracy, timing accuracy, and media parity require human verification.', 'Transcript ingestion does not establish that linked claims are supported.'] });
|
package/src/registries/index.js
CHANGED
|
@@ -23,6 +23,16 @@ export const REGISTRY_SPECS = [
|
|
|
23
23
|
{ file: 'review-items.yaml', kind: 'review_items', schema: 'review-item.schema.json', idField: 'review_item_id' },
|
|
24
24
|
{ file: 'sampling-plans.yaml', kind: 'sampling_plans', schema: 'sampling-plan.schema.json', idField: 'sampling_plan_id' },
|
|
25
25
|
{ file: 'schedules.yaml', kind: 'schedules', schema: 'schedule.schema.json', idField: 'schedule_id' },
|
|
26
|
+
// Executive reporting suite — governed inputs (Phase 1)
|
|
27
|
+
{ file: 'kpis.yaml', kind: 'kpis', schema: 'kpi.schema.json', idField: 'metric_id' },
|
|
28
|
+
{ file: 'variances.yaml', kind: 'variances', schema: 'variance.schema.json', idField: 'variance_id' },
|
|
29
|
+
{ file: 'customer-outcomes.yaml', kind: 'customer-outcomes', schema: 'customer-outcome.schema.json', idField: 'outcome_id' },
|
|
30
|
+
{ file: 'risks.yaml', kind: 'risks', schema: 'risk.schema.json', idField: 'risk_id' },
|
|
31
|
+
// Executive reporting suite — decision support (Phase 2)
|
|
32
|
+
{ file: 'decisions.yaml', kind: 'decisions', schema: 'decision.schema.json', idField: 'decision_id' },
|
|
33
|
+
{ file: 'assumptions.yaml', kind: 'assumptions', schema: 'assumption.schema.json', idField: 'assumption_id' },
|
|
34
|
+
{ file: 'scenarios.yaml', kind: 'scenarios', schema: 'scenario.schema.json', idField: 'scenario_id' },
|
|
35
|
+
{ file: 'initiatives.yaml', kind: 'initiatives', schema: 'initiative.schema.json', idField: 'initiative_id' },
|
|
26
36
|
];
|
|
27
37
|
|
|
28
38
|
export function contextDir(root) {
|
|
@@ -33,6 +43,31 @@ export function emptyRegistry(kind) {
|
|
|
33
43
|
return { version: 1, kind, updated: nowIso(), entries: [] };
|
|
34
44
|
}
|
|
35
45
|
|
|
46
|
+
const LOAD_PROBLEMS = Symbol('registryLoadProblems');
|
|
47
|
+
|
|
48
|
+
/** Read one registry without allowing malformed YAML to crash a command. */
|
|
49
|
+
export function loadRegistryFile(file, kind) {
|
|
50
|
+
let data = emptyRegistry(kind);
|
|
51
|
+
const problems = [];
|
|
52
|
+
if (fs.existsSync(file)) {
|
|
53
|
+
try {
|
|
54
|
+
data = readYaml(file) ?? emptyRegistry(kind);
|
|
55
|
+
if (typeof data !== 'object' || data === null || !Array.isArray(data.entries)) {
|
|
56
|
+
problems.push(`${path.basename(file)}: YAML does not match expected registry shape`);
|
|
57
|
+
data = emptyRegistry(kind);
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
problems.push(`${path.basename(file)}: YAML parse failure: ${error.message}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
Object.defineProperty(data, LOAD_PROBLEMS, { value: problems, enumerable: false });
|
|
64
|
+
return data;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function registryLoadProblems(data) {
|
|
68
|
+
return data?.[LOAD_PROBLEMS] ?? [];
|
|
69
|
+
}
|
|
70
|
+
|
|
36
71
|
/** Load all registries under <root>/.citable. Missing files load as empty. */
|
|
37
72
|
export function loadRegistries(root) {
|
|
38
73
|
const dir = contextDir(root);
|
|
@@ -63,13 +98,21 @@ export function checkReferentialIntegrity(registries) {
|
|
|
63
98
|
const problems = [];
|
|
64
99
|
const ids = {};
|
|
65
100
|
for (const spec of REGISTRY_SPECS) {
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
101
|
+
const registry = registries[spec.kind] ?? emptyRegistry(spec.kind);
|
|
102
|
+
const schemaValid = (registry.entries || []).filter((entry) =>
|
|
103
|
+
validateAgainst(spec.schema, { ...registry, entries: [entry] }).valid);
|
|
104
|
+
const counts = new Map();
|
|
105
|
+
for (const entry of schemaValid) {
|
|
106
|
+
const id = entry[spec.idField];
|
|
107
|
+
counts.set(id, (counts.get(id) ?? 0) + 1);
|
|
72
108
|
}
|
|
109
|
+
for (const [id, count] of counts) {
|
|
110
|
+
if (count > 1) problems.push(`${spec.kind}/${id}: duplicate id ${id}`);
|
|
111
|
+
}
|
|
112
|
+
// Only schema-valid, unambiguous records may satisfy references.
|
|
113
|
+
ids[spec.kind] = new Set(schemaValid
|
|
114
|
+
.map((entry) => entry[spec.idField])
|
|
115
|
+
.filter((id) => counts.get(id) === 1));
|
|
73
116
|
}
|
|
74
117
|
const refChecks = [
|
|
75
118
|
['claims', 'evidence', 'evidence', 'claim_id'],
|
|
@@ -131,6 +174,64 @@ export function checkReferentialIntegrity(registries) {
|
|
|
131
174
|
}
|
|
132
175
|
const reviewItemIds = ids.review_items || new Set();
|
|
133
176
|
for (const plan of registries.sampling_plans?.entries || []) for (const ref of plan.selected_item_ids || []) if (!reviewItemIds.has(ref)) problems.push(`sampling_plans/${plan.sampling_plan_id}: references unknown review item id "${ref}"`);
|
|
177
|
+
|
|
178
|
+
// ── Executive reporting suite cross-registry checks ────────────────────────
|
|
179
|
+
const kpiIds = ids.kpis || new Set();
|
|
180
|
+
const outcomeIds = ids['customer-outcomes'] || new Set();
|
|
181
|
+
const decisionIds = ids.decisions || new Set();
|
|
182
|
+
const assumptionIds = ids.assumptions || new Set();
|
|
183
|
+
const riskIds = ids.risks || new Set();
|
|
184
|
+
const initiativeIds = ids.initiatives || new Set();
|
|
185
|
+
|
|
186
|
+
// variances must reference a known KPI metric_id
|
|
187
|
+
for (const v of registries.variances?.entries || []) {
|
|
188
|
+
if (v.metric_id && !kpiIds.has(v.metric_id))
|
|
189
|
+
problems.push(`variances/${v.variance_id}: metric_id "${v.metric_id}" references unknown kpi`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// decisions: supporting/contradicting evidence can reference outcome IDs
|
|
193
|
+
for (const d of registries.decisions?.entries || []) {
|
|
194
|
+
const prefix = `decisions/${d.decision_id}`;
|
|
195
|
+
for (const ref of d.supporting_evidence || []) {
|
|
196
|
+
if (typeof ref === 'string' && ref.startsWith('OUT-') && !outcomeIds.has(ref))
|
|
197
|
+
problems.push(`${prefix}: supporting_evidence references unknown customer-outcome "${ref}"`);
|
|
198
|
+
}
|
|
199
|
+
for (const ref of d.contradicting_evidence || []) {
|
|
200
|
+
if (typeof ref === 'string' && ref.startsWith('OUT-') && !outcomeIds.has(ref))
|
|
201
|
+
problems.push(`${prefix}: contradicting_evidence references unknown customer-outcome "${ref}"`);
|
|
202
|
+
}
|
|
203
|
+
for (const ref of d.assumptions || []) {
|
|
204
|
+
if (typeof ref === 'string' && ref.startsWith('ASMP-') && !assumptionIds.has(ref))
|
|
205
|
+
problems.push(`${prefix}: assumptions references unknown assumption "${ref}"`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// initiatives: linked_kpis, linked_outcomes, linked_risks, linked_decisions
|
|
210
|
+
for (const i of registries.initiatives?.entries || []) {
|
|
211
|
+
const prefix = `initiatives/${i.initiative_id}`;
|
|
212
|
+
for (const ref of i.linked_kpis || [])
|
|
213
|
+
if (!kpiIds.has(ref)) problems.push(`${prefix}: linked_kpis references unknown kpi "${ref}"`);
|
|
214
|
+
for (const ref of i.linked_outcomes || [])
|
|
215
|
+
if (!outcomeIds.has(ref)) problems.push(`${prefix}: linked_outcomes references unknown customer-outcome "${ref}"`);
|
|
216
|
+
for (const ref of i.linked_risks || [])
|
|
217
|
+
if (!riskIds.has(ref)) problems.push(`${prefix}: linked_risks references unknown risk "${ref}"`);
|
|
218
|
+
for (const ref of i.linked_decisions || [])
|
|
219
|
+
if (!decisionIds.has(ref)) problems.push(`${prefix}: linked_decisions references unknown decision "${ref}"`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// scenarios: variable_ids should reference known KPIs or risks
|
|
223
|
+
for (const s of registries.scenarios?.entries || []) {
|
|
224
|
+
const prefix = `scenarios/${s.scenario_id}`;
|
|
225
|
+
for (const v of s.variables || []) {
|
|
226
|
+
const ref = v.variable_id;
|
|
227
|
+
if (!ref) continue;
|
|
228
|
+
if (ref.startsWith('KPI-') && !kpiIds.has(ref))
|
|
229
|
+
problems.push(`${prefix}: variable "${ref}" references unknown kpi`);
|
|
230
|
+
if (ref.startsWith('RISK-') && !riskIds.has(ref))
|
|
231
|
+
problems.push(`${prefix}: variable "${ref}" references unknown risk`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
134
235
|
return problems;
|
|
135
236
|
}
|
|
136
237
|
|