agent-bober 0.18.0 → 0.19.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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +11 -0
- package/README.md +245 -6
- package/agents/bober-art-director.md +100 -0
- package/agents/bober-design-critic.md +114 -0
- package/agents/bober-frontend-builder.md +101 -0
- package/agents/bober-security-auditor.md +193 -0
- package/agents/bober-security-verifier.md +104 -0
- package/agents/bober-seo-strategist.md +144 -0
- package/agents/bober-seo-verifier.md +103 -0
- package/dist/calendar/calendar-egress.d.ts +26 -0
- package/dist/calendar/calendar-egress.d.ts.map +1 -0
- package/dist/calendar/calendar-egress.js +35 -0
- package/dist/calendar/calendar-egress.js.map +1 -0
- package/dist/calendar/calendar-token.d.ts +34 -0
- package/dist/calendar/calendar-token.d.ts.map +1 -0
- package/dist/calendar/calendar-token.js +56 -0
- package/dist/calendar/calendar-token.js.map +1 -0
- package/dist/calendar/connector.d.ts +22 -0
- package/dist/calendar/connector.d.ts.map +1 -0
- package/dist/calendar/connector.js +3 -0
- package/dist/calendar/connector.js.map +1 -0
- package/dist/calendar/finding-source.d.ts +20 -0
- package/dist/calendar/finding-source.d.ts.map +1 -0
- package/dist/calendar/finding-source.js +35 -0
- package/dist/calendar/finding-source.js.map +1 -0
- package/dist/calendar/google-connector.d.ts +65 -0
- package/dist/calendar/google-connector.d.ts.map +1 -0
- package/dist/calendar/google-connector.js +129 -0
- package/dist/calendar/google-connector.js.map +1 -0
- package/dist/calendar/ics-connector.d.ts +12 -0
- package/dist/calendar/ics-connector.d.ts.map +1 -0
- package/dist/calendar/ics-connector.js +48 -0
- package/dist/calendar/ics-connector.js.map +1 -0
- package/dist/calendar/proposal-gate.d.ts +84 -0
- package/dist/calendar/proposal-gate.d.ts.map +1 -0
- package/dist/calendar/proposal-gate.js +126 -0
- package/dist/calendar/proposal-gate.js.map +1 -0
- package/dist/calendar/slotter.d.ts +34 -0
- package/dist/calendar/slotter.d.ts.map +1 -0
- package/dist/calendar/slotter.js +196 -0
- package/dist/calendar/slotter.js.map +1 -0
- package/dist/calendar/types.d.ts +162 -0
- package/dist/calendar/types.d.ts.map +1 -0
- package/dist/calendar/types.js +28 -0
- package/dist/calendar/types.js.map +1 -0
- package/dist/chat/chat-session.d.ts +27 -0
- package/dist/chat/chat-session.d.ts.map +1 -1
- package/dist/chat/chat-session.js +101 -1
- package/dist/chat/chat-session.js.map +1 -1
- package/dist/chat/slash-commands.d.ts +6 -2
- package/dist/chat/slash-commands.d.ts.map +1 -1
- package/dist/chat/slash-commands.js +22 -2
- package/dist/chat/slash-commands.js.map +1 -1
- package/dist/chat/turn-classifier.d.ts +3 -0
- package/dist/chat/turn-classifier.d.ts.map +1 -1
- package/dist/chat/turn-classifier.js +7 -0
- package/dist/chat/turn-classifier.js.map +1 -1
- package/dist/cli/commands/calendar.d.ts +75 -0
- package/dist/cli/commands/calendar.d.ts.map +1 -0
- package/dist/cli/commands/calendar.js +203 -0
- package/dist/cli/commands/calendar.js.map +1 -0
- package/dist/cli/commands/do.d.ts +52 -0
- package/dist/cli/commands/do.d.ts.map +1 -0
- package/dist/cli/commands/do.js +216 -0
- package/dist/cli/commands/do.js.map +1 -0
- package/dist/cli/commands/hub.d.ts +29 -0
- package/dist/cli/commands/hub.d.ts.map +1 -0
- package/dist/cli/commands/hub.js +233 -0
- package/dist/cli/commands/hub.js.map +1 -0
- package/dist/cli/commands/medical.d.ts +25 -0
- package/dist/cli/commands/medical.d.ts.map +1 -1
- package/dist/cli/commands/medical.js +233 -0
- package/dist/cli/commands/medical.js.map +1 -1
- package/dist/cli/commands/research.d.ts +41 -0
- package/dist/cli/commands/research.d.ts.map +1 -0
- package/dist/cli/commands/research.js +313 -0
- package/dist/cli/commands/research.js.map +1 -0
- package/dist/cli/commands/security-audit.d.ts +89 -0
- package/dist/cli/commands/security-audit.d.ts.map +1 -0
- package/dist/cli/commands/security-audit.js +238 -0
- package/dist/cli/commands/security-audit.js.map +1 -0
- package/dist/cli/commands/task.d.ts +64 -0
- package/dist/cli/commands/task.d.ts.map +1 -0
- package/dist/cli/commands/task.js +422 -0
- package/dist/cli/commands/task.js.map +1 -0
- package/dist/cli/commands/telegram.d.ts +10 -0
- package/dist/cli/commands/telegram.d.ts.map +1 -0
- package/dist/cli/commands/telegram.js +44 -0
- package/dist/cli/commands/telegram.js.map +1 -0
- package/dist/cli/commands/vault.d.ts +40 -0
- package/dist/cli/commands/vault.d.ts.map +1 -0
- package/dist/cli/commands/vault.js +122 -0
- package/dist/cli/commands/vault.js.map +1 -0
- package/dist/cli/index.js +33 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/role-providers.d.ts +15 -0
- package/dist/config/role-providers.d.ts.map +1 -1
- package/dist/config/role-providers.js +8 -1
- package/dist/config/role-providers.js.map +1 -1
- package/dist/config/schema.d.ts +3522 -171
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +405 -2
- package/dist/config/schema.js.map +1 -1
- package/dist/do-bridge/coding-promoter.d.ts +19 -0
- package/dist/do-bridge/coding-promoter.d.ts.map +1 -0
- package/dist/do-bridge/coding-promoter.js +43 -0
- package/dist/do-bridge/coding-promoter.js.map +1 -0
- package/dist/do-bridge/finding-port.d.ts +88 -0
- package/dist/do-bridge/finding-port.d.ts.map +1 -0
- package/dist/do-bridge/finding-port.js +95 -0
- package/dist/do-bridge/finding-port.js.map +1 -0
- package/dist/do-bridge/launcher.d.ts +55 -0
- package/dist/do-bridge/launcher.d.ts.map +1 -0
- package/dist/do-bridge/launcher.js +37 -0
- package/dist/do-bridge/launcher.js.map +1 -0
- package/dist/do-bridge/promote.d.ts +50 -0
- package/dist/do-bridge/promote.d.ts.map +1 -0
- package/dist/do-bridge/promote.js +116 -0
- package/dist/do-bridge/promote.js.map +1 -0
- package/dist/do-bridge/reconcile.d.ts +50 -0
- package/dist/do-bridge/reconcile.d.ts.map +1 -0
- package/dist/do-bridge/reconcile.js +70 -0
- package/dist/do-bridge/reconcile.js.map +1 -0
- package/dist/do-bridge/registry.d.ts +23 -0
- package/dist/do-bridge/registry.d.ts.map +1 -0
- package/dist/do-bridge/registry.js +42 -0
- package/dist/do-bridge/registry.js.map +1 -0
- package/dist/do-bridge/types.d.ts +50 -0
- package/dist/do-bridge/types.d.ts.map +1 -0
- package/dist/do-bridge/types.js +17 -0
- package/dist/do-bridge/types.js.map +1 -0
- package/dist/fleet/child-config.d.ts.map +1 -1
- package/dist/fleet/child-config.js +7 -0
- package/dist/fleet/child-config.js.map +1 -1
- package/dist/fleet/coordinator.d.ts +27 -1
- package/dist/fleet/coordinator.d.ts.map +1 -1
- package/dist/fleet/coordinator.js +70 -0
- package/dist/fleet/coordinator.js.map +1 -1
- package/dist/fleet/critic-deep.d.ts +9 -1
- package/dist/fleet/critic-deep.d.ts.map +1 -1
- package/dist/fleet/critic-deep.js +5 -2
- package/dist/fleet/critic-deep.js.map +1 -1
- package/dist/fleet/decomposer-deep.d.ts +4 -11
- package/dist/fleet/decomposer-deep.d.ts.map +1 -1
- package/dist/fleet/decomposer-deep.js +5 -5
- package/dist/fleet/decomposer-deep.js.map +1 -1
- package/dist/fleet/index.d.ts +9 -0
- package/dist/fleet/index.d.ts.map +1 -1
- package/dist/fleet/index.js +87 -8
- package/dist/fleet/index.js.map +1 -1
- package/dist/fleet/manifest.d.ts +26 -0
- package/dist/fleet/manifest.d.ts.map +1 -1
- package/dist/fleet/manifest.js +8 -0
- package/dist/fleet/manifest.js.map +1 -1
- package/dist/fleet/reporter.d.ts +4 -1
- package/dist/fleet/reporter.d.ts.map +1 -1
- package/dist/fleet/reporter.js +2 -1
- package/dist/fleet/reporter.js.map +1 -1
- package/dist/fleet/scaffolder.d.ts +5 -1
- package/dist/fleet/scaffolder.d.ts.map +1 -1
- package/dist/fleet/scaffolder.js +11 -2
- package/dist/fleet/scaffolder.js.map +1 -1
- package/dist/graph/client.d.ts.map +1 -1
- package/dist/graph/client.js +115 -23
- package/dist/graph/client.js.map +1 -1
- package/dist/graph/mcp-client.d.ts +1 -0
- package/dist/graph/mcp-client.d.ts.map +1 -1
- package/dist/graph/mcp-client.js +58 -7
- package/dist/graph/mcp-client.js.map +1 -1
- package/dist/hub/collector.d.ts +12 -0
- package/dist/hub/collector.d.ts.map +1 -0
- package/dist/hub/collector.js +36 -0
- package/dist/hub/collector.js.map +1 -0
- package/dist/hub/finding-source.d.ts +22 -0
- package/dist/hub/finding-source.d.ts.map +1 -0
- package/dist/hub/finding-source.js +41 -0
- package/dist/hub/finding-source.js.map +1 -0
- package/dist/hub/finding-store.d.ts +68 -0
- package/dist/hub/finding-store.d.ts.map +1 -0
- package/dist/hub/finding-store.js +122 -0
- package/dist/hub/finding-store.js.map +1 -0
- package/dist/hub/finding.d.ts +54 -0
- package/dist/hub/finding.d.ts.map +1 -0
- package/dist/hub/finding.js +24 -0
- package/dist/hub/finding.js.map +1 -0
- package/dist/hub/gmail-to-task.d.ts +69 -0
- package/dist/hub/gmail-to-task.d.ts.map +1 -0
- package/dist/hub/gmail-to-task.js +102 -0
- package/dist/hub/gmail-to-task.js.map +1 -0
- package/dist/hub/hub-config.d.ts +18 -0
- package/dist/hub/hub-config.d.ts.map +1 -0
- package/dist/hub/hub-config.js +40 -0
- package/dist/hub/hub-config.js.map +1 -0
- package/dist/hub/judge.d.ts +30 -0
- package/dist/hub/judge.d.ts.map +1 -0
- package/dist/hub/judge.js +177 -0
- package/dist/hub/judge.js.map +1 -0
- package/dist/hub/lenses.d.ts +60 -0
- package/dist/hub/lenses.d.ts.map +1 -0
- package/dist/hub/lenses.js +123 -0
- package/dist/hub/lenses.js.map +1 -0
- package/dist/hub/priority-md.d.ts +21 -0
- package/dist/hub/priority-md.d.ts.map +1 -0
- package/dist/hub/priority-md.js +64 -0
- package/dist/hub/priority-md.js.map +1 -0
- package/dist/hub/repo-resolver.d.ts +11 -0
- package/dist/hub/repo-resolver.d.ts.map +1 -0
- package/dist/hub/repo-resolver.js +39 -0
- package/dist/hub/repo-resolver.js.map +1 -0
- package/dist/hub/scope.d.ts +39 -0
- package/dist/hub/scope.d.ts.map +1 -0
- package/dist/hub/scope.js +62 -0
- package/dist/hub/scope.js.map +1 -0
- package/dist/hub/task-inbox.d.ts +16 -0
- package/dist/hub/task-inbox.d.ts.map +1 -0
- package/dist/hub/task-inbox.js +39 -0
- package/dist/hub/task-inbox.js.map +1 -0
- package/dist/incident/resolution-verify.d.ts +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/medical/adapters/apple-health.js +1 -1
- package/dist/medical/adapters/apple-health.js.map +1 -1
- package/dist/medical/analysis/cadence.d.ts +32 -0
- package/dist/medical/analysis/cadence.d.ts.map +1 -0
- package/dist/medical/analysis/cadence.js +72 -0
- package/dist/medical/analysis/cadence.js.map +1 -0
- package/dist/medical/analysis/cross-marker.d.ts +33 -0
- package/dist/medical/analysis/cross-marker.d.ts.map +1 -0
- package/dist/medical/analysis/cross-marker.js +79 -0
- package/dist/medical/analysis/cross-marker.js.map +1 -0
- package/dist/medical/analysis/finding-writer.d.ts +26 -0
- package/dist/medical/analysis/finding-writer.d.ts.map +1 -0
- package/dist/medical/analysis/finding-writer.js +60 -0
- package/dist/medical/analysis/finding-writer.js.map +1 -0
- package/dist/medical/analysis/finding.d.ts +63 -0
- package/dist/medical/analysis/finding.d.ts.map +1 -0
- package/dist/medical/analysis/finding.js +70 -0
- package/dist/medical/analysis/finding.js.map +1 -0
- package/dist/medical/analysis/review-pass.d.ts +76 -0
- package/dist/medical/analysis/review-pass.d.ts.map +1 -0
- package/dist/medical/analysis/review-pass.js +119 -0
- package/dist/medical/analysis/review-pass.js.map +1 -0
- package/dist/medical/analysis/trends.d.ts +36 -0
- package/dist/medical/analysis/trends.d.ts.map +1 -0
- package/dist/medical/analysis/trends.js +157 -0
- package/dist/medical/analysis/trends.js.map +1 -0
- package/dist/medical/health-store.d.ts +5 -0
- package/dist/medical/health-store.d.ts.map +1 -1
- package/dist/medical/health-store.js +10 -0
- package/dist/medical/health-store.js.map +1 -1
- package/dist/medical/lab-note.d.ts +72 -0
- package/dist/medical/lab-note.d.ts.map +1 -0
- package/dist/medical/lab-note.js +161 -0
- package/dist/medical/lab-note.js.map +1 -0
- package/dist/medical/lab-pdf-parser.d.ts +19 -0
- package/dist/medical/lab-pdf-parser.d.ts.map +1 -0
- package/dist/medical/lab-pdf-parser.js +57 -0
- package/dist/medical/lab-pdf-parser.js.map +1 -0
- package/dist/medical/lab-reindex.d.ts +24 -0
- package/dist/medical/lab-reindex.d.ts.map +1 -0
- package/dist/medical/lab-reindex.js +45 -0
- package/dist/medical/lab-reindex.js.map +1 -0
- package/dist/medical/lab-types.d.ts +75 -0
- package/dist/medical/lab-types.d.ts.map +1 -0
- package/dist/medical/lab-types.js +17 -0
- package/dist/medical/lab-types.js.map +1 -0
- package/dist/medical/profile.d.ts +96 -0
- package/dist/medical/profile.d.ts.map +1 -0
- package/dist/medical/profile.js +273 -0
- package/dist/medical/profile.js.map +1 -0
- package/dist/medical/recommend/context.d.ts +48 -0
- package/dist/medical/recommend/context.d.ts.map +1 -0
- package/dist/medical/recommend/context.js +109 -0
- package/dist/medical/recommend/context.js.map +1 -0
- package/dist/medical/recommend/judge-panel.d.ts +49 -0
- package/dist/medical/recommend/judge-panel.d.ts.map +1 -0
- package/dist/medical/recommend/judge-panel.js +164 -0
- package/dist/medical/recommend/judge-panel.js.map +1 -0
- package/dist/medical/recommend/lenses.d.ts +72 -0
- package/dist/medical/recommend/lenses.d.ts.map +1 -0
- package/dist/medical/recommend/lenses.js +220 -0
- package/dist/medical/recommend/lenses.js.map +1 -0
- package/dist/medical/recommend/recommend.d.ts +86 -0
- package/dist/medical/recommend/recommend.d.ts.map +1 -0
- package/dist/medical/recommend/recommend.js +211 -0
- package/dist/medical/recommend/recommend.js.map +1 -0
- package/dist/medical/recommend/types.d.ts +98 -0
- package/dist/medical/recommend/types.d.ts.map +1 -0
- package/dist/medical/recommend/types.js +20 -0
- package/dist/medical/recommend/types.js.map +1 -0
- package/dist/medical/recommend/urgency.d.ts +26 -0
- package/dist/medical/recommend/urgency.d.ts.map +1 -0
- package/dist/medical/recommend/urgency.js +124 -0
- package/dist/medical/recommend/urgency.js.map +1 -0
- package/dist/medical/research/online-research.d.ts +65 -0
- package/dist/medical/research/online-research.d.ts.map +1 -0
- package/dist/medical/research/online-research.js +101 -0
- package/dist/medical/research/online-research.js.map +1 -0
- package/dist/medical/research/research-note.d.ts +32 -0
- package/dist/medical/research/research-note.d.ts.map +1 -0
- package/dist/medical/research/research-note.js +55 -0
- package/dist/medical/research/research-note.js.map +1 -0
- package/dist/medical/supplements.d.ts +82 -0
- package/dist/medical/supplements.d.ts.map +1 -0
- package/dist/medical/supplements.js +173 -0
- package/dist/medical/supplements.js.map +1 -0
- package/dist/orchestrator/agentic-loop.d.ts +160 -1
- package/dist/orchestrator/agentic-loop.d.ts.map +1 -1
- package/dist/orchestrator/agentic-loop.js +350 -41
- package/dist/orchestrator/agentic-loop.js.map +1 -1
- package/dist/orchestrator/compaction.d.ts +47 -0
- package/dist/orchestrator/compaction.d.ts.map +1 -0
- package/dist/orchestrator/compaction.js +75 -0
- package/dist/orchestrator/compaction.js.map +1 -0
- package/dist/orchestrator/generator-agent.d.ts +19 -0
- package/dist/orchestrator/generator-agent.d.ts.map +1 -1
- package/dist/orchestrator/generator-agent.js +27 -1
- package/dist/orchestrator/generator-agent.js.map +1 -1
- package/dist/orchestrator/loop-events.d.ts +98 -0
- package/dist/orchestrator/loop-events.d.ts.map +1 -0
- package/dist/orchestrator/loop-events.js +2 -0
- package/dist/orchestrator/loop-events.js.map +1 -0
- package/dist/orchestrator/model-resolver.d.ts.map +1 -1
- package/dist/orchestrator/model-resolver.js +10 -6
- package/dist/orchestrator/model-resolver.js.map +1 -1
- package/dist/orchestrator/pipeline.d.ts +10 -1
- package/dist/orchestrator/pipeline.d.ts.map +1 -1
- package/dist/orchestrator/pipeline.js +102 -4
- package/dist/orchestrator/pipeline.js.map +1 -1
- package/dist/orchestrator/security-audit-types.d.ts +53 -0
- package/dist/orchestrator/security-audit-types.d.ts.map +1 -0
- package/dist/orchestrator/security-audit-types.js +10 -0
- package/dist/orchestrator/security-audit-types.js.map +1 -0
- package/dist/orchestrator/security-auditor-agent.d.ts +68 -0
- package/dist/orchestrator/security-auditor-agent.d.ts.map +1 -0
- package/dist/orchestrator/security-auditor-agent.js +482 -0
- package/dist/orchestrator/security-auditor-agent.js.map +1 -0
- package/dist/orchestrator/security-gate.d.ts +73 -0
- package/dist/orchestrator/security-gate.d.ts.map +1 -0
- package/dist/orchestrator/security-gate.js +174 -0
- package/dist/orchestrator/security-gate.js.map +1 -0
- package/dist/orchestrator/security-hub.d.ts +45 -0
- package/dist/orchestrator/security-hub.d.ts.map +1 -0
- package/dist/orchestrator/security-hub.js +147 -0
- package/dist/orchestrator/security-hub.js.map +1 -0
- package/dist/orchestrator/security-knowledge/benchmark/harness.d.ts +43 -0
- package/dist/orchestrator/security-knowledge/benchmark/harness.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/benchmark/harness.js +13 -0
- package/dist/orchestrator/security-knowledge/benchmark/harness.js.map +1 -0
- package/dist/orchestrator/security-knowledge/diff-provider.d.ts +79 -0
- package/dist/orchestrator/security-knowledge/diff-provider.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/diff-provider.js +320 -0
- package/dist/orchestrator/security-knowledge/diff-provider.js.map +1 -0
- package/dist/orchestrator/security-knowledge/index.d.ts +22 -0
- package/dist/orchestrator/security-knowledge/index.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/index.js +66 -0
- package/dist/orchestrator/security-knowledge/index.js.map +1 -0
- package/dist/orchestrator/security-knowledge/parser.d.ts +9 -0
- package/dist/orchestrator/security-knowledge/parser.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/parser.js +137 -0
- package/dist/orchestrator/security-knowledge/parser.js.map +1 -0
- package/dist/orchestrator/security-knowledge/registry.d.ts +25 -0
- package/dist/orchestrator/security-knowledge/registry.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/registry.js +114 -0
- package/dist/orchestrator/security-knowledge/registry.js.map +1 -0
- package/dist/orchestrator/security-knowledge/resolver.d.ts +48 -0
- package/dist/orchestrator/security-knowledge/resolver.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/resolver.js +63 -0
- package/dist/orchestrator/security-knowledge/resolver.js.map +1 -0
- package/dist/orchestrator/security-knowledge/selector.d.ts +18 -0
- package/dist/orchestrator/security-knowledge/selector.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/selector.js +46 -0
- package/dist/orchestrator/security-knowledge/selector.js.map +1 -0
- package/dist/orchestrator/security-knowledge/signature.d.ts +37 -0
- package/dist/orchestrator/security-knowledge/signature.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/signature.js +2 -0
- package/dist/orchestrator/security-knowledge/signature.js.map +1 -0
- package/dist/orchestrator/security-knowledge/supply-chain-inspector.d.ts +29 -0
- package/dist/orchestrator/security-knowledge/supply-chain-inspector.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/supply-chain-inspector.js +211 -0
- package/dist/orchestrator/security-knowledge/supply-chain-inspector.js.map +1 -0
- package/dist/orchestrator/security-scanners.d.ts +126 -0
- package/dist/orchestrator/security-scanners.d.ts.map +1 -0
- package/dist/orchestrator/security-scanners.js +501 -0
- package/dist/orchestrator/security-scanners.js.map +1 -0
- package/dist/orchestrator/security-verifier-agent.d.ts +62 -0
- package/dist/orchestrator/security-verifier-agent.d.ts.map +1 -0
- package/dist/orchestrator/security-verifier-agent.js +230 -0
- package/dist/orchestrator/security-verifier-agent.js.map +1 -0
- package/dist/orchestrator/session-store.d.ts +95 -0
- package/dist/orchestrator/session-store.d.ts.map +1 -0
- package/dist/orchestrator/session-store.js +186 -0
- package/dist/orchestrator/session-store.js.map +1 -0
- package/dist/orchestrator/stack-knowledge.d.ts +17 -0
- package/dist/orchestrator/stack-knowledge.d.ts.map +1 -0
- package/dist/orchestrator/stack-knowledge.js +35 -0
- package/dist/orchestrator/stack-knowledge.js.map +1 -0
- package/dist/orchestrator/subagents.d.ts +62 -0
- package/dist/orchestrator/subagents.d.ts.map +1 -0
- package/dist/orchestrator/subagents.js +143 -0
- package/dist/orchestrator/subagents.js.map +1 -0
- package/dist/orchestrator/tools/executor.d.ts +68 -0
- package/dist/orchestrator/tools/executor.d.ts.map +1 -0
- package/dist/orchestrator/tools/executor.js +104 -0
- package/dist/orchestrator/tools/executor.js.map +1 -0
- package/dist/orchestrator/tools/mcp-bridge.d.ts +76 -0
- package/dist/orchestrator/tools/mcp-bridge.d.ts.map +1 -0
- package/dist/orchestrator/tools/mcp-bridge.js +154 -0
- package/dist/orchestrator/tools/mcp-bridge.js.map +1 -0
- package/dist/orchestrator/tools/schemas.d.ts.map +1 -1
- package/dist/orchestrator/tools/schemas.js +3 -0
- package/dist/orchestrator/tools/schemas.js.map +1 -1
- package/dist/orchestrator/workflow/budget.d.ts +24 -2
- package/dist/orchestrator/workflow/budget.d.ts.map +1 -1
- package/dist/orchestrator/workflow/budget.js +39 -1
- package/dist/orchestrator/workflow/budget.js.map +1 -1
- package/dist/orchestrator/workflow/engine.d.ts +1 -1
- package/dist/orchestrator/workflow/engine.d.ts.map +1 -1
- package/dist/orchestrator/workflow/selector.d.ts.map +1 -1
- package/dist/orchestrator/workflow/selector.js +10 -0
- package/dist/orchestrator/workflow/selector.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +116 -26
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/claude-code.d.ts.map +1 -1
- package/dist/providers/claude-code.js +17 -0
- package/dist/providers/claude-code.js.map +1 -1
- package/dist/providers/cost-meter.d.ts +52 -0
- package/dist/providers/cost-meter.d.ts.map +1 -0
- package/dist/providers/cost-meter.js +81 -0
- package/dist/providers/cost-meter.js.map +1 -0
- package/dist/providers/factory.d.ts +6 -1
- package/dist/providers/factory.d.ts.map +1 -1
- package/dist/providers/factory.js +24 -5
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +29 -0
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/grounded-search.d.ts +128 -0
- package/dist/providers/grounded-search.d.ts.map +1 -0
- package/dist/providers/grounded-search.js +160 -0
- package/dist/providers/grounded-search.js.map +1 -0
- package/dist/providers/openai-compat.d.ts +15 -1
- package/dist/providers/openai-compat.d.ts.map +1 -1
- package/dist/providers/openai-compat.js +24 -0
- package/dist/providers/openai-compat.js.map +1 -1
- package/dist/providers/openai.d.ts +7 -0
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +95 -4
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/types.d.ts +88 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/research/cadence.d.ts +33 -0
- package/dist/research/cadence.d.ts.map +1 -0
- package/dist/research/cadence.js +55 -0
- package/dist/research/cadence.js.map +1 -0
- package/dist/research/digest.d.ts +80 -0
- package/dist/research/digest.d.ts.map +1 -0
- package/dist/research/digest.js +119 -0
- package/dist/research/digest.js.map +1 -0
- package/dist/research/egress.d.ts +28 -0
- package/dist/research/egress.d.ts.map +1 -0
- package/dist/research/egress.js +41 -0
- package/dist/research/egress.js.map +1 -0
- package/dist/research/job-store.d.ts +30 -0
- package/dist/research/job-store.d.ts.map +1 -0
- package/dist/research/job-store.js +100 -0
- package/dist/research/job-store.js.map +1 -0
- package/dist/research/model-diversity.d.ts +27 -0
- package/dist/research/model-diversity.d.ts.map +1 -0
- package/dist/research/model-diversity.js +52 -0
- package/dist/research/model-diversity.js.map +1 -0
- package/dist/research/note-writer.d.ts +36 -0
- package/dist/research/note-writer.d.ts.map +1 -0
- package/dist/research/note-writer.js +53 -0
- package/dist/research/note-writer.js.map +1 -0
- package/dist/research/online-retrieval.d.ts +27 -0
- package/dist/research/online-retrieval.d.ts.map +1 -0
- package/dist/research/online-retrieval.js +22 -0
- package/dist/research/online-retrieval.js.map +1 -0
- package/dist/research/runner.d.ts +80 -0
- package/dist/research/runner.d.ts.map +1 -0
- package/dist/research/runner.js +115 -0
- package/dist/research/runner.js.map +1 -0
- package/dist/research/scheduler.d.ts +61 -0
- package/dist/research/scheduler.d.ts.map +1 -0
- package/dist/research/scheduler.js +58 -0
- package/dist/research/scheduler.js.map +1 -0
- package/dist/research/types.d.ts +81 -0
- package/dist/research/types.d.ts.map +1 -0
- package/dist/research/types.js +57 -0
- package/dist/research/types.js.map +1 -0
- package/dist/seo/adapters/http.d.ts +43 -0
- package/dist/seo/adapters/http.d.ts.map +1 -0
- package/dist/seo/adapters/http.js +35 -0
- package/dist/seo/adapters/http.js.map +1 -0
- package/dist/seo/ai-visibility-provider.d.ts +171 -0
- package/dist/seo/ai-visibility-provider.d.ts.map +1 -0
- package/dist/seo/ai-visibility-provider.js +165 -0
- package/dist/seo/ai-visibility-provider.js.map +1 -0
- package/dist/seo/ai-visibility-scorer.d.ts +43 -0
- package/dist/seo/ai-visibility-scorer.d.ts.map +1 -0
- package/dist/seo/ai-visibility-scorer.js +102 -0
- package/dist/seo/ai-visibility-scorer.js.map +1 -0
- package/dist/seo/analyzer.d.ts +58 -0
- package/dist/seo/analyzer.d.ts.map +1 -0
- package/dist/seo/analyzer.js +265 -0
- package/dist/seo/analyzer.js.map +1 -0
- package/dist/seo/benchmark/harness.d.ts +56 -0
- package/dist/seo/benchmark/harness.d.ts.map +1 -0
- package/dist/seo/benchmark/harness.js +172 -0
- package/dist/seo/benchmark/harness.js.map +1 -0
- package/dist/seo/builder/approved-finding.d.ts +115 -0
- package/dist/seo/builder/approved-finding.d.ts.map +1 -0
- package/dist/seo/builder/approved-finding.js +145 -0
- package/dist/seo/builder/approved-finding.js.map +1 -0
- package/dist/seo/builder/build-runner.d.ts +41 -0
- package/dist/seo/builder/build-runner.d.ts.map +1 -0
- package/dist/seo/builder/build-runner.js +156 -0
- package/dist/seo/builder/build-runner.js.map +1 -0
- package/dist/seo/builder/draft-generators.d.ts +32 -0
- package/dist/seo/builder/draft-generators.d.ts.map +1 -0
- package/dist/seo/builder/draft-generators.js +31 -0
- package/dist/seo/builder/draft-generators.js.map +1 -0
- package/dist/seo/builder/draft-store.d.ts +30 -0
- package/dist/seo/builder/draft-store.d.ts.map +1 -0
- package/dist/seo/builder/draft-store.js +76 -0
- package/dist/seo/builder/draft-store.js.map +1 -0
- package/dist/seo/builder/draft-types.d.ts +36 -0
- package/dist/seo/builder/draft-types.d.ts.map +1 -0
- package/dist/seo/builder/draft-types.js +14 -0
- package/dist/seo/builder/draft-types.js.map +1 -0
- package/dist/seo/builder/hub-approved-source.d.ts +11 -0
- package/dist/seo/builder/hub-approved-source.d.ts.map +1 -0
- package/dist/seo/builder/hub-approved-source.js +48 -0
- package/dist/seo/builder/hub-approved-source.js.map +1 -0
- package/dist/seo/builder/seo-builder.d.ts +72 -0
- package/dist/seo/builder/seo-builder.d.ts.map +1 -0
- package/dist/seo/builder/seo-builder.js +72 -0
- package/dist/seo/builder/seo-builder.js.map +1 -0
- package/dist/seo/citation-gate.d.ts +36 -0
- package/dist/seo/citation-gate.d.ts.map +1 -0
- package/dist/seo/citation-gate.js +59 -0
- package/dist/seo/citation-gate.js.map +1 -0
- package/dist/seo/command.d.ts +11 -0
- package/dist/seo/command.d.ts.map +1 -0
- package/dist/seo/command.js +90 -0
- package/dist/seo/command.js.map +1 -0
- package/dist/seo/content-sanitizer.d.ts +56 -0
- package/dist/seo/content-sanitizer.d.ts.map +1 -0
- package/dist/seo/content-sanitizer.js +55 -0
- package/dist/seo/content-sanitizer.js.map +1 -0
- package/dist/seo/crawl-engine.d.ts +35 -0
- package/dist/seo/crawl-engine.d.ts.map +1 -0
- package/dist/seo/crawl-engine.js +2 -0
- package/dist/seo/crawl-engine.js.map +1 -0
- package/dist/seo/data-source.d.ts +156 -0
- package/dist/seo/data-source.d.ts.map +1 -0
- package/dist/seo/data-source.js +2 -0
- package/dist/seo/data-source.js.map +1 -0
- package/dist/seo/egress.d.ts +39 -0
- package/dist/seo/egress.d.ts.map +1 -0
- package/dist/seo/egress.js +64 -0
- package/dist/seo/egress.js.map +1 -0
- package/dist/seo/hub-emitter.d.ts +28 -0
- package/dist/seo/hub-emitter.d.ts.map +1 -0
- package/dist/seo/hub-emitter.js +95 -0
- package/dist/seo/hub-emitter.js.map +1 -0
- package/dist/seo/index.d.ts +42 -0
- package/dist/seo/index.d.ts.map +1 -0
- package/dist/seo/index.js +19 -0
- package/dist/seo/index.js.map +1 -0
- package/dist/seo/never-encode-filter.d.ts +45 -0
- package/dist/seo/never-encode-filter.d.ts.map +1 -0
- package/dist/seo/never-encode-filter.js +51 -0
- package/dist/seo/never-encode-filter.js.map +1 -0
- package/dist/seo/parser.d.ts +46 -0
- package/dist/seo/parser.d.ts.map +1 -0
- package/dist/seo/parser.js +113 -0
- package/dist/seo/parser.js.map +1 -0
- package/dist/seo/playbook-index.d.ts +19 -0
- package/dist/seo/playbook-index.d.ts.map +1 -0
- package/dist/seo/playbook-index.js +74 -0
- package/dist/seo/playbook-index.js.map +1 -0
- package/dist/seo/quota-governor.d.ts +100 -0
- package/dist/seo/quota-governor.d.ts.map +1 -0
- package/dist/seo/quota-governor.js +199 -0
- package/dist/seo/quota-governor.js.map +1 -0
- package/dist/seo/quota-ledger.d.ts +50 -0
- package/dist/seo/quota-ledger.d.ts.map +1 -0
- package/dist/seo/quota-ledger.js +95 -0
- package/dist/seo/quota-ledger.js.map +1 -0
- package/dist/seo/report-store.d.ts +30 -0
- package/dist/seo/report-store.d.ts.map +1 -0
- package/dist/seo/report-store.js +94 -0
- package/dist/seo/report-store.js.map +1 -0
- package/dist/seo/retriever.d.ts +34 -0
- package/dist/seo/retriever.d.ts.map +1 -0
- package/dist/seo/retriever.js +95 -0
- package/dist/seo/retriever.js.map +1 -0
- package/dist/seo/runner.d.ts +108 -0
- package/dist/seo/runner.d.ts.map +1 -0
- package/dist/seo/runner.js +512 -0
- package/dist/seo/runner.js.map +1 -0
- package/dist/seo/scrape-throttle.d.ts +84 -0
- package/dist/seo/scrape-throttle.d.ts.map +1 -0
- package/dist/seo/scrape-throttle.js +149 -0
- package/dist/seo/scrape-throttle.js.map +1 -0
- package/dist/seo/serp-provider.d.ts +52 -0
- package/dist/seo/serp-provider.d.ts.map +1 -0
- package/dist/seo/serp-provider.js +17 -0
- package/dist/seo/serp-provider.js.map +1 -0
- package/dist/seo/sources/ai-visibility-adapter.d.ts +87 -0
- package/dist/seo/sources/ai-visibility-adapter.d.ts.map +1 -0
- package/dist/seo/sources/ai-visibility-adapter.js +85 -0
- package/dist/seo/sources/ai-visibility-adapter.js.map +1 -0
- package/dist/seo/sources/api-spine-provider.d.ts +66 -0
- package/dist/seo/sources/api-spine-provider.d.ts.map +1 -0
- package/dist/seo/sources/api-spine-provider.js +68 -0
- package/dist/seo/sources/api-spine-provider.js.map +1 -0
- package/dist/seo/sources/citation-verifier.d.ts +95 -0
- package/dist/seo/sources/citation-verifier.d.ts.map +1 -0
- package/dist/seo/sources/citation-verifier.js +106 -0
- package/dist/seo/sources/citation-verifier.js.map +1 -0
- package/dist/seo/sources/crawl-source.d.ts +62 -0
- package/dist/seo/sources/crawl-source.d.ts.map +1 -0
- package/dist/seo/sources/crawl-source.js +87 -0
- package/dist/seo/sources/crawl-source.js.map +1 -0
- package/dist/seo/sources/damcrawler-crawl-engine.d.ts +151 -0
- package/dist/seo/sources/damcrawler-crawl-engine.d.ts.map +1 -0
- package/dist/seo/sources/damcrawler-crawl-engine.js +154 -0
- package/dist/seo/sources/damcrawler-crawl-engine.js.map +1 -0
- package/dist/seo/sources/damcrawler-serp-provider.d.ts +75 -0
- package/dist/seo/sources/damcrawler-serp-provider.d.ts.map +1 -0
- package/dist/seo/sources/damcrawler-serp-provider.js +60 -0
- package/dist/seo/sources/damcrawler-serp-provider.js.map +1 -0
- package/dist/seo/sources/dataforseo-adapter.d.ts +46 -0
- package/dist/seo/sources/dataforseo-adapter.d.ts.map +1 -0
- package/dist/seo/sources/dataforseo-adapter.js +335 -0
- package/dist/seo/sources/dataforseo-adapter.js.map +1 -0
- package/dist/seo/sources/dataforseo-serp-provider.d.ts +30 -0
- package/dist/seo/sources/dataforseo-serp-provider.d.ts.map +1 -0
- package/dist/seo/sources/dataforseo-serp-provider.js +20 -0
- package/dist/seo/sources/dataforseo-serp-provider.js.map +1 -0
- package/dist/seo/sources/engine-scrape-parser-chatgpt.d.ts +62 -0
- package/dist/seo/sources/engine-scrape-parser-chatgpt.d.ts.map +1 -0
- package/dist/seo/sources/engine-scrape-parser-chatgpt.js +72 -0
- package/dist/seo/sources/engine-scrape-parser-chatgpt.js.map +1 -0
- package/dist/seo/sources/engine-scrape-parser-perplexity.d.ts +10 -0
- package/dist/seo/sources/engine-scrape-parser-perplexity.d.ts.map +1 -0
- package/dist/seo/sources/engine-scrape-parser-perplexity.js +72 -0
- package/dist/seo/sources/engine-scrape-parser-perplexity.js.map +1 -0
- package/dist/seo/sources/gsc-adapter.d.ts +64 -0
- package/dist/seo/sources/gsc-adapter.d.ts.map +1 -0
- package/dist/seo/sources/gsc-adapter.js +221 -0
- package/dist/seo/sources/gsc-adapter.js.map +1 -0
- package/dist/seo/sources/local-export.d.ts +53 -0
- package/dist/seo/sources/local-export.d.ts.map +1 -0
- package/dist/seo/sources/local-export.js +307 -0
- package/dist/seo/sources/local-export.js.map +1 -0
- package/dist/seo/sources/mention-citation-extractor.d.ts +136 -0
- package/dist/seo/sources/mention-citation-extractor.d.ts.map +1 -0
- package/dist/seo/sources/mention-citation-extractor.js +272 -0
- package/dist/seo/sources/mention-citation-extractor.js.map +1 -0
- package/dist/seo/sources/scrape-arm-provider.d.ts +109 -0
- package/dist/seo/sources/scrape-arm-provider.d.ts.map +1 -0
- package/dist/seo/sources/scrape-arm-provider.js +129 -0
- package/dist/seo/sources/scrape-arm-provider.js.map +1 -0
- package/dist/seo/tracked-prompt-store.d.ts +33 -0
- package/dist/seo/tracked-prompt-store.d.ts.map +1 -0
- package/dist/seo/tracked-prompt-store.js +68 -0
- package/dist/seo/tracked-prompt-store.js.map +1 -0
- package/dist/seo/types.d.ts +128 -0
- package/dist/seo/types.d.ts.map +1 -0
- package/dist/seo/types.js +14 -0
- package/dist/seo/types.js.map +1 -0
- package/dist/seo/verifier.d.ts +34 -0
- package/dist/seo/verifier.d.ts.map +1 -0
- package/dist/seo/verifier.js +204 -0
- package/dist/seo/verifier.js.map +1 -0
- package/dist/seo/workflow-capabilities.d.ts +26 -0
- package/dist/seo/workflow-capabilities.d.ts.map +1 -0
- package/dist/seo/workflow-capabilities.js +12 -0
- package/dist/seo/workflow-capabilities.js.map +1 -0
- package/dist/state/facts.d.ts +5 -1
- package/dist/state/facts.d.ts.map +1 -1
- package/dist/state/facts.js +29 -19
- package/dist/state/facts.js.map +1 -1
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +1 -1
- package/dist/state/index.js.map +1 -1
- package/dist/state/outline-state.d.ts +0 -12
- package/dist/state/outline-state.d.ts.map +1 -1
- package/dist/state/outline-state.js +1 -18
- package/dist/state/outline-state.js.map +1 -1
- package/dist/state/security-audit-state.d.ts +20 -0
- package/dist/state/security-audit-state.d.ts.map +1 -0
- package/dist/state/security-audit-state.js +59 -0
- package/dist/state/security-audit-state.js.map +1 -0
- package/dist/teams/registry.d.ts.map +1 -1
- package/dist/teams/registry.js +17 -0
- package/dist/teams/registry.js.map +1 -1
- package/dist/telegram/bot.d.ts +137 -0
- package/dist/telegram/bot.d.ts.map +1 -0
- package/dist/telegram/bot.js +323 -0
- package/dist/telegram/bot.js.map +1 -0
- package/dist/telegram/digest.d.ts +19 -0
- package/dist/telegram/digest.d.ts.map +1 -0
- package/dist/telegram/digest.js +23 -0
- package/dist/telegram/digest.js.map +1 -0
- package/dist/telegram/fleet-view.d.ts +38 -0
- package/dist/telegram/fleet-view.d.ts.map +1 -0
- package/dist/telegram/fleet-view.js +98 -0
- package/dist/telegram/fleet-view.js.map +1 -0
- package/dist/telegram/handlers/approvals.d.ts +61 -0
- package/dist/telegram/handlers/approvals.d.ts.map +1 -0
- package/dist/telegram/handlers/approvals.js +122 -0
- package/dist/telegram/handlers/approvals.js.map +1 -0
- package/dist/telegram/handlers/capture.d.ts +43 -0
- package/dist/telegram/handlers/capture.d.ts.map +1 -0
- package/dist/telegram/handlers/capture.js +51 -0
- package/dist/telegram/handlers/capture.js.map +1 -0
- package/dist/telegram/handlers/prioritize.d.ts +50 -0
- package/dist/telegram/handlers/prioritize.d.ts.map +1 -0
- package/dist/telegram/handlers/prioritize.js +99 -0
- package/dist/telegram/handlers/prioritize.js.map +1 -0
- package/dist/telegram/handlers/upload.d.ts +105 -0
- package/dist/telegram/handlers/upload.d.ts.map +1 -0
- package/dist/telegram/handlers/upload.js +149 -0
- package/dist/telegram/handlers/upload.js.map +1 -0
- package/dist/telegram/keyboard.d.ts +48 -0
- package/dist/telegram/keyboard.d.ts.map +1 -0
- package/dist/telegram/keyboard.js +81 -0
- package/dist/telegram/keyboard.js.map +1 -0
- package/dist/telegram/outbound.d.ts +77 -0
- package/dist/telegram/outbound.d.ts.map +1 -0
- package/dist/telegram/outbound.js +45 -0
- package/dist/telegram/outbound.js.map +1 -0
- package/dist/telegram/router.d.ts +46 -0
- package/dist/telegram/router.d.ts.map +1 -0
- package/dist/telegram/router.js +63 -0
- package/dist/telegram/router.js.map +1 -0
- package/dist/telegram/streaming.d.ts +36 -0
- package/dist/telegram/streaming.d.ts.map +1 -0
- package/dist/telegram/streaming.js +55 -0
- package/dist/telegram/streaming.js.map +1 -0
- package/dist/telegram/whitelist.d.ts +20 -0
- package/dist/telegram/whitelist.d.ts.map +1 -0
- package/dist/telegram/whitelist.js +34 -0
- package/dist/telegram/whitelist.js.map +1 -0
- package/dist/utils/git.d.ts +0 -6
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +0 -19
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/vault/conventions.d.ts +23 -0
- package/dist/vault/conventions.d.ts.map +1 -0
- package/dist/vault/conventions.js +22 -0
- package/dist/vault/conventions.js.map +1 -0
- package/dist/vault/frontmatter.d.ts +47 -0
- package/dist/vault/frontmatter.d.ts.map +1 -0
- package/dist/vault/frontmatter.js +149 -0
- package/dist/vault/frontmatter.js.map +1 -0
- package/dist/vault/index-map.d.ts +35 -0
- package/dist/vault/index-map.d.ts.map +1 -0
- package/dist/vault/index-map.js +67 -0
- package/dist/vault/index-map.js.map +1 -0
- package/dist/vault/mcp-adapter.d.ts +96 -0
- package/dist/vault/mcp-adapter.d.ts.map +1 -0
- package/dist/vault/mcp-adapter.js +176 -0
- package/dist/vault/mcp-adapter.js.map +1 -0
- package/dist/vault/note-io.d.ts +29 -0
- package/dist/vault/note-io.d.ts.map +1 -0
- package/dist/vault/note-io.js +44 -0
- package/dist/vault/note-io.js.map +1 -0
- package/dist/vault/profile.d.ts +35 -0
- package/dist/vault/profile.d.ts.map +1 -0
- package/dist/vault/profile.js +50 -0
- package/dist/vault/profile.js.map +1 -0
- package/dist/vault/reindex.d.ts +55 -0
- package/dist/vault/reindex.d.ts.map +1 -0
- package/dist/vault/reindex.js +69 -0
- package/dist/vault/reindex.js.map +1 -0
- package/dist/vault/types.d.ts +25 -0
- package/dist/vault/types.d.ts.map +1 -0
- package/dist/vault/types.js +9 -0
- package/dist/vault/types.js.map +1 -0
- package/package.json +20 -4
- package/scripts/sync-targets.json +2 -1
- package/skills/bober.design/SKILL.md +190 -0
- package/skills/bober.design/references/1-anti-slop.md +102 -0
- package/skills/bober.design/references/2-design-brief.md +84 -0
- package/skills/bober.design/references/3-critique-rubric.md +62 -0
- package/skills/bober.design/references/4-copy-guide.md +43 -0
- package/skills/bober.plan/SKILL.md +15 -1
- package/skills/bober.run/SKILL.md +7 -4
- package/skills/bober.security-anchor/SKILL.md +172 -0
- package/skills/bober.security-audit/SKILL.md +288 -0
- package/skills/bober.security-dex-backend/SKILL.md +306 -0
- package/skills/bober.security-generic/SKILL.md +295 -0
- package/skills/bober.security-igaming/SKILL.md +290 -0
- package/skills/bober.security-node/SKILL.md +267 -0
- package/skills/bober.security-payments/SKILL.md +249 -0
- package/skills/bober.security-react/SKILL.md +194 -0
- package/skills/bober.security-solidity/SKILL.md +306 -0
- package/skills/bober.seo/SKILL.md +132 -0
- package/skills/bober.seo-ai-visibility/SKILL.md +110 -0
- package/skills/bober.seo-content-decay/SKILL.md +99 -0
- package/skills/bober.seo-generic/SKILL.md +173 -0
- package/skills/bober.seo-internal-linking/SKILL.md +87 -0
- package/skills/bober.seo-parasite-watch/SKILL.md +121 -0
- package/skills/bober.seo-rank-track/SKILL.md +98 -0
- package/skills/bober.seo-schema-audit/SKILL.md +97 -0
- package/skills/bober.seo-technical-audit/SKILL.md +113 -0
- package/skills/bober.seo-topical-map/SKILL.md +100 -0
- package/skills/bober.seo-verticals/SKILL.md +133 -0
- package/skills/bober.using-bober/SKILL.md +1 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SeoAnalyzer — LLM-grounded synthesis of `SeoFinding[]` via the
|
|
3
|
+
* provider-agnostic adapter layer (spec-20260715-ultimate-seo-suite,
|
|
4
|
+
* Sprint 10; arch-20260715-ultimate-seo-agents-skills-architecture.md:242-276).
|
|
5
|
+
*
|
|
6
|
+
* The `llm`/`model` are CONSTRUCTOR-injected (mirrors
|
|
7
|
+
* `SeoPlaybookRetriever(index)`, retriever.ts:121, and
|
|
8
|
+
* `getGroundingVerdict({llm,model})`, grounding-critic.ts:170-177) — the
|
|
9
|
+
* real client is built by the Sprint 11 runner via `createClient`
|
|
10
|
+
* (providers/factory.ts:192); tests inject a scripted fake, never a real
|
|
11
|
+
* provider.
|
|
12
|
+
*
|
|
13
|
+
* Defensive parse (3-tier extraction + zod `safeParse`, copied from
|
|
14
|
+
* `validateGroundingVerdict`, grounding-critic.ts:40-88) NEVER throws on a
|
|
15
|
+
* parse failure — it returns `{ findings: [], parsed: false }`
|
|
16
|
+
* (fail-closed, sc-10-2). A TRANSPORT error from `llm.chat` is a different
|
|
17
|
+
* failure mode and is left to propagate (mirrors
|
|
18
|
+
* grounding-critic.test.ts:273-289) — it is not caught here.
|
|
19
|
+
*
|
|
20
|
+
* `now` is injected (Sprint 10 nonGoal: "Analyzer must not read the clock
|
|
21
|
+
* or the filesystem for time") — this file never constructs a Date object
|
|
22
|
+
* and never looks up the current wall-clock time itself.
|
|
23
|
+
*
|
|
24
|
+
* `context` is typed as `SeoRetrieveResult` (retriever.ts:22-25), the
|
|
25
|
+
* concrete type that already carries `promptFragment` — NOT a
|
|
26
|
+
* `SeoPlaybookContext` (that name appears in the architecture prose but no
|
|
27
|
+
* such type exists in the codebase; see the sprint briefing §0).
|
|
28
|
+
*/
|
|
29
|
+
import { z } from "zod";
|
|
30
|
+
import { AiVisibilityScorer } from "./ai-visibility-scorer.js";
|
|
31
|
+
// -- Model-facing finding schema (defensive, never trusts the LLM blindly) --
|
|
32
|
+
const SeoFindingEvidenceSchema = z.object({
|
|
33
|
+
metric: z.string(),
|
|
34
|
+
value: z.string(),
|
|
35
|
+
source: z.string(),
|
|
36
|
+
url: z.string(),
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* What we require the MODEL to emit per finding. `workflow` is deliberately
|
|
40
|
+
* excluded — the analyzer stamps `input.workflow` onto every finding itself
|
|
41
|
+
* rather than trusting the model to echo it back correctly. `severity` is a
|
|
42
|
+
* strict 1..5 literal union: an out-of-range value (e.g. `7`) fails
|
|
43
|
+
* validation rather than silently producing an out-of-range `SeoFinding`.
|
|
44
|
+
*/
|
|
45
|
+
const SeoModelFindingSchema = z.object({
|
|
46
|
+
recommendation: z.string().min(1),
|
|
47
|
+
playbookRef: z.string().min(1),
|
|
48
|
+
citationUrl: z.string(),
|
|
49
|
+
evidence: z.array(SeoFindingEvidenceSchema).default([]),
|
|
50
|
+
severity: z.union([z.literal(1), z.literal(2), z.literal(3), z.literal(4), z.literal(5)]),
|
|
51
|
+
humanApprovalRequired: z.boolean(),
|
|
52
|
+
confidence: z.enum(["firm", "tentative"]),
|
|
53
|
+
});
|
|
54
|
+
const SeoFindingsContainerSchema = z.object({
|
|
55
|
+
findings: z.array(SeoModelFindingSchema),
|
|
56
|
+
});
|
|
57
|
+
// -- Prompt construction ------------------------------------------------
|
|
58
|
+
const SEO_FINDING_JSON_SHAPE = `{
|
|
59
|
+
"findings": [
|
|
60
|
+
{
|
|
61
|
+
"recommendation": "<concrete, actionable recommendation>",
|
|
62
|
+
"playbookRef": "<the playbookId (from the playbook context above) this recommendation is grounded in>",
|
|
63
|
+
"citationUrl": "<REQUIRED absolute http(s) URL to a primary source backing this recommendation>",
|
|
64
|
+
"evidence": [ { "metric": "<name>", "value": "<observed value>", "source": "<data source>", "url": "<source url>" } ],
|
|
65
|
+
"severity": 1,
|
|
66
|
+
"humanApprovalRequired": false,
|
|
67
|
+
"confidence": "firm"
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}`;
|
|
71
|
+
function describeDataOutcome(label, outcome) {
|
|
72
|
+
if (outcome === undefined)
|
|
73
|
+
return `${label}: not requested.`;
|
|
74
|
+
switch (outcome.kind) {
|
|
75
|
+
case "disabled":
|
|
76
|
+
return `${label}: disabled (no data source configured for this capability).`;
|
|
77
|
+
case "abstain":
|
|
78
|
+
return `${label}: abstained — ${outcome.reason}.`;
|
|
79
|
+
case "data":
|
|
80
|
+
return (`${label} (source: ${outcome.provenance.source}, retrieved: ${outcome.provenance.retrievedAt}):\n` +
|
|
81
|
+
JSON.stringify(outcome.rows));
|
|
82
|
+
default: {
|
|
83
|
+
const _exhaustive = outcome;
|
|
84
|
+
return _exhaustive;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Runs `AiVisibilityScorer.aggregate` ONLY when the outcome is a live
|
|
90
|
+
* ai-visibility arm — i.e. `kind === "data"` AND
|
|
91
|
+
* `provenance.source === "ai-visibility"` (the ONLY producer of that stamp
|
|
92
|
+
* is the live adapter, `ai-visibility-adapter.ts:136`; NOT the decoy
|
|
93
|
+
* `QuotaRequest.source` at `ai-visibility-adapter.ts:116`). Every other
|
|
94
|
+
* outcome (local-export, disabled, abstain, undefined) falls through to the
|
|
95
|
+
* UNCHANGED `describeDataOutcome` path — byte-identical to pre-change
|
|
96
|
+
* (sc-5-4, ADR-5 byte-identical-when-off guarantee).
|
|
97
|
+
*/
|
|
98
|
+
function describeAiVisibility(outcome) {
|
|
99
|
+
if (outcome?.kind === "data" && outcome.provenance.source === "ai-visibility") {
|
|
100
|
+
const metrics = new AiVisibilityScorer().aggregate(outcome.rows);
|
|
101
|
+
return (`AI Visibility (source: ${outcome.provenance.source}, retrieved: ${outcome.provenance.retrievedAt}):\n` +
|
|
102
|
+
JSON.stringify(metrics));
|
|
103
|
+
}
|
|
104
|
+
return describeDataOutcome("AI Visibility", outcome);
|
|
105
|
+
}
|
|
106
|
+
function buildDataBundleSummary(data) {
|
|
107
|
+
return [
|
|
108
|
+
describeDataOutcome("Search Analytics", data.searchAnalytics),
|
|
109
|
+
describeDataOutcome("URL Inspection", data.urlInspection),
|
|
110
|
+
describeDataOutcome("SERP", data.serp),
|
|
111
|
+
describeDataOutcome("Keywords", data.keywords),
|
|
112
|
+
describeDataOutcome("Backlinks", data.backlinks),
|
|
113
|
+
describeAiVisibility(data.aiVisibility),
|
|
114
|
+
describeDataOutcome("Link Graph", data.linkGraph),
|
|
115
|
+
].join("\n\n");
|
|
116
|
+
}
|
|
117
|
+
/** Prompt = the retriever's `promptFragment` + the serialized `DataOutcome` bundle + an explicit output contract. */
|
|
118
|
+
function buildSystemPrompt(input) {
|
|
119
|
+
return [
|
|
120
|
+
`You are an SEO analysis engine for the "${input.workflow}" workflow, target "${input.target}".`,
|
|
121
|
+
`Current reference date/time (for freshness judgments only): ${input.now}.`,
|
|
122
|
+
`Ground every recommendation in the playbook context and the gathered data below — never invent data.`,
|
|
123
|
+
`--- Playbook context ---`,
|
|
124
|
+
input.context.promptFragment,
|
|
125
|
+
`--- Gathered data ---`,
|
|
126
|
+
buildDataBundleSummary(input.data),
|
|
127
|
+
`--- Output contract ---`,
|
|
128
|
+
`Output ONLY a single JSON object (no prose, no markdown fences, no tool calls) with EXACTLY this shape:`,
|
|
129
|
+
SEO_FINDING_JSON_SHAPE,
|
|
130
|
+
`Rules:`,
|
|
131
|
+
`- EVERY finding MUST have a non-empty, well-formed http(s) "citationUrl" pointing to a primary ` +
|
|
132
|
+
`source (an official search-engine/platform documentation page, or a first-party data point ` +
|
|
133
|
+
`already present in the gathered data above). A finding without a well-formed citationUrl will ` +
|
|
134
|
+
`be dropped before it reaches any human or report.`,
|
|
135
|
+
`- Set "humanApprovalRequired": true for any tactic that touches policy compliance or spend ` +
|
|
136
|
+
`(paid links, ad/budget spend, live-API-cost actions, or anything that could trigger a manual ` +
|
|
137
|
+
`search-engine action).`,
|
|
138
|
+
`- "severity" must be an integer from 1 (informational) to 5 (critical).`,
|
|
139
|
+
`- If the evidence is thin or indirect, set "confidence": "tentative" rather than overstating certainty.`,
|
|
140
|
+
`- If there is nothing actionable in the data above, return {"findings": []}.`,
|
|
141
|
+
].join("\n\n");
|
|
142
|
+
}
|
|
143
|
+
function parseFindingsContainer(rawText) {
|
|
144
|
+
let parsed;
|
|
145
|
+
try {
|
|
146
|
+
parsed = JSON.parse(rawText.trim());
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Tier 2: extract from a fenced ```json ... ``` block.
|
|
150
|
+
const fenceMatch = /```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/.exec(rawText);
|
|
151
|
+
if (fenceMatch) {
|
|
152
|
+
try {
|
|
153
|
+
parsed = JSON.parse(fenceMatch[1].trim());
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// fall through to tier 3
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Tier 3: take the first { ... last } span.
|
|
160
|
+
if (parsed === undefined) {
|
|
161
|
+
const braceStart = rawText.indexOf("{");
|
|
162
|
+
const braceEnd = rawText.lastIndexOf("}");
|
|
163
|
+
if (braceStart !== -1 && braceEnd > braceStart) {
|
|
164
|
+
try {
|
|
165
|
+
parsed = JSON.parse(rawText.slice(braceStart, braceEnd + 1));
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return { ok: false, error: `No valid JSON object found in response. Raw: ${rawText.slice(0, 200)}` };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
return { ok: false, error: `No JSON object found in response. Raw: ${rawText.slice(0, 200)}` };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const result = SeoFindingsContainerSchema.safeParse(parsed);
|
|
177
|
+
if (!result.success) {
|
|
178
|
+
const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
|
|
179
|
+
return { ok: false, error: issues };
|
|
180
|
+
}
|
|
181
|
+
return { ok: true, findings: result.data.findings };
|
|
182
|
+
}
|
|
183
|
+
// -- Assembly -------------------------------------------------------------
|
|
184
|
+
/**
|
|
185
|
+
* Maps one model-emitted finding onto a full `SeoFinding`, stamping the
|
|
186
|
+
* caller-known `workflow` and applying defense-in-depth for
|
|
187
|
+
* `humanApprovalRequired`: OR the model's value with a lookup — a finding
|
|
188
|
+
* grounded in a `playbookRef` whose matching `SeoSignature.policyClass` is
|
|
189
|
+
* `"human-approve"` is always flagged for human approval, even if the model
|
|
190
|
+
* forgot to set the flag itself.
|
|
191
|
+
*
|
|
192
|
+
* Applies the same signature-driven-override idiom to `confidence`
|
|
193
|
+
* (spec-20260717-seo-improver-builder, Sprint 3, ADR-2): a finding grounded
|
|
194
|
+
* in a signature whose `liveWeightStatus` is `"documented-only"` cannot be
|
|
195
|
+
* emitted as `"firm"` — it is downgraded to `"tentative"`, because
|
|
196
|
+
* "documented" guidance is not (yet) corroborated by a live ranking signal.
|
|
197
|
+
* This is DOWNGRADE-ONLY: `"live-corroborated"`/`"unknown"` never change
|
|
198
|
+
* `confidence`, and there is no branch that upgrades `"tentative"` ->
|
|
199
|
+
* `"firm"`.
|
|
200
|
+
*/
|
|
201
|
+
function toSeoFinding(modelFinding, workflow, signaturesByPlaybookId) {
|
|
202
|
+
const signature = signaturesByPlaybookId.get(modelFinding.playbookRef);
|
|
203
|
+
const humanApprovalRequired = modelFinding.humanApprovalRequired || signature?.policyClass === "human-approve";
|
|
204
|
+
const confidence = signature?.liveWeightStatus === "documented-only" && modelFinding.confidence === "firm"
|
|
205
|
+
? "tentative"
|
|
206
|
+
: modelFinding.confidence;
|
|
207
|
+
return {
|
|
208
|
+
recommendation: modelFinding.recommendation,
|
|
209
|
+
workflow,
|
|
210
|
+
playbookRef: modelFinding.playbookRef,
|
|
211
|
+
citationUrl: modelFinding.citationUrl,
|
|
212
|
+
evidence: modelFinding.evidence,
|
|
213
|
+
severity: modelFinding.severity,
|
|
214
|
+
humanApprovalRequired,
|
|
215
|
+
confidence,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function collectDataProvenance(data) {
|
|
219
|
+
const provenance = [];
|
|
220
|
+
for (const outcome of [
|
|
221
|
+
data.searchAnalytics,
|
|
222
|
+
data.urlInspection,
|
|
223
|
+
data.serp,
|
|
224
|
+
data.keywords,
|
|
225
|
+
data.backlinks,
|
|
226
|
+
data.aiVisibility,
|
|
227
|
+
data.linkGraph,
|
|
228
|
+
]) {
|
|
229
|
+
if (outcome?.kind === "data")
|
|
230
|
+
provenance.push(outcome.provenance);
|
|
231
|
+
}
|
|
232
|
+
return provenance;
|
|
233
|
+
}
|
|
234
|
+
// -- SeoAnalyzer ------------------------------------------------------------
|
|
235
|
+
export class SeoAnalyzer {
|
|
236
|
+
llm;
|
|
237
|
+
model;
|
|
238
|
+
constructor(llm, model) {
|
|
239
|
+
this.llm = llm;
|
|
240
|
+
this.model = model;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Never throws on a PARSE failure (returns `parsed: false` with empty
|
|
244
|
+
* findings). Does NOT catch a transport error from `llm.chat` — that
|
|
245
|
+
* rejects the returned promise, distinct from a parse failure.
|
|
246
|
+
*/
|
|
247
|
+
async analyze(input) {
|
|
248
|
+
const { workflow, target, context, data } = input;
|
|
249
|
+
const response = await this.llm.chat({
|
|
250
|
+
model: this.model,
|
|
251
|
+
system: buildSystemPrompt(input),
|
|
252
|
+
messages: [{ role: "user", content: "Produce the findings JSON now." }],
|
|
253
|
+
jsonObjectMode: true,
|
|
254
|
+
});
|
|
255
|
+
const dataProvenance = collectDataProvenance(data);
|
|
256
|
+
const parsedResult = parseFindingsContainer(response.text);
|
|
257
|
+
if (!parsedResult.ok) {
|
|
258
|
+
return { workflow, target, findings: [], parsed: false, dataProvenance };
|
|
259
|
+
}
|
|
260
|
+
const signaturesByPlaybookId = new Map(context.signatures.map((s) => [s.playbookId, s]));
|
|
261
|
+
const findings = parsedResult.findings.map((f) => toSeoFinding(f, workflow, signaturesByPlaybookId));
|
|
262
|
+
return { workflow, target, findings, parsed: true, dataProvenance };
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/seo/analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAgD/D,8EAA8E;AAE9E,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;CAChB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACvD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACzF,qBAAqB,EAAE,CAAC,CAAC,OAAO,EAAE;IAClC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC1C,CAAC,CAAC;AAIH,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;CACzC,CAAC,CAAC;AAEH,0EAA0E;AAE1E,MAAM,sBAAsB,GAAG;;;;;;;;;;;;EAY7B,CAAC;AAEH,SAAS,mBAAmB,CAAI,KAAa,EAAE,OAAmC;IAChF,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,GAAG,KAAK,kBAAkB,CAAC;IAC7D,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,UAAU;YACb,OAAO,GAAG,KAAK,6DAA6D,CAAC;QAC/E,KAAK,SAAS;YACZ,OAAO,GAAG,KAAK,iBAAiB,OAAO,CAAC,MAAM,GAAG,CAAC;QACpD,KAAK,MAAM;YACT,OAAO,CACL,GAAG,KAAK,aAAa,OAAO,CAAC,UAAU,CAAC,MAAM,gBAAgB,OAAO,CAAC,UAAU,CAAC,WAAW,MAAM;gBAClG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAC7B,CAAC;QACJ,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,OAAO,CAAC;YACnC,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAAC,OAAmD;IAC/E,IAAI,OAAO,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;QAC9E,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjE,OAAO,CACL,0BAA0B,OAAO,CAAC,UAAU,CAAC,MAAM,gBAAgB,OAAO,CAAC,UAAU,CAAC,WAAW,MAAM;YACvG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CACxB,CAAC;IACJ,CAAC;IACD,OAAO,mBAAmB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAmB;IACjD,OAAO;QACL,mBAAmB,CAAC,kBAAkB,EAAE,IAAI,CAAC,eAAe,CAAC;QAC7D,mBAAmB,CAAC,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC;QACzD,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;QACtC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;QAC9C,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC;QAChD,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC;QACvC,mBAAmB,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC;KAClD,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACjB,CAAC;AAED,qHAAqH;AACrH,SAAS,iBAAiB,CAAC,KAAsB;IAC/C,OAAO;QACL,2CAA2C,KAAK,CAAC,QAAQ,uBAAuB,KAAK,CAAC,MAAM,IAAI;QAChG,+DAA+D,KAAK,CAAC,GAAG,GAAG;QAC3E,sGAAsG;QACtG,0BAA0B;QAC1B,KAAK,CAAC,OAAO,CAAC,cAAc;QAC5B,uBAAuB;QACvB,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC;QAClC,yBAAyB;QACzB,yGAAyG;QACzG,sBAAsB;QACtB,QAAQ;QACR,iGAAiG;YAC/F,6FAA6F;YAC7F,gGAAgG;YAChG,mDAAmD;QACrD,6FAA6F;YAC3F,+FAA+F;YAC/F,wBAAwB;QAC1B,yEAAyE;QACzE,yGAAyG;QACzG,8EAA8E;KAC/E,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACjB,CAAC;AAMD,SAAS,sBAAsB,CAAC,OAAe;IAC7C,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;QACvD,MAAM,UAAU,GAAG,uCAAuC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzE,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;YAAC,MAAM,CAAC;gBACP,yBAAyB;YAC3B,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,UAAU,EAAE,CAAC;gBAC/C,IAAI,CAAC;oBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC/D,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gDAAgD,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;gBACvG,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,0CAA0C,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;YACjG,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;AACtD,CAAC;AAED,4EAA4E;AAE5E;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,YAAY,CACnB,YAA6B,EAC7B,QAAqB,EACrB,sBAAiD;IAEjD,MAAM,SAAS,GAAG,sBAAsB,CAAC,GAAG,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IACvE,MAAM,qBAAqB,GACzB,YAAY,CAAC,qBAAqB,IAAI,SAAS,EAAE,WAAW,KAAK,eAAe,CAAC;IAEnF,MAAM,UAAU,GACd,SAAS,EAAE,gBAAgB,KAAK,iBAAiB,IAAI,YAAY,CAAC,UAAU,KAAK,MAAM;QACrF,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC;IAE9B,OAAO;QACL,cAAc,EAAE,YAAY,CAAC,cAAc;QAC3C,QAAQ;QACR,WAAW,EAAE,YAAY,CAAC,WAAW;QACrC,WAAW,EAAE,YAAY,CAAC,WAAW;QACrC,QAAQ,EAAE,YAAY,CAAC,QAAQ;QAC/B,QAAQ,EAAE,YAAY,CAAC,QAAQ;QAC/B,qBAAqB;QACrB,UAAU;KACX,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAmB;IAChD,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,KAAK,MAAM,OAAO,IAAI;QACpB,IAAI,CAAC,eAAe;QACpB,IAAI,CAAC,aAAa;QAClB,IAAI,CAAC,IAAI;QACT,IAAI,CAAC,QAAQ;QACb,IAAI,CAAC,SAAS;QACd,IAAI,CAAC,YAAY;QACjB,IAAI,CAAC,SAAS;KACf,EAAE,CAAC;QACF,IAAI,OAAO,EAAE,IAAI,KAAK,MAAM;YAAE,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,8EAA8E;AAE9E,MAAM,OAAO,WAAW;IAEH;IACA;IAFnB,YACmB,GAAc,EACd,KAAa;QADb,QAAG,GAAH,GAAG,CAAW;QACd,UAAK,GAAL,KAAK,CAAQ;IAC7B,CAAC;IAEJ;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,KAAsB;QAClC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;QAElD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YACnC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC;YAChC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC;YACvE,cAAc,EAAE,IAAI;SACrB,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,YAAY,GAAG,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE3D,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;YACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;QAC3E,CAAC;QAED,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACzF,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,sBAAsB,CAAC,CAAC,CAAC;QAErG,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;IACtE,CAAC;CACF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Finding } from "../../hub/finding.js";
|
|
2
|
+
import type { SeoReport, SeoWorkflow } from "../types.js";
|
|
3
|
+
/** One labelled benchmark case (mirrors a `corpus/manifest.json` entry). */
|
|
4
|
+
export interface SeoBenchmarkCase {
|
|
5
|
+
/** Stable id, unique in the corpus. */
|
|
6
|
+
id: string;
|
|
7
|
+
label: "known-good" | "known-bad";
|
|
8
|
+
workflow: SeoWorkflow;
|
|
9
|
+
target: string;
|
|
10
|
+
/** Written to a temp `<projectRoot>/<id>/imports/<file>` dir before the run. */
|
|
11
|
+
imports: Array<{
|
|
12
|
+
file: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}>;
|
|
15
|
+
/** The recorded raw text the `ScriptedClient` returns (a `{"findings":[...]}` JSON string, or garbage to prove fail-closed parsing). */
|
|
16
|
+
analyzerResponse: string;
|
|
17
|
+
expected: {
|
|
18
|
+
/** Each expected finding names its `playbookRef` and whether it should survive the citation gate. */
|
|
19
|
+
findings: Array<{
|
|
20
|
+
playbookRef: string;
|
|
21
|
+
cited: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
droppedUncited: number;
|
|
24
|
+
verdict: "pass" | "blocked";
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface CorpusMetrics {
|
|
28
|
+
/** ΣTP/(ΣTP+ΣFP) across every case, matched by the `playbook:<ref>` tag. */
|
|
29
|
+
findingPrecision: number;
|
|
30
|
+
/** ΣTP/(ΣTP+ΣFN) across every case. */
|
|
31
|
+
findingRecall: number;
|
|
32
|
+
/** Σ correctlyDropped / Σ expectedDropped — how well the uncited-drop count matches expectation. */
|
|
33
|
+
uncitedDropRecall: number;
|
|
34
|
+
/** INVARIANT: MUST be 0 — count of emitted findings lacking a well-formed `cite:` evidence entry. */
|
|
35
|
+
uncitedReachedSink: number;
|
|
36
|
+
/** INVARIANT: MUST be 0 — count of emitted findings whose text matches a never-encode tactic pattern. */
|
|
37
|
+
neverEncodeEmitted: number;
|
|
38
|
+
cases: Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
emitted: Finding[];
|
|
41
|
+
report?: SeoReport;
|
|
42
|
+
exitCode: 0 | 2;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run the real `SeoWorkflowRunner` over `corpus`, offline and deterministic
|
|
47
|
+
* (both egress axes off, an injected `ScriptedClient`-backed analyzer, and a
|
|
48
|
+
* capturing sink standing in for the hub). Writes each case's inline
|
|
49
|
+
* `imports[]` under `<projectRoot>/<id>/imports/` before running so
|
|
50
|
+
* `LocalExportSource` reads real files (no fs mocks, principle L44).
|
|
51
|
+
*
|
|
52
|
+
* NEVER throws: `SeoWorkflowRunner.run` itself never throws (runner.ts:256),
|
|
53
|
+
* and every step here is either that call or pure aggregation.
|
|
54
|
+
*/
|
|
55
|
+
export declare function runBenchmark(corpus: SeoBenchmarkCase[], projectRoot: string): Promise<CorpusMetrics>;
|
|
56
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../src/seo/benchmark/harness.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAMpD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAsB1D,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,YAAY,GAAG,WAAW,CAAC;IAClC,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,wIAAwI;IACxI,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE;QACR,qGAAqG;QACrG,QAAQ,EAAE,KAAK,CAAC;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QACzD,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;KAC7B,CAAC;CACH;AAiBD,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,oGAAoG;IACpG,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qGAAqG;IACrG,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yGAAyG;IACzG,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAC;QAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,CAAC;CACvF;AAyDD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA6D1G"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SeoWorkflowRunner benchmark harness (spec-20260715-ultimate-seo-suite,
|
|
3
|
+
* Sprint 13, sc-13-1..sc-13-4). Mirrors the shape of the security benchmark
|
|
4
|
+
* (`src/orchestrator/security-knowledge/benchmark/harness.ts`'s pure
|
|
5
|
+
* `measure()`), but is RICHER: this harness actually RUNS the real
|
|
6
|
+
* `SeoWorkflowRunner.run` (async, fs) per labelled corpus case rather than
|
|
7
|
+
* calling an injected pure finder/verifier function directly. Every case
|
|
8
|
+
* injects `dataSource` + `analyzer` + `findingSink` (Pattern A, `runner.ts`)
|
|
9
|
+
* so `selectSource`/`buildDefaultAnalyzer`/`createClient` and the real
|
|
10
|
+
* `FactStore` are never touched — the whole run is offline and
|
|
11
|
+
* credential-free (nonGoal: "offline fixtures only").
|
|
12
|
+
*
|
|
13
|
+
* Not wired into `SeoWorkflowRunner`, the CLI, or any evaluator gate
|
|
14
|
+
* (nonGoal: "do not gate the pipeline on a precision/recall threshold this
|
|
15
|
+
* sprint") — this is a leaf measurement module consumed only by
|
|
16
|
+
* `harness.test.ts`.
|
|
17
|
+
*
|
|
18
|
+
* Clock discipline: `BENCHMARK_NOW` is a fixed constant threaded into every
|
|
19
|
+
* case's `now` — this file never constructs a `Date` for wall-clock
|
|
20
|
+
* purposes and never calls `Math.random`.
|
|
21
|
+
*/
|
|
22
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
import { createDefaultConfig } from "../../config/schema.js";
|
|
25
|
+
import { SeoAnalyzer } from "../analyzer.js";
|
|
26
|
+
import { SeoWorkflowRunner } from "../runner.js";
|
|
27
|
+
import { LocalExportSource } from "../sources/local-export.js";
|
|
28
|
+
// -- ScriptedClient (recorded analyzer response; NO network) --------------
|
|
29
|
+
//
|
|
30
|
+
// Mirrors `src/seo/analyzer.test.ts:11-21` / `src/seo/runner.test.ts:46-56`.
|
|
31
|
+
// Records every `ChatParams` it receives and replays `case.analyzerResponse`
|
|
32
|
+
// verbatim — this is the deterministic "recorded LLM response" a benchmark
|
|
33
|
+
// needs: no network call, no provider key, reproducible across runs.
|
|
34
|
+
class ScriptedClient {
|
|
35
|
+
responses;
|
|
36
|
+
calls = [];
|
|
37
|
+
idx = 0;
|
|
38
|
+
constructor(responses) {
|
|
39
|
+
this.responses = responses;
|
|
40
|
+
}
|
|
41
|
+
async chat(params) {
|
|
42
|
+
this.calls.push(params);
|
|
43
|
+
const text = this.responses[Math.min(this.idx, this.responses.length - 1)] ?? "";
|
|
44
|
+
this.idx += 1;
|
|
45
|
+
return { text, toolCalls: [], stopReason: "end", usage: { inputTokens: 3, outputTokens: 5 } };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// -- Emitted-text never-encode guard ---------------------------------------
|
|
49
|
+
//
|
|
50
|
+
// A documented mirror of the widened `FORBIDDEN_ACTION_PATTERNS`
|
|
51
|
+
// (`src/seo/skills-content.test.ts`) — scanned over EMITTED (sink-reached)
|
|
52
|
+
// findings rather than skill signatures. Deliberately test-local per the
|
|
53
|
+
// briefing (do not import a `.test.ts` const into this build file).
|
|
54
|
+
const NEVER_ENCODE_EMIT_PATTERNS = [
|
|
55
|
+
/\bplace\b[^.]*\b(parasite|high-?authority host|third-?party host)/i,
|
|
56
|
+
/\b(?:buy(?:ing)?|purchas(?:e|ing))\b[^.]*\blinks?\b/i,
|
|
57
|
+
/\bregister(ing)?\b[^.]*\bexpired domain/i,
|
|
58
|
+
/\bgenerate\b[^.]*\bmass\b[^.]*\bpages\b/i,
|
|
59
|
+
/\b(?:mass[-\s]?generat(?:e|ing)|generat(?:e|ing)[-\s]?mass)\b/i,
|
|
60
|
+
/\bpoison/i,
|
|
61
|
+
];
|
|
62
|
+
const BENCHMARK_NOW = "2026-07-16T00:00:00.000Z"; // FIXED — never new Date()
|
|
63
|
+
// -- Matching + invariant helpers (pure) -----------------------------------
|
|
64
|
+
function extractPlaybookRef(finding) {
|
|
65
|
+
const tag = finding.tags.find((t) => t.startsWith("playbook:"));
|
|
66
|
+
return tag?.slice("playbook:".length);
|
|
67
|
+
}
|
|
68
|
+
/** True when `finding` lacks a well-formed absolute http(s) `cite:` evidence entry (uncited-drop invariant scan). */
|
|
69
|
+
function lacksWellFormedCitation(finding) {
|
|
70
|
+
const citeEntry = finding.evidence.find((e) => e.startsWith("cite:"));
|
|
71
|
+
if (!citeEntry)
|
|
72
|
+
return true;
|
|
73
|
+
try {
|
|
74
|
+
const parsed = new URL(citeEntry.slice("cite:".length));
|
|
75
|
+
return parsed.protocol !== "http:" && parsed.protocol !== "https:";
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** True when `finding`'s title+evidence text matches a never-encode tactic pattern. */
|
|
82
|
+
function matchesNeverEncode(finding) {
|
|
83
|
+
const text = `${finding.title} ${finding.evidence.join(" ")}`;
|
|
84
|
+
return NEVER_ENCODE_EMIT_PATTERNS.some((p) => p.test(text));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Score one case's emitted findings against its `expected.findings` by
|
|
88
|
+
* `playbookRef`, matching a multiset (each expected-cited entry consumes at
|
|
89
|
+
* most one emitted finding with the same ref). Pure and total.
|
|
90
|
+
*/
|
|
91
|
+
function scoreCase(caseDef, emitted) {
|
|
92
|
+
const remainingRefs = emitted.map((f) => extractPlaybookRef(f));
|
|
93
|
+
const expectedCitedRefs = caseDef.expected.findings.filter((f) => f.cited).map((f) => f.playbookRef);
|
|
94
|
+
let tp = 0;
|
|
95
|
+
for (const ref of expectedCitedRefs) {
|
|
96
|
+
const idx = remainingRefs.indexOf(ref);
|
|
97
|
+
if (idx !== -1) {
|
|
98
|
+
tp += 1;
|
|
99
|
+
remainingRefs.splice(idx, 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { tp, fp: remainingRefs.length, fn: expectedCitedRefs.length - tp };
|
|
103
|
+
}
|
|
104
|
+
const rate = (numerator, denominator) => (denominator === 0 ? 0 : numerator / denominator);
|
|
105
|
+
// -- runBenchmark -------------------------------------------------------
|
|
106
|
+
/**
|
|
107
|
+
* Run the real `SeoWorkflowRunner` over `corpus`, offline and deterministic
|
|
108
|
+
* (both egress axes off, an injected `ScriptedClient`-backed analyzer, and a
|
|
109
|
+
* capturing sink standing in for the hub). Writes each case's inline
|
|
110
|
+
* `imports[]` under `<projectRoot>/<id>/imports/` before running so
|
|
111
|
+
* `LocalExportSource` reads real files (no fs mocks, principle L44).
|
|
112
|
+
*
|
|
113
|
+
* NEVER throws: `SeoWorkflowRunner.run` itself never throws (runner.ts:256),
|
|
114
|
+
* and every step here is either that call or pure aggregation.
|
|
115
|
+
*/
|
|
116
|
+
export async function runBenchmark(corpus, projectRoot) {
|
|
117
|
+
let tpSum = 0;
|
|
118
|
+
let fpSum = 0;
|
|
119
|
+
let fnSum = 0;
|
|
120
|
+
let correctlyDroppedSum = 0;
|
|
121
|
+
let expectedDroppedSum = 0;
|
|
122
|
+
let uncitedReachedSink = 0;
|
|
123
|
+
let neverEncodeEmitted = 0;
|
|
124
|
+
const cases = [];
|
|
125
|
+
for (const caseDef of corpus) {
|
|
126
|
+
const caseRoot = join(projectRoot, caseDef.id);
|
|
127
|
+
const importsDir = join(caseRoot, "imports");
|
|
128
|
+
await mkdir(importsDir, { recursive: true });
|
|
129
|
+
for (const file of caseDef.imports) {
|
|
130
|
+
await writeFile(join(importsDir, file.file), file.content, "utf-8");
|
|
131
|
+
}
|
|
132
|
+
const dataSource = new LocalExportSource(importsDir);
|
|
133
|
+
const analyzer = new SeoAnalyzer(new ScriptedClient([caseDef.analyzerResponse]), "benchmark-model");
|
|
134
|
+
const emitted = [];
|
|
135
|
+
const findingSink = async (finding) => {
|
|
136
|
+
emitted.push(finding);
|
|
137
|
+
};
|
|
138
|
+
const outcome = await new SeoWorkflowRunner().run({
|
|
139
|
+
projectRoot: caseRoot,
|
|
140
|
+
config: createDefaultConfig("seo-benchmark", "brownfield"),
|
|
141
|
+
workflow: caseDef.workflow,
|
|
142
|
+
target: caseDef.target,
|
|
143
|
+
now: BENCHMARK_NOW,
|
|
144
|
+
dataSource,
|
|
145
|
+
analyzer,
|
|
146
|
+
findingSink,
|
|
147
|
+
});
|
|
148
|
+
const { tp, fp, fn } = scoreCase(caseDef, emitted);
|
|
149
|
+
tpSum += tp;
|
|
150
|
+
fpSum += fp;
|
|
151
|
+
fnSum += fn;
|
|
152
|
+
const actualDropped = outcome.report?.droppedUncited ?? 0;
|
|
153
|
+
correctlyDroppedSum += Math.min(actualDropped, caseDef.expected.droppedUncited);
|
|
154
|
+
expectedDroppedSum += caseDef.expected.droppedUncited;
|
|
155
|
+
for (const finding of emitted) {
|
|
156
|
+
if (lacksWellFormedCitation(finding))
|
|
157
|
+
uncitedReachedSink += 1;
|
|
158
|
+
if (matchesNeverEncode(finding))
|
|
159
|
+
neverEncodeEmitted += 1;
|
|
160
|
+
}
|
|
161
|
+
cases.push({ id: caseDef.id, emitted, report: outcome.report, exitCode: outcome.exitCode });
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
findingPrecision: rate(tpSum, tpSum + fpSum),
|
|
165
|
+
findingRecall: rate(tpSum, tpSum + fnSum),
|
|
166
|
+
uncitedDropRecall: rate(correctlyDroppedSum, expectedDroppedSum),
|
|
167
|
+
uncitedReachedSink,
|
|
168
|
+
neverEncodeEmitted,
|
|
169
|
+
cases,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../src/seo/benchmark/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApprovedFinding — the structural safety boundary between the hub and the
|
|
3
|
+
* Sprint-12 `SeoBuilder` (spec-20260717-seo-improver-builder, Sprint 11;
|
|
4
|
+
* ADR-4, `.bober/architecture/arch-20260716-seo-improver-builder-extension-adr-4.md`).
|
|
5
|
+
*
|
|
6
|
+
* Constructible ONLY via `ApprovedFinding.from(...)` — the sole factory,
|
|
7
|
+
* itself never throwing — which asserts the hub Finding is human-approved
|
|
8
|
+
* AND carries a well-formed `cite:` evidence URL before minting an instance.
|
|
9
|
+
* A raw/dropped/downgraded/uncited `SeoFinding` has NO public path into this
|
|
10
|
+
* type: a dropped finding never reached the hub as an approved action, so no
|
|
11
|
+
* `ApprovedFinding` can exist for it (resurrection structurally impossible,
|
|
12
|
+
* sc-11-1/sc-11-2).
|
|
13
|
+
*
|
|
14
|
+
* Schema-vs-contract reconciliation (see the Sprint-11 briefing §0): the
|
|
15
|
+
* canonical hub `FindingSchema.status` (`../hub/finding.js:23`) is
|
|
16
|
+
* `z.enum(["open","in-progress","snoozed","done","dropped"])` — there is NO
|
|
17
|
+
* `"approved"` status, so `finding.status === "approved"` against a raw
|
|
18
|
+
* `Finding` is a TS2367 compile error. Mirroring the do-bridge port-local
|
|
19
|
+
* pattern (`../do-bridge/finding-port.ts:10-19`, "the hub schema is NOT
|
|
20
|
+
* modified"), `ApprovedHubFindingSchema` below WIDENS the status union
|
|
21
|
+
* locally — `../hub/finding.ts` stays byte-identical. Likewise `Finding` has
|
|
22
|
+
* no top-level `citationUrl`; the SEO citation round-trips inside
|
|
23
|
+
* `evidence[]` as a `cite:<url>` string (encoded at
|
|
24
|
+
* `../hub-emitter.ts:76`, decode precedent at `../benchmark/harness.ts:112-121`)
|
|
25
|
+
* — `extractCitationUrl` below decodes exactly what the emitter encoded.
|
|
26
|
+
*/
|
|
27
|
+
import { z } from "zod";
|
|
28
|
+
/**
|
|
29
|
+
* Builder-local widened view of the hub `Finding` shape — adds `"approved"`
|
|
30
|
+
* to the status union WITHOUT mutating the canonical `FindingSchema`
|
|
31
|
+
* (mirrors `../../do-bridge/finding-port.ts:10-19`). Every other field is
|
|
32
|
+
* reused verbatim via `.extend()`.
|
|
33
|
+
*/
|
|
34
|
+
export declare const ApprovedHubFindingSchema: z.ZodObject<{
|
|
35
|
+
id: z.ZodString;
|
|
36
|
+
domain: z.ZodString;
|
|
37
|
+
title: z.ZodString;
|
|
38
|
+
kind: z.ZodEnum<["action", "watch", "risk", "question"]>;
|
|
39
|
+
urgency: z.ZodNumber;
|
|
40
|
+
severity: z.ZodNumber;
|
|
41
|
+
evidence: z.ZodArray<z.ZodString, "many">;
|
|
42
|
+
surfacedAt: z.ZodString;
|
|
43
|
+
dueBy: z.ZodOptional<z.ZodString>;
|
|
44
|
+
tags: z.ZodArray<z.ZodString, "many">;
|
|
45
|
+
estDurationMin: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
calendarSafeTitle: z.ZodOptional<z.ZodString>;
|
|
47
|
+
promotesTo: z.ZodOptional<z.ZodString>;
|
|
48
|
+
} & {
|
|
49
|
+
status: z.ZodEnum<["open", "in-progress", "snoozed", "done", "dropped", "approved"]>;
|
|
50
|
+
}, "strip", z.ZodTypeAny, {
|
|
51
|
+
id: string;
|
|
52
|
+
domain: string;
|
|
53
|
+
title: string;
|
|
54
|
+
kind: "action" | "watch" | "risk" | "question";
|
|
55
|
+
status: "open" | "in-progress" | "snoozed" | "done" | "dropped" | "approved";
|
|
56
|
+
urgency: number;
|
|
57
|
+
severity: number;
|
|
58
|
+
evidence: string[];
|
|
59
|
+
surfacedAt: string;
|
|
60
|
+
tags: string[];
|
|
61
|
+
dueBy?: string | undefined;
|
|
62
|
+
estDurationMin?: number | undefined;
|
|
63
|
+
calendarSafeTitle?: string | undefined;
|
|
64
|
+
promotesTo?: string | undefined;
|
|
65
|
+
}, {
|
|
66
|
+
id: string;
|
|
67
|
+
domain: string;
|
|
68
|
+
title: string;
|
|
69
|
+
kind: "action" | "watch" | "risk" | "question";
|
|
70
|
+
status: "open" | "in-progress" | "snoozed" | "done" | "dropped" | "approved";
|
|
71
|
+
urgency: number;
|
|
72
|
+
severity: number;
|
|
73
|
+
evidence: string[];
|
|
74
|
+
surfacedAt: string;
|
|
75
|
+
tags: string[];
|
|
76
|
+
dueBy?: string | undefined;
|
|
77
|
+
estDurationMin?: number | undefined;
|
|
78
|
+
calendarSafeTitle?: string | undefined;
|
|
79
|
+
promotesTo?: string | undefined;
|
|
80
|
+
}>;
|
|
81
|
+
export type ApprovedHubFinding = z.infer<typeof ApprovedHubFindingSchema>;
|
|
82
|
+
/**
|
|
83
|
+
* A hub Finding a human has approved, carrying a decoded, well-formed
|
|
84
|
+
* citation. The private constructor + private brand field together make
|
|
85
|
+
* this type NOMINAL: a structurally-similar plain object (e.g. a raw
|
|
86
|
+
* `SeoFinding` literal) is never assignable, and `new ApprovedFinding(...)`
|
|
87
|
+
* is unreachable outside this module. `ApprovedFinding.from` is the ONLY
|
|
88
|
+
* public construction path.
|
|
89
|
+
*/
|
|
90
|
+
export declare class ApprovedFinding {
|
|
91
|
+
/** The hub Finding id this instance was derived from (provenance). */
|
|
92
|
+
readonly sourceFindingId: string;
|
|
93
|
+
readonly title: string;
|
|
94
|
+
/** Extracted from the `cite:` evidence entry — never invented. */
|
|
95
|
+
readonly sourceCitationUrl: string;
|
|
96
|
+
readonly severity: 1 | 2 | 3 | 4 | 5;
|
|
97
|
+
/** From the `playbook:` tag; empty string if the tag is absent. */
|
|
98
|
+
readonly playbookRef: string;
|
|
99
|
+
/** From the `workflow:` tag; empty string if the tag is absent. */
|
|
100
|
+
readonly workflow: string;
|
|
101
|
+
private readonly __brand;
|
|
102
|
+
private constructor();
|
|
103
|
+
/** Debug representation; also reads `__brand` so it is not flagged unused under `noUnusedLocals`. */
|
|
104
|
+
toString(): string;
|
|
105
|
+
/**
|
|
106
|
+
* The ONLY way to build an `ApprovedFinding`. Returns `null` — NEVER
|
|
107
|
+
* throws — when `finding.status !== "approved"` or the `cite:` evidence
|
|
108
|
+
* entry is missing/malformed. This is the single gate ADR-4's Risk
|
|
109
|
+
* section calls out: "if the adapter itself trusts an un-approved
|
|
110
|
+
* Finding, the guarantee leaks" — so both checks happen here, in the one
|
|
111
|
+
* place an `ApprovedFinding` can be minted.
|
|
112
|
+
*/
|
|
113
|
+
static from(finding: ApprovedHubFinding): ApprovedFinding | null;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=approved-finding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approved-finding.d.ts","sourceRoot":"","sources":["../../../src/seo/builder/approved-finding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAgD1E;;;;;;;GAOG;AACH,qBAAa,eAAe;IAQxB,sEAAsE;IACtE,QAAQ,CAAC,eAAe,EAAE,MAAM;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,kEAAkE;IAClE,QAAQ,CAAC,iBAAiB,EAAE,MAAM;IAClC,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;IACpC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAZ3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IAEtD,OAAO;IAaP,qGAAqG;IACrG,QAAQ,IAAI,MAAM;IAIlB;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,GAAG,eAAe,GAAG,IAAI;CAsBjE"}
|